From 7d7d40d4d87daa10a6ecd7e85db3aeb0752423d8 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Sun, 28 Dec 2014 21:41:40 +0200 Subject: [PATCH] linux: add patch for Geniatech T230 USB DVB-T/T2/C tuner --- .../linux-226-geniatech-t230-tuner.patch | 267 ++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 packages/linux/patches/3.17.7/linux-226-geniatech-t230-tuner.patch diff --git a/packages/linux/patches/3.17.7/linux-226-geniatech-t230-tuner.patch b/packages/linux/patches/3.17.7/linux-226-geniatech-t230-tuner.patch new file mode 100644 index 0000000000..0b68eb85d1 --- /dev/null +++ b/packages/linux/patches/3.17.7/linux-226-geniatech-t230-tuner.patch @@ -0,0 +1,267 @@ +diff -urN a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h +--- a/drivers/media/dvb-core/dvb-usb-ids.h 2014-12-28 12:15:39.000000000 +0200 ++++ b/drivers/media/dvb-core/dvb-usb-ids.h 2014-12-28 12:28:28.609442863 +0200 +@@ -354,6 +354,7 @@ + #define USB_PID_TELESTAR_STARSTICK_2 0x8000 + #define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807 + #define USB_PID_SONY_PLAYTV 0x0003 ++#define USB_PID_MYGICA_T230 0xc688 + #define USB_PID_MYGICA_D689 0xd811 + #define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011 + #define USB_PID_ELGATO_EYETV_DTT 0x0021 +diff -urN a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c +--- a/drivers/media/dvb-frontends/si2168.c 2014-12-28 12:15:39.000000000 +0200 ++++ b/drivers/media/dvb-frontends/si2168.c 2014-12-28 12:38:43.013424611 +0200 +@@ -308,14 +308,16 @@ + if (ret) + goto err; + +- memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x18", 6); ++ memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x08", 6); ++ cmd.args[5] |= s->ts_clock_inv ? 0x00 : 0x10; + cmd.wlen = 6; + cmd.rlen = 4; + ret = si2168_cmd_execute(s, &cmd); + if (ret) + goto err; + +- memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x15", 6); ++ memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x05", 6); ++ cmd.args[5] |= s->ts_clock_inv ? 0x00 : 0x10; + cmd.wlen = 6; + cmd.rlen = 4; + ret = si2168_cmd_execute(s, &cmd); +@@ -670,6 +672,7 @@ + *config->i2c_adapter = s->adapter; + *config->fe = &s->fe; + s->ts_mode = config->ts_mode; ++ s->ts_clock_inv = config->ts_clock_inv; + s->fw_loaded = false; + + i2c_set_clientdata(client, s); +diff -urN a/drivers/media/dvb-frontends/si2168.h b/drivers/media/dvb-frontends/si2168.h +--- a/drivers/media/dvb-frontends/si2168.h 2014-12-28 12:15:39.000000000 +0200 ++++ b/drivers/media/dvb-frontends/si2168.h 2014-12-28 12:36:31.273428525 +0200 +@@ -37,6 +37,9 @@ + + /* TS mode */ + u8 ts_mode; ++ ++ /* TS clock inverted */ ++ bool ts_clock_inv; + }; + + #define SI2168_TS_PARALLEL 0x06 +diff -urN a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h +--- a/drivers/media/dvb-frontends/si2168_priv.h 2014-12-28 12:15:39.000000000 +0200 ++++ b/drivers/media/dvb-frontends/si2168_priv.h 2014-12-28 12:36:54.893427823 +0200 +@@ -38,6 +38,7 @@ + bool active; + bool fw_loaded; + u8 ts_mode; ++ bool ts_clock_inv; + }; + + /* firmare command struct */ +diff -urN a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c +--- a/drivers/media/tuners/si2157.c 2014-12-28 12:15:39.000000000 +0200 ++++ b/drivers/media/tuners/si2157.c 2014-12-28 12:35:42.933429961 +0200 +@@ -112,11 +112,13 @@ + cmd.args[4] << 0; + + #define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0) ++ #define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0) + #define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0) + #define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0) + + switch (chip_id) { + case SI2158_A20: ++ case SI2148_A20: + fw_file = SI2158_A20_FIRMWARE; + break; + case SI2157_A30: +diff -urN a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c +--- a/drivers/media/usb/dvb-usb/cxusb.c 2014-12-28 12:15:39.000000000 +0200 ++++ b/drivers/media/usb/dvb-usb/cxusb.c 2014-12-28 12:40:24.637421592 +0200 +@@ -1408,6 +1408,77 @@ + return 0; + } + ++static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap) ++{ ++ struct dvb_usb_device *d = adap->dev; ++ struct cxusb_state *st = d->priv; ++ struct i2c_adapter *adapter; ++ struct i2c_client *client_demod; ++ struct i2c_client *client_tuner; ++ struct i2c_board_info info; ++ struct si2168_config si2168_config; ++ struct si2157_config si2157_config; ++ ++ /* Select required USB configuration */ ++ if (usb_set_interface(d->udev, 0, 0) < 0) ++ err("set interface failed"); ++ ++ /* Unblock all USB pipes */ ++ usb_clear_halt(d->udev, ++ usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); ++ usb_clear_halt(d->udev, ++ usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); ++ usb_clear_halt(d->udev, ++ usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint)); ++ ++ /* attach frontend */ ++ memset(&si2168_config, 0, sizeof(si2168_config)); ++ si2168_config.i2c_adapter = &adapter; ++ si2168_config.fe = &adap->fe_adap[0].fe; ++ si2168_config.ts_mode = SI2168_TS_PARALLEL; ++ si2168_config.ts_clock_inv = 1; ++ memset(&info, 0, sizeof(struct i2c_board_info)); ++ strlcpy(info.type, "si2168", I2C_NAME_SIZE); ++ info.addr = 0x64; ++ info.platform_data = &si2168_config; ++ request_module(info.type); ++ client_demod = i2c_new_device(&d->i2c_adap, &info); ++ if (client_demod == NULL || client_demod->dev.driver == NULL) ++ return -ENODEV; ++ ++ if (!try_module_get(client_demod->dev.driver->owner)) { ++ i2c_unregister_device(client_demod); ++ return -ENODEV; ++ } ++ ++ st->i2c_client_demod = client_demod; ++ ++ /* attach tuner */ ++ memset(&si2157_config, 0, sizeof(si2157_config)); ++ si2157_config.fe = adap->fe_adap[0].fe; ++ memset(&info, 0, sizeof(struct i2c_board_info)); ++ strlcpy(info.type, "si2157", I2C_NAME_SIZE); ++ info.addr = 0x60; ++ info.platform_data = &si2157_config; ++ request_module(info.type); ++ client_tuner = i2c_new_device(adapter, &info); ++ if (client_tuner == NULL || client_tuner->dev.driver == NULL) { ++ module_put(client_demod->dev.driver->owner); ++ i2c_unregister_device(client_demod); ++ return -ENODEV; ++ } ++ if (!try_module_get(client_tuner->dev.driver->owner)) { ++ i2c_unregister_device(client_tuner); ++ module_put(client_demod->dev.driver->owner); ++ i2c_unregister_device(client_demod); ++ return -ENODEV; ++ } ++ ++ st->i2c_client_tuner = client_tuner; ++ ++ return 0; ++} ++ + static int cxusb_tt_ct2_4400_attach(struct dvb_usb_adapter *adap) + { + struct dvb_usb_device *d = adap->dev; +@@ -1435,6 +1506,7 @@ + msleep(100); + + /* attach frontend */ ++ memset(&si2168_config, 0, sizeof(si2168_config)); + si2168_config.i2c_adapter = &adapter; + si2168_config.fe = &adap->fe_adap[0].fe; + si2168_config.ts_mode = SI2168_TS_PARALLEL; +@@ -1609,6 +1681,7 @@ + static struct dvb_usb_device_properties cxusb_aver_a868r_properties; + static struct dvb_usb_device_properties cxusb_d680_dmb_properties; + static struct dvb_usb_device_properties cxusb_mygica_d689_properties; ++static struct dvb_usb_device_properties cxusb_mygica_t230_properties; + static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties; + + static int cxusb_probe(struct usb_interface *intf, +@@ -1640,6 +1713,8 @@ + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties, + THIS_MODULE, NULL, adapter_nr) || ++ 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties, ++ THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &cxusb_tt_ct2_4400_properties, + THIS_MODULE, NULL, adapter_nr) || + 0) +@@ -1701,6 +1776,7 @@ + { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) }, + { USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_TVSTICK_CT2_4400) }, + { USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI) }, ++ { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230) }, + {} /* Terminating entry */ + }; + MODULE_DEVICE_TABLE (usb, cxusb_table); +@@ -2406,6 +2482,59 @@ + }, + } + }; ++ ++static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { ++ .caps = DVB_USB_IS_AN_I2C_ADAPTER, ++ ++ .usb_ctrl = CYPRESS_FX2, ++ ++ .size_of_priv = sizeof(struct cxusb_state), ++ ++ .num_adapters = 1, ++ .adapter = { ++ { ++ .num_frontends = 1, ++ .fe = {{ ++ .streaming_ctrl = cxusb_streaming_ctrl, ++ .frontend_attach = cxusb_mygica_t230_frontend_attach, ++ ++ /* parameter for the MPEG2-data transfer */ ++ .stream = { ++ .type = USB_BULK, ++ .count = 5, ++ .endpoint = 0x02, ++ .u = { ++ .bulk = { ++ .buffersize = 8192, ++ } ++ } ++ }, ++ } }, ++ }, ++ }, ++ ++ .power_ctrl = cxusb_d680_dmb_power_ctrl, ++ ++ .i2c_algo = &cxusb_i2c_algo, ++ ++ .generic_bulk_ctrl_endpoint = 0x01, ++ ++ .rc.legacy = { ++ .rc_interval = 100, ++ .rc_map_table = rc_map_d680_dmb_table, ++ .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table), ++ .rc_query = cxusb_d680_dmb_rc_query, ++ }, ++ ++ .num_device_descs = 1, ++ .devices = { ++ { ++ "Mygica T230 DVB-T/T2/C", ++ { NULL }, ++ { &cxusb_table[22], NULL }, ++ }, ++ } ++}; + + static struct usb_driver cxusb_driver = { + .name = "dvb_usb_cxusb", +diff -urN a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c +--- a/drivers/media/usb/em28xx/em28xx-dvb.c 2014-12-28 12:15:39.000000000 +0200 ++++ b/drivers/media/usb/em28xx/em28xx-dvb.c 2014-12-28 12:41:05.041420392 +0200 +@@ -1531,6 +1531,7 @@ + struct si2157_config si2157_config; + + /* attach demod */ ++ memset(&si2168_config, 0, sizeof(si2168_config)); + si2168_config.i2c_adapter = &adapter; + si2168_config.fe = &dvb->fe[0]; + si2168_config.ts_mode = SI2168_TS_PARALLEL;