/* **************************************************************************************************** * * i2c_read * * Description: * * * Parameters: * * Return value: * * Read/Write interface: * bus_id: the id of the twi bus: 4,3,2,1,0 is to twi4..twi0 * chip: I2C slave chip address, range 0..127 * addr: Memory (register) address within the chip * alen: Number of bytes to use for addr ( * 0, 1: addr len = 8bit * 2: addr len = 16bit * 3, 4: addr len = 32bit * * buffer: Where to read/write the data * len: How many bytes to read/write * * Returns: 0 on success, not 0 on failure * **************************************************************************************************** */ int i2c_read(uint bus_id, uchar chip, uint addr, int alen, uchar *buffer, int len) { int i, ret, ret0, addrlen; char *slave_reg; uint twi_host = 0; ret0 = -1; if(bus_id < SUNXI_TWI_COUNT) { twi_host = SUNXI_TWI0_BASE + SUNXI_TWI_OFFSET * bus_id; } else { printf("i2c bus id %d is error\n", bus_id); return ret0; } ret = i2c_sendstart(twi_host); if(ret) { goto i2c_read_err_occur; } ret = i2c_sendslaveaddr(twi_host, chip, I2C_WRITE); if(ret) { goto i2c_read_err_occur; } //send byte address if(alen >= 3) { addrlen = 2; } else if(alen <= 1) { addrlen = 0; } else { addrlen = 1; } slave_reg = (char *)&addr; for (i = addrlen; i>=0; i--) { ret = i2c_sendbyteaddr(twi_host, slave_reg[i] & 0xff); if(ret) { goto i2c_read_err_occur; } } ret = i2c_sendRestart(twi_host); if(ret) { goto i2c_read_err_occur; } ret = i2c_sendslaveaddr(twi_host, chip, I2C_READ); if(ret) { goto i2c_read_err_occur; } //get data ret = i2c_getdata(twi_host, buffer, len); if(ret) { goto i2c_read_err_occur; } ret0 = 0; i2c_read_err_occur: i2c_stop(twi_host); return ret0; }
/* ********************************************************************************************************************** * i2c_init * * Description: * * Arguments : * * Returns : none * * Notes : none * ********************************************************************************************************************** */ void i2c_exit(void) { #ifndef CONFIG_CPUS_I2C int reg_value = 0; reg_value = readl(CCMU_BUS_CLK_GATING_REG3); reg_value &= ~(1<<bus_num); writel(reg_value,CCMU_BUS_CLK_GATING_REG3); #else int reg_value = 0; reg_value = *((unsigned int *)(R_PRCE_APB0_RESET)); reg_value &= ~(0x01 << 6); *((unsigned int *)(R_PRCE_APB0_RESET)) = reg_value; __msdelay(1); reg_value = *((unsigned int *)(R_PRCM_APB0_GATING)); reg_value &= ~(0x01 << 6); *((unsigned int *)(R_PRCM_APB0_GATING)) = reg_value; __msdelay(1); #endif return ; }/* **************************************************************************************************** * * i2c_read * * Description: * * * Parameters: * * Return value: * * Read/Write interface: * chip: I2C slave chip address, range 0..127 * addr: Memory (register) address within the chip * alen: Number of bytes to use for addr ( * 0, 1: addr len = 8bit * 2: addr len = 16bit * 3, 4: addr len = 32bit * * buffer: Where to read/write the data * len: How many bytes to read/write * * Returns: 0 on success, not 0 on failure * **************************************************************************************************** */ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) { int i, ret, ret0, addrlen; char *slave_reg; ret0 = -1; ret = i2c_sendstart(); if(ret) { goto i2c_read_err_occur; } ret = i2c_sendslaveaddr(chip, I2C_WRITE); if(ret) { goto i2c_read_err_occur; } //send byte address if(alen >= 3) { addrlen = 2; } else if(alen <= 1) { addrlen = 0; } else { addrlen = 1; } slave_reg = (char *)&addr; for (i = addrlen; i>=0; i--) { ret = i2c_sendbyteaddr(slave_reg[i] & 0xff); if(ret) { goto i2c_read_err_occur; } } ret = i2c_sendRestart(); if(ret) { goto i2c_read_err_occur; } ret = i2c_sendslaveaddr(chip, I2C_READ); if(ret) { goto i2c_read_err_occur; } //get data ret = i2c_getdata(buffer, len); if(ret) { goto i2c_read_err_occur; } ret0 = 0; i2c_read_err_occur: i2c_stop(); return ret0; }