aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-designware-core.c27
-rw-r--r--drivers/i2c/busses/i2c-designware-core.h2
-rw-r--r--drivers/i2c/busses/i2c-designware-platdrv.c7
3 files changed, 25 insertions, 11 deletions
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c
index 14c4b30d4ccc..22e92c3d3d07 100644
--- a/drivers/i2c/busses/i2c-designware-core.c
+++ b/drivers/i2c/busses/i2c-designware-core.c
@@ -218,7 +218,7 @@ i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
218 * 218 *
219 * If your hardware is free from tHD;STA issue, try this one. 219 * If your hardware is free from tHD;STA issue, try this one.
220 */ 220 */
221 return (ic_clk * tSYMBOL + 5000) / 10000 - 8 + offset; 221 return (ic_clk * tSYMBOL + 500000) / 1000000 - 8 + offset;
222 else 222 else
223 /* 223 /*
224 * Conditional expression: 224 * Conditional expression:
@@ -234,7 +234,8 @@ i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
234 * The reason why we need to take into account "tf" here, 234 * The reason why we need to take into account "tf" here,
235 * is the same as described in i2c_dw_scl_lcnt(). 235 * is the same as described in i2c_dw_scl_lcnt().
236 */ 236 */
237 return (ic_clk * (tSYMBOL + tf) + 5000) / 10000 - 3 + offset; 237 return (ic_clk * (tSYMBOL + tf) + 500000) / 1000000
238 - 3 + offset;
238} 239}
239 240
240static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) 241static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)
@@ -250,7 +251,7 @@ static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)
250 * account the fall time of SCL signal (tf). Default tf value 251 * account the fall time of SCL signal (tf). Default tf value
251 * should be 0.3 us, for safety. 252 * should be 0.3 us, for safety.
252 */ 253 */
253 return ((ic_clk * (tLOW + tf) + 5000) / 10000) - 1 + offset; 254 return ((ic_clk * (tLOW + tf) + 500000) / 1000000) - 1 + offset;
254} 255}
255 256
256static void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable) 257static void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable)
@@ -287,6 +288,7 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
287 u32 input_clock_khz; 288 u32 input_clock_khz;
288 u32 hcnt, lcnt; 289 u32 hcnt, lcnt;
289 u32 reg; 290 u32 reg;
291 u32 sda_falling_time, scl_falling_time;
290 292
291 input_clock_khz = dev->get_clk_rate_khz(dev); 293 input_clock_khz = dev->get_clk_rate_khz(dev);
292 294
@@ -308,15 +310,18 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
308 310
309 /* set standard and fast speed deviders for high/low periods */ 311 /* set standard and fast speed deviders for high/low periods */
310 312
313 sda_falling_time = dev->sda_falling_time ?: 300; /* ns */
314 scl_falling_time = dev->scl_falling_time ?: 300; /* ns */
315
311 /* Standard-mode */ 316 /* Standard-mode */
312 hcnt = i2c_dw_scl_hcnt(input_clock_khz, 317 hcnt = i2c_dw_scl_hcnt(input_clock_khz,
313 40, /* tHD;STA = tHIGH = 4.0 us */ 318 4000, /* tHD;STA = tHIGH = 4.0 us */
314 3, /* tf = 0.3 us */ 319 sda_falling_time,
315 0, /* 0: DW default, 1: Ideal */ 320 0, /* 0: DW default, 1: Ideal */
316 0); /* No offset */ 321 0); /* No offset */
317 lcnt = i2c_dw_scl_lcnt(input_clock_khz, 322 lcnt = i2c_dw_scl_lcnt(input_clock_khz,
318 47, /* tLOW = 4.7 us */ 323 4700, /* tLOW = 4.7 us */
319 3, /* tf = 0.3 us */ 324 scl_falling_time,
320 0); /* No offset */ 325 0); /* No offset */
321 326
322 /* Allow platforms to specify the ideal HCNT and LCNT values */ 327 /* Allow platforms to specify the ideal HCNT and LCNT values */
@@ -330,13 +335,13 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
330 335
331 /* Fast-mode */ 336 /* Fast-mode */
332 hcnt = i2c_dw_scl_hcnt(input_clock_khz, 337 hcnt = i2c_dw_scl_hcnt(input_clock_khz,
333 6, /* tHD;STA = tHIGH = 0.6 us */ 338 600, /* tHD;STA = tHIGH = 0.6 us */
334 3, /* tf = 0.3 us */ 339 sda_falling_time,
335 0, /* 0: DW default, 1: Ideal */ 340 0, /* 0: DW default, 1: Ideal */
336 0); /* No offset */ 341 0); /* No offset */
337 lcnt = i2c_dw_scl_lcnt(input_clock_khz, 342 lcnt = i2c_dw_scl_lcnt(input_clock_khz,
338 13, /* tLOW = 1.3 us */ 343 1300, /* tLOW = 1.3 us */
339 3, /* tf = 0.3 us */ 344 scl_falling_time,
340 0); /* No offset */ 345 0); /* No offset */
341 346
342 if (dev->fs_hcnt && dev->fs_lcnt) { 347 if (dev->fs_hcnt && dev->fs_lcnt) {
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index e8a756537ed0..d66b6cbc9edc 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -99,6 +99,8 @@ struct dw_i2c_dev {
99 unsigned int rx_fifo_depth; 99 unsigned int rx_fifo_depth;
100 int rx_outstanding; 100 int rx_outstanding;
101 u32 sda_hold_time; 101 u32 sda_hold_time;
102 u32 sda_falling_time;
103 u32 scl_falling_time;
102 u16 ss_hcnt; 104 u16 ss_hcnt;
103 u16 ss_lcnt; 105 u16 ss_lcnt;
104 u16 fs_hcnt; 106 u16 fs_hcnt;
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index d0bdac0498ce..fc243992b4b4 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -159,6 +159,13 @@ static int dw_i2c_probe(struct platform_device *pdev)
159 "i2c-sda-hold-time-ns", &ht); 159 "i2c-sda-hold-time-ns", &ht);
160 dev->sda_hold_time = div_u64((u64)ic_clk * ht + 500000, 160 dev->sda_hold_time = div_u64((u64)ic_clk * ht + 500000,
161 1000000); 161 1000000);
162
163 of_property_read_u32(pdev->dev.of_node,
164 "i2c-sda-falling-time-ns",
165 &dev->sda_falling_time);
166 of_property_read_u32(pdev->dev.of_node,
167 "i2c-scl-falling-time-ns",
168 &dev->scl_falling_time);
162 } 169 }
163 170
164 dev->functionality = 171 dev->functionality =