diff options
author | Olli Salonen <olli.salonen@iki.fi> | 2014-08-08 03:06:37 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-09-02 14:12:38 -0400 |
commit | 6832d11edde3e47ef54e0da5d61380de9043b704 (patch) | |
tree | 066119346b64fae749e3c09527315e38a25f5fa2 /drivers/media | |
parent | 868736ad3404b205794bc04233eca58293818dea (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.h | 1 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/Kconfig | 2 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/cxusb.c | 92 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/cxusb.h | 4 |
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 | ||
135 | config DVB_USB_M920X | 135 | config 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 | ||
676 | static 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; | ||
701 | err: | ||
702 | deb_info("%s: ci usb write returned %d\n", __func__, ret); | ||
703 | return ret; | ||
704 | |||
705 | } | ||
706 | |||
675 | static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) | 707 | static 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 | }; |
1582 | MODULE_DEVICE_TABLE (usb, cxusb_table); | 1667 | MODULE_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 | |||
31 | struct cxusb_state { | 34 | struct 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 |