Merge branch 'topic/cs46xx-drop-fw' into for-next
[sfrench/cifs-2.6.git] / arch / arm / mach-omap2 / board-h4.c
1 /*
2  * linux/arch/arm/mach-omap2/board-h4.c
3  *
4  * Copyright (C) 2005 Nokia Corporation
5  * Author: Paul Mundt <paul.mundt@nokia.com>
6  *
7  * Modified from mach-omap/omap1/board-generic.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 #include <linux/gpio.h>
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/platform_device.h>
17 #include <linux/mtd/mtd.h>
18 #include <linux/mtd/partitions.h>
19 #include <linux/mtd/physmap.h>
20 #include <linux/delay.h>
21 #include <linux/workqueue.h>
22 #include <linux/i2c.h>
23 #include <linux/platform_data/at24.h>
24 #include <linux/input.h>
25 #include <linux/err.h>
26 #include <linux/clk.h>
27 #include <linux/io.h>
28 #include <linux/input/matrix_keypad.h>
29 #include <linux/mfd/menelaus.h>
30 #include <linux/omap-dma.h>
31
32 #include <asm/mach-types.h>
33 #include <asm/mach/arch.h>
34 #include <asm/mach/map.h>
35
36 #include <video/omapdss.h>
37 #include <video/omap-panel-data.h>
38
39 #include "common.h"
40 #include "mux.h"
41 #include "control.h"
42 #include "gpmc.h"
43 #include "gpmc-smc91x.h"
44
45 #define H4_FLASH_CS     0
46
47 #if defined(CONFIG_KEYBOARD_MATRIX) || defined(CONFIG_KEYBOARD_MATRIX_MODULE)
48 static const uint32_t board_matrix_keys[] = {
49         KEY(0, 0, KEY_LEFT),
50         KEY(1, 0, KEY_RIGHT),
51         KEY(2, 0, KEY_A),
52         KEY(3, 0, KEY_B),
53         KEY(4, 0, KEY_C),
54         KEY(0, 1, KEY_DOWN),
55         KEY(1, 1, KEY_UP),
56         KEY(2, 1, KEY_E),
57         KEY(3, 1, KEY_F),
58         KEY(4, 1, KEY_G),
59         KEY(0, 2, KEY_ENTER),
60         KEY(1, 2, KEY_I),
61         KEY(2, 2, KEY_J),
62         KEY(3, 2, KEY_K),
63         KEY(4, 2, KEY_3),
64         KEY(0, 3, KEY_M),
65         KEY(1, 3, KEY_N),
66         KEY(2, 3, KEY_O),
67         KEY(3, 3, KEY_P),
68         KEY(4, 3, KEY_Q),
69         KEY(0, 4, KEY_R),
70         KEY(1, 4, KEY_4),
71         KEY(2, 4, KEY_T),
72         KEY(3, 4, KEY_U),
73         KEY(4, 4, KEY_ENTER),
74         KEY(0, 5, KEY_V),
75         KEY(1, 5, KEY_W),
76         KEY(2, 5, KEY_L),
77         KEY(3, 5, KEY_S),
78         KEY(4, 5, KEY_ENTER),
79 };
80
81 static const struct matrix_keymap_data board_keymap_data = {
82         .keymap                 = board_matrix_keys,
83         .keymap_size            = ARRAY_SIZE(board_matrix_keys),
84 };
85
86 static unsigned int board_keypad_row_gpios[] = {
87         88, 89, 124, 11, 6, 96
88 };
89
90 static unsigned int board_keypad_col_gpios[] = {
91         90, 91, 100, 36, 12, 97, 98
92 };
93
94 static struct matrix_keypad_platform_data board_keypad_platform_data = {
95         .keymap_data    = &board_keymap_data,
96         .row_gpios      = board_keypad_row_gpios,
97         .num_row_gpios  = ARRAY_SIZE(board_keypad_row_gpios),
98         .col_gpios      = board_keypad_col_gpios,
99         .num_col_gpios  = ARRAY_SIZE(board_keypad_col_gpios),
100         .active_low     = 1,
101
102         .debounce_ms            = 20,
103         .col_scan_delay_us      = 5,
104 };
105
106 static struct platform_device board_keyboard = {
107         .name   = "matrix-keypad",
108         .id     = -1,
109         .dev    = {
110                 .platform_data = &board_keypad_platform_data,
111         },
112 };
113 static void __init board_mkp_init(void)
114 {
115         omap_mux_init_gpio(88, OMAP_PULL_ENA | OMAP_PULL_UP);
116         omap_mux_init_gpio(89, OMAP_PULL_ENA | OMAP_PULL_UP);
117         omap_mux_init_gpio(124, OMAP_PULL_ENA | OMAP_PULL_UP);
118         omap_mux_init_signal("mcbsp2_dr.gpio_11", OMAP_PULL_ENA | OMAP_PULL_UP);
119         if (omap_has_menelaus()) {
120                 omap_mux_init_signal("sdrc_a14.gpio0",
121                         OMAP_PULL_ENA | OMAP_PULL_UP);
122                 omap_mux_init_signal("vlynq_rx0.gpio_15", 0);
123                 omap_mux_init_signal("gpio_98", 0);
124                 board_keypad_row_gpios[5] = 0;
125                 board_keypad_col_gpios[2] = 15;
126                 board_keypad_col_gpios[6] = 18;
127         } else {
128                 omap_mux_init_signal("gpio_96", OMAP_PULL_ENA | OMAP_PULL_UP);
129                 omap_mux_init_signal("gpio_100", 0);
130                 omap_mux_init_signal("gpio_98", 0);
131         }
132         omap_mux_init_signal("gpio_90", 0);
133         omap_mux_init_signal("gpio_91", 0);
134         omap_mux_init_signal("gpio_36", 0);
135         omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0);
136         omap_mux_init_signal("gpio_97", 0);
137
138         platform_device_register(&board_keyboard);
139 }
140 #else
141 static inline void board_mkp_init(void)
142 {
143 }
144 #endif
145
146 static struct mtd_partition h4_partitions[] = {
147         /* bootloader (U-Boot, etc) in first sector */
148         {
149               .name             = "bootloader",
150               .offset           = 0,
151               .size             = SZ_128K,
152               .mask_flags       = MTD_WRITEABLE, /* force read-only */
153         },
154         /* bootloader params in the next sector */
155         {
156               .name             = "params",
157               .offset           = MTDPART_OFS_APPEND,
158               .size             = SZ_128K,
159               .mask_flags       = 0,
160         },
161         /* kernel */
162         {
163               .name             = "kernel",
164               .offset           = MTDPART_OFS_APPEND,
165               .size             = SZ_2M,
166               .mask_flags       = 0
167         },
168         /* file system */
169         {
170               .name             = "filesystem",
171               .offset           = MTDPART_OFS_APPEND,
172               .size             = MTDPART_SIZ_FULL,
173               .mask_flags       = 0
174         }
175 };
176
177 static struct physmap_flash_data h4_flash_data = {
178         .width          = 2,
179         .parts          = h4_partitions,
180         .nr_parts       = ARRAY_SIZE(h4_partitions),
181 };
182
183 static struct resource h4_flash_resource = {
184         .flags          = IORESOURCE_MEM,
185 };
186
187 static struct platform_device h4_flash_device = {
188         .name           = "physmap-flash",
189         .id             = 0,
190         .dev            = {
191                 .platform_data  = &h4_flash_data,
192         },
193         .num_resources  = 1,
194         .resource       = &h4_flash_resource,
195 };
196
197 static const struct display_timing cm_t35_lcd_videomode = {
198         .pixelclock     = { 0, 6250000, 0 },
199
200         .hactive = { 0, 240, 0 },
201         .hfront_porch = { 0, 15, 0 },
202         .hback_porch = { 0, 60, 0 },
203         .hsync_len = { 0, 15, 0 },
204
205         .vactive = { 0, 320, 0 },
206         .vfront_porch = { 0, 1, 0 },
207         .vback_porch = { 0, 1, 0 },
208         .vsync_len = { 0, 1, 0 },
209
210         .flags = DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH |
211                 DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE,
212 };
213
214 static struct panel_dpi_platform_data cm_t35_lcd_pdata = {
215         .name                   = "lcd",
216         .source                 = "dpi.0",
217
218         .data_lines             = 16,
219
220         .display_timing         = &cm_t35_lcd_videomode,
221
222         .enable_gpio            = -1,
223         .backlight_gpio         = -1,
224 };
225
226 static struct platform_device cm_t35_lcd_device = {
227         .name                   = "panel-dpi",
228         .id                     = 0,
229         .dev.platform_data      = &cm_t35_lcd_pdata,
230 };
231
232 static struct platform_device *h4_devices[] __initdata = {
233         &h4_flash_device,
234         &cm_t35_lcd_device,
235 };
236
237 static struct omap_dss_board_info h4_dss_data = {
238         .default_display_name = "lcd",
239 };
240
241 /* 2420 Sysboot setup (2430 is different) */
242 static u32 get_sysboot_value(void)
243 {
244         return (omap_ctrl_readl(OMAP24XX_CONTROL_STATUS) &
245                 (OMAP2_SYSBOOT_5_MASK | OMAP2_SYSBOOT_4_MASK |
246                  OMAP2_SYSBOOT_3_MASK | OMAP2_SYSBOOT_2_MASK |
247                  OMAP2_SYSBOOT_1_MASK | OMAP2_SYSBOOT_0_MASK));
248 }
249
250 /* H4-2420's always used muxed mode, H4-2422's always use non-muxed
251  *
252  * Note: OMAP-GIT doesn't correctly do is_cpu_omap2422 and is_cpu_omap2423
253  *  correctly.  The macro needs to look at production_id not just hawkeye.
254  */
255 static u32 is_gpmc_muxed(void)
256 {
257         u32 mux;
258         mux = get_sysboot_value();
259         if ((mux & 0xF) == 0xd)
260                 return 1;       /* NAND config (could be either) */
261         if (mux & 0x2)          /* if mux'ed */
262                 return 1;
263         else
264                 return 0;
265 }
266
267 #if IS_ENABLED(CONFIG_SMC91X)
268
269 static struct omap_smc91x_platform_data board_smc91x_data = {
270         .cs             = 1,
271         .gpio_irq       = 92,
272         .flags          = GPMC_TIMINGS_SMC91C96 | IORESOURCE_IRQ_LOWLEVEL,
273 };
274
275 static void __init board_smc91x_init(void)
276 {
277         if (is_gpmc_muxed())
278                 board_smc91x_data.flags |= GPMC_MUX_ADD_DATA;
279
280         omap_mux_init_gpio(board_smc91x_data.gpio_irq, OMAP_PIN_INPUT);
281         gpmc_smc91x_init(&board_smc91x_data);
282 }
283
284 #else
285
286 static inline void board_smc91x_init(void)
287 {
288 }
289
290 #endif
291
292 static void __init h4_init_flash(void)
293 {
294         unsigned long base;
295
296         if (gpmc_cs_request(H4_FLASH_CS, SZ_64M, &base) < 0) {
297                 printk("Can't request GPMC CS for flash\n");
298                 return;
299         }
300         h4_flash_resource.start = base;
301         h4_flash_resource.end   = base + SZ_64M - 1;
302 }
303
304 static struct at24_platform_data m24c01 = {
305         .byte_len       = SZ_1K / 8,
306         .page_size      = 16,
307 };
308
309 static struct i2c_board_info __initdata h4_i2c_board_info[] = {
310         {
311                 I2C_BOARD_INFO("isp1301_omap", 0x2d),
312         },
313         {       /* EEPROM on mainboard */
314                 I2C_BOARD_INFO("24c01", 0x52),
315                 .platform_data  = &m24c01,
316         },
317         {       /* EEPROM on cpu card */
318                 I2C_BOARD_INFO("24c01", 0x57),
319                 .platform_data  = &m24c01,
320         },
321 };
322
323 #ifdef CONFIG_OMAP_MUX
324 static struct omap_board_mux board_mux[] __initdata = {
325         { .reg_offset = OMAP_MUX_TERMINATOR },
326 };
327 #endif
328
329 static void __init omap_h4_init(void)
330 {
331         omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAF);
332
333         /*
334          * Make sure the serial ports are muxed on at this point.
335          * You have to mux them off in device drivers later on
336          * if not needed.
337          */
338
339         board_mkp_init();
340         h4_i2c_board_info[0].irq = gpio_to_irq(125);
341         i2c_register_board_info(1, h4_i2c_board_info,
342                         ARRAY_SIZE(h4_i2c_board_info));
343
344         platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
345         omap_serial_init();
346         omap_sdrc_init(NULL, NULL);
347         h4_init_flash();
348         board_smc91x_init();
349
350         omap_display_init(&h4_dss_data);
351 }
352
353 MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
354         /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
355         .atag_offset    = 0x100,
356         .reserve        = omap_reserve,
357         .map_io         = omap242x_map_io,
358         .init_early     = omap2420_init_early,
359         .init_irq       = omap2_init_irq,
360         .handle_irq     = omap2_intc_handle_irq,
361         .init_machine   = omap_h4_init,
362         .init_late      = omap2420_init_late,
363         .init_time      = omap2_sync32k_timer_init,
364         .restart        = omap2xxx_restart,
365 MACHINE_END