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