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