static u32 wait_for_rx_byte(struct i2c_au1550_data *adap, u32 *ret_data) { int j; u32 data, stat; volatile psc_smb_t *sp; if (wait_xfer_done(adap)) return -EIO; sp = (volatile psc_smb_t *)(adap->psc_base); j = adap->xfer_timeout * 100; do { j--; if (j <= 0) return -EIO; stat = sp->psc_smbstat; au_sync(); if ((stat & PSC_SMBSTAT_RE) == 0) j = 0; else udelay(1); } while (j > 0); data = sp->psc_smbtxrx; au_sync(); *ret_data = data; return 0; }
static int wait_ack(struct i2c_au1550_data *adap) { unsigned long stat; if (wait_xfer_done(adap)) return -ETIMEDOUT; stat = RD(adap, PSC_SMBEVNT); if ((stat & (PSC_SMBEVNT_DN | PSC_SMBEVNT_AN | PSC_SMBEVNT_AL)) != 0) return -ETIMEDOUT; return 0; }
static int wait_ack(struct i2c_algo_sgi_data *adap) { int i; if (wait_xfer_done(adap)) return -ETIMEDOUT; for (i = 0; i < adap->ack_timeout; i++) { if ((get_control() & SGI_I2C_NACK) == 0) return 0; udelay(1); } return -ETIMEDOUT; }
static int i2c_read(struct i2c_algo_sgi_data *adap, unsigned char *buf, unsigned int len) { int i; set_control(SGI_I2C_HOLD_BUS | SGI_I2C_READ | SGI_I2C_NOT_IDLE); for (i = 0; i < len; i++) { if (wait_xfer_done(adap)) return -EIO; buf[i] = read_data(); } set_control(SGI_I2C_RELEASE_BUS | SGI_I2C_FORCE_IDLE); return 0; }
static int wait_ack(struct i2c_au1550_data *adap) { u32 stat; volatile psc_smb_t *sp; if (wait_xfer_done(adap)) return -ETIMEDOUT; sp = (volatile psc_smb_t *)(adap->psc_base); stat = sp->psc_smbevnt; au_sync(); if ((stat & (PSC_SMBEVNT_DN | PSC_SMBEVNT_AN | PSC_SMBEVNT_AL)) != 0) return -ETIMEDOUT; return 0; }
static int wait_for_rx_byte(struct i2c_au1550_data *adap, unsigned char *out) { int j; if (wait_xfer_done(adap)) return -EIO; j = adap->xfer_timeout * 100; do { j--; if (j <= 0) return -EIO; if ((RD(adap, PSC_SMBSTAT) & PSC_SMBSTAT_RE) == 0) j = 0; else udelay(1); } while (j > 0); *out = RD(adap, PSC_SMBTXRX); return 0; }
/* write followed by read without a stop in between */ static int i2c_write_then_read(struct i2c_msg *msgs, int fifo_len) { int j, ret = 0; u16 xfer_cnt; struct i2c_msg *p = &msgs[0], *q = &msgs[1]; uint32 flags; spin_lock_irqsave(&bcm_i2c_lock, flags); BCM_LOG_DEBUG(BCM_LOG_ID_I2C, "Entering the function %s \n", __FUNCTION__); /* Make sure IIC_Enable bit is zero before start of a new transaction. Note that a 0-1 transition of IIC_Enable is required to initiate an I2C bus transaction */ reg_write((uint32 *)&I2C->IICEnable, 0); /* Set the transfer counts for both the transactions */ xfer_cnt = (q->len << I2C_CNT_REG2_SHIFT) | p->len; /* Set the address, transfer count, and data transfer format */ i2c_rd_wr_common((u8)p->addr, xfer_cnt, I2C_CTL_REG_DTF_WRITE_AND_READ); /* Write the data */ if (fifo_len == 8) { for (j = 0; j < (p->len); j++) reg_write((uint32 *)&I2C->DataIn0 + j, p->buf[j]); } else { int num_dwords = ((p->len) + 3)/4; for (j = 0; j < num_dwords; j++) { #ifdef __LITTLE_ENDIAN reg_write((uint32 *)&I2C->DataIn0 + j, *((int *)&p->buf[j*4])); #else reg_write((uint32 *)&I2C->DataIn0 + j, swab32(*((int *)&p->buf[j*4]))); #endif } } /* Start the I2C transaction */ reg_write((uint32 *)&I2C->IICEnable, I2C_IIC_ENABLE); /* Wait for completion */ if (wait_xfer_done()) { ret = -EIO; goto end; } /* Read the data */ if (fifo_len == 8) { for (j = 0; j < (q->len); j++) q->buf[j] = (u8)reg_read((uint32 *)&I2C->DataOut0 + j); } else { int num_dwords = ((q->len) + 3)/4; for (j = 0; j < num_dwords; j++) { #ifdef __LITTLE_ENDIAN *((int *)&q->buf[j*4]) = reg_read((uint32 *)&I2C->DataOut0 + j); #else *((int *)&q->buf[j*4]) = swab32(reg_read((uint32 *)&I2C->DataOut0 + j)); #endif } } end: /* I2C bus transaction is complete, so set the IIC_Enable to zero */ reg_write((uint32 *)&I2C->IICEnable, 0); spin_unlock_irqrestore(&bcm_i2c_lock, flags); return ret; }
/* Write data of given length to the slave. Note that 2 or more transactions would be required on the bus if the length is more than the fifo_len */ static int i2c_write(struct i2c_msg *p, int fifo_len) { int i, j, ret = 0; u16 xfer_cnt; unsigned int len = p->len; unsigned char *buf = p->buf; unsigned char addr = p->addr; int loops = (len + (fifo_len - 1))/fifo_len; uint32 flags; BCM_LOG_DEBUG(BCM_LOG_ID_I2C, "Entering the function %s \n", __FUNCTION__); spin_lock_irqsave(&bcm_i2c_lock, flags); /* Make sure IIC_Enable bit is zero before start of a new transaction. Note that a 0-1 transition of IIC_Enable is required to initiate an I2C bus transaction */ reg_write((uint32 *)&I2C->IICEnable, 0); for (i = 0; i < loops; i++) { /* Transfer size for the last iteration will be the remaining size */ xfer_cnt = (i==loops-1) ? (len - (i * fifo_len)) : fifo_len; /* Set the address, transfer count, and data transfer format */ i2c_rd_wr_common(addr, xfer_cnt, I2C_CTL_REG_DTF_WRITE); /* Write the data */ if (fifo_len == 8) { for (j = 0; j < xfer_cnt; j++) reg_write((uint32 *)&I2C->DataIn0 + j, buf[i * fifo_len + j]); } else { int num_dwords = (xfer_cnt + 3)/4; for (j = 0; j < num_dwords; j++) { #ifdef __LITTLE_ENDIAN reg_write((uint32 *)&I2C->DataIn0 + j, *((int *)&buf[i * fifo_len + j*4])); #else reg_write((uint32 *)&I2C->DataIn0 + j, swab32(*((int *)&buf[i * fifo_len + j*4]))); #endif } } /* Start the I2C transaction */ reg_write((uint32 *)&I2C->IICEnable, I2C_IIC_ENABLE); /* Wait for completion */ if (wait_xfer_done()) { ret = -EIO; goto end; } } end: /* I2C bus transaction is complete, so set the IIC_Enable to zero */ reg_write((uint32 *)&I2C->IICEnable, 0); spin_unlock_irqrestore(&bcm_i2c_lock, flags); return ret; }