File stv090x_02_dBmV5.patch of Package v4l-dvb-saa716x

--- a/drivers/media/dvb-frontends/stv090x.c.orig	2022-04-05 14:47:31.000000000 +0200
+++ b/drivers/media/dvb-frontends/stv090x.c	2022-04-30 11:50:31.068725786 +0200
@@ -223,20 +223,20 @@
 
 /* RF level C/N lookup table */
 static const struct stv090x_tab stv090x_rf_tab[] = {
-	{  -5, 0xcaa1 }, /*  -5dBm */
-	{ -10, 0xc229 }, /* -10dBm */
-	{ -15, 0xbb08 }, /* -15dBm */
-	{ -20, 0xb4bc }, /* -20dBm */
-	{ -25, 0xad5a }, /* -25dBm */
-	{ -30, 0xa298 }, /* -30dBm */
-	{ -35, 0x98a8 }, /* -35dBm */
-	{ -40, 0x8389 }, /* -40dBm */
-	{ -45, 0x59be }, /* -45dBm */
-	{ -50, 0x3a14 }, /* -50dBm */
-	{ -55, 0x2d11 }, /* -55dBm */
-	{ -60, 0x210d }, /* -60dBm */
-	{ -65, 0xa14f }, /* -65dBm */
-	{ -70, 0x07aa }	 /* -70dBm */
+	{  -50, 0xcaa1 }, /*  -5dBm */
+	{ -100, 0xc229 }, /* -10dBm */
+	{ -150, 0xbb08 }, /* -15dBm */
+	{ -200, 0xb4bc }, /* -20dBm */
+	{ -250, 0xad5a }, /* -25dBm */
+	{ -300, 0xa298 }, /* -30dBm */
+	{ -350, 0x98a8 }, /* -35dBm */
+	{ -400, 0x8389 }, /* -40dBm */
+	{ -450, 0x59be }, /* -45dBm */
+	{ -500, 0x3a14 }, /* -50dBm */
+	{ -550, 0x2d11 }, /* -55dBm */
+	{ -600, 0x210d }, /* -60dBm */
+	{ -650, 0xa14f }, /* -65dBm */
+	{ -700, 0x07aa }  /* -70dBm */
 };
 
 
@@ -3509,11 +3509,16 @@
 	return DVBFE_ALGO_SEARCH_ERROR;
 }
 
+static int stv090x_read_signal_strength_dBm(struct dvb_frontend *fe);
+static int stv090x_read_cnr_dB(struct dvb_frontend *fe);
+
 static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
 {
 	struct stv090x_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	u32 reg, dstatus;
 	u8 search_state;
+	s32 val;
 
 	*status = 0;
 
@@ -3558,6 +3563,28 @@
 		break;
 	}
 
+	/* signal-strength */
+	if (*status & FE_HAS_SIGNAL) {
+		val= stv090x_read_signal_strength_dBm(fe); /* dBm * 10 */
+		c->strength.stat[0].scale = FE_SCALE_DECIBEL;
+		c->strength.stat[0].svalue = val * 100;
+	}
+	else {
+		c->strength.len = 1;
+		c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	}
+
+	/* CNR */
+	if (*status & FE_HAS_LOCK) {
+		val= stv090x_read_cnr_dB(fe); /* dB * 10 */
+		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+		c->cnr.stat[0].svalue = val * 100;
+	}
+	else {
+		c->cnr.len = 1;
+		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	}
+
 	return 0;
 }
 
@@ -3648,7 +3675,7 @@
 	return res;
 }
 
-static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+static int stv090x_read_signal_strength_dBm(struct dvb_frontend *fe)
 {
 	struct stv090x_state *state = fe->demodulator_priv;
 	u32 reg;
@@ -3667,12 +3694,21 @@
 		str = 0;
 	else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read)
 		str = -100;
+
+	return str;
+}
+
+static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+	s32 str;
+
+	str = stv090x_read_signal_strength_dBm(fe); /* dBm */
 	*strength = (str + 100) * 0xFFFF / 100;
 
 	return 0;
 }
 
-static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
+static int stv090x_read_cnr_dB(struct dvb_frontend *fe)
 {
 	struct stv090x_state *state = fe->demodulator_priv;
 	u32 reg_0, reg_1, reg, i;
@@ -3680,14 +3716,14 @@
 	u8 lock_f;
 	s32 div;
 	u32 last;
-
+#define CNR_LOOPS 1
 	switch (state->delsys) {
 	case STV090x_DVBS2:
 		reg = STV090x_READ_DEMOD(state, DSTATUS);
 		lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
 		if (lock_f) {
 			msleep(5);
-			for (i = 0; i < 16; i++) {
+			for (i = 0; i < CNR_LOOPS; i++) {
 				reg_1 = STV090x_READ_DEMOD(state, NNOSPLHT1);
 				val_1 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD);
 				reg_0 = STV090x_READ_DEMOD(state, NNOSPLHT0);
@@ -3695,14 +3731,13 @@
 				val  += MAKEWORD16(val_1, val_0);
 				msleep(1);
 			}
-			val /= 16;
+			val /= CNR_LOOPS;
 			last = ARRAY_SIZE(stv090x_s2cn_tab) - 1;
 			div = stv090x_s2cn_tab[last].real -
 			      stv090x_s2cn_tab[3].real;
 			val = stv090x_table_lookup(stv090x_s2cn_tab, last, val);
 			if (val < 0)
 				val = 0;
-			*cnr = val * 0xFFFF / div;
 		}
 		break;
 
@@ -3712,7 +3747,7 @@
 		lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
 		if (lock_f) {
 			msleep(5);
-			for (i = 0; i < 16; i++) {
+			for (i = 0; i < CNR_LOOPS; i++) {
 				reg_1 = STV090x_READ_DEMOD(state, NOSDATAT1);
 				val_1 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD);
 				reg_0 = STV090x_READ_DEMOD(state, NOSDATAT0);
@@ -3720,18 +3755,45 @@
 				val  += MAKEWORD16(val_1, val_0);
 				msleep(1);
 			}
-			val /= 16;
+			val /= CNR_LOOPS;
 			last = ARRAY_SIZE(stv090x_s1cn_tab) - 1;
 			div = stv090x_s1cn_tab[last].real -
 			      stv090x_s1cn_tab[0].real;
 			val = stv090x_table_lookup(stv090x_s1cn_tab, last, val);
-			*cnr = val * 0xFFFF / div;
 		}
 		break;
 	default:
 		break;
 	}
 
+	return val;
+}
+
+static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
+{
+	struct stv090x_state *state = fe->demodulator_priv;
+	u32 last;
+	s32 div;
+	s32 val = stv090x_read_cnr_dB(fe);
+
+	switch (state->delsys) {
+	case STV090x_DVBS2:
+		last = ARRAY_SIZE(stv090x_s2cn_tab) - 1;
+		div = stv090x_s2cn_tab[last].real -
+			stv090x_s2cn_tab[3].real;
+		*cnr = val * 0xFFFF / div;
+		break;
+	case STV090x_DVBS1:
+	case STV090x_DSS:
+		last = ARRAY_SIZE(stv090x_s1cn_tab) - 1;
+		div = stv090x_s1cn_tab[last].real -
+			 stv090x_s1cn_tab[0].real;
+		*cnr = val * 0xFFFF / div;
+		break;
+	default:
+		*cnr = 0;
+		break;
+	}
 	return 0;
 }
 
@@ -4686,6 +4748,7 @@
 {
 	struct stv090x_state *state = fe->demodulator_priv;
 	const struct stv090x_config *config = state->config;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	u32 reg;
 
 	if (state->internal->mclk == 0) {
@@ -4752,6 +4815,18 @@
 			goto err;
 	}
 
+	/* Init stats here to indicate which stats are supported */
+	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;
+	c->post_bit_error.len = 1;
+	c->post_bit_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->block_error.len = 1;
+	c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
 	return 0;
 
 err_gateoff:
@@ -4977,8 +5052,9 @@
 	.search				= stv090x_search,
 	.read_status			= stv090x_read_status,
 	.read_ber			= stv090x_read_per,
-	.read_signal_strength		= stv090x_read_signal_strength,
-	.read_snr			= stv090x_read_cnr,
+
+//	.read_signal_strength		= stv090x_read_signal_strength,
+//	.read_snr			= stv090x_read_cnr,
 };
 
 static struct dvb_frontend *stv090x_get_dvb_frontend(struct i2c_client *client)
openSUSE Build Service is sponsored by