kernel: update 3.9 to 3.9.11
[openwrt/svn-archive/archive.git] / target / linux / ramips / patches-3.10 / 0018-USB-phy-add-ralink-SoC-driver.patch
1 From c5f51197b13fd312324ac0486a46e530e163eade Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Sun, 14 Jul 2013 23:31:19 +0200
4 Subject: [PATCH 18/33] USB: phy: add ralink SoC driver
5
6 Signed-off-by: John Crispin <blogic@openwrt.org>
7 ---
8 drivers/usb/phy/Kconfig | 8 ++
9 drivers/usb/phy/Makefile | 1 +
10 drivers/usb/phy/ralink-phy.c | 191 ++++++++++++++++++++++++++++++++++++++++++
11 3 files changed, 200 insertions(+)
12 create mode 100644 drivers/usb/phy/ralink-phy.c
13
14 diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
15 index 2311b1e..2944b8c 100644
16 --- a/drivers/usb/phy/Kconfig
17 +++ b/drivers/usb/phy/Kconfig
18 @@ -210,4 +210,12 @@ config USB_ULPI_VIEWPORT
19 Provides read/write operations to the ULPI phy register set for
20 controllers with a viewport register (e.g. Chipidea/ARC controllers).
21
22 +config RALINK_USBPHY
23 + bool "Ralink USB PHY controller Driver"
24 + depends on MIPS && RALINK
25 + select USB_OTG_UTILS
26 + help
27 + Enable this to support ralink USB phy controller for ralink
28 + SoCs.
29 +
30 endif # USB_PHY
31 diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
32 index a9169cb..f7da66b 100644
33 --- a/drivers/usb/phy/Makefile
34 +++ b/drivers/usb/phy/Makefile
35 @@ -31,3 +31,4 @@ obj-$(CONFIG_USB_MXS_PHY) += phy-mxs-usb.o
36 obj-$(CONFIG_USB_RCAR_PHY) += phy-rcar-usb.o
37 obj-$(CONFIG_USB_ULPI) += phy-ulpi.o
38 obj-$(CONFIG_USB_ULPI_VIEWPORT) += phy-ulpi-viewport.o
39 +obj-$(CONFIG_RALINK_USBPHY) += ralink-phy.o
40 diff --git a/drivers/usb/phy/ralink-phy.c b/drivers/usb/phy/ralink-phy.c
41 new file mode 100644
42 index 0000000..269cff4
43 --- /dev/null
44 +++ b/drivers/usb/phy/ralink-phy.c
45 @@ -0,0 +1,191 @@
46 +/*
47 + * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
48 + *
49 + * based on: Renesas R-Car USB phy driver
50 + *
51 + * This program is free software; you can redistribute it and/or modify
52 + * it under the terms of the GNU General Public License version 2 as
53 + * published by the Free Software Foundation.
54 + */
55 +
56 +#include <linux/delay.h>
57 +#include <linux/io.h>
58 +#include <linux/usb/otg.h>
59 +#include <linux/of_platform.h>
60 +#include <linux/platform_device.h>
61 +#include <linux/spinlock.h>
62 +#include <linux/module.h>
63 +#include <linux/reset.h>
64 +
65 +#include <asm/mach-ralink/ralink_regs.h>
66 +
67 +#define RT_SYSC_REG_SYSCFG1 0x014
68 +#define RT_SYSC_REG_CLKCFG1 0x030
69 +#define RT_SYSC_REG_USB_PHY_CFG 0x05c
70 +
71 +#define RT_RSTCTRL_UDEV BIT(25)
72 +#define RT_RSTCTRL_UHST BIT(22)
73 +#define RT_SYSCFG1_USB0_HOST_MODE BIT(10)
74 +
75 +#define MT7620_CLKCFG1_UPHY0_CLK_EN BIT(25)
76 +#define RT_CLKCFG1_UPHY1_CLK_EN BIT(20)
77 +#define RT_CLKCFG1_UPHY0_CLK_EN BIT(18)
78 +
79 +#define USB_PHY_UTMI_8B60M BIT(1)
80 +#define UDEV_WAKEUP BIT(0)
81 +
82 +static atomic_t usb_pwr_ref = ATOMIC_INIT(0);
83 +static struct reset_control *rstdev;
84 +static struct reset_control *rsthost;
85 +static u32 phy_clk;
86 +
87 +static void usb_phy_enable(int state)
88 +{
89 + if (state)
90 + rt_sysc_m32(0, phy_clk, RT_SYSC_REG_CLKCFG1);
91 + else
92 + rt_sysc_m32(phy_clk, 0, RT_SYSC_REG_CLKCFG1);
93 + mdelay(100);
94 +}
95 +
96 +static int usb_power_on(struct usb_phy *phy)
97 +{
98 + if (atomic_inc_return(&usb_pwr_ref) == 1) {
99 + u32 t;
100 +
101 + usb_phy_enable(1);
102 +
103 +// reset_control_assert(rstdev);
104 +// reset_control_assert(rsthost);
105 +
106 + if (OTG_STATE_B_HOST) {
107 + rt_sysc_m32(0, RT_SYSCFG1_USB0_HOST_MODE, RT_SYSC_REG_SYSCFG1);
108 + reset_control_deassert(rsthost);
109 + } else {
110 + rt_sysc_m32(RT_SYSCFG1_USB0_HOST_MODE, 0, RT_SYSC_REG_SYSCFG1);
111 + reset_control_deassert(rstdev);
112 + }
113 + mdelay(100);
114 +
115 + t = rt_sysc_r32(RT_SYSC_REG_USB_PHY_CFG);
116 + dev_info(phy->dev, "remote usb device wakeup %s\n",
117 + (t & UDEV_WAKEUP) ? ("enabbled") : ("disabled"));
118 + if (t & USB_PHY_UTMI_8B60M)
119 + dev_info(phy->dev, "UTMI 8bit 60MHz\n");
120 + else
121 + dev_info(phy->dev, "UTMI 16bit 30MHz\n");
122 + }
123 +
124 + return 0;
125 +}
126 +
127 +static void usb_power_off(struct usb_phy *phy)
128 +{
129 + if (atomic_dec_return(&usb_pwr_ref) == 0) {
130 + usb_phy_enable(0);
131 + reset_control_assert(rstdev);
132 + reset_control_assert(rsthost);
133 + }
134 +}
135 +
136 +static int usb_set_host(struct usb_otg *otg, struct usb_bus *host)
137 +{
138 + otg->gadget = NULL;
139 + otg->host = host;
140 +
141 + return 0;
142 +}
143 +
144 +static int usb_set_peripheral(struct usb_otg *otg,
145 + struct usb_gadget *gadget)
146 +{
147 + otg->host = NULL;
148 + otg->gadget = gadget;
149 +
150 + return 0;
151 +}
152 +
153 +static const struct of_device_id ralink_usbphy_dt_match[] = {
154 + { .compatible = "ralink,rt3xxx-usbphy", .data = (void *) (RT_CLKCFG1_UPHY1_CLK_EN | RT_CLKCFG1_UPHY0_CLK_EN) },
155 + { .compatible = "ralink,mt7620a-usbphy", .data = (void *) MT7620_CLKCFG1_UPHY0_CLK_EN },
156 + {},
157 +};
158 +MODULE_DEVICE_TABLE(of, ralink_usbphy_dt_match);
159 +
160 +static int usb_phy_probe(struct platform_device *pdev)
161 +{
162 + const struct of_device_id *match;
163 + struct device *dev = &pdev->dev;
164 + struct usb_otg *otg;
165 + struct usb_phy *phy;
166 + int ret;
167 +
168 + match = of_match_device(ralink_usbphy_dt_match, &pdev->dev);
169 + phy_clk = (int) match->data;
170 +
171 + rsthost = devm_reset_control_get(&pdev->dev, "host");
172 + if (IS_ERR(rsthost))
173 + return PTR_ERR(rsthost);
174 +
175 + rstdev = devm_reset_control_get(&pdev->dev, "device");
176 + if (IS_ERR(rstdev))
177 + return PTR_ERR(rstdev);
178 +
179 + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
180 + if (!phy) {
181 + dev_err(&pdev->dev, "unable to allocate memory for USB PHY\n");
182 + return -ENOMEM;
183 + }
184 +
185 + otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
186 + if (!otg) {
187 + dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n");
188 + return -ENOMEM;
189 + }
190 +
191 + phy->dev = dev;
192 + phy->label = dev_name(dev);
193 + phy->init = usb_power_on;
194 + phy->shutdown = usb_power_off;
195 + otg->set_host = usb_set_host;
196 + otg->set_peripheral = usb_set_peripheral;
197 + otg->phy = phy;
198 + phy->otg = otg;
199 + ret = usb_add_phy(phy, USB_PHY_TYPE_USB2);
200 +
201 + if (ret < 0) {
202 + dev_err(dev, "usb phy addition error\n");
203 + return ret;
204 + }
205 +
206 + platform_set_drvdata(pdev, phy);
207 +
208 + dev_info(&pdev->dev, "loaded\n");
209 +
210 + return ret;
211 +}
212 +
213 +static int usb_phy_remove(struct platform_device *pdev)
214 +{
215 + struct usb_phy *phy = platform_get_drvdata(pdev);
216 +
217 + usb_remove_phy(phy);
218 +
219 + return 0;
220 +}
221 +
222 +static struct platform_driver usb_phy_driver = {
223 + .driver = {
224 + .owner = THIS_MODULE,
225 + .name = "rt3xxx-usbphy",
226 + .of_match_table = of_match_ptr(ralink_usbphy_dt_match),
227 + },
228 + .probe = usb_phy_probe,
229 + .remove = usb_phy_remove,
230 +};
231 +
232 +module_platform_driver(usb_phy_driver);
233 +
234 +MODULE_LICENSE("GPL v2");
235 +MODULE_DESCRIPTION("Ralink USB phy");
236 +MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
237 --
238 1.7.10.4
239