diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-04-05 18:18:00 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-04-05 18:18:00 -0400 |
commit | 64dc9e2e7320f079b97c46b106133b58b8e18d40 (patch) | |
tree | ab010dc1337d44e29c2b32b7f11788620a91fe4f /drivers/usb/phy/phy-ab8500-usb.c | |
parent | 01a60e76b6392547ad3dca3ac05b9c886fa5da45 (diff) | |
parent | 9b192de60b5a584ee4ed967fb6758773c75e4643 (diff) |
Merge tag 'usb-for-v3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
Felipe writes:
usb: patches for v3.10 merge window
Here is the big Gadget & PHY pull request. Many of us have
been really busy lately getting multiple drivers to a better
position.
Since this pull request is so large, I will divide it in sections
so it's easier to grasp what's included.
- cleanups:
. UDC drivers no longer touch gadget->dev, that's now udc-core
responsibility
. Many more UDC drivers converted to usb_gadget_map/unmap_request()
. UDC drivers no longer initialize DMA-related fields from gadget's
device structure
. UDC drivers don't touch gadget.dev.driver directly
. UDC drivers don't assign gadget.dev.release directly
. Removal of some unused DMA_ADDR_INVALID
. Introduction of CONFIG_USB_PHY
. All phy drivers have been moved to drivers/usb/phy and renamed to
a common naming scheme
. Fix PHY layer so it never returns a NULL pointer, also fix all
callers to avoid using IS_ERR_OR_NULL()
. Sparse fixes all over the place
. drivers/usb/otg/ has been deleted
. Marvel drivers (mv_udc, ehci-mv, mv_otg and mv_u3d) improved clock
usage
- new features:
. UDC core now provides a generic way for tracking and reporting
UDC's state (not attached, resuming, suspended, addressed,
default, etc)
. twl4030-usb learned that it shouldn't be enabled during init
. Full DT support for DWC3 has been implemented
. ab8500-usb learned about pinctrl framework
. nop PHY learned about DeviceTree and regulators
. DWC3 learned about suspend/resume
. DWC3 can now be compiled in host-only and gadget-only (as well as
DRD) configurations
. UVC now enables streaming endpoint based on negotiated speed
. isp1301 now implements the PHY API properly
. configfs-based interface for gadget drivers which will lead to
the removal of all code which just combines functions together
to build functional gadget drivers.
. f_serial and f_obex were converted to new configfs interface while
maintaining old interface around.
- non-critical fixes:
. UVC gadget driver got fixes for Endpoint usage and stream calculation
. ab8500-usb fixed unbalanced clock and regulator API usage
. twl4030-usb got a fix for when OMAP3 is booted with cable connected
. fusb300_udc got a fix for DMA usage
. UVC got fixes for two assertions of the USB Video Class Compliance
specification revision 1.1
. build warning issues caused by recent addition of __must_check to
regulator API
These are all changes which deserve a mention, all other changes are related
to these one or minor spelling fixes and other similar tasks.
Signed-of-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/phy/phy-ab8500-usb.c')
-rw-r--r-- | drivers/usb/phy/phy-ab8500-usb.c | 924 |
1 files changed, 924 insertions, 0 deletions
diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c new file mode 100644 index 000000000000..4acef26a2ef5 --- /dev/null +++ b/drivers/usb/phy/phy-ab8500-usb.c | |||
@@ -0,0 +1,924 @@ | |||
1 | /* | ||
2 | * drivers/usb/otg/ab8500_usb.c | ||
3 | * | ||
4 | * USB transceiver driver for AB8500 chip | ||
5 | * | ||
6 | * Copyright (C) 2010 ST-Ericsson AB | ||
7 | * Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <linux/module.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/usb/otg.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/notifier.h> | ||
30 | #include <linux/interrupt.h> | ||
31 | #include <linux/delay.h> | ||
32 | #include <linux/mfd/abx500.h> | ||
33 | #include <linux/mfd/abx500/ab8500.h> | ||
34 | #include <linux/usb/musb-ux500.h> | ||
35 | #include <linux/regulator/consumer.h> | ||
36 | #include <linux/pinctrl/consumer.h> | ||
37 | |||
38 | /* Bank AB8500_SYS_CTRL2_BLOCK */ | ||
39 | #define AB8500_MAIN_WD_CTRL_REG 0x01 | ||
40 | |||
41 | /* Bank AB8500_USB */ | ||
42 | #define AB8500_USB_LINE_STAT_REG 0x80 | ||
43 | #define AB8505_USB_LINE_STAT_REG 0x94 | ||
44 | #define AB8500_USB_PHY_CTRL_REG 0x8A | ||
45 | |||
46 | /* Bank AB8500_DEVELOPMENT */ | ||
47 | #define AB8500_BANK12_ACCESS 0x00 | ||
48 | |||
49 | /* Bank AB8500_DEBUG */ | ||
50 | #define AB8500_USB_PHY_TUNE1 0x05 | ||
51 | #define AB8500_USB_PHY_TUNE2 0x06 | ||
52 | #define AB8500_USB_PHY_TUNE3 0x07 | ||
53 | |||
54 | #define AB8500_BIT_OTG_STAT_ID (1 << 0) | ||
55 | #define AB8500_BIT_PHY_CTRL_HOST_EN (1 << 0) | ||
56 | #define AB8500_BIT_PHY_CTRL_DEVICE_EN (1 << 1) | ||
57 | #define AB8500_BIT_WD_CTRL_ENABLE (1 << 0) | ||
58 | #define AB8500_BIT_WD_CTRL_KICK (1 << 1) | ||
59 | |||
60 | #define AB8500_WD_KICK_DELAY_US 100 /* usec */ | ||
61 | #define AB8500_WD_V11_DISABLE_DELAY_US 100 /* usec */ | ||
62 | #define AB8500_V20_31952_DISABLE_DELAY_US 100 /* usec */ | ||
63 | |||
64 | /* Usb line status register */ | ||
65 | enum ab8500_usb_link_status { | ||
66 | USB_LINK_NOT_CONFIGURED_8500 = 0, | ||
67 | USB_LINK_STD_HOST_NC_8500, | ||
68 | USB_LINK_STD_HOST_C_NS_8500, | ||
69 | USB_LINK_STD_HOST_C_S_8500, | ||
70 | USB_LINK_HOST_CHG_NM_8500, | ||
71 | USB_LINK_HOST_CHG_HS_8500, | ||
72 | USB_LINK_HOST_CHG_HS_CHIRP_8500, | ||
73 | USB_LINK_DEDICATED_CHG_8500, | ||
74 | USB_LINK_ACA_RID_A_8500, | ||
75 | USB_LINK_ACA_RID_B_8500, | ||
76 | USB_LINK_ACA_RID_C_NM_8500, | ||
77 | USB_LINK_ACA_RID_C_HS_8500, | ||
78 | USB_LINK_ACA_RID_C_HS_CHIRP_8500, | ||
79 | USB_LINK_HM_IDGND_8500, | ||
80 | USB_LINK_RESERVED_8500, | ||
81 | USB_LINK_NOT_VALID_LINK_8500, | ||
82 | }; | ||
83 | |||
84 | enum ab8505_usb_link_status { | ||
85 | USB_LINK_NOT_CONFIGURED_8505 = 0, | ||
86 | USB_LINK_STD_HOST_NC_8505, | ||
87 | USB_LINK_STD_HOST_C_NS_8505, | ||
88 | USB_LINK_STD_HOST_C_S_8505, | ||
89 | USB_LINK_CDP_8505, | ||
90 | USB_LINK_RESERVED0_8505, | ||
91 | USB_LINK_RESERVED1_8505, | ||
92 | USB_LINK_DEDICATED_CHG_8505, | ||
93 | USB_LINK_ACA_RID_A_8505, | ||
94 | USB_LINK_ACA_RID_B_8505, | ||
95 | USB_LINK_ACA_RID_C_NM_8505, | ||
96 | USB_LINK_RESERVED2_8505, | ||
97 | USB_LINK_RESERVED3_8505, | ||
98 | USB_LINK_HM_IDGND_8505, | ||
99 | USB_LINK_CHARGERPORT_NOT_OK_8505, | ||
100 | USB_LINK_CHARGER_DM_HIGH_8505, | ||
101 | USB_LINK_PHYEN_NO_VBUS_NO_IDGND_8505, | ||
102 | USB_LINK_STD_UPSTREAM_NO_IDGNG_NO_VBUS_8505, | ||
103 | USB_LINK_STD_UPSTREAM_8505, | ||
104 | USB_LINK_CHARGER_SE1_8505, | ||
105 | USB_LINK_CARKIT_CHGR_1_8505, | ||
106 | USB_LINK_CARKIT_CHGR_2_8505, | ||
107 | USB_LINK_ACA_DOCK_CHGR_8505, | ||
108 | USB_LINK_SAMSUNG_BOOT_CBL_PHY_EN_8505, | ||
109 | USB_LINK_SAMSUNG_BOOT_CBL_PHY_DISB_8505, | ||
110 | USB_LINK_SAMSUNG_UART_CBL_PHY_EN_8505, | ||
111 | USB_LINK_SAMSUNG_UART_CBL_PHY_DISB_8505, | ||
112 | USB_LINK_MOTOROLA_FACTORY_CBL_PHY_EN_8505, | ||
113 | }; | ||
114 | |||
115 | enum ab8500_usb_mode { | ||
116 | USB_IDLE = 0, | ||
117 | USB_PERIPHERAL, | ||
118 | USB_HOST, | ||
119 | USB_DEDICATED_CHG | ||
120 | }; | ||
121 | |||
122 | struct ab8500_usb { | ||
123 | struct usb_phy phy; | ||
124 | struct device *dev; | ||
125 | struct ab8500 *ab8500; | ||
126 | unsigned vbus_draw; | ||
127 | struct work_struct phy_dis_work; | ||
128 | enum ab8500_usb_mode mode; | ||
129 | struct regulator *v_ape; | ||
130 | struct regulator *v_musb; | ||
131 | struct regulator *v_ulpi; | ||
132 | int saved_v_ulpi; | ||
133 | int previous_link_status_state; | ||
134 | struct pinctrl *pinctrl; | ||
135 | struct pinctrl_state *pins_sleep; | ||
136 | }; | ||
137 | |||
138 | static inline struct ab8500_usb *phy_to_ab(struct usb_phy *x) | ||
139 | { | ||
140 | return container_of(x, struct ab8500_usb, phy); | ||
141 | } | ||
142 | |||
143 | static void ab8500_usb_wd_workaround(struct ab8500_usb *ab) | ||
144 | { | ||
145 | abx500_set_register_interruptible(ab->dev, | ||
146 | AB8500_SYS_CTRL2_BLOCK, | ||
147 | AB8500_MAIN_WD_CTRL_REG, | ||
148 | AB8500_BIT_WD_CTRL_ENABLE); | ||
149 | |||
150 | udelay(AB8500_WD_KICK_DELAY_US); | ||
151 | |||
152 | abx500_set_register_interruptible(ab->dev, | ||
153 | AB8500_SYS_CTRL2_BLOCK, | ||
154 | AB8500_MAIN_WD_CTRL_REG, | ||
155 | (AB8500_BIT_WD_CTRL_ENABLE | ||
156 | | AB8500_BIT_WD_CTRL_KICK)); | ||
157 | |||
158 | udelay(AB8500_WD_V11_DISABLE_DELAY_US); | ||
159 | |||
160 | abx500_set_register_interruptible(ab->dev, | ||
161 | AB8500_SYS_CTRL2_BLOCK, | ||
162 | AB8500_MAIN_WD_CTRL_REG, | ||
163 | 0); | ||
164 | } | ||
165 | |||
166 | static void ab8500_usb_regulator_enable(struct ab8500_usb *ab) | ||
167 | { | ||
168 | int ret, volt; | ||
169 | |||
170 | ret = regulator_enable(ab->v_ape); | ||
171 | if (ret) | ||
172 | dev_err(ab->dev, "Failed to enable v-ape\n"); | ||
173 | |||
174 | if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { | ||
175 | ab->saved_v_ulpi = regulator_get_voltage(ab->v_ulpi); | ||
176 | if (ab->saved_v_ulpi < 0) | ||
177 | dev_err(ab->dev, "Failed to get v_ulpi voltage\n"); | ||
178 | |||
179 | ret = regulator_set_voltage(ab->v_ulpi, 1300000, 1350000); | ||
180 | if (ret < 0) | ||
181 | dev_err(ab->dev, "Failed to set the Vintcore to 1.3V, ret=%d\n", | ||
182 | ret); | ||
183 | |||
184 | ret = regulator_set_optimum_mode(ab->v_ulpi, 28000); | ||
185 | if (ret < 0) | ||
186 | dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n", | ||
187 | ret); | ||
188 | } | ||
189 | |||
190 | ret = regulator_enable(ab->v_ulpi); | ||
191 | if (ret) | ||
192 | dev_err(ab->dev, "Failed to enable vddulpivio18\n"); | ||
193 | |||
194 | if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { | ||
195 | volt = regulator_get_voltage(ab->v_ulpi); | ||
196 | if ((volt != 1300000) && (volt != 1350000)) | ||
197 | dev_err(ab->dev, "Vintcore is not set to 1.3V volt=%d\n", | ||
198 | volt); | ||
199 | } | ||
200 | |||
201 | ret = regulator_enable(ab->v_musb); | ||
202 | if (ret) | ||
203 | dev_err(ab->dev, "Failed to enable musb_1v8\n"); | ||
204 | } | ||
205 | |||
206 | static void ab8500_usb_regulator_disable(struct ab8500_usb *ab) | ||
207 | { | ||
208 | int ret; | ||
209 | |||
210 | regulator_disable(ab->v_musb); | ||
211 | |||
212 | regulator_disable(ab->v_ulpi); | ||
213 | |||
214 | /* USB is not the only consumer of Vintcore, restore old settings */ | ||
215 | if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { | ||
216 | if (ab->saved_v_ulpi > 0) { | ||
217 | ret = regulator_set_voltage(ab->v_ulpi, | ||
218 | ab->saved_v_ulpi, ab->saved_v_ulpi); | ||
219 | if (ret < 0) | ||
220 | dev_err(ab->dev, "Failed to set the Vintcore to %duV, ret=%d\n", | ||
221 | ab->saved_v_ulpi, ret); | ||
222 | } | ||
223 | |||
224 | ret = regulator_set_optimum_mode(ab->v_ulpi, 0); | ||
225 | if (ret < 0) | ||
226 | dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n", | ||
227 | ret); | ||
228 | } | ||
229 | |||
230 | regulator_disable(ab->v_ape); | ||
231 | } | ||
232 | |||
233 | static void ab8500_usb_wd_linkstatus(struct ab8500_usb *ab, u8 bit) | ||
234 | { | ||
235 | /* Workaround for v2.0 bug # 31952 */ | ||
236 | if (is_ab8500_2p0(ab->ab8500)) { | ||
237 | abx500_mask_and_set_register_interruptible(ab->dev, | ||
238 | AB8500_USB, AB8500_USB_PHY_CTRL_REG, | ||
239 | bit, bit); | ||
240 | udelay(AB8500_V20_31952_DISABLE_DELAY_US); | ||
241 | } | ||
242 | } | ||
243 | |||
244 | static void ab8500_usb_phy_enable(struct ab8500_usb *ab, bool sel_host) | ||
245 | { | ||
246 | u8 bit; | ||
247 | bit = sel_host ? AB8500_BIT_PHY_CTRL_HOST_EN : | ||
248 | AB8500_BIT_PHY_CTRL_DEVICE_EN; | ||
249 | |||
250 | /* mux and configure USB pins to DEFAULT state */ | ||
251 | ab->pinctrl = pinctrl_get_select(ab->dev, PINCTRL_STATE_DEFAULT); | ||
252 | if (IS_ERR(ab->pinctrl)) | ||
253 | dev_err(ab->dev, "could not get/set default pinstate\n"); | ||
254 | |||
255 | ab8500_usb_regulator_enable(ab); | ||
256 | |||
257 | abx500_mask_and_set_register_interruptible(ab->dev, | ||
258 | AB8500_USB, AB8500_USB_PHY_CTRL_REG, | ||
259 | bit, bit); | ||
260 | } | ||
261 | |||
262 | static void ab8500_usb_phy_disable(struct ab8500_usb *ab, bool sel_host) | ||
263 | { | ||
264 | u8 bit; | ||
265 | bit = sel_host ? AB8500_BIT_PHY_CTRL_HOST_EN : | ||
266 | AB8500_BIT_PHY_CTRL_DEVICE_EN; | ||
267 | |||
268 | ab8500_usb_wd_linkstatus(ab, bit); | ||
269 | |||
270 | abx500_mask_and_set_register_interruptible(ab->dev, | ||
271 | AB8500_USB, AB8500_USB_PHY_CTRL_REG, | ||
272 | bit, 0); | ||
273 | |||
274 | /* Needed to disable the phy.*/ | ||
275 | ab8500_usb_wd_workaround(ab); | ||
276 | |||
277 | ab8500_usb_regulator_disable(ab); | ||
278 | |||
279 | if (!IS_ERR(ab->pinctrl)) { | ||
280 | /* configure USB pins to SLEEP state */ | ||
281 | ab->pins_sleep = pinctrl_lookup_state(ab->pinctrl, | ||
282 | PINCTRL_STATE_SLEEP); | ||
283 | |||
284 | if (IS_ERR(ab->pins_sleep)) | ||
285 | dev_dbg(ab->dev, "could not get sleep pinstate\n"); | ||
286 | else if (pinctrl_select_state(ab->pinctrl, ab->pins_sleep)) | ||
287 | dev_err(ab->dev, "could not set pins to sleep state\n"); | ||
288 | |||
289 | /* as USB pins are shared with idddet, release them to allow | ||
290 | * iddet to request them | ||
291 | */ | ||
292 | pinctrl_put(ab->pinctrl); | ||
293 | } | ||
294 | } | ||
295 | |||
296 | #define ab8500_usb_host_phy_en(ab) ab8500_usb_phy_enable(ab, true) | ||
297 | #define ab8500_usb_host_phy_dis(ab) ab8500_usb_phy_disable(ab, true) | ||
298 | #define ab8500_usb_peri_phy_en(ab) ab8500_usb_phy_enable(ab, false) | ||
299 | #define ab8500_usb_peri_phy_dis(ab) ab8500_usb_phy_disable(ab, false) | ||
300 | |||
301 | static int ab8505_usb_link_status_update(struct ab8500_usb *ab, | ||
302 | enum ab8505_usb_link_status lsts) | ||
303 | { | ||
304 | enum ux500_musb_vbus_id_status event = 0; | ||
305 | |||
306 | dev_dbg(ab->dev, "ab8505_usb_link_status_update %d\n", lsts); | ||
307 | |||
308 | /* | ||
309 | * Spurious link_status interrupts are seen at the time of | ||
310 | * disconnection of a device in RIDA state | ||
311 | */ | ||
312 | if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8505 && | ||
313 | (lsts == USB_LINK_STD_HOST_NC_8505)) | ||
314 | return 0; | ||
315 | |||
316 | ab->previous_link_status_state = lsts; | ||
317 | |||
318 | switch (lsts) { | ||
319 | case USB_LINK_ACA_RID_B_8505: | ||
320 | event = UX500_MUSB_RIDB; | ||
321 | case USB_LINK_NOT_CONFIGURED_8505: | ||
322 | case USB_LINK_RESERVED0_8505: | ||
323 | case USB_LINK_RESERVED1_8505: | ||
324 | case USB_LINK_RESERVED2_8505: | ||
325 | case USB_LINK_RESERVED3_8505: | ||
326 | ab->mode = USB_IDLE; | ||
327 | ab->phy.otg->default_a = false; | ||
328 | ab->vbus_draw = 0; | ||
329 | if (event != UX500_MUSB_RIDB) | ||
330 | event = UX500_MUSB_NONE; | ||
331 | /* | ||
332 | * Fallback to default B_IDLE as nothing | ||
333 | * is connected | ||
334 | */ | ||
335 | ab->phy.state = OTG_STATE_B_IDLE; | ||
336 | break; | ||
337 | |||
338 | case USB_LINK_ACA_RID_C_NM_8505: | ||
339 | event = UX500_MUSB_RIDC; | ||
340 | case USB_LINK_STD_HOST_NC_8505: | ||
341 | case USB_LINK_STD_HOST_C_NS_8505: | ||
342 | case USB_LINK_STD_HOST_C_S_8505: | ||
343 | case USB_LINK_CDP_8505: | ||
344 | if (ab->mode == USB_IDLE) { | ||
345 | ab->mode = USB_PERIPHERAL; | ||
346 | ab8500_usb_peri_phy_en(ab); | ||
347 | atomic_notifier_call_chain(&ab->phy.notifier, | ||
348 | UX500_MUSB_PREPARE, &ab->vbus_draw); | ||
349 | } | ||
350 | if (event != UX500_MUSB_RIDC) | ||
351 | event = UX500_MUSB_VBUS; | ||
352 | break; | ||
353 | |||
354 | case USB_LINK_ACA_RID_A_8505: | ||
355 | case USB_LINK_ACA_DOCK_CHGR_8505: | ||
356 | event = UX500_MUSB_RIDA; | ||
357 | case USB_LINK_HM_IDGND_8505: | ||
358 | if (ab->mode == USB_IDLE) { | ||
359 | ab->mode = USB_HOST; | ||
360 | ab8500_usb_host_phy_en(ab); | ||
361 | atomic_notifier_call_chain(&ab->phy.notifier, | ||
362 | UX500_MUSB_PREPARE, &ab->vbus_draw); | ||
363 | } | ||
364 | ab->phy.otg->default_a = true; | ||
365 | if (event != UX500_MUSB_RIDA) | ||
366 | event = UX500_MUSB_ID; | ||
367 | atomic_notifier_call_chain(&ab->phy.notifier, | ||
368 | event, &ab->vbus_draw); | ||
369 | break; | ||
370 | |||
371 | case USB_LINK_DEDICATED_CHG_8505: | ||
372 | ab->mode = USB_DEDICATED_CHG; | ||
373 | event = UX500_MUSB_CHARGER; | ||
374 | atomic_notifier_call_chain(&ab->phy.notifier, | ||
375 | event, &ab->vbus_draw); | ||
376 | break; | ||
377 | |||
378 | default: | ||
379 | break; | ||
380 | } | ||
381 | |||
382 | return 0; | ||
383 | } | ||
384 | |||
385 | static int ab8500_usb_link_status_update(struct ab8500_usb *ab, | ||
386 | enum ab8500_usb_link_status lsts) | ||
387 | { | ||
388 | enum ux500_musb_vbus_id_status event = 0; | ||
389 | |||
390 | dev_dbg(ab->dev, "ab8500_usb_link_status_update %d\n", lsts); | ||
391 | |||
392 | /* | ||
393 | * Spurious link_status interrupts are seen in case of a | ||
394 | * disconnection of a device in IDGND and RIDA stage | ||
395 | */ | ||
396 | if (ab->previous_link_status_state == USB_LINK_HM_IDGND_8500 && | ||
397 | (lsts == USB_LINK_STD_HOST_C_NS_8500 || | ||
398 | lsts == USB_LINK_STD_HOST_NC_8500)) | ||
399 | return 0; | ||
400 | |||
401 | if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8500 && | ||
402 | lsts == USB_LINK_STD_HOST_NC_8500) | ||
403 | return 0; | ||
404 | |||
405 | ab->previous_link_status_state = lsts; | ||
406 | |||
407 | switch (lsts) { | ||
408 | case USB_LINK_ACA_RID_B_8500: | ||
409 | event = UX500_MUSB_RIDB; | ||
410 | case USB_LINK_NOT_CONFIGURED_8500: | ||
411 | case USB_LINK_NOT_VALID_LINK_8500: | ||
412 | ab->mode = USB_IDLE; | ||
413 | ab->phy.otg->default_a = false; | ||
414 | ab->vbus_draw = 0; | ||
415 | if (event != UX500_MUSB_RIDB) | ||
416 | event = UX500_MUSB_NONE; | ||
417 | /* Fallback to default B_IDLE as nothing is connected */ | ||
418 | ab->phy.state = OTG_STATE_B_IDLE; | ||
419 | break; | ||
420 | |||
421 | case USB_LINK_ACA_RID_C_NM_8500: | ||
422 | case USB_LINK_ACA_RID_C_HS_8500: | ||
423 | case USB_LINK_ACA_RID_C_HS_CHIRP_8500: | ||
424 | event = UX500_MUSB_RIDC; | ||
425 | case USB_LINK_STD_HOST_NC_8500: | ||
426 | case USB_LINK_STD_HOST_C_NS_8500: | ||
427 | case USB_LINK_STD_HOST_C_S_8500: | ||
428 | case USB_LINK_HOST_CHG_NM_8500: | ||
429 | case USB_LINK_HOST_CHG_HS_8500: | ||
430 | case USB_LINK_HOST_CHG_HS_CHIRP_8500: | ||
431 | if (ab->mode == USB_IDLE) { | ||
432 | ab->mode = USB_PERIPHERAL; | ||
433 | ab8500_usb_peri_phy_en(ab); | ||
434 | atomic_notifier_call_chain(&ab->phy.notifier, | ||
435 | UX500_MUSB_PREPARE, &ab->vbus_draw); | ||
436 | } | ||
437 | if (event != UX500_MUSB_RIDC) | ||
438 | event = UX500_MUSB_VBUS; | ||
439 | break; | ||
440 | |||
441 | case USB_LINK_ACA_RID_A_8500: | ||
442 | event = UX500_MUSB_RIDA; | ||
443 | case USB_LINK_HM_IDGND_8500: | ||
444 | if (ab->mode == USB_IDLE) { | ||
445 | ab->mode = USB_HOST; | ||
446 | ab8500_usb_host_phy_en(ab); | ||
447 | atomic_notifier_call_chain(&ab->phy.notifier, | ||
448 | UX500_MUSB_PREPARE, &ab->vbus_draw); | ||
449 | } | ||
450 | ab->phy.otg->default_a = true; | ||
451 | if (event != UX500_MUSB_RIDA) | ||
452 | event = UX500_MUSB_ID; | ||
453 | atomic_notifier_call_chain(&ab->phy.notifier, | ||
454 | event, &ab->vbus_draw); | ||
455 | break; | ||
456 | |||
457 | case USB_LINK_DEDICATED_CHG_8500: | ||
458 | ab->mode = USB_DEDICATED_CHG; | ||
459 | event = UX500_MUSB_CHARGER; | ||
460 | atomic_notifier_call_chain(&ab->phy.notifier, | ||
461 | event, &ab->vbus_draw); | ||
462 | break; | ||
463 | |||
464 | case USB_LINK_RESERVED_8500: | ||
465 | break; | ||
466 | } | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | /* | ||
472 | * Connection Sequence: | ||
473 | * 1. Link Status Interrupt | ||
474 | * 2. Enable AB clock | ||
475 | * 3. Enable AB regulators | ||
476 | * 4. Enable USB phy | ||
477 | * 5. Reset the musb controller | ||
478 | * 6. Switch the ULPI GPIO pins to fucntion mode | ||
479 | * 7. Enable the musb Peripheral5 clock | ||
480 | * 8. Restore MUSB context | ||
481 | */ | ||
482 | static int abx500_usb_link_status_update(struct ab8500_usb *ab) | ||
483 | { | ||
484 | u8 reg; | ||
485 | int ret = 0; | ||
486 | |||
487 | if (is_ab8500(ab->ab8500)) { | ||
488 | enum ab8500_usb_link_status lsts; | ||
489 | |||
490 | abx500_get_register_interruptible(ab->dev, | ||
491 | AB8500_USB, AB8500_USB_LINE_STAT_REG, ®); | ||
492 | lsts = (reg >> 3) & 0x0F; | ||
493 | ret = ab8500_usb_link_status_update(ab, lsts); | ||
494 | } else if (is_ab8505(ab->ab8500)) { | ||
495 | enum ab8505_usb_link_status lsts; | ||
496 | |||
497 | abx500_get_register_interruptible(ab->dev, | ||
498 | AB8500_USB, AB8505_USB_LINE_STAT_REG, ®); | ||
499 | lsts = (reg >> 3) & 0x1F; | ||
500 | ret = ab8505_usb_link_status_update(ab, lsts); | ||
501 | } | ||
502 | |||
503 | return ret; | ||
504 | } | ||
505 | |||
506 | /* | ||
507 | * Disconnection Sequence: | ||
508 | * 1. Disconect Interrupt | ||
509 | * 2. Disable regulators | ||
510 | * 3. Disable AB clock | ||
511 | * 4. Disable the Phy | ||
512 | * 5. Link Status Interrupt | ||
513 | * 6. Disable Musb Clock | ||
514 | */ | ||
515 | static irqreturn_t ab8500_usb_disconnect_irq(int irq, void *data) | ||
516 | { | ||
517 | struct ab8500_usb *ab = (struct ab8500_usb *) data; | ||
518 | enum usb_phy_events event = UX500_MUSB_NONE; | ||
519 | |||
520 | /* Link status will not be updated till phy is disabled. */ | ||
521 | if (ab->mode == USB_HOST) { | ||
522 | ab->phy.otg->default_a = false; | ||
523 | ab->vbus_draw = 0; | ||
524 | atomic_notifier_call_chain(&ab->phy.notifier, | ||
525 | event, &ab->vbus_draw); | ||
526 | ab8500_usb_host_phy_dis(ab); | ||
527 | ab->mode = USB_IDLE; | ||
528 | } | ||
529 | |||
530 | if (ab->mode == USB_PERIPHERAL) { | ||
531 | atomic_notifier_call_chain(&ab->phy.notifier, | ||
532 | event, &ab->vbus_draw); | ||
533 | ab8500_usb_peri_phy_dis(ab); | ||
534 | atomic_notifier_call_chain(&ab->phy.notifier, | ||
535 | UX500_MUSB_CLEAN, &ab->vbus_draw); | ||
536 | ab->mode = USB_IDLE; | ||
537 | ab->phy.otg->default_a = false; | ||
538 | ab->vbus_draw = 0; | ||
539 | } | ||
540 | |||
541 | if (is_ab8500_2p0(ab->ab8500)) { | ||
542 | if (ab->mode == USB_DEDICATED_CHG) { | ||
543 | ab8500_usb_wd_linkstatus(ab, | ||
544 | AB8500_BIT_PHY_CTRL_DEVICE_EN); | ||
545 | abx500_mask_and_set_register_interruptible(ab->dev, | ||
546 | AB8500_USB, AB8500_USB_PHY_CTRL_REG, | ||
547 | AB8500_BIT_PHY_CTRL_DEVICE_EN, 0); | ||
548 | } | ||
549 | } | ||
550 | |||
551 | return IRQ_HANDLED; | ||
552 | } | ||
553 | |||
554 | static irqreturn_t ab8500_usb_link_status_irq(int irq, void *data) | ||
555 | { | ||
556 | struct ab8500_usb *ab = (struct ab8500_usb *) data; | ||
557 | |||
558 | abx500_usb_link_status_update(ab); | ||
559 | |||
560 | return IRQ_HANDLED; | ||
561 | } | ||
562 | |||
563 | static void ab8500_usb_phy_disable_work(struct work_struct *work) | ||
564 | { | ||
565 | struct ab8500_usb *ab = container_of(work, struct ab8500_usb, | ||
566 | phy_dis_work); | ||
567 | |||
568 | if (!ab->phy.otg->host) | ||
569 | ab8500_usb_host_phy_dis(ab); | ||
570 | |||
571 | if (!ab->phy.otg->gadget) | ||
572 | ab8500_usb_peri_phy_dis(ab); | ||
573 | } | ||
574 | |||
575 | static unsigned ab8500_eyediagram_workaroud(struct ab8500_usb *ab, unsigned mA) | ||
576 | { | ||
577 | /* | ||
578 | * AB8500 V2 has eye diagram issues when drawing more than 100mA from | ||
579 | * VBUS. Set charging current to 100mA in case of standard host | ||
580 | */ | ||
581 | if (is_ab8500_2p0_or_earlier(ab->ab8500)) | ||
582 | if (mA > 100) | ||
583 | mA = 100; | ||
584 | |||
585 | return mA; | ||
586 | } | ||
587 | |||
588 | static int ab8500_usb_set_power(struct usb_phy *phy, unsigned mA) | ||
589 | { | ||
590 | struct ab8500_usb *ab; | ||
591 | |||
592 | if (!phy) | ||
593 | return -ENODEV; | ||
594 | |||
595 | ab = phy_to_ab(phy); | ||
596 | |||
597 | mA = ab8500_eyediagram_workaroud(ab, mA); | ||
598 | |||
599 | ab->vbus_draw = mA; | ||
600 | |||
601 | atomic_notifier_call_chain(&ab->phy.notifier, | ||
602 | UX500_MUSB_VBUS, &ab->vbus_draw); | ||
603 | |||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | static int ab8500_usb_set_suspend(struct usb_phy *x, int suspend) | ||
608 | { | ||
609 | /* TODO */ | ||
610 | return 0; | ||
611 | } | ||
612 | |||
613 | static int ab8500_usb_set_peripheral(struct usb_otg *otg, | ||
614 | struct usb_gadget *gadget) | ||
615 | { | ||
616 | struct ab8500_usb *ab; | ||
617 | |||
618 | if (!otg) | ||
619 | return -ENODEV; | ||
620 | |||
621 | ab = phy_to_ab(otg->phy); | ||
622 | |||
623 | ab->phy.otg->gadget = gadget; | ||
624 | |||
625 | /* Some drivers call this function in atomic context. | ||
626 | * Do not update ab8500 registers directly till this | ||
627 | * is fixed. | ||
628 | */ | ||
629 | |||
630 | if ((ab->mode != USB_IDLE) && (!gadget)) { | ||
631 | ab->mode = USB_IDLE; | ||
632 | schedule_work(&ab->phy_dis_work); | ||
633 | } | ||
634 | |||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | static int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host) | ||
639 | { | ||
640 | struct ab8500_usb *ab; | ||
641 | |||
642 | if (!otg) | ||
643 | return -ENODEV; | ||
644 | |||
645 | ab = phy_to_ab(otg->phy); | ||
646 | |||
647 | ab->phy.otg->host = host; | ||
648 | |||
649 | /* Some drivers call this function in atomic context. | ||
650 | * Do not update ab8500 registers directly till this | ||
651 | * is fixed. | ||
652 | */ | ||
653 | |||
654 | if ((ab->mode != USB_IDLE) && (!host)) { | ||
655 | ab->mode = USB_IDLE; | ||
656 | schedule_work(&ab->phy_dis_work); | ||
657 | } | ||
658 | |||
659 | return 0; | ||
660 | } | ||
661 | |||
662 | static int ab8500_usb_regulator_get(struct ab8500_usb *ab) | ||
663 | { | ||
664 | int err; | ||
665 | |||
666 | ab->v_ape = devm_regulator_get(ab->dev, "v-ape"); | ||
667 | if (IS_ERR(ab->v_ape)) { | ||
668 | dev_err(ab->dev, "Could not get v-ape supply\n"); | ||
669 | err = PTR_ERR(ab->v_ape); | ||
670 | return err; | ||
671 | } | ||
672 | |||
673 | ab->v_ulpi = devm_regulator_get(ab->dev, "vddulpivio18"); | ||
674 | if (IS_ERR(ab->v_ulpi)) { | ||
675 | dev_err(ab->dev, "Could not get vddulpivio18 supply\n"); | ||
676 | err = PTR_ERR(ab->v_ulpi); | ||
677 | return err; | ||
678 | } | ||
679 | |||
680 | ab->v_musb = devm_regulator_get(ab->dev, "musb_1v8"); | ||
681 | if (IS_ERR(ab->v_musb)) { | ||
682 | dev_err(ab->dev, "Could not get musb_1v8 supply\n"); | ||
683 | err = PTR_ERR(ab->v_musb); | ||
684 | return err; | ||
685 | } | ||
686 | |||
687 | return 0; | ||
688 | } | ||
689 | |||
690 | static int ab8500_usb_irq_setup(struct platform_device *pdev, | ||
691 | struct ab8500_usb *ab) | ||
692 | { | ||
693 | int err; | ||
694 | int irq; | ||
695 | |||
696 | irq = platform_get_irq_byname(pdev, "USB_LINK_STATUS"); | ||
697 | if (irq < 0) { | ||
698 | dev_err(&pdev->dev, "Link status irq not found\n"); | ||
699 | return irq; | ||
700 | } | ||
701 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, | ||
702 | ab8500_usb_link_status_irq, | ||
703 | IRQF_NO_SUSPEND | IRQF_SHARED, "usb-link-status", ab); | ||
704 | if (err < 0) { | ||
705 | dev_err(ab->dev, "request_irq failed for link status irq\n"); | ||
706 | return err; | ||
707 | } | ||
708 | |||
709 | irq = platform_get_irq_byname(pdev, "ID_WAKEUP_F"); | ||
710 | if (irq < 0) { | ||
711 | dev_err(&pdev->dev, "ID fall irq not found\n"); | ||
712 | return irq; | ||
713 | } | ||
714 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, | ||
715 | ab8500_usb_disconnect_irq, | ||
716 | IRQF_NO_SUSPEND | IRQF_SHARED, "usb-id-fall", ab); | ||
717 | if (err < 0) { | ||
718 | dev_err(ab->dev, "request_irq failed for ID fall irq\n"); | ||
719 | return err; | ||
720 | } | ||
721 | |||
722 | irq = platform_get_irq_byname(pdev, "VBUS_DET_F"); | ||
723 | if (irq < 0) { | ||
724 | dev_err(&pdev->dev, "VBUS fall irq not found\n"); | ||
725 | return irq; | ||
726 | } | ||
727 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, | ||
728 | ab8500_usb_disconnect_irq, | ||
729 | IRQF_NO_SUSPEND | IRQF_SHARED, "usb-vbus-fall", ab); | ||
730 | if (err < 0) { | ||
731 | dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); | ||
732 | return err; | ||
733 | } | ||
734 | |||
735 | return 0; | ||
736 | } | ||
737 | |||
738 | static int ab8500_usb_probe(struct platform_device *pdev) | ||
739 | { | ||
740 | struct ab8500_usb *ab; | ||
741 | struct ab8500 *ab8500; | ||
742 | struct usb_otg *otg; | ||
743 | int err; | ||
744 | int rev; | ||
745 | |||
746 | ab8500 = dev_get_drvdata(pdev->dev.parent); | ||
747 | rev = abx500_get_chip_id(&pdev->dev); | ||
748 | |||
749 | if (is_ab8500_1p1_or_earlier(ab8500)) { | ||
750 | dev_err(&pdev->dev, "Unsupported AB8500 chip rev=%d\n", rev); | ||
751 | return -ENODEV; | ||
752 | } | ||
753 | |||
754 | ab = devm_kzalloc(&pdev->dev, sizeof(*ab), GFP_KERNEL); | ||
755 | if (!ab) | ||
756 | return -ENOMEM; | ||
757 | |||
758 | otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); | ||
759 | if (!otg) | ||
760 | return -ENOMEM; | ||
761 | |||
762 | ab->dev = &pdev->dev; | ||
763 | ab->ab8500 = ab8500; | ||
764 | ab->phy.dev = ab->dev; | ||
765 | ab->phy.otg = otg; | ||
766 | ab->phy.label = "ab8500"; | ||
767 | ab->phy.set_suspend = ab8500_usb_set_suspend; | ||
768 | ab->phy.set_power = ab8500_usb_set_power; | ||
769 | ab->phy.state = OTG_STATE_UNDEFINED; | ||
770 | |||
771 | otg->phy = &ab->phy; | ||
772 | otg->set_host = ab8500_usb_set_host; | ||
773 | otg->set_peripheral = ab8500_usb_set_peripheral; | ||
774 | |||
775 | platform_set_drvdata(pdev, ab); | ||
776 | |||
777 | ATOMIC_INIT_NOTIFIER_HEAD(&ab->phy.notifier); | ||
778 | |||
779 | /* all: Disable phy when called from set_host and set_peripheral */ | ||
780 | INIT_WORK(&ab->phy_dis_work, ab8500_usb_phy_disable_work); | ||
781 | |||
782 | err = ab8500_usb_regulator_get(ab); | ||
783 | if (err) | ||
784 | return err; | ||
785 | |||
786 | err = ab8500_usb_irq_setup(pdev, ab); | ||
787 | if (err < 0) | ||
788 | return err; | ||
789 | |||
790 | err = usb_add_phy(&ab->phy, USB_PHY_TYPE_USB2); | ||
791 | if (err) { | ||
792 | dev_err(&pdev->dev, "Can't register transceiver\n"); | ||
793 | return err; | ||
794 | } | ||
795 | |||
796 | /* Phy tuning values for AB8500 */ | ||
797 | if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { | ||
798 | /* Enable the PBT/Bank 0x12 access */ | ||
799 | err = abx500_set_register_interruptible(ab->dev, | ||
800 | AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 0x01); | ||
801 | if (err < 0) | ||
802 | dev_err(ab->dev, "Failed to enable bank12 access err=%d\n", | ||
803 | err); | ||
804 | |||
805 | err = abx500_set_register_interruptible(ab->dev, | ||
806 | AB8500_DEBUG, AB8500_USB_PHY_TUNE1, 0xC8); | ||
807 | if (err < 0) | ||
808 | dev_err(ab->dev, "Failed to set PHY_TUNE1 register err=%d\n", | ||
809 | err); | ||
810 | |||
811 | err = abx500_set_register_interruptible(ab->dev, | ||
812 | AB8500_DEBUG, AB8500_USB_PHY_TUNE2, 0x00); | ||
813 | if (err < 0) | ||
814 | dev_err(ab->dev, "Failed to set PHY_TUNE2 register err=%d\n", | ||
815 | err); | ||
816 | |||
817 | err = abx500_set_register_interruptible(ab->dev, | ||
818 | AB8500_DEBUG, AB8500_USB_PHY_TUNE3, 0x78); | ||
819 | if (err < 0) | ||
820 | dev_err(ab->dev, "Failed to set PHY_TUNE3 regester err=%d\n", | ||
821 | err); | ||
822 | |||
823 | /* Switch to normal mode/disable Bank 0x12 access */ | ||
824 | err = abx500_set_register_interruptible(ab->dev, | ||
825 | AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 0x00); | ||
826 | if (err < 0) | ||
827 | dev_err(ab->dev, "Failed to switch bank12 access err=%d\n", | ||
828 | err); | ||
829 | } | ||
830 | |||
831 | /* Phy tuning values for AB8505 */ | ||
832 | if (is_ab8505(ab->ab8500)) { | ||
833 | /* Enable the PBT/Bank 0x12 access */ | ||
834 | err = abx500_mask_and_set_register_interruptible(ab->dev, | ||
835 | AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, | ||
836 | 0x01, 0x01); | ||
837 | if (err < 0) | ||
838 | dev_err(ab->dev, "Failed to enable bank12 access err=%d\n", | ||
839 | err); | ||
840 | |||
841 | err = abx500_mask_and_set_register_interruptible(ab->dev, | ||
842 | AB8500_DEBUG, AB8500_USB_PHY_TUNE1, | ||
843 | 0xC8, 0xC8); | ||
844 | if (err < 0) | ||
845 | dev_err(ab->dev, "Failed to set PHY_TUNE1 register err=%d\n", | ||
846 | err); | ||
847 | |||
848 | err = abx500_mask_and_set_register_interruptible(ab->dev, | ||
849 | AB8500_DEBUG, AB8500_USB_PHY_TUNE2, | ||
850 | 0x60, 0x60); | ||
851 | if (err < 0) | ||
852 | dev_err(ab->dev, "Failed to set PHY_TUNE2 register err=%d\n", | ||
853 | err); | ||
854 | |||
855 | err = abx500_mask_and_set_register_interruptible(ab->dev, | ||
856 | AB8500_DEBUG, AB8500_USB_PHY_TUNE3, | ||
857 | 0xFC, 0x80); | ||
858 | |||
859 | if (err < 0) | ||
860 | dev_err(ab->dev, "Failed to set PHY_TUNE3 regester err=%d\n", | ||
861 | err); | ||
862 | |||
863 | /* Switch to normal mode/disable Bank 0x12 access */ | ||
864 | err = abx500_mask_and_set_register_interruptible(ab->dev, | ||
865 | AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, | ||
866 | 0x00, 0x00); | ||
867 | if (err < 0) | ||
868 | dev_err(ab->dev, "Failed to switch bank12 access err=%d\n", | ||
869 | err); | ||
870 | } | ||
871 | |||
872 | /* Needed to enable ID detection. */ | ||
873 | ab8500_usb_wd_workaround(ab); | ||
874 | |||
875 | abx500_usb_link_status_update(ab); | ||
876 | |||
877 | dev_info(&pdev->dev, "revision 0x%2x driver initialized\n", rev); | ||
878 | |||
879 | return 0; | ||
880 | } | ||
881 | |||
882 | static int ab8500_usb_remove(struct platform_device *pdev) | ||
883 | { | ||
884 | struct ab8500_usb *ab = platform_get_drvdata(pdev); | ||
885 | |||
886 | cancel_work_sync(&ab->phy_dis_work); | ||
887 | |||
888 | usb_remove_phy(&ab->phy); | ||
889 | |||
890 | if (ab->mode == USB_HOST) | ||
891 | ab8500_usb_host_phy_dis(ab); | ||
892 | else if (ab->mode == USB_PERIPHERAL) | ||
893 | ab8500_usb_peri_phy_dis(ab); | ||
894 | |||
895 | platform_set_drvdata(pdev, NULL); | ||
896 | |||
897 | return 0; | ||
898 | } | ||
899 | |||
900 | static struct platform_driver ab8500_usb_driver = { | ||
901 | .probe = ab8500_usb_probe, | ||
902 | .remove = ab8500_usb_remove, | ||
903 | .driver = { | ||
904 | .name = "ab8500-usb", | ||
905 | .owner = THIS_MODULE, | ||
906 | }, | ||
907 | }; | ||
908 | |||
909 | static int __init ab8500_usb_init(void) | ||
910 | { | ||
911 | return platform_driver_register(&ab8500_usb_driver); | ||
912 | } | ||
913 | subsys_initcall(ab8500_usb_init); | ||
914 | |||
915 | static void __exit ab8500_usb_exit(void) | ||
916 | { | ||
917 | platform_driver_unregister(&ab8500_usb_driver); | ||
918 | } | ||
919 | module_exit(ab8500_usb_exit); | ||
920 | |||
921 | MODULE_ALIAS("platform:ab8500_usb"); | ||
922 | MODULE_AUTHOR("ST-Ericsson AB"); | ||
923 | MODULE_DESCRIPTION("AB8500 usb transceiver driver"); | ||
924 | MODULE_LICENSE("GPL"); | ||