]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - drivers/media/pci/bt8xx/dst.c
Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[mirror_ubuntu-jammy-kernel.git] / drivers / media / pci / bt8xx / dst.c
1 /*
2 Frontend/Card driver for TwinHan DST Frontend
3 Copyright (C) 2003 Jamie Honan
4 Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/init.h>
26 #include <linux/string.h>
27 #include <linux/slab.h>
28 #include <linux/vmalloc.h>
29 #include <linux/delay.h>
30 #include <asm/div64.h>
31 #include <media/dvb_frontend.h>
32 #include "dst_priv.h"
33 #include "dst_common.h"
34
35 static unsigned int verbose;
36 module_param(verbose, int, 0644);
37 MODULE_PARM_DESC(verbose, "verbosity level (0 to 3)");
38
39 static unsigned int dst_addons;
40 module_param(dst_addons, int, 0644);
41 MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)");
42
43 static unsigned int dst_algo;
44 module_param(dst_algo, int, 0644);
45 MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)");
46
47 #define HAS_LOCK 1
48 #define ATTEMPT_TUNE 2
49 #define HAS_POWER 4
50
51 #define dprintk(level, fmt, arg...) do { \
52 if (level >= verbose) \
53 printk(KERN_DEBUG pr_fmt("%s: " fmt), \
54 __func__, ##arg); \
55 } while(0)
56
57 static int dst_command(struct dst_state *state, u8 *data, u8 len);
58
59 static void dst_packsize(struct dst_state *state, int psize)
60 {
61 union dst_gpio_packet bits;
62
63 bits.psize = psize;
64 bt878_device_control(state->bt, DST_IG_TS, &bits);
65 }
66
67 static int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb,
68 u32 outhigh, int delay)
69 {
70 union dst_gpio_packet enb;
71 union dst_gpio_packet bits;
72 int err;
73
74 enb.enb.mask = mask;
75 enb.enb.enable = enbb;
76
77 dprintk(2, "mask=[%04x], enbb=[%04x], outhigh=[%04x]\n",
78 mask, enbb, outhigh);
79 if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) {
80 dprintk(2, "dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)\n",
81 err, mask, enbb);
82 return -EREMOTEIO;
83 }
84 udelay(1000);
85 /* because complete disabling means no output, no need to do output packet */
86 if (enbb == 0)
87 return 0;
88 if (delay)
89 msleep(10);
90 bits.outp.mask = enbb;
91 bits.outp.highvals = outhigh;
92 if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) {
93 dprintk(2, "dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)\n",
94 err, enbb, outhigh);
95 return -EREMOTEIO;
96 }
97
98 return 0;
99 }
100
101 static int dst_gpio_inb(struct dst_state *state, u8 *result)
102 {
103 union dst_gpio_packet rd_packet;
104 int err;
105
106 *result = 0;
107 if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) {
108 pr_err("dst_gpio_inb error (err == %i)\n", err);
109 return -EREMOTEIO;
110 }
111 *result = (u8) rd_packet.rd.value;
112
113 return 0;
114 }
115
116 int rdc_reset_state(struct dst_state *state)
117 {
118 dprintk(2, "Resetting state machine\n");
119 if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) {
120 pr_err("dst_gpio_outb ERROR !\n");
121 return -1;
122 }
123 msleep(10);
124 if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) {
125 pr_err("dst_gpio_outb ERROR !\n");
126 msleep(10);
127 return -1;
128 }
129
130 return 0;
131 }
132 EXPORT_SYMBOL(rdc_reset_state);
133
134 static int rdc_8820_reset(struct dst_state *state)
135 {
136 dprintk(3, "Resetting DST\n");
137 if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) {
138 pr_err("dst_gpio_outb ERROR !\n");
139 return -1;
140 }
141 udelay(1000);
142 if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) {
143 pr_err("dst_gpio_outb ERROR !\n");
144 return -1;
145 }
146
147 return 0;
148 }
149
150 static int dst_pio_enable(struct dst_state *state)
151 {
152 if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) {
153 pr_err("dst_gpio_outb ERROR !\n");
154 return -1;
155 }
156 udelay(1000);
157
158 return 0;
159 }
160
161 int dst_pio_disable(struct dst_state *state)
162 {
163 if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) {
164 pr_err("dst_gpio_outb ERROR !\n");
165 return -1;
166 }
167 if (state->type_flags & DST_TYPE_HAS_FW_1)
168 udelay(1000);
169
170 return 0;
171 }
172 EXPORT_SYMBOL(dst_pio_disable);
173
174 int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode)
175 {
176 u8 reply;
177 int i;
178
179 for (i = 0; i < 200; i++) {
180 if (dst_gpio_inb(state, &reply) < 0) {
181 pr_err("dst_gpio_inb ERROR !\n");
182 return -1;
183 }
184 if ((reply & RDC_8820_PIO_0_ENABLE) == 0) {
185 dprintk(2, "dst wait ready after %d\n", i);
186 return 1;
187 }
188 msleep(10);
189 }
190 dprintk(1, "dst wait NOT ready after %d\n", i);
191
192 return 0;
193 }
194 EXPORT_SYMBOL(dst_wait_dst_ready);
195
196 int dst_error_recovery(struct dst_state *state)
197 {
198 dprintk(1, "Trying to return from previous errors.\n");
199 dst_pio_disable(state);
200 msleep(10);
201 dst_pio_enable(state);
202 msleep(10);
203
204 return 0;
205 }
206 EXPORT_SYMBOL(dst_error_recovery);
207
208 int dst_error_bailout(struct dst_state *state)
209 {
210 dprintk(2, "Trying to bailout from previous error.\n");
211 rdc_8820_reset(state);
212 dst_pio_disable(state);
213 msleep(10);
214
215 return 0;
216 }
217 EXPORT_SYMBOL(dst_error_bailout);
218
219 int dst_comm_init(struct dst_state *state)
220 {
221 dprintk(2, "Initializing DST.\n");
222 if ((dst_pio_enable(state)) < 0) {
223 pr_err("PIO Enable Failed\n");
224 return -1;
225 }
226 if ((rdc_reset_state(state)) < 0) {
227 pr_err("RDC 8820 State RESET Failed.\n");
228 return -1;
229 }
230 if (state->type_flags & DST_TYPE_HAS_FW_1)
231 msleep(100);
232 else
233 msleep(5);
234
235 return 0;
236 }
237 EXPORT_SYMBOL(dst_comm_init);
238
239 int write_dst(struct dst_state *state, u8 *data, u8 len)
240 {
241 struct i2c_msg msg = {
242 .addr = state->config->demod_address,
243 .flags = 0,
244 .buf = data,
245 .len = len
246 };
247
248 int err;
249 u8 cnt;
250
251 dprintk(1, "writing [ %*ph ]\n", len, data);
252
253 for (cnt = 0; cnt < 2; cnt++) {
254 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
255 dprintk(2, "_write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n",
256 err, len, data[0]);
257 dst_error_recovery(state);
258 continue;
259 } else
260 break;
261 }
262 if (cnt >= 2) {
263 dprintk(2, "RDC 8820 RESET\n");
264 dst_error_bailout(state);
265
266 return -1;
267 }
268
269 return 0;
270 }
271 EXPORT_SYMBOL(write_dst);
272
273 int read_dst(struct dst_state *state, u8 *ret, u8 len)
274 {
275 struct i2c_msg msg = {
276 .addr = state->config->demod_address,
277 .flags = I2C_M_RD,
278 .buf = ret,
279 .len = len
280 };
281
282 int err;
283 int cnt;
284
285 for (cnt = 0; cnt < 2; cnt++) {
286 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
287 dprintk(2, "read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n",
288 err, len, ret[0]);
289 dst_error_recovery(state);
290 continue;
291 } else
292 break;
293 }
294 if (cnt >= 2) {
295 dprintk(2, "RDC 8820 RESET\n");
296 dst_error_bailout(state);
297
298 return -1;
299 }
300 dprintk(3, "reply is %*ph\n", len, ret);
301
302 return 0;
303 }
304 EXPORT_SYMBOL(read_dst);
305
306 static int dst_set_polarization(struct dst_state *state)
307 {
308 switch (state->voltage) {
309 case SEC_VOLTAGE_13: /* Vertical */
310 dprintk(2, "Polarization=[Vertical]\n");
311 state->tx_tuna[8] &= ~0x40;
312 break;
313 case SEC_VOLTAGE_18: /* Horizontal */
314 dprintk(2, "Polarization=[Horizontal]\n");
315 state->tx_tuna[8] |= 0x40;
316 break;
317 case SEC_VOLTAGE_OFF:
318 break;
319 }
320
321 return 0;
322 }
323
324 static int dst_set_freq(struct dst_state *state, u32 freq)
325 {
326 state->frequency = freq;
327 dprintk(2, "set Frequency %u\n", freq);
328
329 if (state->dst_type == DST_TYPE_IS_SAT) {
330 freq = freq / 1000;
331 if (freq < 950 || freq > 2150)
332 return -EINVAL;
333 state->tx_tuna[2] = (freq >> 8);
334 state->tx_tuna[3] = (u8) freq;
335 state->tx_tuna[4] = 0x01;
336 state->tx_tuna[8] &= ~0x04;
337 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
338 if (freq < 1531)
339 state->tx_tuna[8] |= 0x04;
340 }
341 } else if (state->dst_type == DST_TYPE_IS_TERR) {
342 freq = freq / 1000;
343 if (freq < 137000 || freq > 858000)
344 return -EINVAL;
345 state->tx_tuna[2] = (freq >> 16) & 0xff;
346 state->tx_tuna[3] = (freq >> 8) & 0xff;
347 state->tx_tuna[4] = (u8) freq;
348 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
349 freq = freq / 1000;
350 state->tx_tuna[2] = (freq >> 16) & 0xff;
351 state->tx_tuna[3] = (freq >> 8) & 0xff;
352 state->tx_tuna[4] = (u8) freq;
353 } else if (state->dst_type == DST_TYPE_IS_ATSC) {
354 freq = freq / 1000;
355 if (freq < 51000 || freq > 858000)
356 return -EINVAL;
357 state->tx_tuna[2] = (freq >> 16) & 0xff;
358 state->tx_tuna[3] = (freq >> 8) & 0xff;
359 state->tx_tuna[4] = (u8) freq;
360 state->tx_tuna[5] = 0x00; /* ATSC */
361 state->tx_tuna[6] = 0x00;
362 if (state->dst_hw_cap & DST_TYPE_HAS_ANALOG)
363 state->tx_tuna[7] = 0x00; /* Digital */
364 } else
365 return -EINVAL;
366
367 return 0;
368 }
369
370 static int dst_set_bandwidth(struct dst_state *state, u32 bandwidth)
371 {
372 state->bandwidth = bandwidth;
373
374 if (state->dst_type != DST_TYPE_IS_TERR)
375 return -EOPNOTSUPP;
376
377 switch (bandwidth) {
378 case 6000000:
379 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
380 state->tx_tuna[7] = 0x06;
381 else {
382 state->tx_tuna[6] = 0x06;
383 state->tx_tuna[7] = 0x00;
384 }
385 break;
386 case 7000000:
387 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
388 state->tx_tuna[7] = 0x07;
389 else {
390 state->tx_tuna[6] = 0x07;
391 state->tx_tuna[7] = 0x00;
392 }
393 break;
394 case 8000000:
395 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
396 state->tx_tuna[7] = 0x08;
397 else {
398 state->tx_tuna[6] = 0x08;
399 state->tx_tuna[7] = 0x00;
400 }
401 break;
402 default:
403 return -EINVAL;
404 }
405
406 return 0;
407 }
408
409 static int dst_set_inversion(struct dst_state *state,
410 enum fe_spectral_inversion inversion)
411 {
412 state->inversion = inversion;
413 switch (inversion) {
414 case INVERSION_OFF: /* Inversion = Normal */
415 state->tx_tuna[8] &= ~0x80;
416 break;
417 case INVERSION_ON:
418 state->tx_tuna[8] |= 0x80;
419 break;
420 default:
421 return -EINVAL;
422 }
423
424 return 0;
425 }
426
427 static int dst_set_fec(struct dst_state *state, enum fe_code_rate fec)
428 {
429 state->fec = fec;
430 return 0;
431 }
432
433 static enum fe_code_rate dst_get_fec(struct dst_state *state)
434 {
435 return state->fec;
436 }
437
438 static int dst_set_symbolrate(struct dst_state *state, u32 srate)
439 {
440 u32 symcalc;
441 u64 sval;
442
443 state->symbol_rate = srate;
444 if (state->dst_type == DST_TYPE_IS_TERR) {
445 return -EOPNOTSUPP;
446 }
447 dprintk(2, "set symrate %u\n", srate);
448 srate /= 1000;
449 if (state->dst_type == DST_TYPE_IS_SAT) {
450 if (state->type_flags & DST_TYPE_HAS_SYMDIV) {
451 sval = srate;
452 sval <<= 20;
453 do_div(sval, 88000);
454 symcalc = (u32) sval;
455 dprintk(2, "set symcalc %u\n", symcalc);
456 state->tx_tuna[5] = (u8) (symcalc >> 12);
457 state->tx_tuna[6] = (u8) (symcalc >> 4);
458 state->tx_tuna[7] = (u8) (symcalc << 4);
459 } else {
460 state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f;
461 state->tx_tuna[6] = (u8) (srate >> 8);
462 state->tx_tuna[7] = (u8) srate;
463 }
464 state->tx_tuna[8] &= ~0x20;
465 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
466 if (srate > 8000)
467 state->tx_tuna[8] |= 0x20;
468 }
469 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
470 dprintk(3, "%s\n", state->fw_name);
471 if (!strncmp(state->fw_name, "DCTNEW", 6)) {
472 state->tx_tuna[5] = (u8) (srate >> 8);
473 state->tx_tuna[6] = (u8) srate;
474 state->tx_tuna[7] = 0x00;
475 } else if (!strncmp(state->fw_name, "DCT-CI", 6)) {
476 state->tx_tuna[5] = 0x00;
477 state->tx_tuna[6] = (u8) (srate >> 8);
478 state->tx_tuna[7] = (u8) srate;
479 }
480 }
481 return 0;
482 }
483
484 static int dst_set_modulation(struct dst_state *state,
485 enum fe_modulation modulation)
486 {
487 if (state->dst_type != DST_TYPE_IS_CABLE)
488 return -EOPNOTSUPP;
489
490 state->modulation = modulation;
491 switch (modulation) {
492 case QAM_16:
493 state->tx_tuna[8] = 0x10;
494 break;
495 case QAM_32:
496 state->tx_tuna[8] = 0x20;
497 break;
498 case QAM_64:
499 state->tx_tuna[8] = 0x40;
500 break;
501 case QAM_128:
502 state->tx_tuna[8] = 0x80;
503 break;
504 case QAM_256:
505 if (!strncmp(state->fw_name, "DCTNEW", 6))
506 state->tx_tuna[8] = 0xff;
507 else if (!strncmp(state->fw_name, "DCT-CI", 6))
508 state->tx_tuna[8] = 0x00;
509 break;
510 case QPSK:
511 case QAM_AUTO:
512 case VSB_8:
513 case VSB_16:
514 default:
515 return -EINVAL;
516
517 }
518
519 return 0;
520 }
521
522 static enum fe_modulation dst_get_modulation(struct dst_state *state)
523 {
524 return state->modulation;
525 }
526
527
528 u8 dst_check_sum(u8 *buf, u32 len)
529 {
530 u32 i;
531 u8 val = 0;
532 if (!len)
533 return 0;
534 for (i = 0; i < len; i++) {
535 val += buf[i];
536 }
537 return ((~val) + 1);
538 }
539 EXPORT_SYMBOL(dst_check_sum);
540
541 static void dst_type_flags_print(struct dst_state *state)
542 {
543 u32 type_flags = state->type_flags;
544
545 pr_err("DST type flags :\n");
546 if (type_flags & DST_TYPE_HAS_TS188)
547 pr_err(" 0x%x newtuner\n", DST_TYPE_HAS_TS188);
548 if (type_flags & DST_TYPE_HAS_NEWTUNE_2)
549 pr_err(" 0x%x newtuner 2\n", DST_TYPE_HAS_NEWTUNE_2);
550 if (type_flags & DST_TYPE_HAS_TS204)
551 pr_err(" 0x%x ts204\n", DST_TYPE_HAS_TS204);
552 if (type_flags & DST_TYPE_HAS_VLF)
553 pr_err(" 0x%x VLF\n", DST_TYPE_HAS_VLF);
554 if (type_flags & DST_TYPE_HAS_SYMDIV)
555 pr_err(" 0x%x symdiv\n", DST_TYPE_HAS_SYMDIV);
556 if (type_flags & DST_TYPE_HAS_FW_1)
557 pr_err(" 0x%x firmware version = 1\n", DST_TYPE_HAS_FW_1);
558 if (type_flags & DST_TYPE_HAS_FW_2)
559 pr_err(" 0x%x firmware version = 2\n", DST_TYPE_HAS_FW_2);
560 if (type_flags & DST_TYPE_HAS_FW_3)
561 pr_err(" 0x%x firmware version = 3\n", DST_TYPE_HAS_FW_3);
562 pr_err("\n");
563 }
564
565
566 static int dst_type_print(struct dst_state *state, u8 type)
567 {
568 char *otype;
569 switch (type) {
570 case DST_TYPE_IS_SAT:
571 otype = "satellite";
572 break;
573
574 case DST_TYPE_IS_TERR:
575 otype = "terrestrial";
576 break;
577
578 case DST_TYPE_IS_CABLE:
579 otype = "cable";
580 break;
581
582 case DST_TYPE_IS_ATSC:
583 otype = "atsc";
584 break;
585
586 default:
587 dprintk(2, "invalid dst type %d\n", type);
588 return -EINVAL;
589 }
590 dprintk(2, "DST type: %s\n", otype);
591
592 return 0;
593 }
594
595 static struct tuner_types tuner_list[] = {
596 {
597 .tuner_type = TUNER_TYPE_L64724,
598 .tuner_name = "L 64724",
599 .board_name = "UNKNOWN",
600 .fw_name = "UNKNOWN"
601 },
602
603 {
604 .tuner_type = TUNER_TYPE_STV0299,
605 .tuner_name = "STV 0299",
606 .board_name = "VP1020",
607 .fw_name = "DST-MOT"
608 },
609
610 {
611 .tuner_type = TUNER_TYPE_STV0299,
612 .tuner_name = "STV 0299",
613 .board_name = "VP1020",
614 .fw_name = "DST-03T"
615 },
616
617 {
618 .tuner_type = TUNER_TYPE_MB86A15,
619 .tuner_name = "MB 86A15",
620 .board_name = "VP1022",
621 .fw_name = "DST-03T"
622 },
623
624 {
625 .tuner_type = TUNER_TYPE_MB86A15,
626 .tuner_name = "MB 86A15",
627 .board_name = "VP1025",
628 .fw_name = "DST-03T"
629 },
630
631 {
632 .tuner_type = TUNER_TYPE_STV0299,
633 .tuner_name = "STV 0299",
634 .board_name = "VP1030",
635 .fw_name = "DST-CI"
636 },
637
638 {
639 .tuner_type = TUNER_TYPE_STV0299,
640 .tuner_name = "STV 0299",
641 .board_name = "VP1030",
642 .fw_name = "DSTMCI"
643 },
644
645 {
646 .tuner_type = TUNER_TYPE_UNKNOWN,
647 .tuner_name = "UNKNOWN",
648 .board_name = "VP2021",
649 .fw_name = "DCTNEW"
650 },
651
652 {
653 .tuner_type = TUNER_TYPE_UNKNOWN,
654 .tuner_name = "UNKNOWN",
655 .board_name = "VP2030",
656 .fw_name = "DCT-CI"
657 },
658
659 {
660 .tuner_type = TUNER_TYPE_UNKNOWN,
661 .tuner_name = "UNKNOWN",
662 .board_name = "VP2031",
663 .fw_name = "DCT-CI"
664 },
665
666 {
667 .tuner_type = TUNER_TYPE_UNKNOWN,
668 .tuner_name = "UNKNOWN",
669 .board_name = "VP2040",
670 .fw_name = "DCT-CI"
671 },
672
673 {
674 .tuner_type = TUNER_TYPE_UNKNOWN,
675 .tuner_name = "UNKNOWN",
676 .board_name = "VP3020",
677 .fw_name = "DTTFTA"
678 },
679
680 {
681 .tuner_type = TUNER_TYPE_UNKNOWN,
682 .tuner_name = "UNKNOWN",
683 .board_name = "VP3021",
684 .fw_name = "DTTFTA"
685 },
686
687 {
688 .tuner_type = TUNER_TYPE_TDA10046,
689 .tuner_name = "TDA10046",
690 .board_name = "VP3040",
691 .fw_name = "DTT-CI"
692 },
693
694 {
695 .tuner_type = TUNER_TYPE_UNKNOWN,
696 .tuner_name = "UNKNOWN",
697 .board_name = "VP3051",
698 .fw_name = "DTTNXT"
699 },
700
701 {
702 .tuner_type = TUNER_TYPE_NXT200x,
703 .tuner_name = "NXT200x",
704 .board_name = "VP3220",
705 .fw_name = "ATSCDI"
706 },
707
708 {
709 .tuner_type = TUNER_TYPE_NXT200x,
710 .tuner_name = "NXT200x",
711 .board_name = "VP3250",
712 .fw_name = "ATSCAD"
713 },
714 };
715
716 /*
717 Known cards list
718 Satellite
719 -------------------
720 200103A
721 VP-1020 DST-MOT LG(old), TS=188
722
723 VP-1020 DST-03T LG(new), TS=204
724 VP-1022 DST-03T LG(new), TS=204
725 VP-1025 DST-03T LG(new), TS=204
726
727 VP-1030 DSTMCI, LG(new), TS=188
728 VP-1032 DSTMCI, LG(new), TS=188
729
730 Cable
731 -------------------
732 VP-2030 DCT-CI, Samsung, TS=204
733 VP-2021 DCT-CI, Unknown, TS=204
734 VP-2031 DCT-CI, Philips, TS=188
735 VP-2040 DCT-CI, Philips, TS=188, with CA daughter board
736 VP-2040 DCT-CI, Philips, TS=204, without CA daughter board
737
738 Terrestrial
739 -------------------
740 VP-3050 DTTNXT TS=188
741 VP-3040 DTT-CI, Philips, TS=188
742 VP-3040 DTT-CI, Philips, TS=204
743
744 ATSC
745 -------------------
746 VP-3220 ATSCDI, TS=188
747 VP-3250 ATSCAD, TS=188
748
749 */
750
751 static struct dst_types dst_tlist[] = {
752 {
753 .device_id = "200103A",
754 .offset = 0,
755 .dst_type = DST_TYPE_IS_SAT,
756 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS,
757 .dst_feature = 0,
758 .tuner_type = 0
759 }, /* obsolete */
760
761 {
762 .device_id = "DST-020",
763 .offset = 0,
764 .dst_type = DST_TYPE_IS_SAT,
765 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
766 .dst_feature = 0,
767 .tuner_type = 0
768 }, /* obsolete */
769
770 {
771 .device_id = "DST-030",
772 .offset = 0,
773 .dst_type = DST_TYPE_IS_SAT,
774 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1,
775 .dst_feature = 0,
776 .tuner_type = 0
777 }, /* obsolete */
778
779 {
780 .device_id = "DST-03T",
781 .offset = 0,
782 .dst_type = DST_TYPE_IS_SAT,
783 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
784 .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5
785 | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO,
786 .tuner_type = TUNER_TYPE_MULTI
787 },
788
789 {
790 .device_id = "DST-MOT",
791 .offset = 0,
792 .dst_type = DST_TYPE_IS_SAT,
793 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
794 .dst_feature = 0,
795 .tuner_type = 0
796 }, /* obsolete */
797
798 {
799 .device_id = "DST-CI",
800 .offset = 1,
801 .dst_type = DST_TYPE_IS_SAT,
802 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_1,
803 .dst_feature = DST_TYPE_HAS_CA,
804 .tuner_type = 0
805 }, /* An OEM board */
806
807 {
808 .device_id = "DSTMCI",
809 .offset = 1,
810 .dst_type = DST_TYPE_IS_SAT,
811 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT | DST_TYPE_HAS_VLF,
812 .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4
813 | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC,
814 .tuner_type = TUNER_TYPE_MULTI
815 },
816
817 {
818 .device_id = "DSTFCI",
819 .offset = 1,
820 .dst_type = DST_TYPE_IS_SAT,
821 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1,
822 .dst_feature = 0,
823 .tuner_type = 0
824 }, /* unknown to vendor */
825
826 {
827 .device_id = "DCT-CI",
828 .offset = 1,
829 .dst_type = DST_TYPE_IS_CABLE,
830 .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_VLF,
831 .dst_feature = DST_TYPE_HAS_CA,
832 .tuner_type = 0
833 },
834
835 {
836 .device_id = "DCTNEW",
837 .offset = 1,
838 .dst_type = DST_TYPE_IS_CABLE,
839 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_MULTI_FE,
840 .dst_feature = 0,
841 .tuner_type = 0
842 },
843
844 {
845 .device_id = "DTT-CI",
846 .offset = 1,
847 .dst_type = DST_TYPE_IS_TERR,
848 .type_flags = DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_VLF,
849 .dst_feature = DST_TYPE_HAS_CA,
850 .tuner_type = 0
851 },
852
853 {
854 .device_id = "DTTDIG",
855 .offset = 1,
856 .dst_type = DST_TYPE_IS_TERR,
857 .type_flags = DST_TYPE_HAS_FW_2,
858 .dst_feature = 0,
859 .tuner_type = 0
860 },
861
862 {
863 .device_id = "DTTNXT",
864 .offset = 1,
865 .dst_type = DST_TYPE_IS_TERR,
866 .type_flags = DST_TYPE_HAS_FW_2,
867 .dst_feature = DST_TYPE_HAS_ANALOG,
868 .tuner_type = 0
869 },
870
871 {
872 .device_id = "ATSCDI",
873 .offset = 1,
874 .dst_type = DST_TYPE_IS_ATSC,
875 .type_flags = DST_TYPE_HAS_FW_2,
876 .dst_feature = 0,
877 .tuner_type = 0
878 },
879
880 {
881 .device_id = "ATSCAD",
882 .offset = 1,
883 .dst_type = DST_TYPE_IS_ATSC,
884 .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
885 .dst_feature = DST_TYPE_HAS_MAC | DST_TYPE_HAS_ANALOG,
886 .tuner_type = 0
887 },
888
889 { }
890
891 };
892
893 static int dst_get_mac(struct dst_state *state)
894 {
895 u8 get_mac[] = { 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
896 get_mac[7] = dst_check_sum(get_mac, 7);
897 if (dst_command(state, get_mac, 8) < 0) {
898 dprintk(2, "Unsupported Command\n");
899 return -1;
900 }
901 memset(&state->mac_address, '\0', 8);
902 memcpy(&state->mac_address, &state->rxbuffer, 6);
903 pr_err("MAC Address=[%pM]\n", state->mac_address);
904
905 return 0;
906 }
907
908 static int dst_fw_ver(struct dst_state *state)
909 {
910 u8 get_ver[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
911 get_ver[7] = dst_check_sum(get_ver, 7);
912 if (dst_command(state, get_ver, 8) < 0) {
913 dprintk(2, "Unsupported Command\n");
914 return -1;
915 }
916 memcpy(&state->fw_version, &state->rxbuffer, 8);
917 pr_err("Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x\n",
918 state->fw_version[0] >> 4, state->fw_version[0] & 0x0f,
919 state->fw_version[1],
920 state->fw_version[5], state->fw_version[6],
921 state->fw_version[4], state->fw_version[3], state->fw_version[2]);
922
923 return 0;
924 }
925
926 static int dst_card_type(struct dst_state *state)
927 {
928 int j;
929 struct tuner_types *p_tuner_list = NULL;
930
931 u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
932 get_type[7] = dst_check_sum(get_type, 7);
933 if (dst_command(state, get_type, 8) < 0) {
934 dprintk(2, "Unsupported Command\n");
935 return -1;
936 }
937 memset(&state->card_info, '\0', 8);
938 memcpy(&state->card_info, &state->rxbuffer, 7);
939 pr_err("Device Model=[%s]\n", &state->card_info[0]);
940
941 for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
942 if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) {
943 state->tuner_type = p_tuner_list->tuner_type;
944 pr_err("DST has [%s] tuner, tuner type=[%d]\n",
945 p_tuner_list->tuner_name, p_tuner_list->tuner_type);
946 }
947 }
948
949 return 0;
950 }
951
952 static int dst_get_vendor(struct dst_state *state)
953 {
954 u8 get_vendor[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
955 get_vendor[7] = dst_check_sum(get_vendor, 7);
956 if (dst_command(state, get_vendor, 8) < 0) {
957 dprintk(2, "Unsupported Command\n");
958 return -1;
959 }
960 memset(&state->vendor, '\0', 8);
961 memcpy(&state->vendor, &state->rxbuffer, 7);
962 pr_err("Vendor=[%s]\n", &state->vendor[0]);
963
964 return 0;
965 }
966
967 static void debug_dst_buffer(struct dst_state *state)
968 {
969 dprintk(3, "%s: [ %*ph ]\n", __func__, 8, state->rxbuffer);
970 }
971
972 static int dst_check_stv0299(struct dst_state *state)
973 {
974 u8 check_stv0299[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
975
976 check_stv0299[7] = dst_check_sum(check_stv0299, 7);
977 if (dst_command(state, check_stv0299, 8) < 0) {
978 pr_err("Cmd=[0x04] failed\n");
979 return -1;
980 }
981 debug_dst_buffer(state);
982
983 if (memcmp(&check_stv0299, &state->rxbuffer, 8)) {
984 pr_err("Found a STV0299 NIM\n");
985 state->tuner_type = TUNER_TYPE_STV0299;
986 return 0;
987 }
988
989 return -1;
990 }
991
992 static int dst_check_mb86a15(struct dst_state *state)
993 {
994 u8 check_mb86a15[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
995
996 check_mb86a15[7] = dst_check_sum(check_mb86a15, 7);
997 if (dst_command(state, check_mb86a15, 8) < 0) {
998 pr_err("Cmd=[0x10], failed\n");
999 return -1;
1000 }
1001 debug_dst_buffer(state);
1002
1003 if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) {
1004 pr_err("Found a MB86A15 NIM\n");
1005 state->tuner_type = TUNER_TYPE_MB86A15;
1006 return 0;
1007 }
1008
1009 return -1;
1010 }
1011
1012 static int dst_get_tuner_info(struct dst_state *state)
1013 {
1014 u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1015 u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1016
1017 get_tuner_1[7] = dst_check_sum(get_tuner_1, 7);
1018 get_tuner_2[7] = dst_check_sum(get_tuner_2, 7);
1019 pr_err("DST TYpe = MULTI FE\n");
1020 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
1021 if (dst_command(state, get_tuner_1, 8) < 0) {
1022 dprintk(2, "Cmd=[0x13], Unsupported\n");
1023 goto force;
1024 }
1025 } else {
1026 if (dst_command(state, get_tuner_2, 8) < 0) {
1027 dprintk(2, "Cmd=[0xb], Unsupported\n");
1028 goto force;
1029 }
1030 }
1031 memcpy(&state->board_info, &state->rxbuffer, 8);
1032 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
1033 pr_err("DST type has TS=188\n");
1034 }
1035 if (state->board_info[0] == 0xbc) {
1036 if (state->dst_type != DST_TYPE_IS_ATSC)
1037 state->type_flags |= DST_TYPE_HAS_TS188;
1038 else
1039 state->type_flags |= DST_TYPE_HAS_NEWTUNE_2;
1040
1041 if (state->board_info[1] == 0x01) {
1042 state->dst_hw_cap |= DST_TYPE_HAS_DBOARD;
1043 pr_err("DST has Daughterboard\n");
1044 }
1045 }
1046
1047 return 0;
1048 force:
1049 if (!strncmp(state->fw_name, "DCT-CI", 6)) {
1050 state->type_flags |= DST_TYPE_HAS_TS204;
1051 pr_err("Forcing [%s] to TS188\n", state->fw_name);
1052 }
1053
1054 return -1;
1055 }
1056
1057 static int dst_get_device_id(struct dst_state *state)
1058 {
1059 u8 reply;
1060
1061 int i, j;
1062 struct dst_types *p_dst_type = NULL;
1063 struct tuner_types *p_tuner_list = NULL;
1064
1065 u8 use_dst_type = 0;
1066 u32 use_type_flags = 0;
1067
1068 static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
1069
1070 state->tuner_type = 0;
1071 device_type[7] = dst_check_sum(device_type, 7);
1072
1073 if (write_dst(state, device_type, FIXED_COMM))
1074 return -1; /* Write failed */
1075 if ((dst_pio_disable(state)) < 0)
1076 return -1;
1077 if (read_dst(state, &reply, GET_ACK))
1078 return -1; /* Read failure */
1079 if (reply != ACK) {
1080 dprintk(2, "Write not Acknowledged! [Reply=0x%02x]\n", reply);
1081 return -1; /* Unack'd write */
1082 }
1083 if (!dst_wait_dst_ready(state, DEVICE_INIT))
1084 return -1; /* DST not ready yet */
1085 if (read_dst(state, state->rxbuffer, FIXED_COMM))
1086 return -1;
1087
1088 dst_pio_disable(state);
1089 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
1090 dprintk(2, "Checksum failure!\n");
1091 return -1; /* Checksum failure */
1092 }
1093 state->rxbuffer[7] = '\0';
1094
1095 for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE(dst_tlist); i++, p_dst_type++) {
1096 if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) {
1097 use_type_flags = p_dst_type->type_flags;
1098 use_dst_type = p_dst_type->dst_type;
1099
1100 /* Card capabilities */
1101 state->dst_hw_cap = p_dst_type->dst_feature;
1102 pr_err("Recognise [%s]\n", p_dst_type->device_id);
1103 strscpy(state->fw_name, p_dst_type->device_id,
1104 sizeof(state->fw_name));
1105 /* Multiple tuners */
1106 if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) {
1107 switch (use_dst_type) {
1108 case DST_TYPE_IS_SAT:
1109 /* STV0299 check */
1110 if (dst_check_stv0299(state) < 0) {
1111 pr_err("Unsupported\n");
1112 state->tuner_type = TUNER_TYPE_MB86A15;
1113 }
1114 break;
1115 default:
1116 break;
1117 }
1118 if (dst_check_mb86a15(state) < 0)
1119 pr_err("Unsupported\n");
1120 /* Single tuner */
1121 } else {
1122 state->tuner_type = p_dst_type->tuner_type;
1123 }
1124 for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
1125 if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) &&
1126 p_tuner_list->tuner_type == state->tuner_type) {
1127 pr_err("[%s] has a [%s]\n",
1128 p_dst_type->device_id, p_tuner_list->tuner_name);
1129 }
1130 }
1131 break;
1132 }
1133 }
1134
1135 if (i >= ARRAY_SIZE(dst_tlist)) {
1136 pr_err("Unable to recognize %s or %s\n", &state->rxbuffer[0], &state->rxbuffer[1]);
1137 pr_err("please email linux-dvb@linuxtv.org with this type in");
1138 use_dst_type = DST_TYPE_IS_SAT;
1139 use_type_flags = DST_TYPE_HAS_SYMDIV;
1140 }
1141 dst_type_print(state, use_dst_type);
1142 state->type_flags = use_type_flags;
1143 state->dst_type = use_dst_type;
1144 dst_type_flags_print(state);
1145
1146 return 0;
1147 }
1148
1149 static int dst_probe(struct dst_state *state)
1150 {
1151 mutex_init(&state->dst_mutex);
1152 if (dst_addons & DST_TYPE_HAS_CA) {
1153 if ((rdc_8820_reset(state)) < 0) {
1154 pr_err("RDC 8820 RESET Failed.\n");
1155 return -1;
1156 }
1157 msleep(4000);
1158 } else {
1159 msleep(100);
1160 }
1161 if ((dst_comm_init(state)) < 0) {
1162 pr_err("DST Initialization Failed.\n");
1163 return -1;
1164 }
1165 msleep(100);
1166 if (dst_get_device_id(state) < 0) {
1167 pr_err("unknown device.\n");
1168 return -1;
1169 }
1170 if (dst_get_mac(state) < 0) {
1171 dprintk(2, "MAC: Unsupported command\n");
1172 }
1173 if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {
1174 if (dst_get_tuner_info(state) < 0)
1175 dprintk(2, "Tuner: Unsupported command\n");
1176 }
1177 if (state->type_flags & DST_TYPE_HAS_TS204) {
1178 dst_packsize(state, 204);
1179 }
1180 if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
1181 if (dst_fw_ver(state) < 0) {
1182 dprintk(2, "FW: Unsupported command\n");
1183 return 0;
1184 }
1185 if (dst_card_type(state) < 0) {
1186 dprintk(2, "Card: Unsupported command\n");
1187 return 0;
1188 }
1189 if (dst_get_vendor(state) < 0) {
1190 dprintk(2, "Vendor: Unsupported command\n");
1191 return 0;
1192 }
1193 }
1194
1195 return 0;
1196 }
1197
1198 static int dst_command(struct dst_state *state, u8 *data, u8 len)
1199 {
1200 u8 reply;
1201
1202 mutex_lock(&state->dst_mutex);
1203 if ((dst_comm_init(state)) < 0) {
1204 dprintk(1, "DST Communication Initialization Failed.\n");
1205 goto error;
1206 }
1207 if (write_dst(state, data, len)) {
1208 dprintk(2, "Trying to recover..\n");
1209 if ((dst_error_recovery(state)) < 0) {
1210 pr_err("Recovery Failed.\n");
1211 goto error;
1212 }
1213 goto error;
1214 }
1215 if ((dst_pio_disable(state)) < 0) {
1216 pr_err("PIO Disable Failed.\n");
1217 goto error;
1218 }
1219 if (state->type_flags & DST_TYPE_HAS_FW_1)
1220 mdelay(3);
1221 if (read_dst(state, &reply, GET_ACK)) {
1222 dprintk(3, "Trying to recover..\n");
1223 if ((dst_error_recovery(state)) < 0) {
1224 dprintk(2, "Recovery Failed.\n");
1225 goto error;
1226 }
1227 goto error;
1228 }
1229 if (reply != ACK) {
1230 dprintk(2, "write not acknowledged 0x%02x\n", reply);
1231 goto error;
1232 }
1233 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
1234 goto error;
1235 if (state->type_flags & DST_TYPE_HAS_FW_1)
1236 mdelay(3);
1237 else
1238 udelay(2000);
1239 if (!dst_wait_dst_ready(state, NO_DELAY))
1240 goto error;
1241 if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
1242 dprintk(3, "Trying to recover..\n");
1243 if ((dst_error_recovery(state)) < 0) {
1244 dprintk(2, "Recovery failed.\n");
1245 goto error;
1246 }
1247 goto error;
1248 }
1249 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
1250 dprintk(2, "checksum failure\n");
1251 goto error;
1252 }
1253 mutex_unlock(&state->dst_mutex);
1254 return 0;
1255
1256 error:
1257 mutex_unlock(&state->dst_mutex);
1258 return -EIO;
1259
1260 }
1261
1262 static int dst_get_signal(struct dst_state *state)
1263 {
1264 int retval;
1265 u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
1266 //dprintk("%s: Getting Signal strength and other parameters\n", __func__);
1267 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
1268 state->decode_lock = state->decode_strength = state->decode_snr = 0;
1269 return 0;
1270 }
1271 if (0 == (state->diseq_flags & HAS_LOCK)) {
1272 state->decode_lock = state->decode_strength = state->decode_snr = 0;
1273 return 0;
1274 }
1275 if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) {
1276 retval = dst_command(state, get_signal, 8);
1277 if (retval < 0)
1278 return retval;
1279 if (state->dst_type == DST_TYPE_IS_SAT) {
1280 state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0;
1281 state->decode_strength = state->rxbuffer[5] << 8;
1282 state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
1283 } else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) {
1284 state->decode_lock = (state->rxbuffer[1]) ? 1 : 0;
1285 state->decode_strength = state->rxbuffer[4] << 8;
1286 state->decode_snr = state->rxbuffer[3] << 8;
1287 } else if (state->dst_type == DST_TYPE_IS_ATSC) {
1288 state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0;
1289 state->decode_strength = state->rxbuffer[4] << 8;
1290 state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
1291 }
1292 state->cur_jiff = jiffies;
1293 }
1294 return 0;
1295 }
1296
1297 static int dst_tone_power_cmd(struct dst_state *state)
1298 {
1299 u8 packet[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
1300
1301 if (state->dst_type != DST_TYPE_IS_SAT)
1302 return -EOPNOTSUPP;
1303 packet[4] = state->tx_tuna[4];
1304 packet[2] = state->tx_tuna[2];
1305 packet[3] = state->tx_tuna[3];
1306 packet[7] = dst_check_sum (packet, 7);
1307 return dst_command(state, packet, 8);
1308 }
1309
1310 static int dst_get_tuna(struct dst_state *state)
1311 {
1312 int retval;
1313
1314 if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
1315 return 0;
1316 state->diseq_flags &= ~(HAS_LOCK);
1317 if (!dst_wait_dst_ready(state, NO_DELAY))
1318 return -EIO;
1319 if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1320 !(state->dst_type == DST_TYPE_IS_ATSC))
1321
1322 retval = read_dst(state, state->rx_tuna, 10);
1323 else
1324 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
1325 if (retval < 0) {
1326 dprintk(3, "read not successful\n");
1327 return retval;
1328 }
1329 if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1330 !(state->dst_type == DST_TYPE_IS_ATSC)) {
1331
1332 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
1333 dprintk(2, "checksum failure ?\n");
1334 return -EIO;
1335 }
1336 } else {
1337 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
1338 dprintk(2, "checksum failure?\n");
1339 return -EIO;
1340 }
1341 }
1342 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
1343 return 0;
1344 if (state->dst_type == DST_TYPE_IS_SAT) {
1345 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
1346 } else {
1347 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];
1348 }
1349 state->decode_freq = state->decode_freq * 1000;
1350 state->decode_lock = 1;
1351 state->diseq_flags |= HAS_LOCK;
1352
1353 return 1;
1354 }
1355
1356 static int dst_set_voltage(struct dvb_frontend *fe,
1357 enum fe_sec_voltage voltage);
1358
1359 static int dst_write_tuna(struct dvb_frontend *fe)
1360 {
1361 struct dst_state *state = fe->demodulator_priv;
1362 int retval;
1363 u8 reply;
1364
1365 dprintk(2, "type_flags 0x%x\n", state->type_flags);
1366 state->decode_freq = 0;
1367 state->decode_lock = state->decode_strength = state->decode_snr = 0;
1368 if (state->dst_type == DST_TYPE_IS_SAT) {
1369 if (!(state->diseq_flags & HAS_POWER))
1370 dst_set_voltage(fe, SEC_VOLTAGE_13);
1371 }
1372 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
1373 mutex_lock(&state->dst_mutex);
1374 if ((dst_comm_init(state)) < 0) {
1375 dprintk(3, "DST Communication initialization failed.\n");
1376 goto error;
1377 }
1378 // if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
1379 if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1380 (!(state->dst_type == DST_TYPE_IS_ATSC))) {
1381
1382 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
1383 retval = write_dst(state, &state->tx_tuna[0], 10);
1384 } else {
1385 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
1386 retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
1387 }
1388 if (retval < 0) {
1389 dst_pio_disable(state);
1390 dprintk(3, "write not successful\n");
1391 goto werr;
1392 }
1393 if ((dst_pio_disable(state)) < 0) {
1394 dprintk(3, "DST PIO disable failed !\n");
1395 goto error;
1396 }
1397 if ((read_dst(state, &reply, GET_ACK) < 0)) {
1398 dprintk(3, "read verify not successful.\n");
1399 goto error;
1400 }
1401 if (reply != ACK) {
1402 dprintk(3, "write not acknowledged 0x%02x\n", reply);
1403 goto error;
1404 }
1405 state->diseq_flags |= ATTEMPT_TUNE;
1406 retval = dst_get_tuna(state);
1407 werr:
1408 mutex_unlock(&state->dst_mutex);
1409 return retval;
1410
1411 error:
1412 mutex_unlock(&state->dst_mutex);
1413 return -EIO;
1414 }
1415
1416 /*
1417 * line22k0 0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00
1418 * line22k1 0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00
1419 * line22k2 0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00
1420 * tone 0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00
1421 * data 0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00
1422 * power_off 0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
1423 * power_on 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00
1424 * Diseqc 1 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec
1425 * Diseqc 2 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8
1426 * Diseqc 3 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4
1427 * Diseqc 4 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0
1428 */
1429
1430 static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
1431 {
1432 struct dst_state *state = fe->demodulator_priv;
1433 u8 packet[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
1434
1435 if (state->dst_type != DST_TYPE_IS_SAT)
1436 return -EOPNOTSUPP;
1437 if (cmd->msg_len > 0 && cmd->msg_len < 5)
1438 memcpy(&packet[3], cmd->msg, cmd->msg_len);
1439 else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5)
1440 memcpy(&packet[2], cmd->msg, cmd->msg_len);
1441 else
1442 return -EINVAL;
1443 packet[7] = dst_check_sum(&packet[0], 7);
1444 return dst_command(state, packet, 8);
1445 }
1446
1447 static int dst_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage)
1448 {
1449 int need_cmd, retval = 0;
1450 struct dst_state *state = fe->demodulator_priv;
1451
1452 state->voltage = voltage;
1453 if (state->dst_type != DST_TYPE_IS_SAT)
1454 return -EOPNOTSUPP;
1455
1456 need_cmd = 0;
1457
1458 switch (voltage) {
1459 case SEC_VOLTAGE_13:
1460 case SEC_VOLTAGE_18:
1461 if ((state->diseq_flags & HAS_POWER) == 0)
1462 need_cmd = 1;
1463 state->diseq_flags |= HAS_POWER;
1464 state->tx_tuna[4] = 0x01;
1465 break;
1466 case SEC_VOLTAGE_OFF:
1467 need_cmd = 1;
1468 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
1469 state->tx_tuna[4] = 0x00;
1470 break;
1471 default:
1472 return -EINVAL;
1473 }
1474
1475 if (need_cmd)
1476 retval = dst_tone_power_cmd(state);
1477
1478 return retval;
1479 }
1480
1481 static int dst_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
1482 {
1483 struct dst_state *state = fe->demodulator_priv;
1484
1485 state->tone = tone;
1486 if (state->dst_type != DST_TYPE_IS_SAT)
1487 return -EOPNOTSUPP;
1488
1489 switch (tone) {
1490 case SEC_TONE_OFF:
1491 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1492 state->tx_tuna[2] = 0x00;
1493 else
1494 state->tx_tuna[2] = 0xff;
1495 break;
1496
1497 case SEC_TONE_ON:
1498 state->tx_tuna[2] = 0x02;
1499 break;
1500 default:
1501 return -EINVAL;
1502 }
1503 return dst_tone_power_cmd(state);
1504 }
1505
1506 static int dst_send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd minicmd)
1507 {
1508 struct dst_state *state = fe->demodulator_priv;
1509
1510 if (state->dst_type != DST_TYPE_IS_SAT)
1511 return -EOPNOTSUPP;
1512 state->minicmd = minicmd;
1513 switch (minicmd) {
1514 case SEC_MINI_A:
1515 state->tx_tuna[3] = 0x02;
1516 break;
1517 case SEC_MINI_B:
1518 state->tx_tuna[3] = 0xff;
1519 break;
1520 }
1521 return dst_tone_power_cmd(state);
1522 }
1523
1524
1525 static int bt8xx_dst_init(struct dvb_frontend *fe)
1526 {
1527 struct dst_state *state = fe->demodulator_priv;
1528
1529 static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 };
1530 static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 };
1531 static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1532 static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1533 static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1534 static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1535 static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1536
1537 state->inversion = INVERSION_OFF;
1538 state->voltage = SEC_VOLTAGE_13;
1539 state->tone = SEC_TONE_OFF;
1540 state->diseq_flags = 0;
1541 state->k22 = 0x02;
1542 state->bandwidth = 7000000;
1543 state->cur_jiff = jiffies;
1544 if (state->dst_type == DST_TYPE_IS_SAT)
1545 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204));
1546 else if (state->dst_type == DST_TYPE_IS_TERR)
1547 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204));
1548 else if (state->dst_type == DST_TYPE_IS_CABLE)
1549 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204));
1550 else if (state->dst_type == DST_TYPE_IS_ATSC)
1551 memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner));
1552
1553 return 0;
1554 }
1555
1556 static int dst_read_status(struct dvb_frontend *fe, enum fe_status *status)
1557 {
1558 struct dst_state *state = fe->demodulator_priv;
1559
1560 *status = 0;
1561 if (state->diseq_flags & HAS_LOCK) {
1562 // dst_get_signal(state); // don't require(?) to ask MCU
1563 if (state->decode_lock)
1564 *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI;
1565 }
1566
1567 return 0;
1568 }
1569
1570 static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1571 {
1572 struct dst_state *state = fe->demodulator_priv;
1573
1574 int retval = dst_get_signal(state);
1575 *strength = state->decode_strength;
1576
1577 return retval;
1578 }
1579
1580 static int dst_read_snr(struct dvb_frontend *fe, u16 *snr)
1581 {
1582 struct dst_state *state = fe->demodulator_priv;
1583
1584 int retval = dst_get_signal(state);
1585 *snr = state->decode_snr;
1586
1587 return retval;
1588 }
1589
1590 static int dst_set_frontend(struct dvb_frontend *fe)
1591 {
1592 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1593 int retval = -EINVAL;
1594 struct dst_state *state = fe->demodulator_priv;
1595
1596 if (p != NULL) {
1597 retval = dst_set_freq(state, p->frequency);
1598 if(retval != 0)
1599 return retval;
1600 dprintk(3, "Set Frequency=[%d]\n", p->frequency);
1601
1602 if (state->dst_type == DST_TYPE_IS_SAT) {
1603 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1604 dst_set_inversion(state, p->inversion);
1605 dst_set_fec(state, p->fec_inner);
1606 dst_set_symbolrate(state, p->symbol_rate);
1607 dst_set_polarization(state);
1608 dprintk(3, "Set Symbolrate=[%d]\n", p->symbol_rate);
1609
1610 } else if (state->dst_type == DST_TYPE_IS_TERR)
1611 dst_set_bandwidth(state, p->bandwidth_hz);
1612 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1613 dst_set_fec(state, p->fec_inner);
1614 dst_set_symbolrate(state, p->symbol_rate);
1615 dst_set_modulation(state, p->modulation);
1616 }
1617 retval = dst_write_tuna(fe);
1618 }
1619
1620 return retval;
1621 }
1622
1623 static int dst_tune_frontend(struct dvb_frontend* fe,
1624 bool re_tune,
1625 unsigned int mode_flags,
1626 unsigned int *delay,
1627 enum fe_status *status)
1628 {
1629 struct dst_state *state = fe->demodulator_priv;
1630 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1631
1632 if (re_tune) {
1633 dst_set_freq(state, p->frequency);
1634 dprintk(3, "Set Frequency=[%d]\n", p->frequency);
1635
1636 if (state->dst_type == DST_TYPE_IS_SAT) {
1637 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1638 dst_set_inversion(state, p->inversion);
1639 dst_set_fec(state, p->fec_inner);
1640 dst_set_symbolrate(state, p->symbol_rate);
1641 dst_set_polarization(state);
1642 dprintk(3, "Set Symbolrate=[%d]\n", p->symbol_rate);
1643
1644 } else if (state->dst_type == DST_TYPE_IS_TERR)
1645 dst_set_bandwidth(state, p->bandwidth_hz);
1646 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1647 dst_set_fec(state, p->fec_inner);
1648 dst_set_symbolrate(state, p->symbol_rate);
1649 dst_set_modulation(state, p->modulation);
1650 }
1651 dst_write_tuna(fe);
1652 }
1653
1654 if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
1655 dst_read_status(fe, status);
1656
1657 *delay = HZ/10;
1658 return 0;
1659 }
1660
1661 static enum dvbfe_algo dst_get_tuning_algo(struct dvb_frontend *fe)
1662 {
1663 return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW;
1664 }
1665
1666 static int dst_get_frontend(struct dvb_frontend *fe,
1667 struct dtv_frontend_properties *p)
1668 {
1669 struct dst_state *state = fe->demodulator_priv;
1670
1671 p->frequency = state->decode_freq;
1672 if (state->dst_type == DST_TYPE_IS_SAT) {
1673 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1674 p->inversion = state->inversion;
1675 p->symbol_rate = state->symbol_rate;
1676 p->fec_inner = dst_get_fec(state);
1677 } else if (state->dst_type == DST_TYPE_IS_TERR) {
1678 p->bandwidth_hz = state->bandwidth;
1679 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
1680 p->symbol_rate = state->symbol_rate;
1681 p->fec_inner = dst_get_fec(state);
1682 p->modulation = dst_get_modulation(state);
1683 }
1684
1685 return 0;
1686 }
1687
1688 static void bt8xx_dst_release(struct dvb_frontend *fe)
1689 {
1690 struct dst_state *state = fe->demodulator_priv;
1691 if (state->dst_ca) {
1692 dvb_unregister_device(state->dst_ca);
1693 #ifdef CONFIG_MEDIA_ATTACH
1694 symbol_put(dst_ca_attach);
1695 #endif
1696 }
1697 kfree(state);
1698 }
1699
1700 static const struct dvb_frontend_ops dst_dvbt_ops;
1701 static const struct dvb_frontend_ops dst_dvbs_ops;
1702 static const struct dvb_frontend_ops dst_dvbc_ops;
1703 static const struct dvb_frontend_ops dst_atsc_ops;
1704
1705 struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
1706 {
1707 /* check if the ASIC is there */
1708 if (dst_probe(state) < 0) {
1709 kfree(state);
1710 return NULL;
1711 }
1712 /* determine settings based on type */
1713 /* create dvb_frontend */
1714 switch (state->dst_type) {
1715 case DST_TYPE_IS_TERR:
1716 memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
1717 break;
1718 case DST_TYPE_IS_CABLE:
1719 memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
1720 break;
1721 case DST_TYPE_IS_SAT:
1722 memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
1723 break;
1724 case DST_TYPE_IS_ATSC:
1725 memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops));
1726 break;
1727 default:
1728 pr_err("unknown DST type. please report to the LinuxTV.org DVB mailinglist.\n");
1729 kfree(state);
1730 return NULL;
1731 }
1732 state->frontend.demodulator_priv = state;
1733
1734 return state; /* Manu (DST is a card not a frontend) */
1735 }
1736
1737 EXPORT_SYMBOL(dst_attach);
1738
1739 static const struct dvb_frontend_ops dst_dvbt_ops = {
1740 .delsys = { SYS_DVBT },
1741 .info = {
1742 .name = "DST DVB-T",
1743 .frequency_min_hz = 137 * MHz,
1744 .frequency_max_hz = 858 * MHz,
1745 .frequency_stepsize_hz = 166667,
1746 .caps = FE_CAN_FEC_AUTO |
1747 FE_CAN_QAM_AUTO |
1748 FE_CAN_QAM_16 |
1749 FE_CAN_QAM_32 |
1750 FE_CAN_QAM_64 |
1751 FE_CAN_QAM_128 |
1752 FE_CAN_QAM_256 |
1753 FE_CAN_TRANSMISSION_MODE_AUTO |
1754 FE_CAN_GUARD_INTERVAL_AUTO
1755 },
1756
1757 .release = bt8xx_dst_release,
1758 .init = bt8xx_dst_init,
1759 .tune = dst_tune_frontend,
1760 .set_frontend = dst_set_frontend,
1761 .get_frontend = dst_get_frontend,
1762 .get_frontend_algo = dst_get_tuning_algo,
1763 .read_status = dst_read_status,
1764 .read_signal_strength = dst_read_signal_strength,
1765 .read_snr = dst_read_snr,
1766 };
1767
1768 static const struct dvb_frontend_ops dst_dvbs_ops = {
1769 .delsys = { SYS_DVBS },
1770 .info = {
1771 .name = "DST DVB-S",
1772 .frequency_min_hz = 950 * MHz,
1773 .frequency_max_hz = 2150 * MHz,
1774 .frequency_stepsize_hz = 1 * MHz,
1775 .frequency_tolerance_hz = 29500 * kHz,
1776 .symbol_rate_min = 1000000,
1777 .symbol_rate_max = 45000000,
1778 /* . symbol_rate_tolerance = ???,*/
1779 .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
1780 },
1781
1782 .release = bt8xx_dst_release,
1783 .init = bt8xx_dst_init,
1784 .tune = dst_tune_frontend,
1785 .set_frontend = dst_set_frontend,
1786 .get_frontend = dst_get_frontend,
1787 .get_frontend_algo = dst_get_tuning_algo,
1788 .read_status = dst_read_status,
1789 .read_signal_strength = dst_read_signal_strength,
1790 .read_snr = dst_read_snr,
1791 .diseqc_send_burst = dst_send_burst,
1792 .diseqc_send_master_cmd = dst_set_diseqc,
1793 .set_voltage = dst_set_voltage,
1794 .set_tone = dst_set_tone,
1795 };
1796
1797 static const struct dvb_frontend_ops dst_dvbc_ops = {
1798 .delsys = { SYS_DVBC_ANNEX_A },
1799 .info = {
1800 .name = "DST DVB-C",
1801 .frequency_min_hz = 51 * MHz,
1802 .frequency_max_hz = 858 * MHz,
1803 .frequency_stepsize_hz = 62500,
1804 .symbol_rate_min = 1000000,
1805 .symbol_rate_max = 45000000,
1806 .caps = FE_CAN_FEC_AUTO |
1807 FE_CAN_QAM_AUTO |
1808 FE_CAN_QAM_16 |
1809 FE_CAN_QAM_32 |
1810 FE_CAN_QAM_64 |
1811 FE_CAN_QAM_128 |
1812 FE_CAN_QAM_256
1813 },
1814
1815 .release = bt8xx_dst_release,
1816 .init = bt8xx_dst_init,
1817 .tune = dst_tune_frontend,
1818 .set_frontend = dst_set_frontend,
1819 .get_frontend = dst_get_frontend,
1820 .get_frontend_algo = dst_get_tuning_algo,
1821 .read_status = dst_read_status,
1822 .read_signal_strength = dst_read_signal_strength,
1823 .read_snr = dst_read_snr,
1824 };
1825
1826 static const struct dvb_frontend_ops dst_atsc_ops = {
1827 .delsys = { SYS_ATSC },
1828 .info = {
1829 .name = "DST ATSC",
1830 .frequency_min_hz = 510 * MHz,
1831 .frequency_max_hz = 858 * MHz,
1832 .frequency_stepsize_hz = 62500,
1833 .symbol_rate_min = 1000000,
1834 .symbol_rate_max = 45000000,
1835 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
1836 },
1837
1838 .release = bt8xx_dst_release,
1839 .init = bt8xx_dst_init,
1840 .tune = dst_tune_frontend,
1841 .set_frontend = dst_set_frontend,
1842 .get_frontend = dst_get_frontend,
1843 .get_frontend_algo = dst_get_tuning_algo,
1844 .read_status = dst_read_status,
1845 .read_signal_strength = dst_read_signal_strength,
1846 .read_snr = dst_read_snr,
1847 };
1848
1849 MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver");
1850 MODULE_AUTHOR("Jamie Honan, Manu Abraham");
1851 MODULE_LICENSE("GPL");