On Thu, 2008-05-22 at 17:25 -0700, Michael wrote:
> > On Wed, 2008-05-21 at 17:09 -0700, Michael wrote:
> > > >
> >
> > Could you post the output from /var/log/messages instead of from dmesg?
> > dmesg has a finite amount of space, and the beginning of the
> > initialization was lost. The beginning's the part I really need to see,
> > where the i2c bus is being initialized and reset and the EEPROM is being
> > addressed and read.
> >
> Here you go.
>
> http://h1.ripway.com/hendrick/log.txt
>
> EEPROM is still there.
>From the I2C debug in your latest log, it's highly likely there is a
device other than the EEPROM that is stuck holding the SDA line low.
Also, I see in your latest log:
May 22 20:16:46 localhost kernel: cx18-0 info: GPIO initial dir:
0000ffff/0000ffff out: 00000000/00000000
Which is a dump of the GPIO line state before the cx18 driver messes
with them. This matches my card at boot up (with debug=3 in
modprobe.conf):
May 24 07:03:01 palomino kernel: cx18-0 info: GPIO initial dir:
0000ffff/0000ffff out: 00000000/00000000
For me, after one modprobe -r cx18; modprobe cx18 debug=3 sequence, I have:
May 24 07:05:35 palomino kernel: cx18-0 info: GPIO initial dir:
0000cffe/0000ffff out: 00003001/00000000
reflecting that the initial cx18 driver load raised some GPIO lines and
left them raised.
Comments, in cx18-gpio.c indicate that these are the lines that reset
the Conexant CX24227, Zilog Z8F0811, and Cirrus Logic CS5345 - all
devices that could be stuck holding the SDA line of the I2C bus low.
Attached is a patch to actively reset these I2C slave chips via GPIO
upon modprobe, before the EEPROM is interrogated. The patch is not
perfect, but it should be OK for systems with only one HVR-1600 card
installed. It does no harm to my setup. The patch can be applied with
or without the previous two patches I provided to you.
Let me know if this enables the EEPROM to be detected reliably.
Regards,
Andy
diff -r 9d04bba82511 linux/drivers/media/video/cx18/cx18-cards.c
--- a/linux/drivers/media/video/cx18/cx18-cards.c Wed May 14 23:14:04 2008 +0000
+++ b/linux/drivers/media/video/cx18/cx18-cards.c Sat May 24 08:50:08 2008 -0400
@@ -81,6 +81,10 @@ static const struct cx18_card cx18_card_
},
.gpio_init.initial_value = 0x3001,
.gpio_init.direction = 0x3001,
+ .gpio_i2c_slave_reset.mask = 0x3001,
+ .gpio_i2c_slave_reset.msecs_asserted = 10,
+ .gpio_i2c_slave_reset.msecs_recovery = 40,
+ .gpio_i2c_slave_reset.assert_level = 0,
.i2c = &cx18_i2c_std,
};
@@ -121,6 +125,10 @@ static const struct cx18_card cx18_card_
},
.gpio_init.initial_value = 0x3001,
.gpio_init.direction = 0x3001,
+ .gpio_i2c_slave_reset.mask = 0x3001,
+ .gpio_i2c_slave_reset.msecs_asserted = 10,
+ .gpio_i2c_slave_reset.msecs_recovery = 40,
+ .gpio_i2c_slave_reset.assert_level = 0,
.i2c = &cx18_i2c_std,
};
diff -r 9d04bba82511 linux/drivers/media/video/cx18/cx18-cards.h
--- a/linux/drivers/media/video/cx18/cx18-cards.h Wed May 14 23:14:04 2008 +0000
+++ b/linux/drivers/media/video/cx18/cx18-cards.h Sat May 24 08:50:08 2008 -0400
@@ -118,6 +118,13 @@ struct cx18_gpio_init { /* set initial G
u32 initial_value;
};
+struct cx18_gpio_i2c_slave_reset {
+ u32 mask; /* mask of GPIO outputs that reset i2c chips */
+ int msecs_asserted; /* time period reset must remain asserted */
+ int msecs_recovery; /* time after deassert for chips to be ready */
+ int assert_level; /* 0 = asserted when low, 1 = asserted when high */
+};
+
struct cx18_card_tuner {
v4l2_std_id std; /* standard for which the tuner is suitable */
int tuner; /* tuner ID (from tuner.h) */
@@ -154,7 +161,8 @@ struct cx18_card {
/* GPIO card-specific settings */
u8 xceive_pin; /* XCeive tuner GPIO reset pin */
- struct cx18_gpio_init gpio_init;
+ struct cx18_gpio_init gpio_init;
+ struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset;
struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
struct cx18_card_tuner_i2c *i2c;
diff -r 9d04bba82511 linux/drivers/media/video/cx18/cx18-gpio.c
--- a/linux/drivers/media/video/cx18/cx18-gpio.c Wed May 14 23:14:04 2008 +0000
+++ b/linux/drivers/media/video/cx18/cx18-gpio.c Sat May 24 08:50:08 2008 -0400
@@ -57,6 +57,35 @@ static void gpio_write(struct cx18 *cx)
CX18_REG_GPIO_OUT2);
}
+static void cx18_gpio_i2c_slave_reset(struct cx18 *cx)
+{
+ /*
+ * FIXME - using file scope gpio_val and gpio_dir will not properly
+ * support probe and reset of multiple cards
+ */
+ const struct cx18_gpio_i2c_slave_reset *p = &cx->card->gpio_i2c_slave_reset;
+
+ if (p->mask ==0)
+ return;
+
+ /* Assuming that mask is a subset of the bits in gpio_dir */
+ if (p->assert_level == 0)
+ gpio_val &= ~(p->mask);
+ else
+ gpio_val |= p->mask;
+
+ gpio_write(cx);
+ schedule_timeout_interruptible(msecs_to_jiffies(p->msecs_asserted));
+
+ if (p->assert_level == 0)
+ gpio_val |= p->mask;
+ else
+ gpio_val &= ~(p->mask);
+
+ gpio_write(cx);
+ schedule_timeout_interruptible(msecs_to_jiffies(p->msecs_recovery));
+}
+
void cx18_gpio_init(struct cx18 *cx)
{
gpio_dir = cx->card->gpio_init.direction;
@@ -73,6 +102,8 @@ void cx18_gpio_init(struct cx18 *cx)
read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2));
gpio_write(cx);
+
+ cx18_gpio_i2c_slave_reset(cx);
}
/* Xceive tuner reset function */
_______________________________________________
ivtv-users mailing list
[email protected]
http://ivtvdriver.org/mailman/listinfo/ivtv-users