]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/cbus/tahvo-usb.c
a002fb71585e88d9e605b1a0179af81e313041fc
[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/platform_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.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,
216                                struct device_attribute *attr, char *buf)
217 {
218         struct tahvo_usb *tu = (struct tahvo_usb*) device->driver_data;
219         return sprintf(buf, "%d\n", tu->vbus_state);
220 }
221 static DEVICE_ATTR(vbus_state, 0444, vbus_state_show, NULL);
222
223 int vbus_active = 0;
224
225 static void check_vbus_state(struct tahvo_usb *tu)
226 {
227         int reg, prev_state;
228
229         reg = tahvo_read_reg(TAHVO_REG_IDSR);
230         if (reg & 0x01) {
231                 vbus_active = 1;
232                 switch (tu->otg.state) {
233                 case OTG_STATE_B_IDLE:
234                         /* Enable the gadget driver */
235                         if (tu->otg.gadget)
236                                 usb_gadget_vbus_connect(tu->otg.gadget);
237                         /* Set B-session valid and not B-sessio ended to indicate
238                          * Vbus to be ok. */
239                         OTG_CTRL_REG = (OTG_CTRL_REG & ~OTG_BSESSEND) | OTG_BSESSVLD;
240
241                         tu->otg.state = OTG_STATE_B_PERIPHERAL;
242                         break;
243                 case OTG_STATE_A_IDLE:
244                         /* Session is now valid assuming the USB hub is driving Vbus */
245                         tu->otg.state = OTG_STATE_A_HOST;
246                         if (tu->otg.host)
247                                 ohci_omap_host_enable(tu->otg.host, 1);
248                         break;
249                 default:
250                         break;
251                 }
252                 printk("USB cable connected\n");
253         } else {
254                 vbus_active = 0;
255                 switch (tu->otg.state) {
256                 case OTG_STATE_B_PERIPHERAL:
257                         OTG_CTRL_REG = (OTG_CTRL_REG & ~OTG_BSESSVLD) | OTG_BSESSEND;
258                         if (tu->otg.gadget)
259                                 usb_gadget_vbus_disconnect(tu->otg.gadget);
260                         tu->otg.state = OTG_STATE_B_IDLE;
261                         break;
262                 case OTG_STATE_A_HOST:
263                         tu->otg.state = OTG_STATE_A_IDLE;
264                         if (tu->otg.host)
265                                 ohci_omap_host_enable(tu->otg.host, 0);
266
267                         break;
268                 default:
269                         break;
270                 }
271                 printk("USB cable disconnected\n");
272         }
273
274         prev_state = tu->vbus_state;
275         tu->vbus_state = reg & 0x01;
276         if (prev_state != tu->vbus_state)
277                 kobject_uevent(&tu->pt_dev->dev.kobj, KOBJ_CHANGE);
278 }
279
280 static void tahvo_usb_become_host(struct tahvo_usb *tu)
281 {
282         /* Clear system and transceiver controlled bits
283          * also mark the A-session is always valid */
284         omap_otg_init();
285         OTG_CTRL_REG = (OTG_CTRL_REG & ~(OTG_CTRL_XCVR_MASK|OTG_CTRL_SYS_MASK))
286                 | OTG_ASESSVLD;
287
288         /* Power up the transceiver in USB host mode */
289         tahvo_write_reg(TAHVO_REG_USBR, USBR_REGOUT | USBR_NSUSPEND |
290                         USBR_MASTER_SW2 | USBR_MASTER_SW1);
291         tu->otg.state = OTG_STATE_A_IDLE;
292
293         check_vbus_state(tu);
294 }
295
296 static void tahvo_usb_stop_host(struct tahvo_usb *tu)
297 {
298         if (tu->otg.host)
299                 ohci_omap_host_enable(tu->otg.host, 0);
300         tu->otg.state = OTG_STATE_A_IDLE;
301 }
302
303 static void tahvo_usb_become_peripheral(struct tahvo_usb *tu)
304 {
305         /* Clear system and transceiver controlled bits
306          * and enable ID to mark peripheral mode and
307          * BSESSEND to mark no Vbus */
308         omap_otg_init();
309         OTG_CTRL_REG = (OTG_CTRL_REG & ~(OTG_CTRL_XCVR_MASK|OTG_CTRL_SYS_MASK))
310                 | OTG_ID | OTG_BSESSEND;
311
312         /* Power up transceiver and set it in USB perhiperal mode */
313         tahvo_write_reg(TAHVO_REG_USBR, USBR_SLAVE_CONTROL | USBR_REGOUT | USBR_NSUSPEND | USBR_SLAVE_SW);
314         tu->otg.state = OTG_STATE_B_IDLE;
315
316         check_vbus_state(tu);
317 }
318
319 static void tahvo_usb_stop_peripheral(struct tahvo_usb *tu)
320 {
321         OTG_CTRL_REG = (OTG_CTRL_REG & ~OTG_BSESSVLD) | OTG_BSESSEND;
322         if (tu->otg.gadget)
323                 usb_gadget_vbus_disconnect(tu->otg.gadget);
324         tu->otg.state = OTG_STATE_B_IDLE;
325
326 }
327
328 static void tahvo_usb_power_off(struct tahvo_usb *tu)
329 {
330         int id;
331
332         /* Disable gadget controller if any */
333         if (tu->otg.gadget)
334                 usb_gadget_vbus_disconnect(tu->otg.gadget);
335
336         if (tu->otg.host)
337                 ohci_omap_host_enable(tu->otg.host, 0);
338
339         /* Disable OTG and interrupts */
340         if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
341                 id = OTG_ID;
342         else    id = 0;
343         OTG_CTRL_REG = (OTG_CTRL_REG & ~(OTG_CTRL_XCVR_MASK|OTG_CTRL_SYS_MASK)) | id;
344         OTG_IRQ_EN_REG = 0;
345 #if 0
346         OTG_SYSCON_2_REG &= ~OTG_EN;
347 #endif
348
349         /* Power off transceiver */
350         tahvo_write_reg(TAHVO_REG_USBR, 0);
351         tu->otg.state = OTG_STATE_UNDEFINED;
352 }
353
354
355 static int tahvo_usb_set_power(struct otg_transceiver *dev, unsigned mA)
356 {
357         if (dev->state == OTG_STATE_B_PERIPHERAL) {
358                 /* REVISIT: Can Tahvo charge battery from VBUS? */
359         }
360         return 0;
361 }
362
363 static int tahvo_usb_set_suspend(struct otg_transceiver *dev, int suspend)
364 {
365         u16 w;
366
367         w = tahvo_read_reg(TAHVO_REG_USBR);
368         if (suspend)
369                 w &= ~USBR_NSUSPEND;
370         else
371                 w |= USBR_NSUSPEND;
372         tahvo_write_reg(TAHVO_REG_USBR, w);
373
374         return 0;
375 }
376
377 static int tahvo_usb_start_srp(struct otg_transceiver *dev)
378 {
379         struct tahvo_usb *tu = container_of(dev, struct tahvo_usb, otg);
380         u32 otg_ctrl;
381
382         if (!dev || tu->otg.state != OTG_STATE_B_IDLE)
383                 return -ENODEV;
384
385         otg_ctrl = OTG_CTRL_REG;
386         if (!(otg_ctrl & OTG_BSESSEND))
387                 return -EINVAL;
388
389         otg_ctrl |= OTG_B_BUSREQ;
390         otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_SYS_MASK;
391         OTG_CTRL_REG = otg_ctrl;
392         tu->otg.state = OTG_STATE_B_SRP_INIT;
393
394         pr_debug("otg: SRP, %s ... %06x\n", state_name(tu), OTG_CTRL_REG);
395
396         return 0;
397 }
398
399 static int tahvo_usb_start_hnp(struct otg_transceiver *dev)
400 {
401 #ifdef CONFIG_USB_OTG
402         /* REVISIT: Add this for OTG */
403 #endif
404         return -EINVAL;
405 }
406
407 static int tahvo_usb_set_host(struct otg_transceiver *otg, struct usb_bus *host)
408 {
409         struct tahvo_usb *tu = container_of(otg, struct tahvo_usb, otg);
410
411         if (!otg)
412                 return -ENODEV;
413
414 #if defined(CONFIG_USB_OTG) || !defined(CONFIG_USB_GADGET_OMAP)
415
416         down(&tu->serialize);
417
418         if (!host) {
419                 if (TAHVO_MODE(tu) == TAHVO_MODE_HOST)
420                         tahvo_usb_power_off(tu);
421                 tu->otg.host = 0;
422                 up(&tu->serialize);
423                 return 0;
424         }
425
426         if (TAHVO_MODE(tu) == TAHVO_MODE_HOST) {
427                 tu->otg.host = 0;
428                 tahvo_usb_become_host(tu);
429         } else
430                 ohci_omap_host_enable(host, 0);
431
432         tu->otg.host = host;
433
434         up(&tu->serialize);
435 #else
436         /* No host mode configured, so do not allow host controlled to be set */
437         return -EINVAL;
438 #endif
439
440         return 0;
441 }
442
443 static int tahvo_usb_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
444 {
445         struct tahvo_usb *tu = container_of(otg, struct tahvo_usb, otg);
446
447         if (!otg)
448                 return -ENODEV;
449
450 #if defined(CONFIG_USB_OTG) || defined(CONFIG_USB_GADGET_OMAP)
451
452         down(&tu->serialize);
453
454         if (!gadget) {
455                 if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
456                         tahvo_usb_power_off(tu);
457                 tu->otg.gadget = 0;
458                 up(&tu->serialize);
459                 return 0;
460         }
461
462         tu->otg.gadget = gadget;
463         if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
464                 tahvo_usb_become_peripheral(tu);
465
466         up(&tu->serialize);
467 #else
468         /* No gadget mode configured, so do not allow host controlled to be set */
469         return -EINVAL;
470 #endif
471
472         return 0;
473 }
474
475 static void tahvo_usb_irq_work(void *data)
476 {
477         struct tahvo_usb *tu = (struct tahvo_usb *)data;
478
479         down(&tu->serialize);
480         check_vbus_state(tu);
481         up(&tu->serialize);
482 }
483
484 static void tahvo_usb_vbus_interrupt(unsigned long arg)
485 {
486         struct tahvo_usb *tu = (struct tahvo_usb *) arg;
487
488         tahvo_ack_irq(TAHVO_INT_VBUSON);
489         /* Seems we need this to acknowledge the interrupt */
490         tahvo_read_reg(TAHVO_REG_IDSR);
491         schedule_work(&tu->irq_work);
492 }
493
494 #ifdef CONFIG_USB_OTG
495 static ssize_t otg_mode_show(struct device *device,
496                              struct device_attribute *attr, char *buf)
497 {
498         struct tahvo_usb *tu = (struct tahvo_usb*) device->driver_data;
499         switch (tu->tahvo_mode) {
500         case TAHVO_MODE_HOST:
501                 return sprintf(buf, "host\n");
502         case TAHVO_MODE_PERIPHERAL:
503                 return sprintf(buf, "peripheral\n");
504         }
505         return sprintf(buf, "unknown\n");
506 }
507
508 static ssize_t otg_mode_store(struct device *device,
509                               struct device_attribute *attr,
510                               const char *buf, size_t count)
511 {
512         struct tahvo_usb *tu = (struct tahvo_usb*) device->driver_data;
513         int r;
514
515         r = strlen(buf);
516         down(&tu->serialize);
517         if (strncmp(buf, "host", 4) == 0) {
518                 if (tu->tahvo_mode == TAHVO_MODE_PERIPHERAL)
519                         tahvo_usb_stop_peripheral(tu);
520                 tu->tahvo_mode = TAHVO_MODE_HOST;
521                 if (tu->otg.host) {
522                         printk(KERN_INFO "Selected HOST mode: host controller present.\n");
523                         tahvo_usb_become_host(tu);
524                 } else {
525                         printk(KERN_INFO "Selected HOST mode: no host controller, powering off.\n");
526                         tahvo_usb_power_off(tu);
527                 }
528         } else if (strncmp(buf, "peripheral", 10) == 0) {
529                 if (tu->tahvo_mode == TAHVO_MODE_HOST)
530                         tahvo_usb_stop_host(tu);
531                 tu->tahvo_mode = TAHVO_MODE_PERIPHERAL;
532                 if (tu->otg.gadget) {
533                         printk(KERN_INFO "Selected PERIPHERAL mode: gadget driver present.\n");
534                         tahvo_usb_become_peripheral(tu);
535                 } else {
536                         printk(KERN_INFO "Selected PERIPHERAL mode: no gadget driver, powering off.\n");
537                         tahvo_usb_power_off(tu);
538                 }
539         } else
540                 r = -EINVAL;
541
542         up(&tu->serialize);
543         return r;
544 }
545
546 static DEVICE_ATTR(otg_mode, 0644, otg_mode_show, otg_mode_store);
547 #endif
548
549 static int tahvo_usb_probe(struct device *dev)
550 {
551         struct tahvo_usb *tu;
552         int ret;
553
554         /* Create driver data */
555         tu = kmalloc(sizeof(*tu), GFP_KERNEL);
556         if (!tu)
557                 return -ENOMEM;
558         memset(tu, 0, sizeof(*tu));
559         tu->pt_dev = container_of(dev, struct platform_device, dev);
560 #ifdef CONFIG_USB_OTG
561         /* Default mode */
562 #ifdef CONFIG_CBUS_TAHVO_USB_HOST_BY_DEFAULT
563         tu->tahvo_mode = TAHVO_MODE_HOST;
564 #else
565         tu->tahvo_mode = TAHVO_MODE_PERIPHERAL;
566 #endif
567 #endif
568
569         INIT_WORK(&tu->irq_work, tahvo_usb_irq_work, tu);
570         init_MUTEX(&tu->serialize);
571
572         /* Set initial state, so that we generate kevents only on
573          * state changes */
574         tu->vbus_state = tahvo_read_reg(TAHVO_REG_IDSR) & 0x01;
575
576         /* We cannot enable interrupt until omap_udc is initialized */
577         ret = tahvo_request_irq(TAHVO_INT_VBUSON, tahvo_usb_vbus_interrupt,
578                                 (unsigned long) tu, "vbus_interrupt");
579         if (ret != 0) {
580                 kfree(tu);
581                 printk(KERN_ERR "Could not register Tahvo interrupt for VBUS\n");
582                 return ret;
583         }
584
585         /* Attributes */
586         device_create_file(dev, &dev_attr_vbus_state);
587 #ifdef CONFIG_USB_OTG
588         device_create_file(dev, &dev_attr_otg_mode);
589 #endif
590
591         /* Create OTG interface */
592         tahvo_usb_power_off(tu);
593         tu->otg.state = OTG_STATE_UNDEFINED;
594         tu->otg.label = DRIVER_NAME;
595         tu->otg.set_host = tahvo_usb_set_host;
596         tu->otg.set_peripheral = tahvo_usb_set_peripheral;
597         tu->otg.set_power = tahvo_usb_set_power;
598         tu->otg.set_suspend = tahvo_usb_set_suspend;
599         tu->otg.start_srp = tahvo_usb_start_srp;
600         tu->otg.start_hnp = tahvo_usb_start_hnp;
601
602         ret = otg_set_transceiver(&tu->otg);
603         if (ret < 0) {
604                 printk(KERN_ERR "Cannot register USB transceiver\n");
605                 kfree(tu);
606                 tahvo_free_irq(TAHVO_INT_VBUSON);
607                 return ret;
608         }
609
610         dev->driver_data = tu;
611
612         /* Act upon current vbus state once at startup. A vbus state irq may or
613          * may not be generated in addition to this. */
614         schedule_work(&tu->irq_work);
615         return 0;
616 }
617
618 static int tahvo_usb_remove(struct device *dev)
619 {
620         tahvo_free_irq(TAHVO_INT_VBUSON);
621         flush_scheduled_work();
622         otg_set_transceiver(0);
623         device_remove_file(dev, &dev_attr_vbus_state);
624 #ifdef CONFIG_USB_OTG
625         device_remove_file(dev, &dev_attr_otg_mode);
626 #endif
627         return 0;
628 }
629
630 static struct device_driver tahvo_usb_driver = {
631         .name           = "tahvo-usb",
632         .bus            = &platform_bus_type,
633         .probe          = tahvo_usb_probe,
634         .remove         = tahvo_usb_remove,
635 };
636
637 static struct platform_device tahvo_usb_device = {
638         .name           = "tahvo-usb",
639         .id             = -1,
640 };
641
642 static int __init tahvo_usb_init(void)
643 {
644         int ret = 0;
645
646         printk(KERN_INFO "Tahvo USB transceiver driver initializing\n");
647         ret = driver_register(&tahvo_usb_driver);
648         if (ret)
649                 return ret;
650         ret = platform_device_register(&tahvo_usb_device);
651         if (ret < 0) {
652                 driver_unregister(&tahvo_usb_driver);
653                 return ret;
654         }
655         ret = driver_register(&omap_otg_driver);
656         if (ret) {
657                 platform_device_unregister(&tahvo_usb_device);
658                 driver_unregister(&tahvo_usb_driver);
659                 return ret;
660         }
661         return 0;
662 }
663
664 subsys_initcall(tahvo_usb_init);
665
666 static void __exit tahvo_usb_exit(void)
667 {
668         driver_unregister(&omap_otg_driver);
669         platform_device_unregister(&tahvo_usb_device);
670         driver_unregister(&tahvo_usb_driver);
671 }
672 module_exit(tahvo_usb_exit);
673
674 MODULE_DESCRIPTION("Tahvo USB OTG Transceiver Driver");
675 MODULE_LICENSE("GPL");
676 MODULE_AUTHOR("Juha Yrjölä, Tony Lindgren, and Timo Teräs");