Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/async_tx
[sfrench/cifs-2.6.git] / arch / arm / mach-omap1 / board-htcherald.c
1 /*
2  * HTC Herald board configuration
3  * Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com>
4  * Copyright (C) 2009 Wing Linux
5  *
6  * Based on the board-htcwizard.c file from the linwizard project:
7  * Copyright (C) 2006 Unai Uribarri
8  * Copyright (C) 2008 linwizard.sourceforge.net
9  *
10  * This  program is  free  software; you  can  redistribute it  and/or
11  * modify  it under the  terms of  the GNU  General Public  License as
12  * published by the Free Software  Foundation; either version 2 of the
13  * License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT  ANY  WARRANTY;  without   even  the  implied  warranty  of
17  * MERCHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU
18  * General Public License for more details.
19  *
20  * You should have  received a copy of the  GNU General Public License
21  * along  with  this program;  if  not,  write  to the  Free  Software
22  * Foundation,  Inc.,  51 Franklin  Street,  Fifth  Floor, Boston,  MA
23  * 02110-1301, USA.
24  *
25  */
26
27 #include <linux/kernel.h>
28 #include <linux/init.h>
29 #include <linux/platform_device.h>
30 #include <linux/input.h>
31 #include <linux/bootmem.h>
32 #include <linux/io.h>
33 #include <linux/gpio.h>
34
35 #include <asm/mach-types.h>
36 #include <asm/mach/arch.h>
37
38 #include <plat/omap7xx.h>
39 #include <plat/common.h>
40 #include <plat/board.h>
41 #include <plat/keypad.h>
42 #include <plat/usb.h>
43
44 #include <mach/irqs.h>
45
46 #include <linux/delay.h>
47
48 /* LCD register definition */
49 #define       OMAP_LCDC_CONTROL               (0xfffec000 + 0x00)
50 #define       OMAP_LCDC_STATUS                (0xfffec000 + 0x10)
51 #define       OMAP_DMA_LCD_CCR                (0xfffee300 + 0xc2)
52 #define       OMAP_DMA_LCD_CTRL               (0xfffee300 + 0xc4)
53 #define       OMAP_LCDC_CTRL_LCD_EN           (1 << 0)
54 #define       OMAP_LCDC_STAT_DONE             (1 << 0)
55
56 static struct omap_lcd_config htcherald_lcd_config __initdata = {
57         .ctrl_name      = "internal",
58 };
59
60 static struct omap_board_config_kernel htcherald_config[] __initdata = {
61         { OMAP_TAG_LCD, &htcherald_lcd_config },
62 };
63
64 /* Keyboard definition */
65
66 static int htc_herald_keymap[] = {
67         KEY(0, 0, KEY_RECORD), /* Mail button */
68         KEY(0, 1, KEY_CAMERA), /* Camera */
69         KEY(0, 2, KEY_PHONE), /* Send key */
70         KEY(0, 3, KEY_VOLUMEUP), /* Volume up */
71         KEY(0, 4, KEY_F2),  /* Right bar (landscape) */
72         KEY(0, 5, KEY_MAIL), /* Win key (portrait) */
73         KEY(0, 6, KEY_DIRECTORY), /* Right bar (protrait) */
74         KEY(1, 0, KEY_LEFTCTRL), /* Windows key */
75         KEY(1, 1, KEY_COMMA),
76         KEY(1, 2, KEY_M),
77         KEY(1, 3, KEY_K),
78         KEY(1, 4, KEY_SLASH), /* OK key */
79         KEY(1, 5, KEY_I),
80         KEY(1, 6, KEY_U),
81         KEY(2, 0, KEY_LEFTALT),
82         KEY(2, 1, KEY_TAB),
83         KEY(2, 2, KEY_N),
84         KEY(2, 3, KEY_J),
85         KEY(2, 4, KEY_ENTER),
86         KEY(2, 5, KEY_H),
87         KEY(2, 6, KEY_Y),
88         KEY(3, 0, KEY_SPACE),
89         KEY(3, 1, KEY_L),
90         KEY(3, 2, KEY_B),
91         KEY(3, 3, KEY_V),
92         KEY(3, 4, KEY_BACKSPACE),
93         KEY(3, 5, KEY_G),
94         KEY(3, 6, KEY_T),
95         KEY(4, 0, KEY_CAPSLOCK), /* Shift */
96         KEY(4, 1, KEY_C),
97         KEY(4, 2, KEY_F),
98         KEY(4, 3, KEY_R),
99         KEY(4, 4, KEY_O),
100         KEY(4, 5, KEY_E),
101         KEY(4, 6, KEY_D),
102         KEY(5, 0, KEY_X),
103         KEY(5, 1, KEY_Z),
104         KEY(5, 2, KEY_S),
105         KEY(5, 3, KEY_W),
106         KEY(5, 4, KEY_P),
107         KEY(5, 5, KEY_Q),
108         KEY(5, 6, KEY_A),
109         KEY(6, 0, KEY_CONNECT), /* Voice button */
110         KEY(6, 2, KEY_CANCEL), /* End key */
111         KEY(6, 3, KEY_VOLUMEDOWN), /* Volume down */
112         KEY(6, 4, KEY_F1), /* Left bar (landscape) */
113         KEY(6, 5, KEY_WWW), /* OK button (portrait) */
114         KEY(6, 6, KEY_CALENDAR), /* Left bar (portrait) */
115         0
116 };
117
118 struct omap_kp_platform_data htcherald_kp_data = {
119         .rows   = 7,
120         .cols   = 7,
121         .delay = 20,
122         .rep = 1,
123         .keymap = htc_herald_keymap,
124 };
125
126 static struct resource kp_resources[] = {
127         [0] = {
128                 .start  = INT_7XX_MPUIO_KEYPAD,
129                 .end    = INT_7XX_MPUIO_KEYPAD,
130                 .flags  = IORESOURCE_IRQ,
131         },
132 };
133
134 static struct platform_device kp_device = {
135         .name           = "omap-keypad",
136         .id             = -1,
137         .dev            = {
138                 .platform_data = &htcherald_kp_data,
139         },
140         .num_resources  = ARRAY_SIZE(kp_resources),
141         .resource       = kp_resources,
142 };
143
144 /* USB Device */
145 static struct omap_usb_config htcherald_usb_config __initdata = {
146         .otg = 0,
147         .register_host = 0,
148         .register_dev  = 1,
149         .hmc_mode = 4,
150         .pins[0] = 2,
151 };
152
153 /* LCD Device resources */
154 static struct platform_device lcd_device = {
155         .name           = "lcd_htcherald",
156         .id             = -1,
157 };
158
159 static struct platform_device *devices[] __initdata = {
160         &kp_device,
161         &lcd_device,
162 };
163
164 /*
165  * Init functions from here on
166  */
167
168 static void __init htcherald_lcd_init(void)
169 {
170         u32 reg;
171         unsigned int tries = 200;
172
173         /* disable controller if active */
174         reg = omap_readl(OMAP_LCDC_CONTROL);
175         if (reg & OMAP_LCDC_CTRL_LCD_EN) {
176                 reg &= ~OMAP_LCDC_CTRL_LCD_EN;
177                 omap_writel(reg, OMAP_LCDC_CONTROL);
178
179                 /* wait for end of frame */
180                 while (!(omap_readl(OMAP_LCDC_STATUS) & OMAP_LCDC_STAT_DONE)) {
181                         tries--;
182                         if (!tries)
183                                 break;
184                 }
185                 if (!tries)
186                         printk(KERN_WARNING "Timeout waiting for end of frame "
187                                "-- LCD may not be available\n");
188
189                 /* turn off DMA */
190                 reg = omap_readw(OMAP_DMA_LCD_CCR);
191                 reg &= ~(1 << 7);
192                 omap_writew(reg, OMAP_DMA_LCD_CCR);
193
194                 reg = omap_readw(OMAP_DMA_LCD_CTRL);
195                 reg &= ~(1 << 8);
196                 omap_writew(reg, OMAP_DMA_LCD_CTRL);
197         }
198 }
199
200 static void __init htcherald_map_io(void)
201 {
202         omap1_map_common_io();
203
204         /*
205          * The LCD panel must be disabled and DMA turned off here, as doing
206          * it later causes the LCD never to reinitialize.
207          */
208         htcherald_lcd_init();
209
210         printk(KERN_INFO "htcherald_map_io done.\n");
211 }
212
213 static void __init htcherald_disable_watchdog(void)
214 {
215         /* Disable watchdog if running */
216         if (omap_readl(OMAP_WDT_TIMER_MODE) & 0x8000) {
217                 /*
218                  * disable a potentially running watchdog timer before
219                  * it kills us.
220                  */
221                 printk(KERN_WARNING "OMAP850 Watchdog seems to be activated, disabling it for now.\n");
222                 omap_writel(0xF5, OMAP_WDT_TIMER_MODE);
223                 omap_writel(0xA0, OMAP_WDT_TIMER_MODE);
224         }
225 }
226
227 #define HTCHERALD_GPIO_USB_EN1 33
228 #define HTCHERALD_GPIO_USB_EN2 73
229 #define HTCHERALD_GPIO_USB_DM  35
230 #define HTCHERALD_GPIO_USB_DP  36
231
232 static void __init htcherald_usb_enable(void)
233 {
234         unsigned int tries = 20;
235         unsigned int value = 0;
236
237         /* Request the GPIOs we need to control here */
238         if (gpio_request(HTCHERALD_GPIO_USB_EN1, "herald_usb") < 0)
239                 goto err1;
240
241         if (gpio_request(HTCHERALD_GPIO_USB_EN2, "herald_usb") < 0)
242                 goto err2;
243
244         if (gpio_request(HTCHERALD_GPIO_USB_DM, "herald_usb") < 0)
245                 goto err3;
246
247         if (gpio_request(HTCHERALD_GPIO_USB_DP, "herald_usb") < 0)
248                 goto err4;
249
250         /* force USB_EN GPIO to 0 */
251         do {
252                 /* output low */
253                 gpio_direction_output(HTCHERALD_GPIO_USB_EN1, 0);
254         } while ((value = gpio_get_value(HTCHERALD_GPIO_USB_EN1)) == 1 &&
255                         --tries);
256
257         if (value == 1)
258                 printk(KERN_WARNING "Unable to reset USB, trying to continue\n");
259
260         gpio_direction_output(HTCHERALD_GPIO_USB_EN2, 0); /* output low */
261         gpio_direction_input(HTCHERALD_GPIO_USB_DM); /* input */
262         gpio_direction_input(HTCHERALD_GPIO_USB_DP); /* input */
263
264         goto done;
265
266 err4:
267         gpio_free(HTCHERALD_GPIO_USB_DM);
268 err3:
269         gpio_free(HTCHERALD_GPIO_USB_EN2);
270 err2:
271         gpio_free(HTCHERALD_GPIO_USB_EN1);
272 err1:
273         printk(KERN_ERR "Unabled to request GPIO for USB\n");
274 done:
275         printk(KERN_INFO "USB setup complete.\n");
276 }
277
278 static void __init htcherald_init(void)
279 {
280         printk(KERN_INFO "HTC Herald init.\n");
281
282         omap_gpio_init();
283
284         omap_board_config = htcherald_config;
285         omap_board_config_size = ARRAY_SIZE(htcherald_config);
286         platform_add_devices(devices, ARRAY_SIZE(devices));
287
288         htcherald_disable_watchdog();
289
290         htcherald_usb_enable();
291         omap_usb_init(&htcherald_usb_config);
292 }
293
294 static void __init htcherald_init_irq(void)
295 {
296         printk(KERN_INFO "htcherald_init_irq.\n");
297         omap1_init_common_hw();
298         omap_init_irq();
299 }
300
301 MACHINE_START(HERALD, "HTC Herald")
302         /* Maintainer: Cory Maccarrone <darkstar6262@gmail.com> */
303         /* Maintainer: wing-linux.sourceforge.net */
304         .phys_io        = 0xfff00000,
305         .io_pg_offst    = ((0xfef00000) >> 18) & 0xfffc,
306         .boot_params    = 0x10000100,
307         .map_io         = htcherald_map_io,
308         .init_irq       = htcherald_init_irq,
309         .init_machine   = htcherald_init,
310         .timer          = &omap_timer,
311 MACHINE_END