2 * drivers/cbus/tahvo-usb.c
6 * Copyright (C) 2005-2006 Nokia Corporation
8 * Parts copied from drivers/i2c/chips/isp1301_omap.c
9 * Copyright (C) 2004 Texas Instruments
10 * Copyright (C) 2004 David Brownell
12 * Written by Juha Yrjölä <juha.yrjola@nokia.com>,
13 * Tony Lindgren <tony@atomide.com>, and
14 * Timo Teräs <timo.teras@nokia.com>
16 * This file is subject to the terms and conditions of the GNU General
17 * Public License. See the file "COPYING" in the main directory of this
18 * archive for more details.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include <linux/kernel.h>
31 #include <linux/module.h>
32 #include <linux/init.h>
33 #include <linux/slab.h>
35 #include <linux/interrupt.h>
36 #include <linux/platform_device.h>
37 #include <linux/usb/ch9.h>
38 #include <linux/usb/gadget.h>
39 #include <linux/usb.h>
40 #include <linux/usb/otg.h>
41 #include <linux/i2c.h>
42 #include <linux/workqueue.h>
43 #include <linux/kobject.h>
44 #include <linux/clk.h>
45 #include <linux/mutex.h>
53 #define DRIVER_NAME "tahvo-usb"
55 #define USBR_SLAVE_CONTROL (1 << 8)
56 #define USBR_VPPVIO_SW (1 << 7)
57 #define USBR_SPEED (1 << 6)
58 #define USBR_REGOUT (1 << 5)
59 #define USBR_MASTER_SW2 (1 << 4)
60 #define USBR_MASTER_SW1 (1 << 3)
61 #define USBR_SLAVE_SW (1 << 2)
62 #define USBR_NSUSPEND (1 << 1)
63 #define USBR_SEMODE (1 << 0)
65 /* bits in OTG_CTRL */
67 /* Bits that are controlled by OMAP OTG and are read-only */
68 #define OTG_CTRL_OMAP_MASK (OTG_PULLDOWN|OTG_PULLUP|OTG_DRV_VBUS|\
69 OTG_PD_VBUS|OTG_PU_VBUS|OTG_PU_ID)
70 /* Bits that are controlled by transceiver */
71 #define OTG_CTRL_XCVR_MASK (OTG_ASESSVLD|OTG_BSESSEND|\
72 OTG_BSESSVLD|OTG_VBUSVLD|OTG_ID)
73 /* Bits that are controlled by system */
74 #define OTG_CTRL_SYS_MASK (OTG_A_BUSREQ|OTG_A_SETB_HNPEN|OTG_B_BUSREQ|\
75 OTG_B_HNPEN|OTG_BUSDROP)
77 #if defined(CONFIG_USB_OHCI_HCD) && !defined(CONFIG_USB_OTG)
78 #error tahvo-otg.c does not work with OCHI yet!
81 #define TAHVO_MODE_HOST 0
82 #define TAHVO_MODE_PERIPHERAL 1
85 #define TAHVO_MODE(tu) (tu)->tahvo_mode
86 #elif defined(CONFIG_USB_GADGET_OMAP)
87 #define TAHVO_MODE(tu) TAHVO_MODE_PERIPHERAL
89 #define TAHVO_MODE(tu) TAHVO_MODE_HOST
93 struct platform_device
*pt_dev
;
94 struct otg_transceiver otg
;
96 struct work_struct irq_work
;
97 struct mutex serialize
;
102 static struct platform_device tahvo_usb_device
;
105 * ---------------------------------------------------------------------------
106 * OTG related functions
108 * These shoud be separated into omap-otg.c driver module, as they are used
109 * by various transceivers. These functions are needed in the UDC-only case
110 * as well. These functions are copied from GPL isp1301_omap.c
111 * ---------------------------------------------------------------------------
113 static struct platform_device
*tahvo_otg_dev
;
115 static irqreturn_t
omap_otg_irq(int irq
, void *arg
)
117 struct platform_device
*otg_dev
= (struct platform_device
*) arg
;
118 struct tahvo_usb
*tu
= (struct tahvo_usb
*) otg_dev
->dev
.driver_data
;
121 otg_irq
= omap_readw(OTG_IRQ_SRC
);
122 if (otg_irq
& OPRT_CHG
) {
123 omap_writew(OPRT_CHG
, OTG_IRQ_SRC
);
124 } else if (otg_irq
& B_SRP_TMROUT
) {
125 omap_writew(B_SRP_TMROUT
, OTG_IRQ_SRC
);
126 } else if (otg_irq
& B_HNP_FAIL
) {
127 omap_writew(B_HNP_FAIL
, OTG_IRQ_SRC
);
128 } else if (otg_irq
& A_SRP_DETECT
) {
129 omap_writew(A_SRP_DETECT
, OTG_IRQ_SRC
);
130 } else if (otg_irq
& A_REQ_TMROUT
) {
131 omap_writew(A_REQ_TMROUT
, OTG_IRQ_SRC
);
132 } else if (otg_irq
& A_VBUS_ERR
) {
133 omap_writew(A_VBUS_ERR
, OTG_IRQ_SRC
);
134 } else if (otg_irq
& DRIVER_SWITCH
) {
135 if ((!(omap_readl(OTG_CTRL
) & OTG_DRIVER_SEL
)) &&
136 tu
->otg
.host
&& tu
->otg
.state
== OTG_STATE_A_HOST
) {
138 usb_bus_start_enum(tu
->otg
.host
,
139 tu
->otg
.host
->otg_port
);
141 omap_writew(DRIVER_SWITCH
, OTG_IRQ_SRC
);
149 static int omap_otg_init(void)
153 #ifdef CONFIG_USB_OTG
154 if (!tahvo_otg_dev
) {
155 printk("tahvo-usb: no tahvo_otg_dev\n");
160 l
= omap_readl(OTG_SYSCON_1
);
162 omap_writel(l
, OTG_SYSCON_1
);
165 /* some of these values are board-specific... */
166 l
= omap_readl(OTG_SYSCON_2
);
169 | SRP_GPDATA
/* 9msec Bdev D+ pulse */
170 | SRP_GPDVBUS
/* discharge after VBUS pulse */
171 // | (3 << 24) /* 2msec VBUS pulse */
173 | (0 << 20) /* 200ms nominal A_WAIT_VRISE timer */
174 | SRP_DPW
/* detect 167+ns SRP pulses */
175 | SRP_DATA
| SRP_VBUS
; /* accept both kinds of SRP pulse */
176 omap_writel(l
, OTG_SYSCON_2
);
178 omap_writew(DRIVER_SWITCH
| OPRT_CHG
179 | B_SRP_TMROUT
| B_HNP_FAIL
180 | A_VBUS_ERR
| A_SRP_DETECT
| A_REQ_TMROUT
,
182 l
= omap_readl(OTG_SYSCON_2
);
184 omap_writel(l
, OTG_SYSCON_2
);
189 static int omap_otg_probe(struct device
*dev
)
193 tahvo_otg_dev
= to_platform_device(dev
);
194 ret
= omap_otg_init();
196 printk(KERN_ERR
"tahvo-usb: omap_otg_init failed\n");
200 return request_irq(tahvo_otg_dev
->resource
[1].start
,
201 omap_otg_irq
, IRQF_DISABLED
, DRIVER_NAME
,
205 static int omap_otg_remove(struct device
*dev
)
207 free_irq(tahvo_otg_dev
->resource
[1].start
, &tahvo_usb_device
);
208 tahvo_otg_dev
= NULL
;
213 struct device_driver omap_otg_driver
= {
215 .bus
= &platform_bus_type
,
216 .probe
= omap_otg_probe
,
217 .remove
= omap_otg_remove
,
221 * ---------------------------------------------------------------------------
222 * Tahvo related functions
223 * These are Nokia proprietary code, except for the OTG register settings,
224 * which are copied from isp1301.c
225 * ---------------------------------------------------------------------------
227 static ssize_t
vbus_state_show(struct device
*device
,
228 struct device_attribute
*attr
, char *buf
)
230 struct tahvo_usb
*tu
= (struct tahvo_usb
*) device
->driver_data
;
231 return sprintf(buf
, "%d\n", tu
->vbus_state
);
233 static DEVICE_ATTR(vbus_state
, 0444, vbus_state_show
, NULL
);
239 static int host_suspend(struct tahvo_usb
*tu
)
246 /* Currently ASSUMES only the OTG port matters;
247 * other ports could be active...
249 dev
= tu
->otg
.host
->controller
;
250 return dev
->driver
->suspend(dev
, PMSG_SUSPEND
);
253 static int host_resume(struct tahvo_usb
*tu
)
260 dev
= tu
->otg
.host
->controller
;
261 return dev
->driver
->resume(dev
);
266 static int host_suspend(struct tahvo_usb
*tu
)
271 static int host_resume(struct tahvo_usb
*tu
)
278 static void check_vbus_state(struct tahvo_usb
*tu
)
282 reg
= tahvo_read_reg(TAHVO_REG_IDSR
);
287 switch (tu
->otg
.state
) {
288 case OTG_STATE_B_IDLE
:
289 /* Enable the gadget driver */
291 usb_gadget_vbus_connect(tu
->otg
.gadget
);
292 /* Set B-session valid and not B-sessio ended to indicate
294 l
= omap_readl(OTG_CTRL
);
297 omap_writel(l
, OTG_CTRL
);
299 tu
->otg
.state
= OTG_STATE_B_PERIPHERAL
;
301 case OTG_STATE_A_IDLE
:
302 /* Session is now valid assuming the USB hub is driving Vbus */
303 tu
->otg
.state
= OTG_STATE_A_HOST
;
309 printk("USB cable connected\n");
311 switch (tu
->otg
.state
) {
312 case OTG_STATE_B_PERIPHERAL
:
314 usb_gadget_vbus_disconnect(tu
->otg
.gadget
);
315 tu
->otg
.state
= OTG_STATE_B_IDLE
;
317 case OTG_STATE_A_HOST
:
318 tu
->otg
.state
= OTG_STATE_A_IDLE
;
323 printk("USB cable disconnected\n");
327 prev_state
= tu
->vbus_state
;
328 tu
->vbus_state
= reg
& 0x01;
329 if (prev_state
!= tu
->vbus_state
)
330 sysfs_notify(&tu
->pt_dev
->dev
.kobj
, NULL
, "vbus_state");
333 static void tahvo_usb_become_host(struct tahvo_usb
*tu
)
337 /* Clear system and transceiver controlled bits
338 * also mark the A-session is always valid */
341 l
= omap_readl(OTG_CTRL
);
342 l
&= ~(OTG_CTRL_XCVR_MASK
| OTG_CTRL_SYS_MASK
);
344 omap_writel(l
, OTG_CTRL
);
346 /* Power up the transceiver in USB host mode */
347 tahvo_write_reg(TAHVO_REG_USBR
, USBR_REGOUT
| USBR_NSUSPEND
|
348 USBR_MASTER_SW2
| USBR_MASTER_SW1
);
349 tu
->otg
.state
= OTG_STATE_A_IDLE
;
351 check_vbus_state(tu
);
354 static void tahvo_usb_stop_host(struct tahvo_usb
*tu
)
357 tu
->otg
.state
= OTG_STATE_A_IDLE
;
360 static void tahvo_usb_become_peripheral(struct tahvo_usb
*tu
)
364 /* Clear system and transceiver controlled bits
365 * and enable ID to mark peripheral mode and
366 * BSESSEND to mark no Vbus */
368 l
= omap_readl(OTG_CTRL
);
369 l
&= ~(OTG_CTRL_XCVR_MASK
| OTG_CTRL_SYS_MASK
| OTG_BSESSVLD
);
370 l
|= OTG_ID
| OTG_BSESSEND
;
371 omap_writel(l
, OTG_CTRL
);
373 /* Power up transceiver and set it in USB perhiperal mode */
374 tahvo_write_reg(TAHVO_REG_USBR
, USBR_SLAVE_CONTROL
| USBR_REGOUT
| USBR_NSUSPEND
| USBR_SLAVE_SW
);
375 tu
->otg
.state
= OTG_STATE_B_IDLE
;
377 check_vbus_state(tu
);
380 static void tahvo_usb_stop_peripheral(struct tahvo_usb
*tu
)
384 l
= omap_readl(OTG_CTRL
);
387 omap_writel(l
, OTG_CTRL
);
390 usb_gadget_vbus_disconnect(tu
->otg
.gadget
);
391 tu
->otg
.state
= OTG_STATE_B_IDLE
;
395 static void tahvo_usb_power_off(struct tahvo_usb
*tu
)
400 /* Disable gadget controller if any */
402 usb_gadget_vbus_disconnect(tu
->otg
.gadget
);
406 /* Disable OTG and interrupts */
407 if (TAHVO_MODE(tu
) == TAHVO_MODE_PERIPHERAL
)
411 l
= omap_readl(OTG_CTRL
);
412 l
&= ~(OTG_CTRL_XCVR_MASK
| OTG_CTRL_SYS_MASK
| OTG_BSESSVLD
);
413 l
|= id
| OTG_BSESSEND
;
414 omap_writel(l
, OTG_CTRL
);
415 omap_writew(0, OTG_IRQ_EN
);
417 l
= omap_readl(OTG_SYSCON_2
);
419 omap_writel(l
, OTG_SYSCON_2
);
421 l
= omap_readl(OTG_SYSCON_1
);
423 omap_writel(l
, OTG_SYSCON_1
);
425 /* Power off transceiver */
426 tahvo_write_reg(TAHVO_REG_USBR
, 0);
427 tu
->otg
.state
= OTG_STATE_UNDEFINED
;
431 static int tahvo_usb_set_power(struct otg_transceiver
*dev
, unsigned mA
)
433 struct tahvo_usb
*tu
= container_of(dev
, struct tahvo_usb
, otg
);
435 dev_dbg(&tu
->pt_dev
->dev
, "set_power %d mA\n", mA
);
437 if (dev
->state
== OTG_STATE_B_PERIPHERAL
) {
438 /* REVISIT: Can Tahvo charge battery from VBUS? */
443 static int tahvo_usb_set_suspend(struct otg_transceiver
*dev
, int suspend
)
445 struct tahvo_usb
*tu
= container_of(dev
, struct tahvo_usb
, otg
);
448 dev_dbg(&tu
->pt_dev
->dev
, "set_suspend\n");
450 w
= tahvo_read_reg(TAHVO_REG_USBR
);
455 tahvo_write_reg(TAHVO_REG_USBR
, w
);
460 static int tahvo_usb_start_srp(struct otg_transceiver
*dev
)
462 struct tahvo_usb
*tu
= container_of(dev
, struct tahvo_usb
, otg
);
465 dev_dbg(&tu
->pt_dev
->dev
, "start_srp\n");
467 if (!dev
|| tu
->otg
.state
!= OTG_STATE_B_IDLE
)
470 otg_ctrl
= omap_readl(OTG_CTRL
);
471 if (!(otg_ctrl
& OTG_BSESSEND
))
474 otg_ctrl
|= OTG_B_BUSREQ
;
475 otg_ctrl
&= ~OTG_A_BUSREQ
& OTG_CTRL_SYS_MASK
;
476 omap_writel(otg_ctrl
, OTG_CTRL
);
477 tu
->otg
.state
= OTG_STATE_B_SRP_INIT
;
482 static int tahvo_usb_start_hnp(struct otg_transceiver
*otg
)
484 struct tahvo_usb
*tu
= container_of(otg
, struct tahvo_usb
, otg
);
486 dev_dbg(&tu
->pt_dev
->dev
, "start_hnp\n");
487 #ifdef CONFIG_USB_OTG
488 /* REVISIT: Add this for OTG */
493 static int tahvo_usb_set_host(struct otg_transceiver
*otg
, struct usb_bus
*host
)
495 struct tahvo_usb
*tu
= container_of(otg
, struct tahvo_usb
, otg
);
498 dev_dbg(&tu
->pt_dev
->dev
, "set_host %p\n", host
);
503 #if defined(CONFIG_USB_OTG) || !defined(CONFIG_USB_GADGET_OMAP)
505 mutex_lock(&tu
->serialize
);
508 if (TAHVO_MODE(tu
) == TAHVO_MODE_HOST
)
509 tahvo_usb_power_off(tu
);
511 mutex_unlock(&tu
->serialize
);
515 l
= omap_readl(OTG_SYSCON_1
);
516 l
&= ~(OTG_IDLE_EN
| HST_IDLE_EN
| DEV_IDLE_EN
);
517 omap_writel(l
, OTG_SYSCON_1
);
519 if (TAHVO_MODE(tu
) == TAHVO_MODE_HOST
) {
521 tahvo_usb_become_host(tu
);
527 mutex_unlock(&tu
->serialize
);
529 /* No host mode configured, so do not allow host controlled to be set */
536 static int tahvo_usb_set_peripheral(struct otg_transceiver
*otg
, struct usb_gadget
*gadget
)
538 struct tahvo_usb
*tu
= container_of(otg
, struct tahvo_usb
, otg
);
540 dev_dbg(&tu
->pt_dev
->dev
, "set_peripheral %p\n", gadget
);
545 #if defined(CONFIG_USB_OTG) || defined(CONFIG_USB_GADGET_OMAP)
547 mutex_lock(&tu
->serialize
);
550 if (TAHVO_MODE(tu
) == TAHVO_MODE_PERIPHERAL
)
551 tahvo_usb_power_off(tu
);
552 tu
->otg
.gadget
= NULL
;
553 mutex_unlock(&tu
->serialize
);
557 tu
->otg
.gadget
= gadget
;
558 if (TAHVO_MODE(tu
) == TAHVO_MODE_PERIPHERAL
)
559 tahvo_usb_become_peripheral(tu
);
561 mutex_unlock(&tu
->serialize
);
563 /* No gadget mode configured, so do not allow host controlled to be set */
570 static void tahvo_usb_irq_work(struct work_struct
*work
)
572 struct tahvo_usb
*tu
= container_of(work
, struct tahvo_usb
, irq_work
);
574 mutex_lock(&tu
->serialize
);
575 check_vbus_state(tu
);
576 mutex_unlock(&tu
->serialize
);
579 static void tahvo_usb_vbus_interrupt(unsigned long arg
)
581 struct tahvo_usb
*tu
= (struct tahvo_usb
*) arg
;
583 tahvo_ack_irq(TAHVO_INT_VBUSON
);
584 /* Seems we need this to acknowledge the interrupt */
585 tahvo_read_reg(TAHVO_REG_IDSR
);
586 schedule_work(&tu
->irq_work
);
589 #ifdef CONFIG_USB_OTG
590 static ssize_t
otg_mode_show(struct device
*device
,
591 struct device_attribute
*attr
, char *buf
)
593 struct tahvo_usb
*tu
= (struct tahvo_usb
*) device
->driver_data
;
594 switch (tu
->tahvo_mode
) {
595 case TAHVO_MODE_HOST
:
596 return sprintf(buf
, "host\n");
597 case TAHVO_MODE_PERIPHERAL
:
598 return sprintf(buf
, "peripheral\n");
600 return sprintf(buf
, "unknown\n");
603 static ssize_t
otg_mode_store(struct device
*device
,
604 struct device_attribute
*attr
,
605 const char *buf
, size_t count
)
607 struct tahvo_usb
*tu
= (struct tahvo_usb
*) device
->driver_data
;
611 mutex_lock(&tu
->serialize
);
612 if (strncmp(buf
, "host", 4) == 0) {
613 if (tu
->tahvo_mode
== TAHVO_MODE_PERIPHERAL
)
614 tahvo_usb_stop_peripheral(tu
);
615 tu
->tahvo_mode
= TAHVO_MODE_HOST
;
617 printk(KERN_INFO
"Selected HOST mode: host controller present.\n");
618 tahvo_usb_become_host(tu
);
620 printk(KERN_INFO
"Selected HOST mode: no host controller, powering off.\n");
621 tahvo_usb_power_off(tu
);
623 } else if (strncmp(buf
, "peripheral", 10) == 0) {
624 if (tu
->tahvo_mode
== TAHVO_MODE_HOST
)
625 tahvo_usb_stop_host(tu
);
626 tu
->tahvo_mode
= TAHVO_MODE_PERIPHERAL
;
627 if (tu
->otg
.gadget
) {
628 printk(KERN_INFO
"Selected PERIPHERAL mode: gadget driver present.\n");
629 tahvo_usb_become_peripheral(tu
);
631 printk(KERN_INFO
"Selected PERIPHERAL mode: no gadget driver, powering off.\n");
632 tahvo_usb_power_off(tu
);
637 mutex_unlock(&tu
->serialize
);
641 static DEVICE_ATTR(otg_mode
, 0644, otg_mode_show
, otg_mode_store
);
644 static int tahvo_usb_probe(struct device
*dev
)
646 struct tahvo_usb
*tu
;
649 dev_dbg(dev
, "probe\n");
651 /* Create driver data */
652 tu
= kmalloc(sizeof(*tu
), GFP_KERNEL
);
655 memset(tu
, 0, sizeof(*tu
));
656 tu
->pt_dev
= container_of(dev
, struct platform_device
, dev
);
657 #ifdef CONFIG_USB_OTG
659 #ifdef CONFIG_CBUS_TAHVO_USB_HOST_BY_DEFAULT
660 tu
->tahvo_mode
= TAHVO_MODE_HOST
;
662 tu
->tahvo_mode
= TAHVO_MODE_PERIPHERAL
;
666 INIT_WORK(&tu
->irq_work
, tahvo_usb_irq_work
);
667 mutex_init(&tu
->serialize
);
669 /* Set initial state, so that we generate kevents only on
671 tu
->vbus_state
= tahvo_read_reg(TAHVO_REG_IDSR
) & 0x01;
673 /* We cannot enable interrupt until omap_udc is initialized */
674 ret
= tahvo_request_irq(TAHVO_INT_VBUSON
, tahvo_usb_vbus_interrupt
,
675 (unsigned long) tu
, "vbus_interrupt");
678 printk(KERN_ERR
"Could not register Tahvo interrupt for VBUS\n");
683 ret
= device_create_file(dev
, &dev_attr_vbus_state
);
684 #ifdef CONFIG_USB_OTG
685 ret
|= device_create_file(dev
, &dev_attr_otg_mode
);
688 printk(KERN_ERR
"attribute creation failed: %d\n", ret
);
690 /* Create OTG interface */
691 tahvo_usb_power_off(tu
);
692 tu
->otg
.state
= OTG_STATE_UNDEFINED
;
693 tu
->otg
.label
= DRIVER_NAME
;
694 tu
->otg
.set_host
= tahvo_usb_set_host
;
695 tu
->otg
.set_peripheral
= tahvo_usb_set_peripheral
;
696 tu
->otg
.set_power
= tahvo_usb_set_power
;
697 tu
->otg
.set_suspend
= tahvo_usb_set_suspend
;
698 tu
->otg
.start_srp
= tahvo_usb_start_srp
;
699 tu
->otg
.start_hnp
= tahvo_usb_start_hnp
;
701 ret
= otg_set_transceiver(&tu
->otg
);
703 printk(KERN_ERR
"Cannot register USB transceiver\n");
705 tahvo_free_irq(TAHVO_INT_VBUSON
);
709 dev
->driver_data
= tu
;
711 /* Act upon current vbus state once at startup. A vbus state irq may or
712 * may not be generated in addition to this. */
713 schedule_work(&tu
->irq_work
);
717 static int tahvo_usb_remove(struct device
*dev
)
719 dev_dbg(dev
, "remove\n");
721 tahvo_free_irq(TAHVO_INT_VBUSON
);
722 flush_scheduled_work();
723 otg_set_transceiver(0);
724 device_remove_file(dev
, &dev_attr_vbus_state
);
725 #ifdef CONFIG_USB_OTG
726 device_remove_file(dev
, &dev_attr_otg_mode
);
731 static struct device_driver tahvo_usb_driver
= {
733 .bus
= &platform_bus_type
,
734 .probe
= tahvo_usb_probe
,
735 .remove
= tahvo_usb_remove
,
738 static struct platform_device tahvo_usb_device
= {
743 static int __init
tahvo_usb_init(void)
747 printk(KERN_INFO
"Tahvo USB transceiver driver initializing\n");
748 ret
= driver_register(&tahvo_usb_driver
);
751 ret
= platform_device_register(&tahvo_usb_device
);
753 driver_unregister(&tahvo_usb_driver
);
756 ret
= driver_register(&omap_otg_driver
);
758 platform_device_unregister(&tahvo_usb_device
);
759 driver_unregister(&tahvo_usb_driver
);
765 subsys_initcall(tahvo_usb_init
);
767 static void __exit
tahvo_usb_exit(void)
769 driver_unregister(&omap_otg_driver
);
770 platform_device_unregister(&tahvo_usb_device
);
771 driver_unregister(&tahvo_usb_driver
);
773 module_exit(tahvo_usb_exit
);
775 MODULE_DESCRIPTION("Tahvo USB OTG Transceiver Driver");
776 MODULE_LICENSE("GPL");
777 MODULE_AUTHOR("Juha Yrjölä, Tony Lindgren, and Timo Teräs");