+ /*
+ * 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;
+ }