1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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 "dvb_frontend.h"
32#include "dst_priv.h"
33#include "dst_common.h"
34
35static unsigned int verbose;
36module_param(verbose, int, 0644);
37MODULE_PARM_DESC(verbose, "verbosity level (0 to 3)");
38
39static unsigned int dst_addons;
40module_param(dst_addons, int, 0644);
41MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)");
42
43static unsigned int dst_algo;
44module_param(dst_algo, int, 0644);
45MODULE_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
57static int dst_command(struct dst_state *state, u8 *data, u8 len);
58
59static 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
67static 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
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
101static 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
116int 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}
132EXPORT_SYMBOL(rdc_reset_state);
133
134static 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
150static 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
161int 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}
172EXPORT_SYMBOL(dst_pio_disable);
173
174int 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}
194EXPORT_SYMBOL(dst_wait_dst_ready);
195
196int 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}
206EXPORT_SYMBOL(dst_error_recovery);
207
208int 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}
217EXPORT_SYMBOL(dst_error_bailout);
218
219int 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}
237EXPORT_SYMBOL(dst_comm_init);
238
239int 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}
271EXPORT_SYMBOL(write_dst);
272
273int 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}
304EXPORT_SYMBOL(read_dst);
305
306static int dst_set_polarization(struct dst_state *state)
307{
308 switch (state->voltage) {
309 case SEC_VOLTAGE_13:
310 dprintk(2, "Polarization=[Vertical]\n");
311 state->tx_tuna[8] &= ~0x40;
312 break;
313 case SEC_VOLTAGE_18:
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
324static 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;
361 state->tx_tuna[6] = 0x00;
362 if (state->dst_hw_cap & DST_TYPE_HAS_ANALOG)
363 state->tx_tuna[7] = 0x00;
364 } else
365 return -EINVAL;
366
367 return 0;
368}
369
370static 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
409static 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:
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
427static int dst_set_fec(struct dst_state *state, enum fe_code_rate fec)
428{
429 state->fec = fec;
430 return 0;
431}
432
433static enum fe_code_rate dst_get_fec(struct dst_state *state)
434{
435 return state->fec;
436}
437
438static 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
484static 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
522static enum fe_modulation dst_get_modulation(struct dst_state *state)
523{
524 return state->modulation;
525}
526
527
528u8 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}
539EXPORT_SYMBOL(dst_check_sum);
540
541static 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
566static 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
595static 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
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751static 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 },
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 },
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 },
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 },
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 },
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 },
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
893static 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
908static 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
926static 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
952static 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
967static void debug_dst_buffer(struct dst_state *state)
968{
969 dprintk(3, "%s: [ %*ph ]\n", __func__, 8, state->rxbuffer);
970}
971
972static 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
992static 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
1012static 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;
1048force:
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
1057static 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;
1075 if ((dst_pio_disable(state)) < 0)
1076 return -1;
1077 if (read_dst(state, &reply, GET_ACK))
1078 return -1;
1079 if (reply != ACK) {
1080 dprintk(2, "Write not Acknowledged! [Reply=0x%02x]\n", reply);
1081 return -1;
1082 }
1083 if (!dst_wait_dst_ready(state, DEVICE_INIT))
1084 return -1;
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;
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
1101 state->dst_hw_cap = p_dst_type->dst_feature;
1102 pr_err("Recognise [%s]\n", p_dst_type->device_id);
1103 strncpy(&state->fw_name[0], p_dst_type->device_id, 6);
1104
1105 if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) {
1106 switch (use_dst_type) {
1107 case DST_TYPE_IS_SAT:
1108
1109 if (dst_check_stv0299(state) < 0) {
1110 pr_err("Unsupported\n");
1111 state->tuner_type = TUNER_TYPE_MB86A15;
1112 }
1113 break;
1114 default:
1115 break;
1116 }
1117 if (dst_check_mb86a15(state) < 0)
1118 pr_err("Unsupported\n");
1119
1120 } else {
1121 state->tuner_type = p_dst_type->tuner_type;
1122 }
1123 for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
1124 if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) &&
1125 p_tuner_list->tuner_type == state->tuner_type) {
1126 pr_err("[%s] has a [%s]\n",
1127 p_dst_type->device_id, p_tuner_list->tuner_name);
1128 }
1129 }
1130 break;
1131 }
1132 }
1133
1134 if (i >= ARRAY_SIZE(dst_tlist)) {
1135 pr_err("Unable to recognize %s or %s\n", &state->rxbuffer[0], &state->rxbuffer[1]);
1136 pr_err("please email linux-dvb@linuxtv.org with this type in");
1137 use_dst_type = DST_TYPE_IS_SAT;
1138 use_type_flags = DST_TYPE_HAS_SYMDIV;
1139 }
1140 dst_type_print(state, use_dst_type);
1141 state->type_flags = use_type_flags;
1142 state->dst_type = use_dst_type;
1143 dst_type_flags_print(state);
1144
1145 return 0;
1146}
1147
1148static int dst_probe(struct dst_state *state)
1149{
1150 mutex_init(&state->dst_mutex);
1151 if (dst_addons & DST_TYPE_HAS_CA) {
1152 if ((rdc_8820_reset(state)) < 0) {
1153 pr_err("RDC 8820 RESET Failed.\n");
1154 return -1;
1155 }
1156 msleep(4000);
1157 } else {
1158 msleep(100);
1159 }
1160 if ((dst_comm_init(state)) < 0) {
1161 pr_err("DST Initialization Failed.\n");
1162 return -1;
1163 }
1164 msleep(100);
1165 if (dst_get_device_id(state) < 0) {
1166 pr_err("unknown device.\n");
1167 return -1;
1168 }
1169 if (dst_get_mac(state) < 0) {
1170 dprintk(2, "MAC: Unsupported command\n");
1171 }
1172 if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {
1173 if (dst_get_tuner_info(state) < 0)
1174 dprintk(2, "Tuner: Unsupported command\n");
1175 }
1176 if (state->type_flags & DST_TYPE_HAS_TS204) {
1177 dst_packsize(state, 204);
1178 }
1179 if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
1180 if (dst_fw_ver(state) < 0) {
1181 dprintk(2, "FW: Unsupported command\n");
1182 return 0;
1183 }
1184 if (dst_card_type(state) < 0) {
1185 dprintk(2, "Card: Unsupported command\n");
1186 return 0;
1187 }
1188 if (dst_get_vendor(state) < 0) {
1189 dprintk(2, "Vendor: Unsupported command\n");
1190 return 0;
1191 }
1192 }
1193
1194 return 0;
1195}
1196
1197static int dst_command(struct dst_state *state, u8 *data, u8 len)
1198{
1199 u8 reply;
1200
1201 mutex_lock(&state->dst_mutex);
1202 if ((dst_comm_init(state)) < 0) {
1203 dprintk(1, "DST Communication Initialization Failed.\n");
1204 goto error;
1205 }
1206 if (write_dst(state, data, len)) {
1207 dprintk(2, "Trying to recover..\n");
1208 if ((dst_error_recovery(state)) < 0) {
1209 pr_err("Recovery Failed.\n");
1210 goto error;
1211 }
1212 goto error;
1213 }
1214 if ((dst_pio_disable(state)) < 0) {
1215 pr_err("PIO Disable Failed.\n");
1216 goto error;
1217 }
1218 if (state->type_flags & DST_TYPE_HAS_FW_1)
1219 mdelay(3);
1220 if (read_dst(state, &reply, GET_ACK)) {
1221 dprintk(3, "Trying to recover..\n");
1222 if ((dst_error_recovery(state)) < 0) {
1223 dprintk(2, "Recovery Failed.\n");
1224 goto error;
1225 }
1226 goto error;
1227 }
1228 if (reply != ACK) {
1229 dprintk(2, "write not acknowledged 0x%02x\n", reply);
1230 goto error;
1231 }
1232 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
1233 goto error;
1234 if (state->type_flags & DST_TYPE_HAS_FW_1)
1235 mdelay(3);
1236 else
1237 udelay(2000);
1238 if (!dst_wait_dst_ready(state, NO_DELAY))
1239 goto error;
1240 if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
1241 dprintk(3, "Trying to recover..\n");
1242 if ((dst_error_recovery(state)) < 0) {
1243 dprintk(2, "Recovery failed.\n");
1244 goto error;
1245 }
1246 goto error;
1247 }
1248 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
1249 dprintk(2, "checksum failure\n");
1250 goto error;
1251 }
1252 mutex_unlock(&state->dst_mutex);
1253 return 0;
1254
1255error:
1256 mutex_unlock(&state->dst_mutex);
1257 return -EIO;
1258
1259}
1260
1261static int dst_get_signal(struct dst_state *state)
1262{
1263 int retval;
1264 u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
1265
1266 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
1267 state->decode_lock = state->decode_strength = state->decode_snr = 0;
1268 return 0;
1269 }
1270 if (0 == (state->diseq_flags & HAS_LOCK)) {
1271 state->decode_lock = state->decode_strength = state->decode_snr = 0;
1272 return 0;
1273 }
1274 if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) {
1275 retval = dst_command(state, get_signal, 8);
1276 if (retval < 0)
1277 return retval;
1278 if (state->dst_type == DST_TYPE_IS_SAT) {
1279 state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0;
1280 state->decode_strength = state->rxbuffer[5] << 8;
1281 state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
1282 } else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) {
1283 state->decode_lock = (state->rxbuffer[1]) ? 1 : 0;
1284 state->decode_strength = state->rxbuffer[4] << 8;
1285 state->decode_snr = state->rxbuffer[3] << 8;
1286 } else if (state->dst_type == DST_TYPE_IS_ATSC) {
1287 state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0;
1288 state->decode_strength = state->rxbuffer[4] << 8;
1289 state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
1290 }
1291 state->cur_jiff = jiffies;
1292 }
1293 return 0;
1294}
1295
1296static int dst_tone_power_cmd(struct dst_state *state)
1297{
1298 u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
1299
1300 if (state->dst_type != DST_TYPE_IS_SAT)
1301 return -EOPNOTSUPP;
1302 paket[4] = state->tx_tuna[4];
1303 paket[2] = state->tx_tuna[2];
1304 paket[3] = state->tx_tuna[3];
1305 paket[7] = dst_check_sum (paket, 7);
1306 return dst_command(state, paket, 8);
1307}
1308
1309static int dst_get_tuna(struct dst_state *state)
1310{
1311 int retval;
1312
1313 if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
1314 return 0;
1315 state->diseq_flags &= ~(HAS_LOCK);
1316 if (!dst_wait_dst_ready(state, NO_DELAY))
1317 return -EIO;
1318 if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1319 !(state->dst_type == DST_TYPE_IS_ATSC))
1320
1321 retval = read_dst(state, state->rx_tuna, 10);
1322 else
1323 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
1324 if (retval < 0) {
1325 dprintk(3, "read not successful\n");
1326 return retval;
1327 }
1328 if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1329 !(state->dst_type == DST_TYPE_IS_ATSC)) {
1330
1331 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
1332 dprintk(2, "checksum failure ?\n");
1333 return -EIO;
1334 }
1335 } else {
1336 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
1337 dprintk(2, "checksum failure?\n");
1338 return -EIO;
1339 }
1340 }
1341 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
1342 return 0;
1343 if (state->dst_type == DST_TYPE_IS_SAT) {
1344 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
1345 } else {
1346 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];
1347 }
1348 state->decode_freq = state->decode_freq * 1000;
1349 state->decode_lock = 1;
1350 state->diseq_flags |= HAS_LOCK;
1351
1352 return 1;
1353}
1354
1355static int dst_set_voltage(struct dvb_frontend *fe,
1356 enum fe_sec_voltage voltage);
1357
1358static int dst_write_tuna(struct dvb_frontend *fe)
1359{
1360 struct dst_state *state = fe->demodulator_priv;
1361 int retval;
1362 u8 reply;
1363
1364 dprintk(2, "type_flags 0x%x\n", state->type_flags);
1365 state->decode_freq = 0;
1366 state->decode_lock = state->decode_strength = state->decode_snr = 0;
1367 if (state->dst_type == DST_TYPE_IS_SAT) {
1368 if (!(state->diseq_flags & HAS_POWER))
1369 dst_set_voltage(fe, SEC_VOLTAGE_13);
1370 }
1371 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
1372 mutex_lock(&state->dst_mutex);
1373 if ((dst_comm_init(state)) < 0) {
1374 dprintk(3, "DST Communication initialization failed.\n");
1375 goto error;
1376 }
1377
1378 if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1379 (!(state->dst_type == DST_TYPE_IS_ATSC))) {
1380
1381 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
1382 retval = write_dst(state, &state->tx_tuna[0], 10);
1383 } else {
1384 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
1385 retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
1386 }
1387 if (retval < 0) {
1388 dst_pio_disable(state);
1389 dprintk(3, "write not successful\n");
1390 goto werr;
1391 }
1392 if ((dst_pio_disable(state)) < 0) {
1393 dprintk(3, "DST PIO disable failed !\n");
1394 goto error;
1395 }
1396 if ((read_dst(state, &reply, GET_ACK) < 0)) {
1397 dprintk(3, "read verify not successful.\n");
1398 goto error;
1399 }
1400 if (reply != ACK) {
1401 dprintk(3, "write not acknowledged 0x%02x\n", reply);
1402 goto error;
1403 }
1404 state->diseq_flags |= ATTEMPT_TUNE;
1405 retval = dst_get_tuna(state);
1406werr:
1407 mutex_unlock(&state->dst_mutex);
1408 return retval;
1409
1410error:
1411 mutex_unlock(&state->dst_mutex);
1412 return -EIO;
1413}
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
1430{
1431 struct dst_state *state = fe->demodulator_priv;
1432 u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
1433
1434 if (state->dst_type != DST_TYPE_IS_SAT)
1435 return -EOPNOTSUPP;
1436 if (cmd->msg_len > 0 && cmd->msg_len < 5)
1437 memcpy(&paket[3], cmd->msg, cmd->msg_len);
1438 else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5)
1439 memcpy(&paket[2], cmd->msg, cmd->msg_len);
1440 else
1441 return -EINVAL;
1442 paket[7] = dst_check_sum(&paket[0], 7);
1443 return dst_command(state, paket, 8);
1444}
1445
1446static int dst_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage)
1447{
1448 int need_cmd, retval = 0;
1449 struct dst_state *state = fe->demodulator_priv;
1450
1451 state->voltage = voltage;
1452 if (state->dst_type != DST_TYPE_IS_SAT)
1453 return -EOPNOTSUPP;
1454
1455 need_cmd = 0;
1456
1457 switch (voltage) {
1458 case SEC_VOLTAGE_13:
1459 case SEC_VOLTAGE_18:
1460 if ((state->diseq_flags & HAS_POWER) == 0)
1461 need_cmd = 1;
1462 state->diseq_flags |= HAS_POWER;
1463 state->tx_tuna[4] = 0x01;
1464 break;
1465 case SEC_VOLTAGE_OFF:
1466 need_cmd = 1;
1467 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
1468 state->tx_tuna[4] = 0x00;
1469 break;
1470 default:
1471 return -EINVAL;
1472 }
1473
1474 if (need_cmd)
1475 retval = dst_tone_power_cmd(state);
1476
1477 return retval;
1478}
1479
1480static int dst_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
1481{
1482 struct dst_state *state = fe->demodulator_priv;
1483
1484 state->tone = tone;
1485 if (state->dst_type != DST_TYPE_IS_SAT)
1486 return -EOPNOTSUPP;
1487
1488 switch (tone) {
1489 case SEC_TONE_OFF:
1490 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1491 state->tx_tuna[2] = 0x00;
1492 else
1493 state->tx_tuna[2] = 0xff;
1494 break;
1495
1496 case SEC_TONE_ON:
1497 state->tx_tuna[2] = 0x02;
1498 break;
1499 default:
1500 return -EINVAL;
1501 }
1502 return dst_tone_power_cmd(state);
1503}
1504
1505static int dst_send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd minicmd)
1506{
1507 struct dst_state *state = fe->demodulator_priv;
1508
1509 if (state->dst_type != DST_TYPE_IS_SAT)
1510 return -EOPNOTSUPP;
1511 state->minicmd = minicmd;
1512 switch (minicmd) {
1513 case SEC_MINI_A:
1514 state->tx_tuna[3] = 0x02;
1515 break;
1516 case SEC_MINI_B:
1517 state->tx_tuna[3] = 0xff;
1518 break;
1519 }
1520 return dst_tone_power_cmd(state);
1521}
1522
1523
1524static int bt8xx_dst_init(struct dvb_frontend *fe)
1525{
1526 struct dst_state *state = fe->demodulator_priv;
1527
1528 static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 };
1529 static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 };
1530 static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1531 static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1532 static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1533 static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1534 static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1535
1536 state->inversion = INVERSION_OFF;
1537 state->voltage = SEC_VOLTAGE_13;
1538 state->tone = SEC_TONE_OFF;
1539 state->diseq_flags = 0;
1540 state->k22 = 0x02;
1541 state->bandwidth = 7000000;
1542 state->cur_jiff = jiffies;
1543 if (state->dst_type == DST_TYPE_IS_SAT)
1544 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204));
1545 else if (state->dst_type == DST_TYPE_IS_TERR)
1546 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204));
1547 else if (state->dst_type == DST_TYPE_IS_CABLE)
1548 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204));
1549 else if (state->dst_type == DST_TYPE_IS_ATSC)
1550 memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner));
1551
1552 return 0;
1553}
1554
1555static int dst_read_status(struct dvb_frontend *fe, enum fe_status *status)
1556{
1557 struct dst_state *state = fe->demodulator_priv;
1558
1559 *status = 0;
1560 if (state->diseq_flags & HAS_LOCK) {
1561
1562 if (state->decode_lock)
1563 *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI;
1564 }
1565
1566 return 0;
1567}
1568
1569static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1570{
1571 struct dst_state *state = fe->demodulator_priv;
1572
1573 int retval = dst_get_signal(state);
1574 *strength = state->decode_strength;
1575
1576 return retval;
1577}
1578
1579static int dst_read_snr(struct dvb_frontend *fe, u16 *snr)
1580{
1581 struct dst_state *state = fe->demodulator_priv;
1582
1583 int retval = dst_get_signal(state);
1584 *snr = state->decode_snr;
1585
1586 return retval;
1587}
1588
1589static int dst_set_frontend(struct dvb_frontend *fe)
1590{
1591 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1592 int retval = -EINVAL;
1593 struct dst_state *state = fe->demodulator_priv;
1594
1595 if (p != NULL) {
1596 retval = dst_set_freq(state, p->frequency);
1597 if(retval != 0)
1598 return retval;
1599 dprintk(3, "Set Frequency=[%d]\n", p->frequency);
1600
1601 if (state->dst_type == DST_TYPE_IS_SAT) {
1602 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1603 dst_set_inversion(state, p->inversion);
1604 dst_set_fec(state, p->fec_inner);
1605 dst_set_symbolrate(state, p->symbol_rate);
1606 dst_set_polarization(state);
1607 dprintk(3, "Set Symbolrate=[%d]\n", p->symbol_rate);
1608
1609 } else if (state->dst_type == DST_TYPE_IS_TERR)
1610 dst_set_bandwidth(state, p->bandwidth_hz);
1611 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1612 dst_set_fec(state, p->fec_inner);
1613 dst_set_symbolrate(state, p->symbol_rate);
1614 dst_set_modulation(state, p->modulation);
1615 }
1616 retval = dst_write_tuna(fe);
1617 }
1618
1619 return retval;
1620}
1621
1622static int dst_tune_frontend(struct dvb_frontend* fe,
1623 bool re_tune,
1624 unsigned int mode_flags,
1625 unsigned int *delay,
1626 enum fe_status *status)
1627{
1628 struct dst_state *state = fe->demodulator_priv;
1629 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1630
1631 if (re_tune) {
1632 dst_set_freq(state, p->frequency);
1633 dprintk(3, "Set Frequency=[%d]\n", p->frequency);
1634
1635 if (state->dst_type == DST_TYPE_IS_SAT) {
1636 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1637 dst_set_inversion(state, p->inversion);
1638 dst_set_fec(state, p->fec_inner);
1639 dst_set_symbolrate(state, p->symbol_rate);
1640 dst_set_polarization(state);
1641 dprintk(3, "Set Symbolrate=[%d]\n", p->symbol_rate);
1642
1643 } else if (state->dst_type == DST_TYPE_IS_TERR)
1644 dst_set_bandwidth(state, p->bandwidth_hz);
1645 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1646 dst_set_fec(state, p->fec_inner);
1647 dst_set_symbolrate(state, p->symbol_rate);
1648 dst_set_modulation(state, p->modulation);
1649 }
1650 dst_write_tuna(fe);
1651 }
1652
1653 if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
1654 dst_read_status(fe, status);
1655
1656 *delay = HZ/10;
1657 return 0;
1658}
1659
1660static int dst_get_tuning_algo(struct dvb_frontend *fe)
1661{
1662 return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW;
1663}
1664
1665static int dst_get_frontend(struct dvb_frontend *fe,
1666 struct dtv_frontend_properties *p)
1667{
1668 struct dst_state *state = fe->demodulator_priv;
1669
1670 p->frequency = state->decode_freq;
1671 if (state->dst_type == DST_TYPE_IS_SAT) {
1672 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1673 p->inversion = state->inversion;
1674 p->symbol_rate = state->symbol_rate;
1675 p->fec_inner = dst_get_fec(state);
1676 } else if (state->dst_type == DST_TYPE_IS_TERR) {
1677 p->bandwidth_hz = state->bandwidth;
1678 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
1679 p->symbol_rate = state->symbol_rate;
1680 p->fec_inner = dst_get_fec(state);
1681 p->modulation = dst_get_modulation(state);
1682 }
1683
1684 return 0;
1685}
1686
1687static void bt8xx_dst_release(struct dvb_frontend *fe)
1688{
1689 struct dst_state *state = fe->demodulator_priv;
1690 if (state->dst_ca) {
1691 dvb_unregister_device(state->dst_ca);
1692#ifdef CONFIG_MEDIA_ATTACH
1693 symbol_put(dst_ca_attach);
1694#endif
1695 }
1696 kfree(state);
1697}
1698
1699static const struct dvb_frontend_ops dst_dvbt_ops;
1700static const struct dvb_frontend_ops dst_dvbs_ops;
1701static const struct dvb_frontend_ops dst_dvbc_ops;
1702static const struct dvb_frontend_ops dst_atsc_ops;
1703
1704struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
1705{
1706
1707 if (dst_probe(state) < 0) {
1708 kfree(state);
1709 return NULL;
1710 }
1711
1712
1713 switch (state->dst_type) {
1714 case DST_TYPE_IS_TERR:
1715 memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
1716 break;
1717 case DST_TYPE_IS_CABLE:
1718 memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
1719 break;
1720 case DST_TYPE_IS_SAT:
1721 memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
1722 break;
1723 case DST_TYPE_IS_ATSC:
1724 memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops));
1725 break;
1726 default:
1727 pr_err("unknown DST type. please report to the LinuxTV.org DVB mailinglist.\n");
1728 kfree(state);
1729 return NULL;
1730 }
1731 state->frontend.demodulator_priv = state;
1732
1733 return state;
1734}
1735
1736EXPORT_SYMBOL(dst_attach);
1737
1738static const struct dvb_frontend_ops dst_dvbt_ops = {
1739 .delsys = { SYS_DVBT },
1740 .info = {
1741 .name = "DST DVB-T",
1742 .frequency_min = 137000000,
1743 .frequency_max = 858000000,
1744 .frequency_stepsize = 166667,
1745 .caps = FE_CAN_FEC_AUTO |
1746 FE_CAN_QAM_AUTO |
1747 FE_CAN_QAM_16 |
1748 FE_CAN_QAM_32 |
1749 FE_CAN_QAM_64 |
1750 FE_CAN_QAM_128 |
1751 FE_CAN_QAM_256 |
1752 FE_CAN_TRANSMISSION_MODE_AUTO |
1753 FE_CAN_GUARD_INTERVAL_AUTO
1754 },
1755
1756 .release = bt8xx_dst_release,
1757 .init = bt8xx_dst_init,
1758 .tune = dst_tune_frontend,
1759 .set_frontend = dst_set_frontend,
1760 .get_frontend = dst_get_frontend,
1761 .get_frontend_algo = dst_get_tuning_algo,
1762 .read_status = dst_read_status,
1763 .read_signal_strength = dst_read_signal_strength,
1764 .read_snr = dst_read_snr,
1765};
1766
1767static const struct dvb_frontend_ops dst_dvbs_ops = {
1768 .delsys = { SYS_DVBS },
1769 .info = {
1770 .name = "DST DVB-S",
1771 .frequency_min = 950000,
1772 .frequency_max = 2150000,
1773 .frequency_stepsize = 1000,
1774 .frequency_tolerance = 29500,
1775 .symbol_rate_min = 1000000,
1776 .symbol_rate_max = 45000000,
1777
1778 .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
1779 },
1780
1781 .release = bt8xx_dst_release,
1782 .init = bt8xx_dst_init,
1783 .tune = dst_tune_frontend,
1784 .set_frontend = dst_set_frontend,
1785 .get_frontend = dst_get_frontend,
1786 .get_frontend_algo = dst_get_tuning_algo,
1787 .read_status = dst_read_status,
1788 .read_signal_strength = dst_read_signal_strength,
1789 .read_snr = dst_read_snr,
1790 .diseqc_send_burst = dst_send_burst,
1791 .diseqc_send_master_cmd = dst_set_diseqc,
1792 .set_voltage = dst_set_voltage,
1793 .set_tone = dst_set_tone,
1794};
1795
1796static const struct dvb_frontend_ops dst_dvbc_ops = {
1797 .delsys = { SYS_DVBC_ANNEX_A },
1798 .info = {
1799 .name = "DST DVB-C",
1800 .frequency_stepsize = 62500,
1801 .frequency_min = 51000000,
1802 .frequency_max = 858000000,
1803 .symbol_rate_min = 1000000,
1804 .symbol_rate_max = 45000000,
1805 .caps = FE_CAN_FEC_AUTO |
1806 FE_CAN_QAM_AUTO |
1807 FE_CAN_QAM_16 |
1808 FE_CAN_QAM_32 |
1809 FE_CAN_QAM_64 |
1810 FE_CAN_QAM_128 |
1811 FE_CAN_QAM_256
1812 },
1813
1814 .release = bt8xx_dst_release,
1815 .init = bt8xx_dst_init,
1816 .tune = dst_tune_frontend,
1817 .set_frontend = dst_set_frontend,
1818 .get_frontend = dst_get_frontend,
1819 .get_frontend_algo = dst_get_tuning_algo,
1820 .read_status = dst_read_status,
1821 .read_signal_strength = dst_read_signal_strength,
1822 .read_snr = dst_read_snr,
1823};
1824
1825static const struct dvb_frontend_ops dst_atsc_ops = {
1826 .delsys = { SYS_ATSC },
1827 .info = {
1828 .name = "DST ATSC",
1829 .frequency_stepsize = 62500,
1830 .frequency_min = 510000000,
1831 .frequency_max = 858000000,
1832 .symbol_rate_min = 1000000,
1833 .symbol_rate_max = 45000000,
1834 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
1835 },
1836
1837 .release = bt8xx_dst_release,
1838 .init = bt8xx_dst_init,
1839 .tune = dst_tune_frontend,
1840 .set_frontend = dst_set_frontend,
1841 .get_frontend = dst_get_frontend,
1842 .get_frontend_algo = dst_get_tuning_algo,
1843 .read_status = dst_read_status,
1844 .read_signal_strength = dst_read_signal_strength,
1845 .read_snr = dst_read_snr,
1846};
1847
1848MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver");
1849MODULE_AUTHOR("Jamie Honan, Manu Abraham");
1850MODULE_LICENSE("GPL");
1851