aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorShinya Kuribayashi <shinya.kuribayashi.px@renesas.com>2012-10-24 06:57:27 -0400
committerWolfram Sang <w.sang@pengutronix.de>2012-11-16 03:07:43 -0500
commit23a612916a51cc3772ff46c9dc34a86c9c50840e (patch)
treef1cff85dd93d7cfa457b7d22dd3d00122b3a548f /drivers/i2c
parent7b0e62920ac314eb819e68b7d2c51994b98b19ca (diff)
i2c: i2c-sh_mobile: optimize ICCH/ICCL values according to I2C bus speed
ICCH/ICCL values is supposed to be calculated/optimized to strictly meet the timing specs required by the I2C standard. The resulting I2C bus speed does not matter at all, if it's less than 100 or 400 kHz. With this change, sh_mobile_i2c_icch() is virtually identical to sh_mobile_i2c_iccl(), but they're providing good descriptions of SH-/R-Mobile I2C hardware spec, and I'd leave them as separated. Also fix a typo in the comment, print icch/iccl values at probe, etc. Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com> [wsa: squashed two patches for bisectability] Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-sh_mobile.c126
1 files changed, 77 insertions, 49 deletions
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index 309d0d592890..4dc0cc3611c2 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -122,9 +122,9 @@ struct sh_mobile_i2c_data {
122 unsigned long bus_speed; 122 unsigned long bus_speed;
123 struct clk *clk; 123 struct clk *clk;
124 u_int8_t icic; 124 u_int8_t icic;
125 u_int8_t iccl;
126 u_int8_t icch;
127 u_int8_t flags; 125 u_int8_t flags;
126 u_int16_t iccl;
127 u_int16_t icch;
128 128
129 spinlock_t lock; 129 spinlock_t lock;
130 wait_queue_head_t wait; 130 wait_queue_head_t wait;
@@ -135,7 +135,8 @@ struct sh_mobile_i2c_data {
135 135
136#define IIC_FLAG_HAS_ICIC67 (1 << 0) 136#define IIC_FLAG_HAS_ICIC67 (1 << 0)
137 137
138#define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */ 138#define STANDARD_MODE 100000
139#define FAST_MODE 400000
139 140
140/* Register offsets */ 141/* Register offsets */
141#define ICDR 0x00 142#define ICDR 0x00
@@ -187,55 +188,81 @@ static void iic_set_clr(struct sh_mobile_i2c_data *pd, int offs,
187 iic_wr(pd, offs, (iic_rd(pd, offs) | set) & ~clr); 188 iic_wr(pd, offs, (iic_rd(pd, offs) | set) & ~clr);
188} 189}
189 190
191static u32 sh_mobile_i2c_iccl(unsigned long count_khz, u32 tLOW, u32 tf, int offset)
192{
193 /*
194 * Conditional expression:
195 * ICCL >= COUNT_CLK * (tLOW + tf)
196 *
197 * SH-Mobile IIC hardware starts counting the LOW period of
198 * the SCL signal (tLOW) as soon as it pulls the SCL line.
199 * In order to meet the tLOW timing spec, we need to take into
200 * account the fall time of SCL signal (tf). Default tf value
201 * should be 0.3 us, for safety.
202 */
203 return (((count_khz * (tLOW + tf)) + 5000) / 10000) + offset;
204}
205
206static u32 sh_mobile_i2c_icch(unsigned long count_khz, u32 tHIGH, u32 tf, int offset)
207{
208 /*
209 * Conditional expression:
210 * ICCH >= COUNT_CLK * (tHIGH + tf)
211 *
212 * SH-Mobile IIC hardware is aware of SCL transition period 'tr',
213 * and can ignore it. SH-Mobile IIC controller starts counting
214 * the HIGH period of the SCL signal (tHIGH) after the SCL input
215 * voltage increases at VIH.
216 *
217 * Afterward it turned out calculating ICCH using only tHIGH spec
218 * will result in violation of the tHD;STA timing spec. We need
219 * to take into account the fall time of SDA signal (tf) at START
220 * condition, in order to meet both tHIGH and tHD;STA specs.
221 */
222 return (((count_khz * (tHIGH + tf)) + 5000) / 10000) + offset;
223}
224
190static void sh_mobile_i2c_init(struct sh_mobile_i2c_data *pd) 225static void sh_mobile_i2c_init(struct sh_mobile_i2c_data *pd)
191{ 226{
192 unsigned long i2c_clk; 227 unsigned long i2c_clk_khz;
193 u_int32_t num; 228 u32 tHIGH, tLOW, tf;
194 u_int32_t denom; 229 int offset;
195 u_int32_t tmp;
196 230
197 /* Get clock rate after clock is enabled */ 231 /* Get clock rate after clock is enabled */
198 clk_enable(pd->clk); 232 clk_enable(pd->clk);
199 i2c_clk = clk_get_rate(pd->clk); 233 i2c_clk_khz = clk_get_rate(pd->clk) / 1000;
200 234
201 /* Calculate the value for iccl. From the data sheet: 235 if (pd->bus_speed == STANDARD_MODE) {
202 * iccl = (p clock / transfer rate) * (L / (L + H)) 236 tLOW = 47; /* tLOW = 4.7 us */
203 * where L and H are the SCL low/high ratio (5/4 in this case). 237 tHIGH = 40; /* tHD;STA = tHIGH = 4.0 us */
204 * We also round off the result. 238 tf = 3; /* tf = 0.3 us */
205 */ 239 offset = 0; /* No offset */
206 num = i2c_clk * 5; 240 } else if (pd->bus_speed == FAST_MODE) {
207 denom = pd->bus_speed * 9; 241 tLOW = 13; /* tLOW = 1.3 us */
208 tmp = num * 10 / denom; 242 tHIGH = 6; /* tHD;STA = tHIGH = 0.6 us */
209 if (tmp % 10 >= 5) 243 tf = 3; /* tf = 0.3 us */
210 pd->iccl = (u_int8_t)((num/denom) + 1); 244 offset = 0; /* No offset */
211 else 245 } else {
212 pd->iccl = (u_int8_t)(num/denom); 246 dev_err(pd->dev, "unrecognized bus speed %lu Hz\n",
213 247 pd->bus_speed);
214 /* one more bit of ICCL in ICIC */ 248 goto out;
215 if (pd->flags & IIC_FLAG_HAS_ICIC67) {
216 if ((num/denom) > 0xff)
217 pd->icic |= ICIC_ICCLB8;
218 else
219 pd->icic &= ~ICIC_ICCLB8;
220 } 249 }
221 250
222 /* Calculate the value for icch. From the data sheet: 251 pd->iccl = sh_mobile_i2c_iccl(i2c_clk_khz, tLOW, tf, offset);
223 icch = (p clock / transfer rate) * (H / (L + H)) */ 252 /* one more bit of ICCL in ICIC */
224 num = i2c_clk * 4; 253 if ((pd->iccl > 0xff) && (pd->flags & IIC_FLAG_HAS_ICIC67))
225 tmp = num * 10 / denom; 254 pd->icic |= ICIC_ICCLB8;
226 if (tmp % 10 >= 5)
227 pd->icch = (u_int8_t)((num/denom) + 1);
228 else 255 else
229 pd->icch = (u_int8_t)(num/denom); 256 pd->icic &= ~ICIC_ICCLB8;
230 257
258 pd->icch = sh_mobile_i2c_icch(i2c_clk_khz, tHIGH, tf, offset);
231 /* one more bit of ICCH in ICIC */ 259 /* one more bit of ICCH in ICIC */
232 if (pd->flags & IIC_FLAG_HAS_ICIC67) { 260 if ((pd->icch > 0xff) && (pd->flags & IIC_FLAG_HAS_ICIC67))
233 if ((num/denom) > 0xff) 261 pd->icic |= ICIC_ICCHB8;
234 pd->icic |= ICIC_ICCHB8; 262 else
235 else 263 pd->icic &= ~ICIC_ICCHB8;
236 pd->icic &= ~ICIC_ICCHB8;
237 }
238 264
265out:
239 clk_disable(pd->clk); 266 clk_disable(pd->clk);
240} 267}
241 268
@@ -252,8 +279,8 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
252 iic_wr(pd, ICIC, 0); 279 iic_wr(pd, ICIC, 0);
253 280
254 /* Set the clock */ 281 /* Set the clock */
255 iic_wr(pd, ICCL, pd->iccl); 282 iic_wr(pd, ICCL, pd->iccl & 0xff);
256 iic_wr(pd, ICCH, pd->icch); 283 iic_wr(pd, ICCH, pd->icch & 0xff);
257} 284}
258 285
259static void deactivate_ch(struct sh_mobile_i2c_data *pd) 286static void deactivate_ch(struct sh_mobile_i2c_data *pd)
@@ -457,8 +484,8 @@ static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg)
457 iic_set_clr(pd, ICCR, ICCR_ICE, 0); 484 iic_set_clr(pd, ICCR, ICCR_ICE, 0);
458 485
459 /* Set the clock */ 486 /* Set the clock */
460 iic_wr(pd, ICCL, pd->iccl); 487 iic_wr(pd, ICCL, pd->iccl & 0xff);
461 iic_wr(pd, ICCH, pd->icch); 488 iic_wr(pd, ICCH, pd->icch & 0xff);
462 489
463 pd->msg = usr_msg; 490 pd->msg = usr_msg;
464 pd->pos = -1; 491 pd->pos = -1;
@@ -627,8 +654,8 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
627 goto err_irq; 654 goto err_irq;
628 } 655 }
629 656
630 /* Use platformd data bus speed or NORMAL_SPEED */ 657 /* Use platform data bus speed or STANDARD_MODE */
631 pd->bus_speed = NORMAL_SPEED; 658 pd->bus_speed = STANDARD_MODE;
632 if (pdata && pdata->bus_speed) 659 if (pdata && pdata->bus_speed)
633 pd->bus_speed = pdata->bus_speed; 660 pd->bus_speed = pdata->bus_speed;
634 661
@@ -675,8 +702,9 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
675 goto err_all; 702 goto err_all;
676 } 703 }
677 704
678 dev_info(&dev->dev, "I2C adapter %d with bus speed %lu Hz\n", 705 dev_info(&dev->dev,
679 adap->nr, pd->bus_speed); 706 "I2C adapter %d with bus speed %lu Hz (L/H=%x/%x)\n",
707 adap->nr, pd->bus_speed, pd->iccl, pd->icch);
680 708
681 of_i2c_register_devices(adap); 709 of_i2c_register_devices(adap);
682 return 0; 710 return 0;