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