aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlli Salonen <olli.salonen@iki.fi>2014-07-13 09:52:22 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-07-14 20:07:07 -0400
commit26c42b0dd5fa552bf26451cbd1d4c70fb6b95b67 (patch)
tree9ed52c022eae5bc1168054838d2a5adfa337cb40
parenta1dad50d8cdce0be71489c7544ffcd36cf80e994 (diff)
[media] cxusb: TechnoTrend CT2-4400 USB DVB-T2/C tuner support
USB ID 0b48:3014. USB interface: Cypress CY7C68013A-56LTXC Demodulator: Silicon Labs Si2168-30 Tuner: Silicon Labs Si2158-20 Cc: Michael Krufky <mkrufky@linuxtv.org> Signed-off-by: Olli Salonen <olli.salonen@iki.fi> Reviewed-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Antti Palosaari <crope@iki.fi> Reviewed-by: Michael Ira Krufky <mkrufky@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/dvb-core/dvb-usb-ids.h1
-rw-r--r--drivers/media/usb/dvb-usb/Kconfig3
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.c191
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.h2
4 files changed, 196 insertions, 1 deletions
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
index 11d2bea23b02..f8e31509f12e 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
@@ -244,6 +244,7 @@
244#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 244#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
245#define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009 245#define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009
246#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d 246#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d
247#define USB_PID_TECHNOTREND_TVSTICK_CT2_4400 0x3014
247#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a 248#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
248#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081 249#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
249#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058 250#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058
diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig
index c5d95662e2e1..10aef2188fbe 100644
--- a/drivers/media/usb/dvb-usb/Kconfig
+++ b/drivers/media/usb/dvb-usb/Kconfig
@@ -117,10 +117,12 @@ config DVB_USB_CXUSB
117 select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT 117 select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT
118 select DVB_ATBM8830 if MEDIA_SUBDRV_AUTOSELECT 118 select DVB_ATBM8830 if MEDIA_SUBDRV_AUTOSELECT
119 select DVB_LGS8GXX if MEDIA_SUBDRV_AUTOSELECT 119 select DVB_LGS8GXX if MEDIA_SUBDRV_AUTOSELECT
120 select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
120 select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT 121 select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
121 select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT 122 select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT
122 select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT 123 select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
123 select MEDIA_TUNER_MAX2165 if MEDIA_SUBDRV_AUTOSELECT 124 select MEDIA_TUNER_MAX2165 if MEDIA_SUBDRV_AUTOSELECT
125 select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
124 help 126 help
125 Say Y here to support the Conexant USB2.0 hybrid reference design. 127 Say Y here to support the Conexant USB2.0 hybrid reference design.
126 Currently, only DVB and ATSC modes are supported, analog mode 128 Currently, only DVB and ATSC modes are supported, analog mode
@@ -128,6 +130,7 @@ config DVB_USB_CXUSB
128 130
129 Medion MD95700 hybrid USB2.0 device. 131 Medion MD95700 hybrid USB2.0 device.
130 DViCO FusionHDTV (Bluebird) USB2.0 devices 132 DViCO FusionHDTV (Bluebird) USB2.0 devices
133 TechnoTrend TVStick CT2-4400
131 134
132config DVB_USB_M920X 135config DVB_USB_M920X
133 tristate "Uli m920x DVB-T USB2.0 support" 136 tristate "Uli m920x DVB-T USB2.0 support"
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
index 6acde5ee4324..d60e36d5103a 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -42,6 +42,8 @@
42#include "dib0070.h" 42#include "dib0070.h"
43#include "lgs8gxx.h" 43#include "lgs8gxx.h"
44#include "atbm8830.h" 44#include "atbm8830.h"
45#include "si2168.h"
46#include "si2157.h"
45 47
46/* Max transfer size done by I2C transfer functions */ 48/* Max transfer size done by I2C transfer functions */
47#define MAX_XFER_SIZE 64 49#define MAX_XFER_SIZE 64
@@ -144,6 +146,22 @@ static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d,
144 } 146 }
145} 147}
146 148
149static int cxusb_tt_ct2_4400_gpio_tuner(struct dvb_usb_device *d, int onoff)
150{
151 u8 o[2], i;
152 int rc;
153
154 o[0] = 0x83;
155 o[1] = onoff;
156 rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
157
158 if (rc) {
159 deb_info("gpio_write failed.\n");
160 return -EIO;
161 }
162 return 0;
163}
164
147/* I2C */ 165/* I2C */
148static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], 166static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
149 int num) 167 int num)
@@ -505,6 +523,30 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
505 return 0; 523 return 0;
506} 524}
507 525
526static int cxusb_tt_ct2_4400_rc_query(struct dvb_usb_device *d)
527{
528 u8 i[2];
529 int ret;
530 u32 cmd, keycode;
531 u8 rc5_cmd, rc5_addr, rc5_toggle;
532
533 ret = cxusb_ctrl_msg(d, 0x10, NULL, 0, i, 2);
534 if (ret)
535 return ret;
536
537 cmd = (i[0] << 8) | i[1];
538
539 if (cmd != 0xffff) {
540 rc5_cmd = cmd & 0x3F; /* bits 1-6 for command */
541 rc5_addr = (cmd & 0x07C0) >> 6; /* bits 7-11 for address */
542 rc5_toggle = (cmd & 0x0800) >> 11; /* bit 12 for toggle */
543 keycode = (rc5_addr << 8) | rc5_cmd;
544 rc_keydown(d->rc_dev, keycode, rc5_toggle);
545 }
546
547 return 0;
548}
549
508static struct rc_map_table rc_map_dvico_mce_table[] = { 550static struct rc_map_table rc_map_dvico_mce_table[] = {
509 { 0xfe02, KEY_TV }, 551 { 0xfe02, KEY_TV },
510 { 0xfe0e, KEY_MP3 }, 552 { 0xfe0e, KEY_MP3 },
@@ -1301,6 +1343,73 @@ static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
1301 return 0; 1343 return 0;
1302} 1344}
1303 1345
1346static int cxusb_tt_ct2_4400_attach(struct dvb_usb_adapter *adap)
1347{
1348 struct dvb_usb_device *d = adap->dev;
1349 struct cxusb_state *st = d->priv;
1350 struct i2c_adapter *adapter;
1351 struct i2c_client *client_demod;
1352 struct i2c_client *client_tuner;
1353 struct i2c_board_info info;
1354 struct si2168_config si2168_config;
1355 struct si2157_config si2157_config;
1356
1357 /* reset the tuner */
1358 if (cxusb_tt_ct2_4400_gpio_tuner(d, 0) < 0) {
1359 err("clear tuner gpio failed");
1360 return -EIO;
1361 }
1362 msleep(100);
1363 if (cxusb_tt_ct2_4400_gpio_tuner(d, 1) < 0) {
1364 err("set tuner gpio failed");
1365 return -EIO;
1366 }
1367 msleep(100);
1368
1369 /* attach frontend */
1370 si2168_config.i2c_adapter = &adapter;
1371 si2168_config.fe = &adap->fe_adap[0].fe;
1372 memset(&info, 0, sizeof(struct i2c_board_info));
1373 strlcpy(info.type, "si2168", I2C_NAME_SIZE);
1374 info.addr = 0x64;
1375 info.platform_data = &si2168_config;
1376 request_module(info.type);
1377 client_demod = i2c_new_device(&d->i2c_adap, &info);
1378 if (client_demod == NULL || client_demod->dev.driver == NULL)
1379 return -ENODEV;
1380
1381 if (!try_module_get(client_demod->dev.driver->owner)) {
1382 i2c_unregister_device(client_demod);
1383 return -ENODEV;
1384 }
1385
1386 st->i2c_client_demod = client_demod;
1387
1388 /* attach tuner */
1389 si2157_config.fe = adap->fe_adap[0].fe;
1390 memset(&info, 0, sizeof(struct i2c_board_info));
1391 strlcpy(info.type, "si2157", I2C_NAME_SIZE);
1392 info.addr = 0x60;
1393 info.platform_data = &si2157_config;
1394 request_module(info.type);
1395 client_tuner = i2c_new_device(adapter, &info);
1396 if (client_tuner == NULL || client_tuner->dev.driver == NULL) {
1397 module_put(client_demod->dev.driver->owner);
1398 i2c_unregister_device(client_demod);
1399 return -ENODEV;
1400 }
1401 if (!try_module_get(client_tuner->dev.driver->owner)) {
1402 i2c_unregister_device(client_tuner);
1403 module_put(client_demod->dev.driver->owner);
1404 i2c_unregister_device(client_demod);
1405 return -ENODEV;
1406 }
1407
1408 st->i2c_client_tuner = client_tuner;
1409
1410 return 0;
1411}
1412
1304/* 1413/*
1305 * DViCO has shipped two devices with the same USB ID, but only one of them 1414 * DViCO has shipped two devices with the same USB ID, but only one of them
1306 * needs a firmware download. Check the device class details to see if they 1415 * needs a firmware download. Check the device class details to see if they
@@ -1382,6 +1491,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope
1382static struct dvb_usb_device_properties cxusb_aver_a868r_properties; 1491static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
1383static struct dvb_usb_device_properties cxusb_d680_dmb_properties; 1492static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
1384static struct dvb_usb_device_properties cxusb_mygica_d689_properties; 1493static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
1494static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties;
1385 1495
1386static int cxusb_probe(struct usb_interface *intf, 1496static int cxusb_probe(struct usb_interface *intf,
1387 const struct usb_device_id *id) 1497 const struct usb_device_id *id)
@@ -1412,12 +1522,37 @@ static int cxusb_probe(struct usb_interface *intf,
1412 THIS_MODULE, NULL, adapter_nr) || 1522 THIS_MODULE, NULL, adapter_nr) ||
1413 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties, 1523 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
1414 THIS_MODULE, NULL, adapter_nr) || 1524 THIS_MODULE, NULL, adapter_nr) ||
1525 0 == dvb_usb_device_init(intf, &cxusb_tt_ct2_4400_properties,
1526 THIS_MODULE, NULL, adapter_nr) ||
1415 0) 1527 0)
1416 return 0; 1528 return 0;
1417 1529
1418 return -EINVAL; 1530 return -EINVAL;
1419} 1531}
1420 1532
1533static void cxusb_disconnect(struct usb_interface *intf)
1534{
1535 struct dvb_usb_device *d = usb_get_intfdata(intf);
1536 struct cxusb_state *st = d->priv;
1537 struct i2c_client *client;
1538
1539 /* remove I2C client for tuner */
1540 client = st->i2c_client_tuner;
1541 if (client) {
1542 module_put(client->dev.driver->owner);
1543 i2c_unregister_device(client);
1544 }
1545
1546 /* remove I2C client for demodulator */
1547 client = st->i2c_client_demod;
1548 if (client) {
1549 module_put(client->dev.driver->owner);
1550 i2c_unregister_device(client);
1551 }
1552
1553 dvb_usb_device_exit(intf);
1554}
1555
1421static struct usb_device_id cxusb_table [] = { 1556static struct usb_device_id cxusb_table [] = {
1422 { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) }, 1557 { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
1423 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) }, 1558 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
@@ -1439,6 +1574,7 @@ static struct usb_device_id cxusb_table [] = {
1439 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) }, 1574 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
1440 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) }, 1575 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
1441 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) }, 1576 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) },
1577 { USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_TVSTICK_CT2_4400) },
1442 {} /* Terminating entry */ 1578 {} /* Terminating entry */
1443}; 1579};
1444MODULE_DEVICE_TABLE (usb, cxusb_table); 1580MODULE_DEVICE_TABLE (usb, cxusb_table);
@@ -2085,10 +2221,63 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
2085 } 2221 }
2086}; 2222};
2087 2223
2224static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties = {
2225 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2226
2227 .usb_ctrl = CYPRESS_FX2,
2228
2229 .size_of_priv = sizeof(struct cxusb_state),
2230
2231 .num_adapters = 1,
2232 .adapter = {
2233 {
2234 .num_frontends = 1,
2235 .fe = {{
2236 .streaming_ctrl = cxusb_streaming_ctrl,
2237 /* both frontend and tuner attached in the
2238 same function */
2239 .frontend_attach = cxusb_tt_ct2_4400_attach,
2240
2241 /* parameter for the MPEG2-data transfer */
2242 .stream = {
2243 .type = USB_BULK,
2244 .count = 8,
2245 .endpoint = 0x82,
2246 .u = {
2247 .bulk = {
2248 .buffersize = 4096,
2249 }
2250 }
2251 },
2252 } },
2253 },
2254 },
2255
2256 .i2c_algo = &cxusb_i2c_algo,
2257 .generic_bulk_ctrl_endpoint = 0x01,
2258 .generic_bulk_ctrl_endpoint_response = 0x81,
2259
2260 .rc.core = {
2261 .rc_codes = RC_MAP_TT_1500,
2262 .allowed_protos = RC_BIT_RC5,
2263 .rc_query = cxusb_tt_ct2_4400_rc_query,
2264 .rc_interval = 150,
2265 },
2266
2267 .num_device_descs = 1,
2268 .devices = {
2269 {
2270 "TechnoTrend TVStick CT2-4400",
2271 { NULL },
2272 { &cxusb_table[20], NULL },
2273 },
2274 }
2275};
2276
2088static struct usb_driver cxusb_driver = { 2277static struct usb_driver cxusb_driver = {
2089 .name = "dvb_usb_cxusb", 2278 .name = "dvb_usb_cxusb",
2090 .probe = cxusb_probe, 2279 .probe = cxusb_probe,
2091 .disconnect = dvb_usb_device_exit, 2280 .disconnect = cxusb_disconnect,
2092 .id_table = cxusb_table, 2281 .id_table = cxusb_table,
2093}; 2282};
2094 2283
diff --git a/drivers/media/usb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h
index 1a51eafd31b9..527ff7905e15 100644
--- a/drivers/media/usb/dvb-usb/cxusb.h
+++ b/drivers/media/usb/dvb-usb/cxusb.h
@@ -30,6 +30,8 @@
30 30
31struct cxusb_state { 31struct cxusb_state {
32 u8 gpio_write_state[3]; 32 u8 gpio_write_state[3];
33 struct i2c_client *i2c_client_demod;
34 struct i2c_client *i2c_client_tuner;
33}; 35};
34 36
35#endif 37#endif