-int i2c_set_bus_speed(unsigned int speed)
-{
- struct mxs_i2c_regs *i2c_regs = (struct mxs_i2c_regs *)MXS_I2C0_BASE;
- /*
- * The timing derivation algorithm. There is no documentation for this
- * algorithm available, it was derived by using the scope and fiddling
- * with constants until the result observed on the scope was good enough
- * for 20kHz, 50kHz, 100kHz, 200kHz, 300kHz and 400kHz. It should be
- * possible to assume the algorithm works for other frequencies as well.
- *
- * Note it was necessary to cap the frequency on both ends as it's not
- * possible to configure completely arbitrary frequency for the I2C bus
- * clock.
- */
- uint32_t clk = mxc_get_clock(MXC_XTAL_CLK);
- uint32_t base = ((clk / speed) - 38) / 2;
- uint16_t high_count = base + 3;
- uint16_t low_count = base - 3;
- uint16_t rcv_count = (high_count * 3) / 4;
- uint16_t xmit_count = low_count / 4;
-
- if (speed > 540000) {
- printf("MXS I2C: Speed too high (%d Hz)\n", speed);
- return -EINVAL;
- }
-
- if (speed < 12000) {
- printf("MXS I2C: Speed too low (%d Hz)\n", speed);
- return -EINVAL;
- }
-
- writel((high_count << 16) | rcv_count, &i2c_regs->hw_i2c_timing0);
- writel((low_count << 16) | xmit_count, &i2c_regs->hw_i2c_timing1);
-
- writel((0x0030 << I2C_TIMING2_BUS_FREE_OFFSET) |
- (0x0030 << I2C_TIMING2_LEADIN_COUNT_OFFSET),
- &i2c_regs->hw_i2c_timing2);
-
- return 0;
-}
-
-unsigned int i2c_get_bus_speed(void)
-{
- struct mxs_i2c_regs *i2c_regs = (struct mxs_i2c_regs *)MXS_I2C0_BASE;
- uint32_t clk = mxc_get_clock(MXC_XTAL_CLK);
- uint32_t timing0;
-
- timing0 = readl(&i2c_regs->hw_i2c_timing0);
- /*
- * This is a reverse version of the algorithm presented in
- * i2c_set_bus_speed(). Please refer there for details.
- */
- return clk / ((((timing0 >> 16) - 3) * 2) + 38);
-}
-
-void i2c_init(int speed, int slaveadd)