コード例 #1
0
static int i2c_get_data(unsigned char *data, int ack)
{
	int timeout = TIMEOUT*10;

	if (!ack)
		__i2c_send_nack();
	else
		__i2c_send_ack();

	while (__i2c_check_drf() == 0 && timeout)
		timeout--;

	if (timeout) {
		if (!ack)
			__i2c_send_stop();
		*data = __i2c_read();
		__i2c_clear_drf();
		return 0;
	} else
		return -ETIMEDOUT;
}
コード例 #2
0
static int i2c_jz_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg, int num)
{
	int ret, i;
	
//	printk(KERN_INFO "i2c_jz_xfer %d messages\n", num);
	dev_dbg(&adap->dev, "jz47xx_xfer: processing %d messages:\n", num);
	for (i = 0; i < num; i++, pmsg++) {
		unsigned char *tmpbuf = pmsg->buf;
		int cnt = (pmsg->flags & I2C_M_TEN) ? -2:-1;	// prepare for sending address;
		ret = num;	// assume ok
		dev_dbg(&adap->dev, " #%d: %s %d byte%s %s 0x%02x flags %04x\n", i,
				pmsg->flags & I2C_M_RD ? "reading" : "writing",
				pmsg->len, pmsg->len > 1 ? "s" : "",
				pmsg->flags & I2C_M_RD ? "from" : "to",	pmsg->addr,
				pmsg->flags);
		if (pmsg->flags & (/*I2C_M_TEN|I2C_M_NOSTART|*/I2C_M_REV_DIR_ADDR|/*I2C_M_IGNORE_NAK|*/I2C_M_NO_RD_ACK|I2C_M_RECV_LEN)) {
			dev_dbg(&adap->dev, "jz47xx_xfer: flags=%04x not supported\n", pmsg->flags);
			return -EINVAL;
		}
		
		if (!pmsg->buf)
			continue;	/* sanity check */
//		printk(KERN_INFO "addr=%x flags=%04x\n", pmsg->addr, pmsg->flags);
		if (!(pmsg->flags & I2C_M_NOSTART))
			__i2c_send_start();
		__i2c_send_ack();	// default (only last byte during receive gets nack)

		for(; cnt < pmsg->len; cnt++) {
//			printk(KERN_INFO "%d (%d)", cnt, pmsg->len);
#if 0
			if(cnt == pmsg->len-1 && i == num-1) {
				printk("  send stop\n");
				__i2c_send_stop();	// last byte of last message				
			}
#endif
			if (cnt >= 0 && pmsg->flags & I2C_M_RD) { // read data
				int timeout = TIMEOUT;
				while(!__i2c_check_drf() && timeout--)	// wait for data to arrive
					udelay(10);
				if (timeout < 0)
					ret = -ETIMEDOUT;
				else {
					if(cnt == pmsg->len-2)
						__i2c_send_nack();	// nack last byte
					*tmpbuf++ = __i2c_read();	// read data byte
//					printk("  r: %02x\n", tmpbuf[-1]);
					__i2c_clear_drf();					
				}
			}
			else {
				int timeout = TIMEOUT;
				if(cnt == -2) { // send first byte of 10-bit address
//					printk("  w: %02x\n", ((pmsg->addr >> 7) & 0x06) | ((pmsg->flags & I2C_M_RD) ? (0xf0 | I2C_READ) : (0xf0 | I2C_WRITE)));
					__i2c_write(((pmsg->addr >> 7) & 0x06) | ((pmsg->flags & I2C_M_RD) ? (0xf0 | I2C_READ) : (0xf0 | I2C_WRITE)) ); 	// first 2 bits					
				}
				else if(cnt == -1) { // send 7 bit address or second byte
					if ((pmsg->flags & I2C_M_TEN)) {
//						printk("  w: %02x\n", pmsg->addr & 0xff);
						__i2c_write(pmsg->addr);	// final 8 bits
					}
					else {
//						printk("  w: %02x\n", (pmsg->addr << 1) | ((pmsg->flags & I2C_M_RD) ? I2C_READ : I2C_WRITE));
						__i2c_write((pmsg->addr << 1) | ((pmsg->flags & I2C_M_RD) ? I2C_READ : I2C_WRITE));	// set data to be written				
					}
				}
				else { // send data
//					printk("  w: %02x\n", *tmpbuf);
					__i2c_write(*tmpbuf++);
					
				}
				__i2c_set_drf();	// data is ready flag
				while(__i2c_check_drf() && timeout--) // wait until we can push the next byte
					udelay(10);
				if(cnt == -1 || cnt == pmsg->len-1) { // last byte, wait for end of transission and final ACK
//					printk("  wait transmit_ended\n");
					timeout = TIMEOUT;
					while(!__i2c_transmit_ended() && timeout--)
						udelay(10);
				}
				if (timeout < 0)
					ret = -ETIMEDOUT;
				else if (!(pmsg->flags & I2C_M_IGNORE_NAK) && !__i2c_received_ack())
					ret = -EIO;
			}
			if(ret < 0)
				break;
		}