xref: /openbmc/linux/drivers/media/pci/bt8xx/dst.c (revision 6e6c61d3)
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 			strncpy(&state->fw_name[0], p_dst_type->device_id, 6);
1104 			/*	Multiple tuners		*/
1105 			if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) {
1106 				switch (use_dst_type) {
1107 				case DST_TYPE_IS_SAT:
1108 					/*	STV0299 check	*/
1109 					if (dst_check_stv0299(state) < 0) {
1110 						pr_err("Unsupported\n");
1111 						state->tuner_type = TUNER_TYPE_MB86A15;
1112 					}
1113 					break;
1114 				default:
1115 					break;
1116 				}
1117 				if (dst_check_mb86a15(state) < 0)
1118 					pr_err("Unsupported\n");
1119 			/*	Single tuner		*/
1120 			} else {
1121 				state->tuner_type = p_dst_type->tuner_type;
1122 			}
1123 			for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
1124 				if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) &&
1125 					p_tuner_list->tuner_type == state->tuner_type) {
1126 					pr_err("[%s] has a [%s]\n",
1127 						p_dst_type->device_id, p_tuner_list->tuner_name);
1128 				}
1129 			}
1130 			break;
1131 		}
1132 	}
1133 
1134 	if (i >= ARRAY_SIZE(dst_tlist)) {
1135 		pr_err("Unable to recognize %s or %s\n", &state->rxbuffer[0], &state->rxbuffer[1]);
1136 		pr_err("please email linux-dvb@linuxtv.org with this type in");
1137 		use_dst_type = DST_TYPE_IS_SAT;
1138 		use_type_flags = DST_TYPE_HAS_SYMDIV;
1139 	}
1140 	dst_type_print(state, use_dst_type);
1141 	state->type_flags = use_type_flags;
1142 	state->dst_type = use_dst_type;
1143 	dst_type_flags_print(state);
1144 
1145 	return 0;
1146 }
1147 
1148 static int dst_probe(struct dst_state *state)
1149 {
1150 	mutex_init(&state->dst_mutex);
1151 	if (dst_addons & DST_TYPE_HAS_CA) {
1152 		if ((rdc_8820_reset(state)) < 0) {
1153 			pr_err("RDC 8820 RESET Failed.\n");
1154 			return -1;
1155 		}
1156 		msleep(4000);
1157 	} else {
1158 		msleep(100);
1159 	}
1160 	if ((dst_comm_init(state)) < 0) {
1161 		pr_err("DST Initialization Failed.\n");
1162 		return -1;
1163 	}
1164 	msleep(100);
1165 	if (dst_get_device_id(state) < 0) {
1166 		pr_err("unknown device.\n");
1167 		return -1;
1168 	}
1169 	if (dst_get_mac(state) < 0) {
1170 		dprintk(2, "MAC: Unsupported command\n");
1171 	}
1172 	if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {
1173 		if (dst_get_tuner_info(state) < 0)
1174 			dprintk(2, "Tuner: Unsupported command\n");
1175 	}
1176 	if (state->type_flags & DST_TYPE_HAS_TS204) {
1177 		dst_packsize(state, 204);
1178 	}
1179 	if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
1180 		if (dst_fw_ver(state) < 0) {
1181 			dprintk(2, "FW: Unsupported command\n");
1182 			return 0;
1183 		}
1184 		if (dst_card_type(state) < 0) {
1185 			dprintk(2, "Card: Unsupported command\n");
1186 			return 0;
1187 		}
1188 		if (dst_get_vendor(state) < 0) {
1189 			dprintk(2, "Vendor: Unsupported command\n");
1190 			return 0;
1191 		}
1192 	}
1193 
1194 	return 0;
1195 }
1196 
1197 static int dst_command(struct dst_state *state, u8 *data, u8 len)
1198 {
1199 	u8 reply;
1200 
1201 	mutex_lock(&state->dst_mutex);
1202 	if ((dst_comm_init(state)) < 0) {
1203 		dprintk(1, "DST Communication Initialization Failed.\n");
1204 		goto error;
1205 	}
1206 	if (write_dst(state, data, len)) {
1207 		dprintk(2, "Trying to recover..\n");
1208 		if ((dst_error_recovery(state)) < 0) {
1209 			pr_err("Recovery Failed.\n");
1210 			goto error;
1211 		}
1212 		goto error;
1213 	}
1214 	if ((dst_pio_disable(state)) < 0) {
1215 		pr_err("PIO Disable Failed.\n");
1216 		goto error;
1217 	}
1218 	if (state->type_flags & DST_TYPE_HAS_FW_1)
1219 		mdelay(3);
1220 	if (read_dst(state, &reply, GET_ACK)) {
1221 		dprintk(3, "Trying to recover..\n");
1222 		if ((dst_error_recovery(state)) < 0) {
1223 			dprintk(2, "Recovery Failed.\n");
1224 			goto error;
1225 		}
1226 		goto error;
1227 	}
1228 	if (reply != ACK) {
1229 		dprintk(2, "write not acknowledged 0x%02x\n", reply);
1230 		goto error;
1231 	}
1232 	if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
1233 		goto error;
1234 	if (state->type_flags & DST_TYPE_HAS_FW_1)
1235 		mdelay(3);
1236 	else
1237 		udelay(2000);
1238 	if (!dst_wait_dst_ready(state, NO_DELAY))
1239 		goto error;
1240 	if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
1241 		dprintk(3, "Trying to recover..\n");
1242 		if ((dst_error_recovery(state)) < 0) {
1243 			dprintk(2, "Recovery failed.\n");
1244 			goto error;
1245 		}
1246 		goto error;
1247 	}
1248 	if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
1249 		dprintk(2, "checksum failure\n");
1250 		goto error;
1251 	}
1252 	mutex_unlock(&state->dst_mutex);
1253 	return 0;
1254 
1255 error:
1256 	mutex_unlock(&state->dst_mutex);
1257 	return -EIO;
1258 
1259 }
1260 
1261 static int dst_get_signal(struct dst_state *state)
1262 {
1263 	int retval;
1264 	u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
1265 	//dprintk("%s: Getting Signal strength and other parameters\n", __func__);
1266 	if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
1267 		state->decode_lock = state->decode_strength = state->decode_snr = 0;
1268 		return 0;
1269 	}
1270 	if (0 == (state->diseq_flags & HAS_LOCK)) {
1271 		state->decode_lock = state->decode_strength = state->decode_snr = 0;
1272 		return 0;
1273 	}
1274 	if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) {
1275 		retval = dst_command(state, get_signal, 8);
1276 		if (retval < 0)
1277 			return retval;
1278 		if (state->dst_type == DST_TYPE_IS_SAT) {
1279 			state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0;
1280 			state->decode_strength = state->rxbuffer[5] << 8;
1281 			state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
1282 		} else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) {
1283 			state->decode_lock = (state->rxbuffer[1]) ? 1 : 0;
1284 			state->decode_strength = state->rxbuffer[4] << 8;
1285 			state->decode_snr = state->rxbuffer[3] << 8;
1286 		} else if (state->dst_type == DST_TYPE_IS_ATSC) {
1287 			state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0;
1288 			state->decode_strength = state->rxbuffer[4] << 8;
1289 			state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
1290 		}
1291 		state->cur_jiff = jiffies;
1292 	}
1293 	return 0;
1294 }
1295 
1296 static int dst_tone_power_cmd(struct dst_state *state)
1297 {
1298 	u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
1299 
1300 	if (state->dst_type != DST_TYPE_IS_SAT)
1301 		return -EOPNOTSUPP;
1302 	paket[4] = state->tx_tuna[4];
1303 	paket[2] = state->tx_tuna[2];
1304 	paket[3] = state->tx_tuna[3];
1305 	paket[7] = dst_check_sum (paket, 7);
1306 	return dst_command(state, paket, 8);
1307 }
1308 
1309 static int dst_get_tuna(struct dst_state *state)
1310 {
1311 	int retval;
1312 
1313 	if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
1314 		return 0;
1315 	state->diseq_flags &= ~(HAS_LOCK);
1316 	if (!dst_wait_dst_ready(state, NO_DELAY))
1317 		return -EIO;
1318 	if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1319 		!(state->dst_type == DST_TYPE_IS_ATSC))
1320 
1321 		retval = read_dst(state, state->rx_tuna, 10);
1322 	else
1323 		retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
1324 	if (retval < 0) {
1325 		dprintk(3, "read not successful\n");
1326 		return retval;
1327 	}
1328 	if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1329 	   !(state->dst_type == DST_TYPE_IS_ATSC)) {
1330 
1331 		if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
1332 			dprintk(2, "checksum failure ?\n");
1333 			return -EIO;
1334 		}
1335 	} else {
1336 		if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
1337 			dprintk(2, "checksum failure?\n");
1338 			return -EIO;
1339 		}
1340 	}
1341 	if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
1342 		return 0;
1343 	if (state->dst_type == DST_TYPE_IS_SAT) {
1344 		state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
1345 	} else {
1346 		state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];
1347 	}
1348 	state->decode_freq = state->decode_freq * 1000;
1349 	state->decode_lock = 1;
1350 	state->diseq_flags |= HAS_LOCK;
1351 
1352 	return 1;
1353 }
1354 
1355 static int dst_set_voltage(struct dvb_frontend *fe,
1356 			   enum fe_sec_voltage voltage);
1357 
1358 static int dst_write_tuna(struct dvb_frontend *fe)
1359 {
1360 	struct dst_state *state = fe->demodulator_priv;
1361 	int retval;
1362 	u8 reply;
1363 
1364 	dprintk(2, "type_flags 0x%x\n", state->type_flags);
1365 	state->decode_freq = 0;
1366 	state->decode_lock = state->decode_strength = state->decode_snr = 0;
1367 	if (state->dst_type == DST_TYPE_IS_SAT) {
1368 		if (!(state->diseq_flags & HAS_POWER))
1369 			dst_set_voltage(fe, SEC_VOLTAGE_13);
1370 	}
1371 	state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
1372 	mutex_lock(&state->dst_mutex);
1373 	if ((dst_comm_init(state)) < 0) {
1374 		dprintk(3, "DST Communication initialization failed.\n");
1375 		goto error;
1376 	}
1377 //	if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
1378 	if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1379 		(!(state->dst_type == DST_TYPE_IS_ATSC))) {
1380 
1381 		state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
1382 		retval = write_dst(state, &state->tx_tuna[0], 10);
1383 	} else {
1384 		state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
1385 		retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
1386 	}
1387 	if (retval < 0) {
1388 		dst_pio_disable(state);
1389 		dprintk(3, "write not successful\n");
1390 		goto werr;
1391 	}
1392 	if ((dst_pio_disable(state)) < 0) {
1393 		dprintk(3, "DST PIO disable failed !\n");
1394 		goto error;
1395 	}
1396 	if ((read_dst(state, &reply, GET_ACK) < 0)) {
1397 		dprintk(3, "read verify not successful.\n");
1398 		goto error;
1399 	}
1400 	if (reply != ACK) {
1401 		dprintk(3, "write not acknowledged 0x%02x\n", reply);
1402 		goto error;
1403 	}
1404 	state->diseq_flags |= ATTEMPT_TUNE;
1405 	retval = dst_get_tuna(state);
1406 werr:
1407 	mutex_unlock(&state->dst_mutex);
1408 	return retval;
1409 
1410 error:
1411 	mutex_unlock(&state->dst_mutex);
1412 	return -EIO;
1413 }
1414 
1415 /*
1416  * line22k0    0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00
1417  * line22k1    0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00
1418  * line22k2    0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00
1419  * tone        0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00
1420  * data        0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00
1421  * power_off   0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
1422  * power_on    0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00
1423  * Diseqc 1    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec
1424  * Diseqc 2    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8
1425  * Diseqc 3    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4
1426  * Diseqc 4    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0
1427  */
1428 
1429 static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
1430 {
1431 	struct dst_state *state = fe->demodulator_priv;
1432 	u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
1433 
1434 	if (state->dst_type != DST_TYPE_IS_SAT)
1435 		return -EOPNOTSUPP;
1436 	if (cmd->msg_len > 0 && cmd->msg_len < 5)
1437 		memcpy(&paket[3], cmd->msg, cmd->msg_len);
1438 	else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5)
1439 		memcpy(&paket[2], cmd->msg, cmd->msg_len);
1440 	else
1441 		return -EINVAL;
1442 	paket[7] = dst_check_sum(&paket[0], 7);
1443 	return dst_command(state, paket, 8);
1444 }
1445 
1446 static int dst_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage)
1447 {
1448 	int need_cmd, retval = 0;
1449 	struct dst_state *state = fe->demodulator_priv;
1450 
1451 	state->voltage = voltage;
1452 	if (state->dst_type != DST_TYPE_IS_SAT)
1453 		return -EOPNOTSUPP;
1454 
1455 	need_cmd = 0;
1456 
1457 	switch (voltage) {
1458 	case SEC_VOLTAGE_13:
1459 	case SEC_VOLTAGE_18:
1460 		if ((state->diseq_flags & HAS_POWER) == 0)
1461 			need_cmd = 1;
1462 		state->diseq_flags |= HAS_POWER;
1463 		state->tx_tuna[4] = 0x01;
1464 		break;
1465 	case SEC_VOLTAGE_OFF:
1466 		need_cmd = 1;
1467 		state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
1468 		state->tx_tuna[4] = 0x00;
1469 		break;
1470 	default:
1471 		return -EINVAL;
1472 	}
1473 
1474 	if (need_cmd)
1475 		retval = dst_tone_power_cmd(state);
1476 
1477 	return retval;
1478 }
1479 
1480 static int dst_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
1481 {
1482 	struct dst_state *state = fe->demodulator_priv;
1483 
1484 	state->tone = tone;
1485 	if (state->dst_type != DST_TYPE_IS_SAT)
1486 		return -EOPNOTSUPP;
1487 
1488 	switch (tone) {
1489 	case SEC_TONE_OFF:
1490 		if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1491 		    state->tx_tuna[2] = 0x00;
1492 		else
1493 		    state->tx_tuna[2] = 0xff;
1494 		break;
1495 
1496 	case SEC_TONE_ON:
1497 		state->tx_tuna[2] = 0x02;
1498 		break;
1499 	default:
1500 		return -EINVAL;
1501 	}
1502 	return dst_tone_power_cmd(state);
1503 }
1504 
1505 static int dst_send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd minicmd)
1506 {
1507 	struct dst_state *state = fe->demodulator_priv;
1508 
1509 	if (state->dst_type != DST_TYPE_IS_SAT)
1510 		return -EOPNOTSUPP;
1511 	state->minicmd = minicmd;
1512 	switch (minicmd) {
1513 	case SEC_MINI_A:
1514 		state->tx_tuna[3] = 0x02;
1515 		break;
1516 	case SEC_MINI_B:
1517 		state->tx_tuna[3] = 0xff;
1518 		break;
1519 	}
1520 	return dst_tone_power_cmd(state);
1521 }
1522 
1523 
1524 static int bt8xx_dst_init(struct dvb_frontend *fe)
1525 {
1526 	struct dst_state *state = fe->demodulator_priv;
1527 
1528 	static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 };
1529 	static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 };
1530 	static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1531 	static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1532 	static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1533 	static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1534 	static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1535 
1536 	state->inversion = INVERSION_OFF;
1537 	state->voltage = SEC_VOLTAGE_13;
1538 	state->tone = SEC_TONE_OFF;
1539 	state->diseq_flags = 0;
1540 	state->k22 = 0x02;
1541 	state->bandwidth = 7000000;
1542 	state->cur_jiff = jiffies;
1543 	if (state->dst_type == DST_TYPE_IS_SAT)
1544 		memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204));
1545 	else if (state->dst_type == DST_TYPE_IS_TERR)
1546 		memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204));
1547 	else if (state->dst_type == DST_TYPE_IS_CABLE)
1548 		memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204));
1549 	else if (state->dst_type == DST_TYPE_IS_ATSC)
1550 		memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner));
1551 
1552 	return 0;
1553 }
1554 
1555 static int dst_read_status(struct dvb_frontend *fe, enum fe_status *status)
1556 {
1557 	struct dst_state *state = fe->demodulator_priv;
1558 
1559 	*status = 0;
1560 	if (state->diseq_flags & HAS_LOCK) {
1561 //		dst_get_signal(state);	// don't require(?) to ask MCU
1562 		if (state->decode_lock)
1563 			*status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI;
1564 	}
1565 
1566 	return 0;
1567 }
1568 
1569 static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1570 {
1571 	struct dst_state *state = fe->demodulator_priv;
1572 
1573 	int retval = dst_get_signal(state);
1574 	*strength = state->decode_strength;
1575 
1576 	return retval;
1577 }
1578 
1579 static int dst_read_snr(struct dvb_frontend *fe, u16 *snr)
1580 {
1581 	struct dst_state *state = fe->demodulator_priv;
1582 
1583 	int retval = dst_get_signal(state);
1584 	*snr = state->decode_snr;
1585 
1586 	return retval;
1587 }
1588 
1589 static int dst_set_frontend(struct dvb_frontend *fe)
1590 {
1591 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1592 	int retval = -EINVAL;
1593 	struct dst_state *state = fe->demodulator_priv;
1594 
1595 	if (p != NULL) {
1596 		retval = dst_set_freq(state, p->frequency);
1597 		if(retval != 0)
1598 			return retval;
1599 		dprintk(3, "Set Frequency=[%d]\n", p->frequency);
1600 
1601 		if (state->dst_type == DST_TYPE_IS_SAT) {
1602 			if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1603 				dst_set_inversion(state, p->inversion);
1604 			dst_set_fec(state, p->fec_inner);
1605 			dst_set_symbolrate(state, p->symbol_rate);
1606 			dst_set_polarization(state);
1607 			dprintk(3, "Set Symbolrate=[%d]\n", p->symbol_rate);
1608 
1609 		} else if (state->dst_type == DST_TYPE_IS_TERR)
1610 			dst_set_bandwidth(state, p->bandwidth_hz);
1611 		else if (state->dst_type == DST_TYPE_IS_CABLE) {
1612 			dst_set_fec(state, p->fec_inner);
1613 			dst_set_symbolrate(state, p->symbol_rate);
1614 			dst_set_modulation(state, p->modulation);
1615 		}
1616 		retval = dst_write_tuna(fe);
1617 	}
1618 
1619 	return retval;
1620 }
1621 
1622 static int dst_tune_frontend(struct dvb_frontend* fe,
1623 			    bool re_tune,
1624 			    unsigned int mode_flags,
1625 			    unsigned int *delay,
1626 			    enum fe_status *status)
1627 {
1628 	struct dst_state *state = fe->demodulator_priv;
1629 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1630 
1631 	if (re_tune) {
1632 		dst_set_freq(state, p->frequency);
1633 		dprintk(3, "Set Frequency=[%d]\n", p->frequency);
1634 
1635 		if (state->dst_type == DST_TYPE_IS_SAT) {
1636 			if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1637 				dst_set_inversion(state, p->inversion);
1638 			dst_set_fec(state, p->fec_inner);
1639 			dst_set_symbolrate(state, p->symbol_rate);
1640 			dst_set_polarization(state);
1641 			dprintk(3, "Set Symbolrate=[%d]\n", p->symbol_rate);
1642 
1643 		} else if (state->dst_type == DST_TYPE_IS_TERR)
1644 			dst_set_bandwidth(state, p->bandwidth_hz);
1645 		else if (state->dst_type == DST_TYPE_IS_CABLE) {
1646 			dst_set_fec(state, p->fec_inner);
1647 			dst_set_symbolrate(state, p->symbol_rate);
1648 			dst_set_modulation(state, p->modulation);
1649 		}
1650 		dst_write_tuna(fe);
1651 	}
1652 
1653 	if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
1654 		dst_read_status(fe, status);
1655 
1656 	*delay = HZ/10;
1657 	return 0;
1658 }
1659 
1660 static enum dvbfe_algo dst_get_tuning_algo(struct dvb_frontend *fe)
1661 {
1662 	return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW;
1663 }
1664 
1665 static int dst_get_frontend(struct dvb_frontend *fe,
1666 			    struct dtv_frontend_properties *p)
1667 {
1668 	struct dst_state *state = fe->demodulator_priv;
1669 
1670 	p->frequency = state->decode_freq;
1671 	if (state->dst_type == DST_TYPE_IS_SAT) {
1672 		if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1673 			p->inversion = state->inversion;
1674 		p->symbol_rate = state->symbol_rate;
1675 		p->fec_inner = dst_get_fec(state);
1676 	} else if (state->dst_type == DST_TYPE_IS_TERR) {
1677 		p->bandwidth_hz = state->bandwidth;
1678 	} else if (state->dst_type == DST_TYPE_IS_CABLE) {
1679 		p->symbol_rate = state->symbol_rate;
1680 		p->fec_inner = dst_get_fec(state);
1681 		p->modulation = dst_get_modulation(state);
1682 	}
1683 
1684 	return 0;
1685 }
1686 
1687 static void bt8xx_dst_release(struct dvb_frontend *fe)
1688 {
1689 	struct dst_state *state = fe->demodulator_priv;
1690 	if (state->dst_ca) {
1691 		dvb_unregister_device(state->dst_ca);
1692 #ifdef CONFIG_MEDIA_ATTACH
1693 		symbol_put(dst_ca_attach);
1694 #endif
1695 	}
1696 	kfree(state);
1697 }
1698 
1699 static const struct dvb_frontend_ops dst_dvbt_ops;
1700 static const struct dvb_frontend_ops dst_dvbs_ops;
1701 static const struct dvb_frontend_ops dst_dvbc_ops;
1702 static const struct dvb_frontend_ops dst_atsc_ops;
1703 
1704 struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
1705 {
1706 	/* check if the ASIC is there */
1707 	if (dst_probe(state) < 0) {
1708 		kfree(state);
1709 		return NULL;
1710 	}
1711 	/* determine settings based on type */
1712 	/* create dvb_frontend */
1713 	switch (state->dst_type) {
1714 	case DST_TYPE_IS_TERR:
1715 		memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
1716 		break;
1717 	case DST_TYPE_IS_CABLE:
1718 		memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
1719 		break;
1720 	case DST_TYPE_IS_SAT:
1721 		memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
1722 		break;
1723 	case DST_TYPE_IS_ATSC:
1724 		memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops));
1725 		break;
1726 	default:
1727 		pr_err("unknown DST type. please report to the LinuxTV.org DVB mailinglist.\n");
1728 		kfree(state);
1729 		return NULL;
1730 	}
1731 	state->frontend.demodulator_priv = state;
1732 
1733 	return state;				/*	Manu (DST is a card not a frontend)	*/
1734 }
1735 
1736 EXPORT_SYMBOL(dst_attach);
1737 
1738 static const struct dvb_frontend_ops dst_dvbt_ops = {
1739 	.delsys = { SYS_DVBT },
1740 	.info = {
1741 		.name = "DST DVB-T",
1742 		.frequency_min_hz = 137 * MHz,
1743 		.frequency_max_hz = 858 * MHz,
1744 		.frequency_stepsize_hz = 166667,
1745 		.caps = FE_CAN_FEC_AUTO			|
1746 			FE_CAN_QAM_AUTO			|
1747 			FE_CAN_QAM_16			|
1748 			FE_CAN_QAM_32			|
1749 			FE_CAN_QAM_64			|
1750 			FE_CAN_QAM_128			|
1751 			FE_CAN_QAM_256			|
1752 			FE_CAN_TRANSMISSION_MODE_AUTO	|
1753 			FE_CAN_GUARD_INTERVAL_AUTO
1754 	},
1755 
1756 	.release = bt8xx_dst_release,
1757 	.init = bt8xx_dst_init,
1758 	.tune = dst_tune_frontend,
1759 	.set_frontend = dst_set_frontend,
1760 	.get_frontend = dst_get_frontend,
1761 	.get_frontend_algo = dst_get_tuning_algo,
1762 	.read_status = dst_read_status,
1763 	.read_signal_strength = dst_read_signal_strength,
1764 	.read_snr = dst_read_snr,
1765 };
1766 
1767 static const struct dvb_frontend_ops dst_dvbs_ops = {
1768 	.delsys = { SYS_DVBS },
1769 	.info = {
1770 		.name = "DST DVB-S",
1771 		.frequency_min_hz   =  950 * MHz,
1772 		.frequency_max_hz   = 2150 * MHz,
1773 		.frequency_stepsize_hz = 1 * MHz,
1774 		.frequency_tolerance_hz = 29500 * kHz,
1775 		.symbol_rate_min = 1000000,
1776 		.symbol_rate_max = 45000000,
1777 	/*     . symbol_rate_tolerance	=	???,*/
1778 		.caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
1779 	},
1780 
1781 	.release = bt8xx_dst_release,
1782 	.init = bt8xx_dst_init,
1783 	.tune = dst_tune_frontend,
1784 	.set_frontend = dst_set_frontend,
1785 	.get_frontend = dst_get_frontend,
1786 	.get_frontend_algo = dst_get_tuning_algo,
1787 	.read_status = dst_read_status,
1788 	.read_signal_strength = dst_read_signal_strength,
1789 	.read_snr = dst_read_snr,
1790 	.diseqc_send_burst = dst_send_burst,
1791 	.diseqc_send_master_cmd = dst_set_diseqc,
1792 	.set_voltage = dst_set_voltage,
1793 	.set_tone = dst_set_tone,
1794 };
1795 
1796 static const struct dvb_frontend_ops dst_dvbc_ops = {
1797 	.delsys = { SYS_DVBC_ANNEX_A },
1798 	.info = {
1799 		.name = "DST DVB-C",
1800 		.frequency_min_hz =  51 * MHz,
1801 		.frequency_max_hz = 858 * MHz,
1802 		.frequency_stepsize_hz = 62500,
1803 		.symbol_rate_min = 1000000,
1804 		.symbol_rate_max = 45000000,
1805 		.caps = FE_CAN_FEC_AUTO |
1806 			FE_CAN_QAM_AUTO |
1807 			FE_CAN_QAM_16	|
1808 			FE_CAN_QAM_32	|
1809 			FE_CAN_QAM_64	|
1810 			FE_CAN_QAM_128	|
1811 			FE_CAN_QAM_256
1812 	},
1813 
1814 	.release = bt8xx_dst_release,
1815 	.init = bt8xx_dst_init,
1816 	.tune = dst_tune_frontend,
1817 	.set_frontend = dst_set_frontend,
1818 	.get_frontend = dst_get_frontend,
1819 	.get_frontend_algo = dst_get_tuning_algo,
1820 	.read_status = dst_read_status,
1821 	.read_signal_strength = dst_read_signal_strength,
1822 	.read_snr = dst_read_snr,
1823 };
1824 
1825 static const struct dvb_frontend_ops dst_atsc_ops = {
1826 	.delsys = { SYS_ATSC },
1827 	.info = {
1828 		.name = "DST ATSC",
1829 		.frequency_min_hz = 510 * MHz,
1830 		.frequency_max_hz = 858 * MHz,
1831 		.frequency_stepsize_hz = 62500,
1832 		.symbol_rate_min = 1000000,
1833 		.symbol_rate_max = 45000000,
1834 		.caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
1835 	},
1836 
1837 	.release = bt8xx_dst_release,
1838 	.init = bt8xx_dst_init,
1839 	.tune = dst_tune_frontend,
1840 	.set_frontend = dst_set_frontend,
1841 	.get_frontend = dst_get_frontend,
1842 	.get_frontend_algo = dst_get_tuning_algo,
1843 	.read_status = dst_read_status,
1844 	.read_signal_strength = dst_read_signal_strength,
1845 	.read_snr = dst_read_snr,
1846 };
1847 
1848 MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver");
1849 MODULE_AUTHOR("Jamie Honan, Manu Abraham");
1850 MODULE_LICENSE("GPL");
1851