aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/dvb-usb-v2/lmedm04.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/usb/dvb-usb-v2/lmedm04.c')
-rw-r--r--drivers/media/usb/dvb-usb-v2/lmedm04.c112
1 files changed, 80 insertions, 32 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
index 5de6f7c04d09..4cc55b3a0558 100644
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -126,7 +126,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
struct lme2510_state {
unsigned long int_urb_due;
- fe_status_t lock_status;
+ enum fe_status lock_status;
u8 id;
u8 tuner_config;
u8 signal_level;
@@ -144,12 +144,12 @@ struct lme2510_state {
struct urb *lme_urb;
void *usb_buffer;
/* Frontend original calls */
- int (*fe_read_status)(struct dvb_frontend *, fe_status_t *);
+ int (*fe_read_status)(struct dvb_frontend *, enum fe_status *);
int (*fe_read_signal_strength)(struct dvb_frontend *, u16 *);
int (*fe_read_snr)(struct dvb_frontend *, u16 *);
int (*fe_read_ber)(struct dvb_frontend *, u32 *);
int (*fe_read_ucblocks)(struct dvb_frontend *, u32 *);
- int (*fe_set_voltage)(struct dvb_frontend *, fe_sec_voltage_t);
+ int (*fe_set_voltage)(struct dvb_frontend *, enum fe_sec_voltage);
u8 dvb_usb_lme2510_firmware;
};
@@ -257,6 +257,62 @@ static int lme2510_enable_pid(struct dvb_usb_device *d, u8 index, u16 pid_out)
return ret;
}
+/* Convert range from 0x00-0xff to 0x0000-0xffff */
+#define reg_to_16bits(x) ((x) | ((x) << 8))
+
+static void lme2510_update_stats(struct dvb_usb_adapter *adap)
+{
+ struct lme2510_state *st = adap_to_priv(adap);
+ struct dvb_frontend *fe = adap->fe[0];
+ struct dtv_frontend_properties *c;
+ u32 s_tmp = 0, c_tmp = 0;
+
+ if (!fe)
+ return;
+
+ c = &fe->dtv_property_cache;
+
+ c->block_count.len = 1;
+ c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->block_error.len = 1;
+ c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_count.len = 1;
+ c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_error.len = 1;
+ c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+ if (st->i2c_talk_onoff) {
+ c->strength.len = 1;
+ c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->cnr.len = 1;
+ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ return;
+ }
+
+ switch (st->tuner_config) {
+ case TUNER_LG:
+ s_tmp = reg_to_16bits(0xff - st->signal_level);
+ c_tmp = reg_to_16bits(0xff - st->signal_sn);
+ break;
+ case TUNER_S7395:
+ case TUNER_S0194:
+ s_tmp = 0xffff - (((st->signal_level * 2) << 8) * 5 / 4);
+ c_tmp = reg_to_16bits((0xff - st->signal_sn - 0xa1) * 3);
+ break;
+ case TUNER_RS2000:
+ s_tmp = reg_to_16bits(st->signal_level);
+ c_tmp = reg_to_16bits(st->signal_sn);
+ }
+
+ c->strength.len = 1;
+ c->strength.stat[0].scale = FE_SCALE_RELATIVE;
+ c->strength.stat[0].uvalue = (u64)s_tmp;
+
+ c->cnr.len = 1;
+ c->cnr.stat[0].scale = FE_SCALE_RELATIVE;
+ c->cnr.stat[0].uvalue = (u64)c_tmp;
+}
+
static void lme2510_int_response(struct urb *lme_urb)
{
struct dvb_usb_adapter *adap = lme_urb->context;
@@ -337,6 +393,8 @@ static void lme2510_int_response(struct urb *lme_urb)
if (!signal_lock)
st->lock_status &= ~FE_HAS_LOCK;
+ lme2510_update_stats(adap);
+
debug_data_snipet(5, "INT Remote data snipet in", ibuf);
break;
case 0xcc:
@@ -799,10 +857,11 @@ static struct m88rs2000_config m88rs2000_config = {
static struct ts2020_config ts2020_config = {
.tuner_address = 0x60,
.clk_out_div = 7,
+ .dont_poll = true
};
static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
- fe_sec_voltage_t voltage)
+ enum fe_sec_voltage voltage)
{
struct dvb_usb_device *d = fe_to_d(fe);
struct lme2510_state *st = fe_to_priv(fe);
@@ -837,7 +896,7 @@ static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
return (ret < 0) ? -ENODEV : 0;
}
-static int dm04_read_status(struct dvb_frontend *fe, fe_status_t *status)
+static int dm04_read_status(struct dvb_frontend *fe, enum fe_status *status)
{
struct dvb_usb_device *d = fe_to_d(fe);
struct lme2510_state *st = d->priv;
@@ -871,56 +930,45 @@ static int dm04_read_status(struct dvb_frontend *fe, fe_status_t *status)
*status = st->lock_status;
- if (!(*status & FE_HAS_LOCK))
+ if (!(*status & FE_HAS_LOCK)) {
+ struct dvb_usb_adapter *adap = fe_to_adap(fe);
+
st->i2c_talk_onoff = 1;
+ lme2510_update_stats(adap);
+ }
+
return ret;
}
static int dm04_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
struct lme2510_state *st = fe_to_priv(fe);
if (st->fe_read_signal_strength && !st->stream_on)
return st->fe_read_signal_strength(fe, strength);
- switch (st->tuner_config) {
- case TUNER_LG:
- *strength = 0xff - st->signal_level;
- *strength |= *strength << 8;
- break;
- /* fall through */
- case TUNER_S7395:
- case TUNER_S0194:
- *strength = 0xffff - (((st->signal_level * 2) << 8) * 5 / 4);
- break;
- case TUNER_RS2000:
- *strength = (u16)((u32)st->signal_level * 0xffff / 0xff);
- }
+ if (c->strength.stat[0].scale == FE_SCALE_RELATIVE)
+ *strength = (u16)c->strength.stat[0].uvalue;
+ else
+ *strength = 0;
return 0;
}
static int dm04_read_snr(struct dvb_frontend *fe, u16 *snr)
{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
struct lme2510_state *st = fe_to_priv(fe);
if (st->fe_read_snr && !st->stream_on)
return st->fe_read_snr(fe, snr);
- switch (st->tuner_config) {
- case TUNER_LG:
- *snr = 0xff - st->signal_sn;
- *snr |= *snr << 8;
- break;
- /* fall through */
- case TUNER_S7395:
- case TUNER_S0194:
- *snr = (u16)((0xff - st->signal_sn - 0xa1) * 3) << 8;
- break;
- case TUNER_RS2000:
- *snr = (u16)((u32)st->signal_sn * 0xffff / 0x7f);
- }
+ if (c->cnr.stat[0].scale == FE_SCALE_RELATIVE)
+ *snr = (u16)c->cnr.stat[0].uvalue;
+ else
+ *snr = 0;
return 0;
}