diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c index 800dae6..e297249 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c @@ -607,7 +607,9 @@ void __init bcm2708_init(void) bcm_register_device(&bcm2708_bsc0_device); bcm_register_device(&bcm2708_bsc1_device); +#if defined(CONFIG_GPIO_MCP23S08) || defined(CONFIG_GPIO_MCP23S08_MODULE) i2c_register_board_info(0, pi_i2c_devs,ARRAY_SIZE(pi_i2c_devs)); +#endif #ifdef CONFIG_BCM2708_VCMEM { diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c index 5ec460f..bef45fa 100644 --- a/drivers/i2c/busses/i2c-bcm2708.c +++ b/drivers/i2c/busses/i2c-bcm2708.c @@ -141,11 +141,18 @@ static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi) bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]); } +/* + * When Transmitting: Make SDA valid quarter of a cycle after the falling + * edge of SCL. + * When Receiving: Sample SDA Quarter of a cycle after the rising edge of + * SCL. + */ static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi) { unsigned long bus_hz; u32 cdiv; u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1; + u32 cdel; bus_hz = clk_get_rate(bi->clk); cdiv = bus_hz / I2C_CLOCK_HZ; @@ -159,6 +166,9 @@ static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi) bcm2708_wr(bi, BSC_A, bi->msg->addr); bcm2708_wr(bi, BSC_DLEN, bi->msg->len); bcm2708_wr(bi, BSC_C, c); + cdel = (cdiv / 4) & 0xffff; + cdel = cdel << 16 | cdel; + bcm2708_wr(bi, BSC_DEL, cdel); } static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id)