[1/2] af9033: fix it9135 strength value not correct issue

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Register 0x800048 does not work in it9135. Fix it and conform to NorDig specifications.
>From 5d2f434dd4737a97a954dc775c26295e785a20c6 Mon Sep 17 00:00:00 2001
From: Bimow Chen <Bimow.Chen@xxxxxxxxxx>
Date: Tue, 23 Sep 2014 15:31:44 +0800
Subject: [PATCH 1/2] af9033: fix it9135 strength value not correct issue

Register 0x800048 does not work in it9135. Fix it and conform to NorDig specifications.

Signed-off-by: Bimow Chen <Bimow.Chen@xxxxxxxxxx>
---
 drivers/media/dvb-frontends/af9033.c      |   50 ++++++++++++++++++++++++-----
 drivers/media/dvb-frontends/af9033_priv.h |    6 +++
 2 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c
index 5c90ea6..0a0aeaf 100644
--- a/drivers/media/dvb-frontends/af9033.c
+++ b/drivers/media/dvb-frontends/af9033.c
@@ -28,6 +28,7 @@ struct af9033_state {
 	struct i2c_adapter *i2c;
 	struct dvb_frontend fe;
 	struct af9033_config cfg;
+	bool is_af9035;
 
 	u32 bandwidth_hz;
 	bool ts_mode_parallel;
@@ -892,16 +893,46 @@ err:
 static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 {
 	struct af9033_state *state = fe->demodulator_priv;
-	int ret;
-	u8 strength2;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret, power_real;
+	u8 strength2, gain_offset, buf[8];
 
-	/* read signal strength of 0-100 scale */
-	ret = af9033_rd_reg(state, 0x800048, &strength2);
-	if (ret < 0)
-		goto err;
+	if (state->is_af9035) {
+		/* read signal strength of 0-100 scale */
+		ret = af9033_rd_reg(state, 0x800048, &strength2);
+		if (ret < 0)
+			goto err;
 
-	/* scale value to 0x0000-0xffff */
-	*strength = strength2 * 0xffff / 100;
+		/* scale value to 0x0000-0xffff */
+		*strength = strength2 * 0xffff / 100;
+	} else {
+		ret = af9033_rd_reg(state, 0x8000f7, &strength2);
+		ret |= af9033_rd_regs(state, 0x80f900, buf, sizeof(buf));
+		if (ret < 0)
+			goto err;
+
+		if (c->frequency <= 300000000)
+			gain_offset = 7; /* VHF */
+		else
+			gain_offset = 4; /* UHF */
+
+		power_real = (strength2 - 100 - gain_offset) -
+			power_reference[((buf[3] >> 0) & 3)][((buf[6] >> 0) & 7)];
+
+		if (power_real < -15)
+			*strength = 0;
+		else if ((power_real >= -15) && (power_real < 0))
+			*strength = (u8)((2 * (power_real + 15)) / 3);
+		else if ((power_real >= 0) && (power_real < 20))
+			*strength = (u8)(4 * power_real + 10);
+		else if ((power_real >= 20) && (power_real < 35))
+			*strength = (u8)((2 * (power_real - 20)) / 3 + 90);
+		else
+			*strength = 100;
+
+		/* scale value to 0x0000-0xffff */
+		*strength = *strength * 0xffff / 100;
+	}
 
 	return 0;
 
@@ -1103,6 +1134,7 @@ struct dvb_frontend *af9033_attach(const struct af9033_config *config,
 	case AF9033_TUNER_IT9135_61:
 	case AF9033_TUNER_IT9135_62:
 		/* IT9135 did not like to sleep at that early */
+		state->is_af9035 = false;
 		break;
 	default:
 		ret = af9033_wr_reg(state, 0x80004c, 1);
@@ -1112,6 +1144,8 @@ struct dvb_frontend *af9033_attach(const struct af9033_config *config,
 		ret = af9033_wr_reg(state, 0x800000, 0);
 		if (ret < 0)
 			goto err;
+
+		state->is_af9035 = true;
 	}
 
 	/* configure internal TS mode */
diff --git a/drivers/media/dvb-frontends/af9033_priv.h b/drivers/media/dvb-frontends/af9033_priv.h
index ded7b67..58315e0 100644
--- a/drivers/media/dvb-frontends/af9033_priv.h
+++ b/drivers/media/dvb-frontends/af9033_priv.h
@@ -2050,4 +2050,10 @@ static const struct reg_val tuner_init_it9135_62[] = {
 	{ 0x80fd8b, 0x00 },
 };
 
+/* NorDig power reference table */
+static const int power_reference[][5] = {
+	{-93, -91, -90, -89, -88}, /* QPSK 1/2 ~ 7/8 */
+	{-87, -85, -84, -83, -82}, /* 16QAM 1/2 ~ 7/8 */
+	{-82, -80, -78, -77, -76}, /* 64QAM 1/2 ~ 7/8 */
+};
 #endif /* AF9033_PRIV_H */
-- 
1.7.0.4


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux