/*
 * 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;
}
示例#2
0
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;
}
示例#3
0
/* 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;
	}
示例#4
0
/**
 * 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 {
示例#5
0
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;
	}
示例#7
0
/* 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 {
示例#8
0
/*
 * 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;
}
示例#10
0
/*
 * 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;
}
示例#11
0
/*!
 * 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);
}
示例#12
0
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;
}
示例#13
0
/* 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;
}
示例#14
0
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;
}
示例#15
0
/* 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;
}
示例#16
0
/*
 * 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;
}
示例#18
0
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;
}
示例#19
0
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;

        }
    }
示例#20
0
/* 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;
}
示例#21
0
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;
}
示例#22
0
文件: lmedm04.c 项目: mdamt/linux
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;
}
示例#24
0
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;
}
示例#25
0
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;
}
示例#26
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;
}
示例#28
0
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;
}
示例#29
0
/*
 * 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;
}
示例#30
0
文件: scx200_acb.c 项目: wxlong/Test
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;
}