public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
* Re: [linux-dvb] dib0700 new i2c implementation
@ 2008-08-27  7:10 Eduard Huguet
  2008-08-27  8:24 ` Patrick Boettcher
  2008-08-27  8:25 ` Nicolas Will
  0 siblings, 2 replies; 8+ messages in thread
From: Eduard Huguet @ 2008-08-27  7:10 UTC (permalink / raw)
  To: linux-dvb


[-- Attachment #1.1: Type: text/plain, Size: 1451 bytes --]

>
> ---------- Missatge reenviat ----------
> From: "Devin Heitmueller" <devin.heitmueller@gmail.com>
> To: linux-dvb <linux-dvb@linuxtv.org>
> Date: Tue, 26 Aug 2008 21:15:20 -0400
> Subject: [linux-dvb] dib0700 new i2c implementation
> The attached patch implements the new dib0700 i2c API, which requires
> v1.20 of the firmware.  It addresses some classes of i2c problems (in
> particular the one I had where i2c reads were being sent onto the bus
> as i2c write calls)
>
> I would appreciate it if those with dib0700 based devices would try
> out the patch and provide feedback as to whether they have any
> problems.  I've done testing with the Pinnacle PCTV HD Pro USB 801e
> stick, but I don't have any other dib0700 based devices.
>
> Thanks to Patrick Boettcher for providing the firmware, sample code,
> and peer review of the first version of this patch.
>
> Regards,
>
> Devin
>
> --
> Devin J. Heitmueller
> http://www.devinheitmueller.com
> AIM: devinheitmueller
>


Hi,
    Thanks for your work, first of all. ¿Do you think this patch might
solve the problems that seem to be appeared since the new firmware is out
with the Hauppauge Nova-T 500, like random reboots, etc... (what's ths state
on this, anyway?) ?

I delayed the adoption of the new 1.20 firmware because of those problems,
because I didn't want to leave the machine in a complete unusable state...

Best regards,
  Eduard Huguet

[-- Attachment #1.2: Type: text/html, Size: 1977 bytes --]

[-- Attachment #2: Type: text/plain, Size: 150 bytes --]

_______________________________________________
linux-dvb mailing list
linux-dvb@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

^ permalink raw reply	[flat|nested] 8+ messages in thread
* [linux-dvb] dib0700 new i2c implementation
@ 2008-08-27  1:15 Devin Heitmueller
  0 siblings, 0 replies; 8+ messages in thread
From: Devin Heitmueller @ 2008-08-27  1:15 UTC (permalink / raw)
  To: linux-dvb

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

The attached patch implements the new dib0700 i2c API, which requires
v1.20 of the firmware.  It addresses some classes of i2c problems (in
particular the one I had where i2c reads were being sent onto the bus
as i2c write calls)

I would appreciate it if those with dib0700 based devices would try
out the patch and provide feedback as to whether they have any
problems.  I've done testing with the Pinnacle PCTV HD Pro USB 801e
stick, but I don't have any other dib0700 based devices.

Thanks to Patrick Boettcher for providing the firmware, sample code,
and peer review of the first version of this patch.

Regards,

Devin

-- 
Devin J. Heitmueller
http://www.devinheitmueller.com
AIM: devinheitmueller

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: dib0700_new_i2c_api.patch --]
[-- Type: text/x-diff; name=dib0700_new_i2c_api.patch, Size: 6487 bytes --]

Add support for new i2c API provided in firmware version 1.20

From: Devin Heitmueller <devin.heitmueller@gmail.com>

The Pinnacle PCTV HD Pro has an xc5000, which exposed a bug in the dib0700's
i2c implementation where it did not properly support a single i2c read request
(sending it as an i2c write request instead).  Version 1.20 of the firmware 
added support for a new i2c API which supported such requests.

This change defaults to fw 1.20 for all devices, as well as defaulting to
using the new i2c API.  For testing purposes, the maintainer can disable
use of the new i2c API (falling back to the legacy calls) by putting the
following into their frontend initialization:

struct dib0700_state *st = adap->dev->priv;
st->fw_use_legacy_i2c_api = 1;

Also note that the code expects i2c repeated start to be supported.  If the
i2c slave does not support repeated start, i2c messsages should have the
I2C_M_NOSTART flag set.

Thanks to Patrick Boettcher <patrick.boettcher@desy.de> for providing new
firmware fixing the issue as well as example i2c code utilizing the interface.

Signed-off-by: Devin Heitmueller <devin.heitmueller@gmail.com>

diff -r a4843e1304e6 linux/drivers/media/dvb/dvb-usb/dib0700.h
--- a/linux/drivers/media/dvb/dvb-usb/dib0700.h	Sun Aug 24 12:28:11 2008 -0300
+++ b/linux/drivers/media/dvb/dvb-usb/dib0700.h	Tue Aug 26 21:02:49 2008 -0400
@@ -31,6 +31,8 @@ extern int dvb_usb_dib0700_debug;
 	// 2 Byte: MPEG2 mode:  4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
 	// 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines)    4LSB(     "                "           )
 #define REQUEST_SET_RC       0x11
+#define REQUEST_NEW_I2C_READ 0x12
+#define REQUEST_NEW_I2C_WRITE 0x13
 #define REQUEST_GET_VERSION  0x15
 
 struct dib0700_state {
@@ -39,6 +41,7 @@ struct dib0700_state {
 	u8 rc_toggle;
 	u8 rc_counter;
 	u8 is_dib7000pc;
+	u8 fw_use_legacy_i2c_api;
 };
 
 extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val);
diff -r a4843e1304e6 linux/drivers/media/dvb/dvb-usb/dib0700_core.c
--- a/linux/drivers/media/dvb/dvb-usb/dib0700_core.c	Sun Aug 24 12:28:11 2008 -0300
+++ b/linux/drivers/media/dvb/dvb-usb/dib0700_core.c	Tue Aug 26 21:02:49 2008 -0400
@@ -82,9 +82,98 @@ int dib0700_set_gpio(struct dvb_usb_devi
 }
 
 /*
- * I2C master xfer function
+ * I2C master xfer function (supported in 1.20 firmware)
  */
-static int dib0700_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num)
+static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
+				int num)
+{
+	/* The new i2c firmware messages are more reliable and in particular
+	   properly support i2c read calls not preceded by a write */
+
+	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	uint8_t bus_mode = 1;  /* 0=eeprom bus, 1=frontend bus */
+	uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */
+	uint8_t en_start = 0;
+	uint8_t en_stop = 0;
+	uint8_t buf[255]; /* TBV: malloc ? */
+	int result, i;
+
+	/* Ensure nobody else hits the i2c bus while we're sending our
+	   sequence of messages, (such as the remote control thread) */
+	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+		return -EAGAIN;
+
+	for (i = 0; i < num; i++) {
+		if (i == 0) {
+			/* First message in the transaction */
+			en_start = 1;
+		} else if (!(msg[i].flags & I2C_M_NOSTART)) {
+			/* Device supports repeated-start */
+			en_start = 1;
+		} else {
+			/* Not the first packet and device doesn't support
+			   repeated start */
+			en_start = 0;
+		}
+		if (i == (num - 1)) {
+			/* Last message in the transaction */
+			en_stop = 1;
+		}
+
+		if (msg[i].flags & I2C_M_RD) {
+			/* Read request */
+			u16 index, value;
+			uint8_t i2c_dest;
+
+			i2c_dest = (msg[i].addr << 1);
+			value = ((en_start << 7) | (en_stop << 6) |
+				 (msg[i].len & 0x3F)) << 8 | i2c_dest;
+			/* I2C ctrl + FE bus; */
+			index = ((gen_mode<<6)&0xC0) | ((bus_mode<<4)&0x30);
+
+			result = usb_control_msg(d->udev,
+						 usb_rcvctrlpipe(d->udev, 0),
+						 REQUEST_NEW_I2C_READ,
+						 USB_TYPE_VENDOR | USB_DIR_IN,
+						 value, index, msg[i].buf,
+						 msg[i].len,
+						 USB_CTRL_GET_TIMEOUT);
+			if (result < 0) {
+				err("i2c read error (status = %d)\n", result);
+				break;
+			}
+		} else {
+			/* Write request */
+			buf[0] = REQUEST_NEW_I2C_WRITE;
+			buf[1] = (msg[i].addr << 1);
+			buf[2] = (en_start << 7) | (en_stop << 6) |
+				(msg[i].len & 0x3F);
+			/* I2C ctrl + FE bus; */
+			buf[3] = ((gen_mode<<6)&0xC0) | ((bus_mode<<4)&0x30);
+			/* The Actual i2c payload */
+			memcpy(&buf[4], msg[i].buf, msg[i].len);
+
+			result = usb_control_msg(d->udev,
+						 usb_sndctrlpipe(d->udev, 0),
+						 REQUEST_NEW_I2C_WRITE,
+						 USB_TYPE_VENDOR | USB_DIR_OUT,
+						 0, 0, buf, msg[i].len + 4,
+						 USB_CTRL_GET_TIMEOUT);
+			if (result < 0) {
+				err("i2c write error (status = %d)\n", result);
+				break;
+			}
+		}
+	}
+	mutex_unlock(&d->i2c_mutex);
+	return i;
+}
+
+/*
+ * I2C master xfer function (pre-1.20 firmware)
+ */
+static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
+				   struct i2c_msg *msg, int num)
 {
 	struct dvb_usb_device *d = i2c_get_adapdata(adap);
 	int i,len;
@@ -122,6 +211,21 @@ static int dib0700_i2c_xfer(struct i2c_a
 
 	mutex_unlock(&d->i2c_mutex);
 	return i;
+}
+
+static int dib0700_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
+			    int num)
+{
+	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	struct dib0700_state *st = d->priv;
+
+	if (st->fw_use_legacy_i2c_api == 1) {
+		/* Use legacy calls */
+		return dib0700_i2c_xfer_legacy(adap, msg, num);
+	} else {
+		/* User running at least fw 1.20 */
+		return dib0700_i2c_xfer_new(adap, msg, num);
+	}
 }
 
 static u32 dib0700_i2c_func(struct i2c_adapter *adapter)
diff -r a4843e1304e6 linux/drivers/media/dvb/dvb-usb/dib0700_devices.c
--- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c	Sun Aug 24 12:28:11 2008 -0300
+++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c	Tue Aug 26 21:02:49 2008 -0400
@@ -1125,7 +1125,7 @@ MODULE_DEVICE_TABLE(usb, dib0700_usb_id_
 #define DIB0700_DEFAULT_DEVICE_PROPERTIES \
 	.caps              = DVB_USB_IS_AN_I2C_ADAPTER, \
 	.usb_ctrl          = DEVICE_SPECIFIC, \
-	.firmware          = "dvb-usb-dib0700-1.10.fw", \
+	.firmware          = "dvb-usb-dib0700-1.20.fw", \
 	.download_firmware = dib0700_download_firmware, \
 	.no_reconnect      = 1, \
 	.size_of_priv      = sizeof(struct dib0700_state), \

[-- Attachment #3: Type: text/plain, Size: 150 bytes --]

_______________________________________________
linux-dvb mailing list
linux-dvb@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

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

end of thread, other threads:[~2008-08-27 14:22 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-27  7:10 [linux-dvb] dib0700 new i2c implementation Eduard Huguet
2008-08-27  8:24 ` Patrick Boettcher
2008-08-27  9:12   ` Eduard Huguet
2008-08-27 13:49     ` Devin Heitmueller
2008-08-27 14:02       ` Nicolas Will
2008-08-27 14:21       ` Eduard Huguet
2008-08-27  8:25 ` Nicolas Will
  -- strict thread matches above, loose matches on Subject: below --
2008-08-27  1:15 Devin Heitmueller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox