1bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones 2bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * (e.g. Pinnacle 400e DVB-S USB2.0). 3bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * 4bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * The Pinnacle 400e uses the same protocol as the Technotrend USB1.1 boxes. 5bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * 6bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * TDA8263 + TDA10086 7bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * 8bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * I2C addresses: 9bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * 0x08 - LNBP21PD - LNB power supply 10bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * 0x0e - TDA10086 - Demodulator 11bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * 0x50 - FX2 eeprom 12bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * 0x60 - TDA8263 - Tuner 13bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * 0x78 ??? 14bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * 15bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * Copyright (c) 2002 Holger Waechtler <holger@convergence.de> 16bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net> 17bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.org> 18bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * 19bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * This program is free software; you can redistribute it and/or modify it 20bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * under the terms of the GNU General Public License as published by the Free 21bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * Software Foundation, version 2. 22bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * 23bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher * see Documentation/dvb/README.dvb-usb for more information 24bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher */ 25bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher#define DVB_USB_LOG_PREFIX "ttusb2" 26bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher#include "dvb-usb.h" 27bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 28bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher#include "ttusb2.h" 29bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 30bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher#include "tda826x.h" 31bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher#include "tda10086.h" 3276952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin#include "tda1002x.h" 33c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero#include "tda10048.h" 3476952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin#include "tda827x.h" 35bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher#include "lnbp21.h" 368c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero/* CA */ 378c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero#include "dvb_ca_en50221.h" 38bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 39bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher/* debug */ 40bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcherstatic int dvb_usb_ttusb2_debug; 41bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher#define deb_info(args...) dprintk(dvb_usb_ttusb2_debug,0x01,args) 42bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettchermodule_param_named(debug,dvb_usb_ttusb2_debug, int, 0644); 43bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick BoettcherMODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))." DVB_USB_DEBUG_STATUS); 448c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguerostatic int dvb_usb_ttusb2_debug_ci; 458c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Regueromodule_param_named(debug_ci,dvb_usb_ttusb2_debug_ci, int, 0644); 468c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto RegueroMODULE_PARM_DESC(debug_ci, "set debugging ci." DVB_USB_DEBUG_STATUS); 47bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 4878e92006f410a4044f8c1760c25ac9d11d259aa2Janne GrunauDVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 4978e92006f410a4044f8c1760c25ac9d11d259aa2Janne Grunau 508c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero#define ci_dbg(format, arg...) \ 518c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguerodo { \ 528c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (dvb_usb_ttusb2_debug_ci) \ 538c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero printk(KERN_DEBUG DVB_USB_LOG_PREFIX \ 548c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ": %s " format "\n" , __func__, ## arg); \ 558c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero} while (0) 568c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 578c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Regueroenum { 588c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero TT3650_CMD_CI_TEST = 0x40, 598c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero TT3650_CMD_CI_RD_CTRL, 608c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero TT3650_CMD_CI_WR_CTRL, 618c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero TT3650_CMD_CI_RD_ATTR, 628c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero TT3650_CMD_CI_WR_ATTR, 638c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero TT3650_CMD_CI_RESET, 648c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero TT3650_CMD_CI_SET_VIDEO_PORT 658c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero}; 668c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 67bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcherstruct ttusb2_state { 688c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero struct dvb_ca_en50221 ca; 698c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero struct mutex ca_mutex; 70bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher u8 id; 719d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson u16 last_rc_key; 72bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher}; 73bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 74bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcherstatic int ttusb2_msg(struct dvb_usb_device *d, u8 cmd, 75bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher u8 *wbuf, int wlen, u8 *rbuf, int rlen) 76bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher{ 77bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher struct ttusb2_state *st = d->priv; 78ff17999184ed13829bc14c3be412d980173dff40Josh Boyer u8 *s, *r = NULL; 79bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher int ret = 0; 80bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 81ff17999184ed13829bc14c3be412d980173dff40Josh Boyer s = kzalloc(wlen+4, GFP_KERNEL); 82ff17999184ed13829bc14c3be412d980173dff40Josh Boyer if (!s) 83ff17999184ed13829bc14c3be412d980173dff40Josh Boyer return -ENOMEM; 84ff17999184ed13829bc14c3be412d980173dff40Josh Boyer 85ff17999184ed13829bc14c3be412d980173dff40Josh Boyer r = kzalloc(64, GFP_KERNEL); 86ff17999184ed13829bc14c3be412d980173dff40Josh Boyer if (!r) { 87ff17999184ed13829bc14c3be412d980173dff40Josh Boyer kfree(s); 88ff17999184ed13829bc14c3be412d980173dff40Josh Boyer return -ENOMEM; 89ff17999184ed13829bc14c3be412d980173dff40Josh Boyer } 90bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 91bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher s[0] = 0xaa; 92bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher s[1] = ++st->id; 93bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher s[2] = cmd; 94bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher s[3] = wlen; 95bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher memcpy(&s[4],wbuf,wlen); 96bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 97bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher ret = dvb_usb_generic_rw(d, s, wlen+4, r, 64, 0); 98bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 99bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher if (ret != 0 || 100bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher r[0] != 0x55 || 101bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher r[1] != s[1] || 102bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher r[2] != cmd || 103bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher (rlen > 0 && r[3] != rlen)) { 104bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]); 105ff17999184ed13829bc14c3be412d980173dff40Josh Boyer kfree(s); 106ff17999184ed13829bc14c3be412d980173dff40Josh Boyer kfree(r); 107bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher return -EIO; 108bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher } 109bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 110bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher if (rlen > 0) 111bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher memcpy(rbuf, &r[4], rlen); 112bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 113ff17999184ed13829bc14c3be412d980173dff40Josh Boyer kfree(s); 114ff17999184ed13829bc14c3be412d980173dff40Josh Boyer kfree(r); 115ff17999184ed13829bc14c3be412d980173dff40Josh Boyer 116bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher return 0; 117bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher} 118bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 1198c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero/* ci */ 1208c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguerostatic int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len) 1218c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero{ 1228c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero int ret; 1238c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero u8 rx[60];/* (64 -4) */ 1248c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ret = ttusb2_msg(d, cmd, data, write_len, rx, read_len); 1258c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (!ret) 1268c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero memcpy(data, rx, read_len); 1278c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return ret; 1288c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero} 1298c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1308c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguerostatic int tt3650_ci_msg_locked(struct dvb_ca_en50221 *ca, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len) 1318c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero{ 1328c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero struct dvb_usb_device *d = ca->data; 1338c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero struct ttusb2_state *state = d->priv; 1348c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero int ret; 1358c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1368c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero mutex_lock(&state->ca_mutex); 1378c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ret = tt3650_ci_msg(d, cmd, data, write_len, read_len); 1388c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero mutex_unlock(&state->ca_mutex); 1398c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1408c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return ret; 1418c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero} 1428c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1438c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguerostatic int tt3650_ci_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) 1448c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero{ 1458c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero u8 buf[3]; 1468c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero int ret = 0; 1478c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1488c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (slot) 1498c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return -EINVAL; 1508c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1518c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero buf[0] = (address >> 8) & 0x0F; 1528c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero buf[1] = address; 1538c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1548c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1558c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_ATTR, buf, 2, 3); 1568c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1578c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ci_dbg("%04x -> %d 0x%02x", address, ret, buf[2]); 1588c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1598c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (ret < 0) 1608c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return ret; 1618c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1628c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return buf[2]; 1638c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero} 1648c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1658c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguerostatic int tt3650_ci_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value) 1668c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero{ 1678c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero u8 buf[3]; 1688c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1698c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ci_dbg("%d 0x%04x 0x%02x", slot, address, value); 1708c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1718c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (slot) 1728c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return -EINVAL; 1738c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1748c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero buf[0] = (address >> 8) & 0x0F; 1758c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero buf[1] = address; 1768c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero buf[2] = value; 1778c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1788c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_ATTR, buf, 3, 3); 1798c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero} 1808c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1818c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguerostatic int tt3650_ci_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address) 1828c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero{ 1838c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero u8 buf[2]; 1848c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero int ret; 1858c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1868c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (slot) 1878c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return -EINVAL; 1888c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1898c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero buf[0] = address & 3; 1908c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1918c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_CTRL, buf, 1, 2); 1928c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1938c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ci_dbg("0x%02x -> %d 0x%02x", address, ret, buf[1]); 1948c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1958c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (ret < 0) 1968c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return ret; 1978c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 1988c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return buf[1]; 1998c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero} 2008c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2018c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguerostatic int tt3650_ci_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value) 2028c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero{ 2038c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero u8 buf[2]; 2048c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2058c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ci_dbg("%d 0x%02x 0x%02x", slot, address, value); 2068c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2078c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (slot) 2088c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return -EINVAL; 2098c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2108c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero buf[0] = address; 2118c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero buf[1] = value; 2128c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2138c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_CTRL, buf, 2, 2); 2148c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero} 2158c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2168c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguerostatic int tt3650_ci_set_video_port(struct dvb_ca_en50221 *ca, int slot, int enable) 2178c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero{ 2188c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero u8 buf[1]; 2198c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero int ret; 2208c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2218c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ci_dbg("%d %d", slot, enable); 2228c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2238c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (slot) 2248c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return -EINVAL; 2258c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2268c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero buf[0] = enable; 2278c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2288c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1); 2298c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (ret < 0) 2308c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return ret; 2318c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2328c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (enable != buf[0]) { 2338c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero err("CI not %sabled.", enable ? "en" : "dis"); 2348c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return -EIO; 2358c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero } 2368c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2378c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return 0; 2388c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero} 2398c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2408c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguerostatic int tt3650_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) 2418c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero{ 2428c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return tt3650_ci_set_video_port(ca, slot, 0); 2438c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero} 2448c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2458c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguerostatic int tt3650_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) 2468c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero{ 2478c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return tt3650_ci_set_video_port(ca, slot, 1); 2488c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero} 2498c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2508c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguerostatic int tt3650_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot) 2518c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero{ 2528c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero struct dvb_usb_device *d = ca->data; 2538c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero struct ttusb2_state *state = d->priv; 2548c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero u8 buf[1]; 2558c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero int ret; 2568c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2578c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ci_dbg("%d", slot); 2588c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2598c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (slot) 2608c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return -EINVAL; 2618c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2628c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero buf[0] = 0; 2638c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2648c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero mutex_lock(&state->ca_mutex); 2658c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2668c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1); 2678c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (ret) 2688c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero goto failed; 2698c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2708c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero msleep(500); 2718c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2728c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero buf[0] = 1; 2738c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2748c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1); 2758c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (ret) 2768c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero goto failed; 2778c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2788c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero msleep(500); 2798c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2808c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero buf[0] = 0; /* FTA */ 2818c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2828c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ret = tt3650_ci_msg(d, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1); 2838c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2848c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero msleep(1100); 2858c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2868c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero failed: 2878c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero mutex_unlock(&state->ca_mutex); 2888c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2898c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return ret; 2908c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero} 2918c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2928c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguerostatic int tt3650_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) 2938c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero{ 2948c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero u8 buf[1]; 2958c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero int ret; 2968c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 2978c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (slot) 2988c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return -EINVAL; 2998c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 3008c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_TEST, buf, 0, 1); 3018c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (ret) 3028c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return ret; 3038c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 3048c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (1 == buf[0]) { 3058c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return DVB_CA_EN50221_POLL_CAM_PRESENT | 3068c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero DVB_CA_EN50221_POLL_CAM_READY; 3078c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero } 3088c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return 0; 3098c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero} 3108c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 3118c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguerostatic void tt3650_ci_uninit(struct dvb_usb_device *d) 3128c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero{ 3138c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero struct ttusb2_state *state; 3148c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 3158c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ci_dbg(""); 3168c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 3178c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (NULL == d) 3188c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return; 3198c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 3208c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero state = d->priv; 3218c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (NULL == state) 3228c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return; 3238c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 3248c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (NULL == state->ca.data) 3258c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return; 3268c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 3278c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero dvb_ca_en50221_release(&state->ca); 3288c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 3298c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero memset(&state->ca, 0, sizeof(state->ca)); 3308c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero} 3318c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 3328c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguerostatic int tt3650_ci_init(struct dvb_usb_adapter *a) 3338c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero{ 3348c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero struct dvb_usb_device *d = a->dev; 3358c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero struct ttusb2_state *state = d->priv; 3368c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero int ret; 3378c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 3388c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ci_dbg(""); 3398c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 3408c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero mutex_init(&state->ca_mutex); 3418c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 3428c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero state->ca.owner = THIS_MODULE; 3438c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero state->ca.read_attribute_mem = tt3650_ci_read_attribute_mem; 3448c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero state->ca.write_attribute_mem = tt3650_ci_write_attribute_mem; 3458c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero state->ca.read_cam_control = tt3650_ci_read_cam_control; 3468c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero state->ca.write_cam_control = tt3650_ci_write_cam_control; 3478c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero state->ca.slot_reset = tt3650_ci_slot_reset; 3488c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero state->ca.slot_shutdown = tt3650_ci_slot_shutdown; 3498c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero state->ca.slot_ts_enable = tt3650_ci_slot_ts_enable; 3508c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero state->ca.poll_slot_status = tt3650_ci_poll_slot_status; 3518c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero state->ca.data = d; 3528c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 3538c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero ret = dvb_ca_en50221_init(&a->dvb_adap, 3548c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero &state->ca, 3558c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero /* flags */ 0, 3568c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero /* n_slots */ 1); 3578c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero if (ret) { 3588c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero err("Cannot initialize CI: Error %d.", ret); 3598c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero memset(&state->ca, 0, sizeof(state->ca)); 3608c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return ret; 3618c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero } 3628c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 3638c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero info("CI initialized."); 3648c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 3658c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero return 0; 3668c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero} 3678c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 368bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcherstatic int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) 369bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher{ 370bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher struct dvb_usb_device *d = i2c_get_adapdata(adap); 371bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher static u8 obuf[60], ibuf[60]; 372c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero int i, write_read, read; 373bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 374bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 375bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher return -EAGAIN; 376bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 377bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher if (num > 2) 378bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher warn("more than 2 i2c messages at a time is not handled yet. TODO."); 379bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 380bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher for (i = 0; i < num; i++) { 381c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero write_read = i+1 < num && (msg[i+1].flags & I2C_M_RD); 382c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero read = msg[i].flags & I2C_M_RD; 383bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 384c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero obuf[0] = (msg[i].addr << 1) | (write_read | read); 385c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero if (read) 386c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero obuf[1] = 0; 387c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero else 388c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero obuf[1] = msg[i].len; 389bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 390bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher /* read request */ 391c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero if (write_read) 392bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher obuf[2] = msg[i+1].len; 393c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero else if (read) 394c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero obuf[2] = msg[i].len; 395bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher else 396bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher obuf[2] = 0; 397bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 398c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero memcpy(&obuf[3], msg[i].buf, msg[i].len); 399bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 400a23d9d1227f05cf96d195401fe2af2c14ea44b92Jose Alberto Reguero if (ttusb2_msg(d, CMD_I2C_XFER, obuf, obuf[1]+3, ibuf, obuf[2] + 3) < 0) { 401bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher err("i2c transfer failed."); 402bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher break; 403bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher } 404bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 405c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero if (write_read) { 406c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero memcpy(msg[i+1].buf, &ibuf[3], msg[i+1].len); 407bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher i++; 408c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero } else if (read) 409c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero memcpy(msg[i].buf, &ibuf[3], msg[i].len); 410bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher } 411bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 412bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher mutex_unlock(&d->i2c_mutex); 413bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher return i; 414bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher} 415bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 416bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcherstatic u32 ttusb2_i2c_func(struct i2c_adapter *adapter) 417bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher{ 418bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher return I2C_FUNC_I2C; 419bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher} 420bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 421bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcherstatic struct i2c_algorithm ttusb2_i2c_algo = { 422bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .master_xfer = ttusb2_i2c_xfer, 423bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .functionality = ttusb2_i2c_func, 424bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher}; 425bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 4269d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson/* command to poll IR receiver (copied from pctv452e.c) */ 4279d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson#define CMD_GET_IR_CODE 0x1b 4289d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson 4299d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson/* IR */ 4309d1da730ee17e712c25c0b1e51653048f92d2385David Henningssonstatic int tt3650_rc_query(struct dvb_usb_device *d) 4319d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson{ 4329d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson int ret; 4339d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson u8 rx[9]; /* A CMD_GET_IR_CODE reply is 9 bytes long */ 4349d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson struct ttusb2_state *st = d->priv; 4359d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson ret = ttusb2_msg(d, CMD_GET_IR_CODE, NULL, 0, rx, sizeof(rx)); 4369d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson if (ret != 0) 4379d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson return ret; 4389d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson 4399d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson if (rx[8] & 0x01) { 4409d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson /* got a "press" event */ 4419d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson st->last_rc_key = (rx[3] << 8) | rx[2]; 4429d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson deb_info("%s: cmd=0x%02x sys=0x%02x\n", __func__, rx[2], rx[3]); 4439d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson rc_keydown(d->rc_dev, st->last_rc_key, 0); 4449d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson } else if (st->last_rc_key) { 4459d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson rc_keyup(d->rc_dev); 4469d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson st->last_rc_key = 0; 4479d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson } 4489d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson 4499d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson return 0; 4509d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson} 4519d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson 4529d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson 453bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher/* Callbacks for DVB USB */ 454bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcherstatic int ttusb2_identify_state (struct usb_device *udev, struct 455bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, 456bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher int *cold) 457bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher{ 458bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0; 459bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher return 0; 460bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher} 461bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 462bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcherstatic int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff) 463bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher{ 464bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher u8 b = onoff; 465bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher ttusb2_msg(d, CMD_POWER, &b, 0, NULL, 0); 466bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher return ttusb2_msg(d, CMD_POWER, &b, 1, NULL, 0); 467bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher} 468bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 469bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 470bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcherstatic struct tda10086_config tda10086_config = { 471bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .demod_address = 0x0e, 472bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .invert = 0, 473ea75baf4b0f117564bd50827a49c4b14d61d24e9Hartmut Hackmann .diseqc_tone = 1, 4749a1b04e461fc8127c902a988cd9a082ba0680b11Hartmut Hackmann .xtal_freq = TDA10086_XTAL_16M, 475bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher}; 476bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 47776952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martinstatic struct tda10023_config tda10023_config = { 47876952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .demod_address = 0x0c, 47976952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .invert = 0, 48076952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .xtal = 16000000, 48176952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .pll_m = 11, 48276952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .pll_p = 3, 48376952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .pll_n = 1, 48476952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .deltaf = 0xa511, 48576952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin}; 48676952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin 487c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguerostatic struct tda10048_config tda10048_config = { 488c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero .demod_address = 0x10 >> 1, 489c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero .output_mode = TDA10048_PARALLEL_OUTPUT, 490c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero .inversion = TDA10048_INVERSION_ON, 491c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero .dtv6_if_freq_khz = TDA10048_IF_4000, 492c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero .dtv7_if_freq_khz = TDA10048_IF_4500, 493c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero .dtv8_if_freq_khz = TDA10048_IF_5000, 494c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero .clk_freq_khz = TDA10048_CLK_16000, 495c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero .no_firmware = 1, 496c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero .set_pll = true , 497c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero .pll_m = 5, 498c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero .pll_n = 3, 499c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero .pll_p = 0, 500c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero}; 501c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero 502c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguerostatic struct tda827x_config tda827x_config = { 503c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero .config = 0, 504c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero}; 505c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero 50676952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martinstatic int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap) 507bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher{ 508bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher if (usb_set_interface(adap->dev->udev,0,3) < 0) 509bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher err("set interface to alts=3 failed"); 510bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 51177eed219fed5a913f59329cc846420fdeab0150fMichael Krufky if ((adap->fe_adap[0].fe = dvb_attach(tda10086_attach, &tda10086_config, &adap->dev->i2c_adap)) == NULL) { 512bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher deb_info("TDA10086 attach failed\n"); 513bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher return -ENODEV; 514bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher } 515bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 516bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher return 0; 517bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher} 518bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 519c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguerostatic int ttusb2_ct3650_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) 520c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero{ 521c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero struct dvb_usb_adapter *adap = fe->dvb->priv; 522c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero 52377eed219fed5a913f59329cc846420fdeab0150fMichael Krufky return adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, enable); 524c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero} 525c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero 52676952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martinstatic int ttusb2_frontend_tda10023_attach(struct dvb_usb_adapter *adap) 52776952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin{ 52876952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin if (usb_set_interface(adap->dev->udev, 0, 3) < 0) 52976952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin err("set interface to alts=3 failed"); 530c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero 53177eed219fed5a913f59329cc846420fdeab0150fMichael Krufky if (adap->fe_adap[0].fe == NULL) { 532c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero /* FE 0 DVB-C */ 53377eed219fed5a913f59329cc846420fdeab0150fMichael Krufky adap->fe_adap[0].fe = dvb_attach(tda10023_attach, 534c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero &tda10023_config, &adap->dev->i2c_adap, 0x48); 535c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero 53677eed219fed5a913f59329cc846420fdeab0150fMichael Krufky if (adap->fe_adap[0].fe == NULL) { 537c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero deb_info("TDA10023 attach failed\n"); 538c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero return -ENODEV; 539c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero } 5408c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero tt3650_ci_init(adap); 541c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero } else { 54277eed219fed5a913f59329cc846420fdeab0150fMichael Krufky adap->fe_adap[1].fe = dvb_attach(tda10048_attach, 543c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero &tda10048_config, &adap->dev->i2c_adap); 544c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero 54577eed219fed5a913f59329cc846420fdeab0150fMichael Krufky if (adap->fe_adap[1].fe == NULL) { 546c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero deb_info("TDA10048 attach failed\n"); 547c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero return -ENODEV; 548c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero } 549c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero 550c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero /* tuner is behind TDA10023 I2C-gate */ 55177eed219fed5a913f59329cc846420fdeab0150fMichael Krufky adap->fe_adap[1].fe->ops.i2c_gate_ctrl = ttusb2_ct3650_i2c_gate_ctrl; 552c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero 55376952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin } 554c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero 55576952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin return 0; 55676952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin} 55776952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin 55876952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martinstatic int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap) 55976952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin{ 560c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero struct dvb_frontend *fe; 561c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero 562c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero /* MFE: select correct FE to attach tuner since that's called twice */ 56377eed219fed5a913f59329cc846420fdeab0150fMichael Krufky if (adap->fe_adap[1].fe == NULL) 56477eed219fed5a913f59329cc846420fdeab0150fMichael Krufky fe = adap->fe_adap[0].fe; 565c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero else 56677eed219fed5a913f59329cc846420fdeab0150fMichael Krufky fe = adap->fe_adap[1].fe; 567c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero 568c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero /* attach tuner */ 569c9f88aa976b79a26561fb7754a1e0e00ff7626feJose Alberto Reguero if (dvb_attach(tda827x_attach, fe, 0x61, &adap->dev->i2c_adap, &tda827x_config) == NULL) { 57076952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin printk(KERN_ERR "%s: No tda827x found!\n", __func__); 57176952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin return -ENODEV; 57276952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin } 57376952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin return 0; 57476952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin} 57576952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin 57676952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martinstatic int ttusb2_tuner_tda826x_attach(struct dvb_usb_adapter *adap) 577bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher{ 57877eed219fed5a913f59329cc846420fdeab0150fMichael Krufky if (dvb_attach(tda826x_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) { 579bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher deb_info("TDA8263 attach failed\n"); 580bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher return -ENODEV; 581bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher } 582bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 58377eed219fed5a913f59329cc846420fdeab0150fMichael Krufky if (dvb_attach(lnbp21_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, 0, 0) == NULL) { 584bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher deb_info("LNBP21 attach failed\n"); 585bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher return -ENODEV; 586bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher } 587bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher return 0; 588bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher} 589bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 590bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher/* DVB USB Driver stuff */ 591bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcherstatic struct dvb_usb_device_properties ttusb2_properties; 5928c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemannstatic struct dvb_usb_device_properties ttusb2_properties_s2400; 59376952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martinstatic struct dvb_usb_device_properties ttusb2_properties_ct3650; 594bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 5958c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguerostatic void ttusb2_usb_disconnect(struct usb_interface *intf) 5968c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero{ 5978c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero struct dvb_usb_device *d = usb_get_intfdata(intf); 5988c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 5998c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero tt3650_ci_uninit(d); 6008c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero dvb_usb_device_exit(intf); 6018c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero} 6028c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero 603bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcherstatic int ttusb2_probe(struct usb_interface *intf, 604bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher const struct usb_device_id *id) 605bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher{ 60678e92006f410a4044f8c1760c25ac9d11d259aa2Janne Grunau if (0 == dvb_usb_device_init(intf, &ttusb2_properties, 60778e92006f410a4044f8c1760c25ac9d11d259aa2Janne Grunau THIS_MODULE, NULL, adapter_nr) || 60878e92006f410a4044f8c1760c25ac9d11d259aa2Janne Grunau 0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400, 60976952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin THIS_MODULE, NULL, adapter_nr) || 61076952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin 0 == dvb_usb_device_init(intf, &ttusb2_properties_ct3650, 61178e92006f410a4044f8c1760c25ac9d11d259aa2Janne Grunau THIS_MODULE, NULL, adapter_nr)) 6128c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann return 0; 6138c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann return -ENODEV; 614bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher} 615bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 616bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcherstatic struct usb_device_id ttusb2_table [] = { 6178c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) }, 6188c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) }, 6198c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann { USB_DEVICE(USB_VID_TECHNOTREND, 6208c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann USB_PID_TECHNOTREND_CONNECT_S2400) }, 62176952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin { USB_DEVICE(USB_VID_TECHNOTREND, 62276952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin USB_PID_TECHNOTREND_CONNECT_CT3650) }, 6238c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann {} /* Terminating entry */ 624bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher}; 625bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick BoettcherMODULE_DEVICE_TABLE (usb, ttusb2_table); 626bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 627bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcherstatic struct dvb_usb_device_properties ttusb2_properties = { 628bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .caps = DVB_USB_IS_AN_I2C_ADAPTER, 629bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 630bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .usb_ctrl = CYPRESS_FX2, 631bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .firmware = "dvb-usb-pctv-400e-01.fw", 632bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 633bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .size_of_priv = sizeof(struct ttusb2_state), 634bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 635bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .num_adapters = 1, 636bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .adapter = { 637bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher { 63877eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .num_frontends = 1, 63977eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .fe = {{ 640bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .streaming_ctrl = NULL, // ttusb2_streaming_ctrl, 641bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 64276952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .frontend_attach = ttusb2_frontend_tda10086_attach, 64376952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .tuner_attach = ttusb2_tuner_tda826x_attach, 644bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 645bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher /* parameter for the MPEG2-data transfer */ 646bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .stream = { 647bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .type = USB_ISOC, 648bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .count = 5, 649bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .endpoint = 0x02, 650bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .u = { 651bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .isoc = { 652bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .framesperurb = 4, 653bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .framesize = 940, 654bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .interval = 1, 655bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher } 656bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher } 657bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher } 65877eed219fed5a913f59329cc846420fdeab0150fMichael Krufky }}, 659bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher } 660bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher }, 661bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 662bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .power_ctrl = ttusb2_power_ctrl, 663bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .identify_state = ttusb2_identify_state, 664bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 665bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .i2c_algo = &ttusb2_i2c_algo, 666bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 667bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .generic_bulk_ctrl_endpoint = 0x01, 668bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 669ddc9ece89dbeb374e34772232f5e26f64ce63390Christophe Cattelain .num_device_descs = 2, 670bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .devices = { 671bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher { "Pinnacle 400e DVB-S USB2.0", 672bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher { &ttusb2_table[0], NULL }, 673bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher { NULL }, 674bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher }, 675ddc9ece89dbeb374e34772232f5e26f64ce63390Christophe Cattelain { "Pinnacle 450e DVB-S USB2.0", 676ddc9ece89dbeb374e34772232f5e26f64ce63390Christophe Cattelain { &ttusb2_table[1], NULL }, 677ddc9ece89dbeb374e34772232f5e26f64ce63390Christophe Cattelain { NULL }, 678ddc9ece89dbeb374e34772232f5e26f64ce63390Christophe Cattelain }, 679bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher } 680bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher}; 681bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 6828c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemannstatic struct dvb_usb_device_properties ttusb2_properties_s2400 = { 6838c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .caps = DVB_USB_IS_AN_I2C_ADAPTER, 6848c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann 6858c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .usb_ctrl = CYPRESS_FX2, 6868c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .firmware = "dvb-usb-tt-s2400-01.fw", 6878c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann 6888c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .size_of_priv = sizeof(struct ttusb2_state), 6898c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann 6908c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .num_adapters = 1, 6918c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .adapter = { 6928c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann { 69377eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .num_frontends = 1, 69477eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .fe = {{ 6958c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .streaming_ctrl = NULL, 6968c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann 69776952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .frontend_attach = ttusb2_frontend_tda10086_attach, 69876952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .tuner_attach = ttusb2_tuner_tda826x_attach, 6998c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann 7008c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann /* parameter for the MPEG2-data transfer */ 7018c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .stream = { 7028c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .type = USB_ISOC, 7038c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .count = 5, 7048c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .endpoint = 0x02, 7058c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .u = { 7068c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .isoc = { 7078c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .framesperurb = 4, 7088c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .framesize = 940, 7098c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .interval = 1, 7108c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann } 7118c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann } 7128c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann } 71377eed219fed5a913f59329cc846420fdeab0150fMichael Krufky }}, 7148c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann } 7158c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann }, 7168c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann 7178c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .power_ctrl = ttusb2_power_ctrl, 7188c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .identify_state = ttusb2_identify_state, 7198c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann 7208c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .i2c_algo = &ttusb2_i2c_algo, 7218c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann 7228c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .generic_bulk_ctrl_endpoint = 0x01, 7238c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann 7248c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .num_device_descs = 1, 7258c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann .devices = { 7268c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann { "Technotrend TT-connect S-2400", 7278c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann { &ttusb2_table[2], NULL }, 7288c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann { NULL }, 7298c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann }, 7308c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann } 7318c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann}; 7328c899bce2a5540b19e86dd3b355e5699657da144Andre Weidemann 73376952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martinstatic struct dvb_usb_device_properties ttusb2_properties_ct3650 = { 73476952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .caps = DVB_USB_IS_AN_I2C_ADAPTER, 73576952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin 73676952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .usb_ctrl = CYPRESS_FX2, 73776952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin 73876952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .size_of_priv = sizeof(struct ttusb2_state), 73976952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin 7409d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson .rc.core = { 7419d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson .rc_interval = 150, /* Less than IR_KEYPRESS_TIMEOUT */ 7429d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson .rc_codes = RC_MAP_TT_1500, 7439d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson .rc_query = tt3650_rc_query, 7449d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson .allowed_protos = RC_TYPE_UNKNOWN, 7459d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson }, 7469d1da730ee17e712c25c0b1e51653048f92d2385David Henningsson 74776952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .num_adapters = 1, 74876952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .adapter = { 74976952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin { 75077eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .num_frontends = 2, 75177eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .fe = {{ 75276952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .streaming_ctrl = NULL, 75376952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin 75476952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .frontend_attach = ttusb2_frontend_tda10023_attach, 75576952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .tuner_attach = ttusb2_tuner_tda827x_attach, 75676952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin 75776952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin /* parameter for the MPEG2-data transfer */ 75876952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .stream = { 75976952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .type = USB_ISOC, 76076952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .count = 5, 76176952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .endpoint = 0x02, 76276952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .u = { 76376952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .isoc = { 76476952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .framesperurb = 4, 76576952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .framesize = 940, 76676952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .interval = 1, 76776952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin } 76876952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin } 76976952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin } 7701645c879ff688f776371a2478e1948fdf5e0f7feMichael Krufky }, { 77177eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .streaming_ctrl = NULL, 77277eed219fed5a913f59329cc846420fdeab0150fMichael Krufky 77377eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .frontend_attach = ttusb2_frontend_tda10023_attach, 77477eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .tuner_attach = ttusb2_tuner_tda827x_attach, 77577eed219fed5a913f59329cc846420fdeab0150fMichael Krufky 77677eed219fed5a913f59329cc846420fdeab0150fMichael Krufky /* parameter for the MPEG2-data transfer */ 77777eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .stream = { 77877eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .type = USB_ISOC, 77977eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .count = 5, 78077eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .endpoint = 0x02, 78177eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .u = { 78277eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .isoc = { 78377eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .framesperurb = 4, 78477eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .framesize = 940, 78577eed219fed5a913f59329cc846420fdeab0150fMichael Krufky .interval = 1, 78677eed219fed5a913f59329cc846420fdeab0150fMichael Krufky } 78777eed219fed5a913f59329cc846420fdeab0150fMichael Krufky } 78877eed219fed5a913f59329cc846420fdeab0150fMichael Krufky } 78977eed219fed5a913f59329cc846420fdeab0150fMichael Krufky }}, 79076952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin }, 79176952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin }, 79276952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin 79376952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .power_ctrl = ttusb2_power_ctrl, 79476952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .identify_state = ttusb2_identify_state, 79576952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin 79676952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .i2c_algo = &ttusb2_i2c_algo, 79776952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin 79876952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .generic_bulk_ctrl_endpoint = 0x01, 79976952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin 80076952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .num_device_descs = 1, 80176952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .devices = { 80276952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin { "Technotrend TT-connect CT-3650", 80376952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin .warm_ids = { &ttusb2_table[3], NULL }, 80476952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin }, 80576952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin } 80676952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin}; 80776952c7e598f68bf12adf307d6a9a0de3b33b985Guy Martin 808bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcherstatic struct usb_driver ttusb2_driver = { 809bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .name = "dvb_usb_ttusb2", 810bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .probe = ttusb2_probe, 8118c0bc03c80952e81db8cb11082c0c6375e9083abJose Alberto Reguero .disconnect = ttusb2_usb_disconnect, 812bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher .id_table = ttusb2_table, 813bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher}; 814bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 815ecb3b2b35db49778b6d89e3ffd0c400776c20735Greg Kroah-Hartmanmodule_usb_driver(ttusb2_driver); 816bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick Boettcher 817bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick BoettcherMODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); 818bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick BoettcherMODULE_DESCRIPTION("Driver for Pinnacle PCTV 400e DVB-S USB2.0"); 819bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick BoettcherMODULE_VERSION("1.0"); 820bc2e3913c786d7387e21ee0818c1a3b66a571703Patrick BoettcherMODULE_LICENSE("GPL"); 821