aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/phy
diff options
context:
space:
mode:
authorKishon Vijay Abraham I <kishon@ti.com>2013-09-27 02:23:26 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-09-27 20:36:21 -0400
commit5d93d1e76afbe629caf5d995fd7f8ddd6e3d4d01 (patch)
tree2c41ecee25b1583f388054961e568615eb05d9ee /drivers/usb/phy
parentff764963479a1b18721ab96e531404c50fefe8b1 (diff)
usb: phy: omap-usb2: use the new generic PHY framework
Used the generic PHY framework API to create the PHY. Now the power off and power on are done in omap_usb_power_off and omap_usb_power_on respectively. The omap-usb2 driver is also moved to driver/phy. However using the old USB PHY library cannot be completely removed because OTG is intertwined with PHY and moving to the new framework will break OTG. Once we have a separate OTG state machine, we can get rid of the USB PHY library. Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Acked-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/phy')
-rw-r--r--drivers/usb/phy/Kconfig11
-rw-r--r--drivers/usb/phy/Makefile1
-rw-r--r--drivers/usb/phy/phy-omap-usb2.c272
3 files changed, 0 insertions, 284 deletions
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 51ffe11cf38a..2ce041109993 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -66,17 +66,6 @@ config OMAP_CONTROL_USB
66 power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an 66 power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an
67 additional register to power on USB3 PHY. 67 additional register to power on USB3 PHY.
68 68
69config OMAP_USB2
70 tristate "OMAP USB2 PHY Driver"
71 depends on ARCH_OMAP2PLUS
72 select OMAP_CONTROL_USB
73 select USB_PHY
74 help
75 Enable this to support the transceiver that is part of SOC. This
76 driver takes care of all the PHY functionality apart from comparator.
77 The USB OTG controller communicates with the comparator using this
78 driver.
79
80config OMAP_USB3 69config OMAP_USB3
81 tristate "OMAP USB3 PHY Driver" 70 tristate "OMAP USB3 PHY Driver"
82 depends on ARCH_OMAP2PLUS || COMPILE_TEST 71 depends on ARCH_OMAP2PLUS || COMPILE_TEST
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index 2135e85f46ed..fa4db0e4bdb9 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -15,7 +15,6 @@ obj-$(CONFIG_NOP_USB_XCEIV) += phy-generic.o
15obj-$(CONFIG_OMAP_CONTROL_USB) += phy-omap-control.o 15obj-$(CONFIG_OMAP_CONTROL_USB) += phy-omap-control.o
16obj-$(CONFIG_AM335X_CONTROL_USB) += phy-am335x-control.o 16obj-$(CONFIG_AM335X_CONTROL_USB) += phy-am335x-control.o
17obj-$(CONFIG_AM335X_PHY_USB) += phy-am335x.o 17obj-$(CONFIG_AM335X_PHY_USB) += phy-am335x.o
18obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o
19obj-$(CONFIG_OMAP_USB3) += phy-omap-usb3.o 18obj-$(CONFIG_OMAP_USB3) += phy-omap-usb3.o
20obj-$(CONFIG_SAMSUNG_USBPHY) += phy-samsung-usb.o 19obj-$(CONFIG_SAMSUNG_USBPHY) += phy-samsung-usb.o
21obj-$(CONFIG_SAMSUNG_USB2PHY) += phy-samsung-usb2.o 20obj-$(CONFIG_SAMSUNG_USB2PHY) += phy-samsung-usb2.o
diff --git a/drivers/usb/phy/phy-omap-usb2.c b/drivers/usb/phy/phy-omap-usb2.c
deleted file mode 100644
index d266861d24f7..000000000000
--- a/drivers/usb/phy/phy-omap-usb2.c
+++ /dev/null
@@ -1,272 +0,0 @@
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#include <linux/usb/omap_control_usb.h>
31
32/**
33 * omap_usb2_set_comparator - links the comparator present in the sytem with
34 * this phy
35 * @comparator - the companion phy(comparator) for this phy
36 *
37 * The phy companion driver should call this API passing the phy_companion
38 * filled with set_vbus and start_srp to be used by usb phy.
39 *
40 * For use by phy companion driver
41 */
42int omap_usb2_set_comparator(struct phy_companion *comparator)
43{
44 struct omap_usb *phy;
45 struct usb_phy *x = usb_get_phy(USB_PHY_TYPE_USB2);
46
47 if (IS_ERR(x))
48 return -ENODEV;
49
50 phy = phy_to_omapusb(x);
51 phy->comparator = comparator;
52 return 0;
53}
54EXPORT_SYMBOL_GPL(omap_usb2_set_comparator);
55
56static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled)
57{
58 struct omap_usb *phy = phy_to_omapusb(otg->phy);
59
60 if (!phy->comparator)
61 return -ENODEV;
62
63 return phy->comparator->set_vbus(phy->comparator, enabled);
64}
65
66static int omap_usb_start_srp(struct usb_otg *otg)
67{
68 struct omap_usb *phy = phy_to_omapusb(otg->phy);
69
70 if (!phy->comparator)
71 return -ENODEV;
72
73 return phy->comparator->start_srp(phy->comparator);
74}
75
76static int omap_usb_set_host(struct usb_otg *otg, struct usb_bus *host)
77{
78 struct usb_phy *phy = otg->phy;
79
80 otg->host = host;
81 if (!host)
82 phy->state = OTG_STATE_UNDEFINED;
83
84 return 0;
85}
86
87static int omap_usb_set_peripheral(struct usb_otg *otg,
88 struct usb_gadget *gadget)
89{
90 struct usb_phy *phy = otg->phy;
91
92 otg->gadget = gadget;
93 if (!gadget)
94 phy->state = OTG_STATE_UNDEFINED;
95
96 return 0;
97}
98
99static int omap_usb2_suspend(struct usb_phy *x, int suspend)
100{
101 struct omap_usb *phy = phy_to_omapusb(x);
102 int ret;
103
104 if (suspend && !phy->is_suspended) {
105 omap_control_usb_phy_power(phy->control_dev, 0);
106 pm_runtime_put_sync(phy->dev);
107 phy->is_suspended = 1;
108 } else if (!suspend && phy->is_suspended) {
109 ret = pm_runtime_get_sync(phy->dev);
110 if (ret < 0) {
111 dev_err(phy->dev, "get_sync failed with err %d\n", ret);
112 return ret;
113 }
114 omap_control_usb_phy_power(phy->control_dev, 1);
115 phy->is_suspended = 0;
116 }
117
118 return 0;
119}
120
121static int omap_usb2_probe(struct platform_device *pdev)
122{
123 struct omap_usb *phy;
124 struct usb_otg *otg;
125
126 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
127 if (!phy) {
128 dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n");
129 return -ENOMEM;
130 }
131
132 otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
133 if (!otg) {
134 dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n");
135 return -ENOMEM;
136 }
137
138 phy->dev = &pdev->dev;
139
140 phy->phy.dev = phy->dev;
141 phy->phy.label = "omap-usb2";
142 phy->phy.set_suspend = omap_usb2_suspend;
143 phy->phy.otg = otg;
144 phy->phy.type = USB_PHY_TYPE_USB2;
145
146 phy->control_dev = omap_get_control_dev();
147 if (IS_ERR(phy->control_dev)) {
148 dev_dbg(&pdev->dev, "Failed to get control device\n");
149 return -ENODEV;
150 }
151
152 phy->is_suspended = 1;
153 omap_control_usb_phy_power(phy->control_dev, 0);
154
155 otg->set_host = omap_usb_set_host;
156 otg->set_peripheral = omap_usb_set_peripheral;
157 otg->set_vbus = omap_usb_set_vbus;
158 otg->start_srp = omap_usb_start_srp;
159 otg->phy = &phy->phy;
160
161 phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k");
162 if (IS_ERR(phy->wkupclk)) {
163 dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n");
164 return PTR_ERR(phy->wkupclk);
165 }
166 clk_prepare(phy->wkupclk);
167
168 phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m");
169 if (IS_ERR(phy->optclk))
170 dev_vdbg(&pdev->dev, "unable to get refclk960m\n");
171 else
172 clk_prepare(phy->optclk);
173
174 usb_add_phy_dev(&phy->phy);
175
176 platform_set_drvdata(pdev, phy);
177
178 pm_runtime_enable(phy->dev);
179
180 return 0;
181}
182
183static int omap_usb2_remove(struct platform_device *pdev)
184{
185 struct omap_usb *phy = platform_get_drvdata(pdev);
186
187 clk_unprepare(phy->wkupclk);
188 if (!IS_ERR(phy->optclk))
189 clk_unprepare(phy->optclk);
190 usb_remove_phy(&phy->phy);
191
192 return 0;
193}
194
195#ifdef CONFIG_PM_RUNTIME
196
197static int omap_usb2_runtime_suspend(struct device *dev)
198{
199 struct platform_device *pdev = to_platform_device(dev);
200 struct omap_usb *phy = platform_get_drvdata(pdev);
201
202 clk_disable(phy->wkupclk);
203 if (!IS_ERR(phy->optclk))
204 clk_disable(phy->optclk);
205
206 return 0;
207}
208
209static int omap_usb2_runtime_resume(struct device *dev)
210{
211 struct platform_device *pdev = to_platform_device(dev);
212 struct omap_usb *phy = platform_get_drvdata(pdev);
213 int ret;
214
215 ret = clk_enable(phy->wkupclk);
216 if (ret < 0) {
217 dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret);
218 goto err0;
219 }
220
221 if (!IS_ERR(phy->optclk)) {
222 ret = clk_enable(phy->optclk);
223 if (ret < 0) {
224 dev_err(phy->dev, "Failed to enable optclk %d\n", ret);
225 goto err1;
226 }
227 }
228
229 return 0;
230
231err1:
232 clk_disable(phy->wkupclk);
233
234err0:
235 return ret;
236}
237
238static const struct dev_pm_ops omap_usb2_pm_ops = {
239 SET_RUNTIME_PM_OPS(omap_usb2_runtime_suspend, omap_usb2_runtime_resume,
240 NULL)
241};
242
243#define DEV_PM_OPS (&omap_usb2_pm_ops)
244#else
245#define DEV_PM_OPS NULL
246#endif
247
248#ifdef CONFIG_OF
249static const struct of_device_id omap_usb2_id_table[] = {
250 { .compatible = "ti,omap-usb2" },
251 {}
252};
253MODULE_DEVICE_TABLE(of, omap_usb2_id_table);
254#endif
255
256static struct platform_driver omap_usb2_driver = {
257 .probe = omap_usb2_probe,
258 .remove = omap_usb2_remove,
259 .driver = {
260 .name = "omap-usb2",
261 .owner = THIS_MODULE,
262 .pm = DEV_PM_OPS,
263 .of_match_table = of_match_ptr(omap_usb2_id_table),
264 },
265};
266
267module_platform_driver(omap_usb2_driver);
268
269MODULE_ALIAS("platform: omap_usb2");
270MODULE_AUTHOR("Texas Instruments Inc.");
271MODULE_DESCRIPTION("OMAP USB2 phy driver");
272MODULE_LICENSE("GPL v2");