brintos

brintos / linux-shallow public Read only

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