File Index
Files and directories
Sign in
FILE

dw2102.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/usb/dvb-usb/dw2102.c C
   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#define DW210X_READ_MSG 0
  40#define DW210X_WRITE_MSG 1
  41
  42#define REG_1F_SYMBOLRATE_BYTE0 0x1f
  43#define REG_20_SYMBOLRATE_BYTE1 0x20
  44#define REG_21_SYMBOLRATE_BYTE2 0x21
  45/* 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: cx24116
 425		 * case 0x6a: stv0903
 426		 * case 0x68: ds3000, stv0903
 427		 * case 0x60: ts2020, stv6110, stb6100
 428		 */
 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: cx24116
 628		 * case 0x6a: stv0903
 629		 * case 0x68: ds3000, stv0903, rs2000
 630		 * case 0x60: ts2020, stv6110, stb6100
 631		 * case 0xa0: eeprom
 632		 */
 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 another
 757			 * read msg to/from the same address
 758			 */
 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		} // switch
 829		j++;
 830
 831	} // while
 832	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 const struct i2c_algorithm dw2102_i2c_algo = {
 843	.master_xfer = dw2102_i2c_transfer,
 844	.functionality = dw210x_i2c_func,
 845};
 846
 847static const struct i2c_algorithm dw2102_serit_i2c_algo = {
 848	.master_xfer = dw2102_serit_i2c_transfer,
 849	.functionality = dw210x_i2c_func,
 850};
 851
 852static const struct i2c_algorithm dw2102_earda_i2c_algo = {
 853	.master_xfer = dw2102_earda_i2c_transfer,
 854	.functionality = dw210x_i2c_func,
 855};
 856
 857static const struct i2c_algorithm dw2104_i2c_algo = {
 858	.master_xfer = dw2104_i2c_transfer,
 859	.functionality = dw210x_i2c_func,
 860};
 861
 862static const struct i2c_algorithm dw3101_i2c_algo = {
 863	.master_xfer = dw3101_i2c_transfer,
 864	.functionality = dw210x_i2c_func,
 865};
 866
 867static const struct i2c_algorithm s6x0_i2c_algo = {
 868	.master_xfer = s6x0_i2c_transfer,
 869	.functionality = dw210x_i2c_func,
 870};
 871
 872static const 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 = 1
 950	};
 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		else
1003			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 = 1
1065	};
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, 0xff
1223};
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	else
1676		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 = 2
1750	};
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 = 2
1771	};
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 = 2
1793	};
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_S662
1837};
1838
1839static const 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);
~/ Read-only file preview.