]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/board-ldp.c
twl4030 keypad irq & dependencies
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / board-ldp.c
1 /*
2  * linux/arch/arm/mach-omap2/board-ldp.c
3  *
4  * Copyright (C) 2008 Texas Instruments Inc.
5  * Nishant Kamat <nskamat@ti.com>
6  *
7  * Modified from mach-omap2/board-3430sdp.c
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/platform_device.h>
17 #include <linux/delay.h>
18 #include <linux/input.h>
19 #include <linux/gpio_keys.h>
20 #include <linux/workqueue.h>
21 #include <linux/err.h>
22 #include <linux/clk.h>
23 #include <linux/spi/spi.h>
24 #include <linux/spi/ads7846.h>
25 #include <linux/i2c/twl4030.h>
26
27 #include <mach/hardware.h>
28 #include <asm/mach-types.h>
29 #include <asm/mach/arch.h>
30 #include <asm/mach/map.h>
31
32 #include <mach/board-ldp.h>
33 #include <mach/mcspi.h>
34 #include <mach/gpio.h>
35 #include <mach/board.h>
36 #include <mach/common.h>
37 #include <mach/keypad.h>
38 #include <mach/gpmc.h>
39 #include <mach/mmc.h>
40 #include <mach/usb-musb.h>
41
42 #include <asm/io.h>
43 #include <asm/delay.h>
44 #include <mach/control.h>
45
46 #include "mmc-twl4030.h"
47
48
49 #define SDP3430_SMC91X_CS       3
50 #define CONFIG_DISABLE_HFCLK 1
51
52 #define ENABLE_VAUX1_DEDICATED  0x03
53 #define ENABLE_VAUX1_DEV_GRP    0x20
54
55 #define TWL4030_MSECURE_GPIO    22
56
57 static struct resource ldp_smc911x_resources[] = {
58         [0] = {
59                 .start  = OMAP34XX_ETHR_START,
60                 .end    = OMAP34XX_ETHR_START + SZ_4K,
61                 .flags  = IORESOURCE_MEM,
62         },
63         [1] = {
64                 .start  = 0,
65                 .end    = 0,
66                 .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
67         },
68 };
69
70 static struct platform_device ldp_smc911x_device = {
71         .name           = "smc911x",
72         .id             = -1,
73         .num_resources  = ARRAY_SIZE(ldp_smc911x_resources),
74         .resource       = ldp_smc911x_resources,
75 };
76
77 static int ldp_twl4030_keymap[] = {
78         KEY(0, 0, KEY_1),
79         KEY(1, 0, KEY_2),
80         KEY(2, 0, KEY_3),
81         KEY(0, 1, KEY_4),
82         KEY(1, 1, KEY_5),
83         KEY(2, 1, KEY_6),
84         KEY(3, 1, KEY_F5),
85         KEY(0, 2, KEY_7),
86         KEY(1, 2, KEY_8),
87         KEY(2, 2, KEY_9),
88         KEY(3, 2, KEY_F6),
89         KEY(0, 3, KEY_F7),
90         KEY(1, 3, KEY_0),
91         KEY(2, 3, KEY_F8),
92         PERSISTENT_KEY(4, 5),
93         KEY(4, 4, KEY_VOLUMEUP),
94         KEY(5, 5, KEY_VOLUMEDOWN),
95         0
96 };
97
98 static struct twl4030_keypad_data ldp_kp_twl4030_data = {
99         .rows           = 6,
100         .cols           = 6,
101         .keymap         = ldp_twl4030_keymap,
102         .keymapsize     = ARRAY_SIZE(ldp_twl4030_keymap),
103         .rep            = 1,
104 };
105
106 static struct gpio_keys_button ldp_gpio_keys_buttons[] = {
107         [0] = {
108                 .code                   = KEY_ENTER,
109                 .gpio                   = 101,
110                 .desc                   = "enter sw",
111                 .active_low             = 1,
112                 .debounce_interval      = 30,
113         },
114         [1] = {
115                 .code                   = KEY_F1,
116                 .gpio                   = 102,
117                 .desc                   = "func 1",
118                 .active_low             = 1,
119                 .debounce_interval      = 30,
120         },
121         [2] = {
122                 .code                   = KEY_F2,
123                 .gpio                   = 103,
124                 .desc                   = "func 2",
125                 .active_low             = 1,
126                 .debounce_interval      = 30,
127         },
128         [3] = {
129                 .code                   = KEY_F3,
130                 .gpio                   = 104,
131                 .desc                   = "func 3",
132                 .active_low             = 1,
133                 .debounce_interval      = 30,
134         },
135         [4] = {
136                 .code                   = KEY_F4,
137                 .gpio                   = 105,
138                 .desc                   = "func 4",
139                 .active_low             = 1,
140                 .debounce_interval      = 30,
141         },
142         [5] = {
143                 .code                   = KEY_LEFT,
144                 .gpio                   = 106,
145                 .desc                   = "left sw",
146                 .active_low             = 1,
147                 .debounce_interval      = 30,
148         },
149         [6] = {
150                 .code                   = KEY_RIGHT,
151                 .gpio                   = 107,
152                 .desc                   = "right sw",
153                 .active_low             = 1,
154                 .debounce_interval      = 30,
155         },
156         [7] = {
157                 .code                   = KEY_UP,
158                 .gpio                   = 108,
159                 .desc                   = "up sw",
160                 .active_low             = 1,
161                 .debounce_interval      = 30,
162         },
163         [8] = {
164                 .code                   = KEY_DOWN,
165                 .gpio                   = 109,
166                 .desc                   = "down sw",
167                 .active_low             = 1,
168                 .debounce_interval      = 30,
169         },
170 };
171
172 static struct gpio_keys_platform_data ldp_gpio_keys = {
173         .buttons                = ldp_gpio_keys_buttons,
174         .nbuttons               = ARRAY_SIZE(ldp_gpio_keys_buttons),
175         .rep                    = 1,
176 };
177
178 static struct platform_device ldp_gpio_keys_device = {
179         .name           = "gpio-keys",
180         .id             = -1,
181         .dev            = {
182                 .platform_data  = &ldp_gpio_keys,
183         },
184 };
185
186 static int ts_gpio;
187
188 static int __init msecure_init(void)
189 {
190         int ret = 0;
191
192 #ifdef CONFIG_RTC_DRV_TWL4030
193         /* 3430ES2.0 doesn't have msecure/gpio-22 line connected to T2 */
194         if (omap_type() == OMAP2_DEVICE_TYPE_GP &&
195                         omap_rev() < OMAP3430_REV_ES2_0) {
196                 void __iomem *msecure_pad_config_reg =
197                         omap_ctrl_base_get() + 0xA3C;
198                 int mux_mask = 0x04;
199                 u16 tmp;
200
201                 ret = gpio_request(TWL4030_MSECURE_GPIO, "msecure");
202                 if (ret < 0) {
203                         printk(KERN_ERR "msecure_init: can't"
204                                 "reserve GPIO:%d !\n", TWL4030_MSECURE_GPIO);
205                         goto out;
206                 }
207                 /*
208                  * TWL4030 will be in secure mode if msecure line from OMAP
209                  * is low. Make msecure line high in order to change the
210                  * TWL4030 RTC time and calender registers.
211                  */
212
213                 tmp = __raw_readw(msecure_pad_config_reg);
214                 tmp &= 0xF8;    /* To enable mux mode 03/04 = GPIO_RTC */
215                 tmp |= mux_mask;/* To enable mux mode 03/04 = GPIO_RTC */
216                 __raw_writew(tmp, msecure_pad_config_reg);
217
218                 gpio_direction_output(TWL4030_MSECURE_GPIO, 1);
219         }
220 out:
221 #endif
222         return ret;
223 }
224
225 /**
226  * @brief ads7846_dev_init : Requests & sets GPIO line for pen-irq
227  *
228  * @return - void. If request gpio fails then Flag KERN_ERR.
229  */
230 static void ads7846_dev_init(void)
231 {
232         if (omap_request_gpio(ts_gpio) < 0) {
233                 printk(KERN_ERR "can't get ads746 pen down GPIO\n");
234                 return;
235         }
236
237         gpio_direction_input(ts_gpio);
238
239         omap_set_gpio_debounce(ts_gpio, 1);
240         omap_set_gpio_debounce_time(ts_gpio, 0xa);
241 }
242
243 static int ads7846_get_pendown_state(void)
244 {
245         return !gpio_get_value(ts_gpio);
246 }
247
248 /*
249  * This enable(1)/disable(0) the voltage for TS: uses twl4030 calls
250  */
251 static int ads7846_vaux_control(int vaux_cntrl)
252 {
253         int ret = 0;
254
255 #ifdef CONFIG_TWL4030_CORE
256         /* check for return value of ldo_use: if success it returns 0 */
257         if (vaux_cntrl == VAUX_ENABLE) {
258                 if (ret != twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
259                         ENABLE_VAUX1_DEDICATED, TWL4030_VAUX1_DEDICATED))
260                         return -EIO;
261                 if (ret != twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
262                         ENABLE_VAUX1_DEV_GRP, TWL4030_VAUX1_DEV_GRP))
263                         return -EIO;
264         } else if (vaux_cntrl == VAUX_DISABLE) {
265                 if (ret != twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
266                         0x00, TWL4030_VAUX1_DEDICATED))
267                         return -EIO;
268                 if (ret != twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
269                         0x00, TWL4030_VAUX1_DEV_GRP))
270                         return -EIO;
271         }
272 #else
273         ret = -EIO;
274 #endif
275         return ret;
276 }
277
278 static struct ads7846_platform_data tsc2046_config __initdata = {
279         .get_pendown_state      = ads7846_get_pendown_state,
280         .keep_vref_on           = 1,
281         .vaux_control           = ads7846_vaux_control,
282 };
283
284
285 static struct omap2_mcspi_device_config tsc2046_mcspi_config = {
286         .turbo_mode     = 0,
287         .single_channel = 1,    /* 0: slave, 1: master */
288 };
289
290 static struct spi_board_info ldp_spi_board_info[] __initdata = {
291         [0] = {
292                 /*
293                  * TSC2046 operates at a max freqency of 2MHz, so
294                  * operate slightly below at 1.5MHz
295                  */
296                 .modalias               = "ads7846",
297                 .bus_num                = 1,
298                 .chip_select            = 0,
299                 .max_speed_hz           = 1500000,
300                 .controller_data        = &tsc2046_mcspi_config,
301                 .irq                    = 0,
302                 .platform_data          = &tsc2046_config,
303         },
304 };
305
306 static struct platform_device ldp_lcd_device = {
307         .name           = "ldp_lcd",
308         .id             = -1,
309 };
310
311 static struct platform_device *ldp_devices[] __initdata = {
312         &ldp_smc911x_device,
313         &ldp_lcd_device,
314         &ldp_gpio_keys_device,
315 };
316
317 static inline void __init ldp_init_smc911x(void)
318 {
319         int eth_cs;
320         unsigned long cs_mem_base;
321         int eth_gpio = 0;
322
323         eth_cs = LDP_SMC911X_CS;
324
325         if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
326                 printk(KERN_ERR "Failed to request GPMC mem for smc911x\n");
327                 return;
328         }
329
330         ldp_smc911x_resources[0].start = cs_mem_base + 0x0;
331         ldp_smc911x_resources[0].end   = cs_mem_base + 0xf;
332         udelay(100);
333
334         eth_gpio = LDP_SMC911X_GPIO;
335
336         ldp_smc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio);
337
338         if (omap_request_gpio(eth_gpio) < 0) {
339                 printk(KERN_ERR "Failed to request GPIO%d for smc911x IRQ\n",
340                                 eth_gpio);
341                 return;
342         }
343         omap_set_gpio_direction(eth_gpio, 1);
344 }
345
346
347 static void __init omap_ldp_init_irq(void)
348 {
349         omap2_init_common_hw(NULL);
350         omap_init_irq();
351         omap_gpio_init();
352         ldp_init_smc911x();
353 }
354
355 static struct omap_uart_config ldp_uart_config __initdata = {
356         .enabled_uarts  = ((1 << 0) | (1 << 1) | (1 << 2)),
357 };
358
359 static struct omap_lcd_config ldp_lcd_config __initdata = {
360         .ctrl_name      = "internal",
361 };
362
363 static struct omap_board_config_kernel ldp_config[] __initdata = {
364         { OMAP_TAG_UART,        &ldp_uart_config },
365         { OMAP_TAG_LCD,         &ldp_lcd_config },
366 };
367
368 static int ldp_batt_table[] = {
369 /* 0 C*/
370 30800, 29500, 28300, 27100,
371 26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900,
372 17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100,
373 11600, 11200, 10800, 10400, 10000, 9630,   9280,   8950,   8620,   8310,
374 8020,   7730,   7460,   7200,   6950,   6710,   6470,   6250,   6040,   5830,
375 5640,   5450,   5260,   5090,   4920,   4760,   4600,   4450,   4310,   4170,
376 4040,   3910,   3790,   3670,   3550
377 };
378
379 static struct twl4030_ins __initdata sleep_on_seq[] = {
380 /*
381  * Turn off VDD1 and VDD2.
382  */
383         {MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_OFF), 4},
384         {MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_OFF), 2},
385 #ifdef CONFIG_DISABLE_HFCLK
386 /*
387  * And also turn off the OMAP3 PLLs and the sysclk output.
388  */
389         {MSG_SINGULAR(DEV_GRP_P1, 0x7, RES_STATE_OFF), 3},
390         {MSG_SINGULAR(DEV_GRP_P1, 0x19, RES_STATE_OFF), 3},
391 #endif
392 };
393
394 static struct twl4030_script sleep_on_script __initdata = {
395         .script = sleep_on_seq,
396         .size   = ARRAY_SIZE(sleep_on_seq),
397         .flags  = TRITON_SLEEP_SCRIPT,
398 };
399
400 static struct twl4030_ins wakeup_seq[] __initdata = {
401 #ifndef CONFIG_DISABLE_HFCLK
402 /*
403  * Wakeup VDD1 and VDD2.
404  */
405         {MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_ACTIVE), 4},
406         {MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_ACTIVE), 2},
407 #else
408 /*
409  * Reenable the OMAP3 PLLs.
410  * Wakeup VDD1 and VDD2.
411  * Reenable sysclk output.
412  */
413         {MSG_SINGULAR(DEV_GRP_P1, 0x7, RES_STATE_ACTIVE), 0x30},
414         {MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_ACTIVE), 0x30},
415         {MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_ACTIVE), 0x37},
416         {MSG_SINGULAR(DEV_GRP_P1, 0x19, RES_STATE_ACTIVE), 3},
417 #endif /* #ifndef CONFIG_DISABLE_HFCLK */
418 };
419
420 static struct twl4030_script wakeup_script __initdata = {
421         .script = wakeup_seq,
422         .size   = ARRAY_SIZE(wakeup_seq),
423         .flags  = TRITON_WAKEUP12_SCRIPT | TRITON_WAKEUP3_SCRIPT,
424 };
425
426 static struct twl4030_ins wrst_seq[] __initdata = {
427 /*
428  * Reset twl4030.
429  * Reset VDD1 regulator.
430  * Reset VDD2 regulator.
431  * Reset VPLL1 regulator.
432  * Enable sysclk output.
433  * Reenable twl4030.
434  */
435         {MSG_SINGULAR(DEV_GRP_NULL, 0x1b, RES_STATE_OFF), 2},
436         {MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_WRST), 15},
437         {MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_WRST), 15},
438         {MSG_SINGULAR(DEV_GRP_P1, 0x7, RES_STATE_WRST), 0x60},
439         {MSG_SINGULAR(DEV_GRP_P1, 0x19, RES_STATE_ACTIVE), 2},
440         {MSG_SINGULAR(DEV_GRP_NULL, 0x1b, RES_STATE_ACTIVE), 2},
441 };
442
443 static struct twl4030_script wrst_script __initdata = {
444         .script = wrst_seq,
445         .size   = ARRAY_SIZE(wakeup_seq),
446         .flags  = TRITON_WRST_SCRIPT,
447 };
448
449 static struct twl4030_script *twl4030_scripts[] __initdata = {
450         &sleep_on_script,
451         &wakeup_script,
452         &wrst_script,
453 };
454
455 static struct twl4030_power_data sdp3430_t2scripts_data __initdata = {
456         .scripts        = twl4030_scripts,
457         .size           = ARRAY_SIZE(twl4030_scripts),
458 };
459
460 static struct twl4030_bci_platform_data ldp_bci_data = {
461         .battery_tmp_tbl        = ldp_batt_table,
462         .tblsize                = ARRAY_SIZE(ldp_batt_table),
463 };
464
465 static struct twl4030_usb_data ldp_usb_data = {
466         .usb_mode       = T2_USB_MODE_ULPI,
467 };
468
469 static struct twl4030_gpio_platform_data ldp_gpio_data = {
470         .gpio_base      = OMAP_MAX_GPIO_LINES,
471         .irq_base       = TWL4030_GPIO_IRQ_BASE,
472         .irq_end        = TWL4030_GPIO_IRQ_END,
473 };
474
475 static struct twl4030_madc_platform_data ldp_madc_data = {
476         .irq_line       = 1,
477 };
478
479 static struct twl4030_platform_data ldp_twldata = {
480         .irq_base       = TWL4030_IRQ_BASE,
481         .irq_end        = TWL4030_IRQ_END,
482
483         /* platform_data for children goes here */
484         .bci            = &ldp_bci_data,
485         .madc           = &ldp_madc_data,
486         .usb            = &ldp_usb_data,
487         .power          = &sdp3430_t2scripts_data,
488         .gpio           = &ldp_gpio_data,
489         .keypad         = &ldp_kp_twl4030_data,
490 };
491
492 static struct i2c_board_info __initdata ldp_i2c_boardinfo[] = {
493         {
494                 I2C_BOARD_INFO("twl4030", 0x48),
495                 .flags = I2C_CLIENT_WAKE,
496                 .irq = INT_34XX_SYS_NIRQ,
497                 .platform_data = &ldp_twldata,
498         },
499 };
500
501 static int __init omap_i2c_init(void)
502 {
503         omap_register_i2c_bus(1, 2600, ldp_i2c_boardinfo,
504                         ARRAY_SIZE(ldp_i2c_boardinfo));
505         omap_register_i2c_bus(2, 400, NULL, 0);
506         omap_register_i2c_bus(3, 400, NULL, 0);
507         return 0;
508 }
509
510 static struct twl4030_hsmmc_info mmc[] __initdata = {
511         {
512                 .mmc            = 1,
513                 .wires          = 4,
514                 .gpio_cd        = -EINVAL,
515                 .gpio_wp        = -EINVAL,
516         },
517         {}      /* Terminator */
518 };
519
520 static void __init omap_ldp_init(void)
521 {
522         omap_i2c_init();
523         platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices));
524         omap_board_config = ldp_config;
525         omap_board_config_size = ARRAY_SIZE(ldp_config);
526         ts_gpio = 54;
527         ldp_spi_board_info[0].irq = gpio_to_irq(ts_gpio);
528         spi_register_board_info(ldp_spi_board_info,
529                                 ARRAY_SIZE(ldp_spi_board_info));
530         msecure_init();
531         ads7846_dev_init();
532         omap_serial_init();
533         usb_musb_init();
534         hsmmc_init(mmc);
535 }
536
537 static void __init omap_ldp_map_io(void)
538 {
539         omap2_set_globals_343x();
540         omap2_map_common_io();
541 }
542
543 MACHINE_START(OMAP_LDP, "OMAP LDP board")
544         .phys_io        = 0x48000000,
545         .io_pg_offst    = ((0xd8000000) >> 18) & 0xfffc,
546         .boot_params    = 0x80000100,
547         .map_io         = omap_ldp_map_io,
548         .init_irq       = omap_ldp_init_irq,
549         .init_machine   = omap_ldp_init,
550         .timer          = &omap_timer,
551 MACHINE_END