Re: [PATCH v1 0/2] Remove duplicate driver for MyGica T230C

2018-01-24 Thread Stefan Brüns
On Wednesday, 10 January 2018 00:33:37 CET Stefan Brüns wrote:
> In 2017-02, two drivers for the T230C where submitted, but until now
> only the one based on the older dvb-usb/cxusb.c driver has been part
> of the mainline kernel. As a dvb-usb-v2 driver is preferable, remove
> the other driver.
> 
> The cxusb.c patch also contained an unrelated change for the T230,
> i.e. a correction of the RC model. As this change apparently is
> correct, restore it. This has not been tested due to lack of hardware.
> 
> 
> Evgeny Plehov (1):
>   Revert "[media] dvb-usb-cxusb: Geniatech T230C support"
> 
> Stefan Brüns (1):
>   [media] cxusb: restore RC_MAP for MyGica T230
> 
>  drivers/media/usb/dvb-usb/cxusb.c | 137
> ------ 1 file changed, 137 deletions(-)


Ping!

-- 
Stefan Brüns  /  Bergstraße 21  /  52062 Aachen
home: +49 241 53809034 mobile: +49 151 50412019

signature.asc
Description: This is a digitally signed message part.


[PATCH v1 2/2] [media] cxusb: restore RC_MAP for MyGica T230

2018-01-09 Thread Stefan Brüns
Commit f8585ce655e9cdeabc38e8e2580b05735110e4a5 ("[media] dvb-usb-cxusb:
Geniatech T230C support") sneaked in an unrelated change for the older
T230 (not C) model. As the commit was reverted this change was reverted
too, although likely correct.

Signed-off-by: Stefan Brüns <stefan.bru...@rwth-aachen.de>

---

 drivers/media/usb/dvb-usb/cxusb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/usb/dvb-usb/cxusb.c 
b/drivers/media/usb/dvb-usb/cxusb.c
index edb7cd2e43d9..75f44b534007 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -2165,7 +2165,7 @@ static struct dvb_usb_device_properties 
cxusb_mygica_t230_properties = {
 
.rc.core = {
.rc_interval= 100,
-   .rc_codes   = RC_MAP_D680_DMB,
+   .rc_codes   = RC_MAP_TOTAL_MEDIA_IN_HAND_02,
.module_name= KBUILD_MODNAME,
.rc_query   = cxusb_d680_dmb_rc_query,
.allowed_protos = RC_PROTO_BIT_UNKNOWN,
-- 
2.15.1



[PATCH v1 1/2] Revert "[media] dvb-usb-cxusb: Geniatech T230C support"

2018-01-09 Thread Stefan Brüns
From: Evgeny Plehov <evgenyple...@ukr.net>

This reverts commit f8585ce655e9cdeabc38e8e2580b05735110e4a5.

The T230C is handled by the dvb-usb-v2/dvbsky.c driver, which should
be preferred over a dvb-usb (v1) driver.

Signed-off-by: Stefan Brüns <stefan.bru...@rwth-aachen.de>
---

 drivers/media/usb/dvb-usb/cxusb.c | 139 +-
 1 file changed, 1 insertion(+), 138 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/cxusb.c 
b/drivers/media/usb/dvb-usb/cxusb.c
index 37dea0adc695..edb7cd2e43d9 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -1239,82 +1239,6 @@ static int cxusb_mygica_t230_frontend_attach(struct 
dvb_usb_adapter *adap)
return 0;
 }
 
-static int cxusb_mygica_t230c_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(_config, 0, sizeof(si2168_config));
-   si2168_config.i2c_adapter = 
-   si2168_config.fe = >fe_adap[0].fe;
-   si2168_config.ts_mode = SI2168_TS_PARALLEL;
-   si2168_config.ts_clock_inv = 1;
-   memset(, 0, sizeof(struct i2c_board_info));
-   strlcpy(info.type, "si2168", I2C_NAME_SIZE);
-   info.addr = 0x64;
-   info.platform_data = _config;
-   request_module(info.type);
-   client_demod = i2c_new_device(>i2c_adap, );
-   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;
-   }
-
-   /* attach tuner */
-   memset(_config, 0, sizeof(si2157_config));
-   si2157_config.fe = adap->fe_adap[0].fe;
-   memset(, 0, sizeof(struct i2c_board_info));
-   strlcpy(info.type, "si2141", I2C_NAME_SIZE);
-   info.addr = 0x60;
-   info.platform_data = _config;
-   request_module("si2157");
-   client_tuner = i2c_new_device(adapter, );
-   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_demod = client_demod;
-   st->i2c_client_tuner = client_tuner;
-
-   /* hook fe: need to resync the slave fifo when signal locks. */
-   mutex_init(>stream_mutex);
-   st->last_lock = 0;
-   st->fe_read_status = adap->fe_adap[0].fe->ops.read_status;
-   adap->fe_adap[0].fe->ops.read_status = cxusb_read_status;
-
-   return 0;
-}
-
 /*
  * DViCO has shipped two devices with the same USB ID, but only one of them
  * needs a firmware download.  Check the device class details to see if they
@@ -1397,7 +1321,6 @@ 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_mygica_t230c_properties;
 
 static int cxusb_probe(struct usb_interface *intf,
   const struct usb_device_id *id)
@@ -1430,8 +1353,6 @@ static int cxusb_probe(struct usb_interface *intf,
 THIS_MODULE, NULL, adapter_nr) ||
0 == dvb_usb_device_init(intf, _mygica_t230_properties,
 THIS_MODULE, NULL, adapter_nr) ||
-   0 == dvb_usb_device_init(intf, _mygica_t230c_properties,
-THIS_MODULE, NULL, adapter_nr) ||
0)
return 0;
 
@@ -1483,7

[PATCH v1 0/2] Remove duplicate driver for MyGica T230C

2018-01-09 Thread Stefan Brüns

In 2017-02, two drivers for the T230C where submitted, but until now
only the one based on the older dvb-usb/cxusb.c driver has been part
of the mainline kernel. As a dvb-usb-v2 driver is preferable, remove
the other driver.

The cxusb.c patch also contained an unrelated change for the T230,
i.e. a correction of the RC model. As this change apparently is
correct, restore it. This has not been tested due to lack of hardware.


Evgeny Plehov (1):
  Revert "[media] dvb-usb-cxusb: Geniatech T230C support"

Stefan Brüns (1):
  [media] cxusb: restore RC_MAP for MyGica T230

 drivers/media/usb/dvb-usb/cxusb.c | 137 --
 1 file changed, 137 deletions(-)

-- 
2.15.1



[PATCH v3 1/3] [media] si2157: Add support for Si2141-A10

2017-02-16 Thread Stefan Brüns
The Si2141 needs two distinct commands for powerup/reset, otherwise it
will not respond to chip revision requests. It also needs a firmware
to run properly.

Signed-off-by: Stefan Brüns <stefan.bru...@rwth-aachen.de>
---
 drivers/media/tuners/si2157.c  | 23 +--
 drivers/media/tuners/si2157_priv.h |  2 ++
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index 57b250847cd3..e35b1faf0ddc 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -106,6 +106,9 @@ static int si2157_init(struct dvb_frontend *fe)
if (dev->chiptype == SI2157_CHIPTYPE_SI2146) {
memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9);
cmd.wlen = 9;
+   } else if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
+   memcpy(cmd.args, "\xc0\x00\x0d\x0e\x00\x01\x01\x01\x01\x03", 
10);
+   cmd.wlen = 10;
} else {
memcpy(cmd.args, 
"\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
cmd.wlen = 15;
@@ -115,6 +118,15 @@ static int si2157_init(struct dvb_frontend *fe)
if (ret)
goto err;
 
+   /* Si2141 needs a second command before it answers the revision query */
+   if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
+   memcpy(cmd.args, "\xc0\x08\x01\x02\x00\x00\x01", 7);
+   cmd.wlen = 7;
+   ret = si2157_cmd_execute(client, );
+   if (ret)
+   goto err;
+   }
+
/* query chip revision */
memcpy(cmd.args, "\x02", 1);
cmd.wlen = 1;
@@ -131,12 +143,16 @@ static int si2157_init(struct dvb_frontend *fe)
#define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
#define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0)
#define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
+   #define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
 
switch (chip_id) {
case SI2158_A20:
case SI2148_A20:
fw_name = SI2158_A20_FIRMWARE;
break;
+   case SI2141_A10:
+   fw_name = SI2141_A10_FIRMWARE;
+   break;
case SI2157_A30:
case SI2147_A30:
case SI2146_A10:
@@ -371,7 +387,7 @@ static int si2157_get_if_frequency(struct dvb_frontend *fe, 
u32 *frequency)
 
 static const struct dvb_tuner_ops si2157_ops = {
.info = {
-   .name   = "Silicon Labs Si2146/2147/2148/2157/2158",
+   .name   = "Silicon Labs 
Si2141/Si2146/2147/2148/2157/2158",
.frequency_min  = 4200,
.frequency_max  = 87000,
},
@@ -471,6 +487,7 @@ static int si2157_probe(struct i2c_client *client,
 #endif
 
dev_info(>dev, "Silicon Labs %s successfully attached\n",
+   dev->chiptype == SI2157_CHIPTYPE_SI2141 ?  "Si2141" :
dev->chiptype == SI2157_CHIPTYPE_SI2146 ?
"Si2146" : "Si2147/2148/2157/2158");
 
@@ -508,6 +525,7 @@ static int si2157_remove(struct i2c_client *client)
 static const struct i2c_device_id si2157_id_table[] = {
{"si2157", SI2157_CHIPTYPE_SI2157},
{"si2146", SI2157_CHIPTYPE_SI2146},
+   {"si2141", SI2157_CHIPTYPE_SI2141},
{}
 };
 MODULE_DEVICE_TABLE(i2c, si2157_id_table);
@@ -524,7 +542,8 @@ static struct i2c_driver si2157_driver = {
 
 module_i2c_driver(si2157_driver);
 
-MODULE_DESCRIPTION("Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner 
driver");
+MODULE_DESCRIPTION("Silicon Labs Si2141/Si2146/2147/2148/2157/2158 silicon 
tuner driver");
 MODULE_AUTHOR("Antti Palosaari <cr...@iki.fi>");
 MODULE_LICENSE("GPL");
 MODULE_FIRMWARE(SI2158_A20_FIRMWARE);
+MODULE_FIRMWARE(SI2141_A10_FIRMWARE);
diff --git a/drivers/media/tuners/si2157_priv.h 
b/drivers/media/tuners/si2157_priv.h
index d6b2c7b44053..e6436f74abaa 100644
--- a/drivers/media/tuners/si2157_priv.h
+++ b/drivers/media/tuners/si2157_priv.h
@@ -42,6 +42,7 @@ struct si2157_dev {
 
 #define SI2157_CHIPTYPE_SI2157 0
 #define SI2157_CHIPTYPE_SI2146 1
+#define SI2157_CHIPTYPE_SI2141 2
 
 /* firmware command struct */
 #define SI2157_ARGLEN  30
@@ -52,5 +53,6 @@ struct si2157_cmd {
 };
 
 #define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"
+#define SI2141_A10_FIRMWARE "dvb-tuner-si2141-a10-01.fw"
 
 #endif
-- 
2.11.0



[PATCH v3 3/3] [media] dvbsky: MyGica T230C support

2017-02-16 Thread Stefan Brüns
Mygica T230 DVB-T/T2/C USB stick support. It uses the same FX2/Si2168
bridge/demodulator combo as the other devices supported by the driver,
but uses the Si2141 tuner.
Several DVB-T (MPEG2) and DVB-T2 (H.265) channels were tested, as well as
the included remote control.

Signed-off-by: Stefan Brüns <stefan.bru...@rwth-aachen.de>
---
v2: add support to the dvbsky driver instead of cxusb, correct RC
model
v3: fixed coding style issues, use name as printed on box for id table
---
 drivers/media/dvb-core/dvb-usb-ids.h  |  1 +
 drivers/media/usb/dvb-usb-v2/dvbsky.c | 88 +++
 2 files changed, 89 insertions(+)

diff --git a/drivers/media/dvb-core/dvb-usb-ids.h 
b/drivers/media/dvb-core/dvb-usb-ids.h
index a7a4674ccc40..ce4a3d574dd7 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
@@ -380,6 +380,7 @@
 #define USB_PID_SONY_PLAYTV0x0003
 #define USB_PID_MYGICA_D6890xd811
 #define USB_PID_MYGICA_T2300xc688
+#define USB_PID_MYGICA_T230C   0xc689
 #define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011
 #define USB_PID_ELGATO_EYETV_DTT   0x0021
 #define USB_PID_ELGATO_EYETV_DTT_2 0x003f
diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c 
b/drivers/media/usb/dvb-usb-v2/dvbsky.c
index 02dbc6c45423..f98225767712 100644
--- a/drivers/media/usb/dvb-usb-v2/dvbsky.c
+++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c
@@ -665,6 +665,65 @@ static int dvbsky_t330_attach(struct dvb_usb_adapter *adap)
return ret;
 }
 
+static int dvbsky_mygica_t230c_attach(struct dvb_usb_adapter *adap)
+{
+   struct dvbsky_state *state = adap_to_priv(adap);
+   struct dvb_usb_device *d = adap_to_d(adap);
+   struct i2c_adapter *i2c_adapter;
+   struct i2c_client *client_demod, *client_tuner;
+   struct i2c_board_info info;
+   struct si2168_config si2168_config;
+   struct si2157_config si2157_config;
+
+   /* attach demod */
+   memset(_config, 0, sizeof(si2168_config));
+   si2168_config.i2c_adapter = _adapter;
+   si2168_config.fe = >fe[0];
+   si2168_config.ts_mode = SI2168_TS_PARALLEL;
+   si2168_config.ts_clock_inv = 1;
+   memset(, 0, sizeof(struct i2c_board_info));
+   strlcpy(info.type, "si2168", sizeof(info.type));
+   info.addr = 0x64;
+   info.platform_data = _config;
+
+   request_module("si2168");
+   client_demod = i2c_new_device(>i2c_adap, );
+   if (!client_demod || !client_demod->dev.driver)
+   goto fail_demod_device;
+   if (!try_module_get(client_demod->dev.driver->owner))
+   goto fail_demod_module;
+
+   /* attach tuner */
+   memset(_config, 0, sizeof(si2157_config));
+   si2157_config.fe = adap->fe[0];
+   si2157_config.if_port = 0;
+   memset(, 0, sizeof(struct i2c_board_info));
+   strlcpy(info.type, "si2141", sizeof(info.type));
+   info.addr = 0x60;
+   info.platform_data = _config;
+
+   request_module("si2157");
+   client_tuner = i2c_new_device(i2c_adapter, );
+   if (!client_tuner || !client_tuner->dev.driver)
+   goto fail_tuner_device;
+   if (!try_module_get(client_tuner->dev.driver->owner))
+   goto fail_tuner_module;
+
+   state->i2c_client_demod = client_demod;
+   state->i2c_client_tuner = client_tuner;
+   return 0;
+
+fail_tuner_module:
+   i2c_unregister_device(client_tuner);
+fail_tuner_device:
+   module_put(client_demod->dev.driver->owner);
+fail_demod_module:
+   i2c_unregister_device(client_demod);
+fail_demod_device:
+   return -ENODEV;
+}
+
+
 static int dvbsky_identify_state(struct dvb_usb_device *d, const char **name)
 {
dvbsky_gpio_ctrl(d, 0x04, 1);
@@ -830,6 +889,32 @@ static struct dvb_usb_device_properties dvbsky_t330_props 
= {
}
 };
 
+static struct dvb_usb_device_properties mygica_t230c_props = {
+   .driver_name = KBUILD_MODNAME,
+   .owner = THIS_MODULE,
+   .adapter_nr = adapter_nr,
+   .size_of_priv = sizeof(struct dvbsky_state),
+
+   .generic_bulk_ctrl_endpoint = 0x01,
+   .generic_bulk_ctrl_endpoint_response = 0x81,
+   .generic_bulk_ctrl_delay = DVBSKY_MSG_DELAY,
+
+   .i2c_algo = _i2c_algo,
+   .frontend_attach  = dvbsky_mygica_t230c_attach,
+   .init = dvbsky_init,
+   .get_rc_config= dvbsky_get_rc_config,
+   .streaming_ctrl   = dvbsky_streaming_ctrl,
+   .identify_state   = dvbsky_identify_state,
+   .exit = dvbsky_exit,
+
+   .num_adapters = 1,
+   .adapter = {
+   {
+   .stream = DVB_USB_STREAM_BULK(0x82, 8, 4096),
+   }
+   }
+};
+
 static const struct usb_device_id dvbsky_id_table[] = {
  

[PATCH v3 0/3] Add support for MyGica T230C DVB-T2 stick

2017-02-16 Thread Stefan Brüns
The required command sequence for the new tuner (Si2141) was traced from the
current Windows driver and verified with a small python script/libusb.
The changes to the Si2168 and dvbsky driver are mostly additions of the
required IDs and some glue code.

Stefan Brüns (3):
  [media] si2157: Add support for Si2141-A10
  [media] si2168: add support for Si2168-D60
  [media] dvbsky: MyGica T230C support

 drivers/media/dvb-core/dvb-usb-ids.h  |  1 +
 drivers/media/dvb-frontends/si2168.c  |  4 ++
 drivers/media/dvb-frontends/si2168_priv.h |  2 +
 drivers/media/tuners/si2157.c | 23 +++-
 drivers/media/tuners/si2157_priv.h|  2 +
 drivers/media/usb/dvb-usb-v2/dvbsky.c | 88 +++
 6 files changed, 118 insertions(+), 2 deletions(-)

-- 
2.11.0



[PATCH v3 2/3] [media] si2168: add support for Si2168-D60

2017-02-16 Thread Stefan Brüns
Add handling for new revision, requiring new firmware.

Signed-off-by: Stefan Brüns <stefan.bru...@rwth-aachen.de>
---
 drivers/media/dvb-frontends/si2168.c  | 4 
 drivers/media/dvb-frontends/si2168_priv.h | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/drivers/media/dvb-frontends/si2168.c 
b/drivers/media/dvb-frontends/si2168.c
index 20b4a659e2e4..28f3bbe0af25 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -674,6 +674,9 @@ static int si2168_probe(struct i2c_client *client,
case SI2168_CHIP_ID_B40:
dev->firmware_name = SI2168_B40_FIRMWARE;
break;
+   case SI2168_CHIP_ID_D60:
+   dev->firmware_name = SI2168_D60_FIRMWARE;
+   break;
default:
dev_dbg(>dev, "unknown chip version Si21%d-%c%c%c\n",
cmd.args[2], cmd.args[1], cmd.args[3], cmd.args[4]);
@@ -761,3 +764,4 @@ MODULE_LICENSE("GPL");
 MODULE_FIRMWARE(SI2168_A20_FIRMWARE);
 MODULE_FIRMWARE(SI2168_A30_FIRMWARE);
 MODULE_FIRMWARE(SI2168_B40_FIRMWARE);
+MODULE_FIRMWARE(SI2168_D60_FIRMWARE);
diff --git a/drivers/media/dvb-frontends/si2168_priv.h 
b/drivers/media/dvb-frontends/si2168_priv.h
index 7843ccb448a0..4baa95b7d648 100644
--- a/drivers/media/dvb-frontends/si2168_priv.h
+++ b/drivers/media/dvb-frontends/si2168_priv.h
@@ -25,6 +25,7 @@
 #define SI2168_A20_FIRMWARE "dvb-demod-si2168-a20-01.fw"
 #define SI2168_A30_FIRMWARE "dvb-demod-si2168-a30-01.fw"
 #define SI2168_B40_FIRMWARE "dvb-demod-si2168-b40-01.fw"
+#define SI2168_D60_FIRMWARE "dvb-demod-si2168-d60-01.fw"
 #define SI2168_B40_FIRMWARE_FALLBACK "dvb-demod-si2168-02.fw"
 
 /* state struct */
@@ -37,6 +38,7 @@ struct si2168_dev {
#define SI2168_CHIP_ID_A20 ('A' << 24 | 68 << 16 | '2' << 8 | '0' << 0)
#define SI2168_CHIP_ID_A30 ('A' << 24 | 68 << 16 | '3' << 8 | '0' << 0)
#define SI2168_CHIP_ID_B40 ('B' << 24 | 68 << 16 | '4' << 8 | '0' << 0)
+   #define SI2168_CHIP_ID_D60 ('D' << 24 | 68 << 16 | '6' << 8 | '0' << 0)
unsigned int chip_id;
unsigned int version;
const char *firmware_name;
-- 
2.11.0



[PATCH v2 1/3] [media] si2157: Add support for Si2141-A10

2017-02-14 Thread Stefan Brüns
The Si2141 needs two distinct commands for powerup/reset, otherwise it
will not respond to chip revision requests. It also needs a firmware
to run properly.

Signed-off-by: Stefan Brüns <stefan.bru...@rwth-aachen.de>
---
 drivers/media/tuners/si2157.c  | 23 +--
 drivers/media/tuners/si2157_priv.h |  2 ++
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index 57b250847cd3..e35b1faf0ddc 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -106,6 +106,9 @@ static int si2157_init(struct dvb_frontend *fe)
if (dev->chiptype == SI2157_CHIPTYPE_SI2146) {
memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9);
cmd.wlen = 9;
+   } else if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
+   memcpy(cmd.args, "\xc0\x00\x0d\x0e\x00\x01\x01\x01\x01\x03", 
10);
+   cmd.wlen = 10;
} else {
memcpy(cmd.args, 
"\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
cmd.wlen = 15;
@@ -115,6 +118,15 @@ static int si2157_init(struct dvb_frontend *fe)
if (ret)
goto err;
 
+   /* Si2141 needs a second command before it answers the revision query */
+   if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
+   memcpy(cmd.args, "\xc0\x08\x01\x02\x00\x00\x01", 7);
+   cmd.wlen = 7;
+   ret = si2157_cmd_execute(client, );
+   if (ret)
+   goto err;
+   }
+
/* query chip revision */
memcpy(cmd.args, "\x02", 1);
cmd.wlen = 1;
@@ -131,12 +143,16 @@ static int si2157_init(struct dvb_frontend *fe)
#define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
#define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0)
#define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
+   #define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
 
switch (chip_id) {
case SI2158_A20:
case SI2148_A20:
fw_name = SI2158_A20_FIRMWARE;
break;
+   case SI2141_A10:
+   fw_name = SI2141_A10_FIRMWARE;
+   break;
case SI2157_A30:
case SI2147_A30:
case SI2146_A10:
@@ -371,7 +387,7 @@ static int si2157_get_if_frequency(struct dvb_frontend *fe, 
u32 *frequency)
 
 static const struct dvb_tuner_ops si2157_ops = {
.info = {
-   .name   = "Silicon Labs Si2146/2147/2148/2157/2158",
+   .name   = "Silicon Labs 
Si2141/Si2146/2147/2148/2157/2158",
.frequency_min  = 4200,
.frequency_max  = 87000,
},
@@ -471,6 +487,7 @@ static int si2157_probe(struct i2c_client *client,
 #endif
 
dev_info(>dev, "Silicon Labs %s successfully attached\n",
+   dev->chiptype == SI2157_CHIPTYPE_SI2141 ?  "Si2141" :
dev->chiptype == SI2157_CHIPTYPE_SI2146 ?
"Si2146" : "Si2147/2148/2157/2158");
 
@@ -508,6 +525,7 @@ static int si2157_remove(struct i2c_client *client)
 static const struct i2c_device_id si2157_id_table[] = {
{"si2157", SI2157_CHIPTYPE_SI2157},
{"si2146", SI2157_CHIPTYPE_SI2146},
+   {"si2141", SI2157_CHIPTYPE_SI2141},
{}
 };
 MODULE_DEVICE_TABLE(i2c, si2157_id_table);
@@ -524,7 +542,8 @@ static struct i2c_driver si2157_driver = {
 
 module_i2c_driver(si2157_driver);
 
-MODULE_DESCRIPTION("Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner 
driver");
+MODULE_DESCRIPTION("Silicon Labs Si2141/Si2146/2147/2148/2157/2158 silicon 
tuner driver");
 MODULE_AUTHOR("Antti Palosaari <cr...@iki.fi>");
 MODULE_LICENSE("GPL");
 MODULE_FIRMWARE(SI2158_A20_FIRMWARE);
+MODULE_FIRMWARE(SI2141_A10_FIRMWARE);
diff --git a/drivers/media/tuners/si2157_priv.h 
b/drivers/media/tuners/si2157_priv.h
index d6b2c7b44053..e6436f74abaa 100644
--- a/drivers/media/tuners/si2157_priv.h
+++ b/drivers/media/tuners/si2157_priv.h
@@ -42,6 +42,7 @@ struct si2157_dev {
 
 #define SI2157_CHIPTYPE_SI2157 0
 #define SI2157_CHIPTYPE_SI2146 1
+#define SI2157_CHIPTYPE_SI2141 2
 
 /* firmware command struct */
 #define SI2157_ARGLEN  30
@@ -52,5 +53,6 @@ struct si2157_cmd {
 };
 
 #define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"
+#define SI2141_A10_FIRMWARE "dvb-tuner-si2141-a10-01.fw"
 
 #endif
-- 
2.11.0



[PATCH v2 3/3] [media] dvbsky: MyGica T230C support

2017-02-14 Thread Stefan Brüns
Mygica T230 DVB-T/T2/C USB stick support. It uses the same FX2/Si2168
bridge/demodulator combo as the other devices supported by the driver,
but uses the Si2141 tuner.
Several DVB-T (MPEG2) and DVB-T2 (H.265) channels were tested, as well as
the include remote control.

Signed-off-by: Stefan Brüns <stefan.bru...@rwth-aachen.de>
---
v2: add support to the dvbsky driver instead of cxusb, correct RC
model
---
 drivers/media/dvb-core/dvb-usb-ids.h  |  1 +
 drivers/media/usb/dvb-usb-v2/dvbsky.c | 91 +++
 2 files changed, 92 insertions(+)

diff --git a/drivers/media/dvb-core/dvb-usb-ids.h 
b/drivers/media/dvb-core/dvb-usb-ids.h
index a7a4674ccc40..ce4a3d574dd7 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
@@ -380,6 +380,7 @@
 #define USB_PID_SONY_PLAYTV0x0003
 #define USB_PID_MYGICA_D6890xd811
 #define USB_PID_MYGICA_T2300xc688
+#define USB_PID_MYGICA_T230C   0xc689
 #define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011
 #define USB_PID_ELGATO_EYETV_DTT   0x0021
 #define USB_PID_ELGATO_EYETV_DTT_2 0x003f
diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c 
b/drivers/media/usb/dvb-usb-v2/dvbsky.c
index 02dbc6c45423..729496e5a52e 100644
--- a/drivers/media/usb/dvb-usb-v2/dvbsky.c
+++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c
@@ -665,6 +665,68 @@ static int dvbsky_t330_attach(struct dvb_usb_adapter *adap)
return ret;
 }
 
+static int dvbsky_mygica_t230c_attach(struct dvb_usb_adapter *adap)
+{
+   struct dvbsky_state *state = adap_to_priv(adap);
+   struct dvb_usb_device *d = adap_to_d(adap);
+   int ret = 0;
+   struct i2c_adapter *i2c_adapter;
+   struct i2c_client *client_demod, *client_tuner;
+   struct i2c_board_info info;
+   struct si2168_config si2168_config;
+   struct si2157_config si2157_config;
+
+   /* attach demod */
+   memset(_config, 0, sizeof(si2168_config));
+   si2168_config.i2c_adapter = _adapter;
+   si2168_config.fe = >fe[0];
+   si2168_config.ts_mode = SI2168_TS_PARALLEL;
+   si2168_config.ts_clock_inv = 1;
+   memset(, 0, sizeof(struct i2c_board_info));
+   strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+   info.addr = 0x64;
+   info.platform_data = _config;
+
+   request_module(info.type);
+   client_demod = i2c_new_device(>i2c_adap, );
+   if (client_demod == NULL ||
+   client_demod->dev.driver == NULL)
+   goto fail_demod_device;
+   if (!try_module_get(client_demod->dev.driver->owner))
+   goto fail_demod_module;
+
+   /* attach tuner */
+   memset(_config, 0, sizeof(si2157_config));
+   si2157_config.fe = adap->fe[0];
+   si2157_config.if_port = 0;
+   memset(, 0, sizeof(struct i2c_board_info));
+   strlcpy(info.type, "si2141", I2C_NAME_SIZE);
+   info.addr = 0x60;
+   info.platform_data = _config;
+
+   request_module("si2157");
+   client_tuner = i2c_new_device(i2c_adapter, );
+   if (client_tuner == NULL ||
+   client_tuner->dev.driver == NULL)
+   goto fail_tuner_device;
+   if (!try_module_get(client_tuner->dev.driver->owner))
+   goto fail_tuner_module;
+
+   state->i2c_client_demod = client_demod;
+   state->i2c_client_tuner = client_tuner;
+   return ret;
+fail_tuner_module:
+   i2c_unregister_device(client_tuner);
+fail_tuner_device:
+   module_put(client_demod->dev.driver->owner);
+fail_demod_module:
+   i2c_unregister_device(client_demod);
+fail_demod_device:
+   ret = -ENODEV;
+   return ret;
+}
+
+
 static int dvbsky_identify_state(struct dvb_usb_device *d, const char **name)
 {
dvbsky_gpio_ctrl(d, 0x04, 1);
@@ -830,6 +892,32 @@ static struct dvb_usb_device_properties dvbsky_t330_props 
= {
}
 };
 
+static struct dvb_usb_device_properties mygica_t230c_props = {
+   .driver_name = KBUILD_MODNAME,
+   .owner = THIS_MODULE,
+   .adapter_nr = adapter_nr,
+   .size_of_priv = sizeof(struct dvbsky_state),
+
+   .generic_bulk_ctrl_endpoint = 0x01,
+   .generic_bulk_ctrl_endpoint_response = 0x81,
+   .generic_bulk_ctrl_delay = DVBSKY_MSG_DELAY,
+
+   .i2c_algo = _i2c_algo,
+   .frontend_attach  = dvbsky_mygica_t230c_attach,
+   .init = dvbsky_init,
+   .get_rc_config= dvbsky_get_rc_config,
+   .streaming_ctrl   = dvbsky_streaming_ctrl,
+   .identify_state   = dvbsky_identify_state,
+   .exit = dvbsky_exit,
+
+   .num_adapters = 1,
+   .adapter = {
+   {
+   .stream = DVB_USB_STREAM_BULK(0x82, 8, 4096),
+   }
+   }
+};
+
 static const struct 

[PATCH v2 2/3] [media] si2168: add support for Si2168-D60

2017-02-14 Thread Stefan Brüns
Add handling for new revision, requiring new firmware.

Signed-off-by: Stefan Brüns <stefan.bru...@rwth-aachen.de>
---
 drivers/media/dvb-frontends/si2168.c  | 4 
 drivers/media/dvb-frontends/si2168_priv.h | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/drivers/media/dvb-frontends/si2168.c 
b/drivers/media/dvb-frontends/si2168.c
index 20b4a659e2e4..28f3bbe0af25 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -674,6 +674,9 @@ static int si2168_probe(struct i2c_client *client,
case SI2168_CHIP_ID_B40:
dev->firmware_name = SI2168_B40_FIRMWARE;
break;
+   case SI2168_CHIP_ID_D60:
+   dev->firmware_name = SI2168_D60_FIRMWARE;
+   break;
default:
dev_dbg(>dev, "unknown chip version Si21%d-%c%c%c\n",
cmd.args[2], cmd.args[1], cmd.args[3], cmd.args[4]);
@@ -761,3 +764,4 @@ MODULE_LICENSE("GPL");
 MODULE_FIRMWARE(SI2168_A20_FIRMWARE);
 MODULE_FIRMWARE(SI2168_A30_FIRMWARE);
 MODULE_FIRMWARE(SI2168_B40_FIRMWARE);
+MODULE_FIRMWARE(SI2168_D60_FIRMWARE);
diff --git a/drivers/media/dvb-frontends/si2168_priv.h 
b/drivers/media/dvb-frontends/si2168_priv.h
index 7843ccb448a0..4baa95b7d648 100644
--- a/drivers/media/dvb-frontends/si2168_priv.h
+++ b/drivers/media/dvb-frontends/si2168_priv.h
@@ -25,6 +25,7 @@
 #define SI2168_A20_FIRMWARE "dvb-demod-si2168-a20-01.fw"
 #define SI2168_A30_FIRMWARE "dvb-demod-si2168-a30-01.fw"
 #define SI2168_B40_FIRMWARE "dvb-demod-si2168-b40-01.fw"
+#define SI2168_D60_FIRMWARE "dvb-demod-si2168-d60-01.fw"
 #define SI2168_B40_FIRMWARE_FALLBACK "dvb-demod-si2168-02.fw"
 
 /* state struct */
@@ -37,6 +38,7 @@ struct si2168_dev {
#define SI2168_CHIP_ID_A20 ('A' << 24 | 68 << 16 | '2' << 8 | '0' << 0)
#define SI2168_CHIP_ID_A30 ('A' << 24 | 68 << 16 | '3' << 8 | '0' << 0)
#define SI2168_CHIP_ID_B40 ('B' << 24 | 68 << 16 | '4' << 8 | '0' << 0)
+   #define SI2168_CHIP_ID_D60 ('D' << 24 | 68 << 16 | '6' << 8 | '0' << 0)
unsigned int chip_id;
unsigned int version;
const char *firmware_name;
-- 
2.11.0



[PATCH v2 0/3] Add support for MyGica T230C DVB-T2 stick

2017-02-14 Thread Stefan Brüns
The required command sequence for the new tuner (Si2141) was traced from the
current Windows driver and verified with a small python script/libusb.
The changes to the Si2168 and dvbsky driver are mostly additions of the
required IDs and some glue code.

Stefan Brüns (3):
  [media] si2157: Add support for Si2141-A10
  [media] si2168: add support for Si2168-D60
  [media] dvbsky: MyGica T230C support

 drivers/media/dvb-core/dvb-usb-ids.h  |  1 +
 drivers/media/dvb-frontends/si2168.c  |  4 ++
 drivers/media/dvb-frontends/si2168_priv.h |  2 +
 drivers/media/tuners/si2157.c | 23 +++-
 drivers/media/tuners/si2157_priv.h|  2 +
 drivers/media/usb/dvb-usb-v2/dvbsky.c | 91 +++
 6 files changed, 121 insertions(+), 2 deletions(-)

-- 
2.11.0



[PATCH 3/3] [media] cxusb: MyGica T230C support

2017-02-12 Thread Stefan Brüns
Mygica T230 DVB-T/T2/C USB stick support. It uses the same FX2/Si2168
bridge/demodulator combo as the T230, but uses the Si2141 tuner.
Factor out the common code and pass the tuner type and if port as
parameter, to avoid duplicating the initialization code.

Signed-off-by: Stefan Brüns <stefan.bru...@rwth-aachen.de>
---
 drivers/media/dvb-core/dvb-usb-ids.h |  1 +
 drivers/media/usb/dvb-usb/cxusb.c| 80 ++--
 2 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/drivers/media/dvb-core/dvb-usb-ids.h 
b/drivers/media/dvb-core/dvb-usb-ids.h
index a7a4674ccc40..ce4a3d574dd7 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
@@ -380,6 +380,7 @@
 #define USB_PID_SONY_PLAYTV0x0003
 #define USB_PID_MYGICA_D6890xd811
 #define USB_PID_MYGICA_T2300xc688
+#define USB_PID_MYGICA_T230C   0xc689
 #define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011
 #define USB_PID_ELGATO_EYETV_DTT   0x0021
 #define USB_PID_ELGATO_EYETV_DTT_2 0x003f
diff --git a/drivers/media/usb/dvb-usb/cxusb.c 
b/drivers/media/usb/dvb-usb/cxusb.c
index 9fd43a37154c..967f4f74309c 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -1305,7 +1305,9 @@ static int cxusb_mygica_d689_frontend_attach(struct 
dvb_usb_adapter *adap)
return 0;
 }
 
-static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap)
+static int cxusb_mygica_t230_common_frontend_attach(struct dvb_usb_adapter 
*adap,
+   const char *tuner_name,
+   u8 tuner_if_port)
 {
struct dvb_usb_device *d = adap->dev;
struct cxusb_state *st = d->priv;
@@ -1352,12 +1354,12 @@ static int cxusb_mygica_t230_frontend_attach(struct 
dvb_usb_adapter *adap)
/* attach tuner */
memset(_config, 0, sizeof(si2157_config));
si2157_config.fe = adap->fe_adap[0].fe;
-   si2157_config.if_port = 1;
+   si2157_config.if_port = tuner_if_port;
memset(, 0, sizeof(struct i2c_board_info));
-   strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+   strlcpy(info.type, tuner_name, I2C_NAME_SIZE);
info.addr = 0x60;
info.platform_data = _config;
-   request_module(info.type);
+   request_module("si2157");
client_tuner = i2c_new_device(adapter, );
if (client_tuner == NULL || client_tuner->dev.driver == NULL) {
module_put(client_demod->dev.driver->owner);
@@ -1376,6 +1378,16 @@ static int cxusb_mygica_t230_frontend_attach(struct 
dvb_usb_adapter *adap)
return 0;
 }
 
+static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap)
+{
+   return cxusb_mygica_t230_common_frontend_attach(adap, "si2157", 1);
+}
+
+static int cxusb_mygica_t230c_frontend_attach(struct dvb_usb_adapter *adap)
+{
+   return cxusb_mygica_t230_common_frontend_attach(adap, "si2141", 0);
+}
+
 /*
  * DViCO has shipped two devices with the same USB ID, but only one of them
  * needs a firmware download.  Check the device class details to see if they
@@ -1458,6 +1470,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_mygica_t230c_properties;
 
 static int cxusb_probe(struct usb_interface *intf,
   const struct usb_device_id *id)
@@ -1490,6 +1503,8 @@ static int cxusb_probe(struct usb_interface *intf,
 THIS_MODULE, NULL, adapter_nr) ||
0 == dvb_usb_device_init(intf, _mygica_t230_properties,
 THIS_MODULE, NULL, adapter_nr) ||
+   0 == dvb_usb_device_init(intf, _mygica_t230c_properties,
+THIS_MODULE, NULL, adapter_nr) ||
0)
return 0;
 
@@ -1541,6 +1556,7 @@ enum cxusb_table_index {
CONEXANT_D680_DMB,
MYGICA_D689,
MYGICA_T230,
+   MYGICA_T230C,
NR__cxusb_table_index
 };
 
@@ -1608,6 +1624,9 @@ static struct usb_device_id 
cxusb_table[NR__cxusb_table_index + 1] = {
[MYGICA_T230] = {
USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230)
},
+   [MYGICA_T230C] = {
+   USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C)
+   },
{}  /* Terminating entry */
 };
 MODULE_DEVICE_TABLE (usb, cxusb_table);
@@ -2307,6 +2326,59 @@ static struct dvb_usb_device_properties 
cxusb_mygica_t230_properties = {
}
 };
 
+stati

[PATCH 0/3] Add support for MyGica T230C DVB-T2 stick

2017-02-12 Thread Stefan Brüns
The required command sequence for the new tuner (Si2141) was traced from the
current Windows driver and verified with a small python script/libusb.
The changes to the Si2168 and cxusb driver are mostly addition of the
required IDs and some glue code.

Stefan Brüns (3):
  [media] si2157: Add support for Si2141-A10
  [media] si2168: add support for Si2168-D60
  [media] cxusb: MyGica T230C support

 drivers/media/dvb-core/dvb-usb-ids.h  |  1 +
 drivers/media/dvb-frontends/si2168.c  |  4 ++
 drivers/media/dvb-frontends/si2168_priv.h |  2 +
 drivers/media/tuners/si2157.c | 23 -
 drivers/media/tuners/si2157_priv.h|  2 +
 drivers/media/usb/dvb-usb/cxusb.c | 80 +--
 6 files changed, 106 insertions(+), 6 deletions(-)

-- 
2.11.0



[PATCH 1/3] [media] si2157: Add support for Si2141-A10

2017-02-12 Thread Stefan Brüns
The Si2141 needs two distinct commands for powerup/reset, otherwise it
will not respond to chip revision requests. It also needs a firmware
to run properly.

Signed-off-by: Stefan Brüns <stefan.bru...@rwth-aachen.de>
---
 drivers/media/tuners/si2157.c  | 23 +--
 drivers/media/tuners/si2157_priv.h |  2 ++
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index 57b250847cd3..e35b1faf0ddc 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -106,6 +106,9 @@ static int si2157_init(struct dvb_frontend *fe)
if (dev->chiptype == SI2157_CHIPTYPE_SI2146) {
memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9);
cmd.wlen = 9;
+   } else if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
+   memcpy(cmd.args, "\xc0\x00\x0d\x0e\x00\x01\x01\x01\x01\x03", 
10);
+   cmd.wlen = 10;
} else {
memcpy(cmd.args, 
"\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
cmd.wlen = 15;
@@ -115,6 +118,15 @@ static int si2157_init(struct dvb_frontend *fe)
if (ret)
goto err;
 
+   /* Si2141 needs a second command before it answers the revision query */
+   if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
+   memcpy(cmd.args, "\xc0\x08\x01\x02\x00\x00\x01", 7);
+   cmd.wlen = 7;
+   ret = si2157_cmd_execute(client, );
+   if (ret)
+   goto err;
+   }
+
/* query chip revision */
memcpy(cmd.args, "\x02", 1);
cmd.wlen = 1;
@@ -131,12 +143,16 @@ static int si2157_init(struct dvb_frontend *fe)
#define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
#define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0)
#define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
+   #define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
 
switch (chip_id) {
case SI2158_A20:
case SI2148_A20:
fw_name = SI2158_A20_FIRMWARE;
break;
+   case SI2141_A10:
+   fw_name = SI2141_A10_FIRMWARE;
+   break;
case SI2157_A30:
case SI2147_A30:
case SI2146_A10:
@@ -371,7 +387,7 @@ static int si2157_get_if_frequency(struct dvb_frontend *fe, 
u32 *frequency)
 
 static const struct dvb_tuner_ops si2157_ops = {
.info = {
-   .name   = "Silicon Labs Si2146/2147/2148/2157/2158",
+   .name   = "Silicon Labs 
Si2141/Si2146/2147/2148/2157/2158",
.frequency_min  = 4200,
.frequency_max  = 87000,
},
@@ -471,6 +487,7 @@ static int si2157_probe(struct i2c_client *client,
 #endif
 
dev_info(>dev, "Silicon Labs %s successfully attached\n",
+   dev->chiptype == SI2157_CHIPTYPE_SI2141 ?  "Si2141" :
dev->chiptype == SI2157_CHIPTYPE_SI2146 ?
"Si2146" : "Si2147/2148/2157/2158");
 
@@ -508,6 +525,7 @@ static int si2157_remove(struct i2c_client *client)
 static const struct i2c_device_id si2157_id_table[] = {
{"si2157", SI2157_CHIPTYPE_SI2157},
{"si2146", SI2157_CHIPTYPE_SI2146},
+   {"si2141", SI2157_CHIPTYPE_SI2141},
{}
 };
 MODULE_DEVICE_TABLE(i2c, si2157_id_table);
@@ -524,7 +542,8 @@ static struct i2c_driver si2157_driver = {
 
 module_i2c_driver(si2157_driver);
 
-MODULE_DESCRIPTION("Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner 
driver");
+MODULE_DESCRIPTION("Silicon Labs Si2141/Si2146/2147/2148/2157/2158 silicon 
tuner driver");
 MODULE_AUTHOR("Antti Palosaari <cr...@iki.fi>");
 MODULE_LICENSE("GPL");
 MODULE_FIRMWARE(SI2158_A20_FIRMWARE);
+MODULE_FIRMWARE(SI2141_A10_FIRMWARE);
diff --git a/drivers/media/tuners/si2157_priv.h 
b/drivers/media/tuners/si2157_priv.h
index d6b2c7b44053..e6436f74abaa 100644
--- a/drivers/media/tuners/si2157_priv.h
+++ b/drivers/media/tuners/si2157_priv.h
@@ -42,6 +42,7 @@ struct si2157_dev {
 
 #define SI2157_CHIPTYPE_SI2157 0
 #define SI2157_CHIPTYPE_SI2146 1
+#define SI2157_CHIPTYPE_SI2141 2
 
 /* firmware command struct */
 #define SI2157_ARGLEN  30
@@ -52,5 +53,6 @@ struct si2157_cmd {
 };
 
 #define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"
+#define SI2141_A10_FIRMWARE "dvb-tuner-si2141-a10-01.fw"
 
 #endif
-- 
2.11.0



[PATCH 2/3] [media] si2168: add support for Si2168-D60

2017-02-12 Thread Stefan Brüns
Add handling for new revision, requiring new firmware.

Signed-off-by: Stefan Brüns <stefan.bru...@rwth-aachen.de>
---
 drivers/media/dvb-frontends/si2168.c  | 4 
 drivers/media/dvb-frontends/si2168_priv.h | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/drivers/media/dvb-frontends/si2168.c 
b/drivers/media/dvb-frontends/si2168.c
index 20b4a659e2e4..28f3bbe0af25 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -674,6 +674,9 @@ static int si2168_probe(struct i2c_client *client,
case SI2168_CHIP_ID_B40:
dev->firmware_name = SI2168_B40_FIRMWARE;
break;
+   case SI2168_CHIP_ID_D60:
+   dev->firmware_name = SI2168_D60_FIRMWARE;
+   break;
default:
dev_dbg(>dev, "unknown chip version Si21%d-%c%c%c\n",
cmd.args[2], cmd.args[1], cmd.args[3], cmd.args[4]);
@@ -761,3 +764,4 @@ MODULE_LICENSE("GPL");
 MODULE_FIRMWARE(SI2168_A20_FIRMWARE);
 MODULE_FIRMWARE(SI2168_A30_FIRMWARE);
 MODULE_FIRMWARE(SI2168_B40_FIRMWARE);
+MODULE_FIRMWARE(SI2168_D60_FIRMWARE);
diff --git a/drivers/media/dvb-frontends/si2168_priv.h 
b/drivers/media/dvb-frontends/si2168_priv.h
index 7843ccb448a0..4baa95b7d648 100644
--- a/drivers/media/dvb-frontends/si2168_priv.h
+++ b/drivers/media/dvb-frontends/si2168_priv.h
@@ -25,6 +25,7 @@
 #define SI2168_A20_FIRMWARE "dvb-demod-si2168-a20-01.fw"
 #define SI2168_A30_FIRMWARE "dvb-demod-si2168-a30-01.fw"
 #define SI2168_B40_FIRMWARE "dvb-demod-si2168-b40-01.fw"
+#define SI2168_D60_FIRMWARE "dvb-demod-si2168-d60-01.fw"
 #define SI2168_B40_FIRMWARE_FALLBACK "dvb-demod-si2168-02.fw"
 
 /* state struct */
@@ -37,6 +38,7 @@ struct si2168_dev {
#define SI2168_CHIP_ID_A20 ('A' << 24 | 68 << 16 | '2' << 8 | '0' << 0)
#define SI2168_CHIP_ID_A30 ('A' << 24 | 68 << 16 | '3' << 8 | '0' << 0)
#define SI2168_CHIP_ID_B40 ('B' << 24 | 68 << 16 | '4' << 8 | '0' << 0)
+   #define SI2168_CHIP_ID_D60 ('D' << 24 | 68 << 16 | '6' << 8 | '0' << 0)
unsigned int chip_id;
unsigned int version;
const char *firmware_name;
-- 
2.11.0



[PATCH v2] [media] dvb-usb-firmware: don't do DMA on stack

2017-02-12 Thread Stefan Brüns
The buffer allocation for the firmware data was changed in
commit 43fab9793c1f ("dvb-usb: don't use stack for firmware load"),
but the same applies for the reset value.

Signed-off-by: Stefan Brüns <stefan.bru...@rwth-aachen.de>
---
This patch replaces the earlier submission conflicting with commit
43fab9793c1f, which was a subset of the submitted patch.

 drivers/media/usb/dvb-usb/dvb-usb-firmware.c | 21 -
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c 
b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
index 3271b3fee1f4..1f008f354282 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
@@ -36,16 +36,19 @@ static int usb_cypress_writemem(struct usb_device *udev,u16 
addr,u8 *data, u8 le
 int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware 
*fw, int type)
 {
struct hexline *hx;
-   u8 reset;
+   u8 *buf;
+   u8 *reset;
int ret,pos=0;
+   u16 cpu_cs_register = cypress[type].cpu_cs_register;
 
-   hx = kmalloc(sizeof(*hx), GFP_KERNEL);
-   if (!hx)
+   buf = kmalloc(sizeof(*hx), GFP_KERNEL);
+   if (!buf)
return -ENOMEM;
+   hx = (struct hexline *)buf;
 
/* stop the CPU */
-   reset = 1;
-   if ((ret = 
usb_cypress_writemem(udev,cypress[type].cpu_cs_register,,1)) != 1)
+   buf[0] = 1;
+   if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1)
err("could not stop the USB controller CPU.");
 
while ((ret = dvb_usb_get_hexline(fw, hx, )) > 0) {
@@ -61,21 +64,21 @@ int usb_cypress_load_firmware(struct usb_device *udev, 
const struct firmware *fw
}
if (ret < 0) {
err("firmware download failed at %d with %d",pos,ret);
-   kfree(hx);
+   kfree(buf);
return ret;
}
 
if (ret == 0) {
/* restart the CPU */
-   reset = 0;
-   if (ret || 
usb_cypress_writemem(udev,cypress[type].cpu_cs_register,,1) != 1) {
+   buf[0] = 0;
+   if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1) {
err("could not restart the USB controller CPU.");
ret = -EINVAL;
}
} else
ret = -EIO;
 
-   kfree(hx);
+   kfree(buf);
 
return ret;
 }
-- 
2.11.0



[PATCH 2/2] [media] dvb-usb-firmware: don't do DMA on stack

2017-02-05 Thread Stefan Brüns
The USB control messages require DMA to work. We cannot pass
a stack-allocated buffer, as it is not warranted that the
stack would be into a DMA enabled area.

Signed-off-by: Stefan Brüns <stefan.bru...@rwth-aachen.de>
---
 drivers/media/usb/dvb-usb/dvb-usb-firmware.c | 30 
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c 
b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
index dd048a7c461c..189b6725edd0 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
@@ -35,41 +35,45 @@ static int usb_cypress_writemem(struct usb_device *udev,u16 
addr,u8 *data, u8 le
 
 int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware 
*fw, int type)
 {
-   struct hexline hx;
-   u8 reset;
-   int ret,pos=0;
+   u8 *buf = kmalloc(sizeof(struct hexline), GFP_KERNEL);
+   struct hexline *hx = (struct hexline *)buf;
+   int ret, pos = 0;
+   u16 cpu_cs_register = cypress[type].cpu_cs_register;
 
/* stop the CPU */
-   reset = 1;
-   if ((ret = 
usb_cypress_writemem(udev,cypress[type].cpu_cs_register,,1)) != 1)
+   buf[0] = 1;
+   if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1)
err("could not stop the USB controller CPU.");
 
-   while ((ret = dvb_usb_get_hexline(fw,,)) > 0) {
-   deb_fw("writing to address 0x%04x (buffer: 0x%02x 
%02x)\n",hx.addr,hx.len,hx.chk);
-   ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len);
+   while ((ret = dvb_usb_get_hexline(fw, hx, )) > 0) {
+   deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",
+  hx->addr, hx->len, hx->chk);
+   ret = usb_cypress_writemem(udev, hx->addr, hx->data, hx->len);
 
-   if (ret != hx.len) {
+   if (ret != hx->len) {
err("error while transferring firmware "
"(transferred size: %d, block size: %d)",
-   ret,hx.len);
+   ret, hx->len);
ret = -EINVAL;
break;
}
}
if (ret < 0) {
-   err("firmware download failed at %d with %d",pos,ret);
+   err("firmware download failed at %d with %d", pos, ret);
+   kfree(buf);
return ret;
}
 
if (ret == 0) {
/* restart the CPU */
-   reset = 0;
-   if (ret || 
usb_cypress_writemem(udev,cypress[type].cpu_cs_register,,1) != 1) {
+   buf[0] = 0;
+   if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1) {
err("could not restart the USB controller CPU.");
ret = -EINVAL;
}
} else
ret = -EIO;
+   kfree(buf);
 
return ret;
 }
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] [media] cxusb: Use a dma capable buffer also for reading

2017-02-05 Thread Stefan Brüns
Commit 17ce039b4e54 ("[media] cxusb: don't do DMA on stack")
added a kmalloc'ed bounce buffer for writes, but missed to do the same
for reads. As the read only happens after the write is finished, we can
reuse the same buffer.

As dvb_usb_generic_rw handles a read length of 0 by itself, avoid calling
it using the dvb_usb_generic_read wrapper function.

Signed-off-by: Stefan Brüns <stefan.bru...@rwth-aachen.de>
---
 drivers/media/usb/dvb-usb/cxusb.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/cxusb.c 
b/drivers/media/usb/dvb-usb/cxusb.c
index 9b8c82d94b3f..8f28a63597bd 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -59,23 +59,24 @@ static int cxusb_ctrl_msg(struct dvb_usb_device *d,
  u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
 {
struct cxusb_state *st = d->priv;
-   int ret, wo;
+   int ret;
 
if (1 + wlen > MAX_XFER_SIZE) {
warn("i2c wr: len=%d is too big!\n", wlen);
return -EOPNOTSUPP;
}
 
-   wo = (rbuf == NULL || rlen == 0); /* write-only */
+   if (rlen > MAX_XFER_SIZE) {
+   warn("i2c rd: len=%d is too big!\n", rlen);
+   return -EOPNOTSUPP;
+   }
 
mutex_lock(>data_mutex);
st->data[0] = cmd;
memcpy(>data[1], wbuf, wlen);
-   if (wo)
-   ret = dvb_usb_generic_write(d, st->data, 1 + wlen);
-   else
-   ret = dvb_usb_generic_rw(d, st->data, 1 + wlen,
-rbuf, rlen, 0);
+   ret = dvb_usb_generic_rw(d, st->data, 1 + wlen, st->data, rlen, 0);
+   if (!ret && rbuf && rlen)
+   memcpy(rbuf, st->data, rlen);
 
mutex_unlock(>data_mutex);
return ret;
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html