Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48c91aad authored by Malcolm Priestley's avatar Malcolm Priestley Committed by Mauro Carvalho Chehab
Browse files

[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: default avatarMalcolm Priestley <tvboxspy@gmail.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent baa1fb50
Loading
Loading
Loading
Loading
+77 −27
Original line number Original line Diff line number Diff line
@@ -257,6 +257,65 @@ static int lme2510_enable_pid(struct dvb_usb_device *d, u8 index, u16 pid_out)
	return ret;
	return ret;
}
}


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;
	u64 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 = 0xff - st->signal_level;
		s_tmp |= s_tmp << 8;

		c_tmp = 0xff - st->signal_sn;
		c_tmp |= c_tmp << 8;
		break;
	/* fall through */
	case TUNER_S7395:
	case TUNER_S0194:
		s_tmp = 0xffff - (((st->signal_level * 2) << 8) * 5 / 4);

		c_tmp = ((0xff - st->signal_sn - 0xa1) * 3) << 8;
		break;
	case TUNER_RS2000:
		s_tmp = st->signal_level * 0xffff / 0xff;

		c_tmp = st->signal_sn * 0xffff / 0x7f;
	}

	c->strength.len = 1;
	c->strength.stat[0].scale = FE_SCALE_RELATIVE;
	c->strength.stat[0].uvalue = s_tmp;

	c->cnr.len = 1;
	c->cnr.stat[0].scale = FE_SCALE_RELATIVE;
	c->cnr.stat[0].uvalue = c_tmp;
}

static void lme2510_int_response(struct urb *lme_urb)
static void lme2510_int_response(struct urb *lme_urb)
{
{
	struct dvb_usb_adapter *adap = lme_urb->context;
	struct dvb_usb_adapter *adap = lme_urb->context;
@@ -337,6 +396,8 @@ static void lme2510_int_response(struct urb *lme_urb)
			if (!signal_lock)
			if (!signal_lock)
				st->lock_status &= ~FE_HAS_LOCK;
				st->lock_status &= ~FE_HAS_LOCK;


			lme2510_update_stats(adap);

			debug_data_snipet(5, "INT Remote data snipet in", ibuf);
			debug_data_snipet(5, "INT Remote data snipet in", ibuf);
		break;
		break;
		case 0xcc:
		case 0xcc:
@@ -872,56 +933,45 @@ static int dm04_read_status(struct dvb_frontend *fe, enum fe_status *status)


	*status = st->lock_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;
		st->i2c_talk_onoff = 1;


		lme2510_update_stats(adap);
	}

	return ret;
	return ret;
}
}


static int dm04_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
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);
	struct lme2510_state *st = fe_to_priv(fe);


	if (st->fe_read_signal_strength && !st->stream_on)
	if (st->fe_read_signal_strength && !st->stream_on)
		return st->fe_read_signal_strength(fe, strength);
		return st->fe_read_signal_strength(fe, strength);


	switch (st->tuner_config) {
	if (c->strength.stat[0].scale == FE_SCALE_RELATIVE)
	case TUNER_LG:
		*strength = (u16)c->strength.stat[0].uvalue;
		*strength = 0xff - st->signal_level;
	else
		*strength |= *strength << 8;
		*strength = 0;
		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);
	}


	return 0;
	return 0;
}
}


static int dm04_read_snr(struct dvb_frontend *fe, u16 *snr)
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);
	struct lme2510_state *st = fe_to_priv(fe);


	if (st->fe_read_snr && !st->stream_on)
	if (st->fe_read_snr && !st->stream_on)
		return st->fe_read_snr(fe, snr);
		return st->fe_read_snr(fe, snr);


	switch (st->tuner_config) {
	if (c->cnr.stat[0].scale == FE_SCALE_RELATIVE)
	case TUNER_LG:
		*snr = (u16)c->cnr.stat[0].uvalue;
		*snr = 0xff - st->signal_sn;
	else
		*snr |= *snr << 8;
		*snr = 0;
		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);
	}


	return 0;
	return 0;
}
}