예제 #1
0
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;
}
예제 #2
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;
}
예제 #3
0
파일: i2c-algo-sgi.c 프로젝트: 274914765/C
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;
}
예제 #4
0
파일: i2c-algo-sgi.c 프로젝트: 274914765/C
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;

}
예제 #5
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;
}
예제 #6
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;
}