aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-frontends/af9033.c
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2014-09-02 02:55:21 -0400
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2014-09-21 18:44:43 -0400
commit83f1161911c5f32dc4cfa817a73ae028d32c43b7 (patch)
treedb5b828ed5bfc629b6cdf7b5d7ce57b58e560bc9 /drivers/media/dvb-frontends/af9033.c
parent249c697e5e2c8e1347d79be0a9c93a985f2ad12e (diff)
[media] af9033: implement DVBv5 statistics for signal strength
Let the demod firmware estimate RF signal strength and return it to the app as a dBm. To handle that, use thread which reads signal strengths from firmware in 2 sec intervals when device is active. Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/dvb-frontends/af9033.c')
-rw-r--r--drivers/media/dvb-frontends/af9033.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c
index 1bd5a9af7db5..b9a0b009aeda 100644
--- a/drivers/media/dvb-frontends/af9033.c
+++ b/drivers/media/dvb-frontends/af9033.c
@@ -28,13 +28,17 @@ struct af9033_dev {
28 struct i2c_client *client; 28 struct i2c_client *client;
29 struct dvb_frontend fe; 29 struct dvb_frontend fe;
30 struct af9033_config cfg; 30 struct af9033_config cfg;
31 bool is_af9035;
32 bool is_it9135;
31 33
32 u32 bandwidth_hz; 34 u32 bandwidth_hz;
33 bool ts_mode_parallel; 35 bool ts_mode_parallel;
34 bool ts_mode_serial; 36 bool ts_mode_serial;
35 37
38 fe_status_t fe_status;
36 u32 ber; 39 u32 ber;
37 u32 ucb; 40 u32 ucb;
41 struct delayed_work stat_work;
38 unsigned long last_stat_check; 42 unsigned long last_stat_check;
39}; 43};
40 44
@@ -442,6 +446,8 @@ static int af9033_init(struct dvb_frontend *fe)
442 } 446 }
443 447
444 dev->bandwidth_hz = 0; /* force to program all parameters */ 448 dev->bandwidth_hz = 0; /* force to program all parameters */
449 /* start statistics polling */
450 schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(2000));
445 451
446 return 0; 452 return 0;
447 453
@@ -457,6 +463,9 @@ static int af9033_sleep(struct dvb_frontend *fe)
457 int ret, i; 463 int ret, i;
458 u8 tmp; 464 u8 tmp;
459 465
466 /* stop statistics polling */
467 cancel_delayed_work_sync(&dev->stat_work);
468
460 ret = af9033_wr_reg(dev, 0x80004c, 1); 469 ret = af9033_wr_reg(dev, 0x80004c, 1);
461 if (ret < 0) 470 if (ret < 0)
462 goto err; 471 goto err;
@@ -810,6 +819,8 @@ static int af9033_read_status(struct dvb_frontend *fe, fe_status_t *status)
810 FE_HAS_LOCK; 819 FE_HAS_LOCK;
811 } 820 }
812 821
822 dev->fe_status = *status;
823
813 return 0; 824 return 0;
814 825
815err: 826err:
@@ -1039,6 +1050,40 @@ err:
1039 return ret; 1050 return ret;
1040} 1051}
1041 1052
1053static void af9033_stat_work(struct work_struct *work)
1054{
1055 struct af9033_dev *dev = container_of(work, struct af9033_dev, stat_work.work);
1056 struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
1057 int ret, tmp;
1058 u8 u8tmp;
1059
1060 dev_dbg(&dev->client->dev, "\n");
1061
1062 if (dev->fe_status & FE_HAS_SIGNAL) {
1063 if (dev->is_af9035) {
1064 ret = af9033_rd_reg(dev, 0x80004a, &u8tmp);
1065 tmp = -u8tmp * 1000;
1066 } else {
1067 ret = af9033_rd_reg(dev, 0x8000f7, &u8tmp);
1068 tmp = (u8tmp - 100) * 1000;
1069 }
1070 if (ret)
1071 goto err;
1072
1073 c->strength.len = 1;
1074 c->strength.stat[0].scale = FE_SCALE_DECIBEL;
1075 c->strength.stat[0].svalue = tmp;
1076 } else {
1077 c->strength.len = 1;
1078 c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1079 }
1080
1081 schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(2000));
1082 return;
1083err:
1084 dev_dbg(&dev->client->dev, "failed=%d\n", ret);
1085}
1086
1042static struct dvb_frontend_ops af9033_ops = { 1087static struct dvb_frontend_ops af9033_ops = {
1043 .delsys = { SYS_DVBT }, 1088 .delsys = { SYS_DVBT },
1044 .info = { 1089 .info = {
@@ -1099,6 +1144,7 @@ static int af9033_probe(struct i2c_client *client,
1099 1144
1100 /* setup the state */ 1145 /* setup the state */
1101 dev->client = client; 1146 dev->client = client;
1147 INIT_DELAYED_WORK(&dev->stat_work, af9033_stat_work);
1102 memcpy(&dev->cfg, cfg, sizeof(struct af9033_config)); 1148 memcpy(&dev->cfg, cfg, sizeof(struct af9033_config));
1103 1149
1104 if (dev->cfg.clock != 12000000) { 1150 if (dev->cfg.clock != 12000000) {
@@ -1117,9 +1163,11 @@ static int af9033_probe(struct i2c_client *client,
1117 case AF9033_TUNER_IT9135_60: 1163 case AF9033_TUNER_IT9135_60:
1118 case AF9033_TUNER_IT9135_61: 1164 case AF9033_TUNER_IT9135_61:
1119 case AF9033_TUNER_IT9135_62: 1165 case AF9033_TUNER_IT9135_62:
1166 dev->is_it9135 = true;
1120 reg = 0x004bfc; 1167 reg = 0x004bfc;
1121 break; 1168 break;
1122 default: 1169 default:
1170 dev->is_af9035 = true;
1123 reg = 0x0083e9; 1171 reg = 0x0083e9;
1124 break; 1172 break;
1125 } 1173 }