static int __i2c_set_bus_speed(unsigned int speed) { u32 value; struct u5500_i2c_regs *i2c_regs; i2c_regs = i2c_dev[i2c_bus_num]; /* Select standard (100 kbps) speed mode */ i2c_write_field(&i2c_regs->cr, I2C_CR_SM, I2C_CR_SHIFT_SM, 0x0); /* * Set the Baud Rate Counter 2 value * Baud rate (standard) = fi2cclk / ( (BRCNT2 x 2) + Foncycle ) * Foncycle = 0 (no digital filtering) */ value = (u32) (I2C_INPUT_FREQ / (speed * 2)); i2c_write_field(&i2c_regs->brcr, I2C_BRCR_BRCNT2, I2C_BRCR_SHIFT_BRCNT2, value); /* ensure that BRCNT value is zero */ i2c_write_field(&i2c_regs->brcr, I2C_BRCR_BRCNT1, I2C_BRCR_SHIFT_BRCNT1, 0); return I2C_INPUT_FREQ/(value * 2); }
/* * i2c_init - initialize the i2c bus * * speed: bus speed (in HZ) * slaveaddr: address of device in slave mode * * Slave mode is not implemented. */ void i2c_init(int speed, int slaveaddr) { struct u5500_i2c_regs *i2c_regs; debug("i2c_init bus %d, speed %d\n", i2c_bus_num, speed); u5500_clock_enable(i2c_clock_bits[i2c_bus_num].periph, i2c_clock_bits[i2c_bus_num].pcken, i2c_clock_bits[i2c_bus_num].kcken); i2c_regs = i2c_dev[i2c_bus_num]; /* Disable the controller */ i2c_clr_bit(&i2c_regs->cr, I2C_CR_PE); /* Clear registers */ writel(0, &i2c_regs->cr); writel(0, &i2c_regs->scr); writel(0, &i2c_regs->hsmcr); writel(0, &i2c_regs->tftr); writel(0, &i2c_regs->rftr); writel(0, &i2c_regs->dmar); i2c_bus_speed[i2c_bus_num] = __i2c_set_bus_speed(speed); /* * Set our own address. * Set slave address mode to 7 bit addressing mode */ i2c_clr_bit(&i2c_regs->cr, I2C_CR_SAM); i2c_write_field(&i2c_regs->scr, I2C_SCR_ADDR, I2C_SCR_SHIFT_ADDR, slaveaddr); /* Slave Data Set up Time */ i2c_write_field(&i2c_regs->scr, I2C_SCR_DATA_SETUP_TIME, I2C_SCR_SHIFT_DATA_SETUP_TIME, SLAVE_SETUP_TIME); /* Disable the DMA sync logic */ i2c_write_field(&i2c_regs->cr, I2C_CR_DMA_SLE, I2C_CR_SHIFT_DMA_SLE, 0); /* Disable interrupts */ writel(0, &i2c_regs->imscr); /* Configure bus master mode */ i2c_write_field(&i2c_regs->cr, I2C_CR_OM, I2C_CR_SHIFT_OM, I2C_BUS_MASTER_MODE); /* Set FIFO threshold values */ writel(TX_FIFO_THRESHOLD, &i2c_regs->tftr); writel(RX_FIFO_THRESHOLD, &i2c_regs->rftr); /* Enable the I2C Controller */ i2c_set_bit(&i2c_regs->cr, I2C_CR_PE); bus_initialized[i2c_bus_num] = 1; }
static void mt6311_hw_init(uint8_t i2c_num) { int ret = 0; unsigned char var[3] = {0}; /* * Phase Shedding Trim Software Setting * The phase 2 of MT6311 will enter PWM mode if the threshold is * reached. * The threshold is set according to EFUSE value. */ ret |= i2c_read_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_EFUSE_DOUT_56_63, &var[0], 0x3, 1); ret |= i2c_read_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_EFUSE_DOUT_56_63, &var[1], 0x1, 7); ret |= i2c_read_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_EFUSE_DOUT_64_71, &var[2], 0x1, 0); ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_VDVFS1_ANA_CON10, var[0] | var[1] << 2 | var[2] << 3, 0xf, 0); /* I2C_CONFIG; pushpull setting, Opendrain is '0' */ ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_TOP_INT_CON, 0x1, 0x1, 2); /* RG_WDTRSTB_EN; CC, initial WDRSTB setting. */ ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_TOP_RST_CON, 0x1, 0x1, 5); /* initial INT function */ ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_GPIO_MODE, 0x1, 0x7, 3); ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_STRUP_CON5, 0, 1 << 2 | 1 << 1 | 1 << 0, 0); /* Vo max is 1.15V */ ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_STRUP_ANA_CON1, 0x3, 0x3, 5); ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_BUCK_ALL_CON23, 0x1, 0x1, 0); ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_STRUP_ANA_CON2, 0x3, 0x3, 0); /* Suspend HW control from SPM */ ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_TOP_CON, 0x1, 0x1, 0); ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_VDVFS11_CON7, 0x1, 0x1, 0); /* default VDVFS power on */ ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_VDVFS11_CON9, 0x1, 0x1, 0); /* for DVFS slew rate rising=0.67us */ ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_VDVFS11_CON10, 0x1, 0x7f, 0); /* for DVFS slew rate, falling 2.0us */ ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_VDVFS11_CON11, 0x5, 0x7f, 0); /* default VDVFS11_VOSEL 1.0V, SW control */ ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_VDVFS11_CON12, 0x40, 0x7f, 0); /* default VDVFS11_VOSEL_ON 1.0V, HW control */ ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_VDVFS11_CON13, 0x40, 0x7f, 0); ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_VDVFS11_CON14, 0x40, 0x7f, 0); /* for DVFS sof change, falling 50us */ ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_VDVFS11_CON19, 0x3, 0x3, 0); /* for DVFS sof change, falling only */ ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_VDVFS11_CON19, 0x1, 0x3, 4); /* OFF LDO */ ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_LDO_CON3, 0, 0x1, 0); if (ret) printk(BIOS_ERR, "ERROR: %s failed\n", __func__); }
/* * 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; }