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