aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorPavankumar Kondeti <pkondeti@codeaurora.org>2010-12-07 07:23:55 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-12-10 17:23:31 -0500
commite0c201f339fe7fc38d1b0f6f4755ff627686c7e0 (patch)
treea8245f60d4e0c0e22901a15a655af45eaf17325d /drivers/usb
parent05570297ecbe834b1756b522412b68eaffb9ab11 (diff)
USB: Add MSM OTG Controller driver
This driver implements PHY initialization, clock management, ULPI IO ops and simple OTG state machine to kick host/peripheral based on Id/VBUS line status. VBUS/Id lines are tied to a reference voltage on some boards. Hence provide debugfs interface to select host/peripheral mode. Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/otg/Kconfig10
-rw-r--r--drivers/usb/otg/Makefile1
-rw-r--r--drivers/usb/otg/msm72k_otg.c850
3 files changed, 861 insertions, 0 deletions
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index 5ce07528cd0c..915c729872f8 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -81,4 +81,14 @@ config USB_LANGWELL_OTG
81 To compile this driver as a module, choose M here: the 81 To compile this driver as a module, choose M here: the
82 module will be called langwell_otg. 82 module will be called langwell_otg.
83 83
84config USB_MSM_OTG_72K
85 tristate "OTG support for Qualcomm on-chip USB controller"
86 depends on (USB || USB_GADGET) && ARCH_MSM
87 select USB_OTG_UTILS
88 help
89 Enable this to support the USB OTG transceiver on MSM chips. It
90 handles PHY initialization, clock management, and workarounds
91 required after resetting the hardware. This driver is required
92 even for peripheral only or host only mode configuration.
93
84endif # USB || OTG 94endif # USB || OTG
diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile
index 66f1b83e4fa7..3b1b0960fb68 100644
--- a/drivers/usb/otg/Makefile
+++ b/drivers/usb/otg/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o
15obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o 15obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o
16obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o 16obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o
17obj-$(CONFIG_USB_ULPI) += ulpi.o 17obj-$(CONFIG_USB_ULPI) += ulpi.o
18obj-$(CONFIG_USB_MSM_OTG_72K) += msm72k_otg.o
diff --git a/drivers/usb/otg/msm72k_otg.c b/drivers/usb/otg/msm72k_otg.c
new file mode 100644
index 000000000000..46f468a912f4
--- /dev/null
+++ b/drivers/usb/otg/msm72k_otg.c
@@ -0,0 +1,850 @@
1/* 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>
32
33#include <linux/usb.h>
34#include <linux/usb/otg.h>
35#include <linux/usb/ulpi.h>
36#include <linux/usb/gadget.h>
37#include <linux/usb/hcd.h>
38#include <linux/usb/msm_hsusb.h>
39#include <linux/usb/msm_hsusb_hw.h>
40
41#include <mach/clk.h>
42
43#define MSM_USB_BASE (motg->regs)
44#define DRIVER_NAME "msm_otg"
45
46#define ULPI_IO_TIMEOUT_USEC (10 * 1000)
47static int ulpi_read(struct otg_transceiver *otg, u32 reg)
48{
49 struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
50 int cnt = 0;
51
52 /* initiate read operation */
53 writel(ULPI_RUN | ULPI_READ | ULPI_ADDR(reg),
54 USB_ULPI_VIEWPORT);
55
56 /* wait for completion */
57 while (cnt < ULPI_IO_TIMEOUT_USEC) {
58 if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN))
59 break;
60 udelay(1);
61 cnt++;
62 }
63
64 if (cnt >= ULPI_IO_TIMEOUT_USEC) {
65 dev_err(otg->dev, "ulpi_read: timeout %08x\n",
66 readl(USB_ULPI_VIEWPORT));
67 return -ETIMEDOUT;
68 }
69 return ULPI_DATA_READ(readl(USB_ULPI_VIEWPORT));
70}
71
72static int ulpi_write(struct otg_transceiver *otg, u32 val, u32 reg)
73{
74 struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
75 int cnt = 0;
76
77 /* initiate write operation */
78 writel(ULPI_RUN | ULPI_WRITE |
79 ULPI_ADDR(reg) | ULPI_DATA(val),
80 USB_ULPI_VIEWPORT);
81
82 /* wait for completion */
83 while (cnt < ULPI_IO_TIMEOUT_USEC) {
84 if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN))
85 break;
86 udelay(1);
87 cnt++;
88 }
89
90 if (cnt >= ULPI_IO_TIMEOUT_USEC) {
91 dev_err(otg->dev, "ulpi_write: timeout\n");
92 return -ETIMEDOUT;
93 }
94 return 0;
95}
96
97static struct otg_io_access_ops msm_otg_io_ops = {
98 .read = ulpi_read,
99 .write = ulpi_write,
100};
101
102static void ulpi_init(struct msm_otg *motg)
103{
104 struct msm_otg_platform_data *pdata = motg->pdata;
105 int *seq = pdata->phy_init_seq;
106
107 if (!seq)
108 return;
109
110 while (seq[0] >= 0) {
111 dev_vdbg(motg->otg.dev, "ulpi: write 0x%02x to 0x%02x\n",
112 seq[0], seq[1]);
113 ulpi_write(&motg->otg, seq[0], seq[1]);
114 seq += 2;
115 }
116}
117
118static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert)
119{
120 int ret;
121
122 if (assert) {
123 ret = clk_reset(motg->clk, CLK_RESET_ASSERT);
124 if (ret)
125 dev_err(motg->otg.dev, "usb hs_clk assert failed\n");
126 } else {
127 ret = clk_reset(motg->clk, CLK_RESET_DEASSERT);
128 if (ret)
129 dev_err(motg->otg.dev, "usb hs_clk deassert failed\n");
130 }
131 return ret;
132}
133
134static int msm_otg_phy_clk_reset(struct msm_otg *motg)
135{
136 int ret;
137
138 ret = clk_reset(motg->phy_reset_clk, CLK_RESET_ASSERT);
139 if (ret) {
140 dev_err(motg->otg.dev, "usb phy clk assert failed\n");
141 return ret;
142 }
143 usleep_range(10000, 12000);
144 ret = clk_reset(motg->phy_reset_clk, CLK_RESET_DEASSERT);
145 if (ret)
146 dev_err(motg->otg.dev, "usb phy clk deassert failed\n");
147 return ret;
148}
149
150static int msm_otg_phy_reset(struct msm_otg *motg)
151{
152 u32 val;
153 int ret;
154 int retries;
155
156 ret = msm_otg_link_clk_reset(motg, 1);
157 if (ret)
158 return ret;
159 ret = msm_otg_phy_clk_reset(motg);
160 if (ret)
161 return ret;
162 ret = msm_otg_link_clk_reset(motg, 0);
163 if (ret)
164 return ret;
165
166 val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK;
167 writel(val | PORTSC_PTS_ULPI, USB_PORTSC);
168
169 for (retries = 3; retries > 0; retries--) {
170 ret = ulpi_write(&motg->otg, ULPI_FUNC_CTRL_SUSPENDM,
171 ULPI_CLR(ULPI_FUNC_CTRL));
172 if (!ret)
173 break;
174 ret = msm_otg_phy_clk_reset(motg);
175 if (ret)
176 return ret;
177 }
178 if (!retries)
179 return -ETIMEDOUT;
180
181 /* This reset calibrates the phy, if the above write succeeded */
182 ret = msm_otg_phy_clk_reset(motg);
183 if (ret)
184 return ret;
185
186 for (retries = 3; retries > 0; retries--) {
187 ret = ulpi_read(&motg->otg, ULPI_DEBUG);
188 if (ret != -ETIMEDOUT)
189 break;
190 ret = msm_otg_phy_clk_reset(motg);
191 if (ret)
192 return ret;
193 }
194 if (!retries)
195 return -ETIMEDOUT;
196
197 dev_info(motg->otg.dev, "phy_reset: success\n");
198 return 0;
199}
200
201#define LINK_RESET_TIMEOUT_USEC (250 * 1000)
202static int msm_otg_reset(struct otg_transceiver *otg)
203{
204 struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
205 struct msm_otg_platform_data *pdata = motg->pdata;
206 int cnt = 0;
207 int ret;
208 u32 val = 0;
209 u32 ulpi_val = 0;
210
211 ret = msm_otg_phy_reset(motg);
212 if (ret) {
213 dev_err(otg->dev, "phy_reset failed\n");
214 return ret;
215 }
216
217 ulpi_init(motg);
218
219 writel(USBCMD_RESET, USB_USBCMD);
220 while (cnt < LINK_RESET_TIMEOUT_USEC) {
221 if (!(readl(USB_USBCMD) & USBCMD_RESET))
222 break;
223 udelay(1);
224 cnt++;
225 }
226 if (cnt >= LINK_RESET_TIMEOUT_USEC)
227 return -ETIMEDOUT;
228
229 /* select ULPI phy */
230 writel(0x80000000, USB_PORTSC);
231
232 msleep(100);
233
234 writel(0x0, USB_AHBBURST);
235 writel(0x00, USB_AHBMODE);
236
237 if (pdata->otg_control == OTG_PHY_CONTROL) {
238 val = readl(USB_OTGSC);
239 if (pdata->mode == USB_OTG) {
240 ulpi_val = ULPI_INT_IDGRD | ULPI_INT_SESS_VALID;
241 val |= OTGSC_IDIE | OTGSC_BSVIE;
242 } else if (pdata->mode == USB_PERIPHERAL) {
243 ulpi_val = ULPI_INT_SESS_VALID;
244 val |= OTGSC_BSVIE;
245 }
246 writel(val, USB_OTGSC);
247 ulpi_write(otg, ulpi_val, ULPI_USB_INT_EN_RISE);
248 ulpi_write(otg, ulpi_val, ULPI_USB_INT_EN_FALL);
249 }
250
251 return 0;
252}
253
254static void msm_otg_start_host(struct otg_transceiver *otg, int on)
255{
256 struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
257 struct msm_otg_platform_data *pdata = motg->pdata;
258 struct usb_hcd *hcd;
259
260 if (!otg->host)
261 return;
262
263 hcd = bus_to_hcd(otg->host);
264
265 if (on) {
266 dev_dbg(otg->dev, "host on\n");
267
268 if (pdata->vbus_power)
269 pdata->vbus_power(1);
270 /*
271 * Some boards have a switch cotrolled by gpio
272 * to enable/disable internal HUB. Enable internal
273 * HUB before kicking the host.
274 */
275 if (pdata->setup_gpio)
276 pdata->setup_gpio(OTG_STATE_A_HOST);
277#ifdef CONFIG_USB
278 usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
279#endif
280 } else {
281 dev_dbg(otg->dev, "host off\n");
282
283#ifdef CONFIG_USB
284 usb_remove_hcd(hcd);
285#endif
286 if (pdata->setup_gpio)
287 pdata->setup_gpio(OTG_STATE_UNDEFINED);
288 if (pdata->vbus_power)
289 pdata->vbus_power(0);
290 }
291}
292
293static int msm_otg_set_host(struct otg_transceiver *otg, struct usb_bus *host)
294{
295 struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
296 struct usb_hcd *hcd;
297
298 /*
299 * Fail host registration if this board can support
300 * only peripheral configuration.
301 */
302 if (motg->pdata->mode == USB_PERIPHERAL) {
303 dev_info(otg->dev, "Host mode is not supported\n");
304 return -ENODEV;
305 }
306
307 if (!host) {
308 if (otg->state == OTG_STATE_A_HOST) {
309 msm_otg_start_host(otg, 0);
310 otg->host = NULL;
311 otg->state = OTG_STATE_UNDEFINED;
312 schedule_work(&motg->sm_work);
313 } else {
314 otg->host = NULL;
315 }
316
317 return 0;
318 }
319
320 hcd = bus_to_hcd(host);
321 hcd->power_budget = motg->pdata->power_budget;
322
323 otg->host = host;
324 dev_dbg(otg->dev, "host driver registered w/ tranceiver\n");
325
326 /*
327 * Kick the state machine work, if peripheral is not supported
328 * or peripheral is already registered with us.
329 */
330 if (motg->pdata->mode == USB_HOST || otg->gadget)
331 schedule_work(&motg->sm_work);
332
333 return 0;
334}
335
336static void msm_otg_start_peripheral(struct otg_transceiver *otg, int on)
337{
338 struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
339 struct msm_otg_platform_data *pdata = motg->pdata;
340
341 if (!otg->gadget)
342 return;
343
344 if (on) {
345 dev_dbg(otg->dev, "gadget on\n");
346 /*
347 * Some boards have a switch cotrolled by gpio
348 * to enable/disable internal HUB. Disable internal
349 * HUB before kicking the gadget.
350 */
351 if (pdata->setup_gpio)
352 pdata->setup_gpio(OTG_STATE_B_PERIPHERAL);
353 usb_gadget_vbus_connect(otg->gadget);
354 } else {
355 dev_dbg(otg->dev, "gadget off\n");
356 usb_gadget_vbus_disconnect(otg->gadget);
357 if (pdata->setup_gpio)
358 pdata->setup_gpio(OTG_STATE_UNDEFINED);
359 }
360
361}
362
363static int msm_otg_set_peripheral(struct otg_transceiver *otg,
364 struct usb_gadget *gadget)
365{
366 struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
367
368 /*
369 * Fail peripheral registration if this board can support
370 * only host configuration.
371 */
372 if (motg->pdata->mode == USB_HOST) {
373 dev_info(otg->dev, "Peripheral mode is not supported\n");
374 return -ENODEV;
375 }
376
377 if (!gadget) {
378 if (otg->state == OTG_STATE_B_PERIPHERAL) {
379 msm_otg_start_peripheral(otg, 0);
380 otg->gadget = NULL;
381 otg->state = OTG_STATE_UNDEFINED;
382 schedule_work(&motg->sm_work);
383 } else {
384 otg->gadget = NULL;
385 }
386
387 return 0;
388 }
389 otg->gadget = gadget;
390 dev_dbg(otg->dev, "peripheral driver registered w/ tranceiver\n");
391
392 /*
393 * Kick the state machine work, if host is not supported
394 * or host is already registered with us.
395 */
396 if (motg->pdata->mode == USB_PERIPHERAL || otg->host)
397 schedule_work(&motg->sm_work);
398
399 return 0;
400}
401
402/*
403 * We support OTG, Peripheral only and Host only configurations. In case
404 * of OTG, mode switch (host-->peripheral/peripheral-->host) can happen
405 * via Id pin status or user request (debugfs). Id/BSV interrupts are not
406 * enabled when switch is controlled by user and default mode is supplied
407 * by board file, which can be changed by userspace later.
408 */
409static void msm_otg_init_sm(struct msm_otg *motg)
410{
411 struct msm_otg_platform_data *pdata = motg->pdata;
412 u32 otgsc = readl(USB_OTGSC);
413
414 switch (pdata->mode) {
415 case USB_OTG:
416 if (pdata->otg_control == OTG_PHY_CONTROL) {
417 if (otgsc & OTGSC_ID)
418 set_bit(ID, &motg->inputs);
419 else
420 clear_bit(ID, &motg->inputs);
421
422 if (otgsc & OTGSC_BSV)
423 set_bit(B_SESS_VLD, &motg->inputs);
424 else
425 clear_bit(B_SESS_VLD, &motg->inputs);
426 } else if (pdata->otg_control == OTG_USER_CONTROL) {
427 if (pdata->default_mode == USB_HOST) {
428 clear_bit(ID, &motg->inputs);
429 } else if (pdata->default_mode == USB_PERIPHERAL) {
430 set_bit(ID, &motg->inputs);
431 set_bit(B_SESS_VLD, &motg->inputs);
432 } else {
433 set_bit(ID, &motg->inputs);
434 clear_bit(B_SESS_VLD, &motg->inputs);
435 }
436 }
437 break;
438 case USB_HOST:
439 clear_bit(ID, &motg->inputs);
440 break;
441 case USB_PERIPHERAL:
442 set_bit(ID, &motg->inputs);
443 if (otgsc & OTGSC_BSV)
444 set_bit(B_SESS_VLD, &motg->inputs);
445 else
446 clear_bit(B_SESS_VLD, &motg->inputs);
447 break;
448 default:
449 break;
450 }
451}
452
453static void msm_otg_sm_work(struct work_struct *w)
454{
455 struct msm_otg *motg = container_of(w, struct msm_otg, sm_work);
456 struct otg_transceiver *otg = &motg->otg;
457
458 switch (otg->state) {
459 case OTG_STATE_UNDEFINED:
460 dev_dbg(otg->dev, "OTG_STATE_UNDEFINED state\n");
461 msm_otg_reset(otg);
462 msm_otg_init_sm(motg);
463 otg->state = OTG_STATE_B_IDLE;
464 /* FALL THROUGH */
465 case OTG_STATE_B_IDLE:
466 dev_dbg(otg->dev, "OTG_STATE_B_IDLE state\n");
467 if (!test_bit(ID, &motg->inputs) && otg->host) {
468 /* disable BSV bit */
469 writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC);
470 msm_otg_start_host(otg, 1);
471 otg->state = OTG_STATE_A_HOST;
472 } else if (test_bit(B_SESS_VLD, &motg->inputs) && otg->gadget) {
473 msm_otg_start_peripheral(otg, 1);
474 otg->state = OTG_STATE_B_PERIPHERAL;
475 }
476 break;
477 case OTG_STATE_B_PERIPHERAL:
478 dev_dbg(otg->dev, "OTG_STATE_B_PERIPHERAL state\n");
479 if (!test_bit(B_SESS_VLD, &motg->inputs) ||
480 !test_bit(ID, &motg->inputs)) {
481 msm_otg_start_peripheral(otg, 0);
482 otg->state = OTG_STATE_B_IDLE;
483 msm_otg_reset(otg);
484 schedule_work(w);
485 }
486 break;
487 case OTG_STATE_A_HOST:
488 dev_dbg(otg->dev, "OTG_STATE_A_HOST state\n");
489 if (test_bit(ID, &motg->inputs)) {
490 msm_otg_start_host(otg, 0);
491 otg->state = OTG_STATE_B_IDLE;
492 msm_otg_reset(otg);
493 schedule_work(w);
494 }
495 break;
496 default:
497 break;
498 }
499}
500
501static irqreturn_t msm_otg_irq(int irq, void *data)
502{
503 struct msm_otg *motg = data;
504 struct otg_transceiver *otg = &motg->otg;
505 u32 otgsc = 0;
506
507 otgsc = readl(USB_OTGSC);
508 if (!(otgsc & (OTGSC_IDIS | OTGSC_BSVIS)))
509 return IRQ_NONE;
510
511 if ((otgsc & OTGSC_IDIS) && (otgsc & OTGSC_IDIE)) {
512 if (otgsc & OTGSC_ID)
513 set_bit(ID, &motg->inputs);
514 else
515 clear_bit(ID, &motg->inputs);
516 dev_dbg(otg->dev, "ID set/clear\n");
517 } else if ((otgsc & OTGSC_BSVIS) && (otgsc & OTGSC_BSVIE)) {
518 if (otgsc & OTGSC_BSV)
519 set_bit(B_SESS_VLD, &motg->inputs);
520 else
521 clear_bit(B_SESS_VLD, &motg->inputs);
522 dev_dbg(otg->dev, "BSV set/clear\n");
523 }
524
525 writel(otgsc, USB_OTGSC);
526 schedule_work(&motg->sm_work);
527 return IRQ_HANDLED;
528}
529
530static int msm_otg_mode_show(struct seq_file *s, void *unused)
531{
532 struct msm_otg *motg = s->private;
533 struct otg_transceiver *otg = &motg->otg;
534
535 switch (otg->state) {
536 case OTG_STATE_A_HOST:
537 seq_printf(s, "host\n");
538 break;
539 case OTG_STATE_B_PERIPHERAL:
540 seq_printf(s, "peripheral\n");
541 break;
542 default:
543 seq_printf(s, "none\n");
544 break;
545 }
546
547 return 0;
548}
549
550static int msm_otg_mode_open(struct inode *inode, struct file *file)
551{
552 return single_open(file, msm_otg_mode_show, inode->i_private);
553}
554
555static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf,
556 size_t count, loff_t *ppos)
557{
558 struct msm_otg *motg = file->private_data;
559 char buf[16];
560 struct otg_transceiver *otg = &motg->otg;
561 int status = count;
562 enum usb_mode_type req_mode;
563
564 memset(buf, 0x00, sizeof(buf));
565
566 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) {
567 status = -EFAULT;
568 goto out;
569 }
570
571 if (!strncmp(buf, "host", 4)) {
572 req_mode = USB_HOST;
573 } else if (!strncmp(buf, "peripheral", 10)) {
574 req_mode = USB_PERIPHERAL;
575 } else if (!strncmp(buf, "none", 4)) {
576 req_mode = USB_NONE;
577 } else {
578 status = -EINVAL;
579 goto out;
580 }
581
582 switch (req_mode) {
583 case USB_NONE:
584 switch (otg->state) {
585 case OTG_STATE_A_HOST:
586 case OTG_STATE_B_PERIPHERAL:
587 set_bit(ID, &motg->inputs);
588 clear_bit(B_SESS_VLD, &motg->inputs);
589 break;
590 default:
591 goto out;
592 }
593 break;
594 case USB_PERIPHERAL:
595 switch (otg->state) {
596 case OTG_STATE_B_IDLE:
597 case OTG_STATE_A_HOST:
598 set_bit(ID, &motg->inputs);
599 set_bit(B_SESS_VLD, &motg->inputs);
600 break;
601 default:
602 goto out;
603 }
604 break;
605 case USB_HOST:
606 switch (otg->state) {
607 case OTG_STATE_B_IDLE:
608 case OTG_STATE_B_PERIPHERAL:
609 clear_bit(ID, &motg->inputs);
610 break;
611 default:
612 goto out;
613 }
614 break;
615 default:
616 goto out;
617 }
618
619 schedule_work(&motg->sm_work);
620out:
621 return status;
622}
623
624const struct file_operations msm_otg_mode_fops = {
625 .open = msm_otg_mode_open,
626 .read = seq_read,
627 .write = msm_otg_mode_write,
628 .llseek = seq_lseek,
629 .release = single_release,
630};
631
632static struct dentry *msm_otg_dbg_root;
633static struct dentry *msm_otg_dbg_mode;
634
635static int msm_otg_debugfs_init(struct msm_otg *motg)
636{
637 msm_otg_dbg_root = debugfs_create_dir("msm_otg", NULL);
638
639 if (!msm_otg_dbg_root || IS_ERR(msm_otg_dbg_root))
640 return -ENODEV;
641
642 msm_otg_dbg_mode = debugfs_create_file("mode", S_IRUGO | S_IWUSR,
643 msm_otg_dbg_root, motg, &msm_otg_mode_fops);
644 if (!msm_otg_dbg_mode) {
645 debugfs_remove(msm_otg_dbg_root);
646 msm_otg_dbg_root = NULL;
647 return -ENODEV;
648 }
649
650 return 0;
651}
652
653static void msm_otg_debugfs_cleanup(void)
654{
655 debugfs_remove(msm_otg_dbg_mode);
656 debugfs_remove(msm_otg_dbg_root);
657}
658
659static int __init msm_otg_probe(struct platform_device *pdev)
660{
661 int ret = 0;
662 struct resource *res;
663 struct msm_otg *motg;
664 struct otg_transceiver *otg;
665
666 dev_info(&pdev->dev, "msm_otg probe\n");
667 if (!pdev->dev.platform_data) {
668 dev_err(&pdev->dev, "No platform data given. Bailing out\n");
669 return -ENODEV;
670 }
671
672 motg = kzalloc(sizeof(struct msm_otg), GFP_KERNEL);
673 if (!motg) {
674 dev_err(&pdev->dev, "unable to allocate msm_otg\n");
675 return -ENOMEM;
676 }
677
678 motg->pdata = pdev->dev.platform_data;
679 otg = &motg->otg;
680 otg->dev = &pdev->dev;
681
682 motg->phy_reset_clk = clk_get(&pdev->dev, "usb_phy_clk");
683 if (IS_ERR(motg->phy_reset_clk)) {
684 dev_err(&pdev->dev, "failed to get usb_phy_clk\n");
685 ret = PTR_ERR(motg->phy_reset_clk);
686 goto free_motg;
687 }
688
689 motg->clk = clk_get(&pdev->dev, "usb_hs_clk");
690 if (IS_ERR(motg->clk)) {
691 dev_err(&pdev->dev, "failed to get usb_hs_clk\n");
692 ret = PTR_ERR(motg->clk);
693 goto put_phy_reset_clk;
694 }
695
696 motg->pclk = clk_get(&pdev->dev, "usb_hs_pclk");
697 if (IS_ERR(motg->pclk)) {
698 dev_err(&pdev->dev, "failed to get usb_hs_pclk\n");
699 ret = PTR_ERR(motg->pclk);
700 goto put_clk;
701 }
702
703 /*
704 * USB core clock is not present on all MSM chips. This
705 * clock is introduced to remove the dependency on AXI
706 * bus frequency.
707 */
708 motg->core_clk = clk_get(&pdev->dev, "usb_hs_core_clk");
709 if (IS_ERR(motg->core_clk))
710 motg->core_clk = NULL;
711
712 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
713 if (!res) {
714 dev_err(&pdev->dev, "failed to get platform resource mem\n");
715 ret = -ENODEV;
716 goto put_core_clk;
717 }
718
719 motg->regs = ioremap(res->start, resource_size(res));
720 if (!motg->regs) {
721 dev_err(&pdev->dev, "ioremap failed\n");
722 ret = -ENOMEM;
723 goto put_core_clk;
724 }
725 dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs);
726
727 motg->irq = platform_get_irq(pdev, 0);
728 if (!motg->irq) {
729 dev_err(&pdev->dev, "platform_get_irq failed\n");
730 ret = -ENODEV;
731 goto free_regs;
732 }
733
734 clk_enable(motg->clk);
735 clk_enable(motg->pclk);
736 if (motg->core_clk)
737 clk_enable(motg->core_clk);
738
739 writel(0, USB_USBINTR);
740 writel(0, USB_OTGSC);
741
742 INIT_WORK(&motg->sm_work, msm_otg_sm_work);
743 ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED,
744 "msm_otg", motg);
745 if (ret) {
746 dev_err(&pdev->dev, "request irq failed\n");
747 goto disable_clks;
748 }
749
750 otg->init = msm_otg_reset;
751 otg->set_host = msm_otg_set_host;
752 otg->set_peripheral = msm_otg_set_peripheral;
753
754 otg->io_ops = &msm_otg_io_ops;
755
756 ret = otg_set_transceiver(&motg->otg);
757 if (ret) {
758 dev_err(&pdev->dev, "otg_set_transceiver failed\n");
759 goto free_irq;
760 }
761
762 platform_set_drvdata(pdev, motg);
763 device_init_wakeup(&pdev->dev, 1);
764
765 if (motg->pdata->mode == USB_OTG &&
766 motg->pdata->otg_control == OTG_USER_CONTROL) {
767 ret = msm_otg_debugfs_init(motg);
768 if (ret)
769 dev_dbg(&pdev->dev, "mode debugfs file is"
770 "not available\n");
771 }
772
773 return 0;
774
775free_irq:
776 free_irq(motg->irq, motg);
777disable_clks:
778 clk_disable(motg->pclk);
779 clk_disable(motg->clk);
780free_regs:
781 iounmap(motg->regs);
782put_core_clk:
783 if (motg->core_clk)
784 clk_put(motg->core_clk);
785 clk_put(motg->pclk);
786put_clk:
787 clk_put(motg->clk);
788put_phy_reset_clk:
789 clk_put(motg->phy_reset_clk);
790free_motg:
791 kfree(motg);
792 return ret;
793}
794
795static int __devexit msm_otg_remove(struct platform_device *pdev)
796{
797 struct msm_otg *motg = platform_get_drvdata(pdev);
798 struct otg_transceiver *otg = &motg->otg;
799
800 if (otg->host || otg->gadget)
801 return -EBUSY;
802
803 msm_otg_debugfs_cleanup();
804 cancel_work_sync(&motg->sm_work);
805 device_init_wakeup(&pdev->dev, 0);
806 otg_set_transceiver(NULL);
807
808 free_irq(motg->irq, motg);
809
810 clk_disable(motg->pclk);
811 clk_disable(motg->clk);
812 if (motg->core_clk)
813 clk_disable(motg->core_clk);
814
815 iounmap(motg->regs);
816
817 clk_put(motg->phy_reset_clk);
818 clk_put(motg->pclk);
819 clk_put(motg->clk);
820 if (motg->core_clk)
821 clk_put(motg->core_clk);
822
823 kfree(motg);
824
825 return 0;
826}
827
828static struct platform_driver msm_otg_driver = {
829 .remove = __devexit_p(msm_otg_remove),
830 .driver = {
831 .name = DRIVER_NAME,
832 .owner = THIS_MODULE,
833 },
834};
835
836static int __init msm_otg_init(void)
837{
838 return platform_driver_probe(&msm_otg_driver, msm_otg_probe);
839}
840
841static void __exit msm_otg_exit(void)
842{
843 platform_driver_unregister(&msm_otg_driver);
844}
845
846module_init(msm_otg_init);
847module_exit(msm_otg_exit);
848
849MODULE_LICENSE("GPL v2");
850MODULE_DESCRIPTION("MSM USB transceiver driver");