[RFC PATCH 2/2] media: dvb-usb-v2: Add support for Geniatech/MyGica A681B and PT682C

Forest Crossman posted 2 patches 16 hours ago
[RFC PATCH 2/2] media: dvb-usb-v2: Add support for Geniatech/MyGica A681B and PT682C
Posted by Forest Crossman 16 hours ago
These devices appear to be approximately the same hardware in different
packages. They both use the MxL692 combination tuner and demodulator,
and take roughly the same configuration parameters.

I say "roughly the same" because while the PT682C needs to have its
MxL692's MPEG clock polatity set to "negative" in order to show a
picture, the Windows driver for the A681B sets the clock polarity to
"positive", and the A681B seems to work regardless of what polarity it's
set to. So since setting the clock polarity to "negative" is necessary
for the PT682C, works for both the PT682C and the A681B, and appears to
be the "popular" configuration used by devices that use this chip, I've
left it set to "negative" for all devices.

Signed-off-by: Forest Crossman <cyrozap@gmail.com>
---
 drivers/media/usb/dvb-usb-v2/Kconfig  |  1 +
 drivers/media/usb/dvb-usb-v2/dvbsky.c | 69 +++++++++++++++++++++++++++
 include/media/dvb-usb-ids.h           |  2 +
 3 files changed, 72 insertions(+)

diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig
index 4eadc9539b4c..02f8d5e2cf11 100644
--- a/drivers/media/usb/dvb-usb-v2/Kconfig
+++ b/drivers/media/usb/dvb-usb-v2/Kconfig
@@ -93,6 +93,7 @@ config DVB_USB_DVBSKY
 	tristate "DVBSky USB support"
 	depends on DVB_USB_V2
 	select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT
+	select DVB_MXL692 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_TS2020 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c
index ceac0ea21dab..4281b0f74736 100644
--- a/drivers/media/usb/dvb-usb-v2/dvbsky.c
+++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c
@@ -7,6 +7,7 @@
 
 #include "dvb_usb.h"
 #include "m88ds3103.h"
+#include "mxl692.h"
 #include "ts2020.h"
 #include "sp2.h"
 #include "si2168.h"
@@ -576,6 +577,37 @@ static int dvbsky_mygica_t230c_attach(struct dvb_usb_adapter *adap)
 	return 0;
 }
 
+static int dvbsky_mygica_mxl692_attach(struct dvb_usb_adapter *adap)
+{
+	struct dvbsky_state *state = adap_to_priv(adap);
+	struct dvb_usb_device *d = adap_to_d(adap);
+	struct mxl692_config mxl692_config = {};
+
+	/* attach demod/tuner combo */
+	mxl692_config.id = 0;
+	mxl692_config.fe = &adap->fe[0];
+
+	mxl692_config.xtal_calibration_enable = 1;
+	mxl692_config.xtal_sharing_enable = 0;
+
+	mxl692_config.mpeg_parallel = 1;
+	mxl692_config.mpeg_sync_pulse_width = 1; /* BYTE */
+	mxl692_config.mpeg3wire_mode_enable = 1;
+	mxl692_config.mpeg_clk_freq = 3; /* 13_5MHZ */
+	mxl692_config.mpeg_pad_drv.pad_drv_mpeg_syn = 3; /* 4X */
+	mxl692_config.mpeg_pad_drv.pad_drv_mpeg_dat = 3;
+	mxl692_config.mpeg_pad_drv.pad_drv_mpeg_val = 3;
+	mxl692_config.mpeg_pad_drv.pad_drv_mpeg_clk = 3;
+
+	state->i2c_client_demod = dvb_module_probe("mxl692", NULL,
+						   &d->i2c_adap,
+						   0x60, &mxl692_config);
+	if (!state->i2c_client_demod)
+		return -ENODEV;
+
+	return 0;
+}
+
 
 static int dvbsky_identify_state(struct dvb_usb_device *d, const char **name)
 {
@@ -587,6 +619,11 @@ static int dvbsky_identify_state(struct dvb_usb_device *d, const char **name)
 		msleep(100);
 		dvbsky_gpio_ctrl(d, 0x80, 1);
 		msleep(50);
+	} else if (le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_MYGICA_A681B) {
+		dvbsky_gpio_ctrl(d, 0x80, 0);
+		msleep(100);
+		dvbsky_gpio_ctrl(d, 0x80, 1);
+		msleep(100);
 	} else {
 		dvbsky_gpio_ctrl(d, 0x04, 1);
 		msleep(20);
@@ -756,6 +793,32 @@ static struct dvb_usb_device_properties mygica_t230c_props = {
 	}
 };
 
+static struct dvb_usb_device_properties mygica_mxl692_props = {
+	.driver_name = KBUILD_MODNAME,
+	.owner = THIS_MODULE,
+	.adapter_nr = adapter_nr,
+	.size_of_priv = sizeof(struct dvbsky_state),
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+	.generic_bulk_ctrl_endpoint_response = 0x81,
+	.generic_bulk_ctrl_delay = DVBSKY_MSG_DELAY,
+
+	.i2c_algo         = &dvbsky_i2c_algo,
+	.frontend_attach  = dvbsky_mygica_mxl692_attach,
+	.frontend_detach  = dvbsky_frontend_detach,
+	.init             = dvbsky_init,
+	.get_rc_config    = dvbsky_get_rc_config,
+	.streaming_ctrl   = dvbsky_streaming_ctrl,
+	.identify_state	  = dvbsky_identify_state,
+
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.stream = DVB_USB_STREAM_BULK(0x82, 8, 4096),
+		}
+	}
+};
+
 static const struct usb_device_id dvbsky_id_table[] = {
 	{ DVB_USB_DEVICE(0x0572, 0x6831,
 		&dvbsky_s960_props, "DVBSky S960/S860", RC_MAP_DVBSKY) },
@@ -806,6 +869,12 @@ static const struct usb_device_id dvbsky_id_table[] = {
 	{ DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230A,
 		 &mygica_t230c_props, "MyGica Mini DVB-(T/T2/C) USB Stick T230A",
 		 NULL) },
+	{ DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_MYGICA_A681B,
+		 &mygica_mxl692_props, "MyGica ATSC/QAM HDTV USB Stick A681B",
+		 NULL) },
+	{ DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_MYGICA_PT682C,
+		 &mygica_mxl692_props, "MyGica ATSC/QAM HDTV USB Stick PT682C",
+		 NULL) },
 	{ }
 };
 MODULE_DEVICE_TABLE(usb, dvbsky_id_table);
diff --git a/include/media/dvb-usb-ids.h b/include/media/dvb-usb-ids.h
index 1b7d10f3d4aa..0ce78daa3ef9 100644
--- a/include/media/dvb-usb-ids.h
+++ b/include/media/dvb-usb-ids.h
@@ -301,7 +301,9 @@
 #define USB_PID_MSI_DIGI_VOX_MINI_III			0x8807
 #define USB_PID_MSI_MEGASKY580				0x5580
 #define USB_PID_MSI_MEGASKY580_55801			0x5581
+#define USB_PID_MYGICA_A681B				0x692f
 #define USB_PID_MYGICA_D689				0xd811
+#define USB_PID_MYGICA_PT682C				0xe691
 #define USB_PID_MYGICA_T230				0xc688
 #define USB_PID_MYGICA_T230A				0x689a
 #define USB_PID_MYGICA_T230C				0xc689
-- 
2.51.0