Jarod Wilson 89a6e08
commit 611225f5e7f9d11c4b119fac224f1bd6903b0150
Jarod Wilson 89a6e08
Author: Jarod Wilson <jarod@redhat.com>
Jarod Wilson 89a6e08
Date:   Sun Mar 7 17:55:43 2010 -0300
Jesse Keating 7a32965
Jarod Wilson 89a6e08
    V4L/DVB: dvb: add support for kworld 340u and ub435-q to em28xx-dvb
Jarod Wilson 89a6e08
    
Jarod Wilson 89a6e08
    This adds support for the KWorld PlusTV 340U and KWorld UB345-Q ATSC
Jarod Wilson 89a6e08
    sticks, which are really the same device. The sticks have an eMPIA
Jarod Wilson 89a6e08
    em2870 usb bridge chipset, an LG Electronics LGDT3304 ATSC/QAM
Jarod Wilson 89a6e08
    demodulator and an NXP TDA18271HD tuner -- early versions of the 340U
Jarod Wilson 89a6e08
    have a a TDA18271HD/C1, later models and the UB435-Q have a C2.
Jarod Wilson 89a6e08
    
Jarod Wilson 89a6e08
    The stick has been tested succesfully with both VSB_8 and QAM_256 signals.
Jarod Wilson 89a6e08
    Its using lgdt3304 support added to the lgdt3305 driver by a prior patch,
Jarod Wilson 89a6e08
    rather than the current lgdt3304 driver, as its severely lacking in
Jarod Wilson 89a6e08
    functionality by comparison (see said patch for details).
Jarod Wilson 89a6e08
    
Jarod Wilson 89a6e08
    Signed-off-by: Jarod Wilson <jarod@redhat.com>
Jarod Wilson 89a6e08
    Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Jarod Wilson 89a6e08
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Jesse Keating 7a32965
Jarod Wilson 89a6e08
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
Jarod Wilson 89a6e08
index 3a623aa..5c56875 100644
Jarod Wilson 89a6e08
--- a/Documentation/video4linux/CARDLIST.em28xx
Jarod Wilson 89a6e08
+++ b/Documentation/video4linux/CARDLIST.em28xx
Jarod Wilson 89a6e08
@@ -72,3 +72,4 @@
Jarod Wilson 89a6e08
  73 -> Reddo DVB-C USB TV Box                   (em2870)
Jarod Wilson 89a6e08
  74 -> Actionmaster/LinXcel/Digitus VC211A      (em2800)
Jarod Wilson 89a6e08
  75 -> Dikom DK300                              (em2882)
Jarod Wilson 89a6e08
+ 76 -> KWorld PlusTV 340U or UB435-Q (ATSC)     (em2870)        [1b80:a340]
Jesse Keating 7a32965
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
Jarod Wilson 89a6e08
index 3a4fd85..ffbe544 100644
Jesse Keating 7a32965
--- a/drivers/media/video/em28xx/em28xx-cards.c
Jesse Keating 7a32965
+++ b/drivers/media/video/em28xx/em28xx-cards.c
Jesse Keating 7a32965
@@ -158,6 +158,22 @@ static struct em28xx_reg_seq evga_indtube_digital[] = {
Jesse Keating 7a32965
 	{ -1,			-1,	-1,		-1},
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+/*
Jesse Keating 7a32965
+ * KWorld PlusTV 340U and UB435-Q (ATSC) GPIOs map:
Jesse Keating 7a32965
+ * EM_GPIO_0 - currently unknown
Jesse Keating 7a32965
+ * EM_GPIO_1 - LED disable/enable (1 = off, 0 = on)
Jesse Keating 7a32965
+ * EM_GPIO_2 - currently unknown
Jesse Keating 7a32965
+ * EM_GPIO_3 - currently unknown
Jesse Keating 7a32965
+ * EM_GPIO_4 - TDA18271HD/C1 tuner (1 = active, 0 = in reset)
Jesse Keating 7a32965
+ * EM_GPIO_5 - LGDT3304 ATSC/QAM demod (1 = active, 0 = in reset)
Jesse Keating 7a32965
+ * EM_GPIO_6 - currently unknown
Jesse Keating 7a32965
+ * EM_GPIO_7 - currently unknown
Jesse Keating 7a32965
+ */
Jesse Keating 7a32965
+static struct em28xx_reg_seq kworld_a340_digital[] = {
Jesse Keating 7a32965
+	{EM28XX_R08_GPIO,	0x6d,		~EM_GPIO_4,	10},
Jesse Keating 7a32965
+	{ -1,			-1,		-1,		-1},
Jesse Keating 7a32965
+};
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 /* Pinnacle Hybrid Pro eb1a:2881 */
Jesse Keating 7a32965
 static struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = {
Jesse Keating 7a32965
 	{EM28XX_R08_GPIO,	0xfd,   ~EM_GPIO_4,	10},
Jarod Wilson 89a6e08
@@ -1667,6 +1683,16 @@ struct em28xx_board em28xx_boards[] = {
Jesse Keating 7a32965
 		.tuner_gpio    = reddo_dvb_c_usb_box,
Jesse Keating 7a32965
 		.has_dvb       = 1,
Jesse Keating 7a32965
 	},
Jesse Keating 7a32965
+	/* 1b80:a340 - Empia EM2870, NXP TDA18271HD and LG DT3304, sold
Jesse Keating 7a32965
+	 * initially as the KWorld PlusTV 340U, then as the UB435-Q.
Jesse Keating 7a32965
+	 * Early variants have a TDA18271HD/C1, later ones a TDA18271HD/C2 */
Jesse Keating 7a32965
+	[EM2870_BOARD_KWORLD_A340] = {
Jesse Keating 7a32965
+		.name       = "KWorld PlusTV 340U or UB435-Q (ATSC)",
Jesse Keating 7a32965
+		.tuner_type = TUNER_ABSENT,	/* Digital-only TDA18271HD */
Jesse Keating 7a32965
+		.has_dvb    = 1,
Jesse Keating 7a32965
+		.dvb_gpio   = kworld_a340_digital,
Jesse Keating 7a32965
+		.tuner_gpio = default_tuner_gpio,
Jesse Keating 7a32965
+	},
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
Jesse Keating 7a32965
 
Jarod Wilson 89a6e08
@@ -1788,6 +1814,8 @@ struct usb_device_id em28xx_id_table[] = {
Jesse Keating 7a32965
 			.driver_info = EM2820_BOARD_IODATA_GVMVP_SZ },
Jesse Keating 7a32965
 	{ USB_DEVICE(0xeb1a, 0x50a6),
Jesse Keating 7a32965
 			.driver_info = EM2860_BOARD_GADMEI_UTV330 },
Jesse Keating 7a32965
+	{ USB_DEVICE(0x1b80, 0xa340),
Jesse Keating 7a32965
+			.driver_info = EM2870_BOARD_KWORLD_A340 },
Jesse Keating 7a32965
 	{ },
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 MODULE_DEVICE_TABLE(usb, em28xx_id_table);
Jesse Keating 7a32965
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
Jarod Wilson 89a6e08
index cf1d8c3..3ac8d30 100644
Jesse Keating 7a32965
--- a/drivers/media/video/em28xx/em28xx-dvb.c
Jesse Keating 7a32965
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
Jesse Keating 7a32965
@@ -30,11 +30,13 @@
Jesse Keating 7a32965
 #include "tuner-simple.h"
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 #include "lgdt330x.h"
Jesse Keating 7a32965
+#include "lgdt3305.h"
Jesse Keating 7a32965
 #include "zl10353.h"
Jesse Keating 7a32965
 #include "s5h1409.h"
Jesse Keating 7a32965
 #include "mt352.h"
Jesse Keating 7a32965
 #include "mt352_priv.h" /* FIXME */
Jesse Keating 7a32965
 #include "tda1002x.h"
Jesse Keating 7a32965
+#include "tda18271.h"
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 MODULE_DESCRIPTION("driver for em28xx based DVB cards");
Jesse Keating 7a32965
 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
Jesse Keating 7a32965
@@ -231,6 +233,18 @@ static struct lgdt330x_config em2880_lgdt3303_dev = {
Jesse Keating 7a32965
 	.demod_chip = LGDT3303,
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+static struct lgdt3305_config em2870_lgdt3304_dev = {
Jesse Keating 7a32965
+	.i2c_addr           = 0x0e,
Jesse Keating 7a32965
+	.demod_chip         = LGDT3304,
Jesse Keating 7a32965
+	.spectral_inversion = 1,
Jesse Keating 7a32965
+	.deny_i2c_rptr      = 1,
Jesse Keating 7a32965
+	.mpeg_mode          = LGDT3305_MPEG_PARALLEL,
Jesse Keating 7a32965
+	.tpclk_edge         = LGDT3305_TPCLK_FALLING_EDGE,
Jesse Keating 7a32965
+	.tpvalid_polarity   = LGDT3305_TP_VALID_HIGH,
Jesse Keating 7a32965
+	.vsb_if_khz         = 3250,
Jesse Keating 7a32965
+	.qam_if_khz         = 4000,
Jesse Keating 7a32965
+};
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 static struct zl10353_config em28xx_zl10353_with_xc3028 = {
Jesse Keating 7a32965
 	.demod_address = (0x1e >> 1),
Jesse Keating 7a32965
 	.no_tuner = 1,
Jesse Keating 7a32965
@@ -247,6 +261,17 @@ static struct s5h1409_config em28xx_s5h1409_with_xc3028 = {
Jesse Keating 7a32965
 	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+static struct tda18271_std_map kworld_a340_std_map = {
Jesse Keating 7a32965
+	.atsc_6   = { .if_freq = 3250, .agc_mode = 3, .std = 0,
Jesse Keating 7a32965
+		      .if_lvl = 1, .rfagc_top = 0x37, },
Jesse Keating 7a32965
+	.qam_6    = { .if_freq = 4000, .agc_mode = 3, .std = 1,
Jesse Keating 7a32965
+		      .if_lvl = 1, .rfagc_top = 0x37, },
Jesse Keating 7a32965
+};
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static struct tda18271_config kworld_a340_config = {
Jesse Keating 7a32965
+	.std_map           = &kworld_a340_std_map,
Jesse Keating 7a32965
+};
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate = {
Jesse Keating 7a32965
 	.demod_address = (0x1e >> 1),
Jesse Keating 7a32965
 	.no_tuner = 1,
Jarod Wilson 89a6e08
@@ -572,6 +597,14 @@ static int dvb_init(struct em28xx *dev)
Jesse Keating 7a32965
 			}
Jesse Keating 7a32965
 		}
Jesse Keating 7a32965
 		break;
Jesse Keating 7a32965
+	case EM2870_BOARD_KWORLD_A340:
Jesse Keating 7a32965
+		dvb->frontend = dvb_attach(lgdt3305_attach,
Jesse Keating 7a32965
+					   &em2870_lgdt3304_dev,
Jesse Keating 7a32965
+					   &dev->i2c_adap);
Jesse Keating 7a32965
+		if (dvb->frontend != NULL)
Jesse Keating 7a32965
+			dvb_attach(tda18271_attach, dvb->frontend, 0x60,
Jesse Keating 7a32965
+				   &dev->i2c_adap, &kworld_a340_config);
Jesse Keating 7a32965
+		break;
Jesse Keating 7a32965
 	default:
Jesse Keating 7a32965
 		em28xx_errdev("/2: The frontend of your DVB/ATSC card"
Jesse Keating 7a32965
 				" isn't supported yet\n");
Jesse Keating 7a32965
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
Jarod Wilson 89a6e08
index 6216786..1c61a6b 100644
Jesse Keating 7a32965
--- a/drivers/media/video/em28xx/em28xx.h
Jesse Keating 7a32965
+++ b/drivers/media/video/em28xx/em28xx.h
Jarod Wilson 89a6e08
@@ -114,6 +114,7 @@
Jesse Keating 7a32965
 #define EM2870_BOARD_REDDO_DVB_C_USB_BOX          73
Jesse Keating 7a32965
 #define EM2800_BOARD_VC211A			  74
Jesse Keating 7a32965
 #define EM2882_BOARD_DIKOM_DK300		  75
Jesse Keating 7a32965
+#define EM2870_BOARD_KWORLD_A340		  76
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /* Limits minimum and default number of buffers */
Jesse Keating 7a32965
 #define EM28XX_MIN_BUF 4