From: Tony Lindgren Date: Wed, 28 Feb 2007 11:39:28 +0000 (-0800) Subject: i2c: Merge omap i2c drivers from omap-historic X-Git-Tag: v2.6.21-omap1~32^2~11 X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8788a49b2b426a492c96e11f186e65389699c5ee;p=pandora-kernel.git i2c: Merge omap i2c drivers from omap-historic Merge omap i2c drivers from omap-historic Signed-off-by: Tony Lindgren --- diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 11935f66fcd8..13721f2afaa5 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -6,6 +6,7 @@ menu "I2C support" config I2C tristate "I2C support" + default y if MACH_OMAP_H3 || MACH_OMAP_OSK ---help--- I2C (pronounce: I-square-C) is a slow serial bus protocol used in many micro controller applications and developed by Philips. SMBus, diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 290b54018354..90402dffea0e 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o obj-$(CONFIG_SCx200_ACB) += scx200_acb.o obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o +obj-$(CONFIG_I2C_OMAP) += i2c-omap.o ifeq ($(CONFIG_I2C_DEBUG_BUS),y) EXTRA_CFLAGS += -DDEBUG diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index bcd8367cede1..5308d672255e 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -36,6 +36,10 @@ #include +/* Hack to enable zero length transfers and smbus quick until clean fix + is available */ +#define OMAP_HACK + /* timeout waiting for the controller to respond */ #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) @@ -285,12 +289,16 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) { struct omap_i2c_dev *dev = i2c_get_adapdata(adap); +#ifdef OMAP_HACK + u8 zero_byte = 0; +#endif int r; u16 w; dev_dbg(dev->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n", msg->addr, msg->len, msg->flags, stop); +#ifndef OMAP_HACK if (msg->len == 0) return -EINVAL; @@ -300,6 +308,27 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, dev->buf = msg->buf; dev->buf_len = msg->len; +#else + + omap_i2c_write_reg(dev, OMAP_I2C_SA_REG, msg->addr); + /* REVISIT: Remove this hack when we can get I2C chips from board-*.c + * files + * Sigh, seems we can't do zero length transactions. Thus, we + * can't probe for devices w/o actually sending/receiving at least + * a single byte. So we'll set count to 1 for the zero length + * transaction case and hope we don't cause grief for some + * arbitrary device due to random byte write/read during + * probes. + */ + if (msg->len == 0) { + dev->buf = &zero_byte; + dev->buf_len = 1; + } else { + dev->buf = msg->buf; + dev->buf_len = msg->len; + } +#endif + omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len); init_completion(&dev->cmd_complete); @@ -314,8 +343,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, w |= OMAP_I2C_CON_STP; omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); - r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, - OMAP_I2C_TIMEOUT); + r = wait_for_completion_timeout(&dev->cmd_complete, + OMAP_I2C_TIMEOUT); dev->buf_len = 0; if (r < 0) return r; @@ -383,7 +412,11 @@ out: static u32 omap_i2c_func(struct i2c_adapter *adap) { +#ifndef OMAP_HACK return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); +#else + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +#endif } static inline void @@ -478,9 +511,14 @@ omap_i2c_isr(int this_irq, void *dev_id) if (dev->buf_len) { *dev->buf++ = w; dev->buf_len--; - if (dev->buf_len) { - *dev->buf++ = w >> 8; - dev->buf_len--; + /* + * Data reg in 2430 is 8 bit wide, + */ + if (!cpu_is_omap2430()) { + if (dev->buf_len) { + *dev->buf++ = w >> 8; + dev->buf_len--; + } } } else dev_err(dev->dev, "RRDY IRQ while no data" @@ -493,9 +531,14 @@ omap_i2c_isr(int this_irq, void *dev_id) if (dev->buf_len) { w = *dev->buf++; dev->buf_len--; - if (dev->buf_len) { - w |= *dev->buf++ << 8; - dev->buf_len--; + /* + * Data reg in 2430 is 8 bit wide, + */ + if (!cpu_is_omap2430()) { + if (dev->buf_len) { + w |= *dev->buf++ << 8; + dev->buf_len--; + } } } else dev_err(dev->dev, "XRDY IRQ while no" Reading git-diff-tree failed