]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/board-n800-usb.c
Merge current mainline tree into linux-omap tree
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / board-n800-usb.c
1 /*
2  * linux/arch/arm/mach-omap2/board-n800-usb.c
3  *
4  * Copyright (C) 2006 Nokia Corporation
5  * Author: Juha Yrjola
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11
12 #include <linux/types.h>
13 #include <linux/delay.h>
14 #include <linux/platform_device.h>
15 #include <linux/clk.h>
16 #include <linux/err.h>
17 #include <linux/usb/musb.h>
18 #include <mach/gpmc.h>
19 #include <mach/gpio.h>
20 #include <mach/pm.h>
21
22 #define TUSB_ASYNC_CS           1
23 #define TUSB_SYNC_CS            4
24 #define GPIO_TUSB_INT           58
25 #define GPIO_TUSB_ENABLE        0
26
27 static int tusb_set_power(int state);
28 static int tusb_set_clock(struct clk *osc_ck, int state);
29
30 #if     defined(CONFIG_USB_MUSB_OTG)
31 #       define BOARD_MODE       MUSB_OTG
32 #elif   defined(CONFIG_USB_MUSB_PERIPHERAL)
33 #       define BOARD_MODE       MUSB_PERIPHERAL
34 #else   /* defined(CONFIG_USB_MUSB_HOST) */
35 #       define BOARD_MODE       MUSB_HOST
36 #endif
37
38 static struct musb_hdrc_platform_data tusb_data = {
39         .mode           = BOARD_MODE,
40         .multipoint     = 1,
41         .set_power      = tusb_set_power,
42         .set_clock      = tusb_set_clock,
43         .min_power      = 25,   /* x2 = 50 mA drawn from VBUS as peripheral */
44         .power          = 100,  /* Max 100 mA VBUS for host mode */
45         .clock          = "osc_ck",
46 };
47
48 /*
49  * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
50  * 1.5 V voltage regulators of PM companion chip. Companion chip will then
51  * provide then PGOOD signal to TUSB6010 which will release it from reset.
52  */
53 static int tusb_set_power(int state)
54 {
55         int i, retval = 0;
56
57         if (state) {
58                 omap_set_gpio_dataout(GPIO_TUSB_ENABLE, 1);
59                 msleep(1);
60
61                 /* Wait until TUSB6010 pulls INT pin down */
62                 i = 100;
63                 while (i && omap_get_gpio_datain(GPIO_TUSB_INT)) {
64                         msleep(1);
65                         i--;
66                 }
67
68                 if (!i) {
69                         printk(KERN_ERR "tusb: powerup failed\n");
70                         retval = -ENODEV;
71                 }
72         } else {
73                 omap_set_gpio_dataout(GPIO_TUSB_ENABLE, 0);
74                 msleep(10);
75         }
76
77         return retval;
78 }
79
80 static int              osc_ck_on;
81
82 static int tusb_set_clock(struct clk *osc_ck, int state)
83 {
84         if (state) {
85                 if (osc_ck_on > 0)
86                         return -ENODEV;
87
88                 omap2_block_sleep();
89                 clk_enable(osc_ck);
90                 osc_ck_on = 1;
91         } else {
92                 if (osc_ck_on == 0)
93                         return -ENODEV;
94
95                 clk_disable(osc_ck);
96                 osc_ck_on = 0;
97                 omap2_allow_sleep();
98         }
99
100         return 0;
101 }
102
103 void __init n800_usb_init(void)
104 {
105         int ret = 0;
106         static char     announce[] __initdata = KERN_INFO "TUSB 6010\n";
107
108         /* PM companion chip power control pin */
109         ret = omap_request_gpio(GPIO_TUSB_ENABLE);
110         if (ret != 0) {
111                 printk(KERN_ERR "Could not get TUSB power GPIO%i\n",
112                        GPIO_TUSB_ENABLE);
113                 return;
114         }
115         omap_set_gpio_direction(GPIO_TUSB_ENABLE, 0);
116
117         tusb_set_power(0);
118
119         ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2,
120                                         TUSB_ASYNC_CS, TUSB_SYNC_CS,
121                                         GPIO_TUSB_INT, 0x3f);
122         if (ret != 0)
123                 goto err;
124
125         printk(announce);
126
127         return;
128
129 err:
130         omap_free_gpio(GPIO_TUSB_ENABLE);
131 }