Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] lmedm04: implement dvb v5 statistics

Indroduce function lme2510_update_stats to update
statistics directly from usb interrupt.

Provide signal and snr wrap rounds for dvb v3 functions.

Block and post bit are not available.

When i2c_talk_onoff is on no statistics are available,
with possible future hand over to the relevant frontend/tuner.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>

authored by

Malcolm Priestley and committed by
Mauro Carvalho Chehab
48c91aad baa1fb50

+77 -27
+77 -27
drivers/media/usb/dvb-usb-v2/lmedm04.c
··· 257 257 return ret; 258 258 } 259 259 260 + static void lme2510_update_stats(struct dvb_usb_adapter *adap) 261 + { 262 + struct lme2510_state *st = adap_to_priv(adap); 263 + struct dvb_frontend *fe = adap->fe[0]; 264 + struct dtv_frontend_properties *c; 265 + u64 s_tmp = 0, c_tmp = 0; 266 + 267 + if (!fe) 268 + return; 269 + 270 + c = &fe->dtv_property_cache; 271 + 272 + c->block_count.len = 1; 273 + c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 274 + c->block_error.len = 1; 275 + c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 276 + c->post_bit_count.len = 1; 277 + c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 278 + c->post_bit_error.len = 1; 279 + c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 280 + 281 + if (st->i2c_talk_onoff) { 282 + c->strength.len = 1; 283 + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 284 + c->cnr.len = 1; 285 + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 286 + return; 287 + } 288 + 289 + switch (st->tuner_config) { 290 + case TUNER_LG: 291 + s_tmp = 0xff - st->signal_level; 292 + s_tmp |= s_tmp << 8; 293 + 294 + c_tmp = 0xff - st->signal_sn; 295 + c_tmp |= c_tmp << 8; 296 + break; 297 + /* fall through */ 298 + case TUNER_S7395: 299 + case TUNER_S0194: 300 + s_tmp = 0xffff - (((st->signal_level * 2) << 8) * 5 / 4); 301 + 302 + c_tmp = ((0xff - st->signal_sn - 0xa1) * 3) << 8; 303 + break; 304 + case TUNER_RS2000: 305 + s_tmp = st->signal_level * 0xffff / 0xff; 306 + 307 + c_tmp = st->signal_sn * 0xffff / 0x7f; 308 + } 309 + 310 + c->strength.len = 1; 311 + c->strength.stat[0].scale = FE_SCALE_RELATIVE; 312 + c->strength.stat[0].uvalue = s_tmp; 313 + 314 + c->cnr.len = 1; 315 + c->cnr.stat[0].scale = FE_SCALE_RELATIVE; 316 + c->cnr.stat[0].uvalue = c_tmp; 317 + } 318 + 260 319 static void lme2510_int_response(struct urb *lme_urb) 261 320 { 262 321 struct dvb_usb_adapter *adap = lme_urb->context; ··· 395 336 396 337 if (!signal_lock) 397 338 st->lock_status &= ~FE_HAS_LOCK; 339 + 340 + lme2510_update_stats(adap); 398 341 399 342 debug_data_snipet(5, "INT Remote data snipet in", ibuf); 400 343 break; ··· 933 872 934 873 *status = st->lock_status; 935 874 936 - if (!(*status & FE_HAS_LOCK)) 875 + if (!(*status & FE_HAS_LOCK)) { 876 + struct dvb_usb_adapter *adap = fe_to_adap(fe); 877 + 937 878 st->i2c_talk_onoff = 1; 879 + 880 + lme2510_update_stats(adap); 881 + } 938 882 939 883 return ret; 940 884 } 941 885 942 886 static int dm04_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 943 887 { 888 + struct dtv_frontend_properties *c = &fe->dtv_property_cache; 944 889 struct lme2510_state *st = fe_to_priv(fe); 945 890 946 891 if (st->fe_read_signal_strength && !st->stream_on) 947 892 return st->fe_read_signal_strength(fe, strength); 948 893 949 - switch (st->tuner_config) { 950 - case TUNER_LG: 951 - *strength = 0xff - st->signal_level; 952 - *strength |= *strength << 8; 953 - break; 954 - /* fall through */ 955 - case TUNER_S7395: 956 - case TUNER_S0194: 957 - *strength = 0xffff - (((st->signal_level * 2) << 8) * 5 / 4); 958 - break; 959 - case TUNER_RS2000: 960 - *strength = (u16)((u32)st->signal_level * 0xffff / 0xff); 961 - } 894 + if (c->strength.stat[0].scale == FE_SCALE_RELATIVE) 895 + *strength = (u16)c->strength.stat[0].uvalue; 896 + else 897 + *strength = 0; 962 898 963 899 return 0; 964 900 } 965 901 966 902 static int dm04_read_snr(struct dvb_frontend *fe, u16 *snr) 967 903 { 904 + struct dtv_frontend_properties *c = &fe->dtv_property_cache; 968 905 struct lme2510_state *st = fe_to_priv(fe); 969 906 970 907 if (st->fe_read_snr && !st->stream_on) 971 908 return st->fe_read_snr(fe, snr); 972 909 973 - switch (st->tuner_config) { 974 - case TUNER_LG: 975 - *snr = 0xff - st->signal_sn; 976 - *snr |= *snr << 8; 977 - break; 978 - /* fall through */ 979 - case TUNER_S7395: 980 - case TUNER_S0194: 981 - *snr = (u16)((0xff - st->signal_sn - 0xa1) * 3) << 8; 982 - break; 983 - case TUNER_RS2000: 984 - *snr = (u16)((u32)st->signal_sn * 0xffff / 0x7f); 985 - } 910 + if (c->cnr.stat[0].scale == FE_SCALE_RELATIVE) 911 + *snr = (u16)c->cnr.stat[0].uvalue; 912 + else 913 + *snr = 0; 986 914 987 915 return 0; 988 916 }