public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] media: lgdt3306a: check the register reads for errors
@ 2026-03-16 20:44 Sergey Shtylyov
  0 siblings, 0 replies; only message in thread
From: Sergey Shtylyov @ 2026-03-16 20:44 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, linux-media
  Cc: Sergey Shtylyov, Michael Ira Krufky, Fred Richter, Brad Love

When lgdt3306a_read_reg() fails its parameter val will probably point to
a garbage value which we don't really want to write back (modified) with
lgdt3306a_write_reg(). Add lgdt3306a_read_reg() result checks where they
were missing.

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Fixes: b63b36fa44d0 ("[media] DVB: add support for LG Electronics LGDT3306A ATSC/QAM-B Demodulator")
Fixes: 4c7c3f9b1a85 ("media: lgdt3306a: QAM streaming improvement")
Signed-off-by: Sergey Shtylyov <s.shtylyov@auroraos.dev>

---
The patch is against the fixes branch of the linuxtv.org/media.git repo...

 drivers/media/dvb-frontends/lgdt3306a.c | 56 +++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c
index b6a66e122ed5..03e598d73d9f 100644
--- a/drivers/media/dvb-frontends/lgdt3306a.c
+++ b/drivers/media/dvb-frontends/lgdt3306a.c
@@ -387,6 +387,8 @@ static int lgdt3306a_set_vsb(struct lgdt3306a_state *state)
 
 	/* 0. Spectrum inversion detection manual; spectrum inverted */
 	ret = lgdt3306a_read_reg(state, 0x0002, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xf7; /* SPECINVAUTO Off */
 	val |= 0x04; /* SPECINV On */
 	ret = lgdt3306a_write_reg(state, 0x0002, val);
@@ -400,6 +402,8 @@ static int lgdt3306a_set_vsb(struct lgdt3306a_state *state)
 
 	/* 2. Bandwidth mode for VSB(6MHz) */
 	ret = lgdt3306a_read_reg(state, 0x0009, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xe3;
 	val |= 0x0c; /* STDOPDETTMODE[2:0]=3 */
 	ret = lgdt3306a_write_reg(state, 0x0009, val);
@@ -408,6 +412,8 @@ static int lgdt3306a_set_vsb(struct lgdt3306a_state *state)
 
 	/* 3. QAM mode detection mode(None) */
 	ret = lgdt3306a_read_reg(state, 0x0009, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xfc; /* STDOPDETCMODE[1:0]=0 */
 	ret = lgdt3306a_write_reg(state, 0x0009, val);
 	if (lg_chkerr(ret))
@@ -415,6 +421,8 @@ static int lgdt3306a_set_vsb(struct lgdt3306a_state *state)
 
 	/* 4. ADC sampling frequency rate(2x sampling) */
 	ret = lgdt3306a_read_reg(state, 0x000d, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xbf; /* SAMPLING4XFEN=0 */
 	ret = lgdt3306a_write_reg(state, 0x000d, val);
 	if (lg_chkerr(ret))
@@ -477,6 +485,8 @@ static int lgdt3306a_set_vsb(struct lgdt3306a_state *state)
 #endif
 
 	ret = lgdt3306a_read_reg(state, 0x001e, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0x0f;
 	val |= 0xa0;
 	ret = lgdt3306a_write_reg(state, 0x001e, val);
@@ -486,45 +496,63 @@ static int lgdt3306a_set_vsb(struct lgdt3306a_state *state)
 	ret = lgdt3306a_write_reg(state, 0x0023, 0xFF);
 
 	ret = lgdt3306a_read_reg(state, 0x211f, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xef;
 	ret = lgdt3306a_write_reg(state, 0x211f, val);
 
 	ret = lgdt3306a_write_reg(state, 0x2173, 0x01);
 
 	ret = lgdt3306a_read_reg(state, 0x1061, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xf8;
 	val |= 0x04;
 	ret = lgdt3306a_write_reg(state, 0x1061, val);
 
 	ret = lgdt3306a_read_reg(state, 0x103d, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xcf;
 	ret = lgdt3306a_write_reg(state, 0x103d, val);
 
 	ret = lgdt3306a_write_reg(state, 0x2122, 0x40);
 
 	ret = lgdt3306a_read_reg(state, 0x2141, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0x3f;
 	ret = lgdt3306a_write_reg(state, 0x2141, val);
 
 	ret = lgdt3306a_read_reg(state, 0x2135, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0x0f;
 	val |= 0x70;
 	ret = lgdt3306a_write_reg(state, 0x2135, val);
 
 	ret = lgdt3306a_read_reg(state, 0x0003, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xf7;
 	ret = lgdt3306a_write_reg(state, 0x0003, val);
 
 	ret = lgdt3306a_read_reg(state, 0x001c, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0x7f;
 	ret = lgdt3306a_write_reg(state, 0x001c, val);
 
 	/* 6. EQ step size */
 	ret = lgdt3306a_read_reg(state, 0x2179, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xf8;
 	ret = lgdt3306a_write_reg(state, 0x2179, val);
 
 	ret = lgdt3306a_read_reg(state, 0x217a, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xf8;
 	ret = lgdt3306a_write_reg(state, 0x217a, val);
 
@@ -552,6 +580,8 @@ static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation)
 
 	/* 1a. Spectrum inversion detection to Auto */
 	ret = lgdt3306a_read_reg(state, 0x0002, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xfb; /* SPECINV Off */
 	val |= 0x08; /* SPECINVAUTO On */
 	ret = lgdt3306a_write_reg(state, 0x0002, val);
@@ -560,6 +590,8 @@ static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation)
 
 	/* 2. Bandwidth mode for QAM */
 	ret = lgdt3306a_read_reg(state, 0x0009, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xe3; /* STDOPDETTMODE[2:0]=0 VSB Off */
 	ret = lgdt3306a_write_reg(state, 0x0009, val);
 	if (lg_chkerr(ret))
@@ -567,6 +599,8 @@ static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation)
 
 	/* 3. : 64QAM/256QAM detection(manual, auto) */
 	ret = lgdt3306a_read_reg(state, 0x0009, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xfc;
 	/* Check for forced Manual modulation modes; otherwise always "auto" */
 	if(forced_manual && (modulation != QAM_AUTO)){
@@ -580,6 +614,8 @@ static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation)
 
 	/* 3a. : 64QAM/256QAM selection for manual */
 	ret = lgdt3306a_read_reg(state, 0x101a, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xf8;
 	if (modulation == QAM_64)
 		val |= 0x02; /* QMDQMODE[2:0]=2=QAM64 */
@@ -592,6 +628,8 @@ static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation)
 
 	/* 4. ADC sampling frequency rate(4x sampling) */
 	ret = lgdt3306a_read_reg(state, 0x000d, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xbf;
 	val |= 0x40; /* SAMPLING4XFEN=1 */
 	ret = lgdt3306a_write_reg(state, 0x000d, val);
@@ -600,6 +638,8 @@ static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation)
 
 	/* 5. No AICC operation in QAM mode */
 	ret = lgdt3306a_read_reg(state, 0x0024, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0x00;
 	ret = lgdt3306a_write_reg(state, 0x0024, val);
 	if (lg_chkerr(ret))
@@ -607,6 +647,8 @@ static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation)
 
 	/* 5.1 V0.36 SRDCHKALWAYS : For better QAM detection */
 	ret = lgdt3306a_read_reg(state, 0x000a, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xfd;
 	val |= 0x02;
 	ret = lgdt3306a_write_reg(state, 0x000a, val);
@@ -615,6 +657,8 @@ static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation)
 
 	/* 5.2 V0.36 Control of "no signal" detector function */
 	ret = lgdt3306a_read_reg(state, 0x2849, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xdf;
 	ret = lgdt3306a_write_reg(state, 0x2849, val);
 	if (lg_chkerr(ret))
@@ -622,6 +666,8 @@ static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation)
 
 	/* 5.3 Fix for Blonder Tongue HDE-2H-QAM and AQM modulators */
 	ret = lgdt3306a_read_reg(state, 0x302b, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0x7f;  /* SELFSYNCFINDEN_CQS=0; disable auto reset */
 	ret = lgdt3306a_write_reg(state, 0x302b, val);
 	if (lg_chkerr(ret))
@@ -926,29 +972,39 @@ static int lgdt3306a_init(struct dvb_frontend *fe)
 
 	/* 10a. VSB TR BW gear shift initial step */
 	ret = lgdt3306a_read_reg(state, 0x103c, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0x0f;
 	val |= 0x20; /* SAMGSAUTOSTL_V[3:0] = 2 */
 	ret = lgdt3306a_write_reg(state, 0x103c, val);
 
 	/* 10b. Timing offset calibration in low temperature for VSB */
 	ret = lgdt3306a_read_reg(state, 0x103d, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xfc;
 	val |= 0x03;
 	ret = lgdt3306a_write_reg(state, 0x103d, val);
 
 	/* 10c. Timing offset calibration in low temperature for QAM */
 	ret = lgdt3306a_read_reg(state, 0x1036, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xf0;
 	val |= 0x0c;
 	ret = lgdt3306a_write_reg(state, 0x1036, val);
 
 	/* 11. Using the imaginary part of CIR in CIR loading */
 	ret = lgdt3306a_read_reg(state, 0x211f, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xef; /* do not use imaginary of CIR */
 	ret = lgdt3306a_write_reg(state, 0x211f, val);
 
 	/* 12. Control of no signal detector function */
 	ret = lgdt3306a_read_reg(state, 0x2849, &val);
+	if (lg_chkerr(ret))
+		goto fail;
 	val &= 0xef; /* NOUSENOSIGDET=0, enable no signal detector */
 	ret = lgdt3306a_write_reg(state, 0x2849, val);
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-03-16 20:46 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-16 20:44 [PATCH] media: lgdt3306a: check the register reads for errors Sergey Shtylyov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox