]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/board-n800-usb.c
Merge branch 'omap-fixes'
[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/gpio.h>
18 #include <linux/usb/musb.h>
19 #include <mach/gpmc.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_eps_bits musb_eps[] = {
39         {       "ep1_tx", 5,    },
40         {       "ep1_rx", 5,    },
41         {       "ep2_tx", 5,    },
42         {       "ep2_rx", 5,    },
43         {       "ep3_tx", 3,    },
44         {       "ep3_rx", 3,    },
45         {       "ep4_tx", 3,    },
46         {       "ep4_rx", 3,    },
47         {       "ep5_tx", 2,    },
48         {       "ep5_rx", 2,    },
49         {       "ep6_tx", 2,    },
50         {       "ep6_rx", 2,    },
51         {       "ep7_tx", 2,    },
52         {       "ep7_rx", 2,    },
53         {       "ep8_tx", 2,    },
54         {       "ep8_rx", 2,    },
55         {       "ep9_tx", 2,    },
56         {       "ep9_rx", 2,    },
57         {       "ep10_tx", 2,   },
58         {       "ep10_rx", 2,   },
59         {       "ep11_tx", 2,   },
60         {       "ep11_rx", 2,   },
61         {       "ep12_tx", 2,   },
62         {       "ep12_rx", 2,   },
63         {       "ep13_tx", 2,   },
64         {       "ep13_rx", 2,   },
65         {       "ep14_tx", 2,   },
66         {       "ep14_rx", 2,   },
67         {       "ep15_tx", 2,   },
68         {       "ep15_rx", 2,   },
69 };
70
71 static struct musb_hdrc_config musb_config = {
72         .multipoint     = 1,
73         .dyn_fifo       = 1,
74         .soft_con       = 1,
75         .dma            = 1,
76         .num_eps        = 16,
77         .dma_channels   = 7,
78         .ram_bits       = 12,
79         .eps_bits       = musb_eps,
80 };
81
82 static struct musb_hdrc_platform_data tusb_data = {
83         .mode           = BOARD_MODE,
84         .set_power      = tusb_set_power,
85         .set_clock      = tusb_set_clock,
86         .min_power      = 25,   /* x2 = 50 mA drawn from VBUS as peripheral */
87         .power          = 100,  /* Max 100 mA VBUS for host mode */
88         .clock          = "osc_ck",
89         .config         = &musb_config,
90 };
91
92 /*
93  * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
94  * 1.5 V voltage regulators of PM companion chip. Companion chip will then
95  * provide then PGOOD signal to TUSB6010 which will release it from reset.
96  */
97 static int tusb_set_power(int state)
98 {
99         int i, retval = 0;
100
101         if (state) {
102                 gpio_set_value(GPIO_TUSB_ENABLE, 1);
103                 msleep(1);
104
105                 /* Wait until TUSB6010 pulls INT pin down */
106                 i = 100;
107                 while (i && gpio_get_value(GPIO_TUSB_INT)) {
108                         msleep(1);
109                         i--;
110                 }
111
112                 if (!i) {
113                         printk(KERN_ERR "tusb: powerup failed\n");
114                         retval = -ENODEV;
115                 }
116         } else {
117                 gpio_set_value(GPIO_TUSB_ENABLE, 0);
118                 msleep(10);
119         }
120
121         return retval;
122 }
123
124 static int              osc_ck_on;
125
126 static int tusb_set_clock(struct clk *osc_ck, int state)
127 {
128         if (state) {
129                 if (osc_ck_on > 0)
130                         return -ENODEV;
131
132                 //omap2_block_sleep();
133                 clk_enable(osc_ck);
134                 osc_ck_on = 1;
135         } else {
136                 if (osc_ck_on == 0)
137                         return -ENODEV;
138
139                 clk_disable(osc_ck);
140                 osc_ck_on = 0;
141                 //omap2_allow_sleep();
142         }
143
144         return 0;
145 }
146
147 void __init n800_usb_init(void)
148 {
149         int ret = 0;
150         static char     announce[] __initdata = KERN_INFO "TUSB 6010\n";
151
152         /* PM companion chip power control pin */
153         ret = gpio_request(GPIO_TUSB_ENABLE, "TUSB6010 enable");
154         if (ret != 0) {
155                 printk(KERN_ERR "Could not get TUSB power GPIO%i\n",
156                        GPIO_TUSB_ENABLE);
157                 return;
158         }
159         gpio_direction_output(GPIO_TUSB_ENABLE, 0);
160
161         tusb_set_power(0);
162
163         ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2,
164                                         TUSB_ASYNC_CS, TUSB_SYNC_CS,
165                                         GPIO_TUSB_INT, 0x3f);
166         if (ret != 0)
167                 goto err;
168
169         printk(announce);
170
171         return;
172
173 err:
174         gpio_free(GPIO_TUSB_ENABLE);
175 }