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, fe_spectral_inversion_t inversion)
429{
430 state->inversion = inversion;
431 switch (inversion) {
432 case INVERSION_OFF:
433 state->tx_tuna[8] &= ~0x80;
434 break;
435 case INVERSION_ON:
436 state->tx_tuna[8] |= 0x80;
437 break;
438 default:
439 return -EINVAL;
440 }
441
442 return 0;
443}
444
445static int dst_set_fec(struct dst_state *state, fe_code_rate_t fec)
446{
447 state->fec = fec;
448 return 0;
449}
450
451static fe_code_rate_t dst_get_fec(struct dst_state *state)
452{
453 return state->fec;
454}
455
456static int dst_set_symbolrate(struct dst_state *state, u32 srate)
457{
458 u32 symcalc;
459 u64 sval;
460
461 state->symbol_rate = srate;
462 if (state->dst_type == DST_TYPE_IS_TERR) {
463 return -EOPNOTSUPP;
464 }
465 dprintk(verbose, DST_INFO, 1, "set symrate %u", srate);
466 srate /= 1000;
467 if (state->dst_type == DST_TYPE_IS_SAT) {
468 if (state->type_flags & DST_TYPE_HAS_SYMDIV) {
469 sval = srate;
470 sval <<= 20;
471 do_div(sval, 88000);
472 symcalc = (u32) sval;
473 dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc);
474 state->tx_tuna[5] = (u8) (symcalc >> 12);
475 state->tx_tuna[6] = (u8) (symcalc >> 4);
476 state->tx_tuna[7] = (u8) (symcalc << 4);
477 } else {
478 state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f;
479 state->tx_tuna[6] = (u8) (srate >> 8);
480 state->tx_tuna[7] = (u8) srate;
481 }
482 state->tx_tuna[8] &= ~0x20;
483 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
484 if (srate > 8000)
485 state->tx_tuna[8] |= 0x20;
486 }
487 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
488 dprintk(verbose, DST_DEBUG, 1, "%s", state->fw_name);
489 if (!strncmp(state->fw_name, "DCTNEW", 6)) {
490 state->tx_tuna[5] = (u8) (srate >> 8);
491 state->tx_tuna[6] = (u8) srate;
492 state->tx_tuna[7] = 0x00;
493 } else if (!strncmp(state->fw_name, "DCT-CI", 6)) {
494 state->tx_tuna[5] = 0x00;
495 state->tx_tuna[6] = (u8) (srate >> 8);
496 state->tx_tuna[7] = (u8) srate;
497 }
498 }
499 return 0;
500}
501
502static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation)
503{
504 if (state->dst_type != DST_TYPE_IS_CABLE)
505 return -EOPNOTSUPP;
506
507 state->modulation = modulation;
508 switch (modulation) {
509 case QAM_16:
510 state->tx_tuna[8] = 0x10;
511 break;
512 case QAM_32:
513 state->tx_tuna[8] = 0x20;
514 break;
515 case QAM_64:
516 state->tx_tuna[8] = 0x40;
517 break;
518 case QAM_128:
519 state->tx_tuna[8] = 0x80;
520 break;
521 case QAM_256:
522 if (!strncmp(state->fw_name, "DCTNEW", 6))
523 state->tx_tuna[8] = 0xff;
524 else if (!strncmp(state->fw_name, "DCT-CI", 6))
525 state->tx_tuna[8] = 0x00;
526 break;
527 case QPSK:
528 case QAM_AUTO:
529 case VSB_8:
530 case VSB_16:
531 default:
532 return -EINVAL;
533
534 }
535
536 return 0;
537}
538
539static fe_modulation_t dst_get_modulation(struct dst_state *state)
540{
541 return state->modulation;
542}
543
544
545u8 dst_check_sum(u8 *buf, u32 len)
546{
547 u32 i;
548 u8 val = 0;
549 if (!len)
550 return 0;
551 for (i = 0; i < len; i++) {
552 val += buf[i];
553 }
554 return ((~val) + 1);
555}
556EXPORT_SYMBOL(dst_check_sum);
557
558static void dst_type_flags_print(struct dst_state *state)
559{
560 u32 type_flags = state->type_flags;
561
562 dprintk(verbose, DST_ERROR, 0, "DST type flags :");
563 if (type_flags & DST_TYPE_HAS_TS188)
564 dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_TS188);
565 if (type_flags & DST_TYPE_HAS_NEWTUNE_2)
566 dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner 2", DST_TYPE_HAS_NEWTUNE_2);
567 if (type_flags & DST_TYPE_HAS_TS204)
568 dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204);
569 if (type_flags & DST_TYPE_HAS_VLF)
570 dprintk(verbose, DST_ERROR, 0, " 0x%x VLF", DST_TYPE_HAS_VLF);
571 if (type_flags & DST_TYPE_HAS_SYMDIV)
572 dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
573 if (type_flags & DST_TYPE_HAS_FW_1)
574 dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 1", DST_TYPE_HAS_FW_1);
575 if (type_flags & DST_TYPE_HAS_FW_2)
576 dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 2", DST_TYPE_HAS_FW_2);
577 if (type_flags & DST_TYPE_HAS_FW_3)
578 dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 3", DST_TYPE_HAS_FW_3);
579 dprintk(verbose, DST_ERROR, 0, "\n");
580}
581
582
583static int dst_type_print(struct dst_state *state, u8 type)
584{
585 char *otype;
586 switch (type) {
587 case DST_TYPE_IS_SAT:
588 otype = "satellite";
589 break;
590
591 case DST_TYPE_IS_TERR:
592 otype = "terrestrial";
593 break;
594
595 case DST_TYPE_IS_CABLE:
596 otype = "cable";
597 break;
598
599 case DST_TYPE_IS_ATSC:
600 otype = "atsc";
601 break;
602
603 default:
604 dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type);
605 return -EINVAL;
606 }
607 dprintk(verbose, DST_INFO, 1, "DST type: %s", otype);
608
609 return 0;
610}
611
612static struct tuner_types tuner_list[] = {
613 {
614 .tuner_type = TUNER_TYPE_L64724,
615 .tuner_name = "L 64724",
616 .board_name = "UNKNOWN",
617 .fw_name = "UNKNOWN"
618 },
619
620 {
621 .tuner_type = TUNER_TYPE_STV0299,
622 .tuner_name = "STV 0299",
623 .board_name = "VP1020",
624 .fw_name = "DST-MOT"
625 },
626
627 {
628 .tuner_type = TUNER_TYPE_STV0299,
629 .tuner_name = "STV 0299",
630 .board_name = "VP1020",
631 .fw_name = "DST-03T"
632 },
633
634 {
635 .tuner_type = TUNER_TYPE_MB86A15,
636 .tuner_name = "MB 86A15",
637 .board_name = "VP1022",
638 .fw_name = "DST-03T"
639 },
640
641 {
642 .tuner_type = TUNER_TYPE_MB86A15,
643 .tuner_name = "MB 86A15",
644 .board_name = "VP1025",
645 .fw_name = "DST-03T"
646 },
647
648 {
649 .tuner_type = TUNER_TYPE_STV0299,
650 .tuner_name = "STV 0299",
651 .board_name = "VP1030",
652 .fw_name = "DST-CI"
653 },
654
655 {
656 .tuner_type = TUNER_TYPE_STV0299,
657 .tuner_name = "STV 0299",
658 .board_name = "VP1030",
659 .fw_name = "DSTMCI"
660 },
661
662 {
663 .tuner_type = TUNER_TYPE_UNKNOWN,
664 .tuner_name = "UNKNOWN",
665 .board_name = "VP2021",
666 .fw_name = "DCTNEW"
667 },
668
669 {
670 .tuner_type = TUNER_TYPE_UNKNOWN,
671 .tuner_name = "UNKNOWN",
672 .board_name = "VP2030",
673 .fw_name = "DCT-CI"
674 },
675
676 {
677 .tuner_type = TUNER_TYPE_UNKNOWN,
678 .tuner_name = "UNKNOWN",
679 .board_name = "VP2031",
680 .fw_name = "DCT-CI"
681 },
682
683 {
684 .tuner_type = TUNER_TYPE_UNKNOWN,
685 .tuner_name = "UNKNOWN",
686 .board_name = "VP2040",
687 .fw_name = "DCT-CI"
688 },
689
690 {
691 .tuner_type = TUNER_TYPE_UNKNOWN,
692 .tuner_name = "UNKNOWN",
693 .board_name = "VP3020",
694 .fw_name = "DTTFTA"
695 },
696
697 {
698 .tuner_type = TUNER_TYPE_UNKNOWN,
699 .tuner_name = "UNKNOWN",
700 .board_name = "VP3021",
701 .fw_name = "DTTFTA"
702 },
703
704 {
705 .tuner_type = TUNER_TYPE_TDA10046,
706 .tuner_name = "TDA10046",
707 .board_name = "VP3040",
708 .fw_name = "DTT-CI"
709 },
710
711 {
712 .tuner_type = TUNER_TYPE_UNKNOWN,
713 .tuner_name = "UNKNOWN",
714 .board_name = "VP3051",
715 .fw_name = "DTTNXT"
716 },
717
718 {
719 .tuner_type = TUNER_TYPE_NXT200x,
720 .tuner_name = "NXT200x",
721 .board_name = "VP3220",
722 .fw_name = "ATSCDI"
723 },
724
725 {
726 .tuner_type = TUNER_TYPE_NXT200x,
727 .tuner_name = "NXT200x",
728 .board_name = "VP3250",
729 .fw_name = "ATSCAD"
730 },
731};
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
768static struct dst_types dst_tlist[] = {
769 {
770 .device_id = "200103A",
771 .offset = 0,
772 .dst_type = DST_TYPE_IS_SAT,
773 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS,
774 .dst_feature = 0,
775 .tuner_type = 0
776 },
777
778 {
779 .device_id = "DST-020",
780 .offset = 0,
781 .dst_type = DST_TYPE_IS_SAT,
782 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
783 .dst_feature = 0,
784 .tuner_type = 0
785 },
786
787 {
788 .device_id = "DST-030",
789 .offset = 0,
790 .dst_type = DST_TYPE_IS_SAT,
791 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1,
792 .dst_feature = 0,
793 .tuner_type = 0
794 },
795
796 {
797 .device_id = "DST-03T",
798 .offset = 0,
799 .dst_type = DST_TYPE_IS_SAT,
800 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
801 .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5
802 | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO,
803 .tuner_type = TUNER_TYPE_MULTI
804 },
805
806 {
807 .device_id = "DST-MOT",
808 .offset = 0,
809 .dst_type = DST_TYPE_IS_SAT,
810 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
811 .dst_feature = 0,
812 .tuner_type = 0
813 },
814
815 {
816 .device_id = "DST-CI",
817 .offset = 1,
818 .dst_type = DST_TYPE_IS_SAT,
819 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_1,
820 .dst_feature = DST_TYPE_HAS_CA,
821 .tuner_type = 0
822 },
823
824 {
825 .device_id = "DSTMCI",
826 .offset = 1,
827 .dst_type = DST_TYPE_IS_SAT,
828 .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,
829 .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4
830 | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC,
831 .tuner_type = TUNER_TYPE_MULTI
832 },
833
834 {
835 .device_id = "DSTFCI",
836 .offset = 1,
837 .dst_type = DST_TYPE_IS_SAT,
838 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1,
839 .dst_feature = 0,
840 .tuner_type = 0
841 },
842
843 {
844 .device_id = "DCT-CI",
845 .offset = 1,
846 .dst_type = DST_TYPE_IS_CABLE,
847 .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_VLF,
848 .dst_feature = DST_TYPE_HAS_CA,
849 .tuner_type = 0
850 },
851
852 {
853 .device_id = "DCTNEW",
854 .offset = 1,
855 .dst_type = DST_TYPE_IS_CABLE,
856 .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_MULTI_FE,
857 .dst_feature = 0,
858 .tuner_type = 0
859 },
860
861 {
862 .device_id = "DTT-CI",
863 .offset = 1,
864 .dst_type = DST_TYPE_IS_TERR,
865 .type_flags = DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_VLF,
866 .dst_feature = DST_TYPE_HAS_CA,
867 .tuner_type = 0
868 },
869
870 {
871 .device_id = "DTTDIG",
872 .offset = 1,
873 .dst_type = DST_TYPE_IS_TERR,
874 .type_flags = DST_TYPE_HAS_FW_2,
875 .dst_feature = 0,
876 .tuner_type = 0
877 },
878
879 {
880 .device_id = "DTTNXT",
881 .offset = 1,
882 .dst_type = DST_TYPE_IS_TERR,
883 .type_flags = DST_TYPE_HAS_FW_2,
884 .dst_feature = DST_TYPE_HAS_ANALOG,
885 .tuner_type = 0
886 },
887
888 {
889 .device_id = "ATSCDI",
890 .offset = 1,
891 .dst_type = DST_TYPE_IS_ATSC,
892 .type_flags = DST_TYPE_HAS_FW_2,
893 .dst_feature = 0,
894 .tuner_type = 0
895 },
896
897 {
898 .device_id = "ATSCAD",
899 .offset = 1,
900 .dst_type = DST_TYPE_IS_ATSC,
901 .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
902 .dst_feature = DST_TYPE_HAS_MAC | DST_TYPE_HAS_ANALOG,
903 .tuner_type = 0
904 },
905
906 { }
907
908};
909
910static int dst_get_mac(struct dst_state *state)
911{
912 u8 get_mac[] = { 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
913 get_mac[7] = dst_check_sum(get_mac, 7);
914 if (dst_command(state, get_mac, 8) < 0) {
915 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
916 return -1;
917 }
918 memset(&state->mac_address, '\0', 8);
919 memcpy(&state->mac_address, &state->rxbuffer, 6);
920 dprintk(verbose, DST_ERROR, 1, "MAC Address=[%pM]", state->mac_address);
921
922 return 0;
923}
924
925static int dst_fw_ver(struct dst_state *state)
926{
927 u8 get_ver[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
928 get_ver[7] = dst_check_sum(get_ver, 7);
929 if (dst_command(state, get_ver, 8) < 0) {
930 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
931 return -1;
932 }
933 memcpy(&state->fw_version, &state->rxbuffer, 8);
934 dprintk(verbose, DST_ERROR, 1, "Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x",
935 state->fw_version[0] >> 4, state->fw_version[0] & 0x0f,
936 state->fw_version[1],
937 state->fw_version[5], state->fw_version[6],
938 state->fw_version[4], state->fw_version[3], state->fw_version[2]);
939
940 return 0;
941}
942
943static int dst_card_type(struct dst_state *state)
944{
945 int j;
946 struct tuner_types *p_tuner_list = NULL;
947
948 u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
949 get_type[7] = dst_check_sum(get_type, 7);
950 if (dst_command(state, get_type, 8) < 0) {
951 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
952 return -1;
953 }
954 memset(&state->card_info, '\0', 8);
955 memcpy(&state->card_info, &state->rxbuffer, 7);
956 dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]);
957
958 for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
959 if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) {
960 state->tuner_type = p_tuner_list->tuner_type;
961 dprintk(verbose, DST_ERROR, 1, "DST has [%s] tuner, tuner type=[%d]",
962 p_tuner_list->tuner_name, p_tuner_list->tuner_type);
963 }
964 }
965
966 return 0;
967}
968
969static int dst_get_vendor(struct dst_state *state)
970{
971 u8 get_vendor[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
972 get_vendor[7] = dst_check_sum(get_vendor, 7);
973 if (dst_command(state, get_vendor, 8) < 0) {
974 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
975 return -1;
976 }
977 memset(&state->vendor, '\0', 8);
978 memcpy(&state->vendor, &state->rxbuffer, 7);
979 dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]);
980
981 return 0;
982}
983
984static void debug_dst_buffer(struct dst_state *state)
985{
986 int i;
987
988 if (verbose > 2) {
989 printk("%s: [", __func__);
990 for (i = 0; i < 8; i++)
991 printk(" %02x", state->rxbuffer[i]);
992 printk("]\n");
993 }
994}
995
996static int dst_check_stv0299(struct dst_state *state)
997{
998 u8 check_stv0299[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
999
1000 check_stv0299[7] = dst_check_sum(check_stv0299, 7);
1001 if (dst_command(state, check_stv0299, 8) < 0) {
1002 dprintk(verbose, DST_ERROR, 1, "Cmd=[0x04] failed");
1003 return -1;
1004 }
1005 debug_dst_buffer(state);
1006
1007 if (memcmp(&check_stv0299, &state->rxbuffer, 8)) {
1008 dprintk(verbose, DST_ERROR, 1, "Found a STV0299 NIM");
1009 state->tuner_type = TUNER_TYPE_STV0299;
1010 return 0;
1011 }
1012
1013 return -1;
1014}
1015
1016static int dst_check_mb86a15(struct dst_state *state)
1017{
1018 u8 check_mb86a15[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1019
1020 check_mb86a15[7] = dst_check_sum(check_mb86a15, 7);
1021 if (dst_command(state, check_mb86a15, 8) < 0) {
1022 dprintk(verbose, DST_ERROR, 1, "Cmd=[0x10], failed");
1023 return -1;
1024 }
1025 debug_dst_buffer(state);
1026
1027 if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) {
1028 dprintk(verbose, DST_ERROR, 1, "Found a MB86A15 NIM");
1029 state->tuner_type = TUNER_TYPE_MB86A15;
1030 return 0;
1031 }
1032
1033 return -1;
1034}
1035
1036static int dst_get_tuner_info(struct dst_state *state)
1037{
1038 u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1039 u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1040
1041 get_tuner_1[7] = dst_check_sum(get_tuner_1, 7);
1042 get_tuner_2[7] = dst_check_sum(get_tuner_2, 7);
1043 dprintk(verbose, DST_ERROR, 1, "DST TYpe = MULTI FE");
1044 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
1045 if (dst_command(state, get_tuner_1, 8) < 0) {
1046 dprintk(verbose, DST_INFO, 1, "Cmd=[0x13], Unsupported");
1047 goto force;
1048 }
1049 } else {
1050 if (dst_command(state, get_tuner_2, 8) < 0) {
1051 dprintk(verbose, DST_INFO, 1, "Cmd=[0xb], Unsupported");
1052 goto force;
1053 }
1054 }
1055 memcpy(&state->board_info, &state->rxbuffer, 8);
1056 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
1057 dprintk(verbose, DST_ERROR, 1, "DST type has TS=188");
1058 }
1059 if (state->board_info[0] == 0xbc) {
1060 if (state->dst_type != DST_TYPE_IS_ATSC)
1061 state->type_flags |= DST_TYPE_HAS_TS188;
1062 else
1063 state->type_flags |= DST_TYPE_HAS_NEWTUNE_2;
1064
1065 if (state->board_info[1] == 0x01) {
1066 state->dst_hw_cap |= DST_TYPE_HAS_DBOARD;
1067 dprintk(verbose, DST_ERROR, 1, "DST has Daughterboard");
1068 }
1069 }
1070
1071 return 0;
1072force:
1073 if (!strncmp(state->fw_name, "DCT-CI", 6)) {
1074 state->type_flags |= DST_TYPE_HAS_TS204;
1075 dprintk(verbose, DST_ERROR, 1, "Forcing [%s] to TS188", state->fw_name);
1076 }
1077
1078 return -1;
1079}
1080
1081static int dst_get_device_id(struct dst_state *state)
1082{
1083 u8 reply;
1084
1085 int i, j;
1086 struct dst_types *p_dst_type = NULL;
1087 struct tuner_types *p_tuner_list = NULL;
1088
1089 u8 use_dst_type = 0;
1090 u32 use_type_flags = 0;
1091
1092 static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
1093
1094 state->tuner_type = 0;
1095 device_type[7] = dst_check_sum(device_type, 7);
1096
1097 if (write_dst(state, device_type, FIXED_COMM))
1098 return -1;
1099 if ((dst_pio_disable(state)) < 0)
1100 return -1;
1101 if (read_dst(state, &reply, GET_ACK))
1102 return -1;
1103 if (reply != ACK) {
1104 dprintk(verbose, DST_INFO, 1, "Write not Acknowledged! [Reply=0x%02x]", reply);
1105 return -1;
1106 }
1107 if (!dst_wait_dst_ready(state, DEVICE_INIT))
1108 return -1;
1109 if (read_dst(state, state->rxbuffer, FIXED_COMM))
1110 return -1;
1111
1112 dst_pio_disable(state);
1113 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
1114 dprintk(verbose, DST_INFO, 1, "Checksum failure!");
1115 return -1;
1116 }
1117 state->rxbuffer[7] = '\0';
1118
1119 for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE(dst_tlist); i++, p_dst_type++) {
1120 if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) {
1121 use_type_flags = p_dst_type->type_flags;
1122 use_dst_type = p_dst_type->dst_type;
1123
1124
1125 state->dst_hw_cap = p_dst_type->dst_feature;
1126 dprintk(verbose, DST_ERROR, 1, "Recognise [%s]", p_dst_type->device_id);
1127 strncpy(&state->fw_name[0], p_dst_type->device_id, 6);
1128
1129 if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) {
1130 switch (use_dst_type) {
1131 case DST_TYPE_IS_SAT:
1132
1133 if (dst_check_stv0299(state) < 0) {
1134 dprintk(verbose, DST_ERROR, 1, "Unsupported");
1135 state->tuner_type = TUNER_TYPE_MB86A15;
1136 }
1137 break;
1138 default:
1139 break;
1140 }
1141 if (dst_check_mb86a15(state) < 0)
1142 dprintk(verbose, DST_ERROR, 1, "Unsupported");
1143
1144 } else {
1145 state->tuner_type = p_dst_type->tuner_type;
1146 }
1147 for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
1148 if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) &&
1149 p_tuner_list->tuner_type == state->tuner_type) {
1150 dprintk(verbose, DST_ERROR, 1, "[%s] has a [%s]",
1151 p_dst_type->device_id, p_tuner_list->tuner_name);
1152 }
1153 }
1154 break;
1155 }
1156 }
1157
1158 if (i >= ARRAY_SIZE(dst_tlist)) {
1159 dprintk(verbose, DST_ERROR, 1, "Unable to recognize %s or %s", &state->rxbuffer[0], &state->rxbuffer[1]);
1160 dprintk(verbose, DST_ERROR, 1, "please email linux-dvb@linuxtv.org with this type in");
1161 use_dst_type = DST_TYPE_IS_SAT;
1162 use_type_flags = DST_TYPE_HAS_SYMDIV;
1163 }
1164 dst_type_print(state, use_dst_type);
1165 state->type_flags = use_type_flags;
1166 state->dst_type = use_dst_type;
1167 dst_type_flags_print(state);
1168
1169 return 0;
1170}
1171
1172static int dst_probe(struct dst_state *state)
1173{
1174 mutex_init(&state->dst_mutex);
1175 if (dst_addons & DST_TYPE_HAS_CA) {
1176 if ((rdc_8820_reset(state)) < 0) {
1177 dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
1178 return -1;
1179 }
1180 msleep(4000);
1181 } else {
1182 msleep(100);
1183 }
1184 if ((dst_comm_init(state)) < 0) {
1185 dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed.");
1186 return -1;
1187 }
1188 msleep(100);
1189 if (dst_get_device_id(state) < 0) {
1190 dprintk(verbose, DST_ERROR, 1, "unknown device.");
1191 return -1;
1192 }
1193 if (dst_get_mac(state) < 0) {
1194 dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command");
1195 }
1196 if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {
1197 if (dst_get_tuner_info(state) < 0)
1198 dprintk(verbose, DST_INFO, 1, "Tuner: Unsupported command");
1199 }
1200 if (state->type_flags & DST_TYPE_HAS_TS204) {
1201 dst_packsize(state, 204);
1202 }
1203 if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
1204 if (dst_fw_ver(state) < 0) {
1205 dprintk(verbose, DST_INFO, 1, "FW: Unsupported command");
1206 return 0;
1207 }
1208 if (dst_card_type(state) < 0) {
1209 dprintk(verbose, DST_INFO, 1, "Card: Unsupported command");
1210 return 0;
1211 }
1212 if (dst_get_vendor(state) < 0) {
1213 dprintk(verbose, DST_INFO, 1, "Vendor: Unsupported command");
1214 return 0;
1215 }
1216 }
1217
1218 return 0;
1219}
1220
1221static int dst_command(struct dst_state *state, u8 *data, u8 len)
1222{
1223 u8 reply;
1224
1225 mutex_lock(&state->dst_mutex);
1226 if ((dst_comm_init(state)) < 0) {
1227 dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
1228 goto error;
1229 }
1230 if (write_dst(state, data, len)) {
1231 dprintk(verbose, DST_INFO, 1, "Trying to recover.. ");
1232 if ((dst_error_recovery(state)) < 0) {
1233 dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");
1234 goto error;
1235 }
1236 goto error;
1237 }
1238 if ((dst_pio_disable(state)) < 0) {
1239 dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed.");
1240 goto error;
1241 }
1242 if (state->type_flags & DST_TYPE_HAS_FW_1)
1243 mdelay(3);
1244 if (read_dst(state, &reply, GET_ACK)) {
1245 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
1246 if ((dst_error_recovery(state)) < 0) {
1247 dprintk(verbose, DST_INFO, 1, "Recovery Failed.");
1248 goto error;
1249 }
1250 goto error;
1251 }
1252 if (reply != ACK) {
1253 dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply);
1254 goto error;
1255 }
1256 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
1257 goto error;
1258 if (state->type_flags & DST_TYPE_HAS_FW_1)
1259 mdelay(3);
1260 else
1261 udelay(2000);
1262 if (!dst_wait_dst_ready(state, NO_DELAY))
1263 goto error;
1264 if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
1265 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
1266 if ((dst_error_recovery(state)) < 0) {
1267 dprintk(verbose, DST_INFO, 1, "Recovery failed.");
1268 goto error;
1269 }
1270 goto error;
1271 }
1272 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
1273 dprintk(verbose, DST_INFO, 1, "checksum failure");
1274 goto error;
1275 }
1276 mutex_unlock(&state->dst_mutex);
1277 return 0;
1278
1279error:
1280 mutex_unlock(&state->dst_mutex);
1281 return -EIO;
1282
1283}
1284
1285static int dst_get_signal(struct dst_state *state)
1286{
1287 int retval;
1288 u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
1289
1290 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
1291 state->decode_lock = state->decode_strength = state->decode_snr = 0;
1292 return 0;
1293 }
1294 if (0 == (state->diseq_flags & HAS_LOCK)) {
1295 state->decode_lock = state->decode_strength = state->decode_snr = 0;
1296 return 0;
1297 }
1298 if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) {
1299 retval = dst_command(state, get_signal, 8);
1300 if (retval < 0)
1301 return retval;
1302 if (state->dst_type == DST_TYPE_IS_SAT) {
1303 state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0;
1304 state->decode_strength = state->rxbuffer[5] << 8;
1305 state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
1306 } else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) {
1307 state->decode_lock = (state->rxbuffer[1]) ? 1 : 0;
1308 state->decode_strength = state->rxbuffer[4] << 8;
1309 state->decode_snr = state->rxbuffer[3] << 8;
1310 } else if (state->dst_type == DST_TYPE_IS_ATSC) {
1311 state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0;
1312 state->decode_strength = state->rxbuffer[4] << 8;
1313 state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
1314 }
1315 state->cur_jiff = jiffies;
1316 }
1317 return 0;
1318}
1319
1320static int dst_tone_power_cmd(struct dst_state *state)
1321{
1322 u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
1323
1324 if (state->dst_type != DST_TYPE_IS_SAT)
1325 return -EOPNOTSUPP;
1326 paket[4] = state->tx_tuna[4];
1327 paket[2] = state->tx_tuna[2];
1328 paket[3] = state->tx_tuna[3];
1329 paket[7] = dst_check_sum (paket, 7);
1330 return dst_command(state, paket, 8);
1331}
1332
1333static int dst_get_tuna(struct dst_state *state)
1334{
1335 int retval;
1336
1337 if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
1338 return 0;
1339 state->diseq_flags &= ~(HAS_LOCK);
1340 if (!dst_wait_dst_ready(state, NO_DELAY))
1341 return -EIO;
1342 if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1343 !(state->dst_type == DST_TYPE_IS_ATSC))
1344
1345 retval = read_dst(state, state->rx_tuna, 10);
1346 else
1347 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
1348 if (retval < 0) {
1349 dprintk(verbose, DST_DEBUG, 1, "read not successful");
1350 return retval;
1351 }
1352 if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1353 !(state->dst_type == DST_TYPE_IS_ATSC)) {
1354
1355 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
1356 dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
1357 return -EIO;
1358 }
1359 } else {
1360 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
1361 dprintk(verbose, DST_INFO, 1, "checksum failure? ");
1362 return -EIO;
1363 }
1364 }
1365 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
1366 return 0;
1367 if (state->dst_type == DST_TYPE_IS_SAT) {
1368 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
1369 } else {
1370 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];
1371 }
1372 state->decode_freq = state->decode_freq * 1000;
1373 state->decode_lock = 1;
1374 state->diseq_flags |= HAS_LOCK;
1375
1376 return 1;
1377}
1378
1379static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
1380
1381static int dst_write_tuna(struct dvb_frontend *fe)
1382{
1383 struct dst_state *state = fe->demodulator_priv;
1384 int retval;
1385 u8 reply;
1386
1387 dprintk(verbose, DST_INFO, 1, "type_flags 0x%x ", state->type_flags);
1388 state->decode_freq = 0;
1389 state->decode_lock = state->decode_strength = state->decode_snr = 0;
1390 if (state->dst_type == DST_TYPE_IS_SAT) {
1391 if (!(state->diseq_flags & HAS_POWER))
1392 dst_set_voltage(fe, SEC_VOLTAGE_13);
1393 }
1394 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
1395 mutex_lock(&state->dst_mutex);
1396 if ((dst_comm_init(state)) < 0) {
1397 dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
1398 goto error;
1399 }
1400
1401 if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1402 (!(state->dst_type == DST_TYPE_IS_ATSC))) {
1403
1404 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
1405 retval = write_dst(state, &state->tx_tuna[0], 10);
1406 } else {
1407 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
1408 retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
1409 }
1410 if (retval < 0) {
1411 dst_pio_disable(state);
1412 dprintk(verbose, DST_DEBUG, 1, "write not successful");
1413 goto werr;
1414 }
1415 if ((dst_pio_disable(state)) < 0) {
1416 dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !");
1417 goto error;
1418 }
1419 if ((read_dst(state, &reply, GET_ACK) < 0)) {
1420 dprintk(verbose, DST_DEBUG, 1, "read verify not successful.");
1421 goto error;
1422 }
1423 if (reply != ACK) {
1424 dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply);
1425 goto error;
1426 }
1427 state->diseq_flags |= ATTEMPT_TUNE;
1428 retval = dst_get_tuna(state);
1429werr:
1430 mutex_unlock(&state->dst_mutex);
1431 return retval;
1432
1433error:
1434 mutex_unlock(&state->dst_mutex);
1435 return -EIO;
1436}
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
1453{
1454 struct dst_state *state = fe->demodulator_priv;
1455 u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
1456
1457 if (state->dst_type != DST_TYPE_IS_SAT)
1458 return -EOPNOTSUPP;
1459 if (cmd->msg_len > 0 && cmd->msg_len < 5)
1460 memcpy(&paket[3], cmd->msg, cmd->msg_len);
1461 else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5)
1462 memcpy(&paket[2], cmd->msg, cmd->msg_len);
1463 else
1464 return -EINVAL;
1465 paket[7] = dst_check_sum(&paket[0], 7);
1466 return dst_command(state, paket, 8);
1467}
1468
1469static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
1470{
1471 int need_cmd, retval = 0;
1472 struct dst_state *state = fe->demodulator_priv;
1473
1474 state->voltage = voltage;
1475 if (state->dst_type != DST_TYPE_IS_SAT)
1476 return -EOPNOTSUPP;
1477
1478 need_cmd = 0;
1479
1480 switch (voltage) {
1481 case SEC_VOLTAGE_13:
1482 case SEC_VOLTAGE_18:
1483 if ((state->diseq_flags & HAS_POWER) == 0)
1484 need_cmd = 1;
1485 state->diseq_flags |= HAS_POWER;
1486 state->tx_tuna[4] = 0x01;
1487 break;
1488 case SEC_VOLTAGE_OFF:
1489 need_cmd = 1;
1490 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
1491 state->tx_tuna[4] = 0x00;
1492 break;
1493 default:
1494 return -EINVAL;
1495 }
1496
1497 if (need_cmd)
1498 retval = dst_tone_power_cmd(state);
1499
1500 return retval;
1501}
1502
1503static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
1504{
1505 struct dst_state *state = fe->demodulator_priv;
1506
1507 state->tone = tone;
1508 if (state->dst_type != DST_TYPE_IS_SAT)
1509 return -EOPNOTSUPP;
1510
1511 switch (tone) {
1512 case SEC_TONE_OFF:
1513 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1514 state->tx_tuna[2] = 0x00;
1515 else
1516 state->tx_tuna[2] = 0xff;
1517 break;
1518
1519 case SEC_TONE_ON:
1520 state->tx_tuna[2] = 0x02;
1521 break;
1522 default:
1523 return -EINVAL;
1524 }
1525 return dst_tone_power_cmd(state);
1526}
1527
1528static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
1529{
1530 struct dst_state *state = fe->demodulator_priv;
1531
1532 if (state->dst_type != DST_TYPE_IS_SAT)
1533 return -EOPNOTSUPP;
1534 state->minicmd = minicmd;
1535 switch (minicmd) {
1536 case SEC_MINI_A:
1537 state->tx_tuna[3] = 0x02;
1538 break;
1539 case SEC_MINI_B:
1540 state->tx_tuna[3] = 0xff;
1541 break;
1542 }
1543 return dst_tone_power_cmd(state);
1544}
1545
1546
1547static int dst_init(struct dvb_frontend *fe)
1548{
1549 struct dst_state *state = fe->demodulator_priv;
1550
1551 static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 };
1552 static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 };
1553 static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1554 static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1555 static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1556 static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1557 static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1558
1559 state->inversion = INVERSION_OFF;
1560 state->voltage = SEC_VOLTAGE_13;
1561 state->tone = SEC_TONE_OFF;
1562 state->diseq_flags = 0;
1563 state->k22 = 0x02;
1564 state->bandwidth = 7000000;
1565 state->cur_jiff = jiffies;
1566 if (state->dst_type == DST_TYPE_IS_SAT)
1567 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204));
1568 else if (state->dst_type == DST_TYPE_IS_TERR)
1569 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204));
1570 else if (state->dst_type == DST_TYPE_IS_CABLE)
1571 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204));
1572 else if (state->dst_type == DST_TYPE_IS_ATSC)
1573 memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner));
1574
1575 return 0;
1576}
1577
1578static int dst_read_status(struct dvb_frontend *fe, fe_status_t *status)
1579{
1580 struct dst_state *state = fe->demodulator_priv;
1581
1582 *status = 0;
1583 if (state->diseq_flags & HAS_LOCK) {
1584
1585 if (state->decode_lock)
1586 *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI;
1587 }
1588
1589 return 0;
1590}
1591
1592static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1593{
1594 struct dst_state *state = fe->demodulator_priv;
1595
1596 int retval = dst_get_signal(state);
1597 *strength = state->decode_strength;
1598
1599 return retval;
1600}
1601
1602static int dst_read_snr(struct dvb_frontend *fe, u16 *snr)
1603{
1604 struct dst_state *state = fe->demodulator_priv;
1605
1606 int retval = dst_get_signal(state);
1607 *snr = state->decode_snr;
1608
1609 return retval;
1610}
1611
1612static int dst_set_frontend(struct dvb_frontend *fe)
1613{
1614 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1615 int retval = -EINVAL;
1616 struct dst_state *state = fe->demodulator_priv;
1617
1618 if (p != NULL) {
1619 retval = dst_set_freq(state, p->frequency);
1620 if(retval != 0)
1621 return retval;
1622 dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
1623
1624 if (state->dst_type == DST_TYPE_IS_SAT) {
1625 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1626 dst_set_inversion(state, p->inversion);
1627 dst_set_fec(state, p->fec_inner);
1628 dst_set_symbolrate(state, p->symbol_rate);
1629 dst_set_polarization(state);
1630 dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->symbol_rate);
1631
1632 } else if (state->dst_type == DST_TYPE_IS_TERR)
1633 dst_set_bandwidth(state, p->bandwidth_hz);
1634 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1635 dst_set_fec(state, p->fec_inner);
1636 dst_set_symbolrate(state, p->symbol_rate);
1637 dst_set_modulation(state, p->modulation);
1638 }
1639 retval = dst_write_tuna(fe);
1640 }
1641
1642 return retval;
1643}
1644
1645static int dst_tune_frontend(struct dvb_frontend* fe,
1646 bool re_tune,
1647 unsigned int mode_flags,
1648 unsigned int *delay,
1649 fe_status_t *status)
1650{
1651 struct dst_state *state = fe->demodulator_priv;
1652 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1653
1654 if (re_tune) {
1655 dst_set_freq(state, p->frequency);
1656 dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
1657
1658 if (state->dst_type == DST_TYPE_IS_SAT) {
1659 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1660 dst_set_inversion(state, p->inversion);
1661 dst_set_fec(state, p->fec_inner);
1662 dst_set_symbolrate(state, p->symbol_rate);
1663 dst_set_polarization(state);
1664 dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->symbol_rate);
1665
1666 } else if (state->dst_type == DST_TYPE_IS_TERR)
1667 dst_set_bandwidth(state, p->bandwidth_hz);
1668 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1669 dst_set_fec(state, p->fec_inner);
1670 dst_set_symbolrate(state, p->symbol_rate);
1671 dst_set_modulation(state, p->modulation);
1672 }
1673 dst_write_tuna(fe);
1674 }
1675
1676 if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
1677 dst_read_status(fe, status);
1678
1679 *delay = HZ/10;
1680 return 0;
1681}
1682
1683static int dst_get_tuning_algo(struct dvb_frontend *fe)
1684{
1685 return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW;
1686}
1687
1688static int dst_get_frontend(struct dvb_frontend *fe)
1689{
1690 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1691 struct dst_state *state = fe->demodulator_priv;
1692
1693 p->frequency = state->decode_freq;
1694 if (state->dst_type == DST_TYPE_IS_SAT) {
1695 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1696 p->inversion = state->inversion;
1697 p->symbol_rate = state->symbol_rate;
1698 p->fec_inner = dst_get_fec(state);
1699 } else if (state->dst_type == DST_TYPE_IS_TERR) {
1700 p->bandwidth_hz = state->bandwidth;
1701 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
1702 p->symbol_rate = state->symbol_rate;
1703 p->fec_inner = dst_get_fec(state);
1704 p->modulation = dst_get_modulation(state);
1705 }
1706
1707 return 0;
1708}
1709
1710static void dst_release(struct dvb_frontend *fe)
1711{
1712 struct dst_state *state = fe->demodulator_priv;
1713 if (state->dst_ca) {
1714 dvb_unregister_device(state->dst_ca);
1715#ifdef CONFIG_MEDIA_ATTACH
1716 symbol_put(dst_ca_attach);
1717#endif
1718 }
1719 kfree(state);
1720}
1721
1722static struct dvb_frontend_ops dst_dvbt_ops;
1723static struct dvb_frontend_ops dst_dvbs_ops;
1724static struct dvb_frontend_ops dst_dvbc_ops;
1725static struct dvb_frontend_ops dst_atsc_ops;
1726
1727struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
1728{
1729
1730 if (dst_probe(state) < 0) {
1731 kfree(state);
1732 return NULL;
1733 }
1734
1735
1736 switch (state->dst_type) {
1737 case DST_TYPE_IS_TERR:
1738 memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
1739 break;
1740 case DST_TYPE_IS_CABLE:
1741 memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
1742 break;
1743 case DST_TYPE_IS_SAT:
1744 memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
1745 break;
1746 case DST_TYPE_IS_ATSC:
1747 memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops));
1748 break;
1749 default:
1750 dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist.");
1751 kfree(state);
1752 return NULL;
1753 }
1754 state->frontend.demodulator_priv = state;
1755
1756 return state;
1757}
1758
1759EXPORT_SYMBOL(dst_attach);
1760
1761static struct dvb_frontend_ops dst_dvbt_ops = {
1762 .delsys = { SYS_DVBT },
1763 .info = {
1764 .name = "DST DVB-T",
1765 .frequency_min = 137000000,
1766 .frequency_max = 858000000,
1767 .frequency_stepsize = 166667,
1768 .caps = FE_CAN_FEC_AUTO |
1769 FE_CAN_QAM_AUTO |
1770 FE_CAN_QAM_16 |
1771 FE_CAN_QAM_32 |
1772 FE_CAN_QAM_64 |
1773 FE_CAN_QAM_128 |
1774 FE_CAN_QAM_256 |
1775 FE_CAN_TRANSMISSION_MODE_AUTO |
1776 FE_CAN_GUARD_INTERVAL_AUTO
1777 },
1778
1779 .release = dst_release,
1780 .init = dst_init,
1781 .tune = dst_tune_frontend,
1782 .set_frontend = dst_set_frontend,
1783 .get_frontend = dst_get_frontend,
1784 .get_frontend_algo = dst_get_tuning_algo,
1785 .read_status = dst_read_status,
1786 .read_signal_strength = dst_read_signal_strength,
1787 .read_snr = dst_read_snr,
1788};
1789
1790static struct dvb_frontend_ops dst_dvbs_ops = {
1791 .delsys = { SYS_DVBS },
1792 .info = {
1793 .name = "DST DVB-S",
1794 .frequency_min = 950000,
1795 .frequency_max = 2150000,
1796 .frequency_stepsize = 1000,
1797 .frequency_tolerance = 29500,
1798 .symbol_rate_min = 1000000,
1799 .symbol_rate_max = 45000000,
1800
1801 .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
1802 },
1803
1804 .release = dst_release,
1805 .init = dst_init,
1806 .tune = dst_tune_frontend,
1807 .set_frontend = dst_set_frontend,
1808 .get_frontend = dst_get_frontend,
1809 .get_frontend_algo = dst_get_tuning_algo,
1810 .read_status = dst_read_status,
1811 .read_signal_strength = dst_read_signal_strength,
1812 .read_snr = dst_read_snr,
1813 .diseqc_send_burst = dst_send_burst,
1814 .diseqc_send_master_cmd = dst_set_diseqc,
1815 .set_voltage = dst_set_voltage,
1816 .set_tone = dst_set_tone,
1817};
1818
1819static struct dvb_frontend_ops dst_dvbc_ops = {
1820 .delsys = { SYS_DVBC_ANNEX_A },
1821 .info = {
1822 .name = "DST DVB-C",
1823 .frequency_stepsize = 62500,
1824 .frequency_min = 51000000,
1825 .frequency_max = 858000000,
1826 .symbol_rate_min = 1000000,
1827 .symbol_rate_max = 45000000,
1828 .caps = FE_CAN_FEC_AUTO |
1829 FE_CAN_QAM_AUTO |
1830 FE_CAN_QAM_16 |
1831 FE_CAN_QAM_32 |
1832 FE_CAN_QAM_64 |
1833 FE_CAN_QAM_128 |
1834 FE_CAN_QAM_256
1835 },
1836
1837 .release = dst_release,
1838 .init = 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
1848static struct dvb_frontend_ops dst_atsc_ops = {
1849 .delsys = { SYS_ATSC },
1850 .info = {
1851 .name = "DST ATSC",
1852 .frequency_stepsize = 62500,
1853 .frequency_min = 510000000,
1854 .frequency_max = 858000000,
1855 .symbol_rate_min = 1000000,
1856 .symbol_rate_max = 45000000,
1857 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
1858 },
1859
1860 .release = dst_release,
1861 .init = dst_init,
1862 .tune = dst_tune_frontend,
1863 .set_frontend = dst_set_frontend,
1864 .get_frontend = dst_get_frontend,
1865 .get_frontend_algo = dst_get_tuning_algo,
1866 .read_status = dst_read_status,
1867 .read_signal_strength = dst_read_signal_strength,
1868 .read_snr = dst_read_snr,
1869};
1870
1871MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver");
1872MODULE_AUTHOR("Jamie Honan, Manu Abraham");
1873MODULE_LICENSE("GPL");
1874