cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dst.c (46675B)


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