
-----Original Message----- From: Tom Rix [mailto:Tom.Rix@windriver.com] Sent: Wednesday, June 10, 2009 7:54 AM
void i2c_init (int speed, int slaveadd) {
- u16 scl;
int psc, iclk, scll, sclh;
/* Only handle standard and fast speeds */
if ((speed != OMAP_I2C_STANDARD) &&
(speed != OMAP_I2C_FAST_MODE)) {
printf("Error : I2C unsupported speed %d\n", speed);
return;
}
/*
* Calculate the prescalar to go from from the function clock
* to the internal sampling clock, 12MHz.
*/
psc = I2C_PSC_MAX;
while (psc >= I2C_PSC_MIN) {
iclk = I2C_IP_CLK / (psc + 1);
if (12000000 <= iclk)
break;
psc--;
}
if (psc < I2C_PSC_MIN) {
printf("Error : I2C unsupported prescalar %d\n", psc);
return;
}
/*
* How the low and high time periods are calculated
* See the OMAP3xxx Reference Manual for more details
*
* tlow + thigh = 1 / speed
* thigh = tlow, nice square wave..
*
* tlow = 1 / (2 * speed) = (scll + 7) / iclk;
* scll + 7 = iclk / 2 * speed
* sclh + 5 = iclk / 2 * speed
*/
scll = sclh = iclk / (2 * speed);
scll -= 7;
sclh -= 5;
if ((scll < 0) || (sclh < 0)) {
printf("Error : I2C initializing clock\n");
return;
}
writew(0x2, I2C_SYSC); /* for ES2 after soft reset */ udelay(1000);
@@ -42,12 +84,10 @@ void i2c_init (int speed, int slaveadd) udelay (50000);
This is a repeat story of what happened in linux-omap and kernel. We had a similar discussion in [1] and related patch [2] to change equations. I have the same reservations with this patch: a) using speed as default does not scale for all board combinations. b) need flexible option to provide scll and sclh on a platform basis. Regards, Nishanth Menon Ref: [1] http://marc.info/?t=123540865900002&r=1&w=2 [2] http://marc.info/?l=linux-omap&m=122770723311340&w=2