/* * Prepare controller for a transaction and call omap_i2c_xfer_msg * to do the work during IRQ processing. */ static int omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { struct omap_i2c_dev *dev = i2c_get_adapdata(adap); int i; int r; u16 val; if (dev == NULL) return -EINVAL; r = omap_i2c_hwspinlock_lock(dev); /* To-Do: if we are unable to acquire the lock, we must try to recover somehow */ if (r != 0) return r; omap_i2c_unidle(dev); r = omap_i2c_wait_for_bb(dev); /* If timeout, try to again check after soft reset of I2C block */ if (WARN_ON(r == -ETIMEDOUT)) { /* Provide a permanent clock to recover the peripheral */ val = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG); val |= (OMAP_I2C_SYSTEST_ST_EN | OMAP_I2C_SYSTEST_FREE | (2 << OMAP_I2C_SYSTEST_TMODE_SHIFT)); omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, val); msleep(1); omap_i2c_init(dev); r = omap_i2c_wait_for_bb(dev); } if (r < 0) goto out; /* * When waiting for completion of a i2c transfer, we need to * set a wake up latency constraint for the MPU. This is to * ensure quick enough wakeup from idle, when transfer * completes. */ if (dev->pm_qos) pm_qos_update_request(dev->pm_qos, dev->latency); for (i = 0; i < num; i++) { r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1))); if (r != 0) break; } if (dev->pm_qos) pm_qos_update_request(dev->pm_qos, PM_QOS_DEFAULT_VALUE); if (r == 0) r = num; omap_i2c_wait_for_bb(dev); out: omap_i2c_idle(dev); omap_i2c_hwspinlock_unlock(dev); return r; }
static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, uint32_t flags) { struct dma_async_tx_descriptor *desc; struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap); if (msg->flags & I2C_M_RD) { i2c->dma_read = 1; i2c->addr_data = (msg->addr << 1) | I2C_SMBUS_READ; /* * SELECT command. */ /* Queue the PIO register write transfer. */ i2c->pio_data[0] = MXS_CMD_I2C_SELECT; desc = dmaengine_prep_slave_sg(i2c->dmach, (struct scatterlist *)&i2c->pio_data[0], 1, DMA_TRANS_NONE, 0); if (!desc) { dev_err(i2c->dev, "Failed to get PIO reg. write descriptor.\n"); goto select_init_pio_fail; } /* Queue the DMA data transfer. */ sg_init_one(&i2c->sg_io[0], &i2c->addr_data, 1); dma_map_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE); desc = dmaengine_prep_slave_sg(i2c->dmach, &i2c->sg_io[0], 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { dev_err(i2c->dev, "Failed to get DMA data write descriptor.\n"); goto select_init_dma_fail; } /* * READ command. */ /* Queue the PIO register write transfer. */ i2c->pio_data[1] = flags | MXS_CMD_I2C_READ | MXS_I2C_CTRL0_XFER_COUNT(msg->len); desc = dmaengine_prep_slave_sg(i2c->dmach, (struct scatterlist *)&i2c->pio_data[1], 1, DMA_TRANS_NONE, DMA_PREP_INTERRUPT); if (!desc) { dev_err(i2c->dev, "Failed to get PIO reg. write descriptor.\n"); goto select_init_dma_fail; } /* Queue the DMA data transfer. */ sg_init_one(&i2c->sg_io[1], msg->buf, msg->len); dma_map_sg(i2c->dev, &i2c->sg_io[1], 1, DMA_FROM_DEVICE); desc = dmaengine_prep_slave_sg(i2c->dmach, &i2c->sg_io[1], 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { dev_err(i2c->dev, "Failed to get DMA data write descriptor.\n"); goto read_init_dma_fail; } } else { i2c->dma_read = 0; i2c->addr_data = (msg->addr << 1) | I2C_SMBUS_WRITE; /* * WRITE command. */ /* Queue the PIO register write transfer. */ i2c->pio_data[0] = flags | MXS_CMD_I2C_WRITE | MXS_I2C_CTRL0_XFER_COUNT(msg->len + 1); desc = dmaengine_prep_slave_sg(i2c->dmach, (struct scatterlist *)&i2c->pio_data[0], 1, DMA_TRANS_NONE, 0); if (!desc) { dev_err(i2c->dev, "Failed to get PIO reg. write descriptor.\n"); goto write_init_pio_fail; } /* Queue the DMA data transfer. */ sg_init_table(i2c->sg_io, 2); sg_set_buf(&i2c->sg_io[0], &i2c->addr_data, 1); sg_set_buf(&i2c->sg_io[1], msg->buf, msg->len); dma_map_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE); desc = dmaengine_prep_slave_sg(i2c->dmach, i2c->sg_io, 2, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { dev_err(i2c->dev, "Failed to get DMA data write descriptor.\n"); goto write_init_dma_fail; } } /* * The last descriptor must have this callback, * to finish the DMA transaction. */ desc->callback = mxs_i2c_dma_irq_callback; desc->callback_param = i2c; /* Start the transfer. */ dmaengine_submit(desc); dma_async_issue_pending(i2c->dmach); return 0; /* Read failpath. */ read_init_dma_fail: dma_unmap_sg(i2c->dev, &i2c->sg_io[1], 1, DMA_FROM_DEVICE); select_init_dma_fail: dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE); select_init_pio_fail: dmaengine_terminate_all(i2c->dmach); return -EINVAL; /* Write failpath. */ write_init_dma_fail: dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE); write_init_pio_fail: dmaengine_terminate_all(i2c->dmach); return -EINVAL; }
/* Return negative errno on error. */ static s32 i801_access(struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data *data) { int hwpec; int block = 0; int ret, xact = 0; struct i801_priv *priv = i2c_get_adapdata(adap); hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK && size != I2C_SMBUS_I2C_BLOCK_DATA; switch (size) { case I2C_SMBUS_QUICK: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD(priv)); xact = I801_QUICK; break; case I2C_SMBUS_BYTE: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD(priv)); if (read_write == I2C_SMBUS_WRITE) outb_p(command, SMBHSTCMD(priv)); xact = I801_BYTE; break; case I2C_SMBUS_BYTE_DATA: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD(priv)); outb_p(command, SMBHSTCMD(priv)); if (read_write == I2C_SMBUS_WRITE) outb_p(data->byte, SMBHSTDAT0(priv)); xact = I801_BYTE_DATA; break; case I2C_SMBUS_WORD_DATA: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD(priv)); outb_p(command, SMBHSTCMD(priv)); if (read_write == I2C_SMBUS_WRITE) { outb_p(data->word & 0xff, SMBHSTDAT0(priv)); outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1(priv)); } xact = I801_WORD_DATA; break; case I2C_SMBUS_BLOCK_DATA: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD(priv)); outb_p(command, SMBHSTCMD(priv)); block = 1; break; case I2C_SMBUS_I2C_BLOCK_DATA: /* NB: page 240 of ICH5 datasheet shows that the R/#W * bit should be cleared here, even when reading */ outb_p((addr & 0x7f) << 1, SMBHSTADD(priv)); if (read_write == I2C_SMBUS_READ) { /* NB: page 240 of ICH5 datasheet also shows * that DATA1 is the cmd field when reading */ outb_p(command, SMBHSTDAT1(priv)); } else outb_p(command, SMBHSTCMD(priv)); block = 1; break; default: dev_err(&priv->pci_dev->dev, "Unsupported transaction %d\n", size); return -EOPNOTSUPP; }
/** * ismt_access() - process an SMBus command * @adap: the i2c host adapter * @addr: address of the i2c/SMBus target * @flags: command options * @read_write: read from or write to device * @command: the i2c/SMBus command to issue * @size: SMBus transaction type * @data: read/write data buffer */ static int ismt_access(struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data *data) { int ret; unsigned long time_left; dma_addr_t dma_addr = 0; /* address of the data buffer */ u8 dma_size = 0; enum dma_data_direction dma_direction = 0; struct ismt_desc *desc; struct ismt_priv *priv = i2c_get_adapdata(adap); struct device *dev = &priv->pci_dev->dev; desc = &priv->hw[priv->head]; /* Initialize the DMA buffer */ memset(priv->dma_buffer, 0, sizeof(priv->dma_buffer)); /* Initialize the descriptor */ memset(desc, 0, sizeof(struct ismt_desc)); desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(addr, read_write); /* Initialize common control bits */ if (likely(pci_dev_msi_enabled(priv->pci_dev))) desc->control = ISMT_DESC_INT | ISMT_DESC_FAIR; else desc->control = ISMT_DESC_FAIR; if ((flags & I2C_CLIENT_PEC) && (size != I2C_SMBUS_QUICK) && (size != I2C_SMBUS_I2C_BLOCK_DATA)) desc->control |= ISMT_DESC_PEC; switch (size) { case I2C_SMBUS_QUICK: dev_dbg(dev, "I2C_SMBUS_QUICK\n"); break; case I2C_SMBUS_BYTE: if (read_write == I2C_SMBUS_WRITE) { /* * Send Byte * The command field contains the write data */ dev_dbg(dev, "I2C_SMBUS_BYTE: WRITE\n"); desc->control |= ISMT_DESC_CWRL; desc->wr_len_cmd = command; } else { /* Receive Byte */ dev_dbg(dev, "I2C_SMBUS_BYTE: READ\n"); dma_size = 1; dma_direction = DMA_FROM_DEVICE; desc->rd_len = 1; } break; case I2C_SMBUS_BYTE_DATA: if (read_write == I2C_SMBUS_WRITE) { /* * Write Byte * Command plus 1 data byte */ dev_dbg(dev, "I2C_SMBUS_BYTE_DATA: WRITE\n"); desc->wr_len_cmd = 2; dma_size = 2; dma_direction = DMA_TO_DEVICE; priv->dma_buffer[0] = command; priv->dma_buffer[1] = data->byte; } else { /* Read Byte */ dev_dbg(dev, "I2C_SMBUS_BYTE_DATA: READ\n"); desc->control |= ISMT_DESC_CWRL; desc->wr_len_cmd = command; desc->rd_len = 1; dma_size = 1; dma_direction = DMA_FROM_DEVICE; } break; case I2C_SMBUS_WORD_DATA: if (read_write == I2C_SMBUS_WRITE) { /* Write Word */ dev_dbg(dev, "I2C_SMBUS_WORD_DATA: WRITE\n"); desc->wr_len_cmd = 3; dma_size = 3; dma_direction = DMA_TO_DEVICE; priv->dma_buffer[0] = command; priv->dma_buffer[1] = data->word & 0xff; priv->dma_buffer[2] = data->word >> 8; } else {
static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg, int last) { struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap); u16 val, tcr_val; int ret, wait_result; int xfer_len = 0; if (!(pmsg->flags & I2C_M_NOSTART)) { ret = wmt_i2c_wait_bus_not_busy(i2c_dev); if (ret < 0) return ret; } if (pmsg->len == 0) { /* * We still need to run through the while (..) once, so * start at -1 and break out early from the loop */ xfer_len = -1; writew(0, i2c_dev->base + REG_CDR); } else { writew(pmsg->buf[0] & 0xFF, i2c_dev->base + REG_CDR); } if (!(pmsg->flags & I2C_M_NOSTART)) { val = readw(i2c_dev->base + REG_CR); val &= ~CR_TX_END; writew(val, i2c_dev->base + REG_CR); val = readw(i2c_dev->base + REG_CR); val |= CR_CPU_RDY; writew(val, i2c_dev->base + REG_CR); } reinit_completion(&i2c_dev->complete); if (i2c_dev->mode == I2C_MODE_STANDARD) tcr_val = TCR_STANDARD_MODE; else tcr_val = TCR_FAST_MODE; tcr_val |= (TCR_MASTER_WRITE | (pmsg->addr & TCR_SLAVE_ADDR_MASK)); writew(tcr_val, i2c_dev->base + REG_TCR); if (pmsg->flags & I2C_M_NOSTART) { val = readw(i2c_dev->base + REG_CR); val |= CR_CPU_RDY; writew(val, i2c_dev->base + REG_CR); } while (xfer_len < pmsg->len) { wait_result = wait_for_completion_timeout(&i2c_dev->complete, 500 * HZ / 1000); if (wait_result == 0) return -ETIMEDOUT; ret = wmt_check_status(i2c_dev); if (ret) return ret; xfer_len++; val = readw(i2c_dev->base + REG_CSR); if ((val & CSR_RCV_ACK_MASK) == CSR_RCV_NOT_ACK) { dev_dbg(i2c_dev->dev, "write RCV NACK error\n"); return -EIO; } if (pmsg->len == 0) { val = CR_TX_END | CR_CPU_RDY | CR_ENABLE; writew(val, i2c_dev->base + REG_CR); break; } if (xfer_len == pmsg->len) { if (last != 1) writew(CR_ENABLE, i2c_dev->base + REG_CR); } else { writew(pmsg->buf[xfer_len] & 0xFF, i2c_dev->base + REG_CDR); writew(CR_CPU_RDY | CR_ENABLE, i2c_dev->base + REG_CR); } } return 0; }
/* * SMBUS-type transfer entrypoint */ static s32 smu_smbus_xfer( struct i2c_adapter* adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data* data) { struct smu_iface *iface = i2c_get_adapdata(adap); struct smu_i2c_cmd cmd; int rc = 0; int read = (read_write == I2C_SMBUS_READ); cmd.info.bus = iface->busid; cmd.info.devaddr = (addr << 1) | (read ? 0x01 : 0x00); /* Prepare datas & select mode */ switch (size) { case I2C_SMBUS_QUICK: cmd.info.type = SMU_I2C_TRANSFER_SIMPLE; cmd.info.datalen = 0; break; case I2C_SMBUS_BYTE: cmd.info.type = SMU_I2C_TRANSFER_SIMPLE; cmd.info.datalen = 1; if (!read) cmd.info.data[0] = data->byte; break; case I2C_SMBUS_BYTE_DATA: cmd.info.type = SMU_I2C_TRANSFER_STDSUB; cmd.info.datalen = 1; cmd.info.sublen = 1; cmd.info.subaddr[0] = command; cmd.info.subaddr[1] = 0; cmd.info.subaddr[2] = 0; if (!read) cmd.info.data[0] = data->byte; break; case I2C_SMBUS_WORD_DATA: cmd.info.type = SMU_I2C_TRANSFER_STDSUB; cmd.info.datalen = 2; cmd.info.sublen = 1; cmd.info.subaddr[0] = command; cmd.info.subaddr[1] = 0; cmd.info.subaddr[2] = 0; if (!read) { cmd.info.data[0] = data->byte & 0xff; cmd.info.data[1] = (data->byte >> 8) & 0xff; } break; /* Note that these are broken vs. the expected smbus API where * on reads, the lenght is actually returned from the function, * but I think the current API makes no sense and I don't want * any driver that I haven't verified for correctness to go * anywhere near a pmac i2c bus anyway ... */ case I2C_SMBUS_BLOCK_DATA: cmd.info.type = SMU_I2C_TRANSFER_STDSUB; cmd.info.datalen = data->block[0] + 1; if (cmd.info.datalen > 6) return -EINVAL; if (!read) memcpy(cmd.info.data, data->block, cmd.info.datalen); cmd.info.sublen = 1; cmd.info.subaddr[0] = command; cmd.info.subaddr[1] = 0; cmd.info.subaddr[2] = 0; break; case I2C_SMBUS_I2C_BLOCK_DATA: cmd.info.type = SMU_I2C_TRANSFER_STDSUB; cmd.info.datalen = data->block[0]; if (cmd.info.datalen > 7) return -EINVAL; if (!read) memcpy(cmd.info.data, &data->block[1], cmd.info.datalen); cmd.info.sublen = 1; cmd.info.subaddr[0] = command; cmd.info.subaddr[1] = 0; cmd.info.subaddr[2] = 0; break; default: return -EINVAL; }
/* Return negative errno on error. */ static s32 mcuio_simple_smbus_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data) { struct mcuio_i2c_dev *i2cd = i2c_get_adapdata(adap); s32 ret; u32 ilen = 0, olen = 0; int len; if (!i2cd) { WARN_ON(1); return -ENODEV; } switch (size) { case I2C_SMBUS_QUICK: dev_dbg(&adap->dev, "smbus quick - addr 0x%02x\n", addr); ret = 0; break; case I2C_SMBUS_BYTE: if (read_write == I2C_SMBUS_WRITE) { dev_dbg(&adap->dev, "smbus byte - wr addr 0x%02x, " "write 0x%02x.\n", addr, command); olen = 1; i2cd->buf[0] = command; } else { dev_dbg(&adap->dev, "smbus byte - rd addr 0x%02x\n", addr); ilen = 1; } ret = 0; break; case I2C_SMBUS_BYTE_DATA: if (read_write == I2C_SMBUS_WRITE) { olen = 2; i2cd->buf[0] = command; i2cd->buf[1] = data->byte; dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " "write 0x%02x at 0x%02x.\n", addr, data->byte, command); } else { olen = 1; ilen = 1; i2cd->buf[0] = command; dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " "read at 0x%02x.\n", addr, command); } ret = 0; break; case I2C_SMBUS_WORD_DATA: if (read_write == I2C_SMBUS_WRITE) { olen = 3; i2cd->buf[0] = command; i2cd->buf[1] = data->word & (u16)0x00ff; i2cd->buf[2] = data->word >> 8; dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, " "write 0x%04x at 0x%02x.\n", addr, data->word, command); } else {
/* * Low level master read/write transaction. */ 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); 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); if (msg->len == 0) return -EINVAL; omap_i2c_write_reg(dev, OMAP_I2C_SA_REG, msg->addr); /* REVISIT: Could the STB bit of I2C_CON be used with probing? */ dev->buf = msg->buf; dev->buf_len = msg->len; omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len); /* Clear the FIFO Buffers */ w = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG); w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR; omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, w); init_completion(&dev->cmd_complete); dev->cmd_err = 0; w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT; /* High speed configuration */ if (dev->speed > 400) w |= OMAP_I2C_CON_OPMODE_HS; if (msg->flags & I2C_M_TEN) w |= OMAP_I2C_CON_XA; if (!(msg->flags & I2C_M_RD)) w |= OMAP_I2C_CON_TRX; if (!dev->b_hw && stop) w |= OMAP_I2C_CON_STP; omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); /* * Don't write stt and stp together on some hardware. */ if (dev->b_hw && stop) { unsigned long delay = jiffies + OMAP_I2C_TIMEOUT; u16 con = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG); while (con & OMAP_I2C_CON_STT) { con = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG); /* Let the user know if i2c is in a bad state */ if (time_after(jiffies, delay)) { dev_err(dev->dev, "controller timed out " "waiting for start condition to finish\n"); return -ETIMEDOUT; } cpu_relax(); } /* FIXME: should consider ARDY value before writing to I2C_CON */ w |= OMAP_I2C_CON_STP; w &= ~OMAP_I2C_CON_STT; omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); } /* * REVISIT: We should abort the transfer on signals, but the bus goes * into arbitration and we're currently unable to recover from it. */ /* * REVISIT: Add a mpu wake-up latency constraint to let us wake * quickly enough for i2c transfers to work properly. Should change * the code to use a latency constraint function passed from pdata. */ omap_pm_set_max_mpu_wakeup_lat(dev->dev, 500); r = wait_for_completion_timeout(&dev->cmd_complete, OMAP_I2C_TIMEOUT); omap_pm_set_max_mpu_wakeup_lat(dev->dev, -1); dev->buf_len = 0; if (r < 0) return r; if (r == 0) { dev_err(dev->dev, "controller timed out\n"); omap_i2c_init(dev); return -ETIMEDOUT; } if (likely(!dev->cmd_err)) return 0; /* We have an error */ if (dev->cmd_err & (OMAP_I2C_STAT_AL | OMAP_I2C_STAT_ROVR | OMAP_I2C_STAT_XUDF)) { omap_i2c_init(dev); return -EIO; } if (dev->cmd_err & OMAP_I2C_STAT_NACK) { if (msg->flags & I2C_M_IGNORE_NAK) return 0; if (stop) { w = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG); w |= OMAP_I2C_CON_STP; omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); } return -EREMOTEIO; } return -EIO; }
static int saa716x_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) { struct saa716x_i2c *i2c = i2c_get_adapdata(adapter); struct saa716x_dev *saa716x = i2c->saa716x; u32 DEV = SAA716x_I2C_BUS(i2c->i2c_dev); int i, j, err = 0; int t; u32 data; mutex_lock(&i2c->i2c_lock); for (t = 0; t < 3; t++) { for (i = 0; i < num; i++) { /* first write START width I2C address */ data = (msgs[i].addr << 1) | I2C_START_BIT; if (msgs[i].flags & I2C_M_RD) data |= 1; err = saa716x_i2c_send(i2c, DEV, data); if (err < 0) { dprintk(SAA716x_ERROR, 1, "Address write failed"); err = -EIO; goto retry; } /* now read or write the data */ for (j = 0; j < msgs[i].len; j++) { if (msgs[i].flags & I2C_M_RD) data = 0x00; /* dummy write for reading */ else { data = msgs[i].buf[j]; } if (i == (num - 1) && j == (msgs[i].len - 1)) data |= I2C_STOP_BIT; err = saa716x_i2c_send(i2c, DEV, data); if (err < 0) { dprintk(SAA716x_ERROR, 1, "Data send failed"); err = -EIO; goto retry; } if (msgs[i].flags & I2C_M_RD) { err = saa716x_i2c_recv(i2c, DEV, &data); if (err < 0) { dprintk(SAA716x_ERROR, 1, "Data receive failed"); err = -EIO; goto retry; } msgs[i].buf[j] = data; } } } break; retry: dprintk(SAA716x_INFO, 1, "Error in Transfer, try %d", t); err = saa716x_i2c_hwinit(i2c, DEV); if (err < 0) { dprintk(SAA716x_ERROR, 1, "Error Reinit"); err = -EIO; goto bail_out; } } mutex_unlock(&i2c->i2c_lock); if (t == 3) return -EIO; else return num; bail_out: dprintk(SAA716x_ERROR, 1, "ERROR: Bailing out <%d>", err); mutex_unlock(&i2c->i2c_lock); return err; }
/* * Low level master read/write transaction. This function is called * from i2c_davinci_xfer. */ static int i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) { struct i2c_davinci_device *dev = i2c_get_adapdata(adap); u8 zero_byte = 0; u32 flag = 0, stat = 0; int i; DEB1("addr: 0x%04x, len: %d, flags: 0x%x, stop: %d", msg->addr, msg->len, msg->flags, stop); /* Introduce a 100musec delay. Required for Davinci EVM board only */ if (cpu_is_davinci_dm644x()) udelay(100); /* set the slave address */ dev->regs->icsar = msg->addr; /* 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; } dev->regs->iccnt = dev->buf_len; dev->cmd_complete = 0; dev->cmd_err = 0; /* Clear any pending interrupts by reading the IVR */ stat = dev->regs->icivr; /* Take I2C out of reset, configure it as master and set the start bit */ flag = DAVINCI_I2C_ICMDR_IRS_MASK | DAVINCI_I2C_ICMDR_MST_MASK | DAVINCI_I2C_ICMDR_STT_MASK; /* if the slave address is ten bit address, enable XA bit */ if (msg->flags & I2C_M_TEN) flag |= DAVINCI_I2C_ICMDR_XA_MASK; if (!(msg->flags & I2C_M_RD)) flag |= DAVINCI_I2C_ICMDR_TRX_MASK; if (stop) flag |= DAVINCI_I2C_ICMDR_STP_MASK; /* Enable receive and transmit interrupts */ if (msg->flags & I2C_M_RD) dev->regs->icimr |= DAVINCI_I2C_ICIMR_ICRRDY_MASK; else dev->regs->icimr |= DAVINCI_I2C_ICIMR_ICXRDY_MASK; /* write the data into mode register */ dev->regs->icmdr = flag; /* wait for the transaction to complete */ wait_event_timeout (dev->cmd_wait, dev->cmd_complete, DAVINCI_I2C_TIMEOUT); dev->buf_len = 0; if (!dev->cmd_complete) { i2c_warn("i2c: cmd complete failed: complete = 0x%x, \ icstr = 0x%x\n", dev->cmd_complete, dev->regs->icstr); if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) { /* Send the NACK to the slave */ dev->regs->icmdr |= DAVINCI_I2C_ICMDR_NACKMOD_MASK; /* Disable I2C */ disable_i2c_pins(); /* Send high and low on the SCL line */ for (i = 0; i < 10; i++) pulse_i2c_clock(); /* Re-enable I2C */ enable_i2c_pins(); } i2c_davinci_reset(dev); dev->cmd_complete = 0; return -ETIMEDOUT; } dev->cmd_complete = 0; /* no error */ if (!dev->cmd_err) return msg->len; /* We have an error */ if (dev->cmd_err & DAVINCI_I2C_ICSTR_NACK_MASK) { if (msg->flags & I2C_M_IGNORE_NAK) return msg->len; if (stop) dev->regs->icmdr |= DAVINCI_I2C_ICMDR_STP_MASK; return -EREMOTEIO; } if (dev->cmd_err & DAVINCI_I2C_ICSTR_AL_MASK) { i2c_davinci_reset(dev); return -EIO; } return msg->len; }
/*! * The function is registered in the adapter structure. It is called when an MXC * driver wishes to transfer data to a device connected to the I2C device. * * @param adap adapter structure for the MXC i2c device * @param msgs[] array of messages to be transferred to the device * @param num number of messages to be transferred to the device * * @return The function returns the number of messages transferred, * \b -EREMOTEIO on I2C failure and a 0 if the num argument is * less than 0. */ static int mxc_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { mxc_i2c_device *dev = (mxc_i2c_device *) (i2c_get_adapdata(adap)); int i, ret = 0, addr_comp = 0; volatile unsigned int sr; int retry = 5; if (dev->low_power) { dev_err(&dev->adap.dev, "I2C Device in low power mode\n"); return -EREMOTEIO; } if (num < 1) { return 0; } mxc_i2c_module_en(dev, msgs[0].flags); sr = readw(dev->membase + MXC_I2SR); /* * Check bus state */ while ((sr & MXC_I2SR_IBB) && retry--) { udelay(5); sr = readw(dev->membase + MXC_I2SR); } if ((sr & MXC_I2SR_IBB) && retry < 0) { mxc_i2c_module_dis(dev); dev_err(&dev->adap.dev, "Bus busy\n"); return -EREMOTEIO; } //gpio_i2c_active(dev->adap.id); dev->transfer_done = false; dev->tx_success = false; for (i = 0; i < num && ret >= 0; i++) { addr_comp = 0; /* * Send the slave address and transfer direction in the * address cycle */ if (i == 0) { /* * Send a start or repeat start signal */ if (mxc_i2c_start(dev, &msgs[0])) return -EREMOTEIO; /* Wait for the address cycle to complete */ if (mxc_i2c_wait_for_tc(dev, msgs[0].flags)) { mxc_i2c_stop(dev); //gpio_i2c_inactive(dev->adap.id); mxc_i2c_module_dis(dev); return -EREMOTEIO; } addr_comp = 1; } else { /* * Generate repeat start only if required i.e the address * changed or the transfer direction changed */ if ((msgs[i].addr != msgs[i - 1].addr) || ((msgs[i].flags & I2C_M_RD) != (msgs[i - 1].flags & I2C_M_RD))) { mxc_i2c_repstart(dev, &msgs[i]); /* Wait for the address cycle to complete */ if (mxc_i2c_wait_for_tc(dev, msgs[i].flags)) { mxc_i2c_stop(dev); //gpio_i2c_inactive(dev->adap.id); mxc_i2c_module_dis(dev); return -EREMOTEIO; } addr_comp = 1; } } /* Transfer the data */ if (msgs[i].flags & I2C_M_RD) { /* Read the data */ ret = mxc_i2c_readbytes(dev, &msgs[i], (i + 1 == num), addr_comp); if (ret < 0) { dev_err(&dev->adap.dev, "mxc_i2c_readbytes:" " fail.\n"); break; } } else { /* Write the data */ ret = mxc_i2c_writebytes(dev, &msgs[i], (i + 1 == num)); if (ret < 0) { dev_err(&dev->adap.dev, "mxc_i2c_writebytes:" " fail.\n"); break; } } } //gpio_i2c_inactive(dev->adap.id); mxc_i2c_module_dis(dev); /* * Decrease by 1 as we do not want Start message to be included in * the count */ return (i < 0 ? ret : i); }
static int piix4_transaction(struct i2c_adapter *piix4_adapter) { struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter); unsigned short piix4_smba = adapdata->smba; int temp; int result = 0; int timeout = 0; dev_dbg(&piix4_adapter->dev, "Transaction (pre): CNT=%02x, CMD=%02x, " "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); /* Make sure the SMBus host is ready to start transmitting */ if ((temp = inb_p(SMBHSTSTS)) != 0x00) { dev_dbg(&piix4_adapter->dev, "SMBus busy (%02x). " "Resetting...\n", temp); outb_p(temp, SMBHSTSTS); if ((temp = inb_p(SMBHSTSTS)) != 0x00) { dev_err(&piix4_adapter->dev, "Failed! (%02x)\n", temp); return -EBUSY; } else { dev_dbg(&piix4_adapter->dev, "Successful!\n"); } } /* start the transaction by setting bit 6 */ outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT); /* We will always wait for a fraction of a second! (See PIIX4 docs errata) */ if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */ msleep(2); else msleep(1); while ((++timeout < MAX_TIMEOUT) && ((temp = inb_p(SMBHSTSTS)) & 0x01)) msleep(1); /* If the SMBus is still busy, we give up */ if (timeout == MAX_TIMEOUT) { dev_err(&piix4_adapter->dev, "SMBus Timeout!\n"); result = -ETIMEDOUT; } if (temp & 0x10) { result = -EIO; dev_err(&piix4_adapter->dev, "Error: Failed bus transaction\n"); } if (temp & 0x08) { result = -EIO; dev_dbg(&piix4_adapter->dev, "Bus collision! SMBus may be " "locked until next hard reset. (sorry!)\n"); /* Clock stops and slave is stuck in mid-transmission */ } if (temp & 0x04) { result = -ENXIO; dev_dbg(&piix4_adapter->dev, "Error: no response!\n"); } if (inb_p(SMBHSTSTS) != 0x00) outb_p(inb(SMBHSTSTS), SMBHSTSTS); if ((temp = inb_p(SMBHSTSTS)) != 0x00) { dev_err(&piix4_adapter->dev, "Failed reset at end of " "transaction (%02x)\n", temp); } dev_dbg(&piix4_adapter->dev, "Transaction (post): CNT=%02x, CMD=%02x, " "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); return result; }
/* I2C */ static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); int ret = 0; u8 ibuf[64], obuf[64]; if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; if (num > 2) { dev_err(&d->udev->dev, "too many i2c messages[%d], max 2.", num); ret = -EOPNOTSUPP; goto i2c_error; } if (num == 1) { if (msg[0].len > 60) { dev_err(&d->udev->dev, "too many i2c bytes[%d], max 60.", msg[0].len); ret = -EOPNOTSUPP; goto i2c_error; } if (msg[0].flags & I2C_M_RD) { /* single read */ obuf[0] = 0x09; obuf[1] = 0; obuf[2] = msg[0].len; obuf[3] = msg[0].addr; ret = dvbsky_usb_generic_rw(d, obuf, 4, ibuf, msg[0].len + 1); if (ret) dev_err(&d->udev->dev, "failed=%d\n", ret); if (!ret) memcpy(msg[0].buf, &ibuf[1], msg[0].len); } else { /* write */ obuf[0] = 0x08; obuf[1] = msg[0].addr; obuf[2] = msg[0].len; memcpy(&obuf[3], msg[0].buf, msg[0].len); ret = dvbsky_usb_generic_rw(d, obuf, msg[0].len + 3, ibuf, 1); if (ret) dev_err(&d->udev->dev, "failed=%d\n", ret); } } else { if ((msg[0].len > 60) || (msg[1].len > 60)) { dev_err(&d->udev->dev, "too many i2c bytes[w-%d][r-%d], max 60.", msg[0].len, msg[1].len); ret = -EOPNOTSUPP; goto i2c_error; } /* write then read */ obuf[0] = 0x09; obuf[1] = msg[0].len; obuf[2] = msg[1].len; obuf[3] = msg[0].addr; memcpy(&obuf[4], msg[0].buf, msg[0].len); ret = dvbsky_usb_generic_rw(d, obuf, msg[0].len + 4, ibuf, msg[1].len + 1); if (ret) dev_err(&d->udev->dev, "failed=%d\n", ret); if (!ret) memcpy(msg[1].buf, &ibuf[1], msg[1].len); } i2c_error: mutex_unlock(&d->i2c_mutex); return (ret) ? ret : num; }
static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) { struct at91_twi_dev *dev = i2c_get_adapdata(adap); int ret; unsigned int_addr_flag = 0; struct i2c_msg *m_start = msg; bool is_read; dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num); ret = pm_runtime_get_sync(dev->dev); if (ret < 0) goto out; if (num == 2) { int internal_address = 0; int i; /* 1st msg is put into the internal address, start with 2nd */ m_start = &msg[1]; for (i = 0; i < msg->len; ++i) { const unsigned addr = msg->buf[msg->len - 1 - i]; internal_address |= addr << (8 * i); int_addr_flag += AT91_TWI_IADRSZ_1; } at91_twi_write(dev, AT91_TWI_IADR, internal_address); } dev->use_alt_cmd = false; is_read = (m_start->flags & I2C_M_RD); if (dev->pdata->has_alt_cmd) { if (m_start->len > 0 && m_start->len < AT91_I2C_MAX_ALT_CMD_DATA_SIZE) { at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_ACMEN); at91_twi_write(dev, AT91_TWI_ACR, AT91_TWI_ACR_DATAL(m_start->len) | ((is_read) ? AT91_TWI_ACR_DIR : 0)); dev->use_alt_cmd = true; } else { at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_ACMDIS); } } at91_twi_write(dev, AT91_TWI_MMR, (m_start->addr << 16) | int_addr_flag | ((!dev->use_alt_cmd && is_read) ? AT91_TWI_MREAD : 0)); dev->buf_len = m_start->len; dev->buf = m_start->buf; dev->msg = m_start; dev->recv_len_abort = false; ret = at91_do_twi_transfer(dev); ret = (ret < 0) ? ret : num; out: pm_runtime_mark_last_busy(dev->dev); pm_runtime_put_autosuspend(dev->dev); return ret; }
/* I2C */ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); struct az6007_device_state *st = d->priv; int i, j, len; int ret = 0; u16 index; u16 value; int length; u8 req, addr; if (mutex_lock_interruptible(&st->mutex) < 0) return -EAGAIN; for (i = 0; i < num; i++) { addr = msgs[i].addr << 1; if (((i + 1) < num) && (msgs[i].len == 1) && (!msgs[i].flags & I2C_M_RD) && (msgs[i + 1].flags & I2C_M_RD) && (msgs[i].addr == msgs[i + 1].addr)) { /* * A write + read xfer for the same address, where * the first xfer has just 1 byte length. * Need to join both into one operation */ if (dvb_usb_az6007_debug & 2) printk(KERN_DEBUG "az6007 I2C xfer write+read addr=0x%x len=%d/%d: ", addr, msgs[i].len, msgs[i + 1].len); req = AZ6007_I2C_RD; index = msgs[i].buf[0]; value = addr | (1 << 8); length = 6 + msgs[i + 1].len; len = msgs[i + 1].len; ret = __az6007_read(d->udev, req, value, index, st->data, length); if (ret >= len) { for (j = 0; j < len; j++) { msgs[i + 1].buf[j] = st->data[j + 5]; if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "0x%02x ", msgs[i + 1].buf[j]); } } else ret = -EIO; i++; } else if (!(msgs[i].flags & I2C_M_RD)) { /* write bytes */ if (dvb_usb_az6007_debug & 2) printk(KERN_DEBUG "az6007 I2C xfer write addr=0x%x len=%d: ", addr, msgs[i].len); req = AZ6007_I2C_WR; index = msgs[i].buf[0]; value = addr | (1 << 8); length = msgs[i].len - 1; len = msgs[i].len - 1; if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "(0x%02x) ", msgs[i].buf[0]); for (j = 0; j < len; j++) { st->data[j] = msgs[i].buf[j + 1]; if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "0x%02x ", st->data[j]); } ret = __az6007_write(d->udev, req, value, index, st->data, length); } else { /* read bytes */ if (dvb_usb_az6007_debug & 2) printk(KERN_DEBUG "az6007 I2C xfer read addr=0x%x len=%d: ", addr, msgs[i].len); req = AZ6007_I2C_RD; index = msgs[i].buf[0]; value = addr; length = msgs[i].len + 6; len = msgs[i].len; ret = __az6007_read(d->udev, req, value, index, st->data, length); for (j = 0; j < len; j++) { msgs[i].buf[j] = st->data[j + 5]; if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "0x%02x ", st->data[j + 5]); } } if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "\n"); if (ret < 0) goto err; } err: mutex_unlock(&st->mutex); if (ret < 0) { info("%s ERROR: %i", __func__, ret); return ret; } return num; }
/* * Low level master read/write transaction. */ 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; omap_i2c_write_reg(dev, OMAP_I2C_SA_REG, msg->addr); /* REVISIT: Could the STB bit of I2C_CON be used with probing? */ 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); /* Clear the FIFO Buffers */ w = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG); w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR; omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, w); init_completion(&dev->cmd_complete); dev->cmd_err = 0; w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT; /* High speed configuration */ if (dev->speed > 400) w |= OMAP_I2C_CON_OPMODE_HS; if (msg->flags & I2C_M_TEN) w |= OMAP_I2C_CON_XA; if (!(msg->flags & I2C_M_RD)) w |= OMAP_I2C_CON_TRX; if (!dev->b_hw && stop) w |= OMAP_I2C_CON_STP; omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); if (dev->b_hw && stop) { /* H/w behavior: dont write stt and stp together.. */ while (omap_i2c_read_reg(dev, OMAP_I2C_CON_REG) & OMAP_I2C_CON_STT) { /* Dont do anything - this will come in a couple of loops at max*/ } w |= OMAP_I2C_CON_STP; w &= ~OMAP_I2C_CON_STT; omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); } r = wait_for_completion_timeout(&dev->cmd_complete, OMAP_I2C_TIMEOUT); dev->buf_len = 0; if (r < 0) return r; if (r == 0) { dev_err(dev->dev, "controller timed out\n"); omap_i2c_init(dev); return -ETIMEDOUT; } if (likely(!dev->cmd_err)) return 0; /* We have an error */ if (dev->cmd_err & (OMAP_I2C_STAT_AL | OMAP_I2C_STAT_ROVR | OMAP_I2C_STAT_XUDF)) { omap_i2c_init(dev); return -EIO; } if (dev->cmd_err & OMAP_I2C_STAT_NACK) { if (msg->flags & I2C_M_IGNORE_NAK) return 0; if (stop) { w = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG); w |= OMAP_I2C_CON_STP; omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); } return -EREMOTEIO; } return -EIO; }
static int msm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { DECLARE_COMPLETION_ONSTACK(complete); struct msm_i2c_dev *dev = i2c_get_adapdata(adap); int ret; long timeout; unsigned long flags; wake_lock(&dev->wakelock); clk_enable(dev->clk); enable_irq(dev->irq); ret = msm_i2c_poll_notbusy(dev, 1); if (ret) { ret = msm_i2c_recover_bus_busy(dev); if (ret) goto err; } spin_lock_irqsave(&dev->lock, flags); if (dev->flush_cnt) { dev_warn(dev->dev, "%d unrequested bytes read\n", dev->flush_cnt); } dev->msg = msgs; dev->rem = num; dev->pos = -1; dev->ret = num; dev->need_flush = false; dev->flush_cnt = 0; dev->cnt = msgs->len; dev->complete = &complete; msm_i2c_interrupt_locked(dev); spin_unlock_irqrestore(&dev->lock, flags); /* * Now that we've setup the xfer, the ISR will transfer the data * and wake us up with dev->err set if there was an error */ timeout = wait_for_completion_timeout(&complete, HZ); msm_i2c_poll_notbusy(dev, 0); /* Read may not have stopped in time */ spin_lock_irqsave(&dev->lock, flags); if (dev->flush_cnt) { dev_warn(dev->dev, "%d unrequested bytes read\n", dev->flush_cnt); } ret = dev->ret; dev->complete = NULL; dev->msg = NULL; dev->rem = 0; dev->pos = 0; dev->ret = 0; dev->flush_cnt = 0; dev->cnt = 0; spin_unlock_irqrestore(&dev->lock, flags); if (!timeout) { dev_err(dev->dev, "Transaction timed out\n"); ret = -ETIMEDOUT; } if (ret < 0) { dev_err(dev->dev, "Error during data xfer (%d)\n", ret); msm_i2c_recover_bus_busy(dev); } err: disable_irq(dev->irq); clk_disable(dev->clk); wake_unlock(&dev->wakelock); return ret; }
static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); struct lme2510_state *st = d->priv; static u8 obuf[64], ibuf[512]; int i, read, read_o; u16 len; u8 gate = st->i2c_gate; if (gate == 0) gate = 5; if (num > 2) warn("more than 2 i2c messages" "at a time is not handled yet. TODO."); for (i = 0; i < num; i++) { read_o = 1 & (msg[i].flags & I2C_M_RD); read = i+1 < num && (msg[i+1].flags & I2C_M_RD); read |= read_o; gate = (msg[i].addr == st->i2c_tuner_addr) ? (read) ? st->i2c_tuner_gate_r : st->i2c_tuner_gate_w : st->i2c_gate; obuf[0] = gate | (read << 7); if (gate == 5) obuf[1] = (read) ? 2 : msg[i].len + 1; else obuf[1] = msg[i].len + read + 1; obuf[2] = msg[i].addr; if (read) { if (read_o) len = 3; else { memcpy(&obuf[3], msg[i].buf, msg[i].len); obuf[msg[i].len+3] = msg[i+1].len; len = msg[i].len+4; } } else { memcpy(&obuf[3], msg[i].buf, msg[i].len); len = msg[i].len+3; } if (lme2510_msg(d, obuf, len, ibuf, 512) < 0) { deb_info(1, "i2c transfer failed."); return -EAGAIN; } if (read) { if (read_o) memcpy(msg[i].buf, &ibuf[1], msg[i].len); else { memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len); i++; } } } return i; }
static int iproc_smb_data_send(struct i2c_adapter *adapter, unsigned short addr, struct iproc_xact_info *info) { int rc; unsigned int regval; struct iproc_smb_drv_int_data *dev = i2c_get_adapdata(adapter); unsigned long time_left; /* Make sure the previous transaction completed */ rc = iproc_smb_startbusy_wait(dev); if (rc < 0) { printk(KERN_ERR "%s: Send: bus is busy, exiting\n", __func__);; return rc; } if (dev->enable_evts == ENABLE_INTR) { /* Enable start_busy interrupt */ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG); regval |= CCB_SMB_MSTRSTARTBUSYEN_MASK; iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG, regval); /* Mark as incomplete before sending the data */ INIT_COMPLETION(dev->ses_done); } /* Write transaction bytes to Tx FIFO */ iproc_smb_write_trans_data((unsigned long)dev->block_base_addr, addr, info); /* Program master command register (0x30) with protocol type and set * start_busy_command bit to initiate the write transaction */ regval = (info->smb_proto << CCB_SMB_MSTRSMBUSPROTO_SHIFT) | CCB_SMB_MSTRSTARTBUSYCMD_MASK; iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_MSTRCMD_REG, regval); if (dev->enable_evts == ENABLE_INTR) { /* * Block waiting for the transaction to finish. When it's finished, * we'll be signaled by an interrupt */ time_left = wait_for_completion_timeout(&dev->ses_done, XACT_TIMEOUT); /* Disable start_busy interrupt */ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG); regval &= ~CCB_SMB_MSTRSTARTBUSYEN_MASK; iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG, regval); if (time_left == 0) { printk (KERN_ERR "%s: Send: bus error\n", __func__); return -ETIMEDOUT; } } regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_MSTRCMD_REG); /* If start_busy bit cleared, check if there are any errors */ if (!(regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK)) { /* start_busy bit cleared, check master_status field now */ regval &= CCB_SMB_MSTRSTS_MASK; regval >>= CCB_SMB_MSTRSTS_SHIFT; if (regval != MSTR_STS_XACT_SUCCESS) { /* We can flush Tx FIFO here */ printk(KERN_ERR "\n\n%s:Send: Error in transaction %u, exiting", __func__, regval); return -EREMOTEIO; } }
/* I2C */ static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) { int ret; struct dvb_usb_device *d = i2c_get_adapdata(adap); struct rtl28xxu_priv *priv = d->priv; struct rtl28xxu_req req; /* * It is not known which are real I2C bus xfer limits, but testing * with RTL2831U + MT2060 gives max RD 24 and max WR 22 bytes. * TODO: find out RTL2832U lens */ /* * I2C adapter logic looks rather complicated due to fact it handles * three different access methods. Those methods are; * 1) integrated demod access * 2) old I2C access * 3) new I2C access * * Used method is selected in order 1, 2, 3. Method 3 can handle all * requests but there is two reasons why not use it always; * 1) It is most expensive, usually two USB messages are needed * 2) At least RTL2831U does not support it * * Method 3 is needed in case of I2C write+read (typical register read) * where write is more than one byte. */ if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; if (num == 2 && !(msg[0].flags & I2C_M_RD) && (msg[1].flags & I2C_M_RD)) { if (msg[0].len > 24 || msg[1].len > 24) { /* TODO: check msg[0].len max */ ret = -EOPNOTSUPP; goto err_mutex_unlock; } else if (msg[0].addr == 0x10) { /* method 1 - integrated demod */ req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1); req.index = CMD_DEMOD_RD | priv->page; req.size = msg[1].len; req.data = &msg[1].buf[0]; ret = rtl28xxu_ctrl_msg(d, &req); } else if (msg[0].len < 2) { /* method 2 - old I2C */ req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1); req.index = CMD_I2C_RD; req.size = msg[1].len; req.data = &msg[1].buf[0]; ret = rtl28xxu_ctrl_msg(d, &req); } else { /* method 3 - new I2C */ req.value = (msg[0].addr << 1); req.index = CMD_I2C_DA_WR; req.size = msg[0].len; req.data = msg[0].buf; ret = rtl28xxu_ctrl_msg(d, &req); if (ret) goto err_mutex_unlock; req.value = (msg[0].addr << 1); req.index = CMD_I2C_DA_RD; req.size = msg[1].len; req.data = msg[1].buf; ret = rtl28xxu_ctrl_msg(d, &req); } } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) { if (msg[0].len > 22) { /* TODO: check msg[0].len max */ ret = -EOPNOTSUPP; goto err_mutex_unlock; } else if (msg[0].addr == 0x10) { /* method 1 - integrated demod */ if (msg[0].buf[0] == 0x00) { /* save demod page for later demod access */ priv->page = msg[0].buf[1]; ret = 0; } else { req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1); req.index = CMD_DEMOD_WR | priv->page; req.size = msg[0].len-1; req.data = &msg[0].buf[1]; ret = rtl28xxu_ctrl_msg(d, &req); } } else if (msg[0].len < 23) { /* method 2 - old I2C */ req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1); req.index = CMD_I2C_WR; req.size = msg[0].len-1; req.data = &msg[0].buf[1]; ret = rtl28xxu_ctrl_msg(d, &req); } else { /* method 3 - new I2C */ req.value = (msg[0].addr << 1); req.index = CMD_I2C_DA_WR; req.size = msg[0].len; req.data = msg[0].buf; ret = rtl28xxu_ctrl_msg(d, &req); } } else { ret = -EINVAL; } err_mutex_unlock: mutex_unlock(&d->i2c_mutex); return ret ? ret : num; }
static int zd1301_demod_i2c_master_xfer(struct i2c_adapter *adapter, struct i2c_msg msg[], int num) { struct zd1301_demod_dev *dev = i2c_get_adapdata(adapter); struct platform_device *pdev = dev->pdev; int ret, i; unsigned long timeout; u8 u8tmp; #define I2C_XFER_TIMEOUT 5 #define ZD1301_IS_I2C_XFER_WRITE_READ(_msg, _num) \ (_num == 2 && !(_msg[0].flags & I2C_M_RD) && (_msg[1].flags & I2C_M_RD)) #define ZD1301_IS_I2C_XFER_WRITE(_msg, _num) \ (_num == 1 && !(_msg[0].flags & I2C_M_RD)) #define ZD1301_IS_I2C_XFER_READ(_msg, _num) \ (_num == 1 && (_msg[0].flags & I2C_M_RD)) if (ZD1301_IS_I2C_XFER_WRITE_READ(msg, num)) { dev_dbg(&pdev->dev, "write&read msg[0].len=%u msg[1].len=%u\n", msg[0].len, msg[1].len); if (msg[0].len > 1 || msg[1].len > 8) { ret = -EOPNOTSUPP; goto err; } ret = zd1301_demod_wreg(dev, 0x6811, 0x80); if (ret) goto err; ret = zd1301_demod_wreg(dev, 0x6812, 0x05); if (ret) goto err; ret = zd1301_demod_wreg(dev, 0x6813, msg[1].addr << 1); if (ret) goto err; ret = zd1301_demod_wreg(dev, 0x6801, msg[0].buf[0]); if (ret) goto err; ret = zd1301_demod_wreg(dev, 0x6802, 0x00); if (ret) goto err; ret = zd1301_demod_wreg(dev, 0x6803, 0x06); if (ret) goto err; ret = zd1301_demod_wreg(dev, 0x6805, 0x00); if (ret) goto err; ret = zd1301_demod_wreg(dev, 0x6804, msg[1].len); if (ret) goto err; /* Poll xfer ready */ timeout = jiffies + msecs_to_jiffies(I2C_XFER_TIMEOUT); for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) { usleep_range(500, 800); ret = zd1301_demod_rreg(dev, 0x6804, &u8tmp); if (ret) goto err; } for (i = 0; i < msg[1].len; i++) { ret = zd1301_demod_rreg(dev, 0x0600 + i, &msg[1].buf[i]); if (ret) goto err; } } else if (ZD1301_IS_I2C_XFER_WRITE(msg, num)) { dev_dbg(&pdev->dev, "write msg[0].len=%u\n", msg[0].len); if (msg[0].len > 1 + 8) { ret = -EOPNOTSUPP; goto err; } ret = zd1301_demod_wreg(dev, 0x6811, 0x80); if (ret) goto err; ret = zd1301_demod_wreg(dev, 0x6812, 0x01); if (ret) goto err; ret = zd1301_demod_wreg(dev, 0x6813, msg[0].addr << 1); if (ret) goto err; ret = zd1301_demod_wreg(dev, 0x6800, msg[0].buf[0]); if (ret) goto err; ret = zd1301_demod_wreg(dev, 0x6802, 0x00); if (ret) goto err; ret = zd1301_demod_wreg(dev, 0x6803, 0x06); if (ret) goto err; for (i = 0; i < msg[0].len - 1; i++) { ret = zd1301_demod_wreg(dev, 0x0600 + i, msg[0].buf[1 + i]); if (ret) goto err; } ret = zd1301_demod_wreg(dev, 0x6805, 0x80); if (ret) goto err; ret = zd1301_demod_wreg(dev, 0x6804, msg[0].len - 1); if (ret) goto err; /* Poll xfer ready */ timeout = jiffies + msecs_to_jiffies(I2C_XFER_TIMEOUT); for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) { usleep_range(500, 800); ret = zd1301_demod_rreg(dev, 0x6804, &u8tmp); if (ret) goto err; } } else { dev_dbg(&pdev->dev, "unknown msg[0].len=%u\n", msg[0].len); ret = -EOPNOTSUPP; if (ret) goto err; } return num; err: dev_dbg(&pdev->dev, "failed=%d\n", ret); return ret; }
static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); struct lme2510_state *st = d->priv; static u8 obuf[64], ibuf[64]; int i, read, read_o; u16 len; u8 gate = st->i2c_gate; mutex_lock(&d->i2c_mutex); if (gate == 0) gate = 5; for (i = 0; i < num; i++) { read_o = msg[i].flags & I2C_M_RD; read = i + 1 < num && msg[i + 1].flags & I2C_M_RD; read |= read_o; gate = (msg[i].addr == st->i2c_tuner_addr) ? (read) ? st->i2c_tuner_gate_r : st->i2c_tuner_gate_w : st->i2c_gate; obuf[0] = gate | (read << 7); if (gate == 5) obuf[1] = (read) ? 2 : msg[i].len + 1; else obuf[1] = msg[i].len + read + 1; obuf[2] = msg[i].addr << 1; if (read) { if (read_o) len = 3; else { memcpy(&obuf[3], msg[i].buf, msg[i].len); obuf[msg[i].len+3] = msg[i+1].len; len = msg[i].len+4; } } else { memcpy(&obuf[3], msg[i].buf, msg[i].len); len = msg[i].len+3; } if (lme2510_msg(d, obuf, len, ibuf, 64) < 0) { deb_info(1, "i2c transfer failed."); mutex_unlock(&d->i2c_mutex); return -EAGAIN; } if (read) { if (read_o) memcpy(msg[i].buf, &ibuf[1], msg[i].len); else { memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len); i++; } } } mutex_unlock(&d->i2c_mutex); return i; }
static int i2c_imx_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) { unsigned int i, temp; int result; struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter); dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); /* Start I2C transfer */ result = i2c_imx_start(i2c_imx); if (result) goto fail0; /* read/write data */ for (i = 0; i < num; i++) { if (i) { dev_dbg(&i2c_imx->adapter.dev, "<%s> repeated start\n", __func__); temp = readb(i2c_imx->base + IMX_I2C_I2CR); temp |= I2CR_RSTA; writeb(temp, i2c_imx->base + IMX_I2C_I2CR); result = i2c_imx_bus_busy(i2c_imx, 1); if (result) goto fail0; } dev_dbg(&i2c_imx->adapter.dev, "<%s> transfer message: %d\n", __func__, i); /* write/read data */ #ifdef CONFIG_I2C_DEBUG_BUS temp = readb(i2c_imx->base + IMX_I2C_I2CR); dev_dbg(&i2c_imx->adapter.dev, "<%s> CONTROL: IEN=%d, IIEN=%d, " "MSTA=%d, MTX=%d, TXAK=%d, RSTA=%d\n", __func__, (temp & I2CR_IEN ? 1 : 0), (temp & I2CR_IIEN ? 1 : 0), (temp & I2CR_MSTA ? 1 : 0), (temp & I2CR_MTX ? 1 : 0), (temp & I2CR_TXAK ? 1 : 0), (temp & I2CR_RSTA ? 1 : 0)); temp = readb(i2c_imx->base + IMX_I2C_I2SR); dev_dbg(&i2c_imx->adapter.dev, "<%s> STATUS: ICF=%d, IAAS=%d, IBB=%d, " "IAL=%d, SRW=%d, IIF=%d, RXAK=%d\n", __func__, (temp & I2SR_ICF ? 1 : 0), (temp & I2SR_IAAS ? 1 : 0), (temp & I2SR_IBB ? 1 : 0), (temp & I2SR_IAL ? 1 : 0), (temp & I2SR_SRW ? 1 : 0), (temp & I2SR_IIF ? 1 : 0), (temp & I2SR_RXAK ? 1 : 0)); #endif if (msgs[i].flags & I2C_M_RD) result = i2c_imx_read(i2c_imx, &msgs[i]); else result = i2c_imx_write(i2c_imx, &msgs[i]); if (result) goto fail0; } fail0: /* Stop I2C transfer */ i2c_imx_stop(i2c_imx); dev_dbg(&i2c_imx->adapter.dev, "<%s> exit with: %s: %d\n", __func__, (result < 0) ? "error" : "success msg", (result < 0) ? result : num); return (result < 0) ? result : num; }
static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) { struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter); struct i2c_msg *msg; int err = 0; u_int8_t val; int i, k, retry_count; activate_ch(pd); /* Process all messages */ for (i = 0; i < num; i++) { msg = &msgs[i]; err = start_ch(pd, msg); if (err) break; i2c_op(pd, OP_START, 0); /* The interrupt handler takes care of the rest... */ k = wait_event_timeout(pd->wait, pd->sr & (ICSR_TACK | SW_DONE), 5 * HZ); if (!k) dev_err(pd->dev, "Transfer request timed out\n"); retry_count = 1000; again: val = ioread8(ICSR(pd)); dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr); /* the interrupt handler may wake us up before the * transfer is finished, so poll the hardware * until we're done. */ if (val & ICSR_BUSY) { udelay(10); if (retry_count--) goto again; err = -EIO; dev_err(pd->dev, "Polling timed out\n"); break; } /* handle missing acknowledge and arbitration lost */ if ((val | pd->sr) & (ICSR_TACK | ICSR_AL)) { err = -EIO; break; } } deactivate_ch(pd); if (!err) err = num; return err; }
static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg, int last) { struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap); u16 val, tcr_val; int ret, wait_result; u32 xfer_len = 0; if (!(pmsg->flags & I2C_M_NOSTART)) { ret = wmt_i2c_wait_bus_not_busy(i2c_dev); if (ret < 0) return ret; } val = readw(i2c_dev->base + REG_CR); val &= ~CR_TX_END; writew(val, i2c_dev->base + REG_CR); val = readw(i2c_dev->base + REG_CR); val &= ~CR_TX_NEXT_NO_ACK; writew(val, i2c_dev->base + REG_CR); if (!(pmsg->flags & I2C_M_NOSTART)) { val = readw(i2c_dev->base + REG_CR); val |= CR_CPU_RDY; writew(val, i2c_dev->base + REG_CR); } if (pmsg->len == 1) { val = readw(i2c_dev->base + REG_CR); val |= CR_TX_NEXT_NO_ACK; writew(val, i2c_dev->base + REG_CR); } reinit_completion(&i2c_dev->complete); if (i2c_dev->mode == I2C_MODE_STANDARD) tcr_val = TCR_STANDARD_MODE; else tcr_val = TCR_FAST_MODE; tcr_val |= TCR_MASTER_READ | (pmsg->addr & TCR_SLAVE_ADDR_MASK); writew(tcr_val, i2c_dev->base + REG_TCR); if (pmsg->flags & I2C_M_NOSTART) { val = readw(i2c_dev->base + REG_CR); val |= CR_CPU_RDY; writew(val, i2c_dev->base + REG_CR); } while (xfer_len < pmsg->len) { wait_result = wait_for_completion_timeout(&i2c_dev->complete, 500 * HZ / 1000); if (!wait_result) return -ETIMEDOUT; ret = wmt_check_status(i2c_dev); if (ret) return ret; pmsg->buf[xfer_len] = readw(i2c_dev->base + REG_CDR) >> 8; xfer_len++; if (xfer_len == pmsg->len - 1) { val = readw(i2c_dev->base + REG_CR); val |= (CR_TX_NEXT_NO_ACK | CR_CPU_RDY); writew(val, i2c_dev->base + REG_CR); } else { val = readw(i2c_dev->base + REG_CR); val |= CR_CPU_RDY; writew(val, i2c_dev->base + REG_CR); } } return 0; }
static void uniphier_i2c_unprepare_recovery(struct i2c_adapter *adap) { uniphier_i2c_reset(i2c_get_adapdata(adap), false); }
static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); struct af9015_state *state = d_to_priv(d); int ret = 0, i = 0; u16 addr; u8 uninitialized_var(mbox), addr_len; struct req_t req; /* The bus lock is needed because there is two tuners both using same I2C-address. Due to that the only way to select correct tuner is use demodulator I2C-gate. ................................................ . AF9015 includes integrated AF9013 demodulator. . ____________ ____________ . ____________ .| uC | | demod | . | tuner | .|------------| |------------| . |------------| .| AF9015 | | AF9013/5 | . | MXL5003 | .| |--+----I2C-------|-----/ -----|-.-----I2C-------| | .| | | | addr 0x38 | . | addr 0xc6 | .|____________| | |____________| . |____________| .................|.............................. | ____________ ____________ | | demod | | tuner | | |------------| |------------| | | AF9013 | | MXL5003 | +----I2C-------|-----/ -----|-------I2C-------| | | addr 0x3a | | addr 0xc6 | |____________| |____________| */ if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; while (i < num) { if (msg[i].addr == state->af9013_config[0].i2c_addr || msg[i].addr == state->af9013_config[1].i2c_addr) { addr = msg[i].buf[0] << 8; addr += msg[i].buf[1]; mbox = msg[i].buf[2]; addr_len = 3; } else { addr = msg[i].buf[0]; addr_len = 1; /* mbox is don't care in that case */ } if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { if (msg[i].len > 3 || msg[i+1].len > 61) { ret = -EOPNOTSUPP; goto error; } if (msg[i].addr == state->af9013_config[0].i2c_addr) req.cmd = READ_MEMORY; else req.cmd = READ_I2C; req.i2c_addr = msg[i].addr; req.addr = addr; req.mbox = mbox; req.addr_len = addr_len; req.data_len = msg[i+1].len; req.data = &msg[i+1].buf[0]; ret = af9015_ctrl_msg(d, &req); i += 2; } else if (msg[i].flags & I2C_M_RD) { if (msg[i].len > 61) { ret = -EOPNOTSUPP; goto error; } if (msg[i].addr == state->af9013_config[0].i2c_addr) { ret = -EINVAL; goto error; } req.cmd = READ_I2C; req.i2c_addr = msg[i].addr; req.addr = addr; req.mbox = mbox; req.addr_len = addr_len; req.data_len = msg[i].len; req.data = &msg[i].buf[0]; ret = af9015_ctrl_msg(d, &req); i += 1; } else { if (msg[i].len > 21) { ret = -EOPNOTSUPP; goto error; } if (msg[i].addr == state->af9013_config[0].i2c_addr) req.cmd = WRITE_MEMORY; else req.cmd = WRITE_I2C; req.i2c_addr = msg[i].addr; req.addr = addr; req.mbox = mbox; req.addr_len = addr_len; req.data_len = msg[i].len-addr_len; req.data = &msg[i].buf[addr_len]; ret = af9015_ctrl_msg(d, &req); i += 1; } if (ret) goto error; } ret = i; error: mutex_unlock(&d->i2c_mutex); return ret; }
static int msm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { DECLARE_COMPLETION_ONSTACK(complete); struct msm_i2c_dev *dev = i2c_get_adapdata(adap); int ret; int rem = num; uint16_t addr; long timeout; unsigned long flags; int check_busy = 1; mutex_lock(&dev->mlock); if (dev->suspended) { mutex_unlock(&dev->mlock); return -EIO; } /* Don't allow power collapse until we release remote spinlock */ pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "msm_i2c", dev->pdata->pm_lat); msm_i2c_rmutex_lock(dev); if (adap == &dev->adap_pri) writel(0, dev->base + I2C_INTERFACE_SELECT); else writel(I2C_INTERFACE_SELECT_INTF_SELECT, dev->base + I2C_INTERFACE_SELECT); enable_irq(dev->irq); while (rem) { addr = msgs->addr << 1; if (msgs->flags & I2C_M_RD) addr |= 1; spin_lock_irqsave(&dev->lock, flags); dev->msg = msgs; dev->rem = rem; dev->pos = 0; dev->err = 0; dev->flush_cnt = 0; dev->cnt = msgs->len; dev->complete = &complete; spin_unlock_irqrestore(&dev->lock, flags); if (check_busy) { ret = msm_i2c_poll_notbusy(dev); if (ret) ret = msm_i2c_recover_bus_busy(dev, adap); if (ret) { dev_err(dev->dev, "Error waiting for notbusy\n"); goto out_err; } check_busy = 0; } if (rem == 1 && msgs->len == 0) addr |= I2C_WRITE_DATA_LAST_BYTE; /* Wait for WR buffer not full */ ret = msm_i2c_poll_writeready(dev); if (ret) { ret = msm_i2c_recover_bus_busy(dev, adap); if (ret) { dev_err(dev->dev, "Error waiting for write ready before addr\n"); goto out_err; } } /* special case for doing 1 byte read. * There should be no scheduling between I2C controller becoming * ready to read and writing LAST-BYTE to I2C controller * This will avoid potential of I2C controller starting to latch * another extra byte. */ if ((msgs->len == 1) && (msgs->flags & I2C_M_RD)) { uint32_t retries = 0; spin_lock_irqsave(&dev->lock, flags); writel(I2C_WRITE_DATA_ADDR_BYTE | addr, dev->base + I2C_WRITE_DATA); /* Poll for I2C controller going into RX_DATA mode to * ensure controller goes into receive mode. * Just checking write_buffer_full may not work since * there is delay between the write-buffer becoming * empty and the slave sending ACK to ensure I2C * controller goes in receive mode to receive data. */ while (retries != 2000) { uint32_t status = readl(dev->base + I2C_STATUS); if ((status & I2C_STATUS_RX_DATA_STATE) == I2C_STATUS_RX_DATA_STATE) break; retries++; } if (retries >= 2000) { dev->rd_acked = 0; spin_unlock_irqrestore(&dev->lock, flags); /* 1-byte-reads from slow devices in interrupt * context */ goto wait_for_int; } dev->rd_acked = 1; writel(I2C_WRITE_DATA_LAST_BYTE, dev->base + I2C_WRITE_DATA); spin_unlock_irqrestore(&dev->lock, flags); } else { writel(I2C_WRITE_DATA_ADDR_BYTE | addr, dev->base + I2C_WRITE_DATA); } /* Polling and waiting for write_buffer_empty is not necessary. * Even worse, if we do, it can result in invalid status and * error if interrupt(s) occur while polling. */ /* * Now that we've setup the xfer, the ISR will transfer the data * and wake us up with dev->err set if there was an error */ wait_for_int: timeout = wait_for_completion_timeout(&complete, HZ); if (!timeout) { dev_err(dev->dev, "Transaction timed out\n"); writel(I2C_WRITE_DATA_LAST_BYTE, dev->base + I2C_WRITE_DATA); msleep(100); /* FLUSH */ readl(dev->base + I2C_READ_DATA); readl(dev->base + I2C_STATUS); ret = -ETIMEDOUT; goto out_err; } if (dev->err) { dev_err(dev->dev, "Error during data xfer (%d)\n", dev->err); ret = dev->err; goto out_err; } if (msgs->flags & I2C_M_RD) check_busy = 1; msgs++; rem--; } ret = num; out_err: spin_lock_irqsave(&dev->lock, flags); dev->complete = NULL; dev->msg = NULL; dev->rem = 0; dev->pos = 0; dev->err = 0; dev->flush_cnt = 0; dev->cnt = 0; spin_unlock_irqrestore(&dev->lock, flags); disable_irq(dev->irq); msm_i2c_rmutex_unlock(dev); pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "msm_i2c", PM_QOS_DEFAULT_VALUE); mutex_unlock(&dev->mlock); return ret; }
/* * Low level master read/write transaction. */ 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); 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); if (msg->len == 0) return -EINVAL; omap_i2c_write_reg(dev, OMAP_I2C_SA_REG, msg->addr); /* REVISIT: Could the STB bit of I2C_CON be used with probing? */ dev->buf = msg->buf; dev->buf_len = msg->len; omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len); /* Clear the FIFO Buffers */ w = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG); w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR; omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, w); init_completion(&dev->cmd_complete); dev->cmd_err = 0; w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT; /* High speed configuration */ if (dev->speed > 400) w |= OMAP_I2C_CON_OPMODE_HS; if (msg->flags & I2C_M_TEN) w |= OMAP_I2C_CON_XA; if (!(msg->flags & I2C_M_RD)) w |= OMAP_I2C_CON_TRX; if (!dev->b_hw && stop) w |= OMAP_I2C_CON_STP; omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); /* * Don't write stt and stp together on some hardware. */ if (dev->b_hw && stop) { ktime_t start = ktime_get(); u16 con = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG); while (con & OMAP_I2C_CON_STT) { con = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG); /* Let the user know if i2c is in a bad state */ if (ktime_us_delta(ktime_get(), start) > OMAP_I2C_TIMEOUT) { dev_err(dev->dev, "controller timed out " "waiting for start condition to finish\n"); return -ETIMEDOUT; } cpu_relax(); } w |= OMAP_I2C_CON_STP; w &= ~OMAP_I2C_CON_STT; omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); } /* * REVISIT: We should abort the transfer on signals, but the bus goes * into arbitration and we're currently unable to recover from it. */ r = wait_for_completion_timeout(&dev->cmd_complete, usecs_to_jiffies(OMAP_I2C_TIMEOUT)); dev->buf_len = 0; if (r < 0) return r; if (r == 0) { dev_err(dev->dev, "controller timed out\n"); pr_info("addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n", msg->addr, msg->len, msg->flags, stop); omap_i2c_dump(dev); omap_i2c_init(dev); return -ETIMEDOUT; } if (likely(!dev->cmd_err)) return 0; /* We have an error */ if (dev->cmd_err & OMAP_I2C_STAT_AL) { omap_i2c_init(dev); return -EIO; } if (dev->cmd_err & OMAP_I2C_STAT_NACK) { if (msg->flags & I2C_M_IGNORE_NAK) return 0; if (stop) { w = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG); w |= OMAP_I2C_CON_STP; omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); } return -EREMOTEIO; } return -EIO; }
static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter, u16 address, unsigned short flags, char rw, u8 command, int size, union i2c_smbus_data *data) { struct scx200_acb_iface *iface = i2c_get_adapdata(adapter); int len; u8 *buffer; u16 cur_word; int rc; switch (size) { case I2C_SMBUS_QUICK: len = 0; buffer = NULL; break; case I2C_SMBUS_BYTE: if (rw == I2C_SMBUS_READ) { len = 1; buffer = &data->byte; } else { len = 1; buffer = &command; } break; case I2C_SMBUS_BYTE_DATA: len = 1; buffer = &data->byte; break; case I2C_SMBUS_WORD_DATA: len = 2; cur_word = cpu_to_le16(data->word); buffer = (u8 *)&cur_word; break; case I2C_SMBUS_BLOCK_DATA: len = data->block[0]; buffer = &data->block[1]; break; default: return -EINVAL; } DBG("size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n", size, address, command, len, rw == I2C_SMBUS_READ); if (!len && rw == I2C_SMBUS_READ) { dev_warn(&adapter->dev, "zero length read\n"); return -EINVAL; } if (len && !buffer) { dev_warn(&adapter->dev, "nonzero length but no buffer\n"); return -EFAULT; } down(&iface->sem); iface->address_byte = address<<1; if (rw == I2C_SMBUS_READ) iface->address_byte |= 1; iface->command = command; iface->ptr = buffer; iface->len = len; iface->result = -EINVAL; iface->needs_reset = 0; outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1); if (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE) iface->state = state_quick; else iface->state = state_address; #ifdef POLLED_MODE while (iface->state != state_idle) scx200_acb_poll(iface); #else /* POLLED_MODE */ #error Interrupt driven mode not implemented #endif /* POLLED_MODE */ if (iface->needs_reset) scx200_acb_reset(iface); rc = iface->result; up(&iface->sem); if (rc == 0 && size == I2C_SMBUS_WORD_DATA && rw == I2C_SMBUS_READ) data->word = le16_to_cpu(cur_word); #ifdef DEBUG DBG(": transfer done, result: %d", rc); if (buffer) { int i; printk(" data:"); for (i = 0; i < len; ++i) printk(" %02x", buffer[i]); } printk("\n"); #endif return rc; }