]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/tuner-xc2028.c
V4L/DVB (6429): Avoid having two tuner commands happening at the same time
[linux-2.6-omap-h63xx.git] / drivers / media / video / tuner-xc2028.c
1 /* tuner-xc2028
2  *
3  * Copyright (c) 2007 Mauro Carvalho Chehab (mchehab@infradead.org)
4  * Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com)
5  *       - frontend interface
6  * This code is placed under the terms of the GNU General Public License v2
7  */
8
9 #include <linux/i2c.h>
10 #include <asm/div64.h>
11 #include <linux/firmware.h>
12 #include <linux/videodev.h>
13 #include <linux/delay.h>
14 #include <media/tuner.h>
15 #include <linux/mutex.h>
16 #include "tuner-driver.h"
17 #include "tuner-xc2028.h"
18
19 #include <linux/dvb/frontend.h>
20 #include "dvb_frontend.h"
21
22 /* digital TV standards */
23 #define V4L2_STD_DTV_6MHZ       ((v4l2_std_id)0x04000000)
24 #define V4L2_STD_DTV_7MHZ       ((v4l2_std_id)0x08000000)
25 #define V4L2_STD_DTV_8MHZ       ((v4l2_std_id)0x10000000)
26
27 /* Firmwares used on tm5600/tm6000 + xc2028/xc3028 */
28
29 /* Generic firmwares */
30 static const char *firmware_INIT0      = "tm_xc3028_MTS_init0.fw";
31 static const char *firmware_8MHZ_INIT0 = "tm_xc3028_8M_MTS_init0.fw";
32 static const char *firmware_INIT1      = "tm_xc3028_68M_MTS_init1.fw";
33
34 /* Standard-specific firmwares */
35 static const char *firmware_6M         = "tm_xc3028_DTV_6M.fw";
36 static const char *firmware_7M         = "tm_xc3028_DTV_7M.fw";
37 static const char *firmware_8M         = "tm_xc3028_DTV_8M.fw";
38 static const char *firmware_B          = "tm_xc3028_B_PAL.fw";
39 static const char *firmware_DK         = "tm_xc3028_DK_PAL_MTS.fw";
40 static const char *firmware_MN         = "tm_xc3028_MN_BTSC.fw";
41
42 struct xc2028_data {
43         v4l2_std_id             firm_type;         /* video stds supported
44                                                         by current firmware */
45         fe_bandwidth_t          bandwidth;         /* Firmware bandwidth:
46                                                               6M, 7M or 8M */
47         int                     need_load_generic; /* The generic firmware
48                                                               were loaded? */
49         enum tuner_mode mode;
50         struct i2c_client       *i2c_client;
51         
52         struct mutex lock;
53 };
54
55 #define i2c_send(rc,c,buf,size)                                         \
56 if (size != (rc = i2c_master_send(c, buf, size)))                       \
57         tuner_warn("i2c output error: rc = %d (should be %d)\n",        \
58         rc, (int)size);
59
60 #define i2c_rcv(rc,c,buf,size)                                          \
61 if (size != (rc = i2c_master_recv(c, buf, size)))                       \
62         tuner_warn("i2c input error: rc = %d (should be %d)\n",         \
63         rc, (int)size);
64
65 #define send_seq(c, data...)                                            \
66 {       int rc;                                                         \
67         const static u8 _val[] = data;                                  \
68         if (sizeof(_val) !=                                             \
69                                 (rc = i2c_master_send                   \
70                                 (c, _val, sizeof(_val)))) {             \
71                 printk(KERN_ERR "Error on line %d: %d\n",__LINE__,rc);  \
72                 return;                                                 \
73         }                                                               \
74         msleep (10);                                                    \
75 }
76
77 static int xc2028_get_reg(struct i2c_client *c, u16 reg)
78 {
79         int rc;
80         unsigned char buf[1];
81         struct tuner *t = i2c_get_clientdata(c);
82
83         buf[0]= reg;
84
85         i2c_send(rc, c, buf, sizeof(buf));
86         if (rc<0)
87                 return rc;
88
89         i2c_rcv(rc, c, buf, 2);
90         if (rc<0)
91                 return rc;
92
93         return (buf[1])|(buf[0]<<8);
94 }
95
96 static int load_firmware (struct i2c_client *c, const char *name)
97 {
98         const struct firmware *fw=NULL;
99         struct tuner          *t = i2c_get_clientdata(c);
100         unsigned char         *p, *endp;
101         int                   len=0, rc=0;
102         static const char     firmware_ver[] = "tm6000/xcv v1";
103
104         tuner_info("xc2028: Loading firmware %s\n", name);
105         rc = request_firmware(&fw, name, &c->dev);
106         if (rc < 0) {
107                 if (rc==-ENOENT)
108                         tuner_info("Error: firmware %s not found.\n", name);
109                 else
110                         tuner_info("Error %d while requesting firmware %s \n", rc, name);
111
112                 return rc;
113         }
114         p=fw->data;
115         endp=p+fw->size;
116
117         if(fw->size==0) {
118                 tuner_info("Error: firmware size is zero!\n");
119                 rc=-EINVAL;
120                 goto err;
121         }
122         if (fw->size<sizeof(firmware_ver)-1) {
123                 /* Firmware is incorrect */
124                 tuner_info("Error: firmware size is less than header (%d<%d)!\n",
125                            (int)fw->size,(int)sizeof(firmware_ver)-1);
126                 rc=-EINVAL;
127                 goto err;
128         }
129
130         if (memcmp(p,firmware_ver,sizeof(firmware_ver)-1)) {
131                 /* Firmware is incorrect */
132                 tuner_info("Error: firmware is not for tm5600/6000 + Xcv2028/3028!\n");
133                 rc=-EINVAL;
134                 goto err;
135         }
136         p+=sizeof(firmware_ver)-1;
137
138         while(p<endp) {
139                 if ((*p) & 0x80) {
140                         /* Special callback command received */
141                         rc = t->tuner_callback(c->adapter->algo_data,
142                                              XC2028_TUNER_RESET, (*p)&0x7f);
143                         if (rc<0) {
144                                 tuner_info("Error at RESET code %d\n",
145                                                                 (*p)&0x7f);
146                                 goto err;
147                         }
148                         p++;
149                         continue;
150                 }
151                 len=*p;
152                 p++;
153                 if (p+len+1>endp) {
154                         /* Firmware is incorrect */
155                         tuner_info("Error: firmware is truncated!\n");
156                         rc=-EINVAL;
157                         goto err;
158                 }
159                 if (len<=0) {
160                         tuner_info("Error: firmware file is corrupted!\n");
161                         rc=-EINVAL;
162                         goto err;
163                 }
164
165                 i2c_send(rc, c, p, len);
166                 if (rc<0)
167                         goto err;
168                 p+=len;
169
170                 if (*p)
171                         msleep(*p);
172                 p++;
173         }
174
175
176 err:
177         release_firmware(fw);
178
179         return rc;
180 }
181
182 static int check_firmware(struct i2c_client *c, enum tuner_mode new_mode,
183                                                 fe_bandwidth_t bandwidth)
184 {
185         int                     rc, version;
186         struct tuner            *t = i2c_get_clientdata(c);
187         struct xc2028_data      *xc2028 = t->priv;
188         const char              *name;
189         int change_digital_bandwidth;
190
191         if (!t->tuner_callback) {
192                 printk(KERN_ERR "xc2028: need tuner_callback to load firmware\n");
193                 return -EINVAL;
194         }
195
196         printk(KERN_INFO "xc2028: I am in mode %u and I should switch to mode %i\n",
197                                                             xc2028->mode, new_mode);
198
199         /* first of all, determine whether we have switched the mode */
200         if(new_mode != xc2028->mode) {
201                 xc2028->mode = new_mode;
202                 xc2028->need_load_generic = 1;
203         }
204
205         change_digital_bandwidth = (xc2028->mode == T_DIGITAL_TV
206                                  && bandwidth != xc2028->bandwidth) ? 1 : 0;
207         tuner_info("xc2028: old bandwidth %u, new bandwidth %u\n", xc2028->bandwidth,
208                                                                    bandwidth);
209
210         if (xc2028->need_load_generic) {
211                 if (xc2028->bandwidth==8)
212                         name = firmware_8MHZ_INIT0;
213                 else
214                         name = firmware_INIT0;
215
216                 /* Reset is needed before loading firmware */
217                 rc = t->tuner_callback(c->adapter->algo_data,
218                                      XC2028_TUNER_RESET, 0);
219                 if (rc<0)
220                         return rc;
221
222                 rc = load_firmware(c,name);
223                 if (rc<0)
224                         return rc;
225
226                 xc2028->need_load_generic=0;
227                 xc2028->firm_type=0;
228                 if(xc2028->mode == T_DIGITAL_TV) {
229                         change_digital_bandwidth=1;
230                 }
231         }
232
233         tuner_info("xc2028: I should change bandwidth %u\n",
234                                                    change_digital_bandwidth);
235
236         if (change_digital_bandwidth) {
237                 switch(bandwidth) {
238                         case BANDWIDTH_8_MHZ:
239                                 t->std = V4L2_STD_DTV_8MHZ;
240                         break;
241
242                         case BANDWIDTH_7_MHZ:
243                                 t->std = V4L2_STD_DTV_7MHZ;
244                         break;
245
246                         case BANDWIDTH_6_MHZ:
247                                 t->std = V4L2_STD_DTV_6MHZ;
248                         break;
249
250                         default:
251                                 tuner_info("error: bandwidth not supported.\n");
252                 };
253                 xc2028->bandwidth = bandwidth;
254         }
255
256         if (xc2028->firm_type & t->std) {
257                 tuner_info("xc3028: no need to load a std-specific firmware.\n");
258                 return 0;
259         }
260
261         rc = load_firmware(c,firmware_INIT1);
262
263         if (t->std & V4L2_STD_MN)
264                 name=firmware_MN;
265         else if (t->std & V4L2_STD_DTV_6MHZ)
266                 name=firmware_6M;
267         else if (t->std & V4L2_STD_DTV_7MHZ)
268                 name=firmware_7M;
269         else if (t->std & V4L2_STD_DTV_8MHZ)
270                 name=firmware_8M;
271         else if (t->std & V4L2_STD_PAL_B)
272                 name=firmware_B;
273         else
274                 name=firmware_DK;
275
276         tuner_info("xc2028: loading firmware named %s.\n", name);
277         rc = load_firmware(c, name);
278         if (rc<0)
279                 return rc;
280
281         version = xc2028_get_reg(c, 0x4);
282         tuner_info("Firmware version is %d.%d\n",
283                                         (version>>4)&0x0f,(version)&0x0f);
284
285         xc2028->firm_type=t->std;
286
287         return 0;
288 }
289
290 static int xc2028_signal(struct i2c_client *c)
291 {
292         struct tuner       *t = i2c_get_clientdata(c);
293         struct xc2028_data *xc2028 = t->priv;
294         int                frq_lock, signal=0;
295
296         mutex_lock(&xc2028->lock);
297
298         printk(KERN_INFO "xc2028: %s called\n", __FUNCTION__);
299
300         frq_lock = xc2028_get_reg(c, 0x2);
301         if (frq_lock<=0)
302                 goto ret;
303
304         /* Frequency is locked. Return signal quality */
305
306         signal = xc2028_get_reg(c, 0x40);
307
308         if(signal<=0) {
309                 signal=frq_lock;
310         }
311
312 ret:
313         mutex_unlock(&xc2028->lock);
314
315         return signal;
316 }
317
318 #define DIV 15625
319
320 static void generic_set_tv_freq(struct i2c_client *c, u32 freq /* in Hz */,
321                                 enum tuner_mode new_mode, fe_bandwidth_t bandwidth)
322 {
323         int           rc;
324         unsigned char buf[5];
325         struct tuner  *t  = i2c_get_clientdata(c);
326         u32 div, offset = 0;
327
328         /* HACK: It seems that specific firmware need to be reloaded
329            when freq is changed */
330         struct xc2028_data      *xc2028 = t->priv;
331
332         mutex_lock(&xc2028->lock);
333
334         xc2028->firm_type=0;
335
336         /* Reset GPIO 1 */
337         if (t->tuner_callback) {
338                 rc = t->tuner_callback( c->adapter->algo_data,
339                                         XC2028_TUNER_RESET, 0);
340                 if (rc<0)
341                         goto ret;
342         }
343         msleep(10);
344         printk("xc3028: should set frequency %d kHz)\n", freq / 1000);
345
346         if (check_firmware(c, new_mode, bandwidth)<0)
347                 goto ret;
348
349         if(new_mode == T_DIGITAL_TV)
350                 offset = 2750000;
351
352         div = (freq - offset + DIV/2)/DIV;
353
354         /* CMD= Set frequency */
355         send_seq(c, {0x00, 0x02, 0x00, 0x00});
356         if (t->tuner_callback) {
357                 rc = t->tuner_callback( c->adapter->algo_data,
358                                         XC2028_RESET_CLK, 1);
359                 if (rc<0)
360                         goto ret;
361         }
362
363         msleep(10);
364
365         buf[0]= 0xff & (div>>24);
366         buf[1]= 0xff & (div>>16);
367         buf[2]= 0xff & (div>>8);
368         buf[3]= 0xff & (div);
369         buf[4]= 0;
370
371         i2c_send(rc, c, buf, sizeof(buf));
372         if (rc<0)
373                 goto ret;
374         msleep(100);
375
376         printk("divider= %02x %02x %02x %02x (freq=%d.%02d)\n",
377                  buf[1],buf[2],buf[3],buf[4],
378                  freq / 16, freq % 16 * 100 / 16);
379
380 ret:
381         mutex_unlock(&xc2028->lock);
382 }
383
384
385 static void set_tv_freq(struct i2c_client *c, unsigned int freq)
386 {
387         printk(KERN_INFO "xc2028: %s called\n", __FUNCTION__);
388
389         generic_set_tv_freq(c, freq * 62500l, T_ANALOG_TV,
390                                               BANDWIDTH_8_MHZ /* unimportant */);
391 }
392
393 static void xc2028_release(struct i2c_client *c)
394 {
395         struct tuner *t = i2c_get_clientdata(c);
396
397         kfree(t->priv);
398         t->priv = NULL;
399 }
400
401 static struct tuner_operations tea5767_tuner_ops = {
402         .set_tv_freq    = set_tv_freq,
403         .has_signal     = xc2028_signal,
404         .release        = xc2028_release,
405 //      .is_stereo      = xc2028_stereo,
406 };
407
408
409 static int init=0;
410
411 int xc2028_tuner_init(struct i2c_client *c)
412 {
413         struct tuner *t = i2c_get_clientdata(c);
414         int version = xc2028_get_reg(c, 0x4);
415         int prd_id = xc2028_get_reg(c, 0x8);
416         struct xc2028_data *xc2028;
417
418         tuner_info("Xcv2028/3028 init called!\n");
419
420         if (init) {
421                 printk (KERN_ERR "Module already initialized!\n");
422                 return 0;
423         }
424         init++;
425
426         xc2028 = kzalloc(sizeof(*xc2028), GFP_KERNEL);
427         if (!xc2028)
428                 return -ENOMEM;
429         t->priv = xc2028;
430
431         xc2028->bandwidth=BANDWIDTH_6_MHZ;
432         xc2028->need_load_generic=1;
433         xc2028->mode = T_UNINITIALIZED;
434
435         mutex_init(&xc2028->lock);
436
437         /* FIXME: Check where t->priv will be freed */
438
439         if (version<0)
440                 version=0;
441
442         if (prd_id<0)
443                 prd_id=0;
444
445         strlcpy(c->name, "xc2028", sizeof(c->name));
446         tuner_info("type set to %d (%s, hw ver=%d.%d, fw ver=%d.%d, id=0x%04x)\n",
447                    t->type, c->name,
448                    (version>>12)&0x0f,(version>>8)&0x0f,
449                    (version>>4)&0x0f,(version)&0x0f, prd_id);
450
451         memcpy(&t->ops, &tea5767_tuner_ops, sizeof(struct tuner_operations));
452
453         return 0;
454 }
455
456 static int xc3028_set_params(struct dvb_frontend *fe,
457                              struct dvb_frontend_parameters *p)
458 {
459         struct i2c_client *c = fe->tuner_priv;
460
461         printk(KERN_INFO "xc2028: %s called\n", __FUNCTION__);
462
463         generic_set_tv_freq(c, p->frequency, T_DIGITAL_TV,
464                                              p->u.ofdm.bandwidth);
465
466         return 0;
467 }
468
469 static int xc3028_dvb_release(struct dvb_frontend *fe)
470 {
471         printk(KERN_INFO "xc2028: %s called\n", __FUNCTION__);
472
473         fe->tuner_priv = NULL;
474
475         return 0;
476 }
477
478 static int xc3028_dvb_init(struct dvb_frontend *fe)
479 {
480         printk(KERN_INFO "xc2028: %s called\n", __FUNCTION__);
481
482         return 0;
483 }
484
485 static const struct dvb_tuner_ops xc3028_dvb_tuner_ops = {
486         .info = {
487                         .name           = "Xceive XC3028",
488                         .frequency_min  =  42000000,
489                         .frequency_max  = 864000000,
490                         .frequency_step =     50000,
491                 },
492
493         .release = xc3028_dvb_release,
494         .init = xc3028_dvb_init,
495
496 //      int (*sleep)(struct dvb_frontend *fe);
497
498         /** This is for simple PLLs - set all parameters in one go. */
499         .set_params = xc3028_set_params,
500
501         /** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */
502 //      int (*calc_regs)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len);
503
504 //      int (*get_frequency)(struct dvb_frontend *fe, u32 *frequency);
505 //      int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
506
507 //      int (*get_status)(struct dvb_frontend *fe, u32 *status);
508 };
509
510 int xc2028_attach(struct i2c_client *c, struct dvb_frontend *fe)
511 {
512         fe->tuner_priv = c;
513
514         memcpy(&fe->ops.tuner_ops, &xc3028_dvb_tuner_ops, sizeof(fe->ops.tuner_ops));
515
516         return 0;
517 }
518
519
520
521 EXPORT_SYMBOL(xc2028_attach);
522