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; }
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; }
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; }
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; }