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