diff options
Diffstat (limited to 'drivers/media/tuners/si2157.c')
-rw-r--r-- | drivers/media/tuners/si2157.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c index d74ae26621ca..a6245ef379c4 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) | |||
79 | { | 79 | { |
80 | struct i2c_client *client = fe->tuner_priv; | 80 | struct i2c_client *client = fe->tuner_priv; |
81 | struct si2157_dev *dev = i2c_get_clientdata(client); | 81 | struct si2157_dev *dev = i2c_get_clientdata(client); |
82 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
82 | int ret, len, remaining; | 83 | int ret, len, remaining; |
83 | struct si2157_cmd cmd; | 84 | struct si2157_cmd cmd; |
84 | const struct firmware *fw; | 85 | const struct firmware *fw; |
@@ -201,9 +202,14 @@ skip_fw_download: | |||
201 | dev->fw_loaded = true; | 202 | dev->fw_loaded = true; |
202 | 203 | ||
203 | warm: | 204 | warm: |
205 | /* init statistics in order signal app which are supported */ | ||
206 | c->strength.len = 1; | ||
207 | c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
208 | /* start statistics polling */ | ||
209 | schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(1000)); | ||
210 | |||
204 | dev->active = true; | 211 | dev->active = true; |
205 | return 0; | 212 | return 0; |
206 | |||
207 | err_release_firmware: | 213 | err_release_firmware: |
208 | release_firmware(fw); | 214 | release_firmware(fw); |
209 | err: | 215 | err: |
@@ -222,6 +228,9 @@ static int si2157_sleep(struct dvb_frontend *fe) | |||
222 | 228 | ||
223 | dev->active = false; | 229 | dev->active = false; |
224 | 230 | ||
231 | /* stop statistics polling */ | ||
232 | cancel_delayed_work_sync(&dev->stat_work); | ||
233 | |||
225 | /* standby */ | 234 | /* standby */ |
226 | memcpy(cmd.args, "\x16\x00", 2); | 235 | memcpy(cmd.args, "\x16\x00", 2); |
227 | cmd.wlen = 2; | 236 | cmd.wlen = 2; |
@@ -298,7 +307,8 @@ static int si2157_set_params(struct dvb_frontend *fe) | |||
298 | if (dev->chiptype == SI2157_CHIPTYPE_SI2146) | 307 | if (dev->chiptype == SI2157_CHIPTYPE_SI2146) |
299 | memcpy(cmd.args, "\x14\x00\x02\x07\x00\x01", 6); | 308 | memcpy(cmd.args, "\x14\x00\x02\x07\x00\x01", 6); |
300 | else | 309 | else |
301 | memcpy(cmd.args, "\x14\x00\x02\x07\x01\x00", 6); | 310 | memcpy(cmd.args, "\x14\x00\x02\x07\x00\x00", 6); |
311 | cmd.args[4] = dev->if_port; | ||
302 | cmd.wlen = 6; | 312 | cmd.wlen = 6; |
303 | cmd.rlen = 4; | 313 | cmd.rlen = 4; |
304 | ret = si2157_cmd_execute(client, &cmd); | 314 | ret = si2157_cmd_execute(client, &cmd); |
@@ -359,6 +369,34 @@ static const struct dvb_tuner_ops si2157_ops = { | |||
359 | .get_if_frequency = si2157_get_if_frequency, | 369 | .get_if_frequency = si2157_get_if_frequency, |
360 | }; | 370 | }; |
361 | 371 | ||
372 | static void si2157_stat_work(struct work_struct *work) | ||
373 | { | ||
374 | struct si2157_dev *dev = container_of(work, struct si2157_dev, stat_work.work); | ||
375 | struct dvb_frontend *fe = dev->fe; | ||
376 | struct i2c_client *client = fe->tuner_priv; | ||
377 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
378 | struct si2157_cmd cmd; | ||
379 | int ret; | ||
380 | |||
381 | dev_dbg(&client->dev, "\n"); | ||
382 | |||
383 | memcpy(cmd.args, "\x42\x00", 2); | ||
384 | cmd.wlen = 2; | ||
385 | cmd.rlen = 12; | ||
386 | ret = si2157_cmd_execute(client, &cmd); | ||
387 | if (ret) | ||
388 | goto err; | ||
389 | |||
390 | c->strength.stat[0].scale = FE_SCALE_DECIBEL; | ||
391 | c->strength.stat[0].svalue = (s8) cmd.args[3] * 1000; | ||
392 | |||
393 | schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(2000)); | ||
394 | return; | ||
395 | err: | ||
396 | c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
397 | dev_dbg(&client->dev, "failed=%d\n", ret); | ||
398 | } | ||
399 | |||
362 | static int si2157_probe(struct i2c_client *client, | 400 | static int si2157_probe(struct i2c_client *client, |
363 | const struct i2c_device_id *id) | 401 | const struct i2c_device_id *id) |
364 | { | 402 | { |
@@ -378,10 +416,12 @@ static int si2157_probe(struct i2c_client *client, | |||
378 | i2c_set_clientdata(client, dev); | 416 | i2c_set_clientdata(client, dev); |
379 | dev->fe = cfg->fe; | 417 | dev->fe = cfg->fe; |
380 | dev->inversion = cfg->inversion; | 418 | dev->inversion = cfg->inversion; |
419 | dev->if_port = cfg->if_port; | ||
381 | dev->fw_loaded = false; | 420 | dev->fw_loaded = false; |
382 | dev->chiptype = (u8)id->driver_data; | 421 | dev->chiptype = (u8)id->driver_data; |
383 | dev->if_frequency = 5000000; /* default value of property 0x0706 */ | 422 | dev->if_frequency = 5000000; /* default value of property 0x0706 */ |
384 | mutex_init(&dev->i2c_mutex); | 423 | mutex_init(&dev->i2c_mutex); |
424 | INIT_DELAYED_WORK(&dev->stat_work, si2157_stat_work); | ||
385 | 425 | ||
386 | /* check if the tuner is there */ | 426 | /* check if the tuner is there */ |
387 | cmd.wlen = 0; | 427 | cmd.wlen = 0; |