]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/tuner-xc2028.c
V4L/DVB (6517): CodingStyle fixup
[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  *
5  * Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com)
6  *       - frontend interface
7  *
8  * This code is placed under the terms of the GNU General Public License v2
9  */
10
11 #include <linux/i2c.h>
12 #include <asm/div64.h>
13 #include <linux/firmware.h>
14 #include <linux/videodev2.h>
15 #include <linux/delay.h>
16 #include <media/tuner.h>
17 #include <linux/mutex.h>
18 #include "tuner-i2c.h"
19 #include "tuner-xc2028.h"
20 #include "tuner-xc2028-types.h"
21
22 #include <linux/dvb/frontend.h>
23 #include "dvb_frontend.h"
24
25 #define PREFIX "xc2028 "
26
27 static LIST_HEAD(xc2028_list);
28 /* struct for storing firmware table */
29 struct firmware_description {
30         unsigned int  type;
31         v4l2_std_id   id;
32         unsigned char *ptr;
33         unsigned int  size;
34 };
35
36 struct xc2028_data {
37         struct list_head        xc2028_list;
38         struct tuner_i2c_props  i2c_props;
39         int                     (*tuner_callback) (void *dev,
40                                                    int command, int arg);
41         struct device           *dev;
42         void                    *video_dev;
43         int                     count;
44         __u32                   frequency;
45
46         struct firmware_description *firm;
47         int                     firm_size;
48
49         __u16                   version;
50
51         struct xc2028_ctrl      ctrl;
52
53         v4l2_std_id             firm_type;         /* video stds supported
54                                                         by current firmware */
55         fe_bandwidth_t          bandwidth;         /* Firmware bandwidth:
56                                                               6M, 7M or 8M */
57         int                     need_load_generic; /* The generic firmware
58                                                               were loaded? */
59
60         int                     max_len;        /* Max firmware chunk */
61
62         enum tuner_mode mode;
63         struct i2c_client       *i2c_client;
64
65         struct mutex lock;
66 };
67
68 #define i2c_send(rc, priv, buf, size) do {                              \
69         rc = tuner_i2c_xfer_send(&priv->i2c_props, buf, size);          \
70         if (size != rc)                                                 \
71                 tuner_info("i2c output error: rc = %d (should be %d)\n",\
72                            rc, (int)size);                              \
73 } while (0)
74
75 #define i2c_rcv(rc, priv, buf, size) do {                               \
76         rc = tuner_i2c_xfer_recv(&priv->i2c_props, buf, size);          \
77         if (size != rc)                                                 \
78                 tuner_info("i2c input error: rc = %d (should be %d)\n", \
79                            rc, (int)size);                              \
80 } while (0)
81
82 #define send_seq(priv, data...) do {                                    \
83         int rc;                                                         \
84         static u8 _val[] = data;                                        \
85         if (sizeof(_val) !=                                             \
86                         (rc = tuner_i2c_xfer_send(&priv->i2c_props,     \
87                                                 _val, sizeof(_val)))) { \
88                 tuner_info("Error on line %d: %d\n", __LINE__, rc);     \
89                 return -EINVAL;                                         \
90         }                                                               \
91         msleep(10);                                                     \
92 } while (0)
93
94 static int xc2028_get_reg(struct xc2028_data *priv, u16 reg)
95 {
96         int rc;
97         unsigned char buf[1];
98
99         tuner_info("%s called\n", __FUNCTION__);
100
101         buf[0] = reg;
102
103         i2c_send(rc, priv, buf, sizeof(buf));
104         if (rc < 0)
105                 return rc;
106
107         i2c_rcv(rc, priv, buf, 2);
108         if (rc < 0)
109                 return rc;
110
111         return (buf[1]) | (buf[0] << 8);
112 }
113
114 static void free_firmware(struct xc2028_data *priv)
115 {
116         int i;
117
118         if (!priv->firm)
119                 return;
120
121         for (i = 0; i < priv->firm_size; i++)
122                 kfree(priv->firm[i].ptr);
123
124         kfree(priv->firm);
125
126         priv->firm = NULL;
127         priv->need_load_generic = 1;
128 }
129
130 static int load_all_firmwares(struct dvb_frontend *fe)
131 {
132         struct xc2028_data    *priv = fe->tuner_priv;
133         const struct firmware *fw   = NULL;
134         unsigned char         *p, *endp;
135         int                   rc = 0;
136         int                   n, n_array;
137         char                  name[33];
138
139         tuner_info("%s called\n", __FUNCTION__);
140
141         tuner_info("Loading firmware %s\n", priv->ctrl.fname);
142         rc = request_firmware(&fw, priv->ctrl.fname, priv->dev);
143         if (rc < 0) {
144                 if (rc == -ENOENT)
145                         tuner_info("Error: firmware %s not found.\n",
146                                    priv->ctrl.fname);
147                 else
148                         tuner_info("Error %d while requesting firmware %s \n",
149                                    rc, priv->ctrl.fname);
150
151                 return rc;
152         }
153         p = fw->data;
154         endp = p + fw->size;
155
156         if (fw->size < sizeof(name) - 1 + 2) {
157                 tuner_info("Error: firmware size is zero!\n");
158                 rc = -EINVAL;
159                 goto done;
160         }
161
162         memcpy(name, p, sizeof(name) - 1);
163         name[sizeof(name) - 1] = 0;
164         p += sizeof(name) - 1;
165
166         priv->version = le16_to_cpu(*(__u16 *) p);
167         p += 2;
168
169         tuner_info("firmware: %s, ver %d.%d\n", name,
170                    priv->version >> 8, priv->version & 0xff);
171
172         if (p + 2 > endp)
173                 goto corrupt;
174
175         n_array = le16_to_cpu(*(__u16 *) p);
176         p += 2;
177
178         tuner_info("there are %d firmwares at %s\n", n_array, priv->ctrl.fname);
179
180         priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL);
181
182         if (!fw) {
183                 tuner_info("Not enough memory for loading firmware.\n");
184                 rc = -ENOMEM;
185                 goto done;
186         }
187
188         priv->firm_size = n_array;
189         n = -1;
190         while (p < endp) {
191                 __u32 type, size;
192                 v4l2_std_id id;
193
194                 n++;
195                 if (n >= n_array) {
196                         tuner_info("Too much firmwares at the file\n");
197                         goto corrupt;
198                 }
199
200                 /* Checks if there's enough bytes to read */
201                 if (p + sizeof(type) + sizeof(id) + sizeof(size) > endp) {
202                         tuner_info("Lost firmware!\n");
203                         goto corrupt;
204                 }
205
206                 type = le32_to_cpu(*(__u32 *) p);
207                 p += sizeof(type);
208
209                 id = le64_to_cpu(*(v4l2_std_id *) p);
210                 p += sizeof(id);
211
212                 size = le32_to_cpu(*(v4l2_std_id *) p);
213                 p += sizeof(size);
214
215                 if ((!size) || (size + p > endp)) {
216                         tuner_info("Firmware type %x, id %lx corrupt\n",
217                                    type, (unsigned long)id);
218                         goto corrupt;
219                 }
220
221                 priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
222                 if (!priv->firm[n].ptr) {
223                         tuner_info("Not enough memory.\n");
224                         rc = -ENOMEM;
225                         goto err;
226                 }
227                 tuner_info("Loading firmware type %x, id %lx, size=%d.\n",
228                            type, (unsigned long)id, size);
229
230                 memcpy(priv->firm[n].ptr, p, size);
231                 priv->firm[n].type = type;
232                 priv->firm[n].id   = id;
233                 priv->firm[n].size = size;
234
235                 p += size;
236         }
237
238         if (n + 1 != priv->firm_size) {
239                 tuner_info("Firmware file is incomplete!\n");
240                 goto corrupt;
241         }
242
243         goto done;
244
245 corrupt:
246         rc = -EINVAL;
247         tuner_info("Error: firmware file is corrupted!\n");
248
249 err:
250         tuner_info("Releasing loaded firmware file.\n");
251
252         free_firmware(priv);
253
254 done:
255         release_firmware(fw);
256         tuner_info("Firmware files loaded.\n");
257
258         return rc;
259 }
260
261 static int load_firmware(struct dvb_frontend *fe, unsigned int type,
262                          v4l2_std_id * id)
263 {
264         struct xc2028_data *priv = fe->tuner_priv;
265         int                i, rc;
266         unsigned char      *p, *endp, buf[priv->max_len];
267
268         tuner_info("%s called\n", __FUNCTION__);
269
270         if (!priv->firm) {
271                 printk(KERN_ERR PREFIX "Error! firmware not loaded\n");
272                 return -EINVAL;
273         }
274
275         if ((type == 0) && (*id == 0))
276                 *id = V4L2_STD_PAL;
277
278         /* Seek for exact match */
279         for (i = 0; i < priv->firm_size; i++) {
280                 if ((type == priv->firm[i].type) && (*id == priv->firm[i].id))
281                         goto found;
282         }
283
284         /* Seek for generic video standard match */
285         for (i = 0; i < priv->firm_size; i++) {
286                 if ((type == priv->firm[i].type) && (*id & priv->firm[i].id))
287                         goto found;
288         }
289
290         /*FIXME: Would make sense to seek for type "hint" match ? */
291
292         tuner_info("Can't find firmware for type=%x, id=%lx\n", type,
293                    (long int)*id);
294         return -EINVAL;
295
296 found:
297         *id = priv->firm[i].id;
298         tuner_info("Found firmware for type=%x, id=%lx\n", type, (long int)*id);
299
300         p = priv->firm[i].ptr;
301
302         if (!p) {
303                 printk(KERN_ERR PREFIX "Firmware pointer were freed!");
304                 return -EINVAL;
305         }
306         endp = p + priv->firm[i].size;
307
308         while (p < endp) {
309                 __u16 size;
310
311                 /* Checks if there's enough bytes to read */
312                 if (p + sizeof(size) > endp) {
313                         tuner_info("missing bytes\n");
314                         return -EINVAL;
315                 }
316
317                 size = le16_to_cpu(*(__u16 *) p);
318                 p += sizeof(size);
319
320                 if (size == 0xffff)
321                         return 0;
322
323                 if (!size) {
324                         /* Special callback command received */
325                         rc = priv->tuner_callback(priv->video_dev,
326                                                   XC2028_TUNER_RESET, 0);
327                         if (rc < 0) {
328                                 tuner_info("Error at RESET code %d\n",
329                                            (*p) & 0x7f);
330                                 return -EINVAL;
331                         }
332                         continue;
333                 }
334
335                 /* Checks for a sleep command */
336                 if (size & 0x8000) {
337                         msleep(size & 0x7fff);
338                         continue;
339                 }
340
341                 if ((size + p > endp)) {
342                         tuner_info("missing bytes: need %d, have %d\n",
343                                    size, (int)(endp - p));
344                         return -EINVAL;
345                 }
346
347                 buf[0] = *p;
348                 p++;
349                 size--;
350
351                 /* Sends message chunks */
352                 while (size > 0) {
353                         int len = (size < priv->max_len - 1) ?
354                                    size : priv->max_len - 1;
355
356                         memcpy(buf + 1, p, len);
357
358                         i2c_send(rc, priv, buf, len + 1);
359                         if (rc < 0) {
360                                 tuner_info("%d returned from send\n", rc);
361                                 return -EINVAL;
362                         }
363
364                         p += len;
365                         size -= len;
366                 }
367         }
368         return -EINVAL;
369 }
370
371 static int check_firmware(struct dvb_frontend *fe, enum tuner_mode new_mode,
372                           v4l2_std_id std, fe_bandwidth_t bandwidth)
373 {
374         struct xc2028_data      *priv = fe->tuner_priv;
375         int                     rc, version;
376         v4l2_std_id             std0 = 0;
377         unsigned int            type0 = 0, type = 0;
378         int                     change_digital_bandwidth;
379
380         tuner_info("%s called\n", __FUNCTION__);
381
382         if (!priv->firm) {
383                 if (!priv->ctrl.fname)
384                         return -EINVAL;
385
386                 rc = load_all_firmwares(fe);
387                 if (rc < 0)
388                         return rc;
389         }
390
391         tuner_info("I am in mode %u and I should switch to mode %i\n",
392                    priv->mode, new_mode);
393
394         /* first of all, determine whether we have switched the mode */
395         if (new_mode != priv->mode) {
396                 priv->mode = new_mode;
397                 priv->need_load_generic = 1;
398         }
399
400         change_digital_bandwidth = (priv->mode == T_DIGITAL_TV
401                                     && bandwidth != priv->bandwidth) ? 1 : 0;
402         tuner_info("old bandwidth %u, new bandwidth %u\n", priv->bandwidth,
403                    bandwidth);
404
405         if (priv->need_load_generic) {
406                 /* Reset is needed before loading firmware */
407                 rc = priv->tuner_callback(priv->video_dev,
408                                           XC2028_TUNER_RESET, 0);
409                 if (rc < 0)
410                         return rc;
411
412                 type0 = BASE;
413
414                 if (priv->ctrl.type == XC2028_FIRM_MTS)
415                         type0 |= MTS;
416
417                 if (priv->bandwidth == 8)
418                         type0 |= F8MHZ;
419
420                 /* FIXME: How to load FM and FM|INPUT1 firmwares? */
421
422                 rc = load_firmware(fe, type0, &std0);
423                 if (rc < 0) {
424                         tuner_info("Error %d while loading generic firmware\n",
425                                    rc);
426                         return rc;
427                 }
428
429                 priv->need_load_generic = 0;
430                 priv->firm_type = 0;
431                 if (priv->mode == T_DIGITAL_TV)
432                         change_digital_bandwidth = 1;
433         }
434
435         tuner_info("I should change bandwidth %u\n", change_digital_bandwidth);
436
437         if (change_digital_bandwidth) {
438
439                 /*FIXME: Should allow selecting between D2620 and D2633 */
440                 type |= D2620;
441
442                 /* FIXME: When should select a DTV78 firmware?
443                  */
444                 switch (bandwidth) {
445                 case BANDWIDTH_8_MHZ:
446                         type |= DTV8;
447                         break;
448                 case BANDWIDTH_7_MHZ:
449                         type |= DTV7;
450                         break;
451                 case BANDWIDTH_6_MHZ:
452                         /* FIXME: Should allow select also ATSC */
453                         type |= DTV6_QAM;
454                         break;
455
456                 default:
457                         tuner_info("error: bandwidth not supported.\n");
458                 };
459                 priv->bandwidth = bandwidth;
460         }
461
462         /* Load INIT1, if needed */
463         tuner_info("Trying to load init1 firmware\n");
464         type0 = BASE | INIT1 | priv->ctrl.type;
465         if (priv->ctrl.type == XC2028_FIRM_MTS)
466                 type0 |= MTS;
467
468         /* FIXME: Should handle errors - if INIT1 found */
469         rc = load_firmware(fe, type0, &std0);
470
471         /* FIXME: Should add support for FM radio
472          */
473
474         if (priv->ctrl.type == XC2028_FIRM_MTS)
475                 type |= MTS;
476
477         tuner_info("firmware standard to load: %08lx\n", (unsigned long)std);
478         if (priv->firm_type & std) {
479                 tuner_info("no need to load a std-specific firmware.\n");
480                 return 0;
481         }
482
483         rc = load_firmware(fe, type, &std);
484         if (rc < 0)
485                 return rc;
486
487         version = xc2028_get_reg(priv, 0x4);
488         tuner_info("Firmware version is %d.%d\n",
489                    (version >> 4) & 0x0f, (version) & 0x0f);
490
491         priv->firm_type = std;
492
493         return 0;
494 }
495
496 static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
497 {
498         struct xc2028_data *priv = fe->tuner_priv;
499         int                frq_lock, signal = 0;
500
501         tuner_info("%s called\n", __FUNCTION__);
502
503         mutex_lock(&priv->lock);
504
505         *strength = 0;
506
507         frq_lock = xc2028_get_reg(priv, 0x2);
508         if (frq_lock <= 0)
509                 goto ret;
510
511         /* Frequency is locked. Return signal quality */
512
513         signal = xc2028_get_reg(priv, 0x40);
514
515         if (signal <= 0)
516                 signal = frq_lock;
517
518 ret:
519         mutex_unlock(&priv->lock);
520
521         *strength = signal;
522
523         return 0;
524 }
525
526 #define DIV 15625
527
528 static int generic_set_tv_freq(struct dvb_frontend *fe, u32 freq /* in Hz */ ,
529                                enum tuner_mode new_mode,
530                                v4l2_std_id std, fe_bandwidth_t bandwidth)
531 {
532         struct xc2028_data *priv = fe->tuner_priv;
533         int                rc = -EINVAL;
534         unsigned char      buf[5];
535         u32                div, offset = 0;
536
537         tuner_info("%s called\n", __FUNCTION__);
538
539         mutex_lock(&priv->lock);
540
541         /* HACK: It seems that specific firmware need to be reloaded
542            when freq is changed */
543
544         priv->firm_type = 0;
545
546         /* Reset GPIO 1 */
547         rc = priv->tuner_callback(priv->video_dev, XC2028_TUNER_RESET, 0);
548         if (rc < 0)
549                 goto ret;
550
551         msleep(10);
552         tuner_info("should set frequency %d kHz)\n", freq / 1000);
553
554         if (check_firmware(fe, new_mode, std, bandwidth) < 0)
555                 goto ret;
556
557         if (new_mode == T_DIGITAL_TV)
558                 offset = 2750000;
559
560         div = (freq - offset + DIV / 2) / DIV;
561
562         /* CMD= Set frequency */
563
564         if (priv->version < 0x0202) {
565                 send_seq(priv, {0x00, 0x02, 0x00, 0x00});
566         } else {
567                 send_seq(priv, {0x80, 0x02, 0x00, 0x00});
568         }
569
570         rc = priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1);
571         if (rc < 0)
572                 goto ret;
573
574         msleep(10);
575
576         buf[0] = 0xff & (div >> 24);
577         buf[1] = 0xff & (div >> 16);
578         buf[2] = 0xff & (div >> 8);
579         buf[3] = 0xff & (div);
580         buf[4] = 0;
581
582         i2c_send(rc, priv, buf, sizeof(buf));
583         if (rc < 0)
584                 goto ret;
585         msleep(100);
586
587         priv->frequency = freq;
588
589         printk("divider= %02x %02x %02x %02x (freq=%d.%02d)\n",
590                buf[1], buf[2], buf[3], buf[4],
591                freq / 1000000, (freq % 1000000) / 10000);
592
593         rc = 0;
594
595 ret:
596         mutex_unlock(&priv->lock);
597
598         return rc;
599 }
600
601 static int xc2028_set_tv_freq(struct dvb_frontend *fe,
602                               struct analog_parameters *p)
603 {
604         struct xc2028_data *priv = fe->tuner_priv;
605
606         tuner_info("%s called\n", __FUNCTION__);
607
608         return generic_set_tv_freq(fe, 62500l * p->frequency, T_ANALOG_TV,
609                                    p->std, BANDWIDTH_8_MHZ /* NOT USED */);
610 }
611
612 static int xc2028_set_params(struct dvb_frontend *fe,
613                              struct dvb_frontend_parameters *p)
614 {
615         struct xc2028_data *priv = fe->tuner_priv;
616
617         tuner_info("%s called\n", __FUNCTION__);
618
619         /* FIXME: Only OFDM implemented */
620         if (fe->ops.info.type != FE_OFDM) {
621                 tuner_info("DTV type not implemented.\n");
622                 return -EINVAL;
623         }
624
625         return generic_set_tv_freq(fe, p->frequency, T_DIGITAL_TV,
626                                    0 /* NOT USED */,
627                                    p->u.ofdm.bandwidth);
628
629 }
630
631 static int xc2028_dvb_release(struct dvb_frontend *fe)
632 {
633         struct xc2028_data *priv = fe->tuner_priv;
634
635         tuner_info("%s called\n", __FUNCTION__);
636
637         priv->count--;
638
639         if (!priv->count) {
640                 list_del(&priv->xc2028_list);
641
642                 kfree(priv->ctrl.fname);
643
644                 free_firmware(priv);
645                 kfree(priv);
646         }
647
648         return 0;
649 }
650
651 static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency)
652 {
653         struct xc2028_data *priv = fe->tuner_priv;
654
655         tuner_info("%s called\n", __FUNCTION__);
656
657         *frequency = priv->frequency;
658
659         return 0;
660 }
661
662 static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
663 {
664         struct xc2028_data *priv = fe->tuner_priv;
665         struct xc2028_ctrl *p    = priv_cfg;
666
667         tuner_info("%s called\n", __FUNCTION__);
668
669         priv->ctrl.type = p->type;
670
671         if (p->fname) {
672                 kfree(priv->ctrl.fname);
673
674                 priv->ctrl.fname = kmalloc(strlen(p->fname) + 1, GFP_KERNEL);
675                 if (!priv->ctrl.fname)
676                         return -ENOMEM;
677
678                 free_firmware(priv);
679                 strcpy(priv->ctrl.fname, p->fname);
680         }
681
682         if (p->max_len > 0)
683                 priv->max_len = p->max_len;
684
685         tuner_info("%s OK\n", __FUNCTION__);
686
687         return 0;
688 }
689
690 static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = {
691         .info = {
692                  .name = "Xceive XC3028",
693                  .frequency_min = 42000000,
694                  .frequency_max = 864000000,
695                  .frequency_step = 50000,
696                  },
697
698         .set_config        = xc2028_set_config,
699         .set_analog_params = xc2028_set_tv_freq,
700         .release           = xc2028_dvb_release,
701         .get_frequency     = xc2028_get_frequency,
702         .get_rf_strength   = xc2028_signal,
703         .set_params        = xc2028_set_params,
704
705 };
706
707 int xc2028_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c_adap,
708                   u8 i2c_addr, struct device *dev, void *video_dev,
709                   int (*tuner_callback) (void *dev, int command, int arg))
710 {
711         struct xc2028_data *priv;
712
713         printk(KERN_INFO PREFIX "Xcv2028/3028 init called!\n");
714
715         if (NULL == dev)
716                 return -ENODEV;
717
718         if (NULL == video_dev)
719                 return -ENODEV;
720
721         if (!tuner_callback) {
722                 printk(KERN_ERR PREFIX "No tuner callback!\n");
723                 return -EINVAL;
724         }
725
726         list_for_each_entry(priv, &xc2028_list, xc2028_list) {
727                 if (priv->dev == dev)
728                         dev = NULL;
729         }
730
731         if (dev) {
732                 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
733                 if (priv == NULL)
734                         return -ENOMEM;
735
736                 fe->tuner_priv = priv;
737
738                 priv->bandwidth = BANDWIDTH_6_MHZ;
739                 priv->need_load_generic = 1;
740                 priv->mode = T_UNINITIALIZED;
741                 priv->i2c_props.addr = i2c_addr;
742                 priv->i2c_props.adap = i2c_adap;
743                 priv->dev = dev;
744                 priv->video_dev = video_dev;
745                 priv->tuner_callback = tuner_callback;
746                 priv->max_len = 13;
747
748
749                 mutex_init(&priv->lock);
750
751                 list_add_tail(&priv->xc2028_list, &xc2028_list);
752         }
753         priv->count++;
754
755         memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops,
756                sizeof(xc2028_dvb_tuner_ops));
757
758         tuner_info("type set to %s\n", "XCeive xc2028/xc3028 tuner");
759
760         return 0;
761 }
762 EXPORT_SYMBOL(xc2028_attach);
763
764 MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver");
765 MODULE_AUTHOR("Michel Ludwig <michel.ludwig@gmail.com>");
766 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
767 MODULE_LICENSE("GPL");