aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/phy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/phy')
-rw-r--r--drivers/usb/phy/Kconfig12
-rw-r--r--drivers/usb/phy/Makefile1
-rw-r--r--drivers/usb/phy/mv_u3d_phy.c4
-rw-r--r--drivers/usb/phy/omap-usb2.c6
-rw-r--r--drivers/usb/phy/rcar-phy.c220
-rw-r--r--drivers/usb/phy/tegra_usb_phy.c4
6 files changed, 241 insertions, 6 deletions
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 63c339b3e676..7eb73c561bd2 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -32,3 +32,15 @@ config MV_U3D_PHY
32 help 32 help
33 Enable this to support Marvell USB 3.0 phy controller for Marvell 33 Enable this to support Marvell USB 3.0 phy controller for Marvell
34 SoC. 34 SoC.
35
36config USB_RCAR_PHY
37 tristate "Renesas R-Car USB phy support"
38 depends on USB || USB_GADGET
39 select USB_OTG_UTILS
40 help
41 Say Y here to add support for the Renesas R-Car USB phy driver.
42 This chip is typically used as USB phy for USB host, gadget.
43 This driver supports: R8A7779
44
45 To compile this driver as a module, choose M here: the
46 module will be called rcar-phy.
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index b069f29f1225..1a579a860a03 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_OMAP_USB2) += omap-usb2.o
8obj-$(CONFIG_USB_ISP1301) += isp1301.o 8obj-$(CONFIG_USB_ISP1301) += isp1301.o
9obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o 9obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o
10obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o 10obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o
11obj-$(CONFIG_USB_RCAR_PHY) += rcar-phy.o
diff --git a/drivers/usb/phy/mv_u3d_phy.c b/drivers/usb/phy/mv_u3d_phy.c
index 9f1c5d3c60ec..eaddbe3d4304 100644
--- a/drivers/usb/phy/mv_u3d_phy.c
+++ b/drivers/usb/phy/mv_u3d_phy.c
@@ -262,7 +262,7 @@ calstart:
262 return 0; 262 return 0;
263} 263}
264 264
265static int __devinit mv_u3d_phy_probe(struct platform_device *pdev) 265static int mv_u3d_phy_probe(struct platform_device *pdev)
266{ 266{
267 struct mv_u3d_phy *mv_u3d_phy; 267 struct mv_u3d_phy *mv_u3d_phy;
268 struct mv_usb_platform_data *pdata; 268 struct mv_usb_platform_data *pdata;
@@ -331,7 +331,7 @@ static int __exit mv_u3d_phy_remove(struct platform_device *pdev)
331 331
332static struct platform_driver mv_u3d_phy_driver = { 332static struct platform_driver mv_u3d_phy_driver = {
333 .probe = mv_u3d_phy_probe, 333 .probe = mv_u3d_phy_probe,
334 .remove = __devexit_p(mv_u3d_phy_remove), 334 .remove = mv_u3d_phy_remove,
335 .driver = { 335 .driver = {
336 .name = "mv-u3d-phy", 336 .name = "mv-u3d-phy",
337 .owner = THIS_MODULE, 337 .owner = THIS_MODULE,
diff --git a/drivers/usb/phy/omap-usb2.c b/drivers/usb/phy/omap-usb2.c
index 15ab3d6f2e8c..26ae8f49225c 100644
--- a/drivers/usb/phy/omap-usb2.c
+++ b/drivers/usb/phy/omap-usb2.c
@@ -141,7 +141,7 @@ static int omap_usb2_suspend(struct usb_phy *x, int suspend)
141 return 0; 141 return 0;
142} 142}
143 143
144static int __devinit omap_usb2_probe(struct platform_device *pdev) 144static int omap_usb2_probe(struct platform_device *pdev)
145{ 145{
146 struct omap_usb *phy; 146 struct omap_usb *phy;
147 struct usb_otg *otg; 147 struct usb_otg *otg;
@@ -199,7 +199,7 @@ static int __devinit omap_usb2_probe(struct platform_device *pdev)
199 return 0; 199 return 0;
200} 200}
201 201
202static int __devexit omap_usb2_remove(struct platform_device *pdev) 202static int omap_usb2_remove(struct platform_device *pdev)
203{ 203{
204 struct omap_usb *phy = platform_get_drvdata(pdev); 204 struct omap_usb *phy = platform_get_drvdata(pdev);
205 205
@@ -254,7 +254,7 @@ MODULE_DEVICE_TABLE(of, omap_usb2_id_table);
254 254
255static struct platform_driver omap_usb2_driver = { 255static struct platform_driver omap_usb2_driver = {
256 .probe = omap_usb2_probe, 256 .probe = omap_usb2_probe,
257 .remove = __devexit_p(omap_usb2_remove), 257 .remove = omap_usb2_remove,
258 .driver = { 258 .driver = {
259 .name = "omap-usb2", 259 .name = "omap-usb2",
260 .owner = THIS_MODULE, 260 .owner = THIS_MODULE,
diff --git a/drivers/usb/phy/rcar-phy.c b/drivers/usb/phy/rcar-phy.c
new file mode 100644
index 000000000000..a35681b0c501
--- /dev/null
+++ b/drivers/usb/phy/rcar-phy.c
@@ -0,0 +1,220 @@
1/*
2 * Renesas R-Car USB phy driver
3 *
4 * Copyright (C) 2012 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/delay.h>
13#include <linux/io.h>
14#include <linux/usb/otg.h>
15#include <linux/platform_device.h>
16#include <linux/spinlock.h>
17#include <linux/module.h>
18
19/* USBH common register */
20#define USBPCTRL0 0x0800
21#define USBPCTRL1 0x0804
22#define USBST 0x0808
23#define USBEH0 0x080C
24#define USBOH0 0x081C
25#define USBCTL0 0x0858
26#define EIIBC1 0x0094
27#define EIIBC2 0x009C
28
29/* USBPCTRL1 */
30#define PHY_RST (1 << 2)
31#define PLL_ENB (1 << 1)
32#define PHY_ENB (1 << 0)
33
34/* USBST */
35#define ST_ACT (1 << 31)
36#define ST_PLL (1 << 30)
37
38struct rcar_usb_phy_priv {
39 struct usb_phy phy;
40 spinlock_t lock;
41
42 void __iomem *reg0;
43 void __iomem *reg1;
44 int counter;
45};
46
47#define usb_phy_to_priv(p) container_of(p, struct rcar_usb_phy_priv, phy)
48
49
50/*
51 * USB initial/install operation.
52 *
53 * This function setup USB phy.
54 * The used value and setting order came from
55 * [USB :: Initial setting] on datasheet.
56 */
57static int rcar_usb_phy_init(struct usb_phy *phy)
58{
59 struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy);
60 struct device *dev = phy->dev;
61 void __iomem *reg0 = priv->reg0;
62 void __iomem *reg1 = priv->reg1;
63 int i;
64 u32 val;
65 unsigned long flags;
66
67 spin_lock_irqsave(&priv->lock, flags);
68 if (priv->counter++ == 0) {
69
70 /*
71 * USB phy start-up
72 */
73
74 /* (1) USB-PHY standby release */
75 iowrite32(PHY_ENB, (reg0 + USBPCTRL1));
76
77 /* (2) start USB-PHY internal PLL */
78 iowrite32(PHY_ENB | PLL_ENB, (reg0 + USBPCTRL1));
79
80 /* (3) USB module status check */
81 for (i = 0; i < 1024; i++) {
82 udelay(10);
83 val = ioread32(reg0 + USBST);
84 if (val == (ST_ACT | ST_PLL))
85 break;
86 }
87
88 if (val != (ST_ACT | ST_PLL)) {
89 dev_err(dev, "USB phy not ready\n");
90 goto phy_init_end;
91 }
92
93 /* (4) USB-PHY reset clear */
94 iowrite32(PHY_ENB | PLL_ENB | PHY_RST, (reg0 + USBPCTRL1));
95
96 /* set platform specific port settings */
97 iowrite32(0x00000000, (reg0 + USBPCTRL0));
98
99 /*
100 * EHCI IP internal buffer setting
101 * EHCI IP internal buffer enable
102 *
103 * These are recommended value of a datasheet
104 * see [USB :: EHCI internal buffer setting]
105 */
106 iowrite32(0x00ff0040, (reg0 + EIIBC1));
107 iowrite32(0x00ff0040, (reg1 + EIIBC1));
108
109 iowrite32(0x00000001, (reg0 + EIIBC2));
110 iowrite32(0x00000001, (reg1 + EIIBC2));
111
112 /*
113 * Bus alignment settings
114 */
115
116 /* (1) EHCI bus alignment (little endian) */
117 iowrite32(0x00000000, (reg0 + USBEH0));
118
119 /* (1) OHCI bus alignment (little endian) */
120 iowrite32(0x00000000, (reg0 + USBOH0));
121 }
122
123phy_init_end:
124 spin_unlock_irqrestore(&priv->lock, flags);
125
126 return 0;
127}
128
129static void rcar_usb_phy_shutdown(struct usb_phy *phy)
130{
131 struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy);
132 void __iomem *reg0 = priv->reg0;
133 unsigned long flags;
134
135 spin_lock_irqsave(&priv->lock, flags);
136
137 if (priv->counter-- == 1) { /* last user */
138 iowrite32(0x00000000, (reg0 + USBPCTRL0));
139 iowrite32(0x00000000, (reg0 + USBPCTRL1));
140 }
141
142 spin_unlock_irqrestore(&priv->lock, flags);
143}
144
145static int rcar_usb_phy_probe(struct platform_device *pdev)
146{
147 struct rcar_usb_phy_priv *priv;
148 struct resource *res0, *res1;
149 struct device *dev = &pdev->dev;
150 void __iomem *reg0, *reg1;
151 int ret;
152
153 res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
154 res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
155 if (!res0 || !res1) {
156 dev_err(dev, "Not enough platform resources\n");
157 return -EINVAL;
158 }
159
160 /*
161 * CAUTION
162 *
163 * Because this phy address is also mapped under OHCI/EHCI address area,
164 * this driver can't use devm_request_and_ioremap(dev, res) here
165 */
166 reg0 = devm_ioremap_nocache(dev, res0->start, resource_size(res0));
167 reg1 = devm_ioremap_nocache(dev, res1->start, resource_size(res1));
168 if (!reg0 || !reg1) {
169 dev_err(dev, "ioremap error\n");
170 return -ENOMEM;
171 }
172
173 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
174 if (!priv) {
175 dev_err(dev, "priv data allocation error\n");
176 return -ENOMEM;
177 }
178
179 priv->reg0 = reg0;
180 priv->reg1 = reg1;
181 priv->counter = 0;
182 priv->phy.dev = dev;
183 priv->phy.label = dev_name(dev);
184 priv->phy.init = rcar_usb_phy_init;
185 priv->phy.shutdown = rcar_usb_phy_shutdown;
186 spin_lock_init(&priv->lock);
187
188 ret = usb_add_phy(&priv->phy, USB_PHY_TYPE_USB2);
189 if (ret < 0) {
190 dev_err(dev, "usb phy addition error\n");
191 return ret;
192 }
193
194 platform_set_drvdata(pdev, priv);
195
196 return ret;
197}
198
199static int rcar_usb_phy_remove(struct platform_device *pdev)
200{
201 struct rcar_usb_phy_priv *priv = platform_get_drvdata(pdev);
202
203 usb_remove_phy(&priv->phy);
204
205 return 0;
206}
207
208static struct platform_driver rcar_usb_phy_driver = {
209 .driver = {
210 .name = "rcar_usb_phy",
211 },
212 .probe = rcar_usb_phy_probe,
213 .remove = rcar_usb_phy_remove,
214};
215
216module_platform_driver(rcar_usb_phy_driver);
217
218MODULE_LICENSE("GPL v2");
219MODULE_DESCRIPTION("Renesas R-Car USB phy");
220MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/drivers/usb/phy/tegra_usb_phy.c b/drivers/usb/phy/tegra_usb_phy.c
index 987116f9efcd..9d13c81754e0 100644
--- a/drivers/usb/phy/tegra_usb_phy.c
+++ b/drivers/usb/phy/tegra_usb_phy.c
@@ -29,7 +29,9 @@
29#include <linux/usb/ulpi.h> 29#include <linux/usb/ulpi.h>
30#include <asm/mach-types.h> 30#include <asm/mach-types.h>
31#include <linux/usb/tegra_usb_phy.h> 31#include <linux/usb/tegra_usb_phy.h>
32#include <mach/iomap.h> 32
33#define TEGRA_USB_BASE 0xC5000000
34#define TEGRA_USB_SIZE SZ_16K
33 35
34#define ULPI_VIEWPORT 0x170 36#define ULPI_VIEWPORT 0x170
35 37