aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorOlli Salonen <olli.salonen@iki.fi>2014-08-08 03:06:37 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-09-02 14:12:38 -0400
commit6832d11edde3e47ef54e0da5d61380de9043b704 (patch)
tree066119346b64fae749e3c09527315e38a25f5fa2 /drivers/media
parent868736ad3404b205794bc04233eca58293818dea (diff)
[media] cxusb: Add support for TechnoTrend TT-connect CT2-4650 CI
TechnoTrend TT-connect CT2-4650 CI (0b48:3012) is an USB DVB-T2/C tuner with the following components: USB interface: Cypress CY7C68013A-56LTXC Demodulator: Silicon Labs Si2168-A20 Tuner: Silicon Labs Si2158-A20 CI chip: CIMaX SP2HF The firmware for the tuner is the same as for TechnoTrend TT-TVStick CT2-4400. See https://www.mail-archive.com/linux-media@vger.kernel.org/msg76944.html The demodulator needs a firmware that can be extracted from the Windows drivers. File ttConnect4650_64.sys should be extracted from http://www.tt-downloads.de/bda-treiber_4.1.0.4.zip (MD5 sum below). 3464bfc37a47b4032568718bacba23fb ttConnect4650_64.sys Then the firmware can be extracted: dd if=ttConnect4650_64.sys ibs=1 skip=273376 count=6424 of=dvb-demod-si2168-a20-01.fw The SP2 CI module requires a definition of a function cxusb_tt_ct2_4650_ci_ctrl that is passed on to the SP2 driver and called back for CAM operations. [crope@iki.fi: meld USB ID define patch to this] Signed-off-by: Olli Salonen <olli.salonen@iki.fi> Reviewed-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb-core/dvb-usb-ids.h1
-rw-r--r--drivers/media/usb/dvb-usb/Kconfig2
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.c92
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.h4
4 files changed, 97 insertions, 2 deletions
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
index 5135a096bfa6..b7a9b98db414 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_CONNECT_CT2_4650_CI 0x3012
247#define USB_PID_TECHNOTREND_TVSTICK_CT2_4400 0x3014 248#define USB_PID_TECHNOTREND_TVSTICK_CT2_4400 0x3014
248#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a 249#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
249#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081 250#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig
index 10aef2188fbe..41d3eb922a00 100644
--- a/drivers/media/usb/dvb-usb/Kconfig
+++ b/drivers/media/usb/dvb-usb/Kconfig
@@ -130,7 +130,7 @@ config DVB_USB_CXUSB
130 130
131 Medion MD95700 hybrid USB2.0 device. 131 Medion MD95700 hybrid USB2.0 device.
132 DViCO FusionHDTV (Bluebird) USB2.0 devices 132 DViCO FusionHDTV (Bluebird) USB2.0 devices
133 TechnoTrend TVStick CT2-4400 133 TechnoTrend TVStick CT2-4400 and CT2-4650 CI devices
134 134
135config DVB_USB_M920X 135config DVB_USB_M920X
136 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 87842e9cdb49..4ab34590c2c7 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -44,6 +44,7 @@
44#include "atbm8830.h" 44#include "atbm8830.h"
45#include "si2168.h" 45#include "si2168.h"
46#include "si2157.h" 46#include "si2157.h"
47#include "sp2.h"
47 48
48/* Max transfer size done by I2C transfer functions */ 49/* Max transfer size done by I2C transfer functions */
49#define MAX_XFER_SIZE 80 50#define MAX_XFER_SIZE 80
@@ -672,6 +673,37 @@ static struct rc_map_table rc_map_d680_dmb_table[] = {
672 { 0x0025, KEY_POWER }, 673 { 0x0025, KEY_POWER },
673}; 674};
674 675
676static int cxusb_tt_ct2_4650_ci_ctrl(void *priv, u8 read, int addr,
677 u8 data, int *mem)
678{
679 struct dvb_usb_device *d = priv;
680 u8 wbuf[3];
681 u8 rbuf[2];
682 int ret;
683
684 wbuf[0] = (addr >> 8) & 0xff;
685 wbuf[1] = addr & 0xff;
686
687 if (read) {
688 ret = cxusb_ctrl_msg(d, CMD_SP2_CI_READ, wbuf, 2, rbuf, 2);
689 } else {
690 wbuf[2] = data;
691 ret = cxusb_ctrl_msg(d, CMD_SP2_CI_WRITE, wbuf, 3, rbuf, 1);
692 }
693
694 if (ret)
695 goto err;
696
697 if (read)
698 *mem = rbuf[1];
699
700 return 0;
701err:
702 deb_info("%s: ci usb write returned %d\n", __func__, ret);
703 return ret;
704
705}
706
675static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) 707static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
676{ 708{
677 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; 709 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 };
@@ -1350,9 +1382,12 @@ static int cxusb_tt_ct2_4400_attach(struct dvb_usb_adapter *adap)
1350 struct i2c_adapter *adapter; 1382 struct i2c_adapter *adapter;
1351 struct i2c_client *client_demod; 1383 struct i2c_client *client_demod;
1352 struct i2c_client *client_tuner; 1384 struct i2c_client *client_tuner;
1385 struct i2c_client *client_ci;
1353 struct i2c_board_info info; 1386 struct i2c_board_info info;
1354 struct si2168_config si2168_config; 1387 struct si2168_config si2168_config;
1355 struct si2157_config si2157_config; 1388 struct si2157_config si2157_config;
1389 struct sp2_config sp2_config;
1390 u8 o[2], i;
1356 1391
1357 /* reset the tuner */ 1392 /* reset the tuner */
1358 if (cxusb_tt_ct2_4400_gpio_tuner(d, 0) < 0) { 1393 if (cxusb_tt_ct2_4400_gpio_tuner(d, 0) < 0) {
@@ -1409,6 +1444,48 @@ static int cxusb_tt_ct2_4400_attach(struct dvb_usb_adapter *adap)
1409 1444
1410 st->i2c_client_tuner = client_tuner; 1445 st->i2c_client_tuner = client_tuner;
1411 1446
1447 /* initialize CI */
1448 if (d->udev->descriptor.idProduct ==
1449 USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI) {
1450
1451 memcpy(o, "\xc0\x01", 2);
1452 cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
1453 msleep(100);
1454
1455 memcpy(o, "\xc0\x00", 2);
1456 cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
1457 msleep(100);
1458
1459 memset(&sp2_config, 0, sizeof(sp2_config));
1460 sp2_config.dvb_adap = &adap->dvb_adap;
1461 sp2_config.priv = d;
1462 sp2_config.ci_control = cxusb_tt_ct2_4650_ci_ctrl;
1463 memset(&info, 0, sizeof(struct i2c_board_info));
1464 strlcpy(info.type, "sp2", I2C_NAME_SIZE);
1465 info.addr = 0x40;
1466 info.platform_data = &sp2_config;
1467 request_module(info.type);
1468 client_ci = i2c_new_device(&d->i2c_adap, &info);
1469 if (client_ci == NULL || client_ci->dev.driver == NULL) {
1470 module_put(client_tuner->dev.driver->owner);
1471 i2c_unregister_device(client_tuner);
1472 module_put(client_demod->dev.driver->owner);
1473 i2c_unregister_device(client_demod);
1474 return -ENODEV;
1475 }
1476 if (!try_module_get(client_ci->dev.driver->owner)) {
1477 i2c_unregister_device(client_ci);
1478 module_put(client_tuner->dev.driver->owner);
1479 i2c_unregister_device(client_tuner);
1480 module_put(client_demod->dev.driver->owner);
1481 i2c_unregister_device(client_demod);
1482 return -ENODEV;
1483 }
1484
1485 st->i2c_client_ci = client_ci;
1486
1487 }
1488
1412 return 0; 1489 return 0;
1413} 1490}
1414 1491
@@ -1538,6 +1615,13 @@ static void cxusb_disconnect(struct usb_interface *intf)
1538 struct cxusb_state *st = d->priv; 1615 struct cxusb_state *st = d->priv;
1539 struct i2c_client *client; 1616 struct i2c_client *client;
1540 1617
1618 /* remove I2C client for CI */
1619 client = st->i2c_client_ci;
1620 if (client) {
1621 module_put(client->dev.driver->owner);
1622 i2c_unregister_device(client);
1623 }
1624
1541 /* remove I2C client for tuner */ 1625 /* remove I2C client for tuner */
1542 client = st->i2c_client_tuner; 1626 client = st->i2c_client_tuner;
1543 if (client) { 1627 if (client) {
@@ -1577,6 +1661,7 @@ static struct usb_device_id cxusb_table [] = {
1577 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) }, 1661 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
1578 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) }, 1662 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) },
1579 { USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_TVSTICK_CT2_4400) }, 1663 { USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_TVSTICK_CT2_4400) },
1664 { USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI) },
1580 {} /* Terminating entry */ 1665 {} /* Terminating entry */
1581}; 1666};
1582MODULE_DEVICE_TABLE (usb, cxusb_table); 1667MODULE_DEVICE_TABLE (usb, cxusb_table);
@@ -2266,13 +2351,18 @@ static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties = {
2266 .rc_interval = 150, 2351 .rc_interval = 150,
2267 }, 2352 },
2268 2353
2269 .num_device_descs = 1, 2354 .num_device_descs = 2,
2270 .devices = { 2355 .devices = {
2271 { 2356 {
2272 "TechnoTrend TVStick CT2-4400", 2357 "TechnoTrend TVStick CT2-4400",
2273 { NULL }, 2358 { NULL },
2274 { &cxusb_table[20], NULL }, 2359 { &cxusb_table[20], NULL },
2275 }, 2360 },
2361 {
2362 "TechnoTrend TT-connect CT2-4650 CI",
2363 { NULL },
2364 { &cxusb_table[21], NULL },
2365 },
2276 } 2366 }
2277}; 2367};
2278 2368
diff --git a/drivers/media/usb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h
index 527ff7905e15..29f3e2ea2476 100644
--- a/drivers/media/usb/dvb-usb/cxusb.h
+++ b/drivers/media/usb/dvb-usb/cxusb.h
@@ -28,10 +28,14 @@
28#define CMD_ANALOG 0x50 28#define CMD_ANALOG 0x50
29#define CMD_DIGITAL 0x51 29#define CMD_DIGITAL 0x51
30 30
31#define CMD_SP2_CI_WRITE 0x70
32#define CMD_SP2_CI_READ 0x71
33
31struct cxusb_state { 34struct cxusb_state {
32 u8 gpio_write_state[3]; 35 u8 gpio_write_state[3];
33 struct i2c_client *i2c_client_demod; 36 struct i2c_client *i2c_client_demod;
34 struct i2c_client *i2c_client_tuner; 37 struct i2c_client *i2c_client_tuner;
38 struct i2c_client *i2c_client_ci;
35}; 39};
36 40
37#endif 41#endif