Exemplo n.º 1
0
static int i2c_pxa_do_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
{
	struct i2c_algo_pxa_data * adap;
	struct i2c_msg *pmsg=NULL;
	int i;
	int ret=0, timeout;

	adap = i2c_adap->algo_data;

	timeout = adap->wait_bus_not_busy(adap);

	if (timeout) {
		return I2C_RETRY;
	}

	for (i = 0;ret >= 0 && i < num; i++) {
		int last = i + 1 == num;
		pmsg = &msgs[i];

		ret = i2c_pxa_set_ctrl_byte(adap,pmsg);

		/* Send START */
		if (i == 0) {
			adap->start(adap);
		}else{
			adap->repeat_start(adap);
		}

		adap->transfer(adap, 0, I2C_TRANSMIT, 0);

		/* Wait for ITE (transmit empty) */
		timeout = adap->wait_for_interrupt(adap, I2C_TRANSMIT);

#ifdef DEBUG
		/* Check for ACK (bus error) */
		if (timeout==BUS_ERROR){
			printk(KERN_INFO "i2c_pxa_do_xfer: bus error -> forcing reset\n");
			adap->reset(adap);
			return I2C_RETRY;
		}
#endif

		if (timeout) {
			adap->abort(adap);
			adap->reset(adap);
			return I2C_RETRY;
		}
/* FIXME: handle arbitration... */
#if 0
		/* Check for bus arbitration loss */
		if (adap->arbitration_loss(adap)){
			printk("Arbitration loss detected \n");
			adap->reset(adap);
			return I2C_RETRY;
		}
#endif

		/* Read */
		if (pmsg->flags & I2C_M_RD) {
			/* read bytes into buffer*/
			ret = i2c_pxa_readbytes(i2c_adap, pmsg->buf, pmsg->len, last);
#if DEBUG > 2
			if (ret != pmsg->len) {
				printk(KERN_INFO"i2c_pxa_do_xfer: read %d/%d bytes.\n",
					ret, pmsg->len);
			} else {
				printk(KERN_INFO"i2c_pxa_do_xfer: read %d bytes.\n",ret);
			}
#endif
		} else { /* Write */
			ret = i2c_pxa_sendbytes(i2c_adap, pmsg->buf, pmsg->len, last);
#if DEBUG > 2
			if (ret != pmsg->len) {
				printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d/%d bytes.\n",
					ret, pmsg->len);
			} else {
				printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d bytes.\n",ret);
			}
#endif
		}
	}

	if (ret<0){
		return ret;
	}else{
		return i;
	}
}
Exemplo n.º 2
0
static int i2c_pxa_do_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
{
	struct i2c_algo_pxa_data * adap;
	struct i2c_msg *pmsg=NULL;
	int i;
	int ret=0, timeout;

	adap = i2c_adap->algo_data;

	timeout = adap->wait_bus_not_busy();

	if (timeout) {
		return I2C_RETRY;
	}

#if 0 
	/* If only i2c ack polling the SCL remains low: so I reset the i2c controller 
	   This works but it's not so nice to do run-time: its better don't arrive here
	   with 0 length writes		
	*/
	if (msgs[0].len == 0) {
#ifdef DEBUG
		printk("i2c_pxa_do_xfer: ctrl-byte\n");
#endif
                pmsg = &msgs[0];
		ret = i2c_pxa_set_ctrl_byte(adap,pmsg);
		adap->start();
		adap->transfer(0, I2C_TRANSMIT, 0);
		if ((adap->wait_for_interrupt(I2C_TRANSMIT) != BUS_ERROR)) {
#ifdef DEBUG
			printk("OK");
#endif
			adap->reset(); /* in scannig is abort, but here leaves SCL down */
			return 0;
		} else {
#ifdef DEBUG
			printk("ERR\n");
                        adap->reset(); /* in scannig is stop, but I don't believe that it works */
			return -EIO;
#endif
		}
		udelay(100);
	}
#endif


	for (i = 0;ret >= 0 && i < num; i++) {
		int last = i + 1 == num;
		pmsg = &msgs[i];

		ret = i2c_pxa_set_ctrl_byte(adap,pmsg);

		/* Send START */
		if (i == 0) {
			adap->start();
		}else{
			adap->repeat_start();
		}

		adap->transfer(0, I2C_TRANSMIT, 0);

		/* Wait for ITE (transmit empty) */
		timeout = adap->wait_for_interrupt(I2C_TRANSMIT);

#ifdef DEBUG
		/* Check for ACK (bus error) */
		if (timeout==BUS_ERROR){
			printk(KERN_INFO "i2c_pxa_do_xfer: bus error -> forcing reset\n");
			adap->reset();
			return I2C_RETRY;
		} else
#endif
		if (timeout == -ERESTARTSYS) {
			adap->abort();
			return timeout;
		} else
		if (timeout) {
#ifdef DEBUG
			printk(KERN_INFO "i2c_pxa_do_xfer: timeout -> forcing reset\n");
#endif
			adap->reset();
			return I2C_RETRY;
		}
/* FIXME: handle arbitration... */
#if 0
		/* Check for bus arbitration loss */
		if (adap->arbitration_loss()){
			printk("Arbitration loss detected \n");
			adap->reset();
			return I2C_RETRY;
		}
#endif

		/* Read */ 
		if (pmsg->flags & I2C_M_RD) {
			/* read bytes into buffer*/
			ret = i2c_pxa_readbytes(i2c_adap, pmsg->buf, pmsg->len, last);
#if DEBUG > 2
			if (ret != pmsg->len) {
				printk(KERN_INFO"i2c_pxa_do_xfer: read %d/%d bytes.\n",
					ret, pmsg->len);
			} else {
				printk(KERN_INFO"i2c_pxa_do_xfer: read %d bytes.\n",ret);
			}
#endif
		} else { /* Write */
			ret = i2c_pxa_sendbytes(i2c_adap, pmsg->buf, pmsg->len, last);
#if DEBUG > 2
			if (ret != pmsg->len) {
				printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d/%d bytes.\n",
					ret, pmsg->len);
			} else {
				printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d bytes.\n",ret);
			}
#endif
		}
#if DEBUG > 3
		{
			int idx;
			for(idx=0;idx<ret;idx++){
				printk(KERN_INFO"%02x ",pmsg->buf[idx]);
			}
			printk(KERN_INFO"\n");
		}
#endif
	}

	if (ret<0){
		return ret;
	}else{
		return i;
	}
}