Exemple #1
0
static int i2c_read_byte(u8 devaddr, u8 regoffset, u8 * value)
{
	int i2c_error = 0;
	u16 status;

	/* wait until bus not busy */
	wait_for_bb();

	/* one byte only */
	outw(1, I2C_CNT);
	/* set slave address */
	outw(devaddr, I2C_SA);
	/* no stop bit needed here */
	outw(I2C_CON_EN | ((i2c_speed == OMAP_I2C_HIGH_SPEED) ? 0x1 << 12 : 0) |
	     I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON);

	status = wait_for_pin();

	if (status & I2C_STAT_XRDY) {
		/* Important: have to use byte access */
		outb(regoffset, I2C_DATA);
		udelay(20000);
		if (inw(I2C_STAT) & I2C_STAT_NACK) {
			i2c_error = 1;
		}
	} else {
		i2c_error = 1;
	}

	if (!i2c_error) {
		int err = 10;
		while (inw(I2C_STAT) || (inw(I2C_CON) & I2C_CON_MST)) {
			udelay(10000);
			/* Have to clear pending interrupt to clear I2C_STAT */
			outw(0xFFFF, I2C_STAT);
			if (!err--) {
				break;
			}
		}

		/* set slave address */
		outw(devaddr, I2C_SA);
		/* read one byte from slave */
		outw(1, I2C_CNT);
		/* need stop bit here */
		outw(I2C_CON_EN |
		     ((i2c_speed ==
		       OMAP_I2C_HIGH_SPEED) ? 0x1 << 12 : 0) | I2C_CON_MST |
		     I2C_CON_STT | I2C_CON_STP, I2C_CON);

		status = wait_for_pin();
		if (status & I2C_STAT_RRDY) {
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || defined(CONFIG_OMAP44XX)
			*value = inb(I2C_DATA);
#else
			*value = inw(I2C_DATA);
#endif
			udelay(20000);
		} else {
			i2c_error = 1;
		}

		if (!i2c_error) {
			int err = 10;
			outw(I2C_CON_EN, I2C_CON);
			while (inw(I2C_STAT)
			       || (inw(I2C_CON) & I2C_CON_MST)) {
				udelay(10000);
				outw(0xFFFF, I2C_STAT);
				if (!err--) {
					break;
				}
			}
		}
	}
	flush_fifo();
	outw(0xFFFF, I2C_STAT);
	outw(0, I2C_CNT);
	return i2c_error;
}
Exemple #2
0
int i2c_write_16_byte(u8 devaddr, u8 regoffset, u8* value)
{
	int eout;
	int i2c_error = 0;
	u16 status, stat;
	
	if (!value)	return 1;

	/* wait until bus not busy */
	wait_for_bb();

	/* 16 bytes */
	outw(17, I2C_CNT);
	/* set slave address */
	outw(devaddr, I2C_SA);
	/* stop bit needed here */
	outw(I2C_CON_EN | ((i2c_speed == OMAP_I2C_HIGH_SPEED) ? 0x1 << 12 : 0) |
	     I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP, I2C_CON);

	/* wait until state change */
	status = wait_for_pin();

	if (status & I2C_STAT_XRDY) {
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
		/* send out 1 byte */
		outb(regoffset, I2C_DATA);
		outw(I2C_STAT_XRDY, I2C_STAT);
		status = wait_for_pin();
		if ((status & I2C_STAT_XRDY)) {
			int i;
			for ( i = 0; i <16; i++) {
			/* send out next 1 byte */
			outb(value[i], I2C_DATA);
			outw(I2C_STAT_XRDY, I2C_STAT);
			}
		} else {
			i2c_error = 1;
		}
#else
		/* send out 2 bytes */
		outw((value << 8) | regoffset, I2C_DATA);
#endif
		/* must have enough delay to allow BB bit to go low */
		eout= 20000;
		while (!(inw(I2C_STAT) & I2C_STAT_ARDY) && eout--)
			;
		if (eout <= 0)
			printf("timed out in i2c_write_byte: I2C_STAT=%x\n",
			       inw(I2C_STAT));

		if (inw(I2C_STAT) & I2C_STAT_NACK) {
			i2c_error = 1;
		}
	} else {
		i2c_error = 1;
	}
	if (!i2c_error) {
		eout = 2000;

		outw(I2C_CON_EN, I2C_CON);
		while ((stat = inw(I2C_STAT)) || (inw(I2C_CON) & I2C_CON_MST)) {
			/* have to read to clear intrrupt */
			outw(0xFFFF, I2C_STAT);
			if (--eout == 0)	/* better leave with error than hang */
				break;
		}
	}
	flush_fifo();
	outw(0xFFFF, I2C_STAT);
	outw(0, I2C_CNT);
	return i2c_error;
}
Exemple #3
0
static int i2c_multidata_write_byte(u8 devaddr, u8 regoffset, u8 *values, int len)
{
	int eout;
	int i2c_error = 0;
	u16 status, stat;
        int i=0;
        int count=0;

	/* wait until bus not busy */
	wait_for_bb();
        //printf("I2C DEBUG: Bus not busy complete\n");

        count = len + 1;
	/* length+1 bytes */
	outw(count, I2C_CNT);
        //printf("I2C DEBUG: Count set to %x\n", count);

	/* set slave address */
	outw(devaddr, I2C_SA);
        //printf("I2C DEBUG: Slave Address set to %x\n", devaddr);

	/* stop bit needed here */
	outw(I2C_CON_EN | ((i2c_speed == OMAP_I2C_HIGH_SPEED) ? 0x1 << 12 : 0) |
	     I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP, I2C_CON);
        //printf("I2C DEBUG: Configuration set\n");

	/* wait until state change */
	status = wait_for_pin();
        //printf("I2C DEBUG: Wait pin status change\n");

	if (status & I2C_STAT_XRDY) {
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
		/* send out 1 byte */
                //printf("I2C DEBUG: Transmit ready status\n");

		outb(regoffset, I2C_DATA);
                //printf("I2C DEBUG: Register Offset set to %x\n", regoffset);

		outw(I2C_STAT_XRDY, I2C_STAT);
                //printf("I2C DEBUG: Clearing transmit ready\n");

               	for (i = 0; i < len; i++) {
		  status = wait_for_pin();
                  //printf("I2C DEBUG: Wait pin status change\n");

		  if ((status & I2C_STAT_XRDY)) {
                        //printf("I2C DEBUG: Data output iteration %x\n", i);
			/* send out next 1 byte */
			outb(values[i], I2C_DATA);
                        //printf("I2C DEBUG: Data output value written %x\n", values[i]);
			outw(I2C_STAT_XRDY, I2C_STAT);
                        //printf("I2C DEBUG: Clearing transmit ready \n");
		  } else {
                        printf("I2C error\n");
			i2c_error = 1;
		  }
                }
                //printf("I2C DEBUG: Multidata byte write transfer complete \n");
#else
		/* send out 2 bytes */
		outw((value << 8) | regoffset, I2C_DATA);
#endif
		/* must have enough delay to allow BB bit to go low */
		eout= 20000;
		while (!(inw(I2C_STAT) & I2C_STAT_ARDY) && eout--)
			;
		if (eout <= 0)
			printf("timed out in i2c_write_byte: I2C_STAT=%x\n",
			       inw(I2C_STAT));

		if (inw(I2C_STAT) & I2C_STAT_NACK) {
			i2c_error = 1;
		}
	} else {
		i2c_error = 1;
	}
	if (!i2c_error) {
		eout = 2000;

		outw(I2C_CON_EN, I2C_CON);
		while ((stat = inw(I2C_STAT)) || (inw(I2C_CON) & I2C_CON_MST)) {
			/* have to read to clear intrrupt */
			outw(0xFFFF, I2C_STAT);
			if (--eout == 0)	/* better leave with error than hang */
				break;
		}
	}
	flush_fifo();
	outw(0xFFFF, I2C_STAT);
	outw(0, I2C_CNT);
	return i2c_error;
}
Exemple #4
0
int i2c_read_16_byte(u8 devaddr, u8 regoffset, u8 * value)
{
	int err;
	int i2c_error = 0;
	u16 status;

	if (!value) return 1;
	
	/* wait until bus not busy */
	wait_for_bb();

	/* one byte only */
	outw(1, I2C_CNT);
	/* set slave address */
	outw(devaddr, I2C_SA);
	/* no stop bit needed here */
	outw(I2C_CON_EN | ((i2c_speed == OMAP_I2C_HIGH_SPEED) ? 0x1 << 12 : 0) |
	     I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON);

	status = wait_for_pin();

	if (status & I2C_STAT_XRDY) {
		/* Important: have to use byte access */
		outb(regoffset, I2C_DATA);

		/* Important: wait for ARDY bit to set */
		err = 2000;
		while (!(inw(I2C_STAT) & I2C_STAT_ARDY) && err--)
			;
		if (err <= 0)
			i2c_error = 1;

		if (inw(I2C_STAT) & I2C_STAT_NACK) {
			i2c_error = 1;
		}
	} else {
		i2c_error = 1;
	}

	if (!i2c_error) {
		err = 2000;
		outw(I2C_CON_EN, I2C_CON);
		while (inw(I2C_STAT) || (inw(I2C_CON) & I2C_CON_MST)) {
			/* Have to clear pending interrupt to clear I2C_STAT */
			outw(0xFFFF, I2C_STAT);
			if (!err--) {
				break;
			}
		}

		/* set slave address */
		outw(devaddr, I2C_SA);
		/* read 16 bytes from slave */
		outw(16, I2C_CNT);
		/* need stop bit here */
		outw(I2C_CON_EN |
		     ((i2c_speed ==
		       OMAP_I2C_HIGH_SPEED) ? 0x1 << 12 : 0) | I2C_CON_MST |
		     I2C_CON_STT | I2C_CON_STP, I2C_CON);

		status = wait_for_pin();
		if (status & I2C_STAT_RRDY) {
		int i =0;
		for (i=0; i<16; i++) {
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
				*value++ = inb(I2C_DATA);
#else
				*value = inw(I2C_DATA);
#endif
			/* Important: wait for ARDY bit to set */
			err = 20000;
			while (!(inw(I2C_STAT) & I2C_STAT_ARDY) && err--)
				;
		}	
		if (err <= 0){
printf("i2c_read_byte -- I2C_STAT_ARDY error\n");
			i2c_error = 1;
		}
		} else {
			i2c_error = 1;
		}

		if (!i2c_error) {
			int err = 1000;
			outw(I2C_CON_EN, I2C_CON);
			while (inw(I2C_STAT)
			       || (inw(I2C_CON) & I2C_CON_MST)) {
				outw(0xFFFF, I2C_STAT);
				if (!err--) {
					break;
				}
			}
		}
	}
	flush_fifo();
	outw(0xFFFF, I2C_STAT);
	outw(0, I2C_CNT);
	return i2c_error;
}
static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
{
	int i2c_error = 0;
	u16 status;

	/* wait until bus not busy */
	wait_for_bb ();

	/* one byte only */
	outw (1, I2C_CNT);
	/* set slave address */
	outw (devaddr, I2C_SA);
	/* no stop bit needed here */
	outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON);

	status = wait_for_pin ();

	if (status & I2C_STAT_XRDY) {
		/* Important: have to use byte access */
		*(volatile u8 *) (I2C_DATA) = regoffset;
		udelay (20000);
		if (inw (I2C_STAT) & I2C_STAT_NACK) {
			i2c_error = 1;
		}
	} else {
		i2c_error = 1;
	}

	if (!i2c_error) {
		/* free bus, otherwise we can't use a combined transction */
		outw (0, I2C_CON);
		while (inw (I2C_STAT) || (inw (I2C_CON) & I2C_CON_MST)) {
			udelay (10000);
			/* Have to clear pending interrupt to clear I2C_STAT */
			outw (0xFFFF, I2C_STAT);
		}

		wait_for_bb ();
		/* set slave address */
		outw (devaddr, I2C_SA);
		/* read one byte from slave */
		outw (1, I2C_CNT);
		/* need stop bit here */
		outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
		      I2C_CON);

		status = wait_for_pin ();
		if (status & I2C_STAT_RRDY) {
			*value = inw (I2C_DATA);
			udelay (20000);
		} else {
			i2c_error = 1;
		}

		if (!i2c_error) {
			outw (I2C_CON_EN, I2C_CON);
			while (inw (I2C_STAT)
			       || (inw (I2C_CON) & I2C_CON_MST)) {
				udelay (10000);
				outw (0xFFFF, I2C_STAT);
			}
		}
	}
	flush_fifo();
	outw (0xFFFF, I2C_STAT);
	outw (0, I2C_CNT);
	return i2c_error;
}
static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value)
{
	int i2c_error = 0;
	u16 status;

	/* wait until bus not busy */
	wait_for_bb ();

	/* two bytes */
	writew (2, &i2c_base->cnt);
	/* set slave address */
	writew (devaddr, &i2c_base->sa);
	/* stop bit needed here */
	writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
		I2C_CON_STP, &i2c_base->con);

	while (1) {
		status = wait_for_pin();
		if (status == 0 || status & I2C_STAT_NACK) {
			i2c_error = 1;
			goto write_exit;
		}
		if (status & I2C_STAT_XRDY) {
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
    defined(CONFIG_OMAP44XX)
			/* send register offset */
			writeb(regoffset, &i2c_base->data);
			writew(I2C_STAT_XRDY, &i2c_base->stat);

			while (1) {
				status = wait_for_pin();
				if (status == 0 || status & I2C_STAT_NACK) {
					i2c_error = 1;
					goto write_exit;
				}
				if (status & I2C_STAT_XRDY) {
					/* send data */
					writeb(value, &i2c_base->data);
					writew(I2C_STAT_XRDY, &i2c_base->stat);
				}
				if (status & I2C_STAT_ARDY) {
					writew(I2C_STAT_ARDY, &i2c_base->stat);
					break;
				}
			}
			break;
#else
			/* send out two bytes */
			writew((value << 8) + regoffset, &i2c_base->data);
			writew(I2C_STAT_XRDY, &i2c_base->stat);
#endif
		}
		if (status & I2C_STAT_ARDY) {
			writew(I2C_STAT_ARDY, &i2c_base->stat);
			break;
		}
	}

	wait_for_bb();

	status = readw(&i2c_base->stat);
	if (status & I2C_STAT_NACK)
		i2c_error = 1;

write_exit:
	flush_fifo();
	writew (0xFFFF, &i2c_base->stat);
	writew (0, &i2c_base->cnt);
	return i2c_error;
}
static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
{
	int i2c_error = 0;
	u16 status;

	/* wait until bus not busy */
	wait_for_bb ();

	/* one byte only */
	writew (1, &i2c_base->cnt);
	/* set slave address */
	writew (devaddr, &i2c_base->sa);
	/* no stop bit needed here */
	writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, &i2c_base->con);

	/* send register offset */
	while (1) {
		status = wait_for_pin();
		if (status == 0 || status & I2C_STAT_NACK) {
			i2c_error = 1;
			goto read_exit;
		}
		if (status & I2C_STAT_XRDY) {
			/* Important: have to use byte access */
			writeb(regoffset, &i2c_base->data);
			writew(I2C_STAT_XRDY, &i2c_base->stat);
		}
		if (status & I2C_STAT_ARDY) {
			writew(I2C_STAT_ARDY, &i2c_base->stat);
			break;
		}
	}

	/* set slave address */
	writew(devaddr, &i2c_base->sa);
	/* read one byte from slave */
	writew(1, &i2c_base->cnt);
	/* need stop bit here */
	writew(I2C_CON_EN | I2C_CON_MST |
		I2C_CON_STT | I2C_CON_STP,
		&i2c_base->con);

	/* receive data */
	while (1) {
		status = wait_for_pin();
		if (status == 0 || status & I2C_STAT_NACK) {
			i2c_error = 1;
			goto read_exit;
		}
		if (status & I2C_STAT_RRDY) {
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
    defined(CONFIG_OMAP44XX)
			*value = readb(&i2c_base->data);
#else
			*value = readw(&i2c_base->data);
#endif
			writew(I2C_STAT_RRDY, &i2c_base->stat);
		}
		if (status & I2C_STAT_ARDY) {
			writew(I2C_STAT_ARDY, &i2c_base->stat);
			break;
		}
	}

read_exit:
	flush_fifo();
	writew (0xFFFF, &i2c_base->stat);
	writew (0, &i2c_base->cnt);
	return i2c_error;
}
static int i2c_write_bytes(u8 devaddr, u8 regoffset, u8 *value, int len)
{
    int i2c_error = 0;
    u16 status, stat;
    int timeout;

    /* wait until bus not busy */
    wait_for_bb();

    /* reg + data length bytes */
    outw(len + 1, I2C_CNT);
    /* set slave address */
    outw(devaddr, I2C_SA);
    /* stop bit needed here */
    outw(I2C_CON_EN | ((i2c_speed == OMAP_I2C_HIGH_SPEED) ? 0x1 << 12 : 0) |
         I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP, I2C_CON);

    /* wait until state change */
    status = wait_for_pin();

    if (status & I2C_STAT_XRDY) {
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || defined(CONFIG_OMAP44XX)
        /* send out 1 byte */
        outb(regoffset, I2C_DATA);
        outw(I2C_STAT_XRDY, I2C_STAT);
        status = wait_for_pin();
        int i = 0;

        for (i = 0; i < len && (status & I2C_STAT_XRDY); ++i) {
            /* send out next 1 byte */
            outb(*value, I2C_DATA);
            outw(I2C_STAT_XRDY, I2C_STAT);
            status = wait_for_pin();
            ++value;
        }

        if (i < len) {
            i2c_error = 1;
        }
#else
        /* send out 2 bytes */
        outw((value << 8) | regoffset, I2C_DATA);
#endif
        /* must have enough delay to allow BB bit to go low */
        timeout = 10000;

        while ((inw(I2C_STAT) & I2C_STAT_BB) && timeout--) {
            udelay(50);
        }

        if (inw(I2C_STAT) & I2C_STAT_NACK) {
            i2c_error = 1;
        }
    } else {
        i2c_error = 1;
    }
    if (!i2c_error) {
        int eout = 2000;

        outw(I2C_CON_EN, I2C_CON);
        while ((stat = inw(I2C_STAT)) || (inw(I2C_CON) & I2C_CON_MST)) {
            udelay(100);
            /* have to read to clear intrrupt */
            outw(0xFFFF, I2C_STAT);
            if (--eout == 0)	/* better leave with error than hang */
                break;
        }
    }
    flush_fifo();
    outw(0xFFFF, I2C_STAT);
    outw(0, I2C_CNT);
    return i2c_error;
}