Commit | Line | Data |
---|---|---|
5fd54ace | 1 | // SPDX-License-Identifier: GPL-2.0+ |
96915234 | 2 | /* |
0c380c0e | 3 | * USB transceiver driver for AB8500 family chips |
96915234 | 4 | * |
0c380c0e | 5 | * Copyright (C) 2010-2013 ST-Ericsson AB |
96915234 | 6 | * Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> |
0c380c0e | 7 | * Avinash Kumar <avinash.kumar@stericsson.com> |
f85bff5d | 8 | * Thirupathi Chippakurthy <thirupathi.chippakurthy@stericsson.com> |
96915234 MYK |
9 | */ |
10 | ||
11 | #include <linux/module.h> | |
12 | #include <linux/platform_device.h> | |
13 | #include <linux/usb/otg.h> | |
14 | #include <linux/slab.h> | |
15 | #include <linux/notifier.h> | |
16 | #include <linux/interrupt.h> | |
17 | #include <linux/delay.h> | |
d0ed0645 MYK |
18 | #include <linux/clk.h> |
19 | #include <linux/err.h> | |
96915234 | 20 | #include <linux/mfd/abx500.h> |
ee66e653 | 21 | #include <linux/mfd/abx500/ab8500.h> |
af6882be | 22 | #include <linux/usb/musb-ux500.h> |
e65b36c0 | 23 | #include <linux/regulator/consumer.h> |
899f0f56 | 24 | #include <linux/pinctrl/consumer.h> |
96915234 | 25 | |
7124631a | 26 | /* Bank AB8500_SYS_CTRL2_BLOCK */ |
96915234 | 27 | #define AB8500_MAIN_WD_CTRL_REG 0x01 |
7124631a SB |
28 | |
29 | /* Bank AB8500_USB */ | |
96915234 | 30 | #define AB8500_USB_LINE_STAT_REG 0x80 |
af6882be | 31 | #define AB8505_USB_LINE_STAT_REG 0x94 |
96915234 MYK |
32 | #define AB8500_USB_PHY_CTRL_REG 0x8A |
33 | ||
7124631a SB |
34 | /* Bank AB8500_DEVELOPMENT */ |
35 | #define AB8500_BANK12_ACCESS 0x00 | |
36 | ||
37 | /* Bank AB8500_DEBUG */ | |
38 | #define AB8500_USB_PHY_TUNE1 0x05 | |
39 | #define AB8500_USB_PHY_TUNE2 0x06 | |
40 | #define AB8500_USB_PHY_TUNE3 0x07 | |
41 | ||
0c380c0e FB |
42 | /* Bank AB8500_INTERRUPT */ |
43 | #define AB8500_IT_SOURCE2_REG 0x01 | |
44 | ||
96915234 MYK |
45 | #define AB8500_BIT_OTG_STAT_ID (1 << 0) |
46 | #define AB8500_BIT_PHY_CTRL_HOST_EN (1 << 0) | |
47 | #define AB8500_BIT_PHY_CTRL_DEVICE_EN (1 << 1) | |
48 | #define AB8500_BIT_WD_CTRL_ENABLE (1 << 0) | |
49 | #define AB8500_BIT_WD_CTRL_KICK (1 << 1) | |
0c380c0e | 50 | #define AB8500_BIT_SOURCE2_VBUSDET (1 << 7) |
96915234 | 51 | |
96915234 MYK |
52 | #define AB8500_WD_KICK_DELAY_US 100 /* usec */ |
53 | #define AB8500_WD_V11_DISABLE_DELAY_US 100 /* usec */ | |
af6882be | 54 | #define AB8500_V20_31952_DISABLE_DELAY_US 100 /* usec */ |
96915234 MYK |
55 | |
56 | /* Usb line status register */ | |
57 | enum ab8500_usb_link_status { | |
af6882be FB |
58 | USB_LINK_NOT_CONFIGURED_8500 = 0, |
59 | USB_LINK_STD_HOST_NC_8500, | |
60 | USB_LINK_STD_HOST_C_NS_8500, | |
61 | USB_LINK_STD_HOST_C_S_8500, | |
62 | USB_LINK_HOST_CHG_NM_8500, | |
63 | USB_LINK_HOST_CHG_HS_8500, | |
64 | USB_LINK_HOST_CHG_HS_CHIRP_8500, | |
65 | USB_LINK_DEDICATED_CHG_8500, | |
66 | USB_LINK_ACA_RID_A_8500, | |
67 | USB_LINK_ACA_RID_B_8500, | |
68 | USB_LINK_ACA_RID_C_NM_8500, | |
69 | USB_LINK_ACA_RID_C_HS_8500, | |
70 | USB_LINK_ACA_RID_C_HS_CHIRP_8500, | |
71 | USB_LINK_HM_IDGND_8500, | |
72 | USB_LINK_RESERVED_8500, | |
73 | USB_LINK_NOT_VALID_LINK_8500, | |
74 | }; | |
75 | ||
76 | enum ab8505_usb_link_status { | |
77 | USB_LINK_NOT_CONFIGURED_8505 = 0, | |
78 | USB_LINK_STD_HOST_NC_8505, | |
79 | USB_LINK_STD_HOST_C_NS_8505, | |
80 | USB_LINK_STD_HOST_C_S_8505, | |
81 | USB_LINK_CDP_8505, | |
82 | USB_LINK_RESERVED0_8505, | |
83 | USB_LINK_RESERVED1_8505, | |
84 | USB_LINK_DEDICATED_CHG_8505, | |
85 | USB_LINK_ACA_RID_A_8505, | |
86 | USB_LINK_ACA_RID_B_8505, | |
87 | USB_LINK_ACA_RID_C_NM_8505, | |
88 | USB_LINK_RESERVED2_8505, | |
89 | USB_LINK_RESERVED3_8505, | |
90 | USB_LINK_HM_IDGND_8505, | |
91 | USB_LINK_CHARGERPORT_NOT_OK_8505, | |
92 | USB_LINK_CHARGER_DM_HIGH_8505, | |
93 | USB_LINK_PHYEN_NO_VBUS_NO_IDGND_8505, | |
94 | USB_LINK_STD_UPSTREAM_NO_IDGNG_NO_VBUS_8505, | |
95 | USB_LINK_STD_UPSTREAM_8505, | |
96 | USB_LINK_CHARGER_SE1_8505, | |
97 | USB_LINK_CARKIT_CHGR_1_8505, | |
98 | USB_LINK_CARKIT_CHGR_2_8505, | |
99 | USB_LINK_ACA_DOCK_CHGR_8505, | |
100 | USB_LINK_SAMSUNG_BOOT_CBL_PHY_EN_8505, | |
101 | USB_LINK_SAMSUNG_BOOT_CBL_PHY_DISB_8505, | |
102 | USB_LINK_SAMSUNG_UART_CBL_PHY_EN_8505, | |
103 | USB_LINK_SAMSUNG_UART_CBL_PHY_DISB_8505, | |
104 | USB_LINK_MOTOROLA_FACTORY_CBL_PHY_EN_8505, | |
105 | }; | |
106 | ||
107 | enum ab8500_usb_mode { | |
108 | USB_IDLE = 0, | |
109 | USB_PERIPHERAL, | |
110 | USB_HOST, | |
111 | USB_DEDICATED_CHG | |
96915234 MYK |
112 | }; |
113 | ||
bd4c9f02 FB |
114 | /* Register USB_LINK_STATUS interrupt */ |
115 | #define AB8500_USB_FLAG_USE_LINK_STATUS_IRQ (1 << 0) | |
116 | /* Register ID_WAKEUP_F interrupt */ | |
117 | #define AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ (1 << 1) | |
118 | /* Register VBUS_DET_F interrupt */ | |
119 | #define AB8500_USB_FLAG_USE_VBUS_DET_IRQ (1 << 2) | |
120 | /* Driver is using the ab-iddet driver*/ | |
121 | #define AB8500_USB_FLAG_USE_AB_IDDET (1 << 3) | |
122 | /* Enable setting regulators voltage */ | |
123 | #define AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE (1 << 4) | |
124 | ||
96915234 | 125 | struct ab8500_usb { |
144713f3 | 126 | struct usb_phy phy; |
96915234 | 127 | struct device *dev; |
73f226cb | 128 | struct ab8500 *ab8500; |
96915234 | 129 | unsigned vbus_draw; |
96915234 | 130 | struct work_struct phy_dis_work; |
af6882be | 131 | enum ab8500_usb_mode mode; |
d0ed0645 | 132 | struct clk *sysclk; |
e65b36c0 FB |
133 | struct regulator *v_ape; |
134 | struct regulator *v_musb; | |
135 | struct regulator *v_ulpi; | |
54dfbb08 | 136 | int saved_v_ulpi; |
af6882be | 137 | int previous_link_status_state; |
899f0f56 PC |
138 | struct pinctrl *pinctrl; |
139 | struct pinctrl_state *pins_sleep; | |
0c380c0e | 140 | bool enabled_charging_detection; |
bd4c9f02 | 141 | unsigned int flags; |
96915234 MYK |
142 | }; |
143 | ||
144713f3 | 144 | static inline struct ab8500_usb *phy_to_ab(struct usb_phy *x) |
96915234 | 145 | { |
144713f3 | 146 | return container_of(x, struct ab8500_usb, phy); |
96915234 MYK |
147 | } |
148 | ||
149 | static void ab8500_usb_wd_workaround(struct ab8500_usb *ab) | |
150 | { | |
151 | abx500_set_register_interruptible(ab->dev, | |
152 | AB8500_SYS_CTRL2_BLOCK, | |
153 | AB8500_MAIN_WD_CTRL_REG, | |
154 | AB8500_BIT_WD_CTRL_ENABLE); | |
155 | ||
156 | udelay(AB8500_WD_KICK_DELAY_US); | |
157 | ||
158 | abx500_set_register_interruptible(ab->dev, | |
159 | AB8500_SYS_CTRL2_BLOCK, | |
160 | AB8500_MAIN_WD_CTRL_REG, | |
161 | (AB8500_BIT_WD_CTRL_ENABLE | |
162 | | AB8500_BIT_WD_CTRL_KICK)); | |
163 | ||
73f226cb | 164 | udelay(AB8500_WD_V11_DISABLE_DELAY_US); |
96915234 MYK |
165 | |
166 | abx500_set_register_interruptible(ab->dev, | |
167 | AB8500_SYS_CTRL2_BLOCK, | |
168 | AB8500_MAIN_WD_CTRL_REG, | |
169 | 0); | |
170 | } | |
171 | ||
54dfbb08 FB |
172 | static void ab8500_usb_regulator_enable(struct ab8500_usb *ab) |
173 | { | |
174 | int ret, volt; | |
175 | ||
88b1c78d FB |
176 | ret = regulator_enable(ab->v_ape); |
177 | if (ret) | |
178 | dev_err(ab->dev, "Failed to enable v-ape\n"); | |
54dfbb08 | 179 | |
bd4c9f02 | 180 | if (ab->flags & AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE) { |
54dfbb08 FB |
181 | ab->saved_v_ulpi = regulator_get_voltage(ab->v_ulpi); |
182 | if (ab->saved_v_ulpi < 0) | |
183 | dev_err(ab->dev, "Failed to get v_ulpi voltage\n"); | |
184 | ||
185 | ret = regulator_set_voltage(ab->v_ulpi, 1300000, 1350000); | |
186 | if (ret < 0) | |
187 | dev_err(ab->dev, "Failed to set the Vintcore to 1.3V, ret=%d\n", | |
188 | ret); | |
189 | ||
1d61a694 | 190 | ret = regulator_set_load(ab->v_ulpi, 28000); |
54dfbb08 FB |
191 | if (ret < 0) |
192 | dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n", | |
193 | ret); | |
194 | } | |
195 | ||
88b1c78d FB |
196 | ret = regulator_enable(ab->v_ulpi); |
197 | if (ret) | |
198 | dev_err(ab->dev, "Failed to enable vddulpivio18\n"); | |
54dfbb08 | 199 | |
bd4c9f02 | 200 | if (ab->flags & AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE) { |
54dfbb08 FB |
201 | volt = regulator_get_voltage(ab->v_ulpi); |
202 | if ((volt != 1300000) && (volt != 1350000)) | |
203 | dev_err(ab->dev, "Vintcore is not set to 1.3V volt=%d\n", | |
204 | volt); | |
205 | } | |
206 | ||
88b1c78d FB |
207 | ret = regulator_enable(ab->v_musb); |
208 | if (ret) | |
209 | dev_err(ab->dev, "Failed to enable musb_1v8\n"); | |
54dfbb08 FB |
210 | } |
211 | ||
212 | static void ab8500_usb_regulator_disable(struct ab8500_usb *ab) | |
213 | { | |
214 | int ret; | |
215 | ||
216 | regulator_disable(ab->v_musb); | |
217 | ||
218 | regulator_disable(ab->v_ulpi); | |
219 | ||
220 | /* USB is not the only consumer of Vintcore, restore old settings */ | |
bd4c9f02 | 221 | if (ab->flags & AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE) { |
54dfbb08 FB |
222 | if (ab->saved_v_ulpi > 0) { |
223 | ret = regulator_set_voltage(ab->v_ulpi, | |
224 | ab->saved_v_ulpi, ab->saved_v_ulpi); | |
225 | if (ret < 0) | |
226 | dev_err(ab->dev, "Failed to set the Vintcore to %duV, ret=%d\n", | |
227 | ab->saved_v_ulpi, ret); | |
228 | } | |
229 | ||
1d61a694 | 230 | ret = regulator_set_load(ab->v_ulpi, 0); |
54dfbb08 FB |
231 | if (ret < 0) |
232 | dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n", | |
233 | ret); | |
234 | } | |
235 | ||
236 | regulator_disable(ab->v_ape); | |
237 | } | |
238 | ||
af6882be FB |
239 | static void ab8500_usb_wd_linkstatus(struct ab8500_usb *ab, u8 bit) |
240 | { | |
241 | /* Workaround for v2.0 bug # 31952 */ | |
242 | if (is_ab8500_2p0(ab->ab8500)) { | |
243 | abx500_mask_and_set_register_interruptible(ab->dev, | |
244 | AB8500_USB, AB8500_USB_PHY_CTRL_REG, | |
245 | bit, bit); | |
246 | udelay(AB8500_V20_31952_DISABLE_DELAY_US); | |
247 | } | |
248 | } | |
249 | ||
c0ea7064 | 250 | static void ab8500_usb_phy_enable(struct ab8500_usb *ab, bool sel_host) |
96915234 | 251 | { |
c0ea7064 FB |
252 | u8 bit; |
253 | bit = sel_host ? AB8500_BIT_PHY_CTRL_HOST_EN : | |
254 | AB8500_BIT_PHY_CTRL_DEVICE_EN; | |
96915234 | 255 | |
899f0f56 PC |
256 | /* mux and configure USB pins to DEFAULT state */ |
257 | ab->pinctrl = pinctrl_get_select(ab->dev, PINCTRL_STATE_DEFAULT); | |
258 | if (IS_ERR(ab->pinctrl)) | |
259 | dev_err(ab->dev, "could not get/set default pinstate\n"); | |
260 | ||
d0ed0645 MYK |
261 | if (clk_prepare_enable(ab->sysclk)) |
262 | dev_err(ab->dev, "can't prepare/enable clock\n"); | |
263 | ||
54dfbb08 FB |
264 | ab8500_usb_regulator_enable(ab); |
265 | ||
c0ea7064 FB |
266 | abx500_mask_and_set_register_interruptible(ab->dev, |
267 | AB8500_USB, AB8500_USB_PHY_CTRL_REG, | |
268 | bit, bit); | |
269 | } | |
270 | ||
271 | static void ab8500_usb_phy_disable(struct ab8500_usb *ab, bool sel_host) | |
272 | { | |
273 | u8 bit; | |
274 | bit = sel_host ? AB8500_BIT_PHY_CTRL_HOST_EN : | |
275 | AB8500_BIT_PHY_CTRL_DEVICE_EN; | |
276 | ||
277 | ab8500_usb_wd_linkstatus(ab, bit); | |
278 | ||
279 | abx500_mask_and_set_register_interruptible(ab->dev, | |
280 | AB8500_USB, AB8500_USB_PHY_CTRL_REG, | |
281 | bit, 0); | |
96915234 | 282 | |
c0ea7064 FB |
283 | /* Needed to disable the phy.*/ |
284 | ab8500_usb_wd_workaround(ab); | |
54dfbb08 | 285 | |
d0ed0645 MYK |
286 | clk_disable_unprepare(ab->sysclk); |
287 | ||
54dfbb08 | 288 | ab8500_usb_regulator_disable(ab); |
899f0f56 PC |
289 | |
290 | if (!IS_ERR(ab->pinctrl)) { | |
291 | /* configure USB pins to SLEEP state */ | |
292 | ab->pins_sleep = pinctrl_lookup_state(ab->pinctrl, | |
293 | PINCTRL_STATE_SLEEP); | |
294 | ||
295 | if (IS_ERR(ab->pins_sleep)) | |
296 | dev_dbg(ab->dev, "could not get sleep pinstate\n"); | |
297 | else if (pinctrl_select_state(ab->pinctrl, ab->pins_sleep)) | |
298 | dev_err(ab->dev, "could not set pins to sleep state\n"); | |
299 | ||
3147dad6 FB |
300 | /* |
301 | * as USB pins are shared with iddet, release them to allow | |
899f0f56 PC |
302 | * iddet to request them |
303 | */ | |
304 | pinctrl_put(ab->pinctrl); | |
305 | } | |
96915234 MYK |
306 | } |
307 | ||
c0ea7064 FB |
308 | #define ab8500_usb_host_phy_en(ab) ab8500_usb_phy_enable(ab, true) |
309 | #define ab8500_usb_host_phy_dis(ab) ab8500_usb_phy_disable(ab, true) | |
310 | #define ab8500_usb_peri_phy_en(ab) ab8500_usb_phy_enable(ab, false) | |
311 | #define ab8500_usb_peri_phy_dis(ab) ab8500_usb_phy_disable(ab, false) | |
96915234 | 312 | |
af6882be FB |
313 | static int ab8505_usb_link_status_update(struct ab8500_usb *ab, |
314 | enum ab8505_usb_link_status lsts) | |
96915234 | 315 | { |
af6882be | 316 | enum ux500_musb_vbus_id_status event = 0; |
96915234 | 317 | |
af6882be | 318 | dev_dbg(ab->dev, "ab8505_usb_link_status_update %d\n", lsts); |
96915234 | 319 | |
af6882be FB |
320 | /* |
321 | * Spurious link_status interrupts are seen at the time of | |
322 | * disconnection of a device in RIDA state | |
323 | */ | |
324 | if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8505 && | |
325 | (lsts == USB_LINK_STD_HOST_NC_8505)) | |
326 | return 0; | |
327 | ||
328 | ab->previous_link_status_state = lsts; | |
96915234 MYK |
329 | |
330 | switch (lsts) { | |
af6882be FB |
331 | case USB_LINK_ACA_RID_B_8505: |
332 | event = UX500_MUSB_RIDB; | |
333 | case USB_LINK_NOT_CONFIGURED_8505: | |
334 | case USB_LINK_RESERVED0_8505: | |
335 | case USB_LINK_RESERVED1_8505: | |
336 | case USB_LINK_RESERVED2_8505: | |
337 | case USB_LINK_RESERVED3_8505: | |
338 | ab->mode = USB_IDLE; | |
144713f3 | 339 | ab->phy.otg->default_a = false; |
96915234 | 340 | ab->vbus_draw = 0; |
af6882be FB |
341 | if (event != UX500_MUSB_RIDB) |
342 | event = UX500_MUSB_NONE; | |
343 | /* | |
344 | * Fallback to default B_IDLE as nothing | |
345 | * is connected | |
346 | */ | |
e47d9254 | 347 | ab->phy.otg->state = OTG_STATE_B_IDLE; |
b20f3f9e | 348 | usb_phy_set_event(&ab->phy, USB_EVENT_NONE); |
96915234 MYK |
349 | break; |
350 | ||
af6882be FB |
351 | case USB_LINK_ACA_RID_C_NM_8505: |
352 | event = UX500_MUSB_RIDC; | |
353 | case USB_LINK_STD_HOST_NC_8505: | |
354 | case USB_LINK_STD_HOST_C_NS_8505: | |
355 | case USB_LINK_STD_HOST_C_S_8505: | |
356 | case USB_LINK_CDP_8505: | |
357 | if (ab->mode == USB_IDLE) { | |
358 | ab->mode = USB_PERIPHERAL; | |
96915234 | 359 | ab8500_usb_peri_phy_en(ab); |
af6882be FB |
360 | atomic_notifier_call_chain(&ab->phy.notifier, |
361 | UX500_MUSB_PREPARE, &ab->vbus_draw); | |
b20f3f9e | 362 | usb_phy_set_event(&ab->phy, USB_EVENT_ENUMERATED); |
96915234 | 363 | } |
af6882be FB |
364 | if (event != UX500_MUSB_RIDC) |
365 | event = UX500_MUSB_VBUS; | |
96915234 MYK |
366 | break; |
367 | ||
af6882be FB |
368 | case USB_LINK_ACA_RID_A_8505: |
369 | case USB_LINK_ACA_DOCK_CHGR_8505: | |
370 | event = UX500_MUSB_RIDA; | |
371 | case USB_LINK_HM_IDGND_8505: | |
372 | if (ab->mode == USB_IDLE) { | |
373 | ab->mode = USB_HOST; | |
96915234 | 374 | ab8500_usb_host_phy_en(ab); |
af6882be FB |
375 | atomic_notifier_call_chain(&ab->phy.notifier, |
376 | UX500_MUSB_PREPARE, &ab->vbus_draw); | |
96915234 | 377 | } |
144713f3 | 378 | ab->phy.otg->default_a = true; |
af6882be FB |
379 | if (event != UX500_MUSB_RIDA) |
380 | event = UX500_MUSB_ID; | |
381 | atomic_notifier_call_chain(&ab->phy.notifier, | |
382 | event, &ab->vbus_draw); | |
96915234 MYK |
383 | break; |
384 | ||
af6882be FB |
385 | case USB_LINK_DEDICATED_CHG_8505: |
386 | ab->mode = USB_DEDICATED_CHG; | |
387 | event = UX500_MUSB_CHARGER; | |
388 | atomic_notifier_call_chain(&ab->phy.notifier, | |
389 | event, &ab->vbus_draw); | |
b20f3f9e | 390 | usb_phy_set_event(&ab->phy, USB_EVENT_CHARGER); |
af6882be FB |
391 | break; |
392 | ||
393 | default: | |
96915234 MYK |
394 | break; |
395 | } | |
396 | ||
af6882be FB |
397 | return 0; |
398 | } | |
399 | ||
400 | static int ab8500_usb_link_status_update(struct ab8500_usb *ab, | |
401 | enum ab8500_usb_link_status lsts) | |
402 | { | |
403 | enum ux500_musb_vbus_id_status event = 0; | |
404 | ||
405 | dev_dbg(ab->dev, "ab8500_usb_link_status_update %d\n", lsts); | |
406 | ||
407 | /* | |
408 | * Spurious link_status interrupts are seen in case of a | |
409 | * disconnection of a device in IDGND and RIDA stage | |
410 | */ | |
411 | if (ab->previous_link_status_state == USB_LINK_HM_IDGND_8500 && | |
412 | (lsts == USB_LINK_STD_HOST_C_NS_8500 || | |
413 | lsts == USB_LINK_STD_HOST_NC_8500)) | |
414 | return 0; | |
415 | ||
416 | if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8500 && | |
417 | lsts == USB_LINK_STD_HOST_NC_8500) | |
418 | return 0; | |
419 | ||
420 | ab->previous_link_status_state = lsts; | |
421 | ||
422 | switch (lsts) { | |
423 | case USB_LINK_ACA_RID_B_8500: | |
424 | event = UX500_MUSB_RIDB; | |
425 | case USB_LINK_NOT_CONFIGURED_8500: | |
426 | case USB_LINK_NOT_VALID_LINK_8500: | |
427 | ab->mode = USB_IDLE; | |
428 | ab->phy.otg->default_a = false; | |
429 | ab->vbus_draw = 0; | |
430 | if (event != UX500_MUSB_RIDB) | |
431 | event = UX500_MUSB_NONE; | |
432 | /* Fallback to default B_IDLE as nothing is connected */ | |
e47d9254 | 433 | ab->phy.otg->state = OTG_STATE_B_IDLE; |
b20f3f9e | 434 | usb_phy_set_event(&ab->phy, USB_EVENT_NONE); |
af6882be FB |
435 | break; |
436 | ||
437 | case USB_LINK_ACA_RID_C_NM_8500: | |
438 | case USB_LINK_ACA_RID_C_HS_8500: | |
439 | case USB_LINK_ACA_RID_C_HS_CHIRP_8500: | |
440 | event = UX500_MUSB_RIDC; | |
441 | case USB_LINK_STD_HOST_NC_8500: | |
442 | case USB_LINK_STD_HOST_C_NS_8500: | |
443 | case USB_LINK_STD_HOST_C_S_8500: | |
444 | case USB_LINK_HOST_CHG_NM_8500: | |
445 | case USB_LINK_HOST_CHG_HS_8500: | |
446 | case USB_LINK_HOST_CHG_HS_CHIRP_8500: | |
447 | if (ab->mode == USB_IDLE) { | |
448 | ab->mode = USB_PERIPHERAL; | |
449 | ab8500_usb_peri_phy_en(ab); | |
450 | atomic_notifier_call_chain(&ab->phy.notifier, | |
451 | UX500_MUSB_PREPARE, &ab->vbus_draw); | |
b20f3f9e | 452 | usb_phy_set_event(&ab->phy, USB_EVENT_ENUMERATED); |
af6882be FB |
453 | } |
454 | if (event != UX500_MUSB_RIDC) | |
455 | event = UX500_MUSB_VBUS; | |
456 | break; | |
457 | ||
458 | case USB_LINK_ACA_RID_A_8500: | |
459 | event = UX500_MUSB_RIDA; | |
460 | case USB_LINK_HM_IDGND_8500: | |
461 | if (ab->mode == USB_IDLE) { | |
462 | ab->mode = USB_HOST; | |
463 | ab8500_usb_host_phy_en(ab); | |
464 | atomic_notifier_call_chain(&ab->phy.notifier, | |
465 | UX500_MUSB_PREPARE, &ab->vbus_draw); | |
466 | } | |
467 | ab->phy.otg->default_a = true; | |
468 | if (event != UX500_MUSB_RIDA) | |
469 | event = UX500_MUSB_ID; | |
470 | atomic_notifier_call_chain(&ab->phy.notifier, | |
471 | event, &ab->vbus_draw); | |
472 | break; | |
473 | ||
474 | case USB_LINK_DEDICATED_CHG_8500: | |
475 | ab->mode = USB_DEDICATED_CHG; | |
476 | event = UX500_MUSB_CHARGER; | |
477 | atomic_notifier_call_chain(&ab->phy.notifier, | |
478 | event, &ab->vbus_draw); | |
b20f3f9e | 479 | usb_phy_set_event(&ab->phy, USB_EVENT_CHARGER); |
af6882be FB |
480 | break; |
481 | ||
482 | case USB_LINK_RESERVED_8500: | |
483 | break; | |
484 | } | |
96915234 MYK |
485 | |
486 | return 0; | |
487 | } | |
488 | ||
af6882be FB |
489 | /* |
490 | * Connection Sequence: | |
491 | * 1. Link Status Interrupt | |
492 | * 2. Enable AB clock | |
493 | * 3. Enable AB regulators | |
494 | * 4. Enable USB phy | |
495 | * 5. Reset the musb controller | |
496 | * 6. Switch the ULPI GPIO pins to fucntion mode | |
497 | * 7. Enable the musb Peripheral5 clock | |
498 | * 8. Restore MUSB context | |
499 | */ | |
500 | static int abx500_usb_link_status_update(struct ab8500_usb *ab) | |
96915234 | 501 | { |
af6882be FB |
502 | u8 reg; |
503 | int ret = 0; | |
504 | ||
505 | if (is_ab8500(ab->ab8500)) { | |
506 | enum ab8500_usb_link_status lsts; | |
507 | ||
b8d9ee24 | 508 | ret = abx500_get_register_interruptible(ab->dev, |
af6882be | 509 | AB8500_USB, AB8500_USB_LINE_STAT_REG, ®); |
b8d9ee24 DC |
510 | if (ret < 0) |
511 | return ret; | |
af6882be FB |
512 | lsts = (reg >> 3) & 0x0F; |
513 | ret = ab8500_usb_link_status_update(ab, lsts); | |
514 | } else if (is_ab8505(ab->ab8500)) { | |
515 | enum ab8505_usb_link_status lsts; | |
516 | ||
b8d9ee24 | 517 | ret = abx500_get_register_interruptible(ab->dev, |
af6882be | 518 | AB8500_USB, AB8505_USB_LINE_STAT_REG, ®); |
b8d9ee24 DC |
519 | if (ret < 0) |
520 | return ret; | |
af6882be FB |
521 | lsts = (reg >> 3) & 0x1F; |
522 | ret = ab8505_usb_link_status_update(ab, lsts); | |
523 | } | |
524 | ||
525 | return ret; | |
526 | } | |
527 | ||
528 | /* | |
529 | * Disconnection Sequence: | |
2b08977b | 530 | * 1. Disconnect Interrupt |
af6882be FB |
531 | * 2. Disable regulators |
532 | * 3. Disable AB clock | |
533 | * 4. Disable the Phy | |
534 | * 5. Link Status Interrupt | |
535 | * 6. Disable Musb Clock | |
536 | */ | |
537 | static irqreturn_t ab8500_usb_disconnect_irq(int irq, void *data) | |
538 | { | |
539 | struct ab8500_usb *ab = (struct ab8500_usb *) data; | |
6eb5ac2e | 540 | enum usb_phy_events event = USB_EVENT_NONE; |
af6882be FB |
541 | |
542 | /* Link status will not be updated till phy is disabled. */ | |
543 | if (ab->mode == USB_HOST) { | |
544 | ab->phy.otg->default_a = false; | |
545 | ab->vbus_draw = 0; | |
546 | atomic_notifier_call_chain(&ab->phy.notifier, | |
547 | event, &ab->vbus_draw); | |
548 | ab8500_usb_host_phy_dis(ab); | |
549 | ab->mode = USB_IDLE; | |
550 | } | |
551 | ||
552 | if (ab->mode == USB_PERIPHERAL) { | |
553 | atomic_notifier_call_chain(&ab->phy.notifier, | |
554 | event, &ab->vbus_draw); | |
555 | ab8500_usb_peri_phy_dis(ab); | |
556 | atomic_notifier_call_chain(&ab->phy.notifier, | |
557 | UX500_MUSB_CLEAN, &ab->vbus_draw); | |
558 | ab->mode = USB_IDLE; | |
559 | ab->phy.otg->default_a = false; | |
560 | ab->vbus_draw = 0; | |
561 | } | |
562 | ||
563 | if (is_ab8500_2p0(ab->ab8500)) { | |
564 | if (ab->mode == USB_DEDICATED_CHG) { | |
565 | ab8500_usb_wd_linkstatus(ab, | |
566 | AB8500_BIT_PHY_CTRL_DEVICE_EN); | |
567 | abx500_mask_and_set_register_interruptible(ab->dev, | |
568 | AB8500_USB, AB8500_USB_PHY_CTRL_REG, | |
569 | AB8500_BIT_PHY_CTRL_DEVICE_EN, 0); | |
570 | } | |
571 | } | |
96915234 | 572 | |
af6882be | 573 | return IRQ_HANDLED; |
96915234 MYK |
574 | } |
575 | ||
af6882be | 576 | static irqreturn_t ab8500_usb_link_status_irq(int irq, void *data) |
96915234 | 577 | { |
3147dad6 | 578 | struct ab8500_usb *ab = (struct ab8500_usb *)data; |
96915234 | 579 | |
af6882be | 580 | abx500_usb_link_status_update(ab); |
96915234 MYK |
581 | |
582 | return IRQ_HANDLED; | |
583 | } | |
584 | ||
585 | static void ab8500_usb_phy_disable_work(struct work_struct *work) | |
586 | { | |
587 | struct ab8500_usb *ab = container_of(work, struct ab8500_usb, | |
588 | phy_dis_work); | |
589 | ||
144713f3 | 590 | if (!ab->phy.otg->host) |
96915234 MYK |
591 | ab8500_usb_host_phy_dis(ab); |
592 | ||
144713f3 | 593 | if (!ab->phy.otg->gadget) |
96915234 MYK |
594 | ab8500_usb_peri_phy_dis(ab); |
595 | } | |
596 | ||
86753811 | 597 | static int ab8500_usb_set_suspend(struct usb_phy *x, int suspend) |
96915234 MYK |
598 | { |
599 | /* TODO */ | |
600 | return 0; | |
601 | } | |
602 | ||
144713f3 HK |
603 | static int ab8500_usb_set_peripheral(struct usb_otg *otg, |
604 | struct usb_gadget *gadget) | |
96915234 MYK |
605 | { |
606 | struct ab8500_usb *ab; | |
607 | ||
608 | if (!otg) | |
609 | return -ENODEV; | |
610 | ||
19c1eac2 | 611 | ab = phy_to_ab(otg->usb_phy); |
96915234 | 612 | |
58823373 SB |
613 | ab->phy.otg->gadget = gadget; |
614 | ||
96915234 MYK |
615 | /* Some drivers call this function in atomic context. |
616 | * Do not update ab8500 registers directly till this | |
617 | * is fixed. | |
618 | */ | |
619 | ||
3147dad6 | 620 | if ((ab->mode != USB_IDLE) && !gadget) { |
58823373 | 621 | ab->mode = USB_IDLE; |
96915234 | 622 | schedule_work(&ab->phy_dis_work); |
96915234 MYK |
623 | } |
624 | ||
625 | return 0; | |
626 | } | |
627 | ||
144713f3 | 628 | static int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host) |
96915234 MYK |
629 | { |
630 | struct ab8500_usb *ab; | |
631 | ||
632 | if (!otg) | |
633 | return -ENODEV; | |
634 | ||
19c1eac2 | 635 | ab = phy_to_ab(otg->usb_phy); |
96915234 | 636 | |
58823373 SB |
637 | ab->phy.otg->host = host; |
638 | ||
96915234 MYK |
639 | /* Some drivers call this function in atomic context. |
640 | * Do not update ab8500 registers directly till this | |
641 | * is fixed. | |
642 | */ | |
643 | ||
3147dad6 | 644 | if ((ab->mode != USB_IDLE) && !host) { |
58823373 | 645 | ab->mode = USB_IDLE; |
96915234 | 646 | schedule_work(&ab->phy_dis_work); |
96915234 MYK |
647 | } |
648 | ||
649 | return 0; | |
650 | } | |
651 | ||
fb21f37a SB |
652 | static void ab8500_usb_restart_phy(struct ab8500_usb *ab) |
653 | { | |
654 | abx500_mask_and_set_register_interruptible(ab->dev, | |
655 | AB8500_USB, AB8500_USB_PHY_CTRL_REG, | |
656 | AB8500_BIT_PHY_CTRL_DEVICE_EN, | |
657 | AB8500_BIT_PHY_CTRL_DEVICE_EN); | |
658 | ||
659 | udelay(100); | |
660 | ||
661 | abx500_mask_and_set_register_interruptible(ab->dev, | |
662 | AB8500_USB, AB8500_USB_PHY_CTRL_REG, | |
663 | AB8500_BIT_PHY_CTRL_DEVICE_EN, | |
664 | 0); | |
665 | ||
666 | abx500_mask_and_set_register_interruptible(ab->dev, | |
667 | AB8500_USB, AB8500_USB_PHY_CTRL_REG, | |
668 | AB8500_BIT_PHY_CTRL_HOST_EN, | |
669 | AB8500_BIT_PHY_CTRL_HOST_EN); | |
670 | ||
671 | udelay(100); | |
672 | ||
673 | abx500_mask_and_set_register_interruptible(ab->dev, | |
674 | AB8500_USB, AB8500_USB_PHY_CTRL_REG, | |
675 | AB8500_BIT_PHY_CTRL_HOST_EN, | |
676 | 0); | |
677 | } | |
678 | ||
e65b36c0 FB |
679 | static int ab8500_usb_regulator_get(struct ab8500_usb *ab) |
680 | { | |
681 | int err; | |
682 | ||
683 | ab->v_ape = devm_regulator_get(ab->dev, "v-ape"); | |
684 | if (IS_ERR(ab->v_ape)) { | |
685 | dev_err(ab->dev, "Could not get v-ape supply\n"); | |
686 | err = PTR_ERR(ab->v_ape); | |
687 | return err; | |
688 | } | |
689 | ||
690 | ab->v_ulpi = devm_regulator_get(ab->dev, "vddulpivio18"); | |
691 | if (IS_ERR(ab->v_ulpi)) { | |
692 | dev_err(ab->dev, "Could not get vddulpivio18 supply\n"); | |
693 | err = PTR_ERR(ab->v_ulpi); | |
694 | return err; | |
695 | } | |
696 | ||
697 | ab->v_musb = devm_regulator_get(ab->dev, "musb_1v8"); | |
698 | if (IS_ERR(ab->v_musb)) { | |
699 | dev_err(ab->dev, "Could not get musb_1v8 supply\n"); | |
700 | err = PTR_ERR(ab->v_musb); | |
701 | return err; | |
702 | } | |
703 | ||
704 | return 0; | |
705 | } | |
706 | ||
af6882be FB |
707 | static int ab8500_usb_irq_setup(struct platform_device *pdev, |
708 | struct ab8500_usb *ab) | |
96915234 MYK |
709 | { |
710 | int err; | |
af6882be | 711 | int irq; |
96915234 | 712 | |
bd4c9f02 FB |
713 | if (ab->flags & AB8500_USB_FLAG_USE_LINK_STATUS_IRQ) { |
714 | irq = platform_get_irq_byname(pdev, "USB_LINK_STATUS"); | |
715 | if (irq < 0) { | |
716 | dev_err(&pdev->dev, "Link status irq not found\n"); | |
717 | return irq; | |
718 | } | |
719 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, | |
720 | ab8500_usb_link_status_irq, | |
2b129789 | 721 | IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT, |
bd4c9f02 FB |
722 | "usb-link-status", ab); |
723 | if (err < 0) { | |
724 | dev_err(ab->dev, "request_irq failed for link status irq\n"); | |
725 | return err; | |
726 | } | |
96915234 MYK |
727 | } |
728 | ||
bd4c9f02 FB |
729 | if (ab->flags & AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ) { |
730 | irq = platform_get_irq_byname(pdev, "ID_WAKEUP_F"); | |
731 | if (irq < 0) { | |
732 | dev_err(&pdev->dev, "ID fall irq not found\n"); | |
733 | return irq; | |
734 | } | |
735 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, | |
736 | ab8500_usb_disconnect_irq, | |
2b129789 | 737 | IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT, |
bd4c9f02 FB |
738 | "usb-id-fall", ab); |
739 | if (err < 0) { | |
740 | dev_err(ab->dev, "request_irq failed for ID fall irq\n"); | |
741 | return err; | |
742 | } | |
af6882be FB |
743 | } |
744 | ||
bd4c9f02 FB |
745 | if (ab->flags & AB8500_USB_FLAG_USE_VBUS_DET_IRQ) { |
746 | irq = platform_get_irq_byname(pdev, "VBUS_DET_F"); | |
747 | if (irq < 0) { | |
748 | dev_err(&pdev->dev, "VBUS fall irq not found\n"); | |
749 | return irq; | |
750 | } | |
751 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, | |
752 | ab8500_usb_disconnect_irq, | |
2b129789 | 753 | IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT, |
bd4c9f02 FB |
754 | "usb-vbus-fall", ab); |
755 | if (err < 0) { | |
756 | dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); | |
757 | return err; | |
758 | } | |
96915234 MYK |
759 | } |
760 | ||
761 | return 0; | |
762 | } | |
763 | ||
16604a3c FB |
764 | static void ab8500_usb_set_ab8500_tuning_values(struct ab8500_usb *ab) |
765 | { | |
766 | int err; | |
767 | ||
768 | /* Enable the PBT/Bank 0x12 access */ | |
769 | err = abx500_set_register_interruptible(ab->dev, | |
770 | AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 0x01); | |
771 | if (err < 0) | |
772 | dev_err(ab->dev, "Failed to enable bank12 access err=%d\n", | |
773 | err); | |
774 | ||
775 | err = abx500_set_register_interruptible(ab->dev, | |
776 | AB8500_DEBUG, AB8500_USB_PHY_TUNE1, 0xC8); | |
777 | if (err < 0) | |
778 | dev_err(ab->dev, "Failed to set PHY_TUNE1 register err=%d\n", | |
779 | err); | |
780 | ||
781 | err = abx500_set_register_interruptible(ab->dev, | |
782 | AB8500_DEBUG, AB8500_USB_PHY_TUNE2, 0x00); | |
783 | if (err < 0) | |
784 | dev_err(ab->dev, "Failed to set PHY_TUNE2 register err=%d\n", | |
785 | err); | |
786 | ||
787 | err = abx500_set_register_interruptible(ab->dev, | |
788 | AB8500_DEBUG, AB8500_USB_PHY_TUNE3, 0x78); | |
789 | if (err < 0) | |
7eee236c | 790 | dev_err(ab->dev, "Failed to set PHY_TUNE3 register err=%d\n", |
16604a3c FB |
791 | err); |
792 | ||
793 | /* Switch to normal mode/disable Bank 0x12 access */ | |
794 | err = abx500_set_register_interruptible(ab->dev, | |
795 | AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 0x00); | |
796 | if (err < 0) | |
797 | dev_err(ab->dev, "Failed to switch bank12 access err=%d\n", | |
798 | err); | |
799 | } | |
800 | ||
801 | static void ab8500_usb_set_ab8505_tuning_values(struct ab8500_usb *ab) | |
802 | { | |
803 | int err; | |
804 | ||
805 | /* Enable the PBT/Bank 0x12 access */ | |
806 | err = abx500_mask_and_set_register_interruptible(ab->dev, | |
807 | AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, | |
808 | 0x01, 0x01); | |
809 | if (err < 0) | |
810 | dev_err(ab->dev, "Failed to enable bank12 access err=%d\n", | |
811 | err); | |
812 | ||
813 | err = abx500_mask_and_set_register_interruptible(ab->dev, | |
814 | AB8500_DEBUG, AB8500_USB_PHY_TUNE1, | |
815 | 0xC8, 0xC8); | |
816 | if (err < 0) | |
817 | dev_err(ab->dev, "Failed to set PHY_TUNE1 register err=%d\n", | |
818 | err); | |
819 | ||
820 | err = abx500_mask_and_set_register_interruptible(ab->dev, | |
821 | AB8500_DEBUG, AB8500_USB_PHY_TUNE2, | |
822 | 0x60, 0x60); | |
823 | if (err < 0) | |
824 | dev_err(ab->dev, "Failed to set PHY_TUNE2 register err=%d\n", | |
825 | err); | |
826 | ||
827 | err = abx500_mask_and_set_register_interruptible(ab->dev, | |
828 | AB8500_DEBUG, AB8500_USB_PHY_TUNE3, | |
829 | 0xFC, 0x80); | |
830 | ||
831 | if (err < 0) | |
7eee236c | 832 | dev_err(ab->dev, "Failed to set PHY_TUNE3 register err=%d\n", |
16604a3c FB |
833 | err); |
834 | ||
835 | /* Switch to normal mode/disable Bank 0x12 access */ | |
836 | err = abx500_mask_and_set_register_interruptible(ab->dev, | |
837 | AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, | |
838 | 0x00, 0x00); | |
839 | if (err < 0) | |
840 | dev_err(ab->dev, "Failed to switch bank12 access err=%d\n", | |
841 | err); | |
842 | } | |
843 | ||
41ac7b3a | 844 | static int ab8500_usb_probe(struct platform_device *pdev) |
96915234 MYK |
845 | { |
846 | struct ab8500_usb *ab; | |
73f226cb | 847 | struct ab8500 *ab8500; |
144713f3 | 848 | struct usb_otg *otg; |
96915234 MYK |
849 | int err; |
850 | int rev; | |
851 | ||
73f226cb | 852 | ab8500 = dev_get_drvdata(pdev->dev.parent); |
96915234 | 853 | rev = abx500_get_chip_id(&pdev->dev); |
73f226cb FB |
854 | |
855 | if (is_ab8500_1p1_or_earlier(ab8500)) { | |
856 | dev_err(&pdev->dev, "Unsupported AB8500 chip rev=%d\n", rev); | |
96915234 MYK |
857 | return -ENODEV; |
858 | } | |
859 | ||
81ef6724 | 860 | ab = devm_kzalloc(&pdev->dev, sizeof(*ab), GFP_KERNEL); |
96915234 MYK |
861 | if (!ab) |
862 | return -ENOMEM; | |
863 | ||
81ef6724 FB |
864 | otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); |
865 | if (!otg) | |
144713f3 | 866 | return -ENOMEM; |
144713f3 | 867 | |
96915234 | 868 | ab->dev = &pdev->dev; |
73f226cb | 869 | ab->ab8500 = ab8500; |
144713f3 HK |
870 | ab->phy.dev = ab->dev; |
871 | ab->phy.otg = otg; | |
872 | ab->phy.label = "ab8500"; | |
873 | ab->phy.set_suspend = ab8500_usb_set_suspend; | |
e47d9254 | 874 | ab->phy.otg->state = OTG_STATE_UNDEFINED; |
144713f3 | 875 | |
19c1eac2 | 876 | otg->usb_phy = &ab->phy; |
144713f3 HK |
877 | otg->set_host = ab8500_usb_set_host; |
878 | otg->set_peripheral = ab8500_usb_set_peripheral; | |
96915234 | 879 | |
bd4c9f02 FB |
880 | if (is_ab8500(ab->ab8500)) { |
881 | ab->flags |= AB8500_USB_FLAG_USE_LINK_STATUS_IRQ | | |
882 | AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ | | |
883 | AB8500_USB_FLAG_USE_VBUS_DET_IRQ | | |
884 | AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE; | |
885 | } else if (is_ab8505(ab->ab8500)) { | |
886 | ab->flags |= AB8500_USB_FLAG_USE_LINK_STATUS_IRQ | | |
887 | AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ | | |
888 | AB8500_USB_FLAG_USE_VBUS_DET_IRQ | | |
889 | AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE; | |
890 | } | |
891 | ||
892 | /* Disable regulator voltage setting for AB8500 <= v2.0 */ | |
893 | if (is_ab8500_2p0_or_earlier(ab->ab8500)) | |
894 | ab->flags &= ~AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE; | |
895 | ||
96915234 MYK |
896 | platform_set_drvdata(pdev, ab); |
897 | ||
96915234 MYK |
898 | /* all: Disable phy when called from set_host and set_peripheral */ |
899 | INIT_WORK(&ab->phy_dis_work, ab8500_usb_phy_disable_work); | |
900 | ||
e65b36c0 FB |
901 | err = ab8500_usb_regulator_get(ab); |
902 | if (err) | |
903 | return err; | |
904 | ||
d0ed0645 MYK |
905 | ab->sysclk = devm_clk_get(ab->dev, "sysclk"); |
906 | if (IS_ERR(ab->sysclk)) { | |
907 | dev_err(ab->dev, "Could not get sysclk.\n"); | |
908 | return PTR_ERR(ab->sysclk); | |
909 | } | |
910 | ||
af6882be | 911 | err = ab8500_usb_irq_setup(pdev, ab); |
96915234 | 912 | if (err < 0) |
81ef6724 | 913 | return err; |
96915234 | 914 | |
662dca54 | 915 | err = usb_add_phy(&ab->phy, USB_PHY_TYPE_USB2); |
96915234 MYK |
916 | if (err) { |
917 | dev_err(&pdev->dev, "Can't register transceiver\n"); | |
81ef6724 | 918 | return err; |
96915234 MYK |
919 | } |
920 | ||
16604a3c FB |
921 | if (is_ab8500(ab->ab8500) && !is_ab8500_2p0_or_earlier(ab->ab8500)) |
922 | /* Phy tuning values for AB8500 > v2.0 */ | |
923 | ab8500_usb_set_ab8500_tuning_values(ab); | |
924 | else if (is_ab8505(ab->ab8500)) | |
925 | /* Phy tuning values for AB8505 */ | |
926 | ab8500_usb_set_ab8505_tuning_values(ab); | |
7124631a | 927 | |
af6882be FB |
928 | /* Needed to enable ID detection. */ |
929 | ab8500_usb_wd_workaround(ab); | |
930 | ||
fb21f37a SB |
931 | /* |
932 | * This is required for usb-link-status to work properly when a | |
933 | * cable is connected at boot time. | |
934 | */ | |
935 | ab8500_usb_restart_phy(ab); | |
936 | ||
8db12231 SB |
937 | abx500_usb_link_status_update(ab); |
938 | ||
73f226cb | 939 | dev_info(&pdev->dev, "revision 0x%2x driver initialized\n", rev); |
96915234 MYK |
940 | |
941 | return 0; | |
96915234 MYK |
942 | } |
943 | ||
fb4e98ab | 944 | static int ab8500_usb_remove(struct platform_device *pdev) |
96915234 MYK |
945 | { |
946 | struct ab8500_usb *ab = platform_get_drvdata(pdev); | |
947 | ||
96915234 MYK |
948 | cancel_work_sync(&ab->phy_dis_work); |
949 | ||
662dca54 | 950 | usb_remove_phy(&ab->phy); |
96915234 | 951 | |
f5ef7b42 MYK |
952 | if (ab->mode == USB_HOST) |
953 | ab8500_usb_host_phy_dis(ab); | |
954 | else if (ab->mode == USB_PERIPHERAL) | |
955 | ab8500_usb_peri_phy_dis(ab); | |
96915234 | 956 | |
96915234 MYK |
957 | return 0; |
958 | } | |
959 | ||
1cb39e25 | 960 | static const struct platform_device_id ab8500_usb_devtype[] = { |
b3affc39 FB |
961 | { .name = "ab8500-usb", }, |
962 | { /* sentinel */ } | |
963 | }; | |
964 | MODULE_DEVICE_TABLE(platform, ab8500_usb_devtype); | |
965 | ||
96915234 MYK |
966 | static struct platform_driver ab8500_usb_driver = { |
967 | .probe = ab8500_usb_probe, | |
7690417d | 968 | .remove = ab8500_usb_remove, |
b3affc39 | 969 | .id_table = ab8500_usb_devtype, |
96915234 | 970 | .driver = { |
b3affc39 | 971 | .name = "abx5x0-usb", |
96915234 MYK |
972 | }, |
973 | }; | |
974 | ||
975 | static int __init ab8500_usb_init(void) | |
976 | { | |
977 | return platform_driver_register(&ab8500_usb_driver); | |
978 | } | |
979 | subsys_initcall(ab8500_usb_init); | |
980 | ||
981 | static void __exit ab8500_usb_exit(void) | |
982 | { | |
983 | platform_driver_unregister(&ab8500_usb_driver); | |
984 | } | |
985 | module_exit(ab8500_usb_exit); | |
986 | ||
96915234 | 987 | MODULE_AUTHOR("ST-Ericsson AB"); |
0c380c0e | 988 | MODULE_DESCRIPTION("AB8500 family usb transceiver driver"); |
96915234 | 989 | MODULE_LICENSE("GPL"); |