aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/phy/phy-ab8500-usb.c
diff options
context:
space:
mode:
authorFabio Baltieri <fabio.baltieri@linaro.org>2013-05-15 08:03:31 -0400
committerFelipe Balbi <balbi@ti.com>2013-05-28 13:03:25 -0400
commitbd4c9f0278338585024db55f2ff74d6e0a6a1f6b (patch)
tree63cc44b738f3f70b4d193d80bcefe39ddaae30fe /drivers/usb/phy/phy-ab8500-usb.c
parent16604a3c27f4a43588069ae9a77a9961a485d53f (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.c109
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
124struct ab8500_usb { 135struct 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
141static inline struct ab8500_usb *phy_to_ab(struct usb_phy *x) 153static 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);