aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorWolfgang Grandegger <wg@denx.de>2010-02-17 05:19:19 -0500
committerBen Dooks <ben-linux@fluff.org>2010-03-07 17:03:09 -0500
commitf00d738f04899534e2c372b2ad8b670050a945e2 (patch)
tree596fd931e26ee47c97c8b28df3a30b262af0dd51 /drivers/i2c
parenta93522116ee5aa13eeb74c0fd73d8c5d15211e64 (diff)
i2c-mpc: add support for the MPC512x processors from Freescale
As I2C interrupts must be enabled for the MPC512x by the setup function as well, "fsl,preserve-clocking" is handled in a slighly different way. Also, the old settings are now reported calling dev_dbg(). For the MPC512x the clock setup function of the MPC52xx can be re-used. Furthermore, the Kconfig help has been updated and corrected. Signed-off-by: Wolfgang Grandegger <wg@denx.de> Reviewed-by: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/Kconfig7
-rw-r--r--drivers/i2c/busses/i2c-mpc.c93
2 files changed, 78 insertions, 22 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 10041813c6ed..ecf079b7f931 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -419,13 +419,12 @@ config I2C_IXP2000
419 instead. 419 instead.
420 420
421config I2C_MPC 421config I2C_MPC
422 tristate "MPC107/824x/85xx/52xx/86xx" 422 tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"
423 depends on PPC32 423 depends on PPC32
424 help 424 help
425 If you say yes to this option, support will be included for the 425 If you say yes to this option, support will be included for the
426 built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and 426 built-in I2C interface on the MPC107, Tsi107, MPC512x, MPC52xx,
427 MPC85xx/MPC8641 family processors. The driver may also work on 52xx 427 MPC8240, MPC8245, MPC83xx, MPC85xx and MPC8641 family processors.
428 family processors, though interrupts are known not to work.
429 428
430 This driver can also be built as a module. If so, the module 429 This driver can also be built as a module. If so, the module
431 will be called i2c-mpc. 430 will be called i2c-mpc.
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 370c342e5e81..78a15af32942 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -31,6 +31,9 @@
31 31
32#define DRV_NAME "mpc-i2c" 32#define DRV_NAME "mpc-i2c"
33 33
34#define MPC_I2C_CLOCK_LEGACY 0
35#define MPC_I2C_CLOCK_PRESERVE (~0U)
36
34#define MPC_I2C_FDR 0x04 37#define MPC_I2C_FDR 0x04
35#define MPC_I2C_CR 0x08 38#define MPC_I2C_CR 0x08
36#define MPC_I2C_SR 0x0c 39#define MPC_I2C_SR 0x0c
@@ -163,7 +166,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
163 return 0; 166 return 0;
164} 167}
165 168
166#ifdef CONFIG_PPC_MPC52xx 169#if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_PPC_MPC512x)
167static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] __devinitconst = { 170static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] __devinitconst = {
168 {20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23}, 171 {20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23},
169 {28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02}, 172 {28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02},
@@ -193,7 +196,7 @@ static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock,
193 u32 divider; 196 u32 divider;
194 int i; 197 int i;
195 198
196 if (!clock) 199 if (clock == MPC_I2C_CLOCK_LEGACY)
197 return -EINVAL; 200 return -EINVAL;
198 201
199 /* Determine divider value */ 202 /* Determine divider value */
@@ -221,6 +224,12 @@ static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
221{ 224{
222 int ret, fdr; 225 int ret, fdr;
223 226
227 if (clock == MPC_I2C_CLOCK_PRESERVE) {
228 dev_dbg(i2c->dev, "using fdr %d\n",
229 readb(i2c->base + MPC_I2C_FDR));
230 return;
231 }
232
224 ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler); 233 ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler);
225 fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */ 234 fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */
226 235
@@ -229,13 +238,49 @@ static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
229 if (ret >= 0) 238 if (ret >= 0)
230 dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr); 239 dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr);
231} 240}
232#else /* !CONFIG_PPC_MPC52xx */ 241#else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */
233static void __devinit mpc_i2c_setup_52xx(struct device_node *node, 242static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
234 struct mpc_i2c *i2c, 243 struct mpc_i2c *i2c,
235 u32 clock, u32 prescaler) 244 u32 clock, u32 prescaler)
236{ 245{
237} 246}
238#endif /* CONFIG_PPC_MPC52xx*/ 247#endif /* CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x */
248
249#ifdef CONFIG_PPC_MPC512x
250static void __devinit mpc_i2c_setup_512x(struct device_node *node,
251 struct mpc_i2c *i2c,
252 u32 clock, u32 prescaler)
253{
254 struct device_node *node_ctrl;
255 void __iomem *ctrl;
256 const u32 *pval;
257 u32 idx;
258
259 /* Enable I2C interrupts for mpc5121 */
260 node_ctrl = of_find_compatible_node(NULL, NULL,
261 "fsl,mpc5121-i2c-ctrl");
262 if (node_ctrl) {
263 ctrl = of_iomap(node_ctrl, 0);
264 if (ctrl) {
265 /* Interrupt enable bits for i2c-0/1/2: bit 24/26/28 */
266 pval = of_get_property(node, "reg", NULL);
267 idx = (*pval & 0xff) / 0x20;
268 setbits32(ctrl, 1 << (24 + idx * 2));
269 iounmap(ctrl);
270 }
271 of_node_put(node_ctrl);
272 }
273
274 /* The clock setup for the 52xx works also fine for the 512x */
275 mpc_i2c_setup_52xx(node, i2c, clock, prescaler);
276}
277#else /* CONFIG_PPC_MPC512x */
278static void __devinit mpc_i2c_setup_512x(struct device_node *node,
279 struct mpc_i2c *i2c,
280 u32 clock, u32 prescaler)
281{
282}
283#endif /* CONFIG_PPC_MPC512x */
239 284
240#ifdef CONFIG_FSL_SOC 285#ifdef CONFIG_FSL_SOC
241static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] __devinitconst = { 286static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] __devinitconst = {
@@ -294,7 +339,7 @@ static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
294 u32 divider; 339 u32 divider;
295 int i; 340 int i;
296 341
297 if (!clock) 342 if (clock == MPC_I2C_CLOCK_LEGACY)
298 return -EINVAL; 343 return -EINVAL;
299 344
300 /* Determine proper divider value */ 345 /* Determine proper divider value */
@@ -327,6 +372,13 @@ static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
327{ 372{
328 int ret, fdr; 373 int ret, fdr;
329 374
375 if (clock == MPC_I2C_CLOCK_PRESERVE) {
376 dev_dbg(i2c->dev, "using dfsrr %d, fdr %d\n",
377 readb(i2c->base + MPC_I2C_DFSRR),
378 readb(i2c->base + MPC_I2C_FDR));
379 return;
380 }
381
330 ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler); 382 ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler);
331 fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */ 383 fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */
332 384
@@ -495,7 +547,7 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
495{ 547{
496 struct mpc_i2c *i2c; 548 struct mpc_i2c *i2c;
497 const u32 *prop; 549 const u32 *prop;
498 u32 clock = 0; 550 u32 clock = MPC_I2C_CLOCK_LEGACY;
499 int result = 0; 551 int result = 0;
500 int plen; 552 int plen;
501 553
@@ -524,20 +576,21 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
524 } 576 }
525 } 577 }
526 578
527 if (!of_get_property(op->node, "fsl,preserve-clocking", NULL)) { 579 if (of_get_property(op->node, "fsl,preserve-clocking", NULL)) {
580 clock = MPC_I2C_CLOCK_PRESERVE;
581 } else {
528 prop = of_get_property(op->node, "clock-frequency", &plen); 582 prop = of_get_property(op->node, "clock-frequency", &plen);
529 if (prop && plen == sizeof(u32)) 583 if (prop && plen == sizeof(u32))
530 clock = *prop; 584 clock = *prop;
585 }
531 586
532 if (match->data) { 587 if (match->data) {
533 struct mpc_i2c_data *data = 588 struct mpc_i2c_data *data = match->data;
534 (struct mpc_i2c_data *)match->data; 589 data->setup(op->node, i2c, clock, data->prescaler);
535 data->setup(op->node, i2c, clock, data->prescaler); 590 } else {
536 } else { 591 /* Backwards compatibility */
537 /* Backwards compatibility */ 592 if (of_get_property(op->node, "dfsrr", NULL))
538 if (of_get_property(op->node, "dfsrr", NULL)) 593 mpc_i2c_setup_8xxx(op->node, i2c, clock, 0);
539 mpc_i2c_setup_8xxx(op->node, i2c, clock, 0);
540 }
541 } 594 }
542 595
543 dev_set_drvdata(&op->dev, i2c); 596 dev_set_drvdata(&op->dev, i2c);
@@ -582,6 +635,10 @@ static int __devexit fsl_i2c_remove(struct of_device *op)
582 return 0; 635 return 0;
583}; 636};
584 637
638static struct mpc_i2c_data mpc_i2c_data_512x __devinitdata = {
639 .setup = mpc_i2c_setup_512x,
640};
641
585static struct mpc_i2c_data mpc_i2c_data_52xx __devinitdata = { 642static struct mpc_i2c_data mpc_i2c_data_52xx __devinitdata = {
586 .setup = mpc_i2c_setup_52xx, 643 .setup = mpc_i2c_setup_52xx,
587}; 644};
@@ -604,6 +661,7 @@ static const struct of_device_id mpc_i2c_of_match[] = {
604 {.compatible = "mpc5200-i2c", .data = &mpc_i2c_data_52xx, }, 661 {.compatible = "mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
605 {.compatible = "fsl,mpc5200b-i2c", .data = &mpc_i2c_data_52xx, }, 662 {.compatible = "fsl,mpc5200b-i2c", .data = &mpc_i2c_data_52xx, },
606 {.compatible = "fsl,mpc5200-i2c", .data = &mpc_i2c_data_52xx, }, 663 {.compatible = "fsl,mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
664 {.compatible = "fsl,mpc5121-i2c", .data = &mpc_i2c_data_512x, },
607 {.compatible = "fsl,mpc8313-i2c", .data = &mpc_i2c_data_8313, }, 665 {.compatible = "fsl,mpc8313-i2c", .data = &mpc_i2c_data_8313, },
608 {.compatible = "fsl,mpc8543-i2c", .data = &mpc_i2c_data_8543, }, 666 {.compatible = "fsl,mpc8543-i2c", .data = &mpc_i2c_data_8543, },
609 {.compatible = "fsl,mpc8544-i2c", .data = &mpc_i2c_data_8544, }, 667 {.compatible = "fsl,mpc8544-i2c", .data = &mpc_i2c_data_8544, },
@@ -613,7 +671,6 @@ static const struct of_device_id mpc_i2c_of_match[] = {
613}; 671};
614MODULE_DEVICE_TABLE(of, mpc_i2c_of_match); 672MODULE_DEVICE_TABLE(of, mpc_i2c_of_match);
615 673
616
617/* Structure for a device driver */ 674/* Structure for a device driver */
618static struct of_platform_driver mpc_i2c_driver = { 675static struct of_platform_driver mpc_i2c_driver = {
619 .match_table = mpc_i2c_of_match, 676 .match_table = mpc_i2c_of_match,
@@ -646,5 +703,5 @@ module_exit(fsl_i2c_exit);
646 703
647MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>"); 704MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
648MODULE_DESCRIPTION("I2C-Bus adapter for MPC107 bridge and " 705MODULE_DESCRIPTION("I2C-Bus adapter for MPC107 bridge and "
649 "MPC824x/85xx/52xx processors"); 706 "MPC824x/83xx/85xx/86xx/512x/52xx processors");
650MODULE_LICENSE("GPL"); 707MODULE_LICENSE("GPL");