From: Eero Nurkkala Date: Wed, 26 Nov 2008 13:44:15 +0000 (+0200) Subject: i2c: i2c-omap: Fix standard and fast mode prescalers X-Git-Tag: v2.6.28-omap1~7 X-Git-Url: http://www.pilppa.org/gitweb/gitweb.cgi?p=linux-2.6-omap-h63xx.git;a=commitdiff_plain;h=d3282b387ddc630393d6158e8d6cffb7b1d8a42a i2c: i2c-omap: Fix standard and fast mode prescalers The prescalers for 100 kHz and 400 kHz mode are wrong for omap 3430 and omap 2430. The internal clock is the fclock divided by the prescaler. The PSC is an 8 bit field in omap3430 and omap2430. Moreover, the scll and sclh values should be adjusted properly. Having the correct prescaler is important in the process of getting a finite i2c clock. In addition, the prescaler is used in the process of activating the correct noise filter and thus, lets more error resilient i2c communications. Signed-off-by: Eero Nurkkala Signed-off-by: Tony Lindgren --- diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 71b37ed4b72..c95368c3318 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -337,7 +337,13 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) if (cpu_is_omap2430() || cpu_is_omap34xx()) { /* HSI2C controller internal clk rate should be 19.2 Mhz */ - internal_clk = 19200; + if (dev->speed > 400) + internal_clk = 19200; + else if (dev->speed > 100) + internal_clk = 9600; + else + internal_clk = 4000; + fclk_rate = clk_get_rate(dev->fclk) / 1000; /* Compute prescaler divisor */ @@ -355,8 +361,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) hssclh = fclk_rate / (dev->speed * 2) - 6; } else { /* To handle F/S modes */ - fsscll = internal_clk / (dev->speed * 2) - 6; - fssclh = internal_clk / (dev->speed * 2) - 6; + fsscll = internal_clk / (dev->speed * 2) - 3; + fssclh = internal_clk / (dev->speed * 2) - 9; } scll = (hsscll << OMAP_I2C_SCLL_HSSCLL) | fsscll; sclh = (hssclh << OMAP_I2C_SCLH_HSSCLH) | fssclh;