Linux-Media Archive on lore.kernel.org
 help / Atom feed
* [PATCH 0/4] Add Hauppauge HVR1955/1975 devices
@ 2018-12-20 21:57 Brad Love
  2018-12-20 21:57 ` [PATCH 1/4] si2157: add detection of si2177 tuner Brad Love
                   ` (4 more replies)
  0 siblings, 5 replies; 36+ messages in thread
From: Brad Love @ 2018-12-20 21:57 UTC (permalink / raw)
  To: linux-media, mchehab; +Cc: Brad Love

Hauppauge device HVR1955 and HVR1975 are old Cypress based
devices. When originally produced the demods were lacking
upstream drivers and the tuner was unsupported. Well fast
forward to now and the only thing missing is the identification
of si2177 tuner in the si2157 driver, as well as extension
of the pvrusb2 driver to accomodate i2c client devices
and multiple frontends. This series addresses what is necessary.

QAM/ATSC are fully tested and work, the DVB tuning
*should* work, but is completely untested. Both demod
drivers are compatible with multiple frontend usage due
to previous patches I've submitted, so things should
work in pvrusb2 as well.

Composite video input is tested. Unable to test s-video,
but it should work. Radio is fully untested. Analog TV is
a work in progress, coming soon.

HVR-1955:
- LGDT3306a ATSC/QAM demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

HVR-1975 dual-frontend:
- LGDT3306a ATSC/QAM demod
- si2168 DVB-C/T/T2 demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio


Brad Love (4):
  si2157: add detection of si2177 tuner
  pvrusb2: Add multiple dvb frontend support
  pvrusb2: Add i2c client demod/tuner support
  pvrusb2: Add Hauppauge HVR1955/1975 devices

 drivers/media/tuners/si2157.c                   |   6 +
 drivers/media/tuners/si2157_priv.h              |   3 +-
 drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c |  25 +++
 drivers/media/usb/pvrusb2/pvrusb2-devattr.c     | 202 +++++++++++++++++++++---
 drivers/media/usb/pvrusb2/pvrusb2-devattr.h     |   1 +
 drivers/media/usb/pvrusb2/pvrusb2-dvb.c         |  88 ++++++++---
 drivers/media/usb/pvrusb2/pvrusb2-dvb.h         |   5 +-
 drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h     |   4 +
 drivers/media/usb/pvrusb2/pvrusb2-hdw.c         |  36 ++++-
 9 files changed, 330 insertions(+), 40 deletions(-)

-- 
2.7.4


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

* [PATCH 1/4] si2157: add detection of si2177 tuner
  2018-12-20 21:57 [PATCH 0/4] Add Hauppauge HVR1955/1975 devices Brad Love
@ 2018-12-20 21:57 ` Brad Love
  2019-01-09 17:36   ` Antti Palosaari
  2018-12-20 21:57 ` [PATCH 2/4] pvrusb2: Add multiple dvb frontend support Brad Love
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 36+ messages in thread
From: Brad Love @ 2018-12-20 21:57 UTC (permalink / raw)
  To: linux-media, mchehab; +Cc: Brad Love

Works in ATSC and QAM as is, DVB is completely untested.

Firmware required.

Signed-off-by: Brad Love <brad@nextdimension.cc>
---
 drivers/media/tuners/si2157.c      | 6 ++++++
 drivers/media/tuners/si2157_priv.h | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index d389f1f..3d21af5 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -138,6 +138,7 @@ static int si2157_init(struct dvb_frontend *fe)
 	chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
 			cmd.args[4] << 0;
 
+	#define SI2177_A30 ('A' << 24 | 77 << 16 | '3' << 8 | '0' << 0)
 	#define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
 	#define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0)
 	#define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
@@ -153,6 +154,9 @@ static int si2157_init(struct dvb_frontend *fe)
 	case SI2141_A10:
 		fw_name = SI2141_A10_FIRMWARE;
 		break;
+	case SI2177_A30:
+		fw_name = SI2157_A30_FIRMWARE;
+		break;
 	case SI2157_A30:
 	case SI2147_A30:
 	case SI2146_A10:
@@ -529,6 +533,7 @@ static const struct i2c_device_id si2157_id_table[] = {
 	{"si2157", SI2157_CHIPTYPE_SI2157},
 	{"si2146", SI2157_CHIPTYPE_SI2146},
 	{"si2141", SI2157_CHIPTYPE_SI2141},
+	{"si2177", SI2157_CHIPTYPE_SI2177},
 	{}
 };
 MODULE_DEVICE_TABLE(i2c, si2157_id_table);
@@ -550,3 +555,4 @@ MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 MODULE_LICENSE("GPL");
 MODULE_FIRMWARE(SI2158_A20_FIRMWARE);
 MODULE_FIRMWARE(SI2141_A10_FIRMWARE);
+MODULE_FIRMWARE(SI2157_A30_FIRMWARE);
diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h
index 50f8630..67caee5 100644
--- a/drivers/media/tuners/si2157_priv.h
+++ b/drivers/media/tuners/si2157_priv.h
@@ -50,6 +50,7 @@ struct si2157_dev {
 #define SI2157_CHIPTYPE_SI2157 0
 #define SI2157_CHIPTYPE_SI2146 1
 #define SI2157_CHIPTYPE_SI2141 2
+#define SI2157_CHIPTYPE_SI2177 3
 
 /* firmware command struct */
 #define SI2157_ARGLEN      30
@@ -61,5 +62,5 @@ struct si2157_cmd {
 
 #define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"
 #define SI2141_A10_FIRMWARE "dvb-tuner-si2141-a10-01.fw"
-
+#define SI2157_A30_FIRMWARE "dvb-tuner-si2157-a30-05.fw"
 #endif
-- 
2.7.4


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

* [PATCH 2/4] pvrusb2: Add multiple dvb frontend support
  2018-12-20 21:57 [PATCH 0/4] Add Hauppauge HVR1955/1975 devices Brad Love
  2018-12-20 21:57 ` [PATCH 1/4] si2157: add detection of si2177 tuner Brad Love
@ 2018-12-20 21:57 ` Brad Love
  2018-12-20 21:57 ` [PATCH 3/4] pvrusb2: Add i2c client demod/tuner support Brad Love
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 36+ messages in thread
From: Brad Love @ 2018-12-20 21:57 UTC (permalink / raw)
  To: linux-media, mchehab; +Cc: Brad Love

All changes are equivalent and backwards compatible.
All current devices have been changed to use fe[0]
Cleanup has been added to dvb init to support cleanup after failure.

Signed-off-by: Brad Love <brad@nextdimension.cc>
---
 drivers/media/usb/pvrusb2/pvrusb2-devattr.c | 36 +++++++-------
 drivers/media/usb/pvrusb2/pvrusb2-dvb.c     | 77 ++++++++++++++++++++++-------
 drivers/media/usb/pvrusb2/pvrusb2-dvb.h     |  2 +-
 3 files changed, 77 insertions(+), 38 deletions(-)

diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
index 06de1c8..ef36b62 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
@@ -188,10 +188,10 @@ static struct lgdt330x_config pvr2_lgdt3303_config = {
 
 static int pvr2_lgdt3303_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3303_config,
-			      0x0e,
-			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	adap->fe[0] = dvb_attach(lgdt330x_attach, &pvr2_lgdt3303_config,
+				 0x0e,
+				 &adap->channel.hdw->i2c_adap);
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -199,7 +199,7 @@ static int pvr2_lgdt3303_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_lgh06xf_attach(struct pvr2_dvb_adapter *adap)
 {
-	dvb_attach(simple_tuner_attach, adap->fe,
+	dvb_attach(simple_tuner_attach, adap->fe[0],
 		   &adap->channel.hdw->i2c_adap, 0x61,
 		   TUNER_LG_TDVS_H06XF);
 
@@ -248,10 +248,10 @@ static struct lgdt330x_config pvr2_lgdt3302_config = {
 
 static int pvr2_lgdt3302_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3302_config,
+	adap->fe[0] = dvb_attach(lgdt330x_attach, &pvr2_lgdt3302_config,
 			      0x0e,
 			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -259,7 +259,7 @@ static int pvr2_lgdt3302_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_fcv1236d_attach(struct pvr2_dvb_adapter *adap)
 {
-	dvb_attach(simple_tuner_attach, adap->fe,
+	dvb_attach(simple_tuner_attach, adap->fe[0],
 		   &adap->channel.hdw->i2c_adap, 0x61,
 		   TUNER_PHILIPS_FCV1236D);
 
@@ -335,9 +335,9 @@ static struct tda18271_config hauppauge_tda18271_dvb_config = {
 
 static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(tda10048_attach, &hauppauge_tda10048_config,
+	adap->fe[0] = dvb_attach(tda10048_attach, &hauppauge_tda10048_config,
 			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -345,10 +345,10 @@ static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_73xxx_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
 {
-	dvb_attach(tda829x_attach, adap->fe,
+	dvb_attach(tda829x_attach, adap->fe[0],
 		   &adap->channel.hdw->i2c_adap, 0x42,
 		   &tda829x_no_probe);
-	dvb_attach(tda18271_attach, adap->fe, 0x60,
+	dvb_attach(tda18271_attach, adap->fe[0], 0x60,
 		   &adap->channel.hdw->i2c_adap,
 		   &hauppauge_tda18271_dvb_config);
 
@@ -433,9 +433,9 @@ static struct tda18271_config hauppauge_tda18271_config = {
 
 static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(s5h1409_attach, &pvr2_s5h1409_config,
+	adap->fe[0] = dvb_attach(s5h1409_attach, &pvr2_s5h1409_config,
 			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -443,9 +443,9 @@ static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_s5h1411_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(s5h1411_attach, &pvr2_s5h1411_config,
+	adap->fe[0] = dvb_attach(s5h1411_attach, &pvr2_s5h1411_config,
 			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -453,10 +453,10 @@ static int pvr2_s5h1411_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
 {
-	dvb_attach(tda829x_attach, adap->fe,
+	dvb_attach(tda829x_attach, adap->fe[0],
 		   &adap->channel.hdw->i2c_adap, 0x42,
 		   &tda829x_no_probe);
-	dvb_attach(tda18271_attach, adap->fe, 0x60,
+	dvb_attach(tda18271_attach, adap->fe[0], 0x60,
 		   &adap->channel.hdw->i2c_adap,
 		   &hauppauge_tda18271_config);
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
index 4b32b21..cb5586b 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
@@ -343,26 +343,19 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
 		goto done;
 	}
 
-	if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) {
-
-		if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
+	if (dvb_props->frontend_attach(adap) == 0 && adap->fe[0]) {
+		if (dvb_register_frontend(&adap->dvb_adap, adap->fe[0])) {
 			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 				   "frontend registration failed!");
-			dvb_frontend_detach(adap->fe);
-			adap->fe = NULL;
 			ret = -ENODEV;
-			goto done;
+			goto fail_frontend0;
 		}
+		if (adap->fe[0]->ops.analog_ops.standby)
+			adap->fe[0]->ops.analog_ops.standby(adap->fe[0]);
 
-		if (dvb_props->tuner_attach)
-			dvb_props->tuner_attach(adap);
-
-		if (adap->fe->ops.analog_ops.standby)
-			adap->fe->ops.analog_ops.standby(adap->fe);
-
-		/* Ensure all frontends negotiate bus access */
-		adap->fe->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
-
+		pvr2_trace(PVR2_TRACE_INFO, "transferring fe[%d] ts_bus_ctrl() to pvr2_dvb_bus_ctrl()",
+				adap->fe[0]->id);
+		adap->fe[0]->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
 	} else {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 			   "no frontend was attached!");
@@ -370,16 +363,62 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
 		return ret;
 	}
 
- done:
+	if (dvb_props->tuner_attach && dvb_props->tuner_attach(adap)) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS, "tuner attach failed");
+		ret = -ENODEV;
+		goto fail_tuner;
+	}
+
+	if (adap->fe[1]) {
+		adap->fe[1]->id = 1;
+		adap->fe[1]->tuner_priv = adap->fe[0]->tuner_priv;
+		memcpy(&adap->fe[1]->ops.tuner_ops,
+			&adap->fe[0]->ops.tuner_ops,
+			sizeof(struct dvb_tuner_ops));
+
+		if (dvb_register_frontend(&adap->dvb_adap, adap->fe[1])) {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "frontend registration failed!");
+			ret = -ENODEV;
+			goto fail_frontend1;
+		}
+		/* MFE lock */
+		adap->dvb_adap.mfe_shared = 1;
+
+		if (adap->fe[1]->ops.analog_ops.standby)
+			adap->fe[1]->ops.analog_ops.standby(adap->fe[1]);
+
+		pvr2_trace(PVR2_TRACE_INFO, "transferring fe[%d] ts_bus_ctrl() to pvr2_dvb_bus_ctrl()",
+				adap->fe[1]->id);
+		adap->fe[1]->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
+	}
+done:
 	pvr2_channel_limit_inputs(&adap->channel, 0);
 	return ret;
+
+fail_frontend1:
+	dvb_frontend_detach(adap->fe[1]);
+	adap->fe[1] = NULL;
+fail_tuner:
+	dvb_unregister_frontend(adap->fe[0]);
+fail_frontend0:
+	dvb_frontend_detach(adap->fe[0]);
+	adap->fe[0] = NULL;
+
+	return ret;
 }
 
 static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap)
 {
-	if (adap->fe != NULL) {
-		dvb_unregister_frontend(adap->fe);
-		dvb_frontend_detach(adap->fe);
+	if (adap->fe[1]) {
+		dvb_unregister_frontend(adap->fe[1]);
+		dvb_frontend_detach(adap->fe[1]);
+		adap->fe[1] = NULL;
+	}
+	if (adap->fe[0]) {
+		dvb_unregister_frontend(adap->fe[0]);
+		dvb_frontend_detach(adap->fe[0]);
+		adap->fe[0] = NULL;
 	}
 	return 0;
 }
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
index e7f71fb..91bff57 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
@@ -18,7 +18,7 @@ struct pvr2_dvb_adapter {
 	struct dmxdev		dmxdev;
 	struct dvb_demux	demux;
 	struct dvb_net		dvb_net;
-	struct dvb_frontend	*fe;
+	struct dvb_frontend	*fe[2];
 
 	int			feedcount;
 	int			max_feed_count;
-- 
2.7.4


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

* [PATCH 3/4] pvrusb2: Add i2c client demod/tuner support
  2018-12-20 21:57 [PATCH 0/4] Add Hauppauge HVR1955/1975 devices Brad Love
  2018-12-20 21:57 ` [PATCH 1/4] si2157: add detection of si2177 tuner Brad Love
  2018-12-20 21:57 ` [PATCH 2/4] pvrusb2: Add multiple dvb frontend support Brad Love
@ 2018-12-20 21:57 ` Brad Love
  2018-12-20 21:57 ` [PATCH 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
  2018-12-21 19:40 ` [PATCH v2 0/4] " Brad Love
  4 siblings, 0 replies; 36+ messages in thread
From: Brad Love @ 2018-12-20 21:57 UTC (permalink / raw)
  To: linux-media, mchehab; +Cc: Brad Love

Cleanup code has been added to init in case of failure,
as well as to frontend exit.

Signed-off-by: Brad Love <brad@nextdimension.cc>
---
 drivers/media/usb/pvrusb2/pvrusb2-dvb.c | 11 +++++++++++
 drivers/media/usb/pvrusb2/pvrusb2-dvb.h |  3 +++
 2 files changed, 14 insertions(+)

diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
index cb5586b..8e1735f 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
@@ -404,6 +404,9 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
 fail_frontend0:
 	dvb_frontend_detach(adap->fe[0]);
 	adap->fe[0] = NULL;
+	dvb_module_release(adap->i2c_client_tuner);
+	dvb_module_release(adap->i2c_client_demod[1]);
+	dvb_module_release(adap->i2c_client_demod[0]);
 
 	return ret;
 }
@@ -420,6 +423,14 @@ static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap)
 		dvb_frontend_detach(adap->fe[0]);
 		adap->fe[0] = NULL;
 	}
+
+	dvb_module_release(adap->i2c_client_tuner);
+	adap->i2c_client_tuner = NULL;
+	dvb_module_release(adap->i2c_client_demod[1]);
+	adap->i2c_client_demod[1] = NULL;
+	dvb_module_release(adap->i2c_client_demod[0]);
+	adap->i2c_client_demod[0] = NULL;
+
 	return 0;
 }
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
index 91bff57..c0b27f5 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
@@ -20,6 +20,9 @@ struct pvr2_dvb_adapter {
 	struct dvb_net		dvb_net;
 	struct dvb_frontend	*fe[2];
 
+	struct i2c_client	*i2c_client_demod[2];
+	struct i2c_client	*i2c_client_tuner;
+
 	int			feedcount;
 	int			max_feed_count;
 
-- 
2.7.4


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

* [PATCH 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices
  2018-12-20 21:57 [PATCH 0/4] Add Hauppauge HVR1955/1975 devices Brad Love
                   ` (2 preceding siblings ...)
  2018-12-20 21:57 ` [PATCH 3/4] pvrusb2: Add i2c client demod/tuner support Brad Love
@ 2018-12-20 21:57 ` Brad Love
  2018-12-21  4:56   ` kbuild test robot
  2018-12-21  4:57   ` kbuild test robot
  2018-12-21 19:40 ` [PATCH v2 0/4] " Brad Love
  4 siblings, 2 replies; 36+ messages in thread
From: Brad Love @ 2018-12-20 21:57 UTC (permalink / raw)
  To: linux-media, mchehab; +Cc: Brad Love

Includes support to identify and use two Hauppauge device.
HVR-1955:
- LGDT3306a ATSC/QAM demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

HVR-1975 dual-frontend:
- LGDT3306a ATSC/QAM demod
- si2168 DVB-C/T/T2 demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

Signed-off-by: Brad Love <brad@nextdimension.cc>
---
 drivers/media/usb/pvrusb2/Kconfig               |   2 +
 drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c |  25 ++++
 drivers/media/usb/pvrusb2/pvrusb2-devattr.c     | 166 ++++++++++++++++++++++++
 drivers/media/usb/pvrusb2/pvrusb2-devattr.h     |   1 +
 drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h     |   4 +
 drivers/media/usb/pvrusb2/pvrusb2-hdw.c         |  36 ++++-
 6 files changed, 233 insertions(+), 1 deletion(-)

diff --git a/drivers/media/usb/pvrusb2/Kconfig b/drivers/media/usb/pvrusb2/Kconfig
index 1ad913f..144631c 100644
--- a/drivers/media/usb/pvrusb2/Kconfig
+++ b/drivers/media/usb/pvrusb2/Kconfig
@@ -40,6 +40,8 @@ config VIDEO_PVRUSB2_DVB
 	select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT
+	select DVB_LGDT3306A if MEDIA_SUBDRV_AUTOSELECT
+	select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
index d5bec0f..36016ab 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -111,10 +111,35 @@ static const struct routing_scheme routing_defav400 = {
 	.cnt = ARRAY_SIZE(routing_schemeav400),
 };
 
+static const struct routing_scheme_item routing_scheme160xxx[] = {
+	[PVR2_CVAL_INPUT_TV] = {
+		.vid = CX25840_COMPOSITE7,
+		.aud = CX25840_AUDIO8,
+	},
+	[PVR2_CVAL_INPUT_RADIO] = {
+		.vid = CX25840_COMPOSITE4,
+		.aud = CX25840_AUDIO6,
+	},
+	[PVR2_CVAL_INPUT_COMPOSITE] = {
+		.vid = CX25840_COMPOSITE3,
+		.aud = CX25840_AUDIO_SERIAL,
+	},
+	[PVR2_CVAL_INPUT_SVIDEO] = {
+		.vid = CX25840_SVIDEO1,
+		.aud = CX25840_AUDIO_SERIAL,
+	},
+};
+
+static const struct routing_scheme routing_def160xxx = {
+	.def = routing_scheme160xxx,
+	.cnt = ARRAY_SIZE(routing_scheme160xxx),
+};
+
 static const struct routing_scheme *routing_schemes[] = {
 	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
 	[PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv,
 	[PVR2_ROUTING_SCHEME_AV400] = &routing_defav400,
+	[PVR2_ROUTING_SCHEME_HAUP160XXX] = &routing_def160xxx,
 };
 
 void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
index ef36b62..ecec688 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
@@ -37,6 +37,9 @@ pvr2_device_desc structures.
 #include "tda18271.h"
 #include "tda8290.h"
 #include "tuner-simple.h"
+#include "si2157.h"
+#include "lgdt3306a.h"
+#include "si2168.h"
 #endif
 
 
@@ -474,6 +477,165 @@ static const struct pvr2_dvb_props pvr2_751xx_dvb_props = {
 };
 #endif
 
+/*------------------------------------------------------------------------*/
+/*    Hauppauge PVR-USB2 Model 160000 / 160111 -- HVR-1955 / HVR-1975     */
+
+static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
+{
+	struct si2157_config si2157_config = {};
+
+	si2157_config.inversion = 1;
+	si2157_config.fe = adap->fe[0];
+
+	adap->i2c_client_tuner = dvb_module_probe("si2157", "si2177",
+						&adap->channel.hdw->i2c_adap,
+						0x60, &si2157_config);
+
+	if (!adap->i2c_client_tuner)
+		return -ENODEV;
+
+	return 0;
+}
+
+#define PVR2_FIRMWARE_160xxx "v4l-pvrusb2-160xxx-01.fw"
+static const char *pvr2_fw1_names_160xxx[] = {
+		PVR2_FIRMWARE_160xxx,
+};
+
+static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap);
+static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap);
+static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap);
+
+static const struct pvr2_dvb_props pvr2_160000_dvb_props = {
+	.frontend_attach = pvr2_dual_fe_attach,
+	.tuner_attach    = pvr2_si2157_attach,
+};
+static const struct pvr2_device_client_desc pvr2_cli_160000[] = {
+	{ .module_id = PVR2_CLIENT_ID_CX25840 },
+};
+static const struct pvr2_device_desc pvr2_device_160000 = {
+		.description = "WinTV HVR-1975 Model 160000",
+		.shortname = "160000",
+		.client_table.lst = pvr2_cli_160000,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160000),
+		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
+		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
+		.default_tuner_type = TUNER_ABSENT,
+		.flag_has_cx25840 = !0,
+		.flag_has_hauppauge_rom = !0,
+		.flag_has_analogtuner = !0,
+		.flag_has_composite = !0,
+		.flag_has_svideo = !0,
+		.flag_fx2_16kb = !0,
+		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
+		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
+		.default_std_mask = V4L2_STD_NTSC_M,
+		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
+#ifdef CONFIG_VIDEO_PVRUSB2_DVB
+		.dvb_props = &pvr2_160000_dvb_props,
+#endif
+};
+
+static const struct pvr2_dvb_props pvr2_160111_dvb_props = {
+	.frontend_attach = pvr2_lgdt3306a_attach,
+	.tuner_attach    = pvr2_si2157_attach,
+};
+static const struct pvr2_device_client_desc pvr2_cli_160111[] = {
+	{ .module_id = PVR2_CLIENT_ID_CX25840 },
+};
+static const struct pvr2_device_desc pvr2_device_160111 = {
+		.description = "WinTV HVR-1955 Model 160111",
+		.shortname = "160111",
+		.client_table.lst = pvr2_cli_160111,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160111),
+		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
+		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
+		.default_tuner_type = TUNER_ABSENT,
+		.flag_has_cx25840 = !0,
+		.flag_has_hauppauge_rom = !0,
+		.flag_has_analogtuner = !0,
+		.flag_has_composite = !0,
+		.flag_has_svideo = !0,
+		.flag_fx2_16kb = !0,
+		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
+		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
+		.default_std_mask = V4L2_STD_NTSC_M,
+		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
+#ifdef CONFIG_VIDEO_PVRUSB2_DVB
+		.dvb_props = &pvr2_160111_dvb_props,
+#endif
+};
+
+static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap)
+{
+	struct si2168_config si2168_config = {};
+	struct i2c_adapter *adapter;
+
+	pr_debug("%s()\n", __func__);
+
+	si2168_config.fe = &adap->fe[1];
+	si2168_config.i2c_adapter = &adapter;
+	si2168_config.ts_mode = SI2168_TS_PARALLEL; /*2, 1-serial, 2-parallel.*/
+	si2168_config.ts_clock_gapped = 1; /*0-disabled, 1-enabled.*/
+	si2168_config.ts_clock_inv = 0; /*0-not-invert, 1-invert*/
+	si2168_config.spectral_inversion = 1; /*0-not-invert, 1-invert*/
+
+	adap->i2c_client_demod[1] = dvb_module_probe("si2168", NULL,
+						&adap->channel.hdw->i2c_adap,
+						0x64, &si2168_config);
+
+	if (!adap->i2c_client_demod[1])
+		return -ENODEV;
+
+	return 0;
+}
+
+static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
+{
+	struct lgdt3306a_config lgdt3306a_config;
+	struct i2c_adapter *adapter;
+
+	pr_debug("%s()\n", __func__);
+
+	/* attach demod */
+	lgdt3306a_config.fe = &adap->fe[0];
+	lgdt3306a_config.i2c_adapter = &adapter;
+	lgdt3306a_config.deny_i2c_rptr = 1;
+	lgdt3306a_config.spectral_inversion = 1;
+	lgdt3306a_config.qam_if_khz = 4000;
+	lgdt3306a_config.vsb_if_khz = 3250;
+	lgdt3306a_config.mpeg_mode = LGDT3306A_MPEG_PARALLEL;
+	lgdt3306a_config.tpclk_edge = LGDT3306A_TPCLK_FALLING_EDGE;
+	lgdt3306a_config.tpvalid_polarity = LGDT3306A_TP_VALID_LOW;
+	lgdt3306a_config.xtalMHz = 25, /* demod clock MHz; 24/25 supported */
+
+	adap->i2c_client_demod[0] = dvb_module_probe("lgdt3306a", NULL,
+						&adap->channel.hdw->i2c_adap,
+						0x59, &lgdt3306a_config);
+
+	if (!adap->i2c_client_demod[0])
+		return -ENODEV;
+
+	return 0;
+}
+
+static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap)
+{
+	pr_debug("%s()\n", __func__);
+
+	if (pvr2_lgdt3306a_attach(adap) != 0)
+		return -ENODEV;
+
+	if (pvr2_si2168_attach(adap) != 0) {
+		dvb_module_release(adap->i2c_client_demod[0]);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
 #define PVR2_FIRMWARE_75xxx "v4l-pvrusb2-73xxx-01.fw"
 static const char *pvr2_fw1_names_75xxx[] = {
 		PVR2_FIRMWARE_75xxx,
@@ -552,6 +714,10 @@ struct usb_device_id pvr2_device_table[] = {
 	  .driver_info = (kernel_ulong_t)&pvr2_device_751xx},
 	{ USB_DEVICE(0x0ccd, 0x0039),
 	  .driver_info = (kernel_ulong_t)&pvr2_device_av400},
+	{ USB_DEVICE(0x2040, 0x7502),
+	  .driver_info = (kernel_ulong_t)&pvr2_device_160111},
+	{ USB_DEVICE(0x2040, 0x7510),
+	  .driver_info = (kernel_ulong_t)&pvr2_device_160000},
 	{ }
 };
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.h b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
index c1e7d48..ea0b2bf 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
@@ -66,6 +66,7 @@ struct pvr2_string_table {
 #define PVR2_ROUTING_SCHEME_GOTVIEW 1
 #define PVR2_ROUTING_SCHEME_ONAIR 2
 #define PVR2_ROUTING_SCHEME_AV400 3
+#define PVR2_ROUTING_SCHEME_HAUP160XXX 4
 
 #define PVR2_DIGITAL_SCHEME_NONE 0
 #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
index 0a01de4..640b033 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
@@ -38,6 +38,10 @@
 
 #define FX2CMD_FWPOST1          0x52u
 
+/* These 2 only exist on Model 160xxx */
+#define FX2CMD_HCW_DEMOD_RESET_PIN 0xd4u
+#define FX2CMD_HCW_MAKO_SLEEP_PIN  0xd5u
+
 #define FX2CMD_POWER_OFF        0xdcu
 #define FX2CMD_POWER_ON         0xdeu
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
index 446a999..ab9e822 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
@@ -316,6 +316,8 @@ static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = {
 	{FX2CMD_ONAIR_DTV_STREAMING_OFF, "onair dtv stream off"},
 	{FX2CMD_ONAIR_DTV_POWER_ON, "onair dtv power on"},
 	{FX2CMD_ONAIR_DTV_POWER_OFF, "onair dtv power off"},
+	{FX2CMD_HCW_DEMOD_RESET_PIN, "hcw demod reset pin"},
+	{FX2CMD_HCW_MAKO_SLEEP_PIN, "hcw mako sleep pin"},
 };
 
 
@@ -2137,10 +2139,28 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
 				      ((0) << 16));
 	}
 
-	// This step MUST happen after the earlier powerup step.
+	/* This step MUST happen after the earlier powerup step */
 	pvr2_i2c_core_init(hdw);
 	if (!pvr2_hdw_dev_ok(hdw)) return;
 
+	/* Reset demod only on Hauppauge 160xxx platform */
+	if (hdw->usb_dev->descriptor.idVendor == 0x2040 &&
+	    (hdw->usb_dev->descriptor.idProduct == 0x7502 ||
+	     hdw->usb_dev->descriptor.idProduct == 0x7510)) {
+		pr_info("%s(): resetting 160xxx demod\n", __func__);
+		/* TODO: not sure this is proper place to reset once only */
+		pvr2_issue_simple_cmd(hdw,
+				     FX2CMD_HCW_DEMOD_RESET_PIN |
+				     (1 << 8) |
+				     ((0) << 16));
+		usleep_range(10000, 11000);
+		pvr2_issue_simple_cmd(hdw,
+				     FX2CMD_HCW_DEMOD_RESET_PIN |
+				     (1 << 8) |
+				     ((1) << 16));
+		usleep_range(10000, 11000);
+	}
+
 	pvr2_hdw_load_modules(hdw);
 	if (!pvr2_hdw_dev_ok(hdw)) return;
 
@@ -4011,6 +4031,20 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
 static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff)
 {
 	hdw->flag_ok = !0;
+
+	/* Use this for Hauppauge 160xxx only */
+	if (hdw->usb_dev->descriptor.idVendor == 0x2040 &&
+	    (hdw->usb_dev->descriptor.idProduct == 0x7502 ||
+	     hdw->usb_dev->descriptor.idProduct == 0x7510)) {
+		pr_debug("%s(): resetting demod on Hauppauge 160xxx platform skipped\n",
+			__func__);
+		/* Can't reset 160xxx or it will trash Demod tristate */
+		return pvr2_issue_simple_cmd(hdw,
+				     FX2CMD_HCW_MAKO_SLEEP_PIN |
+				     (1 << 8) |
+				     ((onoff ? 1 : 0) << 16));
+	}
+
 	return pvr2_issue_simple_cmd(hdw,
 				     FX2CMD_HCW_DEMOD_RESETIN |
 				     (1 << 8) |
-- 
2.7.4


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

* Re: [PATCH 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices
  2018-12-20 21:57 ` [PATCH 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
@ 2018-12-21  4:56   ` kbuild test robot
  2018-12-21  4:57   ` kbuild test robot
  1 sibling, 0 replies; 36+ messages in thread
From: kbuild test robot @ 2018-12-21  4:56 UTC (permalink / raw)
  To: Brad Love; +Cc: kbuild-all, linux-media, mchehab, Brad Love

[-- Attachment #1: Type: text/plain, Size: 17783 bytes --]

Hi Brad,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linuxtv-media/master]
[also build test ERROR on v4.20-rc7 next-20181220]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Brad-Love/Add-Hauppauge-HVR1955-1975-devices/20181221-122142
base:   git://linuxtv.org/media_tree.git master
config: x86_64-randconfig-x006-201850 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All error/warnings (new ones prefixed by >>):

>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:483:38: warning: 'struct pvr2_dvb_adapter' declared inside parameter list will not be visible outside of this definition or declaration
    static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
                                         ^~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c: In function 'pvr2_si2157_attach':
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:485:9: error: variable 'si2157_config' has initializer but incomplete type
     struct si2157_config si2157_config = {};
            ^~~~~~~~~~~~~
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:485:23: error: storage size of 'si2157_config' isn't known
     struct si2157_config si2157_config = {};
                          ^~~~~~~~~~~~~
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:488:25: error: dereferencing pointer to incomplete type 'struct pvr2_dvb_adapter'
     si2157_config.fe = adap->fe[0];
                            ^~
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:490:27: error: implicit declaration of function 'dvb_module_probe'; did you mean '__module_get'? [-Werror=implicit-function-declaration]
     adap->i2c_client_tuner = dvb_module_probe("si2157", "si2177",
                              ^~~~~~~~~~~~~~~~
                              __module_get
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:485:23: warning: unused variable 'si2157_config' [-Wunused-variable]
     struct si2157_config si2157_config = {};
                          ^~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c: At top level:
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:505:38: warning: 'struct pvr2_dvb_adapter' declared inside parameter list will not be visible outside of this definition or declaration
    static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap);
                                         ^~~~~~~~~~~~~~~~
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:505:12: error: conflicting types for 'pvr2_si2157_attach'
    static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap);
               ^~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:483:12: note: previous definition of 'pvr2_si2157_attach' was here
    static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:506:39: warning: 'struct pvr2_dvb_adapter' declared inside parameter list will not be visible outside of this definition or declaration
    static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap);
                                          ^~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:507:41: warning: 'struct pvr2_dvb_adapter' declared inside parameter list will not be visible outside of this definition or declaration
    static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap);
                                            ^~~~~~~~~~~~~~~~
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:509:21: error: variable 'pvr2_160000_dvb_props' has initializer but incomplete type
    static const struct pvr2_dvb_props pvr2_160000_dvb_props = {
                        ^~~~~~~~~~~~~~
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:510:3: error: 'const struct pvr2_dvb_props' has no member named 'frontend_attach'
     .frontend_attach = pvr2_dual_fe_attach,
      ^~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:510:21: warning: excess elements in struct initializer
     .frontend_attach = pvr2_dual_fe_attach,
                        ^~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:510:21: note: (near initialization for 'pvr2_160000_dvb_props')
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:511:3: error: 'const struct pvr2_dvb_props' has no member named 'tuner_attach'
     .tuner_attach    = pvr2_si2157_attach,
      ^~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:511:21: warning: excess elements in struct initializer
     .tuner_attach    = pvr2_si2157_attach,
                        ^~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:511:21: note: (near initialization for 'pvr2_160000_dvb_props')
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:540:21: error: variable 'pvr2_160111_dvb_props' has initializer but incomplete type
    static const struct pvr2_dvb_props pvr2_160111_dvb_props = {
                        ^~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:541:3: error: 'const struct pvr2_dvb_props' has no member named 'frontend_attach'
     .frontend_attach = pvr2_lgdt3306a_attach,
      ^~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:541:21: warning: excess elements in struct initializer
     .frontend_attach = pvr2_lgdt3306a_attach,
                        ^~~~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:541:21: note: (near initialization for 'pvr2_160111_dvb_props')
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:542:3: error: 'const struct pvr2_dvb_props' has no member named 'tuner_attach'
     .tuner_attach    = pvr2_si2157_attach,
      ^~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:542:21: warning: excess elements in struct initializer
     .tuner_attach    = pvr2_si2157_attach,
                        ^~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:542:21: note: (near initialization for 'pvr2_160111_dvb_props')
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:571:38: warning: 'struct pvr2_dvb_adapter' declared inside parameter list will not be visible outside of this definition or declaration
    static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap)
                                         ^~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c: In function 'pvr2_si2168_attach':
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:573:9: error: variable 'si2168_config' has initializer but incomplete type
     struct si2168_config si2168_config = {};
            ^~~~~~~~~~~~~
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:573:23: error: storage size of 'si2168_config' isn't known
     struct si2168_config si2168_config = {};
                          ^~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:578:26: error: dereferencing pointer to incomplete type 'struct pvr2_dvb_adapter'
     si2168_config.fe = &adap->fe[1];
                             ^~
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:580:26: error: 'SI2168_TS_PARALLEL' undeclared (first use in this function)
     si2168_config.ts_mode = SI2168_TS_PARALLEL; /*2, 1-serial, 2-parallel.*/
                             ^~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:580:26: note: each undeclared identifier is reported only once for each function it appears in
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:573:23: warning: unused variable 'si2168_config' [-Wunused-variable]
     struct si2168_config si2168_config = {};
                          ^~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c: At top level:
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:595:41: warning: 'struct pvr2_dvb_adapter' declared inside parameter list will not be visible outside of this definition or declaration
    static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
                                            ^~~~~~~~~~~~~~~~
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:595:12: error: conflicting types for 'pvr2_lgdt3306a_attach'
    static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:507:12: note: previous declaration of 'pvr2_lgdt3306a_attach' was here
    static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap);
               ^~~~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c: In function 'pvr2_lgdt3306a_attach':
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:597:26: error: storage size of 'lgdt3306a_config' isn't known
     struct lgdt3306a_config lgdt3306a_config;
                             ^~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:603:29: error: dereferencing pointer to incomplete type 'struct pvr2_dvb_adapter'
     lgdt3306a_config.fe = &adap->fe[0];
                                ^~
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:609:31: error: 'LGDT3306A_MPEG_PARALLEL' undeclared (first use in this function)
     lgdt3306a_config.mpeg_mode = LGDT3306A_MPEG_PARALLEL;
                                  ^~~~~~~~~~~~~~~~~~~~~~~
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:610:32: error: 'LGDT3306A_TPCLK_FALLING_EDGE' undeclared (first use in this function); did you mean 'LGDT3306A_MPEG_PARALLEL'?
     lgdt3306a_config.tpclk_edge = LGDT3306A_TPCLK_FALLING_EDGE;
                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                   LGDT3306A_MPEG_PARALLEL
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:611:38: error: 'LGDT3306A_TP_VALID_LOW' undeclared (first use in this function); did you mean 'LGDT3306A_MPEG_PARALLEL'?
     lgdt3306a_config.tpvalid_polarity = LGDT3306A_TP_VALID_LOW;
                                         ^~~~~~~~~~~~~~~~~~~~~~
                                         LGDT3306A_MPEG_PARALLEL
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:612:31: warning: left-hand operand of comma expression has no effect [-Wunused-value]
     lgdt3306a_config.xtalMHz = 25, /* demod clock MHz; 24/25 supported */
                                  ^
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:597:26: warning: unused variable 'lgdt3306a_config' [-Wunused-variable]
     struct lgdt3306a_config lgdt3306a_config;
                             ^~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c: At top level:
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:624:39: warning: 'struct pvr2_dvb_adapter' declared inside parameter list will not be visible outside of this definition or declaration
    static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap)
                                          ^~~~~~~~~~~~~~~~
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:624:12: error: conflicting types for 'pvr2_dual_fe_attach'
    static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:506:12: note: previous declaration of 'pvr2_dual_fe_attach' was here
    static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap);
               ^~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c: In function 'pvr2_dual_fe_attach':
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:628:28: error: passing argument 1 of 'pvr2_lgdt3306a_attach' from incompatible pointer type [-Werror=incompatible-pointer-types]
     if (pvr2_lgdt3306a_attach(adap) != 0)
                               ^~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:595:12: note: expected 'struct pvr2_dvb_adapter *' but argument is of type 'struct pvr2_dvb_adapter *'
    static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~~~~

vim +/si2157_config +485 drivers/media/usb/pvrusb2/pvrusb2-devattr.c

   482	
 > 483	static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
   484	{
 > 485		struct si2157_config si2157_config = {};
   486	
   487		si2157_config.inversion = 1;
 > 488		si2157_config.fe = adap->fe[0];
   489	
 > 490		adap->i2c_client_tuner = dvb_module_probe("si2157", "si2177",
   491							&adap->channel.hdw->i2c_adap,
   492							0x60, &si2157_config);
   493	
   494		if (!adap->i2c_client_tuner)
   495			return -ENODEV;
   496	
   497		return 0;
   498	}
   499	
   500	#define PVR2_FIRMWARE_160xxx "v4l-pvrusb2-160xxx-01.fw"
   501	static const char *pvr2_fw1_names_160xxx[] = {
   502			PVR2_FIRMWARE_160xxx,
   503	};
   504	
 > 505	static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap);
 > 506	static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap);
 > 507	static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap);
   508	
 > 509	static const struct pvr2_dvb_props pvr2_160000_dvb_props = {
 > 510		.frontend_attach = pvr2_dual_fe_attach,
 > 511		.tuner_attach    = pvr2_si2157_attach,
   512	};
   513	static const struct pvr2_device_client_desc pvr2_cli_160000[] = {
   514		{ .module_id = PVR2_CLIENT_ID_CX25840 },
   515	};
   516	static const struct pvr2_device_desc pvr2_device_160000 = {
   517			.description = "WinTV HVR-1975 Model 160000",
   518			.shortname = "160000",
   519			.client_table.lst = pvr2_cli_160000,
   520			.client_table.cnt = ARRAY_SIZE(pvr2_cli_160000),
   521			.fx2_firmware.lst = pvr2_fw1_names_160xxx,
   522			.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
   523			.default_tuner_type = TUNER_ABSENT,
   524			.flag_has_cx25840 = !0,
   525			.flag_has_hauppauge_rom = !0,
   526			.flag_has_analogtuner = !0,
   527			.flag_has_composite = !0,
   528			.flag_has_svideo = !0,
   529			.flag_fx2_16kb = !0,
   530			.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
   531			.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
   532			.default_std_mask = V4L2_STD_NTSC_M,
   533			.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
   534			.ir_scheme = PVR2_IR_SCHEME_ZILOG,
   535	#ifdef CONFIG_VIDEO_PVRUSB2_DVB
   536			.dvb_props = &pvr2_160000_dvb_props,
   537	#endif
   538	};
   539	
 > 540	static const struct pvr2_dvb_props pvr2_160111_dvb_props = {
   541		.frontend_attach = pvr2_lgdt3306a_attach,
 > 542		.tuner_attach    = pvr2_si2157_attach,
   543	};
   544	static const struct pvr2_device_client_desc pvr2_cli_160111[] = {
   545		{ .module_id = PVR2_CLIENT_ID_CX25840 },
   546	};
   547	static const struct pvr2_device_desc pvr2_device_160111 = {
   548			.description = "WinTV HVR-1955 Model 160111",
   549			.shortname = "160111",
   550			.client_table.lst = pvr2_cli_160111,
   551			.client_table.cnt = ARRAY_SIZE(pvr2_cli_160111),
   552			.fx2_firmware.lst = pvr2_fw1_names_160xxx,
   553			.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
   554			.default_tuner_type = TUNER_ABSENT,
   555			.flag_has_cx25840 = !0,
   556			.flag_has_hauppauge_rom = !0,
   557			.flag_has_analogtuner = !0,
   558			.flag_has_composite = !0,
   559			.flag_has_svideo = !0,
   560			.flag_fx2_16kb = !0,
   561			.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
   562			.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
   563			.default_std_mask = V4L2_STD_NTSC_M,
   564			.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
   565			.ir_scheme = PVR2_IR_SCHEME_ZILOG,
   566	#ifdef CONFIG_VIDEO_PVRUSB2_DVB
   567			.dvb_props = &pvr2_160111_dvb_props,
   568	#endif
   569	};
   570	
   571	static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap)
   572	{
 > 573		struct si2168_config si2168_config = {};
   574		struct i2c_adapter *adapter;
   575	
   576		pr_debug("%s()\n", __func__);
   577	
   578		si2168_config.fe = &adap->fe[1];
   579		si2168_config.i2c_adapter = &adapter;
 > 580		si2168_config.ts_mode = SI2168_TS_PARALLEL; /*2, 1-serial, 2-parallel.*/
   581		si2168_config.ts_clock_gapped = 1; /*0-disabled, 1-enabled.*/
   582		si2168_config.ts_clock_inv = 0; /*0-not-invert, 1-invert*/
   583		si2168_config.spectral_inversion = 1; /*0-not-invert, 1-invert*/
   584	
   585		adap->i2c_client_demod[1] = dvb_module_probe("si2168", NULL,
   586							&adap->channel.hdw->i2c_adap,
   587							0x64, &si2168_config);
   588	
   589		if (!adap->i2c_client_demod[1])
   590			return -ENODEV;
   591	
   592		return 0;
   593	}
   594	
 > 595	static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
   596	{
 > 597		struct lgdt3306a_config lgdt3306a_config;
   598		struct i2c_adapter *adapter;
   599	
   600		pr_debug("%s()\n", __func__);
   601	
   602		/* attach demod */
   603		lgdt3306a_config.fe = &adap->fe[0];
   604		lgdt3306a_config.i2c_adapter = &adapter;
   605		lgdt3306a_config.deny_i2c_rptr = 1;
   606		lgdt3306a_config.spectral_inversion = 1;
   607		lgdt3306a_config.qam_if_khz = 4000;
   608		lgdt3306a_config.vsb_if_khz = 3250;
 > 609		lgdt3306a_config.mpeg_mode = LGDT3306A_MPEG_PARALLEL;
 > 610		lgdt3306a_config.tpclk_edge = LGDT3306A_TPCLK_FALLING_EDGE;
 > 611		lgdt3306a_config.tpvalid_polarity = LGDT3306A_TP_VALID_LOW;
   612		lgdt3306a_config.xtalMHz = 25, /* demod clock MHz; 24/25 supported */
   613	
   614		adap->i2c_client_demod[0] = dvb_module_probe("lgdt3306a", NULL,
   615							&adap->channel.hdw->i2c_adap,
   616							0x59, &lgdt3306a_config);
   617	
   618		if (!adap->i2c_client_demod[0])
   619			return -ENODEV;
   620	
   621		return 0;
   622	}
   623	
 > 624	static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap)
   625	{
   626		pr_debug("%s()\n", __func__);
   627	
 > 628		if (pvr2_lgdt3306a_attach(adap) != 0)
   629			return -ENODEV;
   630	
 > 631		if (pvr2_si2168_attach(adap) != 0) {
 > 632			dvb_module_release(adap->i2c_client_demod[0]);
   633			return -ENODEV;
   634		}
   635	
   636		return 0;
   637	}
   638	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 33698 bytes --]

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

* Re: [PATCH 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices
  2018-12-20 21:57 ` [PATCH 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
  2018-12-21  4:56   ` kbuild test robot
@ 2018-12-21  4:57   ` kbuild test robot
  1 sibling, 0 replies; 36+ messages in thread
From: kbuild test robot @ 2018-12-21  4:57 UTC (permalink / raw)
  To: Brad Love; +Cc: kbuild-all, linux-media, mchehab, Brad Love

[-- Attachment #1: Type: text/plain, Size: 26100 bytes --]

Hi Brad,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linuxtv-media/master]
[also build test ERROR on v4.20-rc7 next-20181220]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Brad-Love/Add-Hauppauge-HVR1955-1975-devices/20181221-122142
base:   git://linuxtv.org/media_tree.git master
config: x86_64-randconfig-x018-201850 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All error/warnings (new ones prefixed by >>):

   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:483:38: warning: 'struct pvr2_dvb_adapter' declared inside parameter list will not be visible outside of this definition or declaration
    static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
                                         ^~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c: In function 'pvr2_si2157_attach':
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:485:9: error: variable 'si2157_config' has initializer but incomplete type
     struct si2157_config si2157_config = {};
            ^~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:485:23: error: storage size of 'si2157_config' isn't known
     struct si2157_config si2157_config = {};
                          ^~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:488:25: error: dereferencing pointer to incomplete type 'struct pvr2_dvb_adapter'
     si2157_config.fe = adap->fe[0];
                            ^~
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:490:27: error: implicit declaration of function 'dvb_module_probe'; did you mean 'module_put'? [-Werror=implicit-function-declaration]
     adap->i2c_client_tuner = dvb_module_probe("si2157", "si2177",
                              ^~~~~~~~~~~~~~~~
                              module_put
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:485:23: warning: unused variable 'si2157_config' [-Wunused-variable]
     struct si2157_config si2157_config = {};
                          ^~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c: At top level:
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:505:38: warning: 'struct pvr2_dvb_adapter' declared inside parameter list will not be visible outside of this definition or declaration
    static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap);
                                         ^~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:505:12: error: conflicting types for 'pvr2_si2157_attach'
    static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap);
               ^~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:483:12: note: previous definition of 'pvr2_si2157_attach' was here
    static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:506:39: warning: 'struct pvr2_dvb_adapter' declared inside parameter list will not be visible outside of this definition or declaration
    static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap);
                                          ^~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:507:41: warning: 'struct pvr2_dvb_adapter' declared inside parameter list will not be visible outside of this definition or declaration
    static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap);
                                            ^~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:509:21: error: variable 'pvr2_160000_dvb_props' has initializer but incomplete type
    static const struct pvr2_dvb_props pvr2_160000_dvb_props = {
                        ^~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:510:3: error: 'const struct pvr2_dvb_props' has no member named 'frontend_attach'
     .frontend_attach = pvr2_dual_fe_attach,
      ^~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:510:21: warning: excess elements in struct initializer
     .frontend_attach = pvr2_dual_fe_attach,
                        ^~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:510:21: note: (near initialization for 'pvr2_160000_dvb_props')
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:511:3: error: 'const struct pvr2_dvb_props' has no member named 'tuner_attach'
     .tuner_attach    = pvr2_si2157_attach,
      ^~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:511:21: warning: excess elements in struct initializer
     .tuner_attach    = pvr2_si2157_attach,
                        ^~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:511:21: note: (near initialization for 'pvr2_160000_dvb_props')
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:540:21: error: variable 'pvr2_160111_dvb_props' has initializer but incomplete type
    static const struct pvr2_dvb_props pvr2_160111_dvb_props = {
                        ^~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:541:3: error: 'const struct pvr2_dvb_props' has no member named 'frontend_attach'
     .frontend_attach = pvr2_lgdt3306a_attach,
      ^~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:541:21: warning: excess elements in struct initializer
     .frontend_attach = pvr2_lgdt3306a_attach,
                        ^~~~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:541:21: note: (near initialization for 'pvr2_160111_dvb_props')
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:542:3: error: 'const struct pvr2_dvb_props' has no member named 'tuner_attach'
     .tuner_attach    = pvr2_si2157_attach,
      ^~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:542:21: warning: excess elements in struct initializer
     .tuner_attach    = pvr2_si2157_attach,
                        ^~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:542:21: note: (near initialization for 'pvr2_160111_dvb_props')
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:571:38: warning: 'struct pvr2_dvb_adapter' declared inside parameter list will not be visible outside of this definition or declaration
    static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap)
                                         ^~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c: In function 'pvr2_si2168_attach':
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:573:9: error: variable 'si2168_config' has initializer but incomplete type
     struct si2168_config si2168_config = {};
            ^~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:573:23: error: storage size of 'si2168_config' isn't known
     struct si2168_config si2168_config = {};
                          ^~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:578:26: error: dereferencing pointer to incomplete type 'struct pvr2_dvb_adapter'
     si2168_config.fe = &adap->fe[1];
                             ^~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:580:26: error: 'SI2168_TS_PARALLEL' undeclared (first use in this function)
     si2168_config.ts_mode = SI2168_TS_PARALLEL; /*2, 1-serial, 2-parallel.*/
                             ^~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:580:26: note: each undeclared identifier is reported only once for each function it appears in
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:573:23: warning: unused variable 'si2168_config' [-Wunused-variable]
     struct si2168_config si2168_config = {};
                          ^~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c: At top level:
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:595:41: warning: 'struct pvr2_dvb_adapter' declared inside parameter list will not be visible outside of this definition or declaration
    static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
                                            ^~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:595:12: error: conflicting types for 'pvr2_lgdt3306a_attach'
    static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:507:12: note: previous declaration of 'pvr2_lgdt3306a_attach' was here
    static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap);
               ^~~~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c: In function 'pvr2_lgdt3306a_attach':
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:597:26: error: storage size of 'lgdt3306a_config' isn't known
     struct lgdt3306a_config lgdt3306a_config;
                             ^~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:603:29: error: dereferencing pointer to incomplete type 'struct pvr2_dvb_adapter'
     lgdt3306a_config.fe = &adap->fe[0];
                                ^~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:609:31: error: 'LGDT3306A_MPEG_PARALLEL' undeclared (first use in this function)
     lgdt3306a_config.mpeg_mode = LGDT3306A_MPEG_PARALLEL;
                                  ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:610:32: error: 'LGDT3306A_TPCLK_FALLING_EDGE' undeclared (first use in this function); did you mean 'LGDT3306A_MPEG_PARALLEL'?
     lgdt3306a_config.tpclk_edge = LGDT3306A_TPCLK_FALLING_EDGE;
                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                   LGDT3306A_MPEG_PARALLEL
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:611:38: error: 'LGDT3306A_TP_VALID_LOW' undeclared (first use in this function); did you mean 'LGDT3306A_MPEG_PARALLEL'?
     lgdt3306a_config.tpvalid_polarity = LGDT3306A_TP_VALID_LOW;
                                         ^~~~~~~~~~~~~~~~~~~~~~
                                         LGDT3306A_MPEG_PARALLEL
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:612:31: warning: left-hand operand of comma expression has no effect [-Wunused-value]
     lgdt3306a_config.xtalMHz = 25, /* demod clock MHz; 24/25 supported */
                                  ^
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:597:26: warning: unused variable 'lgdt3306a_config' [-Wunused-variable]
     struct lgdt3306a_config lgdt3306a_config;
                             ^~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c: At top level:
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:624:39: warning: 'struct pvr2_dvb_adapter' declared inside parameter list will not be visible outside of this definition or declaration
    static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap)
                                          ^~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:624:12: error: conflicting types for 'pvr2_dual_fe_attach'
    static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:506:12: note: previous declaration of 'pvr2_dual_fe_attach' was here
    static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap);
               ^~~~~~~~~~~~~~~~~~~
   In file included from include/linux/string.h:6:0,
                    from include/linux/uuid.h:20,
                    from include/linux/mod_devicetable.h:13,
                    from drivers/media/usb/pvrusb2/pvrusb2-devattr.h:19,
                    from drivers/media/usb/pvrusb2/pvrusb2-devattr.c:25:
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c: In function 'pvr2_dual_fe_attach':
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:628:28: error: passing argument 1 of 'pvr2_lgdt3306a_attach' from incompatible pointer type [-Werror=incompatible-pointer-types]
     if (pvr2_lgdt3306a_attach(adap) != 0)
                               ^
   include/linux/compiler.h:58:30: note: in definition of macro '__trace_if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
                                 ^~~~
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:628:2: note: in expansion of macro 'if'
     if (pvr2_lgdt3306a_attach(adap) != 0)
     ^~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:595:12: note: expected 'struct pvr2_dvb_adapter *' but argument is of type 'struct pvr2_dvb_adapter *'
    static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~~~~
   In file included from include/linux/string.h:6:0,
                    from include/linux/uuid.h:20,
                    from include/linux/mod_devicetable.h:13,
                    from drivers/media/usb/pvrusb2/pvrusb2-devattr.h:19,
                    from drivers/media/usb/pvrusb2/pvrusb2-devattr.c:25:
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:628:28: error: passing argument 1 of 'pvr2_lgdt3306a_attach' from incompatible pointer type [-Werror=incompatible-pointer-types]
     if (pvr2_lgdt3306a_attach(adap) != 0)
                               ^
   include/linux/compiler.h:58:42: note: in definition of macro '__trace_if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
                                             ^~~~
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:628:2: note: in expansion of macro 'if'
     if (pvr2_lgdt3306a_attach(adap) != 0)
     ^~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:595:12: note: expected 'struct pvr2_dvb_adapter *' but argument is of type 'struct pvr2_dvb_adapter *'
    static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~~~~
   In file included from include/linux/string.h:6:0,
                    from include/linux/uuid.h:20,
                    from include/linux/mod_devicetable.h:13,
                    from drivers/media/usb/pvrusb2/pvrusb2-devattr.h:19,
                    from drivers/media/usb/pvrusb2/pvrusb2-devattr.c:25:
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:628:28: error: passing argument 1 of 'pvr2_lgdt3306a_attach' from incompatible pointer type [-Werror=incompatible-pointer-types]
     if (pvr2_lgdt3306a_attach(adap) != 0)
                               ^
   include/linux/compiler.h:69:16: note: in definition of macro '__trace_if'
      ______r = !!(cond);     \
                   ^~~~
>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:628:2: note: in expansion of macro 'if'
     if (pvr2_lgdt3306a_attach(adap) != 0)
     ^~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:595:12: note: expected 'struct pvr2_dvb_adapter *' but argument is of type 'struct pvr2_dvb_adapter *'
    static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~~~~
   In file included from include/linux/string.h:6:0,
                    from include/linux/uuid.h:20,
                    from include/linux/mod_devicetable.h:13,
                    from drivers/media/usb/pvrusb2/pvrusb2-devattr.h:19,
                    from drivers/media/usb/pvrusb2/pvrusb2-devattr.c:25:
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:631:25: error: passing argument 1 of 'pvr2_si2168_attach' from incompatible pointer type [-Werror=incompatible-pointer-types]
     if (pvr2_si2168_attach(adap) != 0) {
                            ^
   include/linux/compiler.h:58:30: note: in definition of macro '__trace_if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
                                 ^~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:631:2: note: in expansion of macro 'if'
     if (pvr2_si2168_attach(adap) != 0) {
     ^~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:571:12: note: expected 'struct pvr2_dvb_adapter *' but argument is of type 'struct pvr2_dvb_adapter *'
    static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~
   In file included from include/linux/string.h:6:0,
                    from include/linux/uuid.h:20,
                    from include/linux/mod_devicetable.h:13,
                    from drivers/media/usb/pvrusb2/pvrusb2-devattr.h:19,
                    from drivers/media/usb/pvrusb2/pvrusb2-devattr.c:25:
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:631:25: error: passing argument 1 of 'pvr2_si2168_attach' from incompatible pointer type [-Werror=incompatible-pointer-types]
     if (pvr2_si2168_attach(adap) != 0) {
                            ^
   include/linux/compiler.h:58:42: note: in definition of macro '__trace_if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
                                             ^~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:631:2: note: in expansion of macro 'if'
     if (pvr2_si2168_attach(adap) != 0) {
     ^~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:571:12: note: expected 'struct pvr2_dvb_adapter *' but argument is of type 'struct pvr2_dvb_adapter *'
    static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~
   In file included from include/linux/string.h:6:0,
                    from include/linux/uuid.h:20,
                    from include/linux/mod_devicetable.h:13,
                    from drivers/media/usb/pvrusb2/pvrusb2-devattr.h:19,
                    from drivers/media/usb/pvrusb2/pvrusb2-devattr.c:25:
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:631:25: error: passing argument 1 of 'pvr2_si2168_attach' from incompatible pointer type [-Werror=incompatible-pointer-types]
     if (pvr2_si2168_attach(adap) != 0) {
                            ^
   include/linux/compiler.h:69:16: note: in definition of macro '__trace_if'
      ______r = !!(cond);     \
                   ^~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:631:2: note: in expansion of macro 'if'
     if (pvr2_si2168_attach(adap) != 0) {
     ^~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:571:12: note: expected 'struct pvr2_dvb_adapter *' but argument is of type 'struct pvr2_dvb_adapter *'
    static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:632:3: error: implicit declaration of function 'dvb_module_release'; did you mean 'complete_release'? [-Werror=implicit-function-declaration]
      dvb_module_release(adap->i2c_client_demod[0]);
      ^~~~~~~~~~~~~~~~~~
      complete_release
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:632:26: error: dereferencing pointer to incomplete type 'struct pvr2_dvb_adapter'
      dvb_module_release(adap->i2c_client_demod[0]);
                             ^~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c: At top level:
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:509:36: error: storage size of 'pvr2_160000_dvb_props' isn't known
    static const struct pvr2_dvb_props pvr2_160000_dvb_props = {
                                       ^~~~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:540:36: error: storage size of 'pvr2_160111_dvb_props' isn't known
    static const struct pvr2_dvb_props pvr2_160111_dvb_props = {
                                       ^~~~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:505:12: warning: 'pvr2_si2157_attach' used but never defined
    static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap);
               ^~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:506:12: warning: 'pvr2_dual_fe_attach' used but never defined
    static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap);
               ^~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:507:12: warning: 'pvr2_lgdt3306a_attach' used but never defined
    static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap);
               ^~~~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:624:12: warning: 'pvr2_dual_fe_attach' defined but not used [-Wunused-function]
    static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:483:12: warning: 'pvr2_si2157_attach' defined but not used [-Wunused-function]
    static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +490 drivers/media/usb/pvrusb2/pvrusb2-devattr.c

   482	
   483	static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
   484	{
 > 485		struct si2157_config si2157_config = {};
   486	
   487		si2157_config.inversion = 1;
   488		si2157_config.fe = adap->fe[0];
   489	
 > 490		adap->i2c_client_tuner = dvb_module_probe("si2157", "si2177",
   491							&adap->channel.hdw->i2c_adap,
   492							0x60, &si2157_config);
   493	
   494		if (!adap->i2c_client_tuner)
   495			return -ENODEV;
   496	
   497		return 0;
   498	}
   499	
   500	#define PVR2_FIRMWARE_160xxx "v4l-pvrusb2-160xxx-01.fw"
   501	static const char *pvr2_fw1_names_160xxx[] = {
   502			PVR2_FIRMWARE_160xxx,
   503	};
   504	
   505	static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap);
   506	static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap);
   507	static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap);
   508	
   509	static const struct pvr2_dvb_props pvr2_160000_dvb_props = {
   510		.frontend_attach = pvr2_dual_fe_attach,
   511		.tuner_attach    = pvr2_si2157_attach,
   512	};
   513	static const struct pvr2_device_client_desc pvr2_cli_160000[] = {
   514		{ .module_id = PVR2_CLIENT_ID_CX25840 },
   515	};
   516	static const struct pvr2_device_desc pvr2_device_160000 = {
   517			.description = "WinTV HVR-1975 Model 160000",
   518			.shortname = "160000",
   519			.client_table.lst = pvr2_cli_160000,
   520			.client_table.cnt = ARRAY_SIZE(pvr2_cli_160000),
   521			.fx2_firmware.lst = pvr2_fw1_names_160xxx,
   522			.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
   523			.default_tuner_type = TUNER_ABSENT,
   524			.flag_has_cx25840 = !0,
   525			.flag_has_hauppauge_rom = !0,
   526			.flag_has_analogtuner = !0,
   527			.flag_has_composite = !0,
   528			.flag_has_svideo = !0,
   529			.flag_fx2_16kb = !0,
   530			.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
   531			.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
   532			.default_std_mask = V4L2_STD_NTSC_M,
   533			.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
   534			.ir_scheme = PVR2_IR_SCHEME_ZILOG,
   535	#ifdef CONFIG_VIDEO_PVRUSB2_DVB
   536			.dvb_props = &pvr2_160000_dvb_props,
   537	#endif
   538	};
   539	
   540	static const struct pvr2_dvb_props pvr2_160111_dvb_props = {
   541		.frontend_attach = pvr2_lgdt3306a_attach,
   542		.tuner_attach    = pvr2_si2157_attach,
   543	};
   544	static const struct pvr2_device_client_desc pvr2_cli_160111[] = {
   545		{ .module_id = PVR2_CLIENT_ID_CX25840 },
   546	};
   547	static const struct pvr2_device_desc pvr2_device_160111 = {
   548			.description = "WinTV HVR-1955 Model 160111",
   549			.shortname = "160111",
   550			.client_table.lst = pvr2_cli_160111,
   551			.client_table.cnt = ARRAY_SIZE(pvr2_cli_160111),
   552			.fx2_firmware.lst = pvr2_fw1_names_160xxx,
   553			.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
   554			.default_tuner_type = TUNER_ABSENT,
   555			.flag_has_cx25840 = !0,
   556			.flag_has_hauppauge_rom = !0,
   557			.flag_has_analogtuner = !0,
   558			.flag_has_composite = !0,
   559			.flag_has_svideo = !0,
   560			.flag_fx2_16kb = !0,
   561			.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
   562			.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
   563			.default_std_mask = V4L2_STD_NTSC_M,
   564			.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
   565			.ir_scheme = PVR2_IR_SCHEME_ZILOG,
   566	#ifdef CONFIG_VIDEO_PVRUSB2_DVB
   567			.dvb_props = &pvr2_160111_dvb_props,
   568	#endif
   569	};
   570	
   571	static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap)
   572	{
   573		struct si2168_config si2168_config = {};
   574		struct i2c_adapter *adapter;
   575	
   576		pr_debug("%s()\n", __func__);
   577	
   578		si2168_config.fe = &adap->fe[1];
   579		si2168_config.i2c_adapter = &adapter;
   580		si2168_config.ts_mode = SI2168_TS_PARALLEL; /*2, 1-serial, 2-parallel.*/
   581		si2168_config.ts_clock_gapped = 1; /*0-disabled, 1-enabled.*/
   582		si2168_config.ts_clock_inv = 0; /*0-not-invert, 1-invert*/
   583		si2168_config.spectral_inversion = 1; /*0-not-invert, 1-invert*/
   584	
   585		adap->i2c_client_demod[1] = dvb_module_probe("si2168", NULL,
   586							&adap->channel.hdw->i2c_adap,
   587							0x64, &si2168_config);
   588	
   589		if (!adap->i2c_client_demod[1])
   590			return -ENODEV;
   591	
   592		return 0;
   593	}
   594	
   595	static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
   596	{
   597		struct lgdt3306a_config lgdt3306a_config;
   598		struct i2c_adapter *adapter;
   599	
   600		pr_debug("%s()\n", __func__);
   601	
   602		/* attach demod */
   603		lgdt3306a_config.fe = &adap->fe[0];
   604		lgdt3306a_config.i2c_adapter = &adapter;
   605		lgdt3306a_config.deny_i2c_rptr = 1;
   606		lgdt3306a_config.spectral_inversion = 1;
   607		lgdt3306a_config.qam_if_khz = 4000;
   608		lgdt3306a_config.vsb_if_khz = 3250;
   609		lgdt3306a_config.mpeg_mode = LGDT3306A_MPEG_PARALLEL;
   610		lgdt3306a_config.tpclk_edge = LGDT3306A_TPCLK_FALLING_EDGE;
   611		lgdt3306a_config.tpvalid_polarity = LGDT3306A_TP_VALID_LOW;
   612		lgdt3306a_config.xtalMHz = 25, /* demod clock MHz; 24/25 supported */
   613	
   614		adap->i2c_client_demod[0] = dvb_module_probe("lgdt3306a", NULL,
   615							&adap->channel.hdw->i2c_adap,
   616							0x59, &lgdt3306a_config);
   617	
   618		if (!adap->i2c_client_demod[0])
   619			return -ENODEV;
   620	
   621		return 0;
   622	}
   623	
   624	static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap)
   625	{
   626		pr_debug("%s()\n", __func__);
   627	
 > 628		if (pvr2_lgdt3306a_attach(adap) != 0)
   629			return -ENODEV;
   630	
   631		if (pvr2_si2168_attach(adap) != 0) {
   632			dvb_module_release(adap->i2c_client_demod[0]);
   633			return -ENODEV;
   634		}
   635	
   636		return 0;
   637	}
   638	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 32677 bytes --]

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

* [PATCH v2 0/4] Add Hauppauge HVR1955/1975 devices
  2018-12-20 21:57 [PATCH 0/4] Add Hauppauge HVR1955/1975 devices Brad Love
                   ` (3 preceding siblings ...)
  2018-12-20 21:57 ` [PATCH 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
@ 2018-12-21 19:40 ` " Brad Love
  2018-12-21 19:40   ` [PATCH v2 1/4] si2157: add detection of si2177 tuner Brad Love
                     ` (5 more replies)
  4 siblings, 6 replies; 36+ messages in thread
From: Brad Love @ 2018-12-21 19:40 UTC (permalink / raw)
  To: linux-media, mchehab; +Cc: Brad Love

Hauppauge device HVR1955 and HVR1975 are old Cypress based
devices. When originally produced the demods were lacking
upstream drivers and the tuner was unsupported. Well fast
forward to now and the only thing missing is the identification
of si2177 tuner in the si2157 driver, as well as extension
of the pvrusb2 driver to accomodate i2c client devices
and multiple frontends. This series addresses what is necessary.

QAM/ATSC are fully tested and work, the DVB tuning
*should* work, but is completely untested. Both demod
drivers are compatible with multiple frontend usage due
to previous patches I've submitted, so things should
work in pvrusb2 as well.

Composite video input is tested. Unable to test s-video,
but it should work. Radio is fully untested. Analog TV is
a work in progress, coming soon.

HVR-1955:
- LGDT3306a ATSC/QAM demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

HVR-1975 dual-frontend:
- LGDT3306a ATSC/QAM demod
- si2168 DVB-C/T/T2 demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

Changes since v1:
- Patch 4/4 build fixes and reorganization


Brad Love (4):
  si2157: add detection of si2177 tuner
  pvrusb2: Add multiple dvb frontend support
  pvrusb2: Add i2c client demod/tuner support
  pvrusb2: Add Hauppauge HVR1955/1975 devices

 drivers/media/tuners/si2157.c                   |   6 +
 drivers/media/tuners/si2157_priv.h              |   3 +-
 drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c |  25 +++
 drivers/media/usb/pvrusb2/pvrusb2-devattr.c     | 202 +++++++++++++++++++++---
 drivers/media/usb/pvrusb2/pvrusb2-devattr.h     |   1 +
 drivers/media/usb/pvrusb2/pvrusb2-dvb.c         |  88 ++++++++---
 drivers/media/usb/pvrusb2/pvrusb2-dvb.h         |   5 +-
 drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h     |   4 +
 drivers/media/usb/pvrusb2/pvrusb2-hdw.c         |  36 ++++-
 9 files changed, 330 insertions(+), 40 deletions(-)

-- 
2.7.4


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

* [PATCH v2 1/4] si2157: add detection of si2177 tuner
  2018-12-21 19:40 ` [PATCH v2 0/4] " Brad Love
@ 2018-12-21 19:40   ` Brad Love
  2018-12-21 19:40   ` [PATCH v2 2/4] pvrusb2: Add multiple dvb frontend support Brad Love
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 36+ messages in thread
From: Brad Love @ 2018-12-21 19:40 UTC (permalink / raw)
  To: linux-media, mchehab; +Cc: Brad Love

Works in ATSC and QAM as is, DVB is completely untested.

Firmware required.

Signed-off-by: Brad Love <brad@nextdimension.cc>
---
No changes since v1

 drivers/media/tuners/si2157.c      | 6 ++++++
 drivers/media/tuners/si2157_priv.h | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index d389f1f..3d21af5 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -138,6 +138,7 @@ static int si2157_init(struct dvb_frontend *fe)
 	chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
 			cmd.args[4] << 0;
 
+	#define SI2177_A30 ('A' << 24 | 77 << 16 | '3' << 8 | '0' << 0)
 	#define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
 	#define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0)
 	#define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
@@ -153,6 +154,9 @@ static int si2157_init(struct dvb_frontend *fe)
 	case SI2141_A10:
 		fw_name = SI2141_A10_FIRMWARE;
 		break;
+	case SI2177_A30:
+		fw_name = SI2157_A30_FIRMWARE;
+		break;
 	case SI2157_A30:
 	case SI2147_A30:
 	case SI2146_A10:
@@ -529,6 +533,7 @@ static const struct i2c_device_id si2157_id_table[] = {
 	{"si2157", SI2157_CHIPTYPE_SI2157},
 	{"si2146", SI2157_CHIPTYPE_SI2146},
 	{"si2141", SI2157_CHIPTYPE_SI2141},
+	{"si2177", SI2157_CHIPTYPE_SI2177},
 	{}
 };
 MODULE_DEVICE_TABLE(i2c, si2157_id_table);
@@ -550,3 +555,4 @@ MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 MODULE_LICENSE("GPL");
 MODULE_FIRMWARE(SI2158_A20_FIRMWARE);
 MODULE_FIRMWARE(SI2141_A10_FIRMWARE);
+MODULE_FIRMWARE(SI2157_A30_FIRMWARE);
diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h
index 50f8630..67caee5 100644
--- a/drivers/media/tuners/si2157_priv.h
+++ b/drivers/media/tuners/si2157_priv.h
@@ -50,6 +50,7 @@ struct si2157_dev {
 #define SI2157_CHIPTYPE_SI2157 0
 #define SI2157_CHIPTYPE_SI2146 1
 #define SI2157_CHIPTYPE_SI2141 2
+#define SI2157_CHIPTYPE_SI2177 3
 
 /* firmware command struct */
 #define SI2157_ARGLEN      30
@@ -61,5 +62,5 @@ struct si2157_cmd {
 
 #define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"
 #define SI2141_A10_FIRMWARE "dvb-tuner-si2141-a10-01.fw"
-
+#define SI2157_A30_FIRMWARE "dvb-tuner-si2157-a30-05.fw"
 #endif
-- 
2.7.4


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

* [PATCH v2 2/4] pvrusb2: Add multiple dvb frontend support
  2018-12-21 19:40 ` [PATCH v2 0/4] " Brad Love
  2018-12-21 19:40   ` [PATCH v2 1/4] si2157: add detection of si2177 tuner Brad Love
@ 2018-12-21 19:40   ` Brad Love
  2018-12-21 19:40   ` [PATCH v2 3/4] pvrusb2: Add i2c client demod/tuner support Brad Love
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 36+ messages in thread
From: Brad Love @ 2018-12-21 19:40 UTC (permalink / raw)
  To: linux-media, mchehab; +Cc: Brad Love

All changes are equivalent and backwards compatible.
All current devices have been changed to use fe[0]
Cleanup has been added to dvb init to support cleanup after failure.

Signed-off-by: Brad Love <brad@nextdimension.cc>
---
No changes since v1

 drivers/media/usb/pvrusb2/pvrusb2-devattr.c | 36 +++++++-------
 drivers/media/usb/pvrusb2/pvrusb2-dvb.c     | 77 ++++++++++++++++++++++-------
 drivers/media/usb/pvrusb2/pvrusb2-dvb.h     |  2 +-
 3 files changed, 77 insertions(+), 38 deletions(-)

diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
index 06de1c8..ef36b62 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
@@ -188,10 +188,10 @@ static struct lgdt330x_config pvr2_lgdt3303_config = {
 
 static int pvr2_lgdt3303_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3303_config,
-			      0x0e,
-			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	adap->fe[0] = dvb_attach(lgdt330x_attach, &pvr2_lgdt3303_config,
+				 0x0e,
+				 &adap->channel.hdw->i2c_adap);
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -199,7 +199,7 @@ static int pvr2_lgdt3303_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_lgh06xf_attach(struct pvr2_dvb_adapter *adap)
 {
-	dvb_attach(simple_tuner_attach, adap->fe,
+	dvb_attach(simple_tuner_attach, adap->fe[0],
 		   &adap->channel.hdw->i2c_adap, 0x61,
 		   TUNER_LG_TDVS_H06XF);
 
@@ -248,10 +248,10 @@ static struct lgdt330x_config pvr2_lgdt3302_config = {
 
 static int pvr2_lgdt3302_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3302_config,
+	adap->fe[0] = dvb_attach(lgdt330x_attach, &pvr2_lgdt3302_config,
 			      0x0e,
 			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -259,7 +259,7 @@ static int pvr2_lgdt3302_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_fcv1236d_attach(struct pvr2_dvb_adapter *adap)
 {
-	dvb_attach(simple_tuner_attach, adap->fe,
+	dvb_attach(simple_tuner_attach, adap->fe[0],
 		   &adap->channel.hdw->i2c_adap, 0x61,
 		   TUNER_PHILIPS_FCV1236D);
 
@@ -335,9 +335,9 @@ static struct tda18271_config hauppauge_tda18271_dvb_config = {
 
 static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(tda10048_attach, &hauppauge_tda10048_config,
+	adap->fe[0] = dvb_attach(tda10048_attach, &hauppauge_tda10048_config,
 			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -345,10 +345,10 @@ static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_73xxx_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
 {
-	dvb_attach(tda829x_attach, adap->fe,
+	dvb_attach(tda829x_attach, adap->fe[0],
 		   &adap->channel.hdw->i2c_adap, 0x42,
 		   &tda829x_no_probe);
-	dvb_attach(tda18271_attach, adap->fe, 0x60,
+	dvb_attach(tda18271_attach, adap->fe[0], 0x60,
 		   &adap->channel.hdw->i2c_adap,
 		   &hauppauge_tda18271_dvb_config);
 
@@ -433,9 +433,9 @@ static struct tda18271_config hauppauge_tda18271_config = {
 
 static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(s5h1409_attach, &pvr2_s5h1409_config,
+	adap->fe[0] = dvb_attach(s5h1409_attach, &pvr2_s5h1409_config,
 			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -443,9 +443,9 @@ static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_s5h1411_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(s5h1411_attach, &pvr2_s5h1411_config,
+	adap->fe[0] = dvb_attach(s5h1411_attach, &pvr2_s5h1411_config,
 			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -453,10 +453,10 @@ static int pvr2_s5h1411_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
 {
-	dvb_attach(tda829x_attach, adap->fe,
+	dvb_attach(tda829x_attach, adap->fe[0],
 		   &adap->channel.hdw->i2c_adap, 0x42,
 		   &tda829x_no_probe);
-	dvb_attach(tda18271_attach, adap->fe, 0x60,
+	dvb_attach(tda18271_attach, adap->fe[0], 0x60,
 		   &adap->channel.hdw->i2c_adap,
 		   &hauppauge_tda18271_config);
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
index 4b32b21..cb5586b 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
@@ -343,26 +343,19 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
 		goto done;
 	}
 
-	if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) {
-
-		if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
+	if (dvb_props->frontend_attach(adap) == 0 && adap->fe[0]) {
+		if (dvb_register_frontend(&adap->dvb_adap, adap->fe[0])) {
 			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 				   "frontend registration failed!");
-			dvb_frontend_detach(adap->fe);
-			adap->fe = NULL;
 			ret = -ENODEV;
-			goto done;
+			goto fail_frontend0;
 		}
+		if (adap->fe[0]->ops.analog_ops.standby)
+			adap->fe[0]->ops.analog_ops.standby(adap->fe[0]);
 
-		if (dvb_props->tuner_attach)
-			dvb_props->tuner_attach(adap);
-
-		if (adap->fe->ops.analog_ops.standby)
-			adap->fe->ops.analog_ops.standby(adap->fe);
-
-		/* Ensure all frontends negotiate bus access */
-		adap->fe->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
-
+		pvr2_trace(PVR2_TRACE_INFO, "transferring fe[%d] ts_bus_ctrl() to pvr2_dvb_bus_ctrl()",
+				adap->fe[0]->id);
+		adap->fe[0]->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
 	} else {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 			   "no frontend was attached!");
@@ -370,16 +363,62 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
 		return ret;
 	}
 
- done:
+	if (dvb_props->tuner_attach && dvb_props->tuner_attach(adap)) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS, "tuner attach failed");
+		ret = -ENODEV;
+		goto fail_tuner;
+	}
+
+	if (adap->fe[1]) {
+		adap->fe[1]->id = 1;
+		adap->fe[1]->tuner_priv = adap->fe[0]->tuner_priv;
+		memcpy(&adap->fe[1]->ops.tuner_ops,
+			&adap->fe[0]->ops.tuner_ops,
+			sizeof(struct dvb_tuner_ops));
+
+		if (dvb_register_frontend(&adap->dvb_adap, adap->fe[1])) {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "frontend registration failed!");
+			ret = -ENODEV;
+			goto fail_frontend1;
+		}
+		/* MFE lock */
+		adap->dvb_adap.mfe_shared = 1;
+
+		if (adap->fe[1]->ops.analog_ops.standby)
+			adap->fe[1]->ops.analog_ops.standby(adap->fe[1]);
+
+		pvr2_trace(PVR2_TRACE_INFO, "transferring fe[%d] ts_bus_ctrl() to pvr2_dvb_bus_ctrl()",
+				adap->fe[1]->id);
+		adap->fe[1]->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
+	}
+done:
 	pvr2_channel_limit_inputs(&adap->channel, 0);
 	return ret;
+
+fail_frontend1:
+	dvb_frontend_detach(adap->fe[1]);
+	adap->fe[1] = NULL;
+fail_tuner:
+	dvb_unregister_frontend(adap->fe[0]);
+fail_frontend0:
+	dvb_frontend_detach(adap->fe[0]);
+	adap->fe[0] = NULL;
+
+	return ret;
 }
 
 static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap)
 {
-	if (adap->fe != NULL) {
-		dvb_unregister_frontend(adap->fe);
-		dvb_frontend_detach(adap->fe);
+	if (adap->fe[1]) {
+		dvb_unregister_frontend(adap->fe[1]);
+		dvb_frontend_detach(adap->fe[1]);
+		adap->fe[1] = NULL;
+	}
+	if (adap->fe[0]) {
+		dvb_unregister_frontend(adap->fe[0]);
+		dvb_frontend_detach(adap->fe[0]);
+		adap->fe[0] = NULL;
 	}
 	return 0;
 }
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
index e7f71fb..91bff57 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
@@ -18,7 +18,7 @@ struct pvr2_dvb_adapter {
 	struct dmxdev		dmxdev;
 	struct dvb_demux	demux;
 	struct dvb_net		dvb_net;
-	struct dvb_frontend	*fe;
+	struct dvb_frontend	*fe[2];
 
 	int			feedcount;
 	int			max_feed_count;
-- 
2.7.4


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

* [PATCH v2 3/4] pvrusb2: Add i2c client demod/tuner support
  2018-12-21 19:40 ` [PATCH v2 0/4] " Brad Love
  2018-12-21 19:40   ` [PATCH v2 1/4] si2157: add detection of si2177 tuner Brad Love
  2018-12-21 19:40   ` [PATCH v2 2/4] pvrusb2: Add multiple dvb frontend support Brad Love
@ 2018-12-21 19:40   ` Brad Love
  2018-12-21 19:40   ` [PATCH v2 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 36+ messages in thread
From: Brad Love @ 2018-12-21 19:40 UTC (permalink / raw)
  To: linux-media, mchehab; +Cc: Brad Love

Cleanup code has been added to init in case of failure,
as well as to frontend exit.

Signed-off-by: Brad Love <brad@nextdimension.cc>
---
No changes since v1

 drivers/media/usb/pvrusb2/pvrusb2-dvb.c | 11 +++++++++++
 drivers/media/usb/pvrusb2/pvrusb2-dvb.h |  3 +++
 2 files changed, 14 insertions(+)

diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
index cb5586b..8e1735f 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
@@ -404,6 +404,9 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
 fail_frontend0:
 	dvb_frontend_detach(adap->fe[0]);
 	adap->fe[0] = NULL;
+	dvb_module_release(adap->i2c_client_tuner);
+	dvb_module_release(adap->i2c_client_demod[1]);
+	dvb_module_release(adap->i2c_client_demod[0]);
 
 	return ret;
 }
@@ -420,6 +423,14 @@ static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap)
 		dvb_frontend_detach(adap->fe[0]);
 		adap->fe[0] = NULL;
 	}
+
+	dvb_module_release(adap->i2c_client_tuner);
+	adap->i2c_client_tuner = NULL;
+	dvb_module_release(adap->i2c_client_demod[1]);
+	adap->i2c_client_demod[1] = NULL;
+	dvb_module_release(adap->i2c_client_demod[0]);
+	adap->i2c_client_demod[0] = NULL;
+
 	return 0;
 }
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
index 91bff57..c0b27f5 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
@@ -20,6 +20,9 @@ struct pvr2_dvb_adapter {
 	struct dvb_net		dvb_net;
 	struct dvb_frontend	*fe[2];
 
+	struct i2c_client	*i2c_client_demod[2];
+	struct i2c_client	*i2c_client_tuner;
+
 	int			feedcount;
 	int			max_feed_count;
 
-- 
2.7.4


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

* [PATCH v2 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices
  2018-12-21 19:40 ` [PATCH v2 0/4] " Brad Love
                     ` (2 preceding siblings ...)
  2018-12-21 19:40   ` [PATCH v2 3/4] pvrusb2: Add i2c client demod/tuner support Brad Love
@ 2018-12-21 19:40   ` Brad Love
  2018-12-22  4:42     ` kbuild test robot
  2018-12-22 10:04     ` kbuild test robot
  2018-12-24 17:00   ` [PATCH v3 0/4] " Brad Love
  2019-02-27 19:16   ` [PATCH v4 0/4] " Brad Love
  5 siblings, 2 replies; 36+ messages in thread
From: Brad Love @ 2018-12-21 19:40 UTC (permalink / raw)
  To: linux-media, mchehab; +Cc: Brad Love

Includes support to identify and use two Hauppauge device.
HVR-1955:
- LGDT3306a ATSC/QAM demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

HVR-1975 dual-frontend:
- LGDT3306a ATSC/QAM demod
- si2168 DVB-C/T/T2 demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

Signed-off-by: Brad Love <brad@nextdimension.cc>
---
Changes since v1:
- Fix build with VIDEO_PVRUSB2_DVB disabled
- Insert 160xxx code lower, so 75xxx profile is not split
- Reorganize 160xxx board profile
- Share config where possible

 drivers/media/usb/pvrusb2/Kconfig               |   2 +
 drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c |  25 ++++
 drivers/media/usb/pvrusb2/pvrusb2-devattr.c     | 163 ++++++++++++++++++++++++
 drivers/media/usb/pvrusb2/pvrusb2-devattr.h     |   1 +
 drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h     |   4 +
 drivers/media/usb/pvrusb2/pvrusb2-hdw.c         |  36 +++++-
 6 files changed, 230 insertions(+), 1 deletion(-)

diff --git a/drivers/media/usb/pvrusb2/Kconfig b/drivers/media/usb/pvrusb2/Kconfig
index 1ad913f..144631c 100644
--- a/drivers/media/usb/pvrusb2/Kconfig
+++ b/drivers/media/usb/pvrusb2/Kconfig
@@ -40,6 +40,8 @@ config VIDEO_PVRUSB2_DVB
 	select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT
+	select DVB_LGDT3306A if MEDIA_SUBDRV_AUTOSELECT
+	select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
index d5bec0f..36016ab 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -111,10 +111,35 @@ static const struct routing_scheme routing_defav400 = {
 	.cnt = ARRAY_SIZE(routing_schemeav400),
 };
 
+static const struct routing_scheme_item routing_scheme160xxx[] = {
+	[PVR2_CVAL_INPUT_TV] = {
+		.vid = CX25840_COMPOSITE7,
+		.aud = CX25840_AUDIO8,
+	},
+	[PVR2_CVAL_INPUT_RADIO] = {
+		.vid = CX25840_COMPOSITE4,
+		.aud = CX25840_AUDIO6,
+	},
+	[PVR2_CVAL_INPUT_COMPOSITE] = {
+		.vid = CX25840_COMPOSITE3,
+		.aud = CX25840_AUDIO_SERIAL,
+	},
+	[PVR2_CVAL_INPUT_SVIDEO] = {
+		.vid = CX25840_SVIDEO1,
+		.aud = CX25840_AUDIO_SERIAL,
+	},
+};
+
+static const struct routing_scheme routing_def160xxx = {
+	.def = routing_scheme160xxx,
+	.cnt = ARRAY_SIZE(routing_scheme160xxx),
+};
+
 static const struct routing_scheme *routing_schemes[] = {
 	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
 	[PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv,
 	[PVR2_ROUTING_SCHEME_AV400] = &routing_defav400,
+	[PVR2_ROUTING_SCHEME_HAUP160XXX] = &routing_def160xxx,
 };
 
 void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
index ef36b62..b837ad0 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
@@ -37,6 +37,9 @@ pvr2_device_desc structures.
 #include "tda18271.h"
 #include "tda8290.h"
 #include "tuner-simple.h"
+#include "si2157.h"
+#include "lgdt3306a.h"
+#include "si2168.h"
 #endif
 
 
@@ -525,7 +528,163 @@ static const struct pvr2_device_desc pvr2_device_751xx = {
 #endif
 };
 
+/*------------------------------------------------------------------------*/
+/*    Hauppauge PVR-USB2 Model 160000 / 160111 -- HVR-1955 / HVR-1975     */
+
+#ifdef CONFIG_VIDEO_PVRUSB2_DVB
+static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap);
+static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap);
+static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap);
+
+static const struct pvr2_dvb_props pvr2_160000_dvb_props = {
+	.frontend_attach = pvr2_dual_fe_attach,
+	.tuner_attach    = pvr2_si2157_attach,
+};
+static const struct pvr2_dvb_props pvr2_160111_dvb_props = {
+	.frontend_attach = pvr2_lgdt3306a_attach,
+	.tuner_attach    = pvr2_si2157_attach,
+};
+
+static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
+{
+	struct si2157_config si2157_config = {};
+
+	si2157_config.inversion = 1;
+	si2157_config.fe = adap->fe[0];
+
+	adap->i2c_client_tuner = dvb_module_probe("si2157", "si2177",
+						&adap->channel.hdw->i2c_adap,
+						0x60, &si2157_config);
+
+	if (!adap->i2c_client_tuner)
+		return -ENODEV;
+
+	return 0;
+}
+
+static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap)
+{
+	struct si2168_config si2168_config = {};
+	struct i2c_adapter *adapter;
+
+	pr_debug("%s()\n", __func__);
+
+	si2168_config.fe = &adap->fe[1];
+	si2168_config.i2c_adapter = &adapter;
+	si2168_config.ts_mode = SI2168_TS_PARALLEL; /*2, 1-serial, 2-parallel.*/
+	si2168_config.ts_clock_gapped = 1; /*0-disabled, 1-enabled.*/
+	si2168_config.ts_clock_inv = 0; /*0-not-invert, 1-invert*/
+	si2168_config.spectral_inversion = 1; /*0-not-invert, 1-invert*/
+
+	adap->i2c_client_demod[1] = dvb_module_probe("si2168", NULL,
+						&adap->channel.hdw->i2c_adap,
+						0x64, &si2168_config);
 
+	if (!adap->i2c_client_demod[1])
+		return -ENODEV;
+
+	return 0;
+}
+
+static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
+{
+	struct lgdt3306a_config lgdt3306a_config;
+	struct i2c_adapter *adapter;
+
+	pr_debug("%s()\n", __func__);
+
+	lgdt3306a_config.fe = &adap->fe[0];
+	lgdt3306a_config.i2c_adapter = &adapter;
+	lgdt3306a_config.deny_i2c_rptr = 1;
+	lgdt3306a_config.spectral_inversion = 1;
+	lgdt3306a_config.qam_if_khz = 4000;
+	lgdt3306a_config.vsb_if_khz = 3250;
+	lgdt3306a_config.mpeg_mode = LGDT3306A_MPEG_PARALLEL;
+	lgdt3306a_config.tpclk_edge = LGDT3306A_TPCLK_FALLING_EDGE;
+	lgdt3306a_config.tpvalid_polarity = LGDT3306A_TP_VALID_LOW;
+	lgdt3306a_config.xtalMHz = 25, /* demod clock MHz; 24/25 supported */
+
+	adap->i2c_client_demod[0] = dvb_module_probe("lgdt3306a", NULL,
+						&adap->channel.hdw->i2c_adap,
+						0x59, &lgdt3306a_config);
+
+	if (!adap->i2c_client_demod[0])
+		return -ENODEV;
+
+	return 0;
+}
+
+static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap)
+{
+	pr_debug("%s()\n", __func__);
+
+	if (pvr2_lgdt3306a_attach(adap) != 0)
+		return -ENODEV;
+
+	if (pvr2_si2168_attach(adap) != 0) {
+		dvb_module_release(adap->i2c_client_demod[0]);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+#endif
+
+#define PVR2_FIRMWARE_160xxx "v4l-pvrusb2-160xxx-01.fw"
+static const char *pvr2_fw1_names_160xxx[] = {
+		PVR2_FIRMWARE_160xxx,
+};
+
+static const struct pvr2_device_client_desc pvr2_cli_160xxx[] = {
+	{ .module_id = PVR2_CLIENT_ID_CX25840 },
+};
+
+static const struct pvr2_device_desc pvr2_device_160000 = {
+		.description = "WinTV HVR-1975 Model 160000",
+		.shortname = "160000",
+		.client_table.lst = pvr2_cli_160xxx,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160xxx),
+		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
+		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
+		.default_tuner_type = TUNER_ABSENT,
+		.flag_has_cx25840 = !0,
+		.flag_has_hauppauge_rom = !0,
+		.flag_has_analogtuner = !0,
+		.flag_has_composite = !0,
+		.flag_has_svideo = !0,
+		.flag_fx2_16kb = !0,
+		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
+		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
+		.default_std_mask = V4L2_STD_NTSC_M,
+		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
+#ifdef CONFIG_VIDEO_PVRUSB2_DVB
+		.dvb_props = &pvr2_160000_dvb_props,
+#endif
+};
+static const struct pvr2_device_desc pvr2_device_160111 = {
+		.description = "WinTV HVR-1955 Model 160111",
+		.shortname = "160111",
+		.client_table.lst = pvr2_cli_160xxx,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160xxx),
+		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
+		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
+		.default_tuner_type = TUNER_ABSENT,
+		.flag_has_cx25840 = !0,
+		.flag_has_hauppauge_rom = !0,
+		.flag_has_analogtuner = !0,
+		.flag_has_composite = !0,
+		.flag_has_svideo = !0,
+		.flag_fx2_16kb = !0,
+		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
+		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
+		.default_std_mask = V4L2_STD_NTSC_M,
+		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
+#ifdef CONFIG_VIDEO_PVRUSB2_DVB
+		.dvb_props = &pvr2_160111_dvb_props,
+#endif
+};
 
 /*------------------------------------------------------------------------*/
 
@@ -552,6 +711,10 @@ struct usb_device_id pvr2_device_table[] = {
 	  .driver_info = (kernel_ulong_t)&pvr2_device_751xx},
 	{ USB_DEVICE(0x0ccd, 0x0039),
 	  .driver_info = (kernel_ulong_t)&pvr2_device_av400},
+	{ USB_DEVICE(0x2040, 0x7502),
+	  .driver_info = (kernel_ulong_t)&pvr2_device_160111},
+	{ USB_DEVICE(0x2040, 0x7510),
+	  .driver_info = (kernel_ulong_t)&pvr2_device_160000},
 	{ }
 };
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.h b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
index c1e7d48..ea0b2bf 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
@@ -66,6 +66,7 @@ struct pvr2_string_table {
 #define PVR2_ROUTING_SCHEME_GOTVIEW 1
 #define PVR2_ROUTING_SCHEME_ONAIR 2
 #define PVR2_ROUTING_SCHEME_AV400 3
+#define PVR2_ROUTING_SCHEME_HAUP160XXX 4
 
 #define PVR2_DIGITAL_SCHEME_NONE 0
 #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
index 0a01de4..640b033 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
@@ -38,6 +38,10 @@
 
 #define FX2CMD_FWPOST1          0x52u
 
+/* These 2 only exist on Model 160xxx */
+#define FX2CMD_HCW_DEMOD_RESET_PIN 0xd4u
+#define FX2CMD_HCW_MAKO_SLEEP_PIN  0xd5u
+
 #define FX2CMD_POWER_OFF        0xdcu
 #define FX2CMD_POWER_ON         0xdeu
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
index 446a999..ab9e822 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
@@ -316,6 +316,8 @@ static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = {
 	{FX2CMD_ONAIR_DTV_STREAMING_OFF, "onair dtv stream off"},
 	{FX2CMD_ONAIR_DTV_POWER_ON, "onair dtv power on"},
 	{FX2CMD_ONAIR_DTV_POWER_OFF, "onair dtv power off"},
+	{FX2CMD_HCW_DEMOD_RESET_PIN, "hcw demod reset pin"},
+	{FX2CMD_HCW_MAKO_SLEEP_PIN, "hcw mako sleep pin"},
 };
 
 
@@ -2137,10 +2139,28 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
 				      ((0) << 16));
 	}
 
-	// This step MUST happen after the earlier powerup step.
+	/* This step MUST happen after the earlier powerup step */
 	pvr2_i2c_core_init(hdw);
 	if (!pvr2_hdw_dev_ok(hdw)) return;
 
+	/* Reset demod only on Hauppauge 160xxx platform */
+	if (hdw->usb_dev->descriptor.idVendor == 0x2040 &&
+	    (hdw->usb_dev->descriptor.idProduct == 0x7502 ||
+	     hdw->usb_dev->descriptor.idProduct == 0x7510)) {
+		pr_info("%s(): resetting 160xxx demod\n", __func__);
+		/* TODO: not sure this is proper place to reset once only */
+		pvr2_issue_simple_cmd(hdw,
+				     FX2CMD_HCW_DEMOD_RESET_PIN |
+				     (1 << 8) |
+				     ((0) << 16));
+		msleep(10);
+		pvr2_issue_simple_cmd(hdw,
+				     FX2CMD_HCW_DEMOD_RESET_PIN |
+				     (1 << 8) |
+				     ((1) << 16));
+		msleep(10);
+	}
+
 	pvr2_hdw_load_modules(hdw);
 	if (!pvr2_hdw_dev_ok(hdw)) return;
 
@@ -4011,6 +4031,20 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
 static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff)
 {
 	hdw->flag_ok = !0;
+
+	/* Use this for Hauppauge 160xxx only */
+	if (hdw->usb_dev->descriptor.idVendor == 0x2040 &&
+	    (hdw->usb_dev->descriptor.idProduct == 0x7502 ||
+	     hdw->usb_dev->descriptor.idProduct == 0x7510)) {
+		pr_debug("%s(): resetting demod on Hauppauge 160xxx platform skipped\n",
+			__func__);
+		/* Can't reset 160xxx or it will trash Demod tristate */
+		return pvr2_issue_simple_cmd(hdw,
+				     FX2CMD_HCW_MAKO_SLEEP_PIN |
+				     (1 << 8) |
+				     ((onoff ? 1 : 0) << 16));
+	}
+
 	return pvr2_issue_simple_cmd(hdw,
 				     FX2CMD_HCW_DEMOD_RESETIN |
 				     (1 << 8) |
-- 
2.7.4


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

* Re: [PATCH v2 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices
  2018-12-21 19:40   ` [PATCH v2 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
@ 2018-12-22  4:42     ` kbuild test robot
  2018-12-22 10:04     ` kbuild test robot
  1 sibling, 0 replies; 36+ messages in thread
From: kbuild test robot @ 2018-12-22  4:42 UTC (permalink / raw)
  To: Brad Love; +Cc: kbuild-all, linux-media, mchehab, Brad Love

[-- Attachment #1: Type: text/plain, Size: 1736 bytes --]

Hi Brad,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linuxtv-media/master]
[also build test ERROR on v4.20-rc7 next-20181221]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Brad-Love/Add-Hauppauge-HVR1955-1975-devices/20181222-110834
base:   git://linuxtv.org/media_tree.git master
config: x86_64-rhel-7.2-clear (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

>> drivers/media//usb/pvrusb2/pvrusb2-devattr.c:541:21: error: 'pvr2_si2157_attach' undeclared here (not in a function); did you mean 'pvr2_si2168_attach'?
     .tuner_attach    = pvr2_si2157_attach,
                        ^~~~~~~~~~~~~~~~~~
                        pvr2_si2168_attach
   drivers/media//usb/pvrusb2/pvrusb2-devattr.c:548:12: warning: 'pvr2_si2157_attach' defined but not used [-Wunused-function]
    static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~

vim +541 drivers/media//usb/pvrusb2/pvrusb2-devattr.c

   538	
   539	static const struct pvr2_dvb_props pvr2_160000_dvb_props = {
   540		.frontend_attach = pvr2_dual_fe_attach,
 > 541		.tuner_attach    = pvr2_si2157_attach,
   542	};
   543	static const struct pvr2_dvb_props pvr2_160111_dvb_props = {
   544		.frontend_attach = pvr2_lgdt3306a_attach,
   545		.tuner_attach    = pvr2_si2157_attach,
   546	};
   547	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 41458 bytes --]

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

* Re: [PATCH v2 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices
  2018-12-21 19:40   ` [PATCH v2 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
  2018-12-22  4:42     ` kbuild test robot
@ 2018-12-22 10:04     ` kbuild test robot
  1 sibling, 0 replies; 36+ messages in thread
From: kbuild test robot @ 2018-12-22 10:04 UTC (permalink / raw)
  To: Brad Love; +Cc: kbuild-all, linux-media, mchehab, Brad Love

[-- Attachment #1: Type: text/plain, Size: 1845 bytes --]

Hi Brad,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linuxtv-media/master]
[also build test ERROR on v4.20-rc7 next-20181221]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Brad-Love/Add-Hauppauge-HVR1955-1975-devices/20181222-110834
base:   git://linuxtv.org/media_tree.git master
config: openrisc-allmodconfig (attached as .config)
compiler: or1k-linux-gcc (GCC) 6.0.0 20160327 (experimental)
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=openrisc 

All errors (new ones prefixed by >>):

>> drivers/media/usb/pvrusb2/pvrusb2-devattr.c:541:21: error: 'pvr2_si2157_attach' undeclared here (not in a function)
     .tuner_attach    = pvr2_si2157_attach,
                        ^~~~~~~~~~~~~~~~~~
   drivers/media/usb/pvrusb2/pvrusb2-devattr.c:548:12: warning: 'pvr2_si2157_attach' defined but not used [-Wunused-function]
    static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
               ^~~~~~~~~~~~~~~~~~

vim +/pvr2_si2157_attach +541 drivers/media/usb/pvrusb2/pvrusb2-devattr.c

   538	
   539	static const struct pvr2_dvb_props pvr2_160000_dvb_props = {
   540		.frontend_attach = pvr2_dual_fe_attach,
 > 541		.tuner_attach    = pvr2_si2157_attach,
   542	};
   543	static const struct pvr2_dvb_props pvr2_160111_dvb_props = {
   544		.frontend_attach = pvr2_lgdt3306a_attach,
   545		.tuner_attach    = pvr2_si2157_attach,
   546	};
   547	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 47069 bytes --]

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

* [PATCH v3 0/4] Add Hauppauge HVR1955/1975 devices
  2018-12-21 19:40 ` [PATCH v2 0/4] " Brad Love
                     ` (3 preceding siblings ...)
  2018-12-21 19:40   ` [PATCH v2 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
@ 2018-12-24 17:00   ` " Brad Love
  2018-12-24 17:00     ` [PATCH v3 1/4] si2157: add detection of si2177 tuner Brad Love
                       ` (3 more replies)
  2019-02-27 19:16   ` [PATCH v4 0/4] " Brad Love
  5 siblings, 4 replies; 36+ messages in thread
From: Brad Love @ 2018-12-24 17:00 UTC (permalink / raw)
  To: linux-media, mchehab; +Cc: Brad Love

Hauppauge device HVR1955 and HVR1975 are old Cypress based
devices. When originally produced the demods were lacking
upstream drivers and the tuner was unsupported. Well fast
forward to now and the only thing missing is the identification
of si2177 tuner in the si2157 driver, as well as extension
of the pvrusb2 driver to accomodate i2c client devices
and multiple frontends. This series addresses what is necessary.

QAM/ATSC are fully tested and work, the DVB tuning
*should* work, but is completely untested. Both demod
drivers are compatible with multiple frontend usage due
to previous patches I've submitted, so things should
work in pvrusb2 as well.

Composite video input is tested. Unable to test s-video,
but it should work. Radio is fully untested. Analog TV is
a work in progress, coming soon.

HVR-1955:
- LGDT3306a ATSC/QAM demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

HVR-1975 dual-frontend:
- LGDT3306a ATSC/QAM demod
- si2168 DVB-C/T/T2 demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

Since v2:
- Patch 4/4 build fix
Changes since v1:
- Patch 4/4 build fixes and reorganization


Brad Love (4):
  si2157: add detection of si2177 tuner
  pvrusb2: Add multiple dvb frontend support
  pvrusb2: Add i2c client demod/tuner support
  pvrusb2: Add Hauppauge HVR1955/1975 devices

 drivers/media/tuners/si2157.c                   |   6 +
 drivers/media/tuners/si2157_priv.h              |   3 +-
 drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c |  25 +++
 drivers/media/usb/pvrusb2/pvrusb2-devattr.c     | 202 +++++++++++++++++++++---
 drivers/media/usb/pvrusb2/pvrusb2-devattr.h     |   1 +
 drivers/media/usb/pvrusb2/pvrusb2-dvb.c         |  88 ++++++++---
 drivers/media/usb/pvrusb2/pvrusb2-dvb.h         |   5 +-
 drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h     |   4 +
 drivers/media/usb/pvrusb2/pvrusb2-hdw.c         |  36 ++++-
 9 files changed, 330 insertions(+), 40 deletions(-)

-- 
2.7.4


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

* [PATCH v3 1/4] si2157: add detection of si2177 tuner
  2018-12-24 17:00   ` [PATCH v3 0/4] " Brad Love
@ 2018-12-24 17:00     ` Brad Love
  2018-12-24 17:00     ` [PATCH v3 2/4] pvrusb2: Add multiple dvb frontend support Brad Love
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 36+ messages in thread
From: Brad Love @ 2018-12-24 17:00 UTC (permalink / raw)
  To: linux-media, mchehab; +Cc: Brad Love

Works in ATSC and QAM as is, DVB is completely untested.

Firmware required.

Signed-off-by: Brad Love <brad@nextdimension.cc>
---
No changes

 drivers/media/tuners/si2157.c      | 6 ++++++
 drivers/media/tuners/si2157_priv.h | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index d389f1f..3d21af5 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -138,6 +138,7 @@ static int si2157_init(struct dvb_frontend *fe)
 	chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
 			cmd.args[4] << 0;
 
+	#define SI2177_A30 ('A' << 24 | 77 << 16 | '3' << 8 | '0' << 0)
 	#define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
 	#define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0)
 	#define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
@@ -153,6 +154,9 @@ static int si2157_init(struct dvb_frontend *fe)
 	case SI2141_A10:
 		fw_name = SI2141_A10_FIRMWARE;
 		break;
+	case SI2177_A30:
+		fw_name = SI2157_A30_FIRMWARE;
+		break;
 	case SI2157_A30:
 	case SI2147_A30:
 	case SI2146_A10:
@@ -529,6 +533,7 @@ static const struct i2c_device_id si2157_id_table[] = {
 	{"si2157", SI2157_CHIPTYPE_SI2157},
 	{"si2146", SI2157_CHIPTYPE_SI2146},
 	{"si2141", SI2157_CHIPTYPE_SI2141},
+	{"si2177", SI2157_CHIPTYPE_SI2177},
 	{}
 };
 MODULE_DEVICE_TABLE(i2c, si2157_id_table);
@@ -550,3 +555,4 @@ MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 MODULE_LICENSE("GPL");
 MODULE_FIRMWARE(SI2158_A20_FIRMWARE);
 MODULE_FIRMWARE(SI2141_A10_FIRMWARE);
+MODULE_FIRMWARE(SI2157_A30_FIRMWARE);
diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h
index 50f8630..67caee5 100644
--- a/drivers/media/tuners/si2157_priv.h
+++ b/drivers/media/tuners/si2157_priv.h
@@ -50,6 +50,7 @@ struct si2157_dev {
 #define SI2157_CHIPTYPE_SI2157 0
 #define SI2157_CHIPTYPE_SI2146 1
 #define SI2157_CHIPTYPE_SI2141 2
+#define SI2157_CHIPTYPE_SI2177 3
 
 /* firmware command struct */
 #define SI2157_ARGLEN      30
@@ -61,5 +62,5 @@ struct si2157_cmd {
 
 #define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"
 #define SI2141_A10_FIRMWARE "dvb-tuner-si2141-a10-01.fw"
-
+#define SI2157_A30_FIRMWARE "dvb-tuner-si2157-a30-05.fw"
 #endif
-- 
2.7.4


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

* [PATCH v3 2/4] pvrusb2: Add multiple dvb frontend support
  2018-12-24 17:00   ` [PATCH v3 0/4] " Brad Love
  2018-12-24 17:00     ` [PATCH v3 1/4] si2157: add detection of si2177 tuner Brad Love
@ 2018-12-24 17:00     ` Brad Love
  2018-12-24 17:00     ` [PATCH v3 3/4] pvrusb2: Add i2c client demod/tuner support Brad Love
  2018-12-24 17:00     ` [PATCH v3 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
  3 siblings, 0 replies; 36+ messages in thread
From: Brad Love @ 2018-12-24 17:00 UTC (permalink / raw)
  To: linux-media, mchehab; +Cc: Brad Love

All changes are equivalent and backwards compatible.
All current devices have been changed to use fe[0]
Cleanup has been added to dvb init to support cleanup after failure.

Signed-off-by: Brad Love <brad@nextdimension.cc>
---
No changes

 drivers/media/usb/pvrusb2/pvrusb2-devattr.c | 36 +++++++-------
 drivers/media/usb/pvrusb2/pvrusb2-dvb.c     | 77 ++++++++++++++++++++++-------
 drivers/media/usb/pvrusb2/pvrusb2-dvb.h     |  2 +-
 3 files changed, 77 insertions(+), 38 deletions(-)

diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
index 06de1c8..ef36b62 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
@@ -188,10 +188,10 @@ static struct lgdt330x_config pvr2_lgdt3303_config = {
 
 static int pvr2_lgdt3303_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3303_config,
-			      0x0e,
-			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	adap->fe[0] = dvb_attach(lgdt330x_attach, &pvr2_lgdt3303_config,
+				 0x0e,
+				 &adap->channel.hdw->i2c_adap);
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -199,7 +199,7 @@ static int pvr2_lgdt3303_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_lgh06xf_attach(struct pvr2_dvb_adapter *adap)
 {
-	dvb_attach(simple_tuner_attach, adap->fe,
+	dvb_attach(simple_tuner_attach, adap->fe[0],
 		   &adap->channel.hdw->i2c_adap, 0x61,
 		   TUNER_LG_TDVS_H06XF);
 
@@ -248,10 +248,10 @@ static struct lgdt330x_config pvr2_lgdt3302_config = {
 
 static int pvr2_lgdt3302_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3302_config,
+	adap->fe[0] = dvb_attach(lgdt330x_attach, &pvr2_lgdt3302_config,
 			      0x0e,
 			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -259,7 +259,7 @@ static int pvr2_lgdt3302_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_fcv1236d_attach(struct pvr2_dvb_adapter *adap)
 {
-	dvb_attach(simple_tuner_attach, adap->fe,
+	dvb_attach(simple_tuner_attach, adap->fe[0],
 		   &adap->channel.hdw->i2c_adap, 0x61,
 		   TUNER_PHILIPS_FCV1236D);
 
@@ -335,9 +335,9 @@ static struct tda18271_config hauppauge_tda18271_dvb_config = {
 
 static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(tda10048_attach, &hauppauge_tda10048_config,
+	adap->fe[0] = dvb_attach(tda10048_attach, &hauppauge_tda10048_config,
 			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -345,10 +345,10 @@ static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_73xxx_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
 {
-	dvb_attach(tda829x_attach, adap->fe,
+	dvb_attach(tda829x_attach, adap->fe[0],
 		   &adap->channel.hdw->i2c_adap, 0x42,
 		   &tda829x_no_probe);
-	dvb_attach(tda18271_attach, adap->fe, 0x60,
+	dvb_attach(tda18271_attach, adap->fe[0], 0x60,
 		   &adap->channel.hdw->i2c_adap,
 		   &hauppauge_tda18271_dvb_config);
 
@@ -433,9 +433,9 @@ static struct tda18271_config hauppauge_tda18271_config = {
 
 static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(s5h1409_attach, &pvr2_s5h1409_config,
+	adap->fe[0] = dvb_attach(s5h1409_attach, &pvr2_s5h1409_config,
 			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -443,9 +443,9 @@ static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_s5h1411_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(s5h1411_attach, &pvr2_s5h1411_config,
+	adap->fe[0] = dvb_attach(s5h1411_attach, &pvr2_s5h1411_config,
 			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -453,10 +453,10 @@ static int pvr2_s5h1411_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
 {
-	dvb_attach(tda829x_attach, adap->fe,
+	dvb_attach(tda829x_attach, adap->fe[0],
 		   &adap->channel.hdw->i2c_adap, 0x42,
 		   &tda829x_no_probe);
-	dvb_attach(tda18271_attach, adap->fe, 0x60,
+	dvb_attach(tda18271_attach, adap->fe[0], 0x60,
 		   &adap->channel.hdw->i2c_adap,
 		   &hauppauge_tda18271_config);
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
index 4b32b21..cb5586b 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
@@ -343,26 +343,19 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
 		goto done;
 	}
 
-	if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) {
-
-		if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
+	if (dvb_props->frontend_attach(adap) == 0 && adap->fe[0]) {
+		if (dvb_register_frontend(&adap->dvb_adap, adap->fe[0])) {
 			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 				   "frontend registration failed!");
-			dvb_frontend_detach(adap->fe);
-			adap->fe = NULL;
 			ret = -ENODEV;
-			goto done;
+			goto fail_frontend0;
 		}
+		if (adap->fe[0]->ops.analog_ops.standby)
+			adap->fe[0]->ops.analog_ops.standby(adap->fe[0]);
 
-		if (dvb_props->tuner_attach)
-			dvb_props->tuner_attach(adap);
-
-		if (adap->fe->ops.analog_ops.standby)
-			adap->fe->ops.analog_ops.standby(adap->fe);
-
-		/* Ensure all frontends negotiate bus access */
-		adap->fe->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
-
+		pvr2_trace(PVR2_TRACE_INFO, "transferring fe[%d] ts_bus_ctrl() to pvr2_dvb_bus_ctrl()",
+				adap->fe[0]->id);
+		adap->fe[0]->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
 	} else {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 			   "no frontend was attached!");
@@ -370,16 +363,62 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
 		return ret;
 	}
 
- done:
+	if (dvb_props->tuner_attach && dvb_props->tuner_attach(adap)) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS, "tuner attach failed");
+		ret = -ENODEV;
+		goto fail_tuner;
+	}
+
+	if (adap->fe[1]) {
+		adap->fe[1]->id = 1;
+		adap->fe[1]->tuner_priv = adap->fe[0]->tuner_priv;
+		memcpy(&adap->fe[1]->ops.tuner_ops,
+			&adap->fe[0]->ops.tuner_ops,
+			sizeof(struct dvb_tuner_ops));
+
+		if (dvb_register_frontend(&adap->dvb_adap, adap->fe[1])) {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "frontend registration failed!");
+			ret = -ENODEV;
+			goto fail_frontend1;
+		}
+		/* MFE lock */
+		adap->dvb_adap.mfe_shared = 1;
+
+		if (adap->fe[1]->ops.analog_ops.standby)
+			adap->fe[1]->ops.analog_ops.standby(adap->fe[1]);
+
+		pvr2_trace(PVR2_TRACE_INFO, "transferring fe[%d] ts_bus_ctrl() to pvr2_dvb_bus_ctrl()",
+				adap->fe[1]->id);
+		adap->fe[1]->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
+	}
+done:
 	pvr2_channel_limit_inputs(&adap->channel, 0);
 	return ret;
+
+fail_frontend1:
+	dvb_frontend_detach(adap->fe[1]);
+	adap->fe[1] = NULL;
+fail_tuner:
+	dvb_unregister_frontend(adap->fe[0]);
+fail_frontend0:
+	dvb_frontend_detach(adap->fe[0]);
+	adap->fe[0] = NULL;
+
+	return ret;
 }
 
 static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap)
 {
-	if (adap->fe != NULL) {
-		dvb_unregister_frontend(adap->fe);
-		dvb_frontend_detach(adap->fe);
+	if (adap->fe[1]) {
+		dvb_unregister_frontend(adap->fe[1]);
+		dvb_frontend_detach(adap->fe[1]);
+		adap->fe[1] = NULL;
+	}
+	if (adap->fe[0]) {
+		dvb_unregister_frontend(adap->fe[0]);
+		dvb_frontend_detach(adap->fe[0]);
+		adap->fe[0] = NULL;
 	}
 	return 0;
 }
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
index e7f71fb..91bff57 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
@@ -18,7 +18,7 @@ struct pvr2_dvb_adapter {
 	struct dmxdev		dmxdev;
 	struct dvb_demux	demux;
 	struct dvb_net		dvb_net;
-	struct dvb_frontend	*fe;
+	struct dvb_frontend	*fe[2];
 
 	int			feedcount;
 	int			max_feed_count;
-- 
2.7.4


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

* [PATCH v3 3/4] pvrusb2: Add i2c client demod/tuner support
  2018-12-24 17:00   ` [PATCH v3 0/4] " Brad Love
  2018-12-24 17:00     ` [PATCH v3 1/4] si2157: add detection of si2177 tuner Brad Love
  2018-12-24 17:00     ` [PATCH v3 2/4] pvrusb2: Add multiple dvb frontend support Brad Love
@ 2018-12-24 17:00     ` Brad Love
  2018-12-24 17:00     ` [PATCH v3 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
  3 siblings, 0 replies; 36+ messages in thread
From: Brad Love @ 2018-12-24 17:00 UTC (permalink / raw)
  To: linux-media, mchehab; +Cc: Brad Love

Cleanup code has been added to init in case of failure,
as well as to frontend exit.

Signed-off-by: Brad Love <brad@nextdimension.cc>
---
No changes

 drivers/media/usb/pvrusb2/pvrusb2-dvb.c | 11 +++++++++++
 drivers/media/usb/pvrusb2/pvrusb2-dvb.h |  3 +++
 2 files changed, 14 insertions(+)

diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
index cb5586b..8e1735f 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
@@ -404,6 +404,9 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
 fail_frontend0:
 	dvb_frontend_detach(adap->fe[0]);
 	adap->fe[0] = NULL;
+	dvb_module_release(adap->i2c_client_tuner);
+	dvb_module_release(adap->i2c_client_demod[1]);
+	dvb_module_release(adap->i2c_client_demod[0]);
 
 	return ret;
 }
@@ -420,6 +423,14 @@ static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap)
 		dvb_frontend_detach(adap->fe[0]);
 		adap->fe[0] = NULL;
 	}
+
+	dvb_module_release(adap->i2c_client_tuner);
+	adap->i2c_client_tuner = NULL;
+	dvb_module_release(adap->i2c_client_demod[1]);
+	adap->i2c_client_demod[1] = NULL;
+	dvb_module_release(adap->i2c_client_demod[0]);
+	adap->i2c_client_demod[0] = NULL;
+
 	return 0;
 }
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
index 91bff57..c0b27f5 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
@@ -20,6 +20,9 @@ struct pvr2_dvb_adapter {
 	struct dvb_net		dvb_net;
 	struct dvb_frontend	*fe[2];
 
+	struct i2c_client	*i2c_client_demod[2];
+	struct i2c_client	*i2c_client_tuner;
+
 	int			feedcount;
 	int			max_feed_count;
 
-- 
2.7.4


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

* [PATCH v3 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices
  2018-12-24 17:00   ` [PATCH v3 0/4] " Brad Love
                       ` (2 preceding siblings ...)
  2018-12-24 17:00     ` [PATCH v3 3/4] pvrusb2: Add i2c client demod/tuner support Brad Love
@ 2018-12-24 17:00     ` Brad Love
  3 siblings, 0 replies; 36+ messages in thread
From: Brad Love @ 2018-12-24 17:00 UTC (permalink / raw)
  To: linux-media, mchehab; +Cc: Brad Love

Includes support to identify and use two Hauppauge device.
HVR-1955:
- LGDT3306a ATSC/QAM demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

HVR-1975 dual-frontend:
- LGDT3306a ATSC/QAM demod
- si2168 DVB-C/T/T2 demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

Signed-off-by: Brad Love <brad@nextdimension.cc>
---
Since v2:
- Fix build with VIDEO_PVRUSB2_DVB enabled
Changes since v1:
- Fix build with VIDEO_PVRUSB2_DVB disabled
- Insert 160xxx code lower, so 75xxx profile is not split
- Reorganize 160xxx board profile
- Share config where possible

 drivers/media/usb/pvrusb2/Kconfig               |   2 +
 drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c |  25 ++++
 drivers/media/usb/pvrusb2/pvrusb2-devattr.c     | 164 ++++++++++++++++++++++++
 drivers/media/usb/pvrusb2/pvrusb2-devattr.h     |   1 +
 drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h     |   4 +
 drivers/media/usb/pvrusb2/pvrusb2-hdw.c         |  36 +++++-
 6 files changed, 231 insertions(+), 1 deletion(-)

diff --git a/drivers/media/usb/pvrusb2/Kconfig b/drivers/media/usb/pvrusb2/Kconfig
index 1ad913f..144631c 100644
--- a/drivers/media/usb/pvrusb2/Kconfig
+++ b/drivers/media/usb/pvrusb2/Kconfig
@@ -40,6 +40,8 @@ config VIDEO_PVRUSB2_DVB
 	select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT
+	select DVB_LGDT3306A if MEDIA_SUBDRV_AUTOSELECT
+	select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
index d5bec0f..36016ab 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -111,10 +111,35 @@ static const struct routing_scheme routing_defav400 = {
 	.cnt = ARRAY_SIZE(routing_schemeav400),
 };
 
+static const struct routing_scheme_item routing_scheme160xxx[] = {
+	[PVR2_CVAL_INPUT_TV] = {
+		.vid = CX25840_COMPOSITE7,
+		.aud = CX25840_AUDIO8,
+	},
+	[PVR2_CVAL_INPUT_RADIO] = {
+		.vid = CX25840_COMPOSITE4,
+		.aud = CX25840_AUDIO6,
+	},
+	[PVR2_CVAL_INPUT_COMPOSITE] = {
+		.vid = CX25840_COMPOSITE3,
+		.aud = CX25840_AUDIO_SERIAL,
+	},
+	[PVR2_CVAL_INPUT_SVIDEO] = {
+		.vid = CX25840_SVIDEO1,
+		.aud = CX25840_AUDIO_SERIAL,
+	},
+};
+
+static const struct routing_scheme routing_def160xxx = {
+	.def = routing_scheme160xxx,
+	.cnt = ARRAY_SIZE(routing_scheme160xxx),
+};
+
 static const struct routing_scheme *routing_schemes[] = {
 	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
 	[PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv,
 	[PVR2_ROUTING_SCHEME_AV400] = &routing_defav400,
+	[PVR2_ROUTING_SCHEME_HAUP160XXX] = &routing_def160xxx,
 };
 
 void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
index ef36b62..97b4fc8 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
@@ -37,6 +37,9 @@ pvr2_device_desc structures.
 #include "tda18271.h"
 #include "tda8290.h"
 #include "tuner-simple.h"
+#include "si2157.h"
+#include "lgdt3306a.h"
+#include "si2168.h"
 #endif
 
 
@@ -525,7 +528,164 @@ static const struct pvr2_device_desc pvr2_device_751xx = {
 #endif
 };
 
+/*------------------------------------------------------------------------*/
+/*    Hauppauge PVR-USB2 Model 160000 / 160111 -- HVR-1955 / HVR-1975     */
+
+#ifdef CONFIG_VIDEO_PVRUSB2_DVB
+static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap);
+static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap);
+static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap);
+static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap);
+
+static const struct pvr2_dvb_props pvr2_160000_dvb_props = {
+	.frontend_attach = pvr2_dual_fe_attach,
+	.tuner_attach    = pvr2_si2157_attach,
+};
+static const struct pvr2_dvb_props pvr2_160111_dvb_props = {
+	.frontend_attach = pvr2_lgdt3306a_attach,
+	.tuner_attach    = pvr2_si2157_attach,
+};
+
+static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
+{
+	struct si2157_config si2157_config = {};
+
+	si2157_config.inversion = 1;
+	si2157_config.fe = adap->fe[0];
+
+	adap->i2c_client_tuner = dvb_module_probe("si2157", "si2177",
+						&adap->channel.hdw->i2c_adap,
+						0x60, &si2157_config);
+
+	if (!adap->i2c_client_tuner)
+		return -ENODEV;
+
+	return 0;
+}
+
+static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap)
+{
+	struct si2168_config si2168_config = {};
+	struct i2c_adapter *adapter;
+
+	pr_debug("%s()\n", __func__);
+
+	si2168_config.fe = &adap->fe[1];
+	si2168_config.i2c_adapter = &adapter;
+	si2168_config.ts_mode = SI2168_TS_PARALLEL; /*2, 1-serial, 2-parallel.*/
+	si2168_config.ts_clock_gapped = 1; /*0-disabled, 1-enabled.*/
+	si2168_config.ts_clock_inv = 0; /*0-not-invert, 1-invert*/
+	si2168_config.spectral_inversion = 1; /*0-not-invert, 1-invert*/
+
+	adap->i2c_client_demod[1] = dvb_module_probe("si2168", NULL,
+						&adap->channel.hdw->i2c_adap,
+						0x64, &si2168_config);
 
+	if (!adap->i2c_client_demod[1])
+		return -ENODEV;
+
+	return 0;
+}
+
+static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
+{
+	struct lgdt3306a_config lgdt3306a_config;
+	struct i2c_adapter *adapter;
+
+	pr_debug("%s()\n", __func__);
+
+	lgdt3306a_config.fe = &adap->fe[0];
+	lgdt3306a_config.i2c_adapter = &adapter;
+	lgdt3306a_config.deny_i2c_rptr = 1;
+	lgdt3306a_config.spectral_inversion = 1;
+	lgdt3306a_config.qam_if_khz = 4000;
+	lgdt3306a_config.vsb_if_khz = 3250;
+	lgdt3306a_config.mpeg_mode = LGDT3306A_MPEG_PARALLEL;
+	lgdt3306a_config.tpclk_edge = LGDT3306A_TPCLK_FALLING_EDGE;
+	lgdt3306a_config.tpvalid_polarity = LGDT3306A_TP_VALID_LOW;
+	lgdt3306a_config.xtalMHz = 25, /* demod clock MHz; 24/25 supported */
+
+	adap->i2c_client_demod[0] = dvb_module_probe("lgdt3306a", NULL,
+						&adap->channel.hdw->i2c_adap,
+						0x59, &lgdt3306a_config);
+
+	if (!adap->i2c_client_demod[0])
+		return -ENODEV;
+
+	return 0;
+}
+
+static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap)
+{
+	pr_debug("%s()\n", __func__);
+
+	if (pvr2_lgdt3306a_attach(adap) != 0)
+		return -ENODEV;
+
+	if (pvr2_si2168_attach(adap) != 0) {
+		dvb_module_release(adap->i2c_client_demod[0]);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+#endif
+
+#define PVR2_FIRMWARE_160xxx "v4l-pvrusb2-160xxx-01.fw"
+static const char *pvr2_fw1_names_160xxx[] = {
+		PVR2_FIRMWARE_160xxx,
+};
+
+static const struct pvr2_device_client_desc pvr2_cli_160xxx[] = {
+	{ .module_id = PVR2_CLIENT_ID_CX25840 },
+};
+
+static const struct pvr2_device_desc pvr2_device_160000 = {
+		.description = "WinTV HVR-1975 Model 160000",
+		.shortname = "160000",
+		.client_table.lst = pvr2_cli_160xxx,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160xxx),
+		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
+		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
+		.default_tuner_type = TUNER_ABSENT,
+		.flag_has_cx25840 = !0,
+		.flag_has_hauppauge_rom = !0,
+		.flag_has_analogtuner = !0,
+		.flag_has_composite = !0,
+		.flag_has_svideo = !0,
+		.flag_fx2_16kb = !0,
+		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
+		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
+		.default_std_mask = V4L2_STD_NTSC_M,
+		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
+#ifdef CONFIG_VIDEO_PVRUSB2_DVB
+		.dvb_props = &pvr2_160000_dvb_props,
+#endif
+};
+static const struct pvr2_device_desc pvr2_device_160111 = {
+		.description = "WinTV HVR-1955 Model 160111",
+		.shortname = "160111",
+		.client_table.lst = pvr2_cli_160xxx,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160xxx),
+		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
+		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
+		.default_tuner_type = TUNER_ABSENT,
+		.flag_has_cx25840 = !0,
+		.flag_has_hauppauge_rom = !0,
+		.flag_has_analogtuner = !0,
+		.flag_has_composite = !0,
+		.flag_has_svideo = !0,
+		.flag_fx2_16kb = !0,
+		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
+		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
+		.default_std_mask = V4L2_STD_NTSC_M,
+		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
+#ifdef CONFIG_VIDEO_PVRUSB2_DVB
+		.dvb_props = &pvr2_160111_dvb_props,
+#endif
+};
 
 /*------------------------------------------------------------------------*/
 
@@ -552,6 +712,10 @@ struct usb_device_id pvr2_device_table[] = {
 	  .driver_info = (kernel_ulong_t)&pvr2_device_751xx},
 	{ USB_DEVICE(0x0ccd, 0x0039),
 	  .driver_info = (kernel_ulong_t)&pvr2_device_av400},
+	{ USB_DEVICE(0x2040, 0x7502),
+	  .driver_info = (kernel_ulong_t)&pvr2_device_160111},
+	{ USB_DEVICE(0x2040, 0x7510),
+	  .driver_info = (kernel_ulong_t)&pvr2_device_160000},
 	{ }
 };
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.h b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
index c1e7d48..ea0b2bf 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
@@ -66,6 +66,7 @@ struct pvr2_string_table {
 #define PVR2_ROUTING_SCHEME_GOTVIEW 1
 #define PVR2_ROUTING_SCHEME_ONAIR 2
 #define PVR2_ROUTING_SCHEME_AV400 3
+#define PVR2_ROUTING_SCHEME_HAUP160XXX 4
 
 #define PVR2_DIGITAL_SCHEME_NONE 0
 #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
index 0a01de4..640b033 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
@@ -38,6 +38,10 @@
 
 #define FX2CMD_FWPOST1          0x52u
 
+/* These 2 only exist on Model 160xxx */
+#define FX2CMD_HCW_DEMOD_RESET_PIN 0xd4u
+#define FX2CMD_HCW_MAKO_SLEEP_PIN  0xd5u
+
 #define FX2CMD_POWER_OFF        0xdcu
 #define FX2CMD_POWER_ON         0xdeu
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
index 446a999..ab9e822 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
@@ -316,6 +316,8 @@ static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = {
 	{FX2CMD_ONAIR_DTV_STREAMING_OFF, "onair dtv stream off"},
 	{FX2CMD_ONAIR_DTV_POWER_ON, "onair dtv power on"},
 	{FX2CMD_ONAIR_DTV_POWER_OFF, "onair dtv power off"},
+	{FX2CMD_HCW_DEMOD_RESET_PIN, "hcw demod reset pin"},
+	{FX2CMD_HCW_MAKO_SLEEP_PIN, "hcw mako sleep pin"},
 };
 
 
@@ -2137,10 +2139,28 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
 				      ((0) << 16));
 	}
 
-	// This step MUST happen after the earlier powerup step.
+	/* This step MUST happen after the earlier powerup step */
 	pvr2_i2c_core_init(hdw);
 	if (!pvr2_hdw_dev_ok(hdw)) return;
 
+	/* Reset demod only on Hauppauge 160xxx platform */
+	if (hdw->usb_dev->descriptor.idVendor == 0x2040 &&
+	    (hdw->usb_dev->descriptor.idProduct == 0x7502 ||
+	     hdw->usb_dev->descriptor.idProduct == 0x7510)) {
+		pr_info("%s(): resetting 160xxx demod\n", __func__);
+		/* TODO: not sure this is proper place to reset once only */
+		pvr2_issue_simple_cmd(hdw,
+				     FX2CMD_HCW_DEMOD_RESET_PIN |
+				     (1 << 8) |
+				     ((0) << 16));
+		msleep(10);
+		pvr2_issue_simple_cmd(hdw,
+				     FX2CMD_HCW_DEMOD_RESET_PIN |
+				     (1 << 8) |
+				     ((1) << 16));
+		msleep(10);
+	}
+
 	pvr2_hdw_load_modules(hdw);
 	if (!pvr2_hdw_dev_ok(hdw)) return;
 
@@ -4011,6 +4031,20 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
 static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff)
 {
 	hdw->flag_ok = !0;
+
+	/* Use this for Hauppauge 160xxx only */
+	if (hdw->usb_dev->descriptor.idVendor == 0x2040 &&
+	    (hdw->usb_dev->descriptor.idProduct == 0x7502 ||
+	     hdw->usb_dev->descriptor.idProduct == 0x7510)) {
+		pr_debug("%s(): resetting demod on Hauppauge 160xxx platform skipped\n",
+			__func__);
+		/* Can't reset 160xxx or it will trash Demod tristate */
+		return pvr2_issue_simple_cmd(hdw,
+				     FX2CMD_HCW_MAKO_SLEEP_PIN |
+				     (1 << 8) |
+				     ((onoff ? 1 : 0) << 16));
+	}
+
 	return pvr2_issue_simple_cmd(hdw,
 				     FX2CMD_HCW_DEMOD_RESETIN |
 				     (1 << 8) |
-- 
2.7.4


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

* Re: [PATCH 1/4] si2157: add detection of si2177 tuner
  2018-12-20 21:57 ` [PATCH 1/4] si2157: add detection of si2177 tuner Brad Love
@ 2019-01-09 17:36   ` Antti Palosaari
  2019-01-15 16:32     ` Brad Love
  0 siblings, 1 reply; 36+ messages in thread
From: Antti Palosaari @ 2019-01-09 17:36 UTC (permalink / raw)
  To: Brad Love, linux-media, mchehab

On 12/20/18 11:57 PM, Brad Love wrote:
> Works in ATSC and QAM as is, DVB is completely untested.
> 
> Firmware required.
> 
> Signed-off-by: Brad Love <brad@nextdimension.cc>
> ---
>   drivers/media/tuners/si2157.c      | 6 ++++++
>   drivers/media/tuners/si2157_priv.h | 3 ++-


>   #define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"
>   #define SI2141_A10_FIRMWARE "dvb-tuner-si2141-a10-01.fw"
> -
> +#define SI2157_A30_FIRMWARE "dvb-tuner-si2157-a30-05.fw"

Why you added 05 to that file name? I added that spare number for cases 
you have to replace firmware to another for some reason thus by default 
case it should be 01.

regards
Antti

-- 
http://palosaari.fi/

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

* Re: [PATCH 1/4] si2157: add detection of si2177 tuner
  2019-01-09 17:36   ` Antti Palosaari
@ 2019-01-15 16:32     ` Brad Love
  2019-01-15 17:23       ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 36+ messages in thread
From: Brad Love @ 2019-01-15 16:32 UTC (permalink / raw)
  To: Antti Palosaari, Brad Love, linux-media, mchehab

Hi Antti,


On 09/01/2019 11.36, Antti Palosaari wrote:
> On 12/20/18 11:57 PM, Brad Love wrote:
>> Works in ATSC and QAM as is, DVB is completely untested.
>>
>> Firmware required.
>>
>> Signed-off-by: Brad Love <brad@nextdimension.cc>
>> ---
>>   drivers/media/tuners/si2157.c      | 6 ++++++
>>   drivers/media/tuners/si2157_priv.h | 3 ++-
>
>
>>   #define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"
>>   #define SI2141_A10_FIRMWARE "dvb-tuner-si2141-a10-01.fw"
>> -
>> +#define SI2157_A30_FIRMWARE "dvb-tuner-si2157-a30-05.fw"
>
> Why you added 05 to that file name? I added that spare number for
> cases you have to replace firmware to another for some reason thus by
> default case it should be 01.
>

Barring any explanation of the naming convention, I made it look similar
to the previous two, while reflecting the firmware version. This is
firmware 3.0.5. I have no problem "starting from 1", but reflecting the
firmware version seemed like the sane idea. I'll resubmit if desired.

Regards,

Brad





> regards
> Antti
>

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

* Re: [PATCH 1/4] si2157: add detection of si2177 tuner
  2019-01-15 16:32     ` Brad Love
@ 2019-01-15 17:23       ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 36+ messages in thread
From: Mauro Carvalho Chehab @ 2019-01-15 17:23 UTC (permalink / raw)
  To: Antti Palosaari; +Cc: Brad Love, linux-media

Em Tue, 15 Jan 2019 10:32:01 -0600
Brad Love <brad@nextdimension.cc> escreveu:

> Hi Antti,
> 
> 
> On 09/01/2019 11.36, Antti Palosaari wrote:
> > On 12/20/18 11:57 PM, Brad Love wrote:  
> >> Works in ATSC and QAM as is, DVB is completely untested.
> >>
> >> Firmware required.
> >>
> >> Signed-off-by: Brad Love <brad@nextdimension.cc>
> >> ---
> >>   drivers/media/tuners/si2157.c      | 6 ++++++
> >>   drivers/media/tuners/si2157_priv.h | 3 ++-  
> >
> >  
> >>   #define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"
> >>   #define SI2141_A10_FIRMWARE "dvb-tuner-si2141-a10-01.fw"
> >> -
> >> +#define SI2157_A30_FIRMWARE "dvb-tuner-si2157-a30-05.fw"  
> >
> > Why you added 05 to that file name? I added that spare number for
> > cases you have to replace firmware to another for some reason thus by
> > default case it should be 01.
> >  
> 
> Barring any explanation of the naming convention, I made it look similar
> to the previous two, while reflecting the firmware version. This is
> firmware 3.0.5. I have no problem "starting from 1", but reflecting the
> firmware version seemed like the sane idea. I'll resubmit if desired.

Hi Antti,

Whatever firmware name convention policy you decide works for me, but
it would be really cool if you could send a patch ading a comment just
before the firmware naming macros documenting it, as it would avoid 
further discussions and patch resubmissions ;-)

Thanks,
Mauro

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

* [PATCH v4 0/4] Add Hauppauge HVR1955/1975 devices
  2018-12-21 19:40 ` [PATCH v2 0/4] " Brad Love
                     ` (4 preceding siblings ...)
  2018-12-24 17:00   ` [PATCH v3 0/4] " Brad Love
@ 2019-02-27 19:16   ` " Brad Love
  2019-02-27 19:16     ` [PATCH v4 1/4] si2157: add detection of si2177 tuner Brad Love
                       ` (3 more replies)
  5 siblings, 4 replies; 36+ messages in thread
From: Brad Love @ 2019-02-27 19:16 UTC (permalink / raw)
  To: linux-media; +Cc: Brad Love

Hauppauge device HVR1955 and HVR1975 are old Cypress based
devices. When originally produced the demods were lacking
upstream drivers and the tuner was unsupported. Well fast
forward to now and the only thing missing is the identification
of si2177 tuner in the si2157 driver, as well as extension
of the pvrusb2 driver to accomodate i2c client devices
and multiple frontends. This series addresses what is necessary.

QAM/ATSC are fully tested and work, the DVB tuning
*should* work, but is completely untested. Both demod
drivers are compatible with multiple frontend usage due
to previous patches I've submitted, so things should
work in pvrusb2 as well.

Composite video input is tested. Unable to test s-video,
but it should work. Radio is fully untested. Analog TV is
a work in progress, coming soon.

HVR-1955:
- LGDT3306a ATSC/QAM demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

HVR-1975 dual-frontend:
- LGDT3306a ATSC/QAM demod
- si2168 DVB-C/T/T2 demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

Since v3:
- Fix firmware name to be consistent
Since v2:
- Patch 4/4 build fix
Changes since v1:
- Patch 4/4 build fixes and reorganization


Brad Love (4):
  si2157: add detection of si2177 tuner
  pvrusb2: Add multiple dvb frontend support
  pvrusb2: Add i2c client demod/tuner support
  pvrusb2: Add Hauppauge HVR1955/1975 devices

 drivers/media/tuners/si2157.c                   |   6 +
 drivers/media/tuners/si2157_priv.h              |   3 +-
 drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c |  25 +++
 drivers/media/usb/pvrusb2/pvrusb2-devattr.c     | 202 +++++++++++++++++++++---
 drivers/media/usb/pvrusb2/pvrusb2-devattr.h     |   1 +
 drivers/media/usb/pvrusb2/pvrusb2-dvb.c         |  88 ++++++++---
 drivers/media/usb/pvrusb2/pvrusb2-dvb.h         |   5 +-
 drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h     |   4 +
 drivers/media/usb/pvrusb2/pvrusb2-hdw.c         |  36 ++++-
 9 files changed, 330 insertions(+), 40 deletions(-)

-- 
2.7.4


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

* [PATCH v4 1/4] si2157: add detection of si2177 tuner
  2019-02-27 19:16   ` [PATCH v4 0/4] " Brad Love
@ 2019-02-27 19:16     ` Brad Love
  2019-02-27 19:16     ` [PATCH v4 2/4] pvrusb2: Add multiple dvb frontend support Brad Love
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 36+ messages in thread
From: Brad Love @ 2019-02-27 19:16 UTC (permalink / raw)
  To: linux-media; +Cc: Brad Love

Works in ATSC and QAM as is, DVB is completely untested.

Firmware required.

Signed-off-by: Brad Love <brad@nextdimension.cc>
---
Changes since v3:
- Fix firmware name to be consistent

 drivers/media/tuners/si2157.c      | 6 ++++++
 drivers/media/tuners/si2157_priv.h | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index d389f1f..3d21af5 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -138,6 +138,7 @@ static int si2157_init(struct dvb_frontend *fe)
 	chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
 			cmd.args[4] << 0;
 
+	#define SI2177_A30 ('A' << 24 | 77 << 16 | '3' << 8 | '0' << 0)
 	#define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
 	#define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0)
 	#define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
@@ -153,6 +154,9 @@ static int si2157_init(struct dvb_frontend *fe)
 	case SI2141_A10:
 		fw_name = SI2141_A10_FIRMWARE;
 		break;
+	case SI2177_A30:
+		fw_name = SI2157_A30_FIRMWARE;
+		break;
 	case SI2157_A30:
 	case SI2147_A30:
 	case SI2146_A10:
@@ -529,6 +533,7 @@ static const struct i2c_device_id si2157_id_table[] = {
 	{"si2157", SI2157_CHIPTYPE_SI2157},
 	{"si2146", SI2157_CHIPTYPE_SI2146},
 	{"si2141", SI2157_CHIPTYPE_SI2141},
+	{"si2177", SI2157_CHIPTYPE_SI2177},
 	{}
 };
 MODULE_DEVICE_TABLE(i2c, si2157_id_table);
@@ -550,3 +555,4 @@ MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 MODULE_LICENSE("GPL");
 MODULE_FIRMWARE(SI2158_A20_FIRMWARE);
 MODULE_FIRMWARE(SI2141_A10_FIRMWARE);
+MODULE_FIRMWARE(SI2157_A30_FIRMWARE);
diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h
index 50f8630..67caee5 100644
--- a/drivers/media/tuners/si2157_priv.h
+++ b/drivers/media/tuners/si2157_priv.h
@@ -50,6 +50,7 @@ struct si2157_dev {
 #define SI2157_CHIPTYPE_SI2157 0
 #define SI2157_CHIPTYPE_SI2146 1
 #define SI2157_CHIPTYPE_SI2141 2
+#define SI2157_CHIPTYPE_SI2177 3
 
 /* firmware command struct */
 #define SI2157_ARGLEN      30
@@ -61,5 +62,5 @@ struct si2157_cmd {
 
 #define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"
 #define SI2141_A10_FIRMWARE "dvb-tuner-si2141-a10-01.fw"
-
+#define SI2157_A30_FIRMWARE "dvb-tuner-si2157-a30-01.fw"
 #endif
-- 
2.7.4


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

* [PATCH v4 2/4] pvrusb2: Add multiple dvb frontend support
  2019-02-27 19:16   ` [PATCH v4 0/4] " Brad Love
  2019-02-27 19:16     ` [PATCH v4 1/4] si2157: add detection of si2177 tuner Brad Love
@ 2019-02-27 19:16     ` Brad Love
  2019-04-05 10:00       ` Sean Young
  2019-02-27 19:16     ` [PATCH v4 3/4] pvrusb2: Add i2c client demod/tuner support Brad Love
  2019-02-27 19:16     ` [PATCH v4 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
  3 siblings, 1 reply; 36+ messages in thread
From: Brad Love @ 2019-02-27 19:16 UTC (permalink / raw)
  To: linux-media; +Cc: Brad Love

All changes are equivalent and backwards compatible.
All current devices have been changed to use fe[0]
Cleanup has been added to dvb init to support cleanup after failure.

Signed-off-by: Brad Love <brad@nextdimension.cc>
---
No changes

 drivers/media/usb/pvrusb2/pvrusb2-devattr.c | 36 +++++++-------
 drivers/media/usb/pvrusb2/pvrusb2-dvb.c     | 77 ++++++++++++++++++++++-------
 drivers/media/usb/pvrusb2/pvrusb2-dvb.h     |  2 +-
 3 files changed, 77 insertions(+), 38 deletions(-)

diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
index 06de1c8..ef36b62 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
@@ -188,10 +188,10 @@ static struct lgdt330x_config pvr2_lgdt3303_config = {
 
 static int pvr2_lgdt3303_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3303_config,
-			      0x0e,
-			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	adap->fe[0] = dvb_attach(lgdt330x_attach, &pvr2_lgdt3303_config,
+				 0x0e,
+				 &adap->channel.hdw->i2c_adap);
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -199,7 +199,7 @@ static int pvr2_lgdt3303_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_lgh06xf_attach(struct pvr2_dvb_adapter *adap)
 {
-	dvb_attach(simple_tuner_attach, adap->fe,
+	dvb_attach(simple_tuner_attach, adap->fe[0],
 		   &adap->channel.hdw->i2c_adap, 0x61,
 		   TUNER_LG_TDVS_H06XF);
 
@@ -248,10 +248,10 @@ static struct lgdt330x_config pvr2_lgdt3302_config = {
 
 static int pvr2_lgdt3302_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3302_config,
+	adap->fe[0] = dvb_attach(lgdt330x_attach, &pvr2_lgdt3302_config,
 			      0x0e,
 			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -259,7 +259,7 @@ static int pvr2_lgdt3302_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_fcv1236d_attach(struct pvr2_dvb_adapter *adap)
 {
-	dvb_attach(simple_tuner_attach, adap->fe,
+	dvb_attach(simple_tuner_attach, adap->fe[0],
 		   &adap->channel.hdw->i2c_adap, 0x61,
 		   TUNER_PHILIPS_FCV1236D);
 
@@ -335,9 +335,9 @@ static struct tda18271_config hauppauge_tda18271_dvb_config = {
 
 static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(tda10048_attach, &hauppauge_tda10048_config,
+	adap->fe[0] = dvb_attach(tda10048_attach, &hauppauge_tda10048_config,
 			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -345,10 +345,10 @@ static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_73xxx_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
 {
-	dvb_attach(tda829x_attach, adap->fe,
+	dvb_attach(tda829x_attach, adap->fe[0],
 		   &adap->channel.hdw->i2c_adap, 0x42,
 		   &tda829x_no_probe);
-	dvb_attach(tda18271_attach, adap->fe, 0x60,
+	dvb_attach(tda18271_attach, adap->fe[0], 0x60,
 		   &adap->channel.hdw->i2c_adap,
 		   &hauppauge_tda18271_dvb_config);
 
@@ -433,9 +433,9 @@ static struct tda18271_config hauppauge_tda18271_config = {
 
 static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(s5h1409_attach, &pvr2_s5h1409_config,
+	adap->fe[0] = dvb_attach(s5h1409_attach, &pvr2_s5h1409_config,
 			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -443,9 +443,9 @@ static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_s5h1411_attach(struct pvr2_dvb_adapter *adap)
 {
-	adap->fe = dvb_attach(s5h1411_attach, &pvr2_s5h1411_config,
+	adap->fe[0] = dvb_attach(s5h1411_attach, &pvr2_s5h1411_config,
 			      &adap->channel.hdw->i2c_adap);
-	if (adap->fe)
+	if (adap->fe[0])
 		return 0;
 
 	return -EIO;
@@ -453,10 +453,10 @@ static int pvr2_s5h1411_attach(struct pvr2_dvb_adapter *adap)
 
 static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
 {
-	dvb_attach(tda829x_attach, adap->fe,
+	dvb_attach(tda829x_attach, adap->fe[0],
 		   &adap->channel.hdw->i2c_adap, 0x42,
 		   &tda829x_no_probe);
-	dvb_attach(tda18271_attach, adap->fe, 0x60,
+	dvb_attach(tda18271_attach, adap->fe[0], 0x60,
 		   &adap->channel.hdw->i2c_adap,
 		   &hauppauge_tda18271_config);
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
index 4b32b21..cb5586b 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
@@ -343,26 +343,19 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
 		goto done;
 	}
 
-	if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) {
-
-		if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
+	if (dvb_props->frontend_attach(adap) == 0 && adap->fe[0]) {
+		if (dvb_register_frontend(&adap->dvb_adap, adap->fe[0])) {
 			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 				   "frontend registration failed!");
-			dvb_frontend_detach(adap->fe);
-			adap->fe = NULL;
 			ret = -ENODEV;
-			goto done;
+			goto fail_frontend0;
 		}
+		if (adap->fe[0]->ops.analog_ops.standby)
+			adap->fe[0]->ops.analog_ops.standby(adap->fe[0]);
 
-		if (dvb_props->tuner_attach)
-			dvb_props->tuner_attach(adap);
-
-		if (adap->fe->ops.analog_ops.standby)
-			adap->fe->ops.analog_ops.standby(adap->fe);
-
-		/* Ensure all frontends negotiate bus access */
-		adap->fe->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
-
+		pvr2_trace(PVR2_TRACE_INFO, "transferring fe[%d] ts_bus_ctrl() to pvr2_dvb_bus_ctrl()",
+				adap->fe[0]->id);
+		adap->fe[0]->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
 	} else {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 			   "no frontend was attached!");
@@ -370,16 +363,62 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
 		return ret;
 	}
 
- done:
+	if (dvb_props->tuner_attach && dvb_props->tuner_attach(adap)) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS, "tuner attach failed");
+		ret = -ENODEV;
+		goto fail_tuner;
+	}
+
+	if (adap->fe[1]) {
+		adap->fe[1]->id = 1;
+		adap->fe[1]->tuner_priv = adap->fe[0]->tuner_priv;
+		memcpy(&adap->fe[1]->ops.tuner_ops,
+			&adap->fe[0]->ops.tuner_ops,
+			sizeof(struct dvb_tuner_ops));
+
+		if (dvb_register_frontend(&adap->dvb_adap, adap->fe[1])) {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "frontend registration failed!");
+			ret = -ENODEV;
+			goto fail_frontend1;
+		}
+		/* MFE lock */
+		adap->dvb_adap.mfe_shared = 1;
+
+		if (adap->fe[1]->ops.analog_ops.standby)
+			adap->fe[1]->ops.analog_ops.standby(adap->fe[1]);
+
+		pvr2_trace(PVR2_TRACE_INFO, "transferring fe[%d] ts_bus_ctrl() to pvr2_dvb_bus_ctrl()",
+				adap->fe[1]->id);
+		adap->fe[1]->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
+	}
+done:
 	pvr2_channel_limit_inputs(&adap->channel, 0);
 	return ret;
+
+fail_frontend1:
+	dvb_frontend_detach(adap->fe[1]);
+	adap->fe[1] = NULL;
+fail_tuner:
+	dvb_unregister_frontend(adap->fe[0]);
+fail_frontend0:
+	dvb_frontend_detach(adap->fe[0]);
+	adap->fe[0] = NULL;
+
+	return ret;
 }
 
 static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap)
 {
-	if (adap->fe != NULL) {
-		dvb_unregister_frontend(adap->fe);
-		dvb_frontend_detach(adap->fe);
+	if (adap->fe[1]) {
+		dvb_unregister_frontend(adap->fe[1]);
+		dvb_frontend_detach(adap->fe[1]);
+		adap->fe[1] = NULL;
+	}
+	if (adap->fe[0]) {
+		dvb_unregister_frontend(adap->fe[0]);
+		dvb_frontend_detach(adap->fe[0]);
+		adap->fe[0] = NULL;
 	}
 	return 0;
 }
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
index e7f71fb..91bff57 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
@@ -18,7 +18,7 @@ struct pvr2_dvb_adapter {
 	struct dmxdev		dmxdev;
 	struct dvb_demux	demux;
 	struct dvb_net		dvb_net;
-	struct dvb_frontend	*fe;
+	struct dvb_frontend	*fe[2];
 
 	int			feedcount;
 	int			max_feed_count;
-- 
2.7.4


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

* [PATCH v4 3/4] pvrusb2: Add i2c client demod/tuner support
  2019-02-27 19:16   ` [PATCH v4 0/4] " Brad Love
  2019-02-27 19:16     ` [PATCH v4 1/4] si2157: add detection of si2177 tuner Brad Love
  2019-02-27 19:16     ` [PATCH v4 2/4] pvrusb2: Add multiple dvb frontend support Brad Love
@ 2019-02-27 19:16     ` Brad Love
  2019-02-27 19:16     ` [PATCH v4 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
  3 siblings, 0 replies; 36+ messages in thread
From: Brad Love @ 2019-02-27 19:16 UTC (permalink / raw)
  To: linux-media; +Cc: Brad Love

Cleanup code has been added to init in case of failure,
as well as to frontend exit.

Signed-off-by: Brad Love <brad@nextdimension.cc>
---
No changes

 drivers/media/usb/pvrusb2/pvrusb2-dvb.c | 11 +++++++++++
 drivers/media/usb/pvrusb2/pvrusb2-dvb.h |  3 +++
 2 files changed, 14 insertions(+)

diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
index cb5586b..8e1735f 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
@@ -404,6 +404,9 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
 fail_frontend0:
 	dvb_frontend_detach(adap->fe[0]);
 	adap->fe[0] = NULL;
+	dvb_module_release(adap->i2c_client_tuner);
+	dvb_module_release(adap->i2c_client_demod[1]);
+	dvb_module_release(adap->i2c_client_demod[0]);
 
 	return ret;
 }
@@ -420,6 +423,14 @@ static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap)
 		dvb_frontend_detach(adap->fe[0]);
 		adap->fe[0] = NULL;
 	}
+
+	dvb_module_release(adap->i2c_client_tuner);
+	adap->i2c_client_tuner = NULL;
+	dvb_module_release(adap->i2c_client_demod[1]);
+	adap->i2c_client_demod[1] = NULL;
+	dvb_module_release(adap->i2c_client_demod[0]);
+	adap->i2c_client_demod[0] = NULL;
+
 	return 0;
 }
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
index 91bff57..c0b27f5 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
@@ -20,6 +20,9 @@ struct pvr2_dvb_adapter {
 	struct dvb_net		dvb_net;
 	struct dvb_frontend	*fe[2];
 
+	struct i2c_client	*i2c_client_demod[2];
+	struct i2c_client	*i2c_client_tuner;
+
 	int			feedcount;
 	int			max_feed_count;
 
-- 
2.7.4


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

* [PATCH v4 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices
  2019-02-27 19:16   ` [PATCH v4 0/4] " Brad Love
                       ` (2 preceding siblings ...)
  2019-02-27 19:16     ` [PATCH v4 3/4] pvrusb2: Add i2c client demod/tuner support Brad Love
@ 2019-02-27 19:16     ` Brad Love
  2019-04-05 15:24       ` Sean Young
  3 siblings, 1 reply; 36+ messages in thread
From: Brad Love @ 2019-02-27 19:16 UTC (permalink / raw)
  To: linux-media; +Cc: Brad Love

Includes support to identify and use two Hauppauge device.
HVR-1955:
- LGDT3306a ATSC/QAM demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

HVR-1975 dual-frontend:
- LGDT3306a ATSC/QAM demod
- si2168 DVB-C/T/T2 demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

Signed-off-by: Brad Love <brad@nextdimension.cc>
---
Since v2:
- Fix build with VIDEO_PVRUSB2_DVB enabled
Changes since v1:
- Fix build with VIDEO_PVRUSB2_DVB disabled
- Insert 160xxx code lower, so 75xxx profile is not split
- Reorganize 160xxx board profile
- Share config where possible

 drivers/media/usb/pvrusb2/Kconfig               |   2 +
 drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c |  25 ++++
 drivers/media/usb/pvrusb2/pvrusb2-devattr.c     | 164 ++++++++++++++++++++++++
 drivers/media/usb/pvrusb2/pvrusb2-devattr.h     |   1 +
 drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h     |   4 +
 drivers/media/usb/pvrusb2/pvrusb2-hdw.c         |  36 +++++-
 6 files changed, 231 insertions(+), 1 deletion(-)

diff --git a/drivers/media/usb/pvrusb2/Kconfig b/drivers/media/usb/pvrusb2/Kconfig
index 1ad913f..144631c 100644
--- a/drivers/media/usb/pvrusb2/Kconfig
+++ b/drivers/media/usb/pvrusb2/Kconfig
@@ -40,6 +40,8 @@ config VIDEO_PVRUSB2_DVB
 	select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT
+	select DVB_LGDT3306A if MEDIA_SUBDRV_AUTOSELECT
+	select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
index d5bec0f..36016ab 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -111,10 +111,35 @@ static const struct routing_scheme routing_defav400 = {
 	.cnt = ARRAY_SIZE(routing_schemeav400),
 };
 
+static const struct routing_scheme_item routing_scheme160xxx[] = {
+	[PVR2_CVAL_INPUT_TV] = {
+		.vid = CX25840_COMPOSITE7,
+		.aud = CX25840_AUDIO8,
+	},
+	[PVR2_CVAL_INPUT_RADIO] = {
+		.vid = CX25840_COMPOSITE4,
+		.aud = CX25840_AUDIO6,
+	},
+	[PVR2_CVAL_INPUT_COMPOSITE] = {
+		.vid = CX25840_COMPOSITE3,
+		.aud = CX25840_AUDIO_SERIAL,
+	},
+	[PVR2_CVAL_INPUT_SVIDEO] = {
+		.vid = CX25840_SVIDEO1,
+		.aud = CX25840_AUDIO_SERIAL,
+	},
+};
+
+static const struct routing_scheme routing_def160xxx = {
+	.def = routing_scheme160xxx,
+	.cnt = ARRAY_SIZE(routing_scheme160xxx),
+};
+
 static const struct routing_scheme *routing_schemes[] = {
 	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
 	[PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv,
 	[PVR2_ROUTING_SCHEME_AV400] = &routing_defav400,
+	[PVR2_ROUTING_SCHEME_HAUP160XXX] = &routing_def160xxx,
 };
 
 void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
index ef36b62..97b4fc8 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
@@ -37,6 +37,9 @@ pvr2_device_desc structures.
 #include "tda18271.h"
 #include "tda8290.h"
 #include "tuner-simple.h"
+#include "si2157.h"
+#include "lgdt3306a.h"
+#include "si2168.h"
 #endif
 
 
@@ -525,7 +528,164 @@ static const struct pvr2_device_desc pvr2_device_751xx = {
 #endif
 };
 
+/*------------------------------------------------------------------------*/
+/*    Hauppauge PVR-USB2 Model 160000 / 160111 -- HVR-1955 / HVR-1975     */
+
+#ifdef CONFIG_VIDEO_PVRUSB2_DVB
+static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap);
+static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap);
+static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap);
+static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap);
+
+static const struct pvr2_dvb_props pvr2_160000_dvb_props = {
+	.frontend_attach = pvr2_dual_fe_attach,
+	.tuner_attach    = pvr2_si2157_attach,
+};
+static const struct pvr2_dvb_props pvr2_160111_dvb_props = {
+	.frontend_attach = pvr2_lgdt3306a_attach,
+	.tuner_attach    = pvr2_si2157_attach,
+};
+
+static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
+{
+	struct si2157_config si2157_config = {};
+
+	si2157_config.inversion = 1;
+	si2157_config.fe = adap->fe[0];
+
+	adap->i2c_client_tuner = dvb_module_probe("si2157", "si2177",
+						&adap->channel.hdw->i2c_adap,
+						0x60, &si2157_config);
+
+	if (!adap->i2c_client_tuner)
+		return -ENODEV;
+
+	return 0;
+}
+
+static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap)
+{
+	struct si2168_config si2168_config = {};
+	struct i2c_adapter *adapter;
+
+	pr_debug("%s()\n", __func__);
+
+	si2168_config.fe = &adap->fe[1];
+	si2168_config.i2c_adapter = &adapter;
+	si2168_config.ts_mode = SI2168_TS_PARALLEL; /*2, 1-serial, 2-parallel.*/
+	si2168_config.ts_clock_gapped = 1; /*0-disabled, 1-enabled.*/
+	si2168_config.ts_clock_inv = 0; /*0-not-invert, 1-invert*/
+	si2168_config.spectral_inversion = 1; /*0-not-invert, 1-invert*/
+
+	adap->i2c_client_demod[1] = dvb_module_probe("si2168", NULL,
+						&adap->channel.hdw->i2c_adap,
+						0x64, &si2168_config);
 
+	if (!adap->i2c_client_demod[1])
+		return -ENODEV;
+
+	return 0;
+}
+
+static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
+{
+	struct lgdt3306a_config lgdt3306a_config;
+	struct i2c_adapter *adapter;
+
+	pr_debug("%s()\n", __func__);
+
+	lgdt3306a_config.fe = &adap->fe[0];
+	lgdt3306a_config.i2c_adapter = &adapter;
+	lgdt3306a_config.deny_i2c_rptr = 1;
+	lgdt3306a_config.spectral_inversion = 1;
+	lgdt3306a_config.qam_if_khz = 4000;
+	lgdt3306a_config.vsb_if_khz = 3250;
+	lgdt3306a_config.mpeg_mode = LGDT3306A_MPEG_PARALLEL;
+	lgdt3306a_config.tpclk_edge = LGDT3306A_TPCLK_FALLING_EDGE;
+	lgdt3306a_config.tpvalid_polarity = LGDT3306A_TP_VALID_LOW;
+	lgdt3306a_config.xtalMHz = 25, /* demod clock MHz; 24/25 supported */
+
+	adap->i2c_client_demod[0] = dvb_module_probe("lgdt3306a", NULL,
+						&adap->channel.hdw->i2c_adap,
+						0x59, &lgdt3306a_config);
+
+	if (!adap->i2c_client_demod[0])
+		return -ENODEV;
+
+	return 0;
+}
+
+static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap)
+{
+	pr_debug("%s()\n", __func__);
+
+	if (pvr2_lgdt3306a_attach(adap) != 0)
+		return -ENODEV;
+
+	if (pvr2_si2168_attach(adap) != 0) {
+		dvb_module_release(adap->i2c_client_demod[0]);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+#endif
+
+#define PVR2_FIRMWARE_160xxx "v4l-pvrusb2-160xxx-01.fw"
+static const char *pvr2_fw1_names_160xxx[] = {
+		PVR2_FIRMWARE_160xxx,
+};
+
+static const struct pvr2_device_client_desc pvr2_cli_160xxx[] = {
+	{ .module_id = PVR2_CLIENT_ID_CX25840 },
+};
+
+static const struct pvr2_device_desc pvr2_device_160000 = {
+		.description = "WinTV HVR-1975 Model 160000",
+		.shortname = "160000",
+		.client_table.lst = pvr2_cli_160xxx,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160xxx),
+		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
+		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
+		.default_tuner_type = TUNER_ABSENT,
+		.flag_has_cx25840 = !0,
+		.flag_has_hauppauge_rom = !0,
+		.flag_has_analogtuner = !0,
+		.flag_has_composite = !0,
+		.flag_has_svideo = !0,
+		.flag_fx2_16kb = !0,
+		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
+		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
+		.default_std_mask = V4L2_STD_NTSC_M,
+		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
+#ifdef CONFIG_VIDEO_PVRUSB2_DVB
+		.dvb_props = &pvr2_160000_dvb_props,
+#endif
+};
+static const struct pvr2_device_desc pvr2_device_160111 = {
+		.description = "WinTV HVR-1955 Model 160111",
+		.shortname = "160111",
+		.client_table.lst = pvr2_cli_160xxx,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160xxx),
+		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
+		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
+		.default_tuner_type = TUNER_ABSENT,
+		.flag_has_cx25840 = !0,
+		.flag_has_hauppauge_rom = !0,
+		.flag_has_analogtuner = !0,
+		.flag_has_composite = !0,
+		.flag_has_svideo = !0,
+		.flag_fx2_16kb = !0,
+		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
+		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
+		.default_std_mask = V4L2_STD_NTSC_M,
+		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
+#ifdef CONFIG_VIDEO_PVRUSB2_DVB
+		.dvb_props = &pvr2_160111_dvb_props,
+#endif
+};
 
 /*------------------------------------------------------------------------*/
 
@@ -552,6 +712,10 @@ struct usb_device_id pvr2_device_table[] = {
 	  .driver_info = (kernel_ulong_t)&pvr2_device_751xx},
 	{ USB_DEVICE(0x0ccd, 0x0039),
 	  .driver_info = (kernel_ulong_t)&pvr2_device_av400},
+	{ USB_DEVICE(0x2040, 0x7502),
+	  .driver_info = (kernel_ulong_t)&pvr2_device_160111},
+	{ USB_DEVICE(0x2040, 0x7510),
+	  .driver_info = (kernel_ulong_t)&pvr2_device_160000},
 	{ }
 };
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.h b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
index c1e7d48..ea0b2bf 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
@@ -66,6 +66,7 @@ struct pvr2_string_table {
 #define PVR2_ROUTING_SCHEME_GOTVIEW 1
 #define PVR2_ROUTING_SCHEME_ONAIR 2
 #define PVR2_ROUTING_SCHEME_AV400 3
+#define PVR2_ROUTING_SCHEME_HAUP160XXX 4
 
 #define PVR2_DIGITAL_SCHEME_NONE 0
 #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
index 0a01de4..640b033 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
@@ -38,6 +38,10 @@
 
 #define FX2CMD_FWPOST1          0x52u
 
+/* These 2 only exist on Model 160xxx */
+#define FX2CMD_HCW_DEMOD_RESET_PIN 0xd4u
+#define FX2CMD_HCW_MAKO_SLEEP_PIN  0xd5u
+
 #define FX2CMD_POWER_OFF        0xdcu
 #define FX2CMD_POWER_ON         0xdeu
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
index 446a999..ab9e822 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
@@ -316,6 +316,8 @@ static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = {
 	{FX2CMD_ONAIR_DTV_STREAMING_OFF, "onair dtv stream off"},
 	{FX2CMD_ONAIR_DTV_POWER_ON, "onair dtv power on"},
 	{FX2CMD_ONAIR_DTV_POWER_OFF, "onair dtv power off"},
+	{FX2CMD_HCW_DEMOD_RESET_PIN, "hcw demod reset pin"},
+	{FX2CMD_HCW_MAKO_SLEEP_PIN, "hcw mako sleep pin"},
 };
 
 
@@ -2137,10 +2139,28 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
 				      ((0) << 16));
 	}
 
-	// This step MUST happen after the earlier powerup step.
+	/* This step MUST happen after the earlier powerup step */
 	pvr2_i2c_core_init(hdw);
 	if (!pvr2_hdw_dev_ok(hdw)) return;
 
+	/* Reset demod only on Hauppauge 160xxx platform */
+	if (hdw->usb_dev->descriptor.idVendor == 0x2040 &&
+	    (hdw->usb_dev->descriptor.idProduct == 0x7502 ||
+	     hdw->usb_dev->descriptor.idProduct == 0x7510)) {
+		pr_info("%s(): resetting 160xxx demod\n", __func__);
+		/* TODO: not sure this is proper place to reset once only */
+		pvr2_issue_simple_cmd(hdw,
+				     FX2CMD_HCW_DEMOD_RESET_PIN |
+				     (1 << 8) |
+				     ((0) << 16));
+		msleep(10);
+		pvr2_issue_simple_cmd(hdw,
+				     FX2CMD_HCW_DEMOD_RESET_PIN |
+				     (1 << 8) |
+				     ((1) << 16));
+		msleep(10);
+	}
+
 	pvr2_hdw_load_modules(hdw);
 	if (!pvr2_hdw_dev_ok(hdw)) return;
 
@@ -4011,6 +4031,20 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
 static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff)
 {
 	hdw->flag_ok = !0;
+
+	/* Use this for Hauppauge 160xxx only */
+	if (hdw->usb_dev->descriptor.idVendor == 0x2040 &&
+	    (hdw->usb_dev->descriptor.idProduct == 0x7502 ||
+	     hdw->usb_dev->descriptor.idProduct == 0x7510)) {
+		pr_debug("%s(): resetting demod on Hauppauge 160xxx platform skipped\n",
+			__func__);
+		/* Can't reset 160xxx or it will trash Demod tristate */
+		return pvr2_issue_simple_cmd(hdw,
+				     FX2CMD_HCW_MAKO_SLEEP_PIN |
+				     (1 << 8) |
+				     ((onoff ? 1 : 0) << 16));
+	}
+
 	return pvr2_issue_simple_cmd(hdw,
 				     FX2CMD_HCW_DEMOD_RESETIN |
 				     (1 << 8) |
-- 
2.7.4


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

* Re: [PATCH v4 2/4] pvrusb2: Add multiple dvb frontend support
  2019-02-27 19:16     ` [PATCH v4 2/4] pvrusb2: Add multiple dvb frontend support Brad Love
@ 2019-04-05 10:00       ` Sean Young
  2019-04-08 18:16         ` Brad Love
  0 siblings, 1 reply; 36+ messages in thread
From: Sean Young @ 2019-04-05 10:00 UTC (permalink / raw)
  To: Brad Love; +Cc: linux-media

On Wed, Feb 27, 2019 at 01:16:04PM -0600, Brad Love wrote:
> All changes are equivalent and backwards compatible.
> All current devices have been changed to use fe[0]
> Cleanup has been added to dvb init to support cleanup after failure.

Just very minor note. Here you are adding suppport for 2 frontends, but
you're not explaining why. I would add something like "This is to add support
for Hauppauge HVR1955/1975 devices which will be done in a later commit",
to the commit message. Alternatively you could merge the two commits.


Sean

> 
> Signed-off-by: Brad Love <brad@nextdimension.cc>
> ---
> No changes
> 
>  drivers/media/usb/pvrusb2/pvrusb2-devattr.c | 36 +++++++-------
>  drivers/media/usb/pvrusb2/pvrusb2-dvb.c     | 77 ++++++++++++++++++++++-------
>  drivers/media/usb/pvrusb2/pvrusb2-dvb.h     |  2 +-
>  3 files changed, 77 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
> index 06de1c8..ef36b62 100644
> --- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
> +++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
> @@ -188,10 +188,10 @@ static struct lgdt330x_config pvr2_lgdt3303_config = {
>  
>  static int pvr2_lgdt3303_attach(struct pvr2_dvb_adapter *adap)
>  {
> -	adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3303_config,
> -			      0x0e,
> -			      &adap->channel.hdw->i2c_adap);
> -	if (adap->fe)
> +	adap->fe[0] = dvb_attach(lgdt330x_attach, &pvr2_lgdt3303_config,
> +				 0x0e,
> +				 &adap->channel.hdw->i2c_adap);
> +	if (adap->fe[0])
>  		return 0;
>  
>  	return -EIO;
> @@ -199,7 +199,7 @@ static int pvr2_lgdt3303_attach(struct pvr2_dvb_adapter *adap)
>  
>  static int pvr2_lgh06xf_attach(struct pvr2_dvb_adapter *adap)
>  {
> -	dvb_attach(simple_tuner_attach, adap->fe,
> +	dvb_attach(simple_tuner_attach, adap->fe[0],
>  		   &adap->channel.hdw->i2c_adap, 0x61,
>  		   TUNER_LG_TDVS_H06XF);
>  
> @@ -248,10 +248,10 @@ static struct lgdt330x_config pvr2_lgdt3302_config = {
>  
>  static int pvr2_lgdt3302_attach(struct pvr2_dvb_adapter *adap)
>  {
> -	adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3302_config,
> +	adap->fe[0] = dvb_attach(lgdt330x_attach, &pvr2_lgdt3302_config,
>  			      0x0e,
>  			      &adap->channel.hdw->i2c_adap);
> -	if (adap->fe)
> +	if (adap->fe[0])
>  		return 0;
>  
>  	return -EIO;
> @@ -259,7 +259,7 @@ static int pvr2_lgdt3302_attach(struct pvr2_dvb_adapter *adap)
>  
>  static int pvr2_fcv1236d_attach(struct pvr2_dvb_adapter *adap)
>  {
> -	dvb_attach(simple_tuner_attach, adap->fe,
> +	dvb_attach(simple_tuner_attach, adap->fe[0],
>  		   &adap->channel.hdw->i2c_adap, 0x61,
>  		   TUNER_PHILIPS_FCV1236D);
>  
> @@ -335,9 +335,9 @@ static struct tda18271_config hauppauge_tda18271_dvb_config = {
>  
>  static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
>  {
> -	adap->fe = dvb_attach(tda10048_attach, &hauppauge_tda10048_config,
> +	adap->fe[0] = dvb_attach(tda10048_attach, &hauppauge_tda10048_config,
>  			      &adap->channel.hdw->i2c_adap);
> -	if (adap->fe)
> +	if (adap->fe[0])
>  		return 0;
>  
>  	return -EIO;
> @@ -345,10 +345,10 @@ static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
>  
>  static int pvr2_73xxx_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
>  {
> -	dvb_attach(tda829x_attach, adap->fe,
> +	dvb_attach(tda829x_attach, adap->fe[0],
>  		   &adap->channel.hdw->i2c_adap, 0x42,
>  		   &tda829x_no_probe);
> -	dvb_attach(tda18271_attach, adap->fe, 0x60,
> +	dvb_attach(tda18271_attach, adap->fe[0], 0x60,
>  		   &adap->channel.hdw->i2c_adap,
>  		   &hauppauge_tda18271_dvb_config);
>  
> @@ -433,9 +433,9 @@ static struct tda18271_config hauppauge_tda18271_config = {
>  
>  static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
>  {
> -	adap->fe = dvb_attach(s5h1409_attach, &pvr2_s5h1409_config,
> +	adap->fe[0] = dvb_attach(s5h1409_attach, &pvr2_s5h1409_config,
>  			      &adap->channel.hdw->i2c_adap);
> -	if (adap->fe)
> +	if (adap->fe[0])
>  		return 0;
>  
>  	return -EIO;
> @@ -443,9 +443,9 @@ static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
>  
>  static int pvr2_s5h1411_attach(struct pvr2_dvb_adapter *adap)
>  {
> -	adap->fe = dvb_attach(s5h1411_attach, &pvr2_s5h1411_config,
> +	adap->fe[0] = dvb_attach(s5h1411_attach, &pvr2_s5h1411_config,
>  			      &adap->channel.hdw->i2c_adap);
> -	if (adap->fe)
> +	if (adap->fe[0])
>  		return 0;
>  
>  	return -EIO;
> @@ -453,10 +453,10 @@ static int pvr2_s5h1411_attach(struct pvr2_dvb_adapter *adap)
>  
>  static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
>  {
> -	dvb_attach(tda829x_attach, adap->fe,
> +	dvb_attach(tda829x_attach, adap->fe[0],
>  		   &adap->channel.hdw->i2c_adap, 0x42,
>  		   &tda829x_no_probe);
> -	dvb_attach(tda18271_attach, adap->fe, 0x60,
> +	dvb_attach(tda18271_attach, adap->fe[0], 0x60,
>  		   &adap->channel.hdw->i2c_adap,
>  		   &hauppauge_tda18271_config);
>  
> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
> index 4b32b21..cb5586b 100644
> --- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
> +++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
> @@ -343,26 +343,19 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
>  		goto done;
>  	}
>  
> -	if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) {
> -
> -		if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
> +	if (dvb_props->frontend_attach(adap) == 0 && adap->fe[0]) {
> +		if (dvb_register_frontend(&adap->dvb_adap, adap->fe[0])) {
>  			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
>  				   "frontend registration failed!");
> -			dvb_frontend_detach(adap->fe);
> -			adap->fe = NULL;
>  			ret = -ENODEV;
> -			goto done;
> +			goto fail_frontend0;
>  		}
> +		if (adap->fe[0]->ops.analog_ops.standby)
> +			adap->fe[0]->ops.analog_ops.standby(adap->fe[0]);
>  
> -		if (dvb_props->tuner_attach)
> -			dvb_props->tuner_attach(adap);
> -
> -		if (adap->fe->ops.analog_ops.standby)
> -			adap->fe->ops.analog_ops.standby(adap->fe);
> -
> -		/* Ensure all frontends negotiate bus access */
> -		adap->fe->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
> -
> +		pvr2_trace(PVR2_TRACE_INFO, "transferring fe[%d] ts_bus_ctrl() to pvr2_dvb_bus_ctrl()",
> +				adap->fe[0]->id);
> +		adap->fe[0]->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
>  	} else {
>  		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
>  			   "no frontend was attached!");
> @@ -370,16 +363,62 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
>  		return ret;
>  	}
>  
> - done:
> +	if (dvb_props->tuner_attach && dvb_props->tuner_attach(adap)) {
> +		pvr2_trace(PVR2_TRACE_ERROR_LEGS, "tuner attach failed");
> +		ret = -ENODEV;
> +		goto fail_tuner;
> +	}
> +
> +	if (adap->fe[1]) {
> +		adap->fe[1]->id = 1;
> +		adap->fe[1]->tuner_priv = adap->fe[0]->tuner_priv;
> +		memcpy(&adap->fe[1]->ops.tuner_ops,
> +			&adap->fe[0]->ops.tuner_ops,
> +			sizeof(struct dvb_tuner_ops));
> +
> +		if (dvb_register_frontend(&adap->dvb_adap, adap->fe[1])) {
> +			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
> +				   "frontend registration failed!");
> +			ret = -ENODEV;
> +			goto fail_frontend1;
> +		}
> +		/* MFE lock */
> +		adap->dvb_adap.mfe_shared = 1;
> +
> +		if (adap->fe[1]->ops.analog_ops.standby)
> +			adap->fe[1]->ops.analog_ops.standby(adap->fe[1]);
> +
> +		pvr2_trace(PVR2_TRACE_INFO, "transferring fe[%d] ts_bus_ctrl() to pvr2_dvb_bus_ctrl()",
> +				adap->fe[1]->id);
> +		adap->fe[1]->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
> +	}
> +done:
>  	pvr2_channel_limit_inputs(&adap->channel, 0);
>  	return ret;
> +
> +fail_frontend1:
> +	dvb_frontend_detach(adap->fe[1]);
> +	adap->fe[1] = NULL;
> +fail_tuner:
> +	dvb_unregister_frontend(adap->fe[0]);
> +fail_frontend0:
> +	dvb_frontend_detach(adap->fe[0]);
> +	adap->fe[0] = NULL;
> +
> +	return ret;
>  }
>  
>  static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap)
>  {
> -	if (adap->fe != NULL) {
> -		dvb_unregister_frontend(adap->fe);
> -		dvb_frontend_detach(adap->fe);
> +	if (adap->fe[1]) {
> +		dvb_unregister_frontend(adap->fe[1]);
> +		dvb_frontend_detach(adap->fe[1]);
> +		adap->fe[1] = NULL;
> +	}
> +	if (adap->fe[0]) {
> +		dvb_unregister_frontend(adap->fe[0]);
> +		dvb_frontend_detach(adap->fe[0]);
> +		adap->fe[0] = NULL;
>  	}
>  	return 0;
>  }
> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
> index e7f71fb..91bff57 100644
> --- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
> +++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
> @@ -18,7 +18,7 @@ struct pvr2_dvb_adapter {
>  	struct dmxdev		dmxdev;
>  	struct dvb_demux	demux;
>  	struct dvb_net		dvb_net;
> -	struct dvb_frontend	*fe;
> +	struct dvb_frontend	*fe[2];
>  
>  	int			feedcount;
>  	int			max_feed_count;
> -- 
> 2.7.4

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

* Re: [PATCH v4 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices
  2019-02-27 19:16     ` [PATCH v4 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
@ 2019-04-05 15:24       ` Sean Young
  2019-04-05 15:29         ` Sean Young
  2019-05-31 17:20         ` Brad Love
  0 siblings, 2 replies; 36+ messages in thread
From: Sean Young @ 2019-04-05 15:24 UTC (permalink / raw)
  To: Brad Love; +Cc: linux-media

On Wed, Feb 27, 2019 at 01:16:06PM -0600, Brad Love wrote:
> Includes support to identify and use two Hauppauge device.
> HVR-1955:
> - LGDT3306a ATSC/QAM demod
> - si2177 tuner
> - cx25840 decoder for analog tv/composite/s-video/audio
> 
> HVR-1975 dual-frontend:
> - LGDT3306a ATSC/QAM demod
> - si2168 DVB-C/T/T2 demod
> - si2177 tuner
> - cx25840 decoder for analog tv/composite/s-video/audio
> 
> Signed-off-by: Brad Love <brad@nextdimension.cc>

First of all there are bunch of checkpatch.pl --strict warnings and checks
that need resolving.

> ---
> Since v2:
> - Fix build with VIDEO_PVRUSB2_DVB enabled
> Changes since v1:
> - Fix build with VIDEO_PVRUSB2_DVB disabled
> - Insert 160xxx code lower, so 75xxx profile is not split
> - Reorganize 160xxx board profile
> - Share config where possible
> 
>  drivers/media/usb/pvrusb2/Kconfig               |   2 +
>  drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c |  25 ++++
>  drivers/media/usb/pvrusb2/pvrusb2-devattr.c     | 164 ++++++++++++++++++++++++
>  drivers/media/usb/pvrusb2/pvrusb2-devattr.h     |   1 +
>  drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h     |   4 +
>  drivers/media/usb/pvrusb2/pvrusb2-hdw.c         |  36 +++++-
>  6 files changed, 231 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/usb/pvrusb2/Kconfig b/drivers/media/usb/pvrusb2/Kconfig
> index 1ad913f..144631c 100644
> --- a/drivers/media/usb/pvrusb2/Kconfig
> +++ b/drivers/media/usb/pvrusb2/Kconfig
> @@ -40,6 +40,8 @@ config VIDEO_PVRUSB2_DVB
>  	select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT
>  	select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
>  	select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT
> +	select DVB_LGDT3306A if MEDIA_SUBDRV_AUTOSELECT
> +	select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
>  	select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
>  	select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
>  	select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
> index d5bec0f..36016ab 100644
> --- a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
> +++ b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
> @@ -111,10 +111,35 @@ static const struct routing_scheme routing_defav400 = {
>  	.cnt = ARRAY_SIZE(routing_schemeav400),
>  };
>  
> +static const struct routing_scheme_item routing_scheme160xxx[] = {
> +	[PVR2_CVAL_INPUT_TV] = {
> +		.vid = CX25840_COMPOSITE7,
> +		.aud = CX25840_AUDIO8,
> +	},
> +	[PVR2_CVAL_INPUT_RADIO] = {
> +		.vid = CX25840_COMPOSITE4,
> +		.aud = CX25840_AUDIO6,
> +	},
> +	[PVR2_CVAL_INPUT_COMPOSITE] = {
> +		.vid = CX25840_COMPOSITE3,
> +		.aud = CX25840_AUDIO_SERIAL,
> +	},
> +	[PVR2_CVAL_INPUT_SVIDEO] = {
> +		.vid = CX25840_SVIDEO1,
> +		.aud = CX25840_AUDIO_SERIAL,
> +	},
> +};
> +
> +static const struct routing_scheme routing_def160xxx = {
> +	.def = routing_scheme160xxx,
> +	.cnt = ARRAY_SIZE(routing_scheme160xxx),
> +};
> +
>  static const struct routing_scheme *routing_schemes[] = {
>  	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
>  	[PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv,
>  	[PVR2_ROUTING_SCHEME_AV400] = &routing_defav400,
> +	[PVR2_ROUTING_SCHEME_HAUP160XXX] = &routing_def160xxx,
>  };
>  
>  void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
> index ef36b62..97b4fc8 100644
> --- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
> +++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
> @@ -37,6 +37,9 @@ pvr2_device_desc structures.
>  #include "tda18271.h"
>  #include "tda8290.h"
>  #include "tuner-simple.h"
> +#include "si2157.h"
> +#include "lgdt3306a.h"
> +#include "si2168.h"
>  #endif
>  
>  
> @@ -525,7 +528,164 @@ static const struct pvr2_device_desc pvr2_device_751xx = {
>  #endif
>  };
>  
> +/*------------------------------------------------------------------------*/
> +/*    Hauppauge PVR-USB2 Model 160000 / 160111 -- HVR-1955 / HVR-1975     */
> +
> +#ifdef CONFIG_VIDEO_PVRUSB2_DVB
> +static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap);
> +static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap);
> +static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap);
> +static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap);
> +
> +static const struct pvr2_dvb_props pvr2_160000_dvb_props = {
> +	.frontend_attach = pvr2_dual_fe_attach,
> +	.tuner_attach    = pvr2_si2157_attach,
> +};

Newline.

> +static const struct pvr2_dvb_props pvr2_160111_dvb_props = {
> +	.frontend_attach = pvr2_lgdt3306a_attach,
> +	.tuner_attach    = pvr2_si2157_attach,
> +};
> +
> +static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
> +{
> +	struct si2157_config si2157_config = {};
> +
> +	si2157_config.inversion = 1;
> +	si2157_config.fe = adap->fe[0];
> +
> +	adap->i2c_client_tuner = dvb_module_probe("si2157", "si2177",
> +						&adap->channel.hdw->i2c_adap,
> +						0x60, &si2157_config);

Indentation.

> +
> +	if (!adap->i2c_client_tuner)
> +		return -ENODEV;
> +
> +	return 0;
> +}
> +
> +static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap)
> +{
> +	struct si2168_config si2168_config = {};
> +	struct i2c_adapter *adapter;
> +
> +	pr_debug("%s()\n", __func__);
> +
> +	si2168_config.fe = &adap->fe[1];
> +	si2168_config.i2c_adapter = &adapter;
> +	si2168_config.ts_mode = SI2168_TS_PARALLEL; /*2, 1-serial, 2-parallel.*/
> +	si2168_config.ts_clock_gapped = 1; /*0-disabled, 1-enabled.*/
> +	si2168_config.ts_clock_inv = 0; /*0-not-invert, 1-invert*/
> +	si2168_config.spectral_inversion = 1; /*0-not-invert, 1-invert*/
> +
> +	adap->i2c_client_demod[1] = dvb_module_probe("si2168", NULL,
> +						&adap->channel.hdw->i2c_adap,
> +						0x64, &si2168_config);

Indentation.

>  
> +	if (!adap->i2c_client_demod[1])
> +		return -ENODEV;
> +
> +	return 0;
> +}
> +
> +static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
> +{
> +	struct lgdt3306a_config lgdt3306a_config;
> +	struct i2c_adapter *adapter;
> +
> +	pr_debug("%s()\n", __func__);
> +
> +	lgdt3306a_config.fe = &adap->fe[0];
> +	lgdt3306a_config.i2c_adapter = &adapter;
> +	lgdt3306a_config.deny_i2c_rptr = 1;
> +	lgdt3306a_config.spectral_inversion = 1;
> +	lgdt3306a_config.qam_if_khz = 4000;
> +	lgdt3306a_config.vsb_if_khz = 3250;
> +	lgdt3306a_config.mpeg_mode = LGDT3306A_MPEG_PARALLEL;
> +	lgdt3306a_config.tpclk_edge = LGDT3306A_TPCLK_FALLING_EDGE;
> +	lgdt3306a_config.tpvalid_polarity = LGDT3306A_TP_VALID_LOW;
> +	lgdt3306a_config.xtalMHz = 25, /* demod clock MHz; 24/25 supported */
> +
> +	adap->i2c_client_demod[0] = dvb_module_probe("lgdt3306a", NULL,
> +						&adap->channel.hdw->i2c_adap,
> +						0x59, &lgdt3306a_config);
> +
> +	if (!adap->i2c_client_demod[0])
> +		return -ENODEV;
> +
> +	return 0;
> +}
> +
> +static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap)
> +{
> +	pr_debug("%s()\n", __func__);
> +
> +	if (pvr2_lgdt3306a_attach(adap) != 0)
> +		return -ENODEV;
> +
> +	if (pvr2_si2168_attach(adap) != 0) {
> +		dvb_module_release(adap->i2c_client_demod[0]);
> +		return -ENODEV;
> +	}
> +
> +	return 0;
> +}
> +#endif
> +
> +#define PVR2_FIRMWARE_160xxx "v4l-pvrusb2-160xxx-01.fw"
> +static const char *pvr2_fw1_names_160xxx[] = {
> +		PVR2_FIRMWARE_160xxx,
> +};
> +
> +static const struct pvr2_device_client_desc pvr2_cli_160xxx[] = {
> +	{ .module_id = PVR2_CLIENT_ID_CX25840 },
> +};
> +
> +static const struct pvr2_device_desc pvr2_device_160000 = {
> +		.description = "WinTV HVR-1975 Model 160000",
> +		.shortname = "160000",
> +		.client_table.lst = pvr2_cli_160xxx,
> +		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160xxx),
> +		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
> +		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
> +		.default_tuner_type = TUNER_ABSENT,
> +		.flag_has_cx25840 = !0,
> +		.flag_has_hauppauge_rom = !0,
> +		.flag_has_analogtuner = !0,
> +		.flag_has_composite = !0,
> +		.flag_has_svideo = !0,
> +		.flag_fx2_16kb = !0,

Why are we writing 1 in such a way?

> +		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
> +		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
> +		.default_std_mask = V4L2_STD_NTSC_M,
> +		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
> +		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
> +#ifdef CONFIG_VIDEO_PVRUSB2_DVB
> +		.dvb_props = &pvr2_160000_dvb_props,
> +#endif
> +};

Newline needed.

> +static const struct pvr2_device_desc pvr2_device_160111 = {
> +		.description = "WinTV HVR-1955 Model 160111",
> +		.shortname = "160111",
> +		.client_table.lst = pvr2_cli_160xxx,
> +		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160xxx),
> +		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
> +		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
> +		.default_tuner_type = TUNER_ABSENT,
> +		.flag_has_cx25840 = !0,
> +		.flag_has_hauppauge_rom = !0,
> +		.flag_has_analogtuner = !0,
> +		.flag_has_composite = !0,
> +		.flag_has_svideo = !0,
> +		.flag_fx2_16kb = !0,
> +		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
> +		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
> +		.default_std_mask = V4L2_STD_NTSC_M,
> +		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
> +		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
> +#ifdef CONFIG_VIDEO_PVRUSB2_DVB
> +		.dvb_props = &pvr2_160111_dvb_props,
> +#endif
> +};
>  
>  /*------------------------------------------------------------------------*/
>  
> @@ -552,6 +712,10 @@ struct usb_device_id pvr2_device_table[] = {
>  	  .driver_info = (kernel_ulong_t)&pvr2_device_751xx},
>  	{ USB_DEVICE(0x0ccd, 0x0039),
>  	  .driver_info = (kernel_ulong_t)&pvr2_device_av400},
> +	{ USB_DEVICE(0x2040, 0x7502),
> +	  .driver_info = (kernel_ulong_t)&pvr2_device_160111},
> +	{ USB_DEVICE(0x2040, 0x7510),
> +	  .driver_info = (kernel_ulong_t)&pvr2_device_160000},
>  	{ }
>  };
>  
> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.h b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
> index c1e7d48..ea0b2bf 100644
> --- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
> +++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
> @@ -66,6 +66,7 @@ struct pvr2_string_table {
>  #define PVR2_ROUTING_SCHEME_GOTVIEW 1
>  #define PVR2_ROUTING_SCHEME_ONAIR 2
>  #define PVR2_ROUTING_SCHEME_AV400 3
> +#define PVR2_ROUTING_SCHEME_HAUP160XXX 4
>  
>  #define PVR2_DIGITAL_SCHEME_NONE 0
>  #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
> index 0a01de4..640b033 100644
> --- a/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
> +++ b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
> @@ -38,6 +38,10 @@
>  
>  #define FX2CMD_FWPOST1          0x52u
>  
> +/* These 2 only exist on Model 160xxx */
> +#define FX2CMD_HCW_DEMOD_RESET_PIN 0xd4u
> +#define FX2CMD_HCW_MAKO_SLEEP_PIN  0xd5u
> +
>  #define FX2CMD_POWER_OFF        0xdcu
>  #define FX2CMD_POWER_ON         0xdeu
>  
> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
> index 446a999..ab9e822 100644
> --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
> +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
> @@ -316,6 +316,8 @@ static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = {
>  	{FX2CMD_ONAIR_DTV_STREAMING_OFF, "onair dtv stream off"},
>  	{FX2CMD_ONAIR_DTV_POWER_ON, "onair dtv power on"},
>  	{FX2CMD_ONAIR_DTV_POWER_OFF, "onair dtv power off"},
> +	{FX2CMD_HCW_DEMOD_RESET_PIN, "hcw demod reset pin"},
> +	{FX2CMD_HCW_MAKO_SLEEP_PIN, "hcw mako sleep pin"},
>  };
>  
>  
> @@ -2137,10 +2139,28 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
>  				      ((0) << 16));
>  	}
>  
> -	// This step MUST happen after the earlier powerup step.
> +	/* This step MUST happen after the earlier powerup step */
>  	pvr2_i2c_core_init(hdw);
>  	if (!pvr2_hdw_dev_ok(hdw)) return;
>  
> +	/* Reset demod only on Hauppauge 160xxx platform */
> +	if (hdw->usb_dev->descriptor.idVendor == 0x2040 &&
> +	    (hdw->usb_dev->descriptor.idProduct == 0x7502 ||
> +	     hdw->usb_dev->descriptor.idProduct == 0x7510)) {

These need le16_to_cpu() else it will not work on big-endian machines.

> +		pr_info("%s(): resetting 160xxx demod\n", __func__);
> +		/* TODO: not sure this is proper place to reset once only */
> +		pvr2_issue_simple_cmd(hdw,
> +				     FX2CMD_HCW_DEMOD_RESET_PIN |
> +				     (1 << 8) |
> +				     ((0) << 16));
> +		msleep(10);

usleep_range() is preferred (for delays <= 10), I think. Maybe 10ms is too
long anyway and msleep(1) is enough.

> +		pvr2_issue_simple_cmd(hdw,
> +				     FX2CMD_HCW_DEMOD_RESET_PIN |
> +				     (1 << 8) |
> +				     ((1) << 16));
> +		msleep(10);
> +	}
> +
>  	pvr2_hdw_load_modules(hdw);
>  	if (!pvr2_hdw_dev_ok(hdw)) return;
>  
> @@ -4011,6 +4031,20 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
>  static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff)
>  {
>  	hdw->flag_ok = !0;
> +
> +	/* Use this for Hauppauge 160xxx only */
> +	if (hdw->usb_dev->descriptor.idVendor == 0x2040 &&
> +	    (hdw->usb_dev->descriptor.idProduct == 0x7502 ||
> +	     hdw->usb_dev->descriptor.idProduct == 0x7510)) {

Same as above. le16_to_cpu() needed.

> +		pr_debug("%s(): resetting demod on Hauppauge 160xxx platform skipped\n",
> +			__func__);
> +		/* Can't reset 160xxx or it will trash Demod tristate */
> +		return pvr2_issue_simple_cmd(hdw,
> +				     FX2CMD_HCW_MAKO_SLEEP_PIN |
> +				     (1 << 8) |
> +				     ((onoff ? 1 : 0) << 16));
> +	}
> +
>  	return pvr2_issue_simple_cmd(hdw,
>  				     FX2CMD_HCW_DEMOD_RESETIN |
>  				     (1 << 8) |
> -- 
> 2.7.4

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

* Re: [PATCH v4 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices
  2019-04-05 15:24       ` Sean Young
@ 2019-04-05 15:29         ` Sean Young
  2019-04-08 18:01           ` Brad Love
  2019-05-31 17:20         ` Brad Love
  1 sibling, 1 reply; 36+ messages in thread
From: Sean Young @ 2019-04-05 15:29 UTC (permalink / raw)
  To: Brad Love; +Cc: linux-media

On Fri, Apr 05, 2019 at 04:24:24PM +0100, Sean Young wrote:
> On Wed, Feb 27, 2019 at 01:16:06PM -0600, Brad Love wrote:
 > +		pr_info("%s(): resetting 160xxx demod\n", __func__);
> > +		/* TODO: not sure this is proper place to reset once only */
> > +		pvr2_issue_simple_cmd(hdw,
> > +				     FX2CMD_HCW_DEMOD_RESET_PIN |
> > +				     (1 << 8) |
> > +				     ((0) << 16));
> > +		msleep(10);
> 
> usleep_range() is preferred (for delays <= 10), I think. Maybe 10ms is too
> long anyway and msleep(1) is enough.

Sorry that was wrong. usleep_range() is preferred 1ms - 20ms, see:

https://www.kernel.org/doc/Documentation/timers/timers-howto.txt



Sean

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

* Re: [PATCH v4 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices
  2019-04-05 15:29         ` Sean Young
@ 2019-04-08 18:01           ` Brad Love
  2019-04-08 20:17             ` Sean Young
  0 siblings, 1 reply; 36+ messages in thread
From: Brad Love @ 2019-04-08 18:01 UTC (permalink / raw)
  To: Sean Young, Brad Love; +Cc: linux-media


On 05/04/2019 10.29, Sean Young wrote:
> On Fri, Apr 05, 2019 at 04:24:24PM +0100, Sean Young wrote:
>> On Wed, Feb 27, 2019 at 01:16:06PM -0600, Brad Love wrote:
>  > +		pr_info("%s(): resetting 160xxx demod\n", __func__);
>>> +		/* TODO: not sure this is proper place to reset once only */
>>> +		pvr2_issue_simple_cmd(hdw,
>>> +				     FX2CMD_HCW_DEMOD_RESET_PIN |
>>> +				     (1 << 8) |
>>> +				     ((0) << 16));
>>> +		msleep(10);
>> usleep_range() is preferred (for delays <= 10), I think. Maybe 10ms is too
>> long anyway and msleep(1) is enough.
> Sorry that was wrong. usleep_range() is preferred 1ms - 20ms, see:
>
> https://www.kernel.org/doc/Documentation/timers/timers-howto.txt
>

Hi Shawn,

Thanks for reviewing things. Please explain what your rationale is for
arbitrarily reducing the delay to 1ms? I'm a Hauppauge engineer, this is
a Hauppauge device, I'm going off Hauppauge documentation and reference
code...and it says 10ms. I'll change to the proper sleep function,
apologies for missing this instance, but the delay will stay at 10ms as
that is what my documentation says.

Regards,

Brad





>
> Sean


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

* Re: [PATCH v4 2/4] pvrusb2: Add multiple dvb frontend support
  2019-04-05 10:00       ` Sean Young
@ 2019-04-08 18:16         ` Brad Love
  0 siblings, 0 replies; 36+ messages in thread
From: Brad Love @ 2019-04-08 18:16 UTC (permalink / raw)
  To: Sean Young, Brad Love; +Cc: linux-media


On 05/04/2019 05.00, Sean Young wrote:
> On Wed, Feb 27, 2019 at 01:16:04PM -0600, Brad Love wrote:
>> All changes are equivalent and backwards compatible.
>> All current devices have been changed to use fe[0]
>> Cleanup has been added to dvb init to support cleanup after failure.
> Just very minor note. Here you are adding suppport for 2 frontends, but
> you're not explaining why. I would add something like "This is to add support
> for Hauppauge HVR1955/1975 devices which will be done in a later commit",
> to the commit message. Alternatively you could merge the two commits.

Hi Sean,

I'll add a note to the commit message. Combining the commits seems
bizarre and contrary to "one issue in a commit."

Regards,

Brad



>
> Sean
>
>> Signed-off-by: Brad Love <brad@nextdimension.cc>
>> ---
>> No changes
>>
>>  drivers/media/usb/pvrusb2/pvrusb2-devattr.c | 36 +++++++-------
>>  drivers/media/usb/pvrusb2/pvrusb2-dvb.c     | 77 ++++++++++++++++++++++-------
>>  drivers/media/usb/pvrusb2/pvrusb2-dvb.h     |  2 +-
>>  3 files changed, 77 insertions(+), 38 deletions(-)
>>
>> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
>> index 06de1c8..ef36b62 100644
>> --- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
>> +++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
>> @@ -188,10 +188,10 @@ static struct lgdt330x_config pvr2_lgdt3303_config = {
>>  
>>  static int pvr2_lgdt3303_attach(struct pvr2_dvb_adapter *adap)
>>  {
>> -	adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3303_config,
>> -			      0x0e,
>> -			      &adap->channel.hdw->i2c_adap);
>> -	if (adap->fe)
>> +	adap->fe[0] = dvb_attach(lgdt330x_attach, &pvr2_lgdt3303_config,
>> +				 0x0e,
>> +				 &adap->channel.hdw->i2c_adap);
>> +	if (adap->fe[0])
>>  		return 0;
>>  
>>  	return -EIO;
>> @@ -199,7 +199,7 @@ static int pvr2_lgdt3303_attach(struct pvr2_dvb_adapter *adap)
>>  
>>  static int pvr2_lgh06xf_attach(struct pvr2_dvb_adapter *adap)
>>  {
>> -	dvb_attach(simple_tuner_attach, adap->fe,
>> +	dvb_attach(simple_tuner_attach, adap->fe[0],
>>  		   &adap->channel.hdw->i2c_adap, 0x61,
>>  		   TUNER_LG_TDVS_H06XF);
>>  
>> @@ -248,10 +248,10 @@ static struct lgdt330x_config pvr2_lgdt3302_config = {
>>  
>>  static int pvr2_lgdt3302_attach(struct pvr2_dvb_adapter *adap)
>>  {
>> -	adap->fe = dvb_attach(lgdt330x_attach, &pvr2_lgdt3302_config,
>> +	adap->fe[0] = dvb_attach(lgdt330x_attach, &pvr2_lgdt3302_config,
>>  			      0x0e,
>>  			      &adap->channel.hdw->i2c_adap);
>> -	if (adap->fe)
>> +	if (adap->fe[0])
>>  		return 0;
>>  
>>  	return -EIO;
>> @@ -259,7 +259,7 @@ static int pvr2_lgdt3302_attach(struct pvr2_dvb_adapter *adap)
>>  
>>  static int pvr2_fcv1236d_attach(struct pvr2_dvb_adapter *adap)
>>  {
>> -	dvb_attach(simple_tuner_attach, adap->fe,
>> +	dvb_attach(simple_tuner_attach, adap->fe[0],
>>  		   &adap->channel.hdw->i2c_adap, 0x61,
>>  		   TUNER_PHILIPS_FCV1236D);
>>  
>> @@ -335,9 +335,9 @@ static struct tda18271_config hauppauge_tda18271_dvb_config = {
>>  
>>  static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
>>  {
>> -	adap->fe = dvb_attach(tda10048_attach, &hauppauge_tda10048_config,
>> +	adap->fe[0] = dvb_attach(tda10048_attach, &hauppauge_tda10048_config,
>>  			      &adap->channel.hdw->i2c_adap);
>> -	if (adap->fe)
>> +	if (adap->fe[0])
>>  		return 0;
>>  
>>  	return -EIO;
>> @@ -345,10 +345,10 @@ static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
>>  
>>  static int pvr2_73xxx_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
>>  {
>> -	dvb_attach(tda829x_attach, adap->fe,
>> +	dvb_attach(tda829x_attach, adap->fe[0],
>>  		   &adap->channel.hdw->i2c_adap, 0x42,
>>  		   &tda829x_no_probe);
>> -	dvb_attach(tda18271_attach, adap->fe, 0x60,
>> +	dvb_attach(tda18271_attach, adap->fe[0], 0x60,
>>  		   &adap->channel.hdw->i2c_adap,
>>  		   &hauppauge_tda18271_dvb_config);
>>  
>> @@ -433,9 +433,9 @@ static struct tda18271_config hauppauge_tda18271_config = {
>>  
>>  static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
>>  {
>> -	adap->fe = dvb_attach(s5h1409_attach, &pvr2_s5h1409_config,
>> +	adap->fe[0] = dvb_attach(s5h1409_attach, &pvr2_s5h1409_config,
>>  			      &adap->channel.hdw->i2c_adap);
>> -	if (adap->fe)
>> +	if (adap->fe[0])
>>  		return 0;
>>  
>>  	return -EIO;
>> @@ -443,9 +443,9 @@ static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
>>  
>>  static int pvr2_s5h1411_attach(struct pvr2_dvb_adapter *adap)
>>  {
>> -	adap->fe = dvb_attach(s5h1411_attach, &pvr2_s5h1411_config,
>> +	adap->fe[0] = dvb_attach(s5h1411_attach, &pvr2_s5h1411_config,
>>  			      &adap->channel.hdw->i2c_adap);
>> -	if (adap->fe)
>> +	if (adap->fe[0])
>>  		return 0;
>>  
>>  	return -EIO;
>> @@ -453,10 +453,10 @@ static int pvr2_s5h1411_attach(struct pvr2_dvb_adapter *adap)
>>  
>>  static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
>>  {
>> -	dvb_attach(tda829x_attach, adap->fe,
>> +	dvb_attach(tda829x_attach, adap->fe[0],
>>  		   &adap->channel.hdw->i2c_adap, 0x42,
>>  		   &tda829x_no_probe);
>> -	dvb_attach(tda18271_attach, adap->fe, 0x60,
>> +	dvb_attach(tda18271_attach, adap->fe[0], 0x60,
>>  		   &adap->channel.hdw->i2c_adap,
>>  		   &hauppauge_tda18271_config);
>>  
>> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
>> index 4b32b21..cb5586b 100644
>> --- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
>> +++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
>> @@ -343,26 +343,19 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
>>  		goto done;
>>  	}
>>  
>> -	if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) {
>> -
>> -		if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
>> +	if (dvb_props->frontend_attach(adap) == 0 && adap->fe[0]) {
>> +		if (dvb_register_frontend(&adap->dvb_adap, adap->fe[0])) {
>>  			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
>>  				   "frontend registration failed!");
>> -			dvb_frontend_detach(adap->fe);
>> -			adap->fe = NULL;
>>  			ret = -ENODEV;
>> -			goto done;
>> +			goto fail_frontend0;
>>  		}
>> +		if (adap->fe[0]->ops.analog_ops.standby)
>> +			adap->fe[0]->ops.analog_ops.standby(adap->fe[0]);
>>  
>> -		if (dvb_props->tuner_attach)
>> -			dvb_props->tuner_attach(adap);
>> -
>> -		if (adap->fe->ops.analog_ops.standby)
>> -			adap->fe->ops.analog_ops.standby(adap->fe);
>> -
>> -		/* Ensure all frontends negotiate bus access */
>> -		adap->fe->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
>> -
>> +		pvr2_trace(PVR2_TRACE_INFO, "transferring fe[%d] ts_bus_ctrl() to pvr2_dvb_bus_ctrl()",
>> +				adap->fe[0]->id);
>> +		adap->fe[0]->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
>>  	} else {
>>  		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
>>  			   "no frontend was attached!");
>> @@ -370,16 +363,62 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
>>  		return ret;
>>  	}
>>  
>> - done:
>> +	if (dvb_props->tuner_attach && dvb_props->tuner_attach(adap)) {
>> +		pvr2_trace(PVR2_TRACE_ERROR_LEGS, "tuner attach failed");
>> +		ret = -ENODEV;
>> +		goto fail_tuner;
>> +	}
>> +
>> +	if (adap->fe[1]) {
>> +		adap->fe[1]->id = 1;
>> +		adap->fe[1]->tuner_priv = adap->fe[0]->tuner_priv;
>> +		memcpy(&adap->fe[1]->ops.tuner_ops,
>> +			&adap->fe[0]->ops.tuner_ops,
>> +			sizeof(struct dvb_tuner_ops));
>> +
>> +		if (dvb_register_frontend(&adap->dvb_adap, adap->fe[1])) {
>> +			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
>> +				   "frontend registration failed!");
>> +			ret = -ENODEV;
>> +			goto fail_frontend1;
>> +		}
>> +		/* MFE lock */
>> +		adap->dvb_adap.mfe_shared = 1;
>> +
>> +		if (adap->fe[1]->ops.analog_ops.standby)
>> +			adap->fe[1]->ops.analog_ops.standby(adap->fe[1]);
>> +
>> +		pvr2_trace(PVR2_TRACE_INFO, "transferring fe[%d] ts_bus_ctrl() to pvr2_dvb_bus_ctrl()",
>> +				adap->fe[1]->id);
>> +		adap->fe[1]->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
>> +	}
>> +done:
>>  	pvr2_channel_limit_inputs(&adap->channel, 0);
>>  	return ret;
>> +
>> +fail_frontend1:
>> +	dvb_frontend_detach(adap->fe[1]);
>> +	adap->fe[1] = NULL;
>> +fail_tuner:
>> +	dvb_unregister_frontend(adap->fe[0]);
>> +fail_frontend0:
>> +	dvb_frontend_detach(adap->fe[0]);
>> +	adap->fe[0] = NULL;
>> +
>> +	return ret;
>>  }
>>  
>>  static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap)
>>  {
>> -	if (adap->fe != NULL) {
>> -		dvb_unregister_frontend(adap->fe);
>> -		dvb_frontend_detach(adap->fe);
>> +	if (adap->fe[1]) {
>> +		dvb_unregister_frontend(adap->fe[1]);
>> +		dvb_frontend_detach(adap->fe[1]);
>> +		adap->fe[1] = NULL;
>> +	}
>> +	if (adap->fe[0]) {
>> +		dvb_unregister_frontend(adap->fe[0]);
>> +		dvb_frontend_detach(adap->fe[0]);
>> +		adap->fe[0] = NULL;
>>  	}
>>  	return 0;
>>  }
>> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
>> index e7f71fb..91bff57 100644
>> --- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
>> +++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
>> @@ -18,7 +18,7 @@ struct pvr2_dvb_adapter {
>>  	struct dmxdev		dmxdev;
>>  	struct dvb_demux	demux;
>>  	struct dvb_net		dvb_net;
>> -	struct dvb_frontend	*fe;
>> +	struct dvb_frontend	*fe[2];
>>  
>>  	int			feedcount;
>>  	int			max_feed_count;
>> -- 
>> 2.7.4

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

* Re: [PATCH v4 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices
  2019-04-08 18:01           ` Brad Love
@ 2019-04-08 20:17             ` Sean Young
  0 siblings, 0 replies; 36+ messages in thread
From: Sean Young @ 2019-04-08 20:17 UTC (permalink / raw)
  To: Brad Love; +Cc: linux-media

Hi Brad,

On Mon, Apr 08, 2019 at 01:01:43PM -0500, Brad Love wrote:
> 
> On 05/04/2019 10.29, Sean Young wrote:
> > On Fri, Apr 05, 2019 at 04:24:24PM +0100, Sean Young wrote:
> >> On Wed, Feb 27, 2019 at 01:16:06PM -0600, Brad Love wrote:
> >  > +		pr_info("%s(): resetting 160xxx demod\n", __func__);
> >>> +		/* TODO: not sure this is proper place to reset once only */
> >>> +		pvr2_issue_simple_cmd(hdw,
> >>> +				     FX2CMD_HCW_DEMOD_RESET_PIN |
> >>> +				     (1 << 8) |
> >>> +				     ((0) << 16));
> >>> +		msleep(10);
> >> usleep_range() is preferred (for delays <= 10), I think. Maybe 10ms is too
> >> long anyway and msleep(1) is enough.
> > Sorry that was wrong. usleep_range() is preferred 1ms - 20ms, see:
> >
> > https://www.kernel.org/doc/Documentation/timers/timers-howto.txt
> >
> 
> Hi Shawn,
> 
> Thanks for reviewing things. Please explain what your rationale is for
> arbitrarily reducing the delay to 1ms? I'm a Hauppauge engineer, this is
> a Hauppauge device, I'm going off Hauppauge documentation and reference
> code...and it says 10ms. I'll change to the proper sleep function,
> apologies for missing this instance, but the delay will stay at 10ms as
> that is what my documentation says.

I had not seen a device before that needed reset to be asserted for so long.
Clearly I was completely wrong there.

All I was trying to point out that either the msleep() should be reduced
if possible else usleep_range() should be used. I probably could have
expressed that more clearly.


Sean

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

* Re: [PATCH v4 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices
  2019-04-05 15:24       ` Sean Young
  2019-04-05 15:29         ` Sean Young
@ 2019-05-31 17:20         ` Brad Love
  2019-05-31 18:25           ` Brad Love
  2019-05-31 21:30           ` Sean Young
  1 sibling, 2 replies; 36+ messages in thread
From: Brad Love @ 2019-05-31 17:20 UTC (permalink / raw)
  To: Sean Young, Brad Love; +Cc: linux-media

Hi Shawn,

Just found time to get back to this. I fixed all the checkpatch strict
warnings, no problem. Then I noticed a few comments of yours that I
somehow missed first time around. I've replied inline to those.


On 05/04/2019 10.24, Sean Young wrote:
> On Wed, Feb 27, 2019 at 01:16:06PM -0600, Brad Love wrote:
>> Includes support to identify and use two Hauppauge device.
>> HVR-1955:
>> - LGDT3306a ATSC/QAM demod
>> - si2177 tuner
>> - cx25840 decoder for analog tv/composite/s-video/audio
>>
>> HVR-1975 dual-frontend:
>> - LGDT3306a ATSC/QAM demod
>> - si2168 DVB-C/T/T2 demod
>> - si2177 tuner
>> - cx25840 decoder for analog tv/composite/s-video/audio
>>
>> Signed-off-by: Brad Love <brad@nextdimension.cc>
> First of all there are bunch of checkpatch.pl --strict warnings and checks
> that need resolving.
>
>> ---
>> Since v2:
>> - Fix build with VIDEO_PVRUSB2_DVB enabled
>> Changes since v1:
>> - Fix build with VIDEO_PVRUSB2_DVB disabled
>> - Insert 160xxx code lower, so 75xxx profile is not split
>> - Reorganize 160xxx board profile
>> - Share config where possible
>>
>>  drivers/media/usb/pvrusb2/Kconfig               |   2 +
>>  drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c |  25 ++++
>>  drivers/media/usb/pvrusb2/pvrusb2-devattr.c     | 164 ++++++++++++++++++++++++
>>  drivers/media/usb/pvrusb2/pvrusb2-devattr.h     |   1 +
>>  drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h     |   4 +
>>  drivers/media/usb/pvrusb2/pvrusb2-hdw.c         |  36 +++++-
>>  6 files changed, 231 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/media/usb/pvrusb2/Kconfig b/drivers/media/usb/pvrusb2/Kconfig
>> index 1ad913f..144631c 100644
>> --- a/drivers/media/usb/pvrusb2/Kconfig
>> +++ b/drivers/media/usb/pvrusb2/Kconfig
>> @@ -40,6 +40,8 @@ config VIDEO_PVRUSB2_DVB
>>  	select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT
>>  	select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
>>  	select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT
>> +	select DVB_LGDT3306A if MEDIA_SUBDRV_AUTOSELECT
>> +	select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
>>  	select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
>>  	select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
>>  	select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
>> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
>> index d5bec0f..36016ab 100644
>> --- a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
>> +++ b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
>> @@ -111,10 +111,35 @@ static const struct routing_scheme routing_defav400 = {
>>  	.cnt = ARRAY_SIZE(routing_schemeav400),
>>  };
>>  
>> +static const struct routing_scheme_item routing_scheme160xxx[] = {
>> +	[PVR2_CVAL_INPUT_TV] = {
>> +		.vid = CX25840_COMPOSITE7,
>> +		.aud = CX25840_AUDIO8,
>> +	},
>> +	[PVR2_CVAL_INPUT_RADIO] = {
>> +		.vid = CX25840_COMPOSITE4,
>> +		.aud = CX25840_AUDIO6,
>> +	},
>> +	[PVR2_CVAL_INPUT_COMPOSITE] = {
>> +		.vid = CX25840_COMPOSITE3,
>> +		.aud = CX25840_AUDIO_SERIAL,
>> +	},
>> +	[PVR2_CVAL_INPUT_SVIDEO] = {
>> +		.vid = CX25840_SVIDEO1,
>> +		.aud = CX25840_AUDIO_SERIAL,
>> +	},
>> +};
>> +
>> +static const struct routing_scheme routing_def160xxx = {
>> +	.def = routing_scheme160xxx,
>> +	.cnt = ARRAY_SIZE(routing_scheme160xxx),
>> +};
>> +
>>  static const struct routing_scheme *routing_schemes[] = {
>>  	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
>>  	[PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv,
>>  	[PVR2_ROUTING_SCHEME_AV400] = &routing_defav400,
>> +	[PVR2_ROUTING_SCHEME_HAUP160XXX] = &routing_def160xxx,
>>  };
>>  
>>  void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
>> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
>> index ef36b62..97b4fc8 100644
>> --- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
>> +++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
>> @@ -37,6 +37,9 @@ pvr2_device_desc structures.
>>  #include "tda18271.h"
>>  #include "tda8290.h"
>>  #include "tuner-simple.h"
>> +#include "si2157.h"
>> +#include "lgdt3306a.h"
>> +#include "si2168.h"
>>  #endif
>>  
>>  
>> @@ -525,7 +528,164 @@ static const struct pvr2_device_desc pvr2_device_751xx = {
>>  #endif
>>  };
>>  
>> +/*------------------------------------------------------------------------*/
>> +/*    Hauppauge PVR-USB2 Model 160000 / 160111 -- HVR-1955 / HVR-1975     */
>> +
>> +#ifdef CONFIG_VIDEO_PVRUSB2_DVB
>> +static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap);
>> +static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap);
>> +static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap);
>> +static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap);
>> +
>> +static const struct pvr2_dvb_props pvr2_160000_dvb_props = {
>> +	.frontend_attach = pvr2_dual_fe_attach,
>> +	.tuner_attach    = pvr2_si2157_attach,
>> +};
> Newline.
>
>> +static const struct pvr2_dvb_props pvr2_160111_dvb_props = {
>> +	.frontend_attach = pvr2_lgdt3306a_attach,
>> +	.tuner_attach    = pvr2_si2157_attach,
>> +};
>> +
>> +static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
>> +{
>> +	struct si2157_config si2157_config = {};
>> +
>> +	si2157_config.inversion = 1;
>> +	si2157_config.fe = adap->fe[0];
>> +
>> +	adap->i2c_client_tuner = dvb_module_probe("si2157", "si2177",
>> +						&adap->channel.hdw->i2c_adap,
>> +						0x60, &si2157_config);
> Indentation.
>
>> +
>> +	if (!adap->i2c_client_tuner)
>> +		return -ENODEV;
>> +
>> +	return 0;
>> +}
>> +
>> +static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap)
>> +{
>> +	struct si2168_config si2168_config = {};
>> +	struct i2c_adapter *adapter;
>> +
>> +	pr_debug("%s()\n", __func__);
>> +
>> +	si2168_config.fe = &adap->fe[1];
>> +	si2168_config.i2c_adapter = &adapter;
>> +	si2168_config.ts_mode = SI2168_TS_PARALLEL; /*2, 1-serial, 2-parallel.*/
>> +	si2168_config.ts_clock_gapped = 1; /*0-disabled, 1-enabled.*/
>> +	si2168_config.ts_clock_inv = 0; /*0-not-invert, 1-invert*/
>> +	si2168_config.spectral_inversion = 1; /*0-not-invert, 1-invert*/
>> +
>> +	adap->i2c_client_demod[1] = dvb_module_probe("si2168", NULL,
>> +						&adap->channel.hdw->i2c_adap,
>> +						0x64, &si2168_config);
> Indentation.
>
>>  
>> +	if (!adap->i2c_client_demod[1])
>> +		return -ENODEV;
>> +
>> +	return 0;
>> +}
>> +
>> +static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
>> +{
>> +	struct lgdt3306a_config lgdt3306a_config;
>> +	struct i2c_adapter *adapter;
>> +
>> +	pr_debug("%s()\n", __func__);
>> +
>> +	lgdt3306a_config.fe = &adap->fe[0];
>> +	lgdt3306a_config.i2c_adapter = &adapter;
>> +	lgdt3306a_config.deny_i2c_rptr = 1;
>> +	lgdt3306a_config.spectral_inversion = 1;
>> +	lgdt3306a_config.qam_if_khz = 4000;
>> +	lgdt3306a_config.vsb_if_khz = 3250;
>> +	lgdt3306a_config.mpeg_mode = LGDT3306A_MPEG_PARALLEL;
>> +	lgdt3306a_config.tpclk_edge = LGDT3306A_TPCLK_FALLING_EDGE;
>> +	lgdt3306a_config.tpvalid_polarity = LGDT3306A_TP_VALID_LOW;
>> +	lgdt3306a_config.xtalMHz = 25, /* demod clock MHz; 24/25 supported */
>> +
>> +	adap->i2c_client_demod[0] = dvb_module_probe("lgdt3306a", NULL,
>> +						&adap->channel.hdw->i2c_adap,
>> +						0x59, &lgdt3306a_config);
>> +
>> +	if (!adap->i2c_client_demod[0])
>> +		return -ENODEV;
>> +
>> +	return 0;
>> +}
>> +
>> +static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap)
>> +{
>> +	pr_debug("%s()\n", __func__);
>> +
>> +	if (pvr2_lgdt3306a_attach(adap) != 0)
>> +		return -ENODEV;
>> +
>> +	if (pvr2_si2168_attach(adap) != 0) {
>> +		dvb_module_release(adap->i2c_client_demod[0]);
>> +		return -ENODEV;
>> +	}
>> +
>> +	return 0;
>> +}
>> +#endif
>> +
>> +#define PVR2_FIRMWARE_160xxx "v4l-pvrusb2-160xxx-01.fw"
>> +static const char *pvr2_fw1_names_160xxx[] = {
>> +		PVR2_FIRMWARE_160xxx,
>> +};
>> +
>> +static const struct pvr2_device_client_desc pvr2_cli_160xxx[] = {
>> +	{ .module_id = PVR2_CLIENT_ID_CX25840 },
>> +};
>> +
>> +static const struct pvr2_device_desc pvr2_device_160000 = {
>> +		.description = "WinTV HVR-1975 Model 160000",
>> +		.shortname = "160000",
>> +		.client_table.lst = pvr2_cli_160xxx,
>> +		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160xxx),
>> +		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
>> +		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
>> +		.default_tuner_type = TUNER_ABSENT,
>> +		.flag_has_cx25840 = !0,
>> +		.flag_has_hauppauge_rom = !0,
>> +		.flag_has_analogtuner = !0,
>> +		.flag_has_composite = !0,
>> +		.flag_has_svideo = !0,
>> +		.flag_fx2_16kb = !0,
> Why are we writing 1 in such a way?



I did not originate the board profile part. I do see the similar
notation used throughout this particular driver, but I cannot state the
rational in setting it like that. In v5 I have this just set these
properties to 1.





>
>> +		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
>> +		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
>> +		.default_std_mask = V4L2_STD_NTSC_M,
>> +		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
>> +		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
>> +#ifdef CONFIG_VIDEO_PVRUSB2_DVB
>> +		.dvb_props = &pvr2_160000_dvb_props,
>> +#endif
>> +};
> Newline needed.
>
>> +static const struct pvr2_device_desc pvr2_device_160111 = {
>> +		.description = "WinTV HVR-1955 Model 160111",
>> +		.shortname = "160111",
>> +		.client_table.lst = pvr2_cli_160xxx,
>> +		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160xxx),
>> +		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
>> +		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
>> +		.default_tuner_type = TUNER_ABSENT,
>> +		.flag_has_cx25840 = !0,
>> +		.flag_has_hauppauge_rom = !0,
>> +		.flag_has_analogtuner = !0,
>> +		.flag_has_composite = !0,
>> +		.flag_has_svideo = !0,
>> +		.flag_fx2_16kb = !0,
>> +		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
>> +		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
>> +		.default_std_mask = V4L2_STD_NTSC_M,
>> +		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
>> +		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
>> +#ifdef CONFIG_VIDEO_PVRUSB2_DVB
>> +		.dvb_props = &pvr2_160111_dvb_props,
>> +#endif
>> +};
>>  
>>  /*------------------------------------------------------------------------*/
>>  
>> @@ -552,6 +712,10 @@ struct usb_device_id pvr2_device_table[] = {
>>  	  .driver_info = (kernel_ulong_t)&pvr2_device_751xx},
>>  	{ USB_DEVICE(0x0ccd, 0x0039),
>>  	  .driver_info = (kernel_ulong_t)&pvr2_device_av400},
>> +	{ USB_DEVICE(0x2040, 0x7502),
>> +	  .driver_info = (kernel_ulong_t)&pvr2_device_160111},
>> +	{ USB_DEVICE(0x2040, 0x7510),
>> +	  .driver_info = (kernel_ulong_t)&pvr2_device_160000},
>>  	{ }
>>  };
>>  
>> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.h b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
>> index c1e7d48..ea0b2bf 100644
>> --- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
>> +++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
>> @@ -66,6 +66,7 @@ struct pvr2_string_table {
>>  #define PVR2_ROUTING_SCHEME_GOTVIEW 1
>>  #define PVR2_ROUTING_SCHEME_ONAIR 2
>>  #define PVR2_ROUTING_SCHEME_AV400 3
>> +#define PVR2_ROUTING_SCHEME_HAUP160XXX 4
>>  
>>  #define PVR2_DIGITAL_SCHEME_NONE 0
>>  #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
>> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
>> index 0a01de4..640b033 100644
>> --- a/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
>> +++ b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
>> @@ -38,6 +38,10 @@
>>  
>>  #define FX2CMD_FWPOST1          0x52u
>>  
>> +/* These 2 only exist on Model 160xxx */
>> +#define FX2CMD_HCW_DEMOD_RESET_PIN 0xd4u
>> +#define FX2CMD_HCW_MAKO_SLEEP_PIN  0xd5u
>> +
>>  #define FX2CMD_POWER_OFF        0xdcu
>>  #define FX2CMD_POWER_ON         0xdeu
>>  
>> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
>> index 446a999..ab9e822 100644
>> --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
>> +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
>> @@ -316,6 +316,8 @@ static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = {
>>  	{FX2CMD_ONAIR_DTV_STREAMING_OFF, "onair dtv stream off"},
>>  	{FX2CMD_ONAIR_DTV_POWER_ON, "onair dtv power on"},
>>  	{FX2CMD_ONAIR_DTV_POWER_OFF, "onair dtv power off"},
>> +	{FX2CMD_HCW_DEMOD_RESET_PIN, "hcw demod reset pin"},
>> +	{FX2CMD_HCW_MAKO_SLEEP_PIN, "hcw mako sleep pin"},
>>  };
>>  
>>  
>> @@ -2137,10 +2139,28 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
>>  				      ((0) << 16));
>>  	}
>>  
>> -	// This step MUST happen after the earlier powerup step.
>> +	/* This step MUST happen after the earlier powerup step */
>>  	pvr2_i2c_core_init(hdw);
>>  	if (!pvr2_hdw_dev_ok(hdw)) return;
>>  
>> +	/* Reset demod only on Hauppauge 160xxx platform */
>> +	if (hdw->usb_dev->descriptor.idVendor == 0x2040 &&
>> +	    (hdw->usb_dev->descriptor.idProduct == 0x7502 ||
>> +	     hdw->usb_dev->descriptor.idProduct == 0x7510)) {
> These need le16_to_cpu() else it will not work on big-endian machines.



Are you sure about this? This isn't doing byte order comparison, this is
a simple number equivalence. The compiler should be taking the two byte
hex values, and inserting them into memory however the architecture
dictates, correct? All constant values are interpreted by the compiler
as little endian, but they're stored based on endianess.





>
>> +		pr_info("%s(): resetting 160xxx demod\n", __func__);
>> +		/* TODO: not sure this is proper place to reset once only */
>> +		pvr2_issue_simple_cmd(hdw,
>> +				     FX2CMD_HCW_DEMOD_RESET_PIN |
>> +				     (1 << 8) |
>> +				     ((0) << 16));
>> +		msleep(10);
> usleep_range() is preferred (for delays <= 10), I think. Maybe 10ms is too
> long anyway and msleep(1) is enough.
>
>> +		pvr2_issue_simple_cmd(hdw,
>> +				     FX2CMD_HCW_DEMOD_RESET_PIN |
>> +				     (1 << 8) |
>> +				     ((1) << 16));
>> +		msleep(10);
>> +	}
>> +
>>  	pvr2_hdw_load_modules(hdw);
>>  	if (!pvr2_hdw_dev_ok(hdw)) return;
>>  
>> @@ -4011,6 +4031,20 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
>>  static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff)
>>  {
>>  	hdw->flag_ok = !0;
>> +
>> +	/* Use this for Hauppauge 160xxx only */
>> +	if (hdw->usb_dev->descriptor.idVendor == 0x2040 &&
>> +	    (hdw->usb_dev->descriptor.idProduct == 0x7502 ||
>> +	     hdw->usb_dev->descriptor.idProduct == 0x7510)) {
> Same as above. le16_to_cpu() needed.


Same comment here. The rest of your concerns have been handled.

I'm pushing up a v5 of this series now, without the le16_to_cpu bit
done, until that detail is reviewed again.

Cheers,

Brad




>
>> +		pr_debug("%s(): resetting demod on Hauppauge 160xxx platform skipped\n",
>> +			__func__);
>> +		/* Can't reset 160xxx or it will trash Demod tristate */
>> +		return pvr2_issue_simple_cmd(hdw,
>> +				     FX2CMD_HCW_MAKO_SLEEP_PIN |
>> +				     (1 << 8) |
>> +				     ((onoff ? 1 : 0) << 16));
>> +	}
>> +
>>  	return pvr2_issue_simple_cmd(hdw,
>>  				     FX2CMD_HCW_DEMOD_RESETIN |
>>  				     (1 << 8) |
>> -- 
>> 2.7.4


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

* Re: [PATCH v4 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices
  2019-05-31 17:20         ` Brad Love
@ 2019-05-31 18:25           ` Brad Love
  2019-05-31 21:30           ` Sean Young
  1 sibling, 0 replies; 36+ messages in thread
From: Brad Love @ 2019-05-31 18:25 UTC (permalink / raw)
  To: Brad Love, Sean Young; +Cc: linux-media

Hi Sean,

Discussed this with Mauro on irc. I went ahead and made the le16_to_cpu
fixes and set up v6. The series should be good to go now.

Cheers,

Brad


On 31/05/2019 12.20, Brad Love wrote:
> Hi Shawn,
>
> Just found time to get back to this. I fixed all the checkpatch strict
> warnings, no problem. Then I noticed a few comments of yours that I
> somehow missed first time around. I've replied inline to those.
>
>
> On 05/04/2019 10.24, Sean Young wrote:
>> On Wed, Feb 27, 2019 at 01:16:06PM -0600, Brad Love wrote:
>>> Includes support to identify and use two Hauppauge device.
>>> HVR-1955:
>>> - LGDT3306a ATSC/QAM demod
>>> - si2177 tuner
>>> - cx25840 decoder for analog tv/composite/s-video/audio
>>>
>>> HVR-1975 dual-frontend:
>>> - LGDT3306a ATSC/QAM demod
>>> - si2168 DVB-C/T/T2 demod
>>> - si2177 tuner
>>> - cx25840 decoder for analog tv/composite/s-video/audio
>>>
>>> Signed-off-by: Brad Love <brad@nextdimension.cc>
>> First of all there are bunch of checkpatch.pl --strict warnings and checks
>> that need resolving.
>>
>>> ---
>>> Since v2:
>>> - Fix build with VIDEO_PVRUSB2_DVB enabled
>>> Changes since v1:
>>> - Fix build with VIDEO_PVRUSB2_DVB disabled
>>> - Insert 160xxx code lower, so 75xxx profile is not split
>>> - Reorganize 160xxx board profile
>>> - Share config where possible
>>>
>>>  drivers/media/usb/pvrusb2/Kconfig               |   2 +
>>>  drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c |  25 ++++
>>>  drivers/media/usb/pvrusb2/pvrusb2-devattr.c     | 164 ++++++++++++++++++++++++
>>>  drivers/media/usb/pvrusb2/pvrusb2-devattr.h     |   1 +
>>>  drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h     |   4 +
>>>  drivers/media/usb/pvrusb2/pvrusb2-hdw.c         |  36 +++++-
>>>  6 files changed, 231 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/media/usb/pvrusb2/Kconfig b/drivers/media/usb/pvrusb2/Kconfig
>>> index 1ad913f..144631c 100644
>>> --- a/drivers/media/usb/pvrusb2/Kconfig
>>> +++ b/drivers/media/usb/pvrusb2/Kconfig
>>> @@ -40,6 +40,8 @@ config VIDEO_PVRUSB2_DVB
>>>  	select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT
>>>  	select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
>>>  	select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT
>>> +	select DVB_LGDT3306A if MEDIA_SUBDRV_AUTOSELECT
>>> +	select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
>>>  	select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
>>>  	select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
>>>  	select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
>>> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
>>> index d5bec0f..36016ab 100644
>>> --- a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
>>> +++ b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
>>> @@ -111,10 +111,35 @@ static const struct routing_scheme routing_defav400 = {
>>>  	.cnt = ARRAY_SIZE(routing_schemeav400),
>>>  };
>>>  
>>> +static const struct routing_scheme_item routing_scheme160xxx[] = {
>>> +	[PVR2_CVAL_INPUT_TV] = {
>>> +		.vid = CX25840_COMPOSITE7,
>>> +		.aud = CX25840_AUDIO8,
>>> +	},
>>> +	[PVR2_CVAL_INPUT_RADIO] = {
>>> +		.vid = CX25840_COMPOSITE4,
>>> +		.aud = CX25840_AUDIO6,
>>> +	},
>>> +	[PVR2_CVAL_INPUT_COMPOSITE] = {
>>> +		.vid = CX25840_COMPOSITE3,
>>> +		.aud = CX25840_AUDIO_SERIAL,
>>> +	},
>>> +	[PVR2_CVAL_INPUT_SVIDEO] = {
>>> +		.vid = CX25840_SVIDEO1,
>>> +		.aud = CX25840_AUDIO_SERIAL,
>>> +	},
>>> +};
>>> +
>>> +static const struct routing_scheme routing_def160xxx = {
>>> +	.def = routing_scheme160xxx,
>>> +	.cnt = ARRAY_SIZE(routing_scheme160xxx),
>>> +};
>>> +
>>>  static const struct routing_scheme *routing_schemes[] = {
>>>  	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
>>>  	[PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv,
>>>  	[PVR2_ROUTING_SCHEME_AV400] = &routing_defav400,
>>> +	[PVR2_ROUTING_SCHEME_HAUP160XXX] = &routing_def160xxx,
>>>  };
>>>  
>>>  void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
>>> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
>>> index ef36b62..97b4fc8 100644
>>> --- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
>>> +++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
>>> @@ -37,6 +37,9 @@ pvr2_device_desc structures.
>>>  #include "tda18271.h"
>>>  #include "tda8290.h"
>>>  #include "tuner-simple.h"
>>> +#include "si2157.h"
>>> +#include "lgdt3306a.h"
>>> +#include "si2168.h"
>>>  #endif
>>>  
>>>  
>>> @@ -525,7 +528,164 @@ static const struct pvr2_device_desc pvr2_device_751xx = {
>>>  #endif
>>>  };
>>>  
>>> +/*------------------------------------------------------------------------*/
>>> +/*    Hauppauge PVR-USB2 Model 160000 / 160111 -- HVR-1955 / HVR-1975     */
>>> +
>>> +#ifdef CONFIG_VIDEO_PVRUSB2_DVB
>>> +static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap);
>>> +static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap);
>>> +static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap);
>>> +static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap);
>>> +
>>> +static const struct pvr2_dvb_props pvr2_160000_dvb_props = {
>>> +	.frontend_attach = pvr2_dual_fe_attach,
>>> +	.tuner_attach    = pvr2_si2157_attach,
>>> +};
>> Newline.
>>
>>> +static const struct pvr2_dvb_props pvr2_160111_dvb_props = {
>>> +	.frontend_attach = pvr2_lgdt3306a_attach,
>>> +	.tuner_attach    = pvr2_si2157_attach,
>>> +};
>>> +
>>> +static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
>>> +{
>>> +	struct si2157_config si2157_config = {};
>>> +
>>> +	si2157_config.inversion = 1;
>>> +	si2157_config.fe = adap->fe[0];
>>> +
>>> +	adap->i2c_client_tuner = dvb_module_probe("si2157", "si2177",
>>> +						&adap->channel.hdw->i2c_adap,
>>> +						0x60, &si2157_config);
>> Indentation.
>>
>>> +
>>> +	if (!adap->i2c_client_tuner)
>>> +		return -ENODEV;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap)
>>> +{
>>> +	struct si2168_config si2168_config = {};
>>> +	struct i2c_adapter *adapter;
>>> +
>>> +	pr_debug("%s()\n", __func__);
>>> +
>>> +	si2168_config.fe = &adap->fe[1];
>>> +	si2168_config.i2c_adapter = &adapter;
>>> +	si2168_config.ts_mode = SI2168_TS_PARALLEL; /*2, 1-serial, 2-parallel.*/
>>> +	si2168_config.ts_clock_gapped = 1; /*0-disabled, 1-enabled.*/
>>> +	si2168_config.ts_clock_inv = 0; /*0-not-invert, 1-invert*/
>>> +	si2168_config.spectral_inversion = 1; /*0-not-invert, 1-invert*/
>>> +
>>> +	adap->i2c_client_demod[1] = dvb_module_probe("si2168", NULL,
>>> +						&adap->channel.hdw->i2c_adap,
>>> +						0x64, &si2168_config);
>> Indentation.
>>
>>>  
>>> +	if (!adap->i2c_client_demod[1])
>>> +		return -ENODEV;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
>>> +{
>>> +	struct lgdt3306a_config lgdt3306a_config;
>>> +	struct i2c_adapter *adapter;
>>> +
>>> +	pr_debug("%s()\n", __func__);
>>> +
>>> +	lgdt3306a_config.fe = &adap->fe[0];
>>> +	lgdt3306a_config.i2c_adapter = &adapter;
>>> +	lgdt3306a_config.deny_i2c_rptr = 1;
>>> +	lgdt3306a_config.spectral_inversion = 1;
>>> +	lgdt3306a_config.qam_if_khz = 4000;
>>> +	lgdt3306a_config.vsb_if_khz = 3250;
>>> +	lgdt3306a_config.mpeg_mode = LGDT3306A_MPEG_PARALLEL;
>>> +	lgdt3306a_config.tpclk_edge = LGDT3306A_TPCLK_FALLING_EDGE;
>>> +	lgdt3306a_config.tpvalid_polarity = LGDT3306A_TP_VALID_LOW;
>>> +	lgdt3306a_config.xtalMHz = 25, /* demod clock MHz; 24/25 supported */
>>> +
>>> +	adap->i2c_client_demod[0] = dvb_module_probe("lgdt3306a", NULL,
>>> +						&adap->channel.hdw->i2c_adap,
>>> +						0x59, &lgdt3306a_config);
>>> +
>>> +	if (!adap->i2c_client_demod[0])
>>> +		return -ENODEV;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap)
>>> +{
>>> +	pr_debug("%s()\n", __func__);
>>> +
>>> +	if (pvr2_lgdt3306a_attach(adap) != 0)
>>> +		return -ENODEV;
>>> +
>>> +	if (pvr2_si2168_attach(adap) != 0) {
>>> +		dvb_module_release(adap->i2c_client_demod[0]);
>>> +		return -ENODEV;
>>> +	}
>>> +
>>> +	return 0;
>>> +}
>>> +#endif
>>> +
>>> +#define PVR2_FIRMWARE_160xxx "v4l-pvrusb2-160xxx-01.fw"
>>> +static const char *pvr2_fw1_names_160xxx[] = {
>>> +		PVR2_FIRMWARE_160xxx,
>>> +};
>>> +
>>> +static const struct pvr2_device_client_desc pvr2_cli_160xxx[] = {
>>> +	{ .module_id = PVR2_CLIENT_ID_CX25840 },
>>> +};
>>> +
>>> +static const struct pvr2_device_desc pvr2_device_160000 = {
>>> +		.description = "WinTV HVR-1975 Model 160000",
>>> +		.shortname = "160000",
>>> +		.client_table.lst = pvr2_cli_160xxx,
>>> +		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160xxx),
>>> +		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
>>> +		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
>>> +		.default_tuner_type = TUNER_ABSENT,
>>> +		.flag_has_cx25840 = !0,
>>> +		.flag_has_hauppauge_rom = !0,
>>> +		.flag_has_analogtuner = !0,
>>> +		.flag_has_composite = !0,
>>> +		.flag_has_svideo = !0,
>>> +		.flag_fx2_16kb = !0,
>> Why are we writing 1 in such a way?
>
>
> I did not originate the board profile part. I do see the similar
> notation used throughout this particular driver, but I cannot state the
> rational in setting it like that. In v5 I have this just set these
> properties to 1.
>
>
>
>
>
>>> +		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
>>> +		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
>>> +		.default_std_mask = V4L2_STD_NTSC_M,
>>> +		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
>>> +		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
>>> +#ifdef CONFIG_VIDEO_PVRUSB2_DVB
>>> +		.dvb_props = &pvr2_160000_dvb_props,
>>> +#endif
>>> +};
>> Newline needed.
>>
>>> +static const struct pvr2_device_desc pvr2_device_160111 = {
>>> +		.description = "WinTV HVR-1955 Model 160111",
>>> +		.shortname = "160111",
>>> +		.client_table.lst = pvr2_cli_160xxx,
>>> +		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160xxx),
>>> +		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
>>> +		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
>>> +		.default_tuner_type = TUNER_ABSENT,
>>> +		.flag_has_cx25840 = !0,
>>> +		.flag_has_hauppauge_rom = !0,
>>> +		.flag_has_analogtuner = !0,
>>> +		.flag_has_composite = !0,
>>> +		.flag_has_svideo = !0,
>>> +		.flag_fx2_16kb = !0,
>>> +		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
>>> +		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
>>> +		.default_std_mask = V4L2_STD_NTSC_M,
>>> +		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
>>> +		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
>>> +#ifdef CONFIG_VIDEO_PVRUSB2_DVB
>>> +		.dvb_props = &pvr2_160111_dvb_props,
>>> +#endif
>>> +};
>>>  
>>>  /*------------------------------------------------------------------------*/
>>>  
>>> @@ -552,6 +712,10 @@ struct usb_device_id pvr2_device_table[] = {
>>>  	  .driver_info = (kernel_ulong_t)&pvr2_device_751xx},
>>>  	{ USB_DEVICE(0x0ccd, 0x0039),
>>>  	  .driver_info = (kernel_ulong_t)&pvr2_device_av400},
>>> +	{ USB_DEVICE(0x2040, 0x7502),
>>> +	  .driver_info = (kernel_ulong_t)&pvr2_device_160111},
>>> +	{ USB_DEVICE(0x2040, 0x7510),
>>> +	  .driver_info = (kernel_ulong_t)&pvr2_device_160000},
>>>  	{ }
>>>  };
>>>  
>>> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.h b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
>>> index c1e7d48..ea0b2bf 100644
>>> --- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
>>> +++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
>>> @@ -66,6 +66,7 @@ struct pvr2_string_table {
>>>  #define PVR2_ROUTING_SCHEME_GOTVIEW 1
>>>  #define PVR2_ROUTING_SCHEME_ONAIR 2
>>>  #define PVR2_ROUTING_SCHEME_AV400 3
>>> +#define PVR2_ROUTING_SCHEME_HAUP160XXX 4
>>>  
>>>  #define PVR2_DIGITAL_SCHEME_NONE 0
>>>  #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
>>> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
>>> index 0a01de4..640b033 100644
>>> --- a/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
>>> +++ b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
>>> @@ -38,6 +38,10 @@
>>>  
>>>  #define FX2CMD_FWPOST1          0x52u
>>>  
>>> +/* These 2 only exist on Model 160xxx */
>>> +#define FX2CMD_HCW_DEMOD_RESET_PIN 0xd4u
>>> +#define FX2CMD_HCW_MAKO_SLEEP_PIN  0xd5u
>>> +
>>>  #define FX2CMD_POWER_OFF        0xdcu
>>>  #define FX2CMD_POWER_ON         0xdeu
>>>  
>>> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
>>> index 446a999..ab9e822 100644
>>> --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
>>> +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
>>> @@ -316,6 +316,8 @@ static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = {
>>>  	{FX2CMD_ONAIR_DTV_STREAMING_OFF, "onair dtv stream off"},
>>>  	{FX2CMD_ONAIR_DTV_POWER_ON, "onair dtv power on"},
>>>  	{FX2CMD_ONAIR_DTV_POWER_OFF, "onair dtv power off"},
>>> +	{FX2CMD_HCW_DEMOD_RESET_PIN, "hcw demod reset pin"},
>>> +	{FX2CMD_HCW_MAKO_SLEEP_PIN, "hcw mako sleep pin"},
>>>  };
>>>  
>>>  
>>> @@ -2137,10 +2139,28 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
>>>  				      ((0) << 16));
>>>  	}
>>>  
>>> -	// This step MUST happen after the earlier powerup step.
>>> +	/* This step MUST happen after the earlier powerup step */
>>>  	pvr2_i2c_core_init(hdw);
>>>  	if (!pvr2_hdw_dev_ok(hdw)) return;
>>>  
>>> +	/* Reset demod only on Hauppauge 160xxx platform */
>>> +	if (hdw->usb_dev->descriptor.idVendor == 0x2040 &&
>>> +	    (hdw->usb_dev->descriptor.idProduct == 0x7502 ||
>>> +	     hdw->usb_dev->descriptor.idProduct == 0x7510)) {
>> These need le16_to_cpu() else it will not work on big-endian machines.
>
>
> Are you sure about this? This isn't doing byte order comparison, this is
> a simple number equivalence. The compiler should be taking the two byte
> hex values, and inserting them into memory however the architecture
> dictates, correct? All constant values are interpreted by the compiler
> as little endian, but they're stored based on endianess.
>
>
>
>
>
>>> +		pr_info("%s(): resetting 160xxx demod\n", __func__);
>>> +		/* TODO: not sure this is proper place to reset once only */
>>> +		pvr2_issue_simple_cmd(hdw,
>>> +				     FX2CMD_HCW_DEMOD_RESET_PIN |
>>> +				     (1 << 8) |
>>> +				     ((0) << 16));
>>> +		msleep(10);
>> usleep_range() is preferred (for delays <= 10), I think. Maybe 10ms is too
>> long anyway and msleep(1) is enough.
>>
>>> +		pvr2_issue_simple_cmd(hdw,
>>> +				     FX2CMD_HCW_DEMOD_RESET_PIN |
>>> +				     (1 << 8) |
>>> +				     ((1) << 16));
>>> +		msleep(10);
>>> +	}
>>> +
>>>  	pvr2_hdw_load_modules(hdw);
>>>  	if (!pvr2_hdw_dev_ok(hdw)) return;
>>>  
>>> @@ -4011,6 +4031,20 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
>>>  static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff)
>>>  {
>>>  	hdw->flag_ok = !0;
>>> +
>>> +	/* Use this for Hauppauge 160xxx only */
>>> +	if (hdw->usb_dev->descriptor.idVendor == 0x2040 &&
>>> +	    (hdw->usb_dev->descriptor.idProduct == 0x7502 ||
>>> +	     hdw->usb_dev->descriptor.idProduct == 0x7510)) {
>> Same as above. le16_to_cpu() needed.
>
> Same comment here. The rest of your concerns have been handled.
>
> I'm pushing up a v5 of this series now, without the le16_to_cpu bit
> done, until that detail is reviewed again.
>
> Cheers,
>
> Brad
>
>
>
>
>>> +		pr_debug("%s(): resetting demod on Hauppauge 160xxx platform skipped\n",
>>> +			__func__);
>>> +		/* Can't reset 160xxx or it will trash Demod tristate */
>>> +		return pvr2_issue_simple_cmd(hdw,
>>> +				     FX2CMD_HCW_MAKO_SLEEP_PIN |
>>> +				     (1 << 8) |
>>> +				     ((onoff ? 1 : 0) << 16));
>>> +	}
>>> +
>>>  	return pvr2_issue_simple_cmd(hdw,
>>>  				     FX2CMD_HCW_DEMOD_RESETIN |
>>>  				     (1 << 8) |
>>> -- 
>>> 2.7.4

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

* Re: [PATCH v4 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices
  2019-05-31 17:20         ` Brad Love
  2019-05-31 18:25           ` Brad Love
@ 2019-05-31 21:30           ` Sean Young
  1 sibling, 0 replies; 36+ messages in thread
From: Sean Young @ 2019-05-31 21:30 UTC (permalink / raw)
  To: Brad Love; +Cc: linux-media

Hi Brad,

On Fri, May 31, 2019 at 12:20:45PM -0500, Brad Love wrote:
> Hi Shawn,
> 
> Just found time to get back to this. I fixed all the checkpatch strict
> warnings, no problem. Then I noticed a few comments of yours that I
> somehow missed first time around. I've replied inline to those.
> 
> 
> On 05/04/2019 10.24, Sean Young wrote:
> > On Wed, Feb 27, 2019 at 01:16:06PM -0600, Brad Love wrote:
> >> Includes support to identify and use two Hauppauge device.
> >> HVR-1955:
> >> - LGDT3306a ATSC/QAM demod
> >> - si2177 tuner
> >> - cx25840 decoder for analog tv/composite/s-video/audio
> >>
> >> HVR-1975 dual-frontend:
> >> - LGDT3306a ATSC/QAM demod
> >> - si2168 DVB-C/T/T2 demod
> >> - si2177 tuner
> >> - cx25840 decoder for analog tv/composite/s-video/audio
> >>
> >> Signed-off-by: Brad Love <brad@nextdimension.cc>
> > First of all there are bunch of checkpatch.pl --strict warnings and checks
> > that need resolving.
> >
> >> ---
> >> Since v2:
> >> - Fix build with VIDEO_PVRUSB2_DVB enabled
> >> Changes since v1:
> >> - Fix build with VIDEO_PVRUSB2_DVB disabled
> >> - Insert 160xxx code lower, so 75xxx profile is not split
> >> - Reorganize 160xxx board profile
> >> - Share config where possible
> >>
> >>  drivers/media/usb/pvrusb2/Kconfig               |   2 +
> >>  drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c |  25 ++++
> >>  drivers/media/usb/pvrusb2/pvrusb2-devattr.c     | 164 ++++++++++++++++++++++++
> >>  drivers/media/usb/pvrusb2/pvrusb2-devattr.h     |   1 +
> >>  drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h     |   4 +
> >>  drivers/media/usb/pvrusb2/pvrusb2-hdw.c         |  36 +++++-
> >>  6 files changed, 231 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/media/usb/pvrusb2/Kconfig b/drivers/media/usb/pvrusb2/Kconfig
> >> index 1ad913f..144631c 100644
> >> --- a/drivers/media/usb/pvrusb2/Kconfig
> >> +++ b/drivers/media/usb/pvrusb2/Kconfig
> >> @@ -40,6 +40,8 @@ config VIDEO_PVRUSB2_DVB
> >>  	select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT
> >>  	select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
> >>  	select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT
> >> +	select DVB_LGDT3306A if MEDIA_SUBDRV_AUTOSELECT
> >> +	select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
> >>  	select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
> >>  	select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
> >>  	select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
> >> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
> >> index d5bec0f..36016ab 100644
> >> --- a/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
> >> +++ b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
> >> @@ -111,10 +111,35 @@ static const struct routing_scheme routing_defav400 = {
> >>  	.cnt = ARRAY_SIZE(routing_schemeav400),
> >>  };
> >>  
> >> +static const struct routing_scheme_item routing_scheme160xxx[] = {
> >> +	[PVR2_CVAL_INPUT_TV] = {
> >> +		.vid = CX25840_COMPOSITE7,
> >> +		.aud = CX25840_AUDIO8,
> >> +	},
> >> +	[PVR2_CVAL_INPUT_RADIO] = {
> >> +		.vid = CX25840_COMPOSITE4,
> >> +		.aud = CX25840_AUDIO6,
> >> +	},
> >> +	[PVR2_CVAL_INPUT_COMPOSITE] = {
> >> +		.vid = CX25840_COMPOSITE3,
> >> +		.aud = CX25840_AUDIO_SERIAL,
> >> +	},
> >> +	[PVR2_CVAL_INPUT_SVIDEO] = {
> >> +		.vid = CX25840_SVIDEO1,
> >> +		.aud = CX25840_AUDIO_SERIAL,
> >> +	},
> >> +};
> >> +
> >> +static const struct routing_scheme routing_def160xxx = {
> >> +	.def = routing_scheme160xxx,
> >> +	.cnt = ARRAY_SIZE(routing_scheme160xxx),
> >> +};
> >> +
> >>  static const struct routing_scheme *routing_schemes[] = {
> >>  	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
> >>  	[PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv,
> >>  	[PVR2_ROUTING_SCHEME_AV400] = &routing_defav400,
> >> +	[PVR2_ROUTING_SCHEME_HAUP160XXX] = &routing_def160xxx,
> >>  };
> >>  
> >>  void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
> >> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
> >> index ef36b62..97b4fc8 100644
> >> --- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
> >> +++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
> >> @@ -37,6 +37,9 @@ pvr2_device_desc structures.
> >>  #include "tda18271.h"
> >>  #include "tda8290.h"
> >>  #include "tuner-simple.h"
> >> +#include "si2157.h"
> >> +#include "lgdt3306a.h"
> >> +#include "si2168.h"
> >>  #endif
> >>  
> >>  
> >> @@ -525,7 +528,164 @@ static const struct pvr2_device_desc pvr2_device_751xx = {
> >>  #endif
> >>  };
> >>  
> >> +/*------------------------------------------------------------------------*/
> >> +/*    Hauppauge PVR-USB2 Model 160000 / 160111 -- HVR-1955 / HVR-1975     */
> >> +
> >> +#ifdef CONFIG_VIDEO_PVRUSB2_DVB
> >> +static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap);
> >> +static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap);
> >> +static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap);
> >> +static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap);
> >> +
> >> +static const struct pvr2_dvb_props pvr2_160000_dvb_props = {
> >> +	.frontend_attach = pvr2_dual_fe_attach,
> >> +	.tuner_attach    = pvr2_si2157_attach,
> >> +};
> > Newline.
> >
> >> +static const struct pvr2_dvb_props pvr2_160111_dvb_props = {
> >> +	.frontend_attach = pvr2_lgdt3306a_attach,
> >> +	.tuner_attach    = pvr2_si2157_attach,
> >> +};
> >> +
> >> +static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
> >> +{
> >> +	struct si2157_config si2157_config = {};
> >> +
> >> +	si2157_config.inversion = 1;
> >> +	si2157_config.fe = adap->fe[0];
> >> +
> >> +	adap->i2c_client_tuner = dvb_module_probe("si2157", "si2177",
> >> +						&adap->channel.hdw->i2c_adap,
> >> +						0x60, &si2157_config);
> > Indentation.
> >
> >> +
> >> +	if (!adap->i2c_client_tuner)
> >> +		return -ENODEV;
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap)
> >> +{
> >> +	struct si2168_config si2168_config = {};
> >> +	struct i2c_adapter *adapter;
> >> +
> >> +	pr_debug("%s()\n", __func__);
> >> +
> >> +	si2168_config.fe = &adap->fe[1];
> >> +	si2168_config.i2c_adapter = &adapter;
> >> +	si2168_config.ts_mode = SI2168_TS_PARALLEL; /*2, 1-serial, 2-parallel.*/
> >> +	si2168_config.ts_clock_gapped = 1; /*0-disabled, 1-enabled.*/
> >> +	si2168_config.ts_clock_inv = 0; /*0-not-invert, 1-invert*/
> >> +	si2168_config.spectral_inversion = 1; /*0-not-invert, 1-invert*/
> >> +
> >> +	adap->i2c_client_demod[1] = dvb_module_probe("si2168", NULL,
> >> +						&adap->channel.hdw->i2c_adap,
> >> +						0x64, &si2168_config);
> > Indentation.
> >
> >>  
> >> +	if (!adap->i2c_client_demod[1])
> >> +		return -ENODEV;
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
> >> +{
> >> +	struct lgdt3306a_config lgdt3306a_config;
> >> +	struct i2c_adapter *adapter;
> >> +
> >> +	pr_debug("%s()\n", __func__);
> >> +
> >> +	lgdt3306a_config.fe = &adap->fe[0];
> >> +	lgdt3306a_config.i2c_adapter = &adapter;
> >> +	lgdt3306a_config.deny_i2c_rptr = 1;
> >> +	lgdt3306a_config.spectral_inversion = 1;
> >> +	lgdt3306a_config.qam_if_khz = 4000;
> >> +	lgdt3306a_config.vsb_if_khz = 3250;
> >> +	lgdt3306a_config.mpeg_mode = LGDT3306A_MPEG_PARALLEL;
> >> +	lgdt3306a_config.tpclk_edge = LGDT3306A_TPCLK_FALLING_EDGE;
> >> +	lgdt3306a_config.tpvalid_polarity = LGDT3306A_TP_VALID_LOW;
> >> +	lgdt3306a_config.xtalMHz = 25, /* demod clock MHz; 24/25 supported */
> >> +
> >> +	adap->i2c_client_demod[0] = dvb_module_probe("lgdt3306a", NULL,
> >> +						&adap->channel.hdw->i2c_adap,
> >> +						0x59, &lgdt3306a_config);
> >> +
> >> +	if (!adap->i2c_client_demod[0])
> >> +		return -ENODEV;
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap)
> >> +{
> >> +	pr_debug("%s()\n", __func__);
> >> +
> >> +	if (pvr2_lgdt3306a_attach(adap) != 0)
> >> +		return -ENODEV;
> >> +
> >> +	if (pvr2_si2168_attach(adap) != 0) {
> >> +		dvb_module_release(adap->i2c_client_demod[0]);
> >> +		return -ENODEV;
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> >> +#endif
> >> +
> >> +#define PVR2_FIRMWARE_160xxx "v4l-pvrusb2-160xxx-01.fw"
> >> +static const char *pvr2_fw1_names_160xxx[] = {
> >> +		PVR2_FIRMWARE_160xxx,
> >> +};
> >> +
> >> +static const struct pvr2_device_client_desc pvr2_cli_160xxx[] = {
> >> +	{ .module_id = PVR2_CLIENT_ID_CX25840 },
> >> +};
> >> +
> >> +static const struct pvr2_device_desc pvr2_device_160000 = {
> >> +		.description = "WinTV HVR-1975 Model 160000",
> >> +		.shortname = "160000",
> >> +		.client_table.lst = pvr2_cli_160xxx,
> >> +		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160xxx),
> >> +		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
> >> +		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
> >> +		.default_tuner_type = TUNER_ABSENT,
> >> +		.flag_has_cx25840 = !0,
> >> +		.flag_has_hauppauge_rom = !0,
> >> +		.flag_has_analogtuner = !0,
> >> +		.flag_has_composite = !0,
> >> +		.flag_has_svideo = !0,
> >> +		.flag_fx2_16kb = !0,
> > Why are we writing 1 in such a way?
> 
> 
> 
> I did not originate the board profile part. I do see the similar
> notation used throughout this particular driver, but I cannot state the
> rational in setting it like that. In v5 I have this just set these
> properties to 1.

Sure, actually that was not so much a review as a general question. I
should have said so. 

> >> +		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
> >> +		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
> >> +		.default_std_mask = V4L2_STD_NTSC_M,
> >> +		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
> >> +		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
> >> +#ifdef CONFIG_VIDEO_PVRUSB2_DVB
> >> +		.dvb_props = &pvr2_160000_dvb_props,
> >> +#endif
> >> +};
> > Newline needed.
> >
> >> +static const struct pvr2_device_desc pvr2_device_160111 = {
> >> +		.description = "WinTV HVR-1955 Model 160111",
> >> +		.shortname = "160111",
> >> +		.client_table.lst = pvr2_cli_160xxx,
> >> +		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160xxx),
> >> +		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
> >> +		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
> >> +		.default_tuner_type = TUNER_ABSENT,
> >> +		.flag_has_cx25840 = !0,
> >> +		.flag_has_hauppauge_rom = !0,
> >> +		.flag_has_analogtuner = !0,
> >> +		.flag_has_composite = !0,
> >> +		.flag_has_svideo = !0,
> >> +		.flag_fx2_16kb = !0,
> >> +		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
> >> +		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
> >> +		.default_std_mask = V4L2_STD_NTSC_M,
> >> +		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
> >> +		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
> >> +#ifdef CONFIG_VIDEO_PVRUSB2_DVB
> >> +		.dvb_props = &pvr2_160111_dvb_props,
> >> +#endif
> >> +};
> >>  
> >>  /*------------------------------------------------------------------------*/
> >>  
> >> @@ -552,6 +712,10 @@ struct usb_device_id pvr2_device_table[] = {
> >>  	  .driver_info = (kernel_ulong_t)&pvr2_device_751xx},
> >>  	{ USB_DEVICE(0x0ccd, 0x0039),
> >>  	  .driver_info = (kernel_ulong_t)&pvr2_device_av400},
> >> +	{ USB_DEVICE(0x2040, 0x7502),
> >> +	  .driver_info = (kernel_ulong_t)&pvr2_device_160111},
> >> +	{ USB_DEVICE(0x2040, 0x7510),
> >> +	  .driver_info = (kernel_ulong_t)&pvr2_device_160000},
> >>  	{ }
> >>  };
> >>  
> >> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.h b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
> >> index c1e7d48..ea0b2bf 100644
> >> --- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
> >> +++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
> >> @@ -66,6 +66,7 @@ struct pvr2_string_table {
> >>  #define PVR2_ROUTING_SCHEME_GOTVIEW 1
> >>  #define PVR2_ROUTING_SCHEME_ONAIR 2
> >>  #define PVR2_ROUTING_SCHEME_AV400 3
> >> +#define PVR2_ROUTING_SCHEME_HAUP160XXX 4
> >>  
> >>  #define PVR2_DIGITAL_SCHEME_NONE 0
> >>  #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
> >> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
> >> index 0a01de4..640b033 100644
> >> --- a/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
> >> +++ b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
> >> @@ -38,6 +38,10 @@
> >>  
> >>  #define FX2CMD_FWPOST1          0x52u
> >>  
> >> +/* These 2 only exist on Model 160xxx */
> >> +#define FX2CMD_HCW_DEMOD_RESET_PIN 0xd4u
> >> +#define FX2CMD_HCW_MAKO_SLEEP_PIN  0xd5u
> >> +
> >>  #define FX2CMD_POWER_OFF        0xdcu
> >>  #define FX2CMD_POWER_ON         0xdeu
> >>  
> >> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
> >> index 446a999..ab9e822 100644
> >> --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
> >> +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
> >> @@ -316,6 +316,8 @@ static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = {
> >>  	{FX2CMD_ONAIR_DTV_STREAMING_OFF, "onair dtv stream off"},
> >>  	{FX2CMD_ONAIR_DTV_POWER_ON, "onair dtv power on"},
> >>  	{FX2CMD_ONAIR_DTV_POWER_OFF, "onair dtv power off"},
> >> +	{FX2CMD_HCW_DEMOD_RESET_PIN, "hcw demod reset pin"},
> >> +	{FX2CMD_HCW_MAKO_SLEEP_PIN, "hcw mako sleep pin"},
> >>  };
> >>  
> >>  
> >> @@ -2137,10 +2139,28 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
> >>  				      ((0) << 16));
> >>  	}
> >>  
> >> -	// This step MUST happen after the earlier powerup step.
> >> +	/* This step MUST happen after the earlier powerup step */
> >>  	pvr2_i2c_core_init(hdw);
> >>  	if (!pvr2_hdw_dev_ok(hdw)) return;
> >>  
> >> +	/* Reset demod only on Hauppauge 160xxx platform */
> >> +	if (hdw->usb_dev->descriptor.idVendor == 0x2040 &&
> >> +	    (hdw->usb_dev->descriptor.idProduct == 0x7502 ||
> >> +	     hdw->usb_dev->descriptor.idProduct == 0x7510)) {
> > These need le16_to_cpu() else it will not work on big-endian machines.
> 
> 
> 
> Are you sure about this? This isn't doing byte order comparison, this is
> a simple number equivalence. The compiler should be taking the two byte
> hex values, and inserting them into memory however the architecture
> dictates, correct? All constant values are interpreted by the compiler
> as little endian, but they're stored based on endianess.

Yes. Values don't have endianness, only memory loads/stores. So the
constant doesn't have endianness but the fields idProduct and idVendor do.
Those fields are __le16. 

__le16 is a typedef to __u16. The compiler won't do endian conversion
for you. The __le16 typedef is just there for static analysis.

If you run sparse you should see an warning (make C=1).

> >> +		pr_info("%s(): resetting 160xxx demod\n", __func__);
> >> +		/* TODO: not sure this is proper place to reset once only */
> >> +		pvr2_issue_simple_cmd(hdw,
> >> +				     FX2CMD_HCW_DEMOD_RESET_PIN |
> >> +				     (1 << 8) |
> >> +				     ((0) << 16));
> >> +		msleep(10);
> > usleep_range() is preferred (for delays <= 10), I think. Maybe 10ms is too
> > long anyway and msleep(1) is enough.
> >
> >> +		pvr2_issue_simple_cmd(hdw,
> >> +				     FX2CMD_HCW_DEMOD_RESET_PIN |
> >> +				     (1 << 8) |
> >> +				     ((1) << 16));
> >> +		msleep(10);
> >> +	}
> >> +
> >>  	pvr2_hdw_load_modules(hdw);
> >>  	if (!pvr2_hdw_dev_ok(hdw)) return;
> >>  
> >> @@ -4011,6 +4031,20 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
> >>  static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff)
> >>  {
> >>  	hdw->flag_ok = !0;
> >> +
> >> +	/* Use this for Hauppauge 160xxx only */
> >> +	if (hdw->usb_dev->descriptor.idVendor == 0x2040 &&
> >> +	    (hdw->usb_dev->descriptor.idProduct == 0x7502 ||
> >> +	     hdw->usb_dev->descriptor.idProduct == 0x7510)) {
> > Same as above. le16_to_cpu() needed.
> 
> 
> Same comment here. The rest of your concerns have been handled.
> 
> I'm pushing up a v5 of this series now, without the le16_to_cpu bit
> done, until that detail is reviewed again.


Sean

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

end of thread, back to index

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-20 21:57 [PATCH 0/4] Add Hauppauge HVR1955/1975 devices Brad Love
2018-12-20 21:57 ` [PATCH 1/4] si2157: add detection of si2177 tuner Brad Love
2019-01-09 17:36   ` Antti Palosaari
2019-01-15 16:32     ` Brad Love
2019-01-15 17:23       ` Mauro Carvalho Chehab
2018-12-20 21:57 ` [PATCH 2/4] pvrusb2: Add multiple dvb frontend support Brad Love
2018-12-20 21:57 ` [PATCH 3/4] pvrusb2: Add i2c client demod/tuner support Brad Love
2018-12-20 21:57 ` [PATCH 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
2018-12-21  4:56   ` kbuild test robot
2018-12-21  4:57   ` kbuild test robot
2018-12-21 19:40 ` [PATCH v2 0/4] " Brad Love
2018-12-21 19:40   ` [PATCH v2 1/4] si2157: add detection of si2177 tuner Brad Love
2018-12-21 19:40   ` [PATCH v2 2/4] pvrusb2: Add multiple dvb frontend support Brad Love
2018-12-21 19:40   ` [PATCH v2 3/4] pvrusb2: Add i2c client demod/tuner support Brad Love
2018-12-21 19:40   ` [PATCH v2 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
2018-12-22  4:42     ` kbuild test robot
2018-12-22 10:04     ` kbuild test robot
2018-12-24 17:00   ` [PATCH v3 0/4] " Brad Love
2018-12-24 17:00     ` [PATCH v3 1/4] si2157: add detection of si2177 tuner Brad Love
2018-12-24 17:00     ` [PATCH v3 2/4] pvrusb2: Add multiple dvb frontend support Brad Love
2018-12-24 17:00     ` [PATCH v3 3/4] pvrusb2: Add i2c client demod/tuner support Brad Love
2018-12-24 17:00     ` [PATCH v3 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
2019-02-27 19:16   ` [PATCH v4 0/4] " Brad Love
2019-02-27 19:16     ` [PATCH v4 1/4] si2157: add detection of si2177 tuner Brad Love
2019-02-27 19:16     ` [PATCH v4 2/4] pvrusb2: Add multiple dvb frontend support Brad Love
2019-04-05 10:00       ` Sean Young
2019-04-08 18:16         ` Brad Love
2019-02-27 19:16     ` [PATCH v4 3/4] pvrusb2: Add i2c client demod/tuner support Brad Love
2019-02-27 19:16     ` [PATCH v4 4/4] pvrusb2: Add Hauppauge HVR1955/1975 devices Brad Love
2019-04-05 15:24       ` Sean Young
2019-04-05 15:29         ` Sean Young
2019-04-08 18:01           ` Brad Love
2019-04-08 20:17             ` Sean Young
2019-05-31 17:20         ` Brad Love
2019-05-31 18:25           ` Brad Love
2019-05-31 21:30           ` Sean Young

Linux-Media Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-media/0 linux-media/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-media linux-media/ https://lore.kernel.org/linux-media \
		linux-media@vger.kernel.org linux-media@archiver.kernel.org
	public-inbox-index linux-media


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-media


AGPL code for this site: git clone https://public-inbox.org/ public-inbox