All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements.
@ 2011-08-04  7:13 Thierry Reding
  2011-08-04  7:13 ` [PATCH 01/21] [media] tuner/xc2028: Add I2C flush callback Thierry Reding
                   ` (21 more replies)
  0 siblings, 22 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:13 UTC (permalink / raw)
  To: linux-media

This patch series fixes up some issues with the tm6000 driver. These
patches were tested with a Cinergy Hybrid XE which is the only one I
have access to, so it would be nice if someone with access to the other
supported devices could take this series for a test run.

Among the changes are several speed-ups for firmware loading, addition
of radio support for the Cinergy Hybrid XE and some memory leak fixes. I
was able to reproduce the behaviour documented in the README about the
device stopping to work for unknown reasons. Running tests with this
series applied no longer exposes the problem, so I have high hopes that
it's also fixed.

Thierry Reding (21):
  [media] tuner/xc2028: Add I2C flush callback.
  [media] tuner/xc2028: Fix frequency offset for radio mode.
  [staging] tm6000: Miscellaneous cleanups.
  [staging] tm6000: Use correct input in radio mode.
  [staging] tm6000: Implement I2C flush callback.
  [staging] tm6000: Increase maximum I2C packet size.
  [staging] tm6000: Remove artificial delay.
  [staging] tm6000: Flesh out the IRQ callback.
  [staging] tm6000: Rename active interface register.
  [staging] tm6000: Disable video interface in radio mode.
  [staging] tm6000: Rework standard register tables.
  [staging] tm6000: Add locking for USB transfers.
  [staging] tm6000: Properly count device usage.
  [staging] tm6000: Initialize isochronous transfers only once.
  [staging] tm6000: Execute lightweight reset on close.
  [staging] tm6000: Select interface on first open.
  [staging] tm6000: Do not use video buffers in radio mode.
  [staging] tm6000: Plug memory leak on PCM free.
  [staging] tm6000: Enable audio clock in radio mode.
  [staging] tm6000: Enable radio mode for Cinergy Hybrid XE.
  [staging] tm6000: Remove unnecessary workaround.

 drivers/media/common/tuners/tuner-xc2028.c |  144 ++++---
 drivers/media/common/tuners/tuner-xc2028.h |    1 +
 drivers/staging/tm6000/tm6000-alsa.c       |    9 +-
 drivers/staging/tm6000/tm6000-cards.c      |   35 +-
 drivers/staging/tm6000/tm6000-core.c       |  102 +++--
 drivers/staging/tm6000/tm6000-dvb.c        |   14 +-
 drivers/staging/tm6000/tm6000-i2c.c        |    7 +-
 drivers/staging/tm6000/tm6000-input.c      |    2 +-
 drivers/staging/tm6000/tm6000-regs.h       |    4 +-
 drivers/staging/tm6000/tm6000-stds.c       |  642 ++++++++++++++--------------
 drivers/staging/tm6000/tm6000-video.c      |  188 +++++----
 drivers/staging/tm6000/tm6000.h            |    6 +-
 12 files changed, 600 insertions(+), 554 deletions(-)

-- 
1.7.6


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

* [PATCH 01/21] [media] tuner/xc2028: Add I2C flush callback.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
@ 2011-08-04  7:13 ` Thierry Reding
  2011-08-04  7:14 ` [PATCH 02/21] [media] tuner/xc2028: Fix frequency offset for radio mode Thierry Reding
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:13 UTC (permalink / raw)
  To: linux-media

When loading the firmware, complete each chunk by sending an I2C flush
command to the frontend. Some devices like the tm6000 seem to require
this to properly flush the I2C buffers.

The current code in tm6000 executes the flush command once after each
I2C transfer, which slows down the firmware loading especially when
loading large BASE type images.
---
 drivers/media/common/tuners/tuner-xc2028.c |    7 +++++++
 drivers/media/common/tuners/tuner-xc2028.h |    1 +
 2 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index 16fba6b..b6b2868 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -614,6 +614,13 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type,
 			p += len;
 			size -= len;
 		}
+
+		/* silently fail if the frontend doesn't support I2C flush */
+		rc = do_tuner_callback(fe, XC2028_I2C_FLUSH, 0);
+		if ((rc < 0) && (rc != -EINVAL)) {
+			tuner_err("error executing flush: %d\n", rc);
+			return rc;
+		}
 	}
 	return 0;
 }
diff --git a/drivers/media/common/tuners/tuner-xc2028.h b/drivers/media/common/tuners/tuner-xc2028.h
index 9778c96..9ebfb2d 100644
--- a/drivers/media/common/tuners/tuner-xc2028.h
+++ b/drivers/media/common/tuners/tuner-xc2028.h
@@ -54,6 +54,7 @@ struct xc2028_config {
 /* xc2028 commands for callback */
 #define XC2028_TUNER_RESET	0
 #define XC2028_RESET_CLK	1
+#define XC2028_I2C_FLUSH	2
 
 #if defined(CONFIG_MEDIA_TUNER_XC2028) || (defined(CONFIG_MEDIA_TUNER_XC2028_MODULE) && defined(MODULE))
 extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
-- 
1.7.6


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

* [PATCH 02/21] [media] tuner/xc2028: Fix frequency offset for radio mode.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
  2011-08-04  7:13 ` [PATCH 01/21] [media] tuner/xc2028: Add I2C flush callback Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-31 18:32   ` Mauro Carvalho Chehab
  2011-08-04  7:14 ` [PATCH 03/21] [staging] tm6000: Miscellaneous cleanups Thierry Reding
                   ` (19 subsequent siblings)
  21 siblings, 1 reply; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

In radio mode, no frequency offset is needed. While at it, split off the
frequency offset computation for digital TV into a separate function.
---
 drivers/media/common/tuners/tuner-xc2028.c |  137 +++++++++++++++-------------
 1 files changed, 75 insertions(+), 62 deletions(-)

diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index b6b2868..8e53e5e 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -913,6 +913,66 @@ ret:
 
 #define DIV 15625
 
+static u32 digital_freq_offset(struct xc2028_data *priv, u32 freq)
+{
+	u32 offset = 0;
+
+	/*
+	 * Adjust to the center frequency. This is calculated by the
+	 * formula: offset = 1.25MHz - BW/2
+	 * For DTV 7/8, the firmware uses BW = 8000, so it needs a
+	 * further adjustment to get the frequency center on VHF
+	 */
+	if (priv->cur_fw.type & DTV6)
+		offset = 1750000;
+	else if (priv->cur_fw.type & DTV7)
+		offset = 2250000;
+	else /* DTV8 or DTV78 */
+		offset = 2750000;
+
+	if ((priv->cur_fw.type & DTV78) && freq < 470000000)
+		offset -= 500000;
+
+	/*
+	 * xc3028 additional "magic"
+	 * Depending on the firmware version, it needs some adjustments
+	 * to properly centralize the frequency. This seems to be
+	 * needed to compensate the SCODE table adjustments made by
+	 * newer firmwares
+	 */
+
+#if 1
+	/*
+	 * The proper adjustment would be to do it at s-code table.
+	 * However, this didn't work, as reported by
+	 * Robert Lowery <rglowery@exemail.com.au>
+	 */
+
+	if (priv->cur_fw.type & DTV7)
+		offset += 500000;
+
+#else
+	/*
+	 * Still need tests for XC3028L (firmware 3.2 or upper)
+	 * So, for now, let's just comment the per-firmware
+	 * version of this change. Reports with xc3028l working
+	 * with and without the lines bellow are welcome
+	 */
+
+	if (priv->firm_version < 0x0302) {
+		if (priv->cur_fw.type & DTV7)
+			offset += 500000;
+	} else {
+		if (priv->cur_fw.type & DTV7)
+			offset -= 300000;
+		else if (type != ATSC) /* DVB @6MHz, DTV 8 and DTV 7/8 */
+			offset += 200000;
+	}
+#endif
+
+	return offset;
+}
+
 static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
 			    enum v4l2_tuner_type new_type,
 			    unsigned int type,
@@ -933,75 +993,28 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
 	if (check_firmware(fe, type, std, int_freq) < 0)
 		goto ret;
 
-	/* On some cases xc2028 can disable video output, if
-	 * very weak signals are received. By sending a soft
-	 * reset, this is re-enabled. So, it is better to always
-	 * send a soft reset before changing channels, to be sure
-	 * that xc2028 will be in a safe state.
-	 * Maybe this might also be needed for DTV.
-	 */
-	if (new_type == V4L2_TUNER_ANALOG_TV) {
+	switch (new_type) {
+	case V4L2_TUNER_ANALOG_TV:
+		/* On some cases xc2028 can disable video output, if
+		 * very weak signals are received. By sending a soft
+		 * reset, this is re-enabled. So, it is better to always
+		 * send a soft reset before changing channels, to be sure
+		 * that xc2028 will be in a safe state.
+		 * Maybe this might also be needed for DTV.
+		 */
 		rc = send_seq(priv, {0x00, 0x00});
-
+		/* fall through */
+	case V4L2_TUNER_RADIO:
 		/* Analog modes require offset = 0 */
-	} else {
+		break;
+	case V4L2_TUNER_DIGITAL_TV:
 		/*
 		 * Digital modes require an offset to adjust to the
 		 * proper frequency. The offset depends on what
 		 * firmware version is used.
 		 */
-
-		/*
-		 * Adjust to the center frequency. This is calculated by the
-		 * formula: offset = 1.25MHz - BW/2
-		 * For DTV 7/8, the firmware uses BW = 8000, so it needs a
-		 * further adjustment to get the frequency center on VHF
-		 */
-		if (priv->cur_fw.type & DTV6)
-			offset = 1750000;
-		else if (priv->cur_fw.type & DTV7)
-			offset = 2250000;
-		else	/* DTV8 or DTV78 */
-			offset = 2750000;
-		if ((priv->cur_fw.type & DTV78) && freq < 470000000)
-			offset -= 500000;
-
-		/*
-		 * xc3028 additional "magic"
-		 * Depending on the firmware version, it needs some adjustments
-		 * to properly centralize the frequency. This seems to be
-		 * needed to compensate the SCODE table adjustments made by
-		 * newer firmwares
-		 */
-
-#if 1
-		/*
-		 * The proper adjustment would be to do it at s-code table.
-		 * However, this didn't work, as reported by
-		 * Robert Lowery <rglowery@exemail.com.au>
-		 */
-
-		if (priv->cur_fw.type & DTV7)
-			offset += 500000;
-
-#else
-		/*
-		 * Still need tests for XC3028L (firmware 3.2 or upper)
-		 * So, for now, let's just comment the per-firmware
-		 * version of this change. Reports with xc3028l working
-		 * with and without the lines bellow are welcome
-		 */
-
-		if (priv->firm_version < 0x0302) {
-			if (priv->cur_fw.type & DTV7)
-				offset += 500000;
-		} else {
-			if (priv->cur_fw.type & DTV7)
-				offset -= 300000;
-			else if (type != ATSC) /* DVB @6MHz, DTV 8 and DTV 7/8 */
-				offset += 200000;
-		}
-#endif
+		offset = digital_freq_offset(priv, freq);
+		break;
 	}
 
 	div = (freq - offset + DIV / 2) / DIV;
-- 
1.7.6


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

* [PATCH 03/21] [staging] tm6000: Miscellaneous cleanups.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
  2011-08-04  7:13 ` [PATCH 01/21] [media] tuner/xc2028: Add I2C flush callback Thierry Reding
  2011-08-04  7:14 ` [PATCH 02/21] [media] tuner/xc2028: Fix frequency offset for radio mode Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-04  7:14 ` [PATCH 04/21] [staging] tm6000: Use correct input in radio mode Thierry Reding
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

This commit fixes a number of coding style issues as well as some issues
reported by checkpatch and sparse.
---
 drivers/staging/tm6000/tm6000-alsa.c  |    4 +-
 drivers/staging/tm6000/tm6000-cards.c |   18 ++---
 drivers/staging/tm6000/tm6000-core.c  |   17 ++---
 drivers/staging/tm6000/tm6000-dvb.c   |   14 ++--
 drivers/staging/tm6000/tm6000-input.c |    2 +-
 drivers/staging/tm6000/tm6000-stds.c  |    3 +-
 drivers/staging/tm6000/tm6000-video.c |  125 +++++++++++++++------------------
 drivers/staging/tm6000/tm6000.h       |    4 -
 8 files changed, 83 insertions(+), 104 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c
index 2b96047..768d713 100644
--- a/drivers/staging/tm6000/tm6000-alsa.c
+++ b/drivers/staging/tm6000/tm6000-alsa.c
@@ -401,7 +401,7 @@ static struct snd_pcm_ops snd_tm6000_pcm_ops = {
 /*
  * Alsa Constructor - Component probe
  */
-int tm6000_audio_init(struct tm6000_core *dev)
+static int tm6000_audio_init(struct tm6000_core *dev)
 {
 	struct snd_card		*card;
 	struct snd_tm6000_card	*chip;
@@ -494,7 +494,7 @@ static int tm6000_audio_fini(struct tm6000_core *dev)
 	return 0;
 }
 
-struct tm6000_ops audio_ops = {
+static struct tm6000_ops audio_ops = {
 	.type	= TM6000_AUDIO,
 	.name	= "TM6000 Audio Extension",
 	.init	= tm6000_audio_init,
diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index a69c82e..202f454 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -88,7 +88,7 @@ struct tm6000_board {
 	char		*ir_codes;
 };
 
-struct tm6000_board tm6000_boards[] = {
+static struct tm6000_board tm6000_boards[] = {
 	[TM6000_BOARD_UNKNOWN] = {
 		.name         = "Unknown tm6000 video grabber",
 		.caps = {
@@ -395,7 +395,7 @@ struct tm6000_board tm6000_boards[] = {
 			.has_zl10353    = 1,
 			.has_eeprom     = 1,
 			.has_remote     = 1,
-			.has_radio	= 1.
+			.has_radio	= 1,
 		},
 		.gpio = {
 			.tuner_reset	= TM6010_GPIO_0,
@@ -612,7 +612,7 @@ struct tm6000_board tm6000_boards[] = {
 };
 
 /* table of devices that work with this driver */
-struct usb_device_id tm6000_id_table[] = {
+static struct usb_device_id tm6000_id_table[] = {
 	{ USB_DEVICE(0x6000, 0x0001), .driver_info = TM5600_BOARD_GENERIC },
 	{ USB_DEVICE(0x6000, 0x0002), .driver_info = TM6010_BOARD_GENERIC },
 	{ USB_DEVICE(0x06e1, 0xf332), .driver_info = TM6000_BOARD_ADSTECH_DUAL_TV },
@@ -633,7 +633,7 @@ struct usb_device_id tm6000_id_table[] = {
 	{ USB_DEVICE(0x13d3, 0x3264), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
 	{ USB_DEVICE(0x6000, 0xdec2), .driver_info = TM6010_BOARD_BEHOLD_WANDER_LITE },
 	{ USB_DEVICE(0x6000, 0xdec3), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER_LITE },
-	{ },
+	{ }
 };
 
 /* Control power led for show some activity */
@@ -788,8 +788,6 @@ EXPORT_SYMBOL_GPL(tm6000_tuner_callback);
 
 int tm6000_cards_setup(struct tm6000_core *dev)
 {
-	int i, rc;
-
 	/*
 	 * Board-specific initialization sequence. Handles all GPIO
 	 * initialization sequences that are board-specific.
@@ -861,6 +859,9 @@ int tm6000_cards_setup(struct tm6000_core *dev)
 	 */
 
 	if (dev->gpio.tuner_reset) {
+		int rc;
+		int i;
+
 		for (i = 0; i < 2; i++) {
 			rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
 						dev->gpio.tuner_reset, 0x00);
@@ -1173,7 +1174,7 @@ static int tm6000_usb_probe(struct usb_interface *interface,
 	snprintf(dev->name, 29, "tm6000 #%d", nr);
 
 	dev->model = id->driver_info;
-	if ((card[nr] >= 0) && (card[nr] < ARRAY_SIZE(tm6000_boards)))
+	if (card[nr] < ARRAY_SIZE(tm6000_boards))
 		dev->model = card[nr];
 
 	dev->udev = usbdev;
@@ -1194,8 +1195,6 @@ static int tm6000_usb_probe(struct usb_interface *interface,
 		speed = "unknown";
 	}
 
-
-
 	/* Get endpoints */
 	for (i = 0; i < interface->num_altsetting; i++) {
 		int ep;
@@ -1279,7 +1278,6 @@ static int tm6000_usb_probe(struct usb_interface *interface,
 	printk(KERN_INFO "tm6000: Found %s\n", tm6000_boards[dev->model].name);
 
 	rc = tm6000_init_dev(dev);
-
 	if (rc < 0)
 		goto err;
 
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index d7eb2e2..e14bd3d 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -42,7 +42,6 @@ int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req,
 	if (len)
 		data = kzalloc(len, GFP_KERNEL);
 
-
 	if (req_type & USB_DIR_IN)
 		pipe = usb_rcvctrlpipe(dev->udev, 0);
 	else {
@@ -62,7 +61,7 @@ int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req,
 			printk(">>> ");
 			for (i = 0; i < len; i++)
 				printk(" %02x", buf[i]);
-		printk("\n");
+			printk("\n");
 		}
 	}
 
@@ -308,7 +307,7 @@ int tm6000_init_analog_mode(struct tm6000_core *dev)
 	 * FIXME: This is a hack! xc3028 "sleeps" when no channel is detected
 	 * for more than a few seconds. Not sure why, as this behavior does
 	 * not happen on other devices with xc3028. So, I suspect that it
-	 * is yet another bug at tm6000. After start sleeping, decoding 
+	 * is yet another bug at tm6000. After start sleeping, decoding
 	 * doesn't start automatically. Instead, it requires some
 	 * I2C commands to wake it up. As we want to have image at the
 	 * beginning, we needed to add this hack. The better would be to
@@ -390,7 +389,7 @@ struct reg_init {
 };
 
 /* The meaning of those initializations are unknown */
-struct reg_init tm6000_init_tab[] = {
+static struct reg_init tm6000_init_tab[] = {
 	/* REG  VALUE */
 	{ TM6000_REQ07_RDF_PWDOWN_ACLK, 0x1f },
 	{ TM6010_REQ07_RFF_SOFT_RESET, 0x08 },
@@ -458,7 +457,7 @@ struct reg_init tm6000_init_tab[] = {
 	{ TM6010_REQ05_R18_IMASK7, 0x00 },
 };
 
-struct reg_init tm6010_init_tab[] = {
+static struct reg_init tm6010_init_tab[] = {
 	{ TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x00 },
 	{ TM6010_REQ07_RC4_HSTART0, 0xa0 },
 	{ TM6010_REQ07_RC6_HEND0, 0x40 },
@@ -687,7 +686,7 @@ int tm6000_set_audio_rinput(struct tm6000_core *dev)
 	return 0;
 }
 
-void tm6010_set_mute_sif(struct tm6000_core *dev, u8 mute)
+static void tm6010_set_mute_sif(struct tm6000_core *dev, u8 mute)
 {
 	u8 mute_reg = 0;
 
@@ -697,7 +696,7 @@ void tm6010_set_mute_sif(struct tm6000_core *dev, u8 mute)
 	tm6000_set_reg_mask(dev, TM6010_REQ08_R0A_A_I2S_MOD, mute_reg, 0x08);
 }
 
-void tm6010_set_mute_adc(struct tm6000_core *dev, u8 mute)
+static void tm6010_set_mute_adc(struct tm6000_core *dev, u8 mute)
 {
 	u8 mute_reg = 0;
 
@@ -749,7 +748,7 @@ int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute)
 	return 0;
 }
 
-void tm6010_set_volume_sif(struct tm6000_core *dev, int vol)
+static void tm6010_set_volume_sif(struct tm6000_core *dev, int vol)
 {
 	u8 vol_reg;
 
@@ -762,7 +761,7 @@ void tm6010_set_volume_sif(struct tm6000_core *dev, int vol)
 	tm6000_set_reg(dev, TM6010_REQ08_R08_A_RIGHT_VOL, vol_reg);
 }
 
-void tm6010_set_volume_adc(struct tm6000_core *dev, int vol)
+static void tm6010_set_volume_adc(struct tm6000_core *dev, int vol)
 {
 	u8 vol_reg;
 
diff --git a/drivers/staging/tm6000/tm6000-dvb.c b/drivers/staging/tm6000/tm6000-dvb.c
index ff04c89..6e5ce25 100644
--- a/drivers/staging/tm6000/tm6000-dvb.c
+++ b/drivers/staging/tm6000/tm6000-dvb.c
@@ -105,7 +105,7 @@ static void tm6000_urb_received(struct urb *urb)
 	}
 }
 
-int tm6000_start_stream(struct tm6000_core *dev)
+static int tm6000_start_stream(struct tm6000_core *dev)
 {
 	int ret;
 	unsigned int pipe, size;
@@ -166,7 +166,7 @@ int tm6000_start_stream(struct tm6000_core *dev)
 	return 0;
 }
 
-void tm6000_stop_stream(struct tm6000_core *dev)
+static void tm6000_stop_stream(struct tm6000_core *dev)
 {
 	struct tm6000_dvb *dvb = dev->dvb;
 
@@ -180,7 +180,7 @@ void tm6000_stop_stream(struct tm6000_core *dev)
 	}
 }
 
-int tm6000_start_feed(struct dvb_demux_feed *feed)
+static int tm6000_start_feed(struct dvb_demux_feed *feed)
 {
 	struct dvb_demux *demux = feed->demux;
 	struct tm6000_core *dev = demux->priv;
@@ -199,7 +199,7 @@ int tm6000_start_feed(struct dvb_demux_feed *feed)
 	return 0;
 }
 
-int tm6000_stop_feed(struct dvb_demux_feed *feed)
+static int tm6000_stop_feed(struct dvb_demux_feed *feed)
 {
 	struct dvb_demux *demux = feed->demux;
 	struct tm6000_core *dev = demux->priv;
@@ -222,7 +222,7 @@ int tm6000_stop_feed(struct dvb_demux_feed *feed)
 	return 0;
 }
 
-int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
+static int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
 {
 	struct tm6000_dvb *dvb = dev->dvb;
 
@@ -247,7 +247,7 @@ int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
-int register_dvb(struct tm6000_core *dev)
+static int register_dvb(struct tm6000_core *dev)
 {
 	int ret = -1;
 	struct tm6000_dvb *dvb = dev->dvb;
@@ -359,7 +359,7 @@ err:
 	return ret;
 }
 
-void unregister_dvb(struct tm6000_core *dev)
+static void unregister_dvb(struct tm6000_core *dev)
 {
 	struct tm6000_dvb *dvb = dev->dvb;
 
diff --git a/drivers/staging/tm6000/tm6000-input.c b/drivers/staging/tm6000/tm6000-input.c
index dae2f1f..15ac727 100644
--- a/drivers/staging/tm6000/tm6000-input.c
+++ b/drivers/staging/tm6000/tm6000-input.c
@@ -284,7 +284,7 @@ static void tm6000_ir_stop(struct rc_dev *rc)
 	cancel_delayed_work_sync(&ir->work);
 }
 
-int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
+static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
 {
 	struct tm6000_IR *ir = rc->priv;
 
diff --git a/drivers/staging/tm6000/tm6000-stds.c b/drivers/staging/tm6000/tm6000-stds.c
index 8b29d73..bebf1f3 100644
--- a/drivers/staging/tm6000/tm6000-stds.c
+++ b/drivers/staging/tm6000/tm6000-stds.c
@@ -22,7 +22,7 @@
 #include "tm6000.h"
 #include "tm6000-regs.h"
 
-static unsigned int tm6010_a_mode = 0;
+static unsigned int tm6010_a_mode;
 module_param(tm6010_a_mode, int, 0644);
 MODULE_PARM_DESC(tm6010_a_mode, "set tm6010 sif audio mode");
 
@@ -674,6 +674,5 @@ ret:
 
 	msleep(40);
 
-
 	return 0;
 }
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index 4264064..e0cd512 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -19,6 +19,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
+
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
@@ -206,17 +207,6 @@ static inline void buffer_filled(struct tm6000_core *dev,
 	wake_up(&buf->vb.done);
 }
 
-const char *tm6000_msg_type[] = {
-	"unknown(0)",   /* 0 */
-	"video",        /* 1 */
-	"audio",        /* 2 */
-	"vbi",          /* 3 */
-	"pts",          /* 4 */
-	"err",          /* 5 */
-	"unknown(6)",   /* 6 */
-	"unknown(7)",   /* 7 */
-};
-
 /*
  * Identify the tm5600/6000 buffer header type and properly handles
  */
@@ -290,17 +280,18 @@ static int copy_streams(u8 *data, unsigned long len,
 			if (size > TM6000_URB_MSG_LEN)
 				size = TM6000_URB_MSG_LEN;
 			pktsize = TM6000_URB_MSG_LEN;
-			/* calculate position in buffer
-			 * and change the buffer
+			/*
+			 * calculate position in buffer and change the buffer
 			 */
 			switch (cmd) {
 			case TM6000_URB_MSG_VIDEO:
 				if (!dev->radio) {
 					if ((dev->isoc_ctl.vfield != field) &&
 						(field == 1)) {
-					/* Announces that a new buffer
-					 * were filled
-					 */
+						/*
+						 * Announces that a new buffer
+						 * were filled
+						 */
 						buffer_filled(dev, dma_q, vbuf);
 						dprintk(dev, V4L2_DEBUG_ISOC,
 							"new buffer filled\n");
@@ -325,7 +316,7 @@ static int copy_streams(u8 *data, unsigned long len,
 				break;
 			case TM6000_URB_MSG_AUDIO:
 			case TM6000_URB_MSG_PTS:
-				size = pktsize;		/* Size is always 180 bytes */
+				size = pktsize; /* Size is always 180 bytes */
 				break;
 			}
 		} else {
@@ -367,7 +358,8 @@ static int copy_streams(u8 *data, unsigned long len,
 			}
 		}
 		if (ptr + pktsize > endp) {
-			/* End of URB packet, but cmd processing is not
+			/*
+			 * End of URB packet, but cmd processing is not
 			 * complete. Preserve the state for a next packet
 			 */
 			dev->isoc_ctl.pos = pos + cpysize;
@@ -777,7 +769,8 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
 	}
 
 	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
-		if (0 != (rc = videobuf_iolock(vq, &buf->vb, NULL)))
+		rc = videobuf_iolock(vq, &buf->vb, NULL);
+		if (rc != 0)
 			goto fail;
 		urb_init = 1;
 	}
@@ -1038,8 +1031,8 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
 
 static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 {
-	struct tm6000_fh  *fh = priv;
-	struct tm6000_core *dev    = fh->dev;
+	struct tm6000_fh *fh = priv;
+	struct tm6000_core *dev = fh->dev;
 
 	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
@@ -1048,29 +1041,30 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 
 	if (!res_get(dev, fh, false))
 		return -EBUSY;
-	return (videobuf_streamon(&fh->vb_vidq));
+	return videobuf_streamon(&fh->vb_vidq);
 }
 
 static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 {
-	struct tm6000_fh  *fh=priv;
-	struct tm6000_core *dev    = fh->dev;
+	struct tm6000_fh *fh = priv;
+	struct tm6000_core *dev = fh->dev;
 
 	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
+
 	if (i != fh->type)
 		return -EINVAL;
 
 	videobuf_streamoff(&fh->vb_vidq);
-	res_free(dev,fh);
+	res_free(dev, fh);
 
-	return (0);
+	return 0;
 }
 
-static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *norm)
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
 {
-	int rc=0;
-	struct tm6000_fh   *fh=priv;
+	int rc = 0;
+	struct tm6000_fh *fh = priv;
 	struct tm6000_core *dev = fh->dev;
 
 	dev->norm = *norm;
@@ -1079,7 +1073,7 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *norm)
 	fh->width  = dev->width;
 	fh->height = dev->height;
 
-	if (rc<0)
+	if (rc < 0)
 		return rc;
 
 	v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
@@ -1087,7 +1081,7 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *norm)
 	return 0;
 }
 
-static const char *iname [] = {
+static const char * const iname[] = {
 	[TM6000_INPUT_TV] = "Television",
 	[TM6000_INPUT_COMPOSITE1] = "Composite 1",
 	[TM6000_INPUT_COMPOSITE2] = "Composite 2",
@@ -1394,10 +1388,10 @@ static int radio_g_input(struct file *filp, void *priv, unsigned int *i)
 	struct tm6000_fh *fh = priv;
 	struct tm6000_core *dev = fh->dev;
 
-	if (dev->input !=5)
+	if (dev->input != 5)
 		return -EINVAL;
 
-	*i = dev->input -5;
+	*i = dev->input - 5;
 
 	return 0;
 }
@@ -1467,9 +1461,6 @@ static int tm6000_open(struct file *file)
 	int i, rc;
 	int radio = 0;
 
-	printk(KERN_INFO "tm6000: open called (dev=%s)\n",
-		video_device_node_name(vdev));
-
 	dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: open called (dev=%s)\n",
 		video_device_node_name(vdev));
 
@@ -1499,27 +1490,27 @@ static int tm6000_open(struct file *file)
 		return -ENOMEM;
 	}
 
-	file->private_data = fh;
-	fh->dev      = dev;
-	fh->radio    = radio;
-	dev->radio   = radio;
-	fh->type     = type;
-	dev->fourcc  = format[0].fourcc;
-
-	fh->fmt      = format_by_fourcc(dev->fourcc);
-
-	tm6000_get_std_res (dev);
+	dev->radio = radio;
+	dev->fourcc = format[0].fourcc;
+	tm6000_get_std_res(dev);
 
-	fh->width    = dev->width;
-	fh->height   = dev->height;
+	file->private_data = fh;
+	fh->vdev = vdev;
+	fh->dev = dev;
+	fh->radio = radio;
+	fh->type = type;
+	fh->fmt = format_by_fourcc(dev->fourcc);
+	fh->width = dev->width;
+	fh->height = dev->height;
 
 	dprintk(dev, V4L2_DEBUG_OPEN, "Open: fh=0x%08lx, dev=0x%08lx, "
 						"dev->vidq=0x%08lx\n",
-		(unsigned long)fh,(unsigned long)dev,(unsigned long)&dev->vidq);
+			(unsigned long)fh, (unsigned long)dev,
+			(unsigned long)&dev->vidq);
 	dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty "
-				"queued=%d\n",list_empty(&dev->vidq.queued));
+				"queued=%d\n", list_empty(&dev->vidq.queued));
 	dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty "
-				"active=%d\n",list_empty(&dev->vidq.active));
+				"active=%d\n", list_empty(&dev->vidq.active));
 
 	/* initialize hardware on analog mode */
 	rc = tm6000_init_analog_mode(dev);
@@ -1557,7 +1548,7 @@ tm6000_read(struct file *file, char __user *data, size_t count, loff_t *pos)
 {
 	struct tm6000_fh        *fh = file->private_data;
 
-	if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
 		if (!res_get(fh->dev, fh, true))
 			return -EBUSY;
 
@@ -1583,11 +1574,10 @@ tm6000_poll(struct file *file, struct poll_table_struct *wait)
 		/* streaming capture */
 		if (list_empty(&fh->vb_vidq.stream))
 			return POLLERR;
-		buf = list_entry(fh->vb_vidq.stream.next,struct tm6000_buffer,vb.stream);
+		buf = list_entry(fh->vb_vidq.stream.next, struct tm6000_buffer, vb.stream);
 	} else {
 		/* read() capture */
-		return videobuf_poll_stream(file, &fh->vb_vidq,
-					    wait);
+		return videobuf_poll_stream(file, &fh->vb_vidq, wait);
 	}
 	poll_wait(file, &buf->vb.done, wait);
 	if (buf->vb.state == VIDEOBUF_DONE ||
@@ -1620,22 +1610,19 @@ static int tm6000_release(struct file *file)
 
 static int tm6000_mmap(struct file *file, struct vm_area_struct * vma)
 {
-	struct tm6000_fh        *fh = file->private_data;
-	int ret;
-
-	ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+	struct tm6000_fh *fh = file->private_data;
 
-	return ret;
+	return videobuf_mmap_mapper(&fh->vb_vidq, vma);
 }
 
 static struct v4l2_file_operations tm6000_fops = {
-	.owner		= THIS_MODULE,
-	.open           = tm6000_open,
-	.release        = tm6000_release,
-	.unlocked_ioctl	= video_ioctl2, /* V4L2 ioctl handler */
-	.read           = tm6000_read,
-	.poll		= tm6000_poll,
-	.mmap		= tm6000_mmap,
+	.owner = THIS_MODULE,
+	.open = tm6000_open,
+	.release = tm6000_release,
+	.unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
+	.read = tm6000_read,
+	.poll = tm6000_poll,
+	.mmap = tm6000_mmap,
 };
 
 static const struct v4l2_ioctl_ops video_ioctl_ops = {
@@ -1696,10 +1683,10 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = {
 	.vidioc_s_frequency	= vidioc_s_frequency,
 };
 
-struct video_device tm6000_radio_template = {
+static struct video_device tm6000_radio_template = {
 	.name			= "tm6000",
 	.fops			= &radio_fops,
-	.ioctl_ops 		= &radio_ioctl_ops,
+	.ioctl_ops		= &radio_ioctl_ops,
 };
 
 /* -----------------------------------------------------------------
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
index ae6369b..4323fc2 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -20,9 +20,6 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* Use the tm6000-hack, instead of the proper initialization code i*/
-/* #define HACK 1 */
-
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/videobuf-vmalloc.h>
@@ -31,7 +28,6 @@
 #include <linux/mutex.h>
 #include <media/v4l2-device.h>
 
-
 #include <linux/dvb/frontend.h>
 #include "dvb_demux.h"
 #include "dvb_frontend.h"
-- 
1.7.6


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

* [PATCH 04/21] [staging] tm6000: Use correct input in radio mode.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (2 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 03/21] [staging] tm6000: Miscellaneous cleanups Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-04  7:14 ` [PATCH 05/21] [staging] tm6000: Implement I2C flush callback Thierry Reding
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

In radio mode, the correct input is rinput. The pseudo index 5 is used
but cannot be used to index the vinput array because that only has 3
elements.
---
 drivers/staging/tm6000/tm6000-stds.c |   28 +++++++++++++++-------------
 1 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-stds.c b/drivers/staging/tm6000/tm6000-stds.c
index bebf1f3..cd69626 100644
--- a/drivers/staging/tm6000/tm6000-stds.c
+++ b/drivers/staging/tm6000/tm6000-stds.c
@@ -525,6 +525,7 @@ static int tm6000_load_std(struct tm6000_core *dev,
 
 int tm6000_set_standard(struct tm6000_core *dev)
 {
+	struct tm6000_input *input;
 	int i, rc = 0;
 	u8 reg_07_fe = 0x8a;
 	u8 reg_08_f1 = 0xfc;
@@ -533,12 +534,13 @@ int tm6000_set_standard(struct tm6000_core *dev)
 
 	tm6000_get_std_res(dev);
 
-	if (dev->radio) {
-		/* todo */
-	}
+	if (!dev->radio)
+		input = &dev->vinput[dev->input];
+	else
+		input = &dev->rinput;
 
 	if (dev->dev_type == TM6010) {
-		switch (dev->vinput[dev->input].vmux) {
+		switch (input->vmux) {
 		case TM6000_VMUX_VIDEO_A:
 			tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4);
 			tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1);
@@ -567,7 +569,7 @@ int tm6000_set_standard(struct tm6000_core *dev)
 		default:
 			break;
 		}
-		switch (dev->vinput[dev->input].amux) {
+		switch (input->amux) {
 		case TM6000_AMUX_ADC1:
 			tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
 				0x00, 0x0f);
@@ -602,32 +604,32 @@ int tm6000_set_standard(struct tm6000_core *dev)
 		tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, reg_08_f1);
 		tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, reg_07_fe);
 	} else {
-		switch (dev->vinput[dev->input].vmux) {
+		switch (input->vmux) {
 		case TM6000_VMUX_VIDEO_A:
 			tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10);
 			tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00);
 			tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x0f);
 			tm6000_set_reg(dev,
-			    REQ_03_SET_GET_MCU_PIN, dev->vinput[dev->input].v_gpio, 0);
+			    REQ_03_SET_GET_MCU_PIN, input->v_gpio, 0);
 			break;
 		case TM6000_VMUX_VIDEO_B:
 			tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x00);
 			tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00);
 			tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x0f);
 			tm6000_set_reg(dev,
-			    REQ_03_SET_GET_MCU_PIN, dev->vinput[dev->input].v_gpio, 0);
+			    REQ_03_SET_GET_MCU_PIN, input->v_gpio, 0);
 			break;
 		case TM6000_VMUX_VIDEO_AB:
 			tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10);
 			tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x10);
 			tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x00);
 			tm6000_set_reg(dev,
-			    REQ_03_SET_GET_MCU_PIN, dev->vinput[dev->input].v_gpio, 1);
+			    REQ_03_SET_GET_MCU_PIN, input->v_gpio, 1);
 			break;
 		default:
 			break;
 		}
-		switch (dev->vinput[dev->input].amux) {
+		switch (input->amux) {
 		case TM6000_AMUX_ADC1:
 			tm6000_set_reg_mask(dev,
 				TM6000_REQ07_REB_VADC_AADC_MODE, 0x00, 0x0f);
@@ -640,7 +642,7 @@ int tm6000_set_standard(struct tm6000_core *dev)
 			break;
 		}
 	}
-	if (dev->vinput[dev->input].type == TM6000_INPUT_SVIDEO) {
+	if (input->type == TM6000_INPUT_SVIDEO) {
 		for (i = 0; i < ARRAY_SIZE(svideo_stds); i++) {
 			if (dev->norm & svideo_stds[i].id) {
 				rc = tm6000_load_std(dev, svideo_stds[i].common,
@@ -668,8 +670,8 @@ ret:
 		return rc;
 
 	if ((dev->dev_type == TM6010) &&
-	    ((dev->vinput[dev->input].amux == TM6000_AMUX_SIF1) ||
-	    (dev->vinput[dev->input].amux == TM6000_AMUX_SIF2)))
+	    ((input->amux == TM6000_AMUX_SIF1) ||
+	    (input->amux == TM6000_AMUX_SIF2)))
 		tm6000_set_audio_std(dev);
 
 	msleep(40);
-- 
1.7.6


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

* [PATCH 05/21] [staging] tm6000: Implement I2C flush callback.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (3 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 04/21] [staging] tm6000: Use correct input in radio mode Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-04  7:14 ` [PATCH 06/21] [staging] tm6000: Increase maximum I2C packet size Thierry Reding
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

---
 drivers/staging/tm6000/tm6000-cards.c |    5 +++++
 drivers/staging/tm6000/tm6000-i2c.c   |    5 -----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index 202f454..c3b84c9 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -781,6 +781,11 @@ int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
 			rc = tm6000_i2c_reset(dev, 100);
 			break;
 		}
+		break;
+	case XC2028_I2C_FLUSH:
+		tm6000_set_reg(dev, REQ_50_SET_START, 0, 0);
+		tm6000_set_reg(dev, REQ_51_SET_STOP, 0, 0);
+		break;
 	}
 	return rc;
 }
diff --git a/drivers/staging/tm6000/tm6000-i2c.c b/drivers/staging/tm6000/tm6000-i2c.c
index 8828c12..21cd9f8 100644
--- a/drivers/staging/tm6000/tm6000-i2c.c
+++ b/drivers/staging/tm6000/tm6000-i2c.c
@@ -219,11 +219,6 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
 					printk(" %02x", msgs[i].buf[byte]);
 			rc = tm6000_i2c_send_regs(dev, addr, msgs[i].buf[0],
 				msgs[i].buf + 1, msgs[i].len - 1);
-
-			if (addr == dev->tuner_addr  << 1) {
-				tm6000_set_reg(dev, REQ_50_SET_START, 0, 0);
-				tm6000_set_reg(dev, REQ_51_SET_STOP, 0, 0);
-			}
 		}
 		if (i2c_debug >= 2)
 			printk("\n");
-- 
1.7.6


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

* [PATCH 06/21] [staging] tm6000: Increase maximum I2C packet size.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (4 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 05/21] [staging] tm6000: Implement I2C flush callback Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-31 19:45   ` Mauro Carvalho Chehab
  2011-08-04  7:14 ` [PATCH 07/21] [staging] tm6000: Remove artificial delay Thierry Reding
                   ` (15 subsequent siblings)
  21 siblings, 1 reply; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

The TM6010 supports much larger I2C transfers than currently specified.
In fact the Windows driver seems to use 81 bytes per packet by default.
This commit improves the speed of firmware loading a bit.
---
 drivers/staging/tm6000/tm6000-cards.c |    1 +
 drivers/staging/tm6000/tm6000-i2c.c   |    2 +-
 2 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index c3b84c9..a5d2a71 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -929,6 +929,7 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
 		memset(&ctl, 0, sizeof(ctl));
 
 		ctl.demod = XC3028_FE_ZARLINK456;
+		ctl.max_len = 81;
 
 		xc2028_cfg.tuner = TUNER_XC2028;
 		xc2028_cfg.priv  = &ctl;
diff --git a/drivers/staging/tm6000/tm6000-i2c.c b/drivers/staging/tm6000/tm6000-i2c.c
index 21cd9f8..2cb7573 100644
--- a/drivers/staging/tm6000/tm6000-i2c.c
+++ b/drivers/staging/tm6000/tm6000-i2c.c
@@ -50,7 +50,7 @@ static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr,
 	unsigned int i2c_packet_limit = 16;
 
 	if (dev->dev_type == TM6010)
-		i2c_packet_limit = 64;
+		i2c_packet_limit = 256;
 
 	if (!buf)
 		return -1;
-- 
1.7.6


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

* [PATCH 07/21] [staging] tm6000: Remove artificial delay.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (5 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 06/21] [staging] tm6000: Increase maximum I2C packet size Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-31 19:50   ` Mauro Carvalho Chehab
  2011-08-04  7:14 ` [PATCH 08/21] [staging] tm6000: Flesh out the IRQ callback Thierry Reding
                   ` (14 subsequent siblings)
  21 siblings, 1 reply; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

---
 drivers/staging/tm6000/tm6000-core.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index e14bd3d..2c156dd 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -86,9 +86,6 @@ int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req,
 	}
 
 	kfree(data);
-
-	msleep(5);
-
 	return ret;
 }
 
-- 
1.7.6


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

* [PATCH 08/21] [staging] tm6000: Flesh out the IRQ callback.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (6 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 07/21] [staging] tm6000: Remove artificial delay Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-04  7:14 ` [PATCH 09/21] [staging] tm6000: Rename active interface register Thierry Reding
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

This brings the IRQ callback implementation more in line with how other
drivers do it.
---
 drivers/staging/tm6000/tm6000-video.c |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index e0cd512..4b50f6c 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -517,9 +517,21 @@ static void tm6000_irq_callback(struct urb *urb)
 	struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
 	int i;
 
-	if (!dev)
+	switch (urb->status) {
+	case 0:
+	case -ETIMEDOUT:
+		break;
+
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
 		return;
 
+	default:
+		tm6000_err("urb completion error %d.\n", urb->status);
+		break;
+	}
+
 	spin_lock(&dev->slock);
 	tm6000_isoc_copy(urb);
 	spin_unlock(&dev->slock);
-- 
1.7.6


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

* [PATCH 09/21] [staging] tm6000: Rename active interface register.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (7 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 08/21] [staging] tm6000: Flesh out the IRQ callback Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-04  7:14 ` [PATCH 10/21] [staging] tm6000: Disable video interface in radio mode Thierry Reding
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

The register ACTIVE_VIDEO_IF register should be named ACTIVE_IF since it
controls more than just the video interface.
---
 drivers/staging/tm6000/tm6000-alsa.c |    4 ++--
 drivers/staging/tm6000/tm6000-core.c |   12 ++++++------
 drivers/staging/tm6000/tm6000-regs.h |    4 +++-
 3 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c
index 768d713..35ad1f0 100644
--- a/drivers/staging/tm6000/tm6000-alsa.c
+++ b/drivers/staging/tm6000/tm6000-alsa.c
@@ -80,7 +80,7 @@ static int _tm6000_start_audio_dma(struct snd_tm6000_card *chip)
 	dprintk(1, "Starting audio DMA\n");
 
 	/* Enables audio */
-	tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x40, 0x40);
+	tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_IF, 0x40, 0x40);
 
 	tm6000_set_audio_bitrate(core, 48000);
 
@@ -98,7 +98,7 @@ static int _tm6000_stop_audio_dma(struct snd_tm6000_card *chip)
 	dprintk(1, "Stopping audio DMA\n");
 
 	/* Disables audio */
-	tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x00, 0x40);
+	tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_IF, 0x00, 0x40);
 
 	return 0;
 }
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index 2c156dd..2117f8e 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -184,11 +184,11 @@ void tm6000_set_fourcc_format(struct tm6000_core *dev)
 	if (dev->dev_type == TM6010) {
 		int val;
 
-		val = tm6000_get_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0) & 0xfc;
+		val = tm6000_get_reg(dev, TM6010_REQ07_RCC_ACTIVE_IF, 0) & 0xfc;
 		if (dev->fourcc == V4L2_PIX_FMT_UYVY)
-			tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val);
+			tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_IF, val);
 		else
-			tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val | 1);
+			tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_IF, val | 1);
 	} else {
 		if (dev->fourcc == V4L2_PIX_FMT_UYVY)
 			tm6000_set_reg(dev, TM6010_REQ07_RC1_TRESHOLD, 0xd0);
@@ -265,7 +265,7 @@ int tm6000_init_analog_mode(struct tm6000_core *dev)
 
 	if (dev->dev_type == TM6010) {
 		/* Enable video and audio */
-		tm6000_set_reg_mask(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF,
+		tm6000_set_reg_mask(dev, TM6010_REQ07_RCC_ACTIVE_IF,
 							0x60, 0x60);
 		/* Disable TS input */
 		tm6000_set_reg_mask(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE,
@@ -331,7 +331,7 @@ int tm6000_init_digital_mode(struct tm6000_core *dev)
 {
 	if (dev->dev_type == TM6010) {
 		/* Disable video and audio */
-		tm6000_set_reg_mask(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF,
+		tm6000_set_reg_mask(dev, TM6010_REQ07_RCC_ACTIVE_IF,
 				0x00, 0x60);
 		/* Enable TS input */
 		tm6000_set_reg_mask(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE,
@@ -459,7 +459,7 @@ static struct reg_init tm6010_init_tab[] = {
 	{ TM6010_REQ07_RC4_HSTART0, 0xa0 },
 	{ TM6010_REQ07_RC6_HEND0, 0x40 },
 	{ TM6010_REQ07_RCA_VEND0, 0x31 },
-	{ TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0xe1 },
+	{ TM6010_REQ07_RCC_ACTIVE_IF, 0xe1 },
 	{ TM6010_REQ07_RE0_DVIDEO_SOURCE, 0x03 },
 	{ TM6010_REQ07_RFE_POWER_DOWN, 0x7f },
 
diff --git a/drivers/staging/tm6000/tm6000-regs.h b/drivers/staging/tm6000/tm6000-regs.h
index 5375a83..6e4ef95 100644
--- a/drivers/staging/tm6000/tm6000-regs.h
+++ b/drivers/staging/tm6000/tm6000-regs.h
@@ -270,7 +270,9 @@ enum {
 #define TM6010_REQ07_RCA_VEND0				0x07, 0xca
 #define TM6010_REQ07_RCB_DELAY				0x07, 0xcb
 /* ONLY for TM6010 */
-#define TM6010_REQ07_RCC_ACTIVE_VIDEO_IF		0x07, 0xcc
+#define TM6010_REQ07_RCC_ACTIVE_IF			0x07, 0xcc
+#define TM6010_REQ07_RCC_ACTIVE_IF_VIDEO_ENABLE (1 << 5)
+#define TM6010_REQ07_RCC_ACTIVE_IF_AUDIO_ENABLE (1 << 6)
 #define TM6010_REQ07_RD0_USB_PERIPHERY_CONTROL		0x07, 0xd0
 #define TM6010_REQ07_RD1_ADDR_FOR_REQ1			0x07, 0xd1
 #define TM6010_REQ07_RD2_ADDR_FOR_REQ2			0x07, 0xd2
-- 
1.7.6


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

* [PATCH 10/21] [staging] tm6000: Disable video interface in radio mode.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (8 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 09/21] [staging] tm6000: Rename active interface register Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-04  7:14 ` [PATCH 11/21] [staging] tm6000: Rework standard register tables Thierry Reding
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

Video data is useless in radio mode, so the corresponding interface can
be safely disabled. This should reduce the amount of isochronous traffic
noticeably.
---
 drivers/staging/tm6000/tm6000-core.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index 2117f8e..1f8abe3 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -264,9 +264,14 @@ int tm6000_init_analog_mode(struct tm6000_core *dev)
 	struct v4l2_frequency f;
 
 	if (dev->dev_type == TM6010) {
+		u8 active = TM6010_REQ07_RCC_ACTIVE_IF_AUDIO_ENABLE;
+
+		if (!dev->radio)
+			active |= TM6010_REQ07_RCC_ACTIVE_IF_VIDEO_ENABLE;
+
 		/* Enable video and audio */
 		tm6000_set_reg_mask(dev, TM6010_REQ07_RCC_ACTIVE_IF,
-							0x60, 0x60);
+							active, 0x60);
 		/* Disable TS input */
 		tm6000_set_reg_mask(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE,
 							0x00, 0x40);
-- 
1.7.6


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

* [PATCH 11/21] [staging] tm6000: Rework standard register tables.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (9 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 10/21] [staging] tm6000: Disable video interface in radio mode Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-04  7:14 ` [PATCH 12/21] [staging] tm6000: Add locking for USB transfers Thierry Reding
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

This commit uses sentinel entries to terminate the TV standard register
tables instead of hard-coding their size, allowing further entries to be
added more easily. It is also more space-efficient if the tables have a
varying number of entries.
---
 drivers/staging/tm6000/tm6000-stds.c |  610 ++++++++++++++++------------------
 1 files changed, 294 insertions(+), 316 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-stds.c b/drivers/staging/tm6000/tm6000-stds.c
index cd69626..f44451b 100644
--- a/drivers/staging/tm6000/tm6000-stds.c
+++ b/drivers/staging/tm6000/tm6000-stds.c
@@ -35,316 +35,303 @@ struct tm6000_reg_settings {
 
 struct tm6000_std_settings {
 	v4l2_std_id id;
-	struct tm6000_reg_settings common[27];
+	struct tm6000_reg_settings *common;
+};
+
+static struct tm6000_reg_settings composite_pal_m[] = {
+	{ TM6010_REQ07_R3F_RESET, 0x01 },
+	{ TM6010_REQ07_R00_VIDEO_CONTROL0, 0x04 },
+	{ TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
+	{ TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
+	{ TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00 },
+	{ TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
+	{ TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
+	{ TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83 },
+	{ TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a },
+	{ TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0 },
+	{ TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
+	{ TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
+	{ TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
+	{ TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
+	{ TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
+	{ TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x20 },
+	{ TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
+	{ TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
+	{ TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
+	{ TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
+	{ TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
+	{ TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
+	{ TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
+	{ TM6010_REQ07_R3F_RESET, 0x00 },
+	{ 0, 0, 0 }
+};
+
+static struct tm6000_reg_settings composite_pal_nc[] = {
+	{ TM6010_REQ07_R3F_RESET, 0x01 },
+	{ TM6010_REQ07_R00_VIDEO_CONTROL0, 0x36 },
+	{ TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
+	{ TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
+	{ TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02 },
+	{ TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
+	{ TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
+	{ TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91 },
+	{ TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f },
+	{ TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c },
+	{ TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
+	{ TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
+	{ TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
+	{ TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
+	{ TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
+	{ TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c },
+	{ TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
+	{ TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
+	{ TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
+	{ TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
+	{ TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
+	{ TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
+	{ TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
+	{ TM6010_REQ07_R3F_RESET, 0x00 },
+	{ 0, 0, 0 }
+};
+
+static struct tm6000_reg_settings composite_pal[] = {
+	{ TM6010_REQ07_R3F_RESET, 0x01 },
+	{ TM6010_REQ07_R00_VIDEO_CONTROL0, 0x32 },
+	{ TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
+	{ TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
+	{ TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02 },
+	{ TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
+	{ TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25 },
+	{ TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5 },
+	{ TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63 },
+	{ TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50 },
+	{ TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
+	{ TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
+	{ TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
+	{ TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
+	{ TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
+	{ TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c },
+	{ TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
+	{ TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
+	{ TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
+	{ TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
+	{ TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
+	{ TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
+	{ TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
+	{ TM6010_REQ07_R3F_RESET, 0x00 },
+	{ 0, 0, 0 }
+};
+
+static struct tm6000_reg_settings composite_secam[] = {
+	{ TM6010_REQ07_R3F_RESET, 0x01 },
+	{ TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38 },
+	{ TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
+	{ TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
+	{ TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02 },
+	{ TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
+	{ TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24 },
+	{ TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92 },
+	{ TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8 },
+	{ TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed },
+	{ TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
+	{ TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
+	{ TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
+	{ TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
+	{ TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
+	{ TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c },
+	{ TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
+	{ TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c },
+	{ TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18 },
+	{ TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
+	{ TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xff },
+	{ TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
+	{ TM6010_REQ07_R3F_RESET, 0x00 },
+	{ 0, 0, 0 }
+};
+
+static struct tm6000_reg_settings composite_ntsc[] = {
+	{ TM6010_REQ07_R3F_RESET, 0x01 },
+	{ TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00 },
+	{ TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f },
+	{ TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
+	{ TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00 },
+	{ TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
+	{ TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
+	{ TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b },
+	{ TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2 },
+	{ TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9 },
+	{ TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
+	{ TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
+	{ TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
+	{ TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
+	{ TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
+	{ TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
+	{ TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
+	{ TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c },
+	{ TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
+	{ TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
+	{ TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
+	{ TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd },
+	{ TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
+	{ TM6010_REQ07_R3F_RESET, 0x00 },
+	{ 0, 0, 0 }
 };
 
 static struct tm6000_std_settings composite_stds[] = {
-	{
-		.id = V4L2_STD_PAL_M,
-		.common = {
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x04},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x20},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
-
-			{TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-			{TM6010_REQ07_R3F_RESET, 0x00},
-			{0, 0, 0},
-		},
-	 }, {
-		.id = V4L2_STD_PAL_Nc,
-		.common = {
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x36},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
-
-			{TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-			{TM6010_REQ07_R3F_RESET, 0x00},
-			{0, 0, 0},
-		},
-	}, {
-		.id = V4L2_STD_PAL,
-		.common = {
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x32},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
-
-			{TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-			{TM6010_REQ07_R3F_RESET, 0x00},
-			{0, 0, 0},
-		},
-	 }, {
-		.id = V4L2_STD_SECAM,
-		.common = {
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF},
-
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-			{TM6010_REQ07_R3F_RESET, 0x00},
-			{0, 0, 0},
-		},
-	}, {
-		.id = V4L2_STD_NTSC,
-		.common = {
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
-
-			{TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd},
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-			{TM6010_REQ07_R3F_RESET, 0x00},
-			{0, 0, 0},
-		},
-	},
+	{ .id = V4L2_STD_PAL_M, .common = composite_pal_m, },
+	{ .id = V4L2_STD_PAL_Nc, .common = composite_pal_nc, },
+	{ .id = V4L2_STD_PAL, .common = composite_pal, },
+	{ .id = V4L2_STD_SECAM, .common = composite_secam, },
+	{ .id = V4L2_STD_NTSC, .common = composite_ntsc, },
 };
 
-static struct tm6000_std_settings svideo_stds[] = {
-	{
-		.id = V4L2_STD_PAL_M,
-		.common = {
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x05},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
-
-			{TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-			{TM6010_REQ07_R3F_RESET, 0x00},
-			{0, 0, 0},
-		},
-	}, {
-		.id = V4L2_STD_PAL_Nc,
-		.common = {
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x37},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
-
-			{TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-			{TM6010_REQ07_R3F_RESET, 0x00},
-			{0, 0, 0},
-		},
-	}, {
-		.id = V4L2_STD_PAL,
-		.common = {
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x33},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x30},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
-
-			{TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-			{TM6010_REQ07_R3F_RESET, 0x00},
-			{0, 0, 0},
-		},
-	 }, {
-		.id = V4L2_STD_SECAM,
-		.common = {
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x39},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF},
-
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-			{TM6010_REQ07_R3F_RESET, 0x00},
-			{0, 0, 0},
-		},
-	}, {
-		.id = V4L2_STD_NTSC,
-		.common = {
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x01},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x30},
-			{TM6010_REQ07_R17_HLOOP_MAXSTATE, 0x8b},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
-
-			{TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd},
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-			{TM6010_REQ07_R3F_RESET, 0x00},
-			{0, 0, 0},
-		},
-	},
+static struct tm6000_reg_settings svideo_pal_m[] = {
+	{ TM6010_REQ07_R3F_RESET, 0x01 },
+	{ TM6010_REQ07_R00_VIDEO_CONTROL0, 0x05 },
+	{ TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
+	{ TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
+	{ TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04 },
+	{ TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
+	{ TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
+	{ TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83 },
+	{ TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a },
+	{ TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0 },
+	{ TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
+	{ TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
+	{ TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
+	{ TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
+	{ TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
+	{ TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
+	{ TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
+	{ TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
+	{ TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
+	{ TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
+	{ TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
+	{ TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
+	{ TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
+	{ TM6010_REQ07_R3F_RESET, 0x00 },
+	{ 0, 0, 0 }
 };
 
+static struct tm6000_reg_settings svideo_pal_nc[] = {
+	{ TM6010_REQ07_R3F_RESET, 0x01 },
+	{ TM6010_REQ07_R00_VIDEO_CONTROL0, 0x37 },
+	{ TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
+	{ TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
+	{ TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04 },
+	{ TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
+	{ TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
+	{ TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91 },
+	{ TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f },
+	{ TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c },
+	{ TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
+	{ TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
+	{ TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
+	{ TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
+	{ TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
+	{ TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
+	{ TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
+	{ TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
+	{ TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
+	{ TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
+	{ TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
+	{ TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
+	{ TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
+	{ TM6010_REQ07_R3F_RESET, 0x00 },
+	{ 0, 0, 0 }
+};
+
+static struct tm6000_reg_settings svideo_pal[] = {
+	{ TM6010_REQ07_R3F_RESET, 0x01 },
+	{ TM6010_REQ07_R00_VIDEO_CONTROL0, 0x33 },
+	{ TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
+	{ TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
+	{ TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04 },
+	{ TM6010_REQ07_R07_OUTPUT_CONTROL, 0x30 },
+	{ TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25 },
+	{ TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5 },
+	{ TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63 },
+	{ TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50 },
+	{ TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
+	{ TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
+	{ TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
+	{ TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
+	{ TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
+	{ TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a },
+	{ TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
+	{ TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c },
+	{ TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
+	{ TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52 },
+	{ TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
+	{ TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc },
+	{ TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
+	{ TM6010_REQ07_R3F_RESET, 0x00 },
+	{ 0, 0, 0 }
+};
+
+static struct tm6000_reg_settings svideo_secam[] = {
+	{ TM6010_REQ07_R3F_RESET, 0x01 },
+	{ TM6010_REQ07_R00_VIDEO_CONTROL0, 0x39 },
+	{ TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e },
+	{ TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
+	{ TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03 },
+	{ TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31 },
+	{ TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24 },
+	{ TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92 },
+	{ TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8 },
+	{ TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed },
+	{ TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
+	{ TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
+	{ TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
+	{ TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
+	{ TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c },
+	{ TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a },
+	{ TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1 },
+	{ TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c },
+	{ TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18 },
+	{ TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
+	{ TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xff },
+	{ TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
+	{ TM6010_REQ07_R3F_RESET, 0x00 },
+	{ 0, 0, 0 }
+};
+
+static struct tm6000_reg_settings svideo_ntsc[] = {
+	{ TM6010_REQ07_R3F_RESET, 0x01 },
+	{ TM6010_REQ07_R00_VIDEO_CONTROL0, 0x01 },
+	{ TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f },
+	{ TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
+	{ TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03 },
+	{ TM6010_REQ07_R07_OUTPUT_CONTROL, 0x30 },
+	{ TM6010_REQ07_R17_HLOOP_MAXSTATE, 0x8b },
+	{ TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
+	{ TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b },
+	{ TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2 },
+	{ TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9 },
+	{ TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
+	{ TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
+	{ TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
+	{ TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
+	{ TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
+	{ TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
+	{ TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
+	{ TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c },
+	{ TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
+	{ TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
+	{ TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6f },
+	{ TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd },
+	{ TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07 },
+	{ TM6010_REQ07_R3F_RESET, 0x00 },
+	{ 0, 0, 0 }
+};
+
+static struct tm6000_std_settings svideo_stds[] = {
+	{ .id = V4L2_STD_PAL_M, .common = svideo_pal_m, },
+	{ .id = V4L2_STD_PAL_Nc, .common = svideo_pal_nc, },
+	{ .id = V4L2_STD_PAL, .common = svideo_pal, },
+	{ .id = V4L2_STD_SECAM, .common = svideo_secam, },
+	{ .id = V4L2_STD_NTSC, .common = svideo_ntsc, },
+};
 
 static int tm6000_set_audio_std(struct tm6000_core *dev)
 {
@@ -501,16 +488,12 @@ void tm6000_get_std_res(struct tm6000_core *dev)
 	dev->width = 720;
 }
 
-static int tm6000_load_std(struct tm6000_core *dev,
-			   struct tm6000_reg_settings *set, int max_size)
+static int tm6000_load_std(struct tm6000_core *dev, struct tm6000_reg_settings *set)
 {
 	int i, rc;
 
 	/* Load board's initialization table */
-	for (i = 0; max_size; i++) {
-		if (!set[i].req)
-			return 0;
-
+	for (i = 0; set[i].req; i++) {
 		rc = tm6000_set_reg(dev, set[i].req, set[i].reg, set[i].value);
 		if (rc < 0) {
 			printk(KERN_ERR "Error %i while setting "
@@ -645,9 +628,7 @@ int tm6000_set_standard(struct tm6000_core *dev)
 	if (input->type == TM6000_INPUT_SVIDEO) {
 		for (i = 0; i < ARRAY_SIZE(svideo_stds); i++) {
 			if (dev->norm & svideo_stds[i].id) {
-				rc = tm6000_load_std(dev, svideo_stds[i].common,
-						     sizeof(svideo_stds[i].
-							    common));
+				rc = tm6000_load_std(dev, svideo_stds[i].common);
 				goto ret;
 			}
 		}
@@ -655,10 +636,7 @@ int tm6000_set_standard(struct tm6000_core *dev)
 	} else {
 		for (i = 0; i < ARRAY_SIZE(composite_stds); i++) {
 			if (dev->norm & composite_stds[i].id) {
-				rc = tm6000_load_std(dev,
-						     composite_stds[i].common,
-						     sizeof(composite_stds[i].
-							    common));
+				rc = tm6000_load_std(dev, composite_stds[i].common);
 				goto ret;
 			}
 		}
-- 
1.7.6


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

* [PATCH 12/21] [staging] tm6000: Add locking for USB transfers.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (10 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 11/21] [staging] tm6000: Rework standard register tables Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-04  7:14 ` [PATCH 13/21] [staging] tm6000: Properly count device usage Thierry Reding
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

This commit introduces the usb_lock mutex to ensure that a USB request
always gets the proper response. While this is currently not really
necessary it will become important as there are more users.
---
 drivers/staging/tm6000/tm6000-cards.c |    1 +
 drivers/staging/tm6000/tm6000-core.c  |    3 +++
 drivers/staging/tm6000/tm6000.h       |    1 +
 3 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index a5d2a71..68f7c7a 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -1174,6 +1174,7 @@ static int tm6000_usb_probe(struct usb_interface *interface,
 		return -ENOMEM;
 	}
 	spin_lock_init(&dev->slock);
+	mutex_init(&dev->usb_lock);
 
 	/* Increment usage count */
 	tm6000_devused |= 1<<nr;
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index 1f8abe3..317ab7e 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -39,6 +39,8 @@ int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req,
 	unsigned int pipe;
 	u8	     *data = NULL;
 
+	mutex_lock(&dev->usb_lock);
+
 	if (len)
 		data = kzalloc(len, GFP_KERNEL);
 
@@ -86,6 +88,7 @@ int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req,
 	}
 
 	kfree(data);
+	mutex_unlock(&dev->usb_lock);
 	return ret;
 }
 
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
index 4323fc2..cf57e1e 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -245,6 +245,7 @@ struct tm6000_core {
 
 	/* locks */
 	struct mutex			lock;
+	struct mutex			usb_lock;
 
 	/* usb transfer */
 	struct usb_device		*udev;		/* the usb device */
-- 
1.7.6


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

* [PATCH 13/21] [staging] tm6000: Properly count device usage.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (11 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 12/21] [staging] tm6000: Add locking for USB transfers Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-04  7:14 ` [PATCH 14/21] [staging] tm6000: Initialize isochronous transfers only once Thierry Reding
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

When the USB device is disconnected, the device usage bit is not cleared
properly. This leads to errors when a device is unplugged and replugged
several times until all TM6000_MAXBOARDS bits are used and keeps the
driver from binding to the device.
---
 drivers/staging/tm6000/tm6000-cards.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index 68f7c7a..94fd138 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -1177,7 +1177,7 @@ static int tm6000_usb_probe(struct usb_interface *interface,
 	mutex_init(&dev->usb_lock);
 
 	/* Increment usage count */
-	tm6000_devused |= 1<<nr;
+	set_bit(nr, &tm6000_devused);
 	snprintf(dev->name, 29, "tm6000 #%d", nr);
 
 	dev->model = id->driver_info;
@@ -1293,7 +1293,7 @@ static int tm6000_usb_probe(struct usb_interface *interface,
 err:
 	printk(KERN_ERR "tm6000: Error %d while registering\n", rc);
 
-	tm6000_devused &= ~(1<<nr);
+	clear_bit(nr, &tm6000_devused);
 	usb_put_dev(usbdev);
 
 	kfree(dev);
@@ -1351,6 +1351,7 @@ static void tm6000_usb_disconnect(struct usb_interface *interface)
 	tm6000_close_extension(dev);
 	tm6000_remove_from_devlist(dev);
 
+	clear_bit(dev->devno, &tm6000_devused);
 	kfree(dev);
 }
 
-- 
1.7.6


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

* [PATCH 14/21] [staging] tm6000: Initialize isochronous transfers only once.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (12 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 13/21] [staging] tm6000: Properly count device usage Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-04  7:14 ` [PATCH 15/21] [staging] tm6000: Execute lightweight reset on close Thierry Reding
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

This fixes a memory leak where isochronous buffers would be set up for
each video buffer, while it is sufficient to set them up only once per
device.
---
 drivers/staging/tm6000/tm6000-video.c |    8 ++------
 1 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index 4b50f6c..492ec73 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -758,7 +758,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
 	struct tm6000_fh     *fh  = vq->priv_data;
 	struct tm6000_buffer *buf = container_of(vb, struct tm6000_buffer, vb);
 	struct tm6000_core   *dev = fh->dev;
-	int rc = 0, urb_init = 0;
+	int rc = 0;
 
 	BUG_ON(NULL == fh->fmt);
 
@@ -784,13 +784,9 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
 		rc = videobuf_iolock(vq, &buf->vb, NULL);
 		if (rc != 0)
 			goto fail;
-		urb_init = 1;
 	}
 
-	if (!dev->isoc_ctl.num_bufs)
-		urb_init = 1;
-
-	if (urb_init) {
+	if (!dev->isoc_ctl.num_bufs) {
 		rc = tm6000_prepare_isoc(dev);
 		if (rc < 0)
 			goto fail;
-- 
1.7.6


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

* [PATCH 15/21] [staging] tm6000: Execute lightweight reset on close.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (13 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 14/21] [staging] tm6000: Initialize isochronous transfers only once Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-31 20:53   ` Mauro Carvalho Chehab
  2011-08-04  7:14 ` [PATCH 16/21] [staging] tm6000: Select interface on first open Thierry Reding
                   ` (6 subsequent siblings)
  21 siblings, 1 reply; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

When the last user closes the device, perform a lightweight reset of the
device to bring it into a well-known state.

Note that this is not always enough with the TM6010, which sometimes
needs a hard reset to get into a working state again.
---
 drivers/staging/tm6000/tm6000-core.c  |   43 +++++++++++++++++++++++++++++++++
 drivers/staging/tm6000/tm6000-video.c |    8 +++++-
 drivers/staging/tm6000/tm6000.h       |    1 +
 3 files changed, 51 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index 317ab7e..58c1399 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -597,6 +597,49 @@ int tm6000_init(struct tm6000_core *dev)
 	return rc;
 }
 
+int tm6000_reset(struct tm6000_core *dev)
+{
+	int pipe;
+	int err;
+
+	msleep(500);
+
+	err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 0);
+	if (err < 0) {
+		tm6000_err("failed to select interface %d, alt. setting 0\n",
+				dev->isoc_in.bInterfaceNumber);
+		return err;
+	}
+
+	err = usb_reset_configuration(dev->udev);
+	if (err < 0) {
+		tm6000_err("failed to reset configuration\n");
+		return err;
+	}
+
+	msleep(5);
+
+	err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 2);
+	if (err < 0) {
+		tm6000_err("failed to select interface %d, alt. setting 2\n",
+				dev->isoc_in.bInterfaceNumber);
+		return err;
+	}
+
+	msleep(5);
+
+	pipe = usb_rcvintpipe(dev->udev,
+			dev->int_in.endp->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+
+	err = usb_clear_halt(dev->udev, pipe);
+	if (err < 0) {
+		tm6000_err("usb_clear_halt failed: %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
 int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate)
 {
 	int val = 0;
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index 492ec73..70fc19e 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -1503,7 +1503,6 @@ static int tm6000_open(struct file *file)
 	tm6000_get_std_res(dev);
 
 	file->private_data = fh;
-	fh->vdev = vdev;
 	fh->dev = dev;
 	fh->radio = radio;
 	fh->type = type;
@@ -1606,9 +1605,16 @@ static int tm6000_release(struct file *file)
 	dev->users--;
 
 	res_free(dev, fh);
+
 	if (!dev->users) {
+		int err;
+
 		tm6000_uninit_isoc(dev);
 		videobuf_mmap_free(&fh->vb_vidq);
+
+		err = tm6000_reset(dev);
+		if (err < 0)
+			dev_err(&vdev->dev, "reset failed: %d\n", err);
 	}
 
 	kfree(fh);
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
index cf57e1e..dac2063 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -311,6 +311,7 @@ int tm6000_set_reg_mask(struct tm6000_core *dev, u8 req, u16 value,
 						u16 index, u16 mask);
 int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep);
 int tm6000_init(struct tm6000_core *dev);
+int tm6000_reset(struct tm6000_core *dev);
 
 int tm6000_init_analog_mode(struct tm6000_core *dev);
 int tm6000_init_digital_mode(struct tm6000_core *dev);
-- 
1.7.6


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

* [PATCH 16/21] [staging] tm6000: Select interface on first open.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (14 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 15/21] [staging] tm6000: Execute lightweight reset on close Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-31 20:02   ` Mauro Carvalho Chehab
  2011-08-04  7:14 ` [PATCH 17/21] [staging] tm6000: Do not use video buffers in radio mode Thierry Reding
                   ` (5 subsequent siblings)
  21 siblings, 1 reply; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

Instead of selecting the default interface setting when preparing
isochronous transfers, select it on the first call to open() to make
sure it is available earlier.
---
 drivers/staging/tm6000/tm6000-video.c |   17 ++++++++++++-----
 1 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index 70fc19e..b59a0da 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -595,11 +595,6 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev)
 	tm6000_uninit_isoc(dev);
 	/* Stop interrupt USB pipe */
 	tm6000_ir_int_stop(dev);
-
-	usb_set_interface(dev->udev,
-			  dev->isoc_in.bInterfaceNumber,
-			  dev->isoc_in.bAlternateSetting);
-
 	/* Start interrupt USB pipe */
 	tm6000_ir_int_start(dev);
 
@@ -1484,6 +1479,18 @@ static int tm6000_open(struct file *file)
 		break;
 	}
 
+	if (dev->users == 0) {
+		int err = usb_set_interface(dev->udev,
+				dev->isoc_in.bInterfaceNumber,
+				dev->isoc_in.bAlternateSetting);
+		if (err < 0) {
+			dev_err(&vdev->dev, "failed to select interface %d, "
+					"alt. setting %d\n",
+					dev->isoc_in.bInterfaceNumber,
+					dev->isoc_in.bAlternateSetting);
+		}
+	}
+
 	/* If more than one user, mutex should be added */
 	dev->users++;
 
-- 
1.7.6


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

* [PATCH 17/21] [staging] tm6000: Do not use video buffers in radio mode.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (15 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 16/21] [staging] tm6000: Select interface on first open Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-04  7:14 ` [PATCH 18/21] [staging] tm6000: Plug memory leak on PCM free Thierry Reding
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

If the radio device is opened there is no need to initialize the video
buffer queue because it is not used.
---
 drivers/staging/tm6000/tm6000-video.c |   18 ++++++++++--------
 1 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index b59a0da..bb39c91 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -1539,13 +1539,13 @@ static int tm6000_open(struct file *file)
 		dev->mode = TM6000_MODE_ANALOG;
 	}
 
-	videobuf_queue_vmalloc_init(&fh->vb_vidq, &tm6000_video_qops,
-			NULL, &dev->slock,
-			fh->type,
-			V4L2_FIELD_INTERLACED,
-			sizeof(struct tm6000_buffer), fh, &dev->lock);
-
-	if (fh->radio) {
+	if (!fh->radio) {
+		videobuf_queue_vmalloc_init(&fh->vb_vidq, &tm6000_video_qops,
+				NULL, &dev->slock,
+				fh->type,
+				V4L2_FIELD_INTERLACED,
+				sizeof(struct tm6000_buffer), fh, &dev->lock);
+	} else {
 		dprintk(dev, V4L2_DEBUG_OPEN, "video_open: setting radio device\n");
 		dev->input = 5;
 		tm6000_set_audio_rinput(dev);
@@ -1617,7 +1617,9 @@ static int tm6000_release(struct file *file)
 		int err;
 
 		tm6000_uninit_isoc(dev);
-		videobuf_mmap_free(&fh->vb_vidq);
+
+		if (!fh->radio)
+			videobuf_mmap_free(&fh->vb_vidq);
 
 		err = tm6000_reset(dev);
 		if (err < 0)
-- 
1.7.6


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

* [PATCH 18/21] [staging] tm6000: Plug memory leak on PCM free.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (16 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 17/21] [staging] tm6000: Do not use video buffers in radio mode Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-04  7:14 ` [PATCH 19/21] [staging] tm6000: Enable audio clock in radio mode Thierry Reding
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

When releasing hardware resources, the DMA buffer allocated to the PCM
device needs to be freed to prevent a memory leak.
---
 drivers/staging/tm6000/tm6000-alsa.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c
index 35ad1f0..2bf21600 100644
--- a/drivers/staging/tm6000/tm6000-alsa.c
+++ b/drivers/staging/tm6000/tm6000-alsa.c
@@ -308,6 +308,7 @@ static int snd_tm6000_hw_free(struct snd_pcm_substream *substream)
 		schedule_work(&core->wq_trigger);
 	}
 
+	dsp_buffer_free(substream);
 	return 0;
 }
 
-- 
1.7.6


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

* [PATCH 19/21] [staging] tm6000: Enable audio clock in radio mode.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (17 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 18/21] [staging] tm6000: Plug memory leak on PCM free Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-04  7:14 ` [PATCH 20/21] [staging] tm6000: Enable radio mode for Cinergy Hybrid XE Thierry Reding
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

---
 drivers/staging/tm6000/tm6000-stds.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-stds.c b/drivers/staging/tm6000/tm6000-stds.c
index f44451b..9a4145d 100644
--- a/drivers/staging/tm6000/tm6000-stds.c
+++ b/drivers/staging/tm6000/tm6000-stds.c
@@ -357,6 +357,7 @@ static int tm6000_set_audio_std(struct tm6000_core *dev)
 		tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe);
 		tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13);
 		tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80);
+		tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, 0xff);
 		return 0;
 	}
 
-- 
1.7.6


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

* [PATCH 20/21] [staging] tm6000: Enable radio mode for Cinergy Hybrid XE.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (18 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 19/21] [staging] tm6000: Enable audio clock in radio mode Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-04  7:14 ` [PATCH 21/21] [staging] tm6000: Remove unnecessary workaround Thierry Reding
  2011-08-31 12:41 ` [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Mauro Carvalho Chehab
  21 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

---
 drivers/staging/tm6000/tm6000-cards.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index 94fd138..ab3aa2c 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -469,6 +469,7 @@ static struct tm6000_board tm6000_boards[] = {
 			.has_zl10353  = 1,
 			.has_eeprom   = 1,
 			.has_remote   = 1,
+			.has_radio    = 1,
 		},
 		.gpio = {
 			.tuner_reset	= TM6010_GPIO_2,
@@ -494,6 +495,10 @@ static struct tm6000_board tm6000_boards[] = {
 			.amux	= TM6000_AMUX_ADC2,
 			},
 		},
+		.rinput = {
+			.type = TM6000_INPUT_RADIO,
+			.amux = TM6000_AMUX_SIF1,
+		},
 	},
 	[TM5600_BOARD_TERRATEC_GRABSTER] = {
 		.name         = "Terratec Grabster AV 150/250 MX",
-- 
1.7.6


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

* [PATCH 21/21] [staging] tm6000: Remove unnecessary workaround.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (19 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 20/21] [staging] tm6000: Enable radio mode for Cinergy Hybrid XE Thierry Reding
@ 2011-08-04  7:14 ` Thierry Reding
  2011-08-31 12:41 ` [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Mauro Carvalho Chehab
  21 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-04  7:14 UTC (permalink / raw)
  To: linux-media

Implicitly setting the tuner frequency each time the device is opened
seems no longer necessary, so it is removed. This speeds up opening the
device by about 120 ms.

It also avoids excessive firmware reloads because the default will load
the BASE and F8MHZ type firmwares independent of which device, video or
radio, is opened. Before this patch opening the radio device would
automatically trigger a BASE and F8MHZ firmware load only to immediately
replace them by the FM firmware.
---
 drivers/staging/tm6000/tm6000-core.c |   19 -------------------
 1 files changed, 0 insertions(+), 19 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index 58c1399..7bb1d37 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -264,8 +264,6 @@ static void tm6000_set_vbi(struct tm6000_core *dev)
 
 int tm6000_init_analog_mode(struct tm6000_core *dev)
 {
-	struct v4l2_frequency f;
-
 	if (dev->dev_type == TM6010) {
 		u8 active = TM6010_REQ07_RCC_ACTIVE_IF_AUDIO_ENABLE;
 
@@ -304,24 +302,7 @@ int tm6000_init_analog_mode(struct tm6000_core *dev)
 		/* Disables soft reset */
 		tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x00);
 	}
-	msleep(20);
-
-	/* Tuner firmware can now be loaded */
-
-	/*
-	 * FIXME: This is a hack! xc3028 "sleeps" when no channel is detected
-	 * for more than a few seconds. Not sure why, as this behavior does
-	 * not happen on other devices with xc3028. So, I suspect that it
-	 * is yet another bug at tm6000. After start sleeping, decoding
-	 * doesn't start automatically. Instead, it requires some
-	 * I2C commands to wake it up. As we want to have image at the
-	 * beginning, we needed to add this hack. The better would be to
-	 * discover some way to make tm6000 to wake up without this hack.
-	 */
-	f.frequency = dev->freq;
-	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
 
-	msleep(100);
 	tm6000_set_standard(dev);
 	tm6000_set_vbi(dev);
 	tm6000_set_audio_bitrate(dev, 48000);
-- 
1.7.6


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

* Re: [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements.
  2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
                   ` (20 preceding siblings ...)
  2011-08-04  7:14 ` [PATCH 21/21] [staging] tm6000: Remove unnecessary workaround Thierry Reding
@ 2011-08-31 12:41 ` Mauro Carvalho Chehab
  2011-08-31 13:12   ` Thierry Reding
  21 siblings, 1 reply; 48+ messages in thread
From: Mauro Carvalho Chehab @ 2011-08-31 12:41 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-media

Hi Thierry,

Em 04-08-2011 04:13, Thierry Reding escreveu:
> This patch series fixes up some issues with the tm6000 driver. These
> patches were tested with a Cinergy Hybrid XE which is the only one I
> have access to, so it would be nice if someone with access to the other
> supported devices could take this series for a test run.
> 
> Among the changes are several speed-ups for firmware loading, addition
> of radio support for the Cinergy Hybrid XE and some memory leak fixes. I
> was able to reproduce the behaviour documented in the README about the
> device stopping to work for unknown reasons. Running tests with this
> series applied no longer exposes the problem, so I have high hopes that
> it's also fixed.

You forgot to send your Signed-off-by: at the patches you sent me. Could you
please reply on this email with your SOB, for me to be able to apply them
on my tree?

Thanks!
Mauro
> 
> Thierry Reding (21):
>   [media] tuner/xc2028: Add I2C flush callback.
>   [media] tuner/xc2028: Fix frequency offset for radio mode.
>   [staging] tm6000: Miscellaneous cleanups.
>   [staging] tm6000: Use correct input in radio mode.
>   [staging] tm6000: Implement I2C flush callback.
>   [staging] tm6000: Increase maximum I2C packet size.
>   [staging] tm6000: Remove artificial delay.
>   [staging] tm6000: Flesh out the IRQ callback.
>   [staging] tm6000: Rename active interface register.
>   [staging] tm6000: Disable video interface in radio mode.
>   [staging] tm6000: Rework standard register tables.
>   [staging] tm6000: Add locking for USB transfers.
>   [staging] tm6000: Properly count device usage.
>   [staging] tm6000: Initialize isochronous transfers only once.
>   [staging] tm6000: Execute lightweight reset on close.
>   [staging] tm6000: Select interface on first open.
>   [staging] tm6000: Do not use video buffers in radio mode.
>   [staging] tm6000: Plug memory leak on PCM free.
>   [staging] tm6000: Enable audio clock in radio mode.
>   [staging] tm6000: Enable radio mode for Cinergy Hybrid XE.
>   [staging] tm6000: Remove unnecessary workaround.
> 
>  drivers/media/common/tuners/tuner-xc2028.c |  144 ++++---
>  drivers/media/common/tuners/tuner-xc2028.h |    1 +
>  drivers/staging/tm6000/tm6000-alsa.c       |    9 +-
>  drivers/staging/tm6000/tm6000-cards.c      |   35 +-
>  drivers/staging/tm6000/tm6000-core.c       |  102 +++--
>  drivers/staging/tm6000/tm6000-dvb.c        |   14 +-
>  drivers/staging/tm6000/tm6000-i2c.c        |    7 +-
>  drivers/staging/tm6000/tm6000-input.c      |    2 +-
>  drivers/staging/tm6000/tm6000-regs.h       |    4 +-
>  drivers/staging/tm6000/tm6000-stds.c       |  642 ++++++++++++++--------------
>  drivers/staging/tm6000/tm6000-video.c      |  188 +++++----
>  drivers/staging/tm6000/tm6000.h            |    6 +-
>  12 files changed, 600 insertions(+), 554 deletions(-)
> 


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

* Re: [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements.
  2011-08-31 12:41 ` [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Mauro Carvalho Chehab
@ 2011-08-31 13:12   ` Thierry Reding
  0 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-08-31 13:12 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-media

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

* Mauro Carvalho Chehab wrote:
> Hi Thierry,
> 
> Em 04-08-2011 04:13, Thierry Reding escreveu:
> > This patch series fixes up some issues with the tm6000 driver. These
> > patches were tested with a Cinergy Hybrid XE which is the only one I
> > have access to, so it would be nice if someone with access to the other
> > supported devices could take this series for a test run.
> > 
> > Among the changes are several speed-ups for firmware loading, addition
> > of radio support for the Cinergy Hybrid XE and some memory leak fixes. I
> > was able to reproduce the behaviour documented in the README about the
> > device stopping to work for unknown reasons. Running tests with this
> > series applied no longer exposes the problem, so I have high hopes that
> > it's also fixed.
> 
> You forgot to send your Signed-off-by: at the patches you sent me. Could you
> please reply on this email with your SOB, for me to be able to apply them
> on my tree?
> 
> Thanks!
> Mauro
> > 
> > Thierry Reding (21):
> >   [media] tuner/xc2028: Add I2C flush callback.
> >   [media] tuner/xc2028: Fix frequency offset for radio mode.
> >   [staging] tm6000: Miscellaneous cleanups.
> >   [staging] tm6000: Use correct input in radio mode.
> >   [staging] tm6000: Implement I2C flush callback.
> >   [staging] tm6000: Increase maximum I2C packet size.
> >   [staging] tm6000: Remove artificial delay.
> >   [staging] tm6000: Flesh out the IRQ callback.
> >   [staging] tm6000: Rename active interface register.
> >   [staging] tm6000: Disable video interface in radio mode.
> >   [staging] tm6000: Rework standard register tables.
> >   [staging] tm6000: Add locking for USB transfers.
> >   [staging] tm6000: Properly count device usage.
> >   [staging] tm6000: Initialize isochronous transfers only once.
> >   [staging] tm6000: Execute lightweight reset on close.
> >   [staging] tm6000: Select interface on first open.
> >   [staging] tm6000: Do not use video buffers in radio mode.
> >   [staging] tm6000: Plug memory leak on PCM free.
> >   [staging] tm6000: Enable audio clock in radio mode.
> >   [staging] tm6000: Enable radio mode for Cinergy Hybrid XE.
> >   [staging] tm6000: Remove unnecessary workaround.
> > 
> >  drivers/media/common/tuners/tuner-xc2028.c |  144 ++++---
> >  drivers/media/common/tuners/tuner-xc2028.h |    1 +
> >  drivers/staging/tm6000/tm6000-alsa.c       |    9 +-
> >  drivers/staging/tm6000/tm6000-cards.c      |   35 +-
> >  drivers/staging/tm6000/tm6000-core.c       |  102 +++--
> >  drivers/staging/tm6000/tm6000-dvb.c        |   14 +-
> >  drivers/staging/tm6000/tm6000-i2c.c        |    7 +-
> >  drivers/staging/tm6000/tm6000-input.c      |    2 +-
> >  drivers/staging/tm6000/tm6000-regs.h       |    4 +-
> >  drivers/staging/tm6000/tm6000-stds.c       |  642 ++++++++++++++--------------
> >  drivers/staging/tm6000/tm6000-video.c      |  188 +++++----
> >  drivers/staging/tm6000/tm6000.h            |    6 +-
> >  12 files changed, 600 insertions(+), 554 deletions(-)

Sorry for not adding it in the first place. All of the above patches:

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH 02/21] [media] tuner/xc2028: Fix frequency offset for radio mode.
  2011-08-04  7:14 ` [PATCH 02/21] [media] tuner/xc2028: Fix frequency offset for radio mode Thierry Reding
@ 2011-08-31 18:32   ` Mauro Carvalho Chehab
  2011-09-01  5:10     ` Thierry Reding
  0 siblings, 1 reply; 48+ messages in thread
From: Mauro Carvalho Chehab @ 2011-08-31 18:32 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-media

Em 04-08-2011 04:14, Thierry Reding escreveu:
> In radio mode, no frequency offset is needed. While at it, split off the
> frequency offset computation for digital TV into a separate function.

Nah, it is better to keep the offset calculation there. there is already
a set_freq for DVB. breaking the frequency logic even further seems to
increase the driver's logic. Also, patch is simpler and easier to review.

The patch bellow seems to be better. On a quick review, I think that the 
	send_seq(priv, {0x00, 0x00})
sequence may be wrong. I suspect that the device is just discarding that,
but changing it needs more testing.

-

[media] tuner/xc2028: Fix frequency offset for radio mode

In radio mode, no frequency offset should be used.
  
Instead of taking Thierry's patch that creates a separate function
to calculate the digital offset, it seemed better to just keep
everything at the same place.

Reported-by: Thierry Reding <thierry.reding@avionic-design.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index b6b2868..3acbaa0 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -940,11 +940,16 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
 	 * that xc2028 will be in a safe state.
 	 * Maybe this might also be needed for DTV.
 	 */
-	if (new_type == V4L2_TUNER_ANALOG_TV) {
+	switch (new_type) {
+	case V4L2_TUNER_ANALOG_TV:
 		rc = send_seq(priv, {0x00, 0x00});
 
-		/* Analog modes require offset = 0 */
-	} else {
+		/* Analog mode requires offset = 0 */
+		break;
+	case V4L2_TUNER_RADIO:
+		/* Radio mode requires offset = 0 */
+		break;
+	case V4L2_TUNER_DIGITAL_TV:
 		/*
 		 * Digital modes require an offset to adjust to the
 		 * proper frequency. The offset depends on what

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

* Re: [PATCH 06/21] [staging] tm6000: Increase maximum I2C packet size.
  2011-08-04  7:14 ` [PATCH 06/21] [staging] tm6000: Increase maximum I2C packet size Thierry Reding
@ 2011-08-31 19:45   ` Mauro Carvalho Chehab
  2011-09-01  5:08     ` Thierry Reding
  0 siblings, 1 reply; 48+ messages in thread
From: Mauro Carvalho Chehab @ 2011-08-31 19:45 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-media

Em 04-08-2011 04:14, Thierry Reding escreveu:
> The TM6010 supports much larger I2C transfers than currently specified.
> In fact the Windows driver seems to use 81 bytes per packet by default.
> This commit improves the speed of firmware loading a bit.
> ---
>  drivers/staging/tm6000/tm6000-cards.c |    1 +
>  drivers/staging/tm6000/tm6000-i2c.c   |    2 +-
>  2 files changed, 2 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
> index c3b84c9..a5d2a71 100644
> --- a/drivers/staging/tm6000/tm6000-cards.c
> +++ b/drivers/staging/tm6000/tm6000-cards.c
> @@ -929,6 +929,7 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
>  		memset(&ctl, 0, sizeof(ctl));
>  
>  		ctl.demod = XC3028_FE_ZARLINK456;
> +		ctl.max_len = 81;
>  
>  		xc2028_cfg.tuner = TUNER_XC2028;
>  		xc2028_cfg.priv  = &ctl;
> diff --git a/drivers/staging/tm6000/tm6000-i2c.c b/drivers/staging/tm6000/tm6000-i2c.c
> index 21cd9f8..2cb7573 100644
> --- a/drivers/staging/tm6000/tm6000-i2c.c
> +++ b/drivers/staging/tm6000/tm6000-i2c.c
> @@ -50,7 +50,7 @@ static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr,
>  	unsigned int i2c_packet_limit = 16;
>  
>  	if (dev->dev_type == TM6010)
> -		i2c_packet_limit = 64;
> +		i2c_packet_limit = 256;

This shouldn't work fine. As said at USB 2.0 specification:

	An endpoint for control transfers specifies the maximum data payload size that the endpoint can accept from
	or transmit to the bus. The allowable maximum control transfer data payload sizes for full-speed devices is
	8, 16, 32, or 64 bytes; for high-speed devices, it is 64 bytes and for low-speed devices, it is 8 bytes. This
	maximum applies to the data payloads of the Data packets following a Setup; i.e., the size specified is for
	the data field of the packet as defined in Chapter 8, not including other information that is required by the
	protocol. A Setup packet is always eight bytes. A control pipe (including the Default Control Pipe) always
	uses its wMaxPacketSize value for data payloads.
	(Item 5.5.3 Control Transfer Packet Size Constraints).

Using a value higher than 64 may cause troubles with some USB devices
(hubs, USB adapters, etc).

Cheers,
Mauro

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

* Re: [PATCH 07/21] [staging] tm6000: Remove artificial delay.
  2011-08-04  7:14 ` [PATCH 07/21] [staging] tm6000: Remove artificial delay Thierry Reding
@ 2011-08-31 19:50   ` Mauro Carvalho Chehab
  2011-09-01  5:13     ` Thierry Reding
  0 siblings, 1 reply; 48+ messages in thread
From: Mauro Carvalho Chehab @ 2011-08-31 19:50 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-media

Em 04-08-2011 04:14, Thierry Reding escreveu:
> ---
>  drivers/staging/tm6000/tm6000-core.c |    3 ---
>  1 files changed, 0 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
> index e14bd3d..2c156dd 100644
> --- a/drivers/staging/tm6000/tm6000-core.c
> +++ b/drivers/staging/tm6000/tm6000-core.c
> @@ -86,9 +86,6 @@ int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req,
>  	}
>  
>  	kfree(data);
> -
> -	msleep(5);
> -
>  	return ret;
>  }
>  

This delay is needed by some tm5600/6000 devices. Maybe it is due to
some specific chipset revision, but I can't remember anymore what
device(s) were affected.

The right thing to do seems to whitelist the devices that don't need
any delay there.

Thanks,
Mauro

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

* Re: [PATCH 16/21] [staging] tm6000: Select interface on first open.
  2011-08-04  7:14 ` [PATCH 16/21] [staging] tm6000: Select interface on first open Thierry Reding
@ 2011-08-31 20:02   ` Mauro Carvalho Chehab
  2011-09-01  5:19     ` Thierry Reding
  0 siblings, 1 reply; 48+ messages in thread
From: Mauro Carvalho Chehab @ 2011-08-31 20:02 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-media

Em 04-08-2011 04:14, Thierry Reding escreveu:
> Instead of selecting the default interface setting when preparing
> isochronous transfers, select it on the first call to open() to make
> sure it is available earlier.

Hmm... I fail to see what this is needed earlier. The ISOC endpont is used
only when the device is streaming.

Did you get any bug related to it? If so, please describe it better.

> ---
>  drivers/staging/tm6000/tm6000-video.c |   17 ++++++++++++-----
>  1 files changed, 12 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
> index 70fc19e..b59a0da 100644
> --- a/drivers/staging/tm6000/tm6000-video.c
> +++ b/drivers/staging/tm6000/tm6000-video.c
> @@ -595,11 +595,6 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev)
>  	tm6000_uninit_isoc(dev);
>  	/* Stop interrupt USB pipe */
>  	tm6000_ir_int_stop(dev);
> -
> -	usb_set_interface(dev->udev,
> -			  dev->isoc_in.bInterfaceNumber,
> -			  dev->isoc_in.bAlternateSetting);
> -
>  	/* Start interrupt USB pipe */
>  	tm6000_ir_int_start(dev);
>  
> @@ -1484,6 +1479,18 @@ static int tm6000_open(struct file *file)
>  		break;
>  	}
>  
> +	if (dev->users == 0) {
> +		int err = usb_set_interface(dev->udev,
> +				dev->isoc_in.bInterfaceNumber,
> +				dev->isoc_in.bAlternateSetting);
> +		if (err < 0) {
> +			dev_err(&vdev->dev, "failed to select interface %d, "
> +					"alt. setting %d\n",
> +					dev->isoc_in.bInterfaceNumber,
> +					dev->isoc_in.bAlternateSetting);
> +		}
> +	}
> +
>  	/* If more than one user, mutex should be added */
>  	dev->users++;
>  


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

* Re: [PATCH 15/21] [staging] tm6000: Execute lightweight reset on close.
  2011-08-04  7:14 ` [PATCH 15/21] [staging] tm6000: Execute lightweight reset on close Thierry Reding
@ 2011-08-31 20:53   ` Mauro Carvalho Chehab
       [not found]     ` <4E5EAA41.4060502@redhat.com>
  0 siblings, 1 reply; 48+ messages in thread
From: Mauro Carvalho Chehab @ 2011-08-31 20:53 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-media

Em 04-08-2011 04:14, Thierry Reding escreveu:
> When the last user closes the device, perform a lightweight reset of the
> device to bring it into a well-known state.
> 
> Note that this is not always enough with the TM6010, which sometimes
> needs a hard reset to get into a working state again.
> ---
>  drivers/staging/tm6000/tm6000-core.c  |   43 +++++++++++++++++++++++++++++++++
>  drivers/staging/tm6000/tm6000-video.c |    8 +++++-
>  drivers/staging/tm6000/tm6000.h       |    1 +
>  3 files changed, 51 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
> index 317ab7e..58c1399 100644
> --- a/drivers/staging/tm6000/tm6000-core.c
> +++ b/drivers/staging/tm6000/tm6000-core.c
> @@ -597,6 +597,49 @@ int tm6000_init(struct tm6000_core *dev)
>  	return rc;
>  }
>  
> +int tm6000_reset(struct tm6000_core *dev)
> +{
> +	int pipe;
> +	int err;
> +
> +	msleep(500);
> +
> +	err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 0);
> +	if (err < 0) {
> +		tm6000_err("failed to select interface %d, alt. setting 0\n",
> +				dev->isoc_in.bInterfaceNumber);
> +		return err;
> +	}
> +
> +	err = usb_reset_configuration(dev->udev);
> +	if (err < 0) {
> +		tm6000_err("failed to reset configuration\n");
> +		return err;
> +	}
> +
> +	msleep(5);
> +
> +	err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 2);
> +	if (err < 0) {
> +		tm6000_err("failed to select interface %d, alt. setting 2\n",
> +				dev->isoc_in.bInterfaceNumber);
> +		return err;
> +	}
> +
> +	msleep(5);
> +
> +	pipe = usb_rcvintpipe(dev->udev,
> +			dev->int_in.endp->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
> +
> +	err = usb_clear_halt(dev->udev, pipe);
> +	if (err < 0) {
> +		tm6000_err("usb_clear_halt failed: %d\n", err);
> +		return err;
> +	}
> +
> +	return 0;
> +}
> +
>  int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate)
>  {
>  	int val = 0;
> diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
> index 492ec73..70fc19e 100644
> --- a/drivers/staging/tm6000/tm6000-video.c
> +++ b/drivers/staging/tm6000/tm6000-video.c
> @@ -1503,7 +1503,6 @@ static int tm6000_open(struct file *file)
>  	tm6000_get_std_res(dev);
>  
>  	file->private_data = fh;
> -	fh->vdev = vdev;
>  	fh->dev = dev;
>  	fh->radio = radio;
>  	fh->type = type;
> @@ -1606,9 +1605,16 @@ static int tm6000_release(struct file *file)
>  	dev->users--;
>  
>  	res_free(dev, fh);
> +
>  	if (!dev->users) {
> +		int err;
> +
>  		tm6000_uninit_isoc(dev);
>  		videobuf_mmap_free(&fh->vb_vidq);
> +
> +		err = tm6000_reset(dev);
> +		if (err < 0)
> +			dev_err(&vdev->dev, "reset failed: %d\n", err);
>  	}
>  
>  	kfree(fh);
> diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
> index cf57e1e..dac2063 100644
> --- a/drivers/staging/tm6000/tm6000.h
> +++ b/drivers/staging/tm6000/tm6000.h
> @@ -311,6 +311,7 @@ int tm6000_set_reg_mask(struct tm6000_core *dev, u8 req, u16 value,
>  						u16 index, u16 mask);
>  int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep);
>  int tm6000_init(struct tm6000_core *dev);
> +int tm6000_reset(struct tm6000_core *dev);
>  
>  int tm6000_init_analog_mode(struct tm6000_core *dev);
>  int tm6000_init_digital_mode(struct tm6000_core *dev);

Something went wrong with the patchset. Got an OOPS during device probe.
Maybe it were caused due to udev, that opens V4L devices, as soon as they're
registered.


[34883.426065] tm6000 #0: registered device video0
[34883.430591] Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: 0)
[34883.437763] usbcore: registered new interface driver tm6000
[34884.608372] BUG: unable to handle kernel NULL pointer dereference at 00000002
[34884.615514] IP: [<f8c4ceea>] tm6000_reset+0xd7/0x11c [tm6000]
[34884.621260] *pde = 00000000 
[34884.624139] Oops: 0000 [#1] SMP 
[34884.627375] Modules linked in: tuner_xc2028 tuner ir_lirc_codec lirc_dev ir_mce_kbd_decoder ir_sony_decoder ir_jvc_decoder ir_rc6_decoder ir_rc5_decoder tm6000 ir_nec_decoder videobuf_vmalloc videobuf_core rc_core v4l2_common videodev media tcp_lp fuse ebtable_nat ebtables ipt_MASQUERADE iptable_nat nf_nat xt_CHECKSUM iptable_mangle bridge stp llc bnep bluetooth sunrpc cpufreq_ondemand acpi_cpufreq mperf ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_filter nf_conntrack_ipv4 ip6_tables nf_defrag_ipv4 xt_state nf_conntrack snd_hda_codec_realtek snd_hda_intel snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm i7core_edac edac_core snd_timer tg3 snd iTCO_wdt iTCO_vendor_support hp_wmi soundcore pcspkr snd_page_alloc floppy sparse_keymap rfkill serio_raw tpm_infineon microcode vboxnetadp vboxnetflt vboxdrv firewire_ohci firewire_core crc_itu_t nouveau ttm drm_kms_helper drm i2c_algo_bit i2c_core mxm_wmi wmi video [last unloaded: tuner_xc2028]
[34884.712113] 
[34884.713599] Pid: 7448, comm: v4l_id Tainted: G        W   3.0.0+ #1 Hewlett-Packard HP Z400 Workstation/0AE4h
[34884.723513] EIP: 0060:[<f8c4ceea>] EFLAGS: 00010246 CPU: 0
[34884.728983] EIP is at tm6000_reset+0xd7/0x11c [tm6000]
[34884.734104] EAX: f676c800 EBX: e38e5800 ECX: 00000000 EDX: 00000003
[34884.740349] ESI: 00000000 EDI: efc3c400 EBP: efc19f18 ESP: efc19f04
[34884.746594]  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
[34884.751974] Process v4l_id (pid: 7448, ti=efc18000 task=f6608000 task.ti=efc18000)
[34884.759517] Stack:
[34884.761519]  f2b51c00 efc19f18 f8be3f96 e38e5800 f2b51c00 efc19f44 f8c4e6e5 f1b75a40
[34884.769318]  efc19f2c c0429397 efc19f34 c0810501 efc19f44 efc3c400 eb4b8cc0 00000010
[34884.777121]  efc19f54 f8bb619d eb4b8cc0 f66ffe08 efc19f84 c04e9eaf 00000001 00000000
[34884.784918] Call Trace:
[34884.787360]  [<f8be3f96>] ? __videobuf_free+0x10c/0x112 [videobuf_core]
[34884.793958]  [<f8c4e6e5>] tm6000_release+0xc7/0xf3 [tm6000]
[34884.799513]  [<c0429397>] ? should_resched+0xd/0x27
[34884.804378]  [<c0810501>] ? _cond_resched+0xd/0x21
[34884.809158]  [<f8bb619d>] v4l2_release+0x35/0x52 [videodev]
[34884.814713]  [<c04e9eaf>] fput+0x100/0x1a5
[34884.818798]  [<c04e75a1>] filp_close+0x5c/0x64
[34884.823228]  [<c04e7608>] sys_close+0x5f/0x93
[34884.827571]  [<c081745f>] sysenter_do_call+0x12/0x28
[34884.832519] Code: 24 04 40 10 c5 f8 c7 04 24 56 1d c5 f8 89 44 24 08 eb 4b b8 05 00 00 00 e8 b2 a7 7f c7 8b 83 44 06 00 00 8b 8b 78 06 00 00 8b 10 <0f> b6 49 02 c1 e2 08 83 e1 0f 81 ca 80 00 00 40 c1 e1 0f 09 ca 
[34884.851965] EIP: [<f8c4ceea>] tm6000_reset+0xd7/0x11c [tm6000] SS:ESP 0068:efc19f04
[34884.859623] CR2: 0000000000000002


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

* Re: [PATCH 06/21] [staging] tm6000: Increase maximum I2C packet size.
  2011-08-31 19:45   ` Mauro Carvalho Chehab
@ 2011-09-01  5:08     ` Thierry Reding
  0 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-09-01  5:08 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-media

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

* Mauro Carvalho Chehab wrote:
> Em 04-08-2011 04:14, Thierry Reding escreveu:
> > The TM6010 supports much larger I2C transfers than currently specified.
> > In fact the Windows driver seems to use 81 bytes per packet by default.
> > This commit improves the speed of firmware loading a bit.
> > ---
> >  drivers/staging/tm6000/tm6000-cards.c |    1 +
> >  drivers/staging/tm6000/tm6000-i2c.c   |    2 +-
> >  2 files changed, 2 insertions(+), 1 deletions(-)
> > 
> > diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
> > index c3b84c9..a5d2a71 100644
> > --- a/drivers/staging/tm6000/tm6000-cards.c
> > +++ b/drivers/staging/tm6000/tm6000-cards.c
> > @@ -929,6 +929,7 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
> >  		memset(&ctl, 0, sizeof(ctl));
> >  
> >  		ctl.demod = XC3028_FE_ZARLINK456;
> > +		ctl.max_len = 81;
> >  
> >  		xc2028_cfg.tuner = TUNER_XC2028;
> >  		xc2028_cfg.priv  = &ctl;
> > diff --git a/drivers/staging/tm6000/tm6000-i2c.c b/drivers/staging/tm6000/tm6000-i2c.c
> > index 21cd9f8..2cb7573 100644
> > --- a/drivers/staging/tm6000/tm6000-i2c.c
> > +++ b/drivers/staging/tm6000/tm6000-i2c.c
> > @@ -50,7 +50,7 @@ static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr,
> >  	unsigned int i2c_packet_limit = 16;
> >  
> >  	if (dev->dev_type == TM6010)
> > -		i2c_packet_limit = 64;
> > +		i2c_packet_limit = 256;
> 
> This shouldn't work fine. As said at USB 2.0 specification:
> 
> 	An endpoint for control transfers specifies the maximum data payload size that the endpoint can accept from
> 	or transmit to the bus. The allowable maximum control transfer data payload sizes for full-speed devices is
> 	8, 16, 32, or 64 bytes; for high-speed devices, it is 64 bytes and for low-speed devices, it is 8 bytes. This
> 	maximum applies to the data payloads of the Data packets following a Setup; i.e., the size specified is for
> 	the data field of the packet as defined in Chapter 8, not including other information that is required by the
> 	protocol. A Setup packet is always eight bytes. A control pipe (including the Default Control Pipe) always
> 	uses its wMaxPacketSize value for data payloads.
> 	(Item 5.5.3 Control Transfer Packet Size Constraints).
> 
> Using a value higher than 64 may cause troubles with some USB devices
> (hubs, USB adapters, etc).

Okay, fine by me. I was basically just copying what the Windows driver was
doing here, but I've tested with smaller sizes as well and if my memory
serves me well that also worked. As I hinted at in the commit message this
was mostly for performance improvement.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH 02/21] [media] tuner/xc2028: Fix frequency offset for radio mode.
  2011-08-31 18:32   ` Mauro Carvalho Chehab
@ 2011-09-01  5:10     ` Thierry Reding
  2011-09-01 12:45       ` Andrew Goff
  0 siblings, 1 reply; 48+ messages in thread
From: Thierry Reding @ 2011-09-01  5:10 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-media

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

* Mauro Carvalho Chehab wrote:
> Em 04-08-2011 04:14, Thierry Reding escreveu:
> > In radio mode, no frequency offset is needed. While at it, split off the
> > frequency offset computation for digital TV into a separate function.
> 
> Nah, it is better to keep the offset calculation there. there is already
> a set_freq for DVB. breaking the frequency logic even further seems to
> increase the driver's logic. Also, patch is simpler and easier to review.

Okay, no problem. Feel free to replace the patch with yours.

> The patch bellow seems to be better. On a quick review, I think that the 
> 	send_seq(priv, {0x00, 0x00})
> sequence may be wrong. I suspect that the device is just discarding that,
> but changing it needs more testing.

I ran across that as well, but I didn't dare touch it because I wasn't sure
what the broader impact would be.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH 07/21] [staging] tm6000: Remove artificial delay.
  2011-08-31 19:50   ` Mauro Carvalho Chehab
@ 2011-09-01  5:13     ` Thierry Reding
  2011-09-01  5:47       ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 48+ messages in thread
From: Thierry Reding @ 2011-09-01  5:13 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-media

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

* Mauro Carvalho Chehab wrote:
> Em 04-08-2011 04:14, Thierry Reding escreveu:
> > ---
> >  drivers/staging/tm6000/tm6000-core.c |    3 ---
> >  1 files changed, 0 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
> > index e14bd3d..2c156dd 100644
> > --- a/drivers/staging/tm6000/tm6000-core.c
> > +++ b/drivers/staging/tm6000/tm6000-core.c
> > @@ -86,9 +86,6 @@ int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req,
> >  	}
> >  
> >  	kfree(data);
> > -
> > -	msleep(5);
> > -
> >  	return ret;
> >  }
> >  
> 
> This delay is needed by some tm5600/6000 devices. Maybe it is due to
> some specific chipset revision, but I can't remember anymore what
> device(s) were affected.
> 
> The right thing to do seems to whitelist the devices that don't need
> any delay there.

This was actually the first thing I patched because I couldn't see any need
for it (the Cinergy Hybrid USB Stick worked fine without) and it made the
device pretty much unusable (with this delay, firmware loading takes about
30 seconds!).

Do you want me to follow up with a white-listing patch?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH 16/21] [staging] tm6000: Select interface on first open.
  2011-08-31 20:02   ` Mauro Carvalho Chehab
@ 2011-09-01  5:19     ` Thierry Reding
  2011-09-01  5:53       ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 48+ messages in thread
From: Thierry Reding @ 2011-09-01  5:19 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-media

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

* Mauro Carvalho Chehab wrote:
> Em 04-08-2011 04:14, Thierry Reding escreveu:
> > Instead of selecting the default interface setting when preparing
> > isochronous transfers, select it on the first call to open() to make
> > sure it is available earlier.
> 
> Hmm... I fail to see what this is needed earlier. The ISOC endpont is used
> only when the device is streaming.
> 
> Did you get any bug related to it? If so, please describe it better.

I'm not sure whether this really fixes a bug, but it seems a little wrong to
me to selecting the interface so late in the process when in fact the device
is already being configured before (video standard, audio mode, firmware
upload, ...).

Thinking about it, this may actually be part of the fix for the "device hangs
sometimes for inexplicable reasons" bug that this whole patch series seems to
fix.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH 15/21] [staging] tm6000: Execute lightweight reset on close.
       [not found]     ` <4E5EAA41.4060502@redhat.com>
@ 2011-09-01  5:24       ` Thierry Reding
  2011-09-03 17:17         ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 48+ messages in thread
From: Thierry Reding @ 2011-09-01  5:24 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-media

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

* Mauro Carvalho Chehab wrote:
> Em 31-08-2011 17:53, Mauro Carvalho Chehab escreveu:
> > Em 04-08-2011 04:14, Thierry Reding escreveu:
> >> When the last user closes the device, perform a lightweight reset of the
> >> device to bring it into a well-known state.
> >>
> >> Note that this is not always enough with the TM6010, which sometimes
> >> needs a hard reset to get into a working state again.
> >> ---
> >>  drivers/staging/tm6000/tm6000-core.c  |   43 +++++++++++++++++++++++++++++++++
> >>  drivers/staging/tm6000/tm6000-video.c |    8 +++++-
> >>  drivers/staging/tm6000/tm6000.h       |    1 +
> >>  3 files changed, 51 insertions(+), 1 deletions(-)
> >>
> >> diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
> >> index 317ab7e..58c1399 100644
> >> --- a/drivers/staging/tm6000/tm6000-core.c
> >> +++ b/drivers/staging/tm6000/tm6000-core.c
> >> @@ -597,6 +597,49 @@ int tm6000_init(struct tm6000_core *dev)
> >>  	return rc;
> >>  }
> >>  
> >> +int tm6000_reset(struct tm6000_core *dev)
> >> +{
> >> +	int pipe;
> >> +	int err;
> >> +
> >> +	msleep(500);
> >> +
> >> +	err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 0);
> >> +	if (err < 0) {
> >> +		tm6000_err("failed to select interface %d, alt. setting 0\n",
> >> +				dev->isoc_in.bInterfaceNumber);
> >> +		return err;
> >> +	}
> >> +
> >> +	err = usb_reset_configuration(dev->udev);
> >> +	if (err < 0) {
> >> +		tm6000_err("failed to reset configuration\n");
> >> +		return err;
> >> +	}
> >> +
> >> +	msleep(5);
> >> +
> >> +	err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 2);
> >> +	if (err < 0) {
> >> +		tm6000_err("failed to select interface %d, alt. setting 2\n",
> >> +				dev->isoc_in.bInterfaceNumber);
> >> +		return err;
> >> +	}
> >> +
> >> +	msleep(5);
> >> +
> >> +	pipe = usb_rcvintpipe(dev->udev,
> >> +			dev->int_in.endp->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
> >> +
> >> +	err = usb_clear_halt(dev->udev, pipe);
> >> +	if (err < 0) {
> >> +		tm6000_err("usb_clear_halt failed: %d\n", err);
> >> +		return err;
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> >> +
> >>  int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate)
> >>  {
> >>  	int val = 0;
> >> diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
> >> index 492ec73..70fc19e 100644
> >> --- a/drivers/staging/tm6000/tm6000-video.c
> >> +++ b/drivers/staging/tm6000/tm6000-video.c
> >> @@ -1503,7 +1503,6 @@ static int tm6000_open(struct file *file)
> >>  	tm6000_get_std_res(dev);
> >>  
> >>  	file->private_data = fh;
> >> -	fh->vdev = vdev;
> >>  	fh->dev = dev;
> >>  	fh->radio = radio;
> >>  	fh->type = type;
> >> @@ -1606,9 +1605,16 @@ static int tm6000_release(struct file *file)
> >>  	dev->users--;
> >>  
> >>  	res_free(dev, fh);
> >> +
> >>  	if (!dev->users) {
> >> +		int err;
> >> +
> >>  		tm6000_uninit_isoc(dev);
> >>  		videobuf_mmap_free(&fh->vb_vidq);
> >> +
> >> +		err = tm6000_reset(dev);
> >> +		if (err < 0)
> >> +			dev_err(&vdev->dev, "reset failed: %d\n", err);
> >>  	}
> >>  
> >>  	kfree(fh);
> >> diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
> >> index cf57e1e..dac2063 100644
> >> --- a/drivers/staging/tm6000/tm6000.h
> >> +++ b/drivers/staging/tm6000/tm6000.h
> >> @@ -311,6 +311,7 @@ int tm6000_set_reg_mask(struct tm6000_core *dev, u8 req, u16 value,
> >>  						u16 index, u16 mask);
> >>  int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep);
> >>  int tm6000_init(struct tm6000_core *dev);
> >> +int tm6000_reset(struct tm6000_core *dev);
> >>  
> >>  int tm6000_init_analog_mode(struct tm6000_core *dev);
> >>  int tm6000_init_digital_mode(struct tm6000_core *dev);
> > 
> > Something went wrong with the patchset. Got an OOPS during device probe.
> > Maybe it were caused due to udev, that opens V4L devices, as soon as they're
> > registered.
> 
> int tm6000_reset(struct tm6000_core *dev)
> {
> ... 
>         msleep(5);
>  
>         pipe = usb_rcvintpipe(dev->udev,
>                         dev->int_in.endp->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
> 
> 
> The bug is on the above line. It seems that usb_rcvintpipe() didn't like to be
> called before the end of the device registration code.

I fail to see how this can happen. tm6000_reset() is only called when the
last user closes the file. Since the file can only be opened in the first
place when the device has been registered, tm6000_reset() should never be
called before the device is registered.

Thierry

> 
> 
> > 
> > 
> > [34883.426065] tm6000 #0: registered device video0
> > [34883.430591] Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: 0)
> > [34883.437763] usbcore: registered new interface driver tm6000
> > [34884.608372] BUG: unable to handle kernel NULL pointer dereference at 00000002
> > [34884.615514] IP: [<f8c4ceea>] tm6000_reset+0xd7/0x11c [tm6000]
> > [34884.621260] *pde = 00000000 
> > [34884.624139] Oops: 0000 [#1] SMP 
> > [34884.627375] Modules linked in: tuner_xc2028 tuner ir_lirc_codec lirc_dev ir_mce_kbd_decoder ir_sony_decoder ir_jvc_decoder ir_rc6_decoder ir_rc5_decoder tm6000 ir_nec_decoder videobuf_vmalloc videobuf_core rc_core v4l2_common videodev media tcp_lp fuse ebtable_nat ebtables ipt_MASQUERADE iptable_nat nf_nat xt_CHECKSUM iptable_mangle bridge stp llc bnep bluetooth sunrpc cpufreq_ondemand acpi_cpufreq mperf ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_filter nf_conntrack_ipv4 ip6_tables nf_defrag_ipv4 xt_state nf_conntrack snd_hda_codec_realtek snd_hda_intel snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm i7core_edac edac_core snd_timer tg3 snd iTCO_wdt iTCO_vendor_support hp_wmi soundcore pcspkr snd_page_alloc floppy sparse_keymap rfkill serio_raw tpm_infineon microcode vboxnetadp vboxnetflt vboxdrv firewire_ohci firewire_core crc_itu_t nouveau ttm drm_kms_helper drm i2c_algo_bit i2c_core mxm_wmi wmi video [last unloaded: tuner_xc2028]
> > [34884.712113] 
> > [34884.713599] Pid: 7448, comm: v4l_id Tainted: G        W   3.0.0+ #1 Hewlett-Packard HP Z400 Workstation/0AE4h
> > [34884.723513] EIP: 0060:[<f8c4ceea>] EFLAGS: 00010246 CPU: 0
> > [34884.728983] EIP is at tm6000_reset+0xd7/0x11c [tm6000]
> > [34884.734104] EAX: f676c800 EBX: e38e5800 ECX: 00000000 EDX: 00000003
> > [34884.740349] ESI: 00000000 EDI: efc3c400 EBP: efc19f18 ESP: efc19f04
> > [34884.746594]  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
> > [34884.751974] Process v4l_id (pid: 7448, ti=efc18000 task=f6608000 task.ti=efc18000)
> > [34884.759517] Stack:
> > [34884.761519]  f2b51c00 efc19f18 f8be3f96 e38e5800 f2b51c00 efc19f44 f8c4e6e5 f1b75a40
> > [34884.769318]  efc19f2c c0429397 efc19f34 c0810501 efc19f44 efc3c400 eb4b8cc0 00000010
> > [34884.777121]  efc19f54 f8bb619d eb4b8cc0 f66ffe08 efc19f84 c04e9eaf 00000001 00000000
> > [34884.784918] Call Trace:
> > [34884.787360]  [<f8be3f96>] ? __videobuf_free+0x10c/0x112 [videobuf_core]
> > [34884.793958]  [<f8c4e6e5>] tm6000_release+0xc7/0xf3 [tm6000]
> > [34884.799513]  [<c0429397>] ? should_resched+0xd/0x27
> > [34884.804378]  [<c0810501>] ? _cond_resched+0xd/0x21
> > [34884.809158]  [<f8bb619d>] v4l2_release+0x35/0x52 [videodev]
> > [34884.814713]  [<c04e9eaf>] fput+0x100/0x1a5
> > [34884.818798]  [<c04e75a1>] filp_close+0x5c/0x64
> > [34884.823228]  [<c04e7608>] sys_close+0x5f/0x93
> > [34884.827571]  [<c081745f>] sysenter_do_call+0x12/0x28
> > [34884.832519] Code: 24 04 40 10 c5 f8 c7 04 24 56 1d c5 f8 89 44 24 08 eb 4b b8 05 00 00 00 e8 b2 a7 7f c7 8b 83 44 06 00 00 8b 8b 78 06 00 00 8b 10 <0f> b6 49 02 c1 e2 08 83 e1 0f 81 ca 80 00 00 40 c1 e1 0f 09 ca 
> > [34884.851965] EIP: [<f8c4ceea>] tm6000_reset+0xd7/0x11c [tm6000] SS:ESP 0068:efc19f04
> > [34884.859623] CR2: 0000000000000002
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-media" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH 07/21] [staging] tm6000: Remove artificial delay.
  2011-09-01  5:13     ` Thierry Reding
@ 2011-09-01  5:47       ` Mauro Carvalho Chehab
  2011-09-01  6:27         ` [PATCH 1/2] [media] tm6000: Add fast USB access quirk Thierry Reding
  2011-09-01  6:43         ` [PATCH v2 " Thierry Reding
  0 siblings, 2 replies; 48+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-01  5:47 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-media

Em 01-09-2011 02:13, Thierry Reding escreveu:
> * Mauro Carvalho Chehab wrote:
>> Em 04-08-2011 04:14, Thierry Reding escreveu:
>>> ---
>>>  drivers/staging/tm6000/tm6000-core.c |    3 ---
>>>  1 files changed, 0 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
>>> index e14bd3d..2c156dd 100644
>>> --- a/drivers/staging/tm6000/tm6000-core.c
>>> +++ b/drivers/staging/tm6000/tm6000-core.c
>>> @@ -86,9 +86,6 @@ int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req,
>>>  	}
>>>  
>>>  	kfree(data);
>>> -
>>> -	msleep(5);
>>> -
>>>  	return ret;
>>>  }
>>>  
>>
>> This delay is needed by some tm5600/6000 devices. Maybe it is due to
>> some specific chipset revision, but I can't remember anymore what
>> device(s) were affected.
>>
>> The right thing to do seems to whitelist the devices that don't need
>> any delay there.
> 
> This was actually the first thing I patched because I couldn't see any need
> for it (the Cinergy Hybrid USB Stick worked fine without) and it made the
> device pretty much unusable (with this delay, firmware loading takes about
> 30 seconds!).

Firmware load timing sucks, but at least the device works. The windows application
load time is even worse than 30 s, at least for the devices I have here.

> 
> Do you want me to follow up with a white-listing patch?

Yes, please. It is good to speed it up, but only when we're sure that this won't cause
troubles.

> 
> Thierry


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

* Re: [PATCH 16/21] [staging] tm6000: Select interface on first open.
  2011-09-01  5:19     ` Thierry Reding
@ 2011-09-01  5:53       ` Mauro Carvalho Chehab
  2011-09-01  6:10         ` Thierry Reding
  0 siblings, 1 reply; 48+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-01  5:53 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-media

Em 01-09-2011 02:19, Thierry Reding escreveu:
> * Mauro Carvalho Chehab wrote:
>> Em 04-08-2011 04:14, Thierry Reding escreveu:
>>> Instead of selecting the default interface setting when preparing
>>> isochronous transfers, select it on the first call to open() to make
>>> sure it is available earlier.
>>
>> Hmm... I fail to see what this is needed earlier. The ISOC endpont is used
>> only when the device is streaming.
>>
>> Did you get any bug related to it? If so, please describe it better.
> 
> I'm not sure whether this really fixes a bug, but it seems a little wrong to
> me to selecting the interface so late in the process when in fact the device
> is already being configured before (video standard, audio mode, firmware
> upload, ...).

Some applications may open the device just to change the controls. All other drivers
only set alternates/interfaces when the streaming is requested, as alternates/interfaces
are needed only there.

> Thinking about it, this may actually be part of the fix for the "device hangs
> sometimes for inexplicable reasons" bug that this whole patch series seems to
> fix.

It is unlikely, except if the firmware inside the chip is broken (unfortunately, 
we have serious reasons to believe that the internal firmware on this chipset has
serious bugs).

I prefer to not apply this patch, except if we have a good reason for that,
as otherwise this driver will behave different than the others.

Regards,
Mauro.

> 
> Thierry


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

* Re: [PATCH 16/21] [staging] tm6000: Select interface on first open.
  2011-09-01  5:53       ` Mauro Carvalho Chehab
@ 2011-09-01  6:10         ` Thierry Reding
  0 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-09-01  6:10 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-media

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

* Mauro Carvalho Chehab wrote:
> Em 01-09-2011 02:19, Thierry Reding escreveu:
> > * Mauro Carvalho Chehab wrote:
> >> Em 04-08-2011 04:14, Thierry Reding escreveu:
> >>> Instead of selecting the default interface setting when preparing
> >>> isochronous transfers, select it on the first call to open() to make
> >>> sure it is available earlier.
> >>
> >> Hmm... I fail to see what this is needed earlier. The ISOC endpont is used
> >> only when the device is streaming.
> >>
> >> Did you get any bug related to it? If so, please describe it better.
> > 
> > I'm not sure whether this really fixes a bug, but it seems a little wrong to
> > me to selecting the interface so late in the process when in fact the device
> > is already being configured before (video standard, audio mode, firmware
> > upload, ...).
> 
> Some applications may open the device just to change the controls. All other drivers
> only set alternates/interfaces when the streaming is requested, as alternates/interfaces
> are needed only there.

Okay, I didn't know that it was only necessary for streaming.

> > Thinking about it, this may actually be part of the fix for the "device hangs
> > sometimes for inexplicable reasons" bug that this whole patch series seems to
> > fix.
> 
> It is unlikely, except if the firmware inside the chip is broken (unfortunately, 
> we have serious reasons to believe that the internal firmware on this chipset has
> serious bugs).

Indeed! =)

> I prefer to not apply this patch, except if we have a good reason for that,
> as otherwise this driver will behave different than the others.

Okay, it's your call. Unfortunately I no longer have the hardware available
to test if this is really related to the bug. I'll have to check again when I
have the hardware.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH 1/2] [media] tm6000: Add fast USB access quirk
  2011-09-01  5:47       ` Mauro Carvalho Chehab
@ 2011-09-01  6:27         ` Thierry Reding
  2011-09-01  6:27           ` [PATCH 2/2] [media] tm6000: Enable fast USB quirk on Cinergy Hybrid Thierry Reding
  2011-09-01  6:33           ` [PATCH 1/2] [media] tm6000: Add fast USB access quirk Thierry Reding
  2011-09-01  6:43         ` [PATCH v2 " Thierry Reding
  1 sibling, 2 replies; 48+ messages in thread
From: Thierry Reding @ 2011-09-01  6:27 UTC (permalink / raw)
  To: linux-media; +Cc: Mauro Carvalho Chehab

Some devices support fast access to registers using the USB interface
while others require a certain delay after each operation. This commit
adds a quirk that can be enabled by devices that don't need the delay.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
 drivers/staging/tm6000/tm6000-core.c |    3 ++-
 drivers/staging/tm6000/tm6000.h      |    6 ++++++
 2 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index 64fc1c6..93a0772 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -89,7 +89,8 @@ int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req,
 
 	kfree(data);
 
-	msleep(5);
+	if ((dev->quirks & TM6000_QUIRK_NO_USB_DELAY) == 0)
+		msleep(5);
 
 	mutex_unlock(&dev->usb_lock);
 	return ret;
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
index dac2063..0e35812 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -169,6 +169,10 @@ struct tm6000_endpoint {
 	unsigned			maxsize;
 };
 
+enum {
+	TM6000_QUIRK_NO_USB_DELAY,
+};
+
 struct tm6000_core {
 	/* generic device properties */
 	char				name[30];	/* name (including minor) of the device */
@@ -260,6 +264,8 @@ struct tm6000_core {
 	struct usb_isoc_ctl          isoc_ctl;
 
 	spinlock_t                   slock;
+
+	unsigned long quirks;
 };
 
 enum tm6000_ops_type {
-- 
1.7.6.1


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

* [PATCH 2/2] [media] tm6000: Enable fast USB quirk on Cinergy Hybrid
  2011-09-01  6:27         ` [PATCH 1/2] [media] tm6000: Add fast USB access quirk Thierry Reding
@ 2011-09-01  6:27           ` Thierry Reding
  2011-09-01  6:33           ` [PATCH 1/2] [media] tm6000: Add fast USB access quirk Thierry Reding
  1 sibling, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-09-01  6:27 UTC (permalink / raw)
  To: linux-media; +Cc: Mauro Carvalho Chehab

The Cinergy Hybrid cards are known not to need an artificial delay after
USB accesses so the quirk can safely be enabled.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
 drivers/staging/tm6000/tm6000-cards.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index 5393976..aa18173 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -1002,6 +1002,16 @@ static int fill_board_specific_data(struct tm6000_core *dev)
 	dev->vinput[2] = tm6000_boards[dev->model].vinput[2];
 	dev->rinput = tm6000_boards[dev->model].rinput;
 
+	/* setup per-model quirks */
+	switch (dev->model) {
+	case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
+		dev->quirks |= TM6000_QUIRK_NO_USB_DELAY;
+		break;
+
+	default:
+		break;
+	}
+
 	/* initialize hardware */
 	rc = tm6000_init(dev);
 	if (rc < 0)
-- 
1.7.6.1


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

* Re: [PATCH 1/2] [media] tm6000: Add fast USB access quirk
  2011-09-01  6:27         ` [PATCH 1/2] [media] tm6000: Add fast USB access quirk Thierry Reding
  2011-09-01  6:27           ` [PATCH 2/2] [media] tm6000: Enable fast USB quirk on Cinergy Hybrid Thierry Reding
@ 2011-09-01  6:33           ` Thierry Reding
  1 sibling, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-09-01  6:33 UTC (permalink / raw)
  To: linux-media; +Cc: Mauro Carvalho Chehab

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

* Thierry Reding wrote:
> Some devices support fast access to registers using the USB interface
> while others require a certain delay after each operation. This commit
> adds a quirk that can be enabled by devices that don't need the delay.
> 
> Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
> ---
>  drivers/staging/tm6000/tm6000-core.c |    3 ++-
>  drivers/staging/tm6000/tm6000.h      |    6 ++++++
>  2 files changed, 8 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
> index 64fc1c6..93a0772 100644
> --- a/drivers/staging/tm6000/tm6000-core.c
> +++ b/drivers/staging/tm6000/tm6000-core.c
> @@ -89,7 +89,8 @@ int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req,
>  
>  	kfree(data);
>  
> -	msleep(5);
> +	if ((dev->quirks & TM6000_QUIRK_NO_USB_DELAY) == 0)
> +		msleep(5);

This is of course completely wrong. The quirk as defined below is actually a
bit position. I'll send another update where the quirk is defined as bit mask
for the given position.

Thierry

>  
>  	mutex_unlock(&dev->usb_lock);
>  	return ret;
> diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
> index dac2063..0e35812 100644
> --- a/drivers/staging/tm6000/tm6000.h
> +++ b/drivers/staging/tm6000/tm6000.h
> @@ -169,6 +169,10 @@ struct tm6000_endpoint {
>  	unsigned			maxsize;
>  };
>  
> +enum {
> +	TM6000_QUIRK_NO_USB_DELAY,
> +};
> +
>  struct tm6000_core {
>  	/* generic device properties */
>  	char				name[30];	/* name (including minor) of the device */
> @@ -260,6 +264,8 @@ struct tm6000_core {
>  	struct usb_isoc_ctl          isoc_ctl;
>  
>  	spinlock_t                   slock;
> +
> +	unsigned long quirks;
>  };
>  
>  enum tm6000_ops_type {
> -- 
> 1.7.6.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* [PATCH v2 1/2] [media] tm6000: Add fast USB access quirk
  2011-09-01  5:47       ` Mauro Carvalho Chehab
  2011-09-01  6:27         ` [PATCH 1/2] [media] tm6000: Add fast USB access quirk Thierry Reding
@ 2011-09-01  6:43         ` Thierry Reding
  2011-09-01  6:43           ` [PATCH v2 2/2] [media] tm6000: Enable fast USB quirk on Cinergy Hybrid Thierry Reding
  1 sibling, 1 reply; 48+ messages in thread
From: Thierry Reding @ 2011-09-01  6:43 UTC (permalink / raw)
  To: linux-media; +Cc: Mauro Carvalho Chehab

Some devices support fast access to registers using the USB interface
while others require a certain delay after each operation. This commit
adds a quirk that can be enabled by devices that don't need the delay.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
 drivers/staging/tm6000/tm6000-core.c |    3 ++-
 drivers/staging/tm6000/tm6000.h      |    4 ++++
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index 64fc1c6..93a0772 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -89,7 +89,8 @@ int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req,
 
 	kfree(data);
 
-	msleep(5);
+	if ((dev->quirks & TM6000_QUIRK_NO_USB_DELAY) == 0)
+		msleep(5);
 
 	mutex_unlock(&dev->usb_lock);
 	return ret;
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
index dac2063..5bdce84 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -169,6 +169,8 @@ struct tm6000_endpoint {
 	unsigned			maxsize;
 };
 
+#define TM6000_QUIRK_NO_USB_DELAY (1 << 0)
+
 struct tm6000_core {
 	/* generic device properties */
 	char				name[30];	/* name (including minor) of the device */
@@ -260,6 +262,8 @@ struct tm6000_core {
 	struct usb_isoc_ctl          isoc_ctl;
 
 	spinlock_t                   slock;
+
+	unsigned long quirks;
 };
 
 enum tm6000_ops_type {
-- 
1.7.6.1


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

* [PATCH v2 2/2] [media] tm6000: Enable fast USB quirk on Cinergy Hybrid
  2011-09-01  6:43         ` [PATCH v2 " Thierry Reding
@ 2011-09-01  6:43           ` Thierry Reding
  0 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-09-01  6:43 UTC (permalink / raw)
  To: linux-media; +Cc: Mauro Carvalho Chehab

The Cinergy Hybrid cards are known not to need an artificial delay after
USB accesses so the quirk can safely be enabled.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
---
 drivers/staging/tm6000/tm6000-cards.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index 5393976..aa18173 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -1002,6 +1002,16 @@ static int fill_board_specific_data(struct tm6000_core *dev)
 	dev->vinput[2] = tm6000_boards[dev->model].vinput[2];
 	dev->rinput = tm6000_boards[dev->model].rinput;
 
+	/* setup per-model quirks */
+	switch (dev->model) {
+	case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
+		dev->quirks |= TM6000_QUIRK_NO_USB_DELAY;
+		break;
+
+	default:
+		break;
+	}
+
 	/* initialize hardware */
 	rc = tm6000_init(dev);
 	if (rc < 0)
-- 
1.7.6.1


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

* Re: [PATCH 02/21] [media] tuner/xc2028: Fix frequency offset for radio mode.
  2011-09-01  5:10     ` Thierry Reding
@ 2011-09-01 12:45       ` Andrew Goff
  2011-09-01 14:31         ` Mauro Carvalho Chehab
  2011-09-02  8:19         ` Thierry Reding
  0 siblings, 2 replies; 48+ messages in thread
From: Andrew Goff @ 2011-09-01 12:45 UTC (permalink / raw)
  To: Thierry Reding; +Cc: Mauro Carvalho Chehab, linux-media

Hi Thierry,

I have been having problems with the radio tuner in my leadtek 1800h 
card. This card has the xc2028 tuner. Using fmtools i would get an error 
message similar to - frequency out of range 0.0 - 0.0.

After seeing you patches at the beginning of last month I installed the 
recent drivers at the time and applied your patches. The frequency out 
of range error went away but the only sound I got was static. I then 
discovered the frequency is out by 2.7MHz, so if I want to listen to 
104.9 I need to tune the radio to 107.6.

On Ubuntu 10.04 the card works fine, the errors started when applying 
the recent V4L drivers that I require for another card.

Are you able to help resolve this problem and get this card working 
properly again.

Thanks

Andrew



On 1/09/2011 3:10 PM, Thierry Reding wrote:
> * Mauro Carvalho Chehab wrote:
>> Em 04-08-2011 04:14, Thierry Reding escreveu:
>>> In radio mode, no frequency offset is needed. While at it, split off the
>>> frequency offset computation for digital TV into a separate function.
>>
>> Nah, it is better to keep the offset calculation there. there is already
>> a set_freq for DVB. breaking the frequency logic even further seems to
>> increase the driver's logic. Also, patch is simpler and easier to review.
>
> Okay, no problem. Feel free to replace the patch with yours.
>
>> The patch bellow seems to be better. On a quick review, I think that the
>> 	send_seq(priv, {0x00, 0x00})
>> sequence may be wrong. I suspect that the device is just discarding that,
>> but changing it needs more testing.
>
> I ran across that as well, but I didn't dare touch it because I wasn't sure
> what the broader impact would be.
>
> Thierry

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

* Re: [PATCH 02/21] [media] tuner/xc2028: Fix frequency offset for radio mode.
  2011-09-01 12:45       ` Andrew Goff
@ 2011-09-01 14:31         ` Mauro Carvalho Chehab
  2011-09-02  8:19         ` Thierry Reding
  1 sibling, 0 replies; 48+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-01 14:31 UTC (permalink / raw)
  To: goffa72; +Cc: Thierry Reding, linux-media

Em 01-09-2011 09:45, Andrew Goff escreveu:
> Hi Thierry,
> 
> I have been having problems with the radio tuner in my leadtek 1800h card. This card has the xc2028 tuner. Using fmtools i would get an error message similar to - frequency out of range 0.0 - 0.0.

This is due to a bug at the tuner core.

> After seeing you patches at the beginning of last month I installed the recent drivers at the time and applied your patches. The frequency out of range error went away but the only sound I got was static. I then discovered the frequency is out by 2.7MHz, so if I want to listen to 104.9 I need to tune the radio to 107.6.

Try to remove Thierry xc3028 patch. His patches were applied already at the main tree
(I applied them very early today).

> 
> On Ubuntu 10.04 the card works fine, the errors started when applying the recent V4L drivers that I require for another card.
> 
> Are you able to help resolve this problem and get this card working properly again.
> 
> Thanks
> 
> Andrew
> 
> 
> 
> On 1/09/2011 3:10 PM, Thierry Reding wrote:
>> * Mauro Carvalho Chehab wrote:
>>> Em 04-08-2011 04:14, Thierry Reding escreveu:
>>>> In radio mode, no frequency offset is needed. While at it, split off the
>>>> frequency offset computation for digital TV into a separate function.
>>>
>>> Nah, it is better to keep the offset calculation there. there is already
>>> a set_freq for DVB. breaking the frequency logic even further seems to
>>> increase the driver's logic. Also, patch is simpler and easier to review.
>>
>> Okay, no problem. Feel free to replace the patch with yours.
>>
>>> The patch bellow seems to be better. On a quick review, I think that the
>>>     send_seq(priv, {0x00, 0x00})
>>> sequence may be wrong. I suspect that the device is just discarding that,
>>> but changing it needs more testing.
>>
>> I ran across that as well, but I didn't dare touch it because I wasn't sure
>> what the broader impact would be.
>>
>> Thierry


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

* Re: [PATCH 02/21] [media] tuner/xc2028: Fix frequency offset for radio mode.
  2011-09-01 12:45       ` Andrew Goff
  2011-09-01 14:31         ` Mauro Carvalho Chehab
@ 2011-09-02  8:19         ` Thierry Reding
  2011-12-31  0:31           ` Javier S. Pedro
  1 sibling, 1 reply; 48+ messages in thread
From: Thierry Reding @ 2011-09-02  8:19 UTC (permalink / raw)
  To: Andrew Goff; +Cc: Mauro Carvalho Chehab, linux-media

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

* Andrew Goff wrote:
> Hi Thierry,
> 
> I have been having problems with the radio tuner in my leadtek 1800h
> card. This card has the xc2028 tuner. Using fmtools i would get an
> error message similar to - frequency out of range 0.0 - 0.0.
> 
> After seeing you patches at the beginning of last month I installed
> the recent drivers at the time and applied your patches. The
> frequency out of range error went away but the only sound I got was
> static. I then discovered the frequency is out by 2.7MHz, so if I
> want to listen to 104.9 I need to tune the radio to 107.6.
> 
> On Ubuntu 10.04 the card works fine, the errors started when
> applying the recent V4L drivers that I require for another card.
> 
> Are you able to help resolve this problem and get this card working
> properly again.

So you are saying that the card was previously working for you, but when you
apply the xc2028 patches from my series on top the tuning is off by 2.7 MHz?

I don't know the Leadtek 1800 at all, but perhaps it's actually compensating
for the offset before passing the frequency to the tuner?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH 15/21] [staging] tm6000: Execute lightweight reset on close.
  2011-09-01  5:24       ` Thierry Reding
@ 2011-09-03 17:17         ` Mauro Carvalho Chehab
  2011-09-05  5:38           ` Thierry Reding
  0 siblings, 1 reply; 48+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-03 17:17 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-media

Em 01-09-2011 02:24, Thierry Reding escreveu:
> * Mauro Carvalho Chehab wrote:
>> Em 31-08-2011 17:53, Mauro Carvalho Chehab escreveu:
>>> Em 04-08-2011 04:14, Thierry Reding escreveu:
>>>> When the last user closes the device, perform a lightweight reset of the
>>>> device to bring it into a well-known state.
>>>>
>>>> Note that this is not always enough with the TM6010, which sometimes
>>>> needs a hard reset to get into a working state again.
>>>> ---
>>>>  drivers/staging/tm6000/tm6000-core.c  |   43 +++++++++++++++++++++++++++++++++
>>>>  drivers/staging/tm6000/tm6000-video.c |    8 +++++-
>>>>  drivers/staging/tm6000/tm6000.h       |    1 +
>>>>  3 files changed, 51 insertions(+), 1 deletions(-)
>>>>
>>>> diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
>>>> index 317ab7e..58c1399 100644
>>>> --- a/drivers/staging/tm6000/tm6000-core.c
>>>> +++ b/drivers/staging/tm6000/tm6000-core.c
>>>> @@ -597,6 +597,49 @@ int tm6000_init(struct tm6000_core *dev)
>>>>  	return rc;
>>>>  }
>>>>  
>>>> +int tm6000_reset(struct tm6000_core *dev)
>>>> +{
>>>> +	int pipe;
>>>> +	int err;
>>>> +
>>>> +	msleep(500);
>>>> +
>>>> +	err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 0);
>>>> +	if (err < 0) {
>>>> +		tm6000_err("failed to select interface %d, alt. setting 0\n",
>>>> +				dev->isoc_in.bInterfaceNumber);
>>>> +		return err;
>>>> +	}
>>>> +
>>>> +	err = usb_reset_configuration(dev->udev);
>>>> +	if (err < 0) {
>>>> +		tm6000_err("failed to reset configuration\n");
>>>> +		return err;
>>>> +	}
>>>> +
>>>> +	msleep(5);
>>>> +
>>>> +	err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 2);
>>>> +	if (err < 0) {
>>>> +		tm6000_err("failed to select interface %d, alt. setting 2\n",
>>>> +				dev->isoc_in.bInterfaceNumber);
>>>> +		return err;
>>>> +	}
>>>> +
>>>> +	msleep(5);
>>>> +
>>>> +	pipe = usb_rcvintpipe(dev->udev,
>>>> +			dev->int_in.endp->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
>>>> +
>>>> +	err = usb_clear_halt(dev->udev, pipe);
>>>> +	if (err < 0) {
>>>> +		tm6000_err("usb_clear_halt failed: %d\n", err);
>>>> +		return err;
>>>> +	}
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>>  int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate)
>>>>  {
>>>>  	int val = 0;
>>>> diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
>>>> index 492ec73..70fc19e 100644
>>>> --- a/drivers/staging/tm6000/tm6000-video.c
>>>> +++ b/drivers/staging/tm6000/tm6000-video.c
>>>> @@ -1503,7 +1503,6 @@ static int tm6000_open(struct file *file)
>>>>  	tm6000_get_std_res(dev);
>>>>  
>>>>  	file->private_data = fh;
>>>> -	fh->vdev = vdev;
>>>>  	fh->dev = dev;
>>>>  	fh->radio = radio;
>>>>  	fh->type = type;
>>>> @@ -1606,9 +1605,16 @@ static int tm6000_release(struct file *file)
>>>>  	dev->users--;
>>>>  
>>>>  	res_free(dev, fh);
>>>> +
>>>>  	if (!dev->users) {
>>>> +		int err;
>>>> +
>>>>  		tm6000_uninit_isoc(dev);
>>>>  		videobuf_mmap_free(&fh->vb_vidq);
>>>> +
>>>> +		err = tm6000_reset(dev);
>>>> +		if (err < 0)
>>>> +			dev_err(&vdev->dev, "reset failed: %d\n", err);
>>>>  	}
>>>>  
>>>>  	kfree(fh);
>>>> diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
>>>> index cf57e1e..dac2063 100644
>>>> --- a/drivers/staging/tm6000/tm6000.h
>>>> +++ b/drivers/staging/tm6000/tm6000.h
>>>> @@ -311,6 +311,7 @@ int tm6000_set_reg_mask(struct tm6000_core *dev, u8 req, u16 value,
>>>>  						u16 index, u16 mask);
>>>>  int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep);
>>>>  int tm6000_init(struct tm6000_core *dev);
>>>> +int tm6000_reset(struct tm6000_core *dev);
>>>>  
>>>>  int tm6000_init_analog_mode(struct tm6000_core *dev);
>>>>  int tm6000_init_digital_mode(struct tm6000_core *dev);
>>>
>>> Something went wrong with the patchset. Got an OOPS during device probe.
>>> Maybe it were caused due to udev, that opens V4L devices, as soon as they're
>>> registered.
>>
>> int tm6000_reset(struct tm6000_core *dev)
>> {
>> ... 
>>         msleep(5);
>>  
>>         pipe = usb_rcvintpipe(dev->udev,
>>                         dev->int_in.endp->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
>>
>>
>> The bug is on the above line. It seems that usb_rcvintpipe() didn't like to be
>> called before the end of the device registration code.
> 
> I fail to see how this can happen. tm6000_reset() is only called when the
> last user closes the file. Since the file can only be opened in the first
> place when the device has been registered, tm6000_reset() should never be
> called before the device is registered.

It is quite simple: not all tm5600/6000/6010 devices have int_in endpoints.

The enclosed patch fixes it. Tested on a Saphire Wonder TV device (tm5600).

[media] tm6000: Don't try to use a non-existing interface

The dev->int_in USB interfaces is used by some devices for the Remote Controller.
Not all devices seem to define this interface.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index 9cef1d1..b3c4e05 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -621,6 +621,12 @@ int tm6000_reset(struct tm6000_core *dev)
 
 	msleep(5);
 
+	/*
+	 * Not all devices have int_in defined
+	 */
+	if (!dev->int_in.endp)
+		return 0;
+
 	err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 2);
 	if (err < 0) {
 		tm6000_err("failed to select interface %d, alt. setting 2\n",

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

* Re: [PATCH 15/21] [staging] tm6000: Execute lightweight reset on close.
  2011-09-03 17:17         ` Mauro Carvalho Chehab
@ 2011-09-05  5:38           ` Thierry Reding
  0 siblings, 0 replies; 48+ messages in thread
From: Thierry Reding @ 2011-09-05  5:38 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-media

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

* Mauro Carvalho Chehab wrote:
> Em 01-09-2011 02:24, Thierry Reding escreveu:
> > * Mauro Carvalho Chehab wrote:
> >> Em 31-08-2011 17:53, Mauro Carvalho Chehab escreveu:
> >>> Em 04-08-2011 04:14, Thierry Reding escreveu:
> >>>> When the last user closes the device, perform a lightweight reset of the
> >>>> device to bring it into a well-known state.
> >>>>
> >>>> Note that this is not always enough with the TM6010, which sometimes
> >>>> needs a hard reset to get into a working state again.
> >>>> ---
> >>>>  drivers/staging/tm6000/tm6000-core.c  |   43 +++++++++++++++++++++++++++++++++
> >>>>  drivers/staging/tm6000/tm6000-video.c |    8 +++++-
> >>>>  drivers/staging/tm6000/tm6000.h       |    1 +
> >>>>  3 files changed, 51 insertions(+), 1 deletions(-)
> >>>>
> >>>> diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
> >>>> index 317ab7e..58c1399 100644
> >>>> --- a/drivers/staging/tm6000/tm6000-core.c
> >>>> +++ b/drivers/staging/tm6000/tm6000-core.c
> >>>> @@ -597,6 +597,49 @@ int tm6000_init(struct tm6000_core *dev)
> >>>>  	return rc;
> >>>>  }
> >>>>  
> >>>> +int tm6000_reset(struct tm6000_core *dev)
> >>>> +{
> >>>> +	int pipe;
> >>>> +	int err;
> >>>> +
> >>>> +	msleep(500);
> >>>> +
> >>>> +	err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 0);
> >>>> +	if (err < 0) {
> >>>> +		tm6000_err("failed to select interface %d, alt. setting 0\n",
> >>>> +				dev->isoc_in.bInterfaceNumber);
> >>>> +		return err;
> >>>> +	}
> >>>> +
> >>>> +	err = usb_reset_configuration(dev->udev);
> >>>> +	if (err < 0) {
> >>>> +		tm6000_err("failed to reset configuration\n");
> >>>> +		return err;
> >>>> +	}
> >>>> +
> >>>> +	msleep(5);
> >>>> +
> >>>> +	err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 2);
> >>>> +	if (err < 0) {
> >>>> +		tm6000_err("failed to select interface %d, alt. setting 2\n",
> >>>> +				dev->isoc_in.bInterfaceNumber);
> >>>> +		return err;
> >>>> +	}
> >>>> +
> >>>> +	msleep(5);
> >>>> +
> >>>> +	pipe = usb_rcvintpipe(dev->udev,
> >>>> +			dev->int_in.endp->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
> >>>> +
> >>>> +	err = usb_clear_halt(dev->udev, pipe);
> >>>> +	if (err < 0) {
> >>>> +		tm6000_err("usb_clear_halt failed: %d\n", err);
> >>>> +		return err;
> >>>> +	}
> >>>> +
> >>>> +	return 0;
> >>>> +}
> >>>> +
> >>>>  int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate)
> >>>>  {
> >>>>  	int val = 0;
> >>>> diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
> >>>> index 492ec73..70fc19e 100644
> >>>> --- a/drivers/staging/tm6000/tm6000-video.c
> >>>> +++ b/drivers/staging/tm6000/tm6000-video.c
> >>>> @@ -1503,7 +1503,6 @@ static int tm6000_open(struct file *file)
> >>>>  	tm6000_get_std_res(dev);
> >>>>  
> >>>>  	file->private_data = fh;
> >>>> -	fh->vdev = vdev;
> >>>>  	fh->dev = dev;
> >>>>  	fh->radio = radio;
> >>>>  	fh->type = type;
> >>>> @@ -1606,9 +1605,16 @@ static int tm6000_release(struct file *file)
> >>>>  	dev->users--;
> >>>>  
> >>>>  	res_free(dev, fh);
> >>>> +
> >>>>  	if (!dev->users) {
> >>>> +		int err;
> >>>> +
> >>>>  		tm6000_uninit_isoc(dev);
> >>>>  		videobuf_mmap_free(&fh->vb_vidq);
> >>>> +
> >>>> +		err = tm6000_reset(dev);
> >>>> +		if (err < 0)
> >>>> +			dev_err(&vdev->dev, "reset failed: %d\n", err);
> >>>>  	}
> >>>>  
> >>>>  	kfree(fh);
> >>>> diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
> >>>> index cf57e1e..dac2063 100644
> >>>> --- a/drivers/staging/tm6000/tm6000.h
> >>>> +++ b/drivers/staging/tm6000/tm6000.h
> >>>> @@ -311,6 +311,7 @@ int tm6000_set_reg_mask(struct tm6000_core *dev, u8 req, u16 value,
> >>>>  						u16 index, u16 mask);
> >>>>  int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep);
> >>>>  int tm6000_init(struct tm6000_core *dev);
> >>>> +int tm6000_reset(struct tm6000_core *dev);
> >>>>  
> >>>>  int tm6000_init_analog_mode(struct tm6000_core *dev);
> >>>>  int tm6000_init_digital_mode(struct tm6000_core *dev);
> >>>
> >>> Something went wrong with the patchset. Got an OOPS during device probe.
> >>> Maybe it were caused due to udev, that opens V4L devices, as soon as they're
> >>> registered.
> >>
> >> int tm6000_reset(struct tm6000_core *dev)
> >> {
> >> ... 
> >>         msleep(5);
> >>  
> >>         pipe = usb_rcvintpipe(dev->udev,
> >>                         dev->int_in.endp->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
> >>
> >>
> >> The bug is on the above line. It seems that usb_rcvintpipe() didn't like to be
> >> called before the end of the device registration code.
> > 
> > I fail to see how this can happen. tm6000_reset() is only called when the
> > last user closes the file. Since the file can only be opened in the first
> > place when the device has been registered, tm6000_reset() should never be
> > called before the device is registered.
> 
> It is quite simple: not all tm5600/6000/6010 devices have int_in endpoints.
> 
> The enclosed patch fixes it. Tested on a Saphire Wonder TV device (tm5600).
> 
> [media] tm6000: Don't try to use a non-existing interface
> 
> The dev->int_in USB interfaces is used by some devices for the Remote Controller.
> Not all devices seem to define this interface.
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
> 
> diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
> index 9cef1d1..b3c4e05 100644
> --- a/drivers/staging/tm6000/tm6000-core.c
> +++ b/drivers/staging/tm6000/tm6000-core.c
> @@ -621,6 +621,12 @@ int tm6000_reset(struct tm6000_core *dev)
>  
>  	msleep(5);
>  
> +	/*
> +	 * Not all devices have int_in defined
> +	 */
> +	if (!dev->int_in.endp)
> +		return 0;
> +
>  	err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 2);
>  	if (err < 0) {
>  		tm6000_err("failed to select interface %d, alt. setting 2\n",

Wouldn't it make more sense to move this check after the usb_set_interface()
call and right before usb_rcvintpipe()? Note that usb_set_interface() uses
isoc_in, not int_in.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [PATCH 02/21] [media] tuner/xc2028: Fix frequency offset for radio mode.
  2011-09-02  8:19         ` Thierry Reding
@ 2011-12-31  0:31           ` Javier S. Pedro
  0 siblings, 0 replies; 48+ messages in thread
From: Javier S. Pedro @ 2011-12-31  0:31 UTC (permalink / raw)
  To: linux-media

(Fri, 02 Sep 2011 10:19:05 +0200) Thierry Reding:
> So you are saying that the card was previously working for you, but
> when you apply the xc2028 patches from my series on top the tuning is
> off by 2.7 MHz?

I observed the 2.75Mhz offset nearly a year ago [1], but since I got 
silence on this ML I assumed it was a problem specific to my card and 
patched my kernel with a patch very similar to Thierry's.

Seeing some activity around this makes me happy, even if it's to confirm 
it is indeed a problem specific to my card or a set of cards.

In case anyone wants to start a list, my card is AverMedia PCI Hybrid (aka 
'A16D'). By Andrew's post we know Leadtek 1800 seems not to need the 
patch.

Javier.

[1] http://comments.gmane.org/gmane.linux.drivers.video-input-
infrastructure/24251


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

end of thread, other threads:[~2011-12-31  0:31 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-04  7:13 [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Thierry Reding
2011-08-04  7:13 ` [PATCH 01/21] [media] tuner/xc2028: Add I2C flush callback Thierry Reding
2011-08-04  7:14 ` [PATCH 02/21] [media] tuner/xc2028: Fix frequency offset for radio mode Thierry Reding
2011-08-31 18:32   ` Mauro Carvalho Chehab
2011-09-01  5:10     ` Thierry Reding
2011-09-01 12:45       ` Andrew Goff
2011-09-01 14:31         ` Mauro Carvalho Chehab
2011-09-02  8:19         ` Thierry Reding
2011-12-31  0:31           ` Javier S. Pedro
2011-08-04  7:14 ` [PATCH 03/21] [staging] tm6000: Miscellaneous cleanups Thierry Reding
2011-08-04  7:14 ` [PATCH 04/21] [staging] tm6000: Use correct input in radio mode Thierry Reding
2011-08-04  7:14 ` [PATCH 05/21] [staging] tm6000: Implement I2C flush callback Thierry Reding
2011-08-04  7:14 ` [PATCH 06/21] [staging] tm6000: Increase maximum I2C packet size Thierry Reding
2011-08-31 19:45   ` Mauro Carvalho Chehab
2011-09-01  5:08     ` Thierry Reding
2011-08-04  7:14 ` [PATCH 07/21] [staging] tm6000: Remove artificial delay Thierry Reding
2011-08-31 19:50   ` Mauro Carvalho Chehab
2011-09-01  5:13     ` Thierry Reding
2011-09-01  5:47       ` Mauro Carvalho Chehab
2011-09-01  6:27         ` [PATCH 1/2] [media] tm6000: Add fast USB access quirk Thierry Reding
2011-09-01  6:27           ` [PATCH 2/2] [media] tm6000: Enable fast USB quirk on Cinergy Hybrid Thierry Reding
2011-09-01  6:33           ` [PATCH 1/2] [media] tm6000: Add fast USB access quirk Thierry Reding
2011-09-01  6:43         ` [PATCH v2 " Thierry Reding
2011-09-01  6:43           ` [PATCH v2 2/2] [media] tm6000: Enable fast USB quirk on Cinergy Hybrid Thierry Reding
2011-08-04  7:14 ` [PATCH 08/21] [staging] tm6000: Flesh out the IRQ callback Thierry Reding
2011-08-04  7:14 ` [PATCH 09/21] [staging] tm6000: Rename active interface register Thierry Reding
2011-08-04  7:14 ` [PATCH 10/21] [staging] tm6000: Disable video interface in radio mode Thierry Reding
2011-08-04  7:14 ` [PATCH 11/21] [staging] tm6000: Rework standard register tables Thierry Reding
2011-08-04  7:14 ` [PATCH 12/21] [staging] tm6000: Add locking for USB transfers Thierry Reding
2011-08-04  7:14 ` [PATCH 13/21] [staging] tm6000: Properly count device usage Thierry Reding
2011-08-04  7:14 ` [PATCH 14/21] [staging] tm6000: Initialize isochronous transfers only once Thierry Reding
2011-08-04  7:14 ` [PATCH 15/21] [staging] tm6000: Execute lightweight reset on close Thierry Reding
2011-08-31 20:53   ` Mauro Carvalho Chehab
     [not found]     ` <4E5EAA41.4060502@redhat.com>
2011-09-01  5:24       ` Thierry Reding
2011-09-03 17:17         ` Mauro Carvalho Chehab
2011-09-05  5:38           ` Thierry Reding
2011-08-04  7:14 ` [PATCH 16/21] [staging] tm6000: Select interface on first open Thierry Reding
2011-08-31 20:02   ` Mauro Carvalho Chehab
2011-09-01  5:19     ` Thierry Reding
2011-09-01  5:53       ` Mauro Carvalho Chehab
2011-09-01  6:10         ` Thierry Reding
2011-08-04  7:14 ` [PATCH 17/21] [staging] tm6000: Do not use video buffers in radio mode Thierry Reding
2011-08-04  7:14 ` [PATCH 18/21] [staging] tm6000: Plug memory leak on PCM free Thierry Reding
2011-08-04  7:14 ` [PATCH 19/21] [staging] tm6000: Enable audio clock in radio mode Thierry Reding
2011-08-04  7:14 ` [PATCH 20/21] [staging] tm6000: Enable radio mode for Cinergy Hybrid XE Thierry Reding
2011-08-04  7:14 ` [PATCH 21/21] [staging] tm6000: Remove unnecessary workaround Thierry Reding
2011-08-31 12:41 ` [PATCH 00/21] [staging] tm6000: Assorted fixes and improvements Mauro Carvalho Chehab
2011-08-31 13:12   ` Thierry Reding

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.