aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/phy/Kconfig1
-rw-r--r--drivers/usb/phy/phy-am335x-control.c14
-rw-r--r--drivers/usb/phy/phy-am335x-control.h8
-rw-r--r--drivers/usb/phy/phy-am335x.c15
4 files changed, 27 insertions, 11 deletions
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 155694c1a536..c6904742e2aa 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -66,6 +66,7 @@ config AM335X_PHY_USB
66 select USB_PHY 66 select USB_PHY
67 select AM335X_CONTROL_USB 67 select AM335X_CONTROL_USB
68 select NOP_USB_XCEIV 68 select NOP_USB_XCEIV
69 select USB_COMMON
69 help 70 help
70 This driver provides PHY support for that phy which part for the 71 This driver provides PHY support for that phy which part for the
71 AM335x SoC. 72 AM335x SoC.
diff --git a/drivers/usb/phy/phy-am335x-control.c b/drivers/usb/phy/phy-am335x-control.c
index 23fca5192a6b..42a1afe36a90 100644
--- a/drivers/usb/phy/phy-am335x-control.c
+++ b/drivers/usb/phy/phy-am335x-control.c
@@ -4,6 +4,7 @@
4#include <linux/of.h> 4#include <linux/of.h>
5#include <linux/io.h> 5#include <linux/io.h>
6#include <linux/delay.h> 6#include <linux/delay.h>
7#include <linux/usb/otg.h>
7#include "phy-am335x-control.h" 8#include "phy-am335x-control.h"
8 9
9struct am335x_control_usb { 10struct am335x_control_usb {
@@ -58,7 +59,8 @@ static void am335x_phy_wkup(struct phy_control *phy_ctrl, u32 id, bool on)
58 spin_unlock(&usb_ctrl->lock); 59 spin_unlock(&usb_ctrl->lock);
59} 60}
60 61
61static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on) 62static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id,
63 enum usb_dr_mode dr_mode, bool on)
62{ 64{
63 struct am335x_control_usb *usb_ctrl; 65 struct am335x_control_usb *usb_ctrl;
64 u32 val; 66 u32 val;
@@ -80,8 +82,14 @@ static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on)
80 82
81 val = readl(usb_ctrl->phy_reg + reg); 83 val = readl(usb_ctrl->phy_reg + reg);
82 if (on) { 84 if (on) {
83 val &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN); 85 if (dr_mode == USB_DR_MODE_HOST) {
84 val |= USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN; 86 val &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN |
87 USBPHY_OTGVDET_EN);
88 val |= USBPHY_OTGSESSEND_EN;
89 } else {
90 val &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN);
91 val |= USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN;
92 }
85 } else { 93 } else {
86 val |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN; 94 val |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN;
87 } 95 }
diff --git a/drivers/usb/phy/phy-am335x-control.h b/drivers/usb/phy/phy-am335x-control.h
index b96594d1962c..e86b3165d69d 100644
--- a/drivers/usb/phy/phy-am335x-control.h
+++ b/drivers/usb/phy/phy-am335x-control.h
@@ -2,13 +2,15 @@
2#define _AM335x_PHY_CONTROL_H_ 2#define _AM335x_PHY_CONTROL_H_
3 3
4struct phy_control { 4struct phy_control {
5 void (*phy_power)(struct phy_control *phy_ctrl, u32 id, bool on); 5 void (*phy_power)(struct phy_control *phy_ctrl, u32 id,
6 enum usb_dr_mode dr_mode, bool on);
6 void (*phy_wkup)(struct phy_control *phy_ctrl, u32 id, bool on); 7 void (*phy_wkup)(struct phy_control *phy_ctrl, u32 id, bool on);
7}; 8};
8 9
9static inline void phy_ctrl_power(struct phy_control *phy_ctrl, u32 id, bool on) 10static inline void phy_ctrl_power(struct phy_control *phy_ctrl, u32 id,
11 enum usb_dr_mode dr_mode, bool on)
10{ 12{
11 phy_ctrl->phy_power(phy_ctrl, id, on); 13 phy_ctrl->phy_power(phy_ctrl, id, dr_mode, on);
12} 14}
13 15
14static inline void phy_ctrl_wkup(struct phy_control *phy_ctrl, u32 id, bool on) 16static inline void phy_ctrl_wkup(struct phy_control *phy_ctrl, u32 id, bool on)
diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c
index 8b6139dec5eb..39b424f7f629 100644
--- a/drivers/usb/phy/phy-am335x.c
+++ b/drivers/usb/phy/phy-am335x.c
@@ -8,6 +8,7 @@
8#include <linux/regulator/consumer.h> 8#include <linux/regulator/consumer.h>
9#include <linux/of.h> 9#include <linux/of.h>
10#include <linux/of_address.h> 10#include <linux/of_address.h>
11#include <linux/usb/of.h>
11 12
12#include "phy-am335x-control.h" 13#include "phy-am335x-control.h"
13#include "phy-generic.h" 14#include "phy-generic.h"
@@ -16,13 +17,14 @@ struct am335x_phy {
16 struct usb_phy_generic usb_phy_gen; 17 struct usb_phy_generic usb_phy_gen;
17 struct phy_control *phy_ctrl; 18 struct phy_control *phy_ctrl;
18 int id; 19 int id;
20 enum usb_dr_mode dr_mode;
19}; 21};
20 22
21static int am335x_init(struct usb_phy *phy) 23static int am335x_init(struct usb_phy *phy)
22{ 24{
23 struct am335x_phy *am_phy = dev_get_drvdata(phy->dev); 25 struct am335x_phy *am_phy = dev_get_drvdata(phy->dev);
24 26
25 phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, true); 27 phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, true);
26 return 0; 28 return 0;
27} 29}
28 30
@@ -30,7 +32,7 @@ static void am335x_shutdown(struct usb_phy *phy)
30{ 32{
31 struct am335x_phy *am_phy = dev_get_drvdata(phy->dev); 33 struct am335x_phy *am_phy = dev_get_drvdata(phy->dev);
32 34
33 phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, false); 35 phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, false);
34} 36}
35 37
36static int am335x_phy_probe(struct platform_device *pdev) 38static int am335x_phy_probe(struct platform_device *pdev)
@@ -46,12 +48,15 @@ static int am335x_phy_probe(struct platform_device *pdev)
46 am_phy->phy_ctrl = am335x_get_phy_control(dev); 48 am_phy->phy_ctrl = am335x_get_phy_control(dev);
47 if (!am_phy->phy_ctrl) 49 if (!am_phy->phy_ctrl)
48 return -EPROBE_DEFER; 50 return -EPROBE_DEFER;
51
49 am_phy->id = of_alias_get_id(pdev->dev.of_node, "phy"); 52 am_phy->id = of_alias_get_id(pdev->dev.of_node, "phy");
50 if (am_phy->id < 0) { 53 if (am_phy->id < 0) {
51 dev_err(&pdev->dev, "Missing PHY id: %d\n", am_phy->id); 54 dev_err(&pdev->dev, "Missing PHY id: %d\n", am_phy->id);
52 return am_phy->id; 55 return am_phy->id;
53 } 56 }
54 57
58 am_phy->dr_mode = of_usb_get_dr_mode_by_phy(pdev->dev.of_node);
59
55 ret = usb_phy_gen_create_phy(dev, &am_phy->usb_phy_gen, NULL); 60 ret = usb_phy_gen_create_phy(dev, &am_phy->usb_phy_gen, NULL);
56 if (ret) 61 if (ret)
57 return ret; 62 return ret;
@@ -75,7 +80,7 @@ static int am335x_phy_probe(struct platform_device *pdev)
75 */ 80 */
76 81
77 device_set_wakeup_enable(dev, false); 82 device_set_wakeup_enable(dev, false);
78 phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, false); 83 phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, false);
79 84
80 return 0; 85 return 0;
81} 86}
@@ -105,7 +110,7 @@ static int am335x_phy_suspend(struct device *dev)
105 if (device_may_wakeup(dev)) 110 if (device_may_wakeup(dev))
106 phy_ctrl_wkup(am_phy->phy_ctrl, am_phy->id, true); 111 phy_ctrl_wkup(am_phy->phy_ctrl, am_phy->id, true);
107 112
108 phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, false); 113 phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, false);
109 114
110 return 0; 115 return 0;
111} 116}
@@ -115,7 +120,7 @@ static int am335x_phy_resume(struct device *dev)
115 struct platform_device *pdev = to_platform_device(dev); 120 struct platform_device *pdev = to_platform_device(dev);
116 struct am335x_phy *am_phy = platform_get_drvdata(pdev); 121 struct am335x_phy *am_phy = platform_get_drvdata(pdev);
117 122
118 phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, true); 123 phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, true);
119 124
120 if (device_may_wakeup(dev)) 125 if (device_may_wakeup(dev))
121 phy_ctrl_wkup(am_phy->phy_ctrl, am_phy->id, false); 126 phy_ctrl_wkup(am_phy->phy_ctrl, am_phy->id, false);