aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-mv64xxx.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-28 16:43:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-28 16:43:12 -0400
commita410963ba4c0c768302f0298e258b1ee940e8316 (patch)
treef262f101a5bf752ce14775da080aed5fbaf73f0e /drivers/i2c/busses/i2c-mv64xxx.c
parentf7da9cdf45cbbad5029d4858dcbc0134e06084ed (diff)
parent5db20c49e2d6581797c17057e068d89d6677aa24 (diff)
Merge branch 'i2c-embedded/for-next' of git://git.pengutronix.de/git/wsa/linux
Pull embedded i2c changes from Wolfram Sang: "Changes for the "embedded" part of the I2C subsystem: - lots of devicetree conversions of drivers (and preparations for that) - big cleanups for drivers for OMAP, Tegra, Nomadik, Blackfin - Rafael's struct dev_pm_ops conversion patches for I2C - usual driver cleanups and fixes All patches have been in linux-next for an apropriate time and all patches touching files outside of i2c-folders should have proper acks from the maintainers." * 'i2c-embedded/for-next' of git://git.pengutronix.de/git/wsa/linux: (60 commits) Revert "i2c: tegra: convert normal suspend/resume to *_noirq" I2C: MV64XYZ: Add Device Tree support i2c: stu300: use devm managed resources i2c: i2c-ocores: support for 16bit and 32bit IO V4L/DVB: mfd: use reg_shift instead of regstep i2c: i2c-ocores: Use reg-shift property i2c: i2c-ocores: DT bindings and minor fixes. i2c: mv64xxxx: remove EXPERIMENTAL tag i2c-s3c2410: Use plain pm_runtime_put() i2c: s3c2410: Fix pointer type passed to of_match_node() i2c: mxs: Set I2C timing registers for mxs-i2c i2c: i2c-bfin-twi: Move blackfin TWI register access Macro to head file. i2c: i2c-bfin-twi: Move TWI peripheral pin request array to platform data. i2c:i2c-bfin-twi: include twi head file i2c:i2c-bfin-twi: TWI fails to restart next transfer in high system load. i2c: i2c-bfin-twi: Tighten condition when failing I2C transfer if MEN bit is reset unexpectedly. i2c: i2c-bfin-twi: Break dead waiting loop if i2c device misbehaves. i2c: i2c-bfin-twi: Improve the patch for bug "Illegal i2c bus lock upon certain transfer scenarios". i2c: i2c-bfin-twi: Illegal i2c bus lock upon certain transfer scenarios. i2c-mv64xxxx: allow more than one driver instance ... Conflicts: drivers/i2c/busses/i2c-nomadik.c
Diffstat (limited to 'drivers/i2c/busses/i2c-mv64xxx.c')
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c133
1 files changed, 128 insertions, 5 deletions
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 4f44a33017b0..2e9d56719e99 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -18,6 +18,11 @@
18#include <linux/mv643xx_i2c.h> 18#include <linux/mv643xx_i2c.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/of.h>
22#include <linux/of_irq.h>
23#include <linux/of_i2c.h>
24#include <linux/clk.h>
25#include <linux/err.h>
21 26
22/* Register defines */ 27/* Register defines */
23#define MV64XXX_I2C_REG_SLAVE_ADDR 0x00 28#define MV64XXX_I2C_REG_SLAVE_ADDR 0x00
@@ -98,6 +103,9 @@ struct mv64xxx_i2c_data {
98 int rc; 103 int rc;
99 u32 freq_m; 104 u32 freq_m;
100 u32 freq_n; 105 u32 freq_n;
106#if defined(CONFIG_HAVE_CLK)
107 struct clk *clk;
108#endif
101 wait_queue_head_t waitq; 109 wait_queue_head_t waitq;
102 spinlock_t lock; 110 spinlock_t lock;
103 struct i2c_msg *msg; 111 struct i2c_msg *msg;
@@ -521,6 +529,82 @@ mv64xxx_i2c_unmap_regs(struct mv64xxx_i2c_data *drv_data)
521 drv_data->reg_base_p = 0; 529 drv_data->reg_base_p = 0;
522} 530}
523 531
532#ifdef CONFIG_OF
533static int __devinit
534mv64xxx_calc_freq(const int tclk, const int n, const int m)
535{
536 return tclk / (10 * (m + 1) * (2 << n));
537}
538
539static bool __devinit
540mv64xxx_find_baud_factors(const u32 req_freq, const u32 tclk, u32 *best_n,
541 u32 *best_m)
542{
543 int freq, delta, best_delta = INT_MAX;
544 int m, n;
545
546 for (n = 0; n <= 7; n++)
547 for (m = 0; m <= 15; m++) {
548 freq = mv64xxx_calc_freq(tclk, n, m);
549 delta = req_freq - freq;
550 if (delta >= 0 && delta < best_delta) {
551 *best_m = m;
552 *best_n = n;
553 best_delta = delta;
554 }
555 if (best_delta == 0)
556 return true;
557 }
558 if (best_delta == INT_MAX)
559 return false;
560 return true;
561}
562
563static int __devinit
564mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
565 struct device_node *np)
566{
567 u32 bus_freq, tclk;
568 int rc = 0;
569
570 /* CLK is mandatory when using DT to describe the i2c bus. We
571 * need to know tclk in order to calculate bus clock
572 * factors.
573 */
574#if !defined(CONFIG_HAVE_CLK)
575 /* Have OF but no CLK */
576 return -ENODEV;
577#else
578 if (IS_ERR(drv_data->clk)) {
579 rc = -ENODEV;
580 goto out;
581 }
582 tclk = clk_get_rate(drv_data->clk);
583 of_property_read_u32(np, "clock-frequency", &bus_freq);
584 if (!mv64xxx_find_baud_factors(bus_freq, tclk,
585 &drv_data->freq_n, &drv_data->freq_m)) {
586 rc = -EINVAL;
587 goto out;
588 }
589 drv_data->irq = irq_of_parse_and_map(np, 0);
590
591 /* Its not yet defined how timeouts will be specified in device tree.
592 * So hard code the value to 1 second.
593 */
594 drv_data->adapter.timeout = HZ;
595out:
596 return rc;
597#endif
598}
599#else /* CONFIG_OF */
600static int __devinit
601mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
602 struct device_node *np)
603{
604 return -ENODEV;
605}
606#endif /* CONFIG_OF */
607
524static int __devinit 608static int __devinit
525mv64xxx_i2c_probe(struct platform_device *pd) 609mv64xxx_i2c_probe(struct platform_device *pd)
526{ 610{
@@ -528,7 +612,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
528 struct mv64xxx_i2c_pdata *pdata = pd->dev.platform_data; 612 struct mv64xxx_i2c_pdata *pdata = pd->dev.platform_data;
529 int rc; 613 int rc;
530 614
531 if ((pd->id != 0) || !pdata) 615 if ((!pdata && !pd->dev.of_node))
532 return -ENODEV; 616 return -ENODEV;
533 617
534 drv_data = kzalloc(sizeof(struct mv64xxx_i2c_data), GFP_KERNEL); 618 drv_data = kzalloc(sizeof(struct mv64xxx_i2c_data), GFP_KERNEL);
@@ -546,19 +630,35 @@ mv64xxx_i2c_probe(struct platform_device *pd)
546 init_waitqueue_head(&drv_data->waitq); 630 init_waitqueue_head(&drv_data->waitq);
547 spin_lock_init(&drv_data->lock); 631 spin_lock_init(&drv_data->lock);
548 632
549 drv_data->freq_m = pdata->freq_m; 633#if defined(CONFIG_HAVE_CLK)
550 drv_data->freq_n = pdata->freq_n; 634 /* Not all platforms have a clk */
551 drv_data->irq = platform_get_irq(pd, 0); 635 drv_data->clk = clk_get(&pd->dev, NULL);
636 if (!IS_ERR(drv_data->clk)) {
637 clk_prepare(drv_data->clk);
638 clk_enable(drv_data->clk);
639 }
640#endif
641 if (pdata) {
642 drv_data->freq_m = pdata->freq_m;
643 drv_data->freq_n = pdata->freq_n;
644 drv_data->irq = platform_get_irq(pd, 0);
645 drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
646 } else if (pd->dev.of_node) {
647 rc = mv64xxx_of_config(drv_data, pd->dev.of_node);
648 if (rc)
649 goto exit_unmap_regs;
650 }
552 if (drv_data->irq < 0) { 651 if (drv_data->irq < 0) {
553 rc = -ENXIO; 652 rc = -ENXIO;
554 goto exit_unmap_regs; 653 goto exit_unmap_regs;
555 } 654 }
655
556 drv_data->adapter.dev.parent = &pd->dev; 656 drv_data->adapter.dev.parent = &pd->dev;
557 drv_data->adapter.algo = &mv64xxx_i2c_algo; 657 drv_data->adapter.algo = &mv64xxx_i2c_algo;
558 drv_data->adapter.owner = THIS_MODULE; 658 drv_data->adapter.owner = THIS_MODULE;
559 drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; 659 drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
560 drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
561 drv_data->adapter.nr = pd->id; 660 drv_data->adapter.nr = pd->id;
661 drv_data->adapter.dev.of_node = pd->dev.of_node;
562 platform_set_drvdata(pd, drv_data); 662 platform_set_drvdata(pd, drv_data);
563 i2c_set_adapdata(&drv_data->adapter, drv_data); 663 i2c_set_adapdata(&drv_data->adapter, drv_data);
564 664
@@ -577,11 +677,20 @@ mv64xxx_i2c_probe(struct platform_device *pd)
577 goto exit_free_irq; 677 goto exit_free_irq;
578 } 678 }
579 679
680 of_i2c_register_devices(&drv_data->adapter);
681
580 return 0; 682 return 0;
581 683
582 exit_free_irq: 684 exit_free_irq:
583 free_irq(drv_data->irq, drv_data); 685 free_irq(drv_data->irq, drv_data);
584 exit_unmap_regs: 686 exit_unmap_regs:
687#if defined(CONFIG_HAVE_CLK)
688 /* Not all platforms have a clk */
689 if (!IS_ERR(drv_data->clk)) {
690 clk_disable(drv_data->clk);
691 clk_unprepare(drv_data->clk);
692 }
693#endif
585 mv64xxx_i2c_unmap_regs(drv_data); 694 mv64xxx_i2c_unmap_regs(drv_data);
586 exit_kfree: 695 exit_kfree:
587 kfree(drv_data); 696 kfree(drv_data);
@@ -597,17 +706,31 @@ mv64xxx_i2c_remove(struct platform_device *dev)
597 rc = i2c_del_adapter(&drv_data->adapter); 706 rc = i2c_del_adapter(&drv_data->adapter);
598 free_irq(drv_data->irq, drv_data); 707 free_irq(drv_data->irq, drv_data);
599 mv64xxx_i2c_unmap_regs(drv_data); 708 mv64xxx_i2c_unmap_regs(drv_data);
709#if defined(CONFIG_HAVE_CLK)
710 /* Not all platforms have a clk */
711 if (!IS_ERR(drv_data->clk)) {
712 clk_disable(drv_data->clk);
713 clk_unprepare(drv_data->clk);
714 }
715#endif
600 kfree(drv_data); 716 kfree(drv_data);
601 717
602 return rc; 718 return rc;
603} 719}
604 720
721static const struct of_device_id mv64xxx_i2c_of_match_table[] __devinitdata = {
722 { .compatible = "marvell,mv64xxx-i2c", },
723 {}
724};
725MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);
726
605static struct platform_driver mv64xxx_i2c_driver = { 727static struct platform_driver mv64xxx_i2c_driver = {
606 .probe = mv64xxx_i2c_probe, 728 .probe = mv64xxx_i2c_probe,
607 .remove = __devexit_p(mv64xxx_i2c_remove), 729 .remove = __devexit_p(mv64xxx_i2c_remove),
608 .driver = { 730 .driver = {
609 .owner = THIS_MODULE, 731 .owner = THIS_MODULE,
610 .name = MV64XXX_I2C_CTLR_NAME, 732 .name = MV64XXX_I2C_CTLR_NAME,
733 .of_match_table = of_match_ptr(mv64xxx_i2c_of_match_table),
611 }, 734 },
612}; 735};
613 736