[TEST] Regarding m88rc2000 i2c gate operation, SNR, BER and others

Message ID 1682436.JdK20qceHM@useri (mailing list archive)
State RFC, archived
Headers

Commit Message

Igor M. Liplianin May 9, 2012, 11:54 a.m. UTC
  Malcolm,

I made SNR, BER, UCB and signal level code for m88rc2000, but my cards show 
them correctly only if I made changes in m88rs2000_tuner_read function.
Analyzing USB logs I found that register 0x81 never set to 0x85 value.
It is always set to 0x84 regardless of read or write operation to tuner.
I was wondering is this my hardware specific? Can you test you cards with 
attached patch?

Igor
  

Comments

Malcolm Priestley May 9, 2012, 9:02 p.m. UTC | #1
On Wed, 2012-05-09 at 04:54 -0700, Igor M. Liplianin wrote:
> Malcolm,
> 
> I made SNR, BER, UCB and signal level code for m88rc2000, but my cards show 
> them correctly only if I made changes in m88rs2000_tuner_read function.
> Analyzing USB logs I found that register 0x81 never set to 0x85 value.
> It is always set to 0x84 regardless of read or write operation to tuner.
> I was wondering is this my hardware specific? Can you test you cards with 
> attached patch?
> 
> Igor
Hi Igor

I have been testing the patch this evening and have found no problems.

I just need to create in lmedm04 callbacks for m88rs2000_read_snr and
m88rs2000_read_ber as these cannot be called while the device is
streaming. It looks like they are present in the interrupt callback.

Register 0x81 works with either 0x84 or 0x85 on read. What I did notice
if 0x85 is used on writes the device becomes completely unresponsive and
needs to be replugged. So it is safer to use 0x84.

I will try and get the patch for lmedm04 ready in the next few days.

Regards


Malcolm
  
> differences between files attachment (snrber.patch)
> diff --git a/drivers/media/dvb/frontends/m88rs2000.c b/drivers/media/dvb/frontends/m88rs2000.c
> index f6d6e39..f5ece59 100644
> --- a/drivers/media/dvb/frontends/m88rs2000.c
> +++ b/drivers/media/dvb/frontends/m88rs2000.c
> @@ -143,7 +143,7 @@ static u8 m88rs2000_demod_read(struct m88rs2000_state *state, u8 reg)
>  
>  static u8 m88rs2000_tuner_read(struct m88rs2000_state *state, u8 reg)
>  {
> -	m88rs2000_demod_write(state, 0x81, 0x85);
> +	m88rs2000_demod_write(state, 0x81, 0x84);
>  	udelay(10);
>  	return m88rs2000_readreg(state, 0, reg);
>  }
> @@ -492,33 +492,81 @@ static int m88rs2000_read_status(struct dvb_frontend *fe, fe_status_t *status)
>  	return 0;
>  }
>  
> -/* Extact code for these unknown but lmedm04 driver uses interupt callbacks */
> -
>  static int m88rs2000_read_ber(struct dvb_frontend *fe, u32 *ber)
>  {
> -	deb_info("m88rs2000_read_ber %d\n", *ber);
> -	*ber = 0;
> +	struct m88rs2000_state *state = fe->demodulator_priv;
> +	u8 tmp0, tmp1;
> +
> +	m88rs2000_demod_write(state, 0x9a, 0x30);
> +	tmp0 = m88rs2000_demod_read(state, 0xd8);
> +	if ((tmp0 & 0x10) != 0) {
> +		m88rs2000_demod_write(state, 0x9a, 0xb0);
> +		*ber = 0xffffffff;
> +		return 0;
> +	}
> +
> +	*ber = (m88rs2000_demod_read(state, 0xd7) << 8) |
> +		m88rs2000_demod_read(state, 0xd6);
> +
> +	tmp1 = m88rs2000_demod_read(state, 0xd9);
> +	m88rs2000_demod_write(state, 0xd9, (tmp1 & ~7) | 4);
> +	/* needs twice */
> +	m88rs2000_demod_write(state, 0xd8, (tmp0 & ~8) | 0x30);
> +	m88rs2000_demod_write(state, 0xd8, (tmp0 & ~8) | 0x30);
> +	m88rs2000_demod_write(state, 0x9a, 0xb0);
> +
>  	return 0;
>  }
>  
>  static int m88rs2000_read_signal_strength(struct dvb_frontend *fe,
> -	u16 *strength)
> +						u16 *signal_strength)
>  {
> -	*strength = 0;
> +	struct m88rs2000_state *state = fe->demodulator_priv;
> +	u8 rfg, bbg, gain, strength;
> +
> +	rfg = m88rs2000_tuner_read(state, 0x3d) & 0x1f;
> +	bbg = m88rs2000_tuner_read(state, 0x21) & 0x1f;
> +	gain = rfg * 2 + bbg * 3;
> +
> +	if (gain > 80)
> +		strength = 0;
> +	else if (gain > 65)
> +		strength = 4 * (80 - gain);
> +	else if (gain > 50)
> +		strength = 65 + 4 * (65 - gain) / 3;
> +	else
> +		strength = 85 + 2 * (50 - gain) / 3;
> +
> +	*signal_strength = strength * 655;
> +
> +	deb_info("%s: rfg, bbg / gain = %d, %d, %d\n",
> +		__func__, rfg, bbg, gain);
> +
>  	return 0;
>  }
>  
>  static int m88rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
>  {
> -	deb_info("m88rs2000_read_snr %d\n", *snr);
> -	*snr = 0;
> +	struct m88rs2000_state *state = fe->demodulator_priv;
> +
> +	*snr = 512 * m88rs2000_demod_read(state, 0x65);
> +
>  	return 0;
>  }
>  
>  static int m88rs2000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
>  {
> -	deb_info("m88rs2000_read_ber %d\n", *ucblocks);
> -	*ucblocks = 0;
> +	struct m88rs2000_state *state = fe->demodulator_priv;
> +	u8 tmp;
> +
> +	*ucblocks = (m88rs2000_demod_read(state, 0xd5) << 8) |
> +			m88rs2000_demod_read(state, 0xd4);
> +	tmp = m88rs2000_demod_read(state, 0xd8);
> +	m88rs2000_demod_write(state, 0xd8, tmp & ~0x20);
> +	/* needs two times */
> +	m88rs2000_demod_write(state, 0xd8, tmp | 0x20);
> +	m88rs2000_demod_write(state, 0xd8, tmp | 0x20);
> +
>  	return 0;
>  }
>  


--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
  
Malcolm Priestley July 1, 2012, 10:16 a.m. UTC | #2
On Wed, 2012-05-09 at 04:54 -0700, Igor M. Liplianin wrote:
> Malcolm,
> 
> I made SNR, BER, UCB and signal level code for m88rc2000, but my cards show 
> them correctly only if I made changes in m88rs2000_tuner_read function.
> Analyzing USB logs I found that register 0x81 never set to 0x85 value.
> It is always set to 0x84 regardless of read or write operation to tuner.
> I was wondering is this my hardware specific? Can you test you cards with 
> attached patch?
> 
> Igor


Hi Igor

I have no problems with patch, please could you add your signoff

I you and me have followed a typo error with m88rc2000 for m88rs2000 in
the title.

This patch and patch 

http://patchwork.linuxtv.org/patch/11235/

can go upstream

Regards


Malcolm



> differences between files attachment (snrber.patch)
> diff --git a/drivers/media/dvb/frontends/m88rs2000.c b/drivers/media/dvb/frontends/m88rs2000.c
> index f6d6e39..f5ece59 100644
> --- a/drivers/media/dvb/frontends/m88rs2000.c
> +++ b/drivers/media/dvb/frontends/m88rs2000.c
> @@ -143,7 +143,7 @@ static u8 m88rs2000_demod_read(struct m88rs2000_state *state, u8 reg)
>  
>  static u8 m88rs2000_tuner_read(struct m88rs2000_state *state, u8 reg)
>  {
> -	m88rs2000_demod_write(state, 0x81, 0x85);
> +	m88rs2000_demod_write(state, 0x81, 0x84);
>  	udelay(10);
>  	return m88rs2000_readreg(state, 0, reg);
>  }
> @@ -492,33 +492,81 @@ static int m88rs2000_read_status(struct dvb_frontend *fe, fe_status_t *status)
>  	return 0;
>  }
>  
> -/* Extact code for these unknown but lmedm04 driver uses interupt callbacks */
> -
>  static int m88rs2000_read_ber(struct dvb_frontend *fe, u32 *ber)
>  {
> -	deb_info("m88rs2000_read_ber %d\n", *ber);
> -	*ber = 0;
> +	struct m88rs2000_state *state = fe->demodulator_priv;
> +	u8 tmp0, tmp1;
> +
> +	m88rs2000_demod_write(state, 0x9a, 0x30);
> +	tmp0 = m88rs2000_demod_read(state, 0xd8);
> +	if ((tmp0 & 0x10) != 0) {
> +		m88rs2000_demod_write(state, 0x9a, 0xb0);
> +		*ber = 0xffffffff;
> +		return 0;
> +	}
> +
> +	*ber = (m88rs2000_demod_read(state, 0xd7) << 8) |
> +		m88rs2000_demod_read(state, 0xd6);
> +
> +	tmp1 = m88rs2000_demod_read(state, 0xd9);
> +	m88rs2000_demod_write(state, 0xd9, (tmp1 & ~7) | 4);
> +	/* needs twice */
> +	m88rs2000_demod_write(state, 0xd8, (tmp0 & ~8) | 0x30);
> +	m88rs2000_demod_write(state, 0xd8, (tmp0 & ~8) | 0x30);
> +	m88rs2000_demod_write(state, 0x9a, 0xb0);
> +
>  	return 0;
>  }
>  
>  static int m88rs2000_read_signal_strength(struct dvb_frontend *fe,
> -	u16 *strength)
> +						u16 *signal_strength)
>  {
> -	*strength = 0;
> +	struct m88rs2000_state *state = fe->demodulator_priv;
> +	u8 rfg, bbg, gain, strength;
> +
> +	rfg = m88rs2000_tuner_read(state, 0x3d) & 0x1f;
> +	bbg = m88rs2000_tuner_read(state, 0x21) & 0x1f;
> +	gain = rfg * 2 + bbg * 3;
> +
> +	if (gain > 80)
> +		strength = 0;
> +	else if (gain > 65)
> +		strength = 4 * (80 - gain);
> +	else if (gain > 50)
> +		strength = 65 + 4 * (65 - gain) / 3;
> +	else
> +		strength = 85 + 2 * (50 - gain) / 3;
> +
> +	*signal_strength = strength * 655;
> +
> +	deb_info("%s: rfg, bbg / gain = %d, %d, %d\n",
> +		__func__, rfg, bbg, gain);
> +
>  	return 0;
>  }
>  
>  static int m88rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
>  {
> -	deb_info("m88rs2000_read_snr %d\n", *snr);
> -	*snr = 0;
> +	struct m88rs2000_state *state = fe->demodulator_priv;
> +
> +	*snr = 512 * m88rs2000_demod_read(state, 0x65);
> +
>  	return 0;
>  }
>  
>  static int m88rs2000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
>  {
> -	deb_info("m88rs2000_read_ber %d\n", *ucblocks);
> -	*ucblocks = 0;
> +	struct m88rs2000_state *state = fe->demodulator_priv;
> +	u8 tmp;
> +
> +	*ucblocks = (m88rs2000_demod_read(state, 0xd5) << 8) |
> +			m88rs2000_demod_read(state, 0xd4);
> +	tmp = m88rs2000_demod_read(state, 0xd8);
> +	m88rs2000_demod_write(state, 0xd8, tmp & ~0x20);
> +	/* needs two times */
> +	m88rs2000_demod_write(state, 0xd8, tmp | 0x20);
> +	m88rs2000_demod_write(state, 0xd8, tmp | 0x20);
> +
>  	return 0;
>  }
>  


--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
  

Patch

diff --git a/drivers/media/dvb/frontends/m88rs2000.c b/drivers/media/dvb/frontends/m88rs2000.c
index f6d6e39..f5ece59 100644
--- a/drivers/media/dvb/frontends/m88rs2000.c
+++ b/drivers/media/dvb/frontends/m88rs2000.c
@@ -143,7 +143,7 @@  static u8 m88rs2000_demod_read(struct m88rs2000_state *state, u8 reg)
 
 static u8 m88rs2000_tuner_read(struct m88rs2000_state *state, u8 reg)
 {
-	m88rs2000_demod_write(state, 0x81, 0x85);
+	m88rs2000_demod_write(state, 0x81, 0x84);
 	udelay(10);
 	return m88rs2000_readreg(state, 0, reg);
 }
@@ -492,33 +492,81 @@  static int m88rs2000_read_status(struct dvb_frontend *fe, fe_status_t *status)
 	return 0;
 }
 
-/* Extact code for these unknown but lmedm04 driver uses interupt callbacks */
-
 static int m88rs2000_read_ber(struct dvb_frontend *fe, u32 *ber)
 {
-	deb_info("m88rs2000_read_ber %d\n", *ber);
-	*ber = 0;
+	struct m88rs2000_state *state = fe->demodulator_priv;
+	u8 tmp0, tmp1;
+
+	m88rs2000_demod_write(state, 0x9a, 0x30);
+	tmp0 = m88rs2000_demod_read(state, 0xd8);
+	if ((tmp0 & 0x10) != 0) {
+		m88rs2000_demod_write(state, 0x9a, 0xb0);
+		*ber = 0xffffffff;
+		return 0;
+	}
+
+	*ber = (m88rs2000_demod_read(state, 0xd7) << 8) |
+		m88rs2000_demod_read(state, 0xd6);
+
+	tmp1 = m88rs2000_demod_read(state, 0xd9);
+	m88rs2000_demod_write(state, 0xd9, (tmp1 & ~7) | 4);
+	/* needs twice */
+	m88rs2000_demod_write(state, 0xd8, (tmp0 & ~8) | 0x30);
+	m88rs2000_demod_write(state, 0xd8, (tmp0 & ~8) | 0x30);
+	m88rs2000_demod_write(state, 0x9a, 0xb0);
+
 	return 0;
 }
 
 static int m88rs2000_read_signal_strength(struct dvb_frontend *fe,
-	u16 *strength)
+						u16 *signal_strength)
 {
-	*strength = 0;
+	struct m88rs2000_state *state = fe->demodulator_priv;
+	u8 rfg, bbg, gain, strength;
+
+	rfg = m88rs2000_tuner_read(state, 0x3d) & 0x1f;
+	bbg = m88rs2000_tuner_read(state, 0x21) & 0x1f;
+	gain = rfg * 2 + bbg * 3;
+
+	if (gain > 80)
+		strength = 0;
+	else if (gain > 65)
+		strength = 4 * (80 - gain);
+	else if (gain > 50)
+		strength = 65 + 4 * (65 - gain) / 3;
+	else
+		strength = 85 + 2 * (50 - gain) / 3;
+
+	*signal_strength = strength * 655;
+
+	deb_info("%s: rfg, bbg / gain = %d, %d, %d\n",
+		__func__, rfg, bbg, gain);
+
 	return 0;
 }
 
 static int m88rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
 {
-	deb_info("m88rs2000_read_snr %d\n", *snr);
-	*snr = 0;
+	struct m88rs2000_state *state = fe->demodulator_priv;
+
+	*snr = 512 * m88rs2000_demod_read(state, 0x65);
+
 	return 0;
 }
 
 static int m88rs2000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 {
-	deb_info("m88rs2000_read_ber %d\n", *ucblocks);
-	*ucblocks = 0;
+	struct m88rs2000_state *state = fe->demodulator_priv;
+	u8 tmp;
+
+	*ucblocks = (m88rs2000_demod_read(state, 0xd5) << 8) |
+			m88rs2000_demod_read(state, 0xd4);
+	tmp = m88rs2000_demod_read(state, 0xd8);
+	m88rs2000_demod_write(state, 0xd8, tmp & ~0x20);
+	/* needs two times */
+	m88rs2000_demod_write(state, 0xd8, tmp | 0x20);
+	m88rs2000_demod_write(state, 0xd8, tmp | 0x20);
+
 	return 0;
 }