All of lore.kernel.org
 help / color / mirror / Atom feed
* Trying to support for HAUPPAUGE HVR-930C
@ 2011-07-28  8:53 Eddi De Pieri
  2011-07-28 12:13 ` Benjamin Larsson
  0 siblings, 1 reply; 7+ messages in thread
From: Eddi De Pieri @ 2011-07-28  8:53 UTC (permalink / raw)
  To: linux-media; +Cc: devin.heitmueller, mchehab, o.endriss

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

Hi,

I'd like to share my work to get hvr 930c.

I had to apply some change to drxk structure too!

The patch is created with git diff at with these latest 3 commit:
commit 9bc5f6fa12c9e3e1e73e66bfabe9d463ea779b08
commit a65ea1e0dba7df0f3b6d55098162cf0125164c6c
commit e5d993e5423ea4b81ccdbe2fa157ca5a75176d68

I cloned the work done for Terratec H5 devices.

- I fixed the firmware extraction I already posted
- The driver load the firmware to drxk
- The xc5000 firmware upload works and reset too.
- The if_khz should be ok (I dumped the value from usbsnoop)

- added chunk_size to drx_config since it seems hvr930c needs a custom
chunksize for firmware upload (please check since my patch may add
regression other devices)

- I temporary applied the patch
https://patchwork.kernel.org/patch/790352/mbox/ too

Actually the device don't work yet.

Please someone can review my work?


Signed-off-by: Eddi De Pieri <eddi@depieri.net>

regards

[-- Attachment #2: hauppauge-hvr930c_r0.patch --]
[-- Type: application/octet-stream, Size: 11810 bytes --]

diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index c466f58..503d70f 100755
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -27,7 +27,7 @@ use IO::Handle;
 		"or51211", "or51132_qam", "or51132_vsb", "bluebird",
 		"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
 		"af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395",
-		"lme2510c_s7395_old", "drxk", "drxk_terratec_h5");
+		"lme2510c_s7395_old", "drxk", "drxk_hauppauge_hvr930c", "drxk_terratec_h5");
 
 # Check args
 syntax() if (scalar(@ARGV) != 1);
@@ -652,6 +652,24 @@ sub drxk {
     "$fwfile"
 }
 
+sub drxk_hauppauge_hvr930c {
+    my $url = "http://www.wintvcd.co.uk/drivers/";
+    my $zipfile = "HVR-9x0_5_10_325_28153_SIGNED.zip";
+    my $hash = "83ab82e7e9480ec8bf1ae0155ca63c88";
+    my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
+    my $drvfile = "HVR-900/emOEM.sys";
+    my $fwfile = "dvb-usb-hauppauge-hvr930c-drxk.fw";
+
+    checkstandard();
+
+    wgetfile($zipfile, $url . $zipfile);
+    verify($zipfile, $hash);
+    unzip($zipfile, $tmpdir);
+    extract("$tmpdir/$drvfile", 0x117b0, 42692, "$fwfile");
+
+    "$fwfile"
+}
+
 sub drxk_terratec_h5 {
     my $url = "http://www.linuxtv.org/downloads/firmware/";
     my $hash = "19000dada8e2741162ccc50cc91fa7f1";
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index aa1b2e8..a491a5b 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -996,6 +996,8 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
 	struct xc5000_priv *priv = fe->tuner_priv;
 	int ret = 0;
 
+	mutex_lock(&xc5000_list_mutex);
+
 	if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
 		ret = xc5000_fwupload(fe);
 		if (ret != XC_RESULT_SUCCESS)
@@ -1015,6 +1017,8 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
 	/* Default to "CABLE" mode */
 	ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
 
+	mutex_unlock(&xc5000_list_mutex);
+
 	return ret;
 }
 
diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h
index 58baf41..0dc9883 100644
--- a/drivers/media/dvb/frontends/drxk.h
+++ b/drivers/media/dvb/frontends/drxk.h
@@ -25,6 +25,8 @@ struct drxk_config {
 
 	bool	antenna_dvbt;
 	u16	antenna_gpio;
+	
+	int    chunk_size;
 
 	const char *microcode_name;
 };
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c
index 5694955..9a59f29 100644
--- a/drivers/media/dvb/frontends/drxk_hard.c
+++ b/drivers/media/dvb/frontends/drxk_hard.c
@@ -684,7 +684,8 @@ static int init_state(struct drxk_state *state)
 	state->m_hasOOB = false;
 	state->m_hasAudio = false;
 
-	state->m_ChunkSize = 124;
+	if (!state->m_ChunkSize)
+	    state->m_ChunkSize = 124;
 
 	state->m_oscClockFreq = 0;
 	state->m_smartAntInverted = false;
@@ -6422,6 +6423,7 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config,
 	state->no_i2c_bridge = config->no_i2c_bridge;
 	state->antenna_gpio = config->antenna_gpio;
 	state->antenna_dvbt = config->antenna_dvbt;
+	state->m_ChunkSize = config->chunk_size;
 
 	/* NOTE: as more UIO bits will be used, add them to the mask */
 	state->UIO_mask = config->antenna_gpio;
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 3e3959f..538bc91 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -317,6 +317,24 @@ static struct em28xx_reg_seq terratec_h5_digital[] = {
 };
 #endif
 
+static struct em28xx_reg_seq hauppauge_930c_gpio[] = {
+// xc5000 reset
+	{EM2874_R80_GPIO,	0x6f,	0xff,	10},
+	{EM2874_R80_GPIO,	0x4f,	0xff,	10},
+	{EM2874_R80_GPIO,	0x6f,	0xff,	10},
+	{EM2874_R80_GPIO,	0x4f,	0xff,	10},
+	{ -1,			-1,	-1,	-1},
+};
+
+#if 0
+static struct em28xx_reg_seq hauppauge_930c_digital[] = {
+	{EM2874_R80_GPIO,	0xf6,	0xff,	10},
+	{EM2874_R80_GPIO,	0xe6,	0xff,	100},
+	{EM2874_R80_GPIO,	0xa6,	0xff,	10},
+	{ -1,			-1,	-1,	-1},
+};
+#endif
+
 /*
  *  Board definitions
  */
@@ -873,6 +891,19 @@ struct em28xx_board em28xx_boards[] = {
 				EM28XX_I2C_CLK_WAIT_ENABLE |
 				EM28XX_I2C_FREQ_400_KHZ,
 	},
+	[EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = {
+		.name         = "Hauppauge WinTV HVR 930C",
+		.has_dvb      = 1,
+//#if 0
+//		.tuner_type   = TUNER_XC5000,
+//		.tuner_addr   = 0x41,
+//		.dvb_gpio     = hauppauge_930c_digital, /* FIXME: probably wrong */
+		.tuner_gpio   = hauppauge_930c_gpio,
+//#endif
+		.i2c_speed    = EM2874_I2C_SECONDARY_BUS_SELECT |
+				EM28XX_I2C_CLK_WAIT_ENABLE |
+				EM28XX_I2C_FREQ_400_KHZ,
+	},
 	[EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = {
 		.name         = "Hauppauge WinTV HVR 900",
 		.tda9887_conf = TDA9887_PRESENT,
@@ -1941,6 +1972,8 @@ struct usb_device_id em28xx_id_table[] = {
 			.driver_info = EM2870_BOARD_KWORLD_A340 },
 	{ USB_DEVICE(0x2013, 0x024f),
 			.driver_info = EM28174_BOARD_PCTV_290E },
+	{ USB_DEVICE(0x2040, 0x1605),
+			.driver_info = EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C },
 	{ },
 };
 MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -1994,10 +2027,10 @@ int em28xx_tuner_callback(void *ptr, int component, int command, int arg)
 	int rc = 0;
 	struct em28xx *dev = ptr;
 
-	if (dev->tuner_type != TUNER_XC2028)
+	if (dev->tuner_type != TUNER_XC2028 && dev->tuner_type != TUNER_XC5000)
 		return 0;
 
-	if (command != XC2028_TUNER_RESET)
+	if (command != XC2028_TUNER_RESET && command != XC5000_TUNER_RESET)
 		return 0;
 
 	rc = em28xx_gpio_set(dev, dev->board.tuner_gpio);
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index ab8a740..c5f3e78 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -1,4 +1,4 @@
-/*
+/*6
  DVB device driver for em28xx
 
  (c) 2008-2011 Mauro Carvalho Chehab <mchehab@infradead.org>
@@ -309,6 +309,14 @@ struct drxk_config terratec_h5_drxk = {
 	.microcode_name = "dvb-usb-terratec-h5-drxk.fw",
 };
 
+struct drxk_config hauppauge_930c_drxk = {
+	.adr = 0x29,
+	.single_master = 1,
+	.no_i2c_bridge = 1,
+	.microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw",
+	.chunk_size = 56,
+};
+
 static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
 {
 	struct em28xx_dvb *dvb = fe->sec_priv;
@@ -327,6 +335,91 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
 	return status;
 }
 
+static void hauppauge_hvr930c_init(struct em28xx *dev)
+{
+	int i;
+	
+
+	struct em28xx_reg_seq hauppauge_hvr930c_init[] = {
+		{EM2874_R80_GPIO,	0xff,	0xff,	101},  //11111111
+//		{0xd            ,	0xff,	0xff,	101},  //11111111
+		{EM2874_R80_GPIO,	0xfb,	0xff,	50},   //11111011  init bit 3
+		{EM2874_R80_GPIO,	0xff,	0xff,	184},  //11111111
+		{ -1,                   -1,     -1,     -1},
+	};
+	struct em28xx_reg_seq hauppauge_hvr930c_end[] = {
+		{EM2874_R80_GPIO,	0xef,	0xff,	1},    //11101111
+		{EM2874_R80_GPIO,	0xaf,	0xff,	101},  //10101111  init bit 7
+		{EM2874_R80_GPIO,	0xef,	0xff,	118},   //11101111
+
+
+//per il tuner?
+		{EM2874_R80_GPIO,	0xef,	0xff,	1},  //11101111
+		{EM2874_R80_GPIO,	0xcf,	0xff,	11},    //11001111  init bit 6
+		{EM2874_R80_GPIO,	0xef,	0xff,	64},  //11101111
+
+		{EM2874_R80_GPIO,	0xcf,	0xff,	101},  //11001111  init bit 6
+		{EM2874_R80_GPIO,	0xef,	0xff,	101},  //11101111
+		{EM2874_R80_GPIO,	0xcf,	0xff,	11},  //11001111  init bit 6
+		{EM2874_R80_GPIO,	0xef,	0xff,	101},  //11101111
+
+//		{EM2874_R80_GPIO,	0x6f,	0xff,	10},    //01101111
+//		{EM2874_R80_GPIO,	0x6d,	0xff,	100},  //01101101  init bit 2
+		{ -1,                   -1,     -1,     -1},
+	};
+
+	struct em28xx_reg_seq hauppauge_hvr930c_end2[] = {
+//		{EM2874_R80_GPIO,	0x6f,	0xff,	124},  //01101111
+//		{EM2874_R80_GPIO,	0x4f,	0xff,	11},   //01001111  init bit 6
+//		{EM2874_R80_GPIO,	0x6f,	0xff,	1},    //01101111
+//		{EM2874_R80_GPIO,	0x4f,	0xff,	10},   //01001111  init bit 6
+//		{EM2874_R80_GPIO,	0x6f,	0xff,	100},  //01101111
+//		{0xd            ,	0x42,	0xff,	101},  //11111111
+		{ -1,                   -1,     -1,     -1},
+	};
+	struct {
+		unsigned char r[4];
+		int len;
+	} regs[] = {
+		{{ 0x06, 0x02, 0x00, 0x31 }, 4},
+		{{ 0x01, 0x02 }, 2},
+		{{ 0x01, 0x02, 0x00, 0xc6 }, 4},
+		{{ 0x01, 0x00 }, 2},
+		{{ 0x01, 0x00, 0xff, 0xaf }, 4},
+		{{ 0x01, 0x00, 0x03, 0xa0 }, 4},
+		{{ 0x01, 0x00 }, 2},
+		{{ 0x01, 0x00, 0x73, 0xaf }, 4},
+		{{ 0x04, 0x00 }, 2},
+		{{ 0x00, 0x04 }, 2},
+		{{ 0x00, 0x04, 0x00, 0x0a }, 4},
+		{{ 0x04, 0x14 }, 2},
+		{{ 0x04, 0x14, 0x00, 0x00 }, 4},
+	};
+
+	em28xx_gpio_set(dev, hauppauge_hvr930c_init);
+	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
+	msleep(10);
+	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44);
+	msleep(10);
+
+	dev->i2c_client.addr = 0x82 >> 1;
+
+	for (i = 0; i < ARRAY_SIZE(regs); i++)
+		i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len);
+	em28xx_gpio_set(dev, hauppauge_hvr930c_end);
+
+	msleep(100);
+
+	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44);
+	msleep(30);
+
+	em28xx_gpio_set(dev, hauppauge_hvr930c_end2);
+	msleep(10);
+	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45);
+	msleep(10);
+
+}
+
 static void terratec_h5_init(struct em28xx *dev)
 {
 	int i;
@@ -769,6 +862,47 @@ static int dvb_init(struct em28xx *dev)
 			}
 		}
 		break;
+	case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C:
+		hauppauge_hvr930c_init(dev);
+
+		dvb->dont_attach_fe1 = 1;
+
+		dvb->fe[0] = dvb_attach(drxk_attach, &hauppauge_930c_drxk, &dev->i2c_adap, &dvb->fe[1]);
+		if (!dvb->fe[0]) {
+			result = -EINVAL;
+			goto out_free;
+		}
+		/* FIXME: do we need a pll semaphore? */
+		dvb->fe[0]->sec_priv = dvb;
+		sema_init(&dvb->pll_mutex, 1);
+		dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl;
+		dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;
+		dvb->fe[1]->id = 1;
+
+		/* Attach xc5000 */
+		struct xc5000_config cfg;
+		memset(&cfg, 0, sizeof(cfg));
+		cfg.i2c_address  = 0x61;
+		//cfg.if_khz = 4570; //FIXME
+		cfg.if_khz = 4000; //FIXME (should be ok) read from i2c traffic
+
+		if (dvb->fe[0]->ops.i2c_gate_ctrl)
+			dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1);
+		if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap, &cfg)) {
+			result = -EINVAL;
+			goto out_free;
+		}
+
+		if (dvb->fe[0]->ops.i2c_gate_ctrl)
+			dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0);
+
+		/* Hack - needed by drxk/tda18271c2dd */
+		dvb->fe[1]->tuner_priv = dvb->fe[0]->tuner_priv;
+		memcpy(&dvb->fe[1]->ops.tuner_ops,
+		       &dvb->fe[0]->ops.tuner_ops,
+		       sizeof(dvb->fe[0]->ops.tuner_ops));
+
+		break;
 	case EM2884_BOARD_TERRATEC_H5:
 		terratec_h5_init(dev);
 
@@ -779,7 +913,6 @@ static int dvb_init(struct em28xx *dev)
 			result = -EINVAL;
 			goto out_free;
 		}
-
 		/* FIXME: do we need a pll semaphore? */
 		dvb->fe[0]->sec_priv = dvb;
 		sema_init(&dvb->pll_mutex, 1);
@@ -816,7 +949,9 @@ static int dvb_init(struct em28xx *dev)
 	}
 	/* define general-purpose callback pointer */
 	dvb->fe[0]->callback = em28xx_tuner_callback;
-
+	if (dvb->fe[1])
+	    dvb->fe[1]->callback = em28xx_tuner_callback;
+	
 	/* register everything */
 	result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev);
 
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index d80658b..cf44396 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -38,6 +38,7 @@
 #include <media/videobuf-dvb.h>
 #endif
 #include "tuner-xc2028.h"
+#include "xc5000.h"
 #include "em28xx-reg.h"
 
 /* Boards supported by driver */
@@ -120,6 +121,7 @@
 #define EM2874_BOARD_LEADERSHIP_ISDBT		  77
 #define EM28174_BOARD_PCTV_290E                   78
 #define EM2884_BOARD_TERRATEC_H5		  79
+#define EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C	  80
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4

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

end of thread, other threads:[~2011-08-04  6:36 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-28  8:53 Trying to support for HAUPPAUGE HVR-930C Eddi De Pieri
2011-07-28 12:13 ` Benjamin Larsson
2011-07-29 11:15   ` Eddi De Pieri
2011-07-29 13:03     ` Antti Palosaari
2011-07-29 18:10     ` Devin Heitmueller
2011-07-29 20:17       ` Daniel Glöckner
2011-08-04  6:36         ` Devin Heitmueller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.