diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2012-08-18 15:17:46 -0400 |
---|---|---|
committer | Stephen Warren <swarren@nvidia.com> | 2012-09-13 13:40:30 -0400 |
commit | 6ad068ed63100f1bb2f65340e2de9b8727526ef8 (patch) | |
tree | 5ff3150f7bc6fb8a67ea0e9f513fa6445b47fdba /drivers/i2c/busses | |
parent | 29d25c2a0c967cf3832848389d0e457f5317b874 (diff) |
i2c: tegra: I2_M_NOSTART functionality not supported in Tegra20
Tegra20 i2c controller does not support the continue transfer
which implements the I2C_M_NOSTART functionality of i2c
protocol mangling.
Removing the I2C_M_NOSTART functionality support for Tegra20.
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r-- | drivers/i2c/busses/i2c-tegra.c | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 8514d3a95a68..ce701474626f 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/i2c-tegra.h> | 28 | #include <linux/i2c-tegra.h> |
29 | #include <linux/of_i2c.h> | 29 | #include <linux/of_i2c.h> |
30 | #include <linux/of_device.h> | ||
30 | #include <linux/module.h> | 31 | #include <linux/module.h> |
31 | 32 | ||
32 | #include <asm/unaligned.h> | 33 | #include <asm/unaligned.h> |
@@ -114,8 +115,18 @@ enum msg_end_type { | |||
114 | }; | 115 | }; |
115 | 116 | ||
116 | /** | 117 | /** |
118 | * struct tegra_i2c_hw_feature : Different HW support on Tegra | ||
119 | * @has_continue_xfer_support: Continue transfer supports. | ||
120 | */ | ||
121 | |||
122 | struct tegra_i2c_hw_feature { | ||
123 | bool has_continue_xfer_support; | ||
124 | }; | ||
125 | |||
126 | /** | ||
117 | * struct tegra_i2c_dev - per device i2c context | 127 | * struct tegra_i2c_dev - per device i2c context |
118 | * @dev: device reference for power management | 128 | * @dev: device reference for power management |
129 | * @hw: Tegra i2c hw feature. | ||
119 | * @adapter: core i2c layer adapter information | 130 | * @adapter: core i2c layer adapter information |
120 | * @div_clk: clock reference for div clock of i2c controller. | 131 | * @div_clk: clock reference for div clock of i2c controller. |
121 | * @fast_clk: clock reference for fast clock of i2c controller. | 132 | * @fast_clk: clock reference for fast clock of i2c controller. |
@@ -133,6 +144,7 @@ enum msg_end_type { | |||
133 | */ | 144 | */ |
134 | struct tegra_i2c_dev { | 145 | struct tegra_i2c_dev { |
135 | struct device *dev; | 146 | struct device *dev; |
147 | const struct tegra_i2c_hw_feature *hw; | ||
136 | struct i2c_adapter adapter; | 148 | struct i2c_adapter adapter; |
137 | struct clk *div_clk; | 149 | struct clk *div_clk; |
138 | struct clk *fast_clk; | 150 | struct clk *fast_clk; |
@@ -582,8 +594,13 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], | |||
582 | 594 | ||
583 | static u32 tegra_i2c_func(struct i2c_adapter *adap) | 595 | static u32 tegra_i2c_func(struct i2c_adapter *adap) |
584 | { | 596 | { |
585 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | | 597 | struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap); |
586 | I2C_FUNC_PROTOCOL_MANGLING | I2C_FUNC_NOSTART; | 598 | u32 ret = I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | |
599 | I2C_FUNC_PROTOCOL_MANGLING; | ||
600 | |||
601 | if (i2c_dev->hw->has_continue_xfer_support) | ||
602 | ret |= I2C_FUNC_NOSTART; | ||
603 | return ret; | ||
587 | } | 604 | } |
588 | 605 | ||
589 | static const struct i2c_algorithm tegra_i2c_algo = { | 606 | static const struct i2c_algorithm tegra_i2c_algo = { |
@@ -591,6 +608,25 @@ static const struct i2c_algorithm tegra_i2c_algo = { | |||
591 | .functionality = tegra_i2c_func, | 608 | .functionality = tegra_i2c_func, |
592 | }; | 609 | }; |
593 | 610 | ||
611 | static const struct tegra_i2c_hw_feature tegra20_i2c_hw = { | ||
612 | .has_continue_xfer_support = false, | ||
613 | }; | ||
614 | |||
615 | static const struct tegra_i2c_hw_feature tegra30_i2c_hw = { | ||
616 | .has_continue_xfer_support = true, | ||
617 | }; | ||
618 | |||
619 | #if defined(CONFIG_OF) | ||
620 | /* Match table for of_platform binding */ | ||
621 | static const struct of_device_id tegra_i2c_of_match[] __devinitconst = { | ||
622 | { .compatible = "nvidia,tegra30-i2c", .data = &tegra30_i2c_hw, }, | ||
623 | { .compatible = "nvidia,tegra20-i2c", .data = &tegra20_i2c_hw, }, | ||
624 | { .compatible = "nvidia,tegra20-i2c-dvc", .data = &tegra20_i2c_hw, }, | ||
625 | {}, | ||
626 | }; | ||
627 | MODULE_DEVICE_TABLE(of, tegra_i2c_of_match); | ||
628 | #endif | ||
629 | |||
594 | static int __devinit tegra_i2c_probe(struct platform_device *pdev) | 630 | static int __devinit tegra_i2c_probe(struct platform_device *pdev) |
595 | { | 631 | { |
596 | struct tegra_i2c_dev *i2c_dev; | 632 | struct tegra_i2c_dev *i2c_dev; |
@@ -659,11 +695,18 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev) | |||
659 | i2c_dev->bus_clk_rate = be32_to_cpup(prop); | 695 | i2c_dev->bus_clk_rate = be32_to_cpup(prop); |
660 | } | 696 | } |
661 | 697 | ||
662 | if (pdev->dev.of_node) | 698 | i2c_dev->hw = &tegra20_i2c_hw; |
699 | |||
700 | if (pdev->dev.of_node) { | ||
701 | const struct of_device_id *match; | ||
702 | match = of_match_device(of_match_ptr(tegra_i2c_of_match), | ||
703 | &pdev->dev); | ||
704 | i2c_dev->hw = match->data; | ||
663 | i2c_dev->is_dvc = of_device_is_compatible(pdev->dev.of_node, | 705 | i2c_dev->is_dvc = of_device_is_compatible(pdev->dev.of_node, |
664 | "nvidia,tegra20-i2c-dvc"); | 706 | "nvidia,tegra20-i2c-dvc"); |
665 | else if (pdev->id == 3) | 707 | } else if (pdev->id == 3) { |
666 | i2c_dev->is_dvc = 1; | 708 | i2c_dev->is_dvc = 1; |
709 | } | ||
667 | init_completion(&i2c_dev->msg_complete); | 710 | init_completion(&i2c_dev->msg_complete); |
668 | 711 | ||
669 | platform_set_drvdata(pdev, i2c_dev); | 712 | platform_set_drvdata(pdev, i2c_dev); |
@@ -751,16 +794,6 @@ static SIMPLE_DEV_PM_OPS(tegra_i2c_pm, tegra_i2c_suspend, tegra_i2c_resume); | |||
751 | #define TEGRA_I2C_PM NULL | 794 | #define TEGRA_I2C_PM NULL |
752 | #endif | 795 | #endif |
753 | 796 | ||
754 | #if defined(CONFIG_OF) | ||
755 | /* Match table for of_platform binding */ | ||
756 | static const struct of_device_id tegra_i2c_of_match[] __devinitconst = { | ||
757 | { .compatible = "nvidia,tegra20-i2c", }, | ||
758 | { .compatible = "nvidia,tegra20-i2c-dvc", }, | ||
759 | {}, | ||
760 | }; | ||
761 | MODULE_DEVICE_TABLE(of, tegra_i2c_of_match); | ||
762 | #endif | ||
763 | |||
764 | static struct platform_driver tegra_i2c_driver = { | 797 | static struct platform_driver tegra_i2c_driver = { |
765 | .probe = tegra_i2c_probe, | 798 | .probe = tegra_i2c_probe, |
766 | .remove = __devexit_p(tegra_i2c_remove), | 799 | .remove = __devexit_p(tegra_i2c_remove), |