diff options
author | Olli Salonen <olli.salonen@iki.fi> | 2014-07-13 09:52:18 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-07-14 20:07:05 -0400 |
commit | c9cb0820d5d756f2fac550213e664cc0be511349 (patch) | |
tree | 7d118af85c060726ec755bd2ca1b6d35e93a48ec | |
parent | b02db9e1e01253e375e8b760c22858027a2130de (diff) |
[media] si2168: Add support for chip revision Si2168 A30
Add handling for different chip revisions and firmwares.
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>
-rw-r--r-- | drivers/media/dvb-frontends/si2168.c | 34 | ||||
-rw-r--r-- | drivers/media/dvb-frontends/si2168_priv.h | 4 |
2 files changed, 32 insertions, 6 deletions
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 5481c39594c4..c10f4a1c6157 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c | |||
@@ -333,7 +333,7 @@ static int si2168_init(struct dvb_frontend *fe) | |||
333 | struct si2168 *s = fe->demodulator_priv; | 333 | struct si2168 *s = fe->demodulator_priv; |
334 | int ret, len, remaining; | 334 | int ret, len, remaining; |
335 | const struct firmware *fw = NULL; | 335 | const struct firmware *fw = NULL; |
336 | u8 *fw_file = SI2168_FIRMWARE; | 336 | u8 *fw_file; |
337 | const unsigned int i2c_wr_max = 8; | 337 | const unsigned int i2c_wr_max = 8; |
338 | struct si2168_cmd cmd; | 338 | struct si2168_cmd cmd; |
339 | 339 | ||
@@ -353,6 +353,7 @@ static int si2168_init(struct dvb_frontend *fe) | |||
353 | if (ret) | 353 | if (ret) |
354 | goto err; | 354 | goto err; |
355 | 355 | ||
356 | /* query chip revision */ | ||
356 | memcpy(cmd.args, "\x02", 1); | 357 | memcpy(cmd.args, "\x02", 1); |
357 | cmd.wlen = 1; | 358 | cmd.wlen = 1; |
358 | cmd.rlen = 13; | 359 | cmd.rlen = 13; |
@@ -374,6 +375,20 @@ static int si2168_init(struct dvb_frontend *fe) | |||
374 | if (ret) | 375 | if (ret) |
375 | goto err; | 376 | goto err; |
376 | 377 | ||
378 | if (((cmd.args[1] & 0x0f) == 2) && (cmd.args[3] == '4') && | ||
379 | (cmd.args[4] == '0')) | ||
380 | fw_file = SI2168_B40_FIRMWARE; | ||
381 | else if (((cmd.args[1] & 0x0f) == 1) && (cmd.args[3] == '3') && | ||
382 | (cmd.args[4] == '0')) | ||
383 | fw_file = SI2168_A30_FIRMWARE; | ||
384 | else { | ||
385 | dev_err(&s->client->dev, | ||
386 | "%s: no firmware file for Si2168-%c%c defined\n", | ||
387 | KBUILD_MODNAME, cmd.args[3], cmd.args[4]); | ||
388 | ret = -EINVAL; | ||
389 | goto err; | ||
390 | } | ||
391 | |||
377 | /* cold state - try to download firmware */ | 392 | /* cold state - try to download firmware */ |
378 | dev_info(&s->client->dev, "%s: found a '%s' in cold state\n", | 393 | dev_info(&s->client->dev, "%s: found a '%s' in cold state\n", |
379 | KBUILD_MODNAME, si2168_ops.info.name); | 394 | KBUILD_MODNAME, si2168_ops.info.name); |
@@ -381,9 +396,18 @@ static int si2168_init(struct dvb_frontend *fe) | |||
381 | /* request the firmware, this will block and timeout */ | 396 | /* request the firmware, this will block and timeout */ |
382 | ret = request_firmware(&fw, fw_file, &s->client->dev); | 397 | ret = request_firmware(&fw, fw_file, &s->client->dev); |
383 | if (ret) { | 398 | if (ret) { |
384 | dev_err(&s->client->dev, "%s: firmare file '%s' not found\n", | 399 | /* fallback mechanism to handle old name for |
385 | KBUILD_MODNAME, fw_file); | 400 | SI2168_B40_FIRMWARE */ |
386 | goto err; | 401 | if (((cmd.args[1] & 0x0f) == 2) && (cmd.args[3] == '4') && |
402 | (cmd.args[4] == '0')) { | ||
403 | fw_file = SI2168_B40_FIRMWARE_FALLBACK; | ||
404 | ret = request_firmware(&fw, fw_file, &s->client->dev); | ||
405 | } | ||
406 | if (ret) { | ||
407 | dev_err(&s->client->dev, "%s: firmware file '%s' not found\n", | ||
408 | KBUILD_MODNAME, fw_file); | ||
409 | goto err; | ||
410 | } | ||
387 | } | 411 | } |
388 | 412 | ||
389 | dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n", | 413 | dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n", |
@@ -643,4 +667,4 @@ module_i2c_driver(si2168_driver); | |||
643 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | 667 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); |
644 | MODULE_DESCRIPTION("Silicon Labs Si2168 DVB-T/T2/C demodulator driver"); | 668 | MODULE_DESCRIPTION("Silicon Labs Si2168 DVB-T/T2/C demodulator driver"); |
645 | MODULE_LICENSE("GPL"); | 669 | MODULE_LICENSE("GPL"); |
646 | MODULE_FIRMWARE(SI2168_FIRMWARE); | 670 | MODULE_FIRMWARE(SI2168_B40_FIRMWARE); |
diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h index e7d963dbaf34..d606915dea14 100644 --- a/drivers/media/dvb-frontends/si2168_priv.h +++ b/drivers/media/dvb-frontends/si2168_priv.h | |||
@@ -22,7 +22,9 @@ | |||
22 | #include <linux/firmware.h> | 22 | #include <linux/firmware.h> |
23 | #include <linux/i2c-mux.h> | 23 | #include <linux/i2c-mux.h> |
24 | 24 | ||
25 | #define SI2168_FIRMWARE "dvb-demod-si2168-01.fw" | 25 | #define SI2168_A30_FIRMWARE "dvb-demod-si2168-a30-01.fw" |
26 | #define SI2168_B40_FIRMWARE "dvb-demod-si2168-b40-01.fw" | ||
27 | #define SI2168_B40_FIRMWARE_FALLBACK "dvb-demod-si2168-01.fw" | ||
26 | 28 | ||
27 | /* state struct */ | 29 | /* state struct */ |
28 | struct si2168 { | 30 | struct si2168 { |