コード例 #1
0
ファイル: s3c24x0_i2c.c プロジェクト: Philippe12/u-boot-sunxi
static int s3c24x0_do_msg(struct s3c24x0_i2c_bus *i2c_bus, struct i2c_msg *msg,
			  int seq)
{
	struct s3c24x0_i2c *i2c = i2c_bus->regs;
	bool is_read = msg->flags & I2C_M_RD;
	uint status;
	uint addr;
	int ret, i;

	if (!seq)
		setbits_le32(&i2c->iiccon, I2CCON_ACKGEN);

	/* Get the slave chip address going */
	addr = msg->addr << 1;
	writel(addr, &i2c->iicds);
	status = I2C_TXRX_ENA | I2C_START_STOP;
	if (is_read)
		status |= I2C_MODE_MR;
	else
		status |= I2C_MODE_MT;
	writel(status, &i2c->iicstat);
	if (seq)
		read_write_byte(i2c);

	/* Wait for chip address to transmit */
	ret = WaitForXfer(i2c);
	if (ret)
		goto err;

	if (is_read) {
		for (i = 0; !ret && i < msg->len; i++) {
			/* disable ACK for final READ */
			if (i == msg->len - 1)
				clrbits_le32(&i2c->iiccon, I2CCON_ACKGEN);
			read_write_byte(i2c);
			ret = WaitForXfer(i2c);
			msg->buf[i] = readl(&i2c->iicds);
		}
		if (ret == I2C_NACK)
			ret = I2C_OK; /* Normal terminated read */
	} else {
		for (i = 0; !ret && i < msg->len; i++) {
			writel(msg->buf[i], &i2c->iicds);
			read_write_byte(i2c);
			ret = WaitForXfer(i2c);
		}
	}

err:
	return ret;
}
コード例 #2
0
ファイル: fci_i2c.c プロジェクト: VanirAOSP/kernel_lge_f320k
static int fci_i2c_transfer (HANDLE hDevice, u8 cmd_type, u8 chip, u8 addr[], u8 addr_len, u8 data[], u8 data_len)
{
	int i;	
	int result = I2C_OK;
#ifdef FEATURE_SIMPLE_INTERFACE
	u16 cmd;
#endif

	switch (cmd_type) {
		case I2C_WRITE:
#ifdef FEATURE_SIMPLE_INTERFACE
			cmd = (I2C_CR_STA | I2C_CR_WR);
			cmd = (cmd<<8) | (chip | cmd_type);
			bbm_word_write(hDevice, BBM_I2C_TXR, cmd);
#else
			bbm_write(hDevice, BBM_I2C_TXR, chip | cmd_type);
			bbm_write(hDevice, BBM_I2C_CR, I2C_CR_STA | I2C_CR_WR /*0x90*/);
#endif
			result = WaitForXfer(hDevice);
			if(result != I2C_OK) return result;
			
			if (addr && addr_len) {
				i = 0;
				while ((i < addr_len) && (result == I2C_OK)) {
#ifdef FEATURE_SIMPLE_INTERFACE
					cmd = (I2C_CR_WR);
					cmd = (cmd<<8) | (addr[i]);
					bbm_word_write(hDevice, BBM_I2C_TXR, cmd);
#else
					bbm_write(hDevice, BBM_I2C_TXR, addr[i]);
					bbm_write(hDevice, BBM_I2C_CR, I2C_CR_WR /*0x10*/);
#endif
					result = WaitForXfer(hDevice);
					if(result != I2C_OK) return result;
					i++;
				}
			}
			
			i = 0;
			while ((i < data_len) && (result == I2C_OK)) {
#ifdef FEATURE_SIMPLE_INTERFACE
				cmd = (I2C_CR_WR);
				cmd = (cmd<<8) | (data[i]);
				bbm_word_write(hDevice, BBM_I2C_TXR, cmd);
#else
				bbm_write(hDevice, BBM_I2C_TXR, data[i]);
				bbm_write(hDevice, BBM_I2C_CR, I2C_CR_WR /*0x10*/);
#endif
				
				result = WaitForXfer(hDevice);
				if(result != I2C_OK) return result;
				i++;
			}

			bbm_write(hDevice, BBM_I2C_CR, I2C_CR_STO /*0x40*/);
			result = WaitForXfer(hDevice);
			if(result != I2C_OK) return result;
			break;
		case I2C_READ:
			if (addr && addr_len) {
#ifdef FEATURE_SIMPLE_INTERFACE
				cmd = (I2C_CR_STA | I2C_CR_WR);
				cmd = (cmd<<8) | (chip | I2C_WRITE);
				bbm_word_write(hDevice, BBM_I2C_TXR, cmd);
#else
				bbm_write(hDevice, BBM_I2C_TXR, chip | I2C_WRITE);
				bbm_write(hDevice, BBM_I2C_CR, I2C_CR_STA | I2C_CR_WR /*0x90*/); // send start
#endif
				result = WaitForXfer(hDevice);
				if(result != I2C_OK) {
					return result;
				}
			
				i = 0;
				while ((i < addr_len) && (result == I2C_OK)) {
#ifdef FEATURE_SIMPLE_INTERFACE
					cmd = (I2C_CR_WR);
					cmd = (cmd<<8) | (addr[i]);
					bbm_word_write(hDevice, BBM_I2C_TXR, cmd);
#else
					bbm_write(hDevice, BBM_I2C_TXR, addr[i]);
					bbm_write(hDevice, BBM_I2C_CR, I2C_CR_WR /*0x10*/);
#endif	
					result = WaitForXfer(hDevice);
					if(result != I2C_OK) {
						return result;
					}
					i++;
				}
			}
#ifdef FEATURE_SIMPLE_INTERFACE
			cmd = (I2C_CR_STA | I2C_CR_WR);
			cmd = (cmd<<8) | (chip | I2C_READ);
			bbm_word_write(hDevice, BBM_I2C_TXR, cmd);
#else
			bbm_write(hDevice, BBM_I2C_TXR, chip | I2C_READ);
			bbm_write(hDevice, BBM_I2C_CR, I2C_CR_STA | I2C_CR_WR /*0x90*/); // resend start
#endif
			
			result = WaitForXfer(hDevice);
			if(result != I2C_OK) {
				return result;
			}	

			i = 0;
			while ((i < data_len) && (result == I2C_OK)) {
				if (i == data_len - 1) {
					bbm_write(hDevice, BBM_I2C_CR, I2C_CR_RD|I2C_CR_NACK/*0x28*/);	// No Ack Read
					result = WaitForXfer(hDevice);
					if((result != I2C_NACK) && (result != I2C_OK)){
						PRINTF(hDevice, "NACK4-0[%02x]\n", result);
						return result;
					}
				} else {
					bbm_write(hDevice, BBM_I2C_CR, I2C_CR_RD /*0x20*/);	// Ack Read
					result = WaitForXfer(hDevice);
					if(result != I2C_OK){
						PRINTF(hDevice, "NACK4-1[%02x]\n", result);
						return result;
					}
				}
				bbm_read(hDevice, BBM_I2C_RXR, &data[i]);
				i++;
			}	

			bbm_write(hDevice, BBM_I2C_CR, I2C_CR_STO /*0x40*/);		// send stop
			result = WaitForXfer(hDevice);
			if((result != I2C_NACK) && (result != I2C_OK)) {
				PRINTF(hDevice, "NACK5[%02X]\n", result);
				return result;
			}
			break;
		default:
			return I2C_NOK;
	}

	return I2C_OK;
}
コード例 #3
0
ファイル: s3c24x0_i2c.c プロジェクト: Philippe12/u-boot-sunxi
/*
 * cmd_type is 0 for write, 1 for read.
 *
 * addr_len can take any value from 0-255, it is only limited
 * by the char, we could make it larger if needed. If it is
 * 0 we skip the address write cycle.
 */
static int i2c_transfer(struct s3c24x0_i2c *i2c,
			unsigned char cmd_type,
			unsigned char chip,
			unsigned char addr[],
			unsigned char addr_len,
			unsigned char data[],
			unsigned short data_len)
{
	int i = 0, result;
	ulong start_time = get_timer(0);

	if (data == 0 || data_len == 0) {
		/*Don't support data transfer of no length or to address 0 */
		debug("i2c_transfer: bad call\n");
		return I2C_NOK;
	}

	while (readl(&i2c->iicstat) & I2CSTAT_BSY) {
		if (get_timer(start_time) > I2C_TIMEOUT_MS)
			return I2C_NOK_TOUT;
	}

	writel(readl(&i2c->iiccon) | I2CCON_ACKGEN, &i2c->iiccon);

	/* Get the slave chip address going */
	writel(chip, &i2c->iicds);
	if ((cmd_type == I2C_WRITE) || (addr && addr_len))
		writel(I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP,
		       &i2c->iicstat);
	else
		writel(I2C_MODE_MR | I2C_TXRX_ENA | I2C_START_STOP,
		       &i2c->iicstat);

	/* Wait for chip address to transmit. */
	result = WaitForXfer(i2c);
	if (result != I2C_OK)
		goto bailout;

	/* If register address needs to be transmitted - do it now. */
	if (addr && addr_len) {
		while ((i < addr_len) && (result == I2C_OK)) {
			writel(addr[i++], &i2c->iicds);
			read_write_byte(i2c);
			result = WaitForXfer(i2c);
		}
		i = 0;
		if (result != I2C_OK)
			goto bailout;
	}

	switch (cmd_type) {
	case I2C_WRITE:
		while ((i < data_len) && (result == I2C_OK)) {
			writel(data[i++], &i2c->iicds);
			read_write_byte(i2c);
			result = WaitForXfer(i2c);
		}
		break;

	case I2C_READ:
		if (addr && addr_len) {
			/*
			 * Register address has been sent, now send slave chip
			 * address again to start the actual read transaction.
			 */
			writel(chip, &i2c->iicds);

			/* Generate a re-START. */
			writel(I2C_MODE_MR | I2C_TXRX_ENA | I2C_START_STOP,
				&i2c->iicstat);
			read_write_byte(i2c);
			result = WaitForXfer(i2c);

			if (result != I2C_OK)
				goto bailout;
		}

		while ((i < data_len) && (result == I2C_OK)) {
			/* disable ACK for final READ */
			if (i == data_len - 1)
				writel(readl(&i2c->iiccon)
				       & ~I2CCON_ACKGEN,
				       &i2c->iiccon);
			read_write_byte(i2c);
			result = WaitForXfer(i2c);
			data[i++] = readl(&i2c->iicds);
		}
		if (result == I2C_NACK)
			result = I2C_OK; /* Normal terminated read. */
		break;

	default:
		debug("i2c_transfer: bad call\n");
		result = I2C_NOK;
		break;
	}

bailout:
	/* Send STOP. */
	writel(I2C_MODE_MR | I2C_TXRX_ENA, &i2c->iicstat);
	read_write_byte(i2c);

	return result;
}
コード例 #4
0
ファイル: fci_i2c.c プロジェクト: HONO/Bell_V20f_kernel_mod
static int fci_i2c_transfer (HANDLE hDevice, fci_u8 cmd_type, fci_u8 chip, fci_u8 addr[], fci_u8 addr_len, fci_u8 data[], fci_u8 data_len)
{
	int i;	
	int result = I2C_OK;

	switch (cmd_type) {
		case I2C_WRITE:
			bbm_write(hDevice, BBM_I2C_TXR, chip | cmd_type);
			bbm_write(hDevice, BBM_I2C_CR, I2C_CR_STA | I2C_CR_WR /*0x90*/);
			result = WaitForXfer(hDevice);
			if(result != I2C_OK) return result;
			
			if (addr && addr_len) {
				i = 0;
				while ((i < addr_len) && (result == I2C_OK)) {
					bbm_write(hDevice, BBM_I2C_TXR, addr[i]);
					bbm_write(hDevice, BBM_I2C_CR, I2C_CR_WR /*0x10*/);
					result = WaitForXfer(hDevice);
					if(result != I2C_OK) return result;
					i++;
				}
			}
			
			i = 0;
			while ((i < data_len) && (result == I2C_OK)) {
				bbm_write(hDevice, BBM_I2C_TXR, data[i]);
				bbm_write(hDevice, BBM_I2C_CR, I2C_CR_WR /*0x10*/);
				result = WaitForXfer(hDevice);
				if(result != I2C_OK) return result;
				i++;
			}

			bbm_write(hDevice, BBM_I2C_CR, I2C_CR_STO /*0x40*/);
			result = WaitForXfer(hDevice);
			if(result != I2C_OK) return result;
			break;
		case I2C_READ:
			if (addr && addr_len) {
				bbm_write(hDevice, BBM_I2C_TXR, chip | I2C_WRITE);
				bbm_write(hDevice, BBM_I2C_CR, I2C_CR_STA | I2C_CR_WR /*0x90*/); // send start
				result = WaitForXfer(hDevice);
				if(result != I2C_OK) {
					return result;
				}
			
				i = 0;
				while ((i < addr_len) && (result == I2C_OK)) {
					bbm_write(hDevice, BBM_I2C_TXR, addr[i]);
					bbm_write(hDevice, BBM_I2C_CR, I2C_CR_WR /*0x10*/);
					result = WaitForXfer(hDevice);
					if(result != I2C_OK) {
						return result;
					}
					i++;
				}
			}
			
			bbm_write(hDevice, BBM_I2C_TXR, chip | I2C_READ);
			bbm_write(hDevice, BBM_I2C_CR, I2C_CR_STA | I2C_CR_WR /*0x90*/); // resend start
			result = WaitForXfer(hDevice);
			if(result != I2C_OK) {
				return result;
			}	

			i = 0;
			while ((i < data_len) && (result == I2C_OK)) {
				if (i == data_len - 1) {
					bbm_write(hDevice, BBM_I2C_CR, I2C_CR_RD|I2C_CR_NACK/*0x28*/);	// No Ack Read
					result = WaitForXfer(hDevice);
					if((result != I2C_NACK) && (result != I2C_OK)){
						PRINTF(hDevice, "NACK4-0[%02x]\n\r", result);
						return result;
					}
				} else {
					bbm_write(hDevice, BBM_I2C_CR, I2C_CR_RD /*0x20*/);	// Ack Read
					result = WaitForXfer(hDevice);
					if(result != I2C_OK){
						PRINTF(hDevice, "NACK4-1[%02x]\n\r", result);
						return result;
					}
				}
				bbm_read(hDevice, BBM_I2C_RXR, &data[i]);
				i++;
			}	

			bbm_write(hDevice, BBM_I2C_CR, I2C_CR_STO /*0x40*/);		// send stop
			result = WaitForXfer(hDevice);
			if((result != I2C_NACK) && (result != I2C_OK)) {
				PRINTF(hDevice, "NACK5[%02X]\n\r", result);
				return result;
			}
			break;
		default:
			return I2C_NOK;
	}

	return I2C_OK;
}