]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/cbus/tahvo-usb.c
ARM: OMAP: Replace clock.h with clk.h
[linux-2.6-omap-h63xx.git] / drivers / cbus / tahvo-usb.c
1 /**
2  * drivers/cbus/tahvo-usb.c
3  *
4  * Tahvo USB transeiver
5  *
6  * Copyright (C) 2005 Nokia Corporation
7  *
8  * Written by Juha Yrjölä <juha.yrjola@nokia.com>,
9  *            Tony Lindgren <tony@atomide.com>, and
10  *            Timo Teräs <timo.teras@nokia.com>
11  *
12  * This file is subject to the terms and conditions of the GNU General
13  * Public License. See the file "COPYING" in the main directory of this
14  * archive for more details.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25
26 #include <linux/config.h>
27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/init.h>
30 #include <linux/slab.h>
31 #include <linux/interrupt.h>
32 #include <linux/device.h>
33 #include <linux/usb_ch9.h>
34 #include <linux/usb_gadget.h>
35 #include <linux/usb.h>
36 #include <linux/usb_otg.h>
37 #include <linux/i2c.h>
38 #include <linux/workqueue.h>
39 #include <linux/kobject_uevent.h>
40 #include <linux/clk.h>
41
42 #include <asm/irq.h>
43 #include <asm/semaphore.h>
44 #include <asm/arch/usb.h>
45
46 #include "cbus.h"
47 #include "tahvo.h"
48
49 #define DRIVER_NAME     "tahvo-usb"
50
51 #define USBR_SLAVE_CONTROL      (1 << 8)
52 #define USBR_VPPVIO_SW          (1 << 7)
53 #define USBR_SPEED              (1 << 6)
54 #define USBR_REGOUT             (1 << 5)
55 #define USBR_MASTER_SW2         (1 << 4)
56 #define USBR_MASTER_SW1         (1 << 3)
57 #define USBR_SLAVE_SW           (1 << 2)
58 #define USBR_NSUSPEND           (1 << 1)
59 #define USBR_SEMODE             (1 << 0)
60
61 /* bits in OTG_CTRL_REG */
62
63 /* Bits that are controlled by OMAP OTG and are read-only */
64 #define OTG_CTRL_OMAP_MASK      (OTG_PULLDOWN|OTG_PULLUP|OTG_DRV_VBUS|\
65                                 OTG_PD_VBUS|OTG_PU_VBUS|OTG_PU_ID)
66 /* Bits that are controlled by transceiver */
67 #define OTG_CTRL_XCVR_MASK      (OTG_ASESSVLD|OTG_BSESSEND|\
68                                 OTG_BSESSVLD|OTG_VBUSVLD|OTG_ID)
69 /* Bits that are controlled by system */
70 #define OTG_CTRL_SYS_MASK       (OTG_A_BUSREQ|OTG_A_SETB_HNPEN|OTG_B_BUSREQ|\
71                                 OTG_B_HNPEN|OTG_BUSDROP)
72
73 #if defined(CONFIG_USB_OHCI_HCD) && !defined(CONFIG_USB_OTG)
74 #error tahvo-otg.c does not work with OCHI yet!
75 #endif
76
77 #define TAHVO_MODE_HOST         0
78 #define TAHVO_MODE_PERIPHERAL   1
79
80 #ifdef CONFIG_USB_OTG
81 #define TAHVO_MODE(tu)          (tu)->tahvo_mode
82 #elif defined(CONFIG_USB_GADGET_OMAP)
83 #define TAHVO_MODE(tu)          TAHVO_MODE_PERIPHERAL
84 #else
85 #define TAHVO_MODE(tu)          TAHVO_MODE_HOST
86 #endif
87
88 extern int ohci_omap_host_enable(struct usb_bus *host, int enable);
89
90 struct tahvo_usb {
91         struct platform_device *pt_dev;
92         struct otg_transceiver otg;
93         int vbus_state;
94         struct work_struct irq_work;
95         struct semaphore serialize;
96 #ifdef CONFIG_USB_OTG
97         int tahvo_mode;
98 #endif
99 };
100 static struct platform_device tahvo_usb_device;
101
102 /*
103  * ---------------------------------------------------------------------------
104  * OTG related functions
105  *
106  * These shoud be separated into omap-otg.c driver module, as they are used
107  * by various transceivers. These functions are needed in the UDC-only case 
108  * as well. These functions are copied from GPL isp1301_omap.c
109  * ---------------------------------------------------------------------------
110  */
111 static struct platform_device *tahvo_otg_dev;
112
113 static irqreturn_t omap_otg_irq(int irq, void *arg, struct pt_regs *regs)
114 {
115         struct platform_device *otg_dev = (struct platform_device *) arg;
116         struct tahvo_usb *tu = (struct tahvo_usb *) otg_dev->dev.driver_data;
117         u16 otg_irq;
118
119         otg_irq = OTG_IRQ_SRC_REG;
120         if (otg_irq & OPRT_CHG) {
121                 OTG_IRQ_SRC_REG = OPRT_CHG;
122         } else if (otg_irq & B_SRP_TMROUT) {
123                 OTG_IRQ_SRC_REG = B_SRP_TMROUT;
124         } else if (otg_irq & B_HNP_FAIL) {
125                 OTG_IRQ_SRC_REG = B_HNP_FAIL;
126         } else if (otg_irq & A_SRP_DETECT) {
127                 OTG_IRQ_SRC_REG = A_SRP_DETECT;
128         } else if (otg_irq & A_REQ_TMROUT) {
129                 OTG_IRQ_SRC_REG = A_REQ_TMROUT;
130         } else if (otg_irq & A_VBUS_ERR) {
131                 OTG_IRQ_SRC_REG = A_VBUS_ERR;
132         } else if (otg_irq & DRIVER_SWITCH) {
133
134                 if ((!(OTG_CTRL_REG & OTG_DRIVER_SEL)) &&
135                    tu->otg.host && tu->otg.state == OTG_STATE_A_HOST) {
136                         /* role is host */
137                         usb_bus_start_enum(tu->otg.host,
138                                            tu->otg.host->otg_port);
139                 }
140
141                 OTG_IRQ_SRC_REG = DRIVER_SWITCH;
142         } else
143                 return IRQ_NONE;
144
145         return IRQ_HANDLED;
146
147 }
148
149 static int omap_otg_init(void)
150 {
151
152 #ifdef CONFIG_USB_OTG
153         if (!tahvo_otg_dev) {
154                 printk("tahvo-usb: no tahvo_otg_dev\n");
155                 return -ENODEV;
156         }
157 #endif
158
159         /* some of these values are board-specific... */
160         OTG_SYSCON_2_REG |= OTG_EN
161                 /* for B-device: */
162                 | SRP_GPDATA            /* 9msec Bdev D+ pulse */
163                 | SRP_GPDVBUS           /* discharge after VBUS pulse */
164                 // | (3 << 24)          /* 2msec VBUS pulse */
165                 /* for A-device: */
166                 | (0 << 20)             /* 200ms nominal A_WAIT_VRISE timer */
167                 | SRP_DPW               /* detect 167+ns SRP pulses */
168                 | SRP_DATA | SRP_VBUS;  /* accept both kinds of SRP pulse */
169
170         OTG_IRQ_EN_REG = DRIVER_SWITCH | OPRT_CHG
171                         | B_SRP_TMROUT | B_HNP_FAIL
172                         | A_VBUS_ERR | A_SRP_DETECT | A_REQ_TMROUT;
173         OTG_SYSCON_2_REG |= OTG_EN;
174
175         return 0;
176 }
177
178 static int omap_otg_probe(struct device *dev)
179 {
180         int ret;
181
182         tahvo_otg_dev = to_platform_device(dev);
183         ret = omap_otg_init();
184         if (ret != 0) {
185                 printk(KERN_ERR "tahvo-usb: omap_otg_init failed\n");
186                 return ret;
187         }
188
189         return request_irq(tahvo_otg_dev->resource[1].start,
190                            omap_otg_irq, SA_INTERRUPT, DRIVER_NAME,
191                            &tahvo_usb_device);
192 }
193
194 static int omap_otg_remove(struct device *dev)
195 {
196         tahvo_otg_dev = NULL;
197         free_irq(tahvo_otg_dev->resource[1].start, &tahvo_usb_device);
198         return 0;
199 }
200
201 struct device_driver omap_otg_driver = {
202         .name           = "omap_otg",
203         .bus            = &platform_bus_type,
204         .probe          = omap_otg_probe,
205         .remove         = omap_otg_remove,
206 };
207
208 /*
209  * ---------------------------------------------------------------------------
210  * Tahvo related functions
211  * These are Nokia proprietary code, except for the OTG register settings,
212  * which are copied from isp1301.c
213  * ---------------------------------------------------------------------------
214  */
215 static ssize_t vbus_state_show(struct device *device, char *buf)
216 {
217         struct tahvo_usb *tu = (struct tahvo_usb*) device->driver_data;
218         return sprintf(buf, "%d\n", tu->vbus_state);
219 }
220 static DEVICE_ATTR(vbus_state, 0444, vbus_state_show, NULL);
221
222 int vbus_active = 0;
223
224 static void check_vbus_state(struct tahvo_usb *tu)
225 {
226         int reg, prev_state;
227
228         reg = tahvo_read_reg(TAHVO_REG_IDSR);
229         if (reg & 0x01) {
230                 vbus_active = 1;
231                 switch (tu->otg.state) {
232                 case OTG_STATE_B_IDLE:
233                         /* Enable the gadget driver */
234                         if (tu->otg.gadget)
235                                 usb_gadget_vbus_connect(tu->otg.gadget);
236                         /* Set B-session valid and not B-sessio ended to indicate
237                          * Vbus to be ok. */
238                         OTG_CTRL_REG = (OTG_CTRL_REG & ~OTG_BSESSEND) | OTG_BSESSVLD;
239
240                         tu->otg.state = OTG_STATE_B_PERIPHERAL;
241                         break;
242                 case OTG_STATE_A_IDLE:
243                         /* Session is now valid assuming the USB hub is driving Vbus */
244                         tu->otg.state = OTG_STATE_A_HOST;
245                         if (tu->otg.host)
246                                 ohci_omap_host_enable(tu->otg.host, 1);
247                         break;
248                 default:
249                         break;
250                 }
251                 printk("USB cable connected\n");
252         } else {
253                 vbus_active = 0;
254                 switch (tu->otg.state) {
255                 case OTG_STATE_B_PERIPHERAL:
256                         OTG_CTRL_REG = (OTG_CTRL_REG & ~OTG_BSESSVLD) | OTG_BSESSEND;
257                         if (tu->otg.gadget)
258                                 usb_gadget_vbus_disconnect(tu->otg.gadget);
259                         tu->otg.state = OTG_STATE_B_IDLE;
260                         break;
261                 case OTG_STATE_A_HOST:
262                         tu->otg.state = OTG_STATE_A_IDLE;
263                         if (tu->otg.host)
264                                 ohci_omap_host_enable(tu->otg.host, 0);
265
266                         break;
267                 default:
268                         break;
269                 }
270                 printk("USB cable disconnected\n");
271         }
272
273         prev_state = tu->vbus_state;
274         tu->vbus_state = reg & 0x01;
275         if (prev_state != tu->vbus_state) {
276                 kobject_uevent_atomic(&tu->pt_dev->dev.kobj,
277                                       KOBJ_CHANGE,
278                                       &dev_attr_vbus_state.attr);
279         }
280 }
281
282 static void tahvo_usb_become_host(struct tahvo_usb *tu)
283 {
284         /* Clear system and transceiver controlled bits
285          * also mark the A-session is always valid */
286         omap_otg_init();
287         OTG_CTRL_REG = (OTG_CTRL_REG & ~(OTG_CTRL_XCVR_MASK|OTG_CTRL_SYS_MASK))
288                 | OTG_ASESSVLD;
289
290         /* Power up the transceiver in USB host mode */
291         tahvo_write_reg(TAHVO_REG_USBR, USBR_REGOUT | USBR_NSUSPEND |
292                         USBR_MASTER_SW2 | USBR_MASTER_SW1);
293         tu->otg.state = OTG_STATE_A_IDLE;
294
295         check_vbus_state(tu);
296 }
297
298 static void tahvo_usb_stop_host(struct tahvo_usb *tu)
299 {
300         if (tu->otg.host)
301                 ohci_omap_host_enable(tu->otg.host, 0);
302         tu->otg.state = OTG_STATE_A_IDLE;
303 }
304
305 static void tahvo_usb_become_peripheral(struct tahvo_usb *tu)
306 {
307         /* Clear system and transceiver controlled bits
308          * and enable ID to mark peripheral mode and
309          * BSESSEND to mark no Vbus */
310         omap_otg_init();
311         OTG_CTRL_REG = (OTG_CTRL_REG & ~(OTG_CTRL_XCVR_MASK|OTG_CTRL_SYS_MASK))
312                 | OTG_ID | OTG_BSESSEND;
313
314         /* Power up transceiver and set it in USB perhiperal mode */
315         tahvo_write_reg(TAHVO_REG_USBR, USBR_SLAVE_CONTROL | USBR_REGOUT | USBR_NSUSPEND | USBR_SLAVE_SW);
316         tu->otg.state = OTG_STATE_B_IDLE;
317
318         check_vbus_state(tu);
319 }
320
321 static void tahvo_usb_stop_peripheral(struct tahvo_usb *tu)
322 {
323         OTG_CTRL_REG = (OTG_CTRL_REG & ~OTG_BSESSVLD) | OTG_BSESSEND;
324         if (tu->otg.gadget)
325                 usb_gadget_vbus_disconnect(tu->otg.gadget);
326         tu->otg.state = OTG_STATE_B_IDLE;
327
328 }
329
330 static void tahvo_usb_power_off(struct tahvo_usb *tu)
331 {
332         int id;
333
334         /* Disable gadget controller if any */
335         if (tu->otg.gadget)
336                 usb_gadget_vbus_disconnect(tu->otg.gadget);
337
338         if (tu->otg.host)
339                 ohci_omap_host_enable(tu->otg.host, 0);
340
341         /* Disable OTG and interrupts */
342         if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
343                 id = OTG_ID;
344         else    id = 0;
345         OTG_CTRL_REG = (OTG_CTRL_REG & ~(OTG_CTRL_XCVR_MASK|OTG_CTRL_SYS_MASK)) | id;
346         OTG_IRQ_EN_REG = 0;
347 #if 0
348         OTG_SYSCON_2_REG &= ~OTG_EN;
349 #endif
350
351         /* Power off transceiver */
352         tahvo_write_reg(TAHVO_REG_USBR, 0);
353         tu->otg.state = OTG_STATE_UNDEFINED;
354 }
355
356
357 static int tahvo_usb_set_power(struct otg_transceiver *dev, unsigned mA)
358 {
359         if (dev->state == OTG_STATE_B_PERIPHERAL) {
360                 /* REVISIT: Can Tahvo charge battery from VBUS? */
361         }
362         return 0;
363 }
364
365 static int tahvo_usb_set_suspend(struct otg_transceiver *dev, int suspend)
366 {
367         u16 w;
368
369         w = tahvo_read_reg(TAHVO_REG_USBR);
370         if (suspend)
371                 w &= ~USBR_NSUSPEND;
372         else
373                 w |= USBR_NSUSPEND;
374         tahvo_write_reg(TAHVO_REG_USBR, w);
375
376         return 0;
377 }
378
379 static int tahvo_usb_start_srp(struct otg_transceiver *dev)
380 {
381         struct tahvo_usb *tu = container_of(dev, struct tahvo_usb, otg);
382         u32 otg_ctrl;
383
384         if (!dev || tu->otg.state != OTG_STATE_B_IDLE)
385                 return -ENODEV;
386
387         otg_ctrl = OTG_CTRL_REG;
388         if (!(otg_ctrl & OTG_BSESSEND))
389                 return -EINVAL;
390
391         otg_ctrl |= OTG_B_BUSREQ;
392         otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_SYS_MASK;
393         OTG_CTRL_REG = otg_ctrl;
394         tu->otg.state = OTG_STATE_B_SRP_INIT;
395
396         pr_debug("otg: SRP, %s ... %06x\n", state_name(tu), OTG_CTRL_REG);
397
398         return 0;
399 }
400
401 static int tahvo_usb_start_hnp(struct otg_transceiver *dev)
402 {
403 #ifdef CONFIG_USB_OTG
404         /* REVISIT: Add this for OTG */
405 #endif
406         return -EINVAL;
407 }
408
409 static int tahvo_usb_set_host(struct otg_transceiver *otg, struct usb_bus *host)
410 {
411         struct tahvo_usb *tu = container_of(otg, struct tahvo_usb, otg);
412
413         if (!otg)
414                 return -ENODEV;
415
416 #if defined(CONFIG_USB_OTG) || !defined(CONFIG_USB_GADGET_OMAP)
417
418         down(&tu->serialize);
419
420         if (!host) {
421                 if (TAHVO_MODE(tu) == TAHVO_MODE_HOST)
422                         tahvo_usb_power_off(tu);
423                 tu->otg.host = 0;
424                 up(&tu->serialize);
425                 return 0;
426         }
427
428         if (TAHVO_MODE(tu) == TAHVO_MODE_HOST) {
429                 tu->otg.host = 0;
430                 tahvo_usb_become_host(tu);
431         } else
432                 ohci_omap_host_enable(host, 0);
433
434         tu->otg.host = host;
435
436         up(&tu->serialize);
437 #else
438         /* No host mode configured, so do not allow host controlled to be set */
439         return -EINVAL;
440 #endif
441
442         return 0;
443 }
444
445 static int tahvo_usb_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
446 {
447         struct tahvo_usb *tu = container_of(otg, struct tahvo_usb, otg);
448
449         if (!otg)
450                 return -ENODEV;
451
452 #if defined(CONFIG_USB_OTG) || defined(CONFIG_USB_GADGET_OMAP)
453
454         down(&tu->serialize);
455
456         if (!gadget) {
457                 if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
458                         tahvo_usb_power_off(tu);
459                 tu->otg.gadget = 0;
460                 up(&tu->serialize);
461                 return 0;
462         }
463
464         tu->otg.gadget = gadget;
465         if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
466                 tahvo_usb_become_peripheral(tu);
467
468         up(&tu->serialize);
469 #else
470         /* No gadget mode configured, so do not allow host controlled to be set */
471         return -EINVAL;
472 #endif
473
474         return 0;
475 }
476
477 static void tahvo_usb_irq_work(void *data)
478 {
479         struct tahvo_usb *tu = (struct tahvo_usb *)data;
480
481         down(&tu->serialize);
482         check_vbus_state(tu);
483         up(&tu->serialize);
484 }
485
486 static void tahvo_usb_vbus_interrupt(unsigned long arg)
487 {
488         struct tahvo_usb *tu = (struct tahvo_usb *) arg;
489
490         tahvo_ack_irq(TAHVO_INT_VBUSON);
491         /* Seems we need this to acknowledge the interrupt */
492         tahvo_read_reg(TAHVO_REG_IDSR);
493         schedule_work(&tu->irq_work);
494 }
495
496 #ifdef CONFIG_USB_OTG
497 static ssize_t otg_mode_show(struct device *device, char *buf)
498 {
499         struct tahvo_usb *tu = (struct tahvo_usb*) device->driver_data;
500         switch (tu->tahvo_mode) {
501         case TAHVO_MODE_HOST:
502                 return sprintf(buf, "host\n");
503         case TAHVO_MODE_PERIPHERAL:
504                 return sprintf(buf, "peripheral\n");
505         }
506         return sprintf(buf, "unknown\n");
507 }
508
509 static ssize_t otg_mode_store(struct device *device, const char *buf, size_t count)
510 {
511         struct tahvo_usb *tu = (struct tahvo_usb*) device->driver_data;
512         int r;
513
514         r = strlen(buf);
515         down(&tu->serialize);
516         if (strncmp(buf, "host", 4) == 0) {
517                 if (tu->tahvo_mode == TAHVO_MODE_PERIPHERAL)
518                         tahvo_usb_stop_peripheral(tu);
519                 tu->tahvo_mode = TAHVO_MODE_HOST;
520                 if (tu->otg.host) {
521                         printk(KERN_INFO "Selected HOST mode: host controller present.\n");
522                         tahvo_usb_become_host(tu);
523                 } else {
524                         printk(KERN_INFO "Selected HOST mode: no host controller, powering off.\n");
525                         tahvo_usb_power_off(tu);
526                 }
527         } else if (strncmp(buf, "peripheral", 10) == 0) {
528                 if (tu->tahvo_mode == TAHVO_MODE_HOST)
529                         tahvo_usb_stop_host(tu);
530                 tu->tahvo_mode = TAHVO_MODE_PERIPHERAL;
531                 if (tu->otg.gadget) {
532                         printk(KERN_INFO "Selected PERIPHERAL mode: gadget driver present.\n");
533                         tahvo_usb_become_peripheral(tu);
534                 } else {
535                         printk(KERN_INFO "Selected PERIPHERAL mode: no gadget driver, powering off.\n");
536                         tahvo_usb_power_off(tu);
537                 }
538         } else
539                 r = -EINVAL;
540
541         up(&tu->serialize);
542         return r;
543 }
544
545 static DEVICE_ATTR(otg_mode, 0644, otg_mode_show, otg_mode_store);
546 #endif
547
548 static int tahvo_usb_probe(struct device *dev)
549 {
550         struct tahvo_usb *tu;
551         int ret;
552
553         /* Create driver data */
554         tu = kmalloc(sizeof(*tu), GFP_KERNEL);
555         if (!tu)
556                 return -ENOMEM;
557         memset(tu, 0, sizeof(*tu));
558         tu->pt_dev = container_of(dev, struct platform_device, dev);
559 #ifdef CONFIG_USB_OTG
560         /* Default mode */
561 #ifdef CONFIG_CBUS_TAHVO_USB_HOST_BY_DEFAULT
562         tu->tahvo_mode = TAHVO_MODE_HOST;
563 #else
564         tu->tahvo_mode = TAHVO_MODE_PERIPHERAL;
565 #endif
566 #endif
567
568         INIT_WORK(&tu->irq_work, tahvo_usb_irq_work, tu);
569         init_MUTEX(&tu->serialize);
570
571         /* Set initial state, so that we generate kevents only on
572          * state changes */
573         tu->vbus_state = tahvo_read_reg(TAHVO_REG_IDSR) & 0x01;
574
575         /* We cannot enable interrupt until omap_udc is initialized */
576         ret = tahvo_request_irq(TAHVO_INT_VBUSON, tahvo_usb_vbus_interrupt,
577                                 (unsigned long) tu, "vbus_interrupt");
578         if (ret != 0) {
579                 kfree(tu);
580                 printk(KERN_ERR "Could not register Tahvo interrupt for VBUS\n");
581                 return ret;
582         }
583
584         /* Attributes */
585         device_create_file(dev, &dev_attr_vbus_state);
586 #ifdef CONFIG_USB_OTG
587         device_create_file(dev, &dev_attr_otg_mode);
588 #endif
589
590         /* Create OTG interface */
591         tahvo_usb_power_off(tu);
592         tu->otg.state = OTG_STATE_UNDEFINED;
593         tu->otg.label = DRIVER_NAME;
594         tu->otg.set_host = tahvo_usb_set_host;
595         tu->otg.set_peripheral = tahvo_usb_set_peripheral;
596         tu->otg.set_power = tahvo_usb_set_power;
597         tu->otg.set_suspend = tahvo_usb_set_suspend;
598         tu->otg.start_srp = tahvo_usb_start_srp;
599         tu->otg.start_hnp = tahvo_usb_start_hnp;
600
601         ret = otg_set_transceiver(&tu->otg);
602         if (ret < 0) {
603                 printk(KERN_ERR "Cannot register USB transceiver\n");
604                 kfree(tu);
605                 tahvo_free_irq(TAHVO_INT_VBUSON);
606                 return ret;
607         }
608
609         dev->driver_data = tu;
610
611         /* Act upon current vbus state once at startup. A vbus state irq may or
612          * may not be generated in addition to this. */
613         schedule_work(&tu->irq_work);
614         return 0;
615 }
616
617 static int tahvo_usb_remove(struct device *dev)
618 {
619         tahvo_free_irq(TAHVO_INT_VBUSON);
620         flush_scheduled_work();
621         otg_set_transceiver(0);
622         device_remove_file(dev, &dev_attr_vbus_state);
623 #ifdef CONFIG_USB_OTG
624         device_remove_file(dev, &dev_attr_otg_mode);
625 #endif
626         return 0;
627 }
628
629 static struct device_driver tahvo_usb_driver = {
630         .name           = "tahvo-usb",
631         .bus            = &platform_bus_type,
632         .probe          = tahvo_usb_probe,
633         .remove         = tahvo_usb_remove,
634 };
635
636 static struct platform_device tahvo_usb_device = {
637         .name           = "tahvo-usb",
638         .id             = -1,
639 };
640
641 static int __init tahvo_usb_init(void)
642 {
643         int ret = 0;
644
645         printk(KERN_INFO "Tahvo USB transceiver driver initializing\n");
646         ret = driver_register(&tahvo_usb_driver);
647         if (ret)
648                 return ret;
649         ret = platform_device_register(&tahvo_usb_device);
650         if (ret < 0) {
651                 driver_unregister(&tahvo_usb_driver);
652                 return ret;
653         }
654         ret = driver_register(&omap_otg_driver);
655         if (ret) {
656                 platform_device_unregister(&tahvo_usb_device);
657                 driver_unregister(&tahvo_usb_driver);
658                 return ret;
659         }
660         return 0;
661 }
662
663 subsys_initcall(tahvo_usb_init);
664
665 static void __exit tahvo_usb_exit(void)
666 {
667         driver_unregister(&omap_otg_driver);
668         platform_device_unregister(&tahvo_usb_device);
669         driver_unregister(&tahvo_usb_driver);
670 }
671 module_exit(tahvo_usb_exit);
672
673 MODULE_DESCRIPTION("Tahvo USB OTG Transceiver Driver");
674 MODULE_LICENSE("GPL");
675 MODULE_AUTHOR("Juha Yrjölä, Tony Lindgren, and Timo Teräs");