2 * drivers/cbus/tahvo-usb.c
6 * Copyright (C) 2005 Nokia Corporation
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>
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.
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.
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
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>
43 #include <asm/semaphore.h>
44 #include <asm/arch/usb.h>
49 #define DRIVER_NAME "tahvo-usb"
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)
61 /* bits in OTG_CTRL_REG */
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)
73 #if defined(CONFIG_USB_OHCI_HCD) && !defined(CONFIG_USB_OTG)
74 #error tahvo-otg.c does not work with OCHI yet!
77 #define TAHVO_MODE_HOST 0
78 #define TAHVO_MODE_PERIPHERAL 1
81 #define TAHVO_MODE(tu) (tu)->tahvo_mode
82 #elif defined(CONFIG_USB_GADGET_OMAP)
83 #define TAHVO_MODE(tu) TAHVO_MODE_PERIPHERAL
85 #define TAHVO_MODE(tu) TAHVO_MODE_HOST
88 extern int ohci_omap_host_enable(struct usb_bus *host, int enable);
91 struct platform_device *pt_dev;
92 struct otg_transceiver otg;
94 struct work_struct irq_work;
95 struct semaphore serialize;
100 static struct platform_device tahvo_usb_device;
103 * ---------------------------------------------------------------------------
104 * OTG related functions
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 * ---------------------------------------------------------------------------
111 static struct platform_device *tahvo_otg_dev;
113 static irqreturn_t omap_otg_irq(int irq, void *arg, struct pt_regs *regs)
115 struct platform_device *otg_dev = (struct platform_device *) arg;
116 struct tahvo_usb *tu = (struct tahvo_usb *) otg_dev->dev.driver_data;
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) {
134 if ((!(OTG_CTRL_REG & OTG_DRIVER_SEL)) &&
135 tu->otg.host && tu->otg.state == OTG_STATE_A_HOST) {
137 usb_bus_start_enum(tu->otg.host,
138 tu->otg.host->otg_port);
141 OTG_IRQ_SRC_REG = DRIVER_SWITCH;
149 static int omap_otg_init(void)
152 #ifdef CONFIG_USB_OTG
153 if (!tahvo_otg_dev) {
154 printk("tahvo-usb: no tahvo_otg_dev\n");
159 /* some of these values are board-specific... */
160 OTG_SYSCON_2_REG |= OTG_EN
162 | SRP_GPDATA /* 9msec Bdev D+ pulse */
163 | SRP_GPDVBUS /* discharge after VBUS pulse */
164 // | (3 << 24) /* 2msec VBUS pulse */
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 */
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;
178 static int omap_otg_probe(struct device *dev)
182 tahvo_otg_dev = to_platform_device(dev);
183 ret = omap_otg_init();
185 printk(KERN_ERR "tahvo-usb: omap_otg_init failed\n");
189 return request_irq(tahvo_otg_dev->resource[1].start,
190 omap_otg_irq, SA_INTERRUPT, DRIVER_NAME,
194 static int omap_otg_remove(struct device *dev)
196 tahvo_otg_dev = NULL;
197 free_irq(tahvo_otg_dev->resource[1].start, &tahvo_usb_device);
201 struct device_driver omap_otg_driver = {
203 .bus = &platform_bus_type,
204 .probe = omap_otg_probe,
205 .remove = omap_otg_remove,
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 * ---------------------------------------------------------------------------
215 static ssize_t vbus_state_show(struct device *device, char *buf)
217 struct tahvo_usb *tu = (struct tahvo_usb*) device->driver_data;
218 return sprintf(buf, "%d\n", tu->vbus_state);
220 static DEVICE_ATTR(vbus_state, 0444, vbus_state_show, NULL);
224 static void check_vbus_state(struct tahvo_usb *tu)
228 reg = tahvo_read_reg(TAHVO_REG_IDSR);
231 switch (tu->otg.state) {
232 case OTG_STATE_B_IDLE:
233 /* Enable the gadget driver */
235 usb_gadget_vbus_connect(tu->otg.gadget);
236 /* Set B-session valid and not B-sessio ended to indicate
238 OTG_CTRL_REG = (OTG_CTRL_REG & ~OTG_BSESSEND) | OTG_BSESSVLD;
240 tu->otg.state = OTG_STATE_B_PERIPHERAL;
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;
246 ohci_omap_host_enable(tu->otg.host, 1);
251 printk("USB cable connected\n");
254 switch (tu->otg.state) {
255 case OTG_STATE_B_PERIPHERAL:
256 OTG_CTRL_REG = (OTG_CTRL_REG & ~OTG_BSESSVLD) | OTG_BSESSEND;
258 usb_gadget_vbus_disconnect(tu->otg.gadget);
259 tu->otg.state = OTG_STATE_B_IDLE;
261 case OTG_STATE_A_HOST:
262 tu->otg.state = OTG_STATE_A_IDLE;
264 ohci_omap_host_enable(tu->otg.host, 0);
270 printk("USB cable disconnected\n");
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,
278 &dev_attr_vbus_state.attr);
282 static void tahvo_usb_become_host(struct tahvo_usb *tu)
284 /* Clear system and transceiver controlled bits
285 * also mark the A-session is always valid */
287 OTG_CTRL_REG = (OTG_CTRL_REG & ~(OTG_CTRL_XCVR_MASK|OTG_CTRL_SYS_MASK))
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;
295 check_vbus_state(tu);
298 static void tahvo_usb_stop_host(struct tahvo_usb *tu)
301 ohci_omap_host_enable(tu->otg.host, 0);
302 tu->otg.state = OTG_STATE_A_IDLE;
305 static void tahvo_usb_become_peripheral(struct tahvo_usb *tu)
307 /* Clear system and transceiver controlled bits
308 * and enable ID to mark peripheral mode and
309 * BSESSEND to mark no Vbus */
311 OTG_CTRL_REG = (OTG_CTRL_REG & ~(OTG_CTRL_XCVR_MASK|OTG_CTRL_SYS_MASK))
312 | OTG_ID | OTG_BSESSEND;
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;
318 check_vbus_state(tu);
321 static void tahvo_usb_stop_peripheral(struct tahvo_usb *tu)
323 OTG_CTRL_REG = (OTG_CTRL_REG & ~OTG_BSESSVLD) | OTG_BSESSEND;
325 usb_gadget_vbus_disconnect(tu->otg.gadget);
326 tu->otg.state = OTG_STATE_B_IDLE;
330 static void tahvo_usb_power_off(struct tahvo_usb *tu)
334 /* Disable gadget controller if any */
336 usb_gadget_vbus_disconnect(tu->otg.gadget);
339 ohci_omap_host_enable(tu->otg.host, 0);
341 /* Disable OTG and interrupts */
342 if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
345 OTG_CTRL_REG = (OTG_CTRL_REG & ~(OTG_CTRL_XCVR_MASK|OTG_CTRL_SYS_MASK)) | id;
348 OTG_SYSCON_2_REG &= ~OTG_EN;
351 /* Power off transceiver */
352 tahvo_write_reg(TAHVO_REG_USBR, 0);
353 tu->otg.state = OTG_STATE_UNDEFINED;
357 static int tahvo_usb_set_power(struct otg_transceiver *dev, unsigned mA)
359 if (dev->state == OTG_STATE_B_PERIPHERAL) {
360 /* REVISIT: Can Tahvo charge battery from VBUS? */
365 static int tahvo_usb_set_suspend(struct otg_transceiver *dev, int suspend)
369 w = tahvo_read_reg(TAHVO_REG_USBR);
374 tahvo_write_reg(TAHVO_REG_USBR, w);
379 static int tahvo_usb_start_srp(struct otg_transceiver *dev)
381 struct tahvo_usb *tu = container_of(dev, struct tahvo_usb, otg);
384 if (!dev || tu->otg.state != OTG_STATE_B_IDLE)
387 otg_ctrl = OTG_CTRL_REG;
388 if (!(otg_ctrl & OTG_BSESSEND))
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;
396 pr_debug("otg: SRP, %s ... %06x\n", state_name(tu), OTG_CTRL_REG);
401 static int tahvo_usb_start_hnp(struct otg_transceiver *dev)
403 #ifdef CONFIG_USB_OTG
404 /* REVISIT: Add this for OTG */
409 static int tahvo_usb_set_host(struct otg_transceiver *otg, struct usb_bus *host)
411 struct tahvo_usb *tu = container_of(otg, struct tahvo_usb, otg);
416 #if defined(CONFIG_USB_OTG) || !defined(CONFIG_USB_GADGET_OMAP)
418 down(&tu->serialize);
421 if (TAHVO_MODE(tu) == TAHVO_MODE_HOST)
422 tahvo_usb_power_off(tu);
428 if (TAHVO_MODE(tu) == TAHVO_MODE_HOST) {
430 tahvo_usb_become_host(tu);
432 ohci_omap_host_enable(host, 0);
438 /* No host mode configured, so do not allow host controlled to be set */
445 static int tahvo_usb_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
447 struct tahvo_usb *tu = container_of(otg, struct tahvo_usb, otg);
452 #if defined(CONFIG_USB_OTG) || defined(CONFIG_USB_GADGET_OMAP)
454 down(&tu->serialize);
457 if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
458 tahvo_usb_power_off(tu);
464 tu->otg.gadget = gadget;
465 if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL)
466 tahvo_usb_become_peripheral(tu);
470 /* No gadget mode configured, so do not allow host controlled to be set */
477 static void tahvo_usb_irq_work(void *data)
479 struct tahvo_usb *tu = (struct tahvo_usb *)data;
481 down(&tu->serialize);
482 check_vbus_state(tu);
486 static void tahvo_usb_vbus_interrupt(unsigned long arg)
488 struct tahvo_usb *tu = (struct tahvo_usb *) arg;
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);
496 #ifdef CONFIG_USB_OTG
497 static ssize_t otg_mode_show(struct device *device, char *buf)
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");
506 return sprintf(buf, "unknown\n");
509 static ssize_t otg_mode_store(struct device *device, const char *buf, size_t count)
511 struct tahvo_usb *tu = (struct tahvo_usb*) device->driver_data;
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;
521 printk(KERN_INFO "Selected HOST mode: host controller present.\n");
522 tahvo_usb_become_host(tu);
524 printk(KERN_INFO "Selected HOST mode: no host controller, powering off.\n");
525 tahvo_usb_power_off(tu);
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);
535 printk(KERN_INFO "Selected PERIPHERAL mode: no gadget driver, powering off.\n");
536 tahvo_usb_power_off(tu);
545 static DEVICE_ATTR(otg_mode, 0644, otg_mode_show, otg_mode_store);
548 static int tahvo_usb_probe(struct device *dev)
550 struct tahvo_usb *tu;
553 /* Create driver data */
554 tu = kmalloc(sizeof(*tu), GFP_KERNEL);
557 memset(tu, 0, sizeof(*tu));
558 tu->pt_dev = container_of(dev, struct platform_device, dev);
559 #ifdef CONFIG_USB_OTG
561 #ifdef CONFIG_CBUS_TAHVO_USB_HOST_BY_DEFAULT
562 tu->tahvo_mode = TAHVO_MODE_HOST;
564 tu->tahvo_mode = TAHVO_MODE_PERIPHERAL;
568 INIT_WORK(&tu->irq_work, tahvo_usb_irq_work, tu);
569 init_MUTEX(&tu->serialize);
571 /* Set initial state, so that we generate kevents only on
573 tu->vbus_state = tahvo_read_reg(TAHVO_REG_IDSR) & 0x01;
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");
580 printk(KERN_ERR "Could not register Tahvo interrupt for VBUS\n");
585 device_create_file(dev, &dev_attr_vbus_state);
586 #ifdef CONFIG_USB_OTG
587 device_create_file(dev, &dev_attr_otg_mode);
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;
601 ret = otg_set_transceiver(&tu->otg);
603 printk(KERN_ERR "Cannot register USB transceiver\n");
605 tahvo_free_irq(TAHVO_INT_VBUSON);
609 dev->driver_data = tu;
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);
617 static int tahvo_usb_remove(struct device *dev)
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);
629 static struct device_driver tahvo_usb_driver = {
631 .bus = &platform_bus_type,
632 .probe = tahvo_usb_probe,
633 .remove = tahvo_usb_remove,
636 static struct platform_device tahvo_usb_device = {
641 static int __init tahvo_usb_init(void)
645 printk(KERN_INFO "Tahvo USB transceiver driver initializing\n");
646 ret = driver_register(&tahvo_usb_driver);
649 ret = platform_device_register(&tahvo_usb_device);
651 driver_unregister(&tahvo_usb_driver);
654 ret = driver_register(&omap_otg_driver);
656 platform_device_unregister(&tahvo_usb_device);
657 driver_unregister(&tahvo_usb_driver);
663 subsys_initcall(tahvo_usb_init);
665 static void __exit tahvo_usb_exit(void)
667 driver_unregister(&omap_otg_driver);
668 platform_device_unregister(&tahvo_usb_device);
669 driver_unregister(&tahvo_usb_driver);
671 module_exit(tahvo_usb_exit);
673 MODULE_DESCRIPTION("Tahvo USB OTG Transceiver Driver");
674 MODULE_LICENSE("GPL");
675 MODULE_AUTHOR("Juha Yrjölä, Tony Lindgren, and Timo Teräs");