162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* DVB USB framework compliant Linux driver for the 362306a36Sopenharmony_ci * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, 462306a36Sopenharmony_ci * TeVii S421, S480, S482, S600, S630, S632, S650, S660, S662, 562306a36Sopenharmony_ci * Prof 1100, 7500, 662306a36Sopenharmony_ci * Geniatech SU3000, T220, 762306a36Sopenharmony_ci * TechnoTrend S2-4600, 862306a36Sopenharmony_ci * Terratec Cinergy S2 cards 962306a36Sopenharmony_ci * Copyright (C) 2008-2012 Igor M. Liplianin (liplianin@me.by) 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information 1262306a36Sopenharmony_ci */ 1362306a36Sopenharmony_ci#include <media/dvb-usb-ids.h> 1462306a36Sopenharmony_ci#include "dw2102.h" 1562306a36Sopenharmony_ci#include "si21xx.h" 1662306a36Sopenharmony_ci#include "stv0299.h" 1762306a36Sopenharmony_ci#include "z0194a.h" 1862306a36Sopenharmony_ci#include "stv0288.h" 1962306a36Sopenharmony_ci#include "stb6000.h" 2062306a36Sopenharmony_ci#include "eds1547.h" 2162306a36Sopenharmony_ci#include "cx24116.h" 2262306a36Sopenharmony_ci#include "tda1002x.h" 2362306a36Sopenharmony_ci#include "mt312.h" 2462306a36Sopenharmony_ci#include "zl10039.h" 2562306a36Sopenharmony_ci#include "ts2020.h" 2662306a36Sopenharmony_ci#include "ds3000.h" 2762306a36Sopenharmony_ci#include "stv0900.h" 2862306a36Sopenharmony_ci#include "stv6110.h" 2962306a36Sopenharmony_ci#include "stb6100.h" 3062306a36Sopenharmony_ci#include "stb6100_proc.h" 3162306a36Sopenharmony_ci#include "m88rs2000.h" 3262306a36Sopenharmony_ci#include "tda18271.h" 3362306a36Sopenharmony_ci#include "cxd2820r.h" 3462306a36Sopenharmony_ci#include "m88ds3103.h" 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci/* Max transfer size done by I2C transfer functions */ 3762306a36Sopenharmony_ci#define MAX_XFER_SIZE 64 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#define DW210X_READ_MSG 0 4162306a36Sopenharmony_ci#define DW210X_WRITE_MSG 1 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#define REG_1F_SYMBOLRATE_BYTE0 0x1f 4462306a36Sopenharmony_ci#define REG_20_SYMBOLRATE_BYTE1 0x20 4562306a36Sopenharmony_ci#define REG_21_SYMBOLRATE_BYTE2 0x21 4662306a36Sopenharmony_ci/* on my own*/ 4762306a36Sopenharmony_ci#define DW2102_VOLTAGE_CTRL (0x1800) 4862306a36Sopenharmony_ci#define SU3000_STREAM_CTRL (0x1900) 4962306a36Sopenharmony_ci#define DW2102_RC_QUERY (0x1a00) 5062306a36Sopenharmony_ci#define DW2102_LED_CTRL (0x1b00) 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci#define DW2101_FIRMWARE "dvb-usb-dw2101.fw" 5362306a36Sopenharmony_ci#define DW2102_FIRMWARE "dvb-usb-dw2102.fw" 5462306a36Sopenharmony_ci#define DW2104_FIRMWARE "dvb-usb-dw2104.fw" 5562306a36Sopenharmony_ci#define DW3101_FIRMWARE "dvb-usb-dw3101.fw" 5662306a36Sopenharmony_ci#define S630_FIRMWARE "dvb-usb-s630.fw" 5762306a36Sopenharmony_ci#define S660_FIRMWARE "dvb-usb-s660.fw" 5862306a36Sopenharmony_ci#define P1100_FIRMWARE "dvb-usb-p1100.fw" 5962306a36Sopenharmony_ci#define P7500_FIRMWARE "dvb-usb-p7500.fw" 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci#define err_str "did not find the firmware file '%s'. You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware" 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistruct dw2102_state { 6462306a36Sopenharmony_ci u8 initialized; 6562306a36Sopenharmony_ci u8 last_lock; 6662306a36Sopenharmony_ci u8 data[MAX_XFER_SIZE + 4]; 6762306a36Sopenharmony_ci struct i2c_client *i2c_client_demod; 6862306a36Sopenharmony_ci struct i2c_client *i2c_client_tuner; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci /* fe hook functions*/ 7162306a36Sopenharmony_ci int (*old_set_voltage)(struct dvb_frontend *f, enum fe_sec_voltage v); 7262306a36Sopenharmony_ci int (*fe_read_status)(struct dvb_frontend *fe, 7362306a36Sopenharmony_ci enum fe_status *status); 7462306a36Sopenharmony_ci}; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci/* debug */ 7762306a36Sopenharmony_cistatic int dvb_usb_dw2102_debug; 7862306a36Sopenharmony_cimodule_param_named(debug, dvb_usb_dw2102_debug, int, 0644); 7962306a36Sopenharmony_ciMODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))." 8062306a36Sopenharmony_ci DVB_USB_DEBUG_STATUS); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci/* demod probe */ 8362306a36Sopenharmony_cistatic int demod_probe = 1; 8462306a36Sopenharmony_cimodule_param_named(demod, demod_probe, int, 0644); 8562306a36Sopenharmony_ciMODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 4=stv0903+stb6100(or-able))."); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ciDVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cistatic int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value, 9062306a36Sopenharmony_ci u16 index, u8 * data, u16 len, int flags) 9162306a36Sopenharmony_ci{ 9262306a36Sopenharmony_ci int ret; 9362306a36Sopenharmony_ci u8 *u8buf; 9462306a36Sopenharmony_ci unsigned int pipe = (flags == DW210X_READ_MSG) ? 9562306a36Sopenharmony_ci usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); 9662306a36Sopenharmony_ci u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci u8buf = kmalloc(len, GFP_KERNEL); 9962306a36Sopenharmony_ci if (!u8buf) 10062306a36Sopenharmony_ci return -ENOMEM; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci if (flags == DW210X_WRITE_MSG) 10462306a36Sopenharmony_ci memcpy(u8buf, data, len); 10562306a36Sopenharmony_ci ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, 10662306a36Sopenharmony_ci value, index , u8buf, len, 2000); 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci if (flags == DW210X_READ_MSG) 10962306a36Sopenharmony_ci memcpy(data, u8buf, len); 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci kfree(u8buf); 11262306a36Sopenharmony_ci return ret; 11362306a36Sopenharmony_ci} 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci/* I2C */ 11662306a36Sopenharmony_cistatic int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], 11762306a36Sopenharmony_ci int num) 11862306a36Sopenharmony_ci{ 11962306a36Sopenharmony_ci struct dvb_usb_device *d = i2c_get_adapdata(adap); 12062306a36Sopenharmony_ci int i = 0; 12162306a36Sopenharmony_ci u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0}; 12262306a36Sopenharmony_ci u16 value; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci if (!d) 12562306a36Sopenharmony_ci return -ENODEV; 12662306a36Sopenharmony_ci if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 12762306a36Sopenharmony_ci return -EAGAIN; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci switch (num) { 13062306a36Sopenharmony_ci case 2: 13162306a36Sopenharmony_ci if (msg[0].len < 1) { 13262306a36Sopenharmony_ci num = -EOPNOTSUPP; 13362306a36Sopenharmony_ci break; 13462306a36Sopenharmony_ci } 13562306a36Sopenharmony_ci /* read stv0299 register */ 13662306a36Sopenharmony_ci value = msg[0].buf[0];/* register */ 13762306a36Sopenharmony_ci for (i = 0; i < msg[1].len; i++) { 13862306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xb5, value + i, 0, 13962306a36Sopenharmony_ci buf6, 2, DW210X_READ_MSG); 14062306a36Sopenharmony_ci msg[1].buf[i] = buf6[0]; 14162306a36Sopenharmony_ci } 14262306a36Sopenharmony_ci break; 14362306a36Sopenharmony_ci case 1: 14462306a36Sopenharmony_ci switch (msg[0].addr) { 14562306a36Sopenharmony_ci case 0x68: 14662306a36Sopenharmony_ci if (msg[0].len < 2) { 14762306a36Sopenharmony_ci num = -EOPNOTSUPP; 14862306a36Sopenharmony_ci break; 14962306a36Sopenharmony_ci } 15062306a36Sopenharmony_ci /* write to stv0299 register */ 15162306a36Sopenharmony_ci buf6[0] = 0x2a; 15262306a36Sopenharmony_ci buf6[1] = msg[0].buf[0]; 15362306a36Sopenharmony_ci buf6[2] = msg[0].buf[1]; 15462306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xb2, 0, 0, 15562306a36Sopenharmony_ci buf6, 3, DW210X_WRITE_MSG); 15662306a36Sopenharmony_ci break; 15762306a36Sopenharmony_ci case 0x60: 15862306a36Sopenharmony_ci if (msg[0].flags == 0) { 15962306a36Sopenharmony_ci if (msg[0].len < 4) { 16062306a36Sopenharmony_ci num = -EOPNOTSUPP; 16162306a36Sopenharmony_ci break; 16262306a36Sopenharmony_ci } 16362306a36Sopenharmony_ci /* write to tuner pll */ 16462306a36Sopenharmony_ci buf6[0] = 0x2c; 16562306a36Sopenharmony_ci buf6[1] = 5; 16662306a36Sopenharmony_ci buf6[2] = 0xc0; 16762306a36Sopenharmony_ci buf6[3] = msg[0].buf[0]; 16862306a36Sopenharmony_ci buf6[4] = msg[0].buf[1]; 16962306a36Sopenharmony_ci buf6[5] = msg[0].buf[2]; 17062306a36Sopenharmony_ci buf6[6] = msg[0].buf[3]; 17162306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xb2, 0, 0, 17262306a36Sopenharmony_ci buf6, 7, DW210X_WRITE_MSG); 17362306a36Sopenharmony_ci } else { 17462306a36Sopenharmony_ci if (msg[0].len < 1) { 17562306a36Sopenharmony_ci num = -EOPNOTSUPP; 17662306a36Sopenharmony_ci break; 17762306a36Sopenharmony_ci } 17862306a36Sopenharmony_ci /* read from tuner */ 17962306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xb5, 0, 0, 18062306a36Sopenharmony_ci buf6, 1, DW210X_READ_MSG); 18162306a36Sopenharmony_ci msg[0].buf[0] = buf6[0]; 18262306a36Sopenharmony_ci } 18362306a36Sopenharmony_ci break; 18462306a36Sopenharmony_ci case (DW2102_RC_QUERY): 18562306a36Sopenharmony_ci if (msg[0].len < 2) { 18662306a36Sopenharmony_ci num = -EOPNOTSUPP; 18762306a36Sopenharmony_ci break; 18862306a36Sopenharmony_ci } 18962306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xb8, 0, 0, 19062306a36Sopenharmony_ci buf6, 2, DW210X_READ_MSG); 19162306a36Sopenharmony_ci msg[0].buf[0] = buf6[0]; 19262306a36Sopenharmony_ci msg[0].buf[1] = buf6[1]; 19362306a36Sopenharmony_ci break; 19462306a36Sopenharmony_ci case (DW2102_VOLTAGE_CTRL): 19562306a36Sopenharmony_ci if (msg[0].len < 1) { 19662306a36Sopenharmony_ci num = -EOPNOTSUPP; 19762306a36Sopenharmony_ci break; 19862306a36Sopenharmony_ci } 19962306a36Sopenharmony_ci buf6[0] = 0x30; 20062306a36Sopenharmony_ci buf6[1] = msg[0].buf[0]; 20162306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xb2, 0, 0, 20262306a36Sopenharmony_ci buf6, 2, DW210X_WRITE_MSG); 20362306a36Sopenharmony_ci break; 20462306a36Sopenharmony_ci } 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci break; 20762306a36Sopenharmony_ci } 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 21062306a36Sopenharmony_ci return num; 21162306a36Sopenharmony_ci} 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_cistatic int dw2102_serit_i2c_transfer(struct i2c_adapter *adap, 21462306a36Sopenharmony_ci struct i2c_msg msg[], int num) 21562306a36Sopenharmony_ci{ 21662306a36Sopenharmony_ci struct dvb_usb_device *d = i2c_get_adapdata(adap); 21762306a36Sopenharmony_ci u8 buf6[] = {0, 0, 0, 0, 0, 0, 0}; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci if (!d) 22062306a36Sopenharmony_ci return -ENODEV; 22162306a36Sopenharmony_ci if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 22262306a36Sopenharmony_ci return -EAGAIN; 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci switch (num) { 22562306a36Sopenharmony_ci case 2: 22662306a36Sopenharmony_ci if (msg[0].len != 1) { 22762306a36Sopenharmony_ci warn("i2c rd: len=%d is not 1!\n", 22862306a36Sopenharmony_ci msg[0].len); 22962306a36Sopenharmony_ci num = -EOPNOTSUPP; 23062306a36Sopenharmony_ci break; 23162306a36Sopenharmony_ci } 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci if (2 + msg[1].len > sizeof(buf6)) { 23462306a36Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", 23562306a36Sopenharmony_ci msg[1].len); 23662306a36Sopenharmony_ci num = -EOPNOTSUPP; 23762306a36Sopenharmony_ci break; 23862306a36Sopenharmony_ci } 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci /* read si2109 register by number */ 24162306a36Sopenharmony_ci buf6[0] = msg[0].addr << 1; 24262306a36Sopenharmony_ci buf6[1] = msg[0].len; 24362306a36Sopenharmony_ci buf6[2] = msg[0].buf[0]; 24462306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, 24562306a36Sopenharmony_ci buf6, msg[0].len + 2, DW210X_WRITE_MSG); 24662306a36Sopenharmony_ci /* read si2109 register */ 24762306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xc3, 0xd0, 0, 24862306a36Sopenharmony_ci buf6, msg[1].len + 2, DW210X_READ_MSG); 24962306a36Sopenharmony_ci memcpy(msg[1].buf, buf6 + 2, msg[1].len); 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci break; 25262306a36Sopenharmony_ci case 1: 25362306a36Sopenharmony_ci switch (msg[0].addr) { 25462306a36Sopenharmony_ci case 0x68: 25562306a36Sopenharmony_ci if (2 + msg[0].len > sizeof(buf6)) { 25662306a36Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 25762306a36Sopenharmony_ci msg[0].len); 25862306a36Sopenharmony_ci num = -EOPNOTSUPP; 25962306a36Sopenharmony_ci break; 26062306a36Sopenharmony_ci } 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci /* write to si2109 register */ 26362306a36Sopenharmony_ci buf6[0] = msg[0].addr << 1; 26462306a36Sopenharmony_ci buf6[1] = msg[0].len; 26562306a36Sopenharmony_ci memcpy(buf6 + 2, msg[0].buf, msg[0].len); 26662306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6, 26762306a36Sopenharmony_ci msg[0].len + 2, DW210X_WRITE_MSG); 26862306a36Sopenharmony_ci break; 26962306a36Sopenharmony_ci case(DW2102_RC_QUERY): 27062306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xb8, 0, 0, 27162306a36Sopenharmony_ci buf6, 2, DW210X_READ_MSG); 27262306a36Sopenharmony_ci msg[0].buf[0] = buf6[0]; 27362306a36Sopenharmony_ci msg[0].buf[1] = buf6[1]; 27462306a36Sopenharmony_ci break; 27562306a36Sopenharmony_ci case(DW2102_VOLTAGE_CTRL): 27662306a36Sopenharmony_ci buf6[0] = 0x30; 27762306a36Sopenharmony_ci buf6[1] = msg[0].buf[0]; 27862306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xb2, 0, 0, 27962306a36Sopenharmony_ci buf6, 2, DW210X_WRITE_MSG); 28062306a36Sopenharmony_ci break; 28162306a36Sopenharmony_ci } 28262306a36Sopenharmony_ci break; 28362306a36Sopenharmony_ci } 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 28662306a36Sopenharmony_ci return num; 28762306a36Sopenharmony_ci} 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_cistatic int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) 29062306a36Sopenharmony_ci{ 29162306a36Sopenharmony_ci struct dvb_usb_device *d = i2c_get_adapdata(adap); 29262306a36Sopenharmony_ci int ret; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci if (!d) 29562306a36Sopenharmony_ci return -ENODEV; 29662306a36Sopenharmony_ci if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 29762306a36Sopenharmony_ci return -EAGAIN; 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci switch (num) { 30062306a36Sopenharmony_ci case 2: { 30162306a36Sopenharmony_ci /* read */ 30262306a36Sopenharmony_ci /* first write first register number */ 30362306a36Sopenharmony_ci u8 ibuf[MAX_XFER_SIZE], obuf[3]; 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci if (2 + msg[0].len != sizeof(obuf)) { 30662306a36Sopenharmony_ci warn("i2c rd: len=%d is not 1!\n", 30762306a36Sopenharmony_ci msg[0].len); 30862306a36Sopenharmony_ci ret = -EOPNOTSUPP; 30962306a36Sopenharmony_ci goto unlock; 31062306a36Sopenharmony_ci } 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci if (2 + msg[1].len > sizeof(ibuf)) { 31362306a36Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", 31462306a36Sopenharmony_ci msg[1].len); 31562306a36Sopenharmony_ci ret = -EOPNOTSUPP; 31662306a36Sopenharmony_ci goto unlock; 31762306a36Sopenharmony_ci } 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci obuf[0] = msg[0].addr << 1; 32062306a36Sopenharmony_ci obuf[1] = msg[0].len; 32162306a36Sopenharmony_ci obuf[2] = msg[0].buf[0]; 32262306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, 32362306a36Sopenharmony_ci obuf, msg[0].len + 2, DW210X_WRITE_MSG); 32462306a36Sopenharmony_ci /* second read registers */ 32562306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0, 32662306a36Sopenharmony_ci ibuf, msg[1].len + 2, DW210X_READ_MSG); 32762306a36Sopenharmony_ci memcpy(msg[1].buf, ibuf + 2, msg[1].len); 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci break; 33062306a36Sopenharmony_ci } 33162306a36Sopenharmony_ci case 1: 33262306a36Sopenharmony_ci switch (msg[0].addr) { 33362306a36Sopenharmony_ci case 0x68: { 33462306a36Sopenharmony_ci /* write to register */ 33562306a36Sopenharmony_ci u8 obuf[MAX_XFER_SIZE]; 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci if (2 + msg[0].len > sizeof(obuf)) { 33862306a36Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 33962306a36Sopenharmony_ci msg[1].len); 34062306a36Sopenharmony_ci ret = -EOPNOTSUPP; 34162306a36Sopenharmony_ci goto unlock; 34262306a36Sopenharmony_ci } 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci obuf[0] = msg[0].addr << 1; 34562306a36Sopenharmony_ci obuf[1] = msg[0].len; 34662306a36Sopenharmony_ci memcpy(obuf + 2, msg[0].buf, msg[0].len); 34762306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, 34862306a36Sopenharmony_ci obuf, msg[0].len + 2, DW210X_WRITE_MSG); 34962306a36Sopenharmony_ci break; 35062306a36Sopenharmony_ci } 35162306a36Sopenharmony_ci case 0x61: { 35262306a36Sopenharmony_ci /* write to tuner */ 35362306a36Sopenharmony_ci u8 obuf[MAX_XFER_SIZE]; 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci if (2 + msg[0].len > sizeof(obuf)) { 35662306a36Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 35762306a36Sopenharmony_ci msg[1].len); 35862306a36Sopenharmony_ci ret = -EOPNOTSUPP; 35962306a36Sopenharmony_ci goto unlock; 36062306a36Sopenharmony_ci } 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci obuf[0] = msg[0].addr << 1; 36362306a36Sopenharmony_ci obuf[1] = msg[0].len; 36462306a36Sopenharmony_ci memcpy(obuf + 2, msg[0].buf, msg[0].len); 36562306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, 36662306a36Sopenharmony_ci obuf, msg[0].len + 2, DW210X_WRITE_MSG); 36762306a36Sopenharmony_ci break; 36862306a36Sopenharmony_ci } 36962306a36Sopenharmony_ci case(DW2102_RC_QUERY): { 37062306a36Sopenharmony_ci u8 ibuf[2]; 37162306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xb8, 0, 0, 37262306a36Sopenharmony_ci ibuf, 2, DW210X_READ_MSG); 37362306a36Sopenharmony_ci memcpy(msg[0].buf, ibuf , 2); 37462306a36Sopenharmony_ci break; 37562306a36Sopenharmony_ci } 37662306a36Sopenharmony_ci case(DW2102_VOLTAGE_CTRL): { 37762306a36Sopenharmony_ci u8 obuf[2]; 37862306a36Sopenharmony_ci obuf[0] = 0x30; 37962306a36Sopenharmony_ci obuf[1] = msg[0].buf[0]; 38062306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xb2, 0, 0, 38162306a36Sopenharmony_ci obuf, 2, DW210X_WRITE_MSG); 38262306a36Sopenharmony_ci break; 38362306a36Sopenharmony_ci } 38462306a36Sopenharmony_ci } 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci break; 38762306a36Sopenharmony_ci } 38862306a36Sopenharmony_ci ret = num; 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ciunlock: 39162306a36Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 39262306a36Sopenharmony_ci return ret; 39362306a36Sopenharmony_ci} 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_cistatic int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) 39662306a36Sopenharmony_ci{ 39762306a36Sopenharmony_ci struct dvb_usb_device *d = i2c_get_adapdata(adap); 39862306a36Sopenharmony_ci int len, i, j, ret; 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci if (!d) 40162306a36Sopenharmony_ci return -ENODEV; 40262306a36Sopenharmony_ci if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 40362306a36Sopenharmony_ci return -EAGAIN; 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci for (j = 0; j < num; j++) { 40662306a36Sopenharmony_ci switch (msg[j].addr) { 40762306a36Sopenharmony_ci case(DW2102_RC_QUERY): { 40862306a36Sopenharmony_ci u8 ibuf[2]; 40962306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xb8, 0, 0, 41062306a36Sopenharmony_ci ibuf, 2, DW210X_READ_MSG); 41162306a36Sopenharmony_ci memcpy(msg[j].buf, ibuf , 2); 41262306a36Sopenharmony_ci break; 41362306a36Sopenharmony_ci } 41462306a36Sopenharmony_ci case(DW2102_VOLTAGE_CTRL): { 41562306a36Sopenharmony_ci u8 obuf[2]; 41662306a36Sopenharmony_ci obuf[0] = 0x30; 41762306a36Sopenharmony_ci obuf[1] = msg[j].buf[0]; 41862306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xb2, 0, 0, 41962306a36Sopenharmony_ci obuf, 2, DW210X_WRITE_MSG); 42062306a36Sopenharmony_ci break; 42162306a36Sopenharmony_ci } 42262306a36Sopenharmony_ci /*case 0x55: cx24116 42362306a36Sopenharmony_ci case 0x6a: stv0903 42462306a36Sopenharmony_ci case 0x68: ds3000, stv0903 42562306a36Sopenharmony_ci case 0x60: ts2020, stv6110, stb6100 */ 42662306a36Sopenharmony_ci default: { 42762306a36Sopenharmony_ci if (msg[j].flags == I2C_M_RD) { 42862306a36Sopenharmony_ci /* read registers */ 42962306a36Sopenharmony_ci u8 ibuf[MAX_XFER_SIZE]; 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci if (2 + msg[j].len > sizeof(ibuf)) { 43262306a36Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", 43362306a36Sopenharmony_ci msg[j].len); 43462306a36Sopenharmony_ci ret = -EOPNOTSUPP; 43562306a36Sopenharmony_ci goto unlock; 43662306a36Sopenharmony_ci } 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xc3, 43962306a36Sopenharmony_ci (msg[j].addr << 1) + 1, 0, 44062306a36Sopenharmony_ci ibuf, msg[j].len + 2, 44162306a36Sopenharmony_ci DW210X_READ_MSG); 44262306a36Sopenharmony_ci memcpy(msg[j].buf, ibuf + 2, msg[j].len); 44362306a36Sopenharmony_ci mdelay(10); 44462306a36Sopenharmony_ci } else if (((msg[j].buf[0] == 0xb0) && 44562306a36Sopenharmony_ci (msg[j].addr == 0x68)) || 44662306a36Sopenharmony_ci ((msg[j].buf[0] == 0xf7) && 44762306a36Sopenharmony_ci (msg[j].addr == 0x55))) { 44862306a36Sopenharmony_ci /* write firmware */ 44962306a36Sopenharmony_ci u8 obuf[19]; 45062306a36Sopenharmony_ci obuf[0] = msg[j].addr << 1; 45162306a36Sopenharmony_ci obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len); 45262306a36Sopenharmony_ci obuf[2] = msg[j].buf[0]; 45362306a36Sopenharmony_ci len = msg[j].len - 1; 45462306a36Sopenharmony_ci i = 1; 45562306a36Sopenharmony_ci do { 45662306a36Sopenharmony_ci memcpy(obuf + 3, msg[j].buf + i, 45762306a36Sopenharmony_ci (len > 16 ? 16 : len)); 45862306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, 45962306a36Sopenharmony_ci obuf, (len > 16 ? 16 : len) + 3, 46062306a36Sopenharmony_ci DW210X_WRITE_MSG); 46162306a36Sopenharmony_ci i += 16; 46262306a36Sopenharmony_ci len -= 16; 46362306a36Sopenharmony_ci } while (len > 0); 46462306a36Sopenharmony_ci } else { 46562306a36Sopenharmony_ci /* write registers */ 46662306a36Sopenharmony_ci u8 obuf[MAX_XFER_SIZE]; 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci if (2 + msg[j].len > sizeof(obuf)) { 46962306a36Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 47062306a36Sopenharmony_ci msg[j].len); 47162306a36Sopenharmony_ci ret = -EOPNOTSUPP; 47262306a36Sopenharmony_ci goto unlock; 47362306a36Sopenharmony_ci } 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci obuf[0] = msg[j].addr << 1; 47662306a36Sopenharmony_ci obuf[1] = msg[j].len; 47762306a36Sopenharmony_ci memcpy(obuf + 2, msg[j].buf, msg[j].len); 47862306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, 47962306a36Sopenharmony_ci obuf, msg[j].len + 2, 48062306a36Sopenharmony_ci DW210X_WRITE_MSG); 48162306a36Sopenharmony_ci } 48262306a36Sopenharmony_ci break; 48362306a36Sopenharmony_ci } 48462306a36Sopenharmony_ci } 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci } 48762306a36Sopenharmony_ci ret = num; 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ciunlock: 49062306a36Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 49162306a36Sopenharmony_ci return ret; 49262306a36Sopenharmony_ci} 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_cistatic int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], 49562306a36Sopenharmony_ci int num) 49662306a36Sopenharmony_ci{ 49762306a36Sopenharmony_ci struct dvb_usb_device *d = i2c_get_adapdata(adap); 49862306a36Sopenharmony_ci int ret; 49962306a36Sopenharmony_ci int i; 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci if (!d) 50262306a36Sopenharmony_ci return -ENODEV; 50362306a36Sopenharmony_ci if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 50462306a36Sopenharmony_ci return -EAGAIN; 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci switch (num) { 50762306a36Sopenharmony_ci case 2: { 50862306a36Sopenharmony_ci /* read */ 50962306a36Sopenharmony_ci /* first write first register number */ 51062306a36Sopenharmony_ci u8 ibuf[MAX_XFER_SIZE], obuf[3]; 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci if (2 + msg[0].len != sizeof(obuf)) { 51362306a36Sopenharmony_ci warn("i2c rd: len=%d is not 1!\n", 51462306a36Sopenharmony_ci msg[0].len); 51562306a36Sopenharmony_ci ret = -EOPNOTSUPP; 51662306a36Sopenharmony_ci goto unlock; 51762306a36Sopenharmony_ci } 51862306a36Sopenharmony_ci if (2 + msg[1].len > sizeof(ibuf)) { 51962306a36Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", 52062306a36Sopenharmony_ci msg[1].len); 52162306a36Sopenharmony_ci ret = -EOPNOTSUPP; 52262306a36Sopenharmony_ci goto unlock; 52362306a36Sopenharmony_ci } 52462306a36Sopenharmony_ci obuf[0] = msg[0].addr << 1; 52562306a36Sopenharmony_ci obuf[1] = msg[0].len; 52662306a36Sopenharmony_ci obuf[2] = msg[0].buf[0]; 52762306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, 52862306a36Sopenharmony_ci obuf, msg[0].len + 2, DW210X_WRITE_MSG); 52962306a36Sopenharmony_ci /* second read registers */ 53062306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xc3, 0x19 , 0, 53162306a36Sopenharmony_ci ibuf, msg[1].len + 2, DW210X_READ_MSG); 53262306a36Sopenharmony_ci memcpy(msg[1].buf, ibuf + 2, msg[1].len); 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci break; 53562306a36Sopenharmony_ci } 53662306a36Sopenharmony_ci case 1: 53762306a36Sopenharmony_ci switch (msg[0].addr) { 53862306a36Sopenharmony_ci case 0x60: 53962306a36Sopenharmony_ci case 0x0c: { 54062306a36Sopenharmony_ci /* write to register */ 54162306a36Sopenharmony_ci u8 obuf[MAX_XFER_SIZE]; 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_ci if (2 + msg[0].len > sizeof(obuf)) { 54462306a36Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 54562306a36Sopenharmony_ci msg[0].len); 54662306a36Sopenharmony_ci ret = -EOPNOTSUPP; 54762306a36Sopenharmony_ci goto unlock; 54862306a36Sopenharmony_ci } 54962306a36Sopenharmony_ci obuf[0] = msg[0].addr << 1; 55062306a36Sopenharmony_ci obuf[1] = msg[0].len; 55162306a36Sopenharmony_ci memcpy(obuf + 2, msg[0].buf, msg[0].len); 55262306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, 55362306a36Sopenharmony_ci obuf, msg[0].len + 2, DW210X_WRITE_MSG); 55462306a36Sopenharmony_ci break; 55562306a36Sopenharmony_ci } 55662306a36Sopenharmony_ci case(DW2102_RC_QUERY): { 55762306a36Sopenharmony_ci u8 ibuf[2]; 55862306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xb8, 0, 0, 55962306a36Sopenharmony_ci ibuf, 2, DW210X_READ_MSG); 56062306a36Sopenharmony_ci memcpy(msg[0].buf, ibuf , 2); 56162306a36Sopenharmony_ci break; 56262306a36Sopenharmony_ci } 56362306a36Sopenharmony_ci } 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci break; 56662306a36Sopenharmony_ci } 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_ci for (i = 0; i < num; i++) { 56962306a36Sopenharmony_ci deb_xfer("%02x:%02x: %s ", i, msg[i].addr, 57062306a36Sopenharmony_ci msg[i].flags == 0 ? ">>>" : "<<<"); 57162306a36Sopenharmony_ci debug_dump(msg[i].buf, msg[i].len, deb_xfer); 57262306a36Sopenharmony_ci } 57362306a36Sopenharmony_ci ret = num; 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_ciunlock: 57662306a36Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 57762306a36Sopenharmony_ci return ret; 57862306a36Sopenharmony_ci} 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_cistatic int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], 58162306a36Sopenharmony_ci int num) 58262306a36Sopenharmony_ci{ 58362306a36Sopenharmony_ci struct dvb_usb_device *d = i2c_get_adapdata(adap); 58462306a36Sopenharmony_ci struct usb_device *udev; 58562306a36Sopenharmony_ci int len, i, j, ret; 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ci if (!d) 58862306a36Sopenharmony_ci return -ENODEV; 58962306a36Sopenharmony_ci udev = d->udev; 59062306a36Sopenharmony_ci if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 59162306a36Sopenharmony_ci return -EAGAIN; 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci for (j = 0; j < num; j++) { 59462306a36Sopenharmony_ci switch (msg[j].addr) { 59562306a36Sopenharmony_ci case (DW2102_RC_QUERY): { 59662306a36Sopenharmony_ci u8 ibuf[5]; 59762306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0xb8, 0, 0, 59862306a36Sopenharmony_ci ibuf, 5, DW210X_READ_MSG); 59962306a36Sopenharmony_ci memcpy(msg[j].buf, ibuf + 3, 2); 60062306a36Sopenharmony_ci break; 60162306a36Sopenharmony_ci } 60262306a36Sopenharmony_ci case (DW2102_VOLTAGE_CTRL): { 60362306a36Sopenharmony_ci u8 obuf[2]; 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ci obuf[0] = 1; 60662306a36Sopenharmony_ci obuf[1] = msg[j].buf[1];/* off-on */ 60762306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0x8a, 0, 0, 60862306a36Sopenharmony_ci obuf, 2, DW210X_WRITE_MSG); 60962306a36Sopenharmony_ci obuf[0] = 3; 61062306a36Sopenharmony_ci obuf[1] = msg[j].buf[0];/* 13v-18v */ 61162306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0x8a, 0, 0, 61262306a36Sopenharmony_ci obuf, 2, DW210X_WRITE_MSG); 61362306a36Sopenharmony_ci break; 61462306a36Sopenharmony_ci } 61562306a36Sopenharmony_ci case (DW2102_LED_CTRL): { 61662306a36Sopenharmony_ci u8 obuf[2]; 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci obuf[0] = 5; 61962306a36Sopenharmony_ci obuf[1] = msg[j].buf[0]; 62062306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0x8a, 0, 0, 62162306a36Sopenharmony_ci obuf, 2, DW210X_WRITE_MSG); 62262306a36Sopenharmony_ci break; 62362306a36Sopenharmony_ci } 62462306a36Sopenharmony_ci /*case 0x55: cx24116 62562306a36Sopenharmony_ci case 0x6a: stv0903 62662306a36Sopenharmony_ci case 0x68: ds3000, stv0903, rs2000 62762306a36Sopenharmony_ci case 0x60: ts2020, stv6110, stb6100 62862306a36Sopenharmony_ci case 0xa0: eeprom */ 62962306a36Sopenharmony_ci default: { 63062306a36Sopenharmony_ci if (msg[j].flags == I2C_M_RD) { 63162306a36Sopenharmony_ci /* read registers */ 63262306a36Sopenharmony_ci u8 ibuf[MAX_XFER_SIZE]; 63362306a36Sopenharmony_ci 63462306a36Sopenharmony_ci if (msg[j].len > sizeof(ibuf)) { 63562306a36Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", 63662306a36Sopenharmony_ci msg[j].len); 63762306a36Sopenharmony_ci ret = -EOPNOTSUPP; 63862306a36Sopenharmony_ci goto unlock; 63962306a36Sopenharmony_ci } 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0x91, 0, 0, 64262306a36Sopenharmony_ci ibuf, msg[j].len, 64362306a36Sopenharmony_ci DW210X_READ_MSG); 64462306a36Sopenharmony_ci memcpy(msg[j].buf, ibuf, msg[j].len); 64562306a36Sopenharmony_ci break; 64662306a36Sopenharmony_ci } else if ((msg[j].buf[0] == 0xb0) && 64762306a36Sopenharmony_ci (msg[j].addr == 0x68)) { 64862306a36Sopenharmony_ci /* write firmware */ 64962306a36Sopenharmony_ci u8 obuf[19]; 65062306a36Sopenharmony_ci obuf[0] = (msg[j].len > 16 ? 65162306a36Sopenharmony_ci 18 : msg[j].len + 1); 65262306a36Sopenharmony_ci obuf[1] = msg[j].addr << 1; 65362306a36Sopenharmony_ci obuf[2] = msg[j].buf[0]; 65462306a36Sopenharmony_ci len = msg[j].len - 1; 65562306a36Sopenharmony_ci i = 1; 65662306a36Sopenharmony_ci do { 65762306a36Sopenharmony_ci memcpy(obuf + 3, msg[j].buf + i, 65862306a36Sopenharmony_ci (len > 16 ? 16 : len)); 65962306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0x80, 0, 0, 66062306a36Sopenharmony_ci obuf, (len > 16 ? 16 : len) + 3, 66162306a36Sopenharmony_ci DW210X_WRITE_MSG); 66262306a36Sopenharmony_ci i += 16; 66362306a36Sopenharmony_ci len -= 16; 66462306a36Sopenharmony_ci } while (len > 0); 66562306a36Sopenharmony_ci } else if (j < (num - 1)) { 66662306a36Sopenharmony_ci /* write register addr before read */ 66762306a36Sopenharmony_ci u8 obuf[MAX_XFER_SIZE]; 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_ci if (2 + msg[j].len > sizeof(obuf)) { 67062306a36Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 67162306a36Sopenharmony_ci msg[j].len); 67262306a36Sopenharmony_ci ret = -EOPNOTSUPP; 67362306a36Sopenharmony_ci goto unlock; 67462306a36Sopenharmony_ci } 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci obuf[0] = msg[j + 1].len; 67762306a36Sopenharmony_ci obuf[1] = (msg[j].addr << 1); 67862306a36Sopenharmony_ci memcpy(obuf + 2, msg[j].buf, msg[j].len); 67962306a36Sopenharmony_ci dw210x_op_rw(d->udev, 68062306a36Sopenharmony_ci le16_to_cpu(udev->descriptor.idProduct) == 68162306a36Sopenharmony_ci 0x7500 ? 0x92 : 0x90, 0, 0, 68262306a36Sopenharmony_ci obuf, msg[j].len + 2, 68362306a36Sopenharmony_ci DW210X_WRITE_MSG); 68462306a36Sopenharmony_ci break; 68562306a36Sopenharmony_ci } else { 68662306a36Sopenharmony_ci /* write registers */ 68762306a36Sopenharmony_ci u8 obuf[MAX_XFER_SIZE]; 68862306a36Sopenharmony_ci 68962306a36Sopenharmony_ci if (2 + msg[j].len > sizeof(obuf)) { 69062306a36Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 69162306a36Sopenharmony_ci msg[j].len); 69262306a36Sopenharmony_ci ret = -EOPNOTSUPP; 69362306a36Sopenharmony_ci goto unlock; 69462306a36Sopenharmony_ci } 69562306a36Sopenharmony_ci obuf[0] = msg[j].len + 1; 69662306a36Sopenharmony_ci obuf[1] = (msg[j].addr << 1); 69762306a36Sopenharmony_ci memcpy(obuf + 2, msg[j].buf, msg[j].len); 69862306a36Sopenharmony_ci dw210x_op_rw(d->udev, 0x80, 0, 0, 69962306a36Sopenharmony_ci obuf, msg[j].len + 2, 70062306a36Sopenharmony_ci DW210X_WRITE_MSG); 70162306a36Sopenharmony_ci break; 70262306a36Sopenharmony_ci } 70362306a36Sopenharmony_ci break; 70462306a36Sopenharmony_ci } 70562306a36Sopenharmony_ci } 70662306a36Sopenharmony_ci } 70762306a36Sopenharmony_ci ret = num; 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_ciunlock: 71062306a36Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 71162306a36Sopenharmony_ci return ret; 71262306a36Sopenharmony_ci} 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_cistatic int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], 71562306a36Sopenharmony_ci int num) 71662306a36Sopenharmony_ci{ 71762306a36Sopenharmony_ci struct dvb_usb_device *d = i2c_get_adapdata(adap); 71862306a36Sopenharmony_ci struct dw2102_state *state; 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_ci if (!d) 72162306a36Sopenharmony_ci return -ENODEV; 72262306a36Sopenharmony_ci 72362306a36Sopenharmony_ci state = d->priv; 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 72662306a36Sopenharmony_ci return -EAGAIN; 72762306a36Sopenharmony_ci if (mutex_lock_interruptible(&d->data_mutex) < 0) { 72862306a36Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 72962306a36Sopenharmony_ci return -EAGAIN; 73062306a36Sopenharmony_ci } 73162306a36Sopenharmony_ci 73262306a36Sopenharmony_ci switch (num) { 73362306a36Sopenharmony_ci case 1: 73462306a36Sopenharmony_ci switch (msg[0].addr) { 73562306a36Sopenharmony_ci case SU3000_STREAM_CTRL: 73662306a36Sopenharmony_ci state->data[0] = msg[0].buf[0] + 0x36; 73762306a36Sopenharmony_ci state->data[1] = 3; 73862306a36Sopenharmony_ci state->data[2] = 0; 73962306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, 74062306a36Sopenharmony_ci state->data, 0, 0) < 0) 74162306a36Sopenharmony_ci err("i2c transfer failed."); 74262306a36Sopenharmony_ci break; 74362306a36Sopenharmony_ci case DW2102_RC_QUERY: 74462306a36Sopenharmony_ci state->data[0] = 0x10; 74562306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 1, 74662306a36Sopenharmony_ci state->data, 2, 0) < 0) 74762306a36Sopenharmony_ci err("i2c transfer failed."); 74862306a36Sopenharmony_ci msg[0].buf[1] = state->data[0]; 74962306a36Sopenharmony_ci msg[0].buf[0] = state->data[1]; 75062306a36Sopenharmony_ci break; 75162306a36Sopenharmony_ci default: 75262306a36Sopenharmony_ci if (3 + msg[0].len > sizeof(state->data)) { 75362306a36Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 75462306a36Sopenharmony_ci msg[0].len); 75562306a36Sopenharmony_ci num = -EOPNOTSUPP; 75662306a36Sopenharmony_ci break; 75762306a36Sopenharmony_ci } 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_ci /* always i2c write*/ 76062306a36Sopenharmony_ci state->data[0] = 0x08; 76162306a36Sopenharmony_ci state->data[1] = msg[0].addr; 76262306a36Sopenharmony_ci state->data[2] = msg[0].len; 76362306a36Sopenharmony_ci 76462306a36Sopenharmony_ci memcpy(&state->data[3], msg[0].buf, msg[0].len); 76562306a36Sopenharmony_ci 76662306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, msg[0].len + 3, 76762306a36Sopenharmony_ci state->data, 1, 0) < 0) 76862306a36Sopenharmony_ci err("i2c transfer failed."); 76962306a36Sopenharmony_ci 77062306a36Sopenharmony_ci } 77162306a36Sopenharmony_ci break; 77262306a36Sopenharmony_ci case 2: 77362306a36Sopenharmony_ci /* always i2c read */ 77462306a36Sopenharmony_ci if (4 + msg[0].len > sizeof(state->data)) { 77562306a36Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", 77662306a36Sopenharmony_ci msg[0].len); 77762306a36Sopenharmony_ci num = -EOPNOTSUPP; 77862306a36Sopenharmony_ci break; 77962306a36Sopenharmony_ci } 78062306a36Sopenharmony_ci if (1 + msg[1].len > sizeof(state->data)) { 78162306a36Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", 78262306a36Sopenharmony_ci msg[1].len); 78362306a36Sopenharmony_ci num = -EOPNOTSUPP; 78462306a36Sopenharmony_ci break; 78562306a36Sopenharmony_ci } 78662306a36Sopenharmony_ci 78762306a36Sopenharmony_ci state->data[0] = 0x09; 78862306a36Sopenharmony_ci state->data[1] = msg[0].len; 78962306a36Sopenharmony_ci state->data[2] = msg[1].len; 79062306a36Sopenharmony_ci state->data[3] = msg[0].addr; 79162306a36Sopenharmony_ci memcpy(&state->data[4], msg[0].buf, msg[0].len); 79262306a36Sopenharmony_ci 79362306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, msg[0].len + 4, 79462306a36Sopenharmony_ci state->data, msg[1].len + 1, 0) < 0) 79562306a36Sopenharmony_ci err("i2c transfer failed."); 79662306a36Sopenharmony_ci 79762306a36Sopenharmony_ci memcpy(msg[1].buf, &state->data[1], msg[1].len); 79862306a36Sopenharmony_ci break; 79962306a36Sopenharmony_ci default: 80062306a36Sopenharmony_ci warn("more than 2 i2c messages at a time is not handled yet."); 80162306a36Sopenharmony_ci break; 80262306a36Sopenharmony_ci } 80362306a36Sopenharmony_ci mutex_unlock(&d->data_mutex); 80462306a36Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 80562306a36Sopenharmony_ci return num; 80662306a36Sopenharmony_ci} 80762306a36Sopenharmony_ci 80862306a36Sopenharmony_cistatic u32 dw210x_i2c_func(struct i2c_adapter *adapter) 80962306a36Sopenharmony_ci{ 81062306a36Sopenharmony_ci return I2C_FUNC_I2C; 81162306a36Sopenharmony_ci} 81262306a36Sopenharmony_ci 81362306a36Sopenharmony_cistatic struct i2c_algorithm dw2102_i2c_algo = { 81462306a36Sopenharmony_ci .master_xfer = dw2102_i2c_transfer, 81562306a36Sopenharmony_ci .functionality = dw210x_i2c_func, 81662306a36Sopenharmony_ci}; 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_cistatic struct i2c_algorithm dw2102_serit_i2c_algo = { 81962306a36Sopenharmony_ci .master_xfer = dw2102_serit_i2c_transfer, 82062306a36Sopenharmony_ci .functionality = dw210x_i2c_func, 82162306a36Sopenharmony_ci}; 82262306a36Sopenharmony_ci 82362306a36Sopenharmony_cistatic struct i2c_algorithm dw2102_earda_i2c_algo = { 82462306a36Sopenharmony_ci .master_xfer = dw2102_earda_i2c_transfer, 82562306a36Sopenharmony_ci .functionality = dw210x_i2c_func, 82662306a36Sopenharmony_ci}; 82762306a36Sopenharmony_ci 82862306a36Sopenharmony_cistatic struct i2c_algorithm dw2104_i2c_algo = { 82962306a36Sopenharmony_ci .master_xfer = dw2104_i2c_transfer, 83062306a36Sopenharmony_ci .functionality = dw210x_i2c_func, 83162306a36Sopenharmony_ci}; 83262306a36Sopenharmony_ci 83362306a36Sopenharmony_cistatic struct i2c_algorithm dw3101_i2c_algo = { 83462306a36Sopenharmony_ci .master_xfer = dw3101_i2c_transfer, 83562306a36Sopenharmony_ci .functionality = dw210x_i2c_func, 83662306a36Sopenharmony_ci}; 83762306a36Sopenharmony_ci 83862306a36Sopenharmony_cistatic struct i2c_algorithm s6x0_i2c_algo = { 83962306a36Sopenharmony_ci .master_xfer = s6x0_i2c_transfer, 84062306a36Sopenharmony_ci .functionality = dw210x_i2c_func, 84162306a36Sopenharmony_ci}; 84262306a36Sopenharmony_ci 84362306a36Sopenharmony_cistatic struct i2c_algorithm su3000_i2c_algo = { 84462306a36Sopenharmony_ci .master_xfer = su3000_i2c_transfer, 84562306a36Sopenharmony_ci .functionality = dw210x_i2c_func, 84662306a36Sopenharmony_ci}; 84762306a36Sopenharmony_ci 84862306a36Sopenharmony_cistatic int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) 84962306a36Sopenharmony_ci{ 85062306a36Sopenharmony_ci int i; 85162306a36Sopenharmony_ci u8 ibuf[] = {0, 0}; 85262306a36Sopenharmony_ci u8 eeprom[256], eepromline[16]; 85362306a36Sopenharmony_ci 85462306a36Sopenharmony_ci for (i = 0; i < 256; i++) { 85562306a36Sopenharmony_ci if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) { 85662306a36Sopenharmony_ci err("read eeprom failed."); 85762306a36Sopenharmony_ci return -EIO; 85862306a36Sopenharmony_ci } else { 85962306a36Sopenharmony_ci eepromline[i%16] = ibuf[0]; 86062306a36Sopenharmony_ci eeprom[i] = ibuf[0]; 86162306a36Sopenharmony_ci } 86262306a36Sopenharmony_ci if ((i % 16) == 15) { 86362306a36Sopenharmony_ci deb_xfer("%02x: ", i - 15); 86462306a36Sopenharmony_ci debug_dump(eepromline, 16, deb_xfer); 86562306a36Sopenharmony_ci } 86662306a36Sopenharmony_ci } 86762306a36Sopenharmony_ci 86862306a36Sopenharmony_ci memcpy(mac, eeprom + 8, 6); 86962306a36Sopenharmony_ci return 0; 87062306a36Sopenharmony_ci}; 87162306a36Sopenharmony_ci 87262306a36Sopenharmony_cistatic int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) 87362306a36Sopenharmony_ci{ 87462306a36Sopenharmony_ci int i, ret; 87562306a36Sopenharmony_ci u8 ibuf[] = { 0 }, obuf[] = { 0 }; 87662306a36Sopenharmony_ci u8 eeprom[256], eepromline[16]; 87762306a36Sopenharmony_ci struct i2c_msg msg[] = { 87862306a36Sopenharmony_ci { 87962306a36Sopenharmony_ci .addr = 0xa0 >> 1, 88062306a36Sopenharmony_ci .flags = 0, 88162306a36Sopenharmony_ci .buf = obuf, 88262306a36Sopenharmony_ci .len = 1, 88362306a36Sopenharmony_ci }, { 88462306a36Sopenharmony_ci .addr = 0xa0 >> 1, 88562306a36Sopenharmony_ci .flags = I2C_M_RD, 88662306a36Sopenharmony_ci .buf = ibuf, 88762306a36Sopenharmony_ci .len = 1, 88862306a36Sopenharmony_ci } 88962306a36Sopenharmony_ci }; 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_ci for (i = 0; i < 256; i++) { 89262306a36Sopenharmony_ci obuf[0] = i; 89362306a36Sopenharmony_ci ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2); 89462306a36Sopenharmony_ci if (ret != 2) { 89562306a36Sopenharmony_ci err("read eeprom failed."); 89662306a36Sopenharmony_ci return -EIO; 89762306a36Sopenharmony_ci } else { 89862306a36Sopenharmony_ci eepromline[i % 16] = ibuf[0]; 89962306a36Sopenharmony_ci eeprom[i] = ibuf[0]; 90062306a36Sopenharmony_ci } 90162306a36Sopenharmony_ci 90262306a36Sopenharmony_ci if ((i % 16) == 15) { 90362306a36Sopenharmony_ci deb_xfer("%02x: ", i - 15); 90462306a36Sopenharmony_ci debug_dump(eepromline, 16, deb_xfer); 90562306a36Sopenharmony_ci } 90662306a36Sopenharmony_ci } 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_ci memcpy(mac, eeprom + 16, 6); 90962306a36Sopenharmony_ci return 0; 91062306a36Sopenharmony_ci}; 91162306a36Sopenharmony_ci 91262306a36Sopenharmony_cistatic int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 91362306a36Sopenharmony_ci{ 91462306a36Sopenharmony_ci static u8 command_start[] = {0x00}; 91562306a36Sopenharmony_ci static u8 command_stop[] = {0x01}; 91662306a36Sopenharmony_ci struct i2c_msg msg = { 91762306a36Sopenharmony_ci .addr = SU3000_STREAM_CTRL, 91862306a36Sopenharmony_ci .flags = 0, 91962306a36Sopenharmony_ci .buf = onoff ? command_start : command_stop, 92062306a36Sopenharmony_ci .len = 1 92162306a36Sopenharmony_ci }; 92262306a36Sopenharmony_ci 92362306a36Sopenharmony_ci i2c_transfer(&adap->dev->i2c_adap, &msg, 1); 92462306a36Sopenharmony_ci 92562306a36Sopenharmony_ci return 0; 92662306a36Sopenharmony_ci} 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_cistatic int su3000_power_ctrl(struct dvb_usb_device *d, int i) 92962306a36Sopenharmony_ci{ 93062306a36Sopenharmony_ci struct dw2102_state *state = d->priv; 93162306a36Sopenharmony_ci int ret = 0; 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ci info("%s: %d, initialized %d", __func__, i, state->initialized); 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_ci if (i && !state->initialized) { 93662306a36Sopenharmony_ci mutex_lock(&d->data_mutex); 93762306a36Sopenharmony_ci 93862306a36Sopenharmony_ci state->data[0] = 0xde; 93962306a36Sopenharmony_ci state->data[1] = 0; 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_ci state->initialized = 1; 94262306a36Sopenharmony_ci /* reset board */ 94362306a36Sopenharmony_ci ret = dvb_usb_generic_rw(d, state->data, 2, NULL, 0, 0); 94462306a36Sopenharmony_ci mutex_unlock(&d->data_mutex); 94562306a36Sopenharmony_ci } 94662306a36Sopenharmony_ci 94762306a36Sopenharmony_ci return ret; 94862306a36Sopenharmony_ci} 94962306a36Sopenharmony_ci 95062306a36Sopenharmony_cistatic int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) 95162306a36Sopenharmony_ci{ 95262306a36Sopenharmony_ci int i; 95362306a36Sopenharmony_ci u8 obuf[] = { 0x1f, 0xf0 }; 95462306a36Sopenharmony_ci u8 ibuf[] = { 0 }; 95562306a36Sopenharmony_ci struct i2c_msg msg[] = { 95662306a36Sopenharmony_ci { 95762306a36Sopenharmony_ci .addr = 0x51, 95862306a36Sopenharmony_ci .flags = 0, 95962306a36Sopenharmony_ci .buf = obuf, 96062306a36Sopenharmony_ci .len = 2, 96162306a36Sopenharmony_ci }, { 96262306a36Sopenharmony_ci .addr = 0x51, 96362306a36Sopenharmony_ci .flags = I2C_M_RD, 96462306a36Sopenharmony_ci .buf = ibuf, 96562306a36Sopenharmony_ci .len = 1, 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_ci } 96862306a36Sopenharmony_ci }; 96962306a36Sopenharmony_ci 97062306a36Sopenharmony_ci for (i = 0; i < 6; i++) { 97162306a36Sopenharmony_ci obuf[1] = 0xf0 + i; 97262306a36Sopenharmony_ci if (i2c_transfer(&d->i2c_adap, msg, 2) != 2) 97362306a36Sopenharmony_ci return -EIO; 97462306a36Sopenharmony_ci else 97562306a36Sopenharmony_ci mac[i] = ibuf[0]; 97662306a36Sopenharmony_ci } 97762306a36Sopenharmony_ci 97862306a36Sopenharmony_ci return 0; 97962306a36Sopenharmony_ci} 98062306a36Sopenharmony_ci 98162306a36Sopenharmony_cistatic int su3000_identify_state(struct usb_device *udev, 98262306a36Sopenharmony_ci const struct dvb_usb_device_properties *props, 98362306a36Sopenharmony_ci const struct dvb_usb_device_description **desc, 98462306a36Sopenharmony_ci int *cold) 98562306a36Sopenharmony_ci{ 98662306a36Sopenharmony_ci info("%s", __func__); 98762306a36Sopenharmony_ci 98862306a36Sopenharmony_ci *cold = 0; 98962306a36Sopenharmony_ci return 0; 99062306a36Sopenharmony_ci} 99162306a36Sopenharmony_ci 99262306a36Sopenharmony_cistatic int dw210x_set_voltage(struct dvb_frontend *fe, 99362306a36Sopenharmony_ci enum fe_sec_voltage voltage) 99462306a36Sopenharmony_ci{ 99562306a36Sopenharmony_ci static u8 command_13v[] = {0x00, 0x01}; 99662306a36Sopenharmony_ci static u8 command_18v[] = {0x01, 0x01}; 99762306a36Sopenharmony_ci static u8 command_off[] = {0x00, 0x00}; 99862306a36Sopenharmony_ci struct i2c_msg msg = { 99962306a36Sopenharmony_ci .addr = DW2102_VOLTAGE_CTRL, 100062306a36Sopenharmony_ci .flags = 0, 100162306a36Sopenharmony_ci .buf = command_off, 100262306a36Sopenharmony_ci .len = 2, 100362306a36Sopenharmony_ci }; 100462306a36Sopenharmony_ci 100562306a36Sopenharmony_ci struct dvb_usb_adapter *udev_adap = fe->dvb->priv; 100662306a36Sopenharmony_ci if (voltage == SEC_VOLTAGE_18) 100762306a36Sopenharmony_ci msg.buf = command_18v; 100862306a36Sopenharmony_ci else if (voltage == SEC_VOLTAGE_13) 100962306a36Sopenharmony_ci msg.buf = command_13v; 101062306a36Sopenharmony_ci 101162306a36Sopenharmony_ci i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); 101262306a36Sopenharmony_ci 101362306a36Sopenharmony_ci return 0; 101462306a36Sopenharmony_ci} 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_cistatic int s660_set_voltage(struct dvb_frontend *fe, 101762306a36Sopenharmony_ci enum fe_sec_voltage voltage) 101862306a36Sopenharmony_ci{ 101962306a36Sopenharmony_ci struct dvb_usb_adapter *d = fe->dvb->priv; 102062306a36Sopenharmony_ci struct dw2102_state *st = d->dev->priv; 102162306a36Sopenharmony_ci 102262306a36Sopenharmony_ci dw210x_set_voltage(fe, voltage); 102362306a36Sopenharmony_ci if (st->old_set_voltage) 102462306a36Sopenharmony_ci st->old_set_voltage(fe, voltage); 102562306a36Sopenharmony_ci 102662306a36Sopenharmony_ci return 0; 102762306a36Sopenharmony_ci} 102862306a36Sopenharmony_ci 102962306a36Sopenharmony_cistatic void dw210x_led_ctrl(struct dvb_frontend *fe, int offon) 103062306a36Sopenharmony_ci{ 103162306a36Sopenharmony_ci static u8 led_off[] = { 0 }; 103262306a36Sopenharmony_ci static u8 led_on[] = { 1 }; 103362306a36Sopenharmony_ci struct i2c_msg msg = { 103462306a36Sopenharmony_ci .addr = DW2102_LED_CTRL, 103562306a36Sopenharmony_ci .flags = 0, 103662306a36Sopenharmony_ci .buf = led_off, 103762306a36Sopenharmony_ci .len = 1 103862306a36Sopenharmony_ci }; 103962306a36Sopenharmony_ci struct dvb_usb_adapter *udev_adap = fe->dvb->priv; 104062306a36Sopenharmony_ci 104162306a36Sopenharmony_ci if (offon) 104262306a36Sopenharmony_ci msg.buf = led_on; 104362306a36Sopenharmony_ci i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); 104462306a36Sopenharmony_ci} 104562306a36Sopenharmony_ci 104662306a36Sopenharmony_cistatic int tt_s2_4600_read_status(struct dvb_frontend *fe, 104762306a36Sopenharmony_ci enum fe_status *status) 104862306a36Sopenharmony_ci{ 104962306a36Sopenharmony_ci struct dvb_usb_adapter *d = fe->dvb->priv; 105062306a36Sopenharmony_ci struct dw2102_state *st = d->dev->priv; 105162306a36Sopenharmony_ci int ret; 105262306a36Sopenharmony_ci 105362306a36Sopenharmony_ci ret = st->fe_read_status(fe, status); 105462306a36Sopenharmony_ci 105562306a36Sopenharmony_ci /* resync slave fifo when signal change from unlock to lock */ 105662306a36Sopenharmony_ci if ((*status & FE_HAS_LOCK) && (!st->last_lock)) 105762306a36Sopenharmony_ci su3000_streaming_ctrl(d, 1); 105862306a36Sopenharmony_ci 105962306a36Sopenharmony_ci st->last_lock = (*status & FE_HAS_LOCK) ? 1 : 0; 106062306a36Sopenharmony_ci return ret; 106162306a36Sopenharmony_ci} 106262306a36Sopenharmony_ci 106362306a36Sopenharmony_cistatic struct stv0299_config sharp_z0194a_config = { 106462306a36Sopenharmony_ci .demod_address = 0x68, 106562306a36Sopenharmony_ci .inittab = sharp_z0194a_inittab, 106662306a36Sopenharmony_ci .mclk = 88000000UL, 106762306a36Sopenharmony_ci .invert = 1, 106862306a36Sopenharmony_ci .skip_reinit = 0, 106962306a36Sopenharmony_ci .lock_output = STV0299_LOCKOUTPUT_1, 107062306a36Sopenharmony_ci .volt13_op0_op1 = STV0299_VOLT13_OP1, 107162306a36Sopenharmony_ci .min_delay_ms = 100, 107262306a36Sopenharmony_ci .set_symbol_rate = sharp_z0194a_set_symbol_rate, 107362306a36Sopenharmony_ci}; 107462306a36Sopenharmony_ci 107562306a36Sopenharmony_cistatic struct cx24116_config dw2104_config = { 107662306a36Sopenharmony_ci .demod_address = 0x55, 107762306a36Sopenharmony_ci .mpg_clk_pos_pol = 0x01, 107862306a36Sopenharmony_ci}; 107962306a36Sopenharmony_ci 108062306a36Sopenharmony_cistatic struct si21xx_config serit_sp1511lhb_config = { 108162306a36Sopenharmony_ci .demod_address = 0x68, 108262306a36Sopenharmony_ci .min_delay_ms = 100, 108362306a36Sopenharmony_ci 108462306a36Sopenharmony_ci}; 108562306a36Sopenharmony_ci 108662306a36Sopenharmony_cistatic struct tda10023_config dw3101_tda10023_config = { 108762306a36Sopenharmony_ci .demod_address = 0x0c, 108862306a36Sopenharmony_ci .invert = 1, 108962306a36Sopenharmony_ci}; 109062306a36Sopenharmony_ci 109162306a36Sopenharmony_cistatic struct mt312_config zl313_config = { 109262306a36Sopenharmony_ci .demod_address = 0x0e, 109362306a36Sopenharmony_ci}; 109462306a36Sopenharmony_ci 109562306a36Sopenharmony_cistatic struct ds3000_config dw2104_ds3000_config = { 109662306a36Sopenharmony_ci .demod_address = 0x68, 109762306a36Sopenharmony_ci}; 109862306a36Sopenharmony_ci 109962306a36Sopenharmony_cistatic struct ts2020_config dw2104_ts2020_config = { 110062306a36Sopenharmony_ci .tuner_address = 0x60, 110162306a36Sopenharmony_ci .clk_out_div = 1, 110262306a36Sopenharmony_ci .frequency_div = 1060000, 110362306a36Sopenharmony_ci}; 110462306a36Sopenharmony_ci 110562306a36Sopenharmony_cistatic struct ds3000_config s660_ds3000_config = { 110662306a36Sopenharmony_ci .demod_address = 0x68, 110762306a36Sopenharmony_ci .ci_mode = 1, 110862306a36Sopenharmony_ci .set_lock_led = dw210x_led_ctrl, 110962306a36Sopenharmony_ci}; 111062306a36Sopenharmony_ci 111162306a36Sopenharmony_cistatic struct ts2020_config s660_ts2020_config = { 111262306a36Sopenharmony_ci .tuner_address = 0x60, 111362306a36Sopenharmony_ci .clk_out_div = 1, 111462306a36Sopenharmony_ci .frequency_div = 1146000, 111562306a36Sopenharmony_ci}; 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_cistatic struct stv0900_config dw2104a_stv0900_config = { 111862306a36Sopenharmony_ci .demod_address = 0x6a, 111962306a36Sopenharmony_ci .demod_mode = 0, 112062306a36Sopenharmony_ci .xtal = 27000000, 112162306a36Sopenharmony_ci .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ 112262306a36Sopenharmony_ci .diseqc_mode = 2,/* 2/3 PWM */ 112362306a36Sopenharmony_ci .tun1_maddress = 0,/* 0x60 */ 112462306a36Sopenharmony_ci .tun1_adc = 0,/* 2 Vpp */ 112562306a36Sopenharmony_ci .path1_mode = 3, 112662306a36Sopenharmony_ci}; 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_cistatic struct stb6100_config dw2104a_stb6100_config = { 112962306a36Sopenharmony_ci .tuner_address = 0x60, 113062306a36Sopenharmony_ci .refclock = 27000000, 113162306a36Sopenharmony_ci}; 113262306a36Sopenharmony_ci 113362306a36Sopenharmony_cistatic struct stv0900_config dw2104_stv0900_config = { 113462306a36Sopenharmony_ci .demod_address = 0x68, 113562306a36Sopenharmony_ci .demod_mode = 0, 113662306a36Sopenharmony_ci .xtal = 8000000, 113762306a36Sopenharmony_ci .clkmode = 3, 113862306a36Sopenharmony_ci .diseqc_mode = 2, 113962306a36Sopenharmony_ci .tun1_maddress = 0, 114062306a36Sopenharmony_ci .tun1_adc = 1,/* 1 Vpp */ 114162306a36Sopenharmony_ci .path1_mode = 3, 114262306a36Sopenharmony_ci}; 114362306a36Sopenharmony_ci 114462306a36Sopenharmony_cistatic struct stv6110_config dw2104_stv6110_config = { 114562306a36Sopenharmony_ci .i2c_address = 0x60, 114662306a36Sopenharmony_ci .mclk = 16000000, 114762306a36Sopenharmony_ci .clk_div = 1, 114862306a36Sopenharmony_ci}; 114962306a36Sopenharmony_ci 115062306a36Sopenharmony_cistatic struct stv0900_config prof_7500_stv0900_config = { 115162306a36Sopenharmony_ci .demod_address = 0x6a, 115262306a36Sopenharmony_ci .demod_mode = 0, 115362306a36Sopenharmony_ci .xtal = 27000000, 115462306a36Sopenharmony_ci .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ 115562306a36Sopenharmony_ci .diseqc_mode = 2,/* 2/3 PWM */ 115662306a36Sopenharmony_ci .tun1_maddress = 0,/* 0x60 */ 115762306a36Sopenharmony_ci .tun1_adc = 0,/* 2 Vpp */ 115862306a36Sopenharmony_ci .path1_mode = 3, 115962306a36Sopenharmony_ci .tun1_type = 3, 116062306a36Sopenharmony_ci .set_lock_led = dw210x_led_ctrl, 116162306a36Sopenharmony_ci}; 116262306a36Sopenharmony_ci 116362306a36Sopenharmony_cistatic struct ds3000_config su3000_ds3000_config = { 116462306a36Sopenharmony_ci .demod_address = 0x68, 116562306a36Sopenharmony_ci .ci_mode = 1, 116662306a36Sopenharmony_ci .set_lock_led = dw210x_led_ctrl, 116762306a36Sopenharmony_ci}; 116862306a36Sopenharmony_ci 116962306a36Sopenharmony_cistatic struct cxd2820r_config cxd2820r_config = { 117062306a36Sopenharmony_ci .i2c_address = 0x6c, /* (0xd8 >> 1) */ 117162306a36Sopenharmony_ci .ts_mode = 0x38, 117262306a36Sopenharmony_ci .ts_clock_inv = 1, 117362306a36Sopenharmony_ci}; 117462306a36Sopenharmony_ci 117562306a36Sopenharmony_cistatic struct tda18271_config tda18271_config = { 117662306a36Sopenharmony_ci .output_opt = TDA18271_OUTPUT_LT_OFF, 117762306a36Sopenharmony_ci .gate = TDA18271_GATE_DIGITAL, 117862306a36Sopenharmony_ci}; 117962306a36Sopenharmony_ci 118062306a36Sopenharmony_cistatic u8 m88rs2000_inittab[] = { 118162306a36Sopenharmony_ci DEMOD_WRITE, 0x9a, 0x30, 118262306a36Sopenharmony_ci DEMOD_WRITE, 0x00, 0x01, 118362306a36Sopenharmony_ci WRITE_DELAY, 0x19, 0x00, 118462306a36Sopenharmony_ci DEMOD_WRITE, 0x00, 0x00, 118562306a36Sopenharmony_ci DEMOD_WRITE, 0x9a, 0xb0, 118662306a36Sopenharmony_ci DEMOD_WRITE, 0x81, 0xc1, 118762306a36Sopenharmony_ci DEMOD_WRITE, 0x81, 0x81, 118862306a36Sopenharmony_ci DEMOD_WRITE, 0x86, 0xc6, 118962306a36Sopenharmony_ci DEMOD_WRITE, 0x9a, 0x30, 119062306a36Sopenharmony_ci DEMOD_WRITE, 0xf0, 0x80, 119162306a36Sopenharmony_ci DEMOD_WRITE, 0xf1, 0xbf, 119262306a36Sopenharmony_ci DEMOD_WRITE, 0xb0, 0x45, 119362306a36Sopenharmony_ci DEMOD_WRITE, 0xb2, 0x01, 119462306a36Sopenharmony_ci DEMOD_WRITE, 0x9a, 0xb0, 119562306a36Sopenharmony_ci 0xff, 0xaa, 0xff 119662306a36Sopenharmony_ci}; 119762306a36Sopenharmony_ci 119862306a36Sopenharmony_cistatic struct m88rs2000_config s421_m88rs2000_config = { 119962306a36Sopenharmony_ci .demod_addr = 0x68, 120062306a36Sopenharmony_ci .inittab = m88rs2000_inittab, 120162306a36Sopenharmony_ci}; 120262306a36Sopenharmony_ci 120362306a36Sopenharmony_cistatic int dw2104_frontend_attach(struct dvb_usb_adapter *d) 120462306a36Sopenharmony_ci{ 120562306a36Sopenharmony_ci struct dvb_tuner_ops *tuner_ops = NULL; 120662306a36Sopenharmony_ci 120762306a36Sopenharmony_ci if (demod_probe & 4) { 120862306a36Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config, 120962306a36Sopenharmony_ci &d->dev->i2c_adap, 0); 121062306a36Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 121162306a36Sopenharmony_ci if (dvb_attach(stb6100_attach, d->fe_adap[0].fe, 121262306a36Sopenharmony_ci &dw2104a_stb6100_config, 121362306a36Sopenharmony_ci &d->dev->i2c_adap)) { 121462306a36Sopenharmony_ci tuner_ops = &d->fe_adap[0].fe->ops.tuner_ops; 121562306a36Sopenharmony_ci tuner_ops->set_frequency = stb6100_set_freq; 121662306a36Sopenharmony_ci tuner_ops->get_frequency = stb6100_get_freq; 121762306a36Sopenharmony_ci tuner_ops->set_bandwidth = stb6100_set_bandw; 121862306a36Sopenharmony_ci tuner_ops->get_bandwidth = stb6100_get_bandw; 121962306a36Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 122062306a36Sopenharmony_ci info("Attached STV0900+STB6100!"); 122162306a36Sopenharmony_ci return 0; 122262306a36Sopenharmony_ci } 122362306a36Sopenharmony_ci } 122462306a36Sopenharmony_ci } 122562306a36Sopenharmony_ci 122662306a36Sopenharmony_ci if (demod_probe & 2) { 122762306a36Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config, 122862306a36Sopenharmony_ci &d->dev->i2c_adap, 0); 122962306a36Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 123062306a36Sopenharmony_ci if (dvb_attach(stv6110_attach, d->fe_adap[0].fe, 123162306a36Sopenharmony_ci &dw2104_stv6110_config, 123262306a36Sopenharmony_ci &d->dev->i2c_adap)) { 123362306a36Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 123462306a36Sopenharmony_ci info("Attached STV0900+STV6110A!"); 123562306a36Sopenharmony_ci return 0; 123662306a36Sopenharmony_ci } 123762306a36Sopenharmony_ci } 123862306a36Sopenharmony_ci } 123962306a36Sopenharmony_ci 124062306a36Sopenharmony_ci if (demod_probe & 1) { 124162306a36Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(cx24116_attach, &dw2104_config, 124262306a36Sopenharmony_ci &d->dev->i2c_adap); 124362306a36Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 124462306a36Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 124562306a36Sopenharmony_ci info("Attached cx24116!"); 124662306a36Sopenharmony_ci return 0; 124762306a36Sopenharmony_ci } 124862306a36Sopenharmony_ci } 124962306a36Sopenharmony_ci 125062306a36Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, 125162306a36Sopenharmony_ci &d->dev->i2c_adap); 125262306a36Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 125362306a36Sopenharmony_ci dvb_attach(ts2020_attach, d->fe_adap[0].fe, 125462306a36Sopenharmony_ci &dw2104_ts2020_config, &d->dev->i2c_adap); 125562306a36Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 125662306a36Sopenharmony_ci info("Attached DS3000!"); 125762306a36Sopenharmony_ci return 0; 125862306a36Sopenharmony_ci } 125962306a36Sopenharmony_ci 126062306a36Sopenharmony_ci return -EIO; 126162306a36Sopenharmony_ci} 126262306a36Sopenharmony_ci 126362306a36Sopenharmony_cistatic struct dvb_usb_device_properties dw2102_properties; 126462306a36Sopenharmony_cistatic struct dvb_usb_device_properties dw2104_properties; 126562306a36Sopenharmony_cistatic struct dvb_usb_device_properties s6x0_properties; 126662306a36Sopenharmony_ci 126762306a36Sopenharmony_cistatic int dw2102_frontend_attach(struct dvb_usb_adapter *d) 126862306a36Sopenharmony_ci{ 126962306a36Sopenharmony_ci if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) { 127062306a36Sopenharmony_ci /*dw2102_properties.adapter->tuner_attach = NULL;*/ 127162306a36Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config, 127262306a36Sopenharmony_ci &d->dev->i2c_adap); 127362306a36Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 127462306a36Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 127562306a36Sopenharmony_ci info("Attached si21xx!"); 127662306a36Sopenharmony_ci return 0; 127762306a36Sopenharmony_ci } 127862306a36Sopenharmony_ci } 127962306a36Sopenharmony_ci 128062306a36Sopenharmony_ci if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) { 128162306a36Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config, 128262306a36Sopenharmony_ci &d->dev->i2c_adap); 128362306a36Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 128462306a36Sopenharmony_ci if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, 128562306a36Sopenharmony_ci &d->dev->i2c_adap)) { 128662306a36Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 128762306a36Sopenharmony_ci info("Attached stv0288!"); 128862306a36Sopenharmony_ci return 0; 128962306a36Sopenharmony_ci } 129062306a36Sopenharmony_ci } 129162306a36Sopenharmony_ci } 129262306a36Sopenharmony_ci 129362306a36Sopenharmony_ci if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) { 129462306a36Sopenharmony_ci /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/ 129562306a36Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(stv0299_attach, &sharp_z0194a_config, 129662306a36Sopenharmony_ci &d->dev->i2c_adap); 129762306a36Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 129862306a36Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 129962306a36Sopenharmony_ci info("Attached stv0299!"); 130062306a36Sopenharmony_ci return 0; 130162306a36Sopenharmony_ci } 130262306a36Sopenharmony_ci } 130362306a36Sopenharmony_ci return -EIO; 130462306a36Sopenharmony_ci} 130562306a36Sopenharmony_ci 130662306a36Sopenharmony_cistatic int dw3101_frontend_attach(struct dvb_usb_adapter *d) 130762306a36Sopenharmony_ci{ 130862306a36Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config, 130962306a36Sopenharmony_ci &d->dev->i2c_adap, 0x48); 131062306a36Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 131162306a36Sopenharmony_ci info("Attached tda10023!"); 131262306a36Sopenharmony_ci return 0; 131362306a36Sopenharmony_ci } 131462306a36Sopenharmony_ci return -EIO; 131562306a36Sopenharmony_ci} 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_cistatic int zl100313_frontend_attach(struct dvb_usb_adapter *d) 131862306a36Sopenharmony_ci{ 131962306a36Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(mt312_attach, &zl313_config, 132062306a36Sopenharmony_ci &d->dev->i2c_adap); 132162306a36Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 132262306a36Sopenharmony_ci if (dvb_attach(zl10039_attach, d->fe_adap[0].fe, 0x60, 132362306a36Sopenharmony_ci &d->dev->i2c_adap)) { 132462306a36Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 132562306a36Sopenharmony_ci info("Attached zl100313+zl10039!"); 132662306a36Sopenharmony_ci return 0; 132762306a36Sopenharmony_ci } 132862306a36Sopenharmony_ci } 132962306a36Sopenharmony_ci 133062306a36Sopenharmony_ci return -EIO; 133162306a36Sopenharmony_ci} 133262306a36Sopenharmony_ci 133362306a36Sopenharmony_cistatic int stv0288_frontend_attach(struct dvb_usb_adapter *d) 133462306a36Sopenharmony_ci{ 133562306a36Sopenharmony_ci u8 obuf[] = {7, 1}; 133662306a36Sopenharmony_ci 133762306a36Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config, 133862306a36Sopenharmony_ci &d->dev->i2c_adap); 133962306a36Sopenharmony_ci 134062306a36Sopenharmony_ci if (d->fe_adap[0].fe == NULL) 134162306a36Sopenharmony_ci return -EIO; 134262306a36Sopenharmony_ci 134362306a36Sopenharmony_ci if (NULL == dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, &d->dev->i2c_adap)) 134462306a36Sopenharmony_ci return -EIO; 134562306a36Sopenharmony_ci 134662306a36Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 134762306a36Sopenharmony_ci 134862306a36Sopenharmony_ci dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); 134962306a36Sopenharmony_ci 135062306a36Sopenharmony_ci info("Attached stv0288+stb6000!"); 135162306a36Sopenharmony_ci 135262306a36Sopenharmony_ci return 0; 135362306a36Sopenharmony_ci 135462306a36Sopenharmony_ci} 135562306a36Sopenharmony_ci 135662306a36Sopenharmony_cistatic int ds3000_frontend_attach(struct dvb_usb_adapter *d) 135762306a36Sopenharmony_ci{ 135862306a36Sopenharmony_ci struct dw2102_state *st = d->dev->priv; 135962306a36Sopenharmony_ci u8 obuf[] = {7, 1}; 136062306a36Sopenharmony_ci 136162306a36Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(ds3000_attach, &s660_ds3000_config, 136262306a36Sopenharmony_ci &d->dev->i2c_adap); 136362306a36Sopenharmony_ci 136462306a36Sopenharmony_ci if (d->fe_adap[0].fe == NULL) 136562306a36Sopenharmony_ci return -EIO; 136662306a36Sopenharmony_ci 136762306a36Sopenharmony_ci dvb_attach(ts2020_attach, d->fe_adap[0].fe, &s660_ts2020_config, 136862306a36Sopenharmony_ci &d->dev->i2c_adap); 136962306a36Sopenharmony_ci 137062306a36Sopenharmony_ci st->old_set_voltage = d->fe_adap[0].fe->ops.set_voltage; 137162306a36Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = s660_set_voltage; 137262306a36Sopenharmony_ci 137362306a36Sopenharmony_ci dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); 137462306a36Sopenharmony_ci 137562306a36Sopenharmony_ci info("Attached ds3000+ts2020!"); 137662306a36Sopenharmony_ci 137762306a36Sopenharmony_ci return 0; 137862306a36Sopenharmony_ci} 137962306a36Sopenharmony_ci 138062306a36Sopenharmony_cistatic int prof_7500_frontend_attach(struct dvb_usb_adapter *d) 138162306a36Sopenharmony_ci{ 138262306a36Sopenharmony_ci u8 obuf[] = {7, 1}; 138362306a36Sopenharmony_ci 138462306a36Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config, 138562306a36Sopenharmony_ci &d->dev->i2c_adap, 0); 138662306a36Sopenharmony_ci if (d->fe_adap[0].fe == NULL) 138762306a36Sopenharmony_ci return -EIO; 138862306a36Sopenharmony_ci 138962306a36Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 139062306a36Sopenharmony_ci 139162306a36Sopenharmony_ci dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); 139262306a36Sopenharmony_ci 139362306a36Sopenharmony_ci info("Attached STV0900+STB6100A!"); 139462306a36Sopenharmony_ci 139562306a36Sopenharmony_ci return 0; 139662306a36Sopenharmony_ci} 139762306a36Sopenharmony_ci 139862306a36Sopenharmony_cistatic int su3000_frontend_attach(struct dvb_usb_adapter *adap) 139962306a36Sopenharmony_ci{ 140062306a36Sopenharmony_ci struct dvb_usb_device *d = adap->dev; 140162306a36Sopenharmony_ci struct dw2102_state *state = d->priv; 140262306a36Sopenharmony_ci 140362306a36Sopenharmony_ci mutex_lock(&d->data_mutex); 140462306a36Sopenharmony_ci 140562306a36Sopenharmony_ci state->data[0] = 0xe; 140662306a36Sopenharmony_ci state->data[1] = 0x80; 140762306a36Sopenharmony_ci state->data[2] = 0; 140862306a36Sopenharmony_ci 140962306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 141062306a36Sopenharmony_ci err("command 0x0e transfer failed."); 141162306a36Sopenharmony_ci 141262306a36Sopenharmony_ci state->data[0] = 0xe; 141362306a36Sopenharmony_ci state->data[1] = 0x02; 141462306a36Sopenharmony_ci state->data[2] = 1; 141562306a36Sopenharmony_ci 141662306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 141762306a36Sopenharmony_ci err("command 0x0e transfer failed."); 141862306a36Sopenharmony_ci msleep(300); 141962306a36Sopenharmony_ci 142062306a36Sopenharmony_ci state->data[0] = 0xe; 142162306a36Sopenharmony_ci state->data[1] = 0x83; 142262306a36Sopenharmony_ci state->data[2] = 0; 142362306a36Sopenharmony_ci 142462306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 142562306a36Sopenharmony_ci err("command 0x0e transfer failed."); 142662306a36Sopenharmony_ci 142762306a36Sopenharmony_ci state->data[0] = 0xe; 142862306a36Sopenharmony_ci state->data[1] = 0x83; 142962306a36Sopenharmony_ci state->data[2] = 1; 143062306a36Sopenharmony_ci 143162306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 143262306a36Sopenharmony_ci err("command 0x0e transfer failed."); 143362306a36Sopenharmony_ci 143462306a36Sopenharmony_ci state->data[0] = 0x51; 143562306a36Sopenharmony_ci 143662306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0) 143762306a36Sopenharmony_ci err("command 0x51 transfer failed."); 143862306a36Sopenharmony_ci 143962306a36Sopenharmony_ci mutex_unlock(&d->data_mutex); 144062306a36Sopenharmony_ci 144162306a36Sopenharmony_ci adap->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config, 144262306a36Sopenharmony_ci &d->i2c_adap); 144362306a36Sopenharmony_ci if (adap->fe_adap[0].fe == NULL) 144462306a36Sopenharmony_ci return -EIO; 144562306a36Sopenharmony_ci 144662306a36Sopenharmony_ci if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe, 144762306a36Sopenharmony_ci &dw2104_ts2020_config, 144862306a36Sopenharmony_ci &d->i2c_adap)) { 144962306a36Sopenharmony_ci info("Attached DS3000/TS2020!"); 145062306a36Sopenharmony_ci return 0; 145162306a36Sopenharmony_ci } 145262306a36Sopenharmony_ci 145362306a36Sopenharmony_ci info("Failed to attach DS3000/TS2020!"); 145462306a36Sopenharmony_ci return -EIO; 145562306a36Sopenharmony_ci} 145662306a36Sopenharmony_ci 145762306a36Sopenharmony_cistatic int t220_frontend_attach(struct dvb_usb_adapter *adap) 145862306a36Sopenharmony_ci{ 145962306a36Sopenharmony_ci struct dvb_usb_device *d = adap->dev; 146062306a36Sopenharmony_ci struct dw2102_state *state = d->priv; 146162306a36Sopenharmony_ci 146262306a36Sopenharmony_ci mutex_lock(&d->data_mutex); 146362306a36Sopenharmony_ci 146462306a36Sopenharmony_ci state->data[0] = 0xe; 146562306a36Sopenharmony_ci state->data[1] = 0x87; 146662306a36Sopenharmony_ci state->data[2] = 0x0; 146762306a36Sopenharmony_ci 146862306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 146962306a36Sopenharmony_ci err("command 0x0e transfer failed."); 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ci state->data[0] = 0xe; 147262306a36Sopenharmony_ci state->data[1] = 0x86; 147362306a36Sopenharmony_ci state->data[2] = 1; 147462306a36Sopenharmony_ci 147562306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 147662306a36Sopenharmony_ci err("command 0x0e transfer failed."); 147762306a36Sopenharmony_ci 147862306a36Sopenharmony_ci state->data[0] = 0xe; 147962306a36Sopenharmony_ci state->data[1] = 0x80; 148062306a36Sopenharmony_ci state->data[2] = 0; 148162306a36Sopenharmony_ci 148262306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 148362306a36Sopenharmony_ci err("command 0x0e transfer failed."); 148462306a36Sopenharmony_ci 148562306a36Sopenharmony_ci msleep(50); 148662306a36Sopenharmony_ci 148762306a36Sopenharmony_ci state->data[0] = 0xe; 148862306a36Sopenharmony_ci state->data[1] = 0x80; 148962306a36Sopenharmony_ci state->data[2] = 1; 149062306a36Sopenharmony_ci 149162306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 149262306a36Sopenharmony_ci err("command 0x0e transfer failed."); 149362306a36Sopenharmony_ci 149462306a36Sopenharmony_ci state->data[0] = 0x51; 149562306a36Sopenharmony_ci 149662306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0) 149762306a36Sopenharmony_ci err("command 0x51 transfer failed."); 149862306a36Sopenharmony_ci 149962306a36Sopenharmony_ci mutex_unlock(&d->data_mutex); 150062306a36Sopenharmony_ci 150162306a36Sopenharmony_ci adap->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config, 150262306a36Sopenharmony_ci &d->i2c_adap, NULL); 150362306a36Sopenharmony_ci if (adap->fe_adap[0].fe != NULL) { 150462306a36Sopenharmony_ci if (dvb_attach(tda18271_attach, adap->fe_adap[0].fe, 0x60, 150562306a36Sopenharmony_ci &d->i2c_adap, &tda18271_config)) { 150662306a36Sopenharmony_ci info("Attached TDA18271HD/CXD2820R!"); 150762306a36Sopenharmony_ci return 0; 150862306a36Sopenharmony_ci } 150962306a36Sopenharmony_ci } 151062306a36Sopenharmony_ci 151162306a36Sopenharmony_ci info("Failed to attach TDA18271HD/CXD2820R!"); 151262306a36Sopenharmony_ci return -EIO; 151362306a36Sopenharmony_ci} 151462306a36Sopenharmony_ci 151562306a36Sopenharmony_cistatic int m88rs2000_frontend_attach(struct dvb_usb_adapter *adap) 151662306a36Sopenharmony_ci{ 151762306a36Sopenharmony_ci struct dvb_usb_device *d = adap->dev; 151862306a36Sopenharmony_ci struct dw2102_state *state = d->priv; 151962306a36Sopenharmony_ci 152062306a36Sopenharmony_ci mutex_lock(&d->data_mutex); 152162306a36Sopenharmony_ci 152262306a36Sopenharmony_ci state->data[0] = 0x51; 152362306a36Sopenharmony_ci 152462306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0) 152562306a36Sopenharmony_ci err("command 0x51 transfer failed."); 152662306a36Sopenharmony_ci 152762306a36Sopenharmony_ci mutex_unlock(&d->data_mutex); 152862306a36Sopenharmony_ci 152962306a36Sopenharmony_ci adap->fe_adap[0].fe = dvb_attach(m88rs2000_attach, 153062306a36Sopenharmony_ci &s421_m88rs2000_config, 153162306a36Sopenharmony_ci &d->i2c_adap); 153262306a36Sopenharmony_ci 153362306a36Sopenharmony_ci if (adap->fe_adap[0].fe == NULL) 153462306a36Sopenharmony_ci return -EIO; 153562306a36Sopenharmony_ci 153662306a36Sopenharmony_ci if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe, 153762306a36Sopenharmony_ci &dw2104_ts2020_config, 153862306a36Sopenharmony_ci &d->i2c_adap)) { 153962306a36Sopenharmony_ci info("Attached RS2000/TS2020!"); 154062306a36Sopenharmony_ci return 0; 154162306a36Sopenharmony_ci } 154262306a36Sopenharmony_ci 154362306a36Sopenharmony_ci info("Failed to attach RS2000/TS2020!"); 154462306a36Sopenharmony_ci return -EIO; 154562306a36Sopenharmony_ci} 154662306a36Sopenharmony_ci 154762306a36Sopenharmony_cistatic int tt_s2_4600_frontend_attach_probe_demod(struct dvb_usb_device *d, 154862306a36Sopenharmony_ci const int probe_addr) 154962306a36Sopenharmony_ci{ 155062306a36Sopenharmony_ci struct dw2102_state *state = d->priv; 155162306a36Sopenharmony_ci 155262306a36Sopenharmony_ci state->data[0] = 0x9; 155362306a36Sopenharmony_ci state->data[1] = 0x1; 155462306a36Sopenharmony_ci state->data[2] = 0x1; 155562306a36Sopenharmony_ci state->data[3] = probe_addr; 155662306a36Sopenharmony_ci state->data[4] = 0x0; 155762306a36Sopenharmony_ci 155862306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 5, state->data, 2, 0) < 0) { 155962306a36Sopenharmony_ci err("i2c probe for address 0x%x failed.", probe_addr); 156062306a36Sopenharmony_ci return 0; 156162306a36Sopenharmony_ci } 156262306a36Sopenharmony_ci 156362306a36Sopenharmony_ci if (state->data[0] != 8) /* fail(7) or error, no device at address */ 156462306a36Sopenharmony_ci return 0; 156562306a36Sopenharmony_ci 156662306a36Sopenharmony_ci /* probing successful */ 156762306a36Sopenharmony_ci return 1; 156862306a36Sopenharmony_ci} 156962306a36Sopenharmony_ci 157062306a36Sopenharmony_cistatic int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap) 157162306a36Sopenharmony_ci{ 157262306a36Sopenharmony_ci struct dvb_usb_device *d = adap->dev; 157362306a36Sopenharmony_ci struct dw2102_state *state = d->priv; 157462306a36Sopenharmony_ci struct i2c_adapter *i2c_adapter; 157562306a36Sopenharmony_ci struct i2c_client *client; 157662306a36Sopenharmony_ci struct i2c_board_info board_info; 157762306a36Sopenharmony_ci struct m88ds3103_platform_data m88ds3103_pdata = {}; 157862306a36Sopenharmony_ci struct ts2020_config ts2020_config = {}; 157962306a36Sopenharmony_ci int demod_addr; 158062306a36Sopenharmony_ci 158162306a36Sopenharmony_ci mutex_lock(&d->data_mutex); 158262306a36Sopenharmony_ci 158362306a36Sopenharmony_ci state->data[0] = 0xe; 158462306a36Sopenharmony_ci state->data[1] = 0x80; 158562306a36Sopenharmony_ci state->data[2] = 0x0; 158662306a36Sopenharmony_ci 158762306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 158862306a36Sopenharmony_ci err("command 0x0e transfer failed."); 158962306a36Sopenharmony_ci 159062306a36Sopenharmony_ci state->data[0] = 0xe; 159162306a36Sopenharmony_ci state->data[1] = 0x02; 159262306a36Sopenharmony_ci state->data[2] = 1; 159362306a36Sopenharmony_ci 159462306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 159562306a36Sopenharmony_ci err("command 0x0e transfer failed."); 159662306a36Sopenharmony_ci msleep(300); 159762306a36Sopenharmony_ci 159862306a36Sopenharmony_ci state->data[0] = 0xe; 159962306a36Sopenharmony_ci state->data[1] = 0x83; 160062306a36Sopenharmony_ci state->data[2] = 0; 160162306a36Sopenharmony_ci 160262306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 160362306a36Sopenharmony_ci err("command 0x0e transfer failed."); 160462306a36Sopenharmony_ci 160562306a36Sopenharmony_ci state->data[0] = 0xe; 160662306a36Sopenharmony_ci state->data[1] = 0x83; 160762306a36Sopenharmony_ci state->data[2] = 1; 160862306a36Sopenharmony_ci 160962306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 161062306a36Sopenharmony_ci err("command 0x0e transfer failed."); 161162306a36Sopenharmony_ci 161262306a36Sopenharmony_ci state->data[0] = 0x51; 161362306a36Sopenharmony_ci 161462306a36Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0) 161562306a36Sopenharmony_ci err("command 0x51 transfer failed."); 161662306a36Sopenharmony_ci 161762306a36Sopenharmony_ci /* probe for demodulator i2c address */ 161862306a36Sopenharmony_ci demod_addr = -1; 161962306a36Sopenharmony_ci if (tt_s2_4600_frontend_attach_probe_demod(d, 0x68)) 162062306a36Sopenharmony_ci demod_addr = 0x68; 162162306a36Sopenharmony_ci else if (tt_s2_4600_frontend_attach_probe_demod(d, 0x69)) 162262306a36Sopenharmony_ci demod_addr = 0x69; 162362306a36Sopenharmony_ci else if (tt_s2_4600_frontend_attach_probe_demod(d, 0x6a)) 162462306a36Sopenharmony_ci demod_addr = 0x6a; 162562306a36Sopenharmony_ci 162662306a36Sopenharmony_ci mutex_unlock(&d->data_mutex); 162762306a36Sopenharmony_ci 162862306a36Sopenharmony_ci if (demod_addr < 0) { 162962306a36Sopenharmony_ci err("probing for demodulator failed. Is the external power switched on?"); 163062306a36Sopenharmony_ci return -ENODEV; 163162306a36Sopenharmony_ci } 163262306a36Sopenharmony_ci 163362306a36Sopenharmony_ci /* attach demod */ 163462306a36Sopenharmony_ci m88ds3103_pdata.clk = 27000000; 163562306a36Sopenharmony_ci m88ds3103_pdata.i2c_wr_max = 33; 163662306a36Sopenharmony_ci m88ds3103_pdata.ts_mode = M88DS3103_TS_CI; 163762306a36Sopenharmony_ci m88ds3103_pdata.ts_clk = 16000; 163862306a36Sopenharmony_ci m88ds3103_pdata.ts_clk_pol = 0; 163962306a36Sopenharmony_ci m88ds3103_pdata.spec_inv = 0; 164062306a36Sopenharmony_ci m88ds3103_pdata.agc = 0x99; 164162306a36Sopenharmony_ci m88ds3103_pdata.agc_inv = 0; 164262306a36Sopenharmony_ci m88ds3103_pdata.clk_out = M88DS3103_CLOCK_OUT_ENABLED; 164362306a36Sopenharmony_ci m88ds3103_pdata.envelope_mode = 0; 164462306a36Sopenharmony_ci m88ds3103_pdata.lnb_hv_pol = 1; 164562306a36Sopenharmony_ci m88ds3103_pdata.lnb_en_pol = 0; 164662306a36Sopenharmony_ci memset(&board_info, 0, sizeof(board_info)); 164762306a36Sopenharmony_ci if (demod_addr == 0x6a) 164862306a36Sopenharmony_ci strscpy(board_info.type, "m88ds3103b", I2C_NAME_SIZE); 164962306a36Sopenharmony_ci else 165062306a36Sopenharmony_ci strscpy(board_info.type, "m88ds3103", I2C_NAME_SIZE); 165162306a36Sopenharmony_ci board_info.addr = demod_addr; 165262306a36Sopenharmony_ci board_info.platform_data = &m88ds3103_pdata; 165362306a36Sopenharmony_ci request_module("m88ds3103"); 165462306a36Sopenharmony_ci client = i2c_new_client_device(&d->i2c_adap, &board_info); 165562306a36Sopenharmony_ci if (!i2c_client_has_driver(client)) 165662306a36Sopenharmony_ci return -ENODEV; 165762306a36Sopenharmony_ci if (!try_module_get(client->dev.driver->owner)) { 165862306a36Sopenharmony_ci i2c_unregister_device(client); 165962306a36Sopenharmony_ci return -ENODEV; 166062306a36Sopenharmony_ci } 166162306a36Sopenharmony_ci adap->fe_adap[0].fe = m88ds3103_pdata.get_dvb_frontend(client); 166262306a36Sopenharmony_ci i2c_adapter = m88ds3103_pdata.get_i2c_adapter(client); 166362306a36Sopenharmony_ci 166462306a36Sopenharmony_ci state->i2c_client_demod = client; 166562306a36Sopenharmony_ci 166662306a36Sopenharmony_ci /* attach tuner */ 166762306a36Sopenharmony_ci ts2020_config.fe = adap->fe_adap[0].fe; 166862306a36Sopenharmony_ci memset(&board_info, 0, sizeof(board_info)); 166962306a36Sopenharmony_ci strscpy(board_info.type, "ts2022", I2C_NAME_SIZE); 167062306a36Sopenharmony_ci board_info.addr = 0x60; 167162306a36Sopenharmony_ci board_info.platform_data = &ts2020_config; 167262306a36Sopenharmony_ci request_module("ts2020"); 167362306a36Sopenharmony_ci client = i2c_new_client_device(i2c_adapter, &board_info); 167462306a36Sopenharmony_ci 167562306a36Sopenharmony_ci if (!i2c_client_has_driver(client)) { 167662306a36Sopenharmony_ci dvb_frontend_detach(adap->fe_adap[0].fe); 167762306a36Sopenharmony_ci return -ENODEV; 167862306a36Sopenharmony_ci } 167962306a36Sopenharmony_ci 168062306a36Sopenharmony_ci if (!try_module_get(client->dev.driver->owner)) { 168162306a36Sopenharmony_ci i2c_unregister_device(client); 168262306a36Sopenharmony_ci dvb_frontend_detach(adap->fe_adap[0].fe); 168362306a36Sopenharmony_ci return -ENODEV; 168462306a36Sopenharmony_ci } 168562306a36Sopenharmony_ci 168662306a36Sopenharmony_ci /* delegate signal strength measurement to tuner */ 168762306a36Sopenharmony_ci adap->fe_adap[0].fe->ops.read_signal_strength = 168862306a36Sopenharmony_ci adap->fe_adap[0].fe->ops.tuner_ops.get_rf_strength; 168962306a36Sopenharmony_ci 169062306a36Sopenharmony_ci state->i2c_client_tuner = client; 169162306a36Sopenharmony_ci 169262306a36Sopenharmony_ci /* hook fe: need to resync the slave fifo when signal locks */ 169362306a36Sopenharmony_ci state->fe_read_status = adap->fe_adap[0].fe->ops.read_status; 169462306a36Sopenharmony_ci adap->fe_adap[0].fe->ops.read_status = tt_s2_4600_read_status; 169562306a36Sopenharmony_ci 169662306a36Sopenharmony_ci state->last_lock = 0; 169762306a36Sopenharmony_ci 169862306a36Sopenharmony_ci return 0; 169962306a36Sopenharmony_ci} 170062306a36Sopenharmony_ci 170162306a36Sopenharmony_cistatic int dw2102_tuner_attach(struct dvb_usb_adapter *adap) 170262306a36Sopenharmony_ci{ 170362306a36Sopenharmony_ci dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, 170462306a36Sopenharmony_ci &adap->dev->i2c_adap, DVB_PLL_OPERA1); 170562306a36Sopenharmony_ci return 0; 170662306a36Sopenharmony_ci} 170762306a36Sopenharmony_ci 170862306a36Sopenharmony_cistatic int dw3101_tuner_attach(struct dvb_usb_adapter *adap) 170962306a36Sopenharmony_ci{ 171062306a36Sopenharmony_ci dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, 171162306a36Sopenharmony_ci &adap->dev->i2c_adap, DVB_PLL_TUA6034); 171262306a36Sopenharmony_ci 171362306a36Sopenharmony_ci return 0; 171462306a36Sopenharmony_ci} 171562306a36Sopenharmony_ci 171662306a36Sopenharmony_cistatic int dw2102_rc_query(struct dvb_usb_device *d) 171762306a36Sopenharmony_ci{ 171862306a36Sopenharmony_ci u8 key[2]; 171962306a36Sopenharmony_ci struct i2c_msg msg = { 172062306a36Sopenharmony_ci .addr = DW2102_RC_QUERY, 172162306a36Sopenharmony_ci .flags = I2C_M_RD, 172262306a36Sopenharmony_ci .buf = key, 172362306a36Sopenharmony_ci .len = 2 172462306a36Sopenharmony_ci }; 172562306a36Sopenharmony_ci 172662306a36Sopenharmony_ci if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) { 172762306a36Sopenharmony_ci if (msg.buf[0] != 0xff) { 172862306a36Sopenharmony_ci deb_rc("%s: rc code: %x, %x\n", 172962306a36Sopenharmony_ci __func__, key[0], key[1]); 173062306a36Sopenharmony_ci rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, key[0], 0); 173162306a36Sopenharmony_ci } 173262306a36Sopenharmony_ci } 173362306a36Sopenharmony_ci 173462306a36Sopenharmony_ci return 0; 173562306a36Sopenharmony_ci} 173662306a36Sopenharmony_ci 173762306a36Sopenharmony_cistatic int prof_rc_query(struct dvb_usb_device *d) 173862306a36Sopenharmony_ci{ 173962306a36Sopenharmony_ci u8 key[2]; 174062306a36Sopenharmony_ci struct i2c_msg msg = { 174162306a36Sopenharmony_ci .addr = DW2102_RC_QUERY, 174262306a36Sopenharmony_ci .flags = I2C_M_RD, 174362306a36Sopenharmony_ci .buf = key, 174462306a36Sopenharmony_ci .len = 2 174562306a36Sopenharmony_ci }; 174662306a36Sopenharmony_ci 174762306a36Sopenharmony_ci if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) { 174862306a36Sopenharmony_ci if (msg.buf[0] != 0xff) { 174962306a36Sopenharmony_ci deb_rc("%s: rc code: %x, %x\n", 175062306a36Sopenharmony_ci __func__, key[0], key[1]); 175162306a36Sopenharmony_ci rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, key[0] ^ 0xff, 175262306a36Sopenharmony_ci 0); 175362306a36Sopenharmony_ci } 175462306a36Sopenharmony_ci } 175562306a36Sopenharmony_ci 175662306a36Sopenharmony_ci return 0; 175762306a36Sopenharmony_ci} 175862306a36Sopenharmony_ci 175962306a36Sopenharmony_cistatic int su3000_rc_query(struct dvb_usb_device *d) 176062306a36Sopenharmony_ci{ 176162306a36Sopenharmony_ci u8 key[2]; 176262306a36Sopenharmony_ci struct i2c_msg msg = { 176362306a36Sopenharmony_ci .addr = DW2102_RC_QUERY, 176462306a36Sopenharmony_ci .flags = I2C_M_RD, 176562306a36Sopenharmony_ci .buf = key, 176662306a36Sopenharmony_ci .len = 2 176762306a36Sopenharmony_ci }; 176862306a36Sopenharmony_ci 176962306a36Sopenharmony_ci if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) { 177062306a36Sopenharmony_ci if (msg.buf[0] != 0xff) { 177162306a36Sopenharmony_ci deb_rc("%s: rc code: %x, %x\n", 177262306a36Sopenharmony_ci __func__, key[0], key[1]); 177362306a36Sopenharmony_ci rc_keydown(d->rc_dev, RC_PROTO_RC5, 177462306a36Sopenharmony_ci RC_SCANCODE_RC5(key[1], key[0]), 0); 177562306a36Sopenharmony_ci } 177662306a36Sopenharmony_ci } 177762306a36Sopenharmony_ci 177862306a36Sopenharmony_ci return 0; 177962306a36Sopenharmony_ci} 178062306a36Sopenharmony_ci 178162306a36Sopenharmony_cienum dw2102_table_entry { 178262306a36Sopenharmony_ci CYPRESS_DW2102, 178362306a36Sopenharmony_ci CYPRESS_DW2101, 178462306a36Sopenharmony_ci CYPRESS_DW2104, 178562306a36Sopenharmony_ci TEVII_S650, 178662306a36Sopenharmony_ci TERRATEC_CINERGY_S, 178762306a36Sopenharmony_ci CYPRESS_DW3101, 178862306a36Sopenharmony_ci TEVII_S630, 178962306a36Sopenharmony_ci PROF_1100, 179062306a36Sopenharmony_ci TEVII_S660, 179162306a36Sopenharmony_ci PROF_7500, 179262306a36Sopenharmony_ci GENIATECH_SU3000, 179362306a36Sopenharmony_ci HAUPPAUGE_MAX_S2, 179462306a36Sopenharmony_ci TERRATEC_CINERGY_S2_R1, 179562306a36Sopenharmony_ci TEVII_S480_1, 179662306a36Sopenharmony_ci TEVII_S480_2, 179762306a36Sopenharmony_ci GENIATECH_X3M_SPC1400HD, 179862306a36Sopenharmony_ci TEVII_S421, 179962306a36Sopenharmony_ci TEVII_S632, 180062306a36Sopenharmony_ci TERRATEC_CINERGY_S2_R2, 180162306a36Sopenharmony_ci TERRATEC_CINERGY_S2_R3, 180262306a36Sopenharmony_ci TERRATEC_CINERGY_S2_R4, 180362306a36Sopenharmony_ci TERRATEC_CINERGY_S2_1, 180462306a36Sopenharmony_ci TERRATEC_CINERGY_S2_2, 180562306a36Sopenharmony_ci GOTVIEW_SAT_HD, 180662306a36Sopenharmony_ci GENIATECH_T220, 180762306a36Sopenharmony_ci TECHNOTREND_CONNECT_S2_4600, 180862306a36Sopenharmony_ci TEVII_S482_1, 180962306a36Sopenharmony_ci TEVII_S482_2, 181062306a36Sopenharmony_ci TERRATEC_CINERGY_S2_BOX, 181162306a36Sopenharmony_ci TEVII_S662 181262306a36Sopenharmony_ci}; 181362306a36Sopenharmony_ci 181462306a36Sopenharmony_cistatic struct usb_device_id dw2102_table[] = { 181562306a36Sopenharmony_ci DVB_USB_DEV(CYPRESS, CYPRESS_DW2102), 181662306a36Sopenharmony_ci DVB_USB_DEV(CYPRESS, CYPRESS_DW2101), 181762306a36Sopenharmony_ci DVB_USB_DEV(CYPRESS, CYPRESS_DW2104), 181862306a36Sopenharmony_ci DVB_USB_DEV(TEVII, TEVII_S650), 181962306a36Sopenharmony_ci DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S), 182062306a36Sopenharmony_ci DVB_USB_DEV(CYPRESS, CYPRESS_DW3101), 182162306a36Sopenharmony_ci DVB_USB_DEV(TEVII, TEVII_S630), 182262306a36Sopenharmony_ci DVB_USB_DEV(PROF_1, PROF_1100), 182362306a36Sopenharmony_ci DVB_USB_DEV(TEVII, TEVII_S660), 182462306a36Sopenharmony_ci DVB_USB_DEV(PROF_2, PROF_7500), 182562306a36Sopenharmony_ci DVB_USB_DEV(GTEK, GENIATECH_SU3000), 182662306a36Sopenharmony_ci DVB_USB_DEV(HAUPPAUGE, HAUPPAUGE_MAX_S2), 182762306a36Sopenharmony_ci DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S2_R1), 182862306a36Sopenharmony_ci DVB_USB_DEV(TEVII, TEVII_S480_1), 182962306a36Sopenharmony_ci DVB_USB_DEV(TEVII, TEVII_S480_2), 183062306a36Sopenharmony_ci DVB_USB_DEV(GTEK, GENIATECH_X3M_SPC1400HD), 183162306a36Sopenharmony_ci DVB_USB_DEV(TEVII, TEVII_S421), 183262306a36Sopenharmony_ci DVB_USB_DEV(TEVII, TEVII_S632), 183362306a36Sopenharmony_ci DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S2_R2), 183462306a36Sopenharmony_ci DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S2_R3), 183562306a36Sopenharmony_ci DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S2_R4), 183662306a36Sopenharmony_ci DVB_USB_DEV(TERRATEC_2, TERRATEC_CINERGY_S2_1), 183762306a36Sopenharmony_ci DVB_USB_DEV(TERRATEC_2, TERRATEC_CINERGY_S2_2), 183862306a36Sopenharmony_ci DVB_USB_DEV(GOTVIEW, GOTVIEW_SAT_HD), 183962306a36Sopenharmony_ci DVB_USB_DEV(GTEK, GENIATECH_T220), 184062306a36Sopenharmony_ci DVB_USB_DEV(TECHNOTREND, TECHNOTREND_CONNECT_S2_4600), 184162306a36Sopenharmony_ci DVB_USB_DEV(TEVII, TEVII_S482_1), 184262306a36Sopenharmony_ci DVB_USB_DEV(TEVII, TEVII_S482_2), 184362306a36Sopenharmony_ci DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S2_BOX), 184462306a36Sopenharmony_ci DVB_USB_DEV(TEVII, TEVII_S662), 184562306a36Sopenharmony_ci { } 184662306a36Sopenharmony_ci}; 184762306a36Sopenharmony_ci 184862306a36Sopenharmony_ciMODULE_DEVICE_TABLE(usb, dw2102_table); 184962306a36Sopenharmony_ci 185062306a36Sopenharmony_cistatic int dw2102_load_firmware(struct usb_device *dev, 185162306a36Sopenharmony_ci const struct firmware *frmwr) 185262306a36Sopenharmony_ci{ 185362306a36Sopenharmony_ci u8 *b, *p; 185462306a36Sopenharmony_ci int ret = 0, i; 185562306a36Sopenharmony_ci u8 reset; 185662306a36Sopenharmony_ci u8 reset16[] = {0, 0, 0, 0, 0, 0, 0}; 185762306a36Sopenharmony_ci const struct firmware *fw; 185862306a36Sopenharmony_ci 185962306a36Sopenharmony_ci switch (le16_to_cpu(dev->descriptor.idProduct)) { 186062306a36Sopenharmony_ci case 0x2101: 186162306a36Sopenharmony_ci ret = request_firmware(&fw, DW2101_FIRMWARE, &dev->dev); 186262306a36Sopenharmony_ci if (ret != 0) { 186362306a36Sopenharmony_ci err(err_str, DW2101_FIRMWARE); 186462306a36Sopenharmony_ci return ret; 186562306a36Sopenharmony_ci } 186662306a36Sopenharmony_ci break; 186762306a36Sopenharmony_ci default: 186862306a36Sopenharmony_ci fw = frmwr; 186962306a36Sopenharmony_ci break; 187062306a36Sopenharmony_ci } 187162306a36Sopenharmony_ci info("start downloading DW210X firmware"); 187262306a36Sopenharmony_ci p = kmalloc(fw->size, GFP_KERNEL); 187362306a36Sopenharmony_ci reset = 1; 187462306a36Sopenharmony_ci /*stop the CPU*/ 187562306a36Sopenharmony_ci dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG); 187662306a36Sopenharmony_ci dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG); 187762306a36Sopenharmony_ci 187862306a36Sopenharmony_ci if (p != NULL) { 187962306a36Sopenharmony_ci memcpy(p, fw->data, fw->size); 188062306a36Sopenharmony_ci for (i = 0; i < fw->size; i += 0x40) { 188162306a36Sopenharmony_ci b = (u8 *) p + i; 188262306a36Sopenharmony_ci if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40, 188362306a36Sopenharmony_ci DW210X_WRITE_MSG) != 0x40) { 188462306a36Sopenharmony_ci err("error while transferring firmware"); 188562306a36Sopenharmony_ci ret = -EINVAL; 188662306a36Sopenharmony_ci break; 188762306a36Sopenharmony_ci } 188862306a36Sopenharmony_ci } 188962306a36Sopenharmony_ci /* restart the CPU */ 189062306a36Sopenharmony_ci reset = 0; 189162306a36Sopenharmony_ci if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, 189262306a36Sopenharmony_ci DW210X_WRITE_MSG) != 1) { 189362306a36Sopenharmony_ci err("could not restart the USB controller CPU."); 189462306a36Sopenharmony_ci ret = -EINVAL; 189562306a36Sopenharmony_ci } 189662306a36Sopenharmony_ci if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, 189762306a36Sopenharmony_ci DW210X_WRITE_MSG) != 1) { 189862306a36Sopenharmony_ci err("could not restart the USB controller CPU."); 189962306a36Sopenharmony_ci ret = -EINVAL; 190062306a36Sopenharmony_ci } 190162306a36Sopenharmony_ci /* init registers */ 190262306a36Sopenharmony_ci switch (le16_to_cpu(dev->descriptor.idProduct)) { 190362306a36Sopenharmony_ci case USB_PID_TEVII_S650: 190462306a36Sopenharmony_ci dw2104_properties.rc.core.rc_codes = RC_MAP_TEVII_NEC; 190562306a36Sopenharmony_ci fallthrough; 190662306a36Sopenharmony_ci case USB_PID_CYPRESS_DW2104: 190762306a36Sopenharmony_ci reset = 1; 190862306a36Sopenharmony_ci dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1, 190962306a36Sopenharmony_ci DW210X_WRITE_MSG); 191062306a36Sopenharmony_ci fallthrough; 191162306a36Sopenharmony_ci case USB_PID_CYPRESS_DW3101: 191262306a36Sopenharmony_ci reset = 0; 191362306a36Sopenharmony_ci dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, 191462306a36Sopenharmony_ci DW210X_WRITE_MSG); 191562306a36Sopenharmony_ci break; 191662306a36Sopenharmony_ci case USB_PID_TERRATEC_CINERGY_S: 191762306a36Sopenharmony_ci case USB_PID_CYPRESS_DW2102: 191862306a36Sopenharmony_ci dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, 191962306a36Sopenharmony_ci DW210X_WRITE_MSG); 192062306a36Sopenharmony_ci dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2, 192162306a36Sopenharmony_ci DW210X_READ_MSG); 192262306a36Sopenharmony_ci /* check STV0299 frontend */ 192362306a36Sopenharmony_ci dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2, 192462306a36Sopenharmony_ci DW210X_READ_MSG); 192562306a36Sopenharmony_ci if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) { 192662306a36Sopenharmony_ci dw2102_properties.i2c_algo = &dw2102_i2c_algo; 192762306a36Sopenharmony_ci dw2102_properties.adapter->fe[0].tuner_attach = &dw2102_tuner_attach; 192862306a36Sopenharmony_ci break; 192962306a36Sopenharmony_ci } else { 193062306a36Sopenharmony_ci /* check STV0288 frontend */ 193162306a36Sopenharmony_ci reset16[0] = 0xd0; 193262306a36Sopenharmony_ci reset16[1] = 1; 193362306a36Sopenharmony_ci reset16[2] = 0; 193462306a36Sopenharmony_ci dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3, 193562306a36Sopenharmony_ci DW210X_WRITE_MSG); 193662306a36Sopenharmony_ci dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3, 193762306a36Sopenharmony_ci DW210X_READ_MSG); 193862306a36Sopenharmony_ci if (reset16[2] == 0x11) { 193962306a36Sopenharmony_ci dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo; 194062306a36Sopenharmony_ci break; 194162306a36Sopenharmony_ci } 194262306a36Sopenharmony_ci } 194362306a36Sopenharmony_ci fallthrough; 194462306a36Sopenharmony_ci case 0x2101: 194562306a36Sopenharmony_ci dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2, 194662306a36Sopenharmony_ci DW210X_READ_MSG); 194762306a36Sopenharmony_ci dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7, 194862306a36Sopenharmony_ci DW210X_READ_MSG); 194962306a36Sopenharmony_ci dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7, 195062306a36Sopenharmony_ci DW210X_READ_MSG); 195162306a36Sopenharmony_ci dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2, 195262306a36Sopenharmony_ci DW210X_READ_MSG); 195362306a36Sopenharmony_ci break; 195462306a36Sopenharmony_ci } 195562306a36Sopenharmony_ci 195662306a36Sopenharmony_ci msleep(100); 195762306a36Sopenharmony_ci kfree(p); 195862306a36Sopenharmony_ci } 195962306a36Sopenharmony_ci 196062306a36Sopenharmony_ci if (le16_to_cpu(dev->descriptor.idProduct) == 0x2101) 196162306a36Sopenharmony_ci release_firmware(fw); 196262306a36Sopenharmony_ci return ret; 196362306a36Sopenharmony_ci} 196462306a36Sopenharmony_ci 196562306a36Sopenharmony_cistatic struct dvb_usb_device_properties dw2102_properties = { 196662306a36Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 196762306a36Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 196862306a36Sopenharmony_ci .firmware = DW2102_FIRMWARE, 196962306a36Sopenharmony_ci .no_reconnect = 1, 197062306a36Sopenharmony_ci 197162306a36Sopenharmony_ci .i2c_algo = &dw2102_serit_i2c_algo, 197262306a36Sopenharmony_ci 197362306a36Sopenharmony_ci .rc.core = { 197462306a36Sopenharmony_ci .rc_interval = 150, 197562306a36Sopenharmony_ci .rc_codes = RC_MAP_DM1105_NEC, 197662306a36Sopenharmony_ci .module_name = "dw2102", 197762306a36Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 197862306a36Sopenharmony_ci .rc_query = dw2102_rc_query, 197962306a36Sopenharmony_ci }, 198062306a36Sopenharmony_ci 198162306a36Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x81, 198262306a36Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 198362306a36Sopenharmony_ci .num_adapters = 1, 198462306a36Sopenharmony_ci .download_firmware = dw2102_load_firmware, 198562306a36Sopenharmony_ci .read_mac_address = dw210x_read_mac_address, 198662306a36Sopenharmony_ci .adapter = { 198762306a36Sopenharmony_ci { 198862306a36Sopenharmony_ci .num_frontends = 1, 198962306a36Sopenharmony_ci .fe = {{ 199062306a36Sopenharmony_ci .frontend_attach = dw2102_frontend_attach, 199162306a36Sopenharmony_ci .stream = { 199262306a36Sopenharmony_ci .type = USB_BULK, 199362306a36Sopenharmony_ci .count = 8, 199462306a36Sopenharmony_ci .endpoint = 0x82, 199562306a36Sopenharmony_ci .u = { 199662306a36Sopenharmony_ci .bulk = { 199762306a36Sopenharmony_ci .buffersize = 4096, 199862306a36Sopenharmony_ci } 199962306a36Sopenharmony_ci } 200062306a36Sopenharmony_ci }, 200162306a36Sopenharmony_ci }}, 200262306a36Sopenharmony_ci } 200362306a36Sopenharmony_ci }, 200462306a36Sopenharmony_ci .num_device_descs = 3, 200562306a36Sopenharmony_ci .devices = { 200662306a36Sopenharmony_ci {"DVBWorld DVB-S 2102 USB2.0", 200762306a36Sopenharmony_ci {&dw2102_table[CYPRESS_DW2102], NULL}, 200862306a36Sopenharmony_ci {NULL}, 200962306a36Sopenharmony_ci }, 201062306a36Sopenharmony_ci {"DVBWorld DVB-S 2101 USB2.0", 201162306a36Sopenharmony_ci {&dw2102_table[CYPRESS_DW2101], NULL}, 201262306a36Sopenharmony_ci {NULL}, 201362306a36Sopenharmony_ci }, 201462306a36Sopenharmony_ci {"TerraTec Cinergy S USB", 201562306a36Sopenharmony_ci {&dw2102_table[TERRATEC_CINERGY_S], NULL}, 201662306a36Sopenharmony_ci {NULL}, 201762306a36Sopenharmony_ci }, 201862306a36Sopenharmony_ci } 201962306a36Sopenharmony_ci}; 202062306a36Sopenharmony_ci 202162306a36Sopenharmony_cistatic struct dvb_usb_device_properties dw2104_properties = { 202262306a36Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 202362306a36Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 202462306a36Sopenharmony_ci .firmware = DW2104_FIRMWARE, 202562306a36Sopenharmony_ci .no_reconnect = 1, 202662306a36Sopenharmony_ci 202762306a36Sopenharmony_ci .i2c_algo = &dw2104_i2c_algo, 202862306a36Sopenharmony_ci .rc.core = { 202962306a36Sopenharmony_ci .rc_interval = 150, 203062306a36Sopenharmony_ci .rc_codes = RC_MAP_DM1105_NEC, 203162306a36Sopenharmony_ci .module_name = "dw2102", 203262306a36Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 203362306a36Sopenharmony_ci .rc_query = dw2102_rc_query, 203462306a36Sopenharmony_ci }, 203562306a36Sopenharmony_ci 203662306a36Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x81, 203762306a36Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 203862306a36Sopenharmony_ci .num_adapters = 1, 203962306a36Sopenharmony_ci .download_firmware = dw2102_load_firmware, 204062306a36Sopenharmony_ci .read_mac_address = dw210x_read_mac_address, 204162306a36Sopenharmony_ci .adapter = { 204262306a36Sopenharmony_ci { 204362306a36Sopenharmony_ci .num_frontends = 1, 204462306a36Sopenharmony_ci .fe = {{ 204562306a36Sopenharmony_ci .frontend_attach = dw2104_frontend_attach, 204662306a36Sopenharmony_ci .stream = { 204762306a36Sopenharmony_ci .type = USB_BULK, 204862306a36Sopenharmony_ci .count = 8, 204962306a36Sopenharmony_ci .endpoint = 0x82, 205062306a36Sopenharmony_ci .u = { 205162306a36Sopenharmony_ci .bulk = { 205262306a36Sopenharmony_ci .buffersize = 4096, 205362306a36Sopenharmony_ci } 205462306a36Sopenharmony_ci } 205562306a36Sopenharmony_ci }, 205662306a36Sopenharmony_ci }}, 205762306a36Sopenharmony_ci } 205862306a36Sopenharmony_ci }, 205962306a36Sopenharmony_ci .num_device_descs = 2, 206062306a36Sopenharmony_ci .devices = { 206162306a36Sopenharmony_ci { "DVBWorld DW2104 USB2.0", 206262306a36Sopenharmony_ci {&dw2102_table[CYPRESS_DW2104], NULL}, 206362306a36Sopenharmony_ci {NULL}, 206462306a36Sopenharmony_ci }, 206562306a36Sopenharmony_ci { "TeVii S650 USB2.0", 206662306a36Sopenharmony_ci {&dw2102_table[TEVII_S650], NULL}, 206762306a36Sopenharmony_ci {NULL}, 206862306a36Sopenharmony_ci }, 206962306a36Sopenharmony_ci } 207062306a36Sopenharmony_ci}; 207162306a36Sopenharmony_ci 207262306a36Sopenharmony_cistatic struct dvb_usb_device_properties dw3101_properties = { 207362306a36Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 207462306a36Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 207562306a36Sopenharmony_ci .firmware = DW3101_FIRMWARE, 207662306a36Sopenharmony_ci .no_reconnect = 1, 207762306a36Sopenharmony_ci 207862306a36Sopenharmony_ci .i2c_algo = &dw3101_i2c_algo, 207962306a36Sopenharmony_ci .rc.core = { 208062306a36Sopenharmony_ci .rc_interval = 150, 208162306a36Sopenharmony_ci .rc_codes = RC_MAP_DM1105_NEC, 208262306a36Sopenharmony_ci .module_name = "dw2102", 208362306a36Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 208462306a36Sopenharmony_ci .rc_query = dw2102_rc_query, 208562306a36Sopenharmony_ci }, 208662306a36Sopenharmony_ci 208762306a36Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x81, 208862306a36Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 208962306a36Sopenharmony_ci .num_adapters = 1, 209062306a36Sopenharmony_ci .download_firmware = dw2102_load_firmware, 209162306a36Sopenharmony_ci .read_mac_address = dw210x_read_mac_address, 209262306a36Sopenharmony_ci .adapter = { 209362306a36Sopenharmony_ci { 209462306a36Sopenharmony_ci .num_frontends = 1, 209562306a36Sopenharmony_ci .fe = {{ 209662306a36Sopenharmony_ci .frontend_attach = dw3101_frontend_attach, 209762306a36Sopenharmony_ci .tuner_attach = dw3101_tuner_attach, 209862306a36Sopenharmony_ci .stream = { 209962306a36Sopenharmony_ci .type = USB_BULK, 210062306a36Sopenharmony_ci .count = 8, 210162306a36Sopenharmony_ci .endpoint = 0x82, 210262306a36Sopenharmony_ci .u = { 210362306a36Sopenharmony_ci .bulk = { 210462306a36Sopenharmony_ci .buffersize = 4096, 210562306a36Sopenharmony_ci } 210662306a36Sopenharmony_ci } 210762306a36Sopenharmony_ci }, 210862306a36Sopenharmony_ci }}, 210962306a36Sopenharmony_ci } 211062306a36Sopenharmony_ci }, 211162306a36Sopenharmony_ci .num_device_descs = 1, 211262306a36Sopenharmony_ci .devices = { 211362306a36Sopenharmony_ci { "DVBWorld DVB-C 3101 USB2.0", 211462306a36Sopenharmony_ci {&dw2102_table[CYPRESS_DW3101], NULL}, 211562306a36Sopenharmony_ci {NULL}, 211662306a36Sopenharmony_ci }, 211762306a36Sopenharmony_ci } 211862306a36Sopenharmony_ci}; 211962306a36Sopenharmony_ci 212062306a36Sopenharmony_cistatic struct dvb_usb_device_properties s6x0_properties = { 212162306a36Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 212262306a36Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 212362306a36Sopenharmony_ci .size_of_priv = sizeof(struct dw2102_state), 212462306a36Sopenharmony_ci .firmware = S630_FIRMWARE, 212562306a36Sopenharmony_ci .no_reconnect = 1, 212662306a36Sopenharmony_ci 212762306a36Sopenharmony_ci .i2c_algo = &s6x0_i2c_algo, 212862306a36Sopenharmony_ci .rc.core = { 212962306a36Sopenharmony_ci .rc_interval = 150, 213062306a36Sopenharmony_ci .rc_codes = RC_MAP_TEVII_NEC, 213162306a36Sopenharmony_ci .module_name = "dw2102", 213262306a36Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 213362306a36Sopenharmony_ci .rc_query = dw2102_rc_query, 213462306a36Sopenharmony_ci }, 213562306a36Sopenharmony_ci 213662306a36Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x81, 213762306a36Sopenharmony_ci .num_adapters = 1, 213862306a36Sopenharmony_ci .download_firmware = dw2102_load_firmware, 213962306a36Sopenharmony_ci .read_mac_address = s6x0_read_mac_address, 214062306a36Sopenharmony_ci .adapter = { 214162306a36Sopenharmony_ci { 214262306a36Sopenharmony_ci .num_frontends = 1, 214362306a36Sopenharmony_ci .fe = {{ 214462306a36Sopenharmony_ci .frontend_attach = zl100313_frontend_attach, 214562306a36Sopenharmony_ci .stream = { 214662306a36Sopenharmony_ci .type = USB_BULK, 214762306a36Sopenharmony_ci .count = 8, 214862306a36Sopenharmony_ci .endpoint = 0x82, 214962306a36Sopenharmony_ci .u = { 215062306a36Sopenharmony_ci .bulk = { 215162306a36Sopenharmony_ci .buffersize = 4096, 215262306a36Sopenharmony_ci } 215362306a36Sopenharmony_ci } 215462306a36Sopenharmony_ci }, 215562306a36Sopenharmony_ci }}, 215662306a36Sopenharmony_ci } 215762306a36Sopenharmony_ci }, 215862306a36Sopenharmony_ci .num_device_descs = 1, 215962306a36Sopenharmony_ci .devices = { 216062306a36Sopenharmony_ci {"TeVii S630 USB", 216162306a36Sopenharmony_ci {&dw2102_table[TEVII_S630], NULL}, 216262306a36Sopenharmony_ci {NULL}, 216362306a36Sopenharmony_ci }, 216462306a36Sopenharmony_ci } 216562306a36Sopenharmony_ci}; 216662306a36Sopenharmony_ci 216762306a36Sopenharmony_cistatic struct dvb_usb_device_properties p1100_properties = { 216862306a36Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 216962306a36Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 217062306a36Sopenharmony_ci .size_of_priv = sizeof(struct dw2102_state), 217162306a36Sopenharmony_ci .firmware = P1100_FIRMWARE, 217262306a36Sopenharmony_ci .no_reconnect = 1, 217362306a36Sopenharmony_ci 217462306a36Sopenharmony_ci .i2c_algo = &s6x0_i2c_algo, 217562306a36Sopenharmony_ci .rc.core = { 217662306a36Sopenharmony_ci .rc_interval = 150, 217762306a36Sopenharmony_ci .rc_codes = RC_MAP_TBS_NEC, 217862306a36Sopenharmony_ci .module_name = "dw2102", 217962306a36Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 218062306a36Sopenharmony_ci .rc_query = prof_rc_query, 218162306a36Sopenharmony_ci }, 218262306a36Sopenharmony_ci 218362306a36Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x81, 218462306a36Sopenharmony_ci .num_adapters = 1, 218562306a36Sopenharmony_ci .download_firmware = dw2102_load_firmware, 218662306a36Sopenharmony_ci .read_mac_address = s6x0_read_mac_address, 218762306a36Sopenharmony_ci .adapter = { 218862306a36Sopenharmony_ci { 218962306a36Sopenharmony_ci .num_frontends = 1, 219062306a36Sopenharmony_ci .fe = {{ 219162306a36Sopenharmony_ci .frontend_attach = stv0288_frontend_attach, 219262306a36Sopenharmony_ci .stream = { 219362306a36Sopenharmony_ci .type = USB_BULK, 219462306a36Sopenharmony_ci .count = 8, 219562306a36Sopenharmony_ci .endpoint = 0x82, 219662306a36Sopenharmony_ci .u = { 219762306a36Sopenharmony_ci .bulk = { 219862306a36Sopenharmony_ci .buffersize = 4096, 219962306a36Sopenharmony_ci } 220062306a36Sopenharmony_ci } 220162306a36Sopenharmony_ci }, 220262306a36Sopenharmony_ci } }, 220362306a36Sopenharmony_ci } 220462306a36Sopenharmony_ci }, 220562306a36Sopenharmony_ci .num_device_descs = 1, 220662306a36Sopenharmony_ci .devices = { 220762306a36Sopenharmony_ci {"Prof 1100 USB ", 220862306a36Sopenharmony_ci {&dw2102_table[PROF_1100], NULL}, 220962306a36Sopenharmony_ci {NULL}, 221062306a36Sopenharmony_ci }, 221162306a36Sopenharmony_ci } 221262306a36Sopenharmony_ci}; 221362306a36Sopenharmony_ci 221462306a36Sopenharmony_cistatic struct dvb_usb_device_properties s660_properties = { 221562306a36Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 221662306a36Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 221762306a36Sopenharmony_ci .size_of_priv = sizeof(struct dw2102_state), 221862306a36Sopenharmony_ci .firmware = S660_FIRMWARE, 221962306a36Sopenharmony_ci .no_reconnect = 1, 222062306a36Sopenharmony_ci 222162306a36Sopenharmony_ci .i2c_algo = &s6x0_i2c_algo, 222262306a36Sopenharmony_ci .rc.core = { 222362306a36Sopenharmony_ci .rc_interval = 150, 222462306a36Sopenharmony_ci .rc_codes = RC_MAP_TEVII_NEC, 222562306a36Sopenharmony_ci .module_name = "dw2102", 222662306a36Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 222762306a36Sopenharmony_ci .rc_query = dw2102_rc_query, 222862306a36Sopenharmony_ci }, 222962306a36Sopenharmony_ci 223062306a36Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x81, 223162306a36Sopenharmony_ci .num_adapters = 1, 223262306a36Sopenharmony_ci .download_firmware = dw2102_load_firmware, 223362306a36Sopenharmony_ci .read_mac_address = s6x0_read_mac_address, 223462306a36Sopenharmony_ci .adapter = { 223562306a36Sopenharmony_ci { 223662306a36Sopenharmony_ci .num_frontends = 1, 223762306a36Sopenharmony_ci .fe = {{ 223862306a36Sopenharmony_ci .frontend_attach = ds3000_frontend_attach, 223962306a36Sopenharmony_ci .stream = { 224062306a36Sopenharmony_ci .type = USB_BULK, 224162306a36Sopenharmony_ci .count = 8, 224262306a36Sopenharmony_ci .endpoint = 0x82, 224362306a36Sopenharmony_ci .u = { 224462306a36Sopenharmony_ci .bulk = { 224562306a36Sopenharmony_ci .buffersize = 4096, 224662306a36Sopenharmony_ci } 224762306a36Sopenharmony_ci } 224862306a36Sopenharmony_ci }, 224962306a36Sopenharmony_ci } }, 225062306a36Sopenharmony_ci } 225162306a36Sopenharmony_ci }, 225262306a36Sopenharmony_ci .num_device_descs = 3, 225362306a36Sopenharmony_ci .devices = { 225462306a36Sopenharmony_ci {"TeVii S660 USB", 225562306a36Sopenharmony_ci {&dw2102_table[TEVII_S660], NULL}, 225662306a36Sopenharmony_ci {NULL}, 225762306a36Sopenharmony_ci }, 225862306a36Sopenharmony_ci {"TeVii S480.1 USB", 225962306a36Sopenharmony_ci {&dw2102_table[TEVII_S480_1], NULL}, 226062306a36Sopenharmony_ci {NULL}, 226162306a36Sopenharmony_ci }, 226262306a36Sopenharmony_ci {"TeVii S480.2 USB", 226362306a36Sopenharmony_ci {&dw2102_table[TEVII_S480_2], NULL}, 226462306a36Sopenharmony_ci {NULL}, 226562306a36Sopenharmony_ci }, 226662306a36Sopenharmony_ci } 226762306a36Sopenharmony_ci}; 226862306a36Sopenharmony_ci 226962306a36Sopenharmony_cistatic struct dvb_usb_device_properties p7500_properties = { 227062306a36Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 227162306a36Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 227262306a36Sopenharmony_ci .size_of_priv = sizeof(struct dw2102_state), 227362306a36Sopenharmony_ci .firmware = P7500_FIRMWARE, 227462306a36Sopenharmony_ci .no_reconnect = 1, 227562306a36Sopenharmony_ci 227662306a36Sopenharmony_ci .i2c_algo = &s6x0_i2c_algo, 227762306a36Sopenharmony_ci .rc.core = { 227862306a36Sopenharmony_ci .rc_interval = 150, 227962306a36Sopenharmony_ci .rc_codes = RC_MAP_TBS_NEC, 228062306a36Sopenharmony_ci .module_name = "dw2102", 228162306a36Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 228262306a36Sopenharmony_ci .rc_query = prof_rc_query, 228362306a36Sopenharmony_ci }, 228462306a36Sopenharmony_ci 228562306a36Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x81, 228662306a36Sopenharmony_ci .num_adapters = 1, 228762306a36Sopenharmony_ci .download_firmware = dw2102_load_firmware, 228862306a36Sopenharmony_ci .read_mac_address = s6x0_read_mac_address, 228962306a36Sopenharmony_ci .adapter = { 229062306a36Sopenharmony_ci { 229162306a36Sopenharmony_ci .num_frontends = 1, 229262306a36Sopenharmony_ci .fe = {{ 229362306a36Sopenharmony_ci .frontend_attach = prof_7500_frontend_attach, 229462306a36Sopenharmony_ci .stream = { 229562306a36Sopenharmony_ci .type = USB_BULK, 229662306a36Sopenharmony_ci .count = 8, 229762306a36Sopenharmony_ci .endpoint = 0x82, 229862306a36Sopenharmony_ci .u = { 229962306a36Sopenharmony_ci .bulk = { 230062306a36Sopenharmony_ci .buffersize = 4096, 230162306a36Sopenharmony_ci } 230262306a36Sopenharmony_ci } 230362306a36Sopenharmony_ci }, 230462306a36Sopenharmony_ci } }, 230562306a36Sopenharmony_ci } 230662306a36Sopenharmony_ci }, 230762306a36Sopenharmony_ci .num_device_descs = 1, 230862306a36Sopenharmony_ci .devices = { 230962306a36Sopenharmony_ci {"Prof 7500 USB DVB-S2", 231062306a36Sopenharmony_ci {&dw2102_table[PROF_7500], NULL}, 231162306a36Sopenharmony_ci {NULL}, 231262306a36Sopenharmony_ci }, 231362306a36Sopenharmony_ci } 231462306a36Sopenharmony_ci}; 231562306a36Sopenharmony_ci 231662306a36Sopenharmony_cistatic struct dvb_usb_device_properties su3000_properties = { 231762306a36Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 231862306a36Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 231962306a36Sopenharmony_ci .size_of_priv = sizeof(struct dw2102_state), 232062306a36Sopenharmony_ci .power_ctrl = su3000_power_ctrl, 232162306a36Sopenharmony_ci .num_adapters = 1, 232262306a36Sopenharmony_ci .identify_state = su3000_identify_state, 232362306a36Sopenharmony_ci .i2c_algo = &su3000_i2c_algo, 232462306a36Sopenharmony_ci 232562306a36Sopenharmony_ci .rc.core = { 232662306a36Sopenharmony_ci .rc_interval = 150, 232762306a36Sopenharmony_ci .rc_codes = RC_MAP_SU3000, 232862306a36Sopenharmony_ci .module_name = "dw2102", 232962306a36Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_RC5, 233062306a36Sopenharmony_ci .rc_query = su3000_rc_query, 233162306a36Sopenharmony_ci }, 233262306a36Sopenharmony_ci 233362306a36Sopenharmony_ci .read_mac_address = su3000_read_mac_address, 233462306a36Sopenharmony_ci 233562306a36Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 233662306a36Sopenharmony_ci 233762306a36Sopenharmony_ci .adapter = { 233862306a36Sopenharmony_ci { 233962306a36Sopenharmony_ci .num_frontends = 1, 234062306a36Sopenharmony_ci .fe = {{ 234162306a36Sopenharmony_ci .streaming_ctrl = su3000_streaming_ctrl, 234262306a36Sopenharmony_ci .frontend_attach = su3000_frontend_attach, 234362306a36Sopenharmony_ci .stream = { 234462306a36Sopenharmony_ci .type = USB_BULK, 234562306a36Sopenharmony_ci .count = 8, 234662306a36Sopenharmony_ci .endpoint = 0x82, 234762306a36Sopenharmony_ci .u = { 234862306a36Sopenharmony_ci .bulk = { 234962306a36Sopenharmony_ci .buffersize = 4096, 235062306a36Sopenharmony_ci } 235162306a36Sopenharmony_ci } 235262306a36Sopenharmony_ci } 235362306a36Sopenharmony_ci }}, 235462306a36Sopenharmony_ci } 235562306a36Sopenharmony_ci }, 235662306a36Sopenharmony_ci .num_device_descs = 9, 235762306a36Sopenharmony_ci .devices = { 235862306a36Sopenharmony_ci { "SU3000HD DVB-S USB2.0", 235962306a36Sopenharmony_ci { &dw2102_table[GENIATECH_SU3000], NULL }, 236062306a36Sopenharmony_ci { NULL }, 236162306a36Sopenharmony_ci }, 236262306a36Sopenharmony_ci { "Hauppauge MAX S2 or WinTV NOVA HD USB2.0", 236362306a36Sopenharmony_ci { &dw2102_table[HAUPPAUGE_MAX_S2], NULL }, 236462306a36Sopenharmony_ci { NULL }, 236562306a36Sopenharmony_ci }, 236662306a36Sopenharmony_ci { "Terratec Cinergy S2 USB HD", 236762306a36Sopenharmony_ci { &dw2102_table[TERRATEC_CINERGY_S2_R1], NULL }, 236862306a36Sopenharmony_ci { NULL }, 236962306a36Sopenharmony_ci }, 237062306a36Sopenharmony_ci { "X3M TV SPC1400HD PCI", 237162306a36Sopenharmony_ci { &dw2102_table[GENIATECH_X3M_SPC1400HD], NULL }, 237262306a36Sopenharmony_ci { NULL }, 237362306a36Sopenharmony_ci }, 237462306a36Sopenharmony_ci { "Terratec Cinergy S2 USB HD Rev.2", 237562306a36Sopenharmony_ci { &dw2102_table[TERRATEC_CINERGY_S2_R2], NULL }, 237662306a36Sopenharmony_ci { NULL }, 237762306a36Sopenharmony_ci }, 237862306a36Sopenharmony_ci { "Terratec Cinergy S2 USB HD Rev.3", 237962306a36Sopenharmony_ci { &dw2102_table[TERRATEC_CINERGY_S2_R3], NULL }, 238062306a36Sopenharmony_ci { NULL }, 238162306a36Sopenharmony_ci }, 238262306a36Sopenharmony_ci { "Terratec Cinergy S2 PCIe Dual Port 1", 238362306a36Sopenharmony_ci { &dw2102_table[TERRATEC_CINERGY_S2_1], NULL }, 238462306a36Sopenharmony_ci { NULL }, 238562306a36Sopenharmony_ci }, 238662306a36Sopenharmony_ci { "Terratec Cinergy S2 PCIe Dual Port 2", 238762306a36Sopenharmony_ci { &dw2102_table[TERRATEC_CINERGY_S2_2], NULL }, 238862306a36Sopenharmony_ci { NULL }, 238962306a36Sopenharmony_ci }, 239062306a36Sopenharmony_ci { "GOTVIEW Satellite HD", 239162306a36Sopenharmony_ci { &dw2102_table[GOTVIEW_SAT_HD], NULL }, 239262306a36Sopenharmony_ci { NULL }, 239362306a36Sopenharmony_ci }, 239462306a36Sopenharmony_ci } 239562306a36Sopenharmony_ci}; 239662306a36Sopenharmony_ci 239762306a36Sopenharmony_cistatic struct dvb_usb_device_properties s421_properties = { 239862306a36Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 239962306a36Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 240062306a36Sopenharmony_ci .size_of_priv = sizeof(struct dw2102_state), 240162306a36Sopenharmony_ci .power_ctrl = su3000_power_ctrl, 240262306a36Sopenharmony_ci .num_adapters = 1, 240362306a36Sopenharmony_ci .identify_state = su3000_identify_state, 240462306a36Sopenharmony_ci .i2c_algo = &su3000_i2c_algo, 240562306a36Sopenharmony_ci 240662306a36Sopenharmony_ci .rc.core = { 240762306a36Sopenharmony_ci .rc_interval = 150, 240862306a36Sopenharmony_ci .rc_codes = RC_MAP_SU3000, 240962306a36Sopenharmony_ci .module_name = "dw2102", 241062306a36Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_RC5, 241162306a36Sopenharmony_ci .rc_query = su3000_rc_query, 241262306a36Sopenharmony_ci }, 241362306a36Sopenharmony_ci 241462306a36Sopenharmony_ci .read_mac_address = su3000_read_mac_address, 241562306a36Sopenharmony_ci 241662306a36Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 241762306a36Sopenharmony_ci 241862306a36Sopenharmony_ci .adapter = { 241962306a36Sopenharmony_ci { 242062306a36Sopenharmony_ci .num_frontends = 1, 242162306a36Sopenharmony_ci .fe = {{ 242262306a36Sopenharmony_ci .streaming_ctrl = su3000_streaming_ctrl, 242362306a36Sopenharmony_ci .frontend_attach = m88rs2000_frontend_attach, 242462306a36Sopenharmony_ci .stream = { 242562306a36Sopenharmony_ci .type = USB_BULK, 242662306a36Sopenharmony_ci .count = 8, 242762306a36Sopenharmony_ci .endpoint = 0x82, 242862306a36Sopenharmony_ci .u = { 242962306a36Sopenharmony_ci .bulk = { 243062306a36Sopenharmony_ci .buffersize = 4096, 243162306a36Sopenharmony_ci } 243262306a36Sopenharmony_ci } 243362306a36Sopenharmony_ci } 243462306a36Sopenharmony_ci } }, 243562306a36Sopenharmony_ci } 243662306a36Sopenharmony_ci }, 243762306a36Sopenharmony_ci .num_device_descs = 2, 243862306a36Sopenharmony_ci .devices = { 243962306a36Sopenharmony_ci { "TeVii S421 PCI", 244062306a36Sopenharmony_ci { &dw2102_table[TEVII_S421], NULL }, 244162306a36Sopenharmony_ci { NULL }, 244262306a36Sopenharmony_ci }, 244362306a36Sopenharmony_ci { "TeVii S632 USB", 244462306a36Sopenharmony_ci { &dw2102_table[TEVII_S632], NULL }, 244562306a36Sopenharmony_ci { NULL }, 244662306a36Sopenharmony_ci }, 244762306a36Sopenharmony_ci } 244862306a36Sopenharmony_ci}; 244962306a36Sopenharmony_ci 245062306a36Sopenharmony_cistatic struct dvb_usb_device_properties t220_properties = { 245162306a36Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 245262306a36Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 245362306a36Sopenharmony_ci .size_of_priv = sizeof(struct dw2102_state), 245462306a36Sopenharmony_ci .power_ctrl = su3000_power_ctrl, 245562306a36Sopenharmony_ci .num_adapters = 1, 245662306a36Sopenharmony_ci .identify_state = su3000_identify_state, 245762306a36Sopenharmony_ci .i2c_algo = &su3000_i2c_algo, 245862306a36Sopenharmony_ci 245962306a36Sopenharmony_ci .rc.core = { 246062306a36Sopenharmony_ci .rc_interval = 150, 246162306a36Sopenharmony_ci .rc_codes = RC_MAP_SU3000, 246262306a36Sopenharmony_ci .module_name = "dw2102", 246362306a36Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_RC5, 246462306a36Sopenharmony_ci .rc_query = su3000_rc_query, 246562306a36Sopenharmony_ci }, 246662306a36Sopenharmony_ci 246762306a36Sopenharmony_ci .read_mac_address = su3000_read_mac_address, 246862306a36Sopenharmony_ci 246962306a36Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 247062306a36Sopenharmony_ci 247162306a36Sopenharmony_ci .adapter = { 247262306a36Sopenharmony_ci { 247362306a36Sopenharmony_ci .num_frontends = 1, 247462306a36Sopenharmony_ci .fe = { { 247562306a36Sopenharmony_ci .streaming_ctrl = su3000_streaming_ctrl, 247662306a36Sopenharmony_ci .frontend_attach = t220_frontend_attach, 247762306a36Sopenharmony_ci .stream = { 247862306a36Sopenharmony_ci .type = USB_BULK, 247962306a36Sopenharmony_ci .count = 8, 248062306a36Sopenharmony_ci .endpoint = 0x82, 248162306a36Sopenharmony_ci .u = { 248262306a36Sopenharmony_ci .bulk = { 248362306a36Sopenharmony_ci .buffersize = 4096, 248462306a36Sopenharmony_ci } 248562306a36Sopenharmony_ci } 248662306a36Sopenharmony_ci } 248762306a36Sopenharmony_ci } }, 248862306a36Sopenharmony_ci } 248962306a36Sopenharmony_ci }, 249062306a36Sopenharmony_ci .num_device_descs = 1, 249162306a36Sopenharmony_ci .devices = { 249262306a36Sopenharmony_ci { "Geniatech T220 DVB-T/T2 USB2.0", 249362306a36Sopenharmony_ci { &dw2102_table[GENIATECH_T220], NULL }, 249462306a36Sopenharmony_ci { NULL }, 249562306a36Sopenharmony_ci }, 249662306a36Sopenharmony_ci } 249762306a36Sopenharmony_ci}; 249862306a36Sopenharmony_ci 249962306a36Sopenharmony_cistatic struct dvb_usb_device_properties tt_s2_4600_properties = { 250062306a36Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 250162306a36Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 250262306a36Sopenharmony_ci .size_of_priv = sizeof(struct dw2102_state), 250362306a36Sopenharmony_ci .power_ctrl = su3000_power_ctrl, 250462306a36Sopenharmony_ci .num_adapters = 1, 250562306a36Sopenharmony_ci .identify_state = su3000_identify_state, 250662306a36Sopenharmony_ci .i2c_algo = &su3000_i2c_algo, 250762306a36Sopenharmony_ci 250862306a36Sopenharmony_ci .rc.core = { 250962306a36Sopenharmony_ci .rc_interval = 250, 251062306a36Sopenharmony_ci .rc_codes = RC_MAP_TT_1500, 251162306a36Sopenharmony_ci .module_name = "dw2102", 251262306a36Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_RC5, 251362306a36Sopenharmony_ci .rc_query = su3000_rc_query, 251462306a36Sopenharmony_ci }, 251562306a36Sopenharmony_ci 251662306a36Sopenharmony_ci .read_mac_address = su3000_read_mac_address, 251762306a36Sopenharmony_ci 251862306a36Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 251962306a36Sopenharmony_ci 252062306a36Sopenharmony_ci .adapter = { 252162306a36Sopenharmony_ci { 252262306a36Sopenharmony_ci .num_frontends = 1, 252362306a36Sopenharmony_ci .fe = {{ 252462306a36Sopenharmony_ci .streaming_ctrl = su3000_streaming_ctrl, 252562306a36Sopenharmony_ci .frontend_attach = tt_s2_4600_frontend_attach, 252662306a36Sopenharmony_ci .stream = { 252762306a36Sopenharmony_ci .type = USB_BULK, 252862306a36Sopenharmony_ci .count = 8, 252962306a36Sopenharmony_ci .endpoint = 0x82, 253062306a36Sopenharmony_ci .u = { 253162306a36Sopenharmony_ci .bulk = { 253262306a36Sopenharmony_ci .buffersize = 4096, 253362306a36Sopenharmony_ci } 253462306a36Sopenharmony_ci } 253562306a36Sopenharmony_ci } 253662306a36Sopenharmony_ci } }, 253762306a36Sopenharmony_ci } 253862306a36Sopenharmony_ci }, 253962306a36Sopenharmony_ci .num_device_descs = 5, 254062306a36Sopenharmony_ci .devices = { 254162306a36Sopenharmony_ci { "TechnoTrend TT-connect S2-4600", 254262306a36Sopenharmony_ci { &dw2102_table[TECHNOTREND_CONNECT_S2_4600], NULL }, 254362306a36Sopenharmony_ci { NULL }, 254462306a36Sopenharmony_ci }, 254562306a36Sopenharmony_ci { "TeVii S482 (tuner 1)", 254662306a36Sopenharmony_ci { &dw2102_table[TEVII_S482_1], NULL }, 254762306a36Sopenharmony_ci { NULL }, 254862306a36Sopenharmony_ci }, 254962306a36Sopenharmony_ci { "TeVii S482 (tuner 2)", 255062306a36Sopenharmony_ci { &dw2102_table[TEVII_S482_2], NULL }, 255162306a36Sopenharmony_ci { NULL }, 255262306a36Sopenharmony_ci }, 255362306a36Sopenharmony_ci { "Terratec Cinergy S2 USB BOX", 255462306a36Sopenharmony_ci { &dw2102_table[TERRATEC_CINERGY_S2_BOX], NULL }, 255562306a36Sopenharmony_ci { NULL }, 255662306a36Sopenharmony_ci }, 255762306a36Sopenharmony_ci { "TeVii S662", 255862306a36Sopenharmony_ci { &dw2102_table[TEVII_S662], NULL }, 255962306a36Sopenharmony_ci { NULL }, 256062306a36Sopenharmony_ci }, 256162306a36Sopenharmony_ci } 256262306a36Sopenharmony_ci}; 256362306a36Sopenharmony_ci 256462306a36Sopenharmony_cistatic int dw2102_probe(struct usb_interface *intf, 256562306a36Sopenharmony_ci const struct usb_device_id *id) 256662306a36Sopenharmony_ci{ 256762306a36Sopenharmony_ci if (!(dvb_usb_device_init(intf, &dw2102_properties, 256862306a36Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 256962306a36Sopenharmony_ci dvb_usb_device_init(intf, &dw2104_properties, 257062306a36Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 257162306a36Sopenharmony_ci dvb_usb_device_init(intf, &dw3101_properties, 257262306a36Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 257362306a36Sopenharmony_ci dvb_usb_device_init(intf, &s6x0_properties, 257462306a36Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 257562306a36Sopenharmony_ci dvb_usb_device_init(intf, &p1100_properties, 257662306a36Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 257762306a36Sopenharmony_ci dvb_usb_device_init(intf, &s660_properties, 257862306a36Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 257962306a36Sopenharmony_ci dvb_usb_device_init(intf, &p7500_properties, 258062306a36Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 258162306a36Sopenharmony_ci dvb_usb_device_init(intf, &s421_properties, 258262306a36Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 258362306a36Sopenharmony_ci dvb_usb_device_init(intf, &su3000_properties, 258462306a36Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 258562306a36Sopenharmony_ci dvb_usb_device_init(intf, &t220_properties, 258662306a36Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 258762306a36Sopenharmony_ci dvb_usb_device_init(intf, &tt_s2_4600_properties, 258862306a36Sopenharmony_ci THIS_MODULE, NULL, adapter_nr))) { 258962306a36Sopenharmony_ci 259062306a36Sopenharmony_ci return 0; 259162306a36Sopenharmony_ci } 259262306a36Sopenharmony_ci 259362306a36Sopenharmony_ci return -ENODEV; 259462306a36Sopenharmony_ci} 259562306a36Sopenharmony_ci 259662306a36Sopenharmony_cistatic void dw2102_disconnect(struct usb_interface *intf) 259762306a36Sopenharmony_ci{ 259862306a36Sopenharmony_ci struct dvb_usb_device *d = usb_get_intfdata(intf); 259962306a36Sopenharmony_ci struct dw2102_state *st = d->priv; 260062306a36Sopenharmony_ci struct i2c_client *client; 260162306a36Sopenharmony_ci 260262306a36Sopenharmony_ci /* remove I2C client for tuner */ 260362306a36Sopenharmony_ci client = st->i2c_client_tuner; 260462306a36Sopenharmony_ci if (client) { 260562306a36Sopenharmony_ci module_put(client->dev.driver->owner); 260662306a36Sopenharmony_ci i2c_unregister_device(client); 260762306a36Sopenharmony_ci } 260862306a36Sopenharmony_ci 260962306a36Sopenharmony_ci /* remove I2C client for demodulator */ 261062306a36Sopenharmony_ci client = st->i2c_client_demod; 261162306a36Sopenharmony_ci if (client) { 261262306a36Sopenharmony_ci module_put(client->dev.driver->owner); 261362306a36Sopenharmony_ci i2c_unregister_device(client); 261462306a36Sopenharmony_ci } 261562306a36Sopenharmony_ci 261662306a36Sopenharmony_ci dvb_usb_device_exit(intf); 261762306a36Sopenharmony_ci} 261862306a36Sopenharmony_ci 261962306a36Sopenharmony_cistatic struct usb_driver dw2102_driver = { 262062306a36Sopenharmony_ci .name = "dw2102", 262162306a36Sopenharmony_ci .probe = dw2102_probe, 262262306a36Sopenharmony_ci .disconnect = dw2102_disconnect, 262362306a36Sopenharmony_ci .id_table = dw2102_table, 262462306a36Sopenharmony_ci}; 262562306a36Sopenharmony_ci 262662306a36Sopenharmony_cimodule_usb_driver(dw2102_driver); 262762306a36Sopenharmony_ci 262862306a36Sopenharmony_ciMODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); 262962306a36Sopenharmony_ciMODULE_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"); 263062306a36Sopenharmony_ciMODULE_VERSION("0.1"); 263162306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 263262306a36Sopenharmony_ciMODULE_FIRMWARE(DW2101_FIRMWARE); 263362306a36Sopenharmony_ciMODULE_FIRMWARE(DW2102_FIRMWARE); 263462306a36Sopenharmony_ciMODULE_FIRMWARE(DW2104_FIRMWARE); 263562306a36Sopenharmony_ciMODULE_FIRMWARE(DW3101_FIRMWARE); 263662306a36Sopenharmony_ciMODULE_FIRMWARE(S630_FIRMWARE); 263762306a36Sopenharmony_ciMODULE_FIRMWARE(S660_FIRMWARE); 263862306a36Sopenharmony_ciMODULE_FIRMWARE(P1100_FIRMWARE); 263962306a36Sopenharmony_ciMODULE_FIRMWARE(P7500_FIRMWARE); 2640