#include <asm/io.h>
+/* 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))
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;
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);
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;
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
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"
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"