aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/otg/msm72k_otg.c
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/otg/msm72k_otg.c
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/otg/msm72k_otg.c')
-rw-r--r--drivers/usb/otg/msm72k_otg.c850
1 files changed, 850 insertions, 0 deletions
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");