18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* DVB USB framework compliant Linux driver for the 38c2ecf20Sopenharmony_ci * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, 48c2ecf20Sopenharmony_ci * TeVii S421, S480, S482, S600, S630, S632, S650, S660, S662, 58c2ecf20Sopenharmony_ci * Prof 1100, 7500, 68c2ecf20Sopenharmony_ci * Geniatech SU3000, T220, 78c2ecf20Sopenharmony_ci * TechnoTrend S2-4600, 88c2ecf20Sopenharmony_ci * Terratec Cinergy S2 cards 98c2ecf20Sopenharmony_ci * Copyright (C) 2008-2012 Igor M. Liplianin (liplianin@me.by) 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information 128c2ecf20Sopenharmony_ci */ 138c2ecf20Sopenharmony_ci#include <media/dvb-usb-ids.h> 148c2ecf20Sopenharmony_ci#include "dw2102.h" 158c2ecf20Sopenharmony_ci#include "si21xx.h" 168c2ecf20Sopenharmony_ci#include "stv0299.h" 178c2ecf20Sopenharmony_ci#include "z0194a.h" 188c2ecf20Sopenharmony_ci#include "stv0288.h" 198c2ecf20Sopenharmony_ci#include "stb6000.h" 208c2ecf20Sopenharmony_ci#include "eds1547.h" 218c2ecf20Sopenharmony_ci#include "cx24116.h" 228c2ecf20Sopenharmony_ci#include "tda1002x.h" 238c2ecf20Sopenharmony_ci#include "mt312.h" 248c2ecf20Sopenharmony_ci#include "zl10039.h" 258c2ecf20Sopenharmony_ci#include "ts2020.h" 268c2ecf20Sopenharmony_ci#include "ds3000.h" 278c2ecf20Sopenharmony_ci#include "stv0900.h" 288c2ecf20Sopenharmony_ci#include "stv6110.h" 298c2ecf20Sopenharmony_ci#include "stb6100.h" 308c2ecf20Sopenharmony_ci#include "stb6100_proc.h" 318c2ecf20Sopenharmony_ci#include "m88rs2000.h" 328c2ecf20Sopenharmony_ci#include "tda18271.h" 338c2ecf20Sopenharmony_ci#include "cxd2820r.h" 348c2ecf20Sopenharmony_ci#include "m88ds3103.h" 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci/* Max transfer size done by I2C transfer functions */ 378c2ecf20Sopenharmony_ci#define MAX_XFER_SIZE 64 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#define DW210X_READ_MSG 0 418c2ecf20Sopenharmony_ci#define DW210X_WRITE_MSG 1 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#define REG_1F_SYMBOLRATE_BYTE0 0x1f 448c2ecf20Sopenharmony_ci#define REG_20_SYMBOLRATE_BYTE1 0x20 458c2ecf20Sopenharmony_ci#define REG_21_SYMBOLRATE_BYTE2 0x21 468c2ecf20Sopenharmony_ci/* on my own*/ 478c2ecf20Sopenharmony_ci#define DW2102_VOLTAGE_CTRL (0x1800) 488c2ecf20Sopenharmony_ci#define SU3000_STREAM_CTRL (0x1900) 498c2ecf20Sopenharmony_ci#define DW2102_RC_QUERY (0x1a00) 508c2ecf20Sopenharmony_ci#define DW2102_LED_CTRL (0x1b00) 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci#define DW2101_FIRMWARE "dvb-usb-dw2101.fw" 538c2ecf20Sopenharmony_ci#define DW2102_FIRMWARE "dvb-usb-dw2102.fw" 548c2ecf20Sopenharmony_ci#define DW2104_FIRMWARE "dvb-usb-dw2104.fw" 558c2ecf20Sopenharmony_ci#define DW3101_FIRMWARE "dvb-usb-dw3101.fw" 568c2ecf20Sopenharmony_ci#define S630_FIRMWARE "dvb-usb-s630.fw" 578c2ecf20Sopenharmony_ci#define S660_FIRMWARE "dvb-usb-s660.fw" 588c2ecf20Sopenharmony_ci#define P1100_FIRMWARE "dvb-usb-p1100.fw" 598c2ecf20Sopenharmony_ci#define P7500_FIRMWARE "dvb-usb-p7500.fw" 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci#define err_str "did not find the firmware file '%s'. You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware" 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistruct dw2102_state { 648c2ecf20Sopenharmony_ci u8 initialized; 658c2ecf20Sopenharmony_ci u8 last_lock; 668c2ecf20Sopenharmony_ci u8 data[MAX_XFER_SIZE + 4]; 678c2ecf20Sopenharmony_ci struct i2c_client *i2c_client_demod; 688c2ecf20Sopenharmony_ci struct i2c_client *i2c_client_tuner; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci /* fe hook functions*/ 718c2ecf20Sopenharmony_ci int (*old_set_voltage)(struct dvb_frontend *f, enum fe_sec_voltage v); 728c2ecf20Sopenharmony_ci int (*fe_read_status)(struct dvb_frontend *fe, 738c2ecf20Sopenharmony_ci enum fe_status *status); 748c2ecf20Sopenharmony_ci}; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci/* debug */ 778c2ecf20Sopenharmony_cistatic int dvb_usb_dw2102_debug; 788c2ecf20Sopenharmony_cimodule_param_named(debug, dvb_usb_dw2102_debug, int, 0644); 798c2ecf20Sopenharmony_ciMODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))." 808c2ecf20Sopenharmony_ci DVB_USB_DEBUG_STATUS); 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci/* demod probe */ 838c2ecf20Sopenharmony_cistatic int demod_probe = 1; 848c2ecf20Sopenharmony_cimodule_param_named(demod, demod_probe, int, 0644); 858c2ecf20Sopenharmony_ciMODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 4=stv0903+stb6100(or-able))."); 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ciDVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistatic int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value, 908c2ecf20Sopenharmony_ci u16 index, u8 * data, u16 len, int flags) 918c2ecf20Sopenharmony_ci{ 928c2ecf20Sopenharmony_ci int ret; 938c2ecf20Sopenharmony_ci u8 *u8buf; 948c2ecf20Sopenharmony_ci unsigned int pipe = (flags == DW210X_READ_MSG) ? 958c2ecf20Sopenharmony_ci usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); 968c2ecf20Sopenharmony_ci u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci u8buf = kmalloc(len, GFP_KERNEL); 998c2ecf20Sopenharmony_ci if (!u8buf) 1008c2ecf20Sopenharmony_ci return -ENOMEM; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci if (flags == DW210X_WRITE_MSG) 1048c2ecf20Sopenharmony_ci memcpy(u8buf, data, len); 1058c2ecf20Sopenharmony_ci ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, 1068c2ecf20Sopenharmony_ci value, index , u8buf, len, 2000); 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci if (flags == DW210X_READ_MSG) 1098c2ecf20Sopenharmony_ci memcpy(data, u8buf, len); 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci kfree(u8buf); 1128c2ecf20Sopenharmony_ci return ret; 1138c2ecf20Sopenharmony_ci} 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci/* I2C */ 1168c2ecf20Sopenharmony_cistatic int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], 1178c2ecf20Sopenharmony_ci int num) 1188c2ecf20Sopenharmony_ci{ 1198c2ecf20Sopenharmony_ci struct dvb_usb_device *d = i2c_get_adapdata(adap); 1208c2ecf20Sopenharmony_ci int i = 0; 1218c2ecf20Sopenharmony_ci u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0}; 1228c2ecf20Sopenharmony_ci u16 value; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci if (!d) 1258c2ecf20Sopenharmony_ci return -ENODEV; 1268c2ecf20Sopenharmony_ci if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 1278c2ecf20Sopenharmony_ci return -EAGAIN; 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci switch (num) { 1308c2ecf20Sopenharmony_ci case 2: 1318c2ecf20Sopenharmony_ci if (msg[0].len < 1) { 1328c2ecf20Sopenharmony_ci num = -EOPNOTSUPP; 1338c2ecf20Sopenharmony_ci break; 1348c2ecf20Sopenharmony_ci } 1358c2ecf20Sopenharmony_ci /* read stv0299 register */ 1368c2ecf20Sopenharmony_ci value = msg[0].buf[0];/* register */ 1378c2ecf20Sopenharmony_ci for (i = 0; i < msg[1].len; i++) { 1388c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xb5, value + i, 0, 1398c2ecf20Sopenharmony_ci buf6, 2, DW210X_READ_MSG); 1408c2ecf20Sopenharmony_ci msg[1].buf[i] = buf6[0]; 1418c2ecf20Sopenharmony_ci } 1428c2ecf20Sopenharmony_ci break; 1438c2ecf20Sopenharmony_ci case 1: 1448c2ecf20Sopenharmony_ci switch (msg[0].addr) { 1458c2ecf20Sopenharmony_ci case 0x68: 1468c2ecf20Sopenharmony_ci if (msg[0].len < 2) { 1478c2ecf20Sopenharmony_ci num = -EOPNOTSUPP; 1488c2ecf20Sopenharmony_ci break; 1498c2ecf20Sopenharmony_ci } 1508c2ecf20Sopenharmony_ci /* write to stv0299 register */ 1518c2ecf20Sopenharmony_ci buf6[0] = 0x2a; 1528c2ecf20Sopenharmony_ci buf6[1] = msg[0].buf[0]; 1538c2ecf20Sopenharmony_ci buf6[2] = msg[0].buf[1]; 1548c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xb2, 0, 0, 1558c2ecf20Sopenharmony_ci buf6, 3, DW210X_WRITE_MSG); 1568c2ecf20Sopenharmony_ci break; 1578c2ecf20Sopenharmony_ci case 0x60: 1588c2ecf20Sopenharmony_ci if (msg[0].flags == 0) { 1598c2ecf20Sopenharmony_ci if (msg[0].len < 4) { 1608c2ecf20Sopenharmony_ci num = -EOPNOTSUPP; 1618c2ecf20Sopenharmony_ci break; 1628c2ecf20Sopenharmony_ci } 1638c2ecf20Sopenharmony_ci /* write to tuner pll */ 1648c2ecf20Sopenharmony_ci buf6[0] = 0x2c; 1658c2ecf20Sopenharmony_ci buf6[1] = 5; 1668c2ecf20Sopenharmony_ci buf6[2] = 0xc0; 1678c2ecf20Sopenharmony_ci buf6[3] = msg[0].buf[0]; 1688c2ecf20Sopenharmony_ci buf6[4] = msg[0].buf[1]; 1698c2ecf20Sopenharmony_ci buf6[5] = msg[0].buf[2]; 1708c2ecf20Sopenharmony_ci buf6[6] = msg[0].buf[3]; 1718c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xb2, 0, 0, 1728c2ecf20Sopenharmony_ci buf6, 7, DW210X_WRITE_MSG); 1738c2ecf20Sopenharmony_ci } else { 1748c2ecf20Sopenharmony_ci if (msg[0].len < 1) { 1758c2ecf20Sopenharmony_ci num = -EOPNOTSUPP; 1768c2ecf20Sopenharmony_ci break; 1778c2ecf20Sopenharmony_ci } 1788c2ecf20Sopenharmony_ci /* read from tuner */ 1798c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xb5, 0, 0, 1808c2ecf20Sopenharmony_ci buf6, 1, DW210X_READ_MSG); 1818c2ecf20Sopenharmony_ci msg[0].buf[0] = buf6[0]; 1828c2ecf20Sopenharmony_ci } 1838c2ecf20Sopenharmony_ci break; 1848c2ecf20Sopenharmony_ci case (DW2102_RC_QUERY): 1858c2ecf20Sopenharmony_ci if (msg[0].len < 2) { 1868c2ecf20Sopenharmony_ci num = -EOPNOTSUPP; 1878c2ecf20Sopenharmony_ci break; 1888c2ecf20Sopenharmony_ci } 1898c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xb8, 0, 0, 1908c2ecf20Sopenharmony_ci buf6, 2, DW210X_READ_MSG); 1918c2ecf20Sopenharmony_ci msg[0].buf[0] = buf6[0]; 1928c2ecf20Sopenharmony_ci msg[0].buf[1] = buf6[1]; 1938c2ecf20Sopenharmony_ci break; 1948c2ecf20Sopenharmony_ci case (DW2102_VOLTAGE_CTRL): 1958c2ecf20Sopenharmony_ci if (msg[0].len < 1) { 1968c2ecf20Sopenharmony_ci num = -EOPNOTSUPP; 1978c2ecf20Sopenharmony_ci break; 1988c2ecf20Sopenharmony_ci } 1998c2ecf20Sopenharmony_ci buf6[0] = 0x30; 2008c2ecf20Sopenharmony_ci buf6[1] = msg[0].buf[0]; 2018c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xb2, 0, 0, 2028c2ecf20Sopenharmony_ci buf6, 2, DW210X_WRITE_MSG); 2038c2ecf20Sopenharmony_ci break; 2048c2ecf20Sopenharmony_ci } 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci break; 2078c2ecf20Sopenharmony_ci } 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 2108c2ecf20Sopenharmony_ci return num; 2118c2ecf20Sopenharmony_ci} 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_cistatic int dw2102_serit_i2c_transfer(struct i2c_adapter *adap, 2148c2ecf20Sopenharmony_ci struct i2c_msg msg[], int num) 2158c2ecf20Sopenharmony_ci{ 2168c2ecf20Sopenharmony_ci struct dvb_usb_device *d = i2c_get_adapdata(adap); 2178c2ecf20Sopenharmony_ci u8 buf6[] = {0, 0, 0, 0, 0, 0, 0}; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci if (!d) 2208c2ecf20Sopenharmony_ci return -ENODEV; 2218c2ecf20Sopenharmony_ci if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 2228c2ecf20Sopenharmony_ci return -EAGAIN; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci switch (num) { 2258c2ecf20Sopenharmony_ci case 2: 2268c2ecf20Sopenharmony_ci if (msg[0].len != 1) { 2278c2ecf20Sopenharmony_ci warn("i2c rd: len=%d is not 1!\n", 2288c2ecf20Sopenharmony_ci msg[0].len); 2298c2ecf20Sopenharmony_ci num = -EOPNOTSUPP; 2308c2ecf20Sopenharmony_ci break; 2318c2ecf20Sopenharmony_ci } 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci if (2 + msg[1].len > sizeof(buf6)) { 2348c2ecf20Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", 2358c2ecf20Sopenharmony_ci msg[1].len); 2368c2ecf20Sopenharmony_ci num = -EOPNOTSUPP; 2378c2ecf20Sopenharmony_ci break; 2388c2ecf20Sopenharmony_ci } 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci /* read si2109 register by number */ 2418c2ecf20Sopenharmony_ci buf6[0] = msg[0].addr << 1; 2428c2ecf20Sopenharmony_ci buf6[1] = msg[0].len; 2438c2ecf20Sopenharmony_ci buf6[2] = msg[0].buf[0]; 2448c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, 2458c2ecf20Sopenharmony_ci buf6, msg[0].len + 2, DW210X_WRITE_MSG); 2468c2ecf20Sopenharmony_ci /* read si2109 register */ 2478c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xc3, 0xd0, 0, 2488c2ecf20Sopenharmony_ci buf6, msg[1].len + 2, DW210X_READ_MSG); 2498c2ecf20Sopenharmony_ci memcpy(msg[1].buf, buf6 + 2, msg[1].len); 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci break; 2528c2ecf20Sopenharmony_ci case 1: 2538c2ecf20Sopenharmony_ci switch (msg[0].addr) { 2548c2ecf20Sopenharmony_ci case 0x68: 2558c2ecf20Sopenharmony_ci if (2 + msg[0].len > sizeof(buf6)) { 2568c2ecf20Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 2578c2ecf20Sopenharmony_ci msg[0].len); 2588c2ecf20Sopenharmony_ci num = -EOPNOTSUPP; 2598c2ecf20Sopenharmony_ci break; 2608c2ecf20Sopenharmony_ci } 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci /* write to si2109 register */ 2638c2ecf20Sopenharmony_ci buf6[0] = msg[0].addr << 1; 2648c2ecf20Sopenharmony_ci buf6[1] = msg[0].len; 2658c2ecf20Sopenharmony_ci memcpy(buf6 + 2, msg[0].buf, msg[0].len); 2668c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6, 2678c2ecf20Sopenharmony_ci msg[0].len + 2, DW210X_WRITE_MSG); 2688c2ecf20Sopenharmony_ci break; 2698c2ecf20Sopenharmony_ci case(DW2102_RC_QUERY): 2708c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xb8, 0, 0, 2718c2ecf20Sopenharmony_ci buf6, 2, DW210X_READ_MSG); 2728c2ecf20Sopenharmony_ci msg[0].buf[0] = buf6[0]; 2738c2ecf20Sopenharmony_ci msg[0].buf[1] = buf6[1]; 2748c2ecf20Sopenharmony_ci break; 2758c2ecf20Sopenharmony_ci case(DW2102_VOLTAGE_CTRL): 2768c2ecf20Sopenharmony_ci buf6[0] = 0x30; 2778c2ecf20Sopenharmony_ci buf6[1] = msg[0].buf[0]; 2788c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xb2, 0, 0, 2798c2ecf20Sopenharmony_ci buf6, 2, DW210X_WRITE_MSG); 2808c2ecf20Sopenharmony_ci break; 2818c2ecf20Sopenharmony_ci } 2828c2ecf20Sopenharmony_ci break; 2838c2ecf20Sopenharmony_ci } 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 2868c2ecf20Sopenharmony_ci return num; 2878c2ecf20Sopenharmony_ci} 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_cistatic int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) 2908c2ecf20Sopenharmony_ci{ 2918c2ecf20Sopenharmony_ci struct dvb_usb_device *d = i2c_get_adapdata(adap); 2928c2ecf20Sopenharmony_ci int ret; 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci if (!d) 2958c2ecf20Sopenharmony_ci return -ENODEV; 2968c2ecf20Sopenharmony_ci if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 2978c2ecf20Sopenharmony_ci return -EAGAIN; 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci switch (num) { 3008c2ecf20Sopenharmony_ci case 2: { 3018c2ecf20Sopenharmony_ci /* read */ 3028c2ecf20Sopenharmony_ci /* first write first register number */ 3038c2ecf20Sopenharmony_ci u8 ibuf[MAX_XFER_SIZE], obuf[3]; 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci if (2 + msg[0].len != sizeof(obuf)) { 3068c2ecf20Sopenharmony_ci warn("i2c rd: len=%d is not 1!\n", 3078c2ecf20Sopenharmony_ci msg[0].len); 3088c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 3098c2ecf20Sopenharmony_ci goto unlock; 3108c2ecf20Sopenharmony_ci } 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci if (2 + msg[1].len > sizeof(ibuf)) { 3138c2ecf20Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", 3148c2ecf20Sopenharmony_ci msg[1].len); 3158c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 3168c2ecf20Sopenharmony_ci goto unlock; 3178c2ecf20Sopenharmony_ci } 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ci obuf[0] = msg[0].addr << 1; 3208c2ecf20Sopenharmony_ci obuf[1] = msg[0].len; 3218c2ecf20Sopenharmony_ci obuf[2] = msg[0].buf[0]; 3228c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, 3238c2ecf20Sopenharmony_ci obuf, msg[0].len + 2, DW210X_WRITE_MSG); 3248c2ecf20Sopenharmony_ci /* second read registers */ 3258c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0, 3268c2ecf20Sopenharmony_ci ibuf, msg[1].len + 2, DW210X_READ_MSG); 3278c2ecf20Sopenharmony_ci memcpy(msg[1].buf, ibuf + 2, msg[1].len); 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci break; 3308c2ecf20Sopenharmony_ci } 3318c2ecf20Sopenharmony_ci case 1: 3328c2ecf20Sopenharmony_ci switch (msg[0].addr) { 3338c2ecf20Sopenharmony_ci case 0x68: { 3348c2ecf20Sopenharmony_ci /* write to register */ 3358c2ecf20Sopenharmony_ci u8 obuf[MAX_XFER_SIZE]; 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci if (2 + msg[0].len > sizeof(obuf)) { 3388c2ecf20Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 3398c2ecf20Sopenharmony_ci msg[1].len); 3408c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 3418c2ecf20Sopenharmony_ci goto unlock; 3428c2ecf20Sopenharmony_ci } 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci obuf[0] = msg[0].addr << 1; 3458c2ecf20Sopenharmony_ci obuf[1] = msg[0].len; 3468c2ecf20Sopenharmony_ci memcpy(obuf + 2, msg[0].buf, msg[0].len); 3478c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, 3488c2ecf20Sopenharmony_ci obuf, msg[0].len + 2, DW210X_WRITE_MSG); 3498c2ecf20Sopenharmony_ci break; 3508c2ecf20Sopenharmony_ci } 3518c2ecf20Sopenharmony_ci case 0x61: { 3528c2ecf20Sopenharmony_ci /* write to tuner */ 3538c2ecf20Sopenharmony_ci u8 obuf[MAX_XFER_SIZE]; 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci if (2 + msg[0].len > sizeof(obuf)) { 3568c2ecf20Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 3578c2ecf20Sopenharmony_ci msg[1].len); 3588c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 3598c2ecf20Sopenharmony_ci goto unlock; 3608c2ecf20Sopenharmony_ci } 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci obuf[0] = msg[0].addr << 1; 3638c2ecf20Sopenharmony_ci obuf[1] = msg[0].len; 3648c2ecf20Sopenharmony_ci memcpy(obuf + 2, msg[0].buf, msg[0].len); 3658c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, 3668c2ecf20Sopenharmony_ci obuf, msg[0].len + 2, DW210X_WRITE_MSG); 3678c2ecf20Sopenharmony_ci break; 3688c2ecf20Sopenharmony_ci } 3698c2ecf20Sopenharmony_ci case(DW2102_RC_QUERY): { 3708c2ecf20Sopenharmony_ci u8 ibuf[2]; 3718c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xb8, 0, 0, 3728c2ecf20Sopenharmony_ci ibuf, 2, DW210X_READ_MSG); 3738c2ecf20Sopenharmony_ci memcpy(msg[0].buf, ibuf , 2); 3748c2ecf20Sopenharmony_ci break; 3758c2ecf20Sopenharmony_ci } 3768c2ecf20Sopenharmony_ci case(DW2102_VOLTAGE_CTRL): { 3778c2ecf20Sopenharmony_ci u8 obuf[2]; 3788c2ecf20Sopenharmony_ci obuf[0] = 0x30; 3798c2ecf20Sopenharmony_ci obuf[1] = msg[0].buf[0]; 3808c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xb2, 0, 0, 3818c2ecf20Sopenharmony_ci obuf, 2, DW210X_WRITE_MSG); 3828c2ecf20Sopenharmony_ci break; 3838c2ecf20Sopenharmony_ci } 3848c2ecf20Sopenharmony_ci } 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci break; 3878c2ecf20Sopenharmony_ci } 3888c2ecf20Sopenharmony_ci ret = num; 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ciunlock: 3918c2ecf20Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 3928c2ecf20Sopenharmony_ci return ret; 3938c2ecf20Sopenharmony_ci} 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_cistatic int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) 3968c2ecf20Sopenharmony_ci{ 3978c2ecf20Sopenharmony_ci struct dvb_usb_device *d = i2c_get_adapdata(adap); 3988c2ecf20Sopenharmony_ci int len, i, j, ret; 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci if (!d) 4018c2ecf20Sopenharmony_ci return -ENODEV; 4028c2ecf20Sopenharmony_ci if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 4038c2ecf20Sopenharmony_ci return -EAGAIN; 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_ci for (j = 0; j < num; j++) { 4068c2ecf20Sopenharmony_ci switch (msg[j].addr) { 4078c2ecf20Sopenharmony_ci case(DW2102_RC_QUERY): { 4088c2ecf20Sopenharmony_ci u8 ibuf[2]; 4098c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xb8, 0, 0, 4108c2ecf20Sopenharmony_ci ibuf, 2, DW210X_READ_MSG); 4118c2ecf20Sopenharmony_ci memcpy(msg[j].buf, ibuf , 2); 4128c2ecf20Sopenharmony_ci break; 4138c2ecf20Sopenharmony_ci } 4148c2ecf20Sopenharmony_ci case(DW2102_VOLTAGE_CTRL): { 4158c2ecf20Sopenharmony_ci u8 obuf[2]; 4168c2ecf20Sopenharmony_ci obuf[0] = 0x30; 4178c2ecf20Sopenharmony_ci obuf[1] = msg[j].buf[0]; 4188c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xb2, 0, 0, 4198c2ecf20Sopenharmony_ci obuf, 2, DW210X_WRITE_MSG); 4208c2ecf20Sopenharmony_ci break; 4218c2ecf20Sopenharmony_ci } 4228c2ecf20Sopenharmony_ci /*case 0x55: cx24116 4238c2ecf20Sopenharmony_ci case 0x6a: stv0903 4248c2ecf20Sopenharmony_ci case 0x68: ds3000, stv0903 4258c2ecf20Sopenharmony_ci case 0x60: ts2020, stv6110, stb6100 */ 4268c2ecf20Sopenharmony_ci default: { 4278c2ecf20Sopenharmony_ci if (msg[j].flags == I2C_M_RD) { 4288c2ecf20Sopenharmony_ci /* read registers */ 4298c2ecf20Sopenharmony_ci u8 ibuf[MAX_XFER_SIZE]; 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci if (2 + msg[j].len > sizeof(ibuf)) { 4328c2ecf20Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", 4338c2ecf20Sopenharmony_ci msg[j].len); 4348c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 4358c2ecf20Sopenharmony_ci goto unlock; 4368c2ecf20Sopenharmony_ci } 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xc3, 4398c2ecf20Sopenharmony_ci (msg[j].addr << 1) + 1, 0, 4408c2ecf20Sopenharmony_ci ibuf, msg[j].len + 2, 4418c2ecf20Sopenharmony_ci DW210X_READ_MSG); 4428c2ecf20Sopenharmony_ci memcpy(msg[j].buf, ibuf + 2, msg[j].len); 4438c2ecf20Sopenharmony_ci mdelay(10); 4448c2ecf20Sopenharmony_ci } else if (((msg[j].buf[0] == 0xb0) && 4458c2ecf20Sopenharmony_ci (msg[j].addr == 0x68)) || 4468c2ecf20Sopenharmony_ci ((msg[j].buf[0] == 0xf7) && 4478c2ecf20Sopenharmony_ci (msg[j].addr == 0x55))) { 4488c2ecf20Sopenharmony_ci /* write firmware */ 4498c2ecf20Sopenharmony_ci u8 obuf[19]; 4508c2ecf20Sopenharmony_ci obuf[0] = msg[j].addr << 1; 4518c2ecf20Sopenharmony_ci obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len); 4528c2ecf20Sopenharmony_ci obuf[2] = msg[j].buf[0]; 4538c2ecf20Sopenharmony_ci len = msg[j].len - 1; 4548c2ecf20Sopenharmony_ci i = 1; 4558c2ecf20Sopenharmony_ci do { 4568c2ecf20Sopenharmony_ci memcpy(obuf + 3, msg[j].buf + i, 4578c2ecf20Sopenharmony_ci (len > 16 ? 16 : len)); 4588c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, 4598c2ecf20Sopenharmony_ci obuf, (len > 16 ? 16 : len) + 3, 4608c2ecf20Sopenharmony_ci DW210X_WRITE_MSG); 4618c2ecf20Sopenharmony_ci i += 16; 4628c2ecf20Sopenharmony_ci len -= 16; 4638c2ecf20Sopenharmony_ci } while (len > 0); 4648c2ecf20Sopenharmony_ci } else { 4658c2ecf20Sopenharmony_ci /* write registers */ 4668c2ecf20Sopenharmony_ci u8 obuf[MAX_XFER_SIZE]; 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_ci if (2 + msg[j].len > sizeof(obuf)) { 4698c2ecf20Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 4708c2ecf20Sopenharmony_ci msg[j].len); 4718c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 4728c2ecf20Sopenharmony_ci goto unlock; 4738c2ecf20Sopenharmony_ci } 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci obuf[0] = msg[j].addr << 1; 4768c2ecf20Sopenharmony_ci obuf[1] = msg[j].len; 4778c2ecf20Sopenharmony_ci memcpy(obuf + 2, msg[j].buf, msg[j].len); 4788c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, 4798c2ecf20Sopenharmony_ci obuf, msg[j].len + 2, 4808c2ecf20Sopenharmony_ci DW210X_WRITE_MSG); 4818c2ecf20Sopenharmony_ci } 4828c2ecf20Sopenharmony_ci break; 4838c2ecf20Sopenharmony_ci } 4848c2ecf20Sopenharmony_ci } 4858c2ecf20Sopenharmony_ci 4868c2ecf20Sopenharmony_ci } 4878c2ecf20Sopenharmony_ci ret = num; 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_ciunlock: 4908c2ecf20Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 4918c2ecf20Sopenharmony_ci return ret; 4928c2ecf20Sopenharmony_ci} 4938c2ecf20Sopenharmony_ci 4948c2ecf20Sopenharmony_cistatic int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], 4958c2ecf20Sopenharmony_ci int num) 4968c2ecf20Sopenharmony_ci{ 4978c2ecf20Sopenharmony_ci struct dvb_usb_device *d = i2c_get_adapdata(adap); 4988c2ecf20Sopenharmony_ci int ret; 4998c2ecf20Sopenharmony_ci int i; 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_ci if (!d) 5028c2ecf20Sopenharmony_ci return -ENODEV; 5038c2ecf20Sopenharmony_ci if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 5048c2ecf20Sopenharmony_ci return -EAGAIN; 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ci switch (num) { 5078c2ecf20Sopenharmony_ci case 2: { 5088c2ecf20Sopenharmony_ci /* read */ 5098c2ecf20Sopenharmony_ci /* first write first register number */ 5108c2ecf20Sopenharmony_ci u8 ibuf[MAX_XFER_SIZE], obuf[3]; 5118c2ecf20Sopenharmony_ci 5128c2ecf20Sopenharmony_ci if (2 + msg[0].len != sizeof(obuf)) { 5138c2ecf20Sopenharmony_ci warn("i2c rd: len=%d is not 1!\n", 5148c2ecf20Sopenharmony_ci msg[0].len); 5158c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 5168c2ecf20Sopenharmony_ci goto unlock; 5178c2ecf20Sopenharmony_ci } 5188c2ecf20Sopenharmony_ci if (2 + msg[1].len > sizeof(ibuf)) { 5198c2ecf20Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", 5208c2ecf20Sopenharmony_ci msg[1].len); 5218c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 5228c2ecf20Sopenharmony_ci goto unlock; 5238c2ecf20Sopenharmony_ci } 5248c2ecf20Sopenharmony_ci obuf[0] = msg[0].addr << 1; 5258c2ecf20Sopenharmony_ci obuf[1] = msg[0].len; 5268c2ecf20Sopenharmony_ci obuf[2] = msg[0].buf[0]; 5278c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, 5288c2ecf20Sopenharmony_ci obuf, msg[0].len + 2, DW210X_WRITE_MSG); 5298c2ecf20Sopenharmony_ci /* second read registers */ 5308c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xc3, 0x19 , 0, 5318c2ecf20Sopenharmony_ci ibuf, msg[1].len + 2, DW210X_READ_MSG); 5328c2ecf20Sopenharmony_ci memcpy(msg[1].buf, ibuf + 2, msg[1].len); 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_ci break; 5358c2ecf20Sopenharmony_ci } 5368c2ecf20Sopenharmony_ci case 1: 5378c2ecf20Sopenharmony_ci switch (msg[0].addr) { 5388c2ecf20Sopenharmony_ci case 0x60: 5398c2ecf20Sopenharmony_ci case 0x0c: { 5408c2ecf20Sopenharmony_ci /* write to register */ 5418c2ecf20Sopenharmony_ci u8 obuf[MAX_XFER_SIZE]; 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_ci if (2 + msg[0].len > sizeof(obuf)) { 5448c2ecf20Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 5458c2ecf20Sopenharmony_ci msg[0].len); 5468c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 5478c2ecf20Sopenharmony_ci goto unlock; 5488c2ecf20Sopenharmony_ci } 5498c2ecf20Sopenharmony_ci obuf[0] = msg[0].addr << 1; 5508c2ecf20Sopenharmony_ci obuf[1] = msg[0].len; 5518c2ecf20Sopenharmony_ci memcpy(obuf + 2, msg[0].buf, msg[0].len); 5528c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xc2, 0, 0, 5538c2ecf20Sopenharmony_ci obuf, msg[0].len + 2, DW210X_WRITE_MSG); 5548c2ecf20Sopenharmony_ci break; 5558c2ecf20Sopenharmony_ci } 5568c2ecf20Sopenharmony_ci case(DW2102_RC_QUERY): { 5578c2ecf20Sopenharmony_ci u8 ibuf[2]; 5588c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xb8, 0, 0, 5598c2ecf20Sopenharmony_ci ibuf, 2, DW210X_READ_MSG); 5608c2ecf20Sopenharmony_ci memcpy(msg[0].buf, ibuf , 2); 5618c2ecf20Sopenharmony_ci break; 5628c2ecf20Sopenharmony_ci } 5638c2ecf20Sopenharmony_ci } 5648c2ecf20Sopenharmony_ci 5658c2ecf20Sopenharmony_ci break; 5668c2ecf20Sopenharmony_ci } 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_ci for (i = 0; i < num; i++) { 5698c2ecf20Sopenharmony_ci deb_xfer("%02x:%02x: %s ", i, msg[i].addr, 5708c2ecf20Sopenharmony_ci msg[i].flags == 0 ? ">>>" : "<<<"); 5718c2ecf20Sopenharmony_ci debug_dump(msg[i].buf, msg[i].len, deb_xfer); 5728c2ecf20Sopenharmony_ci } 5738c2ecf20Sopenharmony_ci ret = num; 5748c2ecf20Sopenharmony_ci 5758c2ecf20Sopenharmony_ciunlock: 5768c2ecf20Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 5778c2ecf20Sopenharmony_ci return ret; 5788c2ecf20Sopenharmony_ci} 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_cistatic int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], 5818c2ecf20Sopenharmony_ci int num) 5828c2ecf20Sopenharmony_ci{ 5838c2ecf20Sopenharmony_ci struct dvb_usb_device *d = i2c_get_adapdata(adap); 5848c2ecf20Sopenharmony_ci struct usb_device *udev; 5858c2ecf20Sopenharmony_ci int len, i, j, ret; 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ci if (!d) 5888c2ecf20Sopenharmony_ci return -ENODEV; 5898c2ecf20Sopenharmony_ci udev = d->udev; 5908c2ecf20Sopenharmony_ci if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 5918c2ecf20Sopenharmony_ci return -EAGAIN; 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_ci for (j = 0; j < num; j++) { 5948c2ecf20Sopenharmony_ci switch (msg[j].addr) { 5958c2ecf20Sopenharmony_ci case (DW2102_RC_QUERY): { 5968c2ecf20Sopenharmony_ci u8 ibuf[5]; 5978c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0xb8, 0, 0, 5988c2ecf20Sopenharmony_ci ibuf, 5, DW210X_READ_MSG); 5998c2ecf20Sopenharmony_ci memcpy(msg[j].buf, ibuf + 3, 2); 6008c2ecf20Sopenharmony_ci break; 6018c2ecf20Sopenharmony_ci } 6028c2ecf20Sopenharmony_ci case (DW2102_VOLTAGE_CTRL): { 6038c2ecf20Sopenharmony_ci u8 obuf[2]; 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ci obuf[0] = 1; 6068c2ecf20Sopenharmony_ci obuf[1] = msg[j].buf[1];/* off-on */ 6078c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0x8a, 0, 0, 6088c2ecf20Sopenharmony_ci obuf, 2, DW210X_WRITE_MSG); 6098c2ecf20Sopenharmony_ci obuf[0] = 3; 6108c2ecf20Sopenharmony_ci obuf[1] = msg[j].buf[0];/* 13v-18v */ 6118c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0x8a, 0, 0, 6128c2ecf20Sopenharmony_ci obuf, 2, DW210X_WRITE_MSG); 6138c2ecf20Sopenharmony_ci break; 6148c2ecf20Sopenharmony_ci } 6158c2ecf20Sopenharmony_ci case (DW2102_LED_CTRL): { 6168c2ecf20Sopenharmony_ci u8 obuf[2]; 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_ci obuf[0] = 5; 6198c2ecf20Sopenharmony_ci obuf[1] = msg[j].buf[0]; 6208c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0x8a, 0, 0, 6218c2ecf20Sopenharmony_ci obuf, 2, DW210X_WRITE_MSG); 6228c2ecf20Sopenharmony_ci break; 6238c2ecf20Sopenharmony_ci } 6248c2ecf20Sopenharmony_ci /*case 0x55: cx24116 6258c2ecf20Sopenharmony_ci case 0x6a: stv0903 6268c2ecf20Sopenharmony_ci case 0x68: ds3000, stv0903, rs2000 6278c2ecf20Sopenharmony_ci case 0x60: ts2020, stv6110, stb6100 6288c2ecf20Sopenharmony_ci case 0xa0: eeprom */ 6298c2ecf20Sopenharmony_ci default: { 6308c2ecf20Sopenharmony_ci if (msg[j].flags == I2C_M_RD) { 6318c2ecf20Sopenharmony_ci /* read registers */ 6328c2ecf20Sopenharmony_ci u8 ibuf[MAX_XFER_SIZE]; 6338c2ecf20Sopenharmony_ci 6348c2ecf20Sopenharmony_ci if (msg[j].len > sizeof(ibuf)) { 6358c2ecf20Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", 6368c2ecf20Sopenharmony_ci msg[j].len); 6378c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 6388c2ecf20Sopenharmony_ci goto unlock; 6398c2ecf20Sopenharmony_ci } 6408c2ecf20Sopenharmony_ci 6418c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0x91, 0, 0, 6428c2ecf20Sopenharmony_ci ibuf, msg[j].len, 6438c2ecf20Sopenharmony_ci DW210X_READ_MSG); 6448c2ecf20Sopenharmony_ci memcpy(msg[j].buf, ibuf, msg[j].len); 6458c2ecf20Sopenharmony_ci break; 6468c2ecf20Sopenharmony_ci } else if ((msg[j].buf[0] == 0xb0) && 6478c2ecf20Sopenharmony_ci (msg[j].addr == 0x68)) { 6488c2ecf20Sopenharmony_ci /* write firmware */ 6498c2ecf20Sopenharmony_ci u8 obuf[19]; 6508c2ecf20Sopenharmony_ci obuf[0] = (msg[j].len > 16 ? 6518c2ecf20Sopenharmony_ci 18 : msg[j].len + 1); 6528c2ecf20Sopenharmony_ci obuf[1] = msg[j].addr << 1; 6538c2ecf20Sopenharmony_ci obuf[2] = msg[j].buf[0]; 6548c2ecf20Sopenharmony_ci len = msg[j].len - 1; 6558c2ecf20Sopenharmony_ci i = 1; 6568c2ecf20Sopenharmony_ci do { 6578c2ecf20Sopenharmony_ci memcpy(obuf + 3, msg[j].buf + i, 6588c2ecf20Sopenharmony_ci (len > 16 ? 16 : len)); 6598c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0x80, 0, 0, 6608c2ecf20Sopenharmony_ci obuf, (len > 16 ? 16 : len) + 3, 6618c2ecf20Sopenharmony_ci DW210X_WRITE_MSG); 6628c2ecf20Sopenharmony_ci i += 16; 6638c2ecf20Sopenharmony_ci len -= 16; 6648c2ecf20Sopenharmony_ci } while (len > 0); 6658c2ecf20Sopenharmony_ci } else if (j < (num - 1)) { 6668c2ecf20Sopenharmony_ci /* write register addr before read */ 6678c2ecf20Sopenharmony_ci u8 obuf[MAX_XFER_SIZE]; 6688c2ecf20Sopenharmony_ci 6698c2ecf20Sopenharmony_ci if (2 + msg[j].len > sizeof(obuf)) { 6708c2ecf20Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 6718c2ecf20Sopenharmony_ci msg[j].len); 6728c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 6738c2ecf20Sopenharmony_ci goto unlock; 6748c2ecf20Sopenharmony_ci } 6758c2ecf20Sopenharmony_ci 6768c2ecf20Sopenharmony_ci obuf[0] = msg[j + 1].len; 6778c2ecf20Sopenharmony_ci obuf[1] = (msg[j].addr << 1); 6788c2ecf20Sopenharmony_ci memcpy(obuf + 2, msg[j].buf, msg[j].len); 6798c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 6808c2ecf20Sopenharmony_ci le16_to_cpu(udev->descriptor.idProduct) == 6818c2ecf20Sopenharmony_ci 0x7500 ? 0x92 : 0x90, 0, 0, 6828c2ecf20Sopenharmony_ci obuf, msg[j].len + 2, 6838c2ecf20Sopenharmony_ci DW210X_WRITE_MSG); 6848c2ecf20Sopenharmony_ci break; 6858c2ecf20Sopenharmony_ci } else { 6868c2ecf20Sopenharmony_ci /* write registers */ 6878c2ecf20Sopenharmony_ci u8 obuf[MAX_XFER_SIZE]; 6888c2ecf20Sopenharmony_ci 6898c2ecf20Sopenharmony_ci if (2 + msg[j].len > sizeof(obuf)) { 6908c2ecf20Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 6918c2ecf20Sopenharmony_ci msg[j].len); 6928c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 6938c2ecf20Sopenharmony_ci goto unlock; 6948c2ecf20Sopenharmony_ci } 6958c2ecf20Sopenharmony_ci obuf[0] = msg[j].len + 1; 6968c2ecf20Sopenharmony_ci obuf[1] = (msg[j].addr << 1); 6978c2ecf20Sopenharmony_ci memcpy(obuf + 2, msg[j].buf, msg[j].len); 6988c2ecf20Sopenharmony_ci dw210x_op_rw(d->udev, 0x80, 0, 0, 6998c2ecf20Sopenharmony_ci obuf, msg[j].len + 2, 7008c2ecf20Sopenharmony_ci DW210X_WRITE_MSG); 7018c2ecf20Sopenharmony_ci break; 7028c2ecf20Sopenharmony_ci } 7038c2ecf20Sopenharmony_ci break; 7048c2ecf20Sopenharmony_ci } 7058c2ecf20Sopenharmony_ci } 7068c2ecf20Sopenharmony_ci } 7078c2ecf20Sopenharmony_ci ret = num; 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_ciunlock: 7108c2ecf20Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 7118c2ecf20Sopenharmony_ci return ret; 7128c2ecf20Sopenharmony_ci} 7138c2ecf20Sopenharmony_ci 7148c2ecf20Sopenharmony_cistatic int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], 7158c2ecf20Sopenharmony_ci int num) 7168c2ecf20Sopenharmony_ci{ 7178c2ecf20Sopenharmony_ci struct dvb_usb_device *d = i2c_get_adapdata(adap); 7188c2ecf20Sopenharmony_ci struct dw2102_state *state; 7198c2ecf20Sopenharmony_ci 7208c2ecf20Sopenharmony_ci if (!d) 7218c2ecf20Sopenharmony_ci return -ENODEV; 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci state = d->priv; 7248c2ecf20Sopenharmony_ci 7258c2ecf20Sopenharmony_ci if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 7268c2ecf20Sopenharmony_ci return -EAGAIN; 7278c2ecf20Sopenharmony_ci if (mutex_lock_interruptible(&d->data_mutex) < 0) { 7288c2ecf20Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 7298c2ecf20Sopenharmony_ci return -EAGAIN; 7308c2ecf20Sopenharmony_ci } 7318c2ecf20Sopenharmony_ci 7328c2ecf20Sopenharmony_ci switch (num) { 7338c2ecf20Sopenharmony_ci case 1: 7348c2ecf20Sopenharmony_ci switch (msg[0].addr) { 7358c2ecf20Sopenharmony_ci case SU3000_STREAM_CTRL: 7368c2ecf20Sopenharmony_ci state->data[0] = msg[0].buf[0] + 0x36; 7378c2ecf20Sopenharmony_ci state->data[1] = 3; 7388c2ecf20Sopenharmony_ci state->data[2] = 0; 7398c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, 7408c2ecf20Sopenharmony_ci state->data, 0, 0) < 0) 7418c2ecf20Sopenharmony_ci err("i2c transfer failed."); 7428c2ecf20Sopenharmony_ci break; 7438c2ecf20Sopenharmony_ci case DW2102_RC_QUERY: 7448c2ecf20Sopenharmony_ci state->data[0] = 0x10; 7458c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 1, 7468c2ecf20Sopenharmony_ci state->data, 2, 0) < 0) 7478c2ecf20Sopenharmony_ci err("i2c transfer failed."); 7488c2ecf20Sopenharmony_ci msg[0].buf[1] = state->data[0]; 7498c2ecf20Sopenharmony_ci msg[0].buf[0] = state->data[1]; 7508c2ecf20Sopenharmony_ci break; 7518c2ecf20Sopenharmony_ci default: 7528c2ecf20Sopenharmony_ci if (3 + msg[0].len > sizeof(state->data)) { 7538c2ecf20Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 7548c2ecf20Sopenharmony_ci msg[0].len); 7558c2ecf20Sopenharmony_ci num = -EOPNOTSUPP; 7568c2ecf20Sopenharmony_ci break; 7578c2ecf20Sopenharmony_ci } 7588c2ecf20Sopenharmony_ci 7598c2ecf20Sopenharmony_ci /* always i2c write*/ 7608c2ecf20Sopenharmony_ci state->data[0] = 0x08; 7618c2ecf20Sopenharmony_ci state->data[1] = msg[0].addr; 7628c2ecf20Sopenharmony_ci state->data[2] = msg[0].len; 7638c2ecf20Sopenharmony_ci 7648c2ecf20Sopenharmony_ci memcpy(&state->data[3], msg[0].buf, msg[0].len); 7658c2ecf20Sopenharmony_ci 7668c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, msg[0].len + 3, 7678c2ecf20Sopenharmony_ci state->data, 1, 0) < 0) 7688c2ecf20Sopenharmony_ci err("i2c transfer failed."); 7698c2ecf20Sopenharmony_ci 7708c2ecf20Sopenharmony_ci } 7718c2ecf20Sopenharmony_ci break; 7728c2ecf20Sopenharmony_ci case 2: 7738c2ecf20Sopenharmony_ci /* always i2c read */ 7748c2ecf20Sopenharmony_ci if (4 + msg[0].len > sizeof(state->data)) { 7758c2ecf20Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", 7768c2ecf20Sopenharmony_ci msg[0].len); 7778c2ecf20Sopenharmony_ci num = -EOPNOTSUPP; 7788c2ecf20Sopenharmony_ci break; 7798c2ecf20Sopenharmony_ci } 7808c2ecf20Sopenharmony_ci if (1 + msg[1].len > sizeof(state->data)) { 7818c2ecf20Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", 7828c2ecf20Sopenharmony_ci msg[1].len); 7838c2ecf20Sopenharmony_ci num = -EOPNOTSUPP; 7848c2ecf20Sopenharmony_ci break; 7858c2ecf20Sopenharmony_ci } 7868c2ecf20Sopenharmony_ci 7878c2ecf20Sopenharmony_ci state->data[0] = 0x09; 7888c2ecf20Sopenharmony_ci state->data[1] = msg[0].len; 7898c2ecf20Sopenharmony_ci state->data[2] = msg[1].len; 7908c2ecf20Sopenharmony_ci state->data[3] = msg[0].addr; 7918c2ecf20Sopenharmony_ci memcpy(&state->data[4], msg[0].buf, msg[0].len); 7928c2ecf20Sopenharmony_ci 7938c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, msg[0].len + 4, 7948c2ecf20Sopenharmony_ci state->data, msg[1].len + 1, 0) < 0) 7958c2ecf20Sopenharmony_ci err("i2c transfer failed."); 7968c2ecf20Sopenharmony_ci 7978c2ecf20Sopenharmony_ci memcpy(msg[1].buf, &state->data[1], msg[1].len); 7988c2ecf20Sopenharmony_ci break; 7998c2ecf20Sopenharmony_ci default: 8008c2ecf20Sopenharmony_ci warn("more than 2 i2c messages at a time is not handled yet."); 8018c2ecf20Sopenharmony_ci break; 8028c2ecf20Sopenharmony_ci } 8038c2ecf20Sopenharmony_ci mutex_unlock(&d->data_mutex); 8048c2ecf20Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 8058c2ecf20Sopenharmony_ci return num; 8068c2ecf20Sopenharmony_ci} 8078c2ecf20Sopenharmony_ci 8088c2ecf20Sopenharmony_cistatic u32 dw210x_i2c_func(struct i2c_adapter *adapter) 8098c2ecf20Sopenharmony_ci{ 8108c2ecf20Sopenharmony_ci return I2C_FUNC_I2C; 8118c2ecf20Sopenharmony_ci} 8128c2ecf20Sopenharmony_ci 8138c2ecf20Sopenharmony_cistatic struct i2c_algorithm dw2102_i2c_algo = { 8148c2ecf20Sopenharmony_ci .master_xfer = dw2102_i2c_transfer, 8158c2ecf20Sopenharmony_ci .functionality = dw210x_i2c_func, 8168c2ecf20Sopenharmony_ci}; 8178c2ecf20Sopenharmony_ci 8188c2ecf20Sopenharmony_cistatic struct i2c_algorithm dw2102_serit_i2c_algo = { 8198c2ecf20Sopenharmony_ci .master_xfer = dw2102_serit_i2c_transfer, 8208c2ecf20Sopenharmony_ci .functionality = dw210x_i2c_func, 8218c2ecf20Sopenharmony_ci}; 8228c2ecf20Sopenharmony_ci 8238c2ecf20Sopenharmony_cistatic struct i2c_algorithm dw2102_earda_i2c_algo = { 8248c2ecf20Sopenharmony_ci .master_xfer = dw2102_earda_i2c_transfer, 8258c2ecf20Sopenharmony_ci .functionality = dw210x_i2c_func, 8268c2ecf20Sopenharmony_ci}; 8278c2ecf20Sopenharmony_ci 8288c2ecf20Sopenharmony_cistatic struct i2c_algorithm dw2104_i2c_algo = { 8298c2ecf20Sopenharmony_ci .master_xfer = dw2104_i2c_transfer, 8308c2ecf20Sopenharmony_ci .functionality = dw210x_i2c_func, 8318c2ecf20Sopenharmony_ci}; 8328c2ecf20Sopenharmony_ci 8338c2ecf20Sopenharmony_cistatic struct i2c_algorithm dw3101_i2c_algo = { 8348c2ecf20Sopenharmony_ci .master_xfer = dw3101_i2c_transfer, 8358c2ecf20Sopenharmony_ci .functionality = dw210x_i2c_func, 8368c2ecf20Sopenharmony_ci}; 8378c2ecf20Sopenharmony_ci 8388c2ecf20Sopenharmony_cistatic struct i2c_algorithm s6x0_i2c_algo = { 8398c2ecf20Sopenharmony_ci .master_xfer = s6x0_i2c_transfer, 8408c2ecf20Sopenharmony_ci .functionality = dw210x_i2c_func, 8418c2ecf20Sopenharmony_ci}; 8428c2ecf20Sopenharmony_ci 8438c2ecf20Sopenharmony_cistatic struct i2c_algorithm su3000_i2c_algo = { 8448c2ecf20Sopenharmony_ci .master_xfer = su3000_i2c_transfer, 8458c2ecf20Sopenharmony_ci .functionality = dw210x_i2c_func, 8468c2ecf20Sopenharmony_ci}; 8478c2ecf20Sopenharmony_ci 8488c2ecf20Sopenharmony_cistatic int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) 8498c2ecf20Sopenharmony_ci{ 8508c2ecf20Sopenharmony_ci int i; 8518c2ecf20Sopenharmony_ci u8 ibuf[] = {0, 0}; 8528c2ecf20Sopenharmony_ci u8 eeprom[256], eepromline[16]; 8538c2ecf20Sopenharmony_ci 8548c2ecf20Sopenharmony_ci for (i = 0; i < 256; i++) { 8558c2ecf20Sopenharmony_ci if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) { 8568c2ecf20Sopenharmony_ci err("read eeprom failed."); 8578c2ecf20Sopenharmony_ci return -1; 8588c2ecf20Sopenharmony_ci } else { 8598c2ecf20Sopenharmony_ci eepromline[i%16] = ibuf[0]; 8608c2ecf20Sopenharmony_ci eeprom[i] = ibuf[0]; 8618c2ecf20Sopenharmony_ci } 8628c2ecf20Sopenharmony_ci if ((i % 16) == 15) { 8638c2ecf20Sopenharmony_ci deb_xfer("%02x: ", i - 15); 8648c2ecf20Sopenharmony_ci debug_dump(eepromline, 16, deb_xfer); 8658c2ecf20Sopenharmony_ci } 8668c2ecf20Sopenharmony_ci } 8678c2ecf20Sopenharmony_ci 8688c2ecf20Sopenharmony_ci memcpy(mac, eeprom + 8, 6); 8698c2ecf20Sopenharmony_ci return 0; 8708c2ecf20Sopenharmony_ci}; 8718c2ecf20Sopenharmony_ci 8728c2ecf20Sopenharmony_cistatic int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) 8738c2ecf20Sopenharmony_ci{ 8748c2ecf20Sopenharmony_ci int i, ret; 8758c2ecf20Sopenharmony_ci u8 ibuf[] = { 0 }, obuf[] = { 0 }; 8768c2ecf20Sopenharmony_ci u8 eeprom[256], eepromline[16]; 8778c2ecf20Sopenharmony_ci struct i2c_msg msg[] = { 8788c2ecf20Sopenharmony_ci { 8798c2ecf20Sopenharmony_ci .addr = 0xa0 >> 1, 8808c2ecf20Sopenharmony_ci .flags = 0, 8818c2ecf20Sopenharmony_ci .buf = obuf, 8828c2ecf20Sopenharmony_ci .len = 1, 8838c2ecf20Sopenharmony_ci }, { 8848c2ecf20Sopenharmony_ci .addr = 0xa0 >> 1, 8858c2ecf20Sopenharmony_ci .flags = I2C_M_RD, 8868c2ecf20Sopenharmony_ci .buf = ibuf, 8878c2ecf20Sopenharmony_ci .len = 1, 8888c2ecf20Sopenharmony_ci } 8898c2ecf20Sopenharmony_ci }; 8908c2ecf20Sopenharmony_ci 8918c2ecf20Sopenharmony_ci for (i = 0; i < 256; i++) { 8928c2ecf20Sopenharmony_ci obuf[0] = i; 8938c2ecf20Sopenharmony_ci ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2); 8948c2ecf20Sopenharmony_ci if (ret != 2) { 8958c2ecf20Sopenharmony_ci err("read eeprom failed."); 8968c2ecf20Sopenharmony_ci return -1; 8978c2ecf20Sopenharmony_ci } else { 8988c2ecf20Sopenharmony_ci eepromline[i % 16] = ibuf[0]; 8998c2ecf20Sopenharmony_ci eeprom[i] = ibuf[0]; 9008c2ecf20Sopenharmony_ci } 9018c2ecf20Sopenharmony_ci 9028c2ecf20Sopenharmony_ci if ((i % 16) == 15) { 9038c2ecf20Sopenharmony_ci deb_xfer("%02x: ", i - 15); 9048c2ecf20Sopenharmony_ci debug_dump(eepromline, 16, deb_xfer); 9058c2ecf20Sopenharmony_ci } 9068c2ecf20Sopenharmony_ci } 9078c2ecf20Sopenharmony_ci 9088c2ecf20Sopenharmony_ci memcpy(mac, eeprom + 16, 6); 9098c2ecf20Sopenharmony_ci return 0; 9108c2ecf20Sopenharmony_ci}; 9118c2ecf20Sopenharmony_ci 9128c2ecf20Sopenharmony_cistatic int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 9138c2ecf20Sopenharmony_ci{ 9148c2ecf20Sopenharmony_ci static u8 command_start[] = {0x00}; 9158c2ecf20Sopenharmony_ci static u8 command_stop[] = {0x01}; 9168c2ecf20Sopenharmony_ci struct i2c_msg msg = { 9178c2ecf20Sopenharmony_ci .addr = SU3000_STREAM_CTRL, 9188c2ecf20Sopenharmony_ci .flags = 0, 9198c2ecf20Sopenharmony_ci .buf = onoff ? command_start : command_stop, 9208c2ecf20Sopenharmony_ci .len = 1 9218c2ecf20Sopenharmony_ci }; 9228c2ecf20Sopenharmony_ci 9238c2ecf20Sopenharmony_ci i2c_transfer(&adap->dev->i2c_adap, &msg, 1); 9248c2ecf20Sopenharmony_ci 9258c2ecf20Sopenharmony_ci return 0; 9268c2ecf20Sopenharmony_ci} 9278c2ecf20Sopenharmony_ci 9288c2ecf20Sopenharmony_cistatic int su3000_power_ctrl(struct dvb_usb_device *d, int i) 9298c2ecf20Sopenharmony_ci{ 9308c2ecf20Sopenharmony_ci struct dw2102_state *state = (struct dw2102_state *)d->priv; 9318c2ecf20Sopenharmony_ci int ret = 0; 9328c2ecf20Sopenharmony_ci 9338c2ecf20Sopenharmony_ci info("%s: %d, initialized %d", __func__, i, state->initialized); 9348c2ecf20Sopenharmony_ci 9358c2ecf20Sopenharmony_ci if (i && !state->initialized) { 9368c2ecf20Sopenharmony_ci mutex_lock(&d->data_mutex); 9378c2ecf20Sopenharmony_ci 9388c2ecf20Sopenharmony_ci state->data[0] = 0xde; 9398c2ecf20Sopenharmony_ci state->data[1] = 0; 9408c2ecf20Sopenharmony_ci 9418c2ecf20Sopenharmony_ci state->initialized = 1; 9428c2ecf20Sopenharmony_ci /* reset board */ 9438c2ecf20Sopenharmony_ci ret = dvb_usb_generic_rw(d, state->data, 2, NULL, 0, 0); 9448c2ecf20Sopenharmony_ci mutex_unlock(&d->data_mutex); 9458c2ecf20Sopenharmony_ci } 9468c2ecf20Sopenharmony_ci 9478c2ecf20Sopenharmony_ci return ret; 9488c2ecf20Sopenharmony_ci} 9498c2ecf20Sopenharmony_ci 9508c2ecf20Sopenharmony_cistatic int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) 9518c2ecf20Sopenharmony_ci{ 9528c2ecf20Sopenharmony_ci int i; 9538c2ecf20Sopenharmony_ci u8 obuf[] = { 0x1f, 0xf0 }; 9548c2ecf20Sopenharmony_ci u8 ibuf[] = { 0 }; 9558c2ecf20Sopenharmony_ci struct i2c_msg msg[] = { 9568c2ecf20Sopenharmony_ci { 9578c2ecf20Sopenharmony_ci .addr = 0x51, 9588c2ecf20Sopenharmony_ci .flags = 0, 9598c2ecf20Sopenharmony_ci .buf = obuf, 9608c2ecf20Sopenharmony_ci .len = 2, 9618c2ecf20Sopenharmony_ci }, { 9628c2ecf20Sopenharmony_ci .addr = 0x51, 9638c2ecf20Sopenharmony_ci .flags = I2C_M_RD, 9648c2ecf20Sopenharmony_ci .buf = ibuf, 9658c2ecf20Sopenharmony_ci .len = 1, 9668c2ecf20Sopenharmony_ci 9678c2ecf20Sopenharmony_ci } 9688c2ecf20Sopenharmony_ci }; 9698c2ecf20Sopenharmony_ci 9708c2ecf20Sopenharmony_ci for (i = 0; i < 6; i++) { 9718c2ecf20Sopenharmony_ci obuf[1] = 0xf0 + i; 9728c2ecf20Sopenharmony_ci if (i2c_transfer(&d->i2c_adap, msg, 2) != 2) 9738c2ecf20Sopenharmony_ci return -1; 9748c2ecf20Sopenharmony_ci else 9758c2ecf20Sopenharmony_ci mac[i] = ibuf[0]; 9768c2ecf20Sopenharmony_ci } 9778c2ecf20Sopenharmony_ci 9788c2ecf20Sopenharmony_ci return 0; 9798c2ecf20Sopenharmony_ci} 9808c2ecf20Sopenharmony_ci 9818c2ecf20Sopenharmony_cistatic int su3000_identify_state(struct usb_device *udev, 9828c2ecf20Sopenharmony_ci const struct dvb_usb_device_properties *props, 9838c2ecf20Sopenharmony_ci const struct dvb_usb_device_description **desc, 9848c2ecf20Sopenharmony_ci int *cold) 9858c2ecf20Sopenharmony_ci{ 9868c2ecf20Sopenharmony_ci info("%s", __func__); 9878c2ecf20Sopenharmony_ci 9888c2ecf20Sopenharmony_ci *cold = 0; 9898c2ecf20Sopenharmony_ci return 0; 9908c2ecf20Sopenharmony_ci} 9918c2ecf20Sopenharmony_ci 9928c2ecf20Sopenharmony_cistatic int dw210x_set_voltage(struct dvb_frontend *fe, 9938c2ecf20Sopenharmony_ci enum fe_sec_voltage voltage) 9948c2ecf20Sopenharmony_ci{ 9958c2ecf20Sopenharmony_ci static u8 command_13v[] = {0x00, 0x01}; 9968c2ecf20Sopenharmony_ci static u8 command_18v[] = {0x01, 0x01}; 9978c2ecf20Sopenharmony_ci static u8 command_off[] = {0x00, 0x00}; 9988c2ecf20Sopenharmony_ci struct i2c_msg msg = { 9998c2ecf20Sopenharmony_ci .addr = DW2102_VOLTAGE_CTRL, 10008c2ecf20Sopenharmony_ci .flags = 0, 10018c2ecf20Sopenharmony_ci .buf = command_off, 10028c2ecf20Sopenharmony_ci .len = 2, 10038c2ecf20Sopenharmony_ci }; 10048c2ecf20Sopenharmony_ci 10058c2ecf20Sopenharmony_ci struct dvb_usb_adapter *udev_adap = 10068c2ecf20Sopenharmony_ci (struct dvb_usb_adapter *)(fe->dvb->priv); 10078c2ecf20Sopenharmony_ci if (voltage == SEC_VOLTAGE_18) 10088c2ecf20Sopenharmony_ci msg.buf = command_18v; 10098c2ecf20Sopenharmony_ci else if (voltage == SEC_VOLTAGE_13) 10108c2ecf20Sopenharmony_ci msg.buf = command_13v; 10118c2ecf20Sopenharmony_ci 10128c2ecf20Sopenharmony_ci i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); 10138c2ecf20Sopenharmony_ci 10148c2ecf20Sopenharmony_ci return 0; 10158c2ecf20Sopenharmony_ci} 10168c2ecf20Sopenharmony_ci 10178c2ecf20Sopenharmony_cistatic int s660_set_voltage(struct dvb_frontend *fe, 10188c2ecf20Sopenharmony_ci enum fe_sec_voltage voltage) 10198c2ecf20Sopenharmony_ci{ 10208c2ecf20Sopenharmony_ci struct dvb_usb_adapter *d = 10218c2ecf20Sopenharmony_ci (struct dvb_usb_adapter *)(fe->dvb->priv); 10228c2ecf20Sopenharmony_ci struct dw2102_state *st = (struct dw2102_state *)d->dev->priv; 10238c2ecf20Sopenharmony_ci 10248c2ecf20Sopenharmony_ci dw210x_set_voltage(fe, voltage); 10258c2ecf20Sopenharmony_ci if (st->old_set_voltage) 10268c2ecf20Sopenharmony_ci st->old_set_voltage(fe, voltage); 10278c2ecf20Sopenharmony_ci 10288c2ecf20Sopenharmony_ci return 0; 10298c2ecf20Sopenharmony_ci} 10308c2ecf20Sopenharmony_ci 10318c2ecf20Sopenharmony_cistatic void dw210x_led_ctrl(struct dvb_frontend *fe, int offon) 10328c2ecf20Sopenharmony_ci{ 10338c2ecf20Sopenharmony_ci static u8 led_off[] = { 0 }; 10348c2ecf20Sopenharmony_ci static u8 led_on[] = { 1 }; 10358c2ecf20Sopenharmony_ci struct i2c_msg msg = { 10368c2ecf20Sopenharmony_ci .addr = DW2102_LED_CTRL, 10378c2ecf20Sopenharmony_ci .flags = 0, 10388c2ecf20Sopenharmony_ci .buf = led_off, 10398c2ecf20Sopenharmony_ci .len = 1 10408c2ecf20Sopenharmony_ci }; 10418c2ecf20Sopenharmony_ci struct dvb_usb_adapter *udev_adap = 10428c2ecf20Sopenharmony_ci (struct dvb_usb_adapter *)(fe->dvb->priv); 10438c2ecf20Sopenharmony_ci 10448c2ecf20Sopenharmony_ci if (offon) 10458c2ecf20Sopenharmony_ci msg.buf = led_on; 10468c2ecf20Sopenharmony_ci i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); 10478c2ecf20Sopenharmony_ci} 10488c2ecf20Sopenharmony_ci 10498c2ecf20Sopenharmony_cistatic int tt_s2_4600_read_status(struct dvb_frontend *fe, 10508c2ecf20Sopenharmony_ci enum fe_status *status) 10518c2ecf20Sopenharmony_ci{ 10528c2ecf20Sopenharmony_ci struct dvb_usb_adapter *d = 10538c2ecf20Sopenharmony_ci (struct dvb_usb_adapter *)(fe->dvb->priv); 10548c2ecf20Sopenharmony_ci struct dw2102_state *st = (struct dw2102_state *)d->dev->priv; 10558c2ecf20Sopenharmony_ci int ret; 10568c2ecf20Sopenharmony_ci 10578c2ecf20Sopenharmony_ci ret = st->fe_read_status(fe, status); 10588c2ecf20Sopenharmony_ci 10598c2ecf20Sopenharmony_ci /* resync slave fifo when signal change from unlock to lock */ 10608c2ecf20Sopenharmony_ci if ((*status & FE_HAS_LOCK) && (!st->last_lock)) 10618c2ecf20Sopenharmony_ci su3000_streaming_ctrl(d, 1); 10628c2ecf20Sopenharmony_ci 10638c2ecf20Sopenharmony_ci st->last_lock = (*status & FE_HAS_LOCK) ? 1 : 0; 10648c2ecf20Sopenharmony_ci return ret; 10658c2ecf20Sopenharmony_ci} 10668c2ecf20Sopenharmony_ci 10678c2ecf20Sopenharmony_cistatic struct stv0299_config sharp_z0194a_config = { 10688c2ecf20Sopenharmony_ci .demod_address = 0x68, 10698c2ecf20Sopenharmony_ci .inittab = sharp_z0194a_inittab, 10708c2ecf20Sopenharmony_ci .mclk = 88000000UL, 10718c2ecf20Sopenharmony_ci .invert = 1, 10728c2ecf20Sopenharmony_ci .skip_reinit = 0, 10738c2ecf20Sopenharmony_ci .lock_output = STV0299_LOCKOUTPUT_1, 10748c2ecf20Sopenharmony_ci .volt13_op0_op1 = STV0299_VOLT13_OP1, 10758c2ecf20Sopenharmony_ci .min_delay_ms = 100, 10768c2ecf20Sopenharmony_ci .set_symbol_rate = sharp_z0194a_set_symbol_rate, 10778c2ecf20Sopenharmony_ci}; 10788c2ecf20Sopenharmony_ci 10798c2ecf20Sopenharmony_cistatic struct cx24116_config dw2104_config = { 10808c2ecf20Sopenharmony_ci .demod_address = 0x55, 10818c2ecf20Sopenharmony_ci .mpg_clk_pos_pol = 0x01, 10828c2ecf20Sopenharmony_ci}; 10838c2ecf20Sopenharmony_ci 10848c2ecf20Sopenharmony_cistatic struct si21xx_config serit_sp1511lhb_config = { 10858c2ecf20Sopenharmony_ci .demod_address = 0x68, 10868c2ecf20Sopenharmony_ci .min_delay_ms = 100, 10878c2ecf20Sopenharmony_ci 10888c2ecf20Sopenharmony_ci}; 10898c2ecf20Sopenharmony_ci 10908c2ecf20Sopenharmony_cistatic struct tda10023_config dw3101_tda10023_config = { 10918c2ecf20Sopenharmony_ci .demod_address = 0x0c, 10928c2ecf20Sopenharmony_ci .invert = 1, 10938c2ecf20Sopenharmony_ci}; 10948c2ecf20Sopenharmony_ci 10958c2ecf20Sopenharmony_cistatic struct mt312_config zl313_config = { 10968c2ecf20Sopenharmony_ci .demod_address = 0x0e, 10978c2ecf20Sopenharmony_ci}; 10988c2ecf20Sopenharmony_ci 10998c2ecf20Sopenharmony_cistatic struct ds3000_config dw2104_ds3000_config = { 11008c2ecf20Sopenharmony_ci .demod_address = 0x68, 11018c2ecf20Sopenharmony_ci}; 11028c2ecf20Sopenharmony_ci 11038c2ecf20Sopenharmony_cistatic struct ts2020_config dw2104_ts2020_config = { 11048c2ecf20Sopenharmony_ci .tuner_address = 0x60, 11058c2ecf20Sopenharmony_ci .clk_out_div = 1, 11068c2ecf20Sopenharmony_ci .frequency_div = 1060000, 11078c2ecf20Sopenharmony_ci}; 11088c2ecf20Sopenharmony_ci 11098c2ecf20Sopenharmony_cistatic struct ds3000_config s660_ds3000_config = { 11108c2ecf20Sopenharmony_ci .demod_address = 0x68, 11118c2ecf20Sopenharmony_ci .ci_mode = 1, 11128c2ecf20Sopenharmony_ci .set_lock_led = dw210x_led_ctrl, 11138c2ecf20Sopenharmony_ci}; 11148c2ecf20Sopenharmony_ci 11158c2ecf20Sopenharmony_cistatic struct ts2020_config s660_ts2020_config = { 11168c2ecf20Sopenharmony_ci .tuner_address = 0x60, 11178c2ecf20Sopenharmony_ci .clk_out_div = 1, 11188c2ecf20Sopenharmony_ci .frequency_div = 1146000, 11198c2ecf20Sopenharmony_ci}; 11208c2ecf20Sopenharmony_ci 11218c2ecf20Sopenharmony_cistatic struct stv0900_config dw2104a_stv0900_config = { 11228c2ecf20Sopenharmony_ci .demod_address = 0x6a, 11238c2ecf20Sopenharmony_ci .demod_mode = 0, 11248c2ecf20Sopenharmony_ci .xtal = 27000000, 11258c2ecf20Sopenharmony_ci .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ 11268c2ecf20Sopenharmony_ci .diseqc_mode = 2,/* 2/3 PWM */ 11278c2ecf20Sopenharmony_ci .tun1_maddress = 0,/* 0x60 */ 11288c2ecf20Sopenharmony_ci .tun1_adc = 0,/* 2 Vpp */ 11298c2ecf20Sopenharmony_ci .path1_mode = 3, 11308c2ecf20Sopenharmony_ci}; 11318c2ecf20Sopenharmony_ci 11328c2ecf20Sopenharmony_cistatic struct stb6100_config dw2104a_stb6100_config = { 11338c2ecf20Sopenharmony_ci .tuner_address = 0x60, 11348c2ecf20Sopenharmony_ci .refclock = 27000000, 11358c2ecf20Sopenharmony_ci}; 11368c2ecf20Sopenharmony_ci 11378c2ecf20Sopenharmony_cistatic struct stv0900_config dw2104_stv0900_config = { 11388c2ecf20Sopenharmony_ci .demod_address = 0x68, 11398c2ecf20Sopenharmony_ci .demod_mode = 0, 11408c2ecf20Sopenharmony_ci .xtal = 8000000, 11418c2ecf20Sopenharmony_ci .clkmode = 3, 11428c2ecf20Sopenharmony_ci .diseqc_mode = 2, 11438c2ecf20Sopenharmony_ci .tun1_maddress = 0, 11448c2ecf20Sopenharmony_ci .tun1_adc = 1,/* 1 Vpp */ 11458c2ecf20Sopenharmony_ci .path1_mode = 3, 11468c2ecf20Sopenharmony_ci}; 11478c2ecf20Sopenharmony_ci 11488c2ecf20Sopenharmony_cistatic struct stv6110_config dw2104_stv6110_config = { 11498c2ecf20Sopenharmony_ci .i2c_address = 0x60, 11508c2ecf20Sopenharmony_ci .mclk = 16000000, 11518c2ecf20Sopenharmony_ci .clk_div = 1, 11528c2ecf20Sopenharmony_ci}; 11538c2ecf20Sopenharmony_ci 11548c2ecf20Sopenharmony_cistatic struct stv0900_config prof_7500_stv0900_config = { 11558c2ecf20Sopenharmony_ci .demod_address = 0x6a, 11568c2ecf20Sopenharmony_ci .demod_mode = 0, 11578c2ecf20Sopenharmony_ci .xtal = 27000000, 11588c2ecf20Sopenharmony_ci .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ 11598c2ecf20Sopenharmony_ci .diseqc_mode = 2,/* 2/3 PWM */ 11608c2ecf20Sopenharmony_ci .tun1_maddress = 0,/* 0x60 */ 11618c2ecf20Sopenharmony_ci .tun1_adc = 0,/* 2 Vpp */ 11628c2ecf20Sopenharmony_ci .path1_mode = 3, 11638c2ecf20Sopenharmony_ci .tun1_type = 3, 11648c2ecf20Sopenharmony_ci .set_lock_led = dw210x_led_ctrl, 11658c2ecf20Sopenharmony_ci}; 11668c2ecf20Sopenharmony_ci 11678c2ecf20Sopenharmony_cistatic struct ds3000_config su3000_ds3000_config = { 11688c2ecf20Sopenharmony_ci .demod_address = 0x68, 11698c2ecf20Sopenharmony_ci .ci_mode = 1, 11708c2ecf20Sopenharmony_ci .set_lock_led = dw210x_led_ctrl, 11718c2ecf20Sopenharmony_ci}; 11728c2ecf20Sopenharmony_ci 11738c2ecf20Sopenharmony_cistatic struct cxd2820r_config cxd2820r_config = { 11748c2ecf20Sopenharmony_ci .i2c_address = 0x6c, /* (0xd8 >> 1) */ 11758c2ecf20Sopenharmony_ci .ts_mode = 0x38, 11768c2ecf20Sopenharmony_ci .ts_clock_inv = 1, 11778c2ecf20Sopenharmony_ci}; 11788c2ecf20Sopenharmony_ci 11798c2ecf20Sopenharmony_cistatic struct tda18271_config tda18271_config = { 11808c2ecf20Sopenharmony_ci .output_opt = TDA18271_OUTPUT_LT_OFF, 11818c2ecf20Sopenharmony_ci .gate = TDA18271_GATE_DIGITAL, 11828c2ecf20Sopenharmony_ci}; 11838c2ecf20Sopenharmony_ci 11848c2ecf20Sopenharmony_cistatic u8 m88rs2000_inittab[] = { 11858c2ecf20Sopenharmony_ci DEMOD_WRITE, 0x9a, 0x30, 11868c2ecf20Sopenharmony_ci DEMOD_WRITE, 0x00, 0x01, 11878c2ecf20Sopenharmony_ci WRITE_DELAY, 0x19, 0x00, 11888c2ecf20Sopenharmony_ci DEMOD_WRITE, 0x00, 0x00, 11898c2ecf20Sopenharmony_ci DEMOD_WRITE, 0x9a, 0xb0, 11908c2ecf20Sopenharmony_ci DEMOD_WRITE, 0x81, 0xc1, 11918c2ecf20Sopenharmony_ci DEMOD_WRITE, 0x81, 0x81, 11928c2ecf20Sopenharmony_ci DEMOD_WRITE, 0x86, 0xc6, 11938c2ecf20Sopenharmony_ci DEMOD_WRITE, 0x9a, 0x30, 11948c2ecf20Sopenharmony_ci DEMOD_WRITE, 0xf0, 0x80, 11958c2ecf20Sopenharmony_ci DEMOD_WRITE, 0xf1, 0xbf, 11968c2ecf20Sopenharmony_ci DEMOD_WRITE, 0xb0, 0x45, 11978c2ecf20Sopenharmony_ci DEMOD_WRITE, 0xb2, 0x01, 11988c2ecf20Sopenharmony_ci DEMOD_WRITE, 0x9a, 0xb0, 11998c2ecf20Sopenharmony_ci 0xff, 0xaa, 0xff 12008c2ecf20Sopenharmony_ci}; 12018c2ecf20Sopenharmony_ci 12028c2ecf20Sopenharmony_cistatic struct m88rs2000_config s421_m88rs2000_config = { 12038c2ecf20Sopenharmony_ci .demod_addr = 0x68, 12048c2ecf20Sopenharmony_ci .inittab = m88rs2000_inittab, 12058c2ecf20Sopenharmony_ci}; 12068c2ecf20Sopenharmony_ci 12078c2ecf20Sopenharmony_cistatic int dw2104_frontend_attach(struct dvb_usb_adapter *d) 12088c2ecf20Sopenharmony_ci{ 12098c2ecf20Sopenharmony_ci struct dvb_tuner_ops *tuner_ops = NULL; 12108c2ecf20Sopenharmony_ci 12118c2ecf20Sopenharmony_ci if (demod_probe & 4) { 12128c2ecf20Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config, 12138c2ecf20Sopenharmony_ci &d->dev->i2c_adap, 0); 12148c2ecf20Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 12158c2ecf20Sopenharmony_ci if (dvb_attach(stb6100_attach, d->fe_adap[0].fe, 12168c2ecf20Sopenharmony_ci &dw2104a_stb6100_config, 12178c2ecf20Sopenharmony_ci &d->dev->i2c_adap)) { 12188c2ecf20Sopenharmony_ci tuner_ops = &d->fe_adap[0].fe->ops.tuner_ops; 12198c2ecf20Sopenharmony_ci tuner_ops->set_frequency = stb6100_set_freq; 12208c2ecf20Sopenharmony_ci tuner_ops->get_frequency = stb6100_get_freq; 12218c2ecf20Sopenharmony_ci tuner_ops->set_bandwidth = stb6100_set_bandw; 12228c2ecf20Sopenharmony_ci tuner_ops->get_bandwidth = stb6100_get_bandw; 12238c2ecf20Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 12248c2ecf20Sopenharmony_ci info("Attached STV0900+STB6100!"); 12258c2ecf20Sopenharmony_ci return 0; 12268c2ecf20Sopenharmony_ci } 12278c2ecf20Sopenharmony_ci } 12288c2ecf20Sopenharmony_ci } 12298c2ecf20Sopenharmony_ci 12308c2ecf20Sopenharmony_ci if (demod_probe & 2) { 12318c2ecf20Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config, 12328c2ecf20Sopenharmony_ci &d->dev->i2c_adap, 0); 12338c2ecf20Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 12348c2ecf20Sopenharmony_ci if (dvb_attach(stv6110_attach, d->fe_adap[0].fe, 12358c2ecf20Sopenharmony_ci &dw2104_stv6110_config, 12368c2ecf20Sopenharmony_ci &d->dev->i2c_adap)) { 12378c2ecf20Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 12388c2ecf20Sopenharmony_ci info("Attached STV0900+STV6110A!"); 12398c2ecf20Sopenharmony_ci return 0; 12408c2ecf20Sopenharmony_ci } 12418c2ecf20Sopenharmony_ci } 12428c2ecf20Sopenharmony_ci } 12438c2ecf20Sopenharmony_ci 12448c2ecf20Sopenharmony_ci if (demod_probe & 1) { 12458c2ecf20Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(cx24116_attach, &dw2104_config, 12468c2ecf20Sopenharmony_ci &d->dev->i2c_adap); 12478c2ecf20Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 12488c2ecf20Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 12498c2ecf20Sopenharmony_ci info("Attached cx24116!"); 12508c2ecf20Sopenharmony_ci return 0; 12518c2ecf20Sopenharmony_ci } 12528c2ecf20Sopenharmony_ci } 12538c2ecf20Sopenharmony_ci 12548c2ecf20Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, 12558c2ecf20Sopenharmony_ci &d->dev->i2c_adap); 12568c2ecf20Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 12578c2ecf20Sopenharmony_ci dvb_attach(ts2020_attach, d->fe_adap[0].fe, 12588c2ecf20Sopenharmony_ci &dw2104_ts2020_config, &d->dev->i2c_adap); 12598c2ecf20Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 12608c2ecf20Sopenharmony_ci info("Attached DS3000!"); 12618c2ecf20Sopenharmony_ci return 0; 12628c2ecf20Sopenharmony_ci } 12638c2ecf20Sopenharmony_ci 12648c2ecf20Sopenharmony_ci return -EIO; 12658c2ecf20Sopenharmony_ci} 12668c2ecf20Sopenharmony_ci 12678c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties dw2102_properties; 12688c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties dw2104_properties; 12698c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties s6x0_properties; 12708c2ecf20Sopenharmony_ci 12718c2ecf20Sopenharmony_cistatic int dw2102_frontend_attach(struct dvb_usb_adapter *d) 12728c2ecf20Sopenharmony_ci{ 12738c2ecf20Sopenharmony_ci if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) { 12748c2ecf20Sopenharmony_ci /*dw2102_properties.adapter->tuner_attach = NULL;*/ 12758c2ecf20Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config, 12768c2ecf20Sopenharmony_ci &d->dev->i2c_adap); 12778c2ecf20Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 12788c2ecf20Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 12798c2ecf20Sopenharmony_ci info("Attached si21xx!"); 12808c2ecf20Sopenharmony_ci return 0; 12818c2ecf20Sopenharmony_ci } 12828c2ecf20Sopenharmony_ci } 12838c2ecf20Sopenharmony_ci 12848c2ecf20Sopenharmony_ci if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) { 12858c2ecf20Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config, 12868c2ecf20Sopenharmony_ci &d->dev->i2c_adap); 12878c2ecf20Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 12888c2ecf20Sopenharmony_ci if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, 12898c2ecf20Sopenharmony_ci &d->dev->i2c_adap)) { 12908c2ecf20Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 12918c2ecf20Sopenharmony_ci info("Attached stv0288!"); 12928c2ecf20Sopenharmony_ci return 0; 12938c2ecf20Sopenharmony_ci } 12948c2ecf20Sopenharmony_ci } 12958c2ecf20Sopenharmony_ci } 12968c2ecf20Sopenharmony_ci 12978c2ecf20Sopenharmony_ci if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) { 12988c2ecf20Sopenharmony_ci /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/ 12998c2ecf20Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(stv0299_attach, &sharp_z0194a_config, 13008c2ecf20Sopenharmony_ci &d->dev->i2c_adap); 13018c2ecf20Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 13028c2ecf20Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 13038c2ecf20Sopenharmony_ci info("Attached stv0299!"); 13048c2ecf20Sopenharmony_ci return 0; 13058c2ecf20Sopenharmony_ci } 13068c2ecf20Sopenharmony_ci } 13078c2ecf20Sopenharmony_ci return -EIO; 13088c2ecf20Sopenharmony_ci} 13098c2ecf20Sopenharmony_ci 13108c2ecf20Sopenharmony_cistatic int dw3101_frontend_attach(struct dvb_usb_adapter *d) 13118c2ecf20Sopenharmony_ci{ 13128c2ecf20Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config, 13138c2ecf20Sopenharmony_ci &d->dev->i2c_adap, 0x48); 13148c2ecf20Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 13158c2ecf20Sopenharmony_ci info("Attached tda10023!"); 13168c2ecf20Sopenharmony_ci return 0; 13178c2ecf20Sopenharmony_ci } 13188c2ecf20Sopenharmony_ci return -EIO; 13198c2ecf20Sopenharmony_ci} 13208c2ecf20Sopenharmony_ci 13218c2ecf20Sopenharmony_cistatic int zl100313_frontend_attach(struct dvb_usb_adapter *d) 13228c2ecf20Sopenharmony_ci{ 13238c2ecf20Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(mt312_attach, &zl313_config, 13248c2ecf20Sopenharmony_ci &d->dev->i2c_adap); 13258c2ecf20Sopenharmony_ci if (d->fe_adap[0].fe != NULL) { 13268c2ecf20Sopenharmony_ci if (dvb_attach(zl10039_attach, d->fe_adap[0].fe, 0x60, 13278c2ecf20Sopenharmony_ci &d->dev->i2c_adap)) { 13288c2ecf20Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 13298c2ecf20Sopenharmony_ci info("Attached zl100313+zl10039!"); 13308c2ecf20Sopenharmony_ci return 0; 13318c2ecf20Sopenharmony_ci } 13328c2ecf20Sopenharmony_ci } 13338c2ecf20Sopenharmony_ci 13348c2ecf20Sopenharmony_ci return -EIO; 13358c2ecf20Sopenharmony_ci} 13368c2ecf20Sopenharmony_ci 13378c2ecf20Sopenharmony_cistatic int stv0288_frontend_attach(struct dvb_usb_adapter *d) 13388c2ecf20Sopenharmony_ci{ 13398c2ecf20Sopenharmony_ci u8 obuf[] = {7, 1}; 13408c2ecf20Sopenharmony_ci 13418c2ecf20Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config, 13428c2ecf20Sopenharmony_ci &d->dev->i2c_adap); 13438c2ecf20Sopenharmony_ci 13448c2ecf20Sopenharmony_ci if (d->fe_adap[0].fe == NULL) 13458c2ecf20Sopenharmony_ci return -EIO; 13468c2ecf20Sopenharmony_ci 13478c2ecf20Sopenharmony_ci if (NULL == dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, &d->dev->i2c_adap)) 13488c2ecf20Sopenharmony_ci return -EIO; 13498c2ecf20Sopenharmony_ci 13508c2ecf20Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 13518c2ecf20Sopenharmony_ci 13528c2ecf20Sopenharmony_ci dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); 13538c2ecf20Sopenharmony_ci 13548c2ecf20Sopenharmony_ci info("Attached stv0288+stb6000!"); 13558c2ecf20Sopenharmony_ci 13568c2ecf20Sopenharmony_ci return 0; 13578c2ecf20Sopenharmony_ci 13588c2ecf20Sopenharmony_ci} 13598c2ecf20Sopenharmony_ci 13608c2ecf20Sopenharmony_cistatic int ds3000_frontend_attach(struct dvb_usb_adapter *d) 13618c2ecf20Sopenharmony_ci{ 13628c2ecf20Sopenharmony_ci struct dw2102_state *st = d->dev->priv; 13638c2ecf20Sopenharmony_ci u8 obuf[] = {7, 1}; 13648c2ecf20Sopenharmony_ci 13658c2ecf20Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(ds3000_attach, &s660_ds3000_config, 13668c2ecf20Sopenharmony_ci &d->dev->i2c_adap); 13678c2ecf20Sopenharmony_ci 13688c2ecf20Sopenharmony_ci if (d->fe_adap[0].fe == NULL) 13698c2ecf20Sopenharmony_ci return -EIO; 13708c2ecf20Sopenharmony_ci 13718c2ecf20Sopenharmony_ci dvb_attach(ts2020_attach, d->fe_adap[0].fe, &s660_ts2020_config, 13728c2ecf20Sopenharmony_ci &d->dev->i2c_adap); 13738c2ecf20Sopenharmony_ci 13748c2ecf20Sopenharmony_ci st->old_set_voltage = d->fe_adap[0].fe->ops.set_voltage; 13758c2ecf20Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = s660_set_voltage; 13768c2ecf20Sopenharmony_ci 13778c2ecf20Sopenharmony_ci dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); 13788c2ecf20Sopenharmony_ci 13798c2ecf20Sopenharmony_ci info("Attached ds3000+ts2020!"); 13808c2ecf20Sopenharmony_ci 13818c2ecf20Sopenharmony_ci return 0; 13828c2ecf20Sopenharmony_ci} 13838c2ecf20Sopenharmony_ci 13848c2ecf20Sopenharmony_cistatic int prof_7500_frontend_attach(struct dvb_usb_adapter *d) 13858c2ecf20Sopenharmony_ci{ 13868c2ecf20Sopenharmony_ci u8 obuf[] = {7, 1}; 13878c2ecf20Sopenharmony_ci 13888c2ecf20Sopenharmony_ci d->fe_adap[0].fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config, 13898c2ecf20Sopenharmony_ci &d->dev->i2c_adap, 0); 13908c2ecf20Sopenharmony_ci if (d->fe_adap[0].fe == NULL) 13918c2ecf20Sopenharmony_ci return -EIO; 13928c2ecf20Sopenharmony_ci 13938c2ecf20Sopenharmony_ci d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; 13948c2ecf20Sopenharmony_ci 13958c2ecf20Sopenharmony_ci dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); 13968c2ecf20Sopenharmony_ci 13978c2ecf20Sopenharmony_ci info("Attached STV0900+STB6100A!"); 13988c2ecf20Sopenharmony_ci 13998c2ecf20Sopenharmony_ci return 0; 14008c2ecf20Sopenharmony_ci} 14018c2ecf20Sopenharmony_ci 14028c2ecf20Sopenharmony_cistatic int su3000_frontend_attach(struct dvb_usb_adapter *adap) 14038c2ecf20Sopenharmony_ci{ 14048c2ecf20Sopenharmony_ci struct dvb_usb_device *d = adap->dev; 14058c2ecf20Sopenharmony_ci struct dw2102_state *state = d->priv; 14068c2ecf20Sopenharmony_ci 14078c2ecf20Sopenharmony_ci mutex_lock(&d->data_mutex); 14088c2ecf20Sopenharmony_ci 14098c2ecf20Sopenharmony_ci state->data[0] = 0xe; 14108c2ecf20Sopenharmony_ci state->data[1] = 0x80; 14118c2ecf20Sopenharmony_ci state->data[2] = 0; 14128c2ecf20Sopenharmony_ci 14138c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 14148c2ecf20Sopenharmony_ci err("command 0x0e transfer failed."); 14158c2ecf20Sopenharmony_ci 14168c2ecf20Sopenharmony_ci state->data[0] = 0xe; 14178c2ecf20Sopenharmony_ci state->data[1] = 0x02; 14188c2ecf20Sopenharmony_ci state->data[2] = 1; 14198c2ecf20Sopenharmony_ci 14208c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 14218c2ecf20Sopenharmony_ci err("command 0x0e transfer failed."); 14228c2ecf20Sopenharmony_ci msleep(300); 14238c2ecf20Sopenharmony_ci 14248c2ecf20Sopenharmony_ci state->data[0] = 0xe; 14258c2ecf20Sopenharmony_ci state->data[1] = 0x83; 14268c2ecf20Sopenharmony_ci state->data[2] = 0; 14278c2ecf20Sopenharmony_ci 14288c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 14298c2ecf20Sopenharmony_ci err("command 0x0e transfer failed."); 14308c2ecf20Sopenharmony_ci 14318c2ecf20Sopenharmony_ci state->data[0] = 0xe; 14328c2ecf20Sopenharmony_ci state->data[1] = 0x83; 14338c2ecf20Sopenharmony_ci state->data[2] = 1; 14348c2ecf20Sopenharmony_ci 14358c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 14368c2ecf20Sopenharmony_ci err("command 0x0e transfer failed."); 14378c2ecf20Sopenharmony_ci 14388c2ecf20Sopenharmony_ci state->data[0] = 0x51; 14398c2ecf20Sopenharmony_ci 14408c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0) 14418c2ecf20Sopenharmony_ci err("command 0x51 transfer failed."); 14428c2ecf20Sopenharmony_ci 14438c2ecf20Sopenharmony_ci mutex_unlock(&d->data_mutex); 14448c2ecf20Sopenharmony_ci 14458c2ecf20Sopenharmony_ci adap->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config, 14468c2ecf20Sopenharmony_ci &d->i2c_adap); 14478c2ecf20Sopenharmony_ci if (adap->fe_adap[0].fe == NULL) 14488c2ecf20Sopenharmony_ci return -EIO; 14498c2ecf20Sopenharmony_ci 14508c2ecf20Sopenharmony_ci if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe, 14518c2ecf20Sopenharmony_ci &dw2104_ts2020_config, 14528c2ecf20Sopenharmony_ci &d->i2c_adap)) { 14538c2ecf20Sopenharmony_ci info("Attached DS3000/TS2020!"); 14548c2ecf20Sopenharmony_ci return 0; 14558c2ecf20Sopenharmony_ci } 14568c2ecf20Sopenharmony_ci 14578c2ecf20Sopenharmony_ci info("Failed to attach DS3000/TS2020!"); 14588c2ecf20Sopenharmony_ci return -EIO; 14598c2ecf20Sopenharmony_ci} 14608c2ecf20Sopenharmony_ci 14618c2ecf20Sopenharmony_cistatic int t220_frontend_attach(struct dvb_usb_adapter *adap) 14628c2ecf20Sopenharmony_ci{ 14638c2ecf20Sopenharmony_ci struct dvb_usb_device *d = adap->dev; 14648c2ecf20Sopenharmony_ci struct dw2102_state *state = d->priv; 14658c2ecf20Sopenharmony_ci 14668c2ecf20Sopenharmony_ci mutex_lock(&d->data_mutex); 14678c2ecf20Sopenharmony_ci 14688c2ecf20Sopenharmony_ci state->data[0] = 0xe; 14698c2ecf20Sopenharmony_ci state->data[1] = 0x87; 14708c2ecf20Sopenharmony_ci state->data[2] = 0x0; 14718c2ecf20Sopenharmony_ci 14728c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 14738c2ecf20Sopenharmony_ci err("command 0x0e transfer failed."); 14748c2ecf20Sopenharmony_ci 14758c2ecf20Sopenharmony_ci state->data[0] = 0xe; 14768c2ecf20Sopenharmony_ci state->data[1] = 0x86; 14778c2ecf20Sopenharmony_ci state->data[2] = 1; 14788c2ecf20Sopenharmony_ci 14798c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 14808c2ecf20Sopenharmony_ci err("command 0x0e transfer failed."); 14818c2ecf20Sopenharmony_ci 14828c2ecf20Sopenharmony_ci state->data[0] = 0xe; 14838c2ecf20Sopenharmony_ci state->data[1] = 0x80; 14848c2ecf20Sopenharmony_ci state->data[2] = 0; 14858c2ecf20Sopenharmony_ci 14868c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 14878c2ecf20Sopenharmony_ci err("command 0x0e transfer failed."); 14888c2ecf20Sopenharmony_ci 14898c2ecf20Sopenharmony_ci msleep(50); 14908c2ecf20Sopenharmony_ci 14918c2ecf20Sopenharmony_ci state->data[0] = 0xe; 14928c2ecf20Sopenharmony_ci state->data[1] = 0x80; 14938c2ecf20Sopenharmony_ci state->data[2] = 1; 14948c2ecf20Sopenharmony_ci 14958c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 14968c2ecf20Sopenharmony_ci err("command 0x0e transfer failed."); 14978c2ecf20Sopenharmony_ci 14988c2ecf20Sopenharmony_ci state->data[0] = 0x51; 14998c2ecf20Sopenharmony_ci 15008c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0) 15018c2ecf20Sopenharmony_ci err("command 0x51 transfer failed."); 15028c2ecf20Sopenharmony_ci 15038c2ecf20Sopenharmony_ci mutex_unlock(&d->data_mutex); 15048c2ecf20Sopenharmony_ci 15058c2ecf20Sopenharmony_ci adap->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config, 15068c2ecf20Sopenharmony_ci &d->i2c_adap, NULL); 15078c2ecf20Sopenharmony_ci if (adap->fe_adap[0].fe != NULL) { 15088c2ecf20Sopenharmony_ci if (dvb_attach(tda18271_attach, adap->fe_adap[0].fe, 0x60, 15098c2ecf20Sopenharmony_ci &d->i2c_adap, &tda18271_config)) { 15108c2ecf20Sopenharmony_ci info("Attached TDA18271HD/CXD2820R!"); 15118c2ecf20Sopenharmony_ci return 0; 15128c2ecf20Sopenharmony_ci } 15138c2ecf20Sopenharmony_ci } 15148c2ecf20Sopenharmony_ci 15158c2ecf20Sopenharmony_ci info("Failed to attach TDA18271HD/CXD2820R!"); 15168c2ecf20Sopenharmony_ci return -EIO; 15178c2ecf20Sopenharmony_ci} 15188c2ecf20Sopenharmony_ci 15198c2ecf20Sopenharmony_cistatic int m88rs2000_frontend_attach(struct dvb_usb_adapter *adap) 15208c2ecf20Sopenharmony_ci{ 15218c2ecf20Sopenharmony_ci struct dvb_usb_device *d = adap->dev; 15228c2ecf20Sopenharmony_ci struct dw2102_state *state = d->priv; 15238c2ecf20Sopenharmony_ci 15248c2ecf20Sopenharmony_ci mutex_lock(&d->data_mutex); 15258c2ecf20Sopenharmony_ci 15268c2ecf20Sopenharmony_ci state->data[0] = 0x51; 15278c2ecf20Sopenharmony_ci 15288c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0) 15298c2ecf20Sopenharmony_ci err("command 0x51 transfer failed."); 15308c2ecf20Sopenharmony_ci 15318c2ecf20Sopenharmony_ci mutex_unlock(&d->data_mutex); 15328c2ecf20Sopenharmony_ci 15338c2ecf20Sopenharmony_ci adap->fe_adap[0].fe = dvb_attach(m88rs2000_attach, 15348c2ecf20Sopenharmony_ci &s421_m88rs2000_config, 15358c2ecf20Sopenharmony_ci &d->i2c_adap); 15368c2ecf20Sopenharmony_ci 15378c2ecf20Sopenharmony_ci if (adap->fe_adap[0].fe == NULL) 15388c2ecf20Sopenharmony_ci return -EIO; 15398c2ecf20Sopenharmony_ci 15408c2ecf20Sopenharmony_ci if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe, 15418c2ecf20Sopenharmony_ci &dw2104_ts2020_config, 15428c2ecf20Sopenharmony_ci &d->i2c_adap)) { 15438c2ecf20Sopenharmony_ci info("Attached RS2000/TS2020!"); 15448c2ecf20Sopenharmony_ci return 0; 15458c2ecf20Sopenharmony_ci } 15468c2ecf20Sopenharmony_ci 15478c2ecf20Sopenharmony_ci info("Failed to attach RS2000/TS2020!"); 15488c2ecf20Sopenharmony_ci return -EIO; 15498c2ecf20Sopenharmony_ci} 15508c2ecf20Sopenharmony_ci 15518c2ecf20Sopenharmony_cistatic int tt_s2_4600_frontend_attach_probe_demod(struct dvb_usb_device *d, 15528c2ecf20Sopenharmony_ci const int probe_addr) 15538c2ecf20Sopenharmony_ci{ 15548c2ecf20Sopenharmony_ci struct dw2102_state *state = d->priv; 15558c2ecf20Sopenharmony_ci 15568c2ecf20Sopenharmony_ci state->data[0] = 0x9; 15578c2ecf20Sopenharmony_ci state->data[1] = 0x1; 15588c2ecf20Sopenharmony_ci state->data[2] = 0x1; 15598c2ecf20Sopenharmony_ci state->data[3] = probe_addr; 15608c2ecf20Sopenharmony_ci state->data[4] = 0x0; 15618c2ecf20Sopenharmony_ci 15628c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 5, state->data, 2, 0) < 0) { 15638c2ecf20Sopenharmony_ci err("i2c probe for address 0x%x failed.", probe_addr); 15648c2ecf20Sopenharmony_ci return 0; 15658c2ecf20Sopenharmony_ci } 15668c2ecf20Sopenharmony_ci 15678c2ecf20Sopenharmony_ci if (state->data[0] != 8) /* fail(7) or error, no device at address */ 15688c2ecf20Sopenharmony_ci return 0; 15698c2ecf20Sopenharmony_ci 15708c2ecf20Sopenharmony_ci /* probing successful */ 15718c2ecf20Sopenharmony_ci return 1; 15728c2ecf20Sopenharmony_ci} 15738c2ecf20Sopenharmony_ci 15748c2ecf20Sopenharmony_cistatic int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap) 15758c2ecf20Sopenharmony_ci{ 15768c2ecf20Sopenharmony_ci struct dvb_usb_device *d = adap->dev; 15778c2ecf20Sopenharmony_ci struct dw2102_state *state = d->priv; 15788c2ecf20Sopenharmony_ci struct i2c_adapter *i2c_adapter; 15798c2ecf20Sopenharmony_ci struct i2c_client *client; 15808c2ecf20Sopenharmony_ci struct i2c_board_info board_info; 15818c2ecf20Sopenharmony_ci struct m88ds3103_platform_data m88ds3103_pdata = {}; 15828c2ecf20Sopenharmony_ci struct ts2020_config ts2020_config = {}; 15838c2ecf20Sopenharmony_ci int demod_addr; 15848c2ecf20Sopenharmony_ci 15858c2ecf20Sopenharmony_ci mutex_lock(&d->data_mutex); 15868c2ecf20Sopenharmony_ci 15878c2ecf20Sopenharmony_ci state->data[0] = 0xe; 15888c2ecf20Sopenharmony_ci state->data[1] = 0x80; 15898c2ecf20Sopenharmony_ci state->data[2] = 0x0; 15908c2ecf20Sopenharmony_ci 15918c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 15928c2ecf20Sopenharmony_ci err("command 0x0e transfer failed."); 15938c2ecf20Sopenharmony_ci 15948c2ecf20Sopenharmony_ci state->data[0] = 0xe; 15958c2ecf20Sopenharmony_ci state->data[1] = 0x02; 15968c2ecf20Sopenharmony_ci state->data[2] = 1; 15978c2ecf20Sopenharmony_ci 15988c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 15998c2ecf20Sopenharmony_ci err("command 0x0e transfer failed."); 16008c2ecf20Sopenharmony_ci msleep(300); 16018c2ecf20Sopenharmony_ci 16028c2ecf20Sopenharmony_ci state->data[0] = 0xe; 16038c2ecf20Sopenharmony_ci state->data[1] = 0x83; 16048c2ecf20Sopenharmony_ci state->data[2] = 0; 16058c2ecf20Sopenharmony_ci 16068c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 16078c2ecf20Sopenharmony_ci err("command 0x0e transfer failed."); 16088c2ecf20Sopenharmony_ci 16098c2ecf20Sopenharmony_ci state->data[0] = 0xe; 16108c2ecf20Sopenharmony_ci state->data[1] = 0x83; 16118c2ecf20Sopenharmony_ci state->data[2] = 1; 16128c2ecf20Sopenharmony_ci 16138c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) 16148c2ecf20Sopenharmony_ci err("command 0x0e transfer failed."); 16158c2ecf20Sopenharmony_ci 16168c2ecf20Sopenharmony_ci state->data[0] = 0x51; 16178c2ecf20Sopenharmony_ci 16188c2ecf20Sopenharmony_ci if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0) 16198c2ecf20Sopenharmony_ci err("command 0x51 transfer failed."); 16208c2ecf20Sopenharmony_ci 16218c2ecf20Sopenharmony_ci /* probe for demodulator i2c address */ 16228c2ecf20Sopenharmony_ci demod_addr = -1; 16238c2ecf20Sopenharmony_ci if (tt_s2_4600_frontend_attach_probe_demod(d, 0x68)) 16248c2ecf20Sopenharmony_ci demod_addr = 0x68; 16258c2ecf20Sopenharmony_ci else if (tt_s2_4600_frontend_attach_probe_demod(d, 0x69)) 16268c2ecf20Sopenharmony_ci demod_addr = 0x69; 16278c2ecf20Sopenharmony_ci else if (tt_s2_4600_frontend_attach_probe_demod(d, 0x6a)) 16288c2ecf20Sopenharmony_ci demod_addr = 0x6a; 16298c2ecf20Sopenharmony_ci 16308c2ecf20Sopenharmony_ci mutex_unlock(&d->data_mutex); 16318c2ecf20Sopenharmony_ci 16328c2ecf20Sopenharmony_ci if (demod_addr < 0) { 16338c2ecf20Sopenharmony_ci err("probing for demodulator failed. Is the external power switched on?"); 16348c2ecf20Sopenharmony_ci return -ENODEV; 16358c2ecf20Sopenharmony_ci } 16368c2ecf20Sopenharmony_ci 16378c2ecf20Sopenharmony_ci /* attach demod */ 16388c2ecf20Sopenharmony_ci m88ds3103_pdata.clk = 27000000; 16398c2ecf20Sopenharmony_ci m88ds3103_pdata.i2c_wr_max = 33; 16408c2ecf20Sopenharmony_ci m88ds3103_pdata.ts_mode = M88DS3103_TS_CI; 16418c2ecf20Sopenharmony_ci m88ds3103_pdata.ts_clk = 16000; 16428c2ecf20Sopenharmony_ci m88ds3103_pdata.ts_clk_pol = 0; 16438c2ecf20Sopenharmony_ci m88ds3103_pdata.spec_inv = 0; 16448c2ecf20Sopenharmony_ci m88ds3103_pdata.agc = 0x99; 16458c2ecf20Sopenharmony_ci m88ds3103_pdata.agc_inv = 0; 16468c2ecf20Sopenharmony_ci m88ds3103_pdata.clk_out = M88DS3103_CLOCK_OUT_ENABLED; 16478c2ecf20Sopenharmony_ci m88ds3103_pdata.envelope_mode = 0; 16488c2ecf20Sopenharmony_ci m88ds3103_pdata.lnb_hv_pol = 1; 16498c2ecf20Sopenharmony_ci m88ds3103_pdata.lnb_en_pol = 0; 16508c2ecf20Sopenharmony_ci memset(&board_info, 0, sizeof(board_info)); 16518c2ecf20Sopenharmony_ci if (demod_addr == 0x6a) 16528c2ecf20Sopenharmony_ci strscpy(board_info.type, "m88ds3103b", I2C_NAME_SIZE); 16538c2ecf20Sopenharmony_ci else 16548c2ecf20Sopenharmony_ci strscpy(board_info.type, "m88ds3103", I2C_NAME_SIZE); 16558c2ecf20Sopenharmony_ci board_info.addr = demod_addr; 16568c2ecf20Sopenharmony_ci board_info.platform_data = &m88ds3103_pdata; 16578c2ecf20Sopenharmony_ci request_module("m88ds3103"); 16588c2ecf20Sopenharmony_ci client = i2c_new_client_device(&d->i2c_adap, &board_info); 16598c2ecf20Sopenharmony_ci if (!i2c_client_has_driver(client)) 16608c2ecf20Sopenharmony_ci return -ENODEV; 16618c2ecf20Sopenharmony_ci if (!try_module_get(client->dev.driver->owner)) { 16628c2ecf20Sopenharmony_ci i2c_unregister_device(client); 16638c2ecf20Sopenharmony_ci return -ENODEV; 16648c2ecf20Sopenharmony_ci } 16658c2ecf20Sopenharmony_ci adap->fe_adap[0].fe = m88ds3103_pdata.get_dvb_frontend(client); 16668c2ecf20Sopenharmony_ci i2c_adapter = m88ds3103_pdata.get_i2c_adapter(client); 16678c2ecf20Sopenharmony_ci 16688c2ecf20Sopenharmony_ci state->i2c_client_demod = client; 16698c2ecf20Sopenharmony_ci 16708c2ecf20Sopenharmony_ci /* attach tuner */ 16718c2ecf20Sopenharmony_ci ts2020_config.fe = adap->fe_adap[0].fe; 16728c2ecf20Sopenharmony_ci memset(&board_info, 0, sizeof(board_info)); 16738c2ecf20Sopenharmony_ci strscpy(board_info.type, "ts2022", I2C_NAME_SIZE); 16748c2ecf20Sopenharmony_ci board_info.addr = 0x60; 16758c2ecf20Sopenharmony_ci board_info.platform_data = &ts2020_config; 16768c2ecf20Sopenharmony_ci request_module("ts2020"); 16778c2ecf20Sopenharmony_ci client = i2c_new_client_device(i2c_adapter, &board_info); 16788c2ecf20Sopenharmony_ci 16798c2ecf20Sopenharmony_ci if (!i2c_client_has_driver(client)) { 16808c2ecf20Sopenharmony_ci dvb_frontend_detach(adap->fe_adap[0].fe); 16818c2ecf20Sopenharmony_ci return -ENODEV; 16828c2ecf20Sopenharmony_ci } 16838c2ecf20Sopenharmony_ci 16848c2ecf20Sopenharmony_ci if (!try_module_get(client->dev.driver->owner)) { 16858c2ecf20Sopenharmony_ci i2c_unregister_device(client); 16868c2ecf20Sopenharmony_ci dvb_frontend_detach(adap->fe_adap[0].fe); 16878c2ecf20Sopenharmony_ci return -ENODEV; 16888c2ecf20Sopenharmony_ci } 16898c2ecf20Sopenharmony_ci 16908c2ecf20Sopenharmony_ci /* delegate signal strength measurement to tuner */ 16918c2ecf20Sopenharmony_ci adap->fe_adap[0].fe->ops.read_signal_strength = 16928c2ecf20Sopenharmony_ci adap->fe_adap[0].fe->ops.tuner_ops.get_rf_strength; 16938c2ecf20Sopenharmony_ci 16948c2ecf20Sopenharmony_ci state->i2c_client_tuner = client; 16958c2ecf20Sopenharmony_ci 16968c2ecf20Sopenharmony_ci /* hook fe: need to resync the slave fifo when signal locks */ 16978c2ecf20Sopenharmony_ci state->fe_read_status = adap->fe_adap[0].fe->ops.read_status; 16988c2ecf20Sopenharmony_ci adap->fe_adap[0].fe->ops.read_status = tt_s2_4600_read_status; 16998c2ecf20Sopenharmony_ci 17008c2ecf20Sopenharmony_ci state->last_lock = 0; 17018c2ecf20Sopenharmony_ci 17028c2ecf20Sopenharmony_ci return 0; 17038c2ecf20Sopenharmony_ci} 17048c2ecf20Sopenharmony_ci 17058c2ecf20Sopenharmony_cistatic int dw2102_tuner_attach(struct dvb_usb_adapter *adap) 17068c2ecf20Sopenharmony_ci{ 17078c2ecf20Sopenharmony_ci dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, 17088c2ecf20Sopenharmony_ci &adap->dev->i2c_adap, DVB_PLL_OPERA1); 17098c2ecf20Sopenharmony_ci return 0; 17108c2ecf20Sopenharmony_ci} 17118c2ecf20Sopenharmony_ci 17128c2ecf20Sopenharmony_cistatic int dw3101_tuner_attach(struct dvb_usb_adapter *adap) 17138c2ecf20Sopenharmony_ci{ 17148c2ecf20Sopenharmony_ci dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, 17158c2ecf20Sopenharmony_ci &adap->dev->i2c_adap, DVB_PLL_TUA6034); 17168c2ecf20Sopenharmony_ci 17178c2ecf20Sopenharmony_ci return 0; 17188c2ecf20Sopenharmony_ci} 17198c2ecf20Sopenharmony_ci 17208c2ecf20Sopenharmony_cistatic int dw2102_rc_query(struct dvb_usb_device *d) 17218c2ecf20Sopenharmony_ci{ 17228c2ecf20Sopenharmony_ci u8 key[2]; 17238c2ecf20Sopenharmony_ci struct i2c_msg msg = { 17248c2ecf20Sopenharmony_ci .addr = DW2102_RC_QUERY, 17258c2ecf20Sopenharmony_ci .flags = I2C_M_RD, 17268c2ecf20Sopenharmony_ci .buf = key, 17278c2ecf20Sopenharmony_ci .len = 2 17288c2ecf20Sopenharmony_ci }; 17298c2ecf20Sopenharmony_ci 17308c2ecf20Sopenharmony_ci if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) { 17318c2ecf20Sopenharmony_ci if (msg.buf[0] != 0xff) { 17328c2ecf20Sopenharmony_ci deb_rc("%s: rc code: %x, %x\n", 17338c2ecf20Sopenharmony_ci __func__, key[0], key[1]); 17348c2ecf20Sopenharmony_ci rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, key[0], 0); 17358c2ecf20Sopenharmony_ci } 17368c2ecf20Sopenharmony_ci } 17378c2ecf20Sopenharmony_ci 17388c2ecf20Sopenharmony_ci return 0; 17398c2ecf20Sopenharmony_ci} 17408c2ecf20Sopenharmony_ci 17418c2ecf20Sopenharmony_cistatic int prof_rc_query(struct dvb_usb_device *d) 17428c2ecf20Sopenharmony_ci{ 17438c2ecf20Sopenharmony_ci u8 key[2]; 17448c2ecf20Sopenharmony_ci struct i2c_msg msg = { 17458c2ecf20Sopenharmony_ci .addr = DW2102_RC_QUERY, 17468c2ecf20Sopenharmony_ci .flags = I2C_M_RD, 17478c2ecf20Sopenharmony_ci .buf = key, 17488c2ecf20Sopenharmony_ci .len = 2 17498c2ecf20Sopenharmony_ci }; 17508c2ecf20Sopenharmony_ci 17518c2ecf20Sopenharmony_ci if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) { 17528c2ecf20Sopenharmony_ci if (msg.buf[0] != 0xff) { 17538c2ecf20Sopenharmony_ci deb_rc("%s: rc code: %x, %x\n", 17548c2ecf20Sopenharmony_ci __func__, key[0], key[1]); 17558c2ecf20Sopenharmony_ci rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, key[0] ^ 0xff, 17568c2ecf20Sopenharmony_ci 0); 17578c2ecf20Sopenharmony_ci } 17588c2ecf20Sopenharmony_ci } 17598c2ecf20Sopenharmony_ci 17608c2ecf20Sopenharmony_ci return 0; 17618c2ecf20Sopenharmony_ci} 17628c2ecf20Sopenharmony_ci 17638c2ecf20Sopenharmony_cistatic int su3000_rc_query(struct dvb_usb_device *d) 17648c2ecf20Sopenharmony_ci{ 17658c2ecf20Sopenharmony_ci u8 key[2]; 17668c2ecf20Sopenharmony_ci struct i2c_msg msg = { 17678c2ecf20Sopenharmony_ci .addr = DW2102_RC_QUERY, 17688c2ecf20Sopenharmony_ci .flags = I2C_M_RD, 17698c2ecf20Sopenharmony_ci .buf = key, 17708c2ecf20Sopenharmony_ci .len = 2 17718c2ecf20Sopenharmony_ci }; 17728c2ecf20Sopenharmony_ci 17738c2ecf20Sopenharmony_ci if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) { 17748c2ecf20Sopenharmony_ci if (msg.buf[0] != 0xff) { 17758c2ecf20Sopenharmony_ci deb_rc("%s: rc code: %x, %x\n", 17768c2ecf20Sopenharmony_ci __func__, key[0], key[1]); 17778c2ecf20Sopenharmony_ci rc_keydown(d->rc_dev, RC_PROTO_RC5, 17788c2ecf20Sopenharmony_ci RC_SCANCODE_RC5(key[1], key[0]), 0); 17798c2ecf20Sopenharmony_ci } 17808c2ecf20Sopenharmony_ci } 17818c2ecf20Sopenharmony_ci 17828c2ecf20Sopenharmony_ci return 0; 17838c2ecf20Sopenharmony_ci} 17848c2ecf20Sopenharmony_ci 17858c2ecf20Sopenharmony_cienum dw2102_table_entry { 17868c2ecf20Sopenharmony_ci CYPRESS_DW2102, 17878c2ecf20Sopenharmony_ci CYPRESS_DW2101, 17888c2ecf20Sopenharmony_ci CYPRESS_DW2104, 17898c2ecf20Sopenharmony_ci TEVII_S650, 17908c2ecf20Sopenharmony_ci TERRATEC_CINERGY_S, 17918c2ecf20Sopenharmony_ci CYPRESS_DW3101, 17928c2ecf20Sopenharmony_ci TEVII_S630, 17938c2ecf20Sopenharmony_ci PROF_1100, 17948c2ecf20Sopenharmony_ci TEVII_S660, 17958c2ecf20Sopenharmony_ci PROF_7500, 17968c2ecf20Sopenharmony_ci GENIATECH_SU3000, 17978c2ecf20Sopenharmony_ci TERRATEC_CINERGY_S2, 17988c2ecf20Sopenharmony_ci TEVII_S480_1, 17998c2ecf20Sopenharmony_ci TEVII_S480_2, 18008c2ecf20Sopenharmony_ci X3M_SPC1400HD, 18018c2ecf20Sopenharmony_ci TEVII_S421, 18028c2ecf20Sopenharmony_ci TEVII_S632, 18038c2ecf20Sopenharmony_ci TERRATEC_CINERGY_S2_R2, 18048c2ecf20Sopenharmony_ci TERRATEC_CINERGY_S2_R3, 18058c2ecf20Sopenharmony_ci TERRATEC_CINERGY_S2_R4, 18068c2ecf20Sopenharmony_ci TERRATEC_CINERGY_S2_1, 18078c2ecf20Sopenharmony_ci TERRATEC_CINERGY_S2_2, 18088c2ecf20Sopenharmony_ci GOTVIEW_SAT_HD, 18098c2ecf20Sopenharmony_ci GENIATECH_T220, 18108c2ecf20Sopenharmony_ci TECHNOTREND_S2_4600, 18118c2ecf20Sopenharmony_ci TEVII_S482_1, 18128c2ecf20Sopenharmony_ci TEVII_S482_2, 18138c2ecf20Sopenharmony_ci TERRATEC_CINERGY_S2_BOX, 18148c2ecf20Sopenharmony_ci TEVII_S662 18158c2ecf20Sopenharmony_ci}; 18168c2ecf20Sopenharmony_ci 18178c2ecf20Sopenharmony_cistatic struct usb_device_id dw2102_table[] = { 18188c2ecf20Sopenharmony_ci [CYPRESS_DW2102] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, 18198c2ecf20Sopenharmony_ci [CYPRESS_DW2101] = {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, 18208c2ecf20Sopenharmony_ci [CYPRESS_DW2104] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)}, 18218c2ecf20Sopenharmony_ci [TEVII_S650] = {USB_DEVICE(0x9022, USB_PID_TEVII_S650)}, 18228c2ecf20Sopenharmony_ci [TERRATEC_CINERGY_S] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S)}, 18238c2ecf20Sopenharmony_ci [CYPRESS_DW3101] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)}, 18248c2ecf20Sopenharmony_ci [TEVII_S630] = {USB_DEVICE(0x9022, USB_PID_TEVII_S630)}, 18258c2ecf20Sopenharmony_ci [PROF_1100] = {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, 18268c2ecf20Sopenharmony_ci [TEVII_S660] = {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, 18278c2ecf20Sopenharmony_ci [PROF_7500] = {USB_DEVICE(0x3034, 0x7500)}, 18288c2ecf20Sopenharmony_ci [GENIATECH_SU3000] = {USB_DEVICE(0x1f4d, 0x3000)}, 18298c2ecf20Sopenharmony_ci [TERRATEC_CINERGY_S2] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R1)}, 18308c2ecf20Sopenharmony_ci [TEVII_S480_1] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)}, 18318c2ecf20Sopenharmony_ci [TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)}, 18328c2ecf20Sopenharmony_ci [X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)}, 18338c2ecf20Sopenharmony_ci [TEVII_S421] = {USB_DEVICE(0x9022, USB_PID_TEVII_S421)}, 18348c2ecf20Sopenharmony_ci [TEVII_S632] = {USB_DEVICE(0x9022, USB_PID_TEVII_S632)}, 18358c2ecf20Sopenharmony_ci [TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, 18368c2ecf20Sopenharmony_ci USB_PID_TERRATEC_CINERGY_S2_R2)}, 18378c2ecf20Sopenharmony_ci [TERRATEC_CINERGY_S2_R3] = {USB_DEVICE(USB_VID_TERRATEC, 18388c2ecf20Sopenharmony_ci USB_PID_TERRATEC_CINERGY_S2_R3)}, 18398c2ecf20Sopenharmony_ci [TERRATEC_CINERGY_S2_R4] = {USB_DEVICE(USB_VID_TERRATEC, 18408c2ecf20Sopenharmony_ci USB_PID_TERRATEC_CINERGY_S2_R4)}, 18418c2ecf20Sopenharmony_ci [TERRATEC_CINERGY_S2_1] = {USB_DEVICE(USB_VID_TERRATEC_2, 18428c2ecf20Sopenharmony_ci USB_PID_TERRATEC_CINERGY_S2_1)}, 18438c2ecf20Sopenharmony_ci [TERRATEC_CINERGY_S2_2] = {USB_DEVICE(USB_VID_TERRATEC_2, 18448c2ecf20Sopenharmony_ci USB_PID_TERRATEC_CINERGY_S2_2)}, 18458c2ecf20Sopenharmony_ci [GOTVIEW_SAT_HD] = {USB_DEVICE(0x1FE1, USB_PID_GOTVIEW_SAT_HD)}, 18468c2ecf20Sopenharmony_ci [GENIATECH_T220] = {USB_DEVICE(0x1f4d, 0xD220)}, 18478c2ecf20Sopenharmony_ci [TECHNOTREND_S2_4600] = {USB_DEVICE(USB_VID_TECHNOTREND, 18488c2ecf20Sopenharmony_ci USB_PID_TECHNOTREND_CONNECT_S2_4600)}, 18498c2ecf20Sopenharmony_ci [TEVII_S482_1] = {USB_DEVICE(0x9022, 0xd483)}, 18508c2ecf20Sopenharmony_ci [TEVII_S482_2] = {USB_DEVICE(0x9022, 0xd484)}, 18518c2ecf20Sopenharmony_ci [TERRATEC_CINERGY_S2_BOX] = {USB_DEVICE(USB_VID_TERRATEC, 0x0105)}, 18528c2ecf20Sopenharmony_ci [TEVII_S662] = {USB_DEVICE(0x9022, USB_PID_TEVII_S662)}, 18538c2ecf20Sopenharmony_ci { } 18548c2ecf20Sopenharmony_ci}; 18558c2ecf20Sopenharmony_ci 18568c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(usb, dw2102_table); 18578c2ecf20Sopenharmony_ci 18588c2ecf20Sopenharmony_cistatic int dw2102_load_firmware(struct usb_device *dev, 18598c2ecf20Sopenharmony_ci const struct firmware *frmwr) 18608c2ecf20Sopenharmony_ci{ 18618c2ecf20Sopenharmony_ci u8 *b, *p; 18628c2ecf20Sopenharmony_ci int ret = 0, i; 18638c2ecf20Sopenharmony_ci u8 reset; 18648c2ecf20Sopenharmony_ci u8 reset16[] = {0, 0, 0, 0, 0, 0, 0}; 18658c2ecf20Sopenharmony_ci const struct firmware *fw; 18668c2ecf20Sopenharmony_ci 18678c2ecf20Sopenharmony_ci switch (le16_to_cpu(dev->descriptor.idProduct)) { 18688c2ecf20Sopenharmony_ci case 0x2101: 18698c2ecf20Sopenharmony_ci ret = request_firmware(&fw, DW2101_FIRMWARE, &dev->dev); 18708c2ecf20Sopenharmony_ci if (ret != 0) { 18718c2ecf20Sopenharmony_ci err(err_str, DW2101_FIRMWARE); 18728c2ecf20Sopenharmony_ci return ret; 18738c2ecf20Sopenharmony_ci } 18748c2ecf20Sopenharmony_ci break; 18758c2ecf20Sopenharmony_ci default: 18768c2ecf20Sopenharmony_ci fw = frmwr; 18778c2ecf20Sopenharmony_ci break; 18788c2ecf20Sopenharmony_ci } 18798c2ecf20Sopenharmony_ci info("start downloading DW210X firmware"); 18808c2ecf20Sopenharmony_ci p = kmalloc(fw->size, GFP_KERNEL); 18818c2ecf20Sopenharmony_ci reset = 1; 18828c2ecf20Sopenharmony_ci /*stop the CPU*/ 18838c2ecf20Sopenharmony_ci dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG); 18848c2ecf20Sopenharmony_ci dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG); 18858c2ecf20Sopenharmony_ci 18868c2ecf20Sopenharmony_ci if (p != NULL) { 18878c2ecf20Sopenharmony_ci memcpy(p, fw->data, fw->size); 18888c2ecf20Sopenharmony_ci for (i = 0; i < fw->size; i += 0x40) { 18898c2ecf20Sopenharmony_ci b = (u8 *) p + i; 18908c2ecf20Sopenharmony_ci if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40, 18918c2ecf20Sopenharmony_ci DW210X_WRITE_MSG) != 0x40) { 18928c2ecf20Sopenharmony_ci err("error while transferring firmware"); 18938c2ecf20Sopenharmony_ci ret = -EINVAL; 18948c2ecf20Sopenharmony_ci break; 18958c2ecf20Sopenharmony_ci } 18968c2ecf20Sopenharmony_ci } 18978c2ecf20Sopenharmony_ci /* restart the CPU */ 18988c2ecf20Sopenharmony_ci reset = 0; 18998c2ecf20Sopenharmony_ci if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, 19008c2ecf20Sopenharmony_ci DW210X_WRITE_MSG) != 1) { 19018c2ecf20Sopenharmony_ci err("could not restart the USB controller CPU."); 19028c2ecf20Sopenharmony_ci ret = -EINVAL; 19038c2ecf20Sopenharmony_ci } 19048c2ecf20Sopenharmony_ci if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, 19058c2ecf20Sopenharmony_ci DW210X_WRITE_MSG) != 1) { 19068c2ecf20Sopenharmony_ci err("could not restart the USB controller CPU."); 19078c2ecf20Sopenharmony_ci ret = -EINVAL; 19088c2ecf20Sopenharmony_ci } 19098c2ecf20Sopenharmony_ci /* init registers */ 19108c2ecf20Sopenharmony_ci switch (le16_to_cpu(dev->descriptor.idProduct)) { 19118c2ecf20Sopenharmony_ci case USB_PID_TEVII_S650: 19128c2ecf20Sopenharmony_ci dw2104_properties.rc.core.rc_codes = RC_MAP_TEVII_NEC; 19138c2ecf20Sopenharmony_ci fallthrough; 19148c2ecf20Sopenharmony_ci case USB_PID_DW2104: 19158c2ecf20Sopenharmony_ci reset = 1; 19168c2ecf20Sopenharmony_ci dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1, 19178c2ecf20Sopenharmony_ci DW210X_WRITE_MSG); 19188c2ecf20Sopenharmony_ci fallthrough; 19198c2ecf20Sopenharmony_ci case USB_PID_DW3101: 19208c2ecf20Sopenharmony_ci reset = 0; 19218c2ecf20Sopenharmony_ci dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, 19228c2ecf20Sopenharmony_ci DW210X_WRITE_MSG); 19238c2ecf20Sopenharmony_ci break; 19248c2ecf20Sopenharmony_ci case USB_PID_TERRATEC_CINERGY_S: 19258c2ecf20Sopenharmony_ci case USB_PID_DW2102: 19268c2ecf20Sopenharmony_ci dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, 19278c2ecf20Sopenharmony_ci DW210X_WRITE_MSG); 19288c2ecf20Sopenharmony_ci dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2, 19298c2ecf20Sopenharmony_ci DW210X_READ_MSG); 19308c2ecf20Sopenharmony_ci /* check STV0299 frontend */ 19318c2ecf20Sopenharmony_ci dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2, 19328c2ecf20Sopenharmony_ci DW210X_READ_MSG); 19338c2ecf20Sopenharmony_ci if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) { 19348c2ecf20Sopenharmony_ci dw2102_properties.i2c_algo = &dw2102_i2c_algo; 19358c2ecf20Sopenharmony_ci dw2102_properties.adapter->fe[0].tuner_attach = &dw2102_tuner_attach; 19368c2ecf20Sopenharmony_ci break; 19378c2ecf20Sopenharmony_ci } else { 19388c2ecf20Sopenharmony_ci /* check STV0288 frontend */ 19398c2ecf20Sopenharmony_ci reset16[0] = 0xd0; 19408c2ecf20Sopenharmony_ci reset16[1] = 1; 19418c2ecf20Sopenharmony_ci reset16[2] = 0; 19428c2ecf20Sopenharmony_ci dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3, 19438c2ecf20Sopenharmony_ci DW210X_WRITE_MSG); 19448c2ecf20Sopenharmony_ci dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3, 19458c2ecf20Sopenharmony_ci DW210X_READ_MSG); 19468c2ecf20Sopenharmony_ci if (reset16[2] == 0x11) { 19478c2ecf20Sopenharmony_ci dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo; 19488c2ecf20Sopenharmony_ci break; 19498c2ecf20Sopenharmony_ci } 19508c2ecf20Sopenharmony_ci } 19518c2ecf20Sopenharmony_ci fallthrough; 19528c2ecf20Sopenharmony_ci case 0x2101: 19538c2ecf20Sopenharmony_ci dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2, 19548c2ecf20Sopenharmony_ci DW210X_READ_MSG); 19558c2ecf20Sopenharmony_ci dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7, 19568c2ecf20Sopenharmony_ci DW210X_READ_MSG); 19578c2ecf20Sopenharmony_ci dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7, 19588c2ecf20Sopenharmony_ci DW210X_READ_MSG); 19598c2ecf20Sopenharmony_ci dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2, 19608c2ecf20Sopenharmony_ci DW210X_READ_MSG); 19618c2ecf20Sopenharmony_ci break; 19628c2ecf20Sopenharmony_ci } 19638c2ecf20Sopenharmony_ci 19648c2ecf20Sopenharmony_ci msleep(100); 19658c2ecf20Sopenharmony_ci kfree(p); 19668c2ecf20Sopenharmony_ci } 19678c2ecf20Sopenharmony_ci 19688c2ecf20Sopenharmony_ci if (le16_to_cpu(dev->descriptor.idProduct) == 0x2101) 19698c2ecf20Sopenharmony_ci release_firmware(fw); 19708c2ecf20Sopenharmony_ci return ret; 19718c2ecf20Sopenharmony_ci} 19728c2ecf20Sopenharmony_ci 19738c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties dw2102_properties = { 19748c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 19758c2ecf20Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 19768c2ecf20Sopenharmony_ci .firmware = DW2102_FIRMWARE, 19778c2ecf20Sopenharmony_ci .no_reconnect = 1, 19788c2ecf20Sopenharmony_ci 19798c2ecf20Sopenharmony_ci .i2c_algo = &dw2102_serit_i2c_algo, 19808c2ecf20Sopenharmony_ci 19818c2ecf20Sopenharmony_ci .rc.core = { 19828c2ecf20Sopenharmony_ci .rc_interval = 150, 19838c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_DM1105_NEC, 19848c2ecf20Sopenharmony_ci .module_name = "dw2102", 19858c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 19868c2ecf20Sopenharmony_ci .rc_query = dw2102_rc_query, 19878c2ecf20Sopenharmony_ci }, 19888c2ecf20Sopenharmony_ci 19898c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x81, 19908c2ecf20Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 19918c2ecf20Sopenharmony_ci .num_adapters = 1, 19928c2ecf20Sopenharmony_ci .download_firmware = dw2102_load_firmware, 19938c2ecf20Sopenharmony_ci .read_mac_address = dw210x_read_mac_address, 19948c2ecf20Sopenharmony_ci .adapter = { 19958c2ecf20Sopenharmony_ci { 19968c2ecf20Sopenharmony_ci .num_frontends = 1, 19978c2ecf20Sopenharmony_ci .fe = {{ 19988c2ecf20Sopenharmony_ci .frontend_attach = dw2102_frontend_attach, 19998c2ecf20Sopenharmony_ci .stream = { 20008c2ecf20Sopenharmony_ci .type = USB_BULK, 20018c2ecf20Sopenharmony_ci .count = 8, 20028c2ecf20Sopenharmony_ci .endpoint = 0x82, 20038c2ecf20Sopenharmony_ci .u = { 20048c2ecf20Sopenharmony_ci .bulk = { 20058c2ecf20Sopenharmony_ci .buffersize = 4096, 20068c2ecf20Sopenharmony_ci } 20078c2ecf20Sopenharmony_ci } 20088c2ecf20Sopenharmony_ci }, 20098c2ecf20Sopenharmony_ci }}, 20108c2ecf20Sopenharmony_ci } 20118c2ecf20Sopenharmony_ci }, 20128c2ecf20Sopenharmony_ci .num_device_descs = 3, 20138c2ecf20Sopenharmony_ci .devices = { 20148c2ecf20Sopenharmony_ci {"DVBWorld DVB-S 2102 USB2.0", 20158c2ecf20Sopenharmony_ci {&dw2102_table[CYPRESS_DW2102], NULL}, 20168c2ecf20Sopenharmony_ci {NULL}, 20178c2ecf20Sopenharmony_ci }, 20188c2ecf20Sopenharmony_ci {"DVBWorld DVB-S 2101 USB2.0", 20198c2ecf20Sopenharmony_ci {&dw2102_table[CYPRESS_DW2101], NULL}, 20208c2ecf20Sopenharmony_ci {NULL}, 20218c2ecf20Sopenharmony_ci }, 20228c2ecf20Sopenharmony_ci {"TerraTec Cinergy S USB", 20238c2ecf20Sopenharmony_ci {&dw2102_table[TERRATEC_CINERGY_S], NULL}, 20248c2ecf20Sopenharmony_ci {NULL}, 20258c2ecf20Sopenharmony_ci }, 20268c2ecf20Sopenharmony_ci } 20278c2ecf20Sopenharmony_ci}; 20288c2ecf20Sopenharmony_ci 20298c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties dw2104_properties = { 20308c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 20318c2ecf20Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 20328c2ecf20Sopenharmony_ci .firmware = DW2104_FIRMWARE, 20338c2ecf20Sopenharmony_ci .no_reconnect = 1, 20348c2ecf20Sopenharmony_ci 20358c2ecf20Sopenharmony_ci .i2c_algo = &dw2104_i2c_algo, 20368c2ecf20Sopenharmony_ci .rc.core = { 20378c2ecf20Sopenharmony_ci .rc_interval = 150, 20388c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_DM1105_NEC, 20398c2ecf20Sopenharmony_ci .module_name = "dw2102", 20408c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 20418c2ecf20Sopenharmony_ci .rc_query = dw2102_rc_query, 20428c2ecf20Sopenharmony_ci }, 20438c2ecf20Sopenharmony_ci 20448c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x81, 20458c2ecf20Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 20468c2ecf20Sopenharmony_ci .num_adapters = 1, 20478c2ecf20Sopenharmony_ci .download_firmware = dw2102_load_firmware, 20488c2ecf20Sopenharmony_ci .read_mac_address = dw210x_read_mac_address, 20498c2ecf20Sopenharmony_ci .adapter = { 20508c2ecf20Sopenharmony_ci { 20518c2ecf20Sopenharmony_ci .num_frontends = 1, 20528c2ecf20Sopenharmony_ci .fe = {{ 20538c2ecf20Sopenharmony_ci .frontend_attach = dw2104_frontend_attach, 20548c2ecf20Sopenharmony_ci .stream = { 20558c2ecf20Sopenharmony_ci .type = USB_BULK, 20568c2ecf20Sopenharmony_ci .count = 8, 20578c2ecf20Sopenharmony_ci .endpoint = 0x82, 20588c2ecf20Sopenharmony_ci .u = { 20598c2ecf20Sopenharmony_ci .bulk = { 20608c2ecf20Sopenharmony_ci .buffersize = 4096, 20618c2ecf20Sopenharmony_ci } 20628c2ecf20Sopenharmony_ci } 20638c2ecf20Sopenharmony_ci }, 20648c2ecf20Sopenharmony_ci }}, 20658c2ecf20Sopenharmony_ci } 20668c2ecf20Sopenharmony_ci }, 20678c2ecf20Sopenharmony_ci .num_device_descs = 2, 20688c2ecf20Sopenharmony_ci .devices = { 20698c2ecf20Sopenharmony_ci { "DVBWorld DW2104 USB2.0", 20708c2ecf20Sopenharmony_ci {&dw2102_table[CYPRESS_DW2104], NULL}, 20718c2ecf20Sopenharmony_ci {NULL}, 20728c2ecf20Sopenharmony_ci }, 20738c2ecf20Sopenharmony_ci { "TeVii S650 USB2.0", 20748c2ecf20Sopenharmony_ci {&dw2102_table[TEVII_S650], NULL}, 20758c2ecf20Sopenharmony_ci {NULL}, 20768c2ecf20Sopenharmony_ci }, 20778c2ecf20Sopenharmony_ci } 20788c2ecf20Sopenharmony_ci}; 20798c2ecf20Sopenharmony_ci 20808c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties dw3101_properties = { 20818c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 20828c2ecf20Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 20838c2ecf20Sopenharmony_ci .firmware = DW3101_FIRMWARE, 20848c2ecf20Sopenharmony_ci .no_reconnect = 1, 20858c2ecf20Sopenharmony_ci 20868c2ecf20Sopenharmony_ci .i2c_algo = &dw3101_i2c_algo, 20878c2ecf20Sopenharmony_ci .rc.core = { 20888c2ecf20Sopenharmony_ci .rc_interval = 150, 20898c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_DM1105_NEC, 20908c2ecf20Sopenharmony_ci .module_name = "dw2102", 20918c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 20928c2ecf20Sopenharmony_ci .rc_query = dw2102_rc_query, 20938c2ecf20Sopenharmony_ci }, 20948c2ecf20Sopenharmony_ci 20958c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x81, 20968c2ecf20Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 20978c2ecf20Sopenharmony_ci .num_adapters = 1, 20988c2ecf20Sopenharmony_ci .download_firmware = dw2102_load_firmware, 20998c2ecf20Sopenharmony_ci .read_mac_address = dw210x_read_mac_address, 21008c2ecf20Sopenharmony_ci .adapter = { 21018c2ecf20Sopenharmony_ci { 21028c2ecf20Sopenharmony_ci .num_frontends = 1, 21038c2ecf20Sopenharmony_ci .fe = {{ 21048c2ecf20Sopenharmony_ci .frontend_attach = dw3101_frontend_attach, 21058c2ecf20Sopenharmony_ci .tuner_attach = dw3101_tuner_attach, 21068c2ecf20Sopenharmony_ci .stream = { 21078c2ecf20Sopenharmony_ci .type = USB_BULK, 21088c2ecf20Sopenharmony_ci .count = 8, 21098c2ecf20Sopenharmony_ci .endpoint = 0x82, 21108c2ecf20Sopenharmony_ci .u = { 21118c2ecf20Sopenharmony_ci .bulk = { 21128c2ecf20Sopenharmony_ci .buffersize = 4096, 21138c2ecf20Sopenharmony_ci } 21148c2ecf20Sopenharmony_ci } 21158c2ecf20Sopenharmony_ci }, 21168c2ecf20Sopenharmony_ci }}, 21178c2ecf20Sopenharmony_ci } 21188c2ecf20Sopenharmony_ci }, 21198c2ecf20Sopenharmony_ci .num_device_descs = 1, 21208c2ecf20Sopenharmony_ci .devices = { 21218c2ecf20Sopenharmony_ci { "DVBWorld DVB-C 3101 USB2.0", 21228c2ecf20Sopenharmony_ci {&dw2102_table[CYPRESS_DW3101], NULL}, 21238c2ecf20Sopenharmony_ci {NULL}, 21248c2ecf20Sopenharmony_ci }, 21258c2ecf20Sopenharmony_ci } 21268c2ecf20Sopenharmony_ci}; 21278c2ecf20Sopenharmony_ci 21288c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties s6x0_properties = { 21298c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 21308c2ecf20Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 21318c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct dw2102_state), 21328c2ecf20Sopenharmony_ci .firmware = S630_FIRMWARE, 21338c2ecf20Sopenharmony_ci .no_reconnect = 1, 21348c2ecf20Sopenharmony_ci 21358c2ecf20Sopenharmony_ci .i2c_algo = &s6x0_i2c_algo, 21368c2ecf20Sopenharmony_ci .rc.core = { 21378c2ecf20Sopenharmony_ci .rc_interval = 150, 21388c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_TEVII_NEC, 21398c2ecf20Sopenharmony_ci .module_name = "dw2102", 21408c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 21418c2ecf20Sopenharmony_ci .rc_query = dw2102_rc_query, 21428c2ecf20Sopenharmony_ci }, 21438c2ecf20Sopenharmony_ci 21448c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x81, 21458c2ecf20Sopenharmony_ci .num_adapters = 1, 21468c2ecf20Sopenharmony_ci .download_firmware = dw2102_load_firmware, 21478c2ecf20Sopenharmony_ci .read_mac_address = s6x0_read_mac_address, 21488c2ecf20Sopenharmony_ci .adapter = { 21498c2ecf20Sopenharmony_ci { 21508c2ecf20Sopenharmony_ci .num_frontends = 1, 21518c2ecf20Sopenharmony_ci .fe = {{ 21528c2ecf20Sopenharmony_ci .frontend_attach = zl100313_frontend_attach, 21538c2ecf20Sopenharmony_ci .stream = { 21548c2ecf20Sopenharmony_ci .type = USB_BULK, 21558c2ecf20Sopenharmony_ci .count = 8, 21568c2ecf20Sopenharmony_ci .endpoint = 0x82, 21578c2ecf20Sopenharmony_ci .u = { 21588c2ecf20Sopenharmony_ci .bulk = { 21598c2ecf20Sopenharmony_ci .buffersize = 4096, 21608c2ecf20Sopenharmony_ci } 21618c2ecf20Sopenharmony_ci } 21628c2ecf20Sopenharmony_ci }, 21638c2ecf20Sopenharmony_ci }}, 21648c2ecf20Sopenharmony_ci } 21658c2ecf20Sopenharmony_ci }, 21668c2ecf20Sopenharmony_ci .num_device_descs = 1, 21678c2ecf20Sopenharmony_ci .devices = { 21688c2ecf20Sopenharmony_ci {"TeVii S630 USB", 21698c2ecf20Sopenharmony_ci {&dw2102_table[TEVII_S630], NULL}, 21708c2ecf20Sopenharmony_ci {NULL}, 21718c2ecf20Sopenharmony_ci }, 21728c2ecf20Sopenharmony_ci } 21738c2ecf20Sopenharmony_ci}; 21748c2ecf20Sopenharmony_ci 21758c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties p1100_properties = { 21768c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 21778c2ecf20Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 21788c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct dw2102_state), 21798c2ecf20Sopenharmony_ci .firmware = P1100_FIRMWARE, 21808c2ecf20Sopenharmony_ci .no_reconnect = 1, 21818c2ecf20Sopenharmony_ci 21828c2ecf20Sopenharmony_ci .i2c_algo = &s6x0_i2c_algo, 21838c2ecf20Sopenharmony_ci .rc.core = { 21848c2ecf20Sopenharmony_ci .rc_interval = 150, 21858c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_TBS_NEC, 21868c2ecf20Sopenharmony_ci .module_name = "dw2102", 21878c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 21888c2ecf20Sopenharmony_ci .rc_query = prof_rc_query, 21898c2ecf20Sopenharmony_ci }, 21908c2ecf20Sopenharmony_ci 21918c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x81, 21928c2ecf20Sopenharmony_ci .num_adapters = 1, 21938c2ecf20Sopenharmony_ci .download_firmware = dw2102_load_firmware, 21948c2ecf20Sopenharmony_ci .read_mac_address = s6x0_read_mac_address, 21958c2ecf20Sopenharmony_ci .adapter = { 21968c2ecf20Sopenharmony_ci { 21978c2ecf20Sopenharmony_ci .num_frontends = 1, 21988c2ecf20Sopenharmony_ci .fe = {{ 21998c2ecf20Sopenharmony_ci .frontend_attach = stv0288_frontend_attach, 22008c2ecf20Sopenharmony_ci .stream = { 22018c2ecf20Sopenharmony_ci .type = USB_BULK, 22028c2ecf20Sopenharmony_ci .count = 8, 22038c2ecf20Sopenharmony_ci .endpoint = 0x82, 22048c2ecf20Sopenharmony_ci .u = { 22058c2ecf20Sopenharmony_ci .bulk = { 22068c2ecf20Sopenharmony_ci .buffersize = 4096, 22078c2ecf20Sopenharmony_ci } 22088c2ecf20Sopenharmony_ci } 22098c2ecf20Sopenharmony_ci }, 22108c2ecf20Sopenharmony_ci } }, 22118c2ecf20Sopenharmony_ci } 22128c2ecf20Sopenharmony_ci }, 22138c2ecf20Sopenharmony_ci .num_device_descs = 1, 22148c2ecf20Sopenharmony_ci .devices = { 22158c2ecf20Sopenharmony_ci {"Prof 1100 USB ", 22168c2ecf20Sopenharmony_ci {&dw2102_table[PROF_1100], NULL}, 22178c2ecf20Sopenharmony_ci {NULL}, 22188c2ecf20Sopenharmony_ci }, 22198c2ecf20Sopenharmony_ci } 22208c2ecf20Sopenharmony_ci}; 22218c2ecf20Sopenharmony_ci 22228c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties s660_properties = { 22238c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 22248c2ecf20Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 22258c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct dw2102_state), 22268c2ecf20Sopenharmony_ci .firmware = S660_FIRMWARE, 22278c2ecf20Sopenharmony_ci .no_reconnect = 1, 22288c2ecf20Sopenharmony_ci 22298c2ecf20Sopenharmony_ci .i2c_algo = &s6x0_i2c_algo, 22308c2ecf20Sopenharmony_ci .rc.core = { 22318c2ecf20Sopenharmony_ci .rc_interval = 150, 22328c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_TEVII_NEC, 22338c2ecf20Sopenharmony_ci .module_name = "dw2102", 22348c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 22358c2ecf20Sopenharmony_ci .rc_query = dw2102_rc_query, 22368c2ecf20Sopenharmony_ci }, 22378c2ecf20Sopenharmony_ci 22388c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x81, 22398c2ecf20Sopenharmony_ci .num_adapters = 1, 22408c2ecf20Sopenharmony_ci .download_firmware = dw2102_load_firmware, 22418c2ecf20Sopenharmony_ci .read_mac_address = s6x0_read_mac_address, 22428c2ecf20Sopenharmony_ci .adapter = { 22438c2ecf20Sopenharmony_ci { 22448c2ecf20Sopenharmony_ci .num_frontends = 1, 22458c2ecf20Sopenharmony_ci .fe = {{ 22468c2ecf20Sopenharmony_ci .frontend_attach = ds3000_frontend_attach, 22478c2ecf20Sopenharmony_ci .stream = { 22488c2ecf20Sopenharmony_ci .type = USB_BULK, 22498c2ecf20Sopenharmony_ci .count = 8, 22508c2ecf20Sopenharmony_ci .endpoint = 0x82, 22518c2ecf20Sopenharmony_ci .u = { 22528c2ecf20Sopenharmony_ci .bulk = { 22538c2ecf20Sopenharmony_ci .buffersize = 4096, 22548c2ecf20Sopenharmony_ci } 22558c2ecf20Sopenharmony_ci } 22568c2ecf20Sopenharmony_ci }, 22578c2ecf20Sopenharmony_ci } }, 22588c2ecf20Sopenharmony_ci } 22598c2ecf20Sopenharmony_ci }, 22608c2ecf20Sopenharmony_ci .num_device_descs = 3, 22618c2ecf20Sopenharmony_ci .devices = { 22628c2ecf20Sopenharmony_ci {"TeVii S660 USB", 22638c2ecf20Sopenharmony_ci {&dw2102_table[TEVII_S660], NULL}, 22648c2ecf20Sopenharmony_ci {NULL}, 22658c2ecf20Sopenharmony_ci }, 22668c2ecf20Sopenharmony_ci {"TeVii S480.1 USB", 22678c2ecf20Sopenharmony_ci {&dw2102_table[TEVII_S480_1], NULL}, 22688c2ecf20Sopenharmony_ci {NULL}, 22698c2ecf20Sopenharmony_ci }, 22708c2ecf20Sopenharmony_ci {"TeVii S480.2 USB", 22718c2ecf20Sopenharmony_ci {&dw2102_table[TEVII_S480_2], NULL}, 22728c2ecf20Sopenharmony_ci {NULL}, 22738c2ecf20Sopenharmony_ci }, 22748c2ecf20Sopenharmony_ci } 22758c2ecf20Sopenharmony_ci}; 22768c2ecf20Sopenharmony_ci 22778c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties p7500_properties = { 22788c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 22798c2ecf20Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 22808c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct dw2102_state), 22818c2ecf20Sopenharmony_ci .firmware = P7500_FIRMWARE, 22828c2ecf20Sopenharmony_ci .no_reconnect = 1, 22838c2ecf20Sopenharmony_ci 22848c2ecf20Sopenharmony_ci .i2c_algo = &s6x0_i2c_algo, 22858c2ecf20Sopenharmony_ci .rc.core = { 22868c2ecf20Sopenharmony_ci .rc_interval = 150, 22878c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_TBS_NEC, 22888c2ecf20Sopenharmony_ci .module_name = "dw2102", 22898c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 22908c2ecf20Sopenharmony_ci .rc_query = prof_rc_query, 22918c2ecf20Sopenharmony_ci }, 22928c2ecf20Sopenharmony_ci 22938c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x81, 22948c2ecf20Sopenharmony_ci .num_adapters = 1, 22958c2ecf20Sopenharmony_ci .download_firmware = dw2102_load_firmware, 22968c2ecf20Sopenharmony_ci .read_mac_address = s6x0_read_mac_address, 22978c2ecf20Sopenharmony_ci .adapter = { 22988c2ecf20Sopenharmony_ci { 22998c2ecf20Sopenharmony_ci .num_frontends = 1, 23008c2ecf20Sopenharmony_ci .fe = {{ 23018c2ecf20Sopenharmony_ci .frontend_attach = prof_7500_frontend_attach, 23028c2ecf20Sopenharmony_ci .stream = { 23038c2ecf20Sopenharmony_ci .type = USB_BULK, 23048c2ecf20Sopenharmony_ci .count = 8, 23058c2ecf20Sopenharmony_ci .endpoint = 0x82, 23068c2ecf20Sopenharmony_ci .u = { 23078c2ecf20Sopenharmony_ci .bulk = { 23088c2ecf20Sopenharmony_ci .buffersize = 4096, 23098c2ecf20Sopenharmony_ci } 23108c2ecf20Sopenharmony_ci } 23118c2ecf20Sopenharmony_ci }, 23128c2ecf20Sopenharmony_ci } }, 23138c2ecf20Sopenharmony_ci } 23148c2ecf20Sopenharmony_ci }, 23158c2ecf20Sopenharmony_ci .num_device_descs = 1, 23168c2ecf20Sopenharmony_ci .devices = { 23178c2ecf20Sopenharmony_ci {"Prof 7500 USB DVB-S2", 23188c2ecf20Sopenharmony_ci {&dw2102_table[PROF_7500], NULL}, 23198c2ecf20Sopenharmony_ci {NULL}, 23208c2ecf20Sopenharmony_ci }, 23218c2ecf20Sopenharmony_ci } 23228c2ecf20Sopenharmony_ci}; 23238c2ecf20Sopenharmony_ci 23248c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties su3000_properties = { 23258c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 23268c2ecf20Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 23278c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct dw2102_state), 23288c2ecf20Sopenharmony_ci .power_ctrl = su3000_power_ctrl, 23298c2ecf20Sopenharmony_ci .num_adapters = 1, 23308c2ecf20Sopenharmony_ci .identify_state = su3000_identify_state, 23318c2ecf20Sopenharmony_ci .i2c_algo = &su3000_i2c_algo, 23328c2ecf20Sopenharmony_ci 23338c2ecf20Sopenharmony_ci .rc.core = { 23348c2ecf20Sopenharmony_ci .rc_interval = 150, 23358c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_SU3000, 23368c2ecf20Sopenharmony_ci .module_name = "dw2102", 23378c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_RC5, 23388c2ecf20Sopenharmony_ci .rc_query = su3000_rc_query, 23398c2ecf20Sopenharmony_ci }, 23408c2ecf20Sopenharmony_ci 23418c2ecf20Sopenharmony_ci .read_mac_address = su3000_read_mac_address, 23428c2ecf20Sopenharmony_ci 23438c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 23448c2ecf20Sopenharmony_ci 23458c2ecf20Sopenharmony_ci .adapter = { 23468c2ecf20Sopenharmony_ci { 23478c2ecf20Sopenharmony_ci .num_frontends = 1, 23488c2ecf20Sopenharmony_ci .fe = {{ 23498c2ecf20Sopenharmony_ci .streaming_ctrl = su3000_streaming_ctrl, 23508c2ecf20Sopenharmony_ci .frontend_attach = su3000_frontend_attach, 23518c2ecf20Sopenharmony_ci .stream = { 23528c2ecf20Sopenharmony_ci .type = USB_BULK, 23538c2ecf20Sopenharmony_ci .count = 8, 23548c2ecf20Sopenharmony_ci .endpoint = 0x82, 23558c2ecf20Sopenharmony_ci .u = { 23568c2ecf20Sopenharmony_ci .bulk = { 23578c2ecf20Sopenharmony_ci .buffersize = 4096, 23588c2ecf20Sopenharmony_ci } 23598c2ecf20Sopenharmony_ci } 23608c2ecf20Sopenharmony_ci } 23618c2ecf20Sopenharmony_ci }}, 23628c2ecf20Sopenharmony_ci } 23638c2ecf20Sopenharmony_ci }, 23648c2ecf20Sopenharmony_ci .num_device_descs = 8, 23658c2ecf20Sopenharmony_ci .devices = { 23668c2ecf20Sopenharmony_ci { "SU3000HD DVB-S USB2.0", 23678c2ecf20Sopenharmony_ci { &dw2102_table[GENIATECH_SU3000], NULL }, 23688c2ecf20Sopenharmony_ci { NULL }, 23698c2ecf20Sopenharmony_ci }, 23708c2ecf20Sopenharmony_ci { "Terratec Cinergy S2 USB HD", 23718c2ecf20Sopenharmony_ci { &dw2102_table[TERRATEC_CINERGY_S2], NULL }, 23728c2ecf20Sopenharmony_ci { NULL }, 23738c2ecf20Sopenharmony_ci }, 23748c2ecf20Sopenharmony_ci { "X3M TV SPC1400HD PCI", 23758c2ecf20Sopenharmony_ci { &dw2102_table[X3M_SPC1400HD], NULL }, 23768c2ecf20Sopenharmony_ci { NULL }, 23778c2ecf20Sopenharmony_ci }, 23788c2ecf20Sopenharmony_ci { "Terratec Cinergy S2 USB HD Rev.2", 23798c2ecf20Sopenharmony_ci { &dw2102_table[TERRATEC_CINERGY_S2_R2], NULL }, 23808c2ecf20Sopenharmony_ci { NULL }, 23818c2ecf20Sopenharmony_ci }, 23828c2ecf20Sopenharmony_ci { "Terratec Cinergy S2 USB HD Rev.3", 23838c2ecf20Sopenharmony_ci { &dw2102_table[TERRATEC_CINERGY_S2_R3], NULL }, 23848c2ecf20Sopenharmony_ci { NULL }, 23858c2ecf20Sopenharmony_ci }, 23868c2ecf20Sopenharmony_ci { "Terratec Cinergy S2 PCIe Dual Port 1", 23878c2ecf20Sopenharmony_ci { &dw2102_table[TERRATEC_CINERGY_S2_1], NULL }, 23888c2ecf20Sopenharmony_ci { NULL }, 23898c2ecf20Sopenharmony_ci }, 23908c2ecf20Sopenharmony_ci { "Terratec Cinergy S2 PCIe Dual Port 2", 23918c2ecf20Sopenharmony_ci { &dw2102_table[TERRATEC_CINERGY_S2_2], NULL }, 23928c2ecf20Sopenharmony_ci { NULL }, 23938c2ecf20Sopenharmony_ci }, 23948c2ecf20Sopenharmony_ci { "GOTVIEW Satellite HD", 23958c2ecf20Sopenharmony_ci { &dw2102_table[GOTVIEW_SAT_HD], NULL }, 23968c2ecf20Sopenharmony_ci { NULL }, 23978c2ecf20Sopenharmony_ci }, 23988c2ecf20Sopenharmony_ci } 23998c2ecf20Sopenharmony_ci}; 24008c2ecf20Sopenharmony_ci 24018c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties s421_properties = { 24028c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 24038c2ecf20Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 24048c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct dw2102_state), 24058c2ecf20Sopenharmony_ci .power_ctrl = su3000_power_ctrl, 24068c2ecf20Sopenharmony_ci .num_adapters = 1, 24078c2ecf20Sopenharmony_ci .identify_state = su3000_identify_state, 24088c2ecf20Sopenharmony_ci .i2c_algo = &su3000_i2c_algo, 24098c2ecf20Sopenharmony_ci 24108c2ecf20Sopenharmony_ci .rc.core = { 24118c2ecf20Sopenharmony_ci .rc_interval = 150, 24128c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_SU3000, 24138c2ecf20Sopenharmony_ci .module_name = "dw2102", 24148c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_RC5, 24158c2ecf20Sopenharmony_ci .rc_query = su3000_rc_query, 24168c2ecf20Sopenharmony_ci }, 24178c2ecf20Sopenharmony_ci 24188c2ecf20Sopenharmony_ci .read_mac_address = su3000_read_mac_address, 24198c2ecf20Sopenharmony_ci 24208c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 24218c2ecf20Sopenharmony_ci 24228c2ecf20Sopenharmony_ci .adapter = { 24238c2ecf20Sopenharmony_ci { 24248c2ecf20Sopenharmony_ci .num_frontends = 1, 24258c2ecf20Sopenharmony_ci .fe = {{ 24268c2ecf20Sopenharmony_ci .streaming_ctrl = su3000_streaming_ctrl, 24278c2ecf20Sopenharmony_ci .frontend_attach = m88rs2000_frontend_attach, 24288c2ecf20Sopenharmony_ci .stream = { 24298c2ecf20Sopenharmony_ci .type = USB_BULK, 24308c2ecf20Sopenharmony_ci .count = 8, 24318c2ecf20Sopenharmony_ci .endpoint = 0x82, 24328c2ecf20Sopenharmony_ci .u = { 24338c2ecf20Sopenharmony_ci .bulk = { 24348c2ecf20Sopenharmony_ci .buffersize = 4096, 24358c2ecf20Sopenharmony_ci } 24368c2ecf20Sopenharmony_ci } 24378c2ecf20Sopenharmony_ci } 24388c2ecf20Sopenharmony_ci } }, 24398c2ecf20Sopenharmony_ci } 24408c2ecf20Sopenharmony_ci }, 24418c2ecf20Sopenharmony_ci .num_device_descs = 2, 24428c2ecf20Sopenharmony_ci .devices = { 24438c2ecf20Sopenharmony_ci { "TeVii S421 PCI", 24448c2ecf20Sopenharmony_ci { &dw2102_table[TEVII_S421], NULL }, 24458c2ecf20Sopenharmony_ci { NULL }, 24468c2ecf20Sopenharmony_ci }, 24478c2ecf20Sopenharmony_ci { "TeVii S632 USB", 24488c2ecf20Sopenharmony_ci { &dw2102_table[TEVII_S632], NULL }, 24498c2ecf20Sopenharmony_ci { NULL }, 24508c2ecf20Sopenharmony_ci }, 24518c2ecf20Sopenharmony_ci } 24528c2ecf20Sopenharmony_ci}; 24538c2ecf20Sopenharmony_ci 24548c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties t220_properties = { 24558c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 24568c2ecf20Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 24578c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct dw2102_state), 24588c2ecf20Sopenharmony_ci .power_ctrl = su3000_power_ctrl, 24598c2ecf20Sopenharmony_ci .num_adapters = 1, 24608c2ecf20Sopenharmony_ci .identify_state = su3000_identify_state, 24618c2ecf20Sopenharmony_ci .i2c_algo = &su3000_i2c_algo, 24628c2ecf20Sopenharmony_ci 24638c2ecf20Sopenharmony_ci .rc.core = { 24648c2ecf20Sopenharmony_ci .rc_interval = 150, 24658c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_SU3000, 24668c2ecf20Sopenharmony_ci .module_name = "dw2102", 24678c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_RC5, 24688c2ecf20Sopenharmony_ci .rc_query = su3000_rc_query, 24698c2ecf20Sopenharmony_ci }, 24708c2ecf20Sopenharmony_ci 24718c2ecf20Sopenharmony_ci .read_mac_address = su3000_read_mac_address, 24728c2ecf20Sopenharmony_ci 24738c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 24748c2ecf20Sopenharmony_ci 24758c2ecf20Sopenharmony_ci .adapter = { 24768c2ecf20Sopenharmony_ci { 24778c2ecf20Sopenharmony_ci .num_frontends = 1, 24788c2ecf20Sopenharmony_ci .fe = { { 24798c2ecf20Sopenharmony_ci .streaming_ctrl = su3000_streaming_ctrl, 24808c2ecf20Sopenharmony_ci .frontend_attach = t220_frontend_attach, 24818c2ecf20Sopenharmony_ci .stream = { 24828c2ecf20Sopenharmony_ci .type = USB_BULK, 24838c2ecf20Sopenharmony_ci .count = 8, 24848c2ecf20Sopenharmony_ci .endpoint = 0x82, 24858c2ecf20Sopenharmony_ci .u = { 24868c2ecf20Sopenharmony_ci .bulk = { 24878c2ecf20Sopenharmony_ci .buffersize = 4096, 24888c2ecf20Sopenharmony_ci } 24898c2ecf20Sopenharmony_ci } 24908c2ecf20Sopenharmony_ci } 24918c2ecf20Sopenharmony_ci } }, 24928c2ecf20Sopenharmony_ci } 24938c2ecf20Sopenharmony_ci }, 24948c2ecf20Sopenharmony_ci .num_device_descs = 1, 24958c2ecf20Sopenharmony_ci .devices = { 24968c2ecf20Sopenharmony_ci { "Geniatech T220 DVB-T/T2 USB2.0", 24978c2ecf20Sopenharmony_ci { &dw2102_table[GENIATECH_T220], NULL }, 24988c2ecf20Sopenharmony_ci { NULL }, 24998c2ecf20Sopenharmony_ci }, 25008c2ecf20Sopenharmony_ci } 25018c2ecf20Sopenharmony_ci}; 25028c2ecf20Sopenharmony_ci 25038c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties tt_s2_4600_properties = { 25048c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 25058c2ecf20Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 25068c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct dw2102_state), 25078c2ecf20Sopenharmony_ci .power_ctrl = su3000_power_ctrl, 25088c2ecf20Sopenharmony_ci .num_adapters = 1, 25098c2ecf20Sopenharmony_ci .identify_state = su3000_identify_state, 25108c2ecf20Sopenharmony_ci .i2c_algo = &su3000_i2c_algo, 25118c2ecf20Sopenharmony_ci 25128c2ecf20Sopenharmony_ci .rc.core = { 25138c2ecf20Sopenharmony_ci .rc_interval = 250, 25148c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_TT_1500, 25158c2ecf20Sopenharmony_ci .module_name = "dw2102", 25168c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_RC5, 25178c2ecf20Sopenharmony_ci .rc_query = su3000_rc_query, 25188c2ecf20Sopenharmony_ci }, 25198c2ecf20Sopenharmony_ci 25208c2ecf20Sopenharmony_ci .read_mac_address = su3000_read_mac_address, 25218c2ecf20Sopenharmony_ci 25228c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 25238c2ecf20Sopenharmony_ci 25248c2ecf20Sopenharmony_ci .adapter = { 25258c2ecf20Sopenharmony_ci { 25268c2ecf20Sopenharmony_ci .num_frontends = 1, 25278c2ecf20Sopenharmony_ci .fe = {{ 25288c2ecf20Sopenharmony_ci .streaming_ctrl = su3000_streaming_ctrl, 25298c2ecf20Sopenharmony_ci .frontend_attach = tt_s2_4600_frontend_attach, 25308c2ecf20Sopenharmony_ci .stream = { 25318c2ecf20Sopenharmony_ci .type = USB_BULK, 25328c2ecf20Sopenharmony_ci .count = 8, 25338c2ecf20Sopenharmony_ci .endpoint = 0x82, 25348c2ecf20Sopenharmony_ci .u = { 25358c2ecf20Sopenharmony_ci .bulk = { 25368c2ecf20Sopenharmony_ci .buffersize = 4096, 25378c2ecf20Sopenharmony_ci } 25388c2ecf20Sopenharmony_ci } 25398c2ecf20Sopenharmony_ci } 25408c2ecf20Sopenharmony_ci } }, 25418c2ecf20Sopenharmony_ci } 25428c2ecf20Sopenharmony_ci }, 25438c2ecf20Sopenharmony_ci .num_device_descs = 5, 25448c2ecf20Sopenharmony_ci .devices = { 25458c2ecf20Sopenharmony_ci { "TechnoTrend TT-connect S2-4600", 25468c2ecf20Sopenharmony_ci { &dw2102_table[TECHNOTREND_S2_4600], NULL }, 25478c2ecf20Sopenharmony_ci { NULL }, 25488c2ecf20Sopenharmony_ci }, 25498c2ecf20Sopenharmony_ci { "TeVii S482 (tuner 1)", 25508c2ecf20Sopenharmony_ci { &dw2102_table[TEVII_S482_1], NULL }, 25518c2ecf20Sopenharmony_ci { NULL }, 25528c2ecf20Sopenharmony_ci }, 25538c2ecf20Sopenharmony_ci { "TeVii S482 (tuner 2)", 25548c2ecf20Sopenharmony_ci { &dw2102_table[TEVII_S482_2], NULL }, 25558c2ecf20Sopenharmony_ci { NULL }, 25568c2ecf20Sopenharmony_ci }, 25578c2ecf20Sopenharmony_ci { "Terratec Cinergy S2 USB BOX", 25588c2ecf20Sopenharmony_ci { &dw2102_table[TERRATEC_CINERGY_S2_BOX], NULL }, 25598c2ecf20Sopenharmony_ci { NULL }, 25608c2ecf20Sopenharmony_ci }, 25618c2ecf20Sopenharmony_ci { "TeVii S662", 25628c2ecf20Sopenharmony_ci { &dw2102_table[TEVII_S662], NULL }, 25638c2ecf20Sopenharmony_ci { NULL }, 25648c2ecf20Sopenharmony_ci }, 25658c2ecf20Sopenharmony_ci } 25668c2ecf20Sopenharmony_ci}; 25678c2ecf20Sopenharmony_ci 25688c2ecf20Sopenharmony_cistatic int dw2102_probe(struct usb_interface *intf, 25698c2ecf20Sopenharmony_ci const struct usb_device_id *id) 25708c2ecf20Sopenharmony_ci{ 25718c2ecf20Sopenharmony_ci if (!(dvb_usb_device_init(intf, &dw2102_properties, 25728c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 25738c2ecf20Sopenharmony_ci dvb_usb_device_init(intf, &dw2104_properties, 25748c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 25758c2ecf20Sopenharmony_ci dvb_usb_device_init(intf, &dw3101_properties, 25768c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 25778c2ecf20Sopenharmony_ci dvb_usb_device_init(intf, &s6x0_properties, 25788c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 25798c2ecf20Sopenharmony_ci dvb_usb_device_init(intf, &p1100_properties, 25808c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 25818c2ecf20Sopenharmony_ci dvb_usb_device_init(intf, &s660_properties, 25828c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 25838c2ecf20Sopenharmony_ci dvb_usb_device_init(intf, &p7500_properties, 25848c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 25858c2ecf20Sopenharmony_ci dvb_usb_device_init(intf, &s421_properties, 25868c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 25878c2ecf20Sopenharmony_ci dvb_usb_device_init(intf, &su3000_properties, 25888c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 25898c2ecf20Sopenharmony_ci dvb_usb_device_init(intf, &t220_properties, 25908c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) && 25918c2ecf20Sopenharmony_ci dvb_usb_device_init(intf, &tt_s2_4600_properties, 25928c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr))) { 25938c2ecf20Sopenharmony_ci 25948c2ecf20Sopenharmony_ci return 0; 25958c2ecf20Sopenharmony_ci } 25968c2ecf20Sopenharmony_ci 25978c2ecf20Sopenharmony_ci return -ENODEV; 25988c2ecf20Sopenharmony_ci} 25998c2ecf20Sopenharmony_ci 26008c2ecf20Sopenharmony_cistatic void dw2102_disconnect(struct usb_interface *intf) 26018c2ecf20Sopenharmony_ci{ 26028c2ecf20Sopenharmony_ci struct dvb_usb_device *d = usb_get_intfdata(intf); 26038c2ecf20Sopenharmony_ci struct dw2102_state *st = (struct dw2102_state *)d->priv; 26048c2ecf20Sopenharmony_ci struct i2c_client *client; 26058c2ecf20Sopenharmony_ci 26068c2ecf20Sopenharmony_ci /* remove I2C client for tuner */ 26078c2ecf20Sopenharmony_ci client = st->i2c_client_tuner; 26088c2ecf20Sopenharmony_ci if (client) { 26098c2ecf20Sopenharmony_ci module_put(client->dev.driver->owner); 26108c2ecf20Sopenharmony_ci i2c_unregister_device(client); 26118c2ecf20Sopenharmony_ci } 26128c2ecf20Sopenharmony_ci 26138c2ecf20Sopenharmony_ci /* remove I2C client for demodulator */ 26148c2ecf20Sopenharmony_ci client = st->i2c_client_demod; 26158c2ecf20Sopenharmony_ci if (client) { 26168c2ecf20Sopenharmony_ci module_put(client->dev.driver->owner); 26178c2ecf20Sopenharmony_ci i2c_unregister_device(client); 26188c2ecf20Sopenharmony_ci } 26198c2ecf20Sopenharmony_ci 26208c2ecf20Sopenharmony_ci dvb_usb_device_exit(intf); 26218c2ecf20Sopenharmony_ci} 26228c2ecf20Sopenharmony_ci 26238c2ecf20Sopenharmony_cistatic struct usb_driver dw2102_driver = { 26248c2ecf20Sopenharmony_ci .name = "dw2102", 26258c2ecf20Sopenharmony_ci .probe = dw2102_probe, 26268c2ecf20Sopenharmony_ci .disconnect = dw2102_disconnect, 26278c2ecf20Sopenharmony_ci .id_table = dw2102_table, 26288c2ecf20Sopenharmony_ci}; 26298c2ecf20Sopenharmony_ci 26308c2ecf20Sopenharmony_cimodule_usb_driver(dw2102_driver); 26318c2ecf20Sopenharmony_ci 26328c2ecf20Sopenharmony_ciMODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); 26338c2ecf20Sopenharmony_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"); 26348c2ecf20Sopenharmony_ciMODULE_VERSION("0.1"); 26358c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 26368c2ecf20Sopenharmony_ciMODULE_FIRMWARE(DW2101_FIRMWARE); 26378c2ecf20Sopenharmony_ciMODULE_FIRMWARE(DW2102_FIRMWARE); 26388c2ecf20Sopenharmony_ciMODULE_FIRMWARE(DW2104_FIRMWARE); 26398c2ecf20Sopenharmony_ciMODULE_FIRMWARE(DW3101_FIRMWARE); 26408c2ecf20Sopenharmony_ciMODULE_FIRMWARE(S630_FIRMWARE); 26418c2ecf20Sopenharmony_ciMODULE_FIRMWARE(S660_FIRMWARE); 26428c2ecf20Sopenharmony_ciMODULE_FIRMWARE(P1100_FIRMWARE); 26438c2ecf20Sopenharmony_ciMODULE_FIRMWARE(P7500_FIRMWARE); 2644