dw2102.c 60.4 KB
Newer Older
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 8
 *	TechnoTrend S2-4600,
 *	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 17
#include "stv0299.h"
#include "z0194a.h"
18 19 20
#include "stv0288.h"
#include "stb6000.h"
#include "eds1547.h"
21
#include "cx24116.h"
22
#include "tda1002x.h"
23 24
#include "mt312.h"
#include "zl10039.h"
25
#include "ts2020.h"
26 27 28 29 30
#include "ds3000.h"
#include "stv0900.h"
#include "stv6110.h"
#include "stb6100.h"
#include "stb6100_proc.h"
31
#include "m88rs2000.h"
32 33
#include "tda18271.h"
#include "cxd2820r.h"
34
#include "m88ds3103.h"
35

36 37 38
/* Max transfer size done by I2C transfer functions */
#define MAX_XFER_SIZE  64

39

40 41
#define DW210X_READ_MSG 0
#define DW210X_WRITE_MSG 1
42 43 44 45

#define REG_1F_SYMBOLRATE_BYTE0 0x1f
#define REG_20_SYMBOLRATE_BYTE1 0x20
#define REG_21_SYMBOLRATE_BYTE2 0x21
46
/* on my own*/
47
#define DW2102_VOLTAGE_CTRL (0x1800)
48
#define SU3000_STREAM_CTRL (0x1900)
49
#define DW2102_RC_QUERY (0x1a00)
50
#define DW2102_LED_CTRL (0x1b00)
51

52 53 54 55 56 57 58 59 60
#define DW2101_FIRMWARE "dvb-usb-dw2101.fw"
#define DW2102_FIRMWARE "dvb-usb-dw2102.fw"
#define DW2104_FIRMWARE "dvb-usb-dw2104.fw"
#define DW3101_FIRMWARE "dvb-usb-dw3101.fw"
#define S630_FIRMWARE   "dvb-usb-s630.fw"
#define S660_FIRMWARE   "dvb-usb-s660.fw"
#define P1100_FIRMWARE  "dvb-usb-p1100.fw"
#define P7500_FIRMWARE  "dvb-usb-p7500.fw"

61
#define	err_str "did not find the firmware file '%s'. You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware"
62

63
struct dw2102_state {
64
	u8 initialized;
65
	u8 last_lock;
66
	u8 data[MAX_XFER_SIZE + 4];
67
	struct i2c_client *i2c_client_demod;
68
	struct i2c_client *i2c_client_tuner;
69 70

	/* fe hook functions*/
71
	int (*old_set_voltage)(struct dvb_frontend *f, enum fe_sec_voltage v);
72
	int (*fe_read_status)(struct dvb_frontend *fe,
73
			      enum fe_status *status);
74 75
};

76 77 78
/* debug */
static int dvb_usb_dw2102_debug;
module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
79 80 81
MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
						DVB_USB_DEBUG_STATUS);

82 83 84
/* demod probe */
static int demod_probe = 1;
module_param_named(demod, demod_probe, int, 0644);
85
MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 4=stv0903+stb6100(or-able)).");
86

87 88
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);

89
static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
90
			u16 index, u8 * data, u16 len, int flags)
91 92
{
	int ret;
93
	u8 *u8buf;
94
	unsigned int pipe = (flags == DW210X_READ_MSG) ?
95
				usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
96
	u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
97

98 99 100 101 102
	u8buf = kmalloc(len, GFP_KERNEL);
	if (!u8buf)
		return -ENOMEM;


103
	if (flags == DW210X_WRITE_MSG)
104
		memcpy(u8buf, data, len);
105 106
	ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
				value, index , u8buf, len, 2000);
107

108
	if (flags == DW210X_READ_MSG)
109
		memcpy(data, u8buf, len);
110 111

	kfree(u8buf);
112 113 114 115 116 117 118
	return ret;
}

/* I2C */
static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
		int num)
{
119
	struct dvb_usb_device *d = i2c_get_adapdata(adap);
120
	int i = 0;
121 122 123 124 125 126 127 128 129 130 131 132 133
	u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
	u16 value;

	if (!d)
		return -ENODEV;
	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
		return -EAGAIN;

	switch (num) {
	case 2:
		/* read stv0299 register */
		value = msg[0].buf[0];/* register */
		for (i = 0; i < msg[1].len; i++) {
134
			dw210x_op_rw(d->udev, 0xb5, value + i, 0,
135
					buf6, 2, DW210X_READ_MSG);
136 137 138 139 140 141 142 143 144 145
			msg[1].buf[i] = buf6[0];
		}
		break;
	case 1:
		switch (msg[0].addr) {
		case 0x68:
			/* write to stv0299 register */
			buf6[0] = 0x2a;
			buf6[1] = msg[0].buf[0];
			buf6[2] = msg[0].buf[1];
146
			dw210x_op_rw(d->udev, 0xb2, 0, 0,
147
					buf6, 3, DW210X_WRITE_MSG);
148 149 150 151 152 153 154 155 156 157 158
			break;
		case 0x60:
			if (msg[0].flags == 0) {
			/* write to tuner pll */
				buf6[0] = 0x2c;
				buf6[1] = 5;
				buf6[2] = 0xc0;
				buf6[3] = msg[0].buf[0];
				buf6[4] = msg[0].buf[1];
				buf6[5] = msg[0].buf[2];
				buf6[6] = msg[0].buf[3];
159
				dw210x_op_rw(d->udev, 0xb2, 0, 0,
160
						buf6, 7, DW210X_WRITE_MSG);
161
			} else {
162
			/* read from tuner */
163
				dw210x_op_rw(d->udev, 0xb5, 0, 0,
164
						buf6, 1, DW210X_READ_MSG);
165 166 167 168
				msg[0].buf[0] = buf6[0];
			}
			break;
		case (DW2102_RC_QUERY):
169
			dw210x_op_rw(d->udev, 0xb8, 0, 0,
170
					buf6, 2, DW210X_READ_MSG);
171 172 173 174 175 176
			msg[0].buf[0] = buf6[0];
			msg[0].buf[1] = buf6[1];
			break;
		case (DW2102_VOLTAGE_CTRL):
			buf6[0] = 0x30;
			buf6[1] = msg[0].buf[0];
177
			dw210x_op_rw(d->udev, 0xb2, 0, 0,
178
					buf6, 2, DW210X_WRITE_MSG);
179 180 181 182 183 184 185 186 187 188
			break;
		}

		break;
	}

	mutex_unlock(&d->i2c_mutex);
	return num;
}

189 190 191 192 193 194 195 196 197 198 199 200 201
static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
						struct i2c_msg msg[], int num)
{
	struct dvb_usb_device *d = i2c_get_adapdata(adap);
	u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};

	if (!d)
		return -ENODEV;
	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
		return -EAGAIN;

	switch (num) {
	case 2:
202 203 204 205 206 207 208 209 210 211 212 213 214 215
		if (msg[0].len != 1) {
			warn("i2c rd: len=%d is not 1!\n",
			     msg[0].len);
			num = -EOPNOTSUPP;
			break;
		}

		if (2 + msg[1].len > sizeof(buf6)) {
			warn("i2c rd: len=%d is too big!\n",
			     msg[1].len);
			num = -EOPNOTSUPP;
			break;
		}

216
		/* read si2109 register by number */
217
		buf6[0] = msg[0].addr << 1;
218 219
		buf6[1] = msg[0].len;
		buf6[2] = msg[0].buf[0];
220
		dw210x_op_rw(d->udev, 0xc2, 0, 0,
221 222
				buf6, msg[0].len + 2, DW210X_WRITE_MSG);
		/* read si2109 register */
223
		dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
224 225 226 227 228 229 230
				buf6, msg[1].len + 2, DW210X_READ_MSG);
		memcpy(msg[1].buf, buf6 + 2, msg[1].len);

		break;
	case 1:
		switch (msg[0].addr) {
		case 0x68:
231 232 233 234 235 236 237
			if (2 + msg[0].len > sizeof(buf6)) {
				warn("i2c wr: len=%d is too big!\n",
				     msg[0].len);
				num = -EOPNOTSUPP;
				break;
			}

238
			/* write to si2109 register */
239
			buf6[0] = msg[0].addr << 1;
240 241
			buf6[1] = msg[0].len;
			memcpy(buf6 + 2, msg[0].buf, msg[0].len);
242
			dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
243 244 245
					msg[0].len + 2, DW210X_WRITE_MSG);
			break;
		case(DW2102_RC_QUERY):
246
			dw210x_op_rw(d->udev, 0xb8, 0, 0,
247 248 249 250 251 252 253
					buf6, 2, DW210X_READ_MSG);
			msg[0].buf[0] = buf6[0];
			msg[0].buf[1] = buf6[1];
			break;
		case(DW2102_VOLTAGE_CTRL):
			buf6[0] = 0x30;
			buf6[1] = msg[0].buf[0];
254
			dw210x_op_rw(d->udev, 0xb2, 0, 0,
255 256 257 258 259 260 261 262 263
					buf6, 2, DW210X_WRITE_MSG);
			break;
		}
		break;
	}

	mutex_unlock(&d->i2c_mutex);
	return num;
}
264

265 266 267
static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
{
	struct dvb_usb_device *d = i2c_get_adapdata(adap);
268
	int ret;
269 270 271 272 273 274 275 276 277 278

	if (!d)
		return -ENODEV;
	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
		return -EAGAIN;

	switch (num) {
	case 2: {
		/* read */
		/* first write first register number */
279 280
		u8 ibuf[MAX_XFER_SIZE], obuf[3];

281 282 283 284 285 286 287
		if (2 + msg[0].len != sizeof(obuf)) {
			warn("i2c rd: len=%d is not 1!\n",
			     msg[0].len);
			ret = -EOPNOTSUPP;
			goto unlock;
		}

288 289 290
		if (2 + msg[1].len > sizeof(ibuf)) {
			warn("i2c rd: len=%d is too big!\n",
			     msg[1].len);
291 292
			ret = -EOPNOTSUPP;
			goto unlock;
293 294
		}

295
		obuf[0] = msg[0].addr << 1;
296 297
		obuf[1] = msg[0].len;
		obuf[2] = msg[0].buf[0];
298
		dw210x_op_rw(d->udev, 0xc2, 0, 0,
299 300
				obuf, msg[0].len + 2, DW210X_WRITE_MSG);
		/* second read registers */
301
		dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
302 303 304 305 306 307 308 309 310
				ibuf, msg[1].len + 2, DW210X_READ_MSG);
		memcpy(msg[1].buf, ibuf + 2, msg[1].len);

		break;
	}
	case 1:
		switch (msg[0].addr) {
		case 0x68: {
			/* write to register */
311 312 313 314 315
			u8 obuf[MAX_XFER_SIZE];

			if (2 + msg[0].len > sizeof(obuf)) {
				warn("i2c wr: len=%d is too big!\n",
				     msg[1].len);
316 317
				ret = -EOPNOTSUPP;
				goto unlock;
318 319
			}

320
			obuf[0] = msg[0].addr << 1;
321 322
			obuf[1] = msg[0].len;
			memcpy(obuf + 2, msg[0].buf, msg[0].len);
323
			dw210x_op_rw(d->udev, 0xc2, 0, 0,
324 325 326 327 328
					obuf, msg[0].len + 2, DW210X_WRITE_MSG);
			break;
		}
		case 0x61: {
			/* write to tuner */
329 330 331 332 333
			u8 obuf[MAX_XFER_SIZE];

			if (2 + msg[0].len > sizeof(obuf)) {
				warn("i2c wr: len=%d is too big!\n",
				     msg[1].len);
334 335
				ret = -EOPNOTSUPP;
				goto unlock;
336 337
			}

338
			obuf[0] = msg[0].addr << 1;
339 340
			obuf[1] = msg[0].len;
			memcpy(obuf + 2, msg[0].buf, msg[0].len);
341
			dw210x_op_rw(d->udev, 0xc2, 0, 0,
342 343 344 345 346
					obuf, msg[0].len + 2, DW210X_WRITE_MSG);
			break;
		}
		case(DW2102_RC_QUERY): {
			u8 ibuf[2];
347
			dw210x_op_rw(d->udev, 0xb8, 0, 0,
348 349 350 351 352 353 354 355
					ibuf, 2, DW210X_READ_MSG);
			memcpy(msg[0].buf, ibuf , 2);
			break;
		}
		case(DW2102_VOLTAGE_CTRL): {
			u8 obuf[2];
			obuf[0] = 0x30;
			obuf[1] = msg[0].buf[0];
356
			dw210x_op_rw(d->udev, 0xb2, 0, 0,
357 358 359 360 361 362 363
					obuf, 2, DW210X_WRITE_MSG);
			break;
		}
		}

		break;
	}
364
	ret = num;
365

366
unlock:
367
	mutex_unlock(&d->i2c_mutex);
368
	return ret;
369
}
370

371 372 373
static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
{
	struct dvb_usb_device *d = i2c_get_adapdata(adap);
374
	int len, i, j, ret;
375 376 377 378 379 380

	if (!d)
		return -ENODEV;
	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
		return -EAGAIN;

381 382
	for (j = 0; j < num; j++) {
		switch (msg[j].addr) {
383 384
		case(DW2102_RC_QUERY): {
			u8 ibuf[2];
385
			dw210x_op_rw(d->udev, 0xb8, 0, 0,
386
					ibuf, 2, DW210X_READ_MSG);
387
			memcpy(msg[j].buf, ibuf , 2);
388 389 390 391 392
			break;
		}
		case(DW2102_VOLTAGE_CTRL): {
			u8 obuf[2];
			obuf[0] = 0x30;
393
			obuf[1] = msg[j].buf[0];
394
			dw210x_op_rw(d->udev, 0xb2, 0, 0,
395
					obuf, 2, DW210X_WRITE_MSG);
396 397
			break;
		}
398 399 400 401 402 403 404
		/*case 0x55: cx24116
		case 0x6a: stv0903
		case 0x68: ds3000, stv0903
		case 0x60: ts2020, stv6110, stb6100 */
		default: {
			if (msg[j].flags == I2C_M_RD) {
				/* read registers */
405 406 407 408 409
				u8  ibuf[MAX_XFER_SIZE];

				if (2 + msg[j].len > sizeof(ibuf)) {
					warn("i2c rd: len=%d is too big!\n",
					     msg[j].len);
410 411
					ret = -EOPNOTSUPP;
					goto unlock;
412 413
				}

414
				dw210x_op_rw(d->udev, 0xc3,
415 416 417 418
						(msg[j].addr << 1) + 1, 0,
						ibuf, msg[j].len + 2,
						DW210X_READ_MSG);
				memcpy(msg[j].buf, ibuf + 2, msg[j].len);
419
				mdelay(10);
420 421 422 423 424 425 426 427 428 429 430 431 432 433
			} else if (((msg[j].buf[0] == 0xb0) &&
						(msg[j].addr == 0x68)) ||
						((msg[j].buf[0] == 0xf7) &&
						(msg[j].addr == 0x55))) {
				/* write firmware */
				u8 obuf[19];
				obuf[0] = msg[j].addr << 1;
				obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
				obuf[2] = msg[j].buf[0];
				len = msg[j].len - 1;
				i = 1;
				do {
					memcpy(obuf + 3, msg[j].buf + i,
							(len > 16 ? 16 : len));
434
					dw210x_op_rw(d->udev, 0xc2, 0, 0,
435 436 437 438 439 440 441
						obuf, (len > 16 ? 16 : len) + 3,
						DW210X_WRITE_MSG);
					i += 16;
					len -= 16;
				} while (len > 0);
			} else {
				/* write registers */
442 443 444 445 446
				u8 obuf[MAX_XFER_SIZE];

				if (2 + msg[j].len > sizeof(obuf)) {
					warn("i2c wr: len=%d is too big!\n",
					     msg[j].len);
447 448
					ret = -EOPNOTSUPP;
					goto unlock;
449 450
				}

451 452 453
				obuf[0] = msg[j].addr << 1;
				obuf[1] = msg[j].len;
				memcpy(obuf + 2, msg[j].buf, msg[j].len);
454
				dw210x_op_rw(d->udev, 0xc2, 0, 0,
455 456 457 458 459
						obuf, msg[j].len + 2,
						DW210X_WRITE_MSG);
			}
			break;
		}
460 461 462
		}

	}
463
	ret = num;
464

465
unlock:
466
	mutex_unlock(&d->i2c_mutex);
467
	return ret;
468 469
}

470 471 472 473
static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
								int num)
{
	struct dvb_usb_device *d = i2c_get_adapdata(adap);
474
	int ret;
475
	int i;
476 477 478 479 480 481 482 483 484 485

	if (!d)
		return -ENODEV;
	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
		return -EAGAIN;

	switch (num) {
	case 2: {
		/* read */
		/* first write first register number */
486 487
		u8 ibuf[MAX_XFER_SIZE], obuf[3];

488 489 490 491 492 493
		if (2 + msg[0].len != sizeof(obuf)) {
			warn("i2c rd: len=%d is not 1!\n",
			     msg[0].len);
			ret = -EOPNOTSUPP;
			goto unlock;
		}
494 495 496
		if (2 + msg[1].len > sizeof(ibuf)) {
			warn("i2c rd: len=%d is too big!\n",
			     msg[1].len);
497 498
			ret = -EOPNOTSUPP;
			goto unlock;
499
		}
500 501 502
		obuf[0] = msg[0].addr << 1;
		obuf[1] = msg[0].len;
		obuf[2] = msg[0].buf[0];
503
		dw210x_op_rw(d->udev, 0xc2, 0, 0,
504 505
				obuf, msg[0].len + 2, DW210X_WRITE_MSG);
		/* second read registers */
506
		dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
507 508 509 510 511 512 513 514 515 516
				ibuf, msg[1].len + 2, DW210X_READ_MSG);
		memcpy(msg[1].buf, ibuf + 2, msg[1].len);

		break;
	}
	case 1:
		switch (msg[0].addr) {
		case 0x60:
		case 0x0c: {
			/* write to register */
517 518 519 520 521
			u8 obuf[MAX_XFER_SIZE];

			if (2 + msg[0].len > sizeof(obuf)) {
				warn("i2c wr: len=%d is too big!\n",
				     msg[0].len);
522 523
				ret = -EOPNOTSUPP;
				goto unlock;
524
			}
525 526 527
			obuf[0] = msg[0].addr << 1;
			obuf[1] = msg[0].len;
			memcpy(obuf + 2, msg[0].buf, msg[0].len);
528
			dw210x_op_rw(d->udev, 0xc2, 0, 0,
529 530 531 532 533
					obuf, msg[0].len + 2, DW210X_WRITE_MSG);
			break;
		}
		case(DW2102_RC_QUERY): {
			u8 ibuf[2];
534
			dw210x_op_rw(d->udev, 0xb8, 0, 0,
535 536 537 538 539 540 541 542 543 544 545 546 547 548
					ibuf, 2, DW210X_READ_MSG);
			memcpy(msg[0].buf, ibuf , 2);
			break;
		}
		}

		break;
	}

	for (i = 0; i < num; i++) {
		deb_xfer("%02x:%02x: %s ", i, msg[i].addr,
				msg[i].flags == 0 ? ">>>" : "<<<");
		debug_dump(msg[i].buf, msg[i].len, deb_xfer);
	}
549
	ret = num;
550

551
unlock:
552
	mutex_unlock(&d->i2c_mutex);
553
	return ret;
554 555
}

556
static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
557 558 559
								int num)
{
	struct dvb_usb_device *d = i2c_get_adapdata(adap);
560
	struct usb_device *udev;
561
	int len, i, j, ret;
562 563 564

	if (!d)
		return -ENODEV;
565
	udev = d->udev;
566 567 568
	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
		return -EAGAIN;

569 570
	for (j = 0; j < num; j++) {
		switch (msg[j].addr) {
571
		case (DW2102_RC_QUERY): {
572
			u8 ibuf[5];
573
			dw210x_op_rw(d->udev, 0xb8, 0, 0,
574 575
					ibuf, 5, DW210X_READ_MSG);
			memcpy(msg[j].buf, ibuf + 3, 2);
576 577 578 579
			break;
		}
		case (DW2102_VOLTAGE_CTRL): {
			u8 obuf[2];
580 581 582

			obuf[0] = 1;
			obuf[1] = msg[j].buf[1];/* off-on */
583
			dw210x_op_rw(d->udev, 0x8a, 0, 0,
584
					obuf, 2, DW210X_WRITE_MSG);
585
			obuf[0] = 3;
586
			obuf[1] = msg[j].buf[0];/* 13v-18v */
587
			dw210x_op_rw(d->udev, 0x8a, 0, 0,
588 589 590
					obuf, 2, DW210X_WRITE_MSG);
			break;
		}
591 592 593 594 595
		case (DW2102_LED_CTRL): {
			u8 obuf[2];

			obuf[0] = 5;
			obuf[1] = msg[j].buf[0];
596
			dw210x_op_rw(d->udev, 0x8a, 0, 0,
597 598 599
					obuf, 2, DW210X_WRITE_MSG);
			break;
		}
600 601
		/*case 0x55: cx24116
		case 0x6a: stv0903
602
		case 0x68: ds3000, stv0903, rs2000
603 604 605 606 607
		case 0x60: ts2020, stv6110, stb6100
		case 0xa0: eeprom */
		default: {
			if (msg[j].flags == I2C_M_RD) {
				/* read registers */
608 609 610 611 612
				u8 ibuf[MAX_XFER_SIZE];

				if (msg[j].len > sizeof(ibuf)) {
					warn("i2c rd: len=%d is too big!\n",
					     msg[j].len);
613 614
					ret = -EOPNOTSUPP;
					goto unlock;
615 616
				}

617
				dw210x_op_rw(d->udev, 0x91, 0, 0,
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634
						ibuf, msg[j].len,
						DW210X_READ_MSG);
				memcpy(msg[j].buf, ibuf, msg[j].len);
				break;
			} else if ((msg[j].buf[0] == 0xb0) &&
						(msg[j].addr == 0x68)) {
				/* write firmware */
				u8 obuf[19];
				obuf[0] = (msg[j].len > 16 ?
						18 : msg[j].len + 1);
				obuf[1] = msg[j].addr << 1;
				obuf[2] = msg[j].buf[0];
				len = msg[j].len - 1;
				i = 1;
				do {
					memcpy(obuf + 3, msg[j].buf + i,
							(len > 16 ? 16 : len));
635
					dw210x_op_rw(d->udev, 0x80, 0, 0,
636 637 638 639 640
						obuf, (len > 16 ? 16 : len) + 3,
						DW210X_WRITE_MSG);
					i += 16;
					len -= 16;
				} while (len > 0);
641
			} else if (j < (num - 1)) {
642
				/* write register addr before read */
643 644 645 646 647
				u8 obuf[MAX_XFER_SIZE];

				if (2 + msg[j].len > sizeof(obuf)) {
					warn("i2c wr: len=%d is too big!\n",
					     msg[j].len);
648 649
					ret = -EOPNOTSUPP;
					goto unlock;
650 651
				}

652 653 654
				obuf[0] = msg[j + 1].len;
				obuf[1] = (msg[j].addr << 1);
				memcpy(obuf + 2, msg[j].buf, msg[j].len);
655
				dw210x_op_rw(d->udev,
656
						le16_to_cpu(udev->descriptor.idProduct) ==
657
						0x7500 ? 0x92 : 0x90, 0, 0,
658 659 660
						obuf, msg[j].len + 2,
						DW210X_WRITE_MSG);
				break;
661 662
			} else {
				/* write registers */
663 664 665 666 667
				u8 obuf[MAX_XFER_SIZE];

				if (2 + msg[j].len > sizeof(obuf)) {
					warn("i2c wr: len=%d is too big!\n",
					     msg[j].len);
668 669
					ret = -EOPNOTSUPP;
					goto unlock;
670
				}
671 672 673
				obuf[0] = msg[j].len + 1;
				obuf[1] = (msg[j].addr << 1);
				memcpy(obuf + 2, msg[j].buf, msg[j].len);
674
				dw210x_op_rw(d->udev, 0x80, 0, 0,
675 676 677 678 679 680
						obuf, msg[j].len + 2,
						DW210X_WRITE_MSG);
				break;
			}
			break;
		}
681 682
		}
	}
683
	ret = num;
684

685
unlock:
686
	mutex_unlock(&d->i2c_mutex);
687
	return ret;
688 689
}

690 691 692 693
static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
								int num)
{
	struct dvb_usb_device *d = i2c_get_adapdata(adap);
694
	struct dw2102_state *state;
695 696 697

	if (!d)
		return -ENODEV;
698 699 700

	state = d->priv;

701 702
	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
		return -EAGAIN;
703 704 705 706
	if (mutex_lock_interruptible(&d->data_mutex) < 0) {
		mutex_unlock(&d->i2c_mutex);
		return -EAGAIN;
	}
707 708 709 710 711

	switch (num) {
	case 1:
		switch (msg[0].addr) {
		case SU3000_STREAM_CTRL:
712 713 714 715 716
			state->data[0] = msg[0].buf[0] + 0x36;
			state->data[1] = 3;
			state->data[2] = 0;
			if (dvb_usb_generic_rw(d, state->data, 3,
					state->data, 0, 0) < 0)
717 718 719
				err("i2c transfer failed.");
			break;
		case DW2102_RC_QUERY:
720 721 722
			state->data[0] = 0x10;
			if (dvb_usb_generic_rw(d, state->data, 1,
					state->data, 2, 0) < 0)
723
				err("i2c transfer failed.");
724 725
			msg[0].buf[1] = state->data[0];
			msg[0].buf[0] = state->data[1];
726 727
			break;
		default:
728 729 730 731 732 733 734
			if (3 + msg[0].len > sizeof(state->data)) {
				warn("i2c wr: len=%d is too big!\n",
				     msg[0].len);
				num = -EOPNOTSUPP;
				break;
			}

735
			/* always i2c write*/
736 737 738
			state->data[0] = 0x08;
			state->data[1] = msg[0].addr;
			state->data[2] = msg[0].len;
739

740
			memcpy(&state->data[3], msg[0].buf, msg[0].len);
741

742 743
			if (dvb_usb_generic_rw(d, state->data, msg[0].len + 3,
						state->data, 1, 0) < 0)
744 745 746 747 748 749
				err("i2c transfer failed.");

		}
		break;
	case 2:
		/* always i2c read */
750 751 752 753 754 755 756 757 758 759 760 761 762
		if (4 + msg[0].len > sizeof(state->data)) {
			warn("i2c rd: len=%d is too big!\n",
			     msg[0].len);
			num = -EOPNOTSUPP;
			break;
		}
		if (1 + msg[1].len > sizeof(state->data)) {
			warn("i2c rd: len=%d is too big!\n",
			     msg[1].len);
			num = -EOPNOTSUPP;
			break;
		}

763 764 765 766 767 768 769 770
		state->data[0] = 0x09;
		state->data[1] = msg[0].len;
		state->data[2] = msg[1].len;
		state->data[3] = msg[0].addr;
		memcpy(&state->data[4], msg[0].buf, msg[0].len);

		if (dvb_usb_generic_rw(d, state->data, msg[0].len + 4,
					state->data, msg[1].len + 1, 0) < 0)
771 772
			err("i2c transfer failed.");

773
		memcpy(msg[1].buf, &state->data[1], msg[1].len);
774 775 776 777 778
		break;
	default:
		warn("more than 2 i2c messages at a time is not handled yet.");
		break;
	}
779
	mutex_unlock(&d->data_mutex);
780 781 782 783
	mutex_unlock(&d->i2c_mutex);
	return num;
}

784
static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
785 786 787 788 789 790
{
	return I2C_FUNC_I2C;
}

static struct i2c_algorithm dw2102_i2c_algo = {
	.master_xfer = dw2102_i2c_transfer,
791 792 793 794 795 796
	.functionality = dw210x_i2c_func,
};

static struct i2c_algorithm dw2102_serit_i2c_algo = {
	.master_xfer = dw2102_serit_i2c_transfer,
	.functionality = dw210x_i2c_func,
797 798
};

799 800 801 802 803
static struct i2c_algorithm dw2102_earda_i2c_algo = {
	.master_xfer = dw2102_earda_i2c_transfer,
	.functionality = dw210x_i2c_func,
};

804 805
static struct i2c_algorithm dw2104_i2c_algo = {
	.master_xfer = dw2104_i2c_transfer,
806
	.functionality = dw210x_i2c_func,
807 808
};

809 810 811 812 813
static struct i2c_algorithm dw3101_i2c_algo = {
	.master_xfer = dw3101_i2c_transfer,
	.functionality = dw210x_i2c_func,
};

814 815
static struct i2c_algorithm s6x0_i2c_algo = {
	.master_xfer = s6x0_i2c_transfer,
816 817 818
	.functionality = dw210x_i2c_func,
};

819 820 821 822 823
static struct i2c_algorithm su3000_i2c_algo = {
	.master_xfer = su3000_i2c_transfer,
	.functionality = dw210x_i2c_func,
};

824
static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
825 826 827 828 829 830
{
	int i;
	u8 ibuf[] = {0, 0};
	u8 eeprom[256], eepromline[16];

	for (i = 0; i < 256; i++) {
831
		if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) {
832 833 834 835 836 837 838 839 840 841 842
			err("read eeprom failed.");
			return -1;
		} else {
			eepromline[i%16] = ibuf[0];
			eeprom[i] = ibuf[0];
		}
		if ((i % 16) == 15) {
			deb_xfer("%02x: ", i - 15);
			debug_dump(eepromline, 16, deb_xfer);
		}
	}
843

844 845 846 847
	memcpy(mac, eeprom + 8, 6);
	return 0;
};

848
static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
849 850
{
	int i, ret;
851 852 853 854 855 856 857 858 859 860 861 862 863 864 865
	u8 ibuf[] = { 0 }, obuf[] = { 0 };
	u8 eeprom[256], eepromline[16];
	struct i2c_msg msg[] = {
		{
			.addr = 0xa0 >> 1,
			.flags = 0,
			.buf = obuf,
			.len = 1,
		}, {
			.addr = 0xa0 >> 1,
			.flags = I2C_M_RD,
			.buf = ibuf,
			.len = 1,
		}
	};
866 867

	for (i = 0; i < 256; i++) {
868 869 870
		obuf[0] = i;
		ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
		if (ret != 2) {
871 872 873
			err("read eeprom failed.");
			return -1;
		} else {
874 875
			eepromline[i % 16] = ibuf[0];
			eeprom[i] = ibuf[0];
876 877 878 879 880 881 882 883 884 885 886 887
		}

		if ((i % 16) == 15) {
			deb_xfer("%02x: ", i - 15);
			debug_dump(eepromline, 16, deb_xfer);
		}
	}

	memcpy(mac, eeprom + 16, 6);
	return 0;
};

888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905
static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
	static u8 command_start[] = {0x00};
	static u8 command_stop[] = {0x01};
	struct i2c_msg msg = {
		.addr = SU3000_STREAM_CTRL,
		.flags = 0,
		.buf = onoff ? command_start : command_stop,
		.len = 1
	};

	i2c_transfer(&adap->dev->i2c_adap, &msg, 1);

	return 0;
}

static int su3000_power_ctrl(struct dvb_usb_device *d, int i)
{
906
	struct dw2102_state *state = (struct dw2102_state *)d->priv;
907
	int ret = 0;
908

909
	info("%s: %d, initialized %d", __func__, i, state->initialized);
910 911

	if (i && !state->initialized) {
912 913 914 915 916
		mutex_lock(&d->data_mutex);

		state->data[0] = 0xde;
		state->data[1] = 0;

917 918
		state->initialized = 1;
		/* reset board */
919 920
		ret = dvb_usb_generic_rw(d, state->data, 2, NULL, 0, 0);
		mutex_unlock(&d->data_mutex);
921 922
	}

923
	return ret;
924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948
}

static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
{
	int i;
	u8 obuf[] = { 0x1f, 0xf0 };
	u8 ibuf[] = { 0 };
	struct i2c_msg msg[] = {
		{
			.addr = 0x51,
			.flags = 0,
			.buf = obuf,
			.len = 2,
		}, {
			.addr = 0x51,
			.flags = I2C_M_RD,
			.buf = ibuf,
			.len = 1,

		}
	};

	for (i = 0; i < 6; i++) {
		obuf[1] = 0xf0 + i;
		if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
949
			return -1;
950 951 952 953 954 955 956 957
		else
			mac[i] = ibuf[0];
	}

	return 0;
}

static int su3000_identify_state(struct usb_device *udev,
958 959
				 const struct dvb_usb_device_properties *props,
				 const struct dvb_usb_device_description **desc,
960 961
				 int *cold)
{
962
	info("%s", __func__);
963 964 965 966 967

	*cold = 0;
	return 0;
}

968 969
static int dw210x_set_voltage(struct dvb_frontend *fe,
			      enum fe_sec_voltage voltage)
970
{
971 972 973 974 975 976 977 978
	static u8 command_13v[] = {0x00, 0x01};
	static u8 command_18v[] = {0x01, 0x01};
	static u8 command_off[] = {0x00, 0x00};
	struct i2c_msg msg = {
		.addr = DW2102_VOLTAGE_CTRL,
		.flags = 0,
		.buf = command_off,
		.len = 2,
979 980 981 982 983
	};

	struct dvb_usb_adapter *udev_adap =
		(struct dvb_usb_adapter *)(fe->dvb->priv);
	if (voltage == SEC_VOLTAGE_18)
984 985 986 987 988 989
		msg.buf = command_18v;
	else if (voltage == SEC_VOLTAGE_13)
		msg.buf = command_13v;

	i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);

990 991 992
	return 0;
}

993 994
static int s660_set_voltage(struct dvb_frontend *fe,
			    enum fe_sec_voltage voltage)
995 996 997
{
	struct dvb_usb_adapter *d =
		(struct dvb_usb_adapter *)(fe->dvb->priv);
998
	struct dw2102_state *st = (struct dw2102_state *)d->dev->priv;
999 1000 1001 1002 1003 1004 1005 1006

	dw210x_set_voltage(fe, voltage);
	if (st->old_set_voltage)
		st->old_set_voltage(fe, voltage);

	return 0;
}

1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon)
{
	static u8 led_off[] = { 0 };
	static u8 led_on[] = { 1 };
	struct i2c_msg msg = {
		.addr = DW2102_LED_CTRL,
		.flags = 0,
		.buf = led_off,
		.len = 1
	};
	struct dvb_usb_adapter *udev_adap =
		(struct dvb_usb_adapter *)(fe->dvb->priv);

	if (offon)
		msg.buf = led_on;
	i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
}

1025 1026
static int tt_s2_4600_read_status(struct dvb_frontend *fe,
				  enum fe_status *status)
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
{
	struct dvb_usb_adapter *d =
		(struct dvb_usb_adapter *)(fe->dvb->priv);
	struct dw2102_state *st = (struct dw2102_state *)d->dev->priv;
	int ret;

	ret = st->fe_read_status(fe, status);

	/* resync slave fifo when signal change from unlock to lock */
	if ((*status & FE_HAS_LOCK) && (!st->last_lock))
		su3000_streaming_ctrl(d, 1);

	st->last_lock = (*status & FE_HAS_LOCK) ? 1 : 0;
	return ret;
}

1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054
static struct stv0299_config sharp_z0194a_config = {
	.demod_address = 0x68,
	.inittab = sharp_z0194a_inittab,
	.mclk = 88000000UL,
	.invert = 1,
	.skip_reinit = 0,
	.lock_output = STV0299_LOCKOUTPUT_1,
	.volt13_op0_op1 = STV0299_VOLT13_OP1,
	.min_delay_ms = 100,
	.set_symbol_rate = sharp_z0194a_set_symbol_rate,
};

1055 1056
static struct cx24116_config dw2104_config = {
	.demod_address = 0x55,
1057
	.mpg_clk_pos_pol = 0x01,
1058 1059
};

1060 1061 1062 1063 1064 1065
static struct si21xx_config serit_sp1511lhb_config = {
	.demod_address = 0x68,
	.min_delay_ms = 100,

};

1066 1067 1068 1069 1070
static struct tda10023_config dw3101_tda10023_config = {
	.demod_address = 0x0c,
	.invert = 1,
};

1071 1072 1073 1074
static struct mt312_config zl313_config = {
	.demod_address = 0x0e,
};

1075 1076 1077 1078
static struct ds3000_config dw2104_ds3000_config = {
	.demod_address = 0x68,
};

1079
static struct ts2020_config dw2104_ts2020_config = {
1080
	.tuner_address = 0x60,
1081
	.clk_out_div = 1,
1082
	.frequency_div = 1060000,
1083 1084
};

1085 1086
static struct ds3000_config s660_ds3000_config = {
	.demod_address = 0x68,
1087
	.ci_mode = 1,
1088 1089 1090
	.set_lock_led = dw210x_led_ctrl,
};

1091 1092 1093 1094 1095 1096
static struct ts2020_config s660_ts2020_config = {
	.tuner_address = 0x60,
	.clk_out_div = 1,
	.frequency_div = 1146000,
};

1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129
static struct stv0900_config dw2104a_stv0900_config = {
	.demod_address = 0x6a,
	.demod_mode = 0,
	.xtal = 27000000,
	.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
	.diseqc_mode = 2,/* 2/3 PWM */
	.tun1_maddress = 0,/* 0x60 */
	.tun1_adc = 0,/* 2 Vpp */
	.path1_mode = 3,
};

static struct stb6100_config dw2104a_stb6100_config = {
	.tuner_address = 0x60,
	.refclock = 27000000,
};

static struct stv0900_config dw2104_stv0900_config = {
	.demod_address = 0x68,
	.demod_mode = 0,
	.xtal = 8000000,
	.clkmode = 3,
	.diseqc_mode = 2,
	.tun1_maddress = 0,
	.tun1_adc = 1,/* 1 Vpp */
	.path1_mode = 3,
};

static struct stv6110_config dw2104_stv6110_config = {
	.i2c_address = 0x60,
	.mclk = 16000000,
	.clk_div = 1,
};

1130 1131 1132 1133 1134 1135 1136 1137 1138 1139
static struct stv0900_config prof_7500_stv0900_config = {
	.demod_address = 0x6a,
	.demod_mode = 0,
	.xtal = 27000000,
	.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
	.diseqc_mode = 2,/* 2/3 PWM */
	.tun1_maddress = 0,/* 0x60 */
	.tun1_adc = 0,/* 2 Vpp */
	.path1_mode = 3,
	.tun1_type = 3,
1140
	.set_lock_led = dw210x_led_ctrl,
1141 1142
};

1143 1144 1145
static struct ds3000_config su3000_ds3000_config = {
	.demod_address = 0x68,
	.ci_mode = 1,
1146
	.set_lock_led = dw210x_led_ctrl,
1147 1148
};

1149 1150 1151
static struct cxd2820r_config cxd2820r_config = {
	.i2c_address = 0x6c, /* (0xd8 >> 1) */
	.ts_mode = 0x38,
1152
	.ts_clock_inv = 1,
1153 1154 1155 1156 1157 1158 1159
};

static struct tda18271_config tda18271_config = {
	.output_opt = TDA18271_OUTPUT_LT_OFF,
	.gate = TDA18271_GATE_DIGITAL,
};

1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182
static u8 m88rs2000_inittab[] = {
	DEMOD_WRITE, 0x9a, 0x30,
	DEMOD_WRITE, 0x00, 0x01,
	WRITE_DELAY, 0x19, 0x00,
	DEMOD_WRITE, 0x00, 0x00,
	DEMOD_WRITE, 0x9a, 0xb0,
	DEMOD_WRITE, 0x81, 0xc1,
	DEMOD_WRITE, 0x81, 0x81,
	DEMOD_WRITE, 0x86, 0xc6,
	DEMOD_WRITE, 0x9a, 0x30,
	DEMOD_WRITE, 0xf0, 0x80,
	DEMOD_WRITE, 0xf1, 0xbf,
	DEMOD_WRITE, 0xb0, 0x45,
	DEMOD_WRITE, 0xb2, 0x01,
	DEMOD_WRITE, 0x9a, 0xb0,
	0xff, 0xaa, 0xff
};

static struct m88rs2000_config s421_m88rs2000_config = {
	.demod_addr = 0x68,
	.inittab = m88rs2000_inittab,
};

1183 1184
static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
{
1185 1186 1187
	struct dvb_tuner_ops *tuner_ops = NULL;

	if (demod_probe & 4) {
1188
		d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
1189
				&d->dev->i2c_adap, 0);
1190 1191
		if (d->fe_adap[0].fe != NULL) {
			if (dvb_attach(stb6100_attach, d->fe_adap[0].fe,
1192 1193
					&dw2104a_stb6100_config,
					&d->dev->i2c_adap)) {
1194
				tuner_ops = &d->fe_adap[0].fe->ops.tuner_ops;
1195 1196 1197 1198
				tuner_ops->set_frequency = stb6100_set_freq;
				tuner_ops->get_frequency = stb6100_get_freq;
				tuner_ops->set_bandwidth = stb6100_set_bandw;
				tuner_ops->get_bandwidth = stb6100_get_bandw;
1199
				d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1200
				info("Attached STV0900+STB6100!");
1201 1202 1203 1204 1205 1206
				return 0;
			}
		}
	}

	if (demod_probe & 2) {
1207
		d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
1208
				&d->dev->i2c_adap, 0);
1209 1210
		if (d->fe_adap[0].fe != NULL) {
			if (dvb_attach(stv6110_attach, d->fe_adap[0].fe,
1211 1212
					&dw2104_stv6110_config,
					&d->dev->i2c_adap)) {
1213
				d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1214
				info("Attached STV0900+STV6110A!");
1215 1216 1217 1218 1219 1220
				return 0;
			}
		}
	}

	if (demod_probe & 1) {
1221
		d->fe_adap[0].fe = dvb_attach(cx24116_attach, &dw2104_config,
1222
				&d->dev->i2c_adap);
1223 1224
		if (d->fe_adap[0].fe != NULL) {
			d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1225
			info("Attached cx24116!");
1226 1227 1228 1229
			return 0;
		}
	}

1230
	d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
1231
			&d->dev->i2c_adap);
1232
	if (d->fe_adap[0].fe != NULL) {
1233 1234
		dvb_attach(ts2020_attach, d->fe_adap[0].fe,
			&dw2104_ts2020_config, &d->dev->i2c_adap);
1235
		d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1236
		info("Attached DS3000!");
1237 1238
		return 0;
	}
1239

1240 1241 1242
	return -EIO;
}

1243
static struct dvb_usb_device_properties dw2102_properties;
1244
static struct dvb_usb_device_properties dw2104_properties;
1245
static struct dvb_usb_device_properties s6x0_properties;
1246

1247 1248
static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
{
1249 1250
	if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) {
		/*dw2102_properties.adapter->tuner_attach = NULL;*/
1251
		d->fe_adap[0].fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config,
1252
					&d->dev->i2c_adap);
1253 1254
		if (d->fe_adap[0].fe != NULL) {
			d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1255
			info("Attached si21xx!");
1256 1257 1258
			return 0;
		}
	}
1259

1260
	if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
1261
		d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config,
1262
					&d->dev->i2c_adap);
1263 1264
		if (d->fe_adap[0].fe != NULL) {
			if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61,
1265
					&d->dev->i2c_adap)) {
1266
				d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1267
				info("Attached stv0288!");
1268 1269
				return 0;
			}
1270 1271 1272
		}
	}

1273 1274
	if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) {
		/*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
1275
		d->fe_adap[0].fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
1276
					&d->dev->i2c_adap);
1277 1278
		if (d->fe_adap[0].fe != NULL) {
			d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1279
			info("Attached stv0299!");
1280 1281
			return 0;
		}
1282 1283 1284 1285
	}
	return -EIO;
}

1286 1287
static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
{
1288
	d->fe_adap[0].fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
1289
				&d->dev->i2c_adap, 0x48);
1290
	if (d->fe_adap[0].fe != NULL) {
1291
		info("Attached tda10023!");
1292 1293 1294 1295 1296
		return 0;
	}
	return -EIO;
}

1297
static int zl100313_frontend_attach(struct dvb_usb_adapter *d)
1298
{
1299
	d->fe_adap[0].fe = dvb_attach(mt312_attach, &zl313_config,
1300
			&d->dev->i2c_adap);
1301 1302
	if (d->fe_adap[0].fe != NULL) {
		if (dvb_attach(zl10039_attach, d->fe_adap[0].fe, 0x60,
1303
				&d->dev->i2c_adap)) {
1304
			d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1305
			info("Attached zl100313+zl10039!");
1306 1307 1308 1309
			return 0;
		}
	}

1310 1311 1312 1313 1314
	return -EIO;
}

static int stv0288_frontend_attach(struct dvb_usb_adapter *d)
{
1315 1316
	u8 obuf[] = {7, 1};

1317
	d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config,
1318 1319
			&d->dev->i2c_adap);

1320
	if (d->fe_adap[0].fe == NULL)
1321 1322
		return -EIO;

1323
	if (NULL == dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, &d->dev->i2c_adap))
1324 1325
		return -EIO;

1326
	d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1327 1328 1329

	dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);

1330
	info("Attached stv0288+stb6000!");
1331 1332 1333

	return 0;

1334 1335 1336 1337
}

static int ds3000_frontend_attach(struct dvb_usb_adapter *d)
{
1338
	struct dw2102_state *st = d->dev->priv;
1339
	u8 obuf[] = {7, 1};
1340

1341
	d->fe_adap[0].fe = dvb_attach(ds3000_attach, &s660_ds3000_config,
1342 1343
			&d->dev->i2c_adap);

1344
	if (d->fe_adap[0].fe == NULL)
1345 1346
		return -EIO;

1347
	dvb_attach(ts2020_attach, d->fe_adap[0].fe, &s660_ts2020_config,
1348 1349
		&d->dev->i2c_adap);

1350 1351
	st->old_set_voltage = d->fe_adap[0].fe->ops.set_voltage;
	d->fe_adap[0].fe->ops.set_voltage = s660_set_voltage;
1352 1353 1354

	dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);

1355
	info("Attached ds3000+ts2020!");
1356 1357

	return 0;
1358 1359
}

1360 1361
static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
{
1362 1363
	u8 obuf[] = {7, 1};

1364
	d->fe_adap[0].fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config,
1365
					&d->dev->i2c_adap, 0);
1366
	if (d->fe_adap[0].fe == NULL)
1367
		return -EIO;
1368

1369
	d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1370

1371 1372
	dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);

1373
	info("Attached STV0900+STB6100A!");
1374 1375 1376 1377

	return 0;
}

1378
static int su3000_frontend_attach(struct dvb_usb_adapter *adap)
1379
{
1380 1381 1382 1383 1384 1385 1386 1387
	struct dvb_usb_device *d = adap->dev;
	struct dw2102_state *state = d->priv;

	mutex_lock(&d->data_mutex);

	state->data[0] = 0xe;
	state->data[1] = 0x80;
	state->data[2] = 0;
1388

1389
	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
1390 1391
		err("command 0x0e transfer failed.");

1392 1393 1394
	state->data[0] = 0xe;
	state->data[1] = 0x02;
	state->data[2] = 1;
1395

1396
	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
1397 1398 1399
		err("command 0x0e transfer failed.");
	msleep(300);

1400 1401 1402
	state->data[0] = 0xe;
	state->data[1] = 0x83;
	state->data[2] = 0;
1403

1404
	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
1405 1406
		err("command 0x0e transfer failed.");

1407 1408 1409
	state->data[0] = 0xe;
	state->data[1] = 0x83;
	state->data[2] = 1;
1410

1411
	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
1412 1413
		err("command 0x0e transfer failed.");

1414
	state->data[0] = 0x51;
1415

1416
	if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
1417 1418
		err("command 0x51 transfer failed.");

1419 1420 1421 1422 1423
	mutex_unlock(&d->data_mutex);

	adap->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
					&d->i2c_adap);
	if (adap->fe_adap[0].fe == NULL)
1424 1425
		return -EIO;

1426
	if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe,
1427
				&dw2104_ts2020_config,
1428
				&d->i2c_adap)) {
1429
		info("Attached DS3000/TS2020!");
1430 1431
		return 0;
	}
1432

1433
	info("Failed to attach DS3000/TS2020!");
1434
	return -EIO;
1435 1436
}

1437
static int t220_frontend_attach(struct dvb_usb_adapter *adap)
1438
{
1439 1440 1441 1442
	struct dvb_usb_device *d = adap->dev;
	struct dw2102_state *state = d->priv;

	mutex_lock(&d->data_mutex);
1443

1444 1445 1446 1447 1448
	state->data[0] = 0xe;
	state->data[1] = 0x87;
	state->data[2] = 0x0;

	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
1449 1450
		err("command 0x0e transfer failed.");

1451 1452 1453
	state->data[0] = 0xe;
	state->data[1] = 0x86;
	state->data[2] = 1;
1454

1455
	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
1456 1457
		err("command 0x0e transfer failed.");

1458 1459 1460
	state->data[0] = 0xe;
	state->data[1] = 0x80;
	state->data[2] = 0;
1461

1462
	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
1463 1464
		err("command 0x0e transfer failed.");

1465
	msleep(50);
1466

1467 1468 1469
	state->data[0] = 0xe;
	state->data[1] = 0x80;
	state->data[2] = 1;
1470

1471
	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
1472 1473
		err("command 0x0e transfer failed.");

1474
	state->data[0] = 0x51;
1475

1476
	if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
1477 1478
		err("command 0x51 transfer failed.");

1479 1480 1481 1482 1483 1484 1485
	mutex_unlock(&d->data_mutex);

	adap->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config,
					&d->i2c_adap, NULL);
	if (adap->fe_adap[0].fe != NULL) {
		if (dvb_attach(tda18271_attach, adap->fe_adap[0].fe, 0x60,
					&d->i2c_adap, &tda18271_config)) {
1486
			info("Attached TDA18271HD/CXD2820R!");
1487 1488 1489 1490
			return 0;
		}
	}

1491
	info("Failed to attach TDA18271HD/CXD2820R!");
1492 1493 1494
	return -EIO;
}

1495
static int m88rs2000_frontend_attach(struct dvb_usb_adapter *adap)
1496
{
1497 1498 1499 1500
	struct dvb_usb_device *d = adap->dev;
	struct dw2102_state *state = d->priv;

	mutex_lock(&d->data_mutex);
1501

1502 1503 1504
	state->data[0] = 0x51;

	if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
1505 1506
		err("command 0x51 transfer failed.");

1507
	mutex_unlock(&d->data_mutex);
1508

1509 1510 1511 1512 1513
	adap->fe_adap[0].fe = dvb_attach(m88rs2000_attach,
					&s421_m88rs2000_config,
					&d->i2c_adap);

	if (adap->fe_adap[0].fe == NULL)
1514 1515
		return -EIO;

1516
	if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe,
1517
				&dw2104_ts2020_config,
1518
				&d->i2c_adap)) {
1519
		info("Attached RS2000/TS2020!");
1520 1521
		return 0;
	}
1522

1523
	info("Failed to attach RS2000/TS2020!");
1524
	return -EIO;
1525 1526
}

1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549
static int tt_s2_4600_frontend_attach_probe_demod(struct dvb_usb_device *d,
						  const int probe_addr)
{
	struct dw2102_state *state = d->priv;

	state->data[0] = 0x9;
	state->data[1] = 0x1;
	state->data[2] = 0x1;
	state->data[3] = probe_addr;
	state->data[4] = 0x0;

	if (dvb_usb_generic_rw(d, state->data, 5, state->data, 2, 0) < 0) {
		err("i2c probe for address 0x%x failed.", probe_addr);
		return 0;
	}

	if (state->data[0] != 8) /* fail(7) or error, no device at address */
		return 0;

	/* probing successful */
	return 1;
}

1550 1551 1552 1553 1554 1555
static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap)
{
	struct dvb_usb_device *d = adap->dev;
	struct dw2102_state *state = d->priv;
	struct i2c_adapter *i2c_adapter;
	struct i2c_client *client;
1556 1557
	struct i2c_board_info board_info;
	struct m88ds3103_platform_data m88ds3103_pdata = {};
1558
	struct ts2020_config ts2020_config = {};
1559
	int demod_addr;
1560

1561 1562 1563 1564 1565 1566 1567
	mutex_lock(&d->data_mutex);

	state->data[0] = 0xe;
	state->data[1] = 0x80;
	state->data[2] = 0x0;

	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
1568 1569
		err("command 0x0e transfer failed.");

1570 1571 1572
	state->data[0] = 0xe;
	state->data[1] = 0x02;
	state->data[2] = 1;
1573

1574
	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
1575 1576 1577
		err("command 0x0e transfer failed.");
	msleep(300);

1578 1579 1580
	state->data[0] = 0xe;
	state->data[1] = 0x83;
	state->data[2] = 0;
1581

1582
	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
1583 1584
		err("command 0x0e transfer failed.");

1585 1586 1587
	state->data[0] = 0xe;
	state->data[1] = 0x83;
	state->data[2] = 1;
1588

1589
	if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
1590 1591
		err("command 0x0e transfer failed.");

1592
	state->data[0] = 0x51;
1593

1594
	if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
1595 1596
		err("command 0x51 transfer failed.");

1597 1598 1599 1600 1601 1602 1603 1604 1605
	/* probe for demodulator i2c address */
	demod_addr = -1;
	if (tt_s2_4600_frontend_attach_probe_demod(d, 0x68))
		demod_addr = 0x68;
	else if (tt_s2_4600_frontend_attach_probe_demod(d, 0x69))
		demod_addr = 0x69;
	else if (tt_s2_4600_frontend_attach_probe_demod(d, 0x6a))
		demod_addr = 0x6a;

1606 1607
	mutex_unlock(&d->data_mutex);

1608 1609 1610 1611 1612
	if (demod_addr < 0) {
		err("probing for demodulator failed. Is the external power switched on?");
		return -ENODEV;
	}

1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626
	/* attach demod */
	m88ds3103_pdata.clk = 27000000;
	m88ds3103_pdata.i2c_wr_max = 33;
	m88ds3103_pdata.ts_mode = M88DS3103_TS_CI;
	m88ds3103_pdata.ts_clk = 16000;
	m88ds3103_pdata.ts_clk_pol = 0;
	m88ds3103_pdata.spec_inv = 0;
	m88ds3103_pdata.agc = 0x99;
	m88ds3103_pdata.agc_inv = 0;
	m88ds3103_pdata.clk_out = M88DS3103_CLOCK_OUT_ENABLED;
	m88ds3103_pdata.envelope_mode = 0;
	m88ds3103_pdata.lnb_hv_pol = 1;
	m88ds3103_pdata.lnb_en_pol = 0;
	memset(&board_info, 0, sizeof(board_info));
1627 1628 1629 1630 1631
	if (demod_addr == 0x6a)
		strscpy(board_info.type, "m88ds3103b", I2C_NAME_SIZE);
	else
		strscpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
	board_info.addr = demod_addr;
1632 1633
	board_info.platform_data = &m88ds3103_pdata;
	request_module("m88ds3103");
1634 1635
	client = i2c_new_client_device(&d->i2c_adap, &board_info);
	if (!i2c_client_has_driver(client))
1636
		return -ENODEV;
1637 1638 1639 1640 1641 1642 1643 1644
	if (!try_module_get(client->dev.driver->owner)) {
		i2c_unregister_device(client);
		return -ENODEV;
	}
	adap->fe_adap[0].fe = m88ds3103_pdata.get_dvb_frontend(client);
	i2c_adapter = m88ds3103_pdata.get_i2c_adapter(client);

	state->i2c_client_demod = client;
1645 1646

	/* attach tuner */
1647
	ts2020_config.fe = adap->fe_adap[0].fe;
1648
	memset(&board_info, 0, sizeof(board_info));
1649
	strscpy(board_info.type, "ts2022", I2C_NAME_SIZE);
1650 1651
	board_info.addr = 0x60;
	board_info.platform_data = &ts2020_config;
1652
	request_module("ts2020");
1653
	client = i2c_new_client_device(i2c_adapter, &board_info);
1654

1655
	if (!i2c_client_has_driver(client)) {
1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671
		dvb_frontend_detach(adap->fe_adap[0].fe);
		return -ENODEV;
	}

	if (!try_module_get(client->dev.driver->owner)) {
		i2c_unregister_device(client);
		dvb_frontend_detach(adap->fe_adap[0].fe);
		return -ENODEV;
	}

	/* delegate signal strength measurement to tuner */
	adap->fe_adap[0].fe->ops.read_signal_strength =
			adap->fe_adap[0].fe->ops.tuner_ops.get_rf_strength;

	state->i2c_client_tuner = client;

1672 1673 1674 1675 1676 1677
	/* hook fe: need to resync the slave fifo when signal locks */
	state->fe_read_status = adap->fe_adap[0].fe->ops.read_status;
	adap->fe_adap[0].fe->ops.read_status = tt_s2_4600_read_status;

	state->last_lock = 0;

1678 1679 1680
	return 0;
}

1681 1682
static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
{
1683
	dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
1684 1685 1686 1687
		&adap->dev->i2c_adap, DVB_PLL_OPERA1);
	return 0;
}

1688 1689
static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
{
1690
	dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
1691 1692 1693 1694 1695
		&adap->dev->i2c_adap, DVB_PLL_TUA6034);

	return 0;
}

1696 1697 1698 1699 1700 1701 1702 1703 1704
static int dw2102_rc_query(struct dvb_usb_device *d)
{
	u8 key[2];
	struct i2c_msg msg = {
		.addr = DW2102_RC_QUERY,
		.flags = I2C_M_RD,
		.buf = key,
		.len = 2
	};
1705

1706 1707 1708 1709
	if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
		if (msg.buf[0] != 0xff) {
			deb_rc("%s: rc code: %x, %x\n",
					__func__, key[0], key[1]);
1710
			rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, key[0], 0);
1711 1712
		}
	}
1713

1714 1715
	return 0;
}
1716

1717
static int prof_rc_query(struct dvb_usb_device *d)
1718 1719
{
	u8 key[2];
1720 1721 1722 1723 1724
	struct i2c_msg msg = {
		.addr = DW2102_RC_QUERY,
		.flags = I2C_M_RD,
		.buf = key,
		.len = 2
1725
	};
1726

1727 1728 1729 1730
	if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
		if (msg.buf[0] != 0xff) {
			deb_rc("%s: rc code: %x, %x\n",
					__func__, key[0], key[1]);
1731 1732
			rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, key[0] ^ 0xff,
				   0);
1733
		}
1734
	}
1735

1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747
	return 0;
}

static int su3000_rc_query(struct dvb_usb_device *d)
{
	u8 key[2];
	struct i2c_msg msg = {
		.addr = DW2102_RC_QUERY,
		.flags = I2C_M_RD,
		.buf = key,
		.len = 2
	};
1748

1749 1750 1751 1752
	if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
		if (msg.buf[0] != 0xff) {
			deb_rc("%s: rc code: %x, %x\n",
					__func__, key[0], key[1]);
1753
			rc_keydown(d->rc_dev, RC_PROTO_RC5,
1754
				   RC_SCANCODE_RC5(key[1], key[0]), 0);
1755
		}
1756
	}
1757

1758 1759 1760
	return 0;
}

1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772
enum dw2102_table_entry {
	CYPRESS_DW2102,
	CYPRESS_DW2101,
	CYPRESS_DW2104,
	TEVII_S650,
	TERRATEC_CINERGY_S,
	CYPRESS_DW3101,
	TEVII_S630,
	PROF_1100,
	TEVII_S660,
	PROF_7500,
	GENIATECH_SU3000,
1773
	HAUPPAUGE_MAX_S2,
1774
	TERRATEC_CINERGY_S2_R1,
1775 1776
	TEVII_S480_1,
	TEVII_S480_2,
1777
	GENIATECH_X3M_SPC1400HD,
1778 1779
	TEVII_S421,
	TEVII_S632,
1780
	TERRATEC_CINERGY_S2_R2,
1781
	TERRATEC_CINERGY_S2_R3,
1782
	TERRATEC_CINERGY_S2_R4,
1783 1784
	TERRATEC_CINERGY_S2_1,
	TERRATEC_CINERGY_S2_2,
1785
	GOTVIEW_SAT_HD,
1786
	GENIATECH_T220,
1787
	TECHNOTREND_CONNECT_S2_4600,
1788 1789
	TEVII_S482_1,
	TEVII_S482_2,
1790
	TERRATEC_CINERGY_S2_BOX,
1791
	TEVII_S662
1792 1793
};

1794
static struct usb_device_id dw2102_table[] = {
1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824
	DVB_USB_DEV(CYPRESS, CYPRESS_DW2102),
	DVB_USB_DEV(CYPRESS, CYPRESS_DW2101),
	DVB_USB_DEV(CYPRESS, CYPRESS_DW2104),
	DVB_USB_DEV(TEVII, TEVII_S650),
	DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S),
	DVB_USB_DEV(CYPRESS, CYPRESS_DW3101),
	DVB_USB_DEV(TEVII, TEVII_S630),
	DVB_USB_DEV(PROF_1, PROF_1100),
	DVB_USB_DEV(TEVII, TEVII_S660),
	DVB_USB_DEV(PROF_2, PROF_7500),
	DVB_USB_DEV(GTEK, GENIATECH_SU3000),
	DVB_USB_DEV(HAUPPAUGE, HAUPPAUGE_MAX_S2),
	DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S2_R1),
	DVB_USB_DEV(TEVII, TEVII_S480_1),
	DVB_USB_DEV(TEVII, TEVII_S480_2),
	DVB_USB_DEV(GTEK, GENIATECH_X3M_SPC1400HD),
	DVB_USB_DEV(TEVII, TEVII_S421),
	DVB_USB_DEV(TEVII, TEVII_S632),
	DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S2_R2),
	DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S2_R3),
	DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S2_R4),
	DVB_USB_DEV(TERRATEC_2, TERRATEC_CINERGY_S2_1),
	DVB_USB_DEV(TERRATEC_2, TERRATEC_CINERGY_S2_2),
	DVB_USB_DEV(GOTVIEW, GOTVIEW_SAT_HD),
	DVB_USB_DEV(GTEK, GENIATECH_T220),
	DVB_USB_DEV(TECHNOTREND, TECHNOTREND_CONNECT_S2_4600),
	DVB_USB_DEV(TEVII, TEVII_S482_1),
	DVB_USB_DEV(TEVII, TEVII_S482_2),
	DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S2_BOX),
	DVB_USB_DEV(TEVII, TEVII_S662),
1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835
	{ }
};

MODULE_DEVICE_TABLE(usb, dw2102_table);

static int dw2102_load_firmware(struct usb_device *dev,
			const struct firmware *frmwr)
{
	u8 *b, *p;
	int ret = 0, i;
	u8 reset;
1836
	u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
1837
	const struct firmware *fw;
1838

1839
	switch (le16_to_cpu(dev->descriptor.idProduct)) {
1840
	case 0x2101:
1841
		ret = request_firmware(&fw, DW2101_FIRMWARE, &dev->dev);
1842
		if (ret != 0) {
1843
			err(err_str, DW2101_FIRMWARE);
1844 1845 1846
			return ret;
		}
		break;
1847
	default:
1848 1849 1850
		fw = frmwr;
		break;
	}
1851
	info("start downloading DW210X firmware");
1852 1853 1854
	p = kmalloc(fw->size, GFP_KERNEL);
	reset = 1;
	/*stop the CPU*/
1855 1856
	dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG);
	dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG);
1857 1858 1859 1860 1861

	if (p != NULL) {
		memcpy(p, fw->data, fw->size);
		for (i = 0; i < fw->size; i += 0x40) {
			b = (u8 *) p + i;
1862 1863
			if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40,
					DW210X_WRITE_MSG) != 0x40) {
1864 1865 1866 1867 1868 1869 1870
				err("error while transferring firmware");
				ret = -EINVAL;
				break;
			}
		}
		/* restart the CPU */
		reset = 0;
1871 1872
		if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1,
					DW210X_WRITE_MSG) != 1) {
1873 1874 1875
			err("could not restart the USB controller CPU.");
			ret = -EINVAL;
		}
1876 1877
		if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1,
					DW210X_WRITE_MSG) != 1) {
1878 1879 1880 1881
			err("could not restart the USB controller CPU.");
			ret = -EINVAL;
		}
		/* init registers */
1882
		switch (le16_to_cpu(dev->descriptor.idProduct)) {
1883
		case USB_PID_TEVII_S650:
1884
			dw2104_properties.rc.core.rc_codes = RC_MAP_TEVII_NEC;
1885
			fallthrough;
1886
		case USB_PID_CYPRESS_DW2104:
1887
			reset = 1;
1888 1889
			dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
					DW210X_WRITE_MSG);
1890
			fallthrough;
1891
		case USB_PID_CYPRESS_DW3101:
1892
			reset = 0;
1893 1894
			dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
					DW210X_WRITE_MSG);
1895
			break;
1896
		case USB_PID_TERRATEC_CINERGY_S:
1897
		case USB_PID_CYPRESS_DW2102:
1898 1899 1900 1901 1902 1903 1904
			dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
					DW210X_WRITE_MSG);
			dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
					DW210X_READ_MSG);
			/* check STV0299 frontend  */
			dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
					DW210X_READ_MSG);
1905
			if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) {
1906
				dw2102_properties.i2c_algo = &dw2102_i2c_algo;
1907
				dw2102_properties.adapter->fe[0].tuner_attach = &dw2102_tuner_attach;
1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922
				break;
			} else {
				/* check STV0288 frontend  */
				reset16[0] = 0xd0;
				reset16[1] = 1;
				reset16[2] = 0;
				dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3,
						DW210X_WRITE_MSG);
				dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3,
						DW210X_READ_MSG);
				if (reset16[2] == 0x11) {
					dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
					break;
				}
			}
1923
			fallthrough;
1924
		case 0x2101:
1925 1926 1927 1928 1929 1930 1931 1932
			dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
					DW210X_READ_MSG);
			dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
					DW210X_READ_MSG);
			dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
					DW210X_READ_MSG);
			dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
					DW210X_READ_MSG);
1933 1934
			break;
		}
1935

1936
		msleep(100);
1937 1938
		kfree(p);
	}
1939 1940 1941

	if (le16_to_cpu(dev->descriptor.idProduct) == 0x2101)
		release_firmware(fw);
1942 1943 1944 1945 1946 1947
	return ret;
}

static struct dvb_usb_device_properties dw2102_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
	.usb_ctrl = DEVICE_SPECIFIC,
1948
	.firmware = DW2102_FIRMWARE,
1949 1950
	.no_reconnect = 1,

1951
	.i2c_algo = &dw2102_serit_i2c_algo,
1952

1953
	.rc.core = {
1954
		.rc_interval = 150,
1955 1956
		.rc_codes = RC_MAP_DM1105_NEC,
		.module_name = "dw2102",
1957
		.allowed_protos   = RC_PROTO_BIT_NEC,
1958 1959
		.rc_query = dw2102_rc_query,
	},
1960 1961 1962 1963 1964

	.generic_bulk_ctrl_endpoint = 0x81,
	/* parameter for the MPEG2-data transfer */
	.num_adapters = 1,
	.download_firmware = dw2102_load_firmware,
1965
	.read_mac_address = dw210x_read_mac_address,
1966
	.adapter = {
1967
		{
1968 1969
		.num_frontends = 1,
		.fe = {{
1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980
			.frontend_attach = dw2102_frontend_attach,
			.stream = {
				.type = USB_BULK,
				.count = 8,
				.endpoint = 0x82,
				.u = {
					.bulk = {
						.buffersize = 4096,
					}
				}
			},
1981
		}},
1982 1983
		}
	},
1984
	.num_device_descs = 3,
1985 1986
	.devices = {
		{"DVBWorld DVB-S 2102 USB2.0",
1987
			{&dw2102_table[CYPRESS_DW2102], NULL},
1988 1989 1990
			{NULL},
		},
		{"DVBWorld DVB-S 2101 USB2.0",
1991
			{&dw2102_table[CYPRESS_DW2101], NULL},
1992
			{NULL},
1993 1994
		},
		{"TerraTec Cinergy S USB",
1995
			{&dw2102_table[TERRATEC_CINERGY_S], NULL},
1996
			{NULL},
1997 1998 1999 2000
		},
	}
};

2001 2002 2003
static struct dvb_usb_device_properties dw2104_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
	.usb_ctrl = DEVICE_SPECIFIC,
2004
	.firmware = DW2104_FIRMWARE,
2005 2006 2007
	.no_reconnect = 1,

	.i2c_algo = &dw2104_i2c_algo,
2008
	.rc.core = {
2009
		.rc_interval = 150,
2010 2011
		.rc_codes = RC_MAP_DM1105_NEC,
		.module_name = "dw2102",
2012
		.allowed_protos   = RC_PROTO_BIT_NEC,
2013 2014
		.rc_query = dw2102_rc_query,
	},
2015 2016 2017 2018 2019

	.generic_bulk_ctrl_endpoint = 0x81,
	/* parameter for the MPEG2-data transfer */
	.num_adapters = 1,
	.download_firmware = dw2102_load_firmware,
2020
	.read_mac_address = dw210x_read_mac_address,
2021 2022
	.adapter = {
		{
2023 2024
		.num_frontends = 1,
		.fe = {{
2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035
			.frontend_attach = dw2104_frontend_attach,
			.stream = {
				.type = USB_BULK,
				.count = 8,
				.endpoint = 0x82,
				.u = {
					.bulk = {
						.buffersize = 4096,
					}
				}
			},
2036
		}},
2037 2038 2039 2040 2041
		}
	},
	.num_device_descs = 2,
	.devices = {
		{ "DVBWorld DW2104 USB2.0",
2042
			{&dw2102_table[CYPRESS_DW2104], NULL},
2043 2044 2045
			{NULL},
		},
		{ "TeVii S650 USB2.0",
2046
			{&dw2102_table[TEVII_S650], NULL},
2047 2048 2049 2050 2051
			{NULL},
		},
	}
};

2052 2053 2054
static struct dvb_usb_device_properties dw3101_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
	.usb_ctrl = DEVICE_SPECIFIC,
2055
	.firmware = DW3101_FIRMWARE,
2056 2057 2058
	.no_reconnect = 1,

	.i2c_algo = &dw3101_i2c_algo,
2059
	.rc.core = {
2060
		.rc_interval = 150,
2061 2062
		.rc_codes = RC_MAP_DM1105_NEC,
		.module_name = "dw2102",
2063
		.allowed_protos   = RC_PROTO_BIT_NEC,
2064 2065
		.rc_query = dw2102_rc_query,
	},
2066 2067 2068 2069 2070 2071 2072 2073

	.generic_bulk_ctrl_endpoint = 0x81,
	/* parameter for the MPEG2-data transfer */
	.num_adapters = 1,
	.download_firmware = dw2102_load_firmware,
	.read_mac_address = dw210x_read_mac_address,
	.adapter = {
		{
2074 2075
		.num_frontends = 1,
		.fe = {{
2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087
			.frontend_attach = dw3101_frontend_attach,
			.tuner_attach = dw3101_tuner_attach,
			.stream = {
				.type = USB_BULK,
				.count = 8,
				.endpoint = 0x82,
				.u = {
					.bulk = {
						.buffersize = 4096,
					}
				}
			},
2088
		}},
2089 2090 2091 2092 2093
		}
	},
	.num_device_descs = 1,
	.devices = {
		{ "DVBWorld DVB-C 3101 USB2.0",
2094
			{&dw2102_table[CYPRESS_DW3101], NULL},
2095 2096 2097 2098 2099
			{NULL},
		},
	}
};

2100
static struct dvb_usb_device_properties s6x0_properties = {
2101 2102
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
	.usb_ctrl = DEVICE_SPECIFIC,
2103
	.size_of_priv = sizeof(struct dw2102_state),
2104
	.firmware = S630_FIRMWARE,
2105 2106
	.no_reconnect = 1,

2107
	.i2c_algo = &s6x0_i2c_algo,
2108
	.rc.core = {
2109
		.rc_interval = 150,
2110 2111
		.rc_codes = RC_MAP_TEVII_NEC,
		.module_name = "dw2102",
2112
		.allowed_protos   = RC_PROTO_BIT_NEC,
2113 2114
		.rc_query = dw2102_rc_query,
	},
2115 2116 2117 2118

	.generic_bulk_ctrl_endpoint = 0x81,
	.num_adapters = 1,
	.download_firmware = dw2102_load_firmware,
2119
	.read_mac_address = s6x0_read_mac_address,
2120 2121
	.adapter = {
		{
2122 2123
		.num_frontends = 1,
		.fe = {{
2124
			.frontend_attach = zl100313_frontend_attach,
2125 2126 2127 2128 2129 2130 2131 2132 2133 2134
			.stream = {
				.type = USB_BULK,
				.count = 8,
				.endpoint = 0x82,
				.u = {
					.bulk = {
						.buffersize = 4096,
					}
				}
			},
2135
		}},
2136 2137
		}
	},
2138
	.num_device_descs = 1,
2139 2140
	.devices = {
		{"TeVii S630 USB",
2141
			{&dw2102_table[TEVII_S630], NULL},
2142 2143 2144 2145 2146
			{NULL},
		},
	}
};

A
Anton Vasilyev 已提交
2147 2148 2149 2150 2151 2152
static struct dvb_usb_device_properties p1100_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
	.usb_ctrl = DEVICE_SPECIFIC,
	.size_of_priv = sizeof(struct dw2102_state),
	.firmware = P1100_FIRMWARE,
	.no_reconnect = 1,
2153

A
Anton Vasilyev 已提交
2154 2155 2156 2157 2158 2159 2160 2161
	.i2c_algo = &s6x0_i2c_algo,
	.rc.core = {
		.rc_interval = 150,
		.rc_codes = RC_MAP_TBS_NEC,
		.module_name = "dw2102",
		.allowed_protos   = RC_PROTO_BIT_NEC,
		.rc_query = prof_rc_query,
	},
2162

A
Anton Vasilyev 已提交
2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191
	.generic_bulk_ctrl_endpoint = 0x81,
	.num_adapters = 1,
	.download_firmware = dw2102_load_firmware,
	.read_mac_address = s6x0_read_mac_address,
	.adapter = {
		{
			.num_frontends = 1,
			.fe = {{
				.frontend_attach = stv0288_frontend_attach,
				.stream = {
					.type = USB_BULK,
					.count = 8,
					.endpoint = 0x82,
					.u = {
						.bulk = {
							.buffersize = 4096,
						}
					}
				},
			} },
		}
	},
	.num_device_descs = 1,
	.devices = {
		{"Prof 1100 USB ",
			{&dw2102_table[PROF_1100], NULL},
			{NULL},
		},
	}
2192 2193
};

A
Anton Vasilyev 已提交
2194 2195 2196 2197 2198 2199
static struct dvb_usb_device_properties s660_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
	.usb_ctrl = DEVICE_SPECIFIC,
	.size_of_priv = sizeof(struct dw2102_state),
	.firmware = S660_FIRMWARE,
	.no_reconnect = 1,
2200

A
Anton Vasilyev 已提交
2201 2202 2203 2204 2205 2206 2207 2208
	.i2c_algo = &s6x0_i2c_algo,
	.rc.core = {
		.rc_interval = 150,
		.rc_codes = RC_MAP_TEVII_NEC,
		.module_name = "dw2102",
		.allowed_protos   = RC_PROTO_BIT_NEC,
		.rc_query = dw2102_rc_query,
	},
2209

A
Anton Vasilyev 已提交
2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246
	.generic_bulk_ctrl_endpoint = 0x81,
	.num_adapters = 1,
	.download_firmware = dw2102_load_firmware,
	.read_mac_address = s6x0_read_mac_address,
	.adapter = {
		{
			.num_frontends = 1,
			.fe = {{
				.frontend_attach = ds3000_frontend_attach,
				.stream = {
					.type = USB_BULK,
					.count = 8,
					.endpoint = 0x82,
					.u = {
						.bulk = {
							.buffersize = 4096,
						}
					}
				},
			} },
		}
	},
	.num_device_descs = 3,
	.devices = {
		{"TeVii S660 USB",
			{&dw2102_table[TEVII_S660], NULL},
			{NULL},
		},
		{"TeVii S480.1 USB",
			{&dw2102_table[TEVII_S480_1], NULL},
			{NULL},
		},
		{"TeVii S480.2 USB",
			{&dw2102_table[TEVII_S480_2], NULL},
			{NULL},
		},
	}
2247 2248
};

A
Anton Vasilyev 已提交
2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293
static struct dvb_usb_device_properties p7500_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
	.usb_ctrl = DEVICE_SPECIFIC,
	.size_of_priv = sizeof(struct dw2102_state),
	.firmware = P7500_FIRMWARE,
	.no_reconnect = 1,

	.i2c_algo = &s6x0_i2c_algo,
	.rc.core = {
		.rc_interval = 150,
		.rc_codes = RC_MAP_TBS_NEC,
		.module_name = "dw2102",
		.allowed_protos   = RC_PROTO_BIT_NEC,
		.rc_query = prof_rc_query,
	},

	.generic_bulk_ctrl_endpoint = 0x81,
	.num_adapters = 1,
	.download_firmware = dw2102_load_firmware,
	.read_mac_address = s6x0_read_mac_address,
	.adapter = {
		{
			.num_frontends = 1,
			.fe = {{
				.frontend_attach = prof_7500_frontend_attach,
				.stream = {
					.type = USB_BULK,
					.count = 8,
					.endpoint = 0x82,
					.u = {
						.bulk = {
							.buffersize = 4096,
						}
					}
				},
			} },
		}
	},
	.num_device_descs = 1,
	.devices = {
		{"Prof 7500 USB DVB-S2",
			{&dw2102_table[PROF_7500], NULL},
			{NULL},
		},
	}
2294 2295
};

2296 2297 2298
static struct dvb_usb_device_properties su3000_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
	.usb_ctrl = DEVICE_SPECIFIC,
2299
	.size_of_priv = sizeof(struct dw2102_state),
2300 2301 2302 2303 2304
	.power_ctrl = su3000_power_ctrl,
	.num_adapters = 1,
	.identify_state	= su3000_identify_state,
	.i2c_algo = &su3000_i2c_algo,

2305
	.rc.core = {
2306
		.rc_interval = 150,
2307 2308
		.rc_codes = RC_MAP_SU3000,
		.module_name = "dw2102",
2309
		.allowed_protos   = RC_PROTO_BIT_RC5,
2310
		.rc_query = su3000_rc_query,
2311 2312 2313 2314 2315 2316 2317 2318
	},

	.read_mac_address = su3000_read_mac_address,

	.generic_bulk_ctrl_endpoint = 0x01,

	.adapter = {
		{
2319 2320
		.num_frontends = 1,
		.fe = {{
2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332
			.streaming_ctrl   = su3000_streaming_ctrl,
			.frontend_attach  = su3000_frontend_attach,
			.stream = {
				.type = USB_BULK,
				.count = 8,
				.endpoint = 0x82,
				.u = {
					.bulk = {
						.buffersize = 4096,
					}
				}
			}
2333
		}},
2334 2335
		}
	},
2336
	.num_device_descs = 9,
2337 2338
	.devices = {
		{ "SU3000HD DVB-S USB2.0",
2339
			{ &dw2102_table[GENIATECH_SU3000], NULL },
2340 2341
			{ NULL },
		},
2342 2343 2344 2345
		{ "Hauppauge MAX S2 or WinTV NOVA HD USB2.0",
			{ &dw2102_table[HAUPPAUGE_MAX_S2], NULL },
			{ NULL },
		},
2346
		{ "Terratec Cinergy S2 USB HD",
2347
			{ &dw2102_table[TERRATEC_CINERGY_S2_R1], NULL },
2348 2349
			{ NULL },
		},
2350
		{ "X3M TV SPC1400HD PCI",
2351
			{ &dw2102_table[GENIATECH_X3M_SPC1400HD], NULL },
2352 2353
			{ NULL },
		},
2354 2355 2356 2357
		{ "Terratec Cinergy S2 USB HD Rev.2",
			{ &dw2102_table[TERRATEC_CINERGY_S2_R2], NULL },
			{ NULL },
		},
2358 2359 2360 2361
		{ "Terratec Cinergy S2 USB HD Rev.3",
			{ &dw2102_table[TERRATEC_CINERGY_S2_R3], NULL },
			{ NULL },
		},
2362 2363 2364 2365 2366 2367 2368 2369
		{ "Terratec Cinergy S2 PCIe Dual Port 1",
			{ &dw2102_table[TERRATEC_CINERGY_S2_1], NULL },
			{ NULL },
		},
		{ "Terratec Cinergy S2 PCIe Dual Port 2",
			{ &dw2102_table[TERRATEC_CINERGY_S2_2], NULL },
			{ NULL },
		},
2370 2371 2372 2373
		{ "GOTVIEW Satellite HD",
			{ &dw2102_table[GOTVIEW_SAT_HD], NULL },
			{ NULL },
		},
2374 2375 2376
	}
};

A
Anton Vasilyev 已提交
2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429
static struct dvb_usb_device_properties s421_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
	.usb_ctrl = DEVICE_SPECIFIC,
	.size_of_priv = sizeof(struct dw2102_state),
	.power_ctrl = su3000_power_ctrl,
	.num_adapters = 1,
	.identify_state	= su3000_identify_state,
	.i2c_algo = &su3000_i2c_algo,

	.rc.core = {
		.rc_interval = 150,
		.rc_codes = RC_MAP_SU3000,
		.module_name = "dw2102",
		.allowed_protos   = RC_PROTO_BIT_RC5,
		.rc_query = su3000_rc_query,
	},

	.read_mac_address = su3000_read_mac_address,

	.generic_bulk_ctrl_endpoint = 0x01,

	.adapter = {
		{
		.num_frontends = 1,
		.fe = {{
			.streaming_ctrl   = su3000_streaming_ctrl,
			.frontend_attach  = m88rs2000_frontend_attach,
			.stream = {
				.type = USB_BULK,
				.count = 8,
				.endpoint = 0x82,
				.u = {
					.bulk = {
						.buffersize = 4096,
					}
				}
			}
		} },
		}
	},
	.num_device_descs = 2,
	.devices = {
		{ "TeVii S421 PCI",
			{ &dw2102_table[TEVII_S421], NULL },
			{ NULL },
		},
		{ "TeVii S632 USB",
			{ &dw2102_table[TEVII_S632], NULL },
			{ NULL },
		},
	}
};

2430 2431 2432
static struct dvb_usb_device_properties t220_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
	.usb_ctrl = DEVICE_SPECIFIC,
2433
	.size_of_priv = sizeof(struct dw2102_state),
2434 2435 2436 2437 2438
	.power_ctrl = su3000_power_ctrl,
	.num_adapters = 1,
	.identify_state	= su3000_identify_state,
	.i2c_algo = &su3000_i2c_algo,

2439
	.rc.core = {
2440
		.rc_interval = 150,
2441 2442
		.rc_codes = RC_MAP_SU3000,
		.module_name = "dw2102",
2443
		.allowed_protos   = RC_PROTO_BIT_RC5,
2444
		.rc_query = su3000_rc_query,
2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478
	},

	.read_mac_address = su3000_read_mac_address,

	.generic_bulk_ctrl_endpoint = 0x01,

	.adapter = {
		{
		.num_frontends = 1,
		.fe = { {
			.streaming_ctrl   = su3000_streaming_ctrl,
			.frontend_attach  = t220_frontend_attach,
			.stream = {
				.type = USB_BULK,
				.count = 8,
				.endpoint = 0x82,
				.u = {
					.bulk = {
						.buffersize = 4096,
					}
				}
			}
		} },
		}
	},
	.num_device_descs = 1,
	.devices = {
		{ "Geniatech T220 DVB-T/T2 USB2.0",
			{ &dw2102_table[GENIATECH_T220], NULL },
			{ NULL },
		},
	}
};

2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491
static struct dvb_usb_device_properties tt_s2_4600_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
	.usb_ctrl = DEVICE_SPECIFIC,
	.size_of_priv = sizeof(struct dw2102_state),
	.power_ctrl = su3000_power_ctrl,
	.num_adapters = 1,
	.identify_state	= su3000_identify_state,
	.i2c_algo = &su3000_i2c_algo,

	.rc.core = {
		.rc_interval = 250,
		.rc_codes = RC_MAP_TT_1500,
		.module_name = "dw2102",
2492
		.allowed_protos   = RC_PROTO_BIT_RC5,
2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518
		.rc_query = su3000_rc_query,
	},

	.read_mac_address = su3000_read_mac_address,

	.generic_bulk_ctrl_endpoint = 0x01,

	.adapter = {
		{
		.num_frontends = 1,
		.fe = {{
			.streaming_ctrl   = su3000_streaming_ctrl,
			.frontend_attach  = tt_s2_4600_frontend_attach,
			.stream = {
				.type = USB_BULK,
				.count = 8,
				.endpoint = 0x82,
				.u = {
					.bulk = {
						.buffersize = 4096,
					}
				}
			}
		} },
		}
	},
2519
	.num_device_descs = 5,
2520 2521
	.devices = {
		{ "TechnoTrend TT-connect S2-4600",
2522
			{ &dw2102_table[TECHNOTREND_CONNECT_S2_4600], NULL },
2523 2524
			{ NULL },
		},
2525 2526 2527 2528 2529 2530 2531 2532
		{ "TeVii S482 (tuner 1)",
			{ &dw2102_table[TEVII_S482_1], NULL },
			{ NULL },
		},
		{ "TeVii S482 (tuner 2)",
			{ &dw2102_table[TEVII_S482_2], NULL },
			{ NULL },
		},
2533 2534 2535 2536
		{ "Terratec Cinergy S2 USB BOX",
			{ &dw2102_table[TERRATEC_CINERGY_S2_BOX], NULL },
			{ NULL },
		},
2537 2538 2539 2540
		{ "TeVii S662",
			{ &dw2102_table[TEVII_S662], NULL },
			{ NULL },
		},
2541 2542 2543
	}
};

2544 2545 2546
static int dw2102_probe(struct usb_interface *intf,
		const struct usb_device_id *id)
{
A
Anton Vasilyev 已提交
2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568
	if (!(dvb_usb_device_init(intf, &dw2102_properties,
			          THIS_MODULE, NULL, adapter_nr) &&
	      dvb_usb_device_init(intf, &dw2104_properties,
				  THIS_MODULE, NULL, adapter_nr) &&
	      dvb_usb_device_init(intf, &dw3101_properties,
			          THIS_MODULE, NULL, adapter_nr) &&
	      dvb_usb_device_init(intf, &s6x0_properties,
			          THIS_MODULE, NULL, adapter_nr) &&
	      dvb_usb_device_init(intf, &p1100_properties,
			          THIS_MODULE, NULL, adapter_nr) &&
	      dvb_usb_device_init(intf, &s660_properties,
				  THIS_MODULE, NULL, adapter_nr) &&
	      dvb_usb_device_init(intf, &p7500_properties,
				  THIS_MODULE, NULL, adapter_nr) &&
	      dvb_usb_device_init(intf, &s421_properties,
				  THIS_MODULE, NULL, adapter_nr) &&
	      dvb_usb_device_init(intf, &su3000_properties,
				  THIS_MODULE, NULL, adapter_nr) &&
	      dvb_usb_device_init(intf, &t220_properties,
				  THIS_MODULE, NULL, adapter_nr) &&
	      dvb_usb_device_init(intf, &tt_s2_4600_properties,
				  THIS_MODULE, NULL, adapter_nr))) {
2569

2570
		return 0;
2571
	}
2572

A
Anton Vasilyev 已提交
2573
	return -ENODEV;
2574 2575
}

2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588
static void dw2102_disconnect(struct usb_interface *intf)
{
	struct dvb_usb_device *d = usb_get_intfdata(intf);
	struct dw2102_state *st = (struct dw2102_state *)d->priv;
	struct i2c_client *client;

	/* remove I2C client for tuner */
	client = st->i2c_client_tuner;
	if (client) {
		module_put(client->dev.driver->owner);
		i2c_unregister_device(client);
	}

2589 2590 2591 2592 2593 2594 2595
	/* remove I2C client for demodulator */
	client = st->i2c_client_demod;
	if (client) {
		module_put(client->dev.driver->owner);
		i2c_unregister_device(client);
	}

2596 2597 2598
	dvb_usb_device_exit(intf);
}

2599 2600 2601
static struct usb_driver dw2102_driver = {
	.name = "dw2102",
	.probe = dw2102_probe,
2602
	.disconnect = dw2102_disconnect,
2603 2604 2605
	.id_table = dw2102_table,
};

2606
module_usb_driver(dw2102_driver);
2607 2608

MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
2609
MODULE_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");
2610 2611
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");
2612 2613 2614 2615 2616 2617 2618 2619
MODULE_FIRMWARE(DW2101_FIRMWARE);
MODULE_FIRMWARE(DW2102_FIRMWARE);
MODULE_FIRMWARE(DW2104_FIRMWARE);
MODULE_FIRMWARE(DW3101_FIRMWARE);
MODULE_FIRMWARE(S630_FIRMWARE);
MODULE_FIRMWARE(S660_FIRMWARE);
MODULE_FIRMWARE(P1100_FIRMWARE);
MODULE_FIRMWARE(P7500_FIRMWARE);