18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* DVB USB compliant linux driver for Conexant USB reference design. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * The Conexant reference design I saw on their website was only for analogue 58c2ecf20Sopenharmony_ci * capturing (using the cx25842). The box I took to write this driver (reverse 68c2ecf20Sopenharmony_ci * engineered) is the one labeled Medion MD95700. In addition to the cx25842 78c2ecf20Sopenharmony_ci * for analogue capturing it also has a cx22702 DVB-T demodulator on the main 88c2ecf20Sopenharmony_ci * board. Besides it has a atiremote (X10) and a USB2.0 hub onboard. 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Maybe it is a little bit premature to call this driver cxusb, but I assume 118c2ecf20Sopenharmony_ci * the USB protocol is identical or at least inherited from the reference 128c2ecf20Sopenharmony_ci * design, so it can be reused for the "analogue-only" device (if it will 138c2ecf20Sopenharmony_ci * appear at all). 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@posteo.de) 178c2ecf20Sopenharmony_ci * Copyright (C) 2006 Michael Krufky (mkrufky@linuxtv.org) 188c2ecf20Sopenharmony_ci * Copyright (C) 2006, 2007 Chris Pascoe (c.pascoe@itee.uq.edu.au) 198c2ecf20Sopenharmony_ci * Copyright (C) 2011, 2017 Maciej S. Szmigiero (mail@maciej.szmigiero.name) 208c2ecf20Sopenharmony_ci * 218c2ecf20Sopenharmony_ci * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_ci#include <media/tuner.h> 248c2ecf20Sopenharmony_ci#include <linux/delay.h> 258c2ecf20Sopenharmony_ci#include <linux/device.h> 268c2ecf20Sopenharmony_ci#include <linux/kernel.h> 278c2ecf20Sopenharmony_ci#include <linux/slab.h> 288c2ecf20Sopenharmony_ci#include <linux/string.h> 298c2ecf20Sopenharmony_ci#include <linux/vmalloc.h> 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#include "cxusb.h" 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#include "cx22702.h" 348c2ecf20Sopenharmony_ci#include "lgdt330x.h" 358c2ecf20Sopenharmony_ci#include "mt352.h" 368c2ecf20Sopenharmony_ci#include "mt352_priv.h" 378c2ecf20Sopenharmony_ci#include "zl10353.h" 388c2ecf20Sopenharmony_ci#include "tuner-xc2028.h" 398c2ecf20Sopenharmony_ci#include "tuner-simple.h" 408c2ecf20Sopenharmony_ci#include "mxl5005s.h" 418c2ecf20Sopenharmony_ci#include "max2165.h" 428c2ecf20Sopenharmony_ci#include "dib7000p.h" 438c2ecf20Sopenharmony_ci#include "dib0070.h" 448c2ecf20Sopenharmony_ci#include "lgs8gxx.h" 458c2ecf20Sopenharmony_ci#include "atbm8830.h" 468c2ecf20Sopenharmony_ci#include "si2168.h" 478c2ecf20Sopenharmony_ci#include "si2157.h" 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci/* debug */ 508c2ecf20Sopenharmony_ciint dvb_usb_cxusb_debug; 518c2ecf20Sopenharmony_cimodule_param_named(debug, dvb_usb_cxusb_debug, int, 0644); 528c2ecf20Sopenharmony_ciMODULE_PARM_DESC(debug, "set debugging level (see cxusb.h)." 538c2ecf20Sopenharmony_ci DVB_USB_DEBUG_STATUS); 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ciDVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cienum cxusb_table_index { 588c2ecf20Sopenharmony_ci MEDION_MD95700, 598c2ecf20Sopenharmony_ci DVICO_BLUEBIRD_LG064F_COLD, 608c2ecf20Sopenharmony_ci DVICO_BLUEBIRD_LG064F_WARM, 618c2ecf20Sopenharmony_ci DVICO_BLUEBIRD_DUAL_1_COLD, 628c2ecf20Sopenharmony_ci DVICO_BLUEBIRD_DUAL_1_WARM, 638c2ecf20Sopenharmony_ci DVICO_BLUEBIRD_LGZ201_COLD, 648c2ecf20Sopenharmony_ci DVICO_BLUEBIRD_LGZ201_WARM, 658c2ecf20Sopenharmony_ci DVICO_BLUEBIRD_TH7579_COLD, 668c2ecf20Sopenharmony_ci DVICO_BLUEBIRD_TH7579_WARM, 678c2ecf20Sopenharmony_ci DIGITALNOW_BLUEBIRD_DUAL_1_COLD, 688c2ecf20Sopenharmony_ci DIGITALNOW_BLUEBIRD_DUAL_1_WARM, 698c2ecf20Sopenharmony_ci DVICO_BLUEBIRD_DUAL_2_COLD, 708c2ecf20Sopenharmony_ci DVICO_BLUEBIRD_DUAL_2_WARM, 718c2ecf20Sopenharmony_ci DVICO_BLUEBIRD_DUAL_4, 728c2ecf20Sopenharmony_ci DVICO_BLUEBIRD_DVB_T_NANO_2, 738c2ecf20Sopenharmony_ci DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM, 748c2ecf20Sopenharmony_ci AVERMEDIA_VOLAR_A868R, 758c2ecf20Sopenharmony_ci DVICO_BLUEBIRD_DUAL_4_REV_2, 768c2ecf20Sopenharmony_ci CONEXANT_D680_DMB, 778c2ecf20Sopenharmony_ci MYGICA_D689, 788c2ecf20Sopenharmony_ci NR__cxusb_table_index 798c2ecf20Sopenharmony_ci}; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cistatic struct usb_device_id cxusb_table[]; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ciint cxusb_ctrl_msg(struct dvb_usb_device *d, 848c2ecf20Sopenharmony_ci u8 cmd, const u8 *wbuf, int wlen, u8 *rbuf, int rlen) 858c2ecf20Sopenharmony_ci{ 868c2ecf20Sopenharmony_ci struct cxusb_state *st = d->priv; 878c2ecf20Sopenharmony_ci int ret; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci if (1 + wlen > MAX_XFER_SIZE) { 908c2ecf20Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", wlen); 918c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 928c2ecf20Sopenharmony_ci } 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci if (rlen > MAX_XFER_SIZE) { 958c2ecf20Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", rlen); 968c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 978c2ecf20Sopenharmony_ci } 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci mutex_lock(&d->data_mutex); 1008c2ecf20Sopenharmony_ci st->data[0] = cmd; 1018c2ecf20Sopenharmony_ci memcpy(&st->data[1], wbuf, wlen); 1028c2ecf20Sopenharmony_ci ret = dvb_usb_generic_rw(d, st->data, 1 + wlen, st->data, rlen, 0); 1038c2ecf20Sopenharmony_ci if (!ret && rbuf && rlen) 1048c2ecf20Sopenharmony_ci memcpy(rbuf, st->data, rlen); 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci mutex_unlock(&d->data_mutex); 1078c2ecf20Sopenharmony_ci return ret; 1088c2ecf20Sopenharmony_ci} 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci/* GPIO */ 1118c2ecf20Sopenharmony_cistatic void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff) 1128c2ecf20Sopenharmony_ci{ 1138c2ecf20Sopenharmony_ci struct cxusb_state *st = d->priv; 1148c2ecf20Sopenharmony_ci u8 o[2], i; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci if (st->gpio_write_state[GPIO_TUNER] == onoff && 1178c2ecf20Sopenharmony_ci !st->gpio_write_refresh[GPIO_TUNER]) 1188c2ecf20Sopenharmony_ci return; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci o[0] = GPIO_TUNER; 1218c2ecf20Sopenharmony_ci o[1] = onoff; 1228c2ecf20Sopenharmony_ci cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1); 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci if (i != 0x01) 1258c2ecf20Sopenharmony_ci dev_info(&d->udev->dev, "gpio_write failed.\n"); 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci st->gpio_write_state[GPIO_TUNER] = onoff; 1288c2ecf20Sopenharmony_ci st->gpio_write_refresh[GPIO_TUNER] = false; 1298c2ecf20Sopenharmony_ci} 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_cistatic int cxusb_bluebird_gpio_rw(struct dvb_usb_device *d, u8 changemask, 1328c2ecf20Sopenharmony_ci u8 newval) 1338c2ecf20Sopenharmony_ci{ 1348c2ecf20Sopenharmony_ci u8 o[2], gpio_state; 1358c2ecf20Sopenharmony_ci int rc; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci o[0] = 0xff & ~changemask; /* mask of bits to keep */ 1388c2ecf20Sopenharmony_ci o[1] = newval & changemask; /* new values for bits */ 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci rc = cxusb_ctrl_msg(d, CMD_BLUEBIRD_GPIO_RW, o, 2, &gpio_state, 1); 1418c2ecf20Sopenharmony_ci if (rc < 0 || (gpio_state & changemask) != (newval & changemask)) 1428c2ecf20Sopenharmony_ci dev_info(&d->udev->dev, "bluebird_gpio_write failed.\n"); 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci return rc < 0 ? rc : gpio_state; 1458c2ecf20Sopenharmony_ci} 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_cistatic void cxusb_bluebird_gpio_pulse(struct dvb_usb_device *d, u8 pin, int low) 1488c2ecf20Sopenharmony_ci{ 1498c2ecf20Sopenharmony_ci cxusb_bluebird_gpio_rw(d, pin, low ? 0 : pin); 1508c2ecf20Sopenharmony_ci msleep(5); 1518c2ecf20Sopenharmony_ci cxusb_bluebird_gpio_rw(d, pin, low ? pin : 0); 1528c2ecf20Sopenharmony_ci} 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_cistatic void cxusb_nano2_led(struct dvb_usb_device *d, int onoff) 1558c2ecf20Sopenharmony_ci{ 1568c2ecf20Sopenharmony_ci cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40); 1578c2ecf20Sopenharmony_ci} 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cistatic int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d, 1608c2ecf20Sopenharmony_ci u8 addr, int onoff) 1618c2ecf20Sopenharmony_ci{ 1628c2ecf20Sopenharmony_ci u8 o[2] = {addr, onoff}; 1638c2ecf20Sopenharmony_ci u8 i; 1648c2ecf20Sopenharmony_ci int rc; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1); 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci if (rc < 0) 1698c2ecf20Sopenharmony_ci return rc; 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci if (i == 0x01) 1728c2ecf20Sopenharmony_ci return 0; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci dev_info(&d->udev->dev, "gpio_write failed.\n"); 1758c2ecf20Sopenharmony_ci return -EIO; 1768c2ecf20Sopenharmony_ci} 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci/* I2C */ 1798c2ecf20Sopenharmony_cistatic int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], 1808c2ecf20Sopenharmony_ci int num) 1818c2ecf20Sopenharmony_ci{ 1828c2ecf20Sopenharmony_ci struct dvb_usb_device *d = i2c_get_adapdata(adap); 1838c2ecf20Sopenharmony_ci int ret; 1848c2ecf20Sopenharmony_ci int i; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 1878c2ecf20Sopenharmony_ci return -EAGAIN; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci for (i = 0; i < num; i++) { 1908c2ecf20Sopenharmony_ci if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_MEDION) 1918c2ecf20Sopenharmony_ci switch (msg[i].addr) { 1928c2ecf20Sopenharmony_ci case 0x63: 1938c2ecf20Sopenharmony_ci cxusb_gpio_tuner(d, 0); 1948c2ecf20Sopenharmony_ci break; 1958c2ecf20Sopenharmony_ci default: 1968c2ecf20Sopenharmony_ci cxusb_gpio_tuner(d, 1); 1978c2ecf20Sopenharmony_ci break; 1988c2ecf20Sopenharmony_ci } 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci if (msg[i].flags & I2C_M_RD) { 2018c2ecf20Sopenharmony_ci /* read only */ 2028c2ecf20Sopenharmony_ci u8 obuf[3], ibuf[MAX_XFER_SIZE]; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci if (1 + msg[i].len > sizeof(ibuf)) { 2058c2ecf20Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", 2068c2ecf20Sopenharmony_ci msg[i].len); 2078c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 2088c2ecf20Sopenharmony_ci goto unlock; 2098c2ecf20Sopenharmony_ci } 2108c2ecf20Sopenharmony_ci obuf[0] = 0; 2118c2ecf20Sopenharmony_ci obuf[1] = msg[i].len; 2128c2ecf20Sopenharmony_ci obuf[2] = msg[i].addr; 2138c2ecf20Sopenharmony_ci if (cxusb_ctrl_msg(d, CMD_I2C_READ, 2148c2ecf20Sopenharmony_ci obuf, 3, 2158c2ecf20Sopenharmony_ci ibuf, 1 + msg[i].len) < 0) { 2168c2ecf20Sopenharmony_ci warn("i2c read failed"); 2178c2ecf20Sopenharmony_ci break; 2188c2ecf20Sopenharmony_ci } 2198c2ecf20Sopenharmony_ci memcpy(msg[i].buf, &ibuf[1], msg[i].len); 2208c2ecf20Sopenharmony_ci } else if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD) && 2218c2ecf20Sopenharmony_ci msg[i].addr == msg[i + 1].addr) { 2228c2ecf20Sopenharmony_ci /* write to then read from same address */ 2238c2ecf20Sopenharmony_ci u8 obuf[MAX_XFER_SIZE], ibuf[MAX_XFER_SIZE]; 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci if (3 + msg[i].len > sizeof(obuf)) { 2268c2ecf20Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 2278c2ecf20Sopenharmony_ci msg[i].len); 2288c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 2298c2ecf20Sopenharmony_ci goto unlock; 2308c2ecf20Sopenharmony_ci } 2318c2ecf20Sopenharmony_ci if (1 + msg[i + 1].len > sizeof(ibuf)) { 2328c2ecf20Sopenharmony_ci warn("i2c rd: len=%d is too big!\n", 2338c2ecf20Sopenharmony_ci msg[i + 1].len); 2348c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 2358c2ecf20Sopenharmony_ci goto unlock; 2368c2ecf20Sopenharmony_ci } 2378c2ecf20Sopenharmony_ci obuf[0] = msg[i].len; 2388c2ecf20Sopenharmony_ci obuf[1] = msg[i + 1].len; 2398c2ecf20Sopenharmony_ci obuf[2] = msg[i].addr; 2408c2ecf20Sopenharmony_ci memcpy(&obuf[3], msg[i].buf, msg[i].len); 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci if (cxusb_ctrl_msg(d, CMD_I2C_READ, 2438c2ecf20Sopenharmony_ci obuf, 3 + msg[i].len, 2448c2ecf20Sopenharmony_ci ibuf, 1 + msg[i + 1].len) < 0) 2458c2ecf20Sopenharmony_ci break; 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci if (ibuf[0] != 0x08) 2488c2ecf20Sopenharmony_ci dev_info(&d->udev->dev, "i2c read may have failed\n"); 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci memcpy(msg[i + 1].buf, &ibuf[1], msg[i + 1].len); 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci i++; 2538c2ecf20Sopenharmony_ci } else { 2548c2ecf20Sopenharmony_ci /* write only */ 2558c2ecf20Sopenharmony_ci u8 obuf[MAX_XFER_SIZE], ibuf; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci if (2 + msg[i].len > sizeof(obuf)) { 2588c2ecf20Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", 2598c2ecf20Sopenharmony_ci msg[i].len); 2608c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 2618c2ecf20Sopenharmony_ci goto unlock; 2628c2ecf20Sopenharmony_ci } 2638c2ecf20Sopenharmony_ci obuf[0] = msg[i].addr; 2648c2ecf20Sopenharmony_ci obuf[1] = msg[i].len; 2658c2ecf20Sopenharmony_ci memcpy(&obuf[2], msg[i].buf, msg[i].len); 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci if (cxusb_ctrl_msg(d, CMD_I2C_WRITE, obuf, 2688c2ecf20Sopenharmony_ci 2 + msg[i].len, &ibuf, 1) < 0) 2698c2ecf20Sopenharmony_ci break; 2708c2ecf20Sopenharmony_ci if (ibuf != 0x08) 2718c2ecf20Sopenharmony_ci dev_info(&d->udev->dev, "i2c write may have failed\n"); 2728c2ecf20Sopenharmony_ci } 2738c2ecf20Sopenharmony_ci } 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci if (i == num) 2768c2ecf20Sopenharmony_ci ret = num; 2778c2ecf20Sopenharmony_ci else 2788c2ecf20Sopenharmony_ci ret = -EREMOTEIO; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ciunlock: 2818c2ecf20Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 2828c2ecf20Sopenharmony_ci return ret; 2838c2ecf20Sopenharmony_ci} 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_cistatic u32 cxusb_i2c_func(struct i2c_adapter *adapter) 2868c2ecf20Sopenharmony_ci{ 2878c2ecf20Sopenharmony_ci return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 2888c2ecf20Sopenharmony_ci} 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_cistatic struct i2c_algorithm cxusb_i2c_algo = { 2918c2ecf20Sopenharmony_ci .master_xfer = cxusb_i2c_xfer, 2928c2ecf20Sopenharmony_ci .functionality = cxusb_i2c_func, 2938c2ecf20Sopenharmony_ci}; 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_cistatic int _cxusb_power_ctrl(struct dvb_usb_device *d, int onoff) 2968c2ecf20Sopenharmony_ci{ 2978c2ecf20Sopenharmony_ci u8 b = 0; 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci dev_info(&d->udev->dev, "setting power %s\n", onoff ? "ON" : "OFF"); 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci if (onoff) 3028c2ecf20Sopenharmony_ci return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0); 3038c2ecf20Sopenharmony_ci else 3048c2ecf20Sopenharmony_ci return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0); 3058c2ecf20Sopenharmony_ci} 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_cistatic int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff) 3088c2ecf20Sopenharmony_ci{ 3098c2ecf20Sopenharmony_ci bool is_medion = d->props.devices[0].warm_ids[0] == &cxusb_table[MEDION_MD95700]; 3108c2ecf20Sopenharmony_ci int ret; 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci if (is_medion && !onoff) { 3138c2ecf20Sopenharmony_ci struct cxusb_medion_dev *cxdev = d->priv; 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci mutex_lock(&cxdev->open_lock); 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci if (cxdev->open_type == CXUSB_OPEN_ANALOG) { 3188c2ecf20Sopenharmony_ci dev_info(&d->udev->dev, "preventing DVB core from setting power OFF while we are in analog mode\n"); 3198c2ecf20Sopenharmony_ci ret = -EBUSY; 3208c2ecf20Sopenharmony_ci goto ret_unlock; 3218c2ecf20Sopenharmony_ci } 3228c2ecf20Sopenharmony_ci } 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci ret = _cxusb_power_ctrl(d, onoff); 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ciret_unlock: 3278c2ecf20Sopenharmony_ci if (is_medion && !onoff) { 3288c2ecf20Sopenharmony_ci struct cxusb_medion_dev *cxdev = d->priv; 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci mutex_unlock(&cxdev->open_lock); 3318c2ecf20Sopenharmony_ci } 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci return ret; 3348c2ecf20Sopenharmony_ci} 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_cistatic int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff) 3378c2ecf20Sopenharmony_ci{ 3388c2ecf20Sopenharmony_ci int ret; 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci if (!onoff) 3418c2ecf20Sopenharmony_ci return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0); 3428c2ecf20Sopenharmony_ci if (d->state == DVB_USB_STATE_INIT && 3438c2ecf20Sopenharmony_ci usb_set_interface(d->udev, 0, 0) < 0) 3448c2ecf20Sopenharmony_ci err("set interface failed"); 3458c2ecf20Sopenharmony_ci do { 3468c2ecf20Sopenharmony_ci /* Nothing */ 3478c2ecf20Sopenharmony_ci } while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) && 3488c2ecf20Sopenharmony_ci !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) && 3498c2ecf20Sopenharmony_ci !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0); 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci if (!ret) { 3528c2ecf20Sopenharmony_ci /* 3538c2ecf20Sopenharmony_ci * FIXME: We don't know why, but we need to configure the 3548c2ecf20Sopenharmony_ci * lgdt3303 with the register settings below on resume 3558c2ecf20Sopenharmony_ci */ 3568c2ecf20Sopenharmony_ci int i; 3578c2ecf20Sopenharmony_ci u8 buf; 3588c2ecf20Sopenharmony_ci static const u8 bufs[] = { 3598c2ecf20Sopenharmony_ci 0x0e, 0x2, 0x00, 0x7f, 3608c2ecf20Sopenharmony_ci 0x0e, 0x2, 0x02, 0xfe, 3618c2ecf20Sopenharmony_ci 0x0e, 0x2, 0x02, 0x01, 3628c2ecf20Sopenharmony_ci 0x0e, 0x2, 0x00, 0x03, 3638c2ecf20Sopenharmony_ci 0x0e, 0x2, 0x0d, 0x40, 3648c2ecf20Sopenharmony_ci 0x0e, 0x2, 0x0e, 0x87, 3658c2ecf20Sopenharmony_ci 0x0e, 0x2, 0x0f, 0x8e, 3668c2ecf20Sopenharmony_ci 0x0e, 0x2, 0x10, 0x01, 3678c2ecf20Sopenharmony_ci 0x0e, 0x2, 0x14, 0xd7, 3688c2ecf20Sopenharmony_ci 0x0e, 0x2, 0x47, 0x88, 3698c2ecf20Sopenharmony_ci }; 3708c2ecf20Sopenharmony_ci msleep(20); 3718c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(bufs); i += 4 / sizeof(u8)) { 3728c2ecf20Sopenharmony_ci ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE, 3738c2ecf20Sopenharmony_ci bufs + i, 4, &buf, 1); 3748c2ecf20Sopenharmony_ci if (ret) 3758c2ecf20Sopenharmony_ci break; 3768c2ecf20Sopenharmony_ci if (buf != 0x8) 3778c2ecf20Sopenharmony_ci return -EREMOTEIO; 3788c2ecf20Sopenharmony_ci } 3798c2ecf20Sopenharmony_ci } 3808c2ecf20Sopenharmony_ci return ret; 3818c2ecf20Sopenharmony_ci} 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_cistatic int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff) 3848c2ecf20Sopenharmony_ci{ 3858c2ecf20Sopenharmony_ci u8 b = 0; 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_ci if (onoff) 3888c2ecf20Sopenharmony_ci return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0); 3898c2ecf20Sopenharmony_ci else 3908c2ecf20Sopenharmony_ci return 0; 3918c2ecf20Sopenharmony_ci} 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_cistatic int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff) 3948c2ecf20Sopenharmony_ci{ 3958c2ecf20Sopenharmony_ci int rc = 0; 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci rc = cxusb_power_ctrl(d, onoff); 3988c2ecf20Sopenharmony_ci if (!onoff) 3998c2ecf20Sopenharmony_ci cxusb_nano2_led(d, 0); 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci return rc; 4028c2ecf20Sopenharmony_ci} 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_cistatic int cxusb_d680_dmb_power_ctrl(struct dvb_usb_device *d, int onoff) 4058c2ecf20Sopenharmony_ci{ 4068c2ecf20Sopenharmony_ci int ret; 4078c2ecf20Sopenharmony_ci u8 b; 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci ret = cxusb_power_ctrl(d, onoff); 4108c2ecf20Sopenharmony_ci if (!onoff) 4118c2ecf20Sopenharmony_ci return ret; 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci msleep(128); 4148c2ecf20Sopenharmony_ci cxusb_ctrl_msg(d, CMD_DIGITAL, NULL, 0, &b, 1); 4158c2ecf20Sopenharmony_ci msleep(100); 4168c2ecf20Sopenharmony_ci return ret; 4178c2ecf20Sopenharmony_ci} 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_cistatic int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 4208c2ecf20Sopenharmony_ci{ 4218c2ecf20Sopenharmony_ci struct dvb_usb_device *dvbdev = adap->dev; 4228c2ecf20Sopenharmony_ci bool is_medion = dvbdev->props.devices[0].warm_ids[0] == 4238c2ecf20Sopenharmony_ci &cxusb_table[MEDION_MD95700]; 4248c2ecf20Sopenharmony_ci u8 buf[2] = { 0x03, 0x00 }; 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci if (is_medion && onoff) { 4278c2ecf20Sopenharmony_ci int ret; 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci ret = cxusb_medion_get(dvbdev, CXUSB_OPEN_DIGITAL); 4308c2ecf20Sopenharmony_ci if (ret != 0) 4318c2ecf20Sopenharmony_ci return ret; 4328c2ecf20Sopenharmony_ci } 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci if (onoff) 4358c2ecf20Sopenharmony_ci cxusb_ctrl_msg(dvbdev, CMD_STREAMING_ON, buf, 2, NULL, 0); 4368c2ecf20Sopenharmony_ci else 4378c2ecf20Sopenharmony_ci cxusb_ctrl_msg(dvbdev, CMD_STREAMING_OFF, NULL, 0, NULL, 0); 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_ci if (is_medion && !onoff) 4408c2ecf20Sopenharmony_ci cxusb_medion_put(dvbdev); 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_ci return 0; 4438c2ecf20Sopenharmony_ci} 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_cistatic int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 4468c2ecf20Sopenharmony_ci{ 4478c2ecf20Sopenharmony_ci if (onoff) 4488c2ecf20Sopenharmony_ci cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0); 4498c2ecf20Sopenharmony_ci else 4508c2ecf20Sopenharmony_ci cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF, 4518c2ecf20Sopenharmony_ci NULL, 0, NULL, 0); 4528c2ecf20Sopenharmony_ci return 0; 4538c2ecf20Sopenharmony_ci} 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_cistatic void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d) 4568c2ecf20Sopenharmony_ci{ 4578c2ecf20Sopenharmony_ci int ep = d->props.generic_bulk_ctrl_endpoint; 4588c2ecf20Sopenharmony_ci const int timeout = 100; 4598c2ecf20Sopenharmony_ci const int junk_len = 32; 4608c2ecf20Sopenharmony_ci u8 *junk; 4618c2ecf20Sopenharmony_ci int rd_count; 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci /* Discard remaining data in video pipe */ 4648c2ecf20Sopenharmony_ci junk = kmalloc(junk_len, GFP_KERNEL); 4658c2ecf20Sopenharmony_ci if (!junk) 4668c2ecf20Sopenharmony_ci return; 4678c2ecf20Sopenharmony_ci while (1) { 4688c2ecf20Sopenharmony_ci if (usb_bulk_msg(d->udev, 4698c2ecf20Sopenharmony_ci usb_rcvbulkpipe(d->udev, ep), 4708c2ecf20Sopenharmony_ci junk, junk_len, &rd_count, timeout) < 0) 4718c2ecf20Sopenharmony_ci break; 4728c2ecf20Sopenharmony_ci if (!rd_count) 4738c2ecf20Sopenharmony_ci break; 4748c2ecf20Sopenharmony_ci } 4758c2ecf20Sopenharmony_ci kfree(junk); 4768c2ecf20Sopenharmony_ci} 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_cistatic void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d) 4798c2ecf20Sopenharmony_ci{ 4808c2ecf20Sopenharmony_ci struct usb_data_stream_properties *p = &d->props.adapter[0].fe[0].stream; 4818c2ecf20Sopenharmony_ci const int timeout = 100; 4828c2ecf20Sopenharmony_ci const int junk_len = p->u.bulk.buffersize; 4838c2ecf20Sopenharmony_ci u8 *junk; 4848c2ecf20Sopenharmony_ci int rd_count; 4858c2ecf20Sopenharmony_ci 4868c2ecf20Sopenharmony_ci /* Discard remaining data in video pipe */ 4878c2ecf20Sopenharmony_ci junk = kmalloc(junk_len, GFP_KERNEL); 4888c2ecf20Sopenharmony_ci if (!junk) 4898c2ecf20Sopenharmony_ci return; 4908c2ecf20Sopenharmony_ci while (1) { 4918c2ecf20Sopenharmony_ci if (usb_bulk_msg(d->udev, 4928c2ecf20Sopenharmony_ci usb_rcvbulkpipe(d->udev, p->endpoint), 4938c2ecf20Sopenharmony_ci junk, junk_len, &rd_count, timeout) < 0) 4948c2ecf20Sopenharmony_ci break; 4958c2ecf20Sopenharmony_ci if (!rd_count) 4968c2ecf20Sopenharmony_ci break; 4978c2ecf20Sopenharmony_ci } 4988c2ecf20Sopenharmony_ci kfree(junk); 4998c2ecf20Sopenharmony_ci} 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_cistatic int cxusb_d680_dmb_streaming_ctrl(struct dvb_usb_adapter *adap, 5028c2ecf20Sopenharmony_ci int onoff) 5038c2ecf20Sopenharmony_ci{ 5048c2ecf20Sopenharmony_ci if (onoff) { 5058c2ecf20Sopenharmony_ci u8 buf[2] = { 0x03, 0x00 }; 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_ci cxusb_d680_dmb_drain_video(adap->dev); 5088c2ecf20Sopenharmony_ci return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, 5098c2ecf20Sopenharmony_ci buf, sizeof(buf), NULL, 0); 5108c2ecf20Sopenharmony_ci } else { 5118c2ecf20Sopenharmony_ci int ret = cxusb_ctrl_msg(adap->dev, 5128c2ecf20Sopenharmony_ci CMD_STREAMING_OFF, NULL, 0, NULL, 0); 5138c2ecf20Sopenharmony_ci return ret; 5148c2ecf20Sopenharmony_ci } 5158c2ecf20Sopenharmony_ci} 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_cistatic int cxusb_rc_query(struct dvb_usb_device *d) 5188c2ecf20Sopenharmony_ci{ 5198c2ecf20Sopenharmony_ci u8 ircode[4]; 5208c2ecf20Sopenharmony_ci 5218c2ecf20Sopenharmony_ci if (cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4) < 0) 5228c2ecf20Sopenharmony_ci return 0; 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci if (ircode[2] || ircode[3]) 5258c2ecf20Sopenharmony_ci rc_keydown(d->rc_dev, RC_PROTO_NEC, 5268c2ecf20Sopenharmony_ci RC_SCANCODE_NEC(~ircode[2] & 0xff, ircode[3]), 0); 5278c2ecf20Sopenharmony_ci return 0; 5288c2ecf20Sopenharmony_ci} 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_cistatic int cxusb_bluebird2_rc_query(struct dvb_usb_device *d) 5318c2ecf20Sopenharmony_ci{ 5328c2ecf20Sopenharmony_ci u8 ircode[4]; 5338c2ecf20Sopenharmony_ci struct i2c_msg msg = { 5348c2ecf20Sopenharmony_ci .addr = 0x6b, 5358c2ecf20Sopenharmony_ci .flags = I2C_M_RD, 5368c2ecf20Sopenharmony_ci .buf = ircode, 5378c2ecf20Sopenharmony_ci .len = 4 5388c2ecf20Sopenharmony_ci }; 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1) 5418c2ecf20Sopenharmony_ci return 0; 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_ci if (ircode[1] || ircode[2]) 5448c2ecf20Sopenharmony_ci rc_keydown(d->rc_dev, RC_PROTO_NEC, 5458c2ecf20Sopenharmony_ci RC_SCANCODE_NEC(~ircode[1] & 0xff, ircode[2]), 0); 5468c2ecf20Sopenharmony_ci return 0; 5478c2ecf20Sopenharmony_ci} 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_cistatic int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d) 5508c2ecf20Sopenharmony_ci{ 5518c2ecf20Sopenharmony_ci u8 ircode[2]; 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_ci if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0) 5548c2ecf20Sopenharmony_ci return 0; 5558c2ecf20Sopenharmony_ci 5568c2ecf20Sopenharmony_ci if (ircode[0] || ircode[1]) 5578c2ecf20Sopenharmony_ci rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, 5588c2ecf20Sopenharmony_ci RC_SCANCODE_RC5(ircode[0], ircode[1]), 0); 5598c2ecf20Sopenharmony_ci return 0; 5608c2ecf20Sopenharmony_ci} 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_cistatic int cxusb_dee1601_demod_init(struct dvb_frontend *fe) 5638c2ecf20Sopenharmony_ci{ 5648c2ecf20Sopenharmony_ci static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x28 }; 5658c2ecf20Sopenharmony_ci static u8 reset[] = { RESET, 0x80 }; 5668c2ecf20Sopenharmony_ci static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 }; 5678c2ecf20Sopenharmony_ci static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0x20 }; 5688c2ecf20Sopenharmony_ci static u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 }; 5698c2ecf20Sopenharmony_ci static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci mt352_write(fe, clock_config, sizeof(clock_config)); 5728c2ecf20Sopenharmony_ci udelay(200); 5738c2ecf20Sopenharmony_ci mt352_write(fe, reset, sizeof(reset)); 5748c2ecf20Sopenharmony_ci mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); 5758c2ecf20Sopenharmony_ci 5768c2ecf20Sopenharmony_ci mt352_write(fe, agc_cfg, sizeof(agc_cfg)); 5778c2ecf20Sopenharmony_ci mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); 5788c2ecf20Sopenharmony_ci mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci return 0; 5818c2ecf20Sopenharmony_ci} 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_cistatic int cxusb_mt352_demod_init(struct dvb_frontend *fe) 5848c2ecf20Sopenharmony_ci{ 5858c2ecf20Sopenharmony_ci /* used in both lgz201 and th7579 */ 5868c2ecf20Sopenharmony_ci static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x29 }; 5878c2ecf20Sopenharmony_ci static u8 reset[] = { RESET, 0x80 }; 5888c2ecf20Sopenharmony_ci static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 }; 5898c2ecf20Sopenharmony_ci static u8 agc_cfg[] = { AGC_TARGET, 0x24, 0x20 }; 5908c2ecf20Sopenharmony_ci static u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 }; 5918c2ecf20Sopenharmony_ci static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_ci mt352_write(fe, clock_config, sizeof(clock_config)); 5948c2ecf20Sopenharmony_ci udelay(200); 5958c2ecf20Sopenharmony_ci mt352_write(fe, reset, sizeof(reset)); 5968c2ecf20Sopenharmony_ci mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_ci mt352_write(fe, agc_cfg, sizeof(agc_cfg)); 5998c2ecf20Sopenharmony_ci mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); 6008c2ecf20Sopenharmony_ci mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); 6018c2ecf20Sopenharmony_ci return 0; 6028c2ecf20Sopenharmony_ci} 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_cistatic struct cx22702_config cxusb_cx22702_config = { 6058c2ecf20Sopenharmony_ci .demod_address = 0x63, 6068c2ecf20Sopenharmony_ci .output_mode = CX22702_PARALLEL_OUTPUT, 6078c2ecf20Sopenharmony_ci}; 6088c2ecf20Sopenharmony_ci 6098c2ecf20Sopenharmony_cistatic struct lgdt330x_config cxusb_lgdt3303_config = { 6108c2ecf20Sopenharmony_ci .demod_chip = LGDT3303, 6118c2ecf20Sopenharmony_ci}; 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_cistatic struct lgdt330x_config cxusb_aver_lgdt3303_config = { 6148c2ecf20Sopenharmony_ci .demod_chip = LGDT3303, 6158c2ecf20Sopenharmony_ci .clock_polarity_flip = 2, 6168c2ecf20Sopenharmony_ci}; 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_cistatic struct mt352_config cxusb_dee1601_config = { 6198c2ecf20Sopenharmony_ci .demod_address = 0x0f, 6208c2ecf20Sopenharmony_ci .demod_init = cxusb_dee1601_demod_init, 6218c2ecf20Sopenharmony_ci}; 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_cistatic struct zl10353_config cxusb_zl10353_dee1601_config = { 6248c2ecf20Sopenharmony_ci .demod_address = 0x0f, 6258c2ecf20Sopenharmony_ci .parallel_ts = 1, 6268c2ecf20Sopenharmony_ci}; 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_cistatic struct mt352_config cxusb_mt352_config = { 6298c2ecf20Sopenharmony_ci /* used in both lgz201 and th7579 */ 6308c2ecf20Sopenharmony_ci .demod_address = 0x0f, 6318c2ecf20Sopenharmony_ci .demod_init = cxusb_mt352_demod_init, 6328c2ecf20Sopenharmony_ci}; 6338c2ecf20Sopenharmony_ci 6348c2ecf20Sopenharmony_cistatic struct zl10353_config cxusb_zl10353_xc3028_config = { 6358c2ecf20Sopenharmony_ci .demod_address = 0x0f, 6368c2ecf20Sopenharmony_ci .if2 = 45600, 6378c2ecf20Sopenharmony_ci .no_tuner = 1, 6388c2ecf20Sopenharmony_ci .parallel_ts = 1, 6398c2ecf20Sopenharmony_ci}; 6408c2ecf20Sopenharmony_ci 6418c2ecf20Sopenharmony_cistatic struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = { 6428c2ecf20Sopenharmony_ci .demod_address = 0x0f, 6438c2ecf20Sopenharmony_ci .if2 = 45600, 6448c2ecf20Sopenharmony_ci .no_tuner = 1, 6458c2ecf20Sopenharmony_ci .parallel_ts = 1, 6468c2ecf20Sopenharmony_ci .disable_i2c_gate_ctrl = 1, 6478c2ecf20Sopenharmony_ci}; 6488c2ecf20Sopenharmony_ci 6498c2ecf20Sopenharmony_cistatic struct mt352_config cxusb_mt352_xc3028_config = { 6508c2ecf20Sopenharmony_ci .demod_address = 0x0f, 6518c2ecf20Sopenharmony_ci .if2 = 4560, 6528c2ecf20Sopenharmony_ci .no_tuner = 1, 6538c2ecf20Sopenharmony_ci .demod_init = cxusb_mt352_demod_init, 6548c2ecf20Sopenharmony_ci}; 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ci/* FIXME: needs tweaking */ 6578c2ecf20Sopenharmony_cistatic struct mxl5005s_config aver_a868r_tuner = { 6588c2ecf20Sopenharmony_ci .i2c_address = 0x63, 6598c2ecf20Sopenharmony_ci .if_freq = 6000000UL, 6608c2ecf20Sopenharmony_ci .xtal_freq = CRYSTAL_FREQ_16000000HZ, 6618c2ecf20Sopenharmony_ci .agc_mode = MXL_SINGLE_AGC, 6628c2ecf20Sopenharmony_ci .tracking_filter = MXL_TF_C, 6638c2ecf20Sopenharmony_ci .rssi_enable = MXL_RSSI_ENABLE, 6648c2ecf20Sopenharmony_ci .cap_select = MXL_CAP_SEL_ENABLE, 6658c2ecf20Sopenharmony_ci .div_out = MXL_DIV_OUT_4, 6668c2ecf20Sopenharmony_ci .clock_out = MXL_CLOCK_OUT_DISABLE, 6678c2ecf20Sopenharmony_ci .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, 6688c2ecf20Sopenharmony_ci .top = MXL5005S_TOP_25P2, 6698c2ecf20Sopenharmony_ci .mod_mode = MXL_DIGITAL_MODE, 6708c2ecf20Sopenharmony_ci .if_mode = MXL_ZERO_IF, 6718c2ecf20Sopenharmony_ci .AgcMasterByte = 0x00, 6728c2ecf20Sopenharmony_ci}; 6738c2ecf20Sopenharmony_ci 6748c2ecf20Sopenharmony_ci/* FIXME: needs tweaking */ 6758c2ecf20Sopenharmony_cistatic struct mxl5005s_config d680_dmb_tuner = { 6768c2ecf20Sopenharmony_ci .i2c_address = 0x63, 6778c2ecf20Sopenharmony_ci .if_freq = 36125000UL, 6788c2ecf20Sopenharmony_ci .xtal_freq = CRYSTAL_FREQ_16000000HZ, 6798c2ecf20Sopenharmony_ci .agc_mode = MXL_SINGLE_AGC, 6808c2ecf20Sopenharmony_ci .tracking_filter = MXL_TF_C, 6818c2ecf20Sopenharmony_ci .rssi_enable = MXL_RSSI_ENABLE, 6828c2ecf20Sopenharmony_ci .cap_select = MXL_CAP_SEL_ENABLE, 6838c2ecf20Sopenharmony_ci .div_out = MXL_DIV_OUT_4, 6848c2ecf20Sopenharmony_ci .clock_out = MXL_CLOCK_OUT_DISABLE, 6858c2ecf20Sopenharmony_ci .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, 6868c2ecf20Sopenharmony_ci .top = MXL5005S_TOP_25P2, 6878c2ecf20Sopenharmony_ci .mod_mode = MXL_DIGITAL_MODE, 6888c2ecf20Sopenharmony_ci .if_mode = MXL_ZERO_IF, 6898c2ecf20Sopenharmony_ci .AgcMasterByte = 0x00, 6908c2ecf20Sopenharmony_ci}; 6918c2ecf20Sopenharmony_ci 6928c2ecf20Sopenharmony_cistatic struct max2165_config mygica_d689_max2165_cfg = { 6938c2ecf20Sopenharmony_ci .i2c_address = 0x60, 6948c2ecf20Sopenharmony_ci .osc_clk = 20 6958c2ecf20Sopenharmony_ci}; 6968c2ecf20Sopenharmony_ci 6978c2ecf20Sopenharmony_ci/* Callbacks for DVB USB */ 6988c2ecf20Sopenharmony_cistatic int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) 6998c2ecf20Sopenharmony_ci{ 7008c2ecf20Sopenharmony_ci struct dvb_usb_device *dvbdev = adap->dev; 7018c2ecf20Sopenharmony_ci bool is_medion = dvbdev->props.devices[0].warm_ids[0] == 7028c2ecf20Sopenharmony_ci &cxusb_table[MEDION_MD95700]; 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe, 7058c2ecf20Sopenharmony_ci &dvbdev->i2c_adap, 0x61, 7068c2ecf20Sopenharmony_ci TUNER_PHILIPS_FMD1216ME_MK3); 7078c2ecf20Sopenharmony_ci 7088c2ecf20Sopenharmony_ci if (is_medion && adap->fe_adap[0].fe) 7098c2ecf20Sopenharmony_ci /* 7108c2ecf20Sopenharmony_ci * make sure that DVB core won't put to sleep (reset, really) 7118c2ecf20Sopenharmony_ci * tuner when we might be open in analog mode 7128c2ecf20Sopenharmony_ci */ 7138c2ecf20Sopenharmony_ci adap->fe_adap[0].fe->ops.tuner_ops.sleep = NULL; 7148c2ecf20Sopenharmony_ci 7158c2ecf20Sopenharmony_ci return 0; 7168c2ecf20Sopenharmony_ci} 7178c2ecf20Sopenharmony_ci 7188c2ecf20Sopenharmony_cistatic int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap) 7198c2ecf20Sopenharmony_ci{ 7208c2ecf20Sopenharmony_ci dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, 7218c2ecf20Sopenharmony_ci NULL, DVB_PLL_THOMSON_DTT7579); 7228c2ecf20Sopenharmony_ci return 0; 7238c2ecf20Sopenharmony_ci} 7248c2ecf20Sopenharmony_ci 7258c2ecf20Sopenharmony_cistatic int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap) 7268c2ecf20Sopenharmony_ci{ 7278c2ecf20Sopenharmony_ci dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, 7288c2ecf20Sopenharmony_ci NULL, DVB_PLL_LG_Z201); 7298c2ecf20Sopenharmony_ci return 0; 7308c2ecf20Sopenharmony_ci} 7318c2ecf20Sopenharmony_ci 7328c2ecf20Sopenharmony_cistatic int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap) 7338c2ecf20Sopenharmony_ci{ 7348c2ecf20Sopenharmony_ci dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, 7358c2ecf20Sopenharmony_ci NULL, DVB_PLL_THOMSON_DTT7579); 7368c2ecf20Sopenharmony_ci return 0; 7378c2ecf20Sopenharmony_ci} 7388c2ecf20Sopenharmony_ci 7398c2ecf20Sopenharmony_cistatic int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap) 7408c2ecf20Sopenharmony_ci{ 7418c2ecf20Sopenharmony_ci dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe, 7428c2ecf20Sopenharmony_ci &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF); 7438c2ecf20Sopenharmony_ci return 0; 7448c2ecf20Sopenharmony_ci} 7458c2ecf20Sopenharmony_ci 7468c2ecf20Sopenharmony_cistatic int dvico_bluebird_xc2028_callback(void *ptr, int component, 7478c2ecf20Sopenharmony_ci int command, int arg) 7488c2ecf20Sopenharmony_ci{ 7498c2ecf20Sopenharmony_ci struct dvb_usb_adapter *adap = ptr; 7508c2ecf20Sopenharmony_ci struct dvb_usb_device *d = adap->dev; 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_ci switch (command) { 7538c2ecf20Sopenharmony_ci case XC2028_TUNER_RESET: 7548c2ecf20Sopenharmony_ci dev_info(&d->udev->dev, "XC2028_TUNER_RESET %d\n", arg); 7558c2ecf20Sopenharmony_ci cxusb_bluebird_gpio_pulse(d, 0x01, 1); 7568c2ecf20Sopenharmony_ci break; 7578c2ecf20Sopenharmony_ci case XC2028_RESET_CLK: 7588c2ecf20Sopenharmony_ci dev_info(&d->udev->dev, "XC2028_RESET_CLK %d\n", arg); 7598c2ecf20Sopenharmony_ci break; 7608c2ecf20Sopenharmony_ci case XC2028_I2C_FLUSH: 7618c2ecf20Sopenharmony_ci break; 7628c2ecf20Sopenharmony_ci default: 7638c2ecf20Sopenharmony_ci dev_info(&d->udev->dev, "unknown command %d, arg %d\n", 7648c2ecf20Sopenharmony_ci command, arg); 7658c2ecf20Sopenharmony_ci return -EINVAL; 7668c2ecf20Sopenharmony_ci } 7678c2ecf20Sopenharmony_ci 7688c2ecf20Sopenharmony_ci return 0; 7698c2ecf20Sopenharmony_ci} 7708c2ecf20Sopenharmony_ci 7718c2ecf20Sopenharmony_cistatic int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap) 7728c2ecf20Sopenharmony_ci{ 7738c2ecf20Sopenharmony_ci struct dvb_frontend *fe; 7748c2ecf20Sopenharmony_ci struct xc2028_config cfg = { 7758c2ecf20Sopenharmony_ci .i2c_adap = &adap->dev->i2c_adap, 7768c2ecf20Sopenharmony_ci .i2c_addr = 0x61, 7778c2ecf20Sopenharmony_ci }; 7788c2ecf20Sopenharmony_ci static struct xc2028_ctrl ctl = { 7798c2ecf20Sopenharmony_ci .fname = XC2028_DEFAULT_FIRMWARE, 7808c2ecf20Sopenharmony_ci .max_len = 64, 7818c2ecf20Sopenharmony_ci .demod = XC3028_FE_ZARLINK456, 7828c2ecf20Sopenharmony_ci }; 7838c2ecf20Sopenharmony_ci 7848c2ecf20Sopenharmony_ci /* FIXME: generalize & move to common area */ 7858c2ecf20Sopenharmony_ci adap->fe_adap[0].fe->callback = dvico_bluebird_xc2028_callback; 7868c2ecf20Sopenharmony_ci 7878c2ecf20Sopenharmony_ci fe = dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &cfg); 7888c2ecf20Sopenharmony_ci if (!fe || !fe->ops.tuner_ops.set_config) 7898c2ecf20Sopenharmony_ci return -EIO; 7908c2ecf20Sopenharmony_ci 7918c2ecf20Sopenharmony_ci fe->ops.tuner_ops.set_config(fe, &ctl); 7928c2ecf20Sopenharmony_ci 7938c2ecf20Sopenharmony_ci return 0; 7948c2ecf20Sopenharmony_ci} 7958c2ecf20Sopenharmony_ci 7968c2ecf20Sopenharmony_cistatic int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap) 7978c2ecf20Sopenharmony_ci{ 7988c2ecf20Sopenharmony_ci dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe, 7998c2ecf20Sopenharmony_ci &adap->dev->i2c_adap, &aver_a868r_tuner); 8008c2ecf20Sopenharmony_ci return 0; 8018c2ecf20Sopenharmony_ci} 8028c2ecf20Sopenharmony_ci 8038c2ecf20Sopenharmony_cistatic int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap) 8048c2ecf20Sopenharmony_ci{ 8058c2ecf20Sopenharmony_ci struct dvb_frontend *fe; 8068c2ecf20Sopenharmony_ci 8078c2ecf20Sopenharmony_ci fe = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe, 8088c2ecf20Sopenharmony_ci &adap->dev->i2c_adap, &d680_dmb_tuner); 8098c2ecf20Sopenharmony_ci return (!fe) ? -EIO : 0; 8108c2ecf20Sopenharmony_ci} 8118c2ecf20Sopenharmony_ci 8128c2ecf20Sopenharmony_cistatic int cxusb_mygica_d689_tuner_attach(struct dvb_usb_adapter *adap) 8138c2ecf20Sopenharmony_ci{ 8148c2ecf20Sopenharmony_ci struct dvb_frontend *fe; 8158c2ecf20Sopenharmony_ci 8168c2ecf20Sopenharmony_ci fe = dvb_attach(max2165_attach, adap->fe_adap[0].fe, 8178c2ecf20Sopenharmony_ci &adap->dev->i2c_adap, &mygica_d689_max2165_cfg); 8188c2ecf20Sopenharmony_ci return (!fe) ? -EIO : 0; 8198c2ecf20Sopenharmony_ci} 8208c2ecf20Sopenharmony_ci 8218c2ecf20Sopenharmony_cistatic int cxusb_medion_fe_ts_bus_ctrl(struct dvb_frontend *fe, int acquire) 8228c2ecf20Sopenharmony_ci{ 8238c2ecf20Sopenharmony_ci struct dvb_usb_adapter *adap = fe->dvb->priv; 8248c2ecf20Sopenharmony_ci struct dvb_usb_device *dvbdev = adap->dev; 8258c2ecf20Sopenharmony_ci 8268c2ecf20Sopenharmony_ci if (acquire) 8278c2ecf20Sopenharmony_ci return cxusb_medion_get(dvbdev, CXUSB_OPEN_DIGITAL); 8288c2ecf20Sopenharmony_ci 8298c2ecf20Sopenharmony_ci cxusb_medion_put(dvbdev); 8308c2ecf20Sopenharmony_ci 8318c2ecf20Sopenharmony_ci return 0; 8328c2ecf20Sopenharmony_ci} 8338c2ecf20Sopenharmony_ci 8348c2ecf20Sopenharmony_cistatic int cxusb_medion_set_mode(struct dvb_usb_device *dvbdev, bool digital) 8358c2ecf20Sopenharmony_ci{ 8368c2ecf20Sopenharmony_ci struct cxusb_state *st = dvbdev->priv; 8378c2ecf20Sopenharmony_ci int ret; 8388c2ecf20Sopenharmony_ci u8 b; 8398c2ecf20Sopenharmony_ci unsigned int i; 8408c2ecf20Sopenharmony_ci 8418c2ecf20Sopenharmony_ci /* 8428c2ecf20Sopenharmony_ci * switching mode while doing an I2C transaction often causes 8438c2ecf20Sopenharmony_ci * the device to crash 8448c2ecf20Sopenharmony_ci */ 8458c2ecf20Sopenharmony_ci mutex_lock(&dvbdev->i2c_mutex); 8468c2ecf20Sopenharmony_ci 8478c2ecf20Sopenharmony_ci if (digital) { 8488c2ecf20Sopenharmony_ci ret = usb_set_interface(dvbdev->udev, 0, 6); 8498c2ecf20Sopenharmony_ci if (ret != 0) { 8508c2ecf20Sopenharmony_ci dev_err(&dvbdev->udev->dev, 8518c2ecf20Sopenharmony_ci "digital interface selection failed (%d)\n", 8528c2ecf20Sopenharmony_ci ret); 8538c2ecf20Sopenharmony_ci goto ret_unlock; 8548c2ecf20Sopenharmony_ci } 8558c2ecf20Sopenharmony_ci } else { 8568c2ecf20Sopenharmony_ci ret = usb_set_interface(dvbdev->udev, 0, 1); 8578c2ecf20Sopenharmony_ci if (ret != 0) { 8588c2ecf20Sopenharmony_ci dev_err(&dvbdev->udev->dev, 8598c2ecf20Sopenharmony_ci "analog interface selection failed (%d)\n", 8608c2ecf20Sopenharmony_ci ret); 8618c2ecf20Sopenharmony_ci goto ret_unlock; 8628c2ecf20Sopenharmony_ci } 8638c2ecf20Sopenharmony_ci } 8648c2ecf20Sopenharmony_ci 8658c2ecf20Sopenharmony_ci /* pipes need to be cleared after setting interface */ 8668c2ecf20Sopenharmony_ci ret = usb_clear_halt(dvbdev->udev, usb_rcvbulkpipe(dvbdev->udev, 1)); 8678c2ecf20Sopenharmony_ci if (ret != 0) 8688c2ecf20Sopenharmony_ci dev_warn(&dvbdev->udev->dev, 8698c2ecf20Sopenharmony_ci "clear halt on IN pipe failed (%d)\n", 8708c2ecf20Sopenharmony_ci ret); 8718c2ecf20Sopenharmony_ci 8728c2ecf20Sopenharmony_ci ret = usb_clear_halt(dvbdev->udev, usb_sndbulkpipe(dvbdev->udev, 1)); 8738c2ecf20Sopenharmony_ci if (ret != 0) 8748c2ecf20Sopenharmony_ci dev_warn(&dvbdev->udev->dev, 8758c2ecf20Sopenharmony_ci "clear halt on OUT pipe failed (%d)\n", 8768c2ecf20Sopenharmony_ci ret); 8778c2ecf20Sopenharmony_ci 8788c2ecf20Sopenharmony_ci ret = cxusb_ctrl_msg(dvbdev, digital ? CMD_DIGITAL : CMD_ANALOG, 8798c2ecf20Sopenharmony_ci NULL, 0, &b, 1); 8808c2ecf20Sopenharmony_ci if (ret != 0) { 8818c2ecf20Sopenharmony_ci dev_err(&dvbdev->udev->dev, "mode switch failed (%d)\n", 8828c2ecf20Sopenharmony_ci ret); 8838c2ecf20Sopenharmony_ci goto ret_unlock; 8848c2ecf20Sopenharmony_ci } 8858c2ecf20Sopenharmony_ci 8868c2ecf20Sopenharmony_ci /* mode switch seems to reset GPIO states */ 8878c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(st->gpio_write_refresh); i++) 8888c2ecf20Sopenharmony_ci st->gpio_write_refresh[i] = true; 8898c2ecf20Sopenharmony_ci 8908c2ecf20Sopenharmony_ciret_unlock: 8918c2ecf20Sopenharmony_ci mutex_unlock(&dvbdev->i2c_mutex); 8928c2ecf20Sopenharmony_ci 8938c2ecf20Sopenharmony_ci return ret; 8948c2ecf20Sopenharmony_ci} 8958c2ecf20Sopenharmony_ci 8968c2ecf20Sopenharmony_cistatic int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap) 8978c2ecf20Sopenharmony_ci{ 8988c2ecf20Sopenharmony_ci struct dvb_usb_device *dvbdev = adap->dev; 8998c2ecf20Sopenharmony_ci bool is_medion = dvbdev->props.devices[0].warm_ids[0] == 9008c2ecf20Sopenharmony_ci &cxusb_table[MEDION_MD95700]; 9018c2ecf20Sopenharmony_ci 9028c2ecf20Sopenharmony_ci if (is_medion) { 9038c2ecf20Sopenharmony_ci int ret; 9048c2ecf20Sopenharmony_ci 9058c2ecf20Sopenharmony_ci ret = cxusb_medion_set_mode(dvbdev, true); 9068c2ecf20Sopenharmony_ci if (ret) 9078c2ecf20Sopenharmony_ci return ret; 9088c2ecf20Sopenharmony_ci } 9098c2ecf20Sopenharmony_ci 9108c2ecf20Sopenharmony_ci adap->fe_adap[0].fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config, 9118c2ecf20Sopenharmony_ci &dvbdev->i2c_adap); 9128c2ecf20Sopenharmony_ci if (!adap->fe_adap[0].fe) 9138c2ecf20Sopenharmony_ci return -EIO; 9148c2ecf20Sopenharmony_ci 9158c2ecf20Sopenharmony_ci if (is_medion) 9168c2ecf20Sopenharmony_ci adap->fe_adap[0].fe->ops.ts_bus_ctrl = 9178c2ecf20Sopenharmony_ci cxusb_medion_fe_ts_bus_ctrl; 9188c2ecf20Sopenharmony_ci 9198c2ecf20Sopenharmony_ci return 0; 9208c2ecf20Sopenharmony_ci} 9218c2ecf20Sopenharmony_ci 9228c2ecf20Sopenharmony_cistatic int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap) 9238c2ecf20Sopenharmony_ci{ 9248c2ecf20Sopenharmony_ci if (usb_set_interface(adap->dev->udev, 0, 7) < 0) 9258c2ecf20Sopenharmony_ci err("set interface failed"); 9268c2ecf20Sopenharmony_ci 9278c2ecf20Sopenharmony_ci cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); 9288c2ecf20Sopenharmony_ci 9298c2ecf20Sopenharmony_ci adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach, 9308c2ecf20Sopenharmony_ci &cxusb_lgdt3303_config, 9318c2ecf20Sopenharmony_ci 0x0e, 9328c2ecf20Sopenharmony_ci &adap->dev->i2c_adap); 9338c2ecf20Sopenharmony_ci if (adap->fe_adap[0].fe) 9348c2ecf20Sopenharmony_ci return 0; 9358c2ecf20Sopenharmony_ci 9368c2ecf20Sopenharmony_ci return -EIO; 9378c2ecf20Sopenharmony_ci} 9388c2ecf20Sopenharmony_ci 9398c2ecf20Sopenharmony_cistatic int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap) 9408c2ecf20Sopenharmony_ci{ 9418c2ecf20Sopenharmony_ci adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach, 9428c2ecf20Sopenharmony_ci &cxusb_aver_lgdt3303_config, 9438c2ecf20Sopenharmony_ci 0x0e, 9448c2ecf20Sopenharmony_ci &adap->dev->i2c_adap); 9458c2ecf20Sopenharmony_ci if (adap->fe_adap[0].fe) 9468c2ecf20Sopenharmony_ci return 0; 9478c2ecf20Sopenharmony_ci 9488c2ecf20Sopenharmony_ci return -EIO; 9498c2ecf20Sopenharmony_ci} 9508c2ecf20Sopenharmony_ci 9518c2ecf20Sopenharmony_cistatic int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap) 9528c2ecf20Sopenharmony_ci{ 9538c2ecf20Sopenharmony_ci /* used in both lgz201 and th7579 */ 9548c2ecf20Sopenharmony_ci if (usb_set_interface(adap->dev->udev, 0, 0) < 0) 9558c2ecf20Sopenharmony_ci err("set interface failed"); 9568c2ecf20Sopenharmony_ci 9578c2ecf20Sopenharmony_ci cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); 9588c2ecf20Sopenharmony_ci 9598c2ecf20Sopenharmony_ci adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_mt352_config, 9608c2ecf20Sopenharmony_ci &adap->dev->i2c_adap); 9618c2ecf20Sopenharmony_ci if (adap->fe_adap[0].fe) 9628c2ecf20Sopenharmony_ci return 0; 9638c2ecf20Sopenharmony_ci 9648c2ecf20Sopenharmony_ci return -EIO; 9658c2ecf20Sopenharmony_ci} 9668c2ecf20Sopenharmony_ci 9678c2ecf20Sopenharmony_cistatic int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap) 9688c2ecf20Sopenharmony_ci{ 9698c2ecf20Sopenharmony_ci if (usb_set_interface(adap->dev->udev, 0, 0) < 0) 9708c2ecf20Sopenharmony_ci err("set interface failed"); 9718c2ecf20Sopenharmony_ci 9728c2ecf20Sopenharmony_ci cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); 9738c2ecf20Sopenharmony_ci 9748c2ecf20Sopenharmony_ci adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_dee1601_config, 9758c2ecf20Sopenharmony_ci &adap->dev->i2c_adap); 9768c2ecf20Sopenharmony_ci if (adap->fe_adap[0].fe) 9778c2ecf20Sopenharmony_ci return 0; 9788c2ecf20Sopenharmony_ci 9798c2ecf20Sopenharmony_ci adap->fe_adap[0].fe = dvb_attach(zl10353_attach, 9808c2ecf20Sopenharmony_ci &cxusb_zl10353_dee1601_config, 9818c2ecf20Sopenharmony_ci &adap->dev->i2c_adap); 9828c2ecf20Sopenharmony_ci if (adap->fe_adap[0].fe) 9838c2ecf20Sopenharmony_ci return 0; 9848c2ecf20Sopenharmony_ci 9858c2ecf20Sopenharmony_ci return -EIO; 9868c2ecf20Sopenharmony_ci} 9878c2ecf20Sopenharmony_ci 9888c2ecf20Sopenharmony_cistatic int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap) 9898c2ecf20Sopenharmony_ci{ 9908c2ecf20Sopenharmony_ci u8 ircode[4]; 9918c2ecf20Sopenharmony_ci int i; 9928c2ecf20Sopenharmony_ci struct i2c_msg msg = { 9938c2ecf20Sopenharmony_ci .addr = 0x6b, 9948c2ecf20Sopenharmony_ci .flags = I2C_M_RD, 9958c2ecf20Sopenharmony_ci .buf = ircode, 9968c2ecf20Sopenharmony_ci .len = 4 9978c2ecf20Sopenharmony_ci }; 9988c2ecf20Sopenharmony_ci 9998c2ecf20Sopenharmony_ci if (usb_set_interface(adap->dev->udev, 0, 1) < 0) 10008c2ecf20Sopenharmony_ci err("set interface failed"); 10018c2ecf20Sopenharmony_ci 10028c2ecf20Sopenharmony_ci cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); 10038c2ecf20Sopenharmony_ci 10048c2ecf20Sopenharmony_ci /* reset the tuner and demodulator */ 10058c2ecf20Sopenharmony_ci cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0); 10068c2ecf20Sopenharmony_ci cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1); 10078c2ecf20Sopenharmony_ci cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); 10088c2ecf20Sopenharmony_ci 10098c2ecf20Sopenharmony_ci adap->fe_adap[0].fe = 10108c2ecf20Sopenharmony_ci dvb_attach(zl10353_attach, 10118c2ecf20Sopenharmony_ci &cxusb_zl10353_xc3028_config_no_i2c_gate, 10128c2ecf20Sopenharmony_ci &adap->dev->i2c_adap); 10138c2ecf20Sopenharmony_ci if (!adap->fe_adap[0].fe) 10148c2ecf20Sopenharmony_ci return -EIO; 10158c2ecf20Sopenharmony_ci 10168c2ecf20Sopenharmony_ci /* try to determine if there is no IR decoder on the I2C bus */ 10178c2ecf20Sopenharmony_ci for (i = 0; adap->dev->props.rc.core.rc_codes && i < 5; i++) { 10188c2ecf20Sopenharmony_ci msleep(20); 10198c2ecf20Sopenharmony_ci if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1) 10208c2ecf20Sopenharmony_ci goto no_IR; 10218c2ecf20Sopenharmony_ci if (ircode[0] == 0 && ircode[1] == 0) 10228c2ecf20Sopenharmony_ci continue; 10238c2ecf20Sopenharmony_ci if (ircode[2] + ircode[3] != 0xff) { 10248c2ecf20Sopenharmony_cino_IR: 10258c2ecf20Sopenharmony_ci adap->dev->props.rc.core.rc_codes = NULL; 10268c2ecf20Sopenharmony_ci info("No IR receiver detected on this device."); 10278c2ecf20Sopenharmony_ci break; 10288c2ecf20Sopenharmony_ci } 10298c2ecf20Sopenharmony_ci } 10308c2ecf20Sopenharmony_ci 10318c2ecf20Sopenharmony_ci return 0; 10328c2ecf20Sopenharmony_ci} 10338c2ecf20Sopenharmony_ci 10348c2ecf20Sopenharmony_cistatic struct dibx000_agc_config dib7070_agc_config = { 10358c2ecf20Sopenharmony_ci .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, 10368c2ecf20Sopenharmony_ci 10378c2ecf20Sopenharmony_ci /* 10388c2ecf20Sopenharmony_ci * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, 10398c2ecf20Sopenharmony_ci * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, 10408c2ecf20Sopenharmony_ci * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 10418c2ecf20Sopenharmony_ci */ 10428c2ecf20Sopenharmony_ci .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | 10438c2ecf20Sopenharmony_ci (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), 10448c2ecf20Sopenharmony_ci .inv_gain = 600, 10458c2ecf20Sopenharmony_ci .time_stabiliz = 10, 10468c2ecf20Sopenharmony_ci .alpha_level = 0, 10478c2ecf20Sopenharmony_ci .thlock = 118, 10488c2ecf20Sopenharmony_ci .wbd_inv = 0, 10498c2ecf20Sopenharmony_ci .wbd_ref = 3530, 10508c2ecf20Sopenharmony_ci .wbd_sel = 1, 10518c2ecf20Sopenharmony_ci .wbd_alpha = 5, 10528c2ecf20Sopenharmony_ci .agc1_max = 65535, 10538c2ecf20Sopenharmony_ci .agc1_min = 0, 10548c2ecf20Sopenharmony_ci .agc2_max = 65535, 10558c2ecf20Sopenharmony_ci .agc2_min = 0, 10568c2ecf20Sopenharmony_ci .agc1_pt1 = 0, 10578c2ecf20Sopenharmony_ci .agc1_pt2 = 40, 10588c2ecf20Sopenharmony_ci .agc1_pt3 = 183, 10598c2ecf20Sopenharmony_ci .agc1_slope1 = 206, 10608c2ecf20Sopenharmony_ci .agc1_slope2 = 255, 10618c2ecf20Sopenharmony_ci .agc2_pt1 = 72, 10628c2ecf20Sopenharmony_ci .agc2_pt2 = 152, 10638c2ecf20Sopenharmony_ci .agc2_slope1 = 88, 10648c2ecf20Sopenharmony_ci .agc2_slope2 = 90, 10658c2ecf20Sopenharmony_ci .alpha_mant = 17, 10668c2ecf20Sopenharmony_ci .alpha_exp = 27, 10678c2ecf20Sopenharmony_ci .beta_mant = 23, 10688c2ecf20Sopenharmony_ci .beta_exp = 51, 10698c2ecf20Sopenharmony_ci .perform_agc_softsplit = 0, 10708c2ecf20Sopenharmony_ci}; 10718c2ecf20Sopenharmony_ci 10728c2ecf20Sopenharmony_cistatic struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = { 10738c2ecf20Sopenharmony_ci .internal = 60000, 10748c2ecf20Sopenharmony_ci .sampling = 15000, 10758c2ecf20Sopenharmony_ci .pll_prediv = 1, 10768c2ecf20Sopenharmony_ci .pll_ratio = 20, 10778c2ecf20Sopenharmony_ci .pll_range = 3, 10788c2ecf20Sopenharmony_ci .pll_reset = 1, 10798c2ecf20Sopenharmony_ci .pll_bypass = 0, 10808c2ecf20Sopenharmony_ci .enable_refdiv = 0, 10818c2ecf20Sopenharmony_ci .bypclk_div = 0, 10828c2ecf20Sopenharmony_ci .IO_CLK_en_core = 1, 10838c2ecf20Sopenharmony_ci .ADClkSrc = 1, 10848c2ecf20Sopenharmony_ci .modulo = 2, 10858c2ecf20Sopenharmony_ci /* refsel, sel, freq_15k */ 10868c2ecf20Sopenharmony_ci .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0), 10878c2ecf20Sopenharmony_ci .ifreq = (0 << 25) | 0, 10888c2ecf20Sopenharmony_ci .timf = 20452225, 10898c2ecf20Sopenharmony_ci .xtal_hz = 12000000, 10908c2ecf20Sopenharmony_ci}; 10918c2ecf20Sopenharmony_ci 10928c2ecf20Sopenharmony_cistatic struct dib7000p_config cxusb_dualdig4_rev2_config = { 10938c2ecf20Sopenharmony_ci .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, 10948c2ecf20Sopenharmony_ci .output_mpeg2_in_188_bytes = 1, 10958c2ecf20Sopenharmony_ci 10968c2ecf20Sopenharmony_ci .agc_config_count = 1, 10978c2ecf20Sopenharmony_ci .agc = &dib7070_agc_config, 10988c2ecf20Sopenharmony_ci .bw = &dib7070_bw_config_12_mhz, 10998c2ecf20Sopenharmony_ci .tuner_is_baseband = 1, 11008c2ecf20Sopenharmony_ci .spur_protect = 1, 11018c2ecf20Sopenharmony_ci 11028c2ecf20Sopenharmony_ci .gpio_dir = 0xfcef, 11038c2ecf20Sopenharmony_ci .gpio_val = 0x0110, 11048c2ecf20Sopenharmony_ci 11058c2ecf20Sopenharmony_ci .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, 11068c2ecf20Sopenharmony_ci 11078c2ecf20Sopenharmony_ci .hostbus_diversity = 1, 11088c2ecf20Sopenharmony_ci}; 11098c2ecf20Sopenharmony_ci 11108c2ecf20Sopenharmony_cistruct dib0700_adapter_state { 11118c2ecf20Sopenharmony_ci int (*set_param_save)(struct dvb_frontend *fe); 11128c2ecf20Sopenharmony_ci struct dib7000p_ops dib7000p_ops; 11138c2ecf20Sopenharmony_ci}; 11148c2ecf20Sopenharmony_ci 11158c2ecf20Sopenharmony_cistatic int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap) 11168c2ecf20Sopenharmony_ci{ 11178c2ecf20Sopenharmony_ci struct dib0700_adapter_state *state = adap->priv; 11188c2ecf20Sopenharmony_ci 11198c2ecf20Sopenharmony_ci if (usb_set_interface(adap->dev->udev, 0, 1) < 0) 11208c2ecf20Sopenharmony_ci err("set interface failed"); 11218c2ecf20Sopenharmony_ci 11228c2ecf20Sopenharmony_ci cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); 11238c2ecf20Sopenharmony_ci 11248c2ecf20Sopenharmony_ci cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); 11258c2ecf20Sopenharmony_ci 11268c2ecf20Sopenharmony_ci if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) 11278c2ecf20Sopenharmony_ci return -ENODEV; 11288c2ecf20Sopenharmony_ci 11298c2ecf20Sopenharmony_ci if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 11308c2ecf20Sopenharmony_ci &cxusb_dualdig4_rev2_config) < 0) { 11318c2ecf20Sopenharmony_ci pr_warn("Unable to enumerate dib7000p\n"); 11328c2ecf20Sopenharmony_ci return -ENODEV; 11338c2ecf20Sopenharmony_ci } 11348c2ecf20Sopenharmony_ci 11358c2ecf20Sopenharmony_ci adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 11368c2ecf20Sopenharmony_ci 0x80, 11378c2ecf20Sopenharmony_ci &cxusb_dualdig4_rev2_config); 11388c2ecf20Sopenharmony_ci if (!adap->fe_adap[0].fe) 11398c2ecf20Sopenharmony_ci return -EIO; 11408c2ecf20Sopenharmony_ci 11418c2ecf20Sopenharmony_ci return 0; 11428c2ecf20Sopenharmony_ci} 11438c2ecf20Sopenharmony_ci 11448c2ecf20Sopenharmony_cistatic int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff) 11458c2ecf20Sopenharmony_ci{ 11468c2ecf20Sopenharmony_ci struct dvb_usb_adapter *adap = fe->dvb->priv; 11478c2ecf20Sopenharmony_ci struct dib0700_adapter_state *state = adap->priv; 11488c2ecf20Sopenharmony_ci 11498c2ecf20Sopenharmony_ci return state->dib7000p_ops.set_gpio(fe, 8, 0, !onoff); 11508c2ecf20Sopenharmony_ci} 11518c2ecf20Sopenharmony_ci 11528c2ecf20Sopenharmony_cistatic int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff) 11538c2ecf20Sopenharmony_ci{ 11548c2ecf20Sopenharmony_ci return 0; 11558c2ecf20Sopenharmony_ci} 11568c2ecf20Sopenharmony_ci 11578c2ecf20Sopenharmony_cistatic struct dib0070_config dib7070p_dib0070_config = { 11588c2ecf20Sopenharmony_ci .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, 11598c2ecf20Sopenharmony_ci .reset = dib7070_tuner_reset, 11608c2ecf20Sopenharmony_ci .sleep = dib7070_tuner_sleep, 11618c2ecf20Sopenharmony_ci .clock_khz = 12000, 11628c2ecf20Sopenharmony_ci}; 11638c2ecf20Sopenharmony_ci 11648c2ecf20Sopenharmony_cistatic int dib7070_set_param_override(struct dvb_frontend *fe) 11658c2ecf20Sopenharmony_ci{ 11668c2ecf20Sopenharmony_ci struct dtv_frontend_properties *p = &fe->dtv_property_cache; 11678c2ecf20Sopenharmony_ci struct dvb_usb_adapter *adap = fe->dvb->priv; 11688c2ecf20Sopenharmony_ci struct dib0700_adapter_state *state = adap->priv; 11698c2ecf20Sopenharmony_ci 11708c2ecf20Sopenharmony_ci u16 offset; 11718c2ecf20Sopenharmony_ci u8 band = BAND_OF_FREQUENCY(p->frequency / 1000); 11728c2ecf20Sopenharmony_ci 11738c2ecf20Sopenharmony_ci switch (band) { 11748c2ecf20Sopenharmony_ci case BAND_VHF: 11758c2ecf20Sopenharmony_ci offset = 950; 11768c2ecf20Sopenharmony_ci break; 11778c2ecf20Sopenharmony_ci default: 11788c2ecf20Sopenharmony_ci case BAND_UHF: 11798c2ecf20Sopenharmony_ci offset = 550; 11808c2ecf20Sopenharmony_ci break; 11818c2ecf20Sopenharmony_ci } 11828c2ecf20Sopenharmony_ci 11838c2ecf20Sopenharmony_ci state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); 11848c2ecf20Sopenharmony_ci 11858c2ecf20Sopenharmony_ci return state->set_param_save(fe); 11868c2ecf20Sopenharmony_ci} 11878c2ecf20Sopenharmony_ci 11888c2ecf20Sopenharmony_cistatic int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap) 11898c2ecf20Sopenharmony_ci{ 11908c2ecf20Sopenharmony_ci struct dib0700_adapter_state *st = adap->priv; 11918c2ecf20Sopenharmony_ci struct i2c_adapter *tun_i2c; 11928c2ecf20Sopenharmony_ci 11938c2ecf20Sopenharmony_ci /* 11948c2ecf20Sopenharmony_ci * No need to call dvb7000p_attach here, as it was called 11958c2ecf20Sopenharmony_ci * already, as frontend_attach method is called first, and 11968c2ecf20Sopenharmony_ci * tuner_attach is only called on success. 11978c2ecf20Sopenharmony_ci */ 11988c2ecf20Sopenharmony_ci tun_i2c = st->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, 11998c2ecf20Sopenharmony_ci DIBX000_I2C_INTERFACE_TUNER, 1); 12008c2ecf20Sopenharmony_ci 12018c2ecf20Sopenharmony_ci if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, 12028c2ecf20Sopenharmony_ci &dib7070p_dib0070_config) == NULL) 12038c2ecf20Sopenharmony_ci return -ENODEV; 12048c2ecf20Sopenharmony_ci 12058c2ecf20Sopenharmony_ci st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; 12068c2ecf20Sopenharmony_ci adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override; 12078c2ecf20Sopenharmony_ci return 0; 12088c2ecf20Sopenharmony_ci} 12098c2ecf20Sopenharmony_ci 12108c2ecf20Sopenharmony_cistatic int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap) 12118c2ecf20Sopenharmony_ci{ 12128c2ecf20Sopenharmony_ci if (usb_set_interface(adap->dev->udev, 0, 1) < 0) 12138c2ecf20Sopenharmony_ci err("set interface failed"); 12148c2ecf20Sopenharmony_ci 12158c2ecf20Sopenharmony_ci cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); 12168c2ecf20Sopenharmony_ci 12178c2ecf20Sopenharmony_ci /* reset the tuner and demodulator */ 12188c2ecf20Sopenharmony_ci cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0); 12198c2ecf20Sopenharmony_ci cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1); 12208c2ecf20Sopenharmony_ci cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); 12218c2ecf20Sopenharmony_ci 12228c2ecf20Sopenharmony_ci adap->fe_adap[0].fe = dvb_attach(zl10353_attach, 12238c2ecf20Sopenharmony_ci &cxusb_zl10353_xc3028_config, 12248c2ecf20Sopenharmony_ci &adap->dev->i2c_adap); 12258c2ecf20Sopenharmony_ci if (adap->fe_adap[0].fe) 12268c2ecf20Sopenharmony_ci return 0; 12278c2ecf20Sopenharmony_ci 12288c2ecf20Sopenharmony_ci adap->fe_adap[0].fe = dvb_attach(mt352_attach, 12298c2ecf20Sopenharmony_ci &cxusb_mt352_xc3028_config, 12308c2ecf20Sopenharmony_ci &adap->dev->i2c_adap); 12318c2ecf20Sopenharmony_ci if (adap->fe_adap[0].fe) 12328c2ecf20Sopenharmony_ci return 0; 12338c2ecf20Sopenharmony_ci 12348c2ecf20Sopenharmony_ci return -EIO; 12358c2ecf20Sopenharmony_ci} 12368c2ecf20Sopenharmony_ci 12378c2ecf20Sopenharmony_cistatic struct lgs8gxx_config d680_lgs8gl5_cfg = { 12388c2ecf20Sopenharmony_ci .prod = LGS8GXX_PROD_LGS8GL5, 12398c2ecf20Sopenharmony_ci .demod_address = 0x19, 12408c2ecf20Sopenharmony_ci .serial_ts = 0, 12418c2ecf20Sopenharmony_ci .ts_clk_pol = 0, 12428c2ecf20Sopenharmony_ci .ts_clk_gated = 1, 12438c2ecf20Sopenharmony_ci .if_clk_freq = 30400, /* 30.4 MHz */ 12448c2ecf20Sopenharmony_ci .if_freq = 5725, /* 5.725 MHz */ 12458c2ecf20Sopenharmony_ci .if_neg_center = 0, 12468c2ecf20Sopenharmony_ci .ext_adc = 0, 12478c2ecf20Sopenharmony_ci .adc_signed = 0, 12488c2ecf20Sopenharmony_ci .if_neg_edge = 0, 12498c2ecf20Sopenharmony_ci}; 12508c2ecf20Sopenharmony_ci 12518c2ecf20Sopenharmony_cistatic int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap) 12528c2ecf20Sopenharmony_ci{ 12538c2ecf20Sopenharmony_ci struct dvb_usb_device *d = adap->dev; 12548c2ecf20Sopenharmony_ci int n; 12558c2ecf20Sopenharmony_ci 12568c2ecf20Sopenharmony_ci /* Select required USB configuration */ 12578c2ecf20Sopenharmony_ci if (usb_set_interface(d->udev, 0, 0) < 0) 12588c2ecf20Sopenharmony_ci err("set interface failed"); 12598c2ecf20Sopenharmony_ci 12608c2ecf20Sopenharmony_ci /* Unblock all USB pipes */ 12618c2ecf20Sopenharmony_ci usb_clear_halt(d->udev, 12628c2ecf20Sopenharmony_ci usb_sndbulkpipe(d->udev, 12638c2ecf20Sopenharmony_ci d->props.generic_bulk_ctrl_endpoint)); 12648c2ecf20Sopenharmony_ci usb_clear_halt(d->udev, 12658c2ecf20Sopenharmony_ci usb_rcvbulkpipe(d->udev, 12668c2ecf20Sopenharmony_ci d->props.generic_bulk_ctrl_endpoint)); 12678c2ecf20Sopenharmony_ci usb_clear_halt(d->udev, 12688c2ecf20Sopenharmony_ci usb_rcvbulkpipe(d->udev, 12698c2ecf20Sopenharmony_ci d->props.adapter[0].fe[0].stream.endpoint)); 12708c2ecf20Sopenharmony_ci 12718c2ecf20Sopenharmony_ci /* Drain USB pipes to avoid hang after reboot */ 12728c2ecf20Sopenharmony_ci for (n = 0; n < 5; n++) { 12738c2ecf20Sopenharmony_ci cxusb_d680_dmb_drain_message(d); 12748c2ecf20Sopenharmony_ci cxusb_d680_dmb_drain_video(d); 12758c2ecf20Sopenharmony_ci msleep(200); 12768c2ecf20Sopenharmony_ci } 12778c2ecf20Sopenharmony_ci 12788c2ecf20Sopenharmony_ci /* Reset the tuner */ 12798c2ecf20Sopenharmony_ci if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) { 12808c2ecf20Sopenharmony_ci err("clear tuner gpio failed"); 12818c2ecf20Sopenharmony_ci return -EIO; 12828c2ecf20Sopenharmony_ci } 12838c2ecf20Sopenharmony_ci msleep(100); 12848c2ecf20Sopenharmony_ci if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) { 12858c2ecf20Sopenharmony_ci err("set tuner gpio failed"); 12868c2ecf20Sopenharmony_ci return -EIO; 12878c2ecf20Sopenharmony_ci } 12888c2ecf20Sopenharmony_ci msleep(100); 12898c2ecf20Sopenharmony_ci 12908c2ecf20Sopenharmony_ci /* Attach frontend */ 12918c2ecf20Sopenharmony_ci adap->fe_adap[0].fe = dvb_attach(lgs8gxx_attach, 12928c2ecf20Sopenharmony_ci &d680_lgs8gl5_cfg, &d->i2c_adap); 12938c2ecf20Sopenharmony_ci if (!adap->fe_adap[0].fe) 12948c2ecf20Sopenharmony_ci return -EIO; 12958c2ecf20Sopenharmony_ci 12968c2ecf20Sopenharmony_ci return 0; 12978c2ecf20Sopenharmony_ci} 12988c2ecf20Sopenharmony_ci 12998c2ecf20Sopenharmony_cistatic struct atbm8830_config mygica_d689_atbm8830_cfg = { 13008c2ecf20Sopenharmony_ci .prod = ATBM8830_PROD_8830, 13018c2ecf20Sopenharmony_ci .demod_address = 0x40, 13028c2ecf20Sopenharmony_ci .serial_ts = 0, 13038c2ecf20Sopenharmony_ci .ts_sampling_edge = 1, 13048c2ecf20Sopenharmony_ci .ts_clk_gated = 0, 13058c2ecf20Sopenharmony_ci .osc_clk_freq = 30400, /* in kHz */ 13068c2ecf20Sopenharmony_ci .if_freq = 0, /* zero IF */ 13078c2ecf20Sopenharmony_ci .zif_swap_iq = 1, 13088c2ecf20Sopenharmony_ci .agc_min = 0x2E, 13098c2ecf20Sopenharmony_ci .agc_max = 0x90, 13108c2ecf20Sopenharmony_ci .agc_hold_loop = 0, 13118c2ecf20Sopenharmony_ci}; 13128c2ecf20Sopenharmony_ci 13138c2ecf20Sopenharmony_cistatic int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap) 13148c2ecf20Sopenharmony_ci{ 13158c2ecf20Sopenharmony_ci struct dvb_usb_device *d = adap->dev; 13168c2ecf20Sopenharmony_ci 13178c2ecf20Sopenharmony_ci /* Select required USB configuration */ 13188c2ecf20Sopenharmony_ci if (usb_set_interface(d->udev, 0, 0) < 0) 13198c2ecf20Sopenharmony_ci err("set interface failed"); 13208c2ecf20Sopenharmony_ci 13218c2ecf20Sopenharmony_ci /* Unblock all USB pipes */ 13228c2ecf20Sopenharmony_ci usb_clear_halt(d->udev, 13238c2ecf20Sopenharmony_ci usb_sndbulkpipe(d->udev, 13248c2ecf20Sopenharmony_ci d->props.generic_bulk_ctrl_endpoint)); 13258c2ecf20Sopenharmony_ci usb_clear_halt(d->udev, 13268c2ecf20Sopenharmony_ci usb_rcvbulkpipe(d->udev, 13278c2ecf20Sopenharmony_ci d->props.generic_bulk_ctrl_endpoint)); 13288c2ecf20Sopenharmony_ci usb_clear_halt(d->udev, 13298c2ecf20Sopenharmony_ci usb_rcvbulkpipe(d->udev, 13308c2ecf20Sopenharmony_ci d->props.adapter[0].fe[0].stream.endpoint)); 13318c2ecf20Sopenharmony_ci 13328c2ecf20Sopenharmony_ci /* Reset the tuner */ 13338c2ecf20Sopenharmony_ci if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) { 13348c2ecf20Sopenharmony_ci err("clear tuner gpio failed"); 13358c2ecf20Sopenharmony_ci return -EIO; 13368c2ecf20Sopenharmony_ci } 13378c2ecf20Sopenharmony_ci msleep(100); 13388c2ecf20Sopenharmony_ci if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) { 13398c2ecf20Sopenharmony_ci err("set tuner gpio failed"); 13408c2ecf20Sopenharmony_ci return -EIO; 13418c2ecf20Sopenharmony_ci } 13428c2ecf20Sopenharmony_ci msleep(100); 13438c2ecf20Sopenharmony_ci 13448c2ecf20Sopenharmony_ci /* Attach frontend */ 13458c2ecf20Sopenharmony_ci adap->fe_adap[0].fe = dvb_attach(atbm8830_attach, 13468c2ecf20Sopenharmony_ci &mygica_d689_atbm8830_cfg, 13478c2ecf20Sopenharmony_ci &d->i2c_adap); 13488c2ecf20Sopenharmony_ci if (!adap->fe_adap[0].fe) 13498c2ecf20Sopenharmony_ci return -EIO; 13508c2ecf20Sopenharmony_ci 13518c2ecf20Sopenharmony_ci return 0; 13528c2ecf20Sopenharmony_ci} 13538c2ecf20Sopenharmony_ci 13548c2ecf20Sopenharmony_ci/* 13558c2ecf20Sopenharmony_ci * DViCO has shipped two devices with the same USB ID, but only one of them 13568c2ecf20Sopenharmony_ci * needs a firmware download. Check the device class details to see if they 13578c2ecf20Sopenharmony_ci * have non-default values to decide whether the device is actually cold or 13588c2ecf20Sopenharmony_ci * not, and forget a match if it turns out we selected the wrong device. 13598c2ecf20Sopenharmony_ci */ 13608c2ecf20Sopenharmony_cistatic int bluebird_fx2_identify_state(struct usb_device *udev, 13618c2ecf20Sopenharmony_ci const struct dvb_usb_device_properties *props, 13628c2ecf20Sopenharmony_ci const struct dvb_usb_device_description **desc, 13638c2ecf20Sopenharmony_ci int *cold) 13648c2ecf20Sopenharmony_ci{ 13658c2ecf20Sopenharmony_ci int wascold = *cold; 13668c2ecf20Sopenharmony_ci 13678c2ecf20Sopenharmony_ci *cold = udev->descriptor.bDeviceClass == 0xff && 13688c2ecf20Sopenharmony_ci udev->descriptor.bDeviceSubClass == 0xff && 13698c2ecf20Sopenharmony_ci udev->descriptor.bDeviceProtocol == 0xff; 13708c2ecf20Sopenharmony_ci 13718c2ecf20Sopenharmony_ci if (*cold && !wascold) 13728c2ecf20Sopenharmony_ci *desc = NULL; 13738c2ecf20Sopenharmony_ci 13748c2ecf20Sopenharmony_ci return 0; 13758c2ecf20Sopenharmony_ci} 13768c2ecf20Sopenharmony_ci 13778c2ecf20Sopenharmony_ci/* 13788c2ecf20Sopenharmony_ci * DViCO bluebird firmware needs the "warm" product ID to be patched into the 13798c2ecf20Sopenharmony_ci * firmware file before download. 13808c2ecf20Sopenharmony_ci */ 13818c2ecf20Sopenharmony_ci 13828c2ecf20Sopenharmony_cistatic const int dvico_firmware_id_offsets[] = { 6638, 3204 }; 13838c2ecf20Sopenharmony_cistatic int bluebird_patch_dvico_firmware_download(struct usb_device *udev, 13848c2ecf20Sopenharmony_ci const struct firmware *fw) 13858c2ecf20Sopenharmony_ci{ 13868c2ecf20Sopenharmony_ci int pos; 13878c2ecf20Sopenharmony_ci 13888c2ecf20Sopenharmony_ci for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) { 13898c2ecf20Sopenharmony_ci int idoff = dvico_firmware_id_offsets[pos]; 13908c2ecf20Sopenharmony_ci 13918c2ecf20Sopenharmony_ci if (fw->size < idoff + 4) 13928c2ecf20Sopenharmony_ci continue; 13938c2ecf20Sopenharmony_ci 13948c2ecf20Sopenharmony_ci if (fw->data[idoff] == (USB_VID_DVICO & 0xff) && 13958c2ecf20Sopenharmony_ci fw->data[idoff + 1] == USB_VID_DVICO >> 8) { 13968c2ecf20Sopenharmony_ci struct firmware new_fw; 13978c2ecf20Sopenharmony_ci u8 *new_fw_data = vmalloc(fw->size); 13988c2ecf20Sopenharmony_ci int ret; 13998c2ecf20Sopenharmony_ci 14008c2ecf20Sopenharmony_ci if (!new_fw_data) 14018c2ecf20Sopenharmony_ci return -ENOMEM; 14028c2ecf20Sopenharmony_ci 14038c2ecf20Sopenharmony_ci memcpy(new_fw_data, fw->data, fw->size); 14048c2ecf20Sopenharmony_ci new_fw.size = fw->size; 14058c2ecf20Sopenharmony_ci new_fw.data = new_fw_data; 14068c2ecf20Sopenharmony_ci 14078c2ecf20Sopenharmony_ci new_fw_data[idoff + 2] = 14088c2ecf20Sopenharmony_ci le16_to_cpu(udev->descriptor.idProduct) + 1; 14098c2ecf20Sopenharmony_ci new_fw_data[idoff + 3] = 14108c2ecf20Sopenharmony_ci le16_to_cpu(udev->descriptor.idProduct) >> 8; 14118c2ecf20Sopenharmony_ci 14128c2ecf20Sopenharmony_ci ret = usb_cypress_load_firmware(udev, &new_fw, 14138c2ecf20Sopenharmony_ci CYPRESS_FX2); 14148c2ecf20Sopenharmony_ci vfree(new_fw_data); 14158c2ecf20Sopenharmony_ci return ret; 14168c2ecf20Sopenharmony_ci } 14178c2ecf20Sopenharmony_ci } 14188c2ecf20Sopenharmony_ci 14198c2ecf20Sopenharmony_ci return -EINVAL; 14208c2ecf20Sopenharmony_ci} 14218c2ecf20Sopenharmony_ci 14228c2ecf20Sopenharmony_ciint cxusb_medion_get(struct dvb_usb_device *dvbdev, 14238c2ecf20Sopenharmony_ci enum cxusb_open_type open_type) 14248c2ecf20Sopenharmony_ci{ 14258c2ecf20Sopenharmony_ci struct cxusb_medion_dev *cxdev = dvbdev->priv; 14268c2ecf20Sopenharmony_ci int ret = 0; 14278c2ecf20Sopenharmony_ci 14288c2ecf20Sopenharmony_ci mutex_lock(&cxdev->open_lock); 14298c2ecf20Sopenharmony_ci 14308c2ecf20Sopenharmony_ci if (WARN_ON((cxdev->open_type == CXUSB_OPEN_INIT || 14318c2ecf20Sopenharmony_ci cxdev->open_type == CXUSB_OPEN_NONE) && 14328c2ecf20Sopenharmony_ci cxdev->open_ctr != 0)) { 14338c2ecf20Sopenharmony_ci ret = -EINVAL; 14348c2ecf20Sopenharmony_ci goto ret_unlock; 14358c2ecf20Sopenharmony_ci } 14368c2ecf20Sopenharmony_ci 14378c2ecf20Sopenharmony_ci if (cxdev->open_type == CXUSB_OPEN_INIT) { 14388c2ecf20Sopenharmony_ci ret = -EAGAIN; 14398c2ecf20Sopenharmony_ci goto ret_unlock; 14408c2ecf20Sopenharmony_ci } 14418c2ecf20Sopenharmony_ci 14428c2ecf20Sopenharmony_ci if (cxdev->open_ctr == 0) { 14438c2ecf20Sopenharmony_ci if (cxdev->open_type != open_type) { 14448c2ecf20Sopenharmony_ci dev_info(&dvbdev->udev->dev, "will acquire and switch to %s\n", 14458c2ecf20Sopenharmony_ci open_type == CXUSB_OPEN_ANALOG ? 14468c2ecf20Sopenharmony_ci "analog" : "digital"); 14478c2ecf20Sopenharmony_ci 14488c2ecf20Sopenharmony_ci if (open_type == CXUSB_OPEN_ANALOG) { 14498c2ecf20Sopenharmony_ci ret = _cxusb_power_ctrl(dvbdev, 1); 14508c2ecf20Sopenharmony_ci if (ret != 0) 14518c2ecf20Sopenharmony_ci dev_warn(&dvbdev->udev->dev, 14528c2ecf20Sopenharmony_ci "powerup for analog switch failed (%d)\n", 14538c2ecf20Sopenharmony_ci ret); 14548c2ecf20Sopenharmony_ci 14558c2ecf20Sopenharmony_ci ret = cxusb_medion_set_mode(dvbdev, false); 14568c2ecf20Sopenharmony_ci if (ret != 0) 14578c2ecf20Sopenharmony_ci goto ret_unlock; 14588c2ecf20Sopenharmony_ci 14598c2ecf20Sopenharmony_ci ret = cxusb_medion_analog_init(dvbdev); 14608c2ecf20Sopenharmony_ci if (ret != 0) 14618c2ecf20Sopenharmony_ci goto ret_unlock; 14628c2ecf20Sopenharmony_ci } else { /* digital */ 14638c2ecf20Sopenharmony_ci ret = _cxusb_power_ctrl(dvbdev, 1); 14648c2ecf20Sopenharmony_ci if (ret != 0) 14658c2ecf20Sopenharmony_ci dev_warn(&dvbdev->udev->dev, 14668c2ecf20Sopenharmony_ci "powerup for digital switch failed (%d)\n", 14678c2ecf20Sopenharmony_ci ret); 14688c2ecf20Sopenharmony_ci 14698c2ecf20Sopenharmony_ci ret = cxusb_medion_set_mode(dvbdev, true); 14708c2ecf20Sopenharmony_ci if (ret != 0) 14718c2ecf20Sopenharmony_ci goto ret_unlock; 14728c2ecf20Sopenharmony_ci } 14738c2ecf20Sopenharmony_ci 14748c2ecf20Sopenharmony_ci cxdev->open_type = open_type; 14758c2ecf20Sopenharmony_ci } else { 14768c2ecf20Sopenharmony_ci dev_info(&dvbdev->udev->dev, "reacquired idle %s\n", 14778c2ecf20Sopenharmony_ci open_type == CXUSB_OPEN_ANALOG ? 14788c2ecf20Sopenharmony_ci "analog" : "digital"); 14798c2ecf20Sopenharmony_ci } 14808c2ecf20Sopenharmony_ci 14818c2ecf20Sopenharmony_ci cxdev->open_ctr = 1; 14828c2ecf20Sopenharmony_ci } else if (cxdev->open_type == open_type) { 14838c2ecf20Sopenharmony_ci cxdev->open_ctr++; 14848c2ecf20Sopenharmony_ci dev_info(&dvbdev->udev->dev, "acquired %s\n", 14858c2ecf20Sopenharmony_ci open_type == CXUSB_OPEN_ANALOG ? "analog" : "digital"); 14868c2ecf20Sopenharmony_ci } else { 14878c2ecf20Sopenharmony_ci ret = -EBUSY; 14888c2ecf20Sopenharmony_ci } 14898c2ecf20Sopenharmony_ci 14908c2ecf20Sopenharmony_ciret_unlock: 14918c2ecf20Sopenharmony_ci mutex_unlock(&cxdev->open_lock); 14928c2ecf20Sopenharmony_ci 14938c2ecf20Sopenharmony_ci return ret; 14948c2ecf20Sopenharmony_ci} 14958c2ecf20Sopenharmony_ci 14968c2ecf20Sopenharmony_civoid cxusb_medion_put(struct dvb_usb_device *dvbdev) 14978c2ecf20Sopenharmony_ci{ 14988c2ecf20Sopenharmony_ci struct cxusb_medion_dev *cxdev = dvbdev->priv; 14998c2ecf20Sopenharmony_ci 15008c2ecf20Sopenharmony_ci mutex_lock(&cxdev->open_lock); 15018c2ecf20Sopenharmony_ci 15028c2ecf20Sopenharmony_ci if (cxdev->open_type == CXUSB_OPEN_INIT) { 15038c2ecf20Sopenharmony_ci WARN_ON(cxdev->open_ctr != 0); 15048c2ecf20Sopenharmony_ci cxdev->open_type = CXUSB_OPEN_NONE; 15058c2ecf20Sopenharmony_ci goto unlock; 15068c2ecf20Sopenharmony_ci } 15078c2ecf20Sopenharmony_ci 15088c2ecf20Sopenharmony_ci if (!WARN_ON(cxdev->open_ctr < 1)) { 15098c2ecf20Sopenharmony_ci cxdev->open_ctr--; 15108c2ecf20Sopenharmony_ci 15118c2ecf20Sopenharmony_ci dev_info(&dvbdev->udev->dev, "release %s\n", 15128c2ecf20Sopenharmony_ci cxdev->open_type == CXUSB_OPEN_ANALOG ? 15138c2ecf20Sopenharmony_ci "analog" : "digital"); 15148c2ecf20Sopenharmony_ci } 15158c2ecf20Sopenharmony_ci 15168c2ecf20Sopenharmony_ciunlock: 15178c2ecf20Sopenharmony_ci mutex_unlock(&cxdev->open_lock); 15188c2ecf20Sopenharmony_ci} 15198c2ecf20Sopenharmony_ci 15208c2ecf20Sopenharmony_ci/* DVB USB Driver stuff */ 15218c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_medion_properties; 15228c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties; 15238c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties; 15248c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties; 15258c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties; 15268c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties; 15278c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties; 15288c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_bluebird_nano2_properties; 15298c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties; 15308c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_aver_a868r_properties; 15318c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_d680_dmb_properties; 15328c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_mygica_d689_properties; 15338c2ecf20Sopenharmony_ci 15348c2ecf20Sopenharmony_cistatic int cxusb_medion_priv_init(struct dvb_usb_device *dvbdev) 15358c2ecf20Sopenharmony_ci{ 15368c2ecf20Sopenharmony_ci struct cxusb_medion_dev *cxdev = dvbdev->priv; 15378c2ecf20Sopenharmony_ci 15388c2ecf20Sopenharmony_ci cxdev->dvbdev = dvbdev; 15398c2ecf20Sopenharmony_ci cxdev->open_type = CXUSB_OPEN_INIT; 15408c2ecf20Sopenharmony_ci mutex_init(&cxdev->open_lock); 15418c2ecf20Sopenharmony_ci 15428c2ecf20Sopenharmony_ci return 0; 15438c2ecf20Sopenharmony_ci} 15448c2ecf20Sopenharmony_ci 15458c2ecf20Sopenharmony_cistatic void cxusb_medion_priv_destroy(struct dvb_usb_device *dvbdev) 15468c2ecf20Sopenharmony_ci{ 15478c2ecf20Sopenharmony_ci struct cxusb_medion_dev *cxdev = dvbdev->priv; 15488c2ecf20Sopenharmony_ci 15498c2ecf20Sopenharmony_ci mutex_destroy(&cxdev->open_lock); 15508c2ecf20Sopenharmony_ci} 15518c2ecf20Sopenharmony_ci 15528c2ecf20Sopenharmony_cistatic bool cxusb_medion_check_altsetting(struct usb_host_interface *as) 15538c2ecf20Sopenharmony_ci{ 15548c2ecf20Sopenharmony_ci unsigned int ctr; 15558c2ecf20Sopenharmony_ci 15568c2ecf20Sopenharmony_ci for (ctr = 0; ctr < as->desc.bNumEndpoints; ctr++) { 15578c2ecf20Sopenharmony_ci if ((as->endpoint[ctr].desc.bEndpointAddress & 15588c2ecf20Sopenharmony_ci USB_ENDPOINT_NUMBER_MASK) != 2) 15598c2ecf20Sopenharmony_ci continue; 15608c2ecf20Sopenharmony_ci 15618c2ecf20Sopenharmony_ci if (as->endpoint[ctr].desc.bEndpointAddress & USB_DIR_IN && 15628c2ecf20Sopenharmony_ci ((as->endpoint[ctr].desc.bmAttributes & 15638c2ecf20Sopenharmony_ci USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC)) 15648c2ecf20Sopenharmony_ci return true; 15658c2ecf20Sopenharmony_ci 15668c2ecf20Sopenharmony_ci break; 15678c2ecf20Sopenharmony_ci } 15688c2ecf20Sopenharmony_ci 15698c2ecf20Sopenharmony_ci return false; 15708c2ecf20Sopenharmony_ci} 15718c2ecf20Sopenharmony_ci 15728c2ecf20Sopenharmony_cistatic bool cxusb_medion_check_intf(struct usb_interface *intf) 15738c2ecf20Sopenharmony_ci{ 15748c2ecf20Sopenharmony_ci unsigned int ctr; 15758c2ecf20Sopenharmony_ci 15768c2ecf20Sopenharmony_ci if (intf->num_altsetting < 2) { 15778c2ecf20Sopenharmony_ci dev_err(intf->usb_dev, "no alternate interface"); 15788c2ecf20Sopenharmony_ci 15798c2ecf20Sopenharmony_ci return false; 15808c2ecf20Sopenharmony_ci } 15818c2ecf20Sopenharmony_ci 15828c2ecf20Sopenharmony_ci for (ctr = 0; ctr < intf->num_altsetting; ctr++) { 15838c2ecf20Sopenharmony_ci if (intf->altsetting[ctr].desc.bAlternateSetting != 1) 15848c2ecf20Sopenharmony_ci continue; 15858c2ecf20Sopenharmony_ci 15868c2ecf20Sopenharmony_ci if (cxusb_medion_check_altsetting(&intf->altsetting[ctr])) 15878c2ecf20Sopenharmony_ci return true; 15888c2ecf20Sopenharmony_ci 15898c2ecf20Sopenharmony_ci break; 15908c2ecf20Sopenharmony_ci } 15918c2ecf20Sopenharmony_ci 15928c2ecf20Sopenharmony_ci dev_err(intf->usb_dev, "no iso interface"); 15938c2ecf20Sopenharmony_ci 15948c2ecf20Sopenharmony_ci return false; 15958c2ecf20Sopenharmony_ci} 15968c2ecf20Sopenharmony_ci 15978c2ecf20Sopenharmony_cistatic int cxusb_probe(struct usb_interface *intf, 15988c2ecf20Sopenharmony_ci const struct usb_device_id *id) 15998c2ecf20Sopenharmony_ci{ 16008c2ecf20Sopenharmony_ci struct dvb_usb_device *dvbdev; 16018c2ecf20Sopenharmony_ci int ret; 16028c2ecf20Sopenharmony_ci 16038c2ecf20Sopenharmony_ci /* Medion 95700 */ 16048c2ecf20Sopenharmony_ci if (!dvb_usb_device_init(intf, &cxusb_medion_properties, 16058c2ecf20Sopenharmony_ci THIS_MODULE, &dvbdev, adapter_nr)) { 16068c2ecf20Sopenharmony_ci if (!cxusb_medion_check_intf(intf)) { 16078c2ecf20Sopenharmony_ci ret = -ENODEV; 16088c2ecf20Sopenharmony_ci goto ret_uninit; 16098c2ecf20Sopenharmony_ci } 16108c2ecf20Sopenharmony_ci 16118c2ecf20Sopenharmony_ci _cxusb_power_ctrl(dvbdev, 1); 16128c2ecf20Sopenharmony_ci ret = cxusb_medion_set_mode(dvbdev, false); 16138c2ecf20Sopenharmony_ci if (ret) 16148c2ecf20Sopenharmony_ci goto ret_uninit; 16158c2ecf20Sopenharmony_ci 16168c2ecf20Sopenharmony_ci ret = cxusb_medion_register_analog(dvbdev); 16178c2ecf20Sopenharmony_ci 16188c2ecf20Sopenharmony_ci cxusb_medion_set_mode(dvbdev, true); 16198c2ecf20Sopenharmony_ci _cxusb_power_ctrl(dvbdev, 0); 16208c2ecf20Sopenharmony_ci 16218c2ecf20Sopenharmony_ci if (ret != 0) 16228c2ecf20Sopenharmony_ci goto ret_uninit; 16238c2ecf20Sopenharmony_ci 16248c2ecf20Sopenharmony_ci /* release device from INIT mode to normal operation */ 16258c2ecf20Sopenharmony_ci cxusb_medion_put(dvbdev); 16268c2ecf20Sopenharmony_ci 16278c2ecf20Sopenharmony_ci return 0; 16288c2ecf20Sopenharmony_ci } else if (!dvb_usb_device_init(intf, 16298c2ecf20Sopenharmony_ci &cxusb_bluebird_lgh064f_properties, 16308c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) || 16318c2ecf20Sopenharmony_ci !dvb_usb_device_init(intf, 16328c2ecf20Sopenharmony_ci &cxusb_bluebird_dee1601_properties, 16338c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) || 16348c2ecf20Sopenharmony_ci !dvb_usb_device_init(intf, 16358c2ecf20Sopenharmony_ci &cxusb_bluebird_lgz201_properties, 16368c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) || 16378c2ecf20Sopenharmony_ci !dvb_usb_device_init(intf, 16388c2ecf20Sopenharmony_ci &cxusb_bluebird_dtt7579_properties, 16398c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) || 16408c2ecf20Sopenharmony_ci !dvb_usb_device_init(intf, 16418c2ecf20Sopenharmony_ci &cxusb_bluebird_dualdig4_properties, 16428c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) || 16438c2ecf20Sopenharmony_ci !dvb_usb_device_init(intf, 16448c2ecf20Sopenharmony_ci &cxusb_bluebird_nano2_properties, 16458c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) || 16468c2ecf20Sopenharmony_ci !dvb_usb_device_init(intf, 16478c2ecf20Sopenharmony_ci &cxusb_bluebird_nano2_needsfirmware_properties, 16488c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) || 16498c2ecf20Sopenharmony_ci !dvb_usb_device_init(intf, &cxusb_aver_a868r_properties, 16508c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) || 16518c2ecf20Sopenharmony_ci !dvb_usb_device_init(intf, 16528c2ecf20Sopenharmony_ci &cxusb_bluebird_dualdig4_rev2_properties, 16538c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) || 16548c2ecf20Sopenharmony_ci !dvb_usb_device_init(intf, &cxusb_d680_dmb_properties, 16558c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) || 16568c2ecf20Sopenharmony_ci !dvb_usb_device_init(intf, &cxusb_mygica_d689_properties, 16578c2ecf20Sopenharmony_ci THIS_MODULE, NULL, adapter_nr) || 16588c2ecf20Sopenharmony_ci 0) 16598c2ecf20Sopenharmony_ci return 0; 16608c2ecf20Sopenharmony_ci 16618c2ecf20Sopenharmony_ci return -EINVAL; 16628c2ecf20Sopenharmony_ci 16638c2ecf20Sopenharmony_ciret_uninit: 16648c2ecf20Sopenharmony_ci dvb_usb_device_exit(intf); 16658c2ecf20Sopenharmony_ci 16668c2ecf20Sopenharmony_ci return ret; 16678c2ecf20Sopenharmony_ci} 16688c2ecf20Sopenharmony_ci 16698c2ecf20Sopenharmony_cistatic void cxusb_disconnect(struct usb_interface *intf) 16708c2ecf20Sopenharmony_ci{ 16718c2ecf20Sopenharmony_ci struct dvb_usb_device *d = usb_get_intfdata(intf); 16728c2ecf20Sopenharmony_ci struct cxusb_state *st = d->priv; 16738c2ecf20Sopenharmony_ci struct i2c_client *client; 16748c2ecf20Sopenharmony_ci 16758c2ecf20Sopenharmony_ci if (d->props.devices[0].warm_ids[0] == &cxusb_table[MEDION_MD95700]) 16768c2ecf20Sopenharmony_ci cxusb_medion_unregister_analog(d); 16778c2ecf20Sopenharmony_ci 16788c2ecf20Sopenharmony_ci /* remove I2C client for tuner */ 16798c2ecf20Sopenharmony_ci client = st->i2c_client_tuner; 16808c2ecf20Sopenharmony_ci if (client) { 16818c2ecf20Sopenharmony_ci module_put(client->dev.driver->owner); 16828c2ecf20Sopenharmony_ci i2c_unregister_device(client); 16838c2ecf20Sopenharmony_ci } 16848c2ecf20Sopenharmony_ci 16858c2ecf20Sopenharmony_ci /* remove I2C client for demodulator */ 16868c2ecf20Sopenharmony_ci client = st->i2c_client_demod; 16878c2ecf20Sopenharmony_ci if (client) { 16888c2ecf20Sopenharmony_ci module_put(client->dev.driver->owner); 16898c2ecf20Sopenharmony_ci i2c_unregister_device(client); 16908c2ecf20Sopenharmony_ci } 16918c2ecf20Sopenharmony_ci 16928c2ecf20Sopenharmony_ci dvb_usb_device_exit(intf); 16938c2ecf20Sopenharmony_ci} 16948c2ecf20Sopenharmony_ci 16958c2ecf20Sopenharmony_cistatic struct usb_device_id cxusb_table[NR__cxusb_table_index + 1] = { 16968c2ecf20Sopenharmony_ci [MEDION_MD95700] = { 16978c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) 16988c2ecf20Sopenharmony_ci }, 16998c2ecf20Sopenharmony_ci [DVICO_BLUEBIRD_LG064F_COLD] = { 17008c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) 17018c2ecf20Sopenharmony_ci }, 17028c2ecf20Sopenharmony_ci [DVICO_BLUEBIRD_LG064F_WARM] = { 17038c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) 17048c2ecf20Sopenharmony_ci }, 17058c2ecf20Sopenharmony_ci [DVICO_BLUEBIRD_DUAL_1_COLD] = { 17068c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) 17078c2ecf20Sopenharmony_ci }, 17088c2ecf20Sopenharmony_ci [DVICO_BLUEBIRD_DUAL_1_WARM] = { 17098c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) 17108c2ecf20Sopenharmony_ci }, 17118c2ecf20Sopenharmony_ci [DVICO_BLUEBIRD_LGZ201_COLD] = { 17128c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) 17138c2ecf20Sopenharmony_ci }, 17148c2ecf20Sopenharmony_ci [DVICO_BLUEBIRD_LGZ201_WARM] = { 17158c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) 17168c2ecf20Sopenharmony_ci }, 17178c2ecf20Sopenharmony_ci [DVICO_BLUEBIRD_TH7579_COLD] = { 17188c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) 17198c2ecf20Sopenharmony_ci }, 17208c2ecf20Sopenharmony_ci [DVICO_BLUEBIRD_TH7579_WARM] = { 17218c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) 17228c2ecf20Sopenharmony_ci }, 17238c2ecf20Sopenharmony_ci [DIGITALNOW_BLUEBIRD_DUAL_1_COLD] = { 17248c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_DVICO, 17258c2ecf20Sopenharmony_ci USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) 17268c2ecf20Sopenharmony_ci }, 17278c2ecf20Sopenharmony_ci [DIGITALNOW_BLUEBIRD_DUAL_1_WARM] = { 17288c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_DVICO, 17298c2ecf20Sopenharmony_ci USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) 17308c2ecf20Sopenharmony_ci }, 17318c2ecf20Sopenharmony_ci [DVICO_BLUEBIRD_DUAL_2_COLD] = { 17328c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) 17338c2ecf20Sopenharmony_ci }, 17348c2ecf20Sopenharmony_ci [DVICO_BLUEBIRD_DUAL_2_WARM] = { 17358c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) 17368c2ecf20Sopenharmony_ci }, 17378c2ecf20Sopenharmony_ci [DVICO_BLUEBIRD_DUAL_4] = { 17388c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) 17398c2ecf20Sopenharmony_ci }, 17408c2ecf20Sopenharmony_ci [DVICO_BLUEBIRD_DVB_T_NANO_2] = { 17418c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) 17428c2ecf20Sopenharmony_ci }, 17438c2ecf20Sopenharmony_ci [DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM] = { 17448c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_DVICO, 17458c2ecf20Sopenharmony_ci USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) 17468c2ecf20Sopenharmony_ci }, 17478c2ecf20Sopenharmony_ci [AVERMEDIA_VOLAR_A868R] = { 17488c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) 17498c2ecf20Sopenharmony_ci }, 17508c2ecf20Sopenharmony_ci [DVICO_BLUEBIRD_DUAL_4_REV_2] = { 17518c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) 17528c2ecf20Sopenharmony_ci }, 17538c2ecf20Sopenharmony_ci [CONEXANT_D680_DMB] = { 17548c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) 17558c2ecf20Sopenharmony_ci }, 17568c2ecf20Sopenharmony_ci [MYGICA_D689] = { 17578c2ecf20Sopenharmony_ci USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) 17588c2ecf20Sopenharmony_ci }, 17598c2ecf20Sopenharmony_ci {} /* Terminating entry */ 17608c2ecf20Sopenharmony_ci}; 17618c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(usb, cxusb_table); 17628c2ecf20Sopenharmony_ci 17638c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_medion_properties = { 17648c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 17658c2ecf20Sopenharmony_ci 17668c2ecf20Sopenharmony_ci .usb_ctrl = CYPRESS_FX2, 17678c2ecf20Sopenharmony_ci 17688c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct cxusb_medion_dev), 17698c2ecf20Sopenharmony_ci .priv_init = cxusb_medion_priv_init, 17708c2ecf20Sopenharmony_ci .priv_destroy = cxusb_medion_priv_destroy, 17718c2ecf20Sopenharmony_ci 17728c2ecf20Sopenharmony_ci .num_adapters = 1, 17738c2ecf20Sopenharmony_ci .adapter = { 17748c2ecf20Sopenharmony_ci { 17758c2ecf20Sopenharmony_ci .num_frontends = 1, 17768c2ecf20Sopenharmony_ci .fe = {{ 17778c2ecf20Sopenharmony_ci .streaming_ctrl = cxusb_streaming_ctrl, 17788c2ecf20Sopenharmony_ci .frontend_attach = cxusb_cx22702_frontend_attach, 17798c2ecf20Sopenharmony_ci .tuner_attach = cxusb_fmd1216me_tuner_attach, 17808c2ecf20Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 17818c2ecf20Sopenharmony_ci .stream = { 17828c2ecf20Sopenharmony_ci .type = USB_BULK, 17838c2ecf20Sopenharmony_ci .count = 5, 17848c2ecf20Sopenharmony_ci .endpoint = 0x02, 17858c2ecf20Sopenharmony_ci .u = { 17868c2ecf20Sopenharmony_ci .bulk = { 17878c2ecf20Sopenharmony_ci .buffersize = 8192, 17888c2ecf20Sopenharmony_ci } 17898c2ecf20Sopenharmony_ci } 17908c2ecf20Sopenharmony_ci }, 17918c2ecf20Sopenharmony_ci } }, 17928c2ecf20Sopenharmony_ci }, 17938c2ecf20Sopenharmony_ci }, 17948c2ecf20Sopenharmony_ci .power_ctrl = cxusb_power_ctrl, 17958c2ecf20Sopenharmony_ci 17968c2ecf20Sopenharmony_ci .i2c_algo = &cxusb_i2c_algo, 17978c2ecf20Sopenharmony_ci 17988c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 17998c2ecf20Sopenharmony_ci 18008c2ecf20Sopenharmony_ci .num_device_descs = 1, 18018c2ecf20Sopenharmony_ci .devices = { 18028c2ecf20Sopenharmony_ci { 18038c2ecf20Sopenharmony_ci "Medion MD95700 (MDUSBTV-HYBRID)", 18048c2ecf20Sopenharmony_ci { NULL }, 18058c2ecf20Sopenharmony_ci { &cxusb_table[MEDION_MD95700], NULL }, 18068c2ecf20Sopenharmony_ci }, 18078c2ecf20Sopenharmony_ci } 18088c2ecf20Sopenharmony_ci}; 18098c2ecf20Sopenharmony_ci 18108c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = { 18118c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 18128c2ecf20Sopenharmony_ci 18138c2ecf20Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 18148c2ecf20Sopenharmony_ci .firmware = "dvb-usb-bluebird-01.fw", 18158c2ecf20Sopenharmony_ci .download_firmware = bluebird_patch_dvico_firmware_download, 18168c2ecf20Sopenharmony_ci /* 18178c2ecf20Sopenharmony_ci * use usb alt setting 0 for EP4 transfer (dvb-t), 18188c2ecf20Sopenharmony_ci * use usb alt setting 7 for EP2 transfer (atsc) 18198c2ecf20Sopenharmony_ci */ 18208c2ecf20Sopenharmony_ci 18218c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct cxusb_state), 18228c2ecf20Sopenharmony_ci 18238c2ecf20Sopenharmony_ci .num_adapters = 1, 18248c2ecf20Sopenharmony_ci .adapter = { 18258c2ecf20Sopenharmony_ci { 18268c2ecf20Sopenharmony_ci .num_frontends = 1, 18278c2ecf20Sopenharmony_ci .fe = {{ 18288c2ecf20Sopenharmony_ci .streaming_ctrl = cxusb_streaming_ctrl, 18298c2ecf20Sopenharmony_ci .frontend_attach = cxusb_lgdt3303_frontend_attach, 18308c2ecf20Sopenharmony_ci .tuner_attach = cxusb_lgh064f_tuner_attach, 18318c2ecf20Sopenharmony_ci 18328c2ecf20Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 18338c2ecf20Sopenharmony_ci .stream = { 18348c2ecf20Sopenharmony_ci .type = USB_BULK, 18358c2ecf20Sopenharmony_ci .count = 5, 18368c2ecf20Sopenharmony_ci .endpoint = 0x02, 18378c2ecf20Sopenharmony_ci .u = { 18388c2ecf20Sopenharmony_ci .bulk = { 18398c2ecf20Sopenharmony_ci .buffersize = 8192, 18408c2ecf20Sopenharmony_ci } 18418c2ecf20Sopenharmony_ci } 18428c2ecf20Sopenharmony_ci }, 18438c2ecf20Sopenharmony_ci } }, 18448c2ecf20Sopenharmony_ci }, 18458c2ecf20Sopenharmony_ci }, 18468c2ecf20Sopenharmony_ci 18478c2ecf20Sopenharmony_ci .power_ctrl = cxusb_bluebird_power_ctrl, 18488c2ecf20Sopenharmony_ci 18498c2ecf20Sopenharmony_ci .i2c_algo = &cxusb_i2c_algo, 18508c2ecf20Sopenharmony_ci 18518c2ecf20Sopenharmony_ci .rc.core = { 18528c2ecf20Sopenharmony_ci .rc_interval = 100, 18538c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_DVICO_PORTABLE, 18548c2ecf20Sopenharmony_ci .module_name = KBUILD_MODNAME, 18558c2ecf20Sopenharmony_ci .rc_query = cxusb_rc_query, 18568c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 18578c2ecf20Sopenharmony_ci }, 18588c2ecf20Sopenharmony_ci 18598c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 18608c2ecf20Sopenharmony_ci 18618c2ecf20Sopenharmony_ci .num_device_descs = 1, 18628c2ecf20Sopenharmony_ci .devices = { 18638c2ecf20Sopenharmony_ci { "DViCO FusionHDTV5 USB Gold", 18648c2ecf20Sopenharmony_ci { &cxusb_table[DVICO_BLUEBIRD_LG064F_COLD], NULL }, 18658c2ecf20Sopenharmony_ci { &cxusb_table[DVICO_BLUEBIRD_LG064F_WARM], NULL }, 18668c2ecf20Sopenharmony_ci }, 18678c2ecf20Sopenharmony_ci } 18688c2ecf20Sopenharmony_ci}; 18698c2ecf20Sopenharmony_ci 18708c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = { 18718c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 18728c2ecf20Sopenharmony_ci 18738c2ecf20Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 18748c2ecf20Sopenharmony_ci .firmware = "dvb-usb-bluebird-01.fw", 18758c2ecf20Sopenharmony_ci .download_firmware = bluebird_patch_dvico_firmware_download, 18768c2ecf20Sopenharmony_ci /* 18778c2ecf20Sopenharmony_ci * use usb alt setting 0 for EP4 transfer (dvb-t), 18788c2ecf20Sopenharmony_ci * use usb alt setting 7 for EP2 transfer (atsc) 18798c2ecf20Sopenharmony_ci */ 18808c2ecf20Sopenharmony_ci 18818c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct cxusb_state), 18828c2ecf20Sopenharmony_ci 18838c2ecf20Sopenharmony_ci .num_adapters = 1, 18848c2ecf20Sopenharmony_ci .adapter = { 18858c2ecf20Sopenharmony_ci { 18868c2ecf20Sopenharmony_ci .num_frontends = 1, 18878c2ecf20Sopenharmony_ci .fe = {{ 18888c2ecf20Sopenharmony_ci .streaming_ctrl = cxusb_streaming_ctrl, 18898c2ecf20Sopenharmony_ci .frontend_attach = cxusb_dee1601_frontend_attach, 18908c2ecf20Sopenharmony_ci .tuner_attach = cxusb_dee1601_tuner_attach, 18918c2ecf20Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 18928c2ecf20Sopenharmony_ci .stream = { 18938c2ecf20Sopenharmony_ci .type = USB_BULK, 18948c2ecf20Sopenharmony_ci .count = 5, 18958c2ecf20Sopenharmony_ci .endpoint = 0x04, 18968c2ecf20Sopenharmony_ci .u = { 18978c2ecf20Sopenharmony_ci .bulk = { 18988c2ecf20Sopenharmony_ci .buffersize = 8192, 18998c2ecf20Sopenharmony_ci } 19008c2ecf20Sopenharmony_ci } 19018c2ecf20Sopenharmony_ci }, 19028c2ecf20Sopenharmony_ci } }, 19038c2ecf20Sopenharmony_ci }, 19048c2ecf20Sopenharmony_ci }, 19058c2ecf20Sopenharmony_ci 19068c2ecf20Sopenharmony_ci .power_ctrl = cxusb_bluebird_power_ctrl, 19078c2ecf20Sopenharmony_ci 19088c2ecf20Sopenharmony_ci .i2c_algo = &cxusb_i2c_algo, 19098c2ecf20Sopenharmony_ci 19108c2ecf20Sopenharmony_ci .rc.core = { 19118c2ecf20Sopenharmony_ci .rc_interval = 100, 19128c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_DVICO_MCE, 19138c2ecf20Sopenharmony_ci .module_name = KBUILD_MODNAME, 19148c2ecf20Sopenharmony_ci .rc_query = cxusb_rc_query, 19158c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 19168c2ecf20Sopenharmony_ci }, 19178c2ecf20Sopenharmony_ci 19188c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 19198c2ecf20Sopenharmony_ci 19208c2ecf20Sopenharmony_ci .num_device_descs = 3, 19218c2ecf20Sopenharmony_ci .devices = { 19228c2ecf20Sopenharmony_ci { "DViCO FusionHDTV DVB-T Dual USB", 19238c2ecf20Sopenharmony_ci { &cxusb_table[DVICO_BLUEBIRD_DUAL_1_COLD], NULL }, 19248c2ecf20Sopenharmony_ci { &cxusb_table[DVICO_BLUEBIRD_DUAL_1_WARM], NULL }, 19258c2ecf20Sopenharmony_ci }, 19268c2ecf20Sopenharmony_ci { "DigitalNow DVB-T Dual USB", 19278c2ecf20Sopenharmony_ci { &cxusb_table[DIGITALNOW_BLUEBIRD_DUAL_1_COLD], NULL }, 19288c2ecf20Sopenharmony_ci { &cxusb_table[DIGITALNOW_BLUEBIRD_DUAL_1_WARM], NULL }, 19298c2ecf20Sopenharmony_ci }, 19308c2ecf20Sopenharmony_ci { "DViCO FusionHDTV DVB-T Dual Digital 2", 19318c2ecf20Sopenharmony_ci { &cxusb_table[DVICO_BLUEBIRD_DUAL_2_COLD], NULL }, 19328c2ecf20Sopenharmony_ci { &cxusb_table[DVICO_BLUEBIRD_DUAL_2_WARM], NULL }, 19338c2ecf20Sopenharmony_ci }, 19348c2ecf20Sopenharmony_ci } 19358c2ecf20Sopenharmony_ci}; 19368c2ecf20Sopenharmony_ci 19378c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = { 19388c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 19398c2ecf20Sopenharmony_ci 19408c2ecf20Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 19418c2ecf20Sopenharmony_ci .firmware = "dvb-usb-bluebird-01.fw", 19428c2ecf20Sopenharmony_ci .download_firmware = bluebird_patch_dvico_firmware_download, 19438c2ecf20Sopenharmony_ci /* 19448c2ecf20Sopenharmony_ci * use usb alt setting 0 for EP4 transfer (dvb-t), 19458c2ecf20Sopenharmony_ci * use usb alt setting 7 for EP2 transfer (atsc) 19468c2ecf20Sopenharmony_ci */ 19478c2ecf20Sopenharmony_ci 19488c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct cxusb_state), 19498c2ecf20Sopenharmony_ci 19508c2ecf20Sopenharmony_ci .num_adapters = 1, 19518c2ecf20Sopenharmony_ci .adapter = { 19528c2ecf20Sopenharmony_ci { 19538c2ecf20Sopenharmony_ci .num_frontends = 1, 19548c2ecf20Sopenharmony_ci .fe = {{ 19558c2ecf20Sopenharmony_ci .streaming_ctrl = cxusb_streaming_ctrl, 19568c2ecf20Sopenharmony_ci .frontend_attach = cxusb_mt352_frontend_attach, 19578c2ecf20Sopenharmony_ci .tuner_attach = cxusb_lgz201_tuner_attach, 19588c2ecf20Sopenharmony_ci 19598c2ecf20Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 19608c2ecf20Sopenharmony_ci .stream = { 19618c2ecf20Sopenharmony_ci .type = USB_BULK, 19628c2ecf20Sopenharmony_ci .count = 5, 19638c2ecf20Sopenharmony_ci .endpoint = 0x04, 19648c2ecf20Sopenharmony_ci .u = { 19658c2ecf20Sopenharmony_ci .bulk = { 19668c2ecf20Sopenharmony_ci .buffersize = 8192, 19678c2ecf20Sopenharmony_ci } 19688c2ecf20Sopenharmony_ci } 19698c2ecf20Sopenharmony_ci }, 19708c2ecf20Sopenharmony_ci } }, 19718c2ecf20Sopenharmony_ci }, 19728c2ecf20Sopenharmony_ci }, 19738c2ecf20Sopenharmony_ci .power_ctrl = cxusb_bluebird_power_ctrl, 19748c2ecf20Sopenharmony_ci 19758c2ecf20Sopenharmony_ci .i2c_algo = &cxusb_i2c_algo, 19768c2ecf20Sopenharmony_ci 19778c2ecf20Sopenharmony_ci .rc.core = { 19788c2ecf20Sopenharmony_ci .rc_interval = 100, 19798c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_DVICO_PORTABLE, 19808c2ecf20Sopenharmony_ci .module_name = KBUILD_MODNAME, 19818c2ecf20Sopenharmony_ci .rc_query = cxusb_rc_query, 19828c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 19838c2ecf20Sopenharmony_ci }, 19848c2ecf20Sopenharmony_ci 19858c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 19868c2ecf20Sopenharmony_ci .num_device_descs = 1, 19878c2ecf20Sopenharmony_ci .devices = { 19888c2ecf20Sopenharmony_ci { "DViCO FusionHDTV DVB-T USB (LGZ201)", 19898c2ecf20Sopenharmony_ci { &cxusb_table[DVICO_BLUEBIRD_LGZ201_COLD], NULL }, 19908c2ecf20Sopenharmony_ci { &cxusb_table[DVICO_BLUEBIRD_LGZ201_WARM], NULL }, 19918c2ecf20Sopenharmony_ci }, 19928c2ecf20Sopenharmony_ci } 19938c2ecf20Sopenharmony_ci}; 19948c2ecf20Sopenharmony_ci 19958c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = { 19968c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 19978c2ecf20Sopenharmony_ci 19988c2ecf20Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 19998c2ecf20Sopenharmony_ci .firmware = "dvb-usb-bluebird-01.fw", 20008c2ecf20Sopenharmony_ci .download_firmware = bluebird_patch_dvico_firmware_download, 20018c2ecf20Sopenharmony_ci 20028c2ecf20Sopenharmony_ci /* 20038c2ecf20Sopenharmony_ci * use usb alt setting 0 for EP4 transfer (dvb-t), 20048c2ecf20Sopenharmony_ci * use usb alt setting 7 for EP2 transfer (atsc) 20058c2ecf20Sopenharmony_ci */ 20068c2ecf20Sopenharmony_ci 20078c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct cxusb_state), 20088c2ecf20Sopenharmony_ci 20098c2ecf20Sopenharmony_ci .num_adapters = 1, 20108c2ecf20Sopenharmony_ci .adapter = { 20118c2ecf20Sopenharmony_ci { 20128c2ecf20Sopenharmony_ci .num_frontends = 1, 20138c2ecf20Sopenharmony_ci .fe = {{ 20148c2ecf20Sopenharmony_ci .streaming_ctrl = cxusb_streaming_ctrl, 20158c2ecf20Sopenharmony_ci .frontend_attach = cxusb_mt352_frontend_attach, 20168c2ecf20Sopenharmony_ci .tuner_attach = cxusb_dtt7579_tuner_attach, 20178c2ecf20Sopenharmony_ci 20188c2ecf20Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 20198c2ecf20Sopenharmony_ci .stream = { 20208c2ecf20Sopenharmony_ci .type = USB_BULK, 20218c2ecf20Sopenharmony_ci .count = 5, 20228c2ecf20Sopenharmony_ci .endpoint = 0x04, 20238c2ecf20Sopenharmony_ci .u = { 20248c2ecf20Sopenharmony_ci .bulk = { 20258c2ecf20Sopenharmony_ci .buffersize = 8192, 20268c2ecf20Sopenharmony_ci } 20278c2ecf20Sopenharmony_ci } 20288c2ecf20Sopenharmony_ci }, 20298c2ecf20Sopenharmony_ci } }, 20308c2ecf20Sopenharmony_ci }, 20318c2ecf20Sopenharmony_ci }, 20328c2ecf20Sopenharmony_ci .power_ctrl = cxusb_bluebird_power_ctrl, 20338c2ecf20Sopenharmony_ci 20348c2ecf20Sopenharmony_ci .i2c_algo = &cxusb_i2c_algo, 20358c2ecf20Sopenharmony_ci 20368c2ecf20Sopenharmony_ci .rc.core = { 20378c2ecf20Sopenharmony_ci .rc_interval = 100, 20388c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_DVICO_PORTABLE, 20398c2ecf20Sopenharmony_ci .module_name = KBUILD_MODNAME, 20408c2ecf20Sopenharmony_ci .rc_query = cxusb_rc_query, 20418c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 20428c2ecf20Sopenharmony_ci }, 20438c2ecf20Sopenharmony_ci 20448c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 20458c2ecf20Sopenharmony_ci 20468c2ecf20Sopenharmony_ci .num_device_descs = 1, 20478c2ecf20Sopenharmony_ci .devices = { 20488c2ecf20Sopenharmony_ci { "DViCO FusionHDTV DVB-T USB (TH7579)", 20498c2ecf20Sopenharmony_ci { &cxusb_table[DVICO_BLUEBIRD_TH7579_COLD], NULL }, 20508c2ecf20Sopenharmony_ci { &cxusb_table[DVICO_BLUEBIRD_TH7579_WARM], NULL }, 20518c2ecf20Sopenharmony_ci }, 20528c2ecf20Sopenharmony_ci } 20538c2ecf20Sopenharmony_ci}; 20548c2ecf20Sopenharmony_ci 20558c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = { 20568c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 20578c2ecf20Sopenharmony_ci 20588c2ecf20Sopenharmony_ci .usb_ctrl = CYPRESS_FX2, 20598c2ecf20Sopenharmony_ci 20608c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct cxusb_state), 20618c2ecf20Sopenharmony_ci 20628c2ecf20Sopenharmony_ci .num_adapters = 1, 20638c2ecf20Sopenharmony_ci .adapter = { 20648c2ecf20Sopenharmony_ci { 20658c2ecf20Sopenharmony_ci .num_frontends = 1, 20668c2ecf20Sopenharmony_ci .fe = {{ 20678c2ecf20Sopenharmony_ci .streaming_ctrl = cxusb_streaming_ctrl, 20688c2ecf20Sopenharmony_ci .frontend_attach = cxusb_dualdig4_frontend_attach, 20698c2ecf20Sopenharmony_ci .tuner_attach = cxusb_dvico_xc3028_tuner_attach, 20708c2ecf20Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 20718c2ecf20Sopenharmony_ci .stream = { 20728c2ecf20Sopenharmony_ci .type = USB_BULK, 20738c2ecf20Sopenharmony_ci .count = 5, 20748c2ecf20Sopenharmony_ci .endpoint = 0x02, 20758c2ecf20Sopenharmony_ci .u = { 20768c2ecf20Sopenharmony_ci .bulk = { 20778c2ecf20Sopenharmony_ci .buffersize = 8192, 20788c2ecf20Sopenharmony_ci } 20798c2ecf20Sopenharmony_ci } 20808c2ecf20Sopenharmony_ci }, 20818c2ecf20Sopenharmony_ci } }, 20828c2ecf20Sopenharmony_ci }, 20838c2ecf20Sopenharmony_ci }, 20848c2ecf20Sopenharmony_ci 20858c2ecf20Sopenharmony_ci .power_ctrl = cxusb_power_ctrl, 20868c2ecf20Sopenharmony_ci 20878c2ecf20Sopenharmony_ci .i2c_algo = &cxusb_i2c_algo, 20888c2ecf20Sopenharmony_ci 20898c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 20908c2ecf20Sopenharmony_ci 20918c2ecf20Sopenharmony_ci .rc.core = { 20928c2ecf20Sopenharmony_ci .rc_interval = 100, 20938c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_DVICO_MCE, 20948c2ecf20Sopenharmony_ci .module_name = KBUILD_MODNAME, 20958c2ecf20Sopenharmony_ci .rc_query = cxusb_bluebird2_rc_query, 20968c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 20978c2ecf20Sopenharmony_ci }, 20988c2ecf20Sopenharmony_ci 20998c2ecf20Sopenharmony_ci .num_device_descs = 1, 21008c2ecf20Sopenharmony_ci .devices = { 21018c2ecf20Sopenharmony_ci { "DViCO FusionHDTV DVB-T Dual Digital 4", 21028c2ecf20Sopenharmony_ci { NULL }, 21038c2ecf20Sopenharmony_ci { &cxusb_table[DVICO_BLUEBIRD_DUAL_4], NULL }, 21048c2ecf20Sopenharmony_ci }, 21058c2ecf20Sopenharmony_ci } 21068c2ecf20Sopenharmony_ci}; 21078c2ecf20Sopenharmony_ci 21088c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = { 21098c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 21108c2ecf20Sopenharmony_ci 21118c2ecf20Sopenharmony_ci .usb_ctrl = CYPRESS_FX2, 21128c2ecf20Sopenharmony_ci .identify_state = bluebird_fx2_identify_state, 21138c2ecf20Sopenharmony_ci 21148c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct cxusb_state), 21158c2ecf20Sopenharmony_ci 21168c2ecf20Sopenharmony_ci .num_adapters = 1, 21178c2ecf20Sopenharmony_ci .adapter = { 21188c2ecf20Sopenharmony_ci { 21198c2ecf20Sopenharmony_ci .num_frontends = 1, 21208c2ecf20Sopenharmony_ci .fe = {{ 21218c2ecf20Sopenharmony_ci .streaming_ctrl = cxusb_streaming_ctrl, 21228c2ecf20Sopenharmony_ci .frontend_attach = cxusb_nano2_frontend_attach, 21238c2ecf20Sopenharmony_ci .tuner_attach = cxusb_dvico_xc3028_tuner_attach, 21248c2ecf20Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 21258c2ecf20Sopenharmony_ci .stream = { 21268c2ecf20Sopenharmony_ci .type = USB_BULK, 21278c2ecf20Sopenharmony_ci .count = 5, 21288c2ecf20Sopenharmony_ci .endpoint = 0x02, 21298c2ecf20Sopenharmony_ci .u = { 21308c2ecf20Sopenharmony_ci .bulk = { 21318c2ecf20Sopenharmony_ci .buffersize = 8192, 21328c2ecf20Sopenharmony_ci } 21338c2ecf20Sopenharmony_ci } 21348c2ecf20Sopenharmony_ci }, 21358c2ecf20Sopenharmony_ci } }, 21368c2ecf20Sopenharmony_ci }, 21378c2ecf20Sopenharmony_ci }, 21388c2ecf20Sopenharmony_ci 21398c2ecf20Sopenharmony_ci .power_ctrl = cxusb_nano2_power_ctrl, 21408c2ecf20Sopenharmony_ci 21418c2ecf20Sopenharmony_ci .i2c_algo = &cxusb_i2c_algo, 21428c2ecf20Sopenharmony_ci 21438c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 21448c2ecf20Sopenharmony_ci 21458c2ecf20Sopenharmony_ci .rc.core = { 21468c2ecf20Sopenharmony_ci .rc_interval = 100, 21478c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_DVICO_PORTABLE, 21488c2ecf20Sopenharmony_ci .module_name = KBUILD_MODNAME, 21498c2ecf20Sopenharmony_ci .rc_query = cxusb_bluebird2_rc_query, 21508c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 21518c2ecf20Sopenharmony_ci }, 21528c2ecf20Sopenharmony_ci 21538c2ecf20Sopenharmony_ci .num_device_descs = 1, 21548c2ecf20Sopenharmony_ci .devices = { 21558c2ecf20Sopenharmony_ci { "DViCO FusionHDTV DVB-T NANO2", 21568c2ecf20Sopenharmony_ci { NULL }, 21578c2ecf20Sopenharmony_ci { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2], NULL }, 21588c2ecf20Sopenharmony_ci }, 21598c2ecf20Sopenharmony_ci } 21608c2ecf20Sopenharmony_ci}; 21618c2ecf20Sopenharmony_ci 21628c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties 21638c2ecf20Sopenharmony_cicxusb_bluebird_nano2_needsfirmware_properties = { 21648c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 21658c2ecf20Sopenharmony_ci 21668c2ecf20Sopenharmony_ci .usb_ctrl = DEVICE_SPECIFIC, 21678c2ecf20Sopenharmony_ci .firmware = "dvb-usb-bluebird-02.fw", 21688c2ecf20Sopenharmony_ci .download_firmware = bluebird_patch_dvico_firmware_download, 21698c2ecf20Sopenharmony_ci .identify_state = bluebird_fx2_identify_state, 21708c2ecf20Sopenharmony_ci 21718c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct cxusb_state), 21728c2ecf20Sopenharmony_ci 21738c2ecf20Sopenharmony_ci .num_adapters = 1, 21748c2ecf20Sopenharmony_ci .adapter = { 21758c2ecf20Sopenharmony_ci { 21768c2ecf20Sopenharmony_ci .num_frontends = 1, 21778c2ecf20Sopenharmony_ci .fe = {{ 21788c2ecf20Sopenharmony_ci .streaming_ctrl = cxusb_streaming_ctrl, 21798c2ecf20Sopenharmony_ci .frontend_attach = cxusb_nano2_frontend_attach, 21808c2ecf20Sopenharmony_ci .tuner_attach = cxusb_dvico_xc3028_tuner_attach, 21818c2ecf20Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 21828c2ecf20Sopenharmony_ci .stream = { 21838c2ecf20Sopenharmony_ci .type = USB_BULK, 21848c2ecf20Sopenharmony_ci .count = 5, 21858c2ecf20Sopenharmony_ci .endpoint = 0x02, 21868c2ecf20Sopenharmony_ci .u = { 21878c2ecf20Sopenharmony_ci .bulk = { 21888c2ecf20Sopenharmony_ci .buffersize = 8192, 21898c2ecf20Sopenharmony_ci } 21908c2ecf20Sopenharmony_ci } 21918c2ecf20Sopenharmony_ci }, 21928c2ecf20Sopenharmony_ci } }, 21938c2ecf20Sopenharmony_ci }, 21948c2ecf20Sopenharmony_ci }, 21958c2ecf20Sopenharmony_ci 21968c2ecf20Sopenharmony_ci .power_ctrl = cxusb_nano2_power_ctrl, 21978c2ecf20Sopenharmony_ci 21988c2ecf20Sopenharmony_ci .i2c_algo = &cxusb_i2c_algo, 21998c2ecf20Sopenharmony_ci 22008c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 22018c2ecf20Sopenharmony_ci 22028c2ecf20Sopenharmony_ci .rc.core = { 22038c2ecf20Sopenharmony_ci .rc_interval = 100, 22048c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_DVICO_PORTABLE, 22058c2ecf20Sopenharmony_ci .module_name = KBUILD_MODNAME, 22068c2ecf20Sopenharmony_ci .rc_query = cxusb_rc_query, 22078c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 22088c2ecf20Sopenharmony_ci }, 22098c2ecf20Sopenharmony_ci 22108c2ecf20Sopenharmony_ci .num_device_descs = 1, 22118c2ecf20Sopenharmony_ci .devices = { { 22128c2ecf20Sopenharmony_ci "DViCO FusionHDTV DVB-T NANO2 w/o firmware", 22138c2ecf20Sopenharmony_ci { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2], NULL }, 22148c2ecf20Sopenharmony_ci { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM], 22158c2ecf20Sopenharmony_ci NULL }, 22168c2ecf20Sopenharmony_ci }, 22178c2ecf20Sopenharmony_ci } 22188c2ecf20Sopenharmony_ci}; 22198c2ecf20Sopenharmony_ci 22208c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_aver_a868r_properties = { 22218c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 22228c2ecf20Sopenharmony_ci 22238c2ecf20Sopenharmony_ci .usb_ctrl = CYPRESS_FX2, 22248c2ecf20Sopenharmony_ci 22258c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct cxusb_state), 22268c2ecf20Sopenharmony_ci 22278c2ecf20Sopenharmony_ci .num_adapters = 1, 22288c2ecf20Sopenharmony_ci .adapter = { 22298c2ecf20Sopenharmony_ci { 22308c2ecf20Sopenharmony_ci .num_frontends = 1, 22318c2ecf20Sopenharmony_ci .fe = {{ 22328c2ecf20Sopenharmony_ci .streaming_ctrl = cxusb_aver_streaming_ctrl, 22338c2ecf20Sopenharmony_ci .frontend_attach = cxusb_aver_lgdt3303_frontend_attach, 22348c2ecf20Sopenharmony_ci .tuner_attach = cxusb_mxl5003s_tuner_attach, 22358c2ecf20Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 22368c2ecf20Sopenharmony_ci .stream = { 22378c2ecf20Sopenharmony_ci .type = USB_BULK, 22388c2ecf20Sopenharmony_ci .count = 5, 22398c2ecf20Sopenharmony_ci .endpoint = 0x04, 22408c2ecf20Sopenharmony_ci .u = { 22418c2ecf20Sopenharmony_ci .bulk = { 22428c2ecf20Sopenharmony_ci .buffersize = 8192, 22438c2ecf20Sopenharmony_ci } 22448c2ecf20Sopenharmony_ci } 22458c2ecf20Sopenharmony_ci }, 22468c2ecf20Sopenharmony_ci } }, 22478c2ecf20Sopenharmony_ci }, 22488c2ecf20Sopenharmony_ci }, 22498c2ecf20Sopenharmony_ci .power_ctrl = cxusb_aver_power_ctrl, 22508c2ecf20Sopenharmony_ci 22518c2ecf20Sopenharmony_ci .i2c_algo = &cxusb_i2c_algo, 22528c2ecf20Sopenharmony_ci 22538c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 22548c2ecf20Sopenharmony_ci 22558c2ecf20Sopenharmony_ci .num_device_descs = 1, 22568c2ecf20Sopenharmony_ci .devices = { 22578c2ecf20Sopenharmony_ci { "AVerMedia AVerTVHD Volar (A868R)", 22588c2ecf20Sopenharmony_ci { NULL }, 22598c2ecf20Sopenharmony_ci { &cxusb_table[AVERMEDIA_VOLAR_A868R], NULL }, 22608c2ecf20Sopenharmony_ci }, 22618c2ecf20Sopenharmony_ci } 22628c2ecf20Sopenharmony_ci}; 22638c2ecf20Sopenharmony_ci 22648c2ecf20Sopenharmony_cistatic 22658c2ecf20Sopenharmony_cistruct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = { 22668c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 22678c2ecf20Sopenharmony_ci 22688c2ecf20Sopenharmony_ci .usb_ctrl = CYPRESS_FX2, 22698c2ecf20Sopenharmony_ci 22708c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct cxusb_state), 22718c2ecf20Sopenharmony_ci 22728c2ecf20Sopenharmony_ci .num_adapters = 1, 22738c2ecf20Sopenharmony_ci .adapter = { 22748c2ecf20Sopenharmony_ci { 22758c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct dib0700_adapter_state), 22768c2ecf20Sopenharmony_ci .num_frontends = 1, 22778c2ecf20Sopenharmony_ci .fe = {{ 22788c2ecf20Sopenharmony_ci .streaming_ctrl = cxusb_streaming_ctrl, 22798c2ecf20Sopenharmony_ci .frontend_attach = cxusb_dualdig4_rev2_frontend_attach, 22808c2ecf20Sopenharmony_ci .tuner_attach = cxusb_dualdig4_rev2_tuner_attach, 22818c2ecf20Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 22828c2ecf20Sopenharmony_ci .stream = { 22838c2ecf20Sopenharmony_ci .type = USB_BULK, 22848c2ecf20Sopenharmony_ci .count = 7, 22858c2ecf20Sopenharmony_ci .endpoint = 0x02, 22868c2ecf20Sopenharmony_ci .u = { 22878c2ecf20Sopenharmony_ci .bulk = { 22888c2ecf20Sopenharmony_ci .buffersize = 4096, 22898c2ecf20Sopenharmony_ci } 22908c2ecf20Sopenharmony_ci } 22918c2ecf20Sopenharmony_ci }, 22928c2ecf20Sopenharmony_ci } }, 22938c2ecf20Sopenharmony_ci }, 22948c2ecf20Sopenharmony_ci }, 22958c2ecf20Sopenharmony_ci 22968c2ecf20Sopenharmony_ci .power_ctrl = cxusb_bluebird_power_ctrl, 22978c2ecf20Sopenharmony_ci 22988c2ecf20Sopenharmony_ci .i2c_algo = &cxusb_i2c_algo, 22998c2ecf20Sopenharmony_ci 23008c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 23018c2ecf20Sopenharmony_ci 23028c2ecf20Sopenharmony_ci .rc.core = { 23038c2ecf20Sopenharmony_ci .rc_interval = 100, 23048c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_DVICO_MCE, 23058c2ecf20Sopenharmony_ci .module_name = KBUILD_MODNAME, 23068c2ecf20Sopenharmony_ci .rc_query = cxusb_rc_query, 23078c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_NEC, 23088c2ecf20Sopenharmony_ci }, 23098c2ecf20Sopenharmony_ci 23108c2ecf20Sopenharmony_ci .num_device_descs = 1, 23118c2ecf20Sopenharmony_ci .devices = { 23128c2ecf20Sopenharmony_ci { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)", 23138c2ecf20Sopenharmony_ci { NULL }, 23148c2ecf20Sopenharmony_ci { &cxusb_table[DVICO_BLUEBIRD_DUAL_4_REV_2], NULL }, 23158c2ecf20Sopenharmony_ci }, 23168c2ecf20Sopenharmony_ci } 23178c2ecf20Sopenharmony_ci}; 23188c2ecf20Sopenharmony_ci 23198c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_d680_dmb_properties = { 23208c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 23218c2ecf20Sopenharmony_ci 23228c2ecf20Sopenharmony_ci .usb_ctrl = CYPRESS_FX2, 23238c2ecf20Sopenharmony_ci 23248c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct cxusb_state), 23258c2ecf20Sopenharmony_ci 23268c2ecf20Sopenharmony_ci .num_adapters = 1, 23278c2ecf20Sopenharmony_ci .adapter = { 23288c2ecf20Sopenharmony_ci { 23298c2ecf20Sopenharmony_ci .num_frontends = 1, 23308c2ecf20Sopenharmony_ci .fe = {{ 23318c2ecf20Sopenharmony_ci .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl, 23328c2ecf20Sopenharmony_ci .frontend_attach = cxusb_d680_dmb_frontend_attach, 23338c2ecf20Sopenharmony_ci .tuner_attach = cxusb_d680_dmb_tuner_attach, 23348c2ecf20Sopenharmony_ci 23358c2ecf20Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 23368c2ecf20Sopenharmony_ci .stream = { 23378c2ecf20Sopenharmony_ci .type = USB_BULK, 23388c2ecf20Sopenharmony_ci .count = 5, 23398c2ecf20Sopenharmony_ci .endpoint = 0x02, 23408c2ecf20Sopenharmony_ci .u = { 23418c2ecf20Sopenharmony_ci .bulk = { 23428c2ecf20Sopenharmony_ci .buffersize = 8192, 23438c2ecf20Sopenharmony_ci } 23448c2ecf20Sopenharmony_ci } 23458c2ecf20Sopenharmony_ci }, 23468c2ecf20Sopenharmony_ci } }, 23478c2ecf20Sopenharmony_ci }, 23488c2ecf20Sopenharmony_ci }, 23498c2ecf20Sopenharmony_ci 23508c2ecf20Sopenharmony_ci .power_ctrl = cxusb_d680_dmb_power_ctrl, 23518c2ecf20Sopenharmony_ci 23528c2ecf20Sopenharmony_ci .i2c_algo = &cxusb_i2c_algo, 23538c2ecf20Sopenharmony_ci 23548c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 23558c2ecf20Sopenharmony_ci 23568c2ecf20Sopenharmony_ci .rc.core = { 23578c2ecf20Sopenharmony_ci .rc_interval = 100, 23588c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_TOTAL_MEDIA_IN_HAND_02, 23598c2ecf20Sopenharmony_ci .module_name = KBUILD_MODNAME, 23608c2ecf20Sopenharmony_ci .rc_query = cxusb_d680_dmb_rc_query, 23618c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_UNKNOWN, 23628c2ecf20Sopenharmony_ci }, 23638c2ecf20Sopenharmony_ci 23648c2ecf20Sopenharmony_ci .num_device_descs = 1, 23658c2ecf20Sopenharmony_ci .devices = { 23668c2ecf20Sopenharmony_ci { 23678c2ecf20Sopenharmony_ci "Conexant DMB-TH Stick", 23688c2ecf20Sopenharmony_ci { NULL }, 23698c2ecf20Sopenharmony_ci { &cxusb_table[CONEXANT_D680_DMB], NULL }, 23708c2ecf20Sopenharmony_ci }, 23718c2ecf20Sopenharmony_ci } 23728c2ecf20Sopenharmony_ci}; 23738c2ecf20Sopenharmony_ci 23748c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties cxusb_mygica_d689_properties = { 23758c2ecf20Sopenharmony_ci .caps = DVB_USB_IS_AN_I2C_ADAPTER, 23768c2ecf20Sopenharmony_ci 23778c2ecf20Sopenharmony_ci .usb_ctrl = CYPRESS_FX2, 23788c2ecf20Sopenharmony_ci 23798c2ecf20Sopenharmony_ci .size_of_priv = sizeof(struct cxusb_state), 23808c2ecf20Sopenharmony_ci 23818c2ecf20Sopenharmony_ci .num_adapters = 1, 23828c2ecf20Sopenharmony_ci .adapter = { 23838c2ecf20Sopenharmony_ci { 23848c2ecf20Sopenharmony_ci .num_frontends = 1, 23858c2ecf20Sopenharmony_ci .fe = {{ 23868c2ecf20Sopenharmony_ci .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl, 23878c2ecf20Sopenharmony_ci .frontend_attach = cxusb_mygica_d689_frontend_attach, 23888c2ecf20Sopenharmony_ci .tuner_attach = cxusb_mygica_d689_tuner_attach, 23898c2ecf20Sopenharmony_ci 23908c2ecf20Sopenharmony_ci /* parameter for the MPEG2-data transfer */ 23918c2ecf20Sopenharmony_ci .stream = { 23928c2ecf20Sopenharmony_ci .type = USB_BULK, 23938c2ecf20Sopenharmony_ci .count = 5, 23948c2ecf20Sopenharmony_ci .endpoint = 0x02, 23958c2ecf20Sopenharmony_ci .u = { 23968c2ecf20Sopenharmony_ci .bulk = { 23978c2ecf20Sopenharmony_ci .buffersize = 8192, 23988c2ecf20Sopenharmony_ci } 23998c2ecf20Sopenharmony_ci } 24008c2ecf20Sopenharmony_ci }, 24018c2ecf20Sopenharmony_ci } }, 24028c2ecf20Sopenharmony_ci }, 24038c2ecf20Sopenharmony_ci }, 24048c2ecf20Sopenharmony_ci 24058c2ecf20Sopenharmony_ci .power_ctrl = cxusb_d680_dmb_power_ctrl, 24068c2ecf20Sopenharmony_ci 24078c2ecf20Sopenharmony_ci .i2c_algo = &cxusb_i2c_algo, 24088c2ecf20Sopenharmony_ci 24098c2ecf20Sopenharmony_ci .generic_bulk_ctrl_endpoint = 0x01, 24108c2ecf20Sopenharmony_ci 24118c2ecf20Sopenharmony_ci .rc.core = { 24128c2ecf20Sopenharmony_ci .rc_interval = 100, 24138c2ecf20Sopenharmony_ci .rc_codes = RC_MAP_D680_DMB, 24148c2ecf20Sopenharmony_ci .module_name = KBUILD_MODNAME, 24158c2ecf20Sopenharmony_ci .rc_query = cxusb_d680_dmb_rc_query, 24168c2ecf20Sopenharmony_ci .allowed_protos = RC_PROTO_BIT_UNKNOWN, 24178c2ecf20Sopenharmony_ci }, 24188c2ecf20Sopenharmony_ci 24198c2ecf20Sopenharmony_ci .num_device_descs = 1, 24208c2ecf20Sopenharmony_ci .devices = { 24218c2ecf20Sopenharmony_ci { 24228c2ecf20Sopenharmony_ci "Mygica D689 DMB-TH", 24238c2ecf20Sopenharmony_ci { NULL }, 24248c2ecf20Sopenharmony_ci { &cxusb_table[MYGICA_D689], NULL }, 24258c2ecf20Sopenharmony_ci }, 24268c2ecf20Sopenharmony_ci } 24278c2ecf20Sopenharmony_ci}; 24288c2ecf20Sopenharmony_ci 24298c2ecf20Sopenharmony_cistatic struct usb_driver cxusb_driver = { 24308c2ecf20Sopenharmony_ci .name = "dvb_usb_cxusb", 24318c2ecf20Sopenharmony_ci .probe = cxusb_probe, 24328c2ecf20Sopenharmony_ci .disconnect = cxusb_disconnect, 24338c2ecf20Sopenharmony_ci .id_table = cxusb_table, 24348c2ecf20Sopenharmony_ci}; 24358c2ecf20Sopenharmony_ci 24368c2ecf20Sopenharmony_cimodule_usb_driver(cxusb_driver); 24378c2ecf20Sopenharmony_ci 24388c2ecf20Sopenharmony_ciMODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>"); 24398c2ecf20Sopenharmony_ciMODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); 24408c2ecf20Sopenharmony_ciMODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 24418c2ecf20Sopenharmony_ciMODULE_AUTHOR("Maciej S. Szmigiero <mail@maciej.szmigiero.name>"); 24428c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design"); 24438c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 2444