From 8e417224dfb397633601a04214841df12cd470b0 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Mon, 25 Aug 2014 15:07:04 -0300 Subject: [PATCH] [media] si2168: avoid firmware loading if it has been loaded previously Add a variable to keep track if firmware is loaded or not and skip parts of the initialization if fw is already loaded. Resume from sleep with a different command compared to initial power up and run command 85 after resume command. This behaviour is observed when using manufacturer provided binary-only si2168 driver for TechnoTrend CT2-4400. Signed-off-by: Olli Salonen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/si2168.c | 31 ++++++++++++++++++++--- drivers/media/dvb-frontends/si2168_priv.h | 1 + 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 55a4212aea75..a0797fd95129 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -363,6 +363,7 @@ static int si2168_init(struct dvb_frontend *fe) dev_dbg(&s->client->dev, "\n"); + /* initialize */ memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13); cmd.wlen = 13; cmd.rlen = 0; @@ -370,6 +371,26 @@ static int si2168_init(struct dvb_frontend *fe) if (ret) goto err; + if (s->fw_loaded) { + /* resume */ + memcpy(cmd.args, "\xc0\x06\x08\x0f\x00\x20\x21\x01", 8); + cmd.wlen = 8; + cmd.rlen = 1; + ret = si2168_cmd_execute(s, &cmd); + if (ret) + goto err; + + memcpy(cmd.args, "\x85", 1); + cmd.wlen = 1; + cmd.rlen = 1; + ret = si2168_cmd_execute(s, &cmd); + if (ret) + goto err; + + goto warm; + } + + /* power up */ memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8); cmd.wlen = 8; cmd.rlen = 1; @@ -466,9 +487,6 @@ static int si2168_init(struct dvb_frontend *fe) if (ret) goto err; - dev_info(&s->client->dev, "found a '%s' in warm state\n", - si2168_ops.info.name); - /* set ts mode */ memcpy(cmd.args, "\x14\x00\x01\x10\x10\x00", 6); cmd.args[4] |= s->ts_mode; @@ -478,6 +496,12 @@ static int si2168_init(struct dvb_frontend *fe) if (ret) goto err; + s->fw_loaded = true; + +warm: + dev_info(&s->client->dev, "found a '%s' in warm state\n", + si2168_ops.info.name); + s->active = true; return 0; @@ -645,6 +669,7 @@ static int si2168_probe(struct i2c_client *client, *config->i2c_adapter = s->adapter; *config->fe = &s->fe; s->ts_mode = config->ts_mode; + s->fw_loaded = false; i2c_set_clientdata(client, s); diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h index 0f832844b831..e13983ed4be1 100644 --- a/drivers/media/dvb-frontends/si2168_priv.h +++ b/drivers/media/dvb-frontends/si2168_priv.h @@ -36,6 +36,7 @@ struct si2168 { fe_delivery_system_t delivery_system; fe_status_t fe_status; bool active; + bool fw_loaded; u8 ts_mode; }; -- 2.39.5