Commit | Line | Data |
---|---|---|
4024533e PM |
1 | /* |
2 | * Board-specific setup code for Remote Media Terminal 1 (RMT1) | |
3 | * add-on board for the ATNGW100 Network Gateway | |
4 | * | |
5 | * Copyright (C) 2008 Mediama Technologies | |
6 | * Based on ATNGW100 Network Gateway (Copyright (C) Atmel) | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License version 2 as | |
10 | * published by the Free Software Foundation. | |
11 | */ | |
12 | #include <linux/gpio.h> | |
13 | #include <linux/init.h> | |
14 | #include <linux/irq.h> | |
15 | #include <linux/linkage.h> | |
16 | #include <linux/platform_device.h> | |
17 | #include <linux/types.h> | |
18 | #include <linux/fb.h> | |
19 | #include <linux/leds.h> | |
20 | #include <linux/input.h> | |
21 | #include <linux/gpio_keys.h> | |
22 | #include <linux/atmel_serial.h> | |
23 | #include <linux/spi/spi.h> | |
24 | #include <linux/spi/ads7846.h> | |
25 | ||
26 | #include <video/atmel_lcdc.h> | |
27 | #include <sound/atmel-ac97c.h> | |
28 | ||
29 | #include <asm/delay.h> | |
30 | #include <asm/io.h> | |
31 | #include <asm/setup.h> | |
32 | ||
33 | #include <mach/at32ap700x.h> | |
34 | #include <mach/board.h> | |
35 | #include <mach/init.h> | |
36 | #include <mach/portmux.h> | |
37 | ||
38 | /* Define board-specifoic GPIO assignments */ | |
39 | #define PIN_LCD_BL GPIO_PIN_PA(28) | |
40 | #define PWM_CH_BL 0 /* Must match with GPIO pin definition */ | |
41 | #define PIN_LCD_DISP GPIO_PIN_PA(31) | |
42 | #define PIN_AC97_RST_N GPIO_PIN_PA(30) | |
43 | #define PB_EXTINT_BASE 25 | |
44 | #define TS_IRQ 0 | |
45 | #define PIN_TS_EXTINT GPIO_PIN_PB(PB_EXTINT_BASE+TS_IRQ) | |
46 | #define PIN_PB_LEFT GPIO_PIN_PB(11) | |
47 | #define PIN_PB_RIGHT GPIO_PIN_PB(12) | |
48 | #define PIN_PWR_SW_N GPIO_PIN_PB(14) | |
49 | #define PIN_PWR_ON GPIO_PIN_PB(13) | |
50 | #define PIN_ZB_RST_N GPIO_PIN_PA(21) | |
51 | #define PIN_BT_RST GPIO_PIN_PA(22) | |
52 | #define PIN_LED_SYS GPIO_PIN_PA(16) | |
53 | #define PIN_LED_A GPIO_PIN_PA(19) | |
54 | #define PIN_LED_B GPIO_PIN_PE(19) | |
55 | ||
56 | #ifdef CONFIG_BOARD_MRMT_LCD_LQ043T3DX0X | |
57 | /* Sharp LQ043T3DX0x (or compatible) panel */ | |
58 | static struct fb_videomode __initdata lcd_fb_modes[] = { | |
59 | { | |
60 | .name = "480x272 @ 59.94Hz", | |
61 | .refresh = 59.94, | |
62 | .xres = 480, .yres = 272, | |
63 | .pixclock = KHZ2PICOS(9000), | |
64 | ||
65 | .left_margin = 2, .right_margin = 2, | |
66 | .upper_margin = 3, .lower_margin = 9, | |
67 | .hsync_len = 41, .vsync_len = 1, | |
68 | ||
69 | .sync = 0, | |
70 | .vmode = FB_VMODE_NONINTERLACED, | |
71 | }, | |
72 | }; | |
73 | ||
74 | static struct fb_monspecs __initdata lcd_fb_default_monspecs = { | |
75 | .manufacturer = "SHA", | |
76 | .monitor = "LQ043T3DX02", | |
77 | .modedb = lcd_fb_modes, | |
78 | .modedb_len = ARRAY_SIZE(lcd_fb_modes), | |
79 | .hfmin = 14915, | |
80 | .hfmax = 17638, | |
81 | .vfmin = 53, | |
82 | .vfmax = 61, | |
83 | .dclkmax = 9260000, | |
84 | }; | |
85 | ||
86 | static struct atmel_lcdfb_info __initdata rmt_lcdc_data = { | |
87 | .default_bpp = 24, | |
88 | .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, | |
89 | .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT | |
90 | | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE | |
91 | | ATMEL_LCDC_INVCLK_NORMAL | |
92 | | ATMEL_LCDC_MEMOR_BIG), | |
93 | .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, | |
94 | .default_monspecs = &lcd_fb_default_monspecs, | |
95 | .guard_time = 2, | |
96 | }; | |
97 | #endif | |
98 | ||
99 | #ifdef CONFIG_BOARD_MRMT_LCD_KWH043GM08 | |
100 | /* Sharp KWH043GM08-Fxx (or compatible) panel */ | |
101 | static struct fb_videomode __initdata lcd_fb_modes[] = { | |
102 | { | |
103 | .name = "480x272 @ 59.94Hz", | |
104 | .refresh = 59.94, | |
105 | .xres = 480, .yres = 272, | |
106 | .pixclock = KHZ2PICOS(9000), | |
107 | ||
108 | .left_margin = 2, .right_margin = 2, | |
109 | .upper_margin = 3, .lower_margin = 9, | |
110 | .hsync_len = 41, .vsync_len = 1, | |
111 | ||
112 | .sync = 0, | |
113 | .vmode = FB_VMODE_NONINTERLACED, | |
114 | }, | |
115 | }; | |
116 | ||
117 | static struct fb_monspecs __initdata lcd_fb_default_monspecs = { | |
118 | .manufacturer = "FOR", | |
119 | .monitor = "KWH043GM08", | |
120 | .modedb = lcd_fb_modes, | |
121 | .modedb_len = ARRAY_SIZE(lcd_fb_modes), | |
122 | .hfmin = 14915, | |
123 | .hfmax = 17638, | |
124 | .vfmin = 53, | |
125 | .vfmax = 61, | |
126 | .dclkmax = 9260000, | |
127 | }; | |
128 | ||
129 | static struct atmel_lcdfb_info __initdata rmt_lcdc_data = { | |
130 | .default_bpp = 24, | |
131 | .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, | |
132 | .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT | |
133 | | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE | |
134 | | ATMEL_LCDC_INVCLK_INVERTED | |
135 | | ATMEL_LCDC_MEMOR_BIG), | |
136 | .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, | |
137 | .default_monspecs = &lcd_fb_default_monspecs, | |
138 | .guard_time = 2, | |
139 | }; | |
140 | #endif | |
141 | ||
142 | #ifdef CONFIG_BOARD_MRMT_AC97 | |
143 | static struct ac97c_platform_data __initdata ac97c0_data = { | |
144 | .reset_pin = PIN_AC97_RST_N, | |
145 | }; | |
146 | #endif | |
147 | ||
148 | #ifdef CONFIG_BOARD_MRMT_UCB1400_TS | |
149 | /* NOTE: IRQ assignment relies on kernel module parameter */ | |
150 | static struct platform_device rmt_ts_device = { | |
151 | .name = "ucb1400_ts", | |
152 | .id = -1, | |
153 | } | |
154 | }; | |
155 | #endif | |
156 | ||
157 | #ifdef CONFIG_BOARD_MRMT_BL_PWM | |
158 | /* PWM LEDs: LCD Backlight, etc */ | |
159 | static struct gpio_led rmt_pwm_led[] = { | |
160 | /* here the "gpio" is actually a PWM channel */ | |
161 | { .name = "backlight", .gpio = PWM_CH_BL, }, | |
162 | }; | |
163 | ||
164 | static struct gpio_led_platform_data rmt_pwm_led_data = { | |
165 | .num_leds = ARRAY_SIZE(rmt_pwm_led), | |
166 | .leds = rmt_pwm_led, | |
167 | }; | |
168 | ||
169 | static struct platform_device rmt_pwm_led_dev = { | |
170 | .name = "leds-atmel-pwm", | |
171 | .id = -1, | |
172 | .dev = { | |
173 | .platform_data = &rmt_pwm_led_data, | |
174 | }, | |
175 | }; | |
176 | #endif | |
177 | ||
178 | #ifdef CONFIG_BOARD_MRMT_ADS7846_TS | |
179 | static int ads7846_pendown_state(void) | |
180 | { | |
181 | return !gpio_get_value( PIN_TS_EXTINT ); /* PENIRQ.*/ | |
182 | } | |
183 | ||
184 | static struct ads7846_platform_data ads_info = { | |
185 | .model = 7846, | |
186 | .keep_vref_on = 0, /* Use external VREF pin */ | |
187 | .vref_delay_usecs = 0, | |
188 | .vref_mv = 3300, /* VREF = 3.3V */ | |
189 | .settle_delay_usecs = 800, | |
190 | .penirq_recheck_delay_usecs = 800, | |
191 | .x_plate_ohms = 750, | |
192 | .y_plate_ohms = 300, | |
193 | .pressure_max = 4096, | |
194 | .debounce_max = 1, | |
195 | .debounce_rep = 0, | |
196 | .debounce_tol = (~0), | |
197 | .get_pendown_state = ads7846_pendown_state, | |
198 | .filter = NULL, | |
199 | .filter_init = NULL, | |
200 | }; | |
201 | ||
202 | static struct spi_board_info spi01_board_info[] __initdata = { | |
203 | { | |
204 | .modalias = "ads7846", | |
205 | .max_speed_hz = 31250*26, | |
206 | .bus_num = 0, | |
207 | .chip_select = 1, | |
208 | .platform_data = &ads_info, | |
209 | .irq = AT32_EXTINT(TS_IRQ), | |
210 | }, | |
211 | }; | |
212 | #endif | |
213 | ||
214 | /* GPIO Keys: left, right, power, etc */ | |
215 | static const struct gpio_keys_button rmt_gpio_keys_buttons[] = { | |
216 | [0] = { | |
217 | .type = EV_KEY, | |
218 | .code = KEY_POWER, | |
219 | .gpio = PIN_PWR_SW_N, | |
220 | .active_low = 1, | |
221 | .desc = "power button", | |
222 | }, | |
223 | [1] = { | |
224 | .type = EV_KEY, | |
225 | .code = KEY_LEFT, | |
226 | .gpio = PIN_PB_LEFT, | |
227 | .active_low = 1, | |
228 | .desc = "left button", | |
229 | }, | |
230 | [2] = { | |
231 | .type = EV_KEY, | |
232 | .code = KEY_RIGHT, | |
233 | .gpio = PIN_PB_RIGHT, | |
234 | .active_low = 1, | |
235 | .desc = "right button", | |
236 | }, | |
237 | }; | |
238 | ||
239 | static const struct gpio_keys_platform_data rmt_gpio_keys_data = { | |
240 | .nbuttons = ARRAY_SIZE(rmt_gpio_keys_buttons), | |
241 | .buttons = (void *) rmt_gpio_keys_buttons, | |
242 | }; | |
243 | ||
244 | static struct platform_device rmt_gpio_keys = { | |
245 | .name = "gpio-keys", | |
246 | .id = -1, | |
247 | .dev = { | |
248 | .platform_data = (void *) &rmt_gpio_keys_data, | |
249 | } | |
250 | }; | |
251 | ||
252 | #ifdef CONFIG_BOARD_MRMT_RTC_I2C | |
253 | static struct i2c_board_info __initdata mrmt1_i2c_rtc = { | |
254 | I2C_BOARD_INFO("s35390a", 0x30), | |
255 | .irq = 0, | |
256 | }; | |
257 | #endif | |
258 | ||
259 | static void mrmt_power_off(void) | |
260 | { | |
261 | /* PWR_ON=0 will force power off */ | |
262 | gpio_set_value( PIN_PWR_ON, 0 ); | |
263 | } | |
264 | ||
265 | static int __init mrmt1_init(void) | |
266 | { | |
267 | gpio_set_value( PIN_PWR_ON, 1 ); /* Ensure PWR_ON is enabled */ | |
268 | ||
269 | pm_power_off = mrmt_power_off; | |
270 | ||
271 | /* Setup USARTS (other than console) */ | |
272 | at32_map_usart(2, 1, 0); /* USART 2: /dev/ttyS1, RMT1:DB9M */ | |
273 | at32_map_usart(3, 2, ATMEL_USART_RTS | ATMEL_USART_CTS); | |
274 | /* USART 3: /dev/ttyS2, RMT1:Wireless, w/ RTS/CTS */ | |
275 | at32_add_device_usart(1); | |
276 | at32_add_device_usart(2); | |
277 | ||
278 | /* Select GPIO Key pins */ | |
279 | at32_select_gpio( PIN_PWR_SW_N, AT32_GPIOF_DEGLITCH); | |
280 | at32_select_gpio( PIN_PB_LEFT, AT32_GPIOF_DEGLITCH); | |
281 | at32_select_gpio( PIN_PB_RIGHT, AT32_GPIOF_DEGLITCH); | |
282 | platform_device_register(&rmt_gpio_keys); | |
283 | ||
284 | #ifdef CONFIG_BOARD_MRMT_RTC_I2C | |
285 | i2c_register_board_info(0, &mrmt1_i2c_rtc, 1); | |
286 | #endif | |
287 | ||
288 | #ifndef CONFIG_BOARD_MRMT_LCD_DISABLE | |
289 | /* User "alternate" LCDC inferface on Port E & D */ | |
290 | /* NB: exclude LCDC_CC pin, as NGW100 reserves it for other use */ | |
291 | at32_add_device_lcdc(0, &rmt_lcdc_data, | |
292 | fbmem_start, fbmem_size, | |
293 | (ATMEL_LCDC_ALT_24BIT | ATMEL_LCDC_PE_DVAL ) ); | |
294 | #endif | |
295 | ||
296 | #ifdef CONFIG_BOARD_MRMT_AC97 | |
297 | at32_add_device_ac97c(0, &ac97c0_data, AC97C_BOTH); | |
298 | #endif | |
299 | ||
300 | #ifdef CONFIG_BOARD_MRMT_ADS7846_TS | |
301 | /* Select the Touchscreen interrupt pin mode */ | |
302 | at32_select_periph( GPIO_PIOB_BASE, 1 << (PB_EXTINT_BASE+TS_IRQ), | |
303 | GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH); | |
304 | set_irq_type( AT32_EXTINT(TS_IRQ), IRQ_TYPE_EDGE_FALLING ); | |
305 | spi_register_board_info(spi01_board_info,ARRAY_SIZE(spi01_board_info)); | |
306 | #endif | |
307 | ||
308 | #ifdef CONFIG_BOARD_MRMT_UCB1400_TS | |
309 | /* Select the Touchscreen interrupt pin mode */ | |
310 | at32_select_periph( GPIO_PIOB_BASE, 1 << (PB_EXTINT_BASE+TS_IRQ), | |
311 | GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH); | |
312 | platform_device_register(&rmt_ts_device); | |
313 | #endif | |
314 | ||
315 | at32_select_gpio( PIN_LCD_DISP, AT32_GPIOF_OUTPUT ); | |
316 | gpio_request( PIN_LCD_DISP, "LCD_DISP" ); | |
317 | gpio_direction_output( PIN_LCD_DISP, 0 ); /* LCD DISP */ | |
318 | #ifdef CONFIG_BOARD_MRMT_LCD_DISABLE | |
319 | /* Keep Backlight and DISP off */ | |
320 | at32_select_gpio( PIN_LCD_BL, AT32_GPIOF_OUTPUT ); | |
321 | gpio_request( PIN_LCD_BL, "LCD_BL" ); | |
322 | gpio_direction_output( PIN_LCD_BL, 0 ); /* Backlight */ | |
323 | #else | |
324 | gpio_set_value( PIN_LCD_DISP, 1 ); /* DISP asserted first */ | |
325 | #ifdef CONFIG_BOARD_MRMT_BL_PWM | |
326 | /* Use PWM for Backlight controls */ | |
327 | at32_add_device_pwm(1 << PWM_CH_BL); | |
328 | platform_device_register(&rmt_pwm_led_dev); | |
329 | #else | |
330 | /* Backlight always on */ | |
331 | udelay( 1 ); | |
332 | at32_select_gpio( PIN_LCD_BL, AT32_GPIOF_OUTPUT ); | |
333 | gpio_request( PIN_LCD_BL, "LCD_BL" ); | |
334 | gpio_direction_output( PIN_LCD_BL, 1 ); | |
335 | #endif | |
336 | #endif | |
337 | ||
338 | /* Make sure BT and Zigbee modules in reset */ | |
339 | at32_select_gpio( PIN_BT_RST, AT32_GPIOF_OUTPUT ); | |
340 | gpio_request( PIN_BT_RST, "BT_RST" ); | |
341 | gpio_direction_output( PIN_BT_RST, 1 ); | |
342 | /* BT Module in Reset */ | |
343 | ||
344 | at32_select_gpio( PIN_ZB_RST_N, AT32_GPIOF_OUTPUT ); | |
345 | gpio_request( PIN_ZB_RST_N, "ZB_RST_N" ); | |
346 | gpio_direction_output( PIN_ZB_RST_N, 0 ); | |
347 | /* XBee Module in Reset */ | |
348 | ||
349 | #ifdef CONFIG_BOARD_MRMT_WIRELESS_ZB | |
350 | udelay( 1000 ); | |
351 | /* Unreset the XBee Module */ | |
352 | gpio_set_value( PIN_ZB_RST_N, 1 ); | |
353 | #endif | |
354 | #ifdef CONFIG_BOARD_MRMT_WIRELESS_BT | |
355 | udelay( 1000 ); | |
356 | /* Unreset the BT Module */ | |
357 | gpio_set_value( PIN_BT_RST, 0 ); | |
358 | #endif | |
359 | ||
360 | return 0; | |
361 | } | |
362 | arch_initcall(mrmt1_init); | |
363 | ||
364 | static int __init mrmt1_early_init(void) | |
365 | { | |
366 | /* To maintain power-on signal in case boot loader did not already */ | |
367 | at32_select_gpio( PIN_PWR_ON, AT32_GPIOF_OUTPUT ); | |
368 | gpio_request( PIN_PWR_ON, "PIN_PWR_ON" ); | |
369 | gpio_direction_output( PIN_PWR_ON, 1 ); | |
370 | ||
371 | return 0; | |
372 | } | |
373 | core_initcall(mrmt1_early_init); |