[2/2] si2168: add support for firmware files in new format
Commit Message
This patch adds support for new type of firmware versions of Si2168 chip.
Old type: n x 8 bytes (all data, first byte seems to be 04 or 05)
New type: n x 17 bytes (1 byte indicates len and max 16 bytes data)
New version of TechnoTrend CT2-4400 drivers
(http://www.tt-downloads.de/bda-treiber_4.3.0.0.zip) contains newer
firmware for Si2168-B40 that is in the new format. It can be extracted
with the following command:
dd if=ttTVStick4400_64.sys ibs=1 skip=323872 count=6919 of=dvb-demod-si2168-b40-01.fw
Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
---
drivers/media/dvb-frontends/si2168.c | 46 +++++++++++++++++++++++++-----------
1 file changed, 32 insertions(+), 14 deletions(-)
Comments
On 11/27/2014 09:42 PM, Olli Salonen wrote:
> This patch adds support for new type of firmware versions of Si2168 chip.
>
> Old type: n x 8 bytes (all data, first byte seems to be 04 or 05)
> New type: n x 17 bytes (1 byte indicates len and max 16 bytes data)
>
> New version of TechnoTrend CT2-4400 drivers
> (http://www.tt-downloads.de/bda-treiber_4.3.0.0.zip) contains newer
> firmware for Si2168-B40 that is in the new format. It can be extracted
> with the following command:
>
> dd if=ttTVStick4400_64.sys ibs=1 skip=323872 count=6919 of=dvb-demod-si2168-b40-01.fw
>
> Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
Reviewed-by: Antti Palosaari <crope@iki.fi>
That change makes anyhow some headache on case driver is old and does
not support that newer firmware format... On that case it fails and
error is printed, though. But we can live with it as there is no
regression - kernel update is still possible. Only kernel downgrade
could cause problem if new format firmware is installed.
regards
Antti
@@ -462,20 +462,38 @@ static int si2168_init(struct dvb_frontend *fe)
dev_info(&s->client->dev, "downloading firmware from file '%s'\n",
fw_file);
- for (remaining = fw->size; remaining > 0; remaining -= i2c_wr_max) {
- len = remaining;
- if (len > i2c_wr_max)
- len = i2c_wr_max;
-
- memcpy(cmd.args, &fw->data[fw->size - remaining], len);
- cmd.wlen = len;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret) {
- dev_err(&s->client->dev,
- "firmware download failed=%d\n",
- ret);
- goto error_fw_release;
+ if ((fw->size % 17 == 0) && (fw->data[0] > 5)) {
+ /* firmware is in the new format */
+ for (remaining = fw->size; remaining > 0; remaining -= 17) {
+ len = fw->data[fw->size - remaining];
+ memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
+ cmd.wlen = len;
+ cmd.rlen = 1;
+ ret = si2168_cmd_execute(s, &cmd);
+ if (ret) {
+ dev_err(&s->client->dev,
+ "firmware download failed=%d\n",
+ ret);
+ goto error_fw_release;
+ }
+ }
+ } else {
+ /* firmware is in the old format */
+ for (remaining = fw->size; remaining > 0; remaining -= i2c_wr_max) {
+ len = remaining;
+ if (len > i2c_wr_max)
+ len = i2c_wr_max;
+
+ memcpy(cmd.args, &fw->data[fw->size - remaining], len);
+ cmd.wlen = len;
+ cmd.rlen = 1;
+ ret = si2168_cmd_execute(s, &cmd);
+ if (ret) {
+ dev_err(&s->client->dev,
+ "firmware download failed=%d\n",
+ ret);
+ goto error_fw_release;
+ }
}
}