linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] Astrometa DVB USB support
@ 2014-11-12  4:23 Antti Palosaari
  2014-11-12  4:23 ` [PATCH 1/8] r820t: add DVB-C config Antti Palosaari
                   ` (7 more replies)
  0 siblings, 8 replies; 18+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:23 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

There is 2 device versions. Other has Panasonic MN88472 demod and
the other Panasonic MN88473 demod.

Both demod drivers will go to staging due to multiple problems.

Antti Palosaari (8):
  r820t: add DVB-C config
  rtl2832: implement PIP mode
  rtl28xxu: enable demod ADC only when needed
  rtl28xxu: add support for Panasonic MN88472 slave demod
  rtl28xxu: add support for Panasonic MN88473 slave demod
  rtl28xxu: rename tuner I2C client pointer
  rtl28xxu: remove unused SDR attach logic
  rtl28xxu: add SDR module for devices having R828D tuner

 drivers/media/dvb-frontends/rtl2832.c   |  42 +++++-
 drivers/media/tuners/r820t.c            |  12 ++
 drivers/media/usb/dvb-usb-v2/Kconfig    |   2 +
 drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 239 +++++++++++++++++++++++---------
 drivers/media/usb/dvb-usb-v2/rtl28xxu.h |   8 +-
 5 files changed, 235 insertions(+), 68 deletions(-)

-- 
http://palosaari.fi/


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/8] r820t: add DVB-C config
  2014-11-12  4:23 [PATCH 0/8] Astrometa DVB USB support Antti Palosaari
@ 2014-11-12  4:23 ` Antti Palosaari
  2014-11-12  4:23 ` [PATCH 2/8] rtl2832: implement PIP mode Antti Palosaari
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 18+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:23 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

Add config values for SYS_DVBC_ANNEX_A.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/tuners/r820t.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c
index a759742..8e040cf 100644
--- a/drivers/media/tuners/r820t.c
+++ b/drivers/media/tuners/r820t.c
@@ -959,6 +959,18 @@ static int r820t_set_tv_standard(struct r820t_priv *priv,
 		lt_att = 0x00;		/* r31[7], lt att enable */
 		flt_ext_widest = 0x00;	/* r15[7]: flt_ext_wide off */
 		polyfil_cur = 0x60;	/* r25[6:5]:min */
+	} else if (delsys == SYS_DVBC_ANNEX_A) {
+		if_khz = 5070;
+		filt_cal_lo = 73500;
+		filt_gain = 0x10;	/* +3db, 6mhz on */
+		img_r = 0x00;		/* image negative */
+		filt_q = 0x10;		/* r10[4]:low q(1'b1) */
+		hp_cor = 0x0b;		/* 1.7m disable, +0cap, 1.0mhz */
+		ext_enable = 0x40;	/* r30[6]=1 ext enable; r30[5]:1 ext at lna max-1 */
+		loop_through = 0x00;	/* r5[7], lt on */
+		lt_att = 0x00;		/* r31[7], lt att enable */
+		flt_ext_widest = 0x00;	/* r15[7]: flt_ext_wide off */
+		polyfil_cur = 0x60;	/* r25[6:5]:min */
 	} else {
 		if (bw <= 6) {
 			if_khz = 3570;
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 2/8] rtl2832: implement PIP mode
  2014-11-12  4:23 [PATCH 0/8] Astrometa DVB USB support Antti Palosaari
  2014-11-12  4:23 ` [PATCH 1/8] r820t: add DVB-C config Antti Palosaari
@ 2014-11-12  4:23 ` Antti Palosaari
  2014-11-14 19:34   ` Mauro Carvalho Chehab
  2014-11-12  4:23 ` [PATCH 3/8] rtl28xxu: enable demod ADC only when needed Antti Palosaari
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 18+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:23 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

Implement PIP mode to stream from slave demodulator. PIP mode is
enabled when .set_frontend is called with RF frequency 0, otherwise
normal demod mode is enabled.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/dvb-frontends/rtl2832.c | 42 ++++++++++++++++++++++++++++++++---
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c
index eb737cf..a58b456 100644
--- a/drivers/media/dvb-frontends/rtl2832.c
+++ b/drivers/media/dvb-frontends/rtl2832.c
@@ -258,13 +258,11 @@ static int rtl2832_rd_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
 	return rtl2832_rd(priv, reg, val, len);
 }
 
-#if 0 /* currently not used */
 /* write single register */
 static int rtl2832_wr_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 val)
 {
 	return rtl2832_wr_regs(priv, reg, page, &val, 1);
 }
-#endif
 
 /* read single register */
 static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val)
@@ -595,6 +593,44 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
 			"%s: frequency=%d bandwidth_hz=%d inversion=%d\n",
 			__func__, c->frequency, c->bandwidth_hz, c->inversion);
 
+	/* PIP mode */
+	if (c->frequency == 0) {
+		dev_dbg(&priv->i2c->dev, "%s: setting PIP mode\n", __func__);
+		ret = rtl2832_wr_regs(priv, 0x0c, 1, "\x5f\xff", 2);
+		if (ret)
+			goto err;
+
+		ret = rtl2832_wr_demod_reg(priv, DVBT_PIP_ON, 0x1);
+		if (ret)
+			goto err;
+
+		ret = rtl2832_wr_reg(priv, 0xbc, 0, 0x18);
+		if (ret)
+			goto err;
+
+		ret = rtl2832_wr_reg(priv, 0x22, 0, 0x01);
+		if (ret)
+			goto err;
+
+		ret = rtl2832_wr_reg(priv, 0x26, 0, 0x1f);
+		if (ret)
+			goto err;
+
+		ret = rtl2832_wr_reg(priv, 0x27, 0, 0xff);
+		if (ret)
+			goto err;
+
+		ret = rtl2832_wr_regs(priv, 0x92, 1, "\x7f\xf7\xff", 3);
+		if (ret)
+			goto err;
+
+		goto exit_soft_reset;
+	} else {
+		ret = rtl2832_wr_regs(priv, 0x92, 1, "\x00\x0f\xff", 3);
+		if (ret)
+			goto err;
+	}
+
 	/* program tuner */
 	if (fe->ops.tuner_ops.set_params)
 		fe->ops.tuner_ops.set_params(fe);
@@ -661,7 +697,7 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
-
+exit_soft_reset:
 	/* soft reset */
 	ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
 	if (ret)
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 3/8] rtl28xxu: enable demod ADC only when needed
  2014-11-12  4:23 [PATCH 0/8] Astrometa DVB USB support Antti Palosaari
  2014-11-12  4:23 ` [PATCH 1/8] r820t: add DVB-C config Antti Palosaari
  2014-11-12  4:23 ` [PATCH 2/8] rtl2832: implement PIP mode Antti Palosaari
@ 2014-11-12  4:23 ` Antti Palosaari
  2014-11-12  4:23 ` [PATCH 4/8] rtl28xxu: add support for Panasonic MN88472 slave demod Antti Palosaari
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 18+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:23 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

Enable integrated demod ADC only when demod is used. Keep integrated
demod ADC disabled when external demod is used. This fixes corrupted
stream in a case external demod was used.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 37 ++++++++++++++++++++++-----------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index 27b1e03..5ea52c7 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -1201,13 +1201,6 @@ static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff)
 		if (ret)
 			goto err;
 
-		mdelay(5);
-
-		/* enable ADC */
-		ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x48, 0x48);
-		if (ret)
-			goto err;
-
 		/* streaming EP: clear stall & reset */
 		ret = rtl28xx_wr_regs(d, USB_EPA_CTL, "\x00\x00", 2);
 		if (ret)
@@ -1222,11 +1215,6 @@ static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff)
 		if (ret)
 			goto err;
 
-		/* disable ADC */
-		ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x00, 0x48);
-		if (ret)
-			goto err;
-
 		/* disable PLL */
 		ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x00, 0x80);
 		if (ret)
@@ -1244,6 +1232,30 @@ err:
 	return ret;
 }
 
+static int rtl2832u_frontend_ctrl(struct dvb_frontend *fe, int onoff)
+{
+	struct dvb_usb_device *d = fe_to_d(fe);
+	int ret;
+	u8 val;
+
+	dev_dbg(&d->udev->dev, "%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+
+	/* control internal demod ADC */
+	if (fe->id == 0 && onoff)
+		val = 0x48; /* enable ADC */
+	else
+		val = 0x00; /* disable ADC */
+
+	ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, val, 0x48);
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
+}
+
 #if IS_ENABLED(CONFIG_RC_CORE)
 static int rtl2831u_rc_query(struct dvb_usb_device *d)
 {
@@ -1467,6 +1479,7 @@ static const struct dvb_usb_device_properties rtl2832u_props = {
 	.size_of_priv = sizeof(struct rtl28xxu_priv),
 
 	.power_ctrl = rtl2832u_power_ctrl,
+	.frontend_ctrl = rtl2832u_frontend_ctrl,
 	.i2c_algo = &rtl28xxu_i2c_algo,
 	.read_config = rtl2832u_read_config,
 	.frontend_attach = rtl2832u_frontend_attach,
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 4/8] rtl28xxu: add support for Panasonic MN88472 slave demod
  2014-11-12  4:23 [PATCH 0/8] Astrometa DVB USB support Antti Palosaari
                   ` (2 preceding siblings ...)
  2014-11-12  4:23 ` [PATCH 3/8] rtl28xxu: enable demod ADC only when needed Antti Palosaari
@ 2014-11-12  4:23 ` Antti Palosaari
  2014-11-14 19:39   ` Mauro Carvalho Chehab
  2014-11-12  4:23 ` [PATCH 5/8] rtl28xxu: add support for Panasonic MN88473 " Antti Palosaari
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 18+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:23 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

There is RTL2832P devices having extra MN88472 demodulator. This
patch add support for such configuration. Logically MN88472 slave
demodulator is connected to RTL2832 master demodulator, both I2C
bus and TS input. RTL2832 is integrated to RTL2832U and RTL2832P
chips. Chip version RTL2832P has extra TS interface for connecting
slave demodulator.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/usb/dvb-usb-v2/Kconfig    |   1 +
 drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 143 +++++++++++++++++++++++++-------
 drivers/media/usb/dvb-usb-v2/rtl28xxu.h |   5 ++
 3 files changed, 118 insertions(+), 31 deletions(-)

diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig
index 7423033..9050933 100644
--- a/drivers/media/usb/dvb-usb-v2/Kconfig
+++ b/drivers/media/usb/dvb-usb-v2/Kconfig
@@ -130,6 +130,7 @@ config DVB_USB_RTL28XXU
 	select DVB_RTL2830
 	select DVB_RTL2832
 	select DVB_RTL2832_SDR if (MEDIA_SUBDRV_AUTOSELECT && MEDIA_SDR_SUPPORT)
+	select DVB_MN88472 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index 5ea52c7..e3c20f4 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -24,6 +24,7 @@
 
 #include "rtl2830.h"
 #include "rtl2832.h"
+#include "mn88472.h"
 
 #include "qt1010.h"
 #include "mt2060.h"
@@ -420,6 +421,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
 	struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf};
 	struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 1, buf};
 	struct rtl28xxu_req req_r828d = {0x0074, CMD_I2C_RD, 1, buf};
+	struct rtl28xxu_req req_mn88472 = {0xff38, CMD_I2C_RD, 1, buf};
 
 	dev_dbg(&d->udev->dev, "%s:\n", __func__);
 
@@ -449,7 +451,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
 	if (ret == 0 && buf[0] == 0xa1) {
 		priv->tuner = TUNER_RTL2832_FC0012;
 		priv->tuner_name = "FC0012";
-		goto found;
+		goto tuner_found;
 	}
 
 	/* check FC0013 ID register; reg=00 val=a3 */
@@ -457,7 +459,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
 	if (ret == 0 && buf[0] == 0xa3) {
 		priv->tuner = TUNER_RTL2832_FC0013;
 		priv->tuner_name = "FC0013";
-		goto found;
+		goto tuner_found;
 	}
 
 	/* check MT2266 ID register; reg=00 val=85 */
@@ -465,7 +467,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
 	if (ret == 0 && buf[0] == 0x85) {
 		priv->tuner = TUNER_RTL2832_MT2266;
 		priv->tuner_name = "MT2266";
-		goto found;
+		goto tuner_found;
 	}
 
 	/* check FC2580 ID register; reg=01 val=56 */
@@ -473,7 +475,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
 	if (ret == 0 && buf[0] == 0x56) {
 		priv->tuner = TUNER_RTL2832_FC2580;
 		priv->tuner_name = "FC2580";
-		goto found;
+		goto tuner_found;
 	}
 
 	/* check MT2063 ID register; reg=00 val=9e || 9c */
@@ -481,7 +483,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
 	if (ret == 0 && (buf[0] == 0x9e || buf[0] == 0x9c)) {
 		priv->tuner = TUNER_RTL2832_MT2063;
 		priv->tuner_name = "MT2063";
-		goto found;
+		goto tuner_found;
 	}
 
 	/* check MAX3543 ID register; reg=00 val=38 */
@@ -489,7 +491,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
 	if (ret == 0 && buf[0] == 0x38) {
 		priv->tuner = TUNER_RTL2832_MAX3543;
 		priv->tuner_name = "MAX3543";
-		goto found;
+		goto tuner_found;
 	}
 
 	/* check TUA9001 ID register; reg=7e val=2328 */
@@ -497,7 +499,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
 	if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) {
 		priv->tuner = TUNER_RTL2832_TUA9001;
 		priv->tuner_name = "TUA9001";
-		goto found;
+		goto tuner_found;
 	}
 
 	/* check MXL5007R ID register; reg=d9 val=14 */
@@ -505,7 +507,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
 	if (ret == 0 && buf[0] == 0x14) {
 		priv->tuner = TUNER_RTL2832_MXL5007T;
 		priv->tuner_name = "MXL5007T";
-		goto found;
+		goto tuner_found;
 	}
 
 	/* check E4000 ID register; reg=02 val=40 */
@@ -513,7 +515,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
 	if (ret == 0 && buf[0] == 0x40) {
 		priv->tuner = TUNER_RTL2832_E4000;
 		priv->tuner_name = "E4000";
-		goto found;
+		goto tuner_found;
 	}
 
 	/* check TDA18272 ID register; reg=00 val=c760  */
@@ -521,7 +523,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
 	if (ret == 0 && (buf[0] == 0xc7 || buf[1] == 0x60)) {
 		priv->tuner = TUNER_RTL2832_TDA18272;
 		priv->tuner_name = "TDA18272";
-		goto found;
+		goto tuner_found;
 	}
 
 	/* check R820T ID register; reg=00 val=69 */
@@ -529,7 +531,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
 	if (ret == 0 && buf[0] == 0x69) {
 		priv->tuner = TUNER_RTL2832_R820T;
 		priv->tuner_name = "R820T";
-		goto found;
+		goto tuner_found;
 	}
 
 	/* check R828D ID register; reg=00 val=69 */
@@ -537,13 +539,37 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
 	if (ret == 0 && buf[0] == 0x69) {
 		priv->tuner = TUNER_RTL2832_R828D;
 		priv->tuner_name = "R828D";
-		goto found;
+		goto tuner_found;
 	}
 
-
-found:
+tuner_found:
 	dev_dbg(&d->udev->dev, "%s: tuner=%s\n", __func__, priv->tuner_name);
 
+	/* probe slave demod */
+	if (priv->tuner == TUNER_RTL2832_R828D) {
+		/* power on MN88472 demod on GPIO0 */
+		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x01, 0x01);
+		if (ret)
+			goto err;
+
+		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x01);
+		if (ret)
+			goto err;
+
+		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x01, 0x01);
+		if (ret)
+			goto err;
+
+		/* check MN88472 answers */
+		ret = rtl28xxu_ctrl_msg(d, &req_mn88472);
+		if (ret == 0 && buf[0] == 0x02) {
+			dev_dbg(&d->udev->dev, "%s: MN88472 found\n", __func__);
+			priv->slave_demod = SLAVE_DEMOD_MN88472;
+			goto demod_found;
+		}
+	}
+
+demod_found:
 	/* close demod I2C gate */
 	ret = rtl28xxu_ctrl_msg(d, &req_gate_close);
 	if (ret < 0)
@@ -768,6 +794,18 @@ static int rtl2832u_frontend_callback(void *adapter_priv, int component,
 	return 0;
 }
 
+/* FIXME: this is a bit hackish solution */
+/* slave demod TS output is connected to master demod TS input */
+static int rtl28xxu_mn88472_init(struct dvb_frontend *fe)
+{
+	struct dvb_usb_adapter *adap = fe_to_adap(fe);
+	struct rtl28xxu_priv *priv = fe_to_priv(fe);
+	/* enable RTL2832 PIP mode */
+	adap->fe[0]->dtv_property_cache.frequency = 0;
+	adap->fe[0]->ops.set_frontend(adap->fe[0]);
+	return priv->init(fe);
+}
+
 static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
 {
 	int ret;
@@ -818,7 +856,48 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
 	/* set fe callback */
 	adap->fe[0]->callback = rtl2832u_frontend_callback;
 
+	if (priv->slave_demod) {
+		struct i2c_board_info info = {};
+		struct i2c_client *client;
+
+		/*
+		 * We continue on reduced mode, without DVB-T2/C, using master
+		 * demod, when slave demod fails.
+		 */
+		ret = 0;
+
+		/* attach slave demodulator */
+		if (priv->slave_demod == SLAVE_DEMOD_MN88472) {
+			struct mn88472_config mn88472_config = {};
+
+			mn88472_config.fe = &adap->fe[1];
+			mn88472_config.i2c_wr_max = 22,
+			strlcpy(info.type, "mn88472", I2C_NAME_SIZE);
+			info.addr = 0x18;
+			info.platform_data = &mn88472_config;
+			request_module(info.type);
+			client = i2c_new_device(priv->demod_i2c_adapter, &info);
+			if (client == NULL || client->dev.driver == NULL) {
+				priv->slave_demod = SLAVE_DEMOD_NONE;
+				goto err_slave_demod_failed;
+			}
+
+			if (!try_module_get(client->dev.driver->owner)) {
+				i2c_unregister_device(client);
+				priv->slave_demod = SLAVE_DEMOD_NONE;
+				goto err_slave_demod_failed;
+			}
+
+			priv->i2c_client_slave_demod = client;
+		}
+
+		/* override init as we want configure RTL2832 as TS input */
+		priv->init = adap->fe[1]->ops.init;
+		adap->fe[1]->ops.init = rtl28xxu_mn88472_init;
+	}
+
 	return 0;
+err_slave_demod_failed:
 err:
 	dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
 	return ret;
@@ -1024,25 +1103,19 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
 				&rtl28xxu_rtl2832_r820t_config, NULL);
 		break;
 	case TUNER_RTL2832_R828D:
-		/* power off mn88472 demod on GPIO0 */
-		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x00, 0x01);
-		if (ret)
-			goto err;
-
-		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x01);
-		if (ret)
-			goto err;
-
-		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x01, 0x01);
-		if (ret)
-			goto err;
-
-		fe = dvb_attach(r820t_attach, adap->fe[0], &d->i2c_adap,
+		fe = dvb_attach(r820t_attach, adap->fe[0],
+				priv->demod_i2c_adapter,
 				&rtl2832u_r828d_config);
-
-		/* Use tuner to get the signal strength */
 		adap->fe[0]->ops.read_signal_strength =
 				adap->fe[0]->ops.tuner_ops.get_rf_strength;
+
+		if (adap->fe[1]) {
+			fe = dvb_attach(r820t_attach, adap->fe[1],
+					priv->demod_i2c_adapter,
+					&rtl2832u_r828d_config);
+			adap->fe[1]->ops.read_signal_strength =
+					adap->fe[1]->ops.tuner_ops.get_rf_strength;
+		}
 		break;
 	default:
 		dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
@@ -1097,11 +1170,19 @@ err:
 static void rtl28xxu_exit(struct dvb_usb_device *d)
 {
 	struct rtl28xxu_priv *priv = d->priv;
-	struct i2c_client *client = priv->client;
+	struct i2c_client *client;
 
 	dev_dbg(&d->udev->dev, "%s:\n", __func__);
 
 	/* remove I2C tuner */
+	client = priv->client;
+	if (client) {
+		module_put(client->dev.driver->owner);
+		i2c_unregister_device(client);
+	}
+
+	/* remove I2C slave demod */
+	client = priv->i2c_client_slave_demod;
 	if (client) {
 		module_put(client->dev.driver->owner);
 		i2c_unregister_device(client);
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
index a26cab1..58f2730 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
@@ -58,6 +58,11 @@ struct rtl28xxu_priv {
 	struct i2c_adapter *demod_i2c_adapter;
 	bool rc_active;
 	struct i2c_client *client;
+	struct i2c_client *i2c_client_slave_demod;
+	int (*init)(struct dvb_frontend *fe);
+	#define SLAVE_DEMOD_NONE           0
+	#define SLAVE_DEMOD_MN88472        1
+	unsigned int slave_demod:1;
 };
 
 enum rtl28xxu_chip_id {
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 5/8] rtl28xxu: add support for Panasonic MN88473 slave demod
  2014-11-12  4:23 [PATCH 0/8] Astrometa DVB USB support Antti Palosaari
                   ` (3 preceding siblings ...)
  2014-11-12  4:23 ` [PATCH 4/8] rtl28xxu: add support for Panasonic MN88472 slave demod Antti Palosaari
@ 2014-11-12  4:23 ` Antti Palosaari
  2014-11-14 19:40   ` Mauro Carvalho Chehab
  2014-11-12  4:23 ` [PATCH 6/8] rtl28xxu: rename tuner I2C client pointer Antti Palosaari
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 18+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:23 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

There is RTL2832P devices having extra MN88473 demodulator. This
patch add support for such configuration. Logically MN88473 slave
demodulator is connected to RTL2832 master demodulator, both I2C
bus and TS input. RTL2832 is integrated to RTL2832U and RTL2832P
chips. Chip version RTL2832P has extra TS interface for connecting
slave demodulator.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/usb/dvb-usb-v2/Kconfig    |  1 +
 drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 31 +++++++++++++++++++++++++++++++
 drivers/media/usb/dvb-usb-v2/rtl28xxu.h |  3 ++-
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig
index 9050933..f452a11 100644
--- a/drivers/media/usb/dvb-usb-v2/Kconfig
+++ b/drivers/media/usb/dvb-usb-v2/Kconfig
@@ -131,6 +131,7 @@ config DVB_USB_RTL28XXU
 	select DVB_RTL2832
 	select DVB_RTL2832_SDR if (MEDIA_SUBDRV_AUTOSELECT && MEDIA_SDR_SUPPORT)
 	select DVB_MN88472 if MEDIA_SUBDRV_AUTOSELECT
+	select DVB_MN88473 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index e3c20f4..93f8afc 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -25,6 +25,7 @@
 #include "rtl2830.h"
 #include "rtl2832.h"
 #include "mn88472.h"
+#include "mn88473.h"
 
 #include "qt1010.h"
 #include "mt2060.h"
@@ -422,6 +423,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
 	struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 1, buf};
 	struct rtl28xxu_req req_r828d = {0x0074, CMD_I2C_RD, 1, buf};
 	struct rtl28xxu_req req_mn88472 = {0xff38, CMD_I2C_RD, 1, buf};
+	struct rtl28xxu_req req_mn88473 = {0xff38, CMD_I2C_RD, 1, buf};
 
 	dev_dbg(&d->udev->dev, "%s:\n", __func__);
 
@@ -567,6 +569,13 @@ tuner_found:
 			priv->slave_demod = SLAVE_DEMOD_MN88472;
 			goto demod_found;
 		}
+
+		ret = rtl28xxu_ctrl_msg(d, &req_mn88473);
+		if (ret == 0 && buf[0] == 0x03) {
+			dev_dbg(&d->udev->dev, "%s: MN88473 found\n", __func__);
+			priv->slave_demod = SLAVE_DEMOD_MN88473;
+			goto demod_found;
+		}
 	}
 
 demod_found:
@@ -889,6 +898,28 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
 			}
 
 			priv->i2c_client_slave_demod = client;
+		} else {
+			struct mn88473_config mn88473_config = {};
+
+			mn88473_config.fe = &adap->fe[1];
+			mn88473_config.i2c_wr_max = 22,
+			strlcpy(info.type, "mn88473", I2C_NAME_SIZE);
+			info.addr = 0x18;
+			info.platform_data = &mn88473_config;
+			request_module(info.type);
+			client = i2c_new_device(priv->demod_i2c_adapter, &info);
+			if (client == NULL || client->dev.driver == NULL) {
+				priv->slave_demod = SLAVE_DEMOD_NONE;
+				goto err_slave_demod_failed;
+			}
+
+			if (!try_module_get(client->dev.driver->owner)) {
+				i2c_unregister_device(client);
+				priv->slave_demod = SLAVE_DEMOD_NONE;
+				goto err_slave_demod_failed;
+			}
+
+			priv->i2c_client_slave_demod = client;
 		}
 
 		/* override init as we want configure RTL2832 as TS input */
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
index 58f2730..9c059ac 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
@@ -62,7 +62,8 @@ struct rtl28xxu_priv {
 	int (*init)(struct dvb_frontend *fe);
 	#define SLAVE_DEMOD_NONE           0
 	#define SLAVE_DEMOD_MN88472        1
-	unsigned int slave_demod:1;
+	#define SLAVE_DEMOD_MN88473        2
+	unsigned int slave_demod:2;
 };
 
 enum rtl28xxu_chip_id {
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 6/8] rtl28xxu: rename tuner I2C client pointer
  2014-11-12  4:23 [PATCH 0/8] Astrometa DVB USB support Antti Palosaari
                   ` (4 preceding siblings ...)
  2014-11-12  4:23 ` [PATCH 5/8] rtl28xxu: add support for Panasonic MN88473 " Antti Palosaari
@ 2014-11-12  4:23 ` Antti Palosaari
  2014-11-12  4:23 ` [PATCH 7/8] rtl28xxu: remove unused SDR attach logic Antti Palosaari
  2014-11-12  4:23 ` [PATCH 8/8] rtl28xxu: add SDR module for devices having R828D tuner Antti Palosaari
  7 siblings, 0 replies; 18+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:23 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

Better to rename tuner I2C to something which clearly says it is
for tuner as there is now multiple different I2C clients used.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 6 +++---
 drivers/media/usb/dvb-usb-v2/rtl28xxu.h | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index 93f8afc..47360d3 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -1094,7 +1094,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
 				break;
 			}
 
-			priv->client = client;
+			priv->i2c_client_tuner = client;
 			sd = i2c_get_clientdata(client);
 			i2c_set_adapdata(i2c_adap_internal, d);
 
@@ -1153,7 +1153,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
 				priv->tuner);
 	}
 
-	if (fe == NULL && priv->client == NULL) {
+	if (fe == NULL && priv->i2c_client_tuner == NULL) {
 		ret = -ENODEV;
 		goto err;
 	}
@@ -1206,7 +1206,7 @@ static void rtl28xxu_exit(struct dvb_usb_device *d)
 	dev_dbg(&d->udev->dev, "%s:\n", __func__);
 
 	/* remove I2C tuner */
-	client = priv->client;
+	client = priv->i2c_client_tuner;
 	if (client) {
 		module_put(client->dev.driver->owner);
 		i2c_unregister_device(client);
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
index 9c059ac..bfc0b57 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
@@ -57,7 +57,7 @@ struct rtl28xxu_priv {
 	u8 page; /* integrated demod active register page */
 	struct i2c_adapter *demod_i2c_adapter;
 	bool rc_active;
-	struct i2c_client *client;
+	struct i2c_client *i2c_client_tuner;
 	struct i2c_client *i2c_client_slave_demod;
 	int (*init)(struct dvb_frontend *fe);
 	#define SLAVE_DEMOD_NONE           0
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 7/8] rtl28xxu: remove unused SDR attach logic
  2014-11-12  4:23 [PATCH 0/8] Astrometa DVB USB support Antti Palosaari
                   ` (5 preceding siblings ...)
  2014-11-12  4:23 ` [PATCH 6/8] rtl28xxu: rename tuner I2C client pointer Antti Palosaari
@ 2014-11-12  4:23 ` Antti Palosaari
  2014-11-12  4:23 ` [PATCH 8/8] rtl28xxu: add SDR module for devices having R828D tuner Antti Palosaari
  7 siblings, 0 replies; 18+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:23 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

That logic was duplicated from rtl2832_sdr.h in order to avoid hard
dependency for staging directory. rtl2832_sdr is moved to media, so
we could remove that code now.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 20 +-------------------
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index 47360d3..eadde72 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -24,6 +24,7 @@
 
 #include "rtl2830.h"
 #include "rtl2832.h"
+#include "rtl2832_sdr.h"
 #include "mn88472.h"
 #include "mn88473.h"
 
@@ -37,25 +38,6 @@
 #include "tua9001.h"
 #include "r820t.h"
 
-/*
- * RTL2832_SDR module is in staging. That logic is added in order to avoid any
- * hard dependency to drivers/staging/ directory as we want compile mainline
- * driver even whole staging directory is missing.
- */
-#include <media/v4l2-subdev.h>
-
-#if IS_ENABLED(CONFIG_DVB_RTL2832_SDR)
-struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
-	struct i2c_adapter *i2c, const struct rtl2832_config *cfg,
-	struct v4l2_subdev *sd);
-#else
-static inline struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
-	struct i2c_adapter *i2c, const struct rtl2832_config *cfg,
-	struct v4l2_subdev *sd)
-{
-	return NULL;
-}
-#endif
 
 #ifdef CONFIG_MEDIA_ATTACH
 #define dvb_attach_sdr(FUNCTION, ARGS...) ({ \
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 8/8] rtl28xxu: add SDR module for devices having R828D tuner
  2014-11-12  4:23 [PATCH 0/8] Astrometa DVB USB support Antti Palosaari
                   ` (6 preceding siblings ...)
  2014-11-12  4:23 ` [PATCH 7/8] rtl28xxu: remove unused SDR attach logic Antti Palosaari
@ 2014-11-12  4:23 ` Antti Palosaari
  7 siblings, 0 replies; 18+ messages in thread
From: Antti Palosaari @ 2014-11-12  4:23 UTC (permalink / raw)
  To: linux-media; +Cc: Antti Palosaari

Load SDR sub-driver in order to support SDR for devices having
this tuner too.

Signed-off-by: Antti Palosaari <crope@iki.fi>
---
 drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index eadde72..4af8a61 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -1129,6 +1129,10 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
 			adap->fe[1]->ops.read_signal_strength =
 					adap->fe[1]->ops.tuner_ops.get_rf_strength;
 		}
+
+		/* attach SDR */
+		dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
+				&rtl28xxu_rtl2832_r820t_config, NULL);
 		break;
 	default:
 		dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
-- 
http://palosaari.fi/


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/8] rtl2832: implement PIP mode
  2014-11-12  4:23 ` [PATCH 2/8] rtl2832: implement PIP mode Antti Palosaari
@ 2014-11-14 19:34   ` Mauro Carvalho Chehab
  2014-11-14 23:36     ` Antti Palosaari
  0 siblings, 1 reply; 18+ messages in thread
From: Mauro Carvalho Chehab @ 2014-11-14 19:34 UTC (permalink / raw)
  To: Antti Palosaari; +Cc: linux-media

Em Wed, 12 Nov 2014 06:23:04 +0200
Antti Palosaari <crope@iki.fi> escreveu:

> Implement PIP mode to stream from slave demodulator. PIP mode is
> enabled when .set_frontend is called with RF frequency 0, otherwise
> normal demod mode is enabled.

This would be an API change, so, a DocBook patch is required.

Anyway, using frequency=0 for PIP doesn't seem to be a good idea,
as a read from GET_PROPERTY should override the cache with the real
frequency.

Also, someone came with me with a case where auto-frequency would
be interesting, and proposed frequency=0. I was not convinced
(and patches weren't sent), but using 0 for AUTO seems more
appropriate, as we do the same for bandwidth (and may do the same
for symbol_rate).

So, the best seems to add a new property to enable PIP mode.

Regards,
Mauro
> 
> Signed-off-by: Antti Palosaari <crope@iki.fi>
> ---
>  drivers/media/dvb-frontends/rtl2832.c | 42 ++++++++++++++++++++++++++++++++---
>  1 file changed, 39 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c
> index eb737cf..a58b456 100644
> --- a/drivers/media/dvb-frontends/rtl2832.c
> +++ b/drivers/media/dvb-frontends/rtl2832.c
> @@ -258,13 +258,11 @@ static int rtl2832_rd_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
>  	return rtl2832_rd(priv, reg, val, len);
>  }
>  
> -#if 0 /* currently not used */
>  /* write single register */
>  static int rtl2832_wr_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 val)
>  {
>  	return rtl2832_wr_regs(priv, reg, page, &val, 1);
>  }
> -#endif
>  
>  /* read single register */
>  static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val)
> @@ -595,6 +593,44 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
>  			"%s: frequency=%d bandwidth_hz=%d inversion=%d\n",
>  			__func__, c->frequency, c->bandwidth_hz, c->inversion);
>  
> +	/* PIP mode */
> +	if (c->frequency == 0) {
> +		dev_dbg(&priv->i2c->dev, "%s: setting PIP mode\n", __func__);
> +		ret = rtl2832_wr_regs(priv, 0x0c, 1, "\x5f\xff", 2);
> +		if (ret)
> +			goto err;
> +
> +		ret = rtl2832_wr_demod_reg(priv, DVBT_PIP_ON, 0x1);
> +		if (ret)
> +			goto err;
> +
> +		ret = rtl2832_wr_reg(priv, 0xbc, 0, 0x18);
> +		if (ret)
> +			goto err;
> +
> +		ret = rtl2832_wr_reg(priv, 0x22, 0, 0x01);
> +		if (ret)
> +			goto err;
> +
> +		ret = rtl2832_wr_reg(priv, 0x26, 0, 0x1f);
> +		if (ret)
> +			goto err;
> +
> +		ret = rtl2832_wr_reg(priv, 0x27, 0, 0xff);
> +		if (ret)
> +			goto err;
> +
> +		ret = rtl2832_wr_regs(priv, 0x92, 1, "\x7f\xf7\xff", 3);
> +		if (ret)
> +			goto err;
> +
> +		goto exit_soft_reset;
> +	} else {
> +		ret = rtl2832_wr_regs(priv, 0x92, 1, "\x00\x0f\xff", 3);
> +		if (ret)
> +			goto err;
> +	}
> +
>  	/* program tuner */
>  	if (fe->ops.tuner_ops.set_params)
>  		fe->ops.tuner_ops.set_params(fe);
> @@ -661,7 +697,7 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
>  	if (ret)
>  		goto err;
>  
> -
> +exit_soft_reset:
>  	/* soft reset */
>  	ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
>  	if (ret)

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 4/8] rtl28xxu: add support for Panasonic MN88472 slave demod
  2014-11-12  4:23 ` [PATCH 4/8] rtl28xxu: add support for Panasonic MN88472 slave demod Antti Palosaari
@ 2014-11-14 19:39   ` Mauro Carvalho Chehab
  2014-11-14 23:42     ` Antti Palosaari
  0 siblings, 1 reply; 18+ messages in thread
From: Mauro Carvalho Chehab @ 2014-11-14 19:39 UTC (permalink / raw)
  To: Antti Palosaari; +Cc: linux-media

Em Wed, 12 Nov 2014 06:23:06 +0200
Antti Palosaari <crope@iki.fi> escreveu:

> There is RTL2832P devices having extra MN88472 demodulator. This
> patch add support for such configuration. Logically MN88472 slave
> demodulator is connected to RTL2832 master demodulator, both I2C
> bus and TS input. RTL2832 is integrated to RTL2832U and RTL2832P
> chips. Chip version RTL2832P has extra TS interface for connecting
> slave demodulator.
> 
> Signed-off-by: Antti Palosaari <crope@iki.fi>
> ---
>  drivers/media/usb/dvb-usb-v2/Kconfig    |   1 +
>  drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 143 +++++++++++++++++++++++++-------
>  drivers/media/usb/dvb-usb-v2/rtl28xxu.h |   5 ++
>  3 files changed, 118 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig
> index 7423033..9050933 100644
> --- a/drivers/media/usb/dvb-usb-v2/Kconfig
> +++ b/drivers/media/usb/dvb-usb-v2/Kconfig
> @@ -130,6 +130,7 @@ config DVB_USB_RTL28XXU
>  	select DVB_RTL2830
>  	select DVB_RTL2832
>  	select DVB_RTL2832_SDR if (MEDIA_SUBDRV_AUTOSELECT && MEDIA_SDR_SUPPORT)
> +	select DVB_MN88472 if MEDIA_SUBDRV_AUTOSELECT
>  	select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
>  	select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
>  	select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT

This is not a good idea, as the MN88472 is in staging.

Select is not recursive, and won't select STAGING. Also, we don't want
to enable a staging driver by default on distros.

> diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
> index 5ea52c7..e3c20f4 100644
> --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
> +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
> @@ -24,6 +24,7 @@
>  
>  #include "rtl2830.h"
>  #include "rtl2832.h"
> +#include "mn88472.h"
>  
>  #include "qt1010.h"
>  #include "mt2060.h"
> @@ -420,6 +421,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>  	struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf};
>  	struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 1, buf};
>  	struct rtl28xxu_req req_r828d = {0x0074, CMD_I2C_RD, 1, buf};
> +	struct rtl28xxu_req req_mn88472 = {0xff38, CMD_I2C_RD, 1, buf};
>  
>  	dev_dbg(&d->udev->dev, "%s:\n", __func__);
>  
> @@ -449,7 +451,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>  	if (ret == 0 && buf[0] == 0xa1) {
>  		priv->tuner = TUNER_RTL2832_FC0012;
>  		priv->tuner_name = "FC0012";
> -		goto found;
> +		goto tuner_found;
>  	}
>  
>  	/* check FC0013 ID register; reg=00 val=a3 */
> @@ -457,7 +459,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>  	if (ret == 0 && buf[0] == 0xa3) {
>  		priv->tuner = TUNER_RTL2832_FC0013;
>  		priv->tuner_name = "FC0013";
> -		goto found;
> +		goto tuner_found;
>  	}
>  
>  	/* check MT2266 ID register; reg=00 val=85 */
> @@ -465,7 +467,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>  	if (ret == 0 && buf[0] == 0x85) {
>  		priv->tuner = TUNER_RTL2832_MT2266;
>  		priv->tuner_name = "MT2266";
> -		goto found;
> +		goto tuner_found;
>  	}
>  
>  	/* check FC2580 ID register; reg=01 val=56 */
> @@ -473,7 +475,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>  	if (ret == 0 && buf[0] == 0x56) {
>  		priv->tuner = TUNER_RTL2832_FC2580;
>  		priv->tuner_name = "FC2580";
> -		goto found;
> +		goto tuner_found;
>  	}
>  
>  	/* check MT2063 ID register; reg=00 val=9e || 9c */
> @@ -481,7 +483,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>  	if (ret == 0 && (buf[0] == 0x9e || buf[0] == 0x9c)) {
>  		priv->tuner = TUNER_RTL2832_MT2063;
>  		priv->tuner_name = "MT2063";
> -		goto found;
> +		goto tuner_found;
>  	}
>  
>  	/* check MAX3543 ID register; reg=00 val=38 */
> @@ -489,7 +491,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>  	if (ret == 0 && buf[0] == 0x38) {
>  		priv->tuner = TUNER_RTL2832_MAX3543;
>  		priv->tuner_name = "MAX3543";
> -		goto found;
> +		goto tuner_found;
>  	}
>  
>  	/* check TUA9001 ID register; reg=7e val=2328 */
> @@ -497,7 +499,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>  	if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) {
>  		priv->tuner = TUNER_RTL2832_TUA9001;
>  		priv->tuner_name = "TUA9001";
> -		goto found;
> +		goto tuner_found;
>  	}
>  
>  	/* check MXL5007R ID register; reg=d9 val=14 */
> @@ -505,7 +507,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>  	if (ret == 0 && buf[0] == 0x14) {
>  		priv->tuner = TUNER_RTL2832_MXL5007T;
>  		priv->tuner_name = "MXL5007T";
> -		goto found;
> +		goto tuner_found;
>  	}
>  
>  	/* check E4000 ID register; reg=02 val=40 */
> @@ -513,7 +515,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>  	if (ret == 0 && buf[0] == 0x40) {
>  		priv->tuner = TUNER_RTL2832_E4000;
>  		priv->tuner_name = "E4000";
> -		goto found;
> +		goto tuner_found;
>  	}
>  
>  	/* check TDA18272 ID register; reg=00 val=c760  */
> @@ -521,7 +523,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>  	if (ret == 0 && (buf[0] == 0xc7 || buf[1] == 0x60)) {
>  		priv->tuner = TUNER_RTL2832_TDA18272;
>  		priv->tuner_name = "TDA18272";
> -		goto found;
> +		goto tuner_found;
>  	}
>  
>  	/* check R820T ID register; reg=00 val=69 */
> @@ -529,7 +531,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>  	if (ret == 0 && buf[0] == 0x69) {
>  		priv->tuner = TUNER_RTL2832_R820T;
>  		priv->tuner_name = "R820T";
> -		goto found;
> +		goto tuner_found;
>  	}
>  
>  	/* check R828D ID register; reg=00 val=69 */
> @@ -537,13 +539,37 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>  	if (ret == 0 && buf[0] == 0x69) {
>  		priv->tuner = TUNER_RTL2832_R828D;
>  		priv->tuner_name = "R828D";
> -		goto found;
> +		goto tuner_found;
>  	}
>  
> -
> -found:
> +tuner_found:
>  	dev_dbg(&d->udev->dev, "%s: tuner=%s\n", __func__, priv->tuner_name);
>  
> +	/* probe slave demod */
> +	if (priv->tuner == TUNER_RTL2832_R828D) {
> +		/* power on MN88472 demod on GPIO0 */
> +		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x01, 0x01);
> +		if (ret)
> +			goto err;
> +
> +		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x01);
> +		if (ret)
> +			goto err;
> +
> +		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x01, 0x01);
> +		if (ret)
> +			goto err;
> +
> +		/* check MN88472 answers */
> +		ret = rtl28xxu_ctrl_msg(d, &req_mn88472);
> +		if (ret == 0 && buf[0] == 0x02) {
> +			dev_dbg(&d->udev->dev, "%s: MN88472 found\n", __func__);
> +			priv->slave_demod = SLAVE_DEMOD_MN88472;
> +			goto demod_found;
> +		}
> +	}
> +
> +demod_found:
>  	/* close demod I2C gate */
>  	ret = rtl28xxu_ctrl_msg(d, &req_gate_close);
>  	if (ret < 0)
> @@ -768,6 +794,18 @@ static int rtl2832u_frontend_callback(void *adapter_priv, int component,
>  	return 0;
>  }
>  
> +/* FIXME: this is a bit hackish solution */
> +/* slave demod TS output is connected to master demod TS input */
> +static int rtl28xxu_mn88472_init(struct dvb_frontend *fe)
> +{
> +	struct dvb_usb_adapter *adap = fe_to_adap(fe);
> +	struct rtl28xxu_priv *priv = fe_to_priv(fe);
> +	/* enable RTL2832 PIP mode */
> +	adap->fe[0]->dtv_property_cache.frequency = 0;
> +	adap->fe[0]->ops.set_frontend(adap->fe[0]);
> +	return priv->init(fe);
> +}
> +
>  static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
>  {
>  	int ret;
> @@ -818,7 +856,48 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
>  	/* set fe callback */
>  	adap->fe[0]->callback = rtl2832u_frontend_callback;
>  
> +	if (priv->slave_demod) {
> +		struct i2c_board_info info = {};
> +		struct i2c_client *client;
> +
> +		/*
> +		 * We continue on reduced mode, without DVB-T2/C, using master
> +		 * demod, when slave demod fails.
> +		 */
> +		ret = 0;
> +
> +		/* attach slave demodulator */
> +		if (priv->slave_demod == SLAVE_DEMOD_MN88472) {
> +			struct mn88472_config mn88472_config = {};
> +
> +			mn88472_config.fe = &adap->fe[1];
> +			mn88472_config.i2c_wr_max = 22,
> +			strlcpy(info.type, "mn88472", I2C_NAME_SIZE);
> +			info.addr = 0x18;
> +			info.platform_data = &mn88472_config;
> +			request_module(info.type);
> +			client = i2c_new_device(priv->demod_i2c_adapter, &info);
> +			if (client == NULL || client->dev.driver == NULL) {
> +				priv->slave_demod = SLAVE_DEMOD_NONE;
> +				goto err_slave_demod_failed;
> +			}
> +
> +			if (!try_module_get(client->dev.driver->owner)) {
> +				i2c_unregister_device(client);
> +				priv->slave_demod = SLAVE_DEMOD_NONE;
> +				goto err_slave_demod_failed;
> +			}
> +
> +			priv->i2c_client_slave_demod = client;
> +		}
> +
> +		/* override init as we want configure RTL2832 as TS input */
> +		priv->init = adap->fe[1]->ops.init;
> +		adap->fe[1]->ops.init = rtl28xxu_mn88472_init;
> +	}
> +
>  	return 0;
> +err_slave_demod_failed:
>  err:
>  	dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
>  	return ret;
> @@ -1024,25 +1103,19 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
>  				&rtl28xxu_rtl2832_r820t_config, NULL);
>  		break;
>  	case TUNER_RTL2832_R828D:
> -		/* power off mn88472 demod on GPIO0 */
> -		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x00, 0x01);
> -		if (ret)
> -			goto err;
> -
> -		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x01);
> -		if (ret)
> -			goto err;
> -
> -		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x01, 0x01);
> -		if (ret)
> -			goto err;
> -
> -		fe = dvb_attach(r820t_attach, adap->fe[0], &d->i2c_adap,
> +		fe = dvb_attach(r820t_attach, adap->fe[0],
> +				priv->demod_i2c_adapter,
>  				&rtl2832u_r828d_config);
> -
> -		/* Use tuner to get the signal strength */
>  		adap->fe[0]->ops.read_signal_strength =
>  				adap->fe[0]->ops.tuner_ops.get_rf_strength;
> +
> +		if (adap->fe[1]) {
> +			fe = dvb_attach(r820t_attach, adap->fe[1],
> +					priv->demod_i2c_adapter,
> +					&rtl2832u_r828d_config);
> +			adap->fe[1]->ops.read_signal_strength =
> +					adap->fe[1]->ops.tuner_ops.get_rf_strength;
> +		}
>  		break;
>  	default:
>  		dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
> @@ -1097,11 +1170,19 @@ err:
>  static void rtl28xxu_exit(struct dvb_usb_device *d)
>  {
>  	struct rtl28xxu_priv *priv = d->priv;
> -	struct i2c_client *client = priv->client;
> +	struct i2c_client *client;
>  
>  	dev_dbg(&d->udev->dev, "%s:\n", __func__);
>  
>  	/* remove I2C tuner */
> +	client = priv->client;
> +	if (client) {
> +		module_put(client->dev.driver->owner);
> +		i2c_unregister_device(client);
> +	}
> +
> +	/* remove I2C slave demod */
> +	client = priv->i2c_client_slave_demod;
>  	if (client) {
>  		module_put(client->dev.driver->owner);
>  		i2c_unregister_device(client);
> diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
> index a26cab1..58f2730 100644
> --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
> +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
> @@ -58,6 +58,11 @@ struct rtl28xxu_priv {
>  	struct i2c_adapter *demod_i2c_adapter;
>  	bool rc_active;
>  	struct i2c_client *client;
> +	struct i2c_client *i2c_client_slave_demod;
> +	int (*init)(struct dvb_frontend *fe);
> +	#define SLAVE_DEMOD_NONE           0
> +	#define SLAVE_DEMOD_MN88472        1
> +	unsigned int slave_demod:1;
>  };
>  
>  enum rtl28xxu_chip_id {

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 5/8] rtl28xxu: add support for Panasonic MN88473 slave demod
  2014-11-12  4:23 ` [PATCH 5/8] rtl28xxu: add support for Panasonic MN88473 " Antti Palosaari
@ 2014-11-14 19:40   ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 18+ messages in thread
From: Mauro Carvalho Chehab @ 2014-11-14 19:40 UTC (permalink / raw)
  To: Antti Palosaari; +Cc: linux-media

Em Wed, 12 Nov 2014 06:23:07 +0200
Antti Palosaari <crope@iki.fi> escreveu:

> There is RTL2832P devices having extra MN88473 demodulator. This
> patch add support for such configuration. Logically MN88473 slave
> demodulator is connected to RTL2832 master demodulator, both I2C
> bus and TS input. RTL2832 is integrated to RTL2832U and RTL2832P
> chips. Chip version RTL2832P has extra TS interface for connecting
> slave demodulator.
> 
> Signed-off-by: Antti Palosaari <crope@iki.fi>
> ---
>  drivers/media/usb/dvb-usb-v2/Kconfig    |  1 +
>  drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 31 +++++++++++++++++++++++++++++++
>  drivers/media/usb/dvb-usb-v2/rtl28xxu.h |  3 ++-
>  3 files changed, 34 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig
> index 9050933..f452a11 100644
> --- a/drivers/media/usb/dvb-usb-v2/Kconfig
> +++ b/drivers/media/usb/dvb-usb-v2/Kconfig
> @@ -131,6 +131,7 @@ config DVB_USB_RTL28XXU
>  	select DVB_RTL2832
>  	select DVB_RTL2832_SDR if (MEDIA_SUBDRV_AUTOSELECT && MEDIA_SDR_SUPPORT)
>  	select DVB_MN88472 if MEDIA_SUBDRV_AUTOSELECT
> +	select DVB_MN88473 if MEDIA_SUBDRV_AUTOSELECT
>  	select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
>  	select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
>  	select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT


This is not a good idea, as the MN88473 is in staging.

Select is not recursive, and won't select STAGING. Also, we don't want
to enable a staging driver by default on distros.

> diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
> index e3c20f4..93f8afc 100644
> --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
> +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
> @@ -25,6 +25,7 @@
>  #include "rtl2830.h"
>  #include "rtl2832.h"
>  #include "mn88472.h"
> +#include "mn88473.h"
>  
>  #include "qt1010.h"
>  #include "mt2060.h"
> @@ -422,6 +423,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>  	struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 1, buf};
>  	struct rtl28xxu_req req_r828d = {0x0074, CMD_I2C_RD, 1, buf};
>  	struct rtl28xxu_req req_mn88472 = {0xff38, CMD_I2C_RD, 1, buf};
> +	struct rtl28xxu_req req_mn88473 = {0xff38, CMD_I2C_RD, 1, buf};
>  
>  	dev_dbg(&d->udev->dev, "%s:\n", __func__);
>  
> @@ -567,6 +569,13 @@ tuner_found:
>  			priv->slave_demod = SLAVE_DEMOD_MN88472;
>  			goto demod_found;
>  		}
> +
> +		ret = rtl28xxu_ctrl_msg(d, &req_mn88473);
> +		if (ret == 0 && buf[0] == 0x03) {
> +			dev_dbg(&d->udev->dev, "%s: MN88473 found\n", __func__);
> +			priv->slave_demod = SLAVE_DEMOD_MN88473;
> +			goto demod_found;
> +		}
>  	}
>  
>  demod_found:
> @@ -889,6 +898,28 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
>  			}
>  
>  			priv->i2c_client_slave_demod = client;
> +		} else {
> +			struct mn88473_config mn88473_config = {};
> +
> +			mn88473_config.fe = &adap->fe[1];
> +			mn88473_config.i2c_wr_max = 22,
> +			strlcpy(info.type, "mn88473", I2C_NAME_SIZE);
> +			info.addr = 0x18;
> +			info.platform_data = &mn88473_config;
> +			request_module(info.type);
> +			client = i2c_new_device(priv->demod_i2c_adapter, &info);
> +			if (client == NULL || client->dev.driver == NULL) {
> +				priv->slave_demod = SLAVE_DEMOD_NONE;
> +				goto err_slave_demod_failed;
> +			}
> +
> +			if (!try_module_get(client->dev.driver->owner)) {
> +				i2c_unregister_device(client);
> +				priv->slave_demod = SLAVE_DEMOD_NONE;
> +				goto err_slave_demod_failed;
> +			}
> +
> +			priv->i2c_client_slave_demod = client;
>  		}
>  
>  		/* override init as we want configure RTL2832 as TS input */
> diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
> index 58f2730..9c059ac 100644
> --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
> +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
> @@ -62,7 +62,8 @@ struct rtl28xxu_priv {
>  	int (*init)(struct dvb_frontend *fe);
>  	#define SLAVE_DEMOD_NONE           0
>  	#define SLAVE_DEMOD_MN88472        1
> -	unsigned int slave_demod:1;
> +	#define SLAVE_DEMOD_MN88473        2
> +	unsigned int slave_demod:2;
>  };
>  
>  enum rtl28xxu_chip_id {

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/8] rtl2832: implement PIP mode
  2014-11-14 19:34   ` Mauro Carvalho Chehab
@ 2014-11-14 23:36     ` Antti Palosaari
  2014-11-16 10:25       ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 18+ messages in thread
From: Antti Palosaari @ 2014-11-14 23:36 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-media

Moikka!

On 11/14/2014 09:34 PM, Mauro Carvalho Chehab wrote:
> Em Wed, 12 Nov 2014 06:23:04 +0200
> Antti Palosaari <crope@iki.fi> escreveu:
>
>> Implement PIP mode to stream from slave demodulator. PIP mode is
>> enabled when .set_frontend is called with RF frequency 0, otherwise
>> normal demod mode is enabled.
>
> This would be an API change, so, a DocBook patch is required.

You are wrong. PIP mode is driver/device internal thing and will not be 
revealed to userspace.

> Anyway, using frequency=0 for PIP doesn't seem to be a good idea,
> as a read from GET_PROPERTY should override the cache with the real
> frequency.

Yes, it is a hackish solution, used to put demod#0 on certain config 
when demod#1 is used. When PIP mode is set that demod#0 is totally 
useless as demod#1 is in use instead. Cache is garbage and no meaning at 
all.

> Also, someone came with me with a case where auto-frequency would
> be interesting, and proposed frequency=0. I was not convinced
> (and patches weren't sent), but using 0 for AUTO seems more
> appropriate, as we do the same for bandwidth (and may do the same
> for symbol_rate).

I totally agree that is is hackish solution. That is called from 
rtl28xxu.c driver and I added already comment it is hackish solution, 
but you didn't apply that commit.

> So, the best seems to add a new property to enable PIP mode.

No, no, no. It is like a PIP filter. It is actually special case of PID 
filter, having mux, to multiplex 2 TS interfaces to one (PIP = Picture 
in Picture).


.............................................
. RTL2832P integrates RTL2832 demodulator   .
. ____________                ____________  .              ____________
.|   USB IF   |              |   demod    | .             |   demod    |
.|------------|              |------------| .             |------------|
.|  RTL2832P  |              |  RTL2832   | .             |  MN88472   |
.|            |----TS bus----|-----/ -----|-.---TS bus----|            |
.|____________|              |____________| .             |____________|
.............................................


So the basically both demod PID filters are now implemented in RTL2832 
demod. Currently PIP mode is configured just to pass all the PIDs from 
MN88472 and reject RTL2832 PIDs. And when PIP mode is off, at pass all 
the PIDs from RTL2832, but rejects all PIDs from MN88472.

regards
Antti


>
> Regards,
> Mauro
>>
>> Signed-off-by: Antti Palosaari <crope@iki.fi>
>> ---
>>   drivers/media/dvb-frontends/rtl2832.c | 42 ++++++++++++++++++++++++++++++++---
>>   1 file changed, 39 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c
>> index eb737cf..a58b456 100644
>> --- a/drivers/media/dvb-frontends/rtl2832.c
>> +++ b/drivers/media/dvb-frontends/rtl2832.c
>> @@ -258,13 +258,11 @@ static int rtl2832_rd_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
>>   	return rtl2832_rd(priv, reg, val, len);
>>   }
>>
>> -#if 0 /* currently not used */
>>   /* write single register */
>>   static int rtl2832_wr_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 val)
>>   {
>>   	return rtl2832_wr_regs(priv, reg, page, &val, 1);
>>   }
>> -#endif
>>
>>   /* read single register */
>>   static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val)
>> @@ -595,6 +593,44 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
>>   			"%s: frequency=%d bandwidth_hz=%d inversion=%d\n",
>>   			__func__, c->frequency, c->bandwidth_hz, c->inversion);
>>
>> +	/* PIP mode */
>> +	if (c->frequency == 0) {
>> +		dev_dbg(&priv->i2c->dev, "%s: setting PIP mode\n", __func__);
>> +		ret = rtl2832_wr_regs(priv, 0x0c, 1, "\x5f\xff", 2);
>> +		if (ret)
>> +			goto err;
>> +
>> +		ret = rtl2832_wr_demod_reg(priv, DVBT_PIP_ON, 0x1);
>> +		if (ret)
>> +			goto err;
>> +
>> +		ret = rtl2832_wr_reg(priv, 0xbc, 0, 0x18);
>> +		if (ret)
>> +			goto err;
>> +
>> +		ret = rtl2832_wr_reg(priv, 0x22, 0, 0x01);
>> +		if (ret)
>> +			goto err;
>> +
>> +		ret = rtl2832_wr_reg(priv, 0x26, 0, 0x1f);
>> +		if (ret)
>> +			goto err;
>> +
>> +		ret = rtl2832_wr_reg(priv, 0x27, 0, 0xff);
>> +		if (ret)
>> +			goto err;
>> +
>> +		ret = rtl2832_wr_regs(priv, 0x92, 1, "\x7f\xf7\xff", 3);
>> +		if (ret)
>> +			goto err;
>> +
>> +		goto exit_soft_reset;
>> +	} else {
>> +		ret = rtl2832_wr_regs(priv, 0x92, 1, "\x00\x0f\xff", 3);
>> +		if (ret)
>> +			goto err;
>> +	}
>> +
>>   	/* program tuner */
>>   	if (fe->ops.tuner_ops.set_params)
>>   		fe->ops.tuner_ops.set_params(fe);
>> @@ -661,7 +697,7 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
>>   	if (ret)
>>   		goto err;
>>
>> -
>> +exit_soft_reset:
>>   	/* soft reset */
>>   	ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
>>   	if (ret)

-- 
http://palosaari.fi/

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 4/8] rtl28xxu: add support for Panasonic MN88472 slave demod
  2014-11-14 19:39   ` Mauro Carvalho Chehab
@ 2014-11-14 23:42     ` Antti Palosaari
  2014-11-15  1:07       ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 18+ messages in thread
From: Antti Palosaari @ 2014-11-14 23:42 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-media



On 11/14/2014 09:39 PM, Mauro Carvalho Chehab wrote:
> Em Wed, 12 Nov 2014 06:23:06 +0200
> Antti Palosaari <crope@iki.fi> escreveu:
>
>> There is RTL2832P devices having extra MN88472 demodulator. This
>> patch add support for such configuration. Logically MN88472 slave
>> demodulator is connected to RTL2832 master demodulator, both I2C
>> bus and TS input. RTL2832 is integrated to RTL2832U and RTL2832P
>> chips. Chip version RTL2832P has extra TS interface for connecting
>> slave demodulator.
>>
>> Signed-off-by: Antti Palosaari <crope@iki.fi>
>> ---
>>   drivers/media/usb/dvb-usb-v2/Kconfig    |   1 +
>>   drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 143 +++++++++++++++++++++++++-------
>>   drivers/media/usb/dvb-usb-v2/rtl28xxu.h |   5 ++
>>   3 files changed, 118 insertions(+), 31 deletions(-)
>>
>> diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig
>> index 7423033..9050933 100644
>> --- a/drivers/media/usb/dvb-usb-v2/Kconfig
>> +++ b/drivers/media/usb/dvb-usb-v2/Kconfig
>> @@ -130,6 +130,7 @@ config DVB_USB_RTL28XXU
>>   	select DVB_RTL2830
>>   	select DVB_RTL2832
>>   	select DVB_RTL2832_SDR if (MEDIA_SUBDRV_AUTOSELECT && MEDIA_SDR_SUPPORT)
>> +	select DVB_MN88472 if MEDIA_SUBDRV_AUTOSELECT
>>   	select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
>>   	select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
>>   	select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
>
> This is not a good idea, as the MN88472 is in staging.
>
> Select is not recursive, and won't select STAGING. Also, we don't want
> to enable a staging driver by default on distros.

I think it should work just fine. It is I2C driver. If distributions 
disables stating nothing will happen but MN88472 driver is not compiled. 
When there is no driver load, it will continue with reduced mode using 
single demod. I tested that scenario where driver was missing. Anyhow, I 
didn't test case where CONFIG_STAGING Kconfig option was disable, but I 
will do.

regards
Antti


>
>> diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
>> index 5ea52c7..e3c20f4 100644
>> --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
>> +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
>> @@ -24,6 +24,7 @@
>>
>>   #include "rtl2830.h"
>>   #include "rtl2832.h"
>> +#include "mn88472.h"
>>
>>   #include "qt1010.h"
>>   #include "mt2060.h"
>> @@ -420,6 +421,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>>   	struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf};
>>   	struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 1, buf};
>>   	struct rtl28xxu_req req_r828d = {0x0074, CMD_I2C_RD, 1, buf};
>> +	struct rtl28xxu_req req_mn88472 = {0xff38, CMD_I2C_RD, 1, buf};
>>
>>   	dev_dbg(&d->udev->dev, "%s:\n", __func__);
>>
>> @@ -449,7 +451,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>>   	if (ret == 0 && buf[0] == 0xa1) {
>>   		priv->tuner = TUNER_RTL2832_FC0012;
>>   		priv->tuner_name = "FC0012";
>> -		goto found;
>> +		goto tuner_found;
>>   	}
>>
>>   	/* check FC0013 ID register; reg=00 val=a3 */
>> @@ -457,7 +459,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>>   	if (ret == 0 && buf[0] == 0xa3) {
>>   		priv->tuner = TUNER_RTL2832_FC0013;
>>   		priv->tuner_name = "FC0013";
>> -		goto found;
>> +		goto tuner_found;
>>   	}
>>
>>   	/* check MT2266 ID register; reg=00 val=85 */
>> @@ -465,7 +467,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>>   	if (ret == 0 && buf[0] == 0x85) {
>>   		priv->tuner = TUNER_RTL2832_MT2266;
>>   		priv->tuner_name = "MT2266";
>> -		goto found;
>> +		goto tuner_found;
>>   	}
>>
>>   	/* check FC2580 ID register; reg=01 val=56 */
>> @@ -473,7 +475,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>>   	if (ret == 0 && buf[0] == 0x56) {
>>   		priv->tuner = TUNER_RTL2832_FC2580;
>>   		priv->tuner_name = "FC2580";
>> -		goto found;
>> +		goto tuner_found;
>>   	}
>>
>>   	/* check MT2063 ID register; reg=00 val=9e || 9c */
>> @@ -481,7 +483,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>>   	if (ret == 0 && (buf[0] == 0x9e || buf[0] == 0x9c)) {
>>   		priv->tuner = TUNER_RTL2832_MT2063;
>>   		priv->tuner_name = "MT2063";
>> -		goto found;
>> +		goto tuner_found;
>>   	}
>>
>>   	/* check MAX3543 ID register; reg=00 val=38 */
>> @@ -489,7 +491,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>>   	if (ret == 0 && buf[0] == 0x38) {
>>   		priv->tuner = TUNER_RTL2832_MAX3543;
>>   		priv->tuner_name = "MAX3543";
>> -		goto found;
>> +		goto tuner_found;
>>   	}
>>
>>   	/* check TUA9001 ID register; reg=7e val=2328 */
>> @@ -497,7 +499,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>>   	if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) {
>>   		priv->tuner = TUNER_RTL2832_TUA9001;
>>   		priv->tuner_name = "TUA9001";
>> -		goto found;
>> +		goto tuner_found;
>>   	}
>>
>>   	/* check MXL5007R ID register; reg=d9 val=14 */
>> @@ -505,7 +507,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>>   	if (ret == 0 && buf[0] == 0x14) {
>>   		priv->tuner = TUNER_RTL2832_MXL5007T;
>>   		priv->tuner_name = "MXL5007T";
>> -		goto found;
>> +		goto tuner_found;
>>   	}
>>
>>   	/* check E4000 ID register; reg=02 val=40 */
>> @@ -513,7 +515,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>>   	if (ret == 0 && buf[0] == 0x40) {
>>   		priv->tuner = TUNER_RTL2832_E4000;
>>   		priv->tuner_name = "E4000";
>> -		goto found;
>> +		goto tuner_found;
>>   	}
>>
>>   	/* check TDA18272 ID register; reg=00 val=c760  */
>> @@ -521,7 +523,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>>   	if (ret == 0 && (buf[0] == 0xc7 || buf[1] == 0x60)) {
>>   		priv->tuner = TUNER_RTL2832_TDA18272;
>>   		priv->tuner_name = "TDA18272";
>> -		goto found;
>> +		goto tuner_found;
>>   	}
>>
>>   	/* check R820T ID register; reg=00 val=69 */
>> @@ -529,7 +531,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>>   	if (ret == 0 && buf[0] == 0x69) {
>>   		priv->tuner = TUNER_RTL2832_R820T;
>>   		priv->tuner_name = "R820T";
>> -		goto found;
>> +		goto tuner_found;
>>   	}
>>
>>   	/* check R828D ID register; reg=00 val=69 */
>> @@ -537,13 +539,37 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
>>   	if (ret == 0 && buf[0] == 0x69) {
>>   		priv->tuner = TUNER_RTL2832_R828D;
>>   		priv->tuner_name = "R828D";
>> -		goto found;
>> +		goto tuner_found;
>>   	}
>>
>> -
>> -found:
>> +tuner_found:
>>   	dev_dbg(&d->udev->dev, "%s: tuner=%s\n", __func__, priv->tuner_name);
>>
>> +	/* probe slave demod */
>> +	if (priv->tuner == TUNER_RTL2832_R828D) {
>> +		/* power on MN88472 demod on GPIO0 */
>> +		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x01, 0x01);
>> +		if (ret)
>> +			goto err;
>> +
>> +		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x01);
>> +		if (ret)
>> +			goto err;
>> +
>> +		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x01, 0x01);
>> +		if (ret)
>> +			goto err;
>> +
>> +		/* check MN88472 answers */
>> +		ret = rtl28xxu_ctrl_msg(d, &req_mn88472);
>> +		if (ret == 0 && buf[0] == 0x02) {
>> +			dev_dbg(&d->udev->dev, "%s: MN88472 found\n", __func__);
>> +			priv->slave_demod = SLAVE_DEMOD_MN88472;
>> +			goto demod_found;
>> +		}
>> +	}
>> +
>> +demod_found:
>>   	/* close demod I2C gate */
>>   	ret = rtl28xxu_ctrl_msg(d, &req_gate_close);
>>   	if (ret < 0)
>> @@ -768,6 +794,18 @@ static int rtl2832u_frontend_callback(void *adapter_priv, int component,
>>   	return 0;
>>   }
>>
>> +/* FIXME: this is a bit hackish solution */
>> +/* slave demod TS output is connected to master demod TS input */
>> +static int rtl28xxu_mn88472_init(struct dvb_frontend *fe)
>> +{
>> +	struct dvb_usb_adapter *adap = fe_to_adap(fe);
>> +	struct rtl28xxu_priv *priv = fe_to_priv(fe);
>> +	/* enable RTL2832 PIP mode */
>> +	adap->fe[0]->dtv_property_cache.frequency = 0;
>> +	adap->fe[0]->ops.set_frontend(adap->fe[0]);
>> +	return priv->init(fe);
>> +}
>> +
>>   static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
>>   {
>>   	int ret;
>> @@ -818,7 +856,48 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
>>   	/* set fe callback */
>>   	adap->fe[0]->callback = rtl2832u_frontend_callback;
>>
>> +	if (priv->slave_demod) {
>> +		struct i2c_board_info info = {};
>> +		struct i2c_client *client;
>> +
>> +		/*
>> +		 * We continue on reduced mode, without DVB-T2/C, using master
>> +		 * demod, when slave demod fails.
>> +		 */
>> +		ret = 0;
>> +
>> +		/* attach slave demodulator */
>> +		if (priv->slave_demod == SLAVE_DEMOD_MN88472) {
>> +			struct mn88472_config mn88472_config = {};
>> +
>> +			mn88472_config.fe = &adap->fe[1];
>> +			mn88472_config.i2c_wr_max = 22,
>> +			strlcpy(info.type, "mn88472", I2C_NAME_SIZE);
>> +			info.addr = 0x18;
>> +			info.platform_data = &mn88472_config;
>> +			request_module(info.type);
>> +			client = i2c_new_device(priv->demod_i2c_adapter, &info);
>> +			if (client == NULL || client->dev.driver == NULL) {
>> +				priv->slave_demod = SLAVE_DEMOD_NONE;
>> +				goto err_slave_demod_failed;
>> +			}
>> +
>> +			if (!try_module_get(client->dev.driver->owner)) {
>> +				i2c_unregister_device(client);
>> +				priv->slave_demod = SLAVE_DEMOD_NONE;
>> +				goto err_slave_demod_failed;
>> +			}
>> +
>> +			priv->i2c_client_slave_demod = client;
>> +		}
>> +
>> +		/* override init as we want configure RTL2832 as TS input */
>> +		priv->init = adap->fe[1]->ops.init;
>> +		adap->fe[1]->ops.init = rtl28xxu_mn88472_init;
>> +	}
>> +
>>   	return 0;
>> +err_slave_demod_failed:
>>   err:
>>   	dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
>>   	return ret;
>> @@ -1024,25 +1103,19 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
>>   				&rtl28xxu_rtl2832_r820t_config, NULL);
>>   		break;
>>   	case TUNER_RTL2832_R828D:
>> -		/* power off mn88472 demod on GPIO0 */
>> -		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x00, 0x01);
>> -		if (ret)
>> -			goto err;
>> -
>> -		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x01);
>> -		if (ret)
>> -			goto err;
>> -
>> -		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x01, 0x01);
>> -		if (ret)
>> -			goto err;
>> -
>> -		fe = dvb_attach(r820t_attach, adap->fe[0], &d->i2c_adap,
>> +		fe = dvb_attach(r820t_attach, adap->fe[0],
>> +				priv->demod_i2c_adapter,
>>   				&rtl2832u_r828d_config);
>> -
>> -		/* Use tuner to get the signal strength */
>>   		adap->fe[0]->ops.read_signal_strength =
>>   				adap->fe[0]->ops.tuner_ops.get_rf_strength;
>> +
>> +		if (adap->fe[1]) {
>> +			fe = dvb_attach(r820t_attach, adap->fe[1],
>> +					priv->demod_i2c_adapter,
>> +					&rtl2832u_r828d_config);
>> +			adap->fe[1]->ops.read_signal_strength =
>> +					adap->fe[1]->ops.tuner_ops.get_rf_strength;
>> +		}
>>   		break;
>>   	default:
>>   		dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
>> @@ -1097,11 +1170,19 @@ err:
>>   static void rtl28xxu_exit(struct dvb_usb_device *d)
>>   {
>>   	struct rtl28xxu_priv *priv = d->priv;
>> -	struct i2c_client *client = priv->client;
>> +	struct i2c_client *client;
>>
>>   	dev_dbg(&d->udev->dev, "%s:\n", __func__);
>>
>>   	/* remove I2C tuner */
>> +	client = priv->client;
>> +	if (client) {
>> +		module_put(client->dev.driver->owner);
>> +		i2c_unregister_device(client);
>> +	}
>> +
>> +	/* remove I2C slave demod */
>> +	client = priv->i2c_client_slave_demod;
>>   	if (client) {
>>   		module_put(client->dev.driver->owner);
>>   		i2c_unregister_device(client);
>> diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
>> index a26cab1..58f2730 100644
>> --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
>> +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
>> @@ -58,6 +58,11 @@ struct rtl28xxu_priv {
>>   	struct i2c_adapter *demod_i2c_adapter;
>>   	bool rc_active;
>>   	struct i2c_client *client;
>> +	struct i2c_client *i2c_client_slave_demod;
>> +	int (*init)(struct dvb_frontend *fe);
>> +	#define SLAVE_DEMOD_NONE           0
>> +	#define SLAVE_DEMOD_MN88472        1
>> +	unsigned int slave_demod:1;
>>   };
>>
>>   enum rtl28xxu_chip_id {

-- 
http://palosaari.fi/

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 4/8] rtl28xxu: add support for Panasonic MN88472 slave demod
  2014-11-14 23:42     ` Antti Palosaari
@ 2014-11-15  1:07       ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 18+ messages in thread
From: Mauro Carvalho Chehab @ 2014-11-15  1:07 UTC (permalink / raw)
  To: Antti Palosaari; +Cc: linux-media

Em Sat, 15 Nov 2014 01:42:43 +0200
Antti Palosaari <crope@iki.fi> escreveu:

> 
> 
> On 11/14/2014 09:39 PM, Mauro Carvalho Chehab wrote:
> > Em Wed, 12 Nov 2014 06:23:06 +0200
> > Antti Palosaari <crope@iki.fi> escreveu:
> >
> >> There is RTL2832P devices having extra MN88472 demodulator. This
> >> patch add support for such configuration. Logically MN88472 slave
> >> demodulator is connected to RTL2832 master demodulator, both I2C
> >> bus and TS input. RTL2832 is integrated to RTL2832U and RTL2832P
> >> chips. Chip version RTL2832P has extra TS interface for connecting
> >> slave demodulator.
> >>
> >> Signed-off-by: Antti Palosaari <crope@iki.fi>
> >> ---
> >>   drivers/media/usb/dvb-usb-v2/Kconfig    |   1 +
> >>   drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 143 +++++++++++++++++++++++++-------
> >>   drivers/media/usb/dvb-usb-v2/rtl28xxu.h |   5 ++
> >>   3 files changed, 118 insertions(+), 31 deletions(-)
> >>
> >> diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig
> >> index 7423033..9050933 100644
> >> --- a/drivers/media/usb/dvb-usb-v2/Kconfig
> >> +++ b/drivers/media/usb/dvb-usb-v2/Kconfig
> >> @@ -130,6 +130,7 @@ config DVB_USB_RTL28XXU
> >>   	select DVB_RTL2830
> >>   	select DVB_RTL2832
> >>   	select DVB_RTL2832_SDR if (MEDIA_SUBDRV_AUTOSELECT && MEDIA_SDR_SUPPORT)
> >> +	select DVB_MN88472 if MEDIA_SUBDRV_AUTOSELECT
> >>   	select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
> >>   	select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
> >>   	select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
> >
> > This is not a good idea, as the MN88472 is in staging.
> >
> > Select is not recursive, and won't select STAGING. Also, we don't want
> > to enable a staging driver by default on distros.
> 
> I think it should work just fine. It is I2C driver. If distributions 
> disables stating nothing will happen but MN88472 driver is not compiled. 
> When there is no driver load, it will continue with reduced mode using 
> single demod. I tested that scenario where driver was missing. Anyhow, I 
> didn't test case where CONFIG_STAGING Kconfig option was disable, but I 
> will do.

select will just ignore config_staging, enabling this driver even if
staging is disabled.

Perhaps one way to solve would be to do:

select DVB_MN88472 if MEDIA_SUBDRV_AUTOSELECT && STAGING

Still, I the best would be to just remove that line, and add a 
documentation on our wiki (and/or via printk) warning the user to
manually enable the driver on staging, if the user has a device that
needs it.

Regards,
Mauro

PS.: I'll do a deeper look on your comments about patch 2/8 likely
tomorrow or next week.
> 
> regards
> Antti
> 
> 
> >
> >> diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
> >> index 5ea52c7..e3c20f4 100644
> >> --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
> >> +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
> >> @@ -24,6 +24,7 @@
> >>
> >>   #include "rtl2830.h"
> >>   #include "rtl2832.h"
> >> +#include "mn88472.h"
> >>
> >>   #include "qt1010.h"
> >>   #include "mt2060.h"
> >> @@ -420,6 +421,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
> >>   	struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf};
> >>   	struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 1, buf};
> >>   	struct rtl28xxu_req req_r828d = {0x0074, CMD_I2C_RD, 1, buf};
> >> +	struct rtl28xxu_req req_mn88472 = {0xff38, CMD_I2C_RD, 1, buf};
> >>
> >>   	dev_dbg(&d->udev->dev, "%s:\n", __func__);
> >>
> >> @@ -449,7 +451,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
> >>   	if (ret == 0 && buf[0] == 0xa1) {
> >>   		priv->tuner = TUNER_RTL2832_FC0012;
> >>   		priv->tuner_name = "FC0012";
> >> -		goto found;
> >> +		goto tuner_found;
> >>   	}
> >>
> >>   	/* check FC0013 ID register; reg=00 val=a3 */
> >> @@ -457,7 +459,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
> >>   	if (ret == 0 && buf[0] == 0xa3) {
> >>   		priv->tuner = TUNER_RTL2832_FC0013;
> >>   		priv->tuner_name = "FC0013";
> >> -		goto found;
> >> +		goto tuner_found;
> >>   	}
> >>
> >>   	/* check MT2266 ID register; reg=00 val=85 */
> >> @@ -465,7 +467,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
> >>   	if (ret == 0 && buf[0] == 0x85) {
> >>   		priv->tuner = TUNER_RTL2832_MT2266;
> >>   		priv->tuner_name = "MT2266";
> >> -		goto found;
> >> +		goto tuner_found;
> >>   	}
> >>
> >>   	/* check FC2580 ID register; reg=01 val=56 */
> >> @@ -473,7 +475,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
> >>   	if (ret == 0 && buf[0] == 0x56) {
> >>   		priv->tuner = TUNER_RTL2832_FC2580;
> >>   		priv->tuner_name = "FC2580";
> >> -		goto found;
> >> +		goto tuner_found;
> >>   	}
> >>
> >>   	/* check MT2063 ID register; reg=00 val=9e || 9c */
> >> @@ -481,7 +483,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
> >>   	if (ret == 0 && (buf[0] == 0x9e || buf[0] == 0x9c)) {
> >>   		priv->tuner = TUNER_RTL2832_MT2063;
> >>   		priv->tuner_name = "MT2063";
> >> -		goto found;
> >> +		goto tuner_found;
> >>   	}
> >>
> >>   	/* check MAX3543 ID register; reg=00 val=38 */
> >> @@ -489,7 +491,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
> >>   	if (ret == 0 && buf[0] == 0x38) {
> >>   		priv->tuner = TUNER_RTL2832_MAX3543;
> >>   		priv->tuner_name = "MAX3543";
> >> -		goto found;
> >> +		goto tuner_found;
> >>   	}
> >>
> >>   	/* check TUA9001 ID register; reg=7e val=2328 */
> >> @@ -497,7 +499,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
> >>   	if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) {
> >>   		priv->tuner = TUNER_RTL2832_TUA9001;
> >>   		priv->tuner_name = "TUA9001";
> >> -		goto found;
> >> +		goto tuner_found;
> >>   	}
> >>
> >>   	/* check MXL5007R ID register; reg=d9 val=14 */
> >> @@ -505,7 +507,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
> >>   	if (ret == 0 && buf[0] == 0x14) {
> >>   		priv->tuner = TUNER_RTL2832_MXL5007T;
> >>   		priv->tuner_name = "MXL5007T";
> >> -		goto found;
> >> +		goto tuner_found;
> >>   	}
> >>
> >>   	/* check E4000 ID register; reg=02 val=40 */
> >> @@ -513,7 +515,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
> >>   	if (ret == 0 && buf[0] == 0x40) {
> >>   		priv->tuner = TUNER_RTL2832_E4000;
> >>   		priv->tuner_name = "E4000";
> >> -		goto found;
> >> +		goto tuner_found;
> >>   	}
> >>
> >>   	/* check TDA18272 ID register; reg=00 val=c760  */
> >> @@ -521,7 +523,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
> >>   	if (ret == 0 && (buf[0] == 0xc7 || buf[1] == 0x60)) {
> >>   		priv->tuner = TUNER_RTL2832_TDA18272;
> >>   		priv->tuner_name = "TDA18272";
> >> -		goto found;
> >> +		goto tuner_found;
> >>   	}
> >>
> >>   	/* check R820T ID register; reg=00 val=69 */
> >> @@ -529,7 +531,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
> >>   	if (ret == 0 && buf[0] == 0x69) {
> >>   		priv->tuner = TUNER_RTL2832_R820T;
> >>   		priv->tuner_name = "R820T";
> >> -		goto found;
> >> +		goto tuner_found;
> >>   	}
> >>
> >>   	/* check R828D ID register; reg=00 val=69 */
> >> @@ -537,13 +539,37 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
> >>   	if (ret == 0 && buf[0] == 0x69) {
> >>   		priv->tuner = TUNER_RTL2832_R828D;
> >>   		priv->tuner_name = "R828D";
> >> -		goto found;
> >> +		goto tuner_found;
> >>   	}
> >>
> >> -
> >> -found:
> >> +tuner_found:
> >>   	dev_dbg(&d->udev->dev, "%s: tuner=%s\n", __func__, priv->tuner_name);
> >>
> >> +	/* probe slave demod */
> >> +	if (priv->tuner == TUNER_RTL2832_R828D) {
> >> +		/* power on MN88472 demod on GPIO0 */
> >> +		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x01, 0x01);
> >> +		if (ret)
> >> +			goto err;
> >> +
> >> +		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x01);
> >> +		if (ret)
> >> +			goto err;
> >> +
> >> +		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x01, 0x01);
> >> +		if (ret)
> >> +			goto err;
> >> +
> >> +		/* check MN88472 answers */
> >> +		ret = rtl28xxu_ctrl_msg(d, &req_mn88472);
> >> +		if (ret == 0 && buf[0] == 0x02) {
> >> +			dev_dbg(&d->udev->dev, "%s: MN88472 found\n", __func__);
> >> +			priv->slave_demod = SLAVE_DEMOD_MN88472;
> >> +			goto demod_found;
> >> +		}
> >> +	}
> >> +
> >> +demod_found:
> >>   	/* close demod I2C gate */
> >>   	ret = rtl28xxu_ctrl_msg(d, &req_gate_close);
> >>   	if (ret < 0)
> >> @@ -768,6 +794,18 @@ static int rtl2832u_frontend_callback(void *adapter_priv, int component,
> >>   	return 0;
> >>   }
> >>
> >> +/* FIXME: this is a bit hackish solution */
> >> +/* slave demod TS output is connected to master demod TS input */
> >> +static int rtl28xxu_mn88472_init(struct dvb_frontend *fe)
> >> +{
> >> +	struct dvb_usb_adapter *adap = fe_to_adap(fe);
> >> +	struct rtl28xxu_priv *priv = fe_to_priv(fe);
> >> +	/* enable RTL2832 PIP mode */
> >> +	adap->fe[0]->dtv_property_cache.frequency = 0;
> >> +	adap->fe[0]->ops.set_frontend(adap->fe[0]);
> >> +	return priv->init(fe);
> >> +}
> >> +
> >>   static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
> >>   {
> >>   	int ret;
> >> @@ -818,7 +856,48 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
> >>   	/* set fe callback */
> >>   	adap->fe[0]->callback = rtl2832u_frontend_callback;
> >>
> >> +	if (priv->slave_demod) {
> >> +		struct i2c_board_info info = {};
> >> +		struct i2c_client *client;
> >> +
> >> +		/*
> >> +		 * We continue on reduced mode, without DVB-T2/C, using master
> >> +		 * demod, when slave demod fails.
> >> +		 */
> >> +		ret = 0;
> >> +
> >> +		/* attach slave demodulator */
> >> +		if (priv->slave_demod == SLAVE_DEMOD_MN88472) {
> >> +			struct mn88472_config mn88472_config = {};
> >> +
> >> +			mn88472_config.fe = &adap->fe[1];
> >> +			mn88472_config.i2c_wr_max = 22,
> >> +			strlcpy(info.type, "mn88472", I2C_NAME_SIZE);
> >> +			info.addr = 0x18;
> >> +			info.platform_data = &mn88472_config;
> >> +			request_module(info.type);
> >> +			client = i2c_new_device(priv->demod_i2c_adapter, &info);
> >> +			if (client == NULL || client->dev.driver == NULL) {
> >> +				priv->slave_demod = SLAVE_DEMOD_NONE;
> >> +				goto err_slave_demod_failed;
> >> +			}
> >> +
> >> +			if (!try_module_get(client->dev.driver->owner)) {
> >> +				i2c_unregister_device(client);
> >> +				priv->slave_demod = SLAVE_DEMOD_NONE;
> >> +				goto err_slave_demod_failed;
> >> +			}
> >> +
> >> +			priv->i2c_client_slave_demod = client;
> >> +		}
> >> +
> >> +		/* override init as we want configure RTL2832 as TS input */
> >> +		priv->init = adap->fe[1]->ops.init;
> >> +		adap->fe[1]->ops.init = rtl28xxu_mn88472_init;
> >> +	}
> >> +
> >>   	return 0;
> >> +err_slave_demod_failed:
> >>   err:
> >>   	dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
> >>   	return ret;
> >> @@ -1024,25 +1103,19 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
> >>   				&rtl28xxu_rtl2832_r820t_config, NULL);
> >>   		break;
> >>   	case TUNER_RTL2832_R828D:
> >> -		/* power off mn88472 demod on GPIO0 */
> >> -		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x00, 0x01);
> >> -		if (ret)
> >> -			goto err;
> >> -
> >> -		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x01);
> >> -		if (ret)
> >> -			goto err;
> >> -
> >> -		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x01, 0x01);
> >> -		if (ret)
> >> -			goto err;
> >> -
> >> -		fe = dvb_attach(r820t_attach, adap->fe[0], &d->i2c_adap,
> >> +		fe = dvb_attach(r820t_attach, adap->fe[0],
> >> +				priv->demod_i2c_adapter,
> >>   				&rtl2832u_r828d_config);
> >> -
> >> -		/* Use tuner to get the signal strength */
> >>   		adap->fe[0]->ops.read_signal_strength =
> >>   				adap->fe[0]->ops.tuner_ops.get_rf_strength;
> >> +
> >> +		if (adap->fe[1]) {
> >> +			fe = dvb_attach(r820t_attach, adap->fe[1],
> >> +					priv->demod_i2c_adapter,
> >> +					&rtl2832u_r828d_config);
> >> +			adap->fe[1]->ops.read_signal_strength =
> >> +					adap->fe[1]->ops.tuner_ops.get_rf_strength;
> >> +		}
> >>   		break;
> >>   	default:
> >>   		dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
> >> @@ -1097,11 +1170,19 @@ err:
> >>   static void rtl28xxu_exit(struct dvb_usb_device *d)
> >>   {
> >>   	struct rtl28xxu_priv *priv = d->priv;
> >> -	struct i2c_client *client = priv->client;
> >> +	struct i2c_client *client;
> >>
> >>   	dev_dbg(&d->udev->dev, "%s:\n", __func__);
> >>
> >>   	/* remove I2C tuner */
> >> +	client = priv->client;
> >> +	if (client) {
> >> +		module_put(client->dev.driver->owner);
> >> +		i2c_unregister_device(client);
> >> +	}
> >> +
> >> +	/* remove I2C slave demod */
> >> +	client = priv->i2c_client_slave_demod;
> >>   	if (client) {
> >>   		module_put(client->dev.driver->owner);
> >>   		i2c_unregister_device(client);
> >> diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
> >> index a26cab1..58f2730 100644
> >> --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
> >> +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
> >> @@ -58,6 +58,11 @@ struct rtl28xxu_priv {
> >>   	struct i2c_adapter *demod_i2c_adapter;
> >>   	bool rc_active;
> >>   	struct i2c_client *client;
> >> +	struct i2c_client *i2c_client_slave_demod;
> >> +	int (*init)(struct dvb_frontend *fe);
> >> +	#define SLAVE_DEMOD_NONE           0
> >> +	#define SLAVE_DEMOD_MN88472        1
> >> +	unsigned int slave_demod:1;
> >>   };
> >>
> >>   enum rtl28xxu_chip_id {
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/8] rtl2832: implement PIP mode
  2014-11-14 23:36     ` Antti Palosaari
@ 2014-11-16 10:25       ` Mauro Carvalho Chehab
  2014-11-16 11:36         ` Benjamin Larsson
  0 siblings, 1 reply; 18+ messages in thread
From: Mauro Carvalho Chehab @ 2014-11-16 10:25 UTC (permalink / raw)
  To: Antti Palosaari; +Cc: linux-media

Em Sat, 15 Nov 2014 01:36:48 +0200
Antti Palosaari <crope@iki.fi> escreveu:

> Moikka!
> 
> On 11/14/2014 09:34 PM, Mauro Carvalho Chehab wrote:
> > Em Wed, 12 Nov 2014 06:23:04 +0200
> > Antti Palosaari <crope@iki.fi> escreveu:
> >
> >> Implement PIP mode to stream from slave demodulator. PIP mode is
> >> enabled when .set_frontend is called with RF frequency 0, otherwise
> >> normal demod mode is enabled.
> >
> > This would be an API change, so, a DocBook patch is required.
> 
> You are wrong. PIP mode is driver/device internal thing and will not be 
> revealed to userspace.
> 
> > Anyway, using frequency=0 for PIP doesn't seem to be a good idea,
> > as a read from GET_PROPERTY should override the cache with the real
> > frequency.
> 
> Yes, it is a hackish solution, used to put demod#0 on certain config 
> when demod#1 is used. When PIP mode is set that demod#0 is totally 
> useless as demod#1 is in use instead. Cache is garbage and no meaning at 
> all.
> 
> > Also, someone came with me with a case where auto-frequency would
> > be interesting, and proposed frequency=0. I was not convinced
> > (and patches weren't sent), but using 0 for AUTO seems more
> > appropriate, as we do the same for bandwidth (and may do the same
> > for symbol_rate).
> 
> I totally agree that is is hackish solution. That is called from 
> rtl28xxu.c driver and I added already comment it is hackish solution, 
> but you didn't apply that commit.
> 
> > So, the best seems to add a new property to enable PIP mode.
> 
> No, no, no. It is like a PIP filter. It is actually special case of PID 
> filter, having mux, to multiplex 2 TS interfaces to one (PIP = Picture 
> in Picture).
> 
> 
> .............................................
> . RTL2832P integrates RTL2832 demodulator   .
> . ____________                ____________  .              ____________
> .|   USB IF   |              |   demod    | .             |   demod    |
> .|------------|              |------------| .             |------------|
> .|  RTL2832P  |              |  RTL2832   | .             |  MN88472   |
> .|            |----TS bus----|-----/ -----|-.---TS bus----|            |
> .|____________|              |____________| .             |____________|
> .............................................
> 
> 
> So the basically both demod PID filters are now implemented in RTL2832 
> demod. Currently PIP mode is configured just to pass all the PIDs from 
> MN88472 and reject RTL2832 PIDs. And when PIP mode is off, at pass all 
> the PIDs from RTL2832, but rejects all PIDs from MN88472.

Oh, I see.

What demod(s) are exposed to userspace? both or just demod#1?

If both are exposed, how userspace knows that demod#0 should not be
used?

Regards,
Mauro

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/8] rtl2832: implement PIP mode
  2014-11-16 10:25       ` Mauro Carvalho Chehab
@ 2014-11-16 11:36         ` Benjamin Larsson
  2014-11-16 15:09           ` Antti Palosaari
  0 siblings, 1 reply; 18+ messages in thread
From: Benjamin Larsson @ 2014-11-16 11:36 UTC (permalink / raw)
  To: linux-media

On 11/16/2014 11:25 AM, Mauro Carvalho Chehab wrote:
>
> [...]
> What demod(s) are exposed to userspace? both or just demod#1?
>
> If both are exposed, how userspace knows that demod#0 should not be
> used?
>
> Regards,
> Mauro
>

Currently both demods are exposed to userspace. While it is nice to have 
both I suggest that if a NM8847x demod is activated only expose that 
demod. That would remove the hack in master and would make it possible 
to faster move the NM8847x demods out of staging. The main reason for 
this hardware is the DVB-C and DVB-T2 support. Lets focus on getting 
that in an easy obtainable way.

MvH
Benjamin Larsson

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/8] rtl2832: implement PIP mode
  2014-11-16 11:36         ` Benjamin Larsson
@ 2014-11-16 15:09           ` Antti Palosaari
  0 siblings, 0 replies; 18+ messages in thread
From: Antti Palosaari @ 2014-11-16 15:09 UTC (permalink / raw)
  To: Benjamin Larsson, linux-media

On 11/16/2014 01:36 PM, Benjamin Larsson wrote:
> On 11/16/2014 11:25 AM, Mauro Carvalho Chehab wrote:
>>
>> [...]
>> What demod(s) are exposed to userspace? both or just demod#1?
>>
>> If both are exposed, how userspace knows that demod#0 should not be
>> used?
>>
>> Regards,
>> Mauro
>>
>
> Currently both demods are exposed to userspace. While it is nice to have
> both I suggest that if a NM8847x demod is activated only expose that
> demod. That would remove the hack in master and would make it possible
> to faster move the NM8847x demods out of staging. The main reason for
> this hardware is the DVB-C and DVB-T2 support. Lets focus on getting
> that in an easy obtainable way.

Yeah, both demods are exposed on single adapter, but two frontends.
frontend0 == DVB-T demod RTL2832
frontend1 == DVB-T/T2/C demod MN88472

frontend0 is pretty useless if frontend1 is loaded...

regards
Antti

-- 
http://palosaari.fi/

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2014-11-16 15:09 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-12  4:23 [PATCH 0/8] Astrometa DVB USB support Antti Palosaari
2014-11-12  4:23 ` [PATCH 1/8] r820t: add DVB-C config Antti Palosaari
2014-11-12  4:23 ` [PATCH 2/8] rtl2832: implement PIP mode Antti Palosaari
2014-11-14 19:34   ` Mauro Carvalho Chehab
2014-11-14 23:36     ` Antti Palosaari
2014-11-16 10:25       ` Mauro Carvalho Chehab
2014-11-16 11:36         ` Benjamin Larsson
2014-11-16 15:09           ` Antti Palosaari
2014-11-12  4:23 ` [PATCH 3/8] rtl28xxu: enable demod ADC only when needed Antti Palosaari
2014-11-12  4:23 ` [PATCH 4/8] rtl28xxu: add support for Panasonic MN88472 slave demod Antti Palosaari
2014-11-14 19:39   ` Mauro Carvalho Chehab
2014-11-14 23:42     ` Antti Palosaari
2014-11-15  1:07       ` Mauro Carvalho Chehab
2014-11-12  4:23 ` [PATCH 5/8] rtl28xxu: add support for Panasonic MN88473 " Antti Palosaari
2014-11-14 19:40   ` Mauro Carvalho Chehab
2014-11-12  4:23 ` [PATCH 6/8] rtl28xxu: rename tuner I2C client pointer Antti Palosaari
2014-11-12  4:23 ` [PATCH 7/8] rtl28xxu: remove unused SDR attach logic Antti Palosaari
2014-11-12  4:23 ` [PATCH 8/8] rtl28xxu: add SDR module for devices having R828D tuner Antti Palosaari

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).