[media] si2157: Add support for Si2141-A10
authorStefan Brüns <stefan.bruens@rwth-aachen.de>
Fri, 17 Feb 2017 00:55:31 +0000 (22:55 -0200)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Sat, 15 Apr 2017 01:27:47 +0000 (22:27 -0300)
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.

Cc: Evgeny Plehov <EvgenyPlehov@ukr.net>
Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/tuners/si2157.c
drivers/media/tuners/si2157_priv.h

index 57b250847cd37cf53fe86862121dfae16e109c2c..e35b1faf0ddc0d68d199be1e5c4dd65e319684b4 100644 (file)
@@ -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, &cmd);
+               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  = 42000000,
                .frequency_max  = 870000000,
        },
@@ -471,6 +487,7 @@ static int si2157_probe(struct i2c_client *client,
 #endif
 
        dev_info(&client->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 <crope@iki.fi>");
 MODULE_LICENSE("GPL");
 MODULE_FIRMWARE(SI2158_A20_FIRMWARE);
+MODULE_FIRMWARE(SI2141_A10_FIRMWARE);
index d6b2c7b4405321558534edf9291dfb217e2e9b76..e6436f74abaafb502f9ac0248a988ce5ec6b343e 100644 (file)
@@ -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