aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/usb/twlxxxx-usb.txt40
-rw-r--r--Documentation/devicetree/bindings/usb/usb-phy.txt17
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c1
-rw-r--r--arch/arm/mach-omap2/omap_phy_internal.c138
-rw-r--r--arch/arm/mach-omap2/twl-common.c5
-rw-r--r--arch/arm/mach-omap2/usb-musb.c3
-rw-r--r--arch/arm/mach-tegra/Makefile1
-rw-r--r--arch/arm/mach-tegra/devices.c2
-rw-r--r--arch/arm/mach-tegra/devices.h2
-rw-r--r--drivers/usb/dwc3/core.c15
-rw-r--r--drivers/usb/dwc3/core.h5
-rw-r--r--drivers/usb/dwc3/dwc3-exynos.c66
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c66
-rw-r--r--drivers/usb/dwc3/dwc3-pci.c67
-rw-r--r--drivers/usb/host/ehci-tegra.c14
-rw-r--r--drivers/usb/musb/am35x.c1
-rw-r--r--drivers/usb/musb/blackfin.c1
-rw-r--r--drivers/usb/musb/da8xx.c1
-rw-r--r--drivers/usb/musb/davinci.c1
-rw-r--r--drivers/usb/musb/musb_dsps.c1
-rw-r--r--drivers/usb/musb/tusb6010.c1
-rw-r--r--drivers/usb/otg/Kconfig2
-rw-r--r--drivers/usb/otg/fsl_otg.c34
-rw-r--r--drivers/usb/otg/mxs-phy.c38
-rw-r--r--drivers/usb/otg/nop-usb-xceiv.c8
-rw-r--r--drivers/usb/otg/otg.c2
-rw-r--r--drivers/usb/otg/twl4030-usb.c26
-rw-r--r--drivers/usb/otg/twl6030-usb.c157
-rw-r--r--drivers/usb/phy/Kconfig17
-rw-r--r--drivers/usb/phy/Makefile3
-rw-r--r--drivers/usb/phy/isp1301.c6
-rw-r--r--drivers/usb/phy/mv_u3d_phy.c345
-rw-r--r--drivers/usb/phy/mv_u3d_phy.h105
-rw-r--r--drivers/usb/phy/omap-usb2.c271
-rw-r--r--drivers/usb/phy/tegra_usb_phy.c (renamed from arch/arm/mach-tegra/usb_phy.c)152
-rw-r--r--include/linux/usb/nop-usb-xceiv.h24
-rw-r--r--include/linux/usb/omap_usb.h46
-rw-r--r--include/linux/usb/otg.h236
-rw-r--r--include/linux/usb/phy.h233
-rw-r--r--include/linux/usb/phy_companion.h34
-rw-r--r--include/linux/usb/tegra_usb_phy.h (renamed from arch/arm/mach-tegra/include/mach/usb_phy.h)16
41 files changed, 1596 insertions, 607 deletions
diff --git a/Documentation/devicetree/bindings/usb/twlxxxx-usb.txt b/Documentation/devicetree/bindings/usb/twlxxxx-usb.txt
new file mode 100644
index 000000000000..36b9aede3f40
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/twlxxxx-usb.txt
@@ -0,0 +1,40 @@
1USB COMPARATOR OF TWL CHIPS
2
3TWL6030 USB COMPARATOR
4 - compatible : Should be "ti,twl6030-usb"
5 - interrupts : Two interrupt numbers to the cpu should be specified. First
6 interrupt number is the otg interrupt number that raises ID interrupts when
7 the controller has to act as host and the second interrupt number is the
8 usb interrupt number that raises VBUS interrupts when the controller has to
9 act as device
10 - usb-supply : phandle to the regulator device tree node. It should be vusb
11 if it is twl6030 or ldousb if it is twl6025 subclass.
12
13twl6030-usb {
14 compatible = "ti,twl6030-usb";
15 interrupts = < 4 10 >;
16};
17
18Board specific device node entry
19&twl6030-usb {
20 usb-supply = <&vusb>;
21};
22
23TWL4030 USB PHY AND COMPARATOR
24 - compatible : Should be "ti,twl4030-usb"
25 - interrupts : The interrupt numbers to the cpu should be specified. First
26 interrupt number is the otg interrupt number that raises ID interrupts
27 and VBUS interrupts. The second interrupt number is optional.
28 - <supply-name>-supply : phandle to the regulator device tree node.
29 <supply-name> should be vusb1v5, vusb1v8 and vusb3v1
30 - usb_mode : The mode used by the phy to connect to the controller. "1"
31 specifies "ULPI" mode and "2" specifies "CEA2011_3PIN" mode.
32
33twl4030-usb {
34 compatible = "ti,twl4030-usb";
35 interrupts = < 10 4 >;
36 usb1v5-supply = <&vusb1v5>;
37 usb1v8-supply = <&vusb1v8>;
38 usb3v1-supply = <&vusb3v1>;
39 usb_mode = <1>;
40};
diff --git a/Documentation/devicetree/bindings/usb/usb-phy.txt b/Documentation/devicetree/bindings/usb/usb-phy.txt
new file mode 100644
index 000000000000..80d4148cb661
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/usb-phy.txt
@@ -0,0 +1,17 @@
1USB PHY
2
3OMAP USB2 PHY
4
5Required properties:
6 - compatible: Should be "ti,omap-usb2"
7 - reg : Address and length of the register set for the device. Also
8add the address of control module dev conf register until a driver for
9control module is added
10
11This is usually a subnode of ocp2scp to which it is connected.
12
13usb2phy@4a0ad080 {
14 compatible = "ti,omap-usb2";
15 reg = <0x4a0ad080 0x58>,
16 <0x4a002300 0x4>;
17};
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 0d362e9f9cb9..3d2a988e3d9a 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -32,6 +32,7 @@
32#include <linux/spi/ads7846.h> 32#include <linux/spi/ads7846.h>
33#include <linux/i2c/twl.h> 33#include <linux/i2c/twl.h>
34#include <linux/usb/otg.h> 34#include <linux/usb/otg.h>
35#include <linux/usb/nop-usb-xceiv.h>
35#include <linux/smsc911x.h> 36#include <linux/smsc911x.h>
36 37
37#include <linux/wl12xx.h> 38#include <linux/wl12xx.h>
diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c
index d52651a05daa..874aecc0faca 100644
--- a/arch/arm/mach-omap2/omap_phy_internal.c
+++ b/arch/arm/mach-omap2/omap_phy_internal.c
@@ -31,144 +31,6 @@
31#include <plat/usb.h> 31#include <plat/usb.h>
32#include "control.h" 32#include "control.h"
33 33
34/* OMAP control module register for UTMI PHY */
35#define CONTROL_DEV_CONF 0x300
36#define PHY_PD 0x1
37
38#define USBOTGHS_CONTROL 0x33c
39#define AVALID BIT(0)
40#define BVALID BIT(1)
41#define VBUSVALID BIT(2)
42#define SESSEND BIT(3)
43#define IDDIG BIT(4)
44
45static struct clk *phyclk, *clk48m, *clk32k;
46static void __iomem *ctrl_base;
47static int usbotghs_control;
48
49int omap4430_phy_init(struct device *dev)
50{
51 ctrl_base = ioremap(OMAP443X_SCM_BASE, SZ_1K);
52 if (!ctrl_base) {
53 pr_err("control module ioremap failed\n");
54 return -ENOMEM;
55 }
56 /* Power down the phy */
57 __raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
58
59 if (!dev) {
60 iounmap(ctrl_base);
61 return 0;
62 }
63
64 phyclk = clk_get(dev, "ocp2scp_usb_phy_ick");
65 if (IS_ERR(phyclk)) {
66 dev_err(dev, "cannot clk_get ocp2scp_usb_phy_ick\n");
67 iounmap(ctrl_base);
68 return PTR_ERR(phyclk);
69 }
70
71 clk48m = clk_get(dev, "ocp2scp_usb_phy_phy_48m");
72 if (IS_ERR(clk48m)) {
73 dev_err(dev, "cannot clk_get ocp2scp_usb_phy_phy_48m\n");
74 clk_put(phyclk);
75 iounmap(ctrl_base);
76 return PTR_ERR(clk48m);
77 }
78
79 clk32k = clk_get(dev, "usb_phy_cm_clk32k");
80 if (IS_ERR(clk32k)) {
81 dev_err(dev, "cannot clk_get usb_phy_cm_clk32k\n");
82 clk_put(phyclk);
83 clk_put(clk48m);
84 iounmap(ctrl_base);
85 return PTR_ERR(clk32k);
86 }
87 return 0;
88}
89
90int omap4430_phy_set_clk(struct device *dev, int on)
91{
92 static int state;
93
94 if (on && !state) {
95 /* Enable the phy clocks */
96 clk_enable(phyclk);
97 clk_enable(clk48m);
98 clk_enable(clk32k);
99 state = 1;
100 } else if (state) {
101 /* Disable the phy clocks */
102 clk_disable(phyclk);
103 clk_disable(clk48m);
104 clk_disable(clk32k);
105 state = 0;
106 }
107 return 0;
108}
109
110int omap4430_phy_power(struct device *dev, int ID, int on)
111{
112 if (on) {
113 if (ID)
114 /* enable VBUS valid, IDDIG groung */
115 __raw_writel(AVALID | VBUSVALID, ctrl_base +
116 USBOTGHS_CONTROL);
117 else
118 /*
119 * Enable VBUS Valid, AValid and IDDIG
120 * high impedance
121 */
122 __raw_writel(IDDIG | AVALID | VBUSVALID,
123 ctrl_base + USBOTGHS_CONTROL);
124 } else {
125 /* Enable session END and IDIG to high impedance. */
126 __raw_writel(SESSEND | IDDIG, ctrl_base +
127 USBOTGHS_CONTROL);
128 }
129 return 0;
130}
131
132int omap4430_phy_suspend(struct device *dev, int suspend)
133{
134 if (suspend) {
135 /* Disable the clocks */
136 omap4430_phy_set_clk(dev, 0);
137 /* Power down the phy */
138 __raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
139
140 /* save the context */
141 usbotghs_control = __raw_readl(ctrl_base + USBOTGHS_CONTROL);
142 } else {
143 /* Enable the internel phy clcoks */
144 omap4430_phy_set_clk(dev, 1);
145 /* power on the phy */
146 if (__raw_readl(ctrl_base + CONTROL_DEV_CONF) & PHY_PD) {
147 __raw_writel(~PHY_PD, ctrl_base + CONTROL_DEV_CONF);
148 mdelay(200);
149 }
150
151 /* restore the context */
152 __raw_writel(usbotghs_control, ctrl_base + USBOTGHS_CONTROL);
153 }
154
155 return 0;
156}
157
158int omap4430_phy_exit(struct device *dev)
159{
160 if (ctrl_base)
161 iounmap(ctrl_base);
162 if (phyclk)
163 clk_put(phyclk);
164 if (clk48m)
165 clk_put(clk48m);
166 if (clk32k)
167 clk_put(clk32k);
168
169 return 0;
170}
171
172void am35x_musb_reset(void) 34void am35x_musb_reset(void)
173{ 35{
174 u32 regval; 36 u32 regval;
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
index db5ff6642375..329b726012f3 100644
--- a/arch/arm/mach-omap2/twl-common.c
+++ b/arch/arm/mach-omap2/twl-common.c
@@ -251,11 +251,6 @@ void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
251 251
252#if defined(CONFIG_ARCH_OMAP4) 252#if defined(CONFIG_ARCH_OMAP4)
253static struct twl4030_usb_data omap4_usb_pdata = { 253static struct twl4030_usb_data omap4_usb_pdata = {
254 .phy_init = omap4430_phy_init,
255 .phy_exit = omap4430_phy_exit,
256 .phy_power = omap4430_phy_power,
257 .phy_set_clock = omap4430_phy_set_clk,
258 .phy_suspend = omap4430_phy_suspend,
259}; 254};
260 255
261static struct regulator_init_data omap4_vdac_idata = { 256static struct regulator_init_data omap4_vdac_idata = {
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index c4a576856661..e9b4b234dc5f 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -117,7 +117,4 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
117 dev->dma_mask = &musb_dmamask; 117 dev->dma_mask = &musb_dmamask;
118 dev->coherent_dma_mask = musb_dmamask; 118 dev->coherent_dma_mask = musb_dmamask;
119 put_device(dev); 119 put_device(dev);
120
121 if (cpu_is_omap44xx())
122 omap4430_phy_init(dev);
123} 120}
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index c3d7303b9ac8..0e82b7f34fc1 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -21,7 +21,6 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
21obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o 21obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o
22obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o 22obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
23obj-$(CONFIG_TEGRA_PCI) += pcie.o 23obj-$(CONFIG_TEGRA_PCI) += pcie.o
24obj-$(CONFIG_USB_SUPPORT) += usb_phy.o
25 24
26obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o 25obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o
27obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o 26obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
index c70e65ffa36b..d8ab76276397 100644
--- a/arch/arm/mach-tegra/devices.c
+++ b/arch/arm/mach-tegra/devices.c
@@ -27,7 +27,7 @@
27#include <mach/irqs.h> 27#include <mach/irqs.h>
28#include <mach/iomap.h> 28#include <mach/iomap.h>
29#include <mach/dma.h> 29#include <mach/dma.h>
30#include <mach/usb_phy.h> 30#include <linux/usb/tegra_usb_phy.h>
31 31
32#include "gpio-names.h" 32#include "gpio-names.h"
33#include "devices.h" 33#include "devices.h"
diff --git a/arch/arm/mach-tegra/devices.h b/arch/arm/mach-tegra/devices.h
index 4f5052726495..906a61f340c8 100644
--- a/arch/arm/mach-tegra/devices.h
+++ b/arch/arm/mach-tegra/devices.h
@@ -22,7 +22,7 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/platform_data/tegra_usb.h> 23#include <linux/platform_data/tegra_usb.h>
24 24
25#include <mach/usb_phy.h> 25#include <linux/usb/tegra_usb_phy.h>
26 26
27extern struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config; 27extern struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config;
28 28
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index a68ff53124dc..66d15c2d6b62 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -50,6 +50,7 @@
50#include <linux/dma-mapping.h> 50#include <linux/dma-mapping.h>
51#include <linux/of.h> 51#include <linux/of.h>
52 52
53#include <linux/usb/otg.h>
53#include <linux/usb/ch9.h> 54#include <linux/usb/ch9.h>
54#include <linux/usb/gadget.h> 55#include <linux/usb/gadget.h>
55 56
@@ -136,6 +137,8 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
136 reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST; 137 reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
137 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); 138 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
138 139
140 usb_phy_init(dwc->usb2_phy);
141 usb_phy_init(dwc->usb3_phy);
139 mdelay(100); 142 mdelay(100);
140 143
141 /* Clear USB3 PHY reset */ 144 /* Clear USB3 PHY reset */
@@ -470,6 +473,18 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
470 return -ENOMEM; 473 return -ENOMEM;
471 } 474 }
472 475
476 dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
477 if (IS_ERR_OR_NULL(dwc->usb2_phy)) {
478 dev_err(dev, "no usb2 phy configured\n");
479 return -EPROBE_DEFER;
480 }
481
482 dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
483 if (IS_ERR_OR_NULL(dwc->usb3_phy)) {
484 dev_err(dev, "no usb3 phy configured\n");
485 return -EPROBE_DEFER;
486 }
487
473 spin_lock_init(&dwc->lock); 488 spin_lock_init(&dwc->lock);
474 platform_set_drvdata(pdev, dwc); 489 platform_set_drvdata(pdev, dwc);
475 490
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 151eca876dfd..dbc5713d84fb 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -624,6 +624,8 @@ struct dwc3_scratchpad_array {
624 * @maximum_speed: maximum speed requested (mainly for testing purposes) 624 * @maximum_speed: maximum speed requested (mainly for testing purposes)
625 * @revision: revision register contents 625 * @revision: revision register contents
626 * @mode: mode of operation 626 * @mode: mode of operation
627 * @usb2_phy: pointer to USB2 PHY
628 * @usb3_phy: pointer to USB3 PHY
627 * @is_selfpowered: true when we are selfpowered 629 * @is_selfpowered: true when we are selfpowered
628 * @three_stage_setup: set if we perform a three phase setup 630 * @three_stage_setup: set if we perform a three phase setup
629 * @ep0_bounced: true when we used bounce buffer 631 * @ep0_bounced: true when we used bounce buffer
@@ -667,6 +669,9 @@ struct dwc3 {
667 struct usb_gadget gadget; 669 struct usb_gadget gadget;
668 struct usb_gadget_driver *gadget_driver; 670 struct usb_gadget_driver *gadget_driver;
669 671
672 struct usb_phy *usb2_phy;
673 struct usb_phy *usb3_phy;
674
670 void __iomem *regs; 675 void __iomem *regs;
671 size_t regs_size; 676 size_t regs_size;
672 677
diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
index b8f00389fa34..ca6597853f90 100644
--- a/drivers/usb/dwc3/dwc3-exynos.c
+++ b/drivers/usb/dwc3/dwc3-exynos.c
@@ -19,16 +19,74 @@
19#include <linux/platform_data/dwc3-exynos.h> 19#include <linux/platform_data/dwc3-exynos.h>
20#include <linux/dma-mapping.h> 20#include <linux/dma-mapping.h>
21#include <linux/clk.h> 21#include <linux/clk.h>
22#include <linux/usb/otg.h>
23#include <linux/usb/nop-usb-xceiv.h>
22 24
23#include "core.h" 25#include "core.h"
24 26
25struct dwc3_exynos { 27struct dwc3_exynos {
26 struct platform_device *dwc3; 28 struct platform_device *dwc3;
29 struct platform_device *usb2_phy;
30 struct platform_device *usb3_phy;
27 struct device *dev; 31 struct device *dev;
28 32
29 struct clk *clk; 33 struct clk *clk;
30}; 34};
31 35
36static int __devinit dwc3_exynos_register_phys(struct dwc3_exynos *exynos)
37{
38 struct nop_usb_xceiv_platform_data pdata;
39 struct platform_device *pdev;
40 int ret;
41
42 memset(&pdata, 0x00, sizeof(pdata));
43
44 pdev = platform_device_alloc("nop_usb_xceiv", 0);
45 if (!pdev)
46 return -ENOMEM;
47
48 exynos->usb2_phy = pdev;
49 pdata.type = USB_PHY_TYPE_USB2;
50
51 ret = platform_device_add_data(exynos->usb2_phy, &pdata, sizeof(pdata));
52 if (ret)
53 goto err1;
54
55 pdev = platform_device_alloc("nop_usb_xceiv", 1);
56 if (!pdev) {
57 ret = -ENOMEM;
58 goto err1;
59 }
60
61 exynos->usb3_phy = pdev;
62 pdata.type = USB_PHY_TYPE_USB3;
63
64 ret = platform_device_add_data(exynos->usb3_phy, &pdata, sizeof(pdata));
65 if (ret)
66 goto err2;
67
68 ret = platform_device_add(exynos->usb2_phy);
69 if (ret)
70 goto err2;
71
72 ret = platform_device_add(exynos->usb3_phy);
73 if (ret)
74 goto err3;
75
76 return 0;
77
78err3:
79 platform_device_del(exynos->usb2_phy);
80
81err2:
82 platform_device_put(exynos->usb3_phy);
83
84err1:
85 platform_device_put(exynos->usb2_phy);
86
87 return ret;
88}
89
32static int __devinit dwc3_exynos_probe(struct platform_device *pdev) 90static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
33{ 91{
34 struct dwc3_exynos_data *pdata = pdev->dev.platform_data; 92 struct dwc3_exynos_data *pdata = pdev->dev.platform_data;
@@ -51,6 +109,12 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
51 if (devid < 0) 109 if (devid < 0)
52 goto err1; 110 goto err1;
53 111
112 ret = dwc3_exynos_register_phys(exynos);
113 if (ret) {
114 dev_err(&pdev->dev, "couldn't register PHYs\n");
115 goto err1;
116 }
117
54 dwc3 = platform_device_alloc("dwc3", devid); 118 dwc3 = platform_device_alloc("dwc3", devid);
55 if (!dwc3) { 119 if (!dwc3) {
56 dev_err(&pdev->dev, "couldn't allocate dwc3 device\n"); 120 dev_err(&pdev->dev, "couldn't allocate dwc3 device\n");
@@ -120,6 +184,8 @@ static int __devexit dwc3_exynos_remove(struct platform_device *pdev)
120 struct dwc3_exynos_data *pdata = pdev->dev.platform_data; 184 struct dwc3_exynos_data *pdata = pdev->dev.platform_data;
121 185
122 platform_device_unregister(exynos->dwc3); 186 platform_device_unregister(exynos->dwc3);
187 platform_device_unregister(exynos->usb2_phy);
188 platform_device_unregister(exynos->usb3_phy);
123 189
124 dwc3_put_device_id(exynos->dwc3->id); 190 dwc3_put_device_id(exynos->dwc3->id);
125 191
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 479dc047da3a..ee57a10d90d0 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -48,6 +48,9 @@
48#include <linux/io.h> 48#include <linux/io.h>
49#include <linux/of.h> 49#include <linux/of.h>
50 50
51#include <linux/usb/otg.h>
52#include <linux/usb/nop-usb-xceiv.h>
53
51#include "core.h" 54#include "core.h"
52 55
53/* 56/*
@@ -131,6 +134,8 @@ struct dwc3_omap {
131 spinlock_t lock; 134 spinlock_t lock;
132 135
133 struct platform_device *dwc3; 136 struct platform_device *dwc3;
137 struct platform_device *usb2_phy;
138 struct platform_device *usb3_phy;
134 struct device *dev; 139 struct device *dev;
135 140
136 int irq; 141 int irq;
@@ -152,6 +157,59 @@ static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value)
152 writel(value, base + offset); 157 writel(value, base + offset);
153} 158}
154 159
160static int __devinit dwc3_omap_register_phys(struct dwc3_omap *omap)
161{
162 struct nop_usb_xceiv_platform_data pdata;
163 struct platform_device *pdev;
164 int ret;
165
166 memset(&pdata, 0x00, sizeof(pdata));
167
168 pdev = platform_device_alloc("nop_usb_xceiv", 0);
169 if (!pdev)
170 return -ENOMEM;
171
172 omap->usb2_phy = pdev;
173 pdata.type = USB_PHY_TYPE_USB2;
174
175 ret = platform_device_add_data(omap->usb2_phy, &pdata, sizeof(pdata));
176 if (ret)
177 goto err1;
178
179 pdev = platform_device_alloc("nop_usb_xceiv", 1);
180 if (!pdev) {
181 ret = -ENOMEM;
182 goto err1;
183 }
184
185 omap->usb3_phy = pdev;
186 pdata.type = USB_PHY_TYPE_USB3;
187
188 ret = platform_device_add_data(omap->usb3_phy, &pdata, sizeof(pdata));
189 if (ret)
190 goto err2;
191
192 ret = platform_device_add(omap->usb2_phy);
193 if (ret)
194 goto err2;
195
196 ret = platform_device_add(omap->usb3_phy);
197 if (ret)
198 goto err3;
199
200 return 0;
201
202err3:
203 platform_device_del(omap->usb2_phy);
204
205err2:
206 platform_device_put(omap->usb3_phy);
207
208err1:
209 platform_device_put(omap->usb2_phy);
210
211 return ret;
212}
155 213
156static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap) 214static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
157{ 215{
@@ -251,6 +309,12 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
251 return -ENOMEM; 309 return -ENOMEM;
252 } 310 }
253 311
312 ret = dwc3_omap_register_phys(omap);
313 if (ret) {
314 dev_err(dev, "couldn't register PHYs\n");
315 return ret;
316 }
317
254 devid = dwc3_get_device_id(); 318 devid = dwc3_get_device_id();
255 if (devid < 0) 319 if (devid < 0)
256 return -ENODEV; 320 return -ENODEV;
@@ -371,6 +435,8 @@ static int __devexit dwc3_omap_remove(struct platform_device *pdev)
371 struct dwc3_omap *omap = platform_get_drvdata(pdev); 435 struct dwc3_omap *omap = platform_get_drvdata(pdev);
372 436
373 platform_device_unregister(omap->dwc3); 437 platform_device_unregister(omap->dwc3);
438 platform_device_unregister(omap->usb2_phy);
439 platform_device_unregister(omap->usb3_phy);
374 440
375 dwc3_put_device_id(omap->dwc3->id); 441 dwc3_put_device_id(omap->dwc3->id);
376 442
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index a9ca9adba391..94f550e37f98 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -42,6 +42,9 @@
42#include <linux/pci.h> 42#include <linux/pci.h>
43#include <linux/platform_device.h> 43#include <linux/platform_device.h>
44 44
45#include <linux/usb/otg.h>
46#include <linux/usb/nop-usb-xceiv.h>
47
45#include "core.h" 48#include "core.h"
46 49
47/* FIXME define these in <linux/pci_ids.h> */ 50/* FIXME define these in <linux/pci_ids.h> */
@@ -51,8 +54,64 @@
51struct dwc3_pci { 54struct dwc3_pci {
52 struct device *dev; 55 struct device *dev;
53 struct platform_device *dwc3; 56 struct platform_device *dwc3;
57 struct platform_device *usb2_phy;
58 struct platform_device *usb3_phy;
54}; 59};
55 60
61static int __devinit dwc3_pci_register_phys(struct dwc3_pci *glue)
62{
63 struct nop_usb_xceiv_platform_data pdata;
64 struct platform_device *pdev;
65 int ret;
66
67 memset(&pdata, 0x00, sizeof(pdata));
68
69 pdev = platform_device_alloc("nop_usb_xceiv", 0);
70 if (!pdev)
71 return -ENOMEM;
72
73 glue->usb2_phy = pdev;
74 pdata.type = USB_PHY_TYPE_USB2;
75
76 ret = platform_device_add_data(glue->usb2_phy, &pdata, sizeof(pdata));
77 if (ret)
78 goto err1;
79
80 pdev = platform_device_alloc("nop_usb_xceiv", 1);
81 if (!pdev) {
82 ret = -ENOMEM;
83 goto err1;
84 }
85
86 glue->usb3_phy = pdev;
87 pdata.type = USB_PHY_TYPE_USB3;
88
89 ret = platform_device_add_data(glue->usb3_phy, &pdata, sizeof(pdata));
90 if (ret)
91 goto err2;
92
93 ret = platform_device_add(glue->usb2_phy);
94 if (ret)
95 goto err2;
96
97 ret = platform_device_add(glue->usb3_phy);
98 if (ret)
99 goto err3;
100
101 return 0;
102
103err3:
104 platform_device_del(glue->usb2_phy);
105
106err2:
107 platform_device_put(glue->usb3_phy);
108
109err1:
110 platform_device_put(glue->usb2_phy);
111
112 return ret;
113}
114
56static int __devinit dwc3_pci_probe(struct pci_dev *pci, 115static int __devinit dwc3_pci_probe(struct pci_dev *pci,
57 const struct pci_device_id *id) 116 const struct pci_device_id *id)
58{ 117{
@@ -80,6 +139,12 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
80 pci_set_power_state(pci, PCI_D0); 139 pci_set_power_state(pci, PCI_D0);
81 pci_set_master(pci); 140 pci_set_master(pci);
82 141
142 ret = dwc3_pci_register_phys(glue);
143 if (ret) {
144 dev_err(dev, "couldn't register PHYs\n");
145 return ret;
146 }
147
83 devid = dwc3_get_device_id(); 148 devid = dwc3_get_device_id();
84 if (devid < 0) { 149 if (devid < 0) {
85 ret = -ENOMEM; 150 ret = -ENOMEM;
@@ -144,6 +209,8 @@ static void __devexit dwc3_pci_remove(struct pci_dev *pci)
144{ 209{
145 struct dwc3_pci *glue = pci_get_drvdata(pci); 210 struct dwc3_pci *glue = pci_get_drvdata(pci);
146 211
212 platform_device_unregister(glue->usb2_phy);
213 platform_device_unregister(glue->usb3_phy);
147 dwc3_put_device_id(glue->dwc3->id); 214 dwc3_put_device_id(glue->dwc3->id);
148 platform_device_unregister(glue->dwc3); 215 platform_device_unregister(glue->dwc3);
149 pci_set_drvdata(pci, NULL); 216 pci_set_drvdata(pci, NULL);
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 26dedb30ad0b..c0d47323b52a 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -27,7 +27,7 @@
27#include <linux/of_gpio.h> 27#include <linux/of_gpio.h>
28#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
29 29
30#include <mach/usb_phy.h> 30#include <linux/usb/tegra_usb_phy.h>
31#include <mach/iomap.h> 31#include <mach/iomap.h>
32 32
33#define TEGRA_USB_DMA_ALIGN 32 33#define TEGRA_USB_DMA_ALIGN 32
@@ -49,7 +49,7 @@ static void tegra_ehci_power_up(struct usb_hcd *hcd)
49 49
50 clk_prepare_enable(tegra->emc_clk); 50 clk_prepare_enable(tegra->emc_clk);
51 clk_prepare_enable(tegra->clk); 51 clk_prepare_enable(tegra->clk);
52 tegra_usb_phy_power_on(tegra->phy); 52 usb_phy_set_suspend(&tegra->phy->u_phy, 0);
53 tegra->host_resumed = 1; 53 tegra->host_resumed = 1;
54} 54}
55 55
@@ -58,7 +58,7 @@ static void tegra_ehci_power_down(struct usb_hcd *hcd)
58 struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); 58 struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
59 59
60 tegra->host_resumed = 0; 60 tegra->host_resumed = 0;
61 tegra_usb_phy_power_off(tegra->phy); 61 usb_phy_set_suspend(&tegra->phy->u_phy, 1);
62 clk_disable_unprepare(tegra->clk); 62 clk_disable_unprepare(tegra->clk);
63 clk_disable_unprepare(tegra->emc_clk); 63 clk_disable_unprepare(tegra->emc_clk);
64} 64}
@@ -715,7 +715,9 @@ static int tegra_ehci_probe(struct platform_device *pdev)
715 goto fail_phy; 715 goto fail_phy;
716 } 716 }
717 717
718 err = tegra_usb_phy_power_on(tegra->phy); 718 usb_phy_init(&tegra->phy->u_phy);
719
720 err = usb_phy_set_suspend(&tegra->phy->u_phy, 0);
719 if (err) { 721 if (err) {
720 dev_err(&pdev->dev, "Failed to power on the phy\n"); 722 dev_err(&pdev->dev, "Failed to power on the phy\n");
721 goto fail; 723 goto fail;
@@ -762,7 +764,7 @@ fail:
762 usb_put_phy(tegra->transceiver); 764 usb_put_phy(tegra->transceiver);
763 } 765 }
764#endif 766#endif
765 tegra_usb_phy_close(tegra->phy); 767 usb_phy_shutdown(&tegra->phy->u_phy);
766fail_phy: 768fail_phy:
767 iounmap(hcd->regs); 769 iounmap(hcd->regs);
768fail_io: 770fail_io:
@@ -800,7 +802,7 @@ static int tegra_ehci_remove(struct platform_device *pdev)
800 802
801 usb_remove_hcd(hcd); 803 usb_remove_hcd(hcd);
802 804
803 tegra_usb_phy_close(tegra->phy); 805 usb_phy_shutdown(&tegra->phy->u_phy);
804 iounmap(hcd->regs); 806 iounmap(hcd->regs);
805 807
806 usb_put_hcd(hcd); 808 usb_put_hcd(hcd);
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c
index 7a95ab87ac00..5d64c5b5ef52 100644
--- a/drivers/usb/musb/am35x.c
+++ b/drivers/usb/musb/am35x.c
@@ -33,6 +33,7 @@
33#include <linux/io.h> 33#include <linux/io.h>
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/dma-mapping.h> 35#include <linux/dma-mapping.h>
36#include <linux/usb/nop-usb-xceiv.h>
36 37
37#include <plat/usb.h> 38#include <plat/usb.h>
38 39
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c
index 428e6aa3e78a..b562623a8971 100644
--- a/drivers/usb/musb/blackfin.c
+++ b/drivers/usb/musb/blackfin.c
@@ -19,6 +19,7 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/dma-mapping.h> 20#include <linux/dma-mapping.h>
21#include <linux/prefetch.h> 21#include <linux/prefetch.h>
22#include <linux/usb/nop-usb-xceiv.h>
22 23
23#include <asm/cacheflush.h> 24#include <asm/cacheflush.h>
24 25
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
index 0f9fcec4e1d3..16798c9e6f38 100644
--- a/drivers/usb/musb/da8xx.c
+++ b/drivers/usb/musb/da8xx.c
@@ -33,6 +33,7 @@
33#include <linux/io.h> 33#include <linux/io.h>
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/dma-mapping.h> 35#include <linux/dma-mapping.h>
36#include <linux/usb/nop-usb-xceiv.h>
36 37
37#include <mach/da8xx.h> 38#include <mach/da8xx.h>
38#include <mach/usb.h> 39#include <mach/usb.h>
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 472c8b42d38b..863a9b6286c3 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -33,6 +33,7 @@
33#include <linux/gpio.h> 33#include <linux/gpio.h>
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/dma-mapping.h> 35#include <linux/dma-mapping.h>
36#include <linux/usb/nop-usb-xceiv.h>
36 37
37#include <mach/cputype.h> 38#include <mach/cputype.h>
38#include <mach/hardware.h> 39#include <mach/hardware.h>
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 494772fc9e23..c20b8776aafa 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -36,6 +36,7 @@
36#include <linux/dma-mapping.h> 36#include <linux/dma-mapping.h>
37#include <linux/pm_runtime.h> 37#include <linux/pm_runtime.h>
38#include <linux/module.h> 38#include <linux/module.h>
39#include <linux/usb/nop-usb-xceiv.h>
39 40
40#include <linux/of.h> 41#include <linux/of.h>
41#include <linux/of_device.h> 42#include <linux/of_device.h>
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c
index 341625442377..c38dab190c9b 100644
--- a/drivers/usb/musb/tusb6010.c
+++ b/drivers/usb/musb/tusb6010.c
@@ -24,6 +24,7 @@
24#include <linux/irq.h> 24#include <linux/irq.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/dma-mapping.h> 26#include <linux/dma-mapping.h>
27#include <linux/usb/nop-usb-xceiv.h>
27 28
28#include "musb_core.h" 29#include "musb_core.h"
29 30
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index 13fd1ddf742f..d8c8a42bff3e 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -68,7 +68,7 @@ config TWL4030_USB
68 68
69config TWL6030_USB 69config TWL6030_USB
70 tristate "TWL6030 USB Transceiver Driver" 70 tristate "TWL6030 USB Transceiver Driver"
71 depends on TWL4030_CORE 71 depends on TWL4030_CORE && OMAP_USB2
72 select USB_OTG_UTILS 72 select USB_OTG_UTILS
73 help 73 help
74 Enable this to support the USB OTG transceiver on TWL6030 74 Enable this to support the USB OTG transceiver on TWL6030
diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c
index 23c798cb2d7f..c19d1d7173a9 100644
--- a/drivers/usb/otg/fsl_otg.c
+++ b/drivers/usb/otg/fsl_otg.c
@@ -544,9 +544,13 @@ int fsl_otg_start_gadget(struct otg_fsm *fsm, int on)
544 */ 544 */
545static int fsl_otg_set_host(struct usb_otg *otg, struct usb_bus *host) 545static int fsl_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
546{ 546{
547 struct fsl_otg *otg_dev = container_of(otg->phy, struct fsl_otg, phy); 547 struct fsl_otg *otg_dev;
548
549 if (!otg)
550 return -ENODEV;
548 551
549 if (!otg || otg_dev != fsl_otg_dev) 552 otg_dev = container_of(otg->phy, struct fsl_otg, phy);
553 if (otg_dev != fsl_otg_dev)
550 return -ENODEV; 554 return -ENODEV;
551 555
552 otg->host = host; 556 otg->host = host;
@@ -590,12 +594,15 @@ static int fsl_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
590static int fsl_otg_set_peripheral(struct usb_otg *otg, 594static int fsl_otg_set_peripheral(struct usb_otg *otg,
591 struct usb_gadget *gadget) 595 struct usb_gadget *gadget)
592{ 596{
593 struct fsl_otg *otg_dev = container_of(otg->phy, struct fsl_otg, phy); 597 struct fsl_otg *otg_dev;
594 598
599 if (!otg)
600 return -ENODEV;
601
602 otg_dev = container_of(otg->phy, struct fsl_otg, phy);
595 VDBG("otg_dev 0x%x\n", (int)otg_dev); 603 VDBG("otg_dev 0x%x\n", (int)otg_dev);
596 VDBG("fsl_otg_dev 0x%x\n", (int)fsl_otg_dev); 604 VDBG("fsl_otg_dev 0x%x\n", (int)fsl_otg_dev);
597 605 if (otg_dev != fsl_otg_dev)
598 if (!otg || otg_dev != fsl_otg_dev)
599 return -ENODEV; 606 return -ENODEV;
600 607
601 if (!gadget) { 608 if (!gadget) {
@@ -660,10 +667,13 @@ static void fsl_otg_event(struct work_struct *work)
660/* B-device start SRP */ 667/* B-device start SRP */
661static int fsl_otg_start_srp(struct usb_otg *otg) 668static int fsl_otg_start_srp(struct usb_otg *otg)
662{ 669{
663 struct fsl_otg *otg_dev = container_of(otg->phy, struct fsl_otg, phy); 670 struct fsl_otg *otg_dev;
671
672 if (!otg || otg->phy->state != OTG_STATE_B_IDLE)
673 return -ENODEV;
664 674
665 if (!otg || otg_dev != fsl_otg_dev 675 otg_dev = container_of(otg->phy, struct fsl_otg, phy);
666 || otg->phy->state != OTG_STATE_B_IDLE) 676 if (otg_dev != fsl_otg_dev)
667 return -ENODEV; 677 return -ENODEV;
668 678
669 otg_dev->fsm.b_bus_req = 1; 679 otg_dev->fsm.b_bus_req = 1;
@@ -675,9 +685,13 @@ static int fsl_otg_start_srp(struct usb_otg *otg)
675/* A_host suspend will call this function to start hnp */ 685/* A_host suspend will call this function to start hnp */
676static int fsl_otg_start_hnp(struct usb_otg *otg) 686static int fsl_otg_start_hnp(struct usb_otg *otg)
677{ 687{
678 struct fsl_otg *otg_dev = container_of(otg->phy, struct fsl_otg, phy); 688 struct fsl_otg *otg_dev;
689
690 if (!otg)
691 return -ENODEV;
679 692
680 if (!otg || otg_dev != fsl_otg_dev) 693 otg_dev = container_of(otg->phy, struct fsl_otg, phy);
694 if (otg_dev != fsl_otg_dev)
681 return -ENODEV; 695 return -ENODEV;
682 696
683 DBG("start_hnp...n"); 697 DBG("start_hnp...n");
diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c
index c1a67cb8e244..88db976647cf 100644
--- a/drivers/usb/otg/mxs-phy.c
+++ b/drivers/usb/otg/mxs-phy.c
@@ -20,6 +20,7 @@
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/workqueue.h>
23 24
24#define DRIVER_NAME "mxs_phy" 25#define DRIVER_NAME "mxs_phy"
25 26
@@ -34,9 +35,16 @@
34#define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14) 35#define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14)
35#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1) 36#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1)
36 37
38/*
39 * Amount of delay in miliseconds to safely enable ENHOSTDISCONDETECT bit
40 * so that connection and reset processing can be completed for the root hub.
41 */
42#define MXY_PHY_ENHOSTDISCONDETECT_DELAY 250
43
37struct mxs_phy { 44struct mxs_phy {
38 struct usb_phy phy; 45 struct usb_phy phy;
39 struct clk *clk; 46 struct clk *clk;
47 struct delayed_work enhostdiscondetect_work;
40}; 48};
41 49
42#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) 50#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
@@ -62,6 +70,7 @@ static int mxs_phy_init(struct usb_phy *phy)
62 70
63 clk_prepare_enable(mxs_phy->clk); 71 clk_prepare_enable(mxs_phy->clk);
64 mxs_phy_hw_init(mxs_phy); 72 mxs_phy_hw_init(mxs_phy);
73 INIT_DELAYED_WORK(&mxs_phy->enhostdiscondetect_work, NULL);
65 74
66 return 0; 75 return 0;
67} 76}
@@ -76,13 +85,34 @@ static void mxs_phy_shutdown(struct usb_phy *phy)
76 clk_disable_unprepare(mxs_phy->clk); 85 clk_disable_unprepare(mxs_phy->clk);
77} 86}
78 87
88static void mxs_phy_enhostdiscondetect_delay(struct work_struct *ws)
89{
90 struct mxs_phy *mxs_phy = container_of(ws, struct mxs_phy,
91 enhostdiscondetect_work.work);
92
93 /* Enable HOSTDISCONDETECT after delay. */
94 dev_dbg(mxs_phy->phy.dev, "Setting ENHOSTDISCONDETECT\n");
95 writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
96 mxs_phy->phy.io_priv + HW_USBPHY_CTRL_SET);
97}
98
79static int mxs_phy_on_connect(struct usb_phy *phy, int port) 99static int mxs_phy_on_connect(struct usb_phy *phy, int port)
80{ 100{
101 struct mxs_phy *mxs_phy = to_mxs_phy(phy);
102
81 dev_dbg(phy->dev, "Connect on port %d\n", port); 103 dev_dbg(phy->dev, "Connect on port %d\n", port);
82 104
83 mxs_phy_hw_init(to_mxs_phy(phy)); 105 mxs_phy_hw_init(mxs_phy);
84 writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, 106
85 phy->io_priv + HW_USBPHY_CTRL_SET); 107 /*
108 * Delay enabling ENHOSTDISCONDETECT so that connection and
109 * reset processing can be completed for the root hub.
110 */
111 dev_dbg(phy->dev, "Delaying setting ENHOSTDISCONDETECT\n");
112 PREPARE_DELAYED_WORK(&mxs_phy->enhostdiscondetect_work,
113 mxs_phy_enhostdiscondetect_delay);
114 schedule_delayed_work(&mxs_phy->enhostdiscondetect_work,
115 msecs_to_jiffies(MXY_PHY_ENHOSTDISCONDETECT_DELAY));
86 116
87 return 0; 117 return 0;
88} 118}
@@ -91,6 +121,8 @@ static int mxs_phy_on_disconnect(struct usb_phy *phy, int port)
91{ 121{
92 dev_dbg(phy->dev, "Disconnect on port %d\n", port); 122 dev_dbg(phy->dev, "Disconnect on port %d\n", port);
93 123
124 /* No need to delay before clearing ENHOSTDISCONDETECT. */
125 dev_dbg(phy->dev, "Clearing ENHOSTDISCONDETECT\n");
94 writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, 126 writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
95 phy->io_priv + HW_USBPHY_CTRL_CLR); 127 phy->io_priv + HW_USBPHY_CTRL_CLR);
96 128
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c
index 803f958f4133..e52e35e7adaf 100644
--- a/drivers/usb/otg/nop-usb-xceiv.c
+++ b/drivers/usb/otg/nop-usb-xceiv.c
@@ -30,6 +30,7 @@
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <linux/usb/otg.h> 32#include <linux/usb/otg.h>
33#include <linux/usb/nop-usb-xceiv.h>
33#include <linux/slab.h> 34#include <linux/slab.h>
34 35
35struct nop_usb_xceiv { 36struct nop_usb_xceiv {
@@ -94,7 +95,9 @@ static int nop_set_host(struct usb_otg *otg, struct usb_bus *host)
94 95
95static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev) 96static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev)
96{ 97{
98 struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data;
97 struct nop_usb_xceiv *nop; 99 struct nop_usb_xceiv *nop;
100 enum usb_phy_type type = USB_PHY_TYPE_USB2;
98 int err; 101 int err;
99 102
100 nop = kzalloc(sizeof *nop, GFP_KERNEL); 103 nop = kzalloc(sizeof *nop, GFP_KERNEL);
@@ -107,6 +110,9 @@ static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev)
107 return -ENOMEM; 110 return -ENOMEM;
108 } 111 }
109 112
113 if (pdata)
114 type = pdata->type;
115
110 nop->dev = &pdev->dev; 116 nop->dev = &pdev->dev;
111 nop->phy.dev = nop->dev; 117 nop->phy.dev = nop->dev;
112 nop->phy.label = "nop-xceiv"; 118 nop->phy.label = "nop-xceiv";
@@ -117,7 +123,7 @@ static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev)
117 nop->phy.otg->set_host = nop_set_host; 123 nop->phy.otg->set_host = nop_set_host;
118 nop->phy.otg->set_peripheral = nop_set_peripheral; 124 nop->phy.otg->set_peripheral = nop_set_peripheral;
119 125
120 err = usb_add_phy(&nop->phy, USB_PHY_TYPE_USB2); 126 err = usb_add_phy(&nop->phy, type);
121 if (err) { 127 if (err) {
122 dev_err(&pdev->dev, "can't register transceiver, err: %d\n", 128 dev_err(&pdev->dev, "can't register transceiver, err: %d\n",
123 err); 129 err);
diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c
index 1bf60a22595c..a30c04115115 100644
--- a/drivers/usb/otg/otg.c
+++ b/drivers/usb/otg/otg.c
@@ -159,7 +159,7 @@ int usb_add_phy(struct usb_phy *x, enum usb_phy_type type)
159 unsigned long flags; 159 unsigned long flags;
160 struct usb_phy *phy; 160 struct usb_phy *phy;
161 161
162 if (x && x->type != USB_PHY_TYPE_UNDEFINED) { 162 if (x->type != USB_PHY_TYPE_UNDEFINED) {
163 dev_err(x->dev, "not accepting initialized PHY %s\n", x->label); 163 dev_err(x->dev, "not accepting initialized PHY %s\n", x->label);
164 return -EINVAL; 164 return -EINVAL;
165 } 165 }
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c
index 523cad5bfea9..f0d2e7530cfe 100644
--- a/drivers/usb/otg/twl4030-usb.c
+++ b/drivers/usb/otg/twl4030-usb.c
@@ -585,23 +585,28 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
585 struct twl4030_usb *twl; 585 struct twl4030_usb *twl;
586 int status, err; 586 int status, err;
587 struct usb_otg *otg; 587 struct usb_otg *otg;
588 588 struct device_node *np = pdev->dev.of_node;
589 if (!pdata) {
590 dev_dbg(&pdev->dev, "platform_data not available\n");
591 return -EINVAL;
592 }
593 589
594 twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL); 590 twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL);
595 if (!twl) 591 if (!twl)
596 return -ENOMEM; 592 return -ENOMEM;
597 593
594 if (np)
595 of_property_read_u32(np, "usb_mode",
596 (enum twl4030_usb_mode *)&twl->usb_mode);
597 else if (pdata)
598 twl->usb_mode = pdata->usb_mode;
599 else {
600 dev_err(&pdev->dev, "twl4030 initialized without pdata\n");
601 return -EINVAL;
602 }
603
598 otg = devm_kzalloc(&pdev->dev, sizeof *otg, GFP_KERNEL); 604 otg = devm_kzalloc(&pdev->dev, sizeof *otg, GFP_KERNEL);
599 if (!otg) 605 if (!otg)
600 return -ENOMEM; 606 return -ENOMEM;
601 607
602 twl->dev = &pdev->dev; 608 twl->dev = &pdev->dev;
603 twl->irq = platform_get_irq(pdev, 0); 609 twl->irq = platform_get_irq(pdev, 0);
604 twl->usb_mode = pdata->usb_mode;
605 twl->vbus_supplied = false; 610 twl->vbus_supplied = false;
606 twl->asleep = 1; 611 twl->asleep = 1;
607 twl->linkstat = OMAP_MUSB_UNKNOWN; 612 twl->linkstat = OMAP_MUSB_UNKNOWN;
@@ -690,12 +695,21 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev)
690 return 0; 695 return 0;
691} 696}
692 697
698#ifdef CONFIG_OF
699static const struct of_device_id twl4030_usb_id_table[] = {
700 { .compatible = "ti,twl4030-usb" },
701 {}
702};
703MODULE_DEVICE_TABLE(of, twl4030_usb_id_table);
704#endif
705
693static struct platform_driver twl4030_usb_driver = { 706static struct platform_driver twl4030_usb_driver = {
694 .probe = twl4030_usb_probe, 707 .probe = twl4030_usb_probe,
695 .remove = __exit_p(twl4030_usb_remove), 708 .remove = __exit_p(twl4030_usb_remove),
696 .driver = { 709 .driver = {
697 .name = "twl4030_usb", 710 .name = "twl4030_usb",
698 .owner = THIS_MODULE, 711 .owner = THIS_MODULE,
712 .of_match_table = of_match_ptr(twl4030_usb_id_table),
699 }, 713 },
700}; 714};
701 715
diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c
index 6907d8df7a27..fcadef7864f1 100644
--- a/drivers/usb/otg/twl6030-usb.c
+++ b/drivers/usb/otg/twl6030-usb.c
@@ -25,8 +25,9 @@
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/usb/otg.h>
29#include <linux/usb/musb-omap.h> 28#include <linux/usb/musb-omap.h>
29#include <linux/usb/phy_companion.h>
30#include <linux/usb/omap_usb.h>
30#include <linux/i2c/twl.h> 31#include <linux/i2c/twl.h>
31#include <linux/regulator/consumer.h> 32#include <linux/regulator/consumer.h>
32#include <linux/err.h> 33#include <linux/err.h>
@@ -87,7 +88,7 @@
87#define VBUS_DET BIT(2) 88#define VBUS_DET BIT(2)
88 89
89struct twl6030_usb { 90struct twl6030_usb {
90 struct usb_phy phy; 91 struct phy_companion comparator;
91 struct device *dev; 92 struct device *dev;
92 93
93 /* for vbus reporting with irqs disabled */ 94 /* for vbus reporting with irqs disabled */
@@ -104,10 +105,10 @@ struct twl6030_usb {
104 u8 asleep; 105 u8 asleep;
105 bool irq_enabled; 106 bool irq_enabled;
106 bool vbus_enable; 107 bool vbus_enable;
107 unsigned long features; 108 const char *regulator;
108}; 109};
109 110
110#define phy_to_twl(x) container_of((x), struct twl6030_usb, phy) 111#define comparator_to_twl(x) container_of((x), struct twl6030_usb, comparator)
111 112
112/*-------------------------------------------------------------------------*/ 113/*-------------------------------------------------------------------------*/
113 114
@@ -137,50 +138,9 @@ static inline u8 twl6030_readb(struct twl6030_usb *twl, u8 module, u8 address)
137 return ret; 138 return ret;
138} 139}
139 140
140static int twl6030_phy_init(struct usb_phy *x) 141static int twl6030_start_srp(struct phy_companion *comparator)
141{ 142{
142 struct twl6030_usb *twl; 143 struct twl6030_usb *twl = comparator_to_twl(comparator);
143 struct device *dev;
144 struct twl4030_usb_data *pdata;
145
146 twl = phy_to_twl(x);
147 dev = twl->dev;
148 pdata = dev->platform_data;
149
150 if (twl->linkstat == OMAP_MUSB_ID_GROUND)
151 pdata->phy_power(twl->dev, 1, 1);
152 else
153 pdata->phy_power(twl->dev, 0, 1);
154
155 return 0;
156}
157
158static void twl6030_phy_shutdown(struct usb_phy *x)
159{
160 struct twl6030_usb *twl;
161 struct device *dev;
162 struct twl4030_usb_data *pdata;
163
164 twl = phy_to_twl(x);
165 dev = twl->dev;
166 pdata = dev->platform_data;
167 pdata->phy_power(twl->dev, 0, 0);
168}
169
170static int twl6030_phy_suspend(struct usb_phy *x, int suspend)
171{
172 struct twl6030_usb *twl = phy_to_twl(x);
173 struct device *dev = twl->dev;
174 struct twl4030_usb_data *pdata = dev->platform_data;
175
176 pdata->phy_suspend(dev, suspend);
177
178 return 0;
179}
180
181static int twl6030_start_srp(struct usb_otg *otg)
182{
183 struct twl6030_usb *twl = phy_to_twl(otg->phy);
184 144
185 twl6030_writeb(twl, TWL_MODULE_USB, 0x24, USB_VBUS_CTRL_SET); 145 twl6030_writeb(twl, TWL_MODULE_USB, 0x24, USB_VBUS_CTRL_SET);
186 twl6030_writeb(twl, TWL_MODULE_USB, 0x84, USB_VBUS_CTRL_SET); 146 twl6030_writeb(twl, TWL_MODULE_USB, 0x84, USB_VBUS_CTRL_SET);
@@ -193,13 +153,6 @@ static int twl6030_start_srp(struct usb_otg *otg)
193 153
194static int twl6030_usb_ldo_init(struct twl6030_usb *twl) 154static int twl6030_usb_ldo_init(struct twl6030_usb *twl)
195{ 155{
196 char *regulator_name;
197
198 if (twl->features & TWL6025_SUBCLASS)
199 regulator_name = "ldousb";
200 else
201 regulator_name = "vusb";
202
203 /* Set to OTG_REV 1.3 and turn on the ID_WAKEUP_COMP */ 156 /* Set to OTG_REV 1.3 and turn on the ID_WAKEUP_COMP */
204 twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_BACKUP_REG); 157 twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_BACKUP_REG);
205 158
@@ -209,7 +162,7 @@ static int twl6030_usb_ldo_init(struct twl6030_usb *twl)
209 /* Program MISC2 register and set bit VUSB_IN_VBAT */ 162 /* Program MISC2 register and set bit VUSB_IN_VBAT */
210 twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x10, TWL6030_MISC2); 163 twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x10, TWL6030_MISC2);
211 164
212 twl->usb3v3 = regulator_get(twl->dev, regulator_name); 165 twl->usb3v3 = regulator_get(twl->dev, twl->regulator);
213 if (IS_ERR(twl->usb3v3)) 166 if (IS_ERR(twl->usb3v3))
214 return -ENODEV; 167 return -ENODEV;
215 168
@@ -313,23 +266,8 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl)
313 return IRQ_HANDLED; 266 return IRQ_HANDLED;
314} 267}
315 268
316static int twl6030_set_peripheral(struct usb_otg *otg, 269static int twl6030_enable_irq(struct twl6030_usb *twl)
317 struct usb_gadget *gadget)
318{
319 if (!otg)
320 return -ENODEV;
321
322 otg->gadget = gadget;
323 if (!gadget)
324 otg->phy->state = OTG_STATE_UNDEFINED;
325
326 return 0;
327}
328
329static int twl6030_enable_irq(struct usb_phy *x)
330{ 270{
331 struct twl6030_usb *twl = phy_to_twl(x);
332
333 twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); 271 twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET);
334 twl6030_interrupt_unmask(0x05, REG_INT_MSK_LINE_C); 272 twl6030_interrupt_unmask(0x05, REG_INT_MSK_LINE_C);
335 twl6030_interrupt_unmask(0x05, REG_INT_MSK_STS_C); 273 twl6030_interrupt_unmask(0x05, REG_INT_MSK_STS_C);
@@ -362,9 +300,9 @@ static void otg_set_vbus_work(struct work_struct *data)
362 CHARGERUSB_CTRL1); 300 CHARGERUSB_CTRL1);
363} 301}
364 302
365static int twl6030_set_vbus(struct usb_otg *otg, bool enabled) 303static int twl6030_set_vbus(struct phy_companion *comparator, bool enabled)
366{ 304{
367 struct twl6030_usb *twl = phy_to_twl(otg->phy); 305 struct twl6030_usb *twl = comparator_to_twl(comparator);
368 306
369 twl->vbus_enable = enabled; 307 twl->vbus_enable = enabled;
370 schedule_work(&twl->set_vbus_work); 308 schedule_work(&twl->set_vbus_work);
@@ -372,52 +310,44 @@ static int twl6030_set_vbus(struct usb_otg *otg, bool enabled)
372 return 0; 310 return 0;
373} 311}
374 312
375static int twl6030_set_host(struct usb_otg *otg, struct usb_bus *host)
376{
377 if (!otg)
378 return -ENODEV;
379
380 otg->host = host;
381 if (!host)
382 otg->phy->state = OTG_STATE_UNDEFINED;
383 return 0;
384}
385
386static int __devinit twl6030_usb_probe(struct platform_device *pdev) 313static int __devinit twl6030_usb_probe(struct platform_device *pdev)
387{ 314{
315 u32 ret;
388 struct twl6030_usb *twl; 316 struct twl6030_usb *twl;
389 int status, err; 317 int status, err;
390 struct twl4030_usb_data *pdata; 318 struct device_node *np = pdev->dev.of_node;
391 struct usb_otg *otg; 319 struct device *dev = &pdev->dev;
392 struct device *dev = &pdev->dev; 320 struct twl4030_usb_data *pdata = dev->platform_data;
393 pdata = dev->platform_data;
394 321
395 twl = devm_kzalloc(dev, sizeof *twl, GFP_KERNEL); 322 twl = devm_kzalloc(dev, sizeof *twl, GFP_KERNEL);
396 if (!twl) 323 if (!twl)
397 return -ENOMEM; 324 return -ENOMEM;
398 325
399 otg = devm_kzalloc(dev, sizeof *otg, GFP_KERNEL);
400 if (!otg)
401 return -ENOMEM;
402
403 twl->dev = &pdev->dev; 326 twl->dev = &pdev->dev;
404 twl->irq1 = platform_get_irq(pdev, 0); 327 twl->irq1 = platform_get_irq(pdev, 0);
405 twl->irq2 = platform_get_irq(pdev, 1); 328 twl->irq2 = platform_get_irq(pdev, 1);
406 twl->features = pdata->features;
407 twl->linkstat = OMAP_MUSB_UNKNOWN; 329 twl->linkstat = OMAP_MUSB_UNKNOWN;
408 330
409 twl->phy.dev = twl->dev; 331 twl->comparator.set_vbus = twl6030_set_vbus;
410 twl->phy.label = "twl6030"; 332 twl->comparator.start_srp = twl6030_start_srp;
411 twl->phy.otg = otg; 333
412 twl->phy.init = twl6030_phy_init; 334 ret = omap_usb2_set_comparator(&twl->comparator);
413 twl->phy.shutdown = twl6030_phy_shutdown; 335 if (ret == -ENODEV) {
414 twl->phy.set_suspend = twl6030_phy_suspend; 336 dev_info(&pdev->dev, "phy not ready, deferring probe");
337 return -EPROBE_DEFER;
338 }
415 339
416 otg->phy = &twl->phy; 340 if (np) {
417 otg->set_host = twl6030_set_host; 341 twl->regulator = "usb";
418 otg->set_peripheral = twl6030_set_peripheral; 342 } else if (pdata) {
419 otg->set_vbus = twl6030_set_vbus; 343 if (pdata->features & TWL6025_SUBCLASS)
420 otg->start_srp = twl6030_start_srp; 344 twl->regulator = "ldousb";
345 else
346 twl->regulator = "vusb";
347 } else {
348 dev_err(&pdev->dev, "twl6030 initialized without pdata\n");
349 return -EINVAL;
350 }
421 351
422 /* init spinlock for workqueue */ 352 /* init spinlock for workqueue */
423 spin_lock_init(&twl->lock); 353 spin_lock_init(&twl->lock);
@@ -427,7 +357,6 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev)
427 dev_err(&pdev->dev, "ldo init failed\n"); 357 dev_err(&pdev->dev, "ldo init failed\n");
428 return err; 358 return err;
429 } 359 }
430 usb_add_phy(&twl->phy, USB_PHY_TYPE_USB2);
431 360
432 platform_set_drvdata(pdev, twl); 361 platform_set_drvdata(pdev, twl);
433 if (device_create_file(&pdev->dev, &dev_attr_vbus)) 362 if (device_create_file(&pdev->dev, &dev_attr_vbus))
@@ -458,9 +387,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev)
458 } 387 }
459 388
460 twl->asleep = 0; 389 twl->asleep = 0;
461 pdata->phy_init(dev); 390 twl6030_enable_irq(twl);
462 twl6030_phy_suspend(&twl->phy, 0);
463 twl6030_enable_irq(&twl->phy);
464 dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); 391 dev_info(&pdev->dev, "Initialized TWL6030 USB module\n");
465 392
466 return 0; 393 return 0;
@@ -470,10 +397,6 @@ static int __exit twl6030_usb_remove(struct platform_device *pdev)
470{ 397{
471 struct twl6030_usb *twl = platform_get_drvdata(pdev); 398 struct twl6030_usb *twl = platform_get_drvdata(pdev);
472 399
473 struct twl4030_usb_data *pdata;
474 struct device *dev = &pdev->dev;
475 pdata = dev->platform_data;
476
477 twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, 400 twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK,
478 REG_INT_MSK_LINE_C); 401 REG_INT_MSK_LINE_C);
479 twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, 402 twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK,
@@ -481,19 +404,27 @@ static int __exit twl6030_usb_remove(struct platform_device *pdev)
481 free_irq(twl->irq1, twl); 404 free_irq(twl->irq1, twl);
482 free_irq(twl->irq2, twl); 405 free_irq(twl->irq2, twl);
483 regulator_put(twl->usb3v3); 406 regulator_put(twl->usb3v3);
484 pdata->phy_exit(twl->dev);
485 device_remove_file(twl->dev, &dev_attr_vbus); 407 device_remove_file(twl->dev, &dev_attr_vbus);
486 cancel_work_sync(&twl->set_vbus_work); 408 cancel_work_sync(&twl->set_vbus_work);
487 409
488 return 0; 410 return 0;
489} 411}
490 412
413#ifdef CONFIG_OF
414static const struct of_device_id twl6030_usb_id_table[] = {
415 { .compatible = "ti,twl6030-usb" },
416 {}
417};
418MODULE_DEVICE_TABLE(of, twl6030_usb_id_table);
419#endif
420
491static struct platform_driver twl6030_usb_driver = { 421static struct platform_driver twl6030_usb_driver = {
492 .probe = twl6030_usb_probe, 422 .probe = twl6030_usb_probe,
493 .remove = __exit_p(twl6030_usb_remove), 423 .remove = __exit_p(twl6030_usb_remove),
494 .driver = { 424 .driver = {
495 .name = "twl6030_usb", 425 .name = "twl6030_usb",
496 .owner = THIS_MODULE, 426 .owner = THIS_MODULE,
427 .of_match_table = of_match_ptr(twl6030_usb_id_table),
497 }, 428 },
498}; 429};
499 430
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index e7cf84f0751a..63c339b3e676 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -4,6 +4,15 @@
4comment "USB Physical Layer drivers" 4comment "USB Physical Layer drivers"
5 depends on USB || USB_GADGET 5 depends on USB || USB_GADGET
6 6
7config OMAP_USB2
8 tristate "OMAP USB2 PHY Driver"
9 select USB_OTG_UTILS
10 help
11 Enable this to support the transceiver that is part of SOC. This
12 driver takes care of all the PHY functionality apart from comparator.
13 The USB OTG controller communicates with the comparator using this
14 driver.
15
7config USB_ISP1301 16config USB_ISP1301
8 tristate "NXP ISP1301 USB transceiver support" 17 tristate "NXP ISP1301 USB transceiver support"
9 depends on USB || USB_GADGET 18 depends on USB || USB_GADGET
@@ -15,3 +24,11 @@ config USB_ISP1301
15 24
16 To compile this driver as a module, choose M here: the 25 To compile this driver as a module, choose M here: the
17 module will be called isp1301. 26 module will be called isp1301.
27
28config MV_U3D_PHY
29 bool "Marvell USB 3.0 PHY controller Driver"
30 depends on USB_MV_U3D
31 select USB_OTG_UTILS
32 help
33 Enable this to support Marvell USB 3.0 phy controller for Marvell
34 SoC.
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index eca095b1a890..b069f29f1225 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -4,4 +4,7 @@
4 4
5ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG 5ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
6 6
7obj-$(CONFIG_OMAP_USB2) += omap-usb2.o
7obj-$(CONFIG_USB_ISP1301) += isp1301.o 8obj-$(CONFIG_USB_ISP1301) += isp1301.o
9obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o
10obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o
diff --git a/drivers/usb/phy/isp1301.c b/drivers/usb/phy/isp1301.c
index b19f4932a037..18dbf7e37607 100644
--- a/drivers/usb/phy/isp1301.c
+++ b/drivers/usb/phy/isp1301.c
@@ -15,12 +15,6 @@
15 15
16#define DRV_NAME "isp1301" 16#define DRV_NAME "isp1301"
17 17
18#define ISP1301_I2C_ADDR 0x2C
19
20static const unsigned short normal_i2c[] = {
21 ISP1301_I2C_ADDR, ISP1301_I2C_ADDR + 1, I2C_CLIENT_END
22};
23
24static const struct i2c_device_id isp1301_id[] = { 18static const struct i2c_device_id isp1301_id[] = {
25 { "isp1301", 0 }, 19 { "isp1301", 0 },
26 { } 20 { }
diff --git a/drivers/usb/phy/mv_u3d_phy.c b/drivers/usb/phy/mv_u3d_phy.c
new file mode 100644
index 000000000000..9f1c5d3c60ec
--- /dev/null
+++ b/drivers/usb/phy/mv_u3d_phy.c
@@ -0,0 +1,345 @@
1/*
2 * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 */
8
9#include <linux/module.h>
10#include <linux/platform_device.h>
11#include <linux/clk.h>
12#include <linux/delay.h>
13#include <linux/err.h>
14#include <linux/io.h>
15#include <linux/usb/otg.h>
16#include <linux/platform_data/mv_usb.h>
17
18#include "mv_u3d_phy.h"
19
20/*
21 * struct mv_u3d_phy - transceiver driver state
22 * @phy: transceiver structure
23 * @dev: The parent device supplied to the probe function
24 * @clk: usb phy clock
25 * @base: usb phy register memory base
26 */
27struct mv_u3d_phy {
28 struct usb_phy phy;
29 struct mv_usb_platform_data *plat;
30 struct device *dev;
31 struct clk *clk;
32 void __iomem *base;
33};
34
35static u32 mv_u3d_phy_read(void __iomem *base, u32 reg)
36{
37 void __iomem *addr, *data;
38
39 addr = base;
40 data = base + 0x4;
41
42 writel_relaxed(reg, addr);
43 return readl_relaxed(data);
44}
45
46static void mv_u3d_phy_set(void __iomem *base, u32 reg, u32 value)
47{
48 void __iomem *addr, *data;
49 u32 tmp;
50
51 addr = base;
52 data = base + 0x4;
53
54 writel_relaxed(reg, addr);
55 tmp = readl_relaxed(data);
56 tmp |= value;
57 writel_relaxed(tmp, data);
58}
59
60static void mv_u3d_phy_clear(void __iomem *base, u32 reg, u32 value)
61{
62 void __iomem *addr, *data;
63 u32 tmp;
64
65 addr = base;
66 data = base + 0x4;
67
68 writel_relaxed(reg, addr);
69 tmp = readl_relaxed(data);
70 tmp &= ~value;
71 writel_relaxed(tmp, data);
72}
73
74static void mv_u3d_phy_write(void __iomem *base, u32 reg, u32 value)
75{
76 void __iomem *addr, *data;
77
78 addr = base;
79 data = base + 0x4;
80
81 writel_relaxed(reg, addr);
82 writel_relaxed(value, data);
83}
84
85void mv_u3d_phy_shutdown(struct usb_phy *phy)
86{
87 struct mv_u3d_phy *mv_u3d_phy;
88 void __iomem *base;
89 u32 val;
90
91 mv_u3d_phy = container_of(phy, struct mv_u3d_phy, phy);
92 base = mv_u3d_phy->base;
93
94 /* Power down Reference Analog current, bit 15
95 * Power down PLL, bit 14
96 * Power down Receiver, bit 13
97 * Power down Transmitter, bit 12
98 * of USB3_POWER_PLL_CONTROL register
99 */
100 val = mv_u3d_phy_read(base, USB3_POWER_PLL_CONTROL);
101 val &= ~(USB3_POWER_PLL_CONTROL_PU);
102 mv_u3d_phy_write(base, USB3_POWER_PLL_CONTROL, val);
103
104 if (mv_u3d_phy->clk)
105 clk_disable(mv_u3d_phy->clk);
106}
107
108static int mv_u3d_phy_init(struct usb_phy *phy)
109{
110 struct mv_u3d_phy *mv_u3d_phy;
111 void __iomem *base;
112 u32 val, count;
113
114 /* enable usb3 phy */
115 mv_u3d_phy = container_of(phy, struct mv_u3d_phy, phy);
116
117 if (mv_u3d_phy->clk)
118 clk_enable(mv_u3d_phy->clk);
119
120 base = mv_u3d_phy->base;
121
122 val = mv_u3d_phy_read(base, USB3_POWER_PLL_CONTROL);
123 val &= ~(USB3_POWER_PLL_CONTROL_PU_MASK);
124 val |= 0xF << USB3_POWER_PLL_CONTROL_PU_SHIFT;
125 mv_u3d_phy_write(base, USB3_POWER_PLL_CONTROL, val);
126 udelay(100);
127
128 mv_u3d_phy_write(base, USB3_RESET_CONTROL,
129 USB3_RESET_CONTROL_RESET_PIPE);
130 udelay(100);
131
132 mv_u3d_phy_write(base, USB3_RESET_CONTROL,
133 USB3_RESET_CONTROL_RESET_PIPE
134 | USB3_RESET_CONTROL_RESET_PHY);
135 udelay(100);
136
137 val = mv_u3d_phy_read(base, USB3_POWER_PLL_CONTROL);
138 val &= ~(USB3_POWER_PLL_CONTROL_REF_FREF_SEL_MASK
139 | USB3_POWER_PLL_CONTROL_PHY_MODE_MASK);
140 val |= (USB3_PLL_25MHZ << USB3_POWER_PLL_CONTROL_REF_FREF_SEL_SHIFT)
141 | (0x5 << USB3_POWER_PLL_CONTROL_PHY_MODE_SHIFT);
142 mv_u3d_phy_write(base, USB3_POWER_PLL_CONTROL, val);
143 udelay(100);
144
145 mv_u3d_phy_clear(base, USB3_KVCO_CALI_CONTROL,
146 USB3_KVCO_CALI_CONTROL_USE_MAX_PLL_RATE_MASK);
147 udelay(100);
148
149 val = mv_u3d_phy_read(base, USB3_SQUELCH_FFE);
150 val &= ~(USB3_SQUELCH_FFE_FFE_CAP_SEL_MASK
151 | USB3_SQUELCH_FFE_FFE_RES_SEL_MASK
152 | USB3_SQUELCH_FFE_SQ_THRESH_IN_MASK);
153 val |= ((0xD << USB3_SQUELCH_FFE_FFE_CAP_SEL_SHIFT)
154 | (0x7 << USB3_SQUELCH_FFE_FFE_RES_SEL_SHIFT)
155 | (0x8 << USB3_SQUELCH_FFE_SQ_THRESH_IN_SHIFT));
156 mv_u3d_phy_write(base, USB3_SQUELCH_FFE, val);
157 udelay(100);
158
159 val = mv_u3d_phy_read(base, USB3_GEN1_SET0);
160 val &= ~USB3_GEN1_SET0_G1_TX_SLEW_CTRL_EN_MASK;
161 val |= 1 << USB3_GEN1_SET0_G1_TX_EMPH_EN_SHIFT;
162 mv_u3d_phy_write(base, USB3_GEN1_SET0, val);
163 udelay(100);
164
165 val = mv_u3d_phy_read(base, USB3_GEN2_SET0);
166 val &= ~(USB3_GEN2_SET0_G2_TX_AMP_MASK
167 | USB3_GEN2_SET0_G2_TX_EMPH_AMP_MASK
168 | USB3_GEN2_SET0_G2_TX_SLEW_CTRL_EN_MASK);
169 val |= ((0x14 << USB3_GEN2_SET0_G2_TX_AMP_SHIFT)
170 | (1 << USB3_GEN2_SET0_G2_TX_AMP_ADJ_SHIFT)
171 | (0xA << USB3_GEN2_SET0_G2_TX_EMPH_AMP_SHIFT)
172 | (1 << USB3_GEN2_SET0_G2_TX_EMPH_EN_SHIFT));
173 mv_u3d_phy_write(base, USB3_GEN2_SET0, val);
174 udelay(100);
175
176 mv_u3d_phy_read(base, USB3_TX_EMPPH);
177 val &= ~(USB3_TX_EMPPH_AMP_MASK
178 | USB3_TX_EMPPH_EN_MASK
179 | USB3_TX_EMPPH_AMP_FORCE_MASK
180 | USB3_TX_EMPPH_PAR1_MASK
181 | USB3_TX_EMPPH_PAR2_MASK);
182 val |= ((0xB << USB3_TX_EMPPH_AMP_SHIFT)
183 | (1 << USB3_TX_EMPPH_EN_SHIFT)
184 | (1 << USB3_TX_EMPPH_AMP_FORCE_SHIFT)
185 | (0x1C << USB3_TX_EMPPH_PAR1_SHIFT)
186 | (1 << USB3_TX_EMPPH_PAR2_SHIFT));
187
188 mv_u3d_phy_write(base, USB3_TX_EMPPH, val);
189 udelay(100);
190
191 val = mv_u3d_phy_read(base, USB3_GEN2_SET1);
192 val &= ~(USB3_GEN2_SET1_G2_RX_SELMUPI_MASK
193 | USB3_GEN2_SET1_G2_RX_SELMUPF_MASK
194 | USB3_GEN2_SET1_G2_RX_SELMUFI_MASK
195 | USB3_GEN2_SET1_G2_RX_SELMUFF_MASK);
196 val |= ((1 << USB3_GEN2_SET1_G2_RX_SELMUPI_SHIFT)
197 | (1 << USB3_GEN2_SET1_G2_RX_SELMUPF_SHIFT)
198 | (1 << USB3_GEN2_SET1_G2_RX_SELMUFI_SHIFT)
199 | (1 << USB3_GEN2_SET1_G2_RX_SELMUFF_SHIFT));
200 mv_u3d_phy_write(base, USB3_GEN2_SET1, val);
201 udelay(100);
202
203 val = mv_u3d_phy_read(base, USB3_DIGITAL_LOOPBACK_EN);
204 val &= ~USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_MASK;
205 val |= 1 << USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_SHIFT;
206 mv_u3d_phy_write(base, USB3_DIGITAL_LOOPBACK_EN, val);
207 udelay(100);
208
209 val = mv_u3d_phy_read(base, USB3_IMPEDANCE_TX_SSC);
210 val &= ~USB3_IMPEDANCE_TX_SSC_SSC_AMP_MASK;
211 val |= 0xC << USB3_IMPEDANCE_TX_SSC_SSC_AMP_SHIFT;
212 mv_u3d_phy_write(base, USB3_IMPEDANCE_TX_SSC, val);
213 udelay(100);
214
215 val = mv_u3d_phy_read(base, USB3_IMPEDANCE_CALI_CTRL);
216 val &= ~USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_MASK;
217 val |= 0x4 << USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_SHIFT;
218 mv_u3d_phy_write(base, USB3_IMPEDANCE_CALI_CTRL, val);
219 udelay(100);
220
221 val = mv_u3d_phy_read(base, USB3_PHY_ISOLATION_MODE);
222 val &= ~(USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_MASK
223 | USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_MASK
224 | USB3_PHY_ISOLATION_MODE_TX_DRV_IDLE_MASK);
225 val |= ((1 << USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_SHIFT)
226 | (1 << USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_SHIFT));
227 mv_u3d_phy_write(base, USB3_PHY_ISOLATION_MODE, val);
228 udelay(100);
229
230 val = mv_u3d_phy_read(base, USB3_TXDETRX);
231 val &= ~(USB3_TXDETRX_VTHSEL_MASK);
232 val |= 0x1 << USB3_TXDETRX_VTHSEL_SHIFT;
233 mv_u3d_phy_write(base, USB3_TXDETRX, val);
234 udelay(100);
235
236 dev_dbg(mv_u3d_phy->dev, "start calibration\n");
237
238calstart:
239 /* Perform Manual Calibration */
240 mv_u3d_phy_set(base, USB3_KVCO_CALI_CONTROL,
241 1 << USB3_KVCO_CALI_CONTROL_CAL_START_SHIFT);
242
243 mdelay(1);
244
245 count = 0;
246 while (1) {
247 val = mv_u3d_phy_read(base, USB3_KVCO_CALI_CONTROL);
248 if (val & (1 << USB3_KVCO_CALI_CONTROL_CAL_DONE_SHIFT))
249 break;
250 else if (count > 50) {
251 dev_dbg(mv_u3d_phy->dev, "calibration failure, retry...\n");
252 goto calstart;
253 }
254 count++;
255 mdelay(1);
256 }
257
258 /* active PIPE interface */
259 mv_u3d_phy_write(base, USB3_PIPE_SM_CTRL,
260 1 << USB3_PIPE_SM_CTRL_PHY_INIT_DONE);
261
262 return 0;
263}
264
265static int __devinit mv_u3d_phy_probe(struct platform_device *pdev)
266{
267 struct mv_u3d_phy *mv_u3d_phy;
268 struct mv_usb_platform_data *pdata;
269 struct device *dev = &pdev->dev;
270 struct resource *res;
271 void __iomem *phy_base;
272 int ret;
273
274 pdata = pdev->dev.platform_data;
275 if (!pdata) {
276 dev_err(&pdev->dev, "%s: no platform data defined\n", __func__);
277 return -EINVAL;
278 }
279
280 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
281 if (!res) {
282 dev_err(dev, "missing mem resource\n");
283 return -ENODEV;
284 }
285
286 phy_base = devm_request_and_ioremap(dev, res);
287 if (!phy_base) {
288 dev_err(dev, "%s: register mapping failed\n", __func__);
289 return -ENXIO;
290 }
291
292 mv_u3d_phy = devm_kzalloc(dev, sizeof(*mv_u3d_phy), GFP_KERNEL);
293 if (!mv_u3d_phy)
294 return -ENOMEM;
295
296 mv_u3d_phy->dev = &pdev->dev;
297 mv_u3d_phy->plat = pdata;
298 mv_u3d_phy->base = phy_base;
299 mv_u3d_phy->phy.dev = mv_u3d_phy->dev;
300 mv_u3d_phy->phy.label = "mv-u3d-phy";
301 mv_u3d_phy->phy.init = mv_u3d_phy_init;
302 mv_u3d_phy->phy.shutdown = mv_u3d_phy_shutdown;
303
304 ret = usb_add_phy(&mv_u3d_phy->phy, USB_PHY_TYPE_USB3);
305 if (ret)
306 goto err;
307
308 if (!mv_u3d_phy->clk)
309 mv_u3d_phy->clk = clk_get(mv_u3d_phy->dev, "u3dphy");
310
311 platform_set_drvdata(pdev, mv_u3d_phy);
312
313 dev_info(&pdev->dev, "Initialized Marvell USB 3.0 PHY\n");
314err:
315 return ret;
316}
317
318static int __exit mv_u3d_phy_remove(struct platform_device *pdev)
319{
320 struct mv_u3d_phy *mv_u3d_phy = platform_get_drvdata(pdev);
321
322 usb_remove_phy(&mv_u3d_phy->phy);
323
324 if (mv_u3d_phy->clk) {
325 clk_put(mv_u3d_phy->clk);
326 mv_u3d_phy->clk = NULL;
327 }
328
329 return 0;
330}
331
332static struct platform_driver mv_u3d_phy_driver = {
333 .probe = mv_u3d_phy_probe,
334 .remove = __devexit_p(mv_u3d_phy_remove),
335 .driver = {
336 .name = "mv-u3d-phy",
337 .owner = THIS_MODULE,
338 },
339};
340
341module_platform_driver(mv_u3d_phy_driver);
342MODULE_DESCRIPTION("Marvell USB 3.0 PHY controller");
343MODULE_AUTHOR("Yu Xu <yuxu@marvell.com>");
344MODULE_LICENSE("GPL");
345MODULE_ALIAS("platform:mv-u3d-phy");
diff --git a/drivers/usb/phy/mv_u3d_phy.h b/drivers/usb/phy/mv_u3d_phy.h
new file mode 100644
index 000000000000..2a658cb9a527
--- /dev/null
+++ b/drivers/usb/phy/mv_u3d_phy.h
@@ -0,0 +1,105 @@
1/*
2 * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 */
8
9#ifndef __MV_U3D_PHY_H
10#define __MV_U3D_PHY_H
11
12#define USB3_POWER_PLL_CONTROL 0x1
13#define USB3_KVCO_CALI_CONTROL 0x2
14#define USB3_IMPEDANCE_CALI_CTRL 0x3
15#define USB3_IMPEDANCE_TX_SSC 0x4
16#define USB3_SQUELCH_FFE 0x6
17#define USB3_GEN1_SET0 0xD
18#define USB3_GEN2_SET0 0xF
19#define USB3_GEN2_SET1 0x10
20#define USB3_DIGITAL_LOOPBACK_EN 0x23
21#define USB3_PHY_ISOLATION_MODE 0x26
22#define USB3_TXDETRX 0x48
23#define USB3_TX_EMPPH 0x5E
24#define USB3_RESET_CONTROL 0x90
25#define USB3_PIPE_SM_CTRL 0x91
26
27#define USB3_RESET_CONTROL_RESET_PIPE 0x1
28#define USB3_RESET_CONTROL_RESET_PHY 0x2
29
30#define USB3_POWER_PLL_CONTROL_REF_FREF_SEL_MASK (0x1F << 0)
31#define USB3_POWER_PLL_CONTROL_REF_FREF_SEL_SHIFT 0
32#define USB3_PLL_25MHZ 0x2
33#define USB3_PLL_26MHZ 0x5
34#define USB3_POWER_PLL_CONTROL_PHY_MODE_MASK (0x7 << 5)
35#define USB3_POWER_PLL_CONTROL_PHY_MODE_SHIFT 5
36#define USB3_POWER_PLL_CONTROL_PU_MASK (0xF << 12)
37#define USB3_POWER_PLL_CONTROL_PU_SHIFT 12
38#define USB3_POWER_PLL_CONTROL_PU (0xF << 12)
39
40#define USB3_KVCO_CALI_CONTROL_USE_MAX_PLL_RATE_MASK (0x1 << 12)
41#define USB3_KVCO_CALI_CONTROL_USE_MAX_PLL_RATE_SHIFT 12
42#define USB3_KVCO_CALI_CONTROL_CAL_DONE_SHIFT 14
43#define USB3_KVCO_CALI_CONTROL_CAL_START_SHIFT 15
44
45#define USB3_SQUELCH_FFE_FFE_CAP_SEL_MASK 0xF
46#define USB3_SQUELCH_FFE_FFE_CAP_SEL_SHIFT 0
47#define USB3_SQUELCH_FFE_FFE_RES_SEL_MASK (0x7 << 4)
48#define USB3_SQUELCH_FFE_FFE_RES_SEL_SHIFT 4
49#define USB3_SQUELCH_FFE_SQ_THRESH_IN_MASK (0x1F << 8)
50#define USB3_SQUELCH_FFE_SQ_THRESH_IN_SHIFT 8
51
52#define USB3_GEN1_SET0_G1_TX_SLEW_CTRL_EN_MASK (0x1 << 15)
53#define USB3_GEN1_SET0_G1_TX_EMPH_EN_SHIFT 11
54
55#define USB3_GEN2_SET0_G2_TX_AMP_MASK (0x1F << 1)
56#define USB3_GEN2_SET0_G2_TX_AMP_SHIFT 1
57#define USB3_GEN2_SET0_G2_TX_AMP_ADJ_SHIFT 6
58#define USB3_GEN2_SET0_G2_TX_EMPH_AMP_MASK (0xF << 7)
59#define USB3_GEN2_SET0_G2_TX_EMPH_AMP_SHIFT 7
60#define USB3_GEN2_SET0_G2_TX_EMPH_EN_MASK (0x1 << 11)
61#define USB3_GEN2_SET0_G2_TX_EMPH_EN_SHIFT 11
62#define USB3_GEN2_SET0_G2_TX_SLEW_CTRL_EN_MASK (0x1 << 15)
63#define USB3_GEN2_SET0_G2_TX_SLEW_CTRL_EN_SHIFT 15
64
65#define USB3_GEN2_SET1_G2_RX_SELMUPI_MASK (0x7 << 0)
66#define USB3_GEN2_SET1_G2_RX_SELMUPI_SHIFT 0
67#define USB3_GEN2_SET1_G2_RX_SELMUPF_MASK (0x7 << 3)
68#define USB3_GEN2_SET1_G2_RX_SELMUPF_SHIFT 3
69#define USB3_GEN2_SET1_G2_RX_SELMUFI_MASK (0x3 << 6)
70#define USB3_GEN2_SET1_G2_RX_SELMUFI_SHIFT 6
71#define USB3_GEN2_SET1_G2_RX_SELMUFF_MASK (0x3 << 8)
72#define USB3_GEN2_SET1_G2_RX_SELMUFF_SHIFT 8
73
74#define USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_MASK (0x3 << 10)
75#define USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_SHIFT 10
76
77#define USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_MASK (0x7 << 12)
78#define USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_SHIFT 12
79
80#define USB3_IMPEDANCE_TX_SSC_SSC_AMP_MASK (0x3F << 0)
81#define USB3_IMPEDANCE_TX_SSC_SSC_AMP_SHIFT 0
82
83#define USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_MASK 0xF
84#define USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_SHIFT 0
85#define USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_MASK (0xF << 4)
86#define USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_SHIFT 4
87#define USB3_PHY_ISOLATION_MODE_TX_DRV_IDLE_MASK (0x1 << 8)
88
89#define USB3_TXDETRX_VTHSEL_MASK (0x3 << 4)
90#define USB3_TXDETRX_VTHSEL_SHIFT 4
91
92#define USB3_TX_EMPPH_AMP_MASK (0xF << 0)
93#define USB3_TX_EMPPH_AMP_SHIFT 0
94#define USB3_TX_EMPPH_EN_MASK (0x1 << 6)
95#define USB3_TX_EMPPH_EN_SHIFT 6
96#define USB3_TX_EMPPH_AMP_FORCE_MASK (0x1 << 7)
97#define USB3_TX_EMPPH_AMP_FORCE_SHIFT 7
98#define USB3_TX_EMPPH_PAR1_MASK (0x1F << 8)
99#define USB3_TX_EMPPH_PAR1_SHIFT 8
100#define USB3_TX_EMPPH_PAR2_MASK (0x1 << 13)
101#define USB3_TX_EMPPH_PAR2_SHIFT 13
102
103#define USB3_PIPE_SM_CTRL_PHY_INIT_DONE 15
104
105#endif /* __MV_U3D_PHY_H */
diff --git a/drivers/usb/phy/omap-usb2.c b/drivers/usb/phy/omap-usb2.c
new file mode 100644
index 000000000000..15ab3d6f2e8c
--- /dev/null
+++ b/drivers/usb/phy/omap-usb2.c
@@ -0,0 +1,271 @@
1/*
2 * omap-usb2.c - USB PHY, talking to musb controller in OMAP.
3 *
4 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * Author: Kishon Vijay Abraham I <kishon@ti.com>
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h>
22#include <linux/of.h>
23#include <linux/io.h>
24#include <linux/usb/omap_usb.h>
25#include <linux/usb/phy_companion.h>
26#include <linux/clk.h>
27#include <linux/err.h>
28#include <linux/pm_runtime.h>
29#include <linux/delay.h>
30
31/**
32 * omap_usb2_set_comparator - links the comparator present in the sytem with
33 * this phy
34 * @comparator - the companion phy(comparator) for this phy
35 *
36 * The phy companion driver should call this API passing the phy_companion
37 * filled with set_vbus and start_srp to be used by usb phy.
38 *
39 * For use by phy companion driver
40 */
41int omap_usb2_set_comparator(struct phy_companion *comparator)
42{
43 struct omap_usb *phy;
44 struct usb_phy *x = usb_get_phy(USB_PHY_TYPE_USB2);
45
46 if (IS_ERR(x))
47 return -ENODEV;
48
49 phy = phy_to_omapusb(x);
50 phy->comparator = comparator;
51 return 0;
52}
53EXPORT_SYMBOL_GPL(omap_usb2_set_comparator);
54
55/**
56 * omap_usb_phy_power - power on/off the phy using control module reg
57 * @phy: struct omap_usb *
58 * @on: 0 or 1, based on powering on or off the PHY
59 *
60 * XXX: Remove this function once control module driver gets merged
61 */
62static void omap_usb_phy_power(struct omap_usb *phy, int on)
63{
64 u32 val;
65
66 if (on) {
67 val = readl(phy->control_dev);
68 if (val & PHY_PD) {
69 writel(~PHY_PD, phy->control_dev);
70 /* XXX: add proper documentation for this delay */
71 mdelay(200);
72 }
73 } else {
74 writel(PHY_PD, phy->control_dev);
75 }
76}
77
78static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled)
79{
80 struct omap_usb *phy = phy_to_omapusb(otg->phy);
81
82 if (!phy->comparator)
83 return -ENODEV;
84
85 return phy->comparator->set_vbus(phy->comparator, enabled);
86}
87
88static int omap_usb_start_srp(struct usb_otg *otg)
89{
90 struct omap_usb *phy = phy_to_omapusb(otg->phy);
91
92 if (!phy->comparator)
93 return -ENODEV;
94
95 return phy->comparator->start_srp(phy->comparator);
96}
97
98static int omap_usb_set_host(struct usb_otg *otg, struct usb_bus *host)
99{
100 struct usb_phy *phy = otg->phy;
101
102 otg->host = host;
103 if (!host)
104 phy->state = OTG_STATE_UNDEFINED;
105
106 return 0;
107}
108
109static int omap_usb_set_peripheral(struct usb_otg *otg,
110 struct usb_gadget *gadget)
111{
112 struct usb_phy *phy = otg->phy;
113
114 otg->gadget = gadget;
115 if (!gadget)
116 phy->state = OTG_STATE_UNDEFINED;
117
118 return 0;
119}
120
121static int omap_usb2_suspend(struct usb_phy *x, int suspend)
122{
123 u32 ret;
124 struct omap_usb *phy = phy_to_omapusb(x);
125
126 if (suspend && !phy->is_suspended) {
127 omap_usb_phy_power(phy, 0);
128 pm_runtime_put_sync(phy->dev);
129 phy->is_suspended = 1;
130 } else if (!suspend && phy->is_suspended) {
131 ret = pm_runtime_get_sync(phy->dev);
132 if (ret < 0) {
133 dev_err(phy->dev, "get_sync failed with err %d\n",
134 ret);
135 return ret;
136 }
137 omap_usb_phy_power(phy, 1);
138 phy->is_suspended = 0;
139 }
140
141 return 0;
142}
143
144static int __devinit omap_usb2_probe(struct platform_device *pdev)
145{
146 struct omap_usb *phy;
147 struct usb_otg *otg;
148 struct resource *res;
149
150 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
151 if (!phy) {
152 dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n");
153 return -ENOMEM;
154 }
155
156 otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
157 if (!otg) {
158 dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n");
159 return -ENOMEM;
160 }
161
162 phy->dev = &pdev->dev;
163
164 phy->phy.dev = phy->dev;
165 phy->phy.label = "omap-usb2";
166 phy->phy.set_suspend = omap_usb2_suspend;
167 phy->phy.otg = otg;
168
169 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
170
171 phy->control_dev = devm_request_and_ioremap(&pdev->dev, res);
172 if (phy->control_dev == NULL) {
173 dev_err(&pdev->dev, "Failed to obtain io memory\n");
174 return -ENXIO;
175 }
176
177 phy->is_suspended = 1;
178 omap_usb_phy_power(phy, 0);
179
180 otg->set_host = omap_usb_set_host;
181 otg->set_peripheral = omap_usb_set_peripheral;
182 otg->set_vbus = omap_usb_set_vbus;
183 otg->start_srp = omap_usb_start_srp;
184 otg->phy = &phy->phy;
185
186 phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k");
187 if (IS_ERR(phy->wkupclk)) {
188 dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n");
189 return PTR_ERR(phy->wkupclk);
190 }
191 clk_prepare(phy->wkupclk);
192
193 usb_add_phy(&phy->phy, USB_PHY_TYPE_USB2);
194
195 platform_set_drvdata(pdev, phy);
196
197 pm_runtime_enable(phy->dev);
198
199 return 0;
200}
201
202static int __devexit omap_usb2_remove(struct platform_device *pdev)
203{
204 struct omap_usb *phy = platform_get_drvdata(pdev);
205
206 clk_unprepare(phy->wkupclk);
207 usb_remove_phy(&phy->phy);
208
209 return 0;
210}
211
212#ifdef CONFIG_PM_RUNTIME
213
214static int omap_usb2_runtime_suspend(struct device *dev)
215{
216 struct platform_device *pdev = to_platform_device(dev);
217 struct omap_usb *phy = platform_get_drvdata(pdev);
218
219 clk_disable(phy->wkupclk);
220
221 return 0;
222}
223
224static int omap_usb2_runtime_resume(struct device *dev)
225{
226 u32 ret = 0;
227 struct platform_device *pdev = to_platform_device(dev);
228 struct omap_usb *phy = platform_get_drvdata(pdev);
229
230 ret = clk_enable(phy->wkupclk);
231 if (ret < 0)
232 dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret);
233
234 return ret;
235}
236
237static const struct dev_pm_ops omap_usb2_pm_ops = {
238 SET_RUNTIME_PM_OPS(omap_usb2_runtime_suspend, omap_usb2_runtime_resume,
239 NULL)
240};
241
242#define DEV_PM_OPS (&omap_usb2_pm_ops)
243#else
244#define DEV_PM_OPS NULL
245#endif
246
247#ifdef CONFIG_OF
248static const struct of_device_id omap_usb2_id_table[] = {
249 { .compatible = "ti,omap-usb2" },
250 {}
251};
252MODULE_DEVICE_TABLE(of, omap_usb2_id_table);
253#endif
254
255static struct platform_driver omap_usb2_driver = {
256 .probe = omap_usb2_probe,
257 .remove = __devexit_p(omap_usb2_remove),
258 .driver = {
259 .name = "omap-usb2",
260 .owner = THIS_MODULE,
261 .pm = DEV_PM_OPS,
262 .of_match_table = of_match_ptr(omap_usb2_id_table),
263 },
264};
265
266module_platform_driver(omap_usb2_driver);
267
268MODULE_ALIAS("platform: omap_usb2");
269MODULE_AUTHOR("Texas Instruments Inc.");
270MODULE_DESCRIPTION("OMAP USB2 phy driver");
271MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-tegra/usb_phy.c b/drivers/usb/phy/tegra_usb_phy.c
index 022b33a05c3a..4739903245e8 100644
--- a/arch/arm/mach-tegra/usb_phy.c
+++ b/drivers/usb/phy/tegra_usb_phy.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/arm/mach-tegra/usb_phy.c
3 *
4 * Copyright (C) 2010 Google, Inc. 2 * Copyright (C) 2010 Google, Inc.
5 * 3 *
6 * Author: 4 * Author:
@@ -31,7 +29,7 @@
31#include <linux/usb/ulpi.h> 29#include <linux/usb/ulpi.h>
32#include <asm/mach-types.h> 30#include <asm/mach-types.h>
33#include <mach/gpio-tegra.h> 31#include <mach/gpio-tegra.h>
34#include <mach/usb_phy.h> 32#include <linux/usb/tegra_usb_phy.h>
35#include <mach/iomap.h> 33#include <mach/iomap.h>
36 34
37#define ULPI_VIEWPORT 0x170 35#define ULPI_VIEWPORT 0x170
@@ -482,7 +480,7 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
482 return 0; 480 return 0;
483} 481}
484 482
485static void utmi_phy_power_off(struct tegra_usb_phy *phy) 483static int utmi_phy_power_off(struct tegra_usb_phy *phy)
486{ 484{
487 unsigned long val; 485 unsigned long val;
488 void __iomem *base = phy->regs; 486 void __iomem *base = phy->regs;
@@ -514,7 +512,7 @@ static void utmi_phy_power_off(struct tegra_usb_phy *phy)
514 UTMIP_FORCE_PDDR_POWERDOWN; 512 UTMIP_FORCE_PDDR_POWERDOWN;
515 writel(val, base + UTMIP_XCVR_CFG1); 513 writel(val, base + UTMIP_XCVR_CFG1);
516 514
517 utmip_pad_power_off(phy); 515 return utmip_pad_power_off(phy);
518} 516}
519 517
520static void utmi_phy_preresume(struct tegra_usb_phy *phy) 518static void utmi_phy_preresume(struct tegra_usb_phy *phy)
@@ -638,7 +636,7 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy)
638 return 0; 636 return 0;
639} 637}
640 638
641static void ulpi_phy_power_off(struct tegra_usb_phy *phy) 639static int ulpi_phy_power_off(struct tegra_usb_phy *phy)
642{ 640{
643 unsigned long val; 641 unsigned long val;
644 void __iomem *base = phy->regs; 642 void __iomem *base = phy->regs;
@@ -651,15 +649,92 @@ static void ulpi_phy_power_off(struct tegra_usb_phy *phy)
651 val &= ~(USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN); 649 val &= ~(USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN);
652 writel(val, base + USB_PORTSC1); 650 writel(val, base + USB_PORTSC1);
653 651
654 gpio_direction_output(config->reset_gpio, 0);
655 clk_disable(phy->clk); 652 clk_disable(phy->clk);
653 return gpio_direction_output(config->reset_gpio, 0);
654}
655
656static int tegra_phy_init(struct usb_phy *x)
657{
658 struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
659 struct tegra_ulpi_config *ulpi_config;
660 int err;
661
662 if (phy_is_ulpi(phy)) {
663 ulpi_config = phy->config;
664 phy->clk = clk_get_sys(NULL, ulpi_config->clk);
665 if (IS_ERR(phy->clk)) {
666 pr_err("%s: can't get ulpi clock\n", __func__);
667 err = -ENXIO;
668 goto err1;
669 }
670 if (!gpio_is_valid(ulpi_config->reset_gpio))
671 ulpi_config->reset_gpio =
672 of_get_named_gpio(phy->dev->of_node,
673 "nvidia,phy-reset-gpio", 0);
674 if (!gpio_is_valid(ulpi_config->reset_gpio)) {
675 pr_err("%s: invalid reset gpio: %d\n", __func__,
676 ulpi_config->reset_gpio);
677 err = -EINVAL;
678 goto err1;
679 }
680 gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b");
681 gpio_direction_output(ulpi_config->reset_gpio, 0);
682 phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
683 phy->ulpi->io_priv = phy->regs + ULPI_VIEWPORT;
684 } else {
685 err = utmip_pad_open(phy);
686 if (err < 0)
687 goto err1;
688 }
689 return 0;
690err1:
691 clk_disable_unprepare(phy->pll_u);
692 clk_put(phy->pll_u);
693 return err;
694}
695
696static void tegra_usb_phy_close(struct usb_phy *x)
697{
698 struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
699
700 if (phy_is_ulpi(phy))
701 clk_put(phy->clk);
702 else
703 utmip_pad_close(phy);
704 clk_disable_unprepare(phy->pll_u);
705 clk_put(phy->pll_u);
706 kfree(phy);
707}
708
709static int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
710{
711 if (phy_is_ulpi(phy))
712 return ulpi_phy_power_on(phy);
713 else
714 return utmi_phy_power_on(phy);
715}
716
717static int tegra_usb_phy_power_off(struct tegra_usb_phy *phy)
718{
719 if (phy_is_ulpi(phy))
720 return ulpi_phy_power_off(phy);
721 else
722 return utmi_phy_power_off(phy);
723}
724
725static int tegra_usb_phy_suspend(struct usb_phy *x, int suspend)
726{
727 struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
728 if (suspend)
729 return tegra_usb_phy_power_off(phy);
730 else
731 return tegra_usb_phy_power_on(phy);
656} 732}
657 733
658struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, 734struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
659 void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode) 735 void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode)
660{ 736{
661 struct tegra_usb_phy *phy; 737 struct tegra_usb_phy *phy;
662 struct tegra_ulpi_config *ulpi_config;
663 unsigned long parent_rate; 738 unsigned long parent_rate;
664 int i; 739 int i;
665 int err; 740 int err;
@@ -672,6 +747,7 @@ struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
672 phy->regs = regs; 747 phy->regs = regs;
673 phy->config = config; 748 phy->config = config;
674 phy->mode = phy_mode; 749 phy->mode = phy_mode;
750 phy->dev = dev;
675 751
676 if (!phy->config) { 752 if (!phy->config) {
677 if (phy_is_ulpi(phy)) { 753 if (phy_is_ulpi(phy)) {
@@ -704,33 +780,9 @@ struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
704 goto err1; 780 goto err1;
705 } 781 }
706 782
707 if (phy_is_ulpi(phy)) { 783 phy->u_phy.init = tegra_phy_init;
708 ulpi_config = config; 784 phy->u_phy.shutdown = tegra_usb_phy_close;
709 phy->clk = clk_get_sys(NULL, ulpi_config->clk); 785 phy->u_phy.set_suspend = tegra_usb_phy_suspend;
710 if (IS_ERR(phy->clk)) {
711 pr_err("%s: can't get ulpi clock\n", __func__);
712 err = -ENXIO;
713 goto err1;
714 }
715 if (!gpio_is_valid(ulpi_config->reset_gpio))
716 ulpi_config->reset_gpio =
717 of_get_named_gpio(dev->of_node,
718 "nvidia,phy-reset-gpio", 0);
719 if (!gpio_is_valid(ulpi_config->reset_gpio)) {
720 pr_err("%s: invalid reset gpio: %d\n", __func__,
721 ulpi_config->reset_gpio);
722 err = -EINVAL;
723 goto err1;
724 }
725 gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b");
726 gpio_direction_output(ulpi_config->reset_gpio, 0);
727 phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
728 phy->ulpi->io_priv = regs + ULPI_VIEWPORT;
729 } else {
730 err = utmip_pad_open(phy);
731 if (err < 0)
732 goto err1;
733 }
734 786
735 return phy; 787 return phy;
736 788
@@ -743,24 +795,6 @@ err0:
743} 795}
744EXPORT_SYMBOL_GPL(tegra_usb_phy_open); 796EXPORT_SYMBOL_GPL(tegra_usb_phy_open);
745 797
746int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
747{
748 if (phy_is_ulpi(phy))
749 return ulpi_phy_power_on(phy);
750 else
751 return utmi_phy_power_on(phy);
752}
753EXPORT_SYMBOL_GPL(tegra_usb_phy_power_on);
754
755void tegra_usb_phy_power_off(struct tegra_usb_phy *phy)
756{
757 if (phy_is_ulpi(phy))
758 ulpi_phy_power_off(phy);
759 else
760 utmi_phy_power_off(phy);
761}
762EXPORT_SYMBOL_GPL(tegra_usb_phy_power_off);
763
764void tegra_usb_phy_preresume(struct tegra_usb_phy *phy) 798void tegra_usb_phy_preresume(struct tegra_usb_phy *phy)
765{ 799{
766 if (!phy_is_ulpi(phy)) 800 if (!phy_is_ulpi(phy))
@@ -803,15 +837,3 @@ void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy)
803 utmi_phy_clk_enable(phy); 837 utmi_phy_clk_enable(phy);
804} 838}
805EXPORT_SYMBOL_GPL(tegra_usb_phy_clk_enable); 839EXPORT_SYMBOL_GPL(tegra_usb_phy_clk_enable);
806
807void tegra_usb_phy_close(struct tegra_usb_phy *phy)
808{
809 if (phy_is_ulpi(phy))
810 clk_put(phy->clk);
811 else
812 utmip_pad_close(phy);
813 clk_disable_unprepare(phy->pll_u);
814 clk_put(phy->pll_u);
815 kfree(phy);
816}
817EXPORT_SYMBOL_GPL(tegra_usb_phy_close);
diff --git a/include/linux/usb/nop-usb-xceiv.h b/include/linux/usb/nop-usb-xceiv.h
new file mode 100644
index 000000000000..28884c717411
--- /dev/null
+++ b/include/linux/usb/nop-usb-xceiv.h
@@ -0,0 +1,24 @@
1#ifndef __LINUX_USB_NOP_XCEIV_H
2#define __LINUX_USB_NOP_XCEIV_H
3
4#include <linux/usb/otg.h>
5
6struct nop_usb_xceiv_platform_data {
7 enum usb_phy_type type;
8};
9
10#if defined(CONFIG_NOP_USB_XCEIV) || (defined(CONFIG_NOP_USB_XCEIV_MODULE) && defined(MODULE))
11/* sometimes transceivers are accessed only through e.g. ULPI */
12extern void usb_nop_xceiv_register(void);
13extern void usb_nop_xceiv_unregister(void);
14#else
15static inline void usb_nop_xceiv_register(void)
16{
17}
18
19static inline void usb_nop_xceiv_unregister(void)
20{
21}
22#endif
23
24#endif /* __LINUX_USB_NOP_XCEIV_H */
diff --git a/include/linux/usb/omap_usb.h b/include/linux/usb/omap_usb.h
new file mode 100644
index 000000000000..0ea17f8ae820
--- /dev/null
+++ b/include/linux/usb/omap_usb.h
@@ -0,0 +1,46 @@
1/*
2 * omap_usb.h -- omap usb2 phy header file
3 *
4 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * Author: Kishon Vijay Abraham I <kishon@ti.com>
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#ifndef __DRIVERS_OMAP_USB2_H
20#define __DRIVERS_OMAP_USB2_H
21
22#include <linux/usb/otg.h>
23
24struct omap_usb {
25 struct usb_phy phy;
26 struct phy_companion *comparator;
27 struct device *dev;
28 u32 __iomem *control_dev;
29 struct clk *wkupclk;
30 u8 is_suspended:1;
31};
32
33#define PHY_PD 0x1
34
35#define phy_to_omapusb(x) container_of((x), struct omap_usb, phy)
36
37#if defined(CONFIG_OMAP_USB2) || defined(CONFIG_OMAP_USB2_MODULE)
38extern int omap_usb2_set_comparator(struct phy_companion *comparator);
39#else
40static inline int omap_usb2_set_comparator(struct phy_companion *comparator)
41{
42 return -ENODEV;
43}
44#endif
45
46#endif /* __DRIVERS_OMAP_USB_H */
diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h
index 45824be0a2f9..e8a5fe87c6bd 100644
--- a/include/linux/usb/otg.h
+++ b/include/linux/usb/otg.h
@@ -9,56 +9,7 @@
9#ifndef __LINUX_USB_OTG_H 9#ifndef __LINUX_USB_OTG_H
10#define __LINUX_USB_OTG_H 10#define __LINUX_USB_OTG_H
11 11
12#include <linux/notifier.h> 12#include <linux/usb/phy.h>
13
14/* OTG defines lots of enumeration states before device reset */
15enum usb_otg_state {
16 OTG_STATE_UNDEFINED = 0,
17
18 /* single-role peripheral, and dual-role default-b */
19 OTG_STATE_B_IDLE,
20 OTG_STATE_B_SRP_INIT,
21 OTG_STATE_B_PERIPHERAL,
22
23 /* extra dual-role default-b states */
24 OTG_STATE_B_WAIT_ACON,
25 OTG_STATE_B_HOST,
26
27 /* dual-role default-a */
28 OTG_STATE_A_IDLE,
29 OTG_STATE_A_WAIT_VRISE,
30 OTG_STATE_A_WAIT_BCON,
31 OTG_STATE_A_HOST,
32 OTG_STATE_A_SUSPEND,
33 OTG_STATE_A_PERIPHERAL,
34 OTG_STATE_A_WAIT_VFALL,
35 OTG_STATE_A_VBUS_ERR,
36};
37
38enum usb_phy_events {
39 USB_EVENT_NONE, /* no events or cable disconnected */
40 USB_EVENT_VBUS, /* vbus valid event */
41 USB_EVENT_ID, /* id was grounded */
42 USB_EVENT_CHARGER, /* usb dedicated charger */
43 USB_EVENT_ENUMERATED, /* gadget driver enumerated */
44};
45
46/* associate a type with PHY */
47enum usb_phy_type {
48 USB_PHY_TYPE_UNDEFINED,
49 USB_PHY_TYPE_USB2,
50 USB_PHY_TYPE_USB3,
51};
52
53struct usb_phy;
54
55/* for transceivers connected thru an ULPI interface, the user must
56 * provide access ops
57 */
58struct usb_phy_io_ops {
59 int (*read)(struct usb_phy *x, u32 reg);
60 int (*write)(struct usb_phy *x, u32 val, u32 reg);
61};
62 13
63struct usb_otg { 14struct usb_otg {
64 u8 default_a; 15 u8 default_a;
@@ -85,134 +36,9 @@ struct usb_otg {
85 36
86}; 37};
87 38
88/*
89 * the otg driver needs to interact with both device side and host side
90 * usb controllers. it decides which controller is active at a given
91 * moment, using the transceiver, ID signal, HNP and sometimes static
92 * configuration information (including "board isn't wired for otg").
93 */
94struct usb_phy {
95 struct device *dev;
96 const char *label;
97 unsigned int flags;
98
99 enum usb_phy_type type;
100 enum usb_otg_state state;
101 enum usb_phy_events last_event;
102
103 struct usb_otg *otg;
104
105 struct device *io_dev;
106 struct usb_phy_io_ops *io_ops;
107 void __iomem *io_priv;
108
109 /* for notification of usb_phy_events */
110 struct atomic_notifier_head notifier;
111
112 /* to pass extra port status to the root hub */
113 u16 port_status;
114 u16 port_change;
115
116 /* to support controllers that have multiple transceivers */
117 struct list_head head;
118
119 /* initialize/shutdown the OTG controller */
120 int (*init)(struct usb_phy *x);
121 void (*shutdown)(struct usb_phy *x);
122
123 /* effective for B devices, ignored for A-peripheral */
124 int (*set_power)(struct usb_phy *x,
125 unsigned mA);
126
127 /* for non-OTG B devices: set transceiver into suspend mode */
128 int (*set_suspend)(struct usb_phy *x,
129 int suspend);
130
131 /* notify phy connect status change */
132 int (*notify_connect)(struct usb_phy *x, int port);
133 int (*notify_disconnect)(struct usb_phy *x, int port);
134};
135
136
137/* for board-specific init logic */
138extern int usb_add_phy(struct usb_phy *, enum usb_phy_type type);
139extern void usb_remove_phy(struct usb_phy *);
140
141#if defined(CONFIG_NOP_USB_XCEIV) || (defined(CONFIG_NOP_USB_XCEIV_MODULE) && defined(MODULE))
142/* sometimes transceivers are accessed only through e.g. ULPI */
143extern void usb_nop_xceiv_register(void);
144extern void usb_nop_xceiv_unregister(void);
145#else
146static inline void usb_nop_xceiv_register(void)
147{
148}
149
150static inline void usb_nop_xceiv_unregister(void)
151{
152}
153#endif
154
155/* helpers for direct access thru low-level io interface */
156static inline int usb_phy_io_read(struct usb_phy *x, u32 reg)
157{
158 if (x->io_ops && x->io_ops->read)
159 return x->io_ops->read(x, reg);
160
161 return -EINVAL;
162}
163
164static inline int usb_phy_io_write(struct usb_phy *x, u32 val, u32 reg)
165{
166 if (x->io_ops && x->io_ops->write)
167 return x->io_ops->write(x, val, reg);
168
169 return -EINVAL;
170}
171
172static inline int
173usb_phy_init(struct usb_phy *x)
174{
175 if (x->init)
176 return x->init(x);
177
178 return 0;
179}
180
181static inline void
182usb_phy_shutdown(struct usb_phy *x)
183{
184 if (x->shutdown)
185 x->shutdown(x);
186}
187
188/* for usb host and peripheral controller drivers */
189#ifdef CONFIG_USB_OTG_UTILS 39#ifdef CONFIG_USB_OTG_UTILS
190extern struct usb_phy *usb_get_phy(enum usb_phy_type type);
191extern struct usb_phy *devm_usb_get_phy(struct device *dev,
192 enum usb_phy_type type);
193extern void usb_put_phy(struct usb_phy *);
194extern void devm_usb_put_phy(struct device *dev, struct usb_phy *x);
195extern const char *otg_state_string(enum usb_otg_state state); 40extern const char *otg_state_string(enum usb_otg_state state);
196#else 41#else
197static inline struct usb_phy *usb_get_phy(enum usb_phy_type type)
198{
199 return NULL;
200}
201
202static inline struct usb_phy *devm_usb_get_phy(struct device *dev,
203 enum usb_phy_type type)
204{
205 return NULL;
206}
207
208static inline void usb_put_phy(struct usb_phy *x)
209{
210}
211
212static inline void devm_usb_put_phy(struct device *dev, struct usb_phy *x)
213{
214}
215
216static inline const char *otg_state_string(enum usb_otg_state state) 42static inline const char *otg_state_string(enum usb_otg_state state)
217{ 43{
218 return NULL; 44 return NULL;
@@ -262,42 +88,6 @@ otg_set_peripheral(struct usb_otg *otg, struct usb_gadget *periph)
262} 88}
263 89
264static inline int 90static inline int
265usb_phy_set_power(struct usb_phy *x, unsigned mA)
266{
267 if (x && x->set_power)
268 return x->set_power(x, mA);
269 return 0;
270}
271
272/* Context: can sleep */
273static inline int
274usb_phy_set_suspend(struct usb_phy *x, int suspend)
275{
276 if (x->set_suspend != NULL)
277 return x->set_suspend(x, suspend);
278 else
279 return 0;
280}
281
282static inline int
283usb_phy_notify_connect(struct usb_phy *x, int port)
284{
285 if (x->notify_connect)
286 return x->notify_connect(x, port);
287 else
288 return 0;
289}
290
291static inline int
292usb_phy_notify_disconnect(struct usb_phy *x, int port)
293{
294 if (x->notify_disconnect)
295 return x->notify_disconnect(x, port);
296 else
297 return 0;
298}
299
300static inline int
301otg_start_srp(struct usb_otg *otg) 91otg_start_srp(struct usb_otg *otg)
302{ 92{
303 if (otg && otg->start_srp) 93 if (otg && otg->start_srp)
@@ -306,31 +96,7 @@ otg_start_srp(struct usb_otg *otg)
306 return -ENOTSUPP; 96 return -ENOTSUPP;
307} 97}
308 98
309/* notifiers */
310static inline int
311usb_register_notifier(struct usb_phy *x, struct notifier_block *nb)
312{
313 return atomic_notifier_chain_register(&x->notifier, nb);
314}
315
316static inline void
317usb_unregister_notifier(struct usb_phy *x, struct notifier_block *nb)
318{
319 atomic_notifier_chain_unregister(&x->notifier, nb);
320}
321
322/* for OTG controller drivers (and maybe other stuff) */ 99/* for OTG controller drivers (and maybe other stuff) */
323extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num); 100extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num);
324 101
325static inline const char *usb_phy_type_string(enum usb_phy_type type)
326{
327 switch (type) {
328 case USB_PHY_TYPE_USB2:
329 return "USB2 PHY";
330 case USB_PHY_TYPE_USB3:
331 return "USB3 PHY";
332 default:
333 return "UNKNOWN PHY TYPE";
334 }
335}
336#endif /* __LINUX_USB_OTG_H */ 102#endif /* __LINUX_USB_OTG_H */
diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h
new file mode 100644
index 000000000000..06b5bae35b29
--- /dev/null
+++ b/include/linux/usb/phy.h
@@ -0,0 +1,233 @@
1/* USB OTG (On The Go) defines */
2/*
3 *
4 * These APIs may be used between USB controllers. USB device drivers
5 * (for either host or peripheral roles) don't use these calls; they
6 * continue to use just usb_device and usb_gadget.
7 */
8
9#ifndef __LINUX_USB_PHY_H
10#define __LINUX_USB_PHY_H
11
12#include <linux/notifier.h>
13
14enum usb_phy_events {
15 USB_EVENT_NONE, /* no events or cable disconnected */
16 USB_EVENT_VBUS, /* vbus valid event */
17 USB_EVENT_ID, /* id was grounded */
18 USB_EVENT_CHARGER, /* usb dedicated charger */
19 USB_EVENT_ENUMERATED, /* gadget driver enumerated */
20};
21
22/* associate a type with PHY */
23enum usb_phy_type {
24 USB_PHY_TYPE_UNDEFINED,
25 USB_PHY_TYPE_USB2,
26 USB_PHY_TYPE_USB3,
27};
28
29/* OTG defines lots of enumeration states before device reset */
30enum usb_otg_state {
31 OTG_STATE_UNDEFINED = 0,
32
33 /* single-role peripheral, and dual-role default-b */
34 OTG_STATE_B_IDLE,
35 OTG_STATE_B_SRP_INIT,
36 OTG_STATE_B_PERIPHERAL,
37
38 /* extra dual-role default-b states */
39 OTG_STATE_B_WAIT_ACON,
40 OTG_STATE_B_HOST,
41
42 /* dual-role default-a */
43 OTG_STATE_A_IDLE,
44 OTG_STATE_A_WAIT_VRISE,
45 OTG_STATE_A_WAIT_BCON,
46 OTG_STATE_A_HOST,
47 OTG_STATE_A_SUSPEND,
48 OTG_STATE_A_PERIPHERAL,
49 OTG_STATE_A_WAIT_VFALL,
50 OTG_STATE_A_VBUS_ERR,
51};
52
53struct usb_phy;
54struct usb_otg;
55
56/* for transceivers connected thru an ULPI interface, the user must
57 * provide access ops
58 */
59struct usb_phy_io_ops {
60 int (*read)(struct usb_phy *x, u32 reg);
61 int (*write)(struct usb_phy *x, u32 val, u32 reg);
62};
63
64struct usb_phy {
65 struct device *dev;
66 const char *label;
67 unsigned int flags;
68
69 enum usb_phy_type type;
70 enum usb_otg_state state;
71 enum usb_phy_events last_event;
72
73 struct usb_otg *otg;
74
75 struct device *io_dev;
76 struct usb_phy_io_ops *io_ops;
77 void __iomem *io_priv;
78
79 /* for notification of usb_phy_events */
80 struct atomic_notifier_head notifier;
81
82 /* to pass extra port status to the root hub */
83 u16 port_status;
84 u16 port_change;
85
86 /* to support controllers that have multiple transceivers */
87 struct list_head head;
88
89 /* initialize/shutdown the OTG controller */
90 int (*init)(struct usb_phy *x);
91 void (*shutdown)(struct usb_phy *x);
92
93 /* effective for B devices, ignored for A-peripheral */
94 int (*set_power)(struct usb_phy *x,
95 unsigned mA);
96
97 /* for non-OTG B devices: set transceiver into suspend mode */
98 int (*set_suspend)(struct usb_phy *x,
99 int suspend);
100
101 /* notify phy connect status change */
102 int (*notify_connect)(struct usb_phy *x, int port);
103 int (*notify_disconnect)(struct usb_phy *x, int port);
104};
105
106
107/* for board-specific init logic */
108extern int usb_add_phy(struct usb_phy *, enum usb_phy_type type);
109extern void usb_remove_phy(struct usb_phy *);
110
111/* helpers for direct access thru low-level io interface */
112static inline int usb_phy_io_read(struct usb_phy *x, u32 reg)
113{
114 if (x->io_ops && x->io_ops->read)
115 return x->io_ops->read(x, reg);
116
117 return -EINVAL;
118}
119
120static inline int usb_phy_io_write(struct usb_phy *x, u32 val, u32 reg)
121{
122 if (x->io_ops && x->io_ops->write)
123 return x->io_ops->write(x, val, reg);
124
125 return -EINVAL;
126}
127
128static inline int
129usb_phy_init(struct usb_phy *x)
130{
131 if (x->init)
132 return x->init(x);
133
134 return 0;
135}
136
137static inline void
138usb_phy_shutdown(struct usb_phy *x)
139{
140 if (x->shutdown)
141 x->shutdown(x);
142}
143
144/* for usb host and peripheral controller drivers */
145#ifdef CONFIG_USB_OTG_UTILS
146extern struct usb_phy *usb_get_phy(enum usb_phy_type type);
147extern struct usb_phy *devm_usb_get_phy(struct device *dev,
148 enum usb_phy_type type);
149extern void usb_put_phy(struct usb_phy *);
150extern void devm_usb_put_phy(struct device *dev, struct usb_phy *x);
151#else
152static inline struct usb_phy *usb_get_phy(enum usb_phy_type type)
153{
154 return NULL;
155}
156
157static inline struct usb_phy *devm_usb_get_phy(struct device *dev,
158 enum usb_phy_type type)
159{
160 return NULL;
161}
162
163static inline void usb_put_phy(struct usb_phy *x)
164{
165}
166
167static inline void devm_usb_put_phy(struct device *dev, struct usb_phy *x)
168{
169}
170
171#endif
172
173static inline int
174usb_phy_set_power(struct usb_phy *x, unsigned mA)
175{
176 if (x && x->set_power)
177 return x->set_power(x, mA);
178 return 0;
179}
180
181/* Context: can sleep */
182static inline int
183usb_phy_set_suspend(struct usb_phy *x, int suspend)
184{
185 if (x->set_suspend != NULL)
186 return x->set_suspend(x, suspend);
187 else
188 return 0;
189}
190
191static inline int
192usb_phy_notify_connect(struct usb_phy *x, int port)
193{
194 if (x->notify_connect)
195 return x->notify_connect(x, port);
196 else
197 return 0;
198}
199
200static inline int
201usb_phy_notify_disconnect(struct usb_phy *x, int port)
202{
203 if (x->notify_disconnect)
204 return x->notify_disconnect(x, port);
205 else
206 return 0;
207}
208
209/* notifiers */
210static inline int
211usb_register_notifier(struct usb_phy *x, struct notifier_block *nb)
212{
213 return atomic_notifier_chain_register(&x->notifier, nb);
214}
215
216static inline void
217usb_unregister_notifier(struct usb_phy *x, struct notifier_block *nb)
218{
219 atomic_notifier_chain_unregister(&x->notifier, nb);
220}
221
222static inline const char *usb_phy_type_string(enum usb_phy_type type)
223{
224 switch (type) {
225 case USB_PHY_TYPE_USB2:
226 return "USB2 PHY";
227 case USB_PHY_TYPE_USB3:
228 return "USB3 PHY";
229 default:
230 return "UNKNOWN PHY TYPE";
231 }
232}
233#endif /* __LINUX_USB_PHY_H */
diff --git a/include/linux/usb/phy_companion.h b/include/linux/usb/phy_companion.h
new file mode 100644
index 000000000000..edd2ec23d282
--- /dev/null
+++ b/include/linux/usb/phy_companion.h
@@ -0,0 +1,34 @@
1/*
2 * phy-companion.h -- phy companion to indicate the comparator part of PHY
3 *
4 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * Author: Kishon Vijay Abraham I <kishon@ti.com>
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#ifndef __DRIVERS_PHY_COMPANION_H
20#define __DRIVERS_PHY_COMPANION_H
21
22#include <linux/usb/otg.h>
23
24/* phy_companion to take care of VBUS, ID and srp capabilities */
25struct phy_companion {
26
27 /* effective for A-peripheral, ignored for B devices */
28 int (*set_vbus)(struct phy_companion *x, bool enabled);
29
30 /* for B devices only: start session with A-Host */
31 int (*start_srp)(struct phy_companion *x);
32};
33
34#endif /* __DRIVERS_PHY_COMPANION_H */
diff --git a/arch/arm/mach-tegra/include/mach/usb_phy.h b/include/linux/usb/tegra_usb_phy.h
index 935ce9f65590..176b1ca06ae4 100644
--- a/arch/arm/mach-tegra/include/mach/usb_phy.h
+++ b/include/linux/usb/tegra_usb_phy.h
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/arm/mach-tegra/include/mach/usb_phy.h
3 *
4 * Copyright (C) 2010 Google, Inc. 2 * Copyright (C) 2010 Google, Inc.
5 * 3 *
6 * This software is licensed under the terms of the GNU General Public 4 * This software is licensed under the terms of the GNU General Public
@@ -14,8 +12,8 @@
14 * 12 *
15 */ 13 */
16 14
17#ifndef __MACH_USB_PHY_H 15#ifndef __TEGRA_USB_PHY_H
18#define __MACH_USB_PHY_H 16#define __TEGRA_USB_PHY_H
19 17
20#include <linux/clk.h> 18#include <linux/clk.h>
21#include <linux/usb/otg.h> 19#include <linux/usb/otg.h>
@@ -59,19 +57,17 @@ struct tegra_usb_phy {
59 enum tegra_usb_phy_mode mode; 57 enum tegra_usb_phy_mode mode;
60 void *config; 58 void *config;
61 struct usb_phy *ulpi; 59 struct usb_phy *ulpi;
60 struct usb_phy u_phy;
61 struct device *dev;
62}; 62};
63 63
64struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, 64struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
65 void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode); 65 void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode);
66 66
67int tegra_usb_phy_power_on(struct tegra_usb_phy *phy);
68
69void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy); 67void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy);
70 68
71void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy); 69void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy);
72 70
73void tegra_usb_phy_power_off(struct tegra_usb_phy *phy);
74
75void tegra_usb_phy_preresume(struct tegra_usb_phy *phy); 71void tegra_usb_phy_preresume(struct tegra_usb_phy *phy);
76 72
77void tegra_usb_phy_postresume(struct tegra_usb_phy *phy); 73void tegra_usb_phy_postresume(struct tegra_usb_phy *phy);
@@ -81,6 +77,4 @@ void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy,
81 77
82void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy); 78void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy);
83 79
84void tegra_usb_phy_close(struct tegra_usb_phy *phy); 80#endif /* __TEGRA_USB_PHY_H */
85
86#endif /* __MACH_USB_PHY_H */