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