コード例 #1
0
ファイル: early_i2c.c プロジェクト: prime5711/blackbox
int early_i2c_read (u8 dev, uint addr, int alen, u8 * data, int length)
{
	int i = 0;
	u8 *a = (u8 *) & addr;

	/* wait while i2c bus is busy */
	if (i2c_wait4bus () < 0)
		goto exit;

	/* transmite the slave_addr+read/write phase */
	if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
		goto exit;

	/* select the i2c slave internal regs phase */
	/* because u32 -> u8, and big endian, so if alen is 1, write a[3] */
	if (__i2c_write (&a[4 - alen], alen) != alen)
		goto exit;
	/* dummy read phase */
	if (i2c_write_addr (dev, I2C_READ, 1) == 0)
		goto exit;

	/* transmite data phase */
	i = __i2c_read (data, length);

exit:
	writel (M83xx_CCR_MEN, I2CCCR);

	return !(i == length);
}
コード例 #2
0
/*
 * Internal simplified write function:
 *   i2c_regs:	Pointer to I2C registers for current bus
 *   chip:	I2C chip address, range 0..127
 *   addr:	Memory (register) address within the chip
 *   alen:	Number of bytes to use for addr (typically 1, 2 for larger
 *		memories, 0 for register type devices with only one register)
 *   data:	Where to read the data
 *   len:	How many bytes to write
 *
 *   Returns:	0 on success, not 0 on failure
 */
static int __i2c_write(struct u5500_i2c_regs *i2c_regs, u8 chip, uint addr,
		int alen, u8 *data, int len)
{
	int i;
	u32 mcr = 0;

	/* Set the address mode to 7 bit */
	WRITE_FIELD(mcr, I2C_MCR_AM, I2C_MCR_SHIFT_AM, 1);

	/* Store the slave address in the master control register */
	WRITE_FIELD(mcr, I2C_MCR_A7, I2C_MCR_SHIFT_A7, chip);

	/* Write operation */
	CLR_BIT(mcr, I2C_MCR_OP);

	/* Current transaction is terminated by STOP condition */
	SET_BIT(mcr, I2C_MCR_STOP);

	/* Frame length: addr byte + len */
	WRITE_FIELD(mcr, I2C_MCR_LENGTH, I2C_MCR_SHIFT_LENGTH, (alen + len));

	/* Write MCR register */
	writel(mcr, &i2c_regs->mcr);

	if (i2c_write_addr(i2c_regs, addr, alen) != 0)
		return -1;

	for (i = 0; i < len; i++) {
		/* Wait until the Tx FIFO is not full */
		if (loop_till_bit_clear((void *)&i2c_regs->risr,
					I2C_INT_TXFF, I2C_ENDAD_COUNTER))
			return -1;

		/* it is a 32 bit register with upper 24 reserved R/O */
		writeb(data[i], &i2c_regs->tfr);
	}

	/* Check for Master Transaction Done */
	if (loop_till_bit_set((void *)&i2c_regs->risr, I2C_INT_MTD,
				I2C_ENDAD_COUNTER)) {
		printf("i2c_write_byte error2: risr %08x\n",
				i2c_regs->risr);
		return -1;
	}

	/* Acknowledge Master Transaction Done */
	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTD);

	/* Acknowledge Master Transaction Done Without Stop */
	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTDWS);

	return 0;
}
コード例 #3
0
ファイル: i2c.c プロジェクト: HonestarKevin/wm8880_4_4_uboot
int
i2c_read (u8 dev, uint addr, int alen, u8 *data, int length)
{
	int i = 0;
	u8 *a = (u8*)&addr;

	if (i2c_wait4bus () < 0)
		goto exit;

	if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
		goto exit;

	if (__i2c_write (&a[4 - alen], alen) != alen)
		goto exit;

	if (i2c_write_addr (dev, I2C_READ, 1) == 0)
		goto exit;

	i = __i2c_read (data, length);

 exit:
	writeb(I2C_CR_MEN, &I2C->cr);
	return !(i == length);
}
コード例 #4
0
/*
 * Internal simplified read function:
 *   i2c_regs:	Pointer to I2C registers for current bus
 *   chip:	I2C chip address, range 0..127
 *   addr:	Memory (register) address within the chip
 *   alen:	Number of bytes to use for addr (typically 1, 2 for larger
 *		memories, 0 for register type devices with only one register)
 *   value:	Where to put the data
 *
 *   Returns:	0 on success, not 0 on failure
 */
static int i2c_read_byte(struct u5500_i2c_regs *i2c_regs, uchar chip,
		uint addr, int alen, uchar *value)
{
	u32   mcr = 0;

	/* Set the address mode to 7 bit */
	WRITE_FIELD(mcr, I2C_MCR_AM, I2C_MCR_SHIFT_AM, 1);

	/* Store the slave address in the master control register */
	WRITE_FIELD(mcr, I2C_MCR_A7, I2C_MCR_SHIFT_A7, chip);

	if (alen != 0) {
		/* Master write operation */
		CLR_BIT(mcr, I2C_MCR_OP);

		/* Configure the Frame length to one byte */
		WRITE_FIELD(mcr, I2C_MCR_LENGTH, I2C_MCR_SHIFT_LENGTH, 1);

		/* Repeated start, no stop */
		CLR_BIT(mcr, I2C_MCR_STOP);

		/* Write Master Control Register */
		writel(mcr, &i2c_regs->mcr);

		/* send addr/index */
		if (i2c_write_addr(i2c_regs, addr, alen) != 0)
			return -1;

		/* Check for the Master Transaction Done Without Stop */
		if (loop_till_bit_set((void *)&i2c_regs->risr,
					I2C_INT_MTDWS, I2C_ENDAD_COUNTER)) {
			return -1;
		}

		/* Acknowledge the Master Transaction Done Without Stop */
		i2c_set_bit(&i2c_regs->icr, I2C_INT_MTDWS);
	}

	/* Master control configuration for read operation  */
	SET_BIT(mcr, I2C_MCR_OP);

	/* Configure the STOP condition, we read only one byte */
	SET_BIT(mcr, I2C_MCR_STOP);

	/* Set the frame length to one byte, we support only 1 byte reads */
	WRITE_FIELD(mcr, I2C_MCR_LENGTH, I2C_MCR_SHIFT_LENGTH, 1);

	i2c_write_field(&i2c_regs->mcr, I2C_MCR_LENGTH_STOP_OP,
			I2C_MCR_SHIFT_LENGTH_STOP_OP, mcr);

	/*
	 * receive_data_polling
	 */

	/* Wait until the Rx FIFO is not empty */
	if (loop_till_bit_clear((void *)&i2c_regs->risr, I2C_INT_RXFE,
			I2C_ENDAD_COUNTER))
		return -1;

	/* Read the data byte from Rx FIFO */
	*value = readb(&i2c_regs->rfr);

	/* Wait until the work is done */
	if (loop_till_bit_set((void *)&i2c_regs->risr, I2C_INT_MTD,
				I2C_ENDAD_COUNTER))
		return -1;

	/* Acknowledge the Master Transaction Done */
	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTD);

	/* If MTD is set, Master Transaction Done Without Stop is set too */
	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTDWS);

	return 0;
}