aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-mpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-mpc.c')
-rw-r--r--drivers/i2c/busses/i2c-mpc.c69
1 files changed, 47 insertions, 22 deletions
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index df00eb1f11f9..54247d475fc3 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -63,6 +63,7 @@ struct mpc_i2c {
63 wait_queue_head_t queue; 63 wait_queue_head_t queue;
64 struct i2c_adapter adap; 64 struct i2c_adapter adap;
65 int irq; 65 int irq;
66 u32 real_clk;
66}; 67};
67 68
68struct mpc_i2c_divider { 69struct mpc_i2c_divider {
@@ -96,20 +97,23 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
96/* Sometimes 9th clock pulse isn't generated, and slave doesn't release 97/* Sometimes 9th clock pulse isn't generated, and slave doesn't release
97 * the bus, because it wants to send ACK. 98 * the bus, because it wants to send ACK.
98 * Following sequence of enabling/disabling and sending start/stop generates 99 * Following sequence of enabling/disabling and sending start/stop generates
99 * the pulse, so it's all OK. 100 * the 9 pulses, so it's all OK.
100 */ 101 */
101static void mpc_i2c_fixup(struct mpc_i2c *i2c) 102static void mpc_i2c_fixup(struct mpc_i2c *i2c)
102{ 103{
103 writeccr(i2c, 0); 104 int k;
104 udelay(30); 105 u32 delay_val = 1000000 / i2c->real_clk + 1;
105 writeccr(i2c, CCR_MEN); 106
106 udelay(30); 107 if (delay_val < 2)
107 writeccr(i2c, CCR_MSTA | CCR_MTX); 108 delay_val = 2;
108 udelay(30); 109
109 writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); 110 for (k = 9; k; k--) {
110 udelay(30); 111 writeccr(i2c, 0);
111 writeccr(i2c, CCR_MEN); 112 writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
112 udelay(30); 113 udelay(delay_val);
114 writeccr(i2c, CCR_MEN);
115 udelay(delay_val << 1);
116 }
113} 117}
114 118
115static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) 119static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
@@ -190,15 +194,18 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] __devinitconst = {
190}; 194};
191 195
192static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, 196static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock,
193 int prescaler) 197 int prescaler, u32 *real_clk)
194{ 198{
195 const struct mpc_i2c_divider *div = NULL; 199 const struct mpc_i2c_divider *div = NULL;
196 unsigned int pvr = mfspr(SPRN_PVR); 200 unsigned int pvr = mfspr(SPRN_PVR);
197 u32 divider; 201 u32 divider;
198 int i; 202 int i;
199 203
200 if (clock == MPC_I2C_CLOCK_LEGACY) 204 if (clock == MPC_I2C_CLOCK_LEGACY) {
205 /* see below - default fdr = 0x3f -> div = 2048 */
206 *real_clk = mpc5xxx_get_bus_frequency(node) / 2048;
201 return -EINVAL; 207 return -EINVAL;
208 }
202 209
203 /* Determine divider value */ 210 /* Determine divider value */
204 divider = mpc5xxx_get_bus_frequency(node) / clock; 211 divider = mpc5xxx_get_bus_frequency(node) / clock;
@@ -216,7 +223,8 @@ static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock,
216 break; 223 break;
217 } 224 }
218 225
219 return div ? (int)div->fdr : -EINVAL; 226 *real_clk = mpc5xxx_get_bus_frequency(node) / div->divider;
227 return (int)div->fdr;
220} 228}
221 229
222static void __devinit mpc_i2c_setup_52xx(struct device_node *node, 230static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
@@ -231,13 +239,14 @@ static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
231 return; 239 return;
232 } 240 }
233 241
234 ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler); 242 ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler, &i2c->real_clk);
235 fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */ 243 fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */
236 244
237 writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR); 245 writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);
238 246
239 if (ret >= 0) 247 if (ret >= 0)
240 dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr); 248 dev_info(i2c->dev, "clock %u Hz (fdr=%d)\n", i2c->real_clk,
249 fdr);
241} 250}
242#else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */ 251#else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */
243static void __devinit mpc_i2c_setup_52xx(struct device_node *node, 252static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
@@ -334,14 +343,17 @@ static u32 __devinit mpc_i2c_get_sec_cfg_8xxx(void)
334} 343}
335 344
336static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, 345static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
337 u32 prescaler) 346 u32 prescaler, u32 *real_clk)
338{ 347{
339 const struct mpc_i2c_divider *div = NULL; 348 const struct mpc_i2c_divider *div = NULL;
340 u32 divider; 349 u32 divider;
341 int i; 350 int i;
342 351
343 if (clock == MPC_I2C_CLOCK_LEGACY) 352 if (clock == MPC_I2C_CLOCK_LEGACY) {
353 /* see below - default fdr = 0x1031 -> div = 16 * 3072 */
354 *real_clk = fsl_get_sys_freq() / prescaler / (16 * 3072);
344 return -EINVAL; 355 return -EINVAL;
356 }
345 357
346 /* Determine proper divider value */ 358 /* Determine proper divider value */
347 if (of_device_is_compatible(node, "fsl,mpc8544-i2c")) 359 if (of_device_is_compatible(node, "fsl,mpc8544-i2c"))
@@ -364,6 +376,7 @@ static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
364 break; 376 break;
365 } 377 }
366 378
379 *real_clk = fsl_get_sys_freq() / prescaler / div->divider;
367 return div ? (int)div->fdr : -EINVAL; 380 return div ? (int)div->fdr : -EINVAL;
368} 381}
369 382
@@ -380,7 +393,7 @@ static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
380 return; 393 return;
381 } 394 }
382 395
383 ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler); 396 ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler, &i2c->real_clk);
384 fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */ 397 fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */
385 398
386 writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR); 399 writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);
@@ -388,7 +401,7 @@ static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
388 401
389 if (ret >= 0) 402 if (ret >= 0)
390 dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n", 403 dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n",
391 clock, fdr >> 8, fdr & 0xff); 404 i2c->real_clk, fdr >> 8, fdr & 0xff);
392} 405}
393 406
394#else /* !CONFIG_FSL_SOC */ 407#else /* !CONFIG_FSL_SOC */
@@ -500,10 +513,14 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
500 return -EINTR; 513 return -EINTR;
501 } 514 }
502 if (time_after(jiffies, orig_jiffies + HZ)) { 515 if (time_after(jiffies, orig_jiffies + HZ)) {
516 u8 status = readb(i2c->base + MPC_I2C_SR);
517
503 dev_dbg(i2c->dev, "timeout\n"); 518 dev_dbg(i2c->dev, "timeout\n");
504 if (readb(i2c->base + MPC_I2C_SR) == 519 if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) {
505 (CSR_MCF | CSR_MBB | CSR_RXAK)) 520 writeb(status & ~CSR_MAL,
521 i2c->base + MPC_I2C_SR);
506 mpc_i2c_fixup(i2c); 522 mpc_i2c_fixup(i2c);
523 }
507 return -EIO; 524 return -EIO;
508 } 525 }
509 schedule(); 526 schedule();
@@ -595,6 +612,14 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
595 mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock, 0); 612 mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock, 0);
596 } 613 }
597 614
615 prop = of_get_property(op->dev.of_node, "fsl,timeout", &plen);
616 if (prop && plen == sizeof(u32)) {
617 mpc_ops.timeout = *prop * HZ / 1000000;
618 if (mpc_ops.timeout < 5)
619 mpc_ops.timeout = 5;
620 }
621 dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ);
622
598 dev_set_drvdata(&op->dev, i2c); 623 dev_set_drvdata(&op->dev, i2c);
599 624
600 i2c->adap = mpc_ops; 625 i2c->adap = mpc_ops;