V4L/DVB (6605): Add a modprobe option to manually select audio standard
[powerpc.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 int debug;
28 module_param(debug, int, 0644);
29 MODULE_PARM_DESC(debug, "enable verbose debug messages");
30
31 static char audio_std[8];
32 module_param_string(audio_std, audio_std, sizeof(audio_std), 0);
33 MODULE_PARM_DESC(audio_std,
34         "Audio standard. XC3028 audio decoder explicitly "
35         "needs to know what audio\n"
36         "standard is needed for some video standards with audio A2 or NICAM.\n"
37         "The valid values are:\n"
38         "A2\n"
39         "A2/A\n"
40         "A2/B\n"
41         "NICAM\n"
42         "NICAM/A\n"
43         "NICAM/B\n");
44
45 static LIST_HEAD(xc2028_list);
46 /* struct for storing firmware table */
47 struct firmware_description {
48         unsigned int  type;
49         v4l2_std_id   id;
50         unsigned char *ptr;
51         unsigned int  size;
52 };
53
54 struct xc2028_data {
55         struct list_head        xc2028_list;
56         struct tuner_i2c_props  i2c_props;
57         int                     (*tuner_callback) (void *dev,
58                                                    int command, int arg);
59         struct device           *dev;
60         void                    *video_dev;
61         int                     count;
62         __u32                   frequency;
63
64         struct firmware_description *firm;
65         int                     firm_size;
66
67         __u16                   version;
68
69         struct xc2028_ctrl      ctrl;
70
71         v4l2_std_id             firm_type;         /* video stds supported
72                                                         by current firmware */
73         fe_bandwidth_t          bandwidth;         /* Firmware bandwidth:
74                                                               6M, 7M or 8M */
75         int                     need_load_generic; /* The generic firmware
76                                                               were loaded? */
77
78         int                     max_len;        /* Max firmware chunk */
79
80         enum tuner_mode mode;
81         struct i2c_client       *i2c_client;
82
83         struct mutex lock;
84 };
85
86 #define i2c_send(rc, priv, buf, size) do {                              \
87         rc = tuner_i2c_xfer_send(&priv->i2c_props, buf, size);          \
88         if (size != rc)                                                 \
89                 tuner_err("i2c output error: rc = %d (should be %d)\n", \
90                            rc, (int)size);                              \
91 } while (0)
92
93 #define i2c_rcv(rc, priv, buf, size) do {                               \
94         rc = tuner_i2c_xfer_recv(&priv->i2c_props, buf, size);          \
95         if (size != rc)                                                 \
96                 tuner_err("i2c input error: rc = %d (should be %d)\n",  \
97                            rc, (int)size);                              \
98 } while (0)
99
100 #define send_seq(priv, data...) do {                                    \
101         int rc;                                                         \
102         static u8 _val[] = data;                                        \
103         if (sizeof(_val) !=                                             \
104                         (rc = tuner_i2c_xfer_send(&priv->i2c_props,     \
105                                                 _val, sizeof(_val)))) { \
106                 tuner_err("Error on line %d: %d\n", __LINE__, rc);      \
107                 return -EINVAL;                                         \
108         }                                                               \
109         msleep(10);                                                     \
110 } while (0)
111
112 static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg)
113 {
114         int rc;
115         unsigned char buf[2];
116
117         tuner_dbg("%s called\n", __FUNCTION__);
118
119         buf[0] = reg>>8;
120         buf[1] = (unsigned char) reg;
121
122         i2c_send(rc, priv, buf, 2);
123         if (rc < 0)
124                 return rc;
125
126         i2c_rcv(rc, priv, buf, 2);
127         if (rc < 0)
128                 return rc;
129
130         return (buf[1]) | (buf[0] << 8);
131 }
132
133 void dump_firm_type(unsigned int type)
134 {
135          if (type & BASE)
136                 printk("BASE ");
137          if (type & INIT1)
138                 printk("INIT1 ");
139          if (type & F8MHZ)
140                 printk("F8MHZ ");
141          if (type & MTS)
142                 printk("MTS ");
143          if (type & D2620)
144                 printk("D2620 ");
145          if (type & D2633)
146                 printk("D2633 ");
147          if (type & DTV6)
148                 printk("DTV6 ");
149          if (type & QAM)
150                 printk("QAM ");
151          if (type & DTV7)
152                 printk("DTV7 ");
153          if (type & DTV78)
154                 printk("DTV78 ");
155          if (type & DTV8)
156                 printk("DTV8 ");
157          if (type & FM)
158                 printk("FM ");
159          if (type & INPUT1)
160                 printk("INPUT1 ");
161          if (type & LCD)
162                 printk("LCD ");
163          if (type & NOGD)
164                 printk("NOGD ");
165          if (type & MONO)
166                 printk("MONO ");
167          if (type & ATSC)
168                 printk("ATSC ");
169          if (type & IF)
170                 printk("IF ");
171          if (type & LG60)
172                 printk("LG60 ");
173          if (type & ATI638)
174                 printk("ATI638 ");
175          if (type & OREN538)
176                 printk("OREN538 ");
177          if (type & OREN36)
178                 printk("OREN36 ");
179          if (type & TOYOTA388)
180                 printk("TOYOTA388 ");
181          if (type & TOYOTA794)
182                 printk("TOYOTA794 ");
183          if (type & DIBCOM52)
184                 printk("DIBCOM52 ");
185          if (type & ZARLINK456)
186                 printk("ZARLINK456 ");
187          if (type & CHINA)
188                 printk("CHINA ");
189          if (type & F6MHZ)
190                 printk("F6MHZ ");
191          if (type & INPUT2)
192                 printk("INPUT2 ");
193          if (type & SCODE)
194                 printk("SCODE ");
195 }
196
197 static v4l2_std_id parse_audio_std_option(void)
198 {
199         if (strcasecmp(audio_std, "A2"))
200                 return V4L2_STD_A2;
201         if (strcasecmp(audio_std, "A2/A"))
202                 return V4L2_STD_A2_A;
203         if (strcasecmp(audio_std, "A2/B"))
204                 return V4L2_STD_A2_B;
205         if (strcasecmp(audio_std, "NICAM"))
206                 return V4L2_STD_NICAM;
207         if (strcasecmp(audio_std, "NICAM/A"))
208                 return V4L2_STD_NICAM_A;
209         if (strcasecmp(audio_std, "NICAM/B"))
210                 return V4L2_STD_NICAM_B;
211
212         return 0;
213 }
214
215 static void free_firmware(struct xc2028_data *priv)
216 {
217         int i;
218
219         if (!priv->firm)
220                 return;
221
222         for (i = 0; i < priv->firm_size; i++)
223                 kfree(priv->firm[i].ptr);
224
225         kfree(priv->firm);
226
227         priv->firm = NULL;
228         priv->need_load_generic = 1;
229 }
230
231 static int load_all_firmwares(struct dvb_frontend *fe)
232 {
233         struct xc2028_data    *priv = fe->tuner_priv;
234         const struct firmware *fw   = NULL;
235         unsigned char         *p, *endp;
236         int                   rc = 0;
237         int                   n, n_array;
238         char                  name[33];
239
240         tuner_dbg("%s called\n", __FUNCTION__);
241
242         tuner_info("Reading firmware %s\n", priv->ctrl.fname);
243         rc = request_firmware(&fw, priv->ctrl.fname, priv->dev);
244         if (rc < 0) {
245                 if (rc == -ENOENT)
246                         tuner_err("Error: firmware %s not found.\n",
247                                    priv->ctrl.fname);
248                 else
249                         tuner_err("Error %d while requesting firmware %s \n",
250                                    rc, priv->ctrl.fname);
251
252                 return rc;
253         }
254         p = fw->data;
255         endp = p + fw->size;
256
257         if (fw->size < sizeof(name) - 1 + 2) {
258                 tuner_err("Error: firmware size is zero!\n");
259                 rc = -EINVAL;
260                 goto done;
261         }
262
263         memcpy(name, p, sizeof(name) - 1);
264         name[sizeof(name) - 1] = 0;
265         p += sizeof(name) - 1;
266
267         priv->version = le16_to_cpu(*(__u16 *) p);
268         p += 2;
269
270         tuner_info("Firmware: %s, ver %d.%d\n", name,
271                    priv->version >> 8, priv->version & 0xff);
272
273         if (p + 2 > endp)
274                 goto corrupt;
275
276         n_array = le16_to_cpu(*(__u16 *) p);
277         p += 2;
278
279         tuner_info("There are %d firmwares at %s\n",
280                    n_array, priv->ctrl.fname);
281
282         priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL);
283
284         if (!fw) {
285                 tuner_err("Not enough memory for reading firmware.\n");
286                 rc = -ENOMEM;
287                 goto done;
288         }
289
290         priv->firm_size = n_array;
291         n = -1;
292         while (p < endp) {
293                 __u32 type, size;
294                 v4l2_std_id id;
295
296                 n++;
297                 if (n >= n_array) {
298                         tuner_err("Too much firmwares at the file\n");
299                         goto corrupt;
300                 }
301
302                 /* Checks if there's enough bytes to read */
303                 if (p + sizeof(type) + sizeof(id) + sizeof(size) > endp) {
304                         tuner_err("Firmware header is incomplete!\n");
305                         goto corrupt;
306                 }
307
308                 type = le32_to_cpu(*(__u32 *) p);
309                 p += sizeof(type);
310
311                 id = le64_to_cpu(*(v4l2_std_id *) p);
312                 p += sizeof(id);
313
314                 size = le32_to_cpu(*(v4l2_std_id *) p);
315                 p += sizeof(size);
316
317                 if ((!size) || (size + p > endp)) {
318                         tuner_err("Firmware type ");
319                         dump_firm_type(type);
320                         printk("(%x), id %lx is corrupted "
321                                "(size=%ld, expected %d)\n",
322                                type, (unsigned long)id, endp - p, size);
323                         goto corrupt;
324                 }
325
326                 priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
327                 if (!priv->firm[n].ptr) {
328                         tuner_err("Not enough memory.\n");
329                         rc = -ENOMEM;
330                         goto err;
331                 }
332                 tuner_info("Reading firmware type ");
333                 dump_firm_type(type);
334                 printk("(%x), id %lx, size=%d.\n",
335                            type, (unsigned long)id, size);
336
337                 memcpy(priv->firm[n].ptr, p, size);
338                 priv->firm[n].type = type;
339                 priv->firm[n].id   = id;
340                 priv->firm[n].size = size;
341
342                 p += size;
343         }
344
345         if (n + 1 != priv->firm_size) {
346                 tuner_err("Firmware file is incomplete!\n");
347                 goto corrupt;
348         }
349
350         goto done;
351
352 corrupt:
353         rc = -EINVAL;
354         tuner_err("Error: firmware file is corrupted!\n");
355
356 err:
357         tuner_info("Releasing loaded firmware file.\n");
358
359         free_firmware(priv);
360
361 done:
362         release_firmware(fw);
363         tuner_dbg("Firmware files loaded.\n");
364
365         return rc;
366 }
367
368 static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
369                          v4l2_std_id *id)
370 {
371         struct xc2028_data *priv = fe->tuner_priv;
372         int                i;
373
374         tuner_dbg("%s called\n", __FUNCTION__);
375
376         if (!priv->firm) {
377                 tuner_err("Error! firmware not loaded\n");
378                 return -EINVAL;
379         }
380
381         if (((type & ~SCODE) == 0) && (*id == 0))
382                 *id = V4L2_STD_PAL;
383
384         /* Seek for exact match */
385         for (i = 0; i < priv->firm_size; i++) {
386                 if ((type == priv->firm[i].type) && (*id == priv->firm[i].id))
387                         goto found;
388         }
389
390         /* Seek for generic video standard match */
391         for (i = 0; i < priv->firm_size; i++) {
392                 if ((type == priv->firm[i].type) && (*id & priv->firm[i].id))
393                         goto found;
394         }
395
396         /*FIXME: Would make sense to seek for type "hint" match ? */
397
398         i = -EINVAL;
399         goto ret;
400
401 found:
402         *id = priv->firm[i].id;
403
404 ret:
405         tuner_dbg("%s firmware for type=", (i < 0)? "Can't find": "Found");
406         if (debug) {
407                 dump_firm_type(type);
408                 printk("(%x), id %08lx.\n", type, (unsigned long)*id);
409         }
410         return i;
411 }
412
413 static int load_firmware(struct dvb_frontend *fe, unsigned int type,
414                          v4l2_std_id *id)
415 {
416         struct xc2028_data *priv = fe->tuner_priv;
417         int                pos, rc;
418         unsigned char      *p, *endp, buf[priv->max_len];
419
420         tuner_dbg("%s called\n", __FUNCTION__);
421
422         pos = seek_firmware(fe, type, id);
423         if (pos < 0)
424                 return pos;
425
426         tuner_info("Loading firmware for type=");
427         dump_firm_type(type);
428         printk("(%x), id %08lx.\n", type, (unsigned long)*id);
429
430         p = priv->firm[pos].ptr;
431
432         if (!p) {
433                 tuner_err("Firmware pointer were freed!");
434                 return -EINVAL;
435         }
436         endp = p + priv->firm[pos].size;
437
438         while (p < endp) {
439                 __u16 size;
440
441                 /* Checks if there's enough bytes to read */
442                 if (p + sizeof(size) > endp) {
443                         tuner_err("Firmware chunk size is wrong\n");
444                         return -EINVAL;
445                 }
446
447                 size = le16_to_cpu(*(__u16 *) p);
448                 p += sizeof(size);
449
450                 if (size == 0xffff)
451                         return 0;
452
453                 if (!size) {
454                         /* Special callback command received */
455                         rc = priv->tuner_callback(priv->video_dev,
456                                                   XC2028_TUNER_RESET, 0);
457                         if (rc < 0) {
458                                 tuner_err("Error at RESET code %d\n",
459                                            (*p) & 0x7f);
460                                 return -EINVAL;
461                         }
462                         continue;
463                 }
464
465                 /* Checks for a sleep command */
466                 if (size & 0x8000) {
467                         msleep(size & 0x7fff);
468                         continue;
469                 }
470
471                 if ((size + p > endp)) {
472                         tuner_err("missing bytes: need %d, have %d\n",
473                                    size, (int)(endp - p));
474                         return -EINVAL;
475                 }
476
477                 buf[0] = *p;
478                 p++;
479                 size--;
480
481                 /* Sends message chunks */
482                 while (size > 0) {
483                         int len = (size < priv->max_len - 1) ?
484                                    size : priv->max_len - 1;
485
486                         memcpy(buf + 1, p, len);
487
488                         i2c_send(rc, priv, buf, len + 1);
489                         if (rc < 0) {
490                                 tuner_err("%d returned from send\n", rc);
491                                 return -EINVAL;
492                         }
493
494                         p += len;
495                         size -= len;
496                 }
497         }
498         return 0;
499 }
500
501 static int load_scode(struct dvb_frontend *fe, unsigned int type,
502                          v4l2_std_id *id, int scode)
503 {
504         struct xc2028_data *priv = fe->tuner_priv;
505         int                pos, rc;
506         unsigned char      *p;
507
508         tuner_dbg("%s called\n", __FUNCTION__);
509
510         pos = seek_firmware(fe, type, id);
511         if (pos < 0)
512                 return pos;
513
514         p = priv->firm[pos].ptr;
515
516         if (!p) {
517                 tuner_err("Firmware pointer were freed!");
518                 return -EINVAL;
519         }
520
521         if ((priv->firm[pos].size != 12 * 16) || (scode >= 16))
522                 return -EINVAL;
523
524         if (priv->version < 0x0202) {
525                 send_seq(priv, {0x20, 0x00, 0x00, 0x00});
526         } else {
527                 send_seq(priv, {0xa0, 0x00, 0x00, 0x00});
528         }
529
530         i2c_send(rc, priv, p + 12 * scode, 12);
531
532         send_seq(priv, {0x00, 0x8c});
533
534         return 0;
535 }
536
537 static int check_firmware(struct dvb_frontend *fe, enum tuner_mode new_mode,
538                           v4l2_std_id std, fe_bandwidth_t bandwidth)
539 {
540         struct xc2028_data      *priv = fe->tuner_priv;
541         int                     rc, version, hwmodel;
542         v4l2_std_id             std0 = 0;
543         unsigned int            type0 = 0, type = 0;
544         int                     change_digital_bandwidth;
545
546         tuner_dbg("%s called\n", __FUNCTION__);
547
548         if (!priv->firm) {
549                 if (!priv->ctrl.fname)
550                         return -EINVAL;
551
552                 rc = load_all_firmwares(fe);
553                 if (rc < 0)
554                         return rc;
555         }
556
557         tuner_dbg("I am in mode %u and I should switch to mode %i\n",
558                    priv->mode, new_mode);
559
560         /* first of all, determine whether we have switched the mode */
561         if (new_mode != priv->mode) {
562                 priv->mode = new_mode;
563                 priv->need_load_generic = 1;
564         }
565
566         change_digital_bandwidth = (priv->mode == T_DIGITAL_TV
567                                     && bandwidth != priv->bandwidth) ? 1 : 0;
568         tuner_dbg("old bandwidth %u, new bandwidth %u\n", priv->bandwidth,
569                    bandwidth);
570
571         if (priv->need_load_generic) {
572                 /* Reset is needed before loading firmware */
573                 rc = priv->tuner_callback(priv->video_dev,
574                                           XC2028_TUNER_RESET, 0);
575                 if (rc < 0)
576                         return rc;
577
578                 type0 = BASE;
579
580                 if (priv->ctrl.type == XC2028_FIRM_MTS)
581                         type0 |= MTS;
582
583                 if (priv->bandwidth == 8)
584                         type0 |= F8MHZ;
585
586                 /* FIXME: How to load FM and FM|INPUT1 firmwares? */
587
588                 rc = load_firmware(fe, type0, &std0);
589                 if (rc < 0) {
590                         tuner_err("Error %d while loading generic firmware\n",
591                                   rc);
592                         return rc;
593                 }
594
595                 priv->need_load_generic = 0;
596                 priv->firm_type = 0;
597                 if (priv->mode == T_DIGITAL_TV)
598                         change_digital_bandwidth = 1;
599         }
600
601         tuner_dbg("I should change bandwidth %u\n", change_digital_bandwidth);
602
603         if (change_digital_bandwidth) {
604
605                 /*FIXME: Should allow selecting between D2620 and D2633 */
606                 type |= D2620;
607
608                 /* FIXME: When should select a DTV78 firmware?
609                  */
610                 switch (bandwidth) {
611                 case BANDWIDTH_8_MHZ:
612                         type |= DTV8;
613                         break;
614                 case BANDWIDTH_7_MHZ:
615                         type |= DTV7;
616                         break;
617                 case BANDWIDTH_6_MHZ:
618                         /* FIXME: Should allow select also ATSC */
619                         type |= DTV6 | QAM;
620                         break;
621
622                 default:
623                         tuner_err("error: bandwidth not supported.\n");
624                 };
625                 priv->bandwidth = bandwidth;
626         }
627
628         /* Load INIT1, if needed */
629         tuner_dbg("Load init1 firmware, if exists\n");
630         type0 = BASE | INIT1;
631         if (priv->ctrl.type == XC2028_FIRM_MTS)
632                 type0 |= MTS;
633
634         /* FIXME: Should handle errors - if INIT1 found */
635         rc = load_firmware(fe, type0, &std0);
636
637         /* FIXME: Should add support for FM radio
638          */
639
640         if (priv->ctrl.type == XC2028_FIRM_MTS)
641                 type |= MTS;
642
643         if (priv->firm_type & std) {
644                 tuner_dbg("Std-specific firmware already loaded.\n");
645                 return 0;
646         }
647
648         /* Add audio hack to std mask */
649         std |= parse_audio_std_option();
650
651         rc = load_firmware(fe, type, &std);
652         if (rc < 0)
653                 return rc;
654
655         /* Load SCODE firmware, if exists */
656         tuner_dbg("Trying to load scode 0\n");
657         type |= SCODE;
658
659         rc = load_scode(fe, type, &std, 0);
660
661         version = xc2028_get_reg(priv, 0x0004);
662         hwmodel = xc2028_get_reg(priv, 0x0008);
663
664         tuner_info("Device is Xceive %d version %d.%d, "
665                    "firmware version %d.%d\n",
666                    hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8,
667                    (version & 0xf0) >> 4, version & 0xf);
668
669         priv->firm_type = std;
670
671         return 0;
672 }
673
674 static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
675 {
676         struct xc2028_data *priv = fe->tuner_priv;
677         int                frq_lock, signal = 0;
678
679         tuner_dbg("%s called\n", __FUNCTION__);
680
681         mutex_lock(&priv->lock);
682
683         *strength = 0;
684
685         /* Sync Lock Indicator */
686         frq_lock = xc2028_get_reg(priv, 0x0002);
687         if (frq_lock <= 0)
688                 goto ret;
689
690         /* Frequency is locked. Return signal quality */
691
692         /* Get SNR of the video signal */
693         signal = xc2028_get_reg(priv, 0x0040);
694
695         if (signal <= 0)
696                 signal = frq_lock;
697
698 ret:
699         mutex_unlock(&priv->lock);
700
701         *strength = signal;
702
703         return 0;
704 }
705
706 #define DIV 15625
707
708 static int generic_set_tv_freq(struct dvb_frontend *fe, u32 freq /* in Hz */ ,
709                                enum tuner_mode new_mode,
710                                v4l2_std_id std, fe_bandwidth_t bandwidth)
711 {
712         struct xc2028_data *priv = fe->tuner_priv;
713         int                rc = -EINVAL;
714         unsigned char      buf[5];
715         u32                div, offset = 0;
716
717         tuner_dbg("%s called\n", __FUNCTION__);
718
719         mutex_lock(&priv->lock);
720
721         /* HACK: It seems that specific firmware need to be reloaded
722            when freq is changed */
723
724         priv->firm_type = 0;
725
726         /* Reset GPIO 1 */
727         rc = priv->tuner_callback(priv->video_dev, XC2028_TUNER_RESET, 0);
728         if (rc < 0)
729                 goto ret;
730
731         msleep(10);
732         tuner_dbg("should set frequency %d kHz)\n", freq / 1000);
733
734         if (check_firmware(fe, new_mode, std, bandwidth) < 0)
735                 goto ret;
736
737         if (new_mode == T_DIGITAL_TV)
738                 offset = 2750000;
739
740         div = (freq - offset + DIV / 2) / DIV;
741
742         /* CMD= Set frequency */
743
744         if (priv->version < 0x0202) {
745                 send_seq(priv, {0x00, 0x02, 0x00, 0x00});
746         } else {
747                 send_seq(priv, {0x80, 0x02, 0x00, 0x00});
748         }
749
750         rc = priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1);
751         if (rc < 0)
752                 goto ret;
753
754         msleep(10);
755
756         buf[0] = 0xff & (div >> 24);
757         buf[1] = 0xff & (div >> 16);
758         buf[2] = 0xff & (div >> 8);
759         buf[3] = 0xff & (div);
760         buf[4] = 0;
761
762         i2c_send(rc, priv, buf, sizeof(buf));
763         if (rc < 0)
764                 goto ret;
765         msleep(100);
766
767         priv->frequency = freq;
768
769         tuner_dbg("divider= %02x %02x %02x %02x (freq=%d.%02d)\n",
770                buf[1], buf[2], buf[3], buf[4],
771                freq / 1000000, (freq % 1000000) / 10000);
772
773         rc = 0;
774
775 ret:
776         mutex_unlock(&priv->lock);
777
778         return rc;
779 }
780
781 static int xc2028_set_tv_freq(struct dvb_frontend *fe,
782                               struct analog_parameters *p)
783 {
784         struct xc2028_data *priv = fe->tuner_priv;
785
786         tuner_dbg("%s called\n", __FUNCTION__);
787
788         return generic_set_tv_freq(fe, 62500l * p->frequency, T_ANALOG_TV,
789                                    p->std, BANDWIDTH_8_MHZ /* NOT USED */);
790 }
791
792 static int xc2028_set_params(struct dvb_frontend *fe,
793                              struct dvb_frontend_parameters *p)
794 {
795         struct xc2028_data *priv = fe->tuner_priv;
796
797         tuner_dbg("%s called\n", __FUNCTION__);
798
799         /* FIXME: Only OFDM implemented */
800         if (fe->ops.info.type != FE_OFDM) {
801                 tuner_err("DTV type not implemented.\n");
802                 return -EINVAL;
803         }
804
805         return generic_set_tv_freq(fe, p->frequency, T_DIGITAL_TV,
806                                    0 /* NOT USED */,
807                                    p->u.ofdm.bandwidth);
808
809 }
810
811 static int xc2028_dvb_release(struct dvb_frontend *fe)
812 {
813         struct xc2028_data *priv = fe->tuner_priv;
814
815         tuner_dbg("%s called\n", __FUNCTION__);
816
817         priv->count--;
818
819         if (!priv->count) {
820                 list_del(&priv->xc2028_list);
821
822                 kfree(priv->ctrl.fname);
823
824                 free_firmware(priv);
825                 kfree(priv);
826         }
827
828         return 0;
829 }
830
831 static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency)
832 {
833         struct xc2028_data *priv = fe->tuner_priv;
834
835         tuner_dbg("%s called\n", __FUNCTION__);
836
837         *frequency = priv->frequency;
838
839         return 0;
840 }
841
842 static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
843 {
844         struct xc2028_data *priv = fe->tuner_priv;
845         struct xc2028_ctrl *p    = priv_cfg;
846
847         tuner_dbg("%s called\n", __FUNCTION__);
848
849         priv->ctrl.type = p->type;
850
851         if (p->fname) {
852                 kfree(priv->ctrl.fname);
853
854                 priv->ctrl.fname = kmalloc(strlen(p->fname) + 1, GFP_KERNEL);
855                 if (!priv->ctrl.fname)
856                         return -ENOMEM;
857
858                 free_firmware(priv);
859                 strcpy(priv->ctrl.fname, p->fname);
860         }
861
862         if (p->max_len > 0)
863                 priv->max_len = p->max_len;
864
865         return 0;
866 }
867
868 static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = {
869         .info = {
870                  .name = "Xceive XC3028",
871                  .frequency_min = 42000000,
872                  .frequency_max = 864000000,
873                  .frequency_step = 50000,
874                  },
875
876         .set_config        = xc2028_set_config,
877         .set_analog_params = xc2028_set_tv_freq,
878         .release           = xc2028_dvb_release,
879         .get_frequency     = xc2028_get_frequency,
880         .get_rf_strength   = xc2028_signal,
881         .set_params        = xc2028_set_params,
882
883 };
884
885 int xc2028_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c_adap,
886                   u8 i2c_addr, struct device *dev, void *video_dev,
887                   int (*tuner_callback) (void *dev, int command, int arg))
888 {
889         struct xc2028_data *priv;
890
891         if (debug)
892                 printk(KERN_DEBUG PREFIX "Xcv2028/3028 init called!\n");
893
894         if (NULL == dev)
895                 return -ENODEV;
896
897         if (NULL == video_dev)
898                 return -ENODEV;
899
900         if (!tuner_callback) {
901                 printk(KERN_ERR PREFIX "No tuner callback!\n");
902                 return -EINVAL;
903         }
904
905         list_for_each_entry(priv, &xc2028_list, xc2028_list) {
906                 if (priv->dev == dev)
907                         dev = NULL;
908         }
909
910         if (dev) {
911                 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
912                 if (priv == NULL)
913                         return -ENOMEM;
914
915                 fe->tuner_priv = priv;
916
917                 priv->bandwidth = BANDWIDTH_6_MHZ;
918                 priv->need_load_generic = 1;
919                 priv->mode = T_UNINITIALIZED;
920                 priv->i2c_props.addr = i2c_addr;
921                 priv->i2c_props.adap = i2c_adap;
922                 priv->dev = dev;
923                 priv->video_dev = video_dev;
924                 priv->tuner_callback = tuner_callback;
925                 priv->max_len = 13;
926
927
928                 mutex_init(&priv->lock);
929
930                 list_add_tail(&priv->xc2028_list, &xc2028_list);
931         }
932         priv->count++;
933
934         memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops,
935                sizeof(xc2028_dvb_tuner_ops));
936
937         tuner_info("type set to %s\n", "XCeive xc2028/xc3028 tuner");
938
939         return 0;
940 }
941 EXPORT_SYMBOL(xc2028_attach);
942
943 MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver");
944 MODULE_AUTHOR("Michel Ludwig <michel.ludwig@gmail.com>");
945 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
946 MODULE_LICENSE("GPL");