diff options
author | Fabio Baltieri <fabio.baltieri@linaro.org> | 2013-05-15 08:03:31 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2013-05-28 13:03:25 -0400 |
commit | bd4c9f0278338585024db55f2ff74d6e0a6a1f6b (patch) | |
tree | 63cc44b738f3f70b4d193d80bcefe39ddaae30fe /drivers/usb/phy/phy-ab8500-usb.c | |
parent | 16604a3c27f4a43588069ae9a77a9961a485d53f (diff) |
usb: phy: ab8500-usb: add flag bits to control driver features
Introduce a "flags" field in "struct ab8500_usb" to allow controlling
driver features and quirks depending on ab8500 chip variant and
revision.
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Maxime Coquelin <maxime.coquelin@st.com>
Signed-off-by: Fabio Baltieri <fabio.baltieri@linaro.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/phy/phy-ab8500-usb.c')
-rw-r--r-- | drivers/usb/phy/phy-ab8500-usb.c | 109 |
1 files changed, 73 insertions, 36 deletions
diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c index bbc46197dce0..54dd2b16c80b 100644 --- a/drivers/usb/phy/phy-ab8500-usb.c +++ b/drivers/usb/phy/phy-ab8500-usb.c | |||
@@ -121,6 +121,17 @@ enum ab8500_usb_mode { | |||
121 | USB_DEDICATED_CHG | 121 | USB_DEDICATED_CHG |
122 | }; | 122 | }; |
123 | 123 | ||
124 | /* Register USB_LINK_STATUS interrupt */ | ||
125 | #define AB8500_USB_FLAG_USE_LINK_STATUS_IRQ (1 << 0) | ||
126 | /* Register ID_WAKEUP_F interrupt */ | ||
127 | #define AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ (1 << 1) | ||
128 | /* Register VBUS_DET_F interrupt */ | ||
129 | #define AB8500_USB_FLAG_USE_VBUS_DET_IRQ (1 << 2) | ||
130 | /* Driver is using the ab-iddet driver*/ | ||
131 | #define AB8500_USB_FLAG_USE_AB_IDDET (1 << 3) | ||
132 | /* Enable setting regulators voltage */ | ||
133 | #define AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE (1 << 4) | ||
134 | |||
124 | struct ab8500_usb { | 135 | struct ab8500_usb { |
125 | struct usb_phy phy; | 136 | struct usb_phy phy; |
126 | struct device *dev; | 137 | struct device *dev; |
@@ -136,6 +147,7 @@ struct ab8500_usb { | |||
136 | int previous_link_status_state; | 147 | int previous_link_status_state; |
137 | struct pinctrl *pinctrl; | 148 | struct pinctrl *pinctrl; |
138 | struct pinctrl_state *pins_sleep; | 149 | struct pinctrl_state *pins_sleep; |
150 | unsigned int flags; | ||
139 | }; | 151 | }; |
140 | 152 | ||
141 | static inline struct ab8500_usb *phy_to_ab(struct usb_phy *x) | 153 | static inline struct ab8500_usb *phy_to_ab(struct usb_phy *x) |
@@ -174,7 +186,7 @@ static void ab8500_usb_regulator_enable(struct ab8500_usb *ab) | |||
174 | if (ret) | 186 | if (ret) |
175 | dev_err(ab->dev, "Failed to enable v-ape\n"); | 187 | dev_err(ab->dev, "Failed to enable v-ape\n"); |
176 | 188 | ||
177 | if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { | 189 | if (ab->flags & AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE) { |
178 | ab->saved_v_ulpi = regulator_get_voltage(ab->v_ulpi); | 190 | ab->saved_v_ulpi = regulator_get_voltage(ab->v_ulpi); |
179 | if (ab->saved_v_ulpi < 0) | 191 | if (ab->saved_v_ulpi < 0) |
180 | dev_err(ab->dev, "Failed to get v_ulpi voltage\n"); | 192 | dev_err(ab->dev, "Failed to get v_ulpi voltage\n"); |
@@ -194,7 +206,7 @@ static void ab8500_usb_regulator_enable(struct ab8500_usb *ab) | |||
194 | if (ret) | 206 | if (ret) |
195 | dev_err(ab->dev, "Failed to enable vddulpivio18\n"); | 207 | dev_err(ab->dev, "Failed to enable vddulpivio18\n"); |
196 | 208 | ||
197 | if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { | 209 | if (ab->flags & AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE) { |
198 | volt = regulator_get_voltage(ab->v_ulpi); | 210 | volt = regulator_get_voltage(ab->v_ulpi); |
199 | if ((volt != 1300000) && (volt != 1350000)) | 211 | if ((volt != 1300000) && (volt != 1350000)) |
200 | dev_err(ab->dev, "Vintcore is not set to 1.3V volt=%d\n", | 212 | dev_err(ab->dev, "Vintcore is not set to 1.3V volt=%d\n", |
@@ -215,7 +227,7 @@ static void ab8500_usb_regulator_disable(struct ab8500_usb *ab) | |||
215 | regulator_disable(ab->v_ulpi); | 227 | regulator_disable(ab->v_ulpi); |
216 | 228 | ||
217 | /* USB is not the only consumer of Vintcore, restore old settings */ | 229 | /* USB is not the only consumer of Vintcore, restore old settings */ |
218 | if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { | 230 | if (ab->flags & AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE) { |
219 | if (ab->saved_v_ulpi > 0) { | 231 | if (ab->saved_v_ulpi > 0) { |
220 | ret = regulator_set_voltage(ab->v_ulpi, | 232 | ret = regulator_set_voltage(ab->v_ulpi, |
221 | ab->saved_v_ulpi, ab->saved_v_ulpi); | 233 | ab->saved_v_ulpi, ab->saved_v_ulpi); |
@@ -729,43 +741,52 @@ static int ab8500_usb_irq_setup(struct platform_device *pdev, | |||
729 | int err; | 741 | int err; |
730 | int irq; | 742 | int irq; |
731 | 743 | ||
732 | irq = platform_get_irq_byname(pdev, "USB_LINK_STATUS"); | 744 | if (ab->flags & AB8500_USB_FLAG_USE_LINK_STATUS_IRQ) { |
733 | if (irq < 0) { | 745 | irq = platform_get_irq_byname(pdev, "USB_LINK_STATUS"); |
734 | dev_err(&pdev->dev, "Link status irq not found\n"); | 746 | if (irq < 0) { |
735 | return irq; | 747 | dev_err(&pdev->dev, "Link status irq not found\n"); |
736 | } | 748 | return irq; |
737 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 749 | } |
738 | ab8500_usb_link_status_irq, | 750 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
739 | IRQF_NO_SUSPEND | IRQF_SHARED, "usb-link-status", ab); | 751 | ab8500_usb_link_status_irq, |
740 | if (err < 0) { | 752 | IRQF_NO_SUSPEND | IRQF_SHARED, |
741 | dev_err(ab->dev, "request_irq failed for link status irq\n"); | 753 | "usb-link-status", ab); |
742 | return err; | 754 | if (err < 0) { |
755 | dev_err(ab->dev, "request_irq failed for link status irq\n"); | ||
756 | return err; | ||
757 | } | ||
743 | } | 758 | } |
744 | 759 | ||
745 | irq = platform_get_irq_byname(pdev, "ID_WAKEUP_F"); | 760 | if (ab->flags & AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ) { |
746 | if (irq < 0) { | 761 | irq = platform_get_irq_byname(pdev, "ID_WAKEUP_F"); |
747 | dev_err(&pdev->dev, "ID fall irq not found\n"); | 762 | if (irq < 0) { |
748 | return irq; | 763 | dev_err(&pdev->dev, "ID fall irq not found\n"); |
749 | } | 764 | return irq; |
750 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 765 | } |
751 | ab8500_usb_disconnect_irq, | 766 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
752 | IRQF_NO_SUSPEND | IRQF_SHARED, "usb-id-fall", ab); | 767 | ab8500_usb_disconnect_irq, |
753 | if (err < 0) { | 768 | IRQF_NO_SUSPEND | IRQF_SHARED, |
754 | dev_err(ab->dev, "request_irq failed for ID fall irq\n"); | 769 | "usb-id-fall", ab); |
755 | return err; | 770 | if (err < 0) { |
771 | dev_err(ab->dev, "request_irq failed for ID fall irq\n"); | ||
772 | return err; | ||
773 | } | ||
756 | } | 774 | } |
757 | 775 | ||
758 | irq = platform_get_irq_byname(pdev, "VBUS_DET_F"); | 776 | if (ab->flags & AB8500_USB_FLAG_USE_VBUS_DET_IRQ) { |
759 | if (irq < 0) { | 777 | irq = platform_get_irq_byname(pdev, "VBUS_DET_F"); |
760 | dev_err(&pdev->dev, "VBUS fall irq not found\n"); | 778 | if (irq < 0) { |
761 | return irq; | 779 | dev_err(&pdev->dev, "VBUS fall irq not found\n"); |
762 | } | 780 | return irq; |
763 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 781 | } |
764 | ab8500_usb_disconnect_irq, | 782 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
765 | IRQF_NO_SUSPEND | IRQF_SHARED, "usb-vbus-fall", ab); | 783 | ab8500_usb_disconnect_irq, |
766 | if (err < 0) { | 784 | IRQF_NO_SUSPEND | IRQF_SHARED, |
767 | dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); | 785 | "usb-vbus-fall", ab); |
768 | return err; | 786 | if (err < 0) { |
787 | dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); | ||
788 | return err; | ||
789 | } | ||
769 | } | 790 | } |
770 | 791 | ||
771 | return 0; | 792 | return 0; |
@@ -888,6 +909,22 @@ static int ab8500_usb_probe(struct platform_device *pdev) | |||
888 | otg->set_host = ab8500_usb_set_host; | 909 | otg->set_host = ab8500_usb_set_host; |
889 | otg->set_peripheral = ab8500_usb_set_peripheral; | 910 | otg->set_peripheral = ab8500_usb_set_peripheral; |
890 | 911 | ||
912 | if (is_ab8500(ab->ab8500)) { | ||
913 | ab->flags |= AB8500_USB_FLAG_USE_LINK_STATUS_IRQ | | ||
914 | AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ | | ||
915 | AB8500_USB_FLAG_USE_VBUS_DET_IRQ | | ||
916 | AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE; | ||
917 | } else if (is_ab8505(ab->ab8500)) { | ||
918 | ab->flags |= AB8500_USB_FLAG_USE_LINK_STATUS_IRQ | | ||
919 | AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ | | ||
920 | AB8500_USB_FLAG_USE_VBUS_DET_IRQ | | ||
921 | AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE; | ||
922 | } | ||
923 | |||
924 | /* Disable regulator voltage setting for AB8500 <= v2.0 */ | ||
925 | if (is_ab8500_2p0_or_earlier(ab->ab8500)) | ||
926 | ab->flags &= ~AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE; | ||
927 | |||
891 | platform_set_drvdata(pdev, ab); | 928 | platform_set_drvdata(pdev, ab); |
892 | 929 | ||
893 | ATOMIC_INIT_NOTIFIER_HEAD(&ab->phy.notifier); | 930 | ATOMIC_INIT_NOTIFIER_HEAD(&ab->phy.notifier); |