diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-omap.c')
-rw-r--r-- | drivers/i2c/busses/i2c-omap.c | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index ece0125a1ee5..c73475dd0fba 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
@@ -333,8 +333,18 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) | |||
333 | 333 | ||
334 | if (cpu_is_omap2430() || cpu_is_omap34xx()) { | 334 | if (cpu_is_omap2430() || cpu_is_omap34xx()) { |
335 | 335 | ||
336 | /* HSI2C controller internal clk rate should be 19.2 Mhz */ | 336 | /* |
337 | internal_clk = 19200; | 337 | * HSI2C controller internal clk rate should be 19.2 Mhz for |
338 | * HS and for all modes on 2430. On 34xx we can use lower rate | ||
339 | * to get longer filter period for better noise suppression. | ||
340 | * The filter is iclk (fclk for HS) period. | ||
341 | */ | ||
342 | if (dev->speed > 400 || cpu_is_omap_2430()) | ||
343 | internal_clk = 19200; | ||
344 | else if (dev->speed > 100) | ||
345 | internal_clk = 9600; | ||
346 | else | ||
347 | internal_clk = 4000; | ||
338 | fclk_rate = clk_get_rate(dev->fclk) / 1000; | 348 | fclk_rate = clk_get_rate(dev->fclk) / 1000; |
339 | 349 | ||
340 | /* Compute prescaler divisor */ | 350 | /* Compute prescaler divisor */ |
@@ -343,17 +353,28 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) | |||
343 | 353 | ||
344 | /* If configured for High Speed */ | 354 | /* If configured for High Speed */ |
345 | if (dev->speed > 400) { | 355 | if (dev->speed > 400) { |
356 | unsigned long scl; | ||
357 | |||
346 | /* For first phase of HS mode */ | 358 | /* For first phase of HS mode */ |
347 | fsscll = internal_clk / (400 * 2) - 6; | 359 | scl = internal_clk / 400; |
348 | fssclh = internal_clk / (400 * 2) - 6; | 360 | fsscll = scl - (scl / 3) - 7; |
361 | fssclh = (scl / 3) - 5; | ||
349 | 362 | ||
350 | /* For second phase of HS mode */ | 363 | /* For second phase of HS mode */ |
351 | hsscll = fclk_rate / (dev->speed * 2) - 6; | 364 | scl = fclk_rate / dev->speed; |
352 | hssclh = fclk_rate / (dev->speed * 2) - 6; | 365 | hsscll = scl - (scl / 3) - 7; |
366 | hssclh = (scl / 3) - 5; | ||
367 | } else if (dev->speed > 100) { | ||
368 | unsigned long scl; | ||
369 | |||
370 | /* Fast mode */ | ||
371 | scl = internal_clk / dev->speed; | ||
372 | fsscll = scl - (scl / 3) - 7; | ||
373 | fssclh = (scl / 3) - 5; | ||
353 | } else { | 374 | } else { |
354 | /* To handle F/S modes */ | 375 | /* Standard mode */ |
355 | fsscll = internal_clk / (dev->speed * 2) - 6; | 376 | fsscll = internal_clk / (dev->speed * 2) - 7; |
356 | fssclh = internal_clk / (dev->speed * 2) - 6; | 377 | fssclh = internal_clk / (dev->speed * 2) - 5; |
357 | } | 378 | } |
358 | scll = (hsscll << OMAP_I2C_SCLL_HSSCLL) | fsscll; | 379 | scll = (hsscll << OMAP_I2C_SCLL_HSSCLL) | fsscll; |
359 | sclh = (hssclh << OMAP_I2C_SCLH_HSSCLH) | fssclh; | 380 | sclh = (hssclh << OMAP_I2C_SCLH_HSSCLH) | fssclh; |