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

dw2102.c (61848B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* DVB USB framework compliant Linux driver for the
      3 *	DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
      4 *	TeVii S421, S480, S482, S600, S630, S632, S650, S660, S662,
      5 *	Prof 1100, 7500,
      6 *	Geniatech SU3000, T220,
      7 *	TechnoTrend S2-4600,
      8 *	Terratec Cinergy S2 cards
      9 * Copyright (C) 2008-2012 Igor M. Liplianin (liplianin@me.by)
     10 *
     11 * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
     12 */
     13#include <media/dvb-usb-ids.h>
     14#include "dw2102.h"
     15#include "si21xx.h"
     16#include "stv0299.h"
     17#include "z0194a.h"
     18#include "stv0288.h"
     19#include "stb6000.h"
     20#include "eds1547.h"
     21#include "cx24116.h"
     22#include "tda1002x.h"
     23#include "mt312.h"
     24#include "zl10039.h"
     25#include "ts2020.h"
     26#include "ds3000.h"
     27#include "stv0900.h"
     28#include "stv6110.h"
     29#include "stb6100.h"
     30#include "stb6100_proc.h"
     31#include "m88rs2000.h"
     32#include "tda18271.h"
     33#include "cxd2820r.h"
     34#include "m88ds3103.h"
     35
     36/* Max transfer size done by I2C transfer functions */
     37#define MAX_XFER_SIZE  64
     38
     39
     40#define DW210X_READ_MSG 0
     41#define DW210X_WRITE_MSG 1
     42
     43#define REG_1F_SYMBOLRATE_BYTE0 0x1f
     44#define REG_20_SYMBOLRATE_BYTE1 0x20
     45#define REG_21_SYMBOLRATE_BYTE2 0x21
     46/* on my own*/
     47#define DW2102_VOLTAGE_CTRL (0x1800)
     48#define SU3000_STREAM_CTRL (0x1900)
     49#define DW2102_RC_QUERY (0x1a00)
     50#define DW2102_LED_CTRL (0x1b00)
     51
     52#define DW2101_FIRMWARE "dvb-usb-dw2101.fw"
     53#define DW2102_FIRMWARE "dvb-usb-dw2102.fw"
     54#define DW2104_FIRMWARE "dvb-usb-dw2104.fw"
     55#define DW3101_FIRMWARE "dvb-usb-dw3101.fw"
     56#define S630_FIRMWARE   "dvb-usb-s630.fw"
     57#define S660_FIRMWARE   "dvb-usb-s660.fw"
     58#define P1100_FIRMWARE  "dvb-usb-p1100.fw"
     59#define P7500_FIRMWARE  "dvb-usb-p7500.fw"
     60
     61#define	err_str "did not find the firmware file '%s'. You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware"
     62
     63struct dw2102_state {
     64	u8 initialized;
     65	u8 last_lock;
     66	u8 data[MAX_XFER_SIZE + 4];
     67	struct i2c_client *i2c_client_demod;
     68	struct i2c_client *i2c_client_tuner;
     69
     70	/* fe hook functions*/
     71	int (*old_set_voltage)(struct dvb_frontend *f, enum fe_sec_voltage v);
     72	int (*fe_read_status)(struct dvb_frontend *fe,
     73			      enum fe_status *status);
     74};
     75
     76/* debug */
     77static int dvb_usb_dw2102_debug;
     78module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
     79MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
     80						DVB_USB_DEBUG_STATUS);
     81
     82/* demod probe */
     83static int demod_probe = 1;
     84module_param_named(demod, demod_probe, int, 0644);
     85MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 4=stv0903+stb6100(or-able)).");
     86
     87DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
     88
     89static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
     90			u16 index, u8 * data, u16 len, int flags)
     91{
     92	int ret;
     93	u8 *u8buf;
     94	unsigned int pipe = (flags == DW210X_READ_MSG) ?
     95				usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
     96	u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
     97
     98	u8buf = kmalloc(len, GFP_KERNEL);
     99	if (!u8buf)
    100		return -ENOMEM;
    101
    102
    103	if (flags == DW210X_WRITE_MSG)
    104		memcpy(u8buf, data, len);
    105	ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
    106				value, index , u8buf, len, 2000);
    107
    108	if (flags == DW210X_READ_MSG)
    109		memcpy(data, u8buf, len);
    110
    111	kfree(u8buf);
    112	return ret;
    113}
    114
    115/* I2C */
    116static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
    117		int num)
    118{
    119	struct dvb_usb_device *d = i2c_get_adapdata(adap);
    120	int i = 0;
    121	u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
    122	u16 value;
    123
    124	if (!d)
    125		return -ENODEV;
    126	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
    127		return -EAGAIN;
    128
    129	switch (num) {
    130	case 2:
    131		/* read stv0299 register */
    132		value = msg[0].buf[0];/* register */
    133		for (i = 0; i < msg[1].len; i++) {
    134			dw210x_op_rw(d->udev, 0xb5, value + i, 0,
    135					buf6, 2, DW210X_READ_MSG);
    136			msg[1].buf[i] = buf6[0];
    137		}
    138		break;
    139	case 1:
    140		switch (msg[0].addr) {
    141		case 0x68:
    142			/* write to stv0299 register */
    143			buf6[0] = 0x2a;
    144			buf6[1] = msg[0].buf[0];
    145			buf6[2] = msg[0].buf[1];
    146			dw210x_op_rw(d->udev, 0xb2, 0, 0,
    147					buf6, 3, DW210X_WRITE_MSG);
    148			break;
    149		case 0x60:
    150			if (msg[0].flags == 0) {
    151			/* write to tuner pll */
    152				buf6[0] = 0x2c;
    153				buf6[1] = 5;
    154				buf6[2] = 0xc0;
    155				buf6[3] = msg[0].buf[0];
    156				buf6[4] = msg[0].buf[1];
    157				buf6[5] = msg[0].buf[2];
    158				buf6[6] = msg[0].buf[3];
    159				dw210x_op_rw(d->udev, 0xb2, 0, 0,
    160						buf6, 7, DW210X_WRITE_MSG);
    161			} else {
    162			/* read from tuner */
    163				dw210x_op_rw(d->udev, 0xb5, 0, 0,
    164						buf6, 1, DW210X_READ_MSG);
    165				msg[0].buf[0] = buf6[0];
    166			}
    167			break;
    168		case (DW2102_RC_QUERY):
    169			dw210x_op_rw(d->udev, 0xb8, 0, 0,
    170					buf6, 2, DW210X_READ_MSG);
    171			msg[0].buf[0] = buf6[0];
    172			msg[0].buf[1] = buf6[1];
    173			break;
    174		case (DW2102_VOLTAGE_CTRL):
    175			buf6[0] = 0x30;
    176			buf6[1] = msg[0].buf[0];
    177			dw210x_op_rw(d->udev, 0xb2, 0, 0,
    178					buf6, 2, DW210X_WRITE_MSG);
    179			break;
    180		}
    181
    182		break;
    183	}
    184
    185	mutex_unlock(&d->i2c_mutex);
    186	return num;
    187}
    188
    189static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
    190						struct i2c_msg msg[], int num)
    191{
    192	struct dvb_usb_device *d = i2c_get_adapdata(adap);
    193	u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};
    194
    195	if (!d)
    196		return -ENODEV;
    197	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
    198		return -EAGAIN;
    199
    200	switch (num) {
    201	case 2:
    202		if (msg[0].len != 1) {
    203			warn("i2c rd: len=%d is not 1!\n",
    204			     msg[0].len);
    205			num = -EOPNOTSUPP;
    206			break;
    207		}
    208
    209		if (2 + msg[1].len > sizeof(buf6)) {
    210			warn("i2c rd: len=%d is too big!\n",
    211			     msg[1].len);
    212			num = -EOPNOTSUPP;
    213			break;
    214		}
    215
    216		/* read si2109 register by number */
    217		buf6[0] = msg[0].addr << 1;
    218		buf6[1] = msg[0].len;
    219		buf6[2] = msg[0].buf[0];
    220		dw210x_op_rw(d->udev, 0xc2, 0, 0,
    221				buf6, msg[0].len + 2, DW210X_WRITE_MSG);
    222		/* read si2109 register */
    223		dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
    224				buf6, msg[1].len + 2, DW210X_READ_MSG);
    225		memcpy(msg[1].buf, buf6 + 2, msg[1].len);
    226
    227		break;
    228	case 1:
    229		switch (msg[0].addr) {
    230		case 0x68:
    231			if (2 + msg[0].len > sizeof(buf6)) {
    232				warn("i2c wr: len=%d is too big!\n",
    233				     msg[0].len);
    234				num = -EOPNOTSUPP;
    235				break;
    236			}
    237
    238			/* write to si2109 register */
    239			buf6[0] = msg[0].addr << 1;
    240			buf6[1] = msg[0].len;
    241			memcpy(buf6 + 2, msg[0].buf, msg[0].len);
    242			dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
    243					msg[0].len + 2, DW210X_WRITE_MSG);
    244			break;
    245		case(DW2102_RC_QUERY):
    246			dw210x_op_rw(d->udev, 0xb8, 0, 0,
    247					buf6, 2, DW210X_READ_MSG);
    248			msg[0].buf[0] = buf6[0];
    249			msg[0].buf[1] = buf6[1];
    250			break;
    251		case(DW2102_VOLTAGE_CTRL):
    252			buf6[0] = 0x30;
    253			buf6[1] = msg[0].buf[0];
    254			dw210x_op_rw(d->udev, 0xb2, 0, 0,
    255					buf6, 2, DW210X_WRITE_MSG);
    256			break;
    257		}
    258		break;
    259	}
    260
    261	mutex_unlock(&d->i2c_mutex);
    262	return num;
    263}
    264
    265static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
    266{
    267	struct dvb_usb_device *d = i2c_get_adapdata(adap);
    268	int ret;
    269
    270	if (!d)
    271		return -ENODEV;
    272	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
    273		return -EAGAIN;
    274
    275	switch (num) {
    276	case 2: {
    277		/* read */
    278		/* first write first register number */
    279		u8 ibuf[MAX_XFER_SIZE], obuf[3];
    280
    281		if (2 + msg[0].len != sizeof(obuf)) {
    282			warn("i2c rd: len=%d is not 1!\n",
    283			     msg[0].len);
    284			ret = -EOPNOTSUPP;
    285			goto unlock;
    286		}
    287
    288		if (2 + msg[1].len > sizeof(ibuf)) {
    289			warn("i2c rd: len=%d is too big!\n",
    290			     msg[1].len);
    291			ret = -EOPNOTSUPP;
    292			goto unlock;
    293		}
    294
    295		obuf[0] = msg[0].addr << 1;
    296		obuf[1] = msg[0].len;
    297		obuf[2] = msg[0].buf[0];
    298		dw210x_op_rw(d->udev, 0xc2, 0, 0,
    299				obuf, msg[0].len + 2, DW210X_WRITE_MSG);
    300		/* second read registers */
    301		dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
    302				ibuf, msg[1].len + 2, DW210X_READ_MSG);
    303		memcpy(msg[1].buf, ibuf + 2, msg[1].len);
    304
    305		break;
    306	}
    307	case 1:
    308		switch (msg[0].addr) {
    309		case 0x68: {
    310			/* write to register */
    311			u8 obuf[MAX_XFER_SIZE];
    312
    313			if (2 + msg[0].len > sizeof(obuf)) {
    314				warn("i2c wr: len=%d is too big!\n",
    315				     msg[1].len);
    316				ret = -EOPNOTSUPP;
    317				goto unlock;
    318			}
    319
    320			obuf[0] = msg[0].addr << 1;
    321			obuf[1] = msg[0].len;
    322			memcpy(obuf + 2, msg[0].buf, msg[0].len);
    323			dw210x_op_rw(d->udev, 0xc2, 0, 0,
    324					obuf, msg[0].len + 2, DW210X_WRITE_MSG);
    325			break;
    326		}
    327		case 0x61: {
    328			/* write to tuner */
    329			u8 obuf[MAX_XFER_SIZE];
    330
    331			if (2 + msg[0].len > sizeof(obuf)) {
    332				warn("i2c wr: len=%d is too big!\n",
    333				     msg[1].len);
    334				ret = -EOPNOTSUPP;
    335				goto unlock;
    336			}
    337
    338			obuf[0] = msg[0].addr << 1;
    339			obuf[1] = msg[0].len;
    340			memcpy(obuf + 2, msg[0].buf, msg[0].len);
    341			dw210x_op_rw(d->udev, 0xc2, 0, 0,
    342					obuf, msg[0].len + 2, DW210X_WRITE_MSG);
    343			break;
    344		}
    345		case(DW2102_RC_QUERY): {
    346			u8 ibuf[2];
    347			dw210x_op_rw(d->udev, 0xb8, 0, 0,
    348					ibuf, 2, DW210X_READ_MSG);
    349			memcpy(msg[0].buf, ibuf , 2);
    350			break;
    351		}
    352		case(DW2102_VOLTAGE_CTRL): {
    353			u8 obuf[2];
    354			obuf[0] = 0x30;
    355			obuf[1] = msg[0].buf[0];
    356			dw210x_op_rw(d->udev, 0xb2, 0, 0,
    357					obuf, 2, DW210X_WRITE_MSG);
    358			break;
    359		}
    360		}
    361
    362		break;
    363	}
    364	ret = num;
    365
    366unlock:
    367	mutex_unlock(&d->i2c_mutex);
    368	return ret;
    369}
    370
    371static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
    372{
    373	struct dvb_usb_device *d = i2c_get_adapdata(adap);
    374	int len, i, j, ret;
    375
    376	if (!d)
    377		return -ENODEV;
    378	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
    379		return -EAGAIN;
    380
    381	for (j = 0; j < num; j++) {
    382		switch (msg[j].addr) {
    383		case(DW2102_RC_QUERY): {
    384			u8 ibuf[2];
    385			dw210x_op_rw(d->udev, 0xb8, 0, 0,
    386					ibuf, 2, DW210X_READ_MSG);
    387			memcpy(msg[j].buf, ibuf , 2);
    388			break;
    389		}
    390		case(DW2102_VOLTAGE_CTRL): {
    391			u8 obuf[2];
    392			obuf[0] = 0x30;
    393			obuf[1] = msg[j].buf[0];
    394			dw210x_op_rw(d->udev, 0xb2, 0, 0,
    395					obuf, 2, DW210X_WRITE_MSG);
    396			break;
    397		}
    398		/*case 0x55: cx24116
    399		case 0x6a: stv0903
    400		case 0x68: ds3000, stv0903
    401		case 0x60: ts2020, stv6110, stb6100 */
    402		default: {
    403			if (msg[j].flags == I2C_M_RD) {
    404				/* read registers */
    405				u8  ibuf[MAX_XFER_SIZE];
    406
    407				if (2 + msg[j].len > sizeof(ibuf)) {
    408					warn("i2c rd: len=%d is too big!\n",
    409					     msg[j].len);
    410					ret = -EOPNOTSUPP;
    411					goto unlock;
    412				}
    413
    414				dw210x_op_rw(d->udev, 0xc3,
    415						(msg[j].addr << 1) + 1, 0,
    416						ibuf, msg[j].len + 2,
    417						DW210X_READ_MSG);
    418				memcpy(msg[j].buf, ibuf + 2, msg[j].len);
    419				mdelay(10);
    420			} else if (((msg[j].buf[0] == 0xb0) &&
    421						(msg[j].addr == 0x68)) ||
    422						((msg[j].buf[0] == 0xf7) &&
    423						(msg[j].addr == 0x55))) {
    424				/* write firmware */
    425				u8 obuf[19];
    426				obuf[0] = msg[j].addr << 1;
    427				obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
    428				obuf[2] = msg[j].buf[0];
    429				len = msg[j].len - 1;
    430				i = 1;
    431				do {
    432					memcpy(obuf + 3, msg[j].buf + i,
    433							(len > 16 ? 16 : len));
    434					dw210x_op_rw(d->udev, 0xc2, 0, 0,
    435						obuf, (len > 16 ? 16 : len) + 3,
    436						DW210X_WRITE_MSG);
    437					i += 16;
    438					len -= 16;
    439				} while (len > 0);
    440			} else {
    441				/* write registers */
    442				u8 obuf[MAX_XFER_SIZE];
    443
    444				if (2 + msg[j].len > sizeof(obuf)) {
    445					warn("i2c wr: len=%d is too big!\n",
    446					     msg[j].len);
    447					ret = -EOPNOTSUPP;
    448					goto unlock;
    449				}
    450
    451				obuf[0] = msg[j].addr << 1;
    452				obuf[1] = msg[j].len;
    453				memcpy(obuf + 2, msg[j].buf, msg[j].len);
    454				dw210x_op_rw(d->udev, 0xc2, 0, 0,
    455						obuf, msg[j].len + 2,
    456						DW210X_WRITE_MSG);
    457			}
    458			break;
    459		}
    460		}
    461
    462	}
    463	ret = num;
    464
    465unlock:
    466	mutex_unlock(&d->i2c_mutex);
    467	return ret;
    468}
    469
    470static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
    471								int num)
    472{
    473	struct dvb_usb_device *d = i2c_get_adapdata(adap);
    474	int ret;
    475	int i;
    476
    477	if (!d)
    478		return -ENODEV;
    479	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
    480		return -EAGAIN;
    481
    482	switch (num) {
    483	case 2: {
    484		/* read */
    485		/* first write first register number */
    486		u8 ibuf[MAX_XFER_SIZE], obuf[3];
    487
    488		if (2 + msg[0].len != sizeof(obuf)) {
    489			warn("i2c rd: len=%d is not 1!\n",
    490			     msg[0].len);
    491			ret = -EOPNOTSUPP;
    492			goto unlock;
    493		}
    494		if (2 + msg[1].len > sizeof(ibuf)) {
    495			warn("i2c rd: len=%d is too big!\n",
    496			     msg[1].len);
    497			ret = -EOPNOTSUPP;
    498			goto unlock;
    499		}
    500		obuf[0] = msg[0].addr << 1;
    501		obuf[1] = msg[0].len;
    502		obuf[2] = msg[0].buf[0];
    503		dw210x_op_rw(d->udev, 0xc2, 0, 0,
    504				obuf, msg[0].len + 2, DW210X_WRITE_MSG);
    505		/* second read registers */
    506		dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
    507				ibuf, msg[1].len + 2, DW210X_READ_MSG);
    508		memcpy(msg[1].buf, ibuf + 2, msg[1].len);
    509
    510		break;
    511	}
    512	case 1:
    513		switch (msg[0].addr) {
    514		case 0x60:
    515		case 0x0c: {
    516			/* write to register */
    517			u8 obuf[MAX_XFER_SIZE];
    518
    519			if (2 + msg[0].len > sizeof(obuf)) {
    520				warn("i2c wr: len=%d is too big!\n",
    521				     msg[0].len);
    522				ret = -EOPNOTSUPP;
    523				goto unlock;
    524			}
    525			obuf[0] = msg[0].addr << 1;
    526			obuf[1] = msg[0].len;
    527			memcpy(obuf + 2, msg[0].buf, msg[0].len);
    528			dw210x_op_rw(d->udev, 0xc2, 0, 0,
    529					obuf, msg[0].len + 2, DW210X_WRITE_MSG);
    530			break;
    531		}
    532		case(DW2102_RC_QUERY): {
    533			u8 ibuf[2];
    534			dw210x_op_rw(d->udev, 0xb8, 0, 0,
    535					ibuf, 2, DW210X_READ_MSG);
    536			memcpy(msg[0].buf, ibuf , 2);
    537			break;
    538		}
    539		}
    540
    541		break;
    542	}
    543
    544	for (i = 0; i < num; i++) {
    545		deb_xfer("%02x:%02x: %s ", i, msg[i].addr,
    546				msg[i].flags == 0 ? ">>>" : "<<<");
    547		debug_dump(msg[i].buf, msg[i].len, deb_xfer);
    548	}
    549	ret = num;
    550
    551unlock:
    552	mutex_unlock(&d->i2c_mutex);
    553	return ret;
    554}
    555
    556static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
    557								int num)
    558{
    559	struct dvb_usb_device *d = i2c_get_adapdata(adap);
    560	struct usb_device *udev;
    561	int len, i, j, ret;
    562
    563	if (!d)
    564		return -ENODEV;
    565	udev = d->udev;
    566	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
    567		return -EAGAIN;
    568
    569	for (j = 0; j < num; j++) {
    570		switch (msg[j].addr) {
    571		case (DW2102_RC_QUERY): {
    572			u8 ibuf[5];
    573			dw210x_op_rw(d->udev, 0xb8, 0, 0,
    574					ibuf, 5, DW210X_READ_MSG);
    575			memcpy(msg[j].buf, ibuf + 3, 2);
    576			break;
    577		}
    578		case (DW2102_VOLTAGE_CTRL): {
    579			u8 obuf[2];
    580
    581			obuf[0] = 1;
    582			obuf[1] = msg[j].buf[1];/* off-on */
    583			dw210x_op_rw(d->udev, 0x8a, 0, 0,
    584					obuf, 2, DW210X_WRITE_MSG);
    585			obuf[0] = 3;
    586			obuf[1] = msg[j].buf[0];/* 13v-18v */
    587			dw210x_op_rw(d->udev, 0x8a, 0, 0,
    588					obuf, 2, DW210X_WRITE_MSG);
    589			break;
    590		}
    591		case (DW2102_LED_CTRL): {
    592			u8 obuf[2];
    593
    594			obuf[0] = 5;
    595			obuf[1] = msg[j].buf[0];
    596			dw210x_op_rw(d->udev, 0x8a, 0, 0,
    597					obuf, 2, DW210X_WRITE_MSG);
    598			break;
    599		}
    600		/*case 0x55: cx24116
    601		case 0x6a: stv0903
    602		case 0x68: ds3000, stv0903, rs2000
    603		case 0x60: ts2020, stv6110, stb6100
    604		case 0xa0: eeprom */
    605		default: {
    606			if (msg[j].flags == I2C_M_RD) {
    607				/* read registers */
    608				u8 ibuf[MAX_XFER_SIZE];
    609
    610				if (msg[j].len > sizeof(ibuf)) {
    611					warn("i2c rd: len=%d is too big!\n",
    612					     msg[j].len);
    613					ret = -EOPNOTSUPP;
    614					goto unlock;
    615				}
    616
    617				dw210x_op_rw(d->udev, 0x91, 0, 0,
    618						ibuf, msg[j].len,
    619						DW210X_READ_MSG);
    620				memcpy(msg[j].buf, ibuf, msg[j].len);
    621				break;
    622			} else if ((msg[j].buf[0] == 0xb0) &&
    623						(msg[j].addr == 0x68)) {
    624				/* write firmware */
    625				u8 obuf[19];
    626				obuf[0] = (msg[j].len > 16 ?
    627						18 : msg[j].len + 1);
    628				obuf[1] = msg[j].addr << 1;
    629				obuf[2] = msg[j].buf[0];
    630				len = msg[j].len - 1;
    631				i = 1;
    632				do {
    633					memcpy(obuf + 3, msg[j].buf + i,
    634							(len > 16 ? 16 : len));
    635					dw210x_op_rw(d->udev, 0x80, 0, 0,
    636						obuf, (len > 16 ? 16 : len) + 3,
    637						DW210X_WRITE_MSG);
    638					i += 16;
    639					len -= 16;
    640				} while (len > 0);
    641			} else if (j < (num - 1)) {
    642				/* write register addr before read */
    643				u8 obuf[MAX_XFER_SIZE];
    644
    645				if (2 + msg[j].len > sizeof(obuf)) {
    646					warn("i2c wr: len=%d is too big!\n",
    647					     msg[j].len);
    648					ret = -EOPNOTSUPP;
    649					goto unlock;
    650				}
    651
    652				obuf[0] = msg[j + 1].len;
    653				obuf[1] = (msg[j].addr << 1);
    654				memcpy(obuf + 2, msg[j].buf, msg[j].len);
    655				dw210x_op_rw(d->udev,
    656						le16_to_cpu(udev->descriptor.idProduct) ==
    657						0x7500 ? 0x92 : 0x90, 0, 0,
    658						obuf, msg[j].len + 2,
    659						DW210X_WRITE_MSG);
    660				break;
    661			} else {
    662				/* write registers */
    663				u8 obuf[MAX_XFER_SIZE];
    664
    665				if (2 + msg[j].len > sizeof(obuf)) {
    666					warn("i2c wr: len=%d is too big!\n",
    667					     msg[j].len);
    668					ret = -EOPNOTSUPP;
    669					goto unlock;
    670				}
    671				obuf[0] = msg[j].len + 1;
    672				obuf[1] = (msg[j].addr << 1);
    673				memcpy(obuf + 2, msg[j].buf, msg[j].len);
    674				dw210x_op_rw(d->udev, 0x80, 0, 0,
    675						obuf, msg[j].len + 2,
    676						DW210X_WRITE_MSG);
    677				break;
    678			}
    679			break;
    680		}
    681		}
    682	}
    683	ret = num;
    684
    685unlock:
    686	mutex_unlock(&d->i2c_mutex);
    687	return ret;
    688}
    689
    690static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
    691								int num)
    692{
    693	struct dvb_usb_device *d = i2c_get_adapdata(adap);
    694	struct dw2102_state *state;
    695
    696	if (!d)
    697		return -ENODEV;
    698
    699	state = d->priv;
    700
    701	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
    702		return -EAGAIN;
    703	if (mutex_lock_interruptible(&d->data_mutex) < 0) {
    704		mutex_unlock(&d->i2c_mutex);
    705		return -EAGAIN;
    706	}
    707
    708	switch (num) {
    709	case 1:
    710		switch (msg[0].addr) {
    711		case SU3000_STREAM_CTRL:
    712			state->data[0] = msg[0].buf[0] + 0x36;
    713			state->data[1] = 3;
    714			state->data[2] = 0;
    715			if (dvb_usb_generic_rw(d, state->data, 3,
    716					state->data, 0, 0) < 0)
    717				err("i2c transfer failed.");
    718			break;
    719		case DW2102_RC_QUERY:
    720			state->data[0] = 0x10;
    721			if (dvb_usb_generic_rw(d, state->data, 1,
    722					state->data, 2, 0) < 0)
    723				err("i2c transfer failed.");
    724			msg[0].buf[1] = state->data[0];
    725			msg[0].buf[0] = state->data[1];
    726			break;
    727		default:
    728			if (3 + msg[0].len > sizeof(state->data)) {
    729				warn("i2c wr: len=%d is too big!\n",
    730				     msg[0].len);
    731				num = -EOPNOTSUPP;
    732				break;
    733			}
    734
    735			/* always i2c write*/
    736			state->data[0] = 0x08;
    737			state->data[1] = msg[0].addr;
    738			state->data[2] = msg[0].len;
    739
    740			memcpy(&state->data[3], msg[0].buf, msg[0].len);
    741
    742			if (dvb_usb_generic_rw(d, state->data, msg[0].len + 3,
    743						state->data, 1, 0) < 0)
    744				err("i2c transfer failed.");
    745
    746		}
    747		break;
    748	case 2:
    749		/* always i2c read */
    750		if (4 + msg[0].len > sizeof(state->data)) {
    751			warn("i2c rd: len=%d is too big!\n",
    752			     msg[0].len);
    753			num = -EOPNOTSUPP;
    754			break;
    755		}
    756		if (1 + msg[1].len > sizeof(state->data)) {
    757			warn("i2c rd: len=%d is too big!\n",
    758			     msg[1].len);
    759			num = -EOPNOTSUPP;
    760			break;
    761		}
    762
    763		state->data[0] = 0x09;
    764		state->data[1] = msg[0].len;
    765		state->data[2] = msg[1].len;
    766		state->data[3] = msg[0].addr;
    767		memcpy(&state->data[4], msg[0].buf, msg[0].len);
    768
    769		if (dvb_usb_generic_rw(d, state->data, msg[0].len + 4,
    770					state->data, msg[1].len + 1, 0) < 0)
    771			err("i2c transfer failed.");
    772
    773		memcpy(msg[1].buf, &state->data[1], msg[1].len);
    774		break;
    775	default:
    776		warn("more than 2 i2c messages at a time is not handled yet.");
    777		break;
    778	}
    779	mutex_unlock(&d->data_mutex);
    780	mutex_unlock(&d->i2c_mutex);
    781	return num;
    782}
    783
    784static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
    785{
    786	return I2C_FUNC_I2C;
    787}
    788
    789static struct i2c_algorithm dw2102_i2c_algo = {
    790	.master_xfer = dw2102_i2c_transfer,
    791	.functionality = dw210x_i2c_func,
    792};
    793
    794static struct i2c_algorithm dw2102_serit_i2c_algo = {
    795	.master_xfer = dw2102_serit_i2c_transfer,
    796	.functionality = dw210x_i2c_func,
    797};
    798
    799static struct i2c_algorithm dw2102_earda_i2c_algo = {
    800	.master_xfer = dw2102_earda_i2c_transfer,
    801	.functionality = dw210x_i2c_func,
    802};
    803
    804static struct i2c_algorithm dw2104_i2c_algo = {
    805	.master_xfer = dw2104_i2c_transfer,
    806	.functionality = dw210x_i2c_func,
    807};
    808
    809static struct i2c_algorithm dw3101_i2c_algo = {
    810	.master_xfer = dw3101_i2c_transfer,
    811	.functionality = dw210x_i2c_func,
    812};
    813
    814static struct i2c_algorithm s6x0_i2c_algo = {
    815	.master_xfer = s6x0_i2c_transfer,
    816	.functionality = dw210x_i2c_func,
    817};
    818
    819static struct i2c_algorithm su3000_i2c_algo = {
    820	.master_xfer = su3000_i2c_transfer,
    821	.functionality = dw210x_i2c_func,
    822};
    823
    824static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
    825{
    826	int i;
    827	u8 ibuf[] = {0, 0};
    828	u8 eeprom[256], eepromline[16];
    829
    830	for (i = 0; i < 256; i++) {
    831		if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) {
    832			err("read eeprom failed.");
    833			return -1;
    834		} else {
    835			eepromline[i%16] = ibuf[0];
    836			eeprom[i] = ibuf[0];
    837		}
    838		if ((i % 16) == 15) {
    839			deb_xfer("%02x: ", i - 15);
    840			debug_dump(eepromline, 16, deb_xfer);
    841		}
    842	}
    843
    844	memcpy(mac, eeprom + 8, 6);
    845	return 0;
    846};
    847
    848static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
    849{
    850	int i, ret;
    851	u8 ibuf[] = { 0 }, obuf[] = { 0 };
    852	u8 eeprom[256], eepromline[16];
    853	struct i2c_msg msg[] = {
    854		{
    855			.addr = 0xa0 >> 1,
    856			.flags = 0,
    857			.buf = obuf,
    858			.len = 1,
    859		}, {
    860			.addr = 0xa0 >> 1,
    861			.flags = I2C_M_RD,
    862			.buf = ibuf,
    863			.len = 1,
    864		}
    865	};
    866
    867	for (i = 0; i < 256; i++) {
    868		obuf[0] = i;
    869		ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
    870		if (ret != 2) {
    871			err("read eeprom failed.");
    872			return -1;
    873		} else {
    874			eepromline[i % 16] = ibuf[0];
    875			eeprom[i] = ibuf[0];
    876		}
    877
    878		if ((i % 16) == 15) {
    879			deb_xfer("%02x: ", i - 15);
    880			debug_dump(eepromline, 16, deb_xfer);
    881		}
    882	}
    883
    884	memcpy(mac, eeprom + 16, 6);
    885	return 0;
    886};
    887
    888static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
    889{
    890	static u8 command_start[] = {0x00};
    891	static u8 command_stop[] = {0x01};
    892	struct i2c_msg msg = {
    893		.addr = SU3000_STREAM_CTRL,
    894		.flags = 0,
    895		.buf = onoff ? command_start : command_stop,
    896		.len = 1
    897	};
    898
    899	i2c_transfer(&adap->dev->i2c_adap, &msg, 1);
    900
    901	return 0;
    902}
    903
    904static int su3000_power_ctrl(struct dvb_usb_device *d, int i)
    905{
    906	struct dw2102_state *state = (struct dw2102_state *)d->priv;
    907	int ret = 0;
    908
    909	info("%s: %d, initialized %d", __func__, i, state->initialized);
    910
    911	if (i && !state->initialized) {
    912		mutex_lock(&d->data_mutex);
    913
    914		state->data[0] = 0xde;
    915		state->data[1] = 0;
    916
    917		state->initialized = 1;
    918		/* reset board */
    919		ret = dvb_usb_generic_rw(d, state->data, 2, NULL, 0, 0);
    920		mutex_unlock(&d->data_mutex);
    921	}
    922
    923	return ret;
    924}
    925
    926static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
    927{
    928	int i;
    929	u8 obuf[] = { 0x1f, 0xf0 };
    930	u8 ibuf[] = { 0 };
    931	struct i2c_msg msg[] = {
    932		{
    933			.addr = 0x51,
    934			.flags = 0,
    935			.buf = obuf,
    936			.len = 2,
    937		}, {
    938			.addr = 0x51,
    939			.flags = I2C_M_RD,
    940			.buf = ibuf,
    941			.len = 1,
    942
    943		}
    944	};
    945
    946	for (i = 0; i < 6; i++) {
    947		obuf[1] = 0xf0 + i;
    948		if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
    949			break;
    950		else
    951			mac[i] = ibuf[0];
    952	}
    953
    954	return 0;
    955}
    956
    957static int su3000_identify_state(struct usb_device *udev,
    958				 const struct dvb_usb_device_properties *props,
    959				 const struct dvb_usb_device_description **desc,
    960				 int *cold)
    961{
    962	info("%s", __func__);
    963
    964	*cold = 0;
    965	return 0;
    966}
    967
    968static int dw210x_set_voltage(struct dvb_frontend *fe,
    969			      enum fe_sec_voltage voltage)
    970{
    971	static u8 command_13v[] = {0x00, 0x01};
    972	static u8 command_18v[] = {0x01, 0x01};
    973	static u8 command_off[] = {0x00, 0x00};
    974	struct i2c_msg msg = {
    975		.addr = DW2102_VOLTAGE_CTRL,
    976		.flags = 0,
    977		.buf = command_off,
    978		.len = 2,
    979	};
    980
    981	struct dvb_usb_adapter *udev_adap =
    982		(struct dvb_usb_adapter *)(fe->dvb->priv);
    983	if (voltage == SEC_VOLTAGE_18)
    984		msg.buf = command_18v;
    985	else if (voltage == SEC_VOLTAGE_13)
    986		msg.buf = command_13v;
    987
    988	i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
    989
    990	return 0;
    991}
    992
    993static int s660_set_voltage(struct dvb_frontend *fe,
    994			    enum fe_sec_voltage voltage)
    995{
    996	struct dvb_usb_adapter *d =
    997		(struct dvb_usb_adapter *)(fe->dvb->priv);
    998	struct dw2102_state *st = (struct dw2102_state *)d->dev->priv;
    999
   1000	dw210x_set_voltage(fe, voltage);
   1001	if (st->old_set_voltage)
   1002		st->old_set_voltage(fe, voltage);
   1003
   1004	return 0;
   1005}
   1006
   1007static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon)
   1008{
   1009	static u8 led_off[] = { 0 };
   1010	static u8 led_on[] = { 1 };
   1011	struct i2c_msg msg = {
   1012		.addr = DW2102_LED_CTRL,
   1013		.flags = 0,
   1014		.buf = led_off,
   1015		.len = 1
   1016	};
   1017	struct dvb_usb_adapter *udev_adap =
   1018		(struct dvb_usb_adapter *)(fe->dvb->priv);
   1019
   1020	if (offon)
   1021		msg.buf = led_on;
   1022	i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
   1023}
   1024
   1025static int tt_s2_4600_read_status(struct dvb_frontend *fe,
   1026				  enum fe_status *status)
   1027{
   1028	struct dvb_usb_adapter *d =
   1029		(struct dvb_usb_adapter *)(fe->dvb->priv);
   1030	struct dw2102_state *st = (struct dw2102_state *)d->dev->priv;
   1031	int ret;
   1032
   1033	ret = st->fe_read_status(fe, status);
   1034
   1035	/* resync slave fifo when signal change from unlock to lock */
   1036	if ((*status & FE_HAS_LOCK) && (!st->last_lock))
   1037		su3000_streaming_ctrl(d, 1);
   1038
   1039	st->last_lock = (*status & FE_HAS_LOCK) ? 1 : 0;
   1040	return ret;
   1041}
   1042
   1043static struct stv0299_config sharp_z0194a_config = {
   1044	.demod_address = 0x68,
   1045	.inittab = sharp_z0194a_inittab,
   1046	.mclk = 88000000UL,
   1047	.invert = 1,
   1048	.skip_reinit = 0,
   1049	.lock_output = STV0299_LOCKOUTPUT_1,
   1050	.volt13_op0_op1 = STV0299_VOLT13_OP1,
   1051	.min_delay_ms = 100,
   1052	.set_symbol_rate = sharp_z0194a_set_symbol_rate,
   1053};
   1054
   1055static struct cx24116_config dw2104_config = {
   1056	.demod_address = 0x55,
   1057	.mpg_clk_pos_pol = 0x01,
   1058};
   1059
   1060static struct si21xx_config serit_sp1511lhb_config = {
   1061	.demod_address = 0x68,
   1062	.min_delay_ms = 100,
   1063
   1064};
   1065
   1066static struct tda10023_config dw3101_tda10023_config = {
   1067	.demod_address = 0x0c,
   1068	.invert = 1,
   1069};
   1070
   1071static struct mt312_config zl313_config = {
   1072	.demod_address = 0x0e,
   1073};
   1074
   1075static struct ds3000_config dw2104_ds3000_config = {
   1076	.demod_address = 0x68,
   1077};
   1078
   1079static struct ts2020_config dw2104_ts2020_config = {
   1080	.tuner_address = 0x60,
   1081	.clk_out_div = 1,
   1082	.frequency_div = 1060000,
   1083};
   1084
   1085static struct ds3000_config s660_ds3000_config = {
   1086	.demod_address = 0x68,
   1087	.ci_mode = 1,
   1088	.set_lock_led = dw210x_led_ctrl,
   1089};
   1090
   1091static struct ts2020_config s660_ts2020_config = {
   1092	.tuner_address = 0x60,
   1093	.clk_out_div = 1,
   1094	.frequency_div = 1146000,
   1095};
   1096
   1097static struct stv0900_config dw2104a_stv0900_config = {
   1098	.demod_address = 0x6a,
   1099	.demod_mode = 0,
   1100	.xtal = 27000000,
   1101	.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
   1102	.diseqc_mode = 2,/* 2/3 PWM */
   1103	.tun1_maddress = 0,/* 0x60 */
   1104	.tun1_adc = 0,/* 2 Vpp */
   1105	.path1_mode = 3,
   1106};
   1107
   1108static struct stb6100_config dw2104a_stb6100_config = {
   1109	.tuner_address = 0x60,
   1110	.refclock = 27000000,
   1111};
   1112
   1113static struct stv0900_config dw2104_stv0900_config = {
   1114	.demod_address = 0x68,
   1115	.demod_mode = 0,
   1116	.xtal = 8000000,
   1117	.clkmode = 3,
   1118	.diseqc_mode = 2,
   1119	.tun1_maddress = 0,
   1120	.tun1_adc = 1,/* 1 Vpp */
   1121	.path1_mode = 3,
   1122};
   1123
   1124static struct stv6110_config dw2104_stv6110_config = {
   1125	.i2c_address = 0x60,
   1126	.mclk = 16000000,
   1127	.clk_div = 1,
   1128};
   1129
   1130static struct stv0900_config prof_7500_stv0900_config = {
   1131	.demod_address = 0x6a,
   1132	.demod_mode = 0,
   1133	.xtal = 27000000,
   1134	.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
   1135	.diseqc_mode = 2,/* 2/3 PWM */
   1136	.tun1_maddress = 0,/* 0x60 */
   1137	.tun1_adc = 0,/* 2 Vpp */
   1138	.path1_mode = 3,
   1139	.tun1_type = 3,
   1140	.set_lock_led = dw210x_led_ctrl,
   1141};
   1142
   1143static struct ds3000_config su3000_ds3000_config = {
   1144	.demod_address = 0x68,
   1145	.ci_mode = 1,
   1146	.set_lock_led = dw210x_led_ctrl,
   1147};
   1148
   1149static struct cxd2820r_config cxd2820r_config = {
   1150	.i2c_address = 0x6c, /* (0xd8 >> 1) */
   1151	.ts_mode = 0x38,
   1152	.ts_clock_inv = 1,
   1153};
   1154
   1155static struct tda18271_config tda18271_config = {
   1156	.output_opt = TDA18271_OUTPUT_LT_OFF,
   1157	.gate = TDA18271_GATE_DIGITAL,
   1158};
   1159
   1160static u8 m88rs2000_inittab[] = {
   1161	DEMOD_WRITE, 0x9a, 0x30,
   1162	DEMOD_WRITE, 0x00, 0x01,
   1163	WRITE_DELAY, 0x19, 0x00,
   1164	DEMOD_WRITE, 0x00, 0x00,
   1165	DEMOD_WRITE, 0x9a, 0xb0,
   1166	DEMOD_WRITE, 0x81, 0xc1,
   1167	DEMOD_WRITE, 0x81, 0x81,
   1168	DEMOD_WRITE, 0x86, 0xc6,
   1169	DEMOD_WRITE, 0x9a, 0x30,
   1170	DEMOD_WRITE, 0xf0, 0x80,
   1171	DEMOD_WRITE, 0xf1, 0xbf,
   1172	DEMOD_WRITE, 0xb0, 0x45,
   1173	DEMOD_WRITE, 0xb2, 0x01,
   1174	DEMOD_WRITE, 0x9a, 0xb0,
   1175	0xff, 0xaa, 0xff
   1176};
   1177
   1178static struct m88rs2000_config s421_m88rs2000_config = {
   1179	.demod_addr = 0x68,
   1180	.inittab = m88rs2000_inittab,
   1181};
   1182
   1183static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
   1184{
   1185	struct dvb_tuner_ops *tuner_ops = NULL;
   1186
   1187	if (demod_probe & 4) {
   1188		d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
   1189				&d->dev->i2c_adap, 0);
   1190		if (d->fe_adap[0].fe != NULL) {
   1191			if (dvb_attach(stb6100_attach, d->fe_adap[0].fe,
   1192					&dw2104a_stb6100_config,
   1193					&d->dev->i2c_adap)) {
   1194				tuner_ops = &d->fe_adap[0].fe->ops.tuner_ops;
   1195				tuner_ops->set_frequency = stb6100_set_freq;
   1196				tuner_ops->get_frequency = stb6100_get_freq;
   1197				tuner_ops->set_bandwidth = stb6100_set_bandw;
   1198				tuner_ops->get_bandwidth = stb6100_get_bandw;
   1199				d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
   1200				info("Attached STV0900+STB6100!");
   1201				return 0;
   1202			}
   1203		}
   1204	}
   1205
   1206	if (demod_probe & 2) {
   1207		d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
   1208				&d->dev->i2c_adap, 0);
   1209		if (d->fe_adap[0].fe != NULL) {
   1210			if (dvb_attach(stv6110_attach, d->fe_adap[0].fe,
   1211					&dw2104_stv6110_config,
   1212					&d->dev->i2c_adap)) {
   1213				d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
   1214				info("Attached STV0900+STV6110A!");
   1215				return 0;
   1216			}
   1217		}
   1218	}
   1219
   1220	if (demod_probe & 1) {
   1221		d->fe_adap[0].fe = dvb_attach(cx24116_attach, &dw2104_config,
   1222				&d->dev->i2c_adap);
   1223		if (d->fe_adap[0].fe != NULL) {
   1224			d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
   1225			info("Attached cx24116!");
   1226			return 0;
   1227		}
   1228	}
   1229
   1230	d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
   1231			&d->dev->i2c_adap);
   1232	if (d->fe_adap[0].fe != NULL) {
   1233		dvb_attach(ts2020_attach, d->fe_adap[0].fe,
   1234			&dw2104_ts2020_config, &d->dev->i2c_adap);
   1235		d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
   1236		info("Attached DS3000!");
   1237		return 0;
   1238	}
   1239
   1240	return -EIO;
   1241}
   1242
   1243static struct dvb_usb_device_properties dw2102_properties;
   1244static struct dvb_usb_device_properties dw2104_properties;
   1245static struct dvb_usb_device_properties s6x0_properties;
   1246
   1247static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
   1248{
   1249	if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) {
   1250		/*dw2102_properties.adapter->tuner_attach = NULL;*/
   1251		d->fe_adap[0].fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config,
   1252					&d->dev->i2c_adap);
   1253		if (d->fe_adap[0].fe != NULL) {
   1254			d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
   1255			info("Attached si21xx!");
   1256			return 0;
   1257		}
   1258	}
   1259
   1260	if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
   1261		d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config,
   1262					&d->dev->i2c_adap);
   1263		if (d->fe_adap[0].fe != NULL) {
   1264			if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61,
   1265					&d->dev->i2c_adap)) {
   1266				d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
   1267				info("Attached stv0288!");
   1268				return 0;
   1269			}
   1270		}
   1271	}
   1272
   1273	if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) {
   1274		/*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
   1275		d->fe_adap[0].fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
   1276					&d->dev->i2c_adap);
   1277		if (d->fe_adap[0].fe != NULL) {
   1278			d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
   1279			info("Attached stv0299!");
   1280			return 0;
   1281		}
   1282	}
   1283	return -EIO;
   1284}
   1285
   1286static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
   1287{
   1288	d->fe_adap[0].fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
   1289				&d->dev->i2c_adap, 0x48);
   1290	if (d->fe_adap[0].fe != NULL) {
   1291		info("Attached tda10023!");
   1292		return 0;
   1293	}
   1294	return -EIO;
   1295}
   1296
   1297static int zl100313_frontend_attach(struct dvb_usb_adapter *d)
   1298{
   1299	d->fe_adap[0].fe = dvb_attach(mt312_attach, &zl313_config,
   1300			&d->dev->i2c_adap);
   1301	if (d->fe_adap[0].fe != NULL) {
   1302		if (dvb_attach(zl10039_attach, d->fe_adap[0].fe, 0x60,
   1303				&d->dev->i2c_adap)) {
   1304			d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
   1305			info("Attached zl100313+zl10039!");
   1306			return 0;
   1307		}
   1308	}
   1309
   1310	return -EIO;
   1311}
   1312
   1313static int stv0288_frontend_attach(struct dvb_usb_adapter *d)
   1314{
   1315	u8 obuf[] = {7, 1};
   1316
   1317	d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config,
   1318			&d->dev->i2c_adap);
   1319
   1320	if (d->fe_adap[0].fe == NULL)
   1321		return -EIO;
   1322
   1323	if (NULL == dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, &d->dev->i2c_adap))
   1324		return -EIO;
   1325
   1326	d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
   1327
   1328	dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
   1329
   1330	info("Attached stv0288+stb6000!");
   1331
   1332	return 0;
   1333
   1334}
   1335
   1336static int ds3000_frontend_attach(struct dvb_usb_adapter *d)
   1337{
   1338	struct dw2102_state *st = d->dev->priv;
   1339	u8 obuf[] = {7, 1};
   1340
   1341	d->fe_adap[0].fe = dvb_attach(ds3000_attach, &s660_ds3000_config,
   1342			&d->dev->i2c_adap);
   1343
   1344	if (d->fe_adap[0].fe == NULL)
   1345		return -EIO;
   1346
   1347	dvb_attach(ts2020_attach, d->fe_adap[0].fe, &s660_ts2020_config,
   1348		&d->dev->i2c_adap);
   1349
   1350	st->old_set_voltage = d->fe_adap[0].fe->ops.set_voltage;
   1351	d->fe_adap[0].fe->ops.set_voltage = s660_set_voltage;
   1352
   1353	dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
   1354
   1355	info("Attached ds3000+ts2020!");
   1356
   1357	return 0;
   1358}
   1359
   1360static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
   1361{
   1362	u8 obuf[] = {7, 1};
   1363
   1364	d->fe_adap[0].fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config,
   1365					&d->dev->i2c_adap, 0);
   1366	if (d->fe_adap[0].fe == NULL)
   1367		return -EIO;
   1368
   1369	d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
   1370
   1371	dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
   1372
   1373	info("Attached STV0900+STB6100A!");
   1374
   1375	return 0;
   1376}
   1377
   1378static int su3000_frontend_attach(struct dvb_usb_adapter *adap)
   1379{
   1380	struct dvb_usb_device *d = adap->dev;
   1381	struct dw2102_state *state = d->priv;
   1382
   1383	mutex_lock(&d->data_mutex);
   1384
   1385	state->data[0] = 0xe;
   1386	state->data[1] = 0x80;
   1387	state->data[2] = 0;
   1388
   1389	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
   1390		err("command 0x0e transfer failed.");
   1391
   1392	state->data[0] = 0xe;
   1393	state->data[1] = 0x02;
   1394	state->data[2] = 1;
   1395
   1396	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
   1397		err("command 0x0e transfer failed.");
   1398	msleep(300);
   1399
   1400	state->data[0] = 0xe;
   1401	state->data[1] = 0x83;
   1402	state->data[2] = 0;
   1403
   1404	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
   1405		err("command 0x0e transfer failed.");
   1406
   1407	state->data[0] = 0xe;
   1408	state->data[1] = 0x83;
   1409	state->data[2] = 1;
   1410
   1411	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
   1412		err("command 0x0e transfer failed.");
   1413
   1414	state->data[0] = 0x51;
   1415
   1416	if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
   1417		err("command 0x51 transfer failed.");
   1418
   1419	mutex_unlock(&d->data_mutex);
   1420
   1421	adap->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
   1422					&d->i2c_adap);
   1423	if (adap->fe_adap[0].fe == NULL)
   1424		return -EIO;
   1425
   1426	if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe,
   1427				&dw2104_ts2020_config,
   1428				&d->i2c_adap)) {
   1429		info("Attached DS3000/TS2020!");
   1430		return 0;
   1431	}
   1432
   1433	info("Failed to attach DS3000/TS2020!");
   1434	return -EIO;
   1435}
   1436
   1437static int t220_frontend_attach(struct dvb_usb_adapter *adap)
   1438{
   1439	struct dvb_usb_device *d = adap->dev;
   1440	struct dw2102_state *state = d->priv;
   1441
   1442	mutex_lock(&d->data_mutex);
   1443
   1444	state->data[0] = 0xe;
   1445	state->data[1] = 0x87;
   1446	state->data[2] = 0x0;
   1447
   1448	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
   1449		err("command 0x0e transfer failed.");
   1450
   1451	state->data[0] = 0xe;
   1452	state->data[1] = 0x86;
   1453	state->data[2] = 1;
   1454
   1455	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
   1456		err("command 0x0e transfer failed.");
   1457
   1458	state->data[0] = 0xe;
   1459	state->data[1] = 0x80;
   1460	state->data[2] = 0;
   1461
   1462	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
   1463		err("command 0x0e transfer failed.");
   1464
   1465	msleep(50);
   1466
   1467	state->data[0] = 0xe;
   1468	state->data[1] = 0x80;
   1469	state->data[2] = 1;
   1470
   1471	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
   1472		err("command 0x0e transfer failed.");
   1473
   1474	state->data[0] = 0x51;
   1475
   1476	if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
   1477		err("command 0x51 transfer failed.");
   1478
   1479	mutex_unlock(&d->data_mutex);
   1480
   1481	adap->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config,
   1482					&d->i2c_adap, NULL);
   1483	if (adap->fe_adap[0].fe != NULL) {
   1484		if (dvb_attach(tda18271_attach, adap->fe_adap[0].fe, 0x60,
   1485					&d->i2c_adap, &tda18271_config)) {
   1486			info("Attached TDA18271HD/CXD2820R!");
   1487			return 0;
   1488		}
   1489	}
   1490
   1491	info("Failed to attach TDA18271HD/CXD2820R!");
   1492	return -EIO;
   1493}
   1494
   1495static int m88rs2000_frontend_attach(struct dvb_usb_adapter *adap)
   1496{
   1497	struct dvb_usb_device *d = adap->dev;
   1498	struct dw2102_state *state = d->priv;
   1499
   1500	mutex_lock(&d->data_mutex);
   1501
   1502	state->data[0] = 0x51;
   1503
   1504	if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
   1505		err("command 0x51 transfer failed.");
   1506
   1507	mutex_unlock(&d->data_mutex);
   1508
   1509	adap->fe_adap[0].fe = dvb_attach(m88rs2000_attach,
   1510					&s421_m88rs2000_config,
   1511					&d->i2c_adap);
   1512
   1513	if (adap->fe_adap[0].fe == NULL)
   1514		return -EIO;
   1515
   1516	if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe,
   1517				&dw2104_ts2020_config,
   1518				&d->i2c_adap)) {
   1519		info("Attached RS2000/TS2020!");
   1520		return 0;
   1521	}
   1522
   1523	info("Failed to attach RS2000/TS2020!");
   1524	return -EIO;
   1525}
   1526
   1527static int tt_s2_4600_frontend_attach_probe_demod(struct dvb_usb_device *d,
   1528						  const int probe_addr)
   1529{
   1530	struct dw2102_state *state = d->priv;
   1531
   1532	state->data[0] = 0x9;
   1533	state->data[1] = 0x1;
   1534	state->data[2] = 0x1;
   1535	state->data[3] = probe_addr;
   1536	state->data[4] = 0x0;
   1537
   1538	if (dvb_usb_generic_rw(d, state->data, 5, state->data, 2, 0) < 0) {
   1539		err("i2c probe for address 0x%x failed.", probe_addr);
   1540		return 0;
   1541	}
   1542
   1543	if (state->data[0] != 8) /* fail(7) or error, no device at address */
   1544		return 0;
   1545
   1546	/* probing successful */
   1547	return 1;
   1548}
   1549
   1550static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap)
   1551{
   1552	struct dvb_usb_device *d = adap->dev;
   1553	struct dw2102_state *state = d->priv;
   1554	struct i2c_adapter *i2c_adapter;
   1555	struct i2c_client *client;
   1556	struct i2c_board_info board_info;
   1557	struct m88ds3103_platform_data m88ds3103_pdata = {};
   1558	struct ts2020_config ts2020_config = {};
   1559	int demod_addr;
   1560
   1561	mutex_lock(&d->data_mutex);
   1562
   1563	state->data[0] = 0xe;
   1564	state->data[1] = 0x80;
   1565	state->data[2] = 0x0;
   1566
   1567	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
   1568		err("command 0x0e transfer failed.");
   1569
   1570	state->data[0] = 0xe;
   1571	state->data[1] = 0x02;
   1572	state->data[2] = 1;
   1573
   1574	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
   1575		err("command 0x0e transfer failed.");
   1576	msleep(300);
   1577
   1578	state->data[0] = 0xe;
   1579	state->data[1] = 0x83;
   1580	state->data[2] = 0;
   1581
   1582	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
   1583		err("command 0x0e transfer failed.");
   1584
   1585	state->data[0] = 0xe;
   1586	state->data[1] = 0x83;
   1587	state->data[2] = 1;
   1588
   1589	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
   1590		err("command 0x0e transfer failed.");
   1591
   1592	state->data[0] = 0x51;
   1593
   1594	if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
   1595		err("command 0x51 transfer failed.");
   1596
   1597	/* probe for demodulator i2c address */
   1598	demod_addr = -1;
   1599	if (tt_s2_4600_frontend_attach_probe_demod(d, 0x68))
   1600		demod_addr = 0x68;
   1601	else if (tt_s2_4600_frontend_attach_probe_demod(d, 0x69))
   1602		demod_addr = 0x69;
   1603	else if (tt_s2_4600_frontend_attach_probe_demod(d, 0x6a))
   1604		demod_addr = 0x6a;
   1605
   1606	mutex_unlock(&d->data_mutex);
   1607
   1608	if (demod_addr < 0) {
   1609		err("probing for demodulator failed. Is the external power switched on?");
   1610		return -ENODEV;
   1611	}
   1612
   1613	/* attach demod */
   1614	m88ds3103_pdata.clk = 27000000;
   1615	m88ds3103_pdata.i2c_wr_max = 33;
   1616	m88ds3103_pdata.ts_mode = M88DS3103_TS_CI;
   1617	m88ds3103_pdata.ts_clk = 16000;
   1618	m88ds3103_pdata.ts_clk_pol = 0;
   1619	m88ds3103_pdata.spec_inv = 0;
   1620	m88ds3103_pdata.agc = 0x99;
   1621	m88ds3103_pdata.agc_inv = 0;
   1622	m88ds3103_pdata.clk_out = M88DS3103_CLOCK_OUT_ENABLED;
   1623	m88ds3103_pdata.envelope_mode = 0;
   1624	m88ds3103_pdata.lnb_hv_pol = 1;
   1625	m88ds3103_pdata.lnb_en_pol = 0;
   1626	memset(&board_info, 0, sizeof(board_info));
   1627	if (demod_addr == 0x6a)
   1628		strscpy(board_info.type, "m88ds3103b", I2C_NAME_SIZE);
   1629	else
   1630		strscpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
   1631	board_info.addr = demod_addr;
   1632	board_info.platform_data = &m88ds3103_pdata;
   1633	request_module("m88ds3103");
   1634	client = i2c_new_client_device(&d->i2c_adap, &board_info);
   1635	if (!i2c_client_has_driver(client))
   1636		return -ENODEV;
   1637	if (!try_module_get(client->dev.driver->owner)) {
   1638		i2c_unregister_device(client);
   1639		return -ENODEV;
   1640	}
   1641	adap->fe_adap[0].fe = m88ds3103_pdata.get_dvb_frontend(client);
   1642	i2c_adapter = m88ds3103_pdata.get_i2c_adapter(client);
   1643
   1644	state->i2c_client_demod = client;
   1645
   1646	/* attach tuner */
   1647	ts2020_config.fe = adap->fe_adap[0].fe;
   1648	memset(&board_info, 0, sizeof(board_info));
   1649	strscpy(board_info.type, "ts2022", I2C_NAME_SIZE);
   1650	board_info.addr = 0x60;
   1651	board_info.platform_data = &ts2020_config;
   1652	request_module("ts2020");
   1653	client = i2c_new_client_device(i2c_adapter, &board_info);
   1654
   1655	if (!i2c_client_has_driver(client)) {
   1656		dvb_frontend_detach(adap->fe_adap[0].fe);
   1657		return -ENODEV;
   1658	}
   1659
   1660	if (!try_module_get(client->dev.driver->owner)) {
   1661		i2c_unregister_device(client);
   1662		dvb_frontend_detach(adap->fe_adap[0].fe);
   1663		return -ENODEV;
   1664	}
   1665
   1666	/* delegate signal strength measurement to tuner */
   1667	adap->fe_adap[0].fe->ops.read_signal_strength =
   1668			adap->fe_adap[0].fe->ops.tuner_ops.get_rf_strength;
   1669
   1670	state->i2c_client_tuner = client;
   1671
   1672	/* hook fe: need to resync the slave fifo when signal locks */
   1673	state->fe_read_status = adap->fe_adap[0].fe->ops.read_status;
   1674	adap->fe_adap[0].fe->ops.read_status = tt_s2_4600_read_status;
   1675
   1676	state->last_lock = 0;
   1677
   1678	return 0;
   1679}
   1680
   1681static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
   1682{
   1683	dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
   1684		&adap->dev->i2c_adap, DVB_PLL_OPERA1);
   1685	return 0;
   1686}
   1687
   1688static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
   1689{
   1690	dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
   1691		&adap->dev->i2c_adap, DVB_PLL_TUA6034);
   1692
   1693	return 0;
   1694}
   1695
   1696static int dw2102_rc_query(struct dvb_usb_device *d)
   1697{
   1698	u8 key[2];
   1699	struct i2c_msg msg = {
   1700		.addr = DW2102_RC_QUERY,
   1701		.flags = I2C_M_RD,
   1702		.buf = key,
   1703		.len = 2
   1704	};
   1705
   1706	if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
   1707		if (msg.buf[0] != 0xff) {
   1708			deb_rc("%s: rc code: %x, %x\n",
   1709					__func__, key[0], key[1]);
   1710			rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, key[0], 0);
   1711		}
   1712	}
   1713
   1714	return 0;
   1715}
   1716
   1717static int prof_rc_query(struct dvb_usb_device *d)
   1718{
   1719	u8 key[2];
   1720	struct i2c_msg msg = {
   1721		.addr = DW2102_RC_QUERY,
   1722		.flags = I2C_M_RD,
   1723		.buf = key,
   1724		.len = 2
   1725	};
   1726
   1727	if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
   1728		if (msg.buf[0] != 0xff) {
   1729			deb_rc("%s: rc code: %x, %x\n",
   1730					__func__, key[0], key[1]);
   1731			rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, key[0] ^ 0xff,
   1732				   0);
   1733		}
   1734	}
   1735
   1736	return 0;
   1737}
   1738
   1739static int su3000_rc_query(struct dvb_usb_device *d)
   1740{
   1741	u8 key[2];
   1742	struct i2c_msg msg = {
   1743		.addr = DW2102_RC_QUERY,
   1744		.flags = I2C_M_RD,
   1745		.buf = key,
   1746		.len = 2
   1747	};
   1748
   1749	if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
   1750		if (msg.buf[0] != 0xff) {
   1751			deb_rc("%s: rc code: %x, %x\n",
   1752					__func__, key[0], key[1]);
   1753			rc_keydown(d->rc_dev, RC_PROTO_RC5,
   1754				   RC_SCANCODE_RC5(key[1], key[0]), 0);
   1755		}
   1756	}
   1757
   1758	return 0;
   1759}
   1760
   1761enum dw2102_table_entry {
   1762	CYPRESS_DW2102,
   1763	CYPRESS_DW2101,
   1764	CYPRESS_DW2104,
   1765	TEVII_S650,
   1766	TERRATEC_CINERGY_S,
   1767	CYPRESS_DW3101,
   1768	TEVII_S630,
   1769	PROF_1100,
   1770	TEVII_S660,
   1771	PROF_7500,
   1772	GENIATECH_SU3000,
   1773	HAUPPAUGE_MAX_S2,
   1774	TERRATEC_CINERGY_S2_R1,
   1775	TEVII_S480_1,
   1776	TEVII_S480_2,
   1777	GENIATECH_X3M_SPC1400HD,
   1778	TEVII_S421,
   1779	TEVII_S632,
   1780	TERRATEC_CINERGY_S2_R2,
   1781	TERRATEC_CINERGY_S2_R3,
   1782	TERRATEC_CINERGY_S2_R4,
   1783	TERRATEC_CINERGY_S2_1,
   1784	TERRATEC_CINERGY_S2_2,
   1785	GOTVIEW_SAT_HD,
   1786	GENIATECH_T220,
   1787	TECHNOTREND_CONNECT_S2_4600,
   1788	TEVII_S482_1,
   1789	TEVII_S482_2,
   1790	TERRATEC_CINERGY_S2_BOX,
   1791	TEVII_S662
   1792};
   1793
   1794static struct usb_device_id dw2102_table[] = {
   1795	DVB_USB_DEV(CYPRESS, CYPRESS_DW2102),
   1796	DVB_USB_DEV(CYPRESS, CYPRESS_DW2101),
   1797	DVB_USB_DEV(CYPRESS, CYPRESS_DW2104),
   1798	DVB_USB_DEV(TEVII, TEVII_S650),
   1799	DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S),
   1800	DVB_USB_DEV(CYPRESS, CYPRESS_DW3101),
   1801	DVB_USB_DEV(TEVII, TEVII_S630),
   1802	DVB_USB_DEV(PROF_1, PROF_1100),
   1803	DVB_USB_DEV(TEVII, TEVII_S660),
   1804	DVB_USB_DEV(PROF_2, PROF_7500),
   1805	DVB_USB_DEV(GTEK, GENIATECH_SU3000),
   1806	DVB_USB_DEV(HAUPPAUGE, HAUPPAUGE_MAX_S2),
   1807	DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S2_R1),
   1808	DVB_USB_DEV(TEVII, TEVII_S480_1),
   1809	DVB_USB_DEV(TEVII, TEVII_S480_2),
   1810	DVB_USB_DEV(GTEK, GENIATECH_X3M_SPC1400HD),
   1811	DVB_USB_DEV(TEVII, TEVII_S421),
   1812	DVB_USB_DEV(TEVII, TEVII_S632),
   1813	DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S2_R2),
   1814	DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S2_R3),
   1815	DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S2_R4),
   1816	DVB_USB_DEV(TERRATEC_2, TERRATEC_CINERGY_S2_1),
   1817	DVB_USB_DEV(TERRATEC_2, TERRATEC_CINERGY_S2_2),
   1818	DVB_USB_DEV(GOTVIEW, GOTVIEW_SAT_HD),
   1819	DVB_USB_DEV(GTEK, GENIATECH_T220),
   1820	DVB_USB_DEV(TECHNOTREND, TECHNOTREND_CONNECT_S2_4600),
   1821	DVB_USB_DEV(TEVII, TEVII_S482_1),
   1822	DVB_USB_DEV(TEVII, TEVII_S482_2),
   1823	DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S2_BOX),
   1824	DVB_USB_DEV(TEVII, TEVII_S662),
   1825	{ }
   1826};
   1827
   1828MODULE_DEVICE_TABLE(usb, dw2102_table);
   1829
   1830static int dw2102_load_firmware(struct usb_device *dev,
   1831			const struct firmware *frmwr)
   1832{
   1833	u8 *b, *p;
   1834	int ret = 0, i;
   1835	u8 reset;
   1836	u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
   1837	const struct firmware *fw;
   1838
   1839	switch (le16_to_cpu(dev->descriptor.idProduct)) {
   1840	case 0x2101:
   1841		ret = request_firmware(&fw, DW2101_FIRMWARE, &dev->dev);
   1842		if (ret != 0) {
   1843			err(err_str, DW2101_FIRMWARE);
   1844			return ret;
   1845		}
   1846		break;
   1847	default:
   1848		fw = frmwr;
   1849		break;
   1850	}
   1851	info("start downloading DW210X firmware");
   1852	p = kmalloc(fw->size, GFP_KERNEL);
   1853	reset = 1;
   1854	/*stop the CPU*/
   1855	dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG);
   1856	dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG);
   1857
   1858	if (p != NULL) {
   1859		memcpy(p, fw->data, fw->size);
   1860		for (i = 0; i < fw->size; i += 0x40) {
   1861			b = (u8 *) p + i;
   1862			if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40,
   1863					DW210X_WRITE_MSG) != 0x40) {
   1864				err("error while transferring firmware");
   1865				ret = -EINVAL;
   1866				break;
   1867			}
   1868		}
   1869		/* restart the CPU */
   1870		reset = 0;
   1871		if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1,
   1872					DW210X_WRITE_MSG) != 1) {
   1873			err("could not restart the USB controller CPU.");
   1874			ret = -EINVAL;
   1875		}
   1876		if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1,
   1877					DW210X_WRITE_MSG) != 1) {
   1878			err("could not restart the USB controller CPU.");
   1879			ret = -EINVAL;
   1880		}
   1881		/* init registers */
   1882		switch (le16_to_cpu(dev->descriptor.idProduct)) {
   1883		case USB_PID_TEVII_S650:
   1884			dw2104_properties.rc.core.rc_codes = RC_MAP_TEVII_NEC;
   1885			fallthrough;
   1886		case USB_PID_CYPRESS_DW2104:
   1887			reset = 1;
   1888			dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
   1889					DW210X_WRITE_MSG);
   1890			fallthrough;
   1891		case USB_PID_CYPRESS_DW3101:
   1892			reset = 0;
   1893			dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
   1894					DW210X_WRITE_MSG);
   1895			break;
   1896		case USB_PID_TERRATEC_CINERGY_S:
   1897		case USB_PID_CYPRESS_DW2102:
   1898			dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
   1899					DW210X_WRITE_MSG);
   1900			dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
   1901					DW210X_READ_MSG);
   1902			/* check STV0299 frontend  */
   1903			dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
   1904					DW210X_READ_MSG);
   1905			if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) {
   1906				dw2102_properties.i2c_algo = &dw2102_i2c_algo;
   1907				dw2102_properties.adapter->fe[0].tuner_attach = &dw2102_tuner_attach;
   1908				break;
   1909			} else {
   1910				/* check STV0288 frontend  */
   1911				reset16[0] = 0xd0;
   1912				reset16[1] = 1;
   1913				reset16[2] = 0;
   1914				dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3,
   1915						DW210X_WRITE_MSG);
   1916				dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3,
   1917						DW210X_READ_MSG);
   1918				if (reset16[2] == 0x11) {
   1919					dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
   1920					break;
   1921				}
   1922			}
   1923			fallthrough;
   1924		case 0x2101:
   1925			dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
   1926					DW210X_READ_MSG);
   1927			dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
   1928					DW210X_READ_MSG);
   1929			dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
   1930					DW210X_READ_MSG);
   1931			dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
   1932					DW210X_READ_MSG);
   1933			break;
   1934		}
   1935
   1936		msleep(100);
   1937		kfree(p);
   1938	}
   1939
   1940	if (le16_to_cpu(dev->descriptor.idProduct) == 0x2101)
   1941		release_firmware(fw);
   1942	return ret;
   1943}
   1944
   1945static struct dvb_usb_device_properties dw2102_properties = {
   1946	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
   1947	.usb_ctrl = DEVICE_SPECIFIC,
   1948	.firmware = DW2102_FIRMWARE,
   1949	.no_reconnect = 1,
   1950
   1951	.i2c_algo = &dw2102_serit_i2c_algo,
   1952
   1953	.rc.core = {
   1954		.rc_interval = 150,
   1955		.rc_codes = RC_MAP_DM1105_NEC,
   1956		.module_name = "dw2102",
   1957		.allowed_protos   = RC_PROTO_BIT_NEC,
   1958		.rc_query = dw2102_rc_query,
   1959	},
   1960
   1961	.generic_bulk_ctrl_endpoint = 0x81,
   1962	/* parameter for the MPEG2-data transfer */
   1963	.num_adapters = 1,
   1964	.download_firmware = dw2102_load_firmware,
   1965	.read_mac_address = dw210x_read_mac_address,
   1966	.adapter = {
   1967		{
   1968		.num_frontends = 1,
   1969		.fe = {{
   1970			.frontend_attach = dw2102_frontend_attach,
   1971			.stream = {
   1972				.type = USB_BULK,
   1973				.count = 8,
   1974				.endpoint = 0x82,
   1975				.u = {
   1976					.bulk = {
   1977						.buffersize = 4096,
   1978					}
   1979				}
   1980			},
   1981		}},
   1982		}
   1983	},
   1984	.num_device_descs = 3,
   1985	.devices = {
   1986		{"DVBWorld DVB-S 2102 USB2.0",
   1987			{&dw2102_table[CYPRESS_DW2102], NULL},
   1988			{NULL},
   1989		},
   1990		{"DVBWorld DVB-S 2101 USB2.0",
   1991			{&dw2102_table[CYPRESS_DW2101], NULL},
   1992			{NULL},
   1993		},
   1994		{"TerraTec Cinergy S USB",
   1995			{&dw2102_table[TERRATEC_CINERGY_S], NULL},
   1996			{NULL},
   1997		},
   1998	}
   1999};
   2000
   2001static struct dvb_usb_device_properties dw2104_properties = {
   2002	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
   2003	.usb_ctrl = DEVICE_SPECIFIC,
   2004	.firmware = DW2104_FIRMWARE,
   2005	.no_reconnect = 1,
   2006
   2007	.i2c_algo = &dw2104_i2c_algo,
   2008	.rc.core = {
   2009		.rc_interval = 150,
   2010		.rc_codes = RC_MAP_DM1105_NEC,
   2011		.module_name = "dw2102",
   2012		.allowed_protos   = RC_PROTO_BIT_NEC,
   2013		.rc_query = dw2102_rc_query,
   2014	},
   2015
   2016	.generic_bulk_ctrl_endpoint = 0x81,
   2017	/* parameter for the MPEG2-data transfer */
   2018	.num_adapters = 1,
   2019	.download_firmware = dw2102_load_firmware,
   2020	.read_mac_address = dw210x_read_mac_address,
   2021	.adapter = {
   2022		{
   2023		.num_frontends = 1,
   2024		.fe = {{
   2025			.frontend_attach = dw2104_frontend_attach,
   2026			.stream = {
   2027				.type = USB_BULK,
   2028				.count = 8,
   2029				.endpoint = 0x82,
   2030				.u = {
   2031					.bulk = {
   2032						.buffersize = 4096,
   2033					}
   2034				}
   2035			},
   2036		}},
   2037		}
   2038	},
   2039	.num_device_descs = 2,
   2040	.devices = {
   2041		{ "DVBWorld DW2104 USB2.0",
   2042			{&dw2102_table[CYPRESS_DW2104], NULL},
   2043			{NULL},
   2044		},
   2045		{ "TeVii S650 USB2.0",
   2046			{&dw2102_table[TEVII_S650], NULL},
   2047			{NULL},
   2048		},
   2049	}
   2050};
   2051
   2052static struct dvb_usb_device_properties dw3101_properties = {
   2053	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
   2054	.usb_ctrl = DEVICE_SPECIFIC,
   2055	.firmware = DW3101_FIRMWARE,
   2056	.no_reconnect = 1,
   2057
   2058	.i2c_algo = &dw3101_i2c_algo,
   2059	.rc.core = {
   2060		.rc_interval = 150,
   2061		.rc_codes = RC_MAP_DM1105_NEC,
   2062		.module_name = "dw2102",
   2063		.allowed_protos   = RC_PROTO_BIT_NEC,
   2064		.rc_query = dw2102_rc_query,
   2065	},
   2066
   2067	.generic_bulk_ctrl_endpoint = 0x81,
   2068	/* parameter for the MPEG2-data transfer */
   2069	.num_adapters = 1,
   2070	.download_firmware = dw2102_load_firmware,
   2071	.read_mac_address = dw210x_read_mac_address,
   2072	.adapter = {
   2073		{
   2074		.num_frontends = 1,
   2075		.fe = {{
   2076			.frontend_attach = dw3101_frontend_attach,
   2077			.tuner_attach = dw3101_tuner_attach,
   2078			.stream = {
   2079				.type = USB_BULK,
   2080				.count = 8,
   2081				.endpoint = 0x82,
   2082				.u = {
   2083					.bulk = {
   2084						.buffersize = 4096,
   2085					}
   2086				}
   2087			},
   2088		}},
   2089		}
   2090	},
   2091	.num_device_descs = 1,
   2092	.devices = {
   2093		{ "DVBWorld DVB-C 3101 USB2.0",
   2094			{&dw2102_table[CYPRESS_DW3101], NULL},
   2095			{NULL},
   2096		},
   2097	}
   2098};
   2099
   2100static struct dvb_usb_device_properties s6x0_properties = {
   2101	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
   2102	.usb_ctrl = DEVICE_SPECIFIC,
   2103	.size_of_priv = sizeof(struct dw2102_state),
   2104	.firmware = S630_FIRMWARE,
   2105	.no_reconnect = 1,
   2106
   2107	.i2c_algo = &s6x0_i2c_algo,
   2108	.rc.core = {
   2109		.rc_interval = 150,
   2110		.rc_codes = RC_MAP_TEVII_NEC,
   2111		.module_name = "dw2102",
   2112		.allowed_protos   = RC_PROTO_BIT_NEC,
   2113		.rc_query = dw2102_rc_query,
   2114	},
   2115
   2116	.generic_bulk_ctrl_endpoint = 0x81,
   2117	.num_adapters = 1,
   2118	.download_firmware = dw2102_load_firmware,
   2119	.read_mac_address = s6x0_read_mac_address,
   2120	.adapter = {
   2121		{
   2122		.num_frontends = 1,
   2123		.fe = {{
   2124			.frontend_attach = zl100313_frontend_attach,
   2125			.stream = {
   2126				.type = USB_BULK,
   2127				.count = 8,
   2128				.endpoint = 0x82,
   2129				.u = {
   2130					.bulk = {
   2131						.buffersize = 4096,
   2132					}
   2133				}
   2134			},
   2135		}},
   2136		}
   2137	},
   2138	.num_device_descs = 1,
   2139	.devices = {
   2140		{"TeVii S630 USB",
   2141			{&dw2102_table[TEVII_S630], NULL},
   2142			{NULL},
   2143		},
   2144	}
   2145};
   2146
   2147static struct dvb_usb_device_properties p1100_properties = {
   2148	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
   2149	.usb_ctrl = DEVICE_SPECIFIC,
   2150	.size_of_priv = sizeof(struct dw2102_state),
   2151	.firmware = P1100_FIRMWARE,
   2152	.no_reconnect = 1,
   2153
   2154	.i2c_algo = &s6x0_i2c_algo,
   2155	.rc.core = {
   2156		.rc_interval = 150,
   2157		.rc_codes = RC_MAP_TBS_NEC,
   2158		.module_name = "dw2102",
   2159		.allowed_protos   = RC_PROTO_BIT_NEC,
   2160		.rc_query = prof_rc_query,
   2161	},
   2162
   2163	.generic_bulk_ctrl_endpoint = 0x81,
   2164	.num_adapters = 1,
   2165	.download_firmware = dw2102_load_firmware,
   2166	.read_mac_address = s6x0_read_mac_address,
   2167	.adapter = {
   2168		{
   2169			.num_frontends = 1,
   2170			.fe = {{
   2171				.frontend_attach = stv0288_frontend_attach,
   2172				.stream = {
   2173					.type = USB_BULK,
   2174					.count = 8,
   2175					.endpoint = 0x82,
   2176					.u = {
   2177						.bulk = {
   2178							.buffersize = 4096,
   2179						}
   2180					}
   2181				},
   2182			} },
   2183		}
   2184	},
   2185	.num_device_descs = 1,
   2186	.devices = {
   2187		{"Prof 1100 USB ",
   2188			{&dw2102_table[PROF_1100], NULL},
   2189			{NULL},
   2190		},
   2191	}
   2192};
   2193
   2194static struct dvb_usb_device_properties s660_properties = {
   2195	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
   2196	.usb_ctrl = DEVICE_SPECIFIC,
   2197	.size_of_priv = sizeof(struct dw2102_state),
   2198	.firmware = S660_FIRMWARE,
   2199	.no_reconnect = 1,
   2200
   2201	.i2c_algo = &s6x0_i2c_algo,
   2202	.rc.core = {
   2203		.rc_interval = 150,
   2204		.rc_codes = RC_MAP_TEVII_NEC,
   2205		.module_name = "dw2102",
   2206		.allowed_protos   = RC_PROTO_BIT_NEC,
   2207		.rc_query = dw2102_rc_query,
   2208	},
   2209
   2210	.generic_bulk_ctrl_endpoint = 0x81,
   2211	.num_adapters = 1,
   2212	.download_firmware = dw2102_load_firmware,
   2213	.read_mac_address = s6x0_read_mac_address,
   2214	.adapter = {
   2215		{
   2216			.num_frontends = 1,
   2217			.fe = {{
   2218				.frontend_attach = ds3000_frontend_attach,
   2219				.stream = {
   2220					.type = USB_BULK,
   2221					.count = 8,
   2222					.endpoint = 0x82,
   2223					.u = {
   2224						.bulk = {
   2225							.buffersize = 4096,
   2226						}
   2227					}
   2228				},
   2229			} },
   2230		}
   2231	},
   2232	.num_device_descs = 3,
   2233	.devices = {
   2234		{"TeVii S660 USB",
   2235			{&dw2102_table[TEVII_S660], NULL},
   2236			{NULL},
   2237		},
   2238		{"TeVii S480.1 USB",
   2239			{&dw2102_table[TEVII_S480_1], NULL},
   2240			{NULL},
   2241		},
   2242		{"TeVii S480.2 USB",
   2243			{&dw2102_table[TEVII_S480_2], NULL},
   2244			{NULL},
   2245		},
   2246	}
   2247};
   2248
   2249static struct dvb_usb_device_properties p7500_properties = {
   2250	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
   2251	.usb_ctrl = DEVICE_SPECIFIC,
   2252	.size_of_priv = sizeof(struct dw2102_state),
   2253	.firmware = P7500_FIRMWARE,
   2254	.no_reconnect = 1,
   2255
   2256	.i2c_algo = &s6x0_i2c_algo,
   2257	.rc.core = {
   2258		.rc_interval = 150,
   2259		.rc_codes = RC_MAP_TBS_NEC,
   2260		.module_name = "dw2102",
   2261		.allowed_protos   = RC_PROTO_BIT_NEC,
   2262		.rc_query = prof_rc_query,
   2263	},
   2264
   2265	.generic_bulk_ctrl_endpoint = 0x81,
   2266	.num_adapters = 1,
   2267	.download_firmware = dw2102_load_firmware,
   2268	.read_mac_address = s6x0_read_mac_address,
   2269	.adapter = {
   2270		{
   2271			.num_frontends = 1,
   2272			.fe = {{
   2273				.frontend_attach = prof_7500_frontend_attach,
   2274				.stream = {
   2275					.type = USB_BULK,
   2276					.count = 8,
   2277					.endpoint = 0x82,
   2278					.u = {
   2279						.bulk = {
   2280							.buffersize = 4096,
   2281						}
   2282					}
   2283				},
   2284			} },
   2285		}
   2286	},
   2287	.num_device_descs = 1,
   2288	.devices = {
   2289		{"Prof 7500 USB DVB-S2",
   2290			{&dw2102_table[PROF_7500], NULL},
   2291			{NULL},
   2292		},
   2293	}
   2294};
   2295
   2296static struct dvb_usb_device_properties su3000_properties = {
   2297	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
   2298	.usb_ctrl = DEVICE_SPECIFIC,
   2299	.size_of_priv = sizeof(struct dw2102_state),
   2300	.power_ctrl = su3000_power_ctrl,
   2301	.num_adapters = 1,
   2302	.identify_state	= su3000_identify_state,
   2303	.i2c_algo = &su3000_i2c_algo,
   2304
   2305	.rc.core = {
   2306		.rc_interval = 150,
   2307		.rc_codes = RC_MAP_SU3000,
   2308		.module_name = "dw2102",
   2309		.allowed_protos   = RC_PROTO_BIT_RC5,
   2310		.rc_query = su3000_rc_query,
   2311	},
   2312
   2313	.read_mac_address = su3000_read_mac_address,
   2314
   2315	.generic_bulk_ctrl_endpoint = 0x01,
   2316
   2317	.adapter = {
   2318		{
   2319		.num_frontends = 1,
   2320		.fe = {{
   2321			.streaming_ctrl   = su3000_streaming_ctrl,
   2322			.frontend_attach  = su3000_frontend_attach,
   2323			.stream = {
   2324				.type = USB_BULK,
   2325				.count = 8,
   2326				.endpoint = 0x82,
   2327				.u = {
   2328					.bulk = {
   2329						.buffersize = 4096,
   2330					}
   2331				}
   2332			}
   2333		}},
   2334		}
   2335	},
   2336	.num_device_descs = 9,
   2337	.devices = {
   2338		{ "SU3000HD DVB-S USB2.0",
   2339			{ &dw2102_table[GENIATECH_SU3000], NULL },
   2340			{ NULL },
   2341		},
   2342		{ "Hauppauge MAX S2 or WinTV NOVA HD USB2.0",
   2343			{ &dw2102_table[HAUPPAUGE_MAX_S2], NULL },
   2344			{ NULL },
   2345		},
   2346		{ "Terratec Cinergy S2 USB HD",
   2347			{ &dw2102_table[TERRATEC_CINERGY_S2_R1], NULL },
   2348			{ NULL },
   2349		},
   2350		{ "X3M TV SPC1400HD PCI",
   2351			{ &dw2102_table[GENIATECH_X3M_SPC1400HD], NULL },
   2352			{ NULL },
   2353		},
   2354		{ "Terratec Cinergy S2 USB HD Rev.2",
   2355			{ &dw2102_table[TERRATEC_CINERGY_S2_R2], NULL },
   2356			{ NULL },
   2357		},
   2358		{ "Terratec Cinergy S2 USB HD Rev.3",
   2359			{ &dw2102_table[TERRATEC_CINERGY_S2_R3], NULL },
   2360			{ NULL },
   2361		},
   2362		{ "Terratec Cinergy S2 PCIe Dual Port 1",
   2363			{ &dw2102_table[TERRATEC_CINERGY_S2_1], NULL },
   2364			{ NULL },
   2365		},
   2366		{ "Terratec Cinergy S2 PCIe Dual Port 2",
   2367			{ &dw2102_table[TERRATEC_CINERGY_S2_2], NULL },
   2368			{ NULL },
   2369		},
   2370		{ "GOTVIEW Satellite HD",
   2371			{ &dw2102_table[GOTVIEW_SAT_HD], NULL },
   2372			{ NULL },
   2373		},
   2374	}
   2375};
   2376
   2377static struct dvb_usb_device_properties s421_properties = {
   2378	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
   2379	.usb_ctrl = DEVICE_SPECIFIC,
   2380	.size_of_priv = sizeof(struct dw2102_state),
   2381	.power_ctrl = su3000_power_ctrl,
   2382	.num_adapters = 1,
   2383	.identify_state	= su3000_identify_state,
   2384	.i2c_algo = &su3000_i2c_algo,
   2385
   2386	.rc.core = {
   2387		.rc_interval = 150,
   2388		.rc_codes = RC_MAP_SU3000,
   2389		.module_name = "dw2102",
   2390		.allowed_protos   = RC_PROTO_BIT_RC5,
   2391		.rc_query = su3000_rc_query,
   2392	},
   2393
   2394	.read_mac_address = su3000_read_mac_address,
   2395
   2396	.generic_bulk_ctrl_endpoint = 0x01,
   2397
   2398	.adapter = {
   2399		{
   2400		.num_frontends = 1,
   2401		.fe = {{
   2402			.streaming_ctrl   = su3000_streaming_ctrl,
   2403			.frontend_attach  = m88rs2000_frontend_attach,
   2404			.stream = {
   2405				.type = USB_BULK,
   2406				.count = 8,
   2407				.endpoint = 0x82,
   2408				.u = {
   2409					.bulk = {
   2410						.buffersize = 4096,
   2411					}
   2412				}
   2413			}
   2414		} },
   2415		}
   2416	},
   2417	.num_device_descs = 2,
   2418	.devices = {
   2419		{ "TeVii S421 PCI",
   2420			{ &dw2102_table[TEVII_S421], NULL },
   2421			{ NULL },
   2422		},
   2423		{ "TeVii S632 USB",
   2424			{ &dw2102_table[TEVII_S632], NULL },
   2425			{ NULL },
   2426		},
   2427	}
   2428};
   2429
   2430static struct dvb_usb_device_properties t220_properties = {
   2431	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
   2432	.usb_ctrl = DEVICE_SPECIFIC,
   2433	.size_of_priv = sizeof(struct dw2102_state),
   2434	.power_ctrl = su3000_power_ctrl,
   2435	.num_adapters = 1,
   2436	.identify_state	= su3000_identify_state,
   2437	.i2c_algo = &su3000_i2c_algo,
   2438
   2439	.rc.core = {
   2440		.rc_interval = 150,
   2441		.rc_codes = RC_MAP_SU3000,
   2442		.module_name = "dw2102",
   2443		.allowed_protos   = RC_PROTO_BIT_RC5,
   2444		.rc_query = su3000_rc_query,
   2445	},
   2446
   2447	.read_mac_address = su3000_read_mac_address,
   2448
   2449	.generic_bulk_ctrl_endpoint = 0x01,
   2450
   2451	.adapter = {
   2452		{
   2453		.num_frontends = 1,
   2454		.fe = { {
   2455			.streaming_ctrl   = su3000_streaming_ctrl,
   2456			.frontend_attach  = t220_frontend_attach,
   2457			.stream = {
   2458				.type = USB_BULK,
   2459				.count = 8,
   2460				.endpoint = 0x82,
   2461				.u = {
   2462					.bulk = {
   2463						.buffersize = 4096,
   2464					}
   2465				}
   2466			}
   2467		} },
   2468		}
   2469	},
   2470	.num_device_descs = 1,
   2471	.devices = {
   2472		{ "Geniatech T220 DVB-T/T2 USB2.0",
   2473			{ &dw2102_table[GENIATECH_T220], NULL },
   2474			{ NULL },
   2475		},
   2476	}
   2477};
   2478
   2479static struct dvb_usb_device_properties tt_s2_4600_properties = {
   2480	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
   2481	.usb_ctrl = DEVICE_SPECIFIC,
   2482	.size_of_priv = sizeof(struct dw2102_state),
   2483	.power_ctrl = su3000_power_ctrl,
   2484	.num_adapters = 1,
   2485	.identify_state	= su3000_identify_state,
   2486	.i2c_algo = &su3000_i2c_algo,
   2487
   2488	.rc.core = {
   2489		.rc_interval = 250,
   2490		.rc_codes = RC_MAP_TT_1500,
   2491		.module_name = "dw2102",
   2492		.allowed_protos   = RC_PROTO_BIT_RC5,
   2493		.rc_query = su3000_rc_query,
   2494	},
   2495
   2496	.read_mac_address = su3000_read_mac_address,
   2497
   2498	.generic_bulk_ctrl_endpoint = 0x01,
   2499
   2500	.adapter = {
   2501		{
   2502		.num_frontends = 1,
   2503		.fe = {{
   2504			.streaming_ctrl   = su3000_streaming_ctrl,
   2505			.frontend_attach  = tt_s2_4600_frontend_attach,
   2506			.stream = {
   2507				.type = USB_BULK,
   2508				.count = 8,
   2509				.endpoint = 0x82,
   2510				.u = {
   2511					.bulk = {
   2512						.buffersize = 4096,
   2513					}
   2514				}
   2515			}
   2516		} },
   2517		}
   2518	},
   2519	.num_device_descs = 5,
   2520	.devices = {
   2521		{ "TechnoTrend TT-connect S2-4600",
   2522			{ &dw2102_table[TECHNOTREND_CONNECT_S2_4600], NULL },
   2523			{ NULL },
   2524		},
   2525		{ "TeVii S482 (tuner 1)",
   2526			{ &dw2102_table[TEVII_S482_1], NULL },
   2527			{ NULL },
   2528		},
   2529		{ "TeVii S482 (tuner 2)",
   2530			{ &dw2102_table[TEVII_S482_2], NULL },
   2531			{ NULL },
   2532		},
   2533		{ "Terratec Cinergy S2 USB BOX",
   2534			{ &dw2102_table[TERRATEC_CINERGY_S2_BOX], NULL },
   2535			{ NULL },
   2536		},
   2537		{ "TeVii S662",
   2538			{ &dw2102_table[TEVII_S662], NULL },
   2539			{ NULL },
   2540		},
   2541	}
   2542};
   2543
   2544static int dw2102_probe(struct usb_interface *intf,
   2545		const struct usb_device_id *id)
   2546{
   2547	if (!(dvb_usb_device_init(intf, &dw2102_properties,
   2548			          THIS_MODULE, NULL, adapter_nr) &&
   2549	      dvb_usb_device_init(intf, &dw2104_properties,
   2550				  THIS_MODULE, NULL, adapter_nr) &&
   2551	      dvb_usb_device_init(intf, &dw3101_properties,
   2552			          THIS_MODULE, NULL, adapter_nr) &&
   2553	      dvb_usb_device_init(intf, &s6x0_properties,
   2554			          THIS_MODULE, NULL, adapter_nr) &&
   2555	      dvb_usb_device_init(intf, &p1100_properties,
   2556			          THIS_MODULE, NULL, adapter_nr) &&
   2557	      dvb_usb_device_init(intf, &s660_properties,
   2558				  THIS_MODULE, NULL, adapter_nr) &&
   2559	      dvb_usb_device_init(intf, &p7500_properties,
   2560				  THIS_MODULE, NULL, adapter_nr) &&
   2561	      dvb_usb_device_init(intf, &s421_properties,
   2562				  THIS_MODULE, NULL, adapter_nr) &&
   2563	      dvb_usb_device_init(intf, &su3000_properties,
   2564				  THIS_MODULE, NULL, adapter_nr) &&
   2565	      dvb_usb_device_init(intf, &t220_properties,
   2566				  THIS_MODULE, NULL, adapter_nr) &&
   2567	      dvb_usb_device_init(intf, &tt_s2_4600_properties,
   2568				  THIS_MODULE, NULL, adapter_nr))) {
   2569
   2570		return 0;
   2571	}
   2572
   2573	return -ENODEV;
   2574}
   2575
   2576static void dw2102_disconnect(struct usb_interface *intf)
   2577{
   2578	struct dvb_usb_device *d = usb_get_intfdata(intf);
   2579	struct dw2102_state *st = (struct dw2102_state *)d->priv;
   2580	struct i2c_client *client;
   2581
   2582	/* remove I2C client for tuner */
   2583	client = st->i2c_client_tuner;
   2584	if (client) {
   2585		module_put(client->dev.driver->owner);
   2586		i2c_unregister_device(client);
   2587	}
   2588
   2589	/* remove I2C client for demodulator */
   2590	client = st->i2c_client_demod;
   2591	if (client) {
   2592		module_put(client->dev.driver->owner);
   2593		i2c_unregister_device(client);
   2594	}
   2595
   2596	dvb_usb_device_exit(intf);
   2597}
   2598
   2599static struct usb_driver dw2102_driver = {
   2600	.name = "dw2102",
   2601	.probe = dw2102_probe,
   2602	.disconnect = dw2102_disconnect,
   2603	.id_table = dw2102_table,
   2604};
   2605
   2606module_usb_driver(dw2102_driver);
   2607
   2608MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
   2609MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101 USB2.0, TeVii S421, S480, S482, S600, S630, S632, S650, TeVii S660, S662, Prof 1100, 7500 USB2.0, Geniatech SU3000, T220, TechnoTrend S2-4600, Terratec Cinergy S2 devices");
   2610MODULE_VERSION("0.1");
   2611MODULE_LICENSE("GPL");
   2612MODULE_FIRMWARE(DW2101_FIRMWARE);
   2613MODULE_FIRMWARE(DW2102_FIRMWARE);
   2614MODULE_FIRMWARE(DW2104_FIRMWARE);
   2615MODULE_FIRMWARE(DW3101_FIRMWARE);
   2616MODULE_FIRMWARE(S630_FIRMWARE);
   2617MODULE_FIRMWARE(S660_FIRMWARE);
   2618MODULE_FIRMWARE(P1100_FIRMWARE);
   2619MODULE_FIRMWARE(P7500_FIRMWARE);