blob: 7792fef0be5e764f868f80cb0fdeb277f9cb6ac6 [file] [log] [blame]
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +05301/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 *
17 */
18
19#include <linux/module.h>
20#include <linux/device.h>
21#include <linux/platform_device.h>
22#include <linux/clk.h>
23#include <linux/slab.h>
24#include <linux/interrupt.h>
25#include <linux/err.h>
26#include <linux/delay.h>
27#include <linux/io.h>
28#include <linux/ioport.h>
29#include <linux/uaccess.h>
30#include <linux/debugfs.h>
31#include <linux/seq_file.h>
Pavankumar Kondeti87c01042010-12-07 17:53:58 +053032#include <linux/pm_runtime.h>
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +053033
34#include <linux/usb.h>
35#include <linux/usb/otg.h>
36#include <linux/usb/ulpi.h>
37#include <linux/usb/gadget.h>
38#include <linux/usb/hcd.h>
39#include <linux/usb/msm_hsusb.h>
40#include <linux/usb/msm_hsusb_hw.h>
41
42#include <mach/clk.h>
43
44#define MSM_USB_BASE (motg->regs)
45#define DRIVER_NAME "msm_otg"
46
47#define ULPI_IO_TIMEOUT_USEC (10 * 1000)
48static int ulpi_read(struct otg_transceiver *otg, u32 reg)
49{
50 struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
51 int cnt = 0;
52
53 /* initiate read operation */
54 writel(ULPI_RUN | ULPI_READ | ULPI_ADDR(reg),
55 USB_ULPI_VIEWPORT);
56
57 /* wait for completion */
58 while (cnt < ULPI_IO_TIMEOUT_USEC) {
59 if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN))
60 break;
61 udelay(1);
62 cnt++;
63 }
64
65 if (cnt >= ULPI_IO_TIMEOUT_USEC) {
66 dev_err(otg->dev, "ulpi_read: timeout %08x\n",
67 readl(USB_ULPI_VIEWPORT));
68 return -ETIMEDOUT;
69 }
70 return ULPI_DATA_READ(readl(USB_ULPI_VIEWPORT));
71}
72
73static int ulpi_write(struct otg_transceiver *otg, u32 val, u32 reg)
74{
75 struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
76 int cnt = 0;
77
78 /* initiate write operation */
79 writel(ULPI_RUN | ULPI_WRITE |
80 ULPI_ADDR(reg) | ULPI_DATA(val),
81 USB_ULPI_VIEWPORT);
82
83 /* wait for completion */
84 while (cnt < ULPI_IO_TIMEOUT_USEC) {
85 if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN))
86 break;
87 udelay(1);
88 cnt++;
89 }
90
91 if (cnt >= ULPI_IO_TIMEOUT_USEC) {
92 dev_err(otg->dev, "ulpi_write: timeout\n");
93 return -ETIMEDOUT;
94 }
95 return 0;
96}
97
98static struct otg_io_access_ops msm_otg_io_ops = {
99 .read = ulpi_read,
100 .write = ulpi_write,
101};
102
103static void ulpi_init(struct msm_otg *motg)
104{
105 struct msm_otg_platform_data *pdata = motg->pdata;
106 int *seq = pdata->phy_init_seq;
107
108 if (!seq)
109 return;
110
111 while (seq[0] >= 0) {
112 dev_vdbg(motg->otg.dev, "ulpi: write 0x%02x to 0x%02x\n",
113 seq[0], seq[1]);
114 ulpi_write(&motg->otg, seq[0], seq[1]);
115 seq += 2;
116 }
117}
118
119static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert)
120{
121 int ret;
122
123 if (assert) {
124 ret = clk_reset(motg->clk, CLK_RESET_ASSERT);
125 if (ret)
126 dev_err(motg->otg.dev, "usb hs_clk assert failed\n");
127 } else {
128 ret = clk_reset(motg->clk, CLK_RESET_DEASSERT);
129 if (ret)
130 dev_err(motg->otg.dev, "usb hs_clk deassert failed\n");
131 }
132 return ret;
133}
134
135static int msm_otg_phy_clk_reset(struct msm_otg *motg)
136{
137 int ret;
138
139 ret = clk_reset(motg->phy_reset_clk, CLK_RESET_ASSERT);
140 if (ret) {
141 dev_err(motg->otg.dev, "usb phy clk assert failed\n");
142 return ret;
143 }
144 usleep_range(10000, 12000);
145 ret = clk_reset(motg->phy_reset_clk, CLK_RESET_DEASSERT);
146 if (ret)
147 dev_err(motg->otg.dev, "usb phy clk deassert failed\n");
148 return ret;
149}
150
151static int msm_otg_phy_reset(struct msm_otg *motg)
152{
153 u32 val;
154 int ret;
155 int retries;
156
157 ret = msm_otg_link_clk_reset(motg, 1);
158 if (ret)
159 return ret;
160 ret = msm_otg_phy_clk_reset(motg);
161 if (ret)
162 return ret;
163 ret = msm_otg_link_clk_reset(motg, 0);
164 if (ret)
165 return ret;
166
167 val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK;
168 writel(val | PORTSC_PTS_ULPI, USB_PORTSC);
169
170 for (retries = 3; retries > 0; retries--) {
171 ret = ulpi_write(&motg->otg, ULPI_FUNC_CTRL_SUSPENDM,
172 ULPI_CLR(ULPI_FUNC_CTRL));
173 if (!ret)
174 break;
175 ret = msm_otg_phy_clk_reset(motg);
176 if (ret)
177 return ret;
178 }
179 if (!retries)
180 return -ETIMEDOUT;
181
182 /* This reset calibrates the phy, if the above write succeeded */
183 ret = msm_otg_phy_clk_reset(motg);
184 if (ret)
185 return ret;
186
187 for (retries = 3; retries > 0; retries--) {
188 ret = ulpi_read(&motg->otg, ULPI_DEBUG);
189 if (ret != -ETIMEDOUT)
190 break;
191 ret = msm_otg_phy_clk_reset(motg);
192 if (ret)
193 return ret;
194 }
195 if (!retries)
196 return -ETIMEDOUT;
197
198 dev_info(motg->otg.dev, "phy_reset: success\n");
199 return 0;
200}
201
202#define LINK_RESET_TIMEOUT_USEC (250 * 1000)
203static int msm_otg_reset(struct otg_transceiver *otg)
204{
205 struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
206 struct msm_otg_platform_data *pdata = motg->pdata;
207 int cnt = 0;
208 int ret;
209 u32 val = 0;
210 u32 ulpi_val = 0;
211
212 ret = msm_otg_phy_reset(motg);
213 if (ret) {
214 dev_err(otg->dev, "phy_reset failed\n");
215 return ret;
216 }
217
218 ulpi_init(motg);
219
220 writel(USBCMD_RESET, USB_USBCMD);
221 while (cnt < LINK_RESET_TIMEOUT_USEC) {
222 if (!(readl(USB_USBCMD) & USBCMD_RESET))
223 break;
224 udelay(1);
225 cnt++;
226 }
227 if (cnt >= LINK_RESET_TIMEOUT_USEC)
228 return -ETIMEDOUT;
229
230 /* select ULPI phy */
231 writel(0x80000000, USB_PORTSC);
232
233 msleep(100);
234
235 writel(0x0, USB_AHBBURST);
236 writel(0x00, USB_AHBMODE);
237
238 if (pdata->otg_control == OTG_PHY_CONTROL) {
239 val = readl(USB_OTGSC);
240 if (pdata->mode == USB_OTG) {
241 ulpi_val = ULPI_INT_IDGRD | ULPI_INT_SESS_VALID;
242 val |= OTGSC_IDIE | OTGSC_BSVIE;
243 } else if (pdata->mode == USB_PERIPHERAL) {
244 ulpi_val = ULPI_INT_SESS_VALID;
245 val |= OTGSC_BSVIE;
246 }
247 writel(val, USB_OTGSC);
248 ulpi_write(otg, ulpi_val, ULPI_USB_INT_EN_RISE);
249 ulpi_write(otg, ulpi_val, ULPI_USB_INT_EN_FALL);
250 }
251
252 return 0;
253}
254
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530255#define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000)
Pavankumar Kondeti70187732011-02-15 09:42:34 +0530256#define PHY_RESUME_TIMEOUT_USEC (100 * 1000)
257
258#ifdef CONFIG_PM_SLEEP
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530259static int msm_otg_suspend(struct msm_otg *motg)
260{
261 struct otg_transceiver *otg = &motg->otg;
262 struct usb_bus *bus = otg->host;
263 struct msm_otg_platform_data *pdata = motg->pdata;
264 int cnt = 0;
265
266 if (atomic_read(&motg->in_lpm))
267 return 0;
268
269 disable_irq(motg->irq);
270 /*
271 * Interrupt Latch Register auto-clear feature is not present
272 * in all PHY versions. Latch register is clear on read type.
273 * Clear latch register to avoid spurious wakeup from
274 * low power mode (LPM).
275 */
276 ulpi_read(otg, 0x14);
277
278 /*
279 * PHY comparators are disabled when PHY enters into low power
280 * mode (LPM). Keep PHY comparators ON in LPM only when we expect
281 * VBUS/Id notifications from USB PHY. Otherwise turn off USB
282 * PHY comparators. This save significant amount of power.
283 */
284 if (pdata->otg_control == OTG_PHY_CONTROL)
285 ulpi_write(otg, 0x01, 0x30);
286
287 /*
288 * PLL is not turned off when PHY enters into low power mode (LPM).
289 * Disable PLL for maximum power savings.
290 */
291 ulpi_write(otg, 0x08, 0x09);
292
293 /*
294 * PHY may take some time or even fail to enter into low power
295 * mode (LPM). Hence poll for 500 msec and reset the PHY and link
296 * in failure case.
297 */
298 writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC);
299 while (cnt < PHY_SUSPEND_TIMEOUT_USEC) {
300 if (readl(USB_PORTSC) & PORTSC_PHCD)
301 break;
302 udelay(1);
303 cnt++;
304 }
305
306 if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) {
307 dev_err(otg->dev, "Unable to suspend PHY\n");
308 msm_otg_reset(otg);
309 enable_irq(motg->irq);
310 return -ETIMEDOUT;
311 }
312
313 /*
314 * PHY has capability to generate interrupt asynchronously in low
315 * power mode (LPM). This interrupt is level triggered. So USB IRQ
316 * line must be disabled till async interrupt enable bit is cleared
317 * in USBCMD register. Assert STP (ULPI interface STOP signal) to
318 * block data communication from PHY.
319 */
320 writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD);
321
322 clk_disable(motg->pclk);
323 clk_disable(motg->clk);
324 if (motg->core_clk)
325 clk_disable(motg->core_clk);
326
Anji jonnala0f73cac2011-05-04 10:19:46 +0530327 if (!IS_ERR(motg->pclk_src))
328 clk_disable(motg->pclk_src);
329
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530330 if (device_may_wakeup(otg->dev))
331 enable_irq_wake(motg->irq);
332 if (bus)
333 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags);
334
335 atomic_set(&motg->in_lpm, 1);
336 enable_irq(motg->irq);
337
338 dev_info(otg->dev, "USB in low power mode\n");
339
340 return 0;
341}
342
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530343static int msm_otg_resume(struct msm_otg *motg)
344{
345 struct otg_transceiver *otg = &motg->otg;
346 struct usb_bus *bus = otg->host;
347 int cnt = 0;
348 unsigned temp;
349
350 if (!atomic_read(&motg->in_lpm))
351 return 0;
352
Anji jonnala0f73cac2011-05-04 10:19:46 +0530353 if (!IS_ERR(motg->pclk_src))
354 clk_enable(motg->pclk_src);
355
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530356 clk_enable(motg->pclk);
357 clk_enable(motg->clk);
358 if (motg->core_clk)
359 clk_enable(motg->core_clk);
360
361 temp = readl(USB_USBCMD);
362 temp &= ~ASYNC_INTR_CTRL;
363 temp &= ~ULPI_STP_CTRL;
364 writel(temp, USB_USBCMD);
365
366 /*
367 * PHY comes out of low power mode (LPM) in case of wakeup
368 * from asynchronous interrupt.
369 */
370 if (!(readl(USB_PORTSC) & PORTSC_PHCD))
371 goto skip_phy_resume;
372
373 writel(readl(USB_PORTSC) & ~PORTSC_PHCD, USB_PORTSC);
374 while (cnt < PHY_RESUME_TIMEOUT_USEC) {
375 if (!(readl(USB_PORTSC) & PORTSC_PHCD))
376 break;
377 udelay(1);
378 cnt++;
379 }
380
381 if (cnt >= PHY_RESUME_TIMEOUT_USEC) {
382 /*
383 * This is a fatal error. Reset the link and
384 * PHY. USB state can not be restored. Re-insertion
385 * of USB cable is the only way to get USB working.
386 */
387 dev_err(otg->dev, "Unable to resume USB."
388 "Re-plugin the cable\n");
389 msm_otg_reset(otg);
390 }
391
392skip_phy_resume:
393 if (device_may_wakeup(otg->dev))
394 disable_irq_wake(motg->irq);
395 if (bus)
396 set_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags);
397
Pavankumar Kondeti2ce2c3a2011-05-02 11:56:33 +0530398 atomic_set(&motg->in_lpm, 0);
399
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530400 if (motg->async_int) {
401 motg->async_int = 0;
402 pm_runtime_put(otg->dev);
403 enable_irq(motg->irq);
404 }
405
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530406 dev_info(otg->dev, "USB exited from low power mode\n");
407
408 return 0;
409}
Pavankumar Kondeti70187732011-02-15 09:42:34 +0530410#endif
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530411
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530412static void msm_otg_start_host(struct otg_transceiver *otg, int on)
413{
414 struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
415 struct msm_otg_platform_data *pdata = motg->pdata;
416 struct usb_hcd *hcd;
417
418 if (!otg->host)
419 return;
420
421 hcd = bus_to_hcd(otg->host);
422
423 if (on) {
424 dev_dbg(otg->dev, "host on\n");
425
426 if (pdata->vbus_power)
427 pdata->vbus_power(1);
428 /*
429 * Some boards have a switch cotrolled by gpio
430 * to enable/disable internal HUB. Enable internal
431 * HUB before kicking the host.
432 */
433 if (pdata->setup_gpio)
434 pdata->setup_gpio(OTG_STATE_A_HOST);
435#ifdef CONFIG_USB
436 usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
437#endif
438 } else {
439 dev_dbg(otg->dev, "host off\n");
440
441#ifdef CONFIG_USB
442 usb_remove_hcd(hcd);
443#endif
444 if (pdata->setup_gpio)
445 pdata->setup_gpio(OTG_STATE_UNDEFINED);
446 if (pdata->vbus_power)
447 pdata->vbus_power(0);
448 }
449}
450
451static int msm_otg_set_host(struct otg_transceiver *otg, struct usb_bus *host)
452{
453 struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
454 struct usb_hcd *hcd;
455
456 /*
457 * Fail host registration if this board can support
458 * only peripheral configuration.
459 */
460 if (motg->pdata->mode == USB_PERIPHERAL) {
461 dev_info(otg->dev, "Host mode is not supported\n");
462 return -ENODEV;
463 }
464
465 if (!host) {
466 if (otg->state == OTG_STATE_A_HOST) {
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530467 pm_runtime_get_sync(otg->dev);
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530468 msm_otg_start_host(otg, 0);
469 otg->host = NULL;
470 otg->state = OTG_STATE_UNDEFINED;
471 schedule_work(&motg->sm_work);
472 } else {
473 otg->host = NULL;
474 }
475
476 return 0;
477 }
478
479 hcd = bus_to_hcd(host);
480 hcd->power_budget = motg->pdata->power_budget;
481
482 otg->host = host;
483 dev_dbg(otg->dev, "host driver registered w/ tranceiver\n");
484
485 /*
486 * Kick the state machine work, if peripheral is not supported
487 * or peripheral is already registered with us.
488 */
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530489 if (motg->pdata->mode == USB_HOST || otg->gadget) {
490 pm_runtime_get_sync(otg->dev);
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530491 schedule_work(&motg->sm_work);
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530492 }
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530493
494 return 0;
495}
496
497static void msm_otg_start_peripheral(struct otg_transceiver *otg, int on)
498{
499 struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
500 struct msm_otg_platform_data *pdata = motg->pdata;
501
502 if (!otg->gadget)
503 return;
504
505 if (on) {
506 dev_dbg(otg->dev, "gadget on\n");
507 /*
508 * Some boards have a switch cotrolled by gpio
509 * to enable/disable internal HUB. Disable internal
510 * HUB before kicking the gadget.
511 */
512 if (pdata->setup_gpio)
513 pdata->setup_gpio(OTG_STATE_B_PERIPHERAL);
514 usb_gadget_vbus_connect(otg->gadget);
515 } else {
516 dev_dbg(otg->dev, "gadget off\n");
517 usb_gadget_vbus_disconnect(otg->gadget);
518 if (pdata->setup_gpio)
519 pdata->setup_gpio(OTG_STATE_UNDEFINED);
520 }
521
522}
523
524static int msm_otg_set_peripheral(struct otg_transceiver *otg,
525 struct usb_gadget *gadget)
526{
527 struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
528
529 /*
530 * Fail peripheral registration if this board can support
531 * only host configuration.
532 */
533 if (motg->pdata->mode == USB_HOST) {
534 dev_info(otg->dev, "Peripheral mode is not supported\n");
535 return -ENODEV;
536 }
537
538 if (!gadget) {
539 if (otg->state == OTG_STATE_B_PERIPHERAL) {
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530540 pm_runtime_get_sync(otg->dev);
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530541 msm_otg_start_peripheral(otg, 0);
542 otg->gadget = NULL;
543 otg->state = OTG_STATE_UNDEFINED;
544 schedule_work(&motg->sm_work);
545 } else {
546 otg->gadget = NULL;
547 }
548
549 return 0;
550 }
551 otg->gadget = gadget;
552 dev_dbg(otg->dev, "peripheral driver registered w/ tranceiver\n");
553
554 /*
555 * Kick the state machine work, if host is not supported
556 * or host is already registered with us.
557 */
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530558 if (motg->pdata->mode == USB_PERIPHERAL || otg->host) {
559 pm_runtime_get_sync(otg->dev);
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530560 schedule_work(&motg->sm_work);
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530561 }
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530562
563 return 0;
564}
565
566/*
567 * We support OTG, Peripheral only and Host only configurations. In case
568 * of OTG, mode switch (host-->peripheral/peripheral-->host) can happen
569 * via Id pin status or user request (debugfs). Id/BSV interrupts are not
570 * enabled when switch is controlled by user and default mode is supplied
571 * by board file, which can be changed by userspace later.
572 */
573static void msm_otg_init_sm(struct msm_otg *motg)
574{
575 struct msm_otg_platform_data *pdata = motg->pdata;
576 u32 otgsc = readl(USB_OTGSC);
577
578 switch (pdata->mode) {
579 case USB_OTG:
580 if (pdata->otg_control == OTG_PHY_CONTROL) {
581 if (otgsc & OTGSC_ID)
582 set_bit(ID, &motg->inputs);
583 else
584 clear_bit(ID, &motg->inputs);
585
586 if (otgsc & OTGSC_BSV)
587 set_bit(B_SESS_VLD, &motg->inputs);
588 else
589 clear_bit(B_SESS_VLD, &motg->inputs);
590 } else if (pdata->otg_control == OTG_USER_CONTROL) {
591 if (pdata->default_mode == USB_HOST) {
592 clear_bit(ID, &motg->inputs);
593 } else if (pdata->default_mode == USB_PERIPHERAL) {
594 set_bit(ID, &motg->inputs);
595 set_bit(B_SESS_VLD, &motg->inputs);
596 } else {
597 set_bit(ID, &motg->inputs);
598 clear_bit(B_SESS_VLD, &motg->inputs);
599 }
600 }
601 break;
602 case USB_HOST:
603 clear_bit(ID, &motg->inputs);
604 break;
605 case USB_PERIPHERAL:
606 set_bit(ID, &motg->inputs);
607 if (otgsc & OTGSC_BSV)
608 set_bit(B_SESS_VLD, &motg->inputs);
609 else
610 clear_bit(B_SESS_VLD, &motg->inputs);
611 break;
612 default:
613 break;
614 }
615}
616
617static void msm_otg_sm_work(struct work_struct *w)
618{
619 struct msm_otg *motg = container_of(w, struct msm_otg, sm_work);
620 struct otg_transceiver *otg = &motg->otg;
621
622 switch (otg->state) {
623 case OTG_STATE_UNDEFINED:
624 dev_dbg(otg->dev, "OTG_STATE_UNDEFINED state\n");
625 msm_otg_reset(otg);
626 msm_otg_init_sm(motg);
627 otg->state = OTG_STATE_B_IDLE;
628 /* FALL THROUGH */
629 case OTG_STATE_B_IDLE:
630 dev_dbg(otg->dev, "OTG_STATE_B_IDLE state\n");
631 if (!test_bit(ID, &motg->inputs) && otg->host) {
632 /* disable BSV bit */
633 writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC);
634 msm_otg_start_host(otg, 1);
635 otg->state = OTG_STATE_A_HOST;
636 } else if (test_bit(B_SESS_VLD, &motg->inputs) && otg->gadget) {
637 msm_otg_start_peripheral(otg, 1);
638 otg->state = OTG_STATE_B_PERIPHERAL;
639 }
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530640 pm_runtime_put_sync(otg->dev);
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530641 break;
642 case OTG_STATE_B_PERIPHERAL:
643 dev_dbg(otg->dev, "OTG_STATE_B_PERIPHERAL state\n");
644 if (!test_bit(B_SESS_VLD, &motg->inputs) ||
645 !test_bit(ID, &motg->inputs)) {
646 msm_otg_start_peripheral(otg, 0);
647 otg->state = OTG_STATE_B_IDLE;
648 msm_otg_reset(otg);
649 schedule_work(w);
650 }
651 break;
652 case OTG_STATE_A_HOST:
653 dev_dbg(otg->dev, "OTG_STATE_A_HOST state\n");
654 if (test_bit(ID, &motg->inputs)) {
655 msm_otg_start_host(otg, 0);
656 otg->state = OTG_STATE_B_IDLE;
657 msm_otg_reset(otg);
658 schedule_work(w);
659 }
660 break;
661 default:
662 break;
663 }
664}
665
666static irqreturn_t msm_otg_irq(int irq, void *data)
667{
668 struct msm_otg *motg = data;
669 struct otg_transceiver *otg = &motg->otg;
670 u32 otgsc = 0;
671
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530672 if (atomic_read(&motg->in_lpm)) {
673 disable_irq_nosync(irq);
674 motg->async_int = 1;
675 pm_runtime_get(otg->dev);
676 return IRQ_HANDLED;
677 }
678
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530679 otgsc = readl(USB_OTGSC);
680 if (!(otgsc & (OTGSC_IDIS | OTGSC_BSVIS)))
681 return IRQ_NONE;
682
683 if ((otgsc & OTGSC_IDIS) && (otgsc & OTGSC_IDIE)) {
684 if (otgsc & OTGSC_ID)
685 set_bit(ID, &motg->inputs);
686 else
687 clear_bit(ID, &motg->inputs);
688 dev_dbg(otg->dev, "ID set/clear\n");
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530689 pm_runtime_get_noresume(otg->dev);
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530690 } else if ((otgsc & OTGSC_BSVIS) && (otgsc & OTGSC_BSVIE)) {
691 if (otgsc & OTGSC_BSV)
692 set_bit(B_SESS_VLD, &motg->inputs);
693 else
694 clear_bit(B_SESS_VLD, &motg->inputs);
695 dev_dbg(otg->dev, "BSV set/clear\n");
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530696 pm_runtime_get_noresume(otg->dev);
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530697 }
698
699 writel(otgsc, USB_OTGSC);
700 schedule_work(&motg->sm_work);
701 return IRQ_HANDLED;
702}
703
704static int msm_otg_mode_show(struct seq_file *s, void *unused)
705{
706 struct msm_otg *motg = s->private;
707 struct otg_transceiver *otg = &motg->otg;
708
709 switch (otg->state) {
710 case OTG_STATE_A_HOST:
711 seq_printf(s, "host\n");
712 break;
713 case OTG_STATE_B_PERIPHERAL:
714 seq_printf(s, "peripheral\n");
715 break;
716 default:
717 seq_printf(s, "none\n");
718 break;
719 }
720
721 return 0;
722}
723
724static int msm_otg_mode_open(struct inode *inode, struct file *file)
725{
726 return single_open(file, msm_otg_mode_show, inode->i_private);
727}
728
729static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf,
730 size_t count, loff_t *ppos)
731{
Pavankumar Kondetie2904ee2011-02-15 09:42:35 +0530732 struct seq_file *s = file->private_data;
733 struct msm_otg *motg = s->private;
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530734 char buf[16];
735 struct otg_transceiver *otg = &motg->otg;
736 int status = count;
737 enum usb_mode_type req_mode;
738
739 memset(buf, 0x00, sizeof(buf));
740
741 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) {
742 status = -EFAULT;
743 goto out;
744 }
745
746 if (!strncmp(buf, "host", 4)) {
747 req_mode = USB_HOST;
748 } else if (!strncmp(buf, "peripheral", 10)) {
749 req_mode = USB_PERIPHERAL;
750 } else if (!strncmp(buf, "none", 4)) {
751 req_mode = USB_NONE;
752 } else {
753 status = -EINVAL;
754 goto out;
755 }
756
757 switch (req_mode) {
758 case USB_NONE:
759 switch (otg->state) {
760 case OTG_STATE_A_HOST:
761 case OTG_STATE_B_PERIPHERAL:
762 set_bit(ID, &motg->inputs);
763 clear_bit(B_SESS_VLD, &motg->inputs);
764 break;
765 default:
766 goto out;
767 }
768 break;
769 case USB_PERIPHERAL:
770 switch (otg->state) {
771 case OTG_STATE_B_IDLE:
772 case OTG_STATE_A_HOST:
773 set_bit(ID, &motg->inputs);
774 set_bit(B_SESS_VLD, &motg->inputs);
775 break;
776 default:
777 goto out;
778 }
779 break;
780 case USB_HOST:
781 switch (otg->state) {
782 case OTG_STATE_B_IDLE:
783 case OTG_STATE_B_PERIPHERAL:
784 clear_bit(ID, &motg->inputs);
785 break;
786 default:
787 goto out;
788 }
789 break;
790 default:
791 goto out;
792 }
793
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530794 pm_runtime_get_sync(otg->dev);
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530795 schedule_work(&motg->sm_work);
796out:
797 return status;
798}
799
800const struct file_operations msm_otg_mode_fops = {
801 .open = msm_otg_mode_open,
802 .read = seq_read,
803 .write = msm_otg_mode_write,
804 .llseek = seq_lseek,
805 .release = single_release,
806};
807
808static struct dentry *msm_otg_dbg_root;
809static struct dentry *msm_otg_dbg_mode;
810
811static int msm_otg_debugfs_init(struct msm_otg *motg)
812{
813 msm_otg_dbg_root = debugfs_create_dir("msm_otg", NULL);
814
815 if (!msm_otg_dbg_root || IS_ERR(msm_otg_dbg_root))
816 return -ENODEV;
817
818 msm_otg_dbg_mode = debugfs_create_file("mode", S_IRUGO | S_IWUSR,
819 msm_otg_dbg_root, motg, &msm_otg_mode_fops);
820 if (!msm_otg_dbg_mode) {
821 debugfs_remove(msm_otg_dbg_root);
822 msm_otg_dbg_root = NULL;
823 return -ENODEV;
824 }
825
826 return 0;
827}
828
829static void msm_otg_debugfs_cleanup(void)
830{
831 debugfs_remove(msm_otg_dbg_mode);
832 debugfs_remove(msm_otg_dbg_root);
833}
834
835static int __init msm_otg_probe(struct platform_device *pdev)
836{
837 int ret = 0;
838 struct resource *res;
839 struct msm_otg *motg;
840 struct otg_transceiver *otg;
841
842 dev_info(&pdev->dev, "msm_otg probe\n");
843 if (!pdev->dev.platform_data) {
844 dev_err(&pdev->dev, "No platform data given. Bailing out\n");
845 return -ENODEV;
846 }
847
848 motg = kzalloc(sizeof(struct msm_otg), GFP_KERNEL);
849 if (!motg) {
850 dev_err(&pdev->dev, "unable to allocate msm_otg\n");
851 return -ENOMEM;
852 }
853
854 motg->pdata = pdev->dev.platform_data;
855 otg = &motg->otg;
856 otg->dev = &pdev->dev;
857
858 motg->phy_reset_clk = clk_get(&pdev->dev, "usb_phy_clk");
859 if (IS_ERR(motg->phy_reset_clk)) {
860 dev_err(&pdev->dev, "failed to get usb_phy_clk\n");
861 ret = PTR_ERR(motg->phy_reset_clk);
862 goto free_motg;
863 }
864
865 motg->clk = clk_get(&pdev->dev, "usb_hs_clk");
866 if (IS_ERR(motg->clk)) {
867 dev_err(&pdev->dev, "failed to get usb_hs_clk\n");
868 ret = PTR_ERR(motg->clk);
869 goto put_phy_reset_clk;
870 }
Anji jonnala0f73cac2011-05-04 10:19:46 +0530871 clk_set_rate(motg->clk, 60000000);
872
873 /*
874 * If USB Core is running its protocol engine based on CORE CLK,
875 * CORE CLK must be running at >55Mhz for correct HSUSB
876 * operation and USB core cannot tolerate frequency changes on
877 * CORE CLK. For such USB cores, vote for maximum clk frequency
878 * on pclk source
879 */
880 if (motg->pdata->pclk_src_name) {
881 motg->pclk_src = clk_get(&pdev->dev,
882 motg->pdata->pclk_src_name);
883 if (IS_ERR(motg->pclk_src))
884 goto put_clk;
885 clk_set_rate(motg->pclk_src, INT_MAX);
886 clk_enable(motg->pclk_src);
887 } else
888 motg->pclk_src = ERR_PTR(-ENOENT);
889
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530890
891 motg->pclk = clk_get(&pdev->dev, "usb_hs_pclk");
892 if (IS_ERR(motg->pclk)) {
893 dev_err(&pdev->dev, "failed to get usb_hs_pclk\n");
894 ret = PTR_ERR(motg->pclk);
Anji jonnala0f73cac2011-05-04 10:19:46 +0530895 goto put_pclk_src;
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530896 }
897
898 /*
899 * USB core clock is not present on all MSM chips. This
900 * clock is introduced to remove the dependency on AXI
901 * bus frequency.
902 */
903 motg->core_clk = clk_get(&pdev->dev, "usb_hs_core_clk");
904 if (IS_ERR(motg->core_clk))
905 motg->core_clk = NULL;
906
907 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
908 if (!res) {
909 dev_err(&pdev->dev, "failed to get platform resource mem\n");
910 ret = -ENODEV;
911 goto put_core_clk;
912 }
913
914 motg->regs = ioremap(res->start, resource_size(res));
915 if (!motg->regs) {
916 dev_err(&pdev->dev, "ioremap failed\n");
917 ret = -ENOMEM;
918 goto put_core_clk;
919 }
920 dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs);
921
922 motg->irq = platform_get_irq(pdev, 0);
923 if (!motg->irq) {
924 dev_err(&pdev->dev, "platform_get_irq failed\n");
925 ret = -ENODEV;
926 goto free_regs;
927 }
928
929 clk_enable(motg->clk);
930 clk_enable(motg->pclk);
931 if (motg->core_clk)
932 clk_enable(motg->core_clk);
933
934 writel(0, USB_USBINTR);
935 writel(0, USB_OTGSC);
936
937 INIT_WORK(&motg->sm_work, msm_otg_sm_work);
938 ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED,
939 "msm_otg", motg);
940 if (ret) {
941 dev_err(&pdev->dev, "request irq failed\n");
942 goto disable_clks;
943 }
944
945 otg->init = msm_otg_reset;
946 otg->set_host = msm_otg_set_host;
947 otg->set_peripheral = msm_otg_set_peripheral;
948
949 otg->io_ops = &msm_otg_io_ops;
950
951 ret = otg_set_transceiver(&motg->otg);
952 if (ret) {
953 dev_err(&pdev->dev, "otg_set_transceiver failed\n");
954 goto free_irq;
955 }
956
957 platform_set_drvdata(pdev, motg);
958 device_init_wakeup(&pdev->dev, 1);
959
960 if (motg->pdata->mode == USB_OTG &&
961 motg->pdata->otg_control == OTG_USER_CONTROL) {
962 ret = msm_otg_debugfs_init(motg);
963 if (ret)
964 dev_dbg(&pdev->dev, "mode debugfs file is"
965 "not available\n");
966 }
967
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530968 pm_runtime_set_active(&pdev->dev);
969 pm_runtime_enable(&pdev->dev);
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530970
Pavankumar Kondeti87c01042010-12-07 17:53:58 +0530971 return 0;
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530972free_irq:
973 free_irq(motg->irq, motg);
974disable_clks:
975 clk_disable(motg->pclk);
976 clk_disable(motg->clk);
977free_regs:
978 iounmap(motg->regs);
979put_core_clk:
980 if (motg->core_clk)
981 clk_put(motg->core_clk);
982 clk_put(motg->pclk);
Anji jonnala0f73cac2011-05-04 10:19:46 +0530983put_pclk_src:
984 if (!IS_ERR(motg->pclk_src)) {
985 clk_disable(motg->pclk_src);
986 clk_put(motg->pclk_src);
987 }
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +0530988put_clk:
989 clk_put(motg->clk);
990put_phy_reset_clk:
991 clk_put(motg->phy_reset_clk);
992free_motg:
993 kfree(motg);
994 return ret;
995}
996
997static int __devexit msm_otg_remove(struct platform_device *pdev)
998{
999 struct msm_otg *motg = platform_get_drvdata(pdev);
1000 struct otg_transceiver *otg = &motg->otg;
Pavankumar Kondeti87c01042010-12-07 17:53:58 +05301001 int cnt = 0;
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +05301002
1003 if (otg->host || otg->gadget)
1004 return -EBUSY;
1005
1006 msm_otg_debugfs_cleanup();
1007 cancel_work_sync(&motg->sm_work);
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +05301008
Pavankumar Kondeti70187732011-02-15 09:42:34 +05301009 pm_runtime_resume(&pdev->dev);
Pavankumar Kondeti87c01042010-12-07 17:53:58 +05301010
1011 device_init_wakeup(&pdev->dev, 0);
1012 pm_runtime_disable(&pdev->dev);
1013
1014 otg_set_transceiver(NULL);
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +05301015 free_irq(motg->irq, motg);
1016
Pavankumar Kondeti87c01042010-12-07 17:53:58 +05301017 /*
1018 * Put PHY in low power mode.
1019 */
1020 ulpi_read(otg, 0x14);
1021 ulpi_write(otg, 0x08, 0x09);
1022
1023 writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC);
1024 while (cnt < PHY_SUSPEND_TIMEOUT_USEC) {
1025 if (readl(USB_PORTSC) & PORTSC_PHCD)
1026 break;
1027 udelay(1);
1028 cnt++;
1029 }
1030 if (cnt >= PHY_SUSPEND_TIMEOUT_USEC)
1031 dev_err(otg->dev, "Unable to suspend PHY\n");
1032
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +05301033 clk_disable(motg->pclk);
1034 clk_disable(motg->clk);
1035 if (motg->core_clk)
1036 clk_disable(motg->core_clk);
Anji jonnala0f73cac2011-05-04 10:19:46 +05301037 if (!IS_ERR(motg->pclk_src)) {
1038 clk_disable(motg->pclk_src);
1039 clk_put(motg->pclk_src);
1040 }
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +05301041
1042 iounmap(motg->regs);
Pavankumar Kondeti87c01042010-12-07 17:53:58 +05301043 pm_runtime_set_suspended(&pdev->dev);
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +05301044
1045 clk_put(motg->phy_reset_clk);
1046 clk_put(motg->pclk);
1047 clk_put(motg->clk);
1048 if (motg->core_clk)
1049 clk_put(motg->core_clk);
1050
1051 kfree(motg);
1052
1053 return 0;
1054}
1055
Pavankumar Kondeti87c01042010-12-07 17:53:58 +05301056#ifdef CONFIG_PM_RUNTIME
1057static int msm_otg_runtime_idle(struct device *dev)
1058{
1059 struct msm_otg *motg = dev_get_drvdata(dev);
1060 struct otg_transceiver *otg = &motg->otg;
1061
1062 dev_dbg(dev, "OTG runtime idle\n");
1063
1064 /*
1065 * It is observed some times that a spurious interrupt
1066 * comes when PHY is put into LPM immediately after PHY reset.
1067 * This 1 sec delay also prevents entering into LPM immediately
1068 * after asynchronous interrupt.
1069 */
1070 if (otg->state != OTG_STATE_UNDEFINED)
1071 pm_schedule_suspend(dev, 1000);
1072
1073 return -EAGAIN;
1074}
1075
1076static int msm_otg_runtime_suspend(struct device *dev)
1077{
1078 struct msm_otg *motg = dev_get_drvdata(dev);
1079
1080 dev_dbg(dev, "OTG runtime suspend\n");
1081 return msm_otg_suspend(motg);
1082}
1083
1084static int msm_otg_runtime_resume(struct device *dev)
1085{
1086 struct msm_otg *motg = dev_get_drvdata(dev);
1087
1088 dev_dbg(dev, "OTG runtime resume\n");
1089 return msm_otg_resume(motg);
1090}
Pavankumar Kondeti87c01042010-12-07 17:53:58 +05301091#endif
1092
Pavankumar Kondeti70187732011-02-15 09:42:34 +05301093#ifdef CONFIG_PM_SLEEP
Pavankumar Kondeti87c01042010-12-07 17:53:58 +05301094static int msm_otg_pm_suspend(struct device *dev)
1095{
1096 struct msm_otg *motg = dev_get_drvdata(dev);
1097
1098 dev_dbg(dev, "OTG PM suspend\n");
1099 return msm_otg_suspend(motg);
1100}
1101
1102static int msm_otg_pm_resume(struct device *dev)
1103{
1104 struct msm_otg *motg = dev_get_drvdata(dev);
1105 int ret;
1106
1107 dev_dbg(dev, "OTG PM resume\n");
1108
1109 ret = msm_otg_resume(motg);
1110 if (ret)
1111 return ret;
1112
1113 /*
1114 * Runtime PM Documentation recommends bringing the
1115 * device to full powered state upon resume.
1116 */
1117 pm_runtime_disable(dev);
1118 pm_runtime_set_active(dev);
1119 pm_runtime_enable(dev);
1120
1121 return 0;
1122}
Pavankumar Kondeti87c01042010-12-07 17:53:58 +05301123#endif
1124
Pavankumar Kondeti70187732011-02-15 09:42:34 +05301125#ifdef CONFIG_PM
Pavankumar Kondeti87c01042010-12-07 17:53:58 +05301126static const struct dev_pm_ops msm_otg_dev_pm_ops = {
Pavankumar Kondeti70187732011-02-15 09:42:34 +05301127 SET_SYSTEM_SLEEP_PM_OPS(msm_otg_pm_suspend, msm_otg_pm_resume)
1128 SET_RUNTIME_PM_OPS(msm_otg_runtime_suspend, msm_otg_runtime_resume,
1129 msm_otg_runtime_idle)
Pavankumar Kondeti87c01042010-12-07 17:53:58 +05301130};
Pavankumar Kondeti70187732011-02-15 09:42:34 +05301131#endif
Pavankumar Kondeti87c01042010-12-07 17:53:58 +05301132
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +05301133static struct platform_driver msm_otg_driver = {
1134 .remove = __devexit_p(msm_otg_remove),
1135 .driver = {
1136 .name = DRIVER_NAME,
1137 .owner = THIS_MODULE,
Pavankumar Kondeti70187732011-02-15 09:42:34 +05301138#ifdef CONFIG_PM
Pavankumar Kondeti87c01042010-12-07 17:53:58 +05301139 .pm = &msm_otg_dev_pm_ops,
Pavankumar Kondeti70187732011-02-15 09:42:34 +05301140#endif
Pavankumar Kondetie0c201f2010-12-07 17:53:55 +05301141 },
1142};
1143
1144static int __init msm_otg_init(void)
1145{
1146 return platform_driver_probe(&msm_otg_driver, msm_otg_probe);
1147}
1148
1149static void __exit msm_otg_exit(void)
1150{
1151 platform_driver_unregister(&msm_otg_driver);
1152}
1153
1154module_init(msm_otg_init);
1155module_exit(msm_otg_exit);
1156
1157MODULE_LICENSE("GPL v2");
1158MODULE_DESCRIPTION("MSM USB transceiver driver");