From e5fd91f1ef340da553f7a79da9540c3db711c937 Mon Sep 17 00:00:00 2001 From: André Fabian Silva Delgado Date: Tue, 8 Sep 2015 01:01:14 -0300 Subject: Linux-libre 4.2-gnu --- drivers/media/tuners/si2157.c | 44 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) (limited to 'drivers/media/tuners/si2157.c') diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c index dbcf73789..a79eb671e 100644 --- a/drivers/media/tuners/si2157.c +++ b/drivers/media/tuners/si2157.c @@ -79,6 +79,7 @@ static int si2157_init(struct dvb_frontend *fe) { struct i2c_client *client = fe->tuner_priv; struct si2157_dev *dev = i2c_get_clientdata(client); + struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, len, remaining; struct si2157_cmd cmd; const struct firmware *fw; @@ -201,9 +202,14 @@ skip_fw_download: dev->fw_loaded = true; warm: + /* init statistics in order signal app which are supported */ + c->strength.len = 1; + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + /* start statistics polling */ + schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(1000)); + dev->active = true; return 0; - err_release_firmware: release_firmware(fw); err: @@ -222,6 +228,9 @@ static int si2157_sleep(struct dvb_frontend *fe) dev->active = false; + /* stop statistics polling */ + cancel_delayed_work_sync(&dev->stat_work); + /* standby */ memcpy(cmd.args, "\x16\x00", 2); cmd.wlen = 2; @@ -298,7 +307,8 @@ static int si2157_set_params(struct dvb_frontend *fe) if (dev->chiptype == SI2157_CHIPTYPE_SI2146) memcpy(cmd.args, "\x14\x00\x02\x07\x00\x01", 6); else - memcpy(cmd.args, "\x14\x00\x02\x07\x01\x00", 6); + memcpy(cmd.args, "\x14\x00\x02\x07\x00\x00", 6); + cmd.args[4] = dev->if_port; cmd.wlen = 6; cmd.rlen = 4; ret = si2157_cmd_execute(client, &cmd); @@ -359,6 +369,34 @@ static const struct dvb_tuner_ops si2157_ops = { .get_if_frequency = si2157_get_if_frequency, }; +static void si2157_stat_work(struct work_struct *work) +{ + struct si2157_dev *dev = container_of(work, struct si2157_dev, stat_work.work); + struct dvb_frontend *fe = dev->fe; + struct i2c_client *client = fe->tuner_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct si2157_cmd cmd; + int ret; + + dev_dbg(&client->dev, "\n"); + + memcpy(cmd.args, "\x42\x00", 2); + cmd.wlen = 2; + cmd.rlen = 12; + ret = si2157_cmd_execute(client, &cmd); + if (ret) + goto err; + + c->strength.stat[0].scale = FE_SCALE_DECIBEL; + c->strength.stat[0].svalue = (s8) cmd.args[3] * 1000; + + schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(2000)); + return; +err: + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + dev_dbg(&client->dev, "failed=%d\n", ret); +} + static int si2157_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -378,10 +416,12 @@ static int si2157_probe(struct i2c_client *client, i2c_set_clientdata(client, dev); dev->fe = cfg->fe; dev->inversion = cfg->inversion; + dev->if_port = cfg->if_port; dev->fw_loaded = false; dev->chiptype = (u8)id->driver_data; dev->if_frequency = 5000000; /* default value of property 0x0706 */ mutex_init(&dev->i2c_mutex); + INIT_DELAYED_WORK(&dev->stat_work, si2157_stat_work); /* check if the tuner is there */ cmd.wlen = 0; -- cgit v1.2.3-54-g00ecf