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, fe_bandwidth_t 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 BANDWIDTH_6_MHZ:
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 BANDWIDTH_7_MHZ:
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 BANDWIDTH_8_MHZ:
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 memset(&state->fw_version, '\0', 8);
934 memcpy(&state->fw_version, &state->rxbuffer, 8);
935 dprintk(verbose, DST_ERROR, 1, "Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x",
936 state->fw_version[0] >> 4, state->fw_version[0] & 0x0f,
937 state->fw_version[1],
938 state->fw_version[5], state->fw_version[6],
939 state->fw_version[4], state->fw_version[3], state->fw_version[2]);
940
941 return 0;
942}
943
944static int dst_card_type(struct dst_state *state)
945{
946 int j;
947 struct tuner_types *p_tuner_list = NULL;
948
949 u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
950 get_type[7] = dst_check_sum(get_type, 7);
951 if (dst_command(state, get_type, 8) < 0) {
952 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
953 return -1;
954 }
955 memset(&state->card_info, '\0', 8);
956 memcpy(&state->card_info, &state->rxbuffer, 7);
957 dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]);
958
959 for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
960 if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) {
961 state->tuner_type = p_tuner_list->tuner_type;
962 dprintk(verbose, DST_ERROR, 1, "DST has [%s] tuner, tuner type=[%d]",
963 p_tuner_list->tuner_name, p_tuner_list->tuner_type);
964 }
965 }
966
967 return 0;
968}
969
970static int dst_get_vendor(struct dst_state *state)
971{
972 u8 get_vendor[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
973 get_vendor[7] = dst_check_sum(get_vendor, 7);
974 if (dst_command(state, get_vendor, 8) < 0) {
975 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
976 return -1;
977 }
978 memset(&state->vendor, '\0', 8);
979 memcpy(&state->vendor, &state->rxbuffer, 7);
980 dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]);
981
982 return 0;
983}
984
985static void debug_dst_buffer(struct dst_state *state)
986{
987 int i;
988
989 if (verbose > 2) {
990 printk("%s: [", __func__);
991 for (i = 0; i < 8; i++)
992 printk(" %02x", state->rxbuffer[i]);
993 printk("]\n");
994 }
995}
996
997static int dst_check_stv0299(struct dst_state *state)
998{
999 u8 check_stv0299[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1000
1001 check_stv0299[7] = dst_check_sum(check_stv0299, 7);
1002 if (dst_command(state, check_stv0299, 8) < 0) {
1003 dprintk(verbose, DST_ERROR, 1, "Cmd=[0x04] failed");
1004 return -1;
1005 }
1006 debug_dst_buffer(state);
1007
1008 if (memcmp(&check_stv0299, &state->rxbuffer, 8)) {
1009 dprintk(verbose, DST_ERROR, 1, "Found a STV0299 NIM");
1010 state->tuner_type = TUNER_TYPE_STV0299;
1011 return 0;
1012 }
1013
1014 return -1;
1015}
1016
1017static int dst_check_mb86a15(struct dst_state *state)
1018{
1019 u8 check_mb86a15[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1020
1021 check_mb86a15[7] = dst_check_sum(check_mb86a15, 7);
1022 if (dst_command(state, check_mb86a15, 8) < 0) {
1023 dprintk(verbose, DST_ERROR, 1, "Cmd=[0x10], failed");
1024 return -1;
1025 }
1026 debug_dst_buffer(state);
1027
1028 if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) {
1029 dprintk(verbose, DST_ERROR, 1, "Found a MB86A15 NIM");
1030 state->tuner_type = TUNER_TYPE_MB86A15;
1031 return 0;
1032 }
1033
1034 return -1;
1035}
1036
1037static int dst_get_tuner_info(struct dst_state *state)
1038{
1039 u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1040 u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1041
1042 get_tuner_1[7] = dst_check_sum(get_tuner_1, 7);
1043 get_tuner_2[7] = dst_check_sum(get_tuner_2, 7);
1044 dprintk(verbose, DST_ERROR, 1, "DST TYpe = MULTI FE");
1045 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
1046 if (dst_command(state, get_tuner_1, 8) < 0) {
1047 dprintk(verbose, DST_INFO, 1, "Cmd=[0x13], Unsupported");
1048 goto force;
1049 }
1050 } else {
1051 if (dst_command(state, get_tuner_2, 8) < 0) {
1052 dprintk(verbose, DST_INFO, 1, "Cmd=[0xb], Unsupported");
1053 goto force;
1054 }
1055 }
1056 memset(&state->board_info, '\0', 8);
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_CABLE) &&
1356 !(state->dst_type == DST_TYPE_IS_ATSC)) {
1357
1358 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
1359 dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
1360 return -EIO;
1361 }
1362 } else {
1363 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
1364 dprintk(verbose, DST_INFO, 1, "checksum failure? ");
1365 return -EIO;
1366 }
1367 }
1368 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
1369 return 0;
1370 if (state->dst_type == DST_TYPE_IS_SAT) {
1371 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
1372 } else {
1373 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];
1374 }
1375 state->decode_freq = state->decode_freq * 1000;
1376 state->decode_lock = 1;
1377 state->diseq_flags |= HAS_LOCK;
1378
1379 return 1;
1380}
1381
1382static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t 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, fe_sec_voltage_t 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, fe_sec_tone_mode_t 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, fe_sec_mini_cmd_t 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 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 = BANDWIDTH_7_MHZ;
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, fe_status_t *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, struct dvb_frontend_parameters *p)
1616{
1617 int retval = -EINVAL;
1618 struct dst_state *state = fe->demodulator_priv;
1619
1620 if (p != NULL) {
1621 retval = dst_set_freq(state, p->frequency);
1622 if(retval != 0)
1623 return retval;
1624 dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
1625
1626 if (state->dst_type == DST_TYPE_IS_SAT) {
1627 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1628 dst_set_inversion(state, p->inversion);
1629 dst_set_fec(state, p->u.qpsk.fec_inner);
1630 dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
1631 dst_set_polarization(state);
1632 dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate);
1633
1634 } else if (state->dst_type == DST_TYPE_IS_TERR)
1635 dst_set_bandwidth(state, p->u.ofdm.bandwidth);
1636 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1637 dst_set_fec(state, p->u.qam.fec_inner);
1638 dst_set_symbolrate(state, p->u.qam.symbol_rate);
1639 dst_set_modulation(state, p->u.qam.modulation);
1640 }
1641 retval = dst_write_tuna(fe);
1642 }
1643
1644 return retval;
1645}
1646
1647static int dst_tune_frontend(struct dvb_frontend* fe,
1648 struct dvb_frontend_parameters* p,
1649 unsigned int mode_flags,
1650 unsigned int *delay,
1651 fe_status_t *status)
1652{
1653 struct dst_state *state = fe->demodulator_priv;
1654
1655 if (p != NULL) {
1656 dst_set_freq(state, p->frequency);
1657 dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
1658
1659 if (state->dst_type == DST_TYPE_IS_SAT) {
1660 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1661 dst_set_inversion(state, p->inversion);
1662 dst_set_fec(state, p->u.qpsk.fec_inner);
1663 dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
1664 dst_set_polarization(state);
1665 dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate);
1666
1667 } else if (state->dst_type == DST_TYPE_IS_TERR)
1668 dst_set_bandwidth(state, p->u.ofdm.bandwidth);
1669 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1670 dst_set_fec(state, p->u.qam.fec_inner);
1671 dst_set_symbolrate(state, p->u.qam.symbol_rate);
1672 dst_set_modulation(state, p->u.qam.modulation);
1673 }
1674 dst_write_tuna(fe);
1675 }
1676
1677 if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
1678 dst_read_status(fe, status);
1679
1680 *delay = HZ/10;
1681 return 0;
1682}
1683
1684static int dst_get_tuning_algo(struct dvb_frontend *fe)
1685{
1686 return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW;
1687}
1688
1689static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
1690{
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->u.qpsk.symbol_rate = state->symbol_rate;
1698 p->u.qpsk.fec_inner = dst_get_fec(state);
1699 } else if (state->dst_type == DST_TYPE_IS_TERR) {
1700 p->u.ofdm.bandwidth = state->bandwidth;
1701 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
1702 p->u.qam.symbol_rate = state->symbol_rate;
1703 p->u.qam.fec_inner = dst_get_fec(state);
1704 p->u.qam.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
1763 .info = {
1764 .name = "DST DVB-T",
1765 .type = FE_OFDM,
1766 .frequency_min = 137000000,
1767 .frequency_max = 858000000,
1768 .frequency_stepsize = 166667,
1769 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
1770 },
1771
1772 .release = dst_release,
1773 .init = dst_init,
1774 .tune = dst_tune_frontend,
1775 .set_frontend = dst_set_frontend,
1776 .get_frontend = dst_get_frontend,
1777 .get_frontend_algo = dst_get_tuning_algo,
1778 .read_status = dst_read_status,
1779 .read_signal_strength = dst_read_signal_strength,
1780 .read_snr = dst_read_snr,
1781};
1782
1783static struct dvb_frontend_ops dst_dvbs_ops = {
1784
1785 .info = {
1786 .name = "DST DVB-S",
1787 .type = FE_QPSK,
1788 .frequency_min = 950000,
1789 .frequency_max = 2150000,
1790 .frequency_stepsize = 1000,
1791 .frequency_tolerance = 29500,
1792 .symbol_rate_min = 1000000,
1793 .symbol_rate_max = 45000000,
1794
1795 .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
1796 },
1797
1798 .release = dst_release,
1799 .init = dst_init,
1800 .tune = dst_tune_frontend,
1801 .set_frontend = dst_set_frontend,
1802 .get_frontend = dst_get_frontend,
1803 .get_frontend_algo = dst_get_tuning_algo,
1804 .read_status = dst_read_status,
1805 .read_signal_strength = dst_read_signal_strength,
1806 .read_snr = dst_read_snr,
1807 .diseqc_send_burst = dst_send_burst,
1808 .diseqc_send_master_cmd = dst_set_diseqc,
1809 .set_voltage = dst_set_voltage,
1810 .set_tone = dst_set_tone,
1811};
1812
1813static struct dvb_frontend_ops dst_dvbc_ops = {
1814
1815 .info = {
1816 .name = "DST DVB-C",
1817 .type = FE_QAM,
1818 .frequency_stepsize = 62500,
1819 .frequency_min = 51000000,
1820 .frequency_max = 858000000,
1821 .symbol_rate_min = 1000000,
1822 .symbol_rate_max = 45000000,
1823
1824 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO
1825 },
1826
1827 .release = dst_release,
1828 .init = dst_init,
1829 .tune = dst_tune_frontend,
1830 .set_frontend = dst_set_frontend,
1831 .get_frontend = dst_get_frontend,
1832 .get_frontend_algo = dst_get_tuning_algo,
1833 .read_status = dst_read_status,
1834 .read_signal_strength = dst_read_signal_strength,
1835 .read_snr = dst_read_snr,
1836};
1837
1838static struct dvb_frontend_ops dst_atsc_ops = {
1839 .info = {
1840 .name = "DST ATSC",
1841 .type = FE_ATSC,
1842 .frequency_stepsize = 62500,
1843 .frequency_min = 510000000,
1844 .frequency_max = 858000000,
1845 .symbol_rate_min = 1000000,
1846 .symbol_rate_max = 45000000,
1847 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
1848 },
1849
1850 .release = dst_release,
1851 .init = dst_init,
1852 .tune = dst_tune_frontend,
1853 .set_frontend = dst_set_frontend,
1854 .get_frontend = dst_get_frontend,
1855 .get_frontend_algo = dst_get_tuning_algo,
1856 .read_status = dst_read_status,
1857 .read_signal_strength = dst_read_signal_strength,
1858 .read_snr = dst_read_snr,
1859};
1860
1861MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver");
1862MODULE_AUTHOR("Jamie Honan, Manu Abraham");
1863MODULE_LICENSE("GPL");
1864