diff options
Diffstat (limited to 'arch/arm/mach-s3c24xx/mach-rx1950.c')
-rw-r--r-- | arch/arm/mach-s3c24xx/mach-rx1950.c | 826 |
1 files changed, 826 insertions, 0 deletions
diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c new file mode 100644 index 000000000000..200debb4c72d --- /dev/null +++ b/arch/arm/mach-s3c24xx/mach-rx1950.c | |||
@@ -0,0 +1,826 @@ | |||
1 | /* linux/arch/arm/mach-s3c2440/mach-rx1950.c | ||
2 | * | ||
3 | * Copyright (c) 2006-2009 Victor Chukhantsev, Denis Grigoriev, | ||
4 | * Copyright (c) 2007-2010 Vasily Khoruzhick | ||
5 | * | ||
6 | * based on smdk2440 written by Ben Dooks | ||
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 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/list.h> | ||
18 | #include <linux/memblock.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/timer.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/serial_core.h> | ||
25 | #include <linux/input.h> | ||
26 | #include <linux/gpio_keys.h> | ||
27 | #include <linux/device.h> | ||
28 | #include <linux/pda_power.h> | ||
29 | #include <linux/pwm_backlight.h> | ||
30 | #include <linux/pwm.h> | ||
31 | #include <linux/s3c_adc_battery.h> | ||
32 | #include <linux/leds.h> | ||
33 | #include <linux/i2c.h> | ||
34 | |||
35 | #include <linux/mtd/mtd.h> | ||
36 | #include <linux/mtd/partitions.h> | ||
37 | |||
38 | #include <linux/mmc/host.h> | ||
39 | |||
40 | #include <asm/mach/arch.h> | ||
41 | #include <asm/mach/map.h> | ||
42 | #include <asm/mach-types.h> | ||
43 | |||
44 | #include <mach/regs-gpio.h> | ||
45 | #include <mach/regs-gpioj.h> | ||
46 | #include <mach/regs-lcd.h> | ||
47 | #include <mach/h1940.h> | ||
48 | #include <mach/fb.h> | ||
49 | |||
50 | #include <plat/clock.h> | ||
51 | #include <plat/regs-serial.h> | ||
52 | #include <plat/regs-iic.h> | ||
53 | #include <plat/mci.h> | ||
54 | #include <plat/udc.h> | ||
55 | #include <plat/nand.h> | ||
56 | #include <plat/iic.h> | ||
57 | #include <plat/devs.h> | ||
58 | #include <plat/cpu.h> | ||
59 | #include <plat/pm.h> | ||
60 | #include <plat/irq.h> | ||
61 | #include <plat/ts.h> | ||
62 | |||
63 | #include <sound/uda1380.h> | ||
64 | |||
65 | #include "common.h" | ||
66 | |||
67 | #define LCD_PWM_PERIOD 192960 | ||
68 | #define LCD_PWM_DUTY 127353 | ||
69 | |||
70 | static struct map_desc rx1950_iodesc[] __initdata = { | ||
71 | }; | ||
72 | |||
73 | static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = { | ||
74 | [0] = { | ||
75 | .hwport = 0, | ||
76 | .flags = 0, | ||
77 | .ucon = 0x3c5, | ||
78 | .ulcon = 0x03, | ||
79 | .ufcon = 0x51, | ||
80 | .clk_sel = S3C2410_UCON_CLKSEL3, | ||
81 | }, | ||
82 | [1] = { | ||
83 | .hwport = 1, | ||
84 | .flags = 0, | ||
85 | .ucon = 0x3c5, | ||
86 | .ulcon = 0x03, | ||
87 | .ufcon = 0x51, | ||
88 | .clk_sel = S3C2410_UCON_CLKSEL3, | ||
89 | }, | ||
90 | /* IR port */ | ||
91 | [2] = { | ||
92 | .hwport = 2, | ||
93 | .flags = 0, | ||
94 | .ucon = 0x3c5, | ||
95 | .ulcon = 0x43, | ||
96 | .ufcon = 0xf1, | ||
97 | .clk_sel = S3C2410_UCON_CLKSEL3, | ||
98 | }, | ||
99 | }; | ||
100 | |||
101 | static struct s3c2410fb_display rx1950_display = { | ||
102 | .type = S3C2410_LCDCON1_TFT, | ||
103 | .width = 240, | ||
104 | .height = 320, | ||
105 | .xres = 240, | ||
106 | .yres = 320, | ||
107 | .bpp = 16, | ||
108 | |||
109 | .pixclock = 260000, | ||
110 | .left_margin = 10, | ||
111 | .right_margin = 20, | ||
112 | .hsync_len = 10, | ||
113 | .upper_margin = 2, | ||
114 | .lower_margin = 2, | ||
115 | .vsync_len = 2, | ||
116 | |||
117 | .lcdcon5 = S3C2410_LCDCON5_FRM565 | | ||
118 | S3C2410_LCDCON5_INVVCLK | | ||
119 | S3C2410_LCDCON5_INVVLINE | | ||
120 | S3C2410_LCDCON5_INVVFRAME | | ||
121 | S3C2410_LCDCON5_HWSWP | | ||
122 | (0x02 << 13) | | ||
123 | (0x02 << 15), | ||
124 | |||
125 | }; | ||
126 | |||
127 | static int power_supply_init(struct device *dev) | ||
128 | { | ||
129 | return gpio_request(S3C2410_GPF(2), "cable plugged"); | ||
130 | } | ||
131 | |||
132 | static int rx1950_is_ac_online(void) | ||
133 | { | ||
134 | return !gpio_get_value(S3C2410_GPF(2)); | ||
135 | } | ||
136 | |||
137 | static void power_supply_exit(struct device *dev) | ||
138 | { | ||
139 | gpio_free(S3C2410_GPF(2)); | ||
140 | } | ||
141 | |||
142 | static char *rx1950_supplicants[] = { | ||
143 | "main-battery" | ||
144 | }; | ||
145 | |||
146 | static struct pda_power_pdata power_supply_info = { | ||
147 | .init = power_supply_init, | ||
148 | .is_ac_online = rx1950_is_ac_online, | ||
149 | .exit = power_supply_exit, | ||
150 | .supplied_to = rx1950_supplicants, | ||
151 | .num_supplicants = ARRAY_SIZE(rx1950_supplicants), | ||
152 | }; | ||
153 | |||
154 | static struct resource power_supply_resources[] = { | ||
155 | [0] = { | ||
156 | .name = "ac", | ||
157 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE | | ||
158 | IORESOURCE_IRQ_HIGHEDGE, | ||
159 | .start = IRQ_EINT2, | ||
160 | .end = IRQ_EINT2, | ||
161 | }, | ||
162 | }; | ||
163 | |||
164 | static struct platform_device power_supply = { | ||
165 | .name = "pda-power", | ||
166 | .id = -1, | ||
167 | .dev = { | ||
168 | .platform_data = | ||
169 | &power_supply_info, | ||
170 | }, | ||
171 | .resource = power_supply_resources, | ||
172 | .num_resources = ARRAY_SIZE(power_supply_resources), | ||
173 | }; | ||
174 | |||
175 | static const struct s3c_adc_bat_thresh bat_lut_noac[] = { | ||
176 | { .volt = 4100, .cur = 156, .level = 100}, | ||
177 | { .volt = 4050, .cur = 156, .level = 95}, | ||
178 | { .volt = 4025, .cur = 141, .level = 90}, | ||
179 | { .volt = 3995, .cur = 144, .level = 85}, | ||
180 | { .volt = 3957, .cur = 162, .level = 80}, | ||
181 | { .volt = 3931, .cur = 147, .level = 75}, | ||
182 | { .volt = 3902, .cur = 147, .level = 70}, | ||
183 | { .volt = 3863, .cur = 153, .level = 65}, | ||
184 | { .volt = 3838, .cur = 150, .level = 60}, | ||
185 | { .volt = 3800, .cur = 153, .level = 55}, | ||
186 | { .volt = 3765, .cur = 153, .level = 50}, | ||
187 | { .volt = 3748, .cur = 172, .level = 45}, | ||
188 | { .volt = 3740, .cur = 153, .level = 40}, | ||
189 | { .volt = 3714, .cur = 175, .level = 35}, | ||
190 | { .volt = 3710, .cur = 156, .level = 30}, | ||
191 | { .volt = 3963, .cur = 156, .level = 25}, | ||
192 | { .volt = 3672, .cur = 178, .level = 20}, | ||
193 | { .volt = 3651, .cur = 178, .level = 15}, | ||
194 | { .volt = 3629, .cur = 178, .level = 10}, | ||
195 | { .volt = 3612, .cur = 162, .level = 5}, | ||
196 | { .volt = 3605, .cur = 162, .level = 0}, | ||
197 | }; | ||
198 | |||
199 | static const struct s3c_adc_bat_thresh bat_lut_acin[] = { | ||
200 | { .volt = 4200, .cur = 0, .level = 100}, | ||
201 | { .volt = 4190, .cur = 0, .level = 99}, | ||
202 | { .volt = 4178, .cur = 0, .level = 95}, | ||
203 | { .volt = 4110, .cur = 0, .level = 70}, | ||
204 | { .volt = 4076, .cur = 0, .level = 65}, | ||
205 | { .volt = 4046, .cur = 0, .level = 60}, | ||
206 | { .volt = 4021, .cur = 0, .level = 55}, | ||
207 | { .volt = 3999, .cur = 0, .level = 50}, | ||
208 | { .volt = 3982, .cur = 0, .level = 45}, | ||
209 | { .volt = 3965, .cur = 0, .level = 40}, | ||
210 | { .volt = 3957, .cur = 0, .level = 35}, | ||
211 | { .volt = 3948, .cur = 0, .level = 30}, | ||
212 | { .volt = 3936, .cur = 0, .level = 25}, | ||
213 | { .volt = 3927, .cur = 0, .level = 20}, | ||
214 | { .volt = 3906, .cur = 0, .level = 15}, | ||
215 | { .volt = 3880, .cur = 0, .level = 10}, | ||
216 | { .volt = 3829, .cur = 0, .level = 5}, | ||
217 | { .volt = 3820, .cur = 0, .level = 0}, | ||
218 | }; | ||
219 | |||
220 | static int rx1950_bat_init(void) | ||
221 | { | ||
222 | int ret; | ||
223 | |||
224 | ret = gpio_request(S3C2410_GPJ(2), "rx1950-charger-enable-1"); | ||
225 | if (ret) | ||
226 | goto err_gpio1; | ||
227 | ret = gpio_request(S3C2410_GPJ(3), "rx1950-charger-enable-2"); | ||
228 | if (ret) | ||
229 | goto err_gpio2; | ||
230 | |||
231 | return 0; | ||
232 | |||
233 | err_gpio2: | ||
234 | gpio_free(S3C2410_GPJ(2)); | ||
235 | err_gpio1: | ||
236 | return ret; | ||
237 | } | ||
238 | |||
239 | static void rx1950_bat_exit(void) | ||
240 | { | ||
241 | gpio_free(S3C2410_GPJ(2)); | ||
242 | gpio_free(S3C2410_GPJ(3)); | ||
243 | } | ||
244 | |||
245 | static void rx1950_enable_charger(void) | ||
246 | { | ||
247 | gpio_direction_output(S3C2410_GPJ(2), 1); | ||
248 | gpio_direction_output(S3C2410_GPJ(3), 1); | ||
249 | } | ||
250 | |||
251 | static void rx1950_disable_charger(void) | ||
252 | { | ||
253 | gpio_direction_output(S3C2410_GPJ(2), 0); | ||
254 | gpio_direction_output(S3C2410_GPJ(3), 0); | ||
255 | } | ||
256 | |||
257 | static DEFINE_SPINLOCK(rx1950_blink_spin); | ||
258 | |||
259 | static int rx1950_led_blink_set(unsigned gpio, int state, | ||
260 | unsigned long *delay_on, unsigned long *delay_off) | ||
261 | { | ||
262 | int blink_gpio, check_gpio; | ||
263 | |||
264 | switch (gpio) { | ||
265 | case S3C2410_GPA(6): | ||
266 | blink_gpio = S3C2410_GPA(4); | ||
267 | check_gpio = S3C2410_GPA(3); | ||
268 | break; | ||
269 | case S3C2410_GPA(7): | ||
270 | blink_gpio = S3C2410_GPA(3); | ||
271 | check_gpio = S3C2410_GPA(4); | ||
272 | break; | ||
273 | default: | ||
274 | return -EINVAL; | ||
275 | break; | ||
276 | } | ||
277 | |||
278 | if (delay_on && delay_off && !*delay_on && !*delay_off) | ||
279 | *delay_on = *delay_off = 500; | ||
280 | |||
281 | spin_lock(&rx1950_blink_spin); | ||
282 | |||
283 | switch (state) { | ||
284 | case GPIO_LED_NO_BLINK_LOW: | ||
285 | case GPIO_LED_NO_BLINK_HIGH: | ||
286 | if (!gpio_get_value(check_gpio)) | ||
287 | gpio_set_value(S3C2410_GPJ(6), 0); | ||
288 | gpio_set_value(blink_gpio, 0); | ||
289 | gpio_set_value(gpio, state); | ||
290 | break; | ||
291 | case GPIO_LED_BLINK: | ||
292 | gpio_set_value(gpio, 0); | ||
293 | gpio_set_value(S3C2410_GPJ(6), 1); | ||
294 | gpio_set_value(blink_gpio, 1); | ||
295 | break; | ||
296 | } | ||
297 | |||
298 | spin_unlock(&rx1950_blink_spin); | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | static struct gpio_led rx1950_leds_desc[] = { | ||
304 | { | ||
305 | .name = "Green", | ||
306 | .default_trigger = "main-battery-full", | ||
307 | .gpio = S3C2410_GPA(6), | ||
308 | .retain_state_suspended = 1, | ||
309 | }, | ||
310 | { | ||
311 | .name = "Red", | ||
312 | .default_trigger | ||
313 | = "main-battery-charging-blink-full-solid", | ||
314 | .gpio = S3C2410_GPA(7), | ||
315 | .retain_state_suspended = 1, | ||
316 | }, | ||
317 | { | ||
318 | .name = "Blue", | ||
319 | .default_trigger = "rx1950-acx-mem", | ||
320 | .gpio = S3C2410_GPA(11), | ||
321 | .retain_state_suspended = 1, | ||
322 | }, | ||
323 | }; | ||
324 | |||
325 | static struct gpio_led_platform_data rx1950_leds_pdata = { | ||
326 | .num_leds = ARRAY_SIZE(rx1950_leds_desc), | ||
327 | .leds = rx1950_leds_desc, | ||
328 | .gpio_blink_set = rx1950_led_blink_set, | ||
329 | }; | ||
330 | |||
331 | static struct platform_device rx1950_leds = { | ||
332 | .name = "leds-gpio", | ||
333 | .id = -1, | ||
334 | .dev = { | ||
335 | .platform_data = &rx1950_leds_pdata, | ||
336 | }, | ||
337 | }; | ||
338 | |||
339 | static struct s3c_adc_bat_pdata rx1950_bat_cfg = { | ||
340 | .init = rx1950_bat_init, | ||
341 | .exit = rx1950_bat_exit, | ||
342 | .enable_charger = rx1950_enable_charger, | ||
343 | .disable_charger = rx1950_disable_charger, | ||
344 | .gpio_charge_finished = S3C2410_GPF(3), | ||
345 | .lut_noac = bat_lut_noac, | ||
346 | .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac), | ||
347 | .lut_acin = bat_lut_acin, | ||
348 | .lut_acin_cnt = ARRAY_SIZE(bat_lut_acin), | ||
349 | .volt_channel = 0, | ||
350 | .current_channel = 1, | ||
351 | .volt_mult = 4235, | ||
352 | .current_mult = 2900, | ||
353 | .internal_impedance = 200, | ||
354 | }; | ||
355 | |||
356 | static struct platform_device rx1950_battery = { | ||
357 | .name = "s3c-adc-battery", | ||
358 | .id = -1, | ||
359 | .dev = { | ||
360 | .parent = &s3c_device_adc.dev, | ||
361 | .platform_data = &rx1950_bat_cfg, | ||
362 | }, | ||
363 | }; | ||
364 | |||
365 | static struct s3c2410fb_mach_info rx1950_lcd_cfg = { | ||
366 | .displays = &rx1950_display, | ||
367 | .num_displays = 1, | ||
368 | .default_display = 0, | ||
369 | |||
370 | .lpcsel = 0x02, | ||
371 | .gpccon = 0xaa9556a9, | ||
372 | .gpccon_mask = 0xffc003fc, | ||
373 | .gpcup = 0x0000ffff, | ||
374 | .gpcup_mask = 0xffffffff, | ||
375 | |||
376 | .gpdcon = 0xaa90aaa1, | ||
377 | .gpdcon_mask = 0xffc0fff0, | ||
378 | .gpdup = 0x0000fcfd, | ||
379 | .gpdup_mask = 0xffffffff, | ||
380 | |||
381 | }; | ||
382 | |||
383 | static struct pwm_device *lcd_pwm; | ||
384 | |||
385 | static void rx1950_lcd_power(int enable) | ||
386 | { | ||
387 | int i; | ||
388 | static int enabled; | ||
389 | if (enabled == enable) | ||
390 | return; | ||
391 | if (!enable) { | ||
392 | |||
393 | /* GPC11-GPC15->OUTPUT */ | ||
394 | for (i = 11; i < 16; i++) | ||
395 | gpio_direction_output(S3C2410_GPC(i), 1); | ||
396 | |||
397 | /* Wait a bit here... */ | ||
398 | mdelay(100); | ||
399 | |||
400 | /* GPD2-GPD7->OUTPUT */ | ||
401 | /* GPD11-GPD15->OUTPUT */ | ||
402 | /* GPD2-GPD7->1, GPD11-GPD15->1 */ | ||
403 | for (i = 2; i < 8; i++) | ||
404 | gpio_direction_output(S3C2410_GPD(i), 1); | ||
405 | for (i = 11; i < 16; i++) | ||
406 | gpio_direction_output(S3C2410_GPD(i), 1); | ||
407 | |||
408 | /* Wait a bit here...*/ | ||
409 | mdelay(100); | ||
410 | |||
411 | /* GPB0->OUTPUT, GPB0->0 */ | ||
412 | gpio_direction_output(S3C2410_GPB(0), 0); | ||
413 | |||
414 | /* GPC1-GPC4->OUTPUT, GPC1-4->0 */ | ||
415 | for (i = 1; i < 5; i++) | ||
416 | gpio_direction_output(S3C2410_GPC(i), 0); | ||
417 | |||
418 | /* GPC15-GPC11->0 */ | ||
419 | for (i = 11; i < 16; i++) | ||
420 | gpio_direction_output(S3C2410_GPC(i), 0); | ||
421 | |||
422 | /* GPD15-GPD11->0, GPD2->GPD7->0 */ | ||
423 | for (i = 11; i < 16; i++) | ||
424 | gpio_direction_output(S3C2410_GPD(i), 0); | ||
425 | |||
426 | for (i = 2; i < 8; i++) | ||
427 | gpio_direction_output(S3C2410_GPD(i), 0); | ||
428 | |||
429 | /* GPC6->0, GPC7->0, GPC5->0 */ | ||
430 | gpio_direction_output(S3C2410_GPC(6), 0); | ||
431 | gpio_direction_output(S3C2410_GPC(7), 0); | ||
432 | gpio_direction_output(S3C2410_GPC(5), 0); | ||
433 | |||
434 | /* GPB1->OUTPUT, GPB1->0 */ | ||
435 | gpio_direction_output(S3C2410_GPB(1), 0); | ||
436 | pwm_config(lcd_pwm, 0, LCD_PWM_PERIOD); | ||
437 | pwm_disable(lcd_pwm); | ||
438 | |||
439 | /* GPC0->0, GPC10->0 */ | ||
440 | gpio_direction_output(S3C2410_GPC(0), 0); | ||
441 | gpio_direction_output(S3C2410_GPC(10), 0); | ||
442 | } else { | ||
443 | pwm_config(lcd_pwm, LCD_PWM_DUTY, LCD_PWM_PERIOD); | ||
444 | pwm_enable(lcd_pwm); | ||
445 | |||
446 | gpio_direction_output(S3C2410_GPC(0), 1); | ||
447 | gpio_direction_output(S3C2410_GPC(5), 1); | ||
448 | |||
449 | s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPB1_TOUT1); | ||
450 | gpio_direction_output(S3C2410_GPC(7), 1); | ||
451 | |||
452 | for (i = 1; i < 5; i++) | ||
453 | s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2)); | ||
454 | |||
455 | for (i = 11; i < 16; i++) | ||
456 | s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2)); | ||
457 | |||
458 | for (i = 2; i < 8; i++) | ||
459 | s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2)); | ||
460 | |||
461 | for (i = 11; i < 16; i++) | ||
462 | s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2)); | ||
463 | |||
464 | gpio_direction_output(S3C2410_GPC(10), 1); | ||
465 | gpio_direction_output(S3C2410_GPC(6), 1); | ||
466 | } | ||
467 | enabled = enable; | ||
468 | } | ||
469 | |||
470 | static void rx1950_bl_power(int enable) | ||
471 | { | ||
472 | static int enabled; | ||
473 | if (enabled == enable) | ||
474 | return; | ||
475 | if (!enable) { | ||
476 | gpio_direction_output(S3C2410_GPB(0), 0); | ||
477 | } else { | ||
478 | /* LED driver need a "push" to power on */ | ||
479 | gpio_direction_output(S3C2410_GPB(0), 1); | ||
480 | /* Warm up backlight for one period of PWM. | ||
481 | * Without this trick its almost impossible to | ||
482 | * enable backlight with low brightness value | ||
483 | */ | ||
484 | ndelay(48000); | ||
485 | s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0); | ||
486 | } | ||
487 | enabled = enable; | ||
488 | } | ||
489 | |||
490 | static int rx1950_backlight_init(struct device *dev) | ||
491 | { | ||
492 | WARN_ON(gpio_request(S3C2410_GPB(0), "Backlight")); | ||
493 | lcd_pwm = pwm_request(1, "RX1950 LCD"); | ||
494 | if (IS_ERR(lcd_pwm)) { | ||
495 | dev_err(dev, "Unable to request PWM for LCD power!\n"); | ||
496 | return PTR_ERR(lcd_pwm); | ||
497 | } | ||
498 | |||
499 | rx1950_lcd_power(1); | ||
500 | rx1950_bl_power(1); | ||
501 | |||
502 | return 0; | ||
503 | } | ||
504 | |||
505 | static void rx1950_backlight_exit(struct device *dev) | ||
506 | { | ||
507 | rx1950_bl_power(0); | ||
508 | rx1950_lcd_power(0); | ||
509 | |||
510 | pwm_free(lcd_pwm); | ||
511 | gpio_free(S3C2410_GPB(0)); | ||
512 | } | ||
513 | |||
514 | |||
515 | static int rx1950_backlight_notify(struct device *dev, int brightness) | ||
516 | { | ||
517 | if (!brightness) { | ||
518 | rx1950_bl_power(0); | ||
519 | rx1950_lcd_power(0); | ||
520 | } else { | ||
521 | rx1950_lcd_power(1); | ||
522 | rx1950_bl_power(1); | ||
523 | } | ||
524 | return brightness; | ||
525 | } | ||
526 | |||
527 | static struct platform_pwm_backlight_data rx1950_backlight_data = { | ||
528 | .pwm_id = 0, | ||
529 | .max_brightness = 24, | ||
530 | .dft_brightness = 4, | ||
531 | .pwm_period_ns = 48000, | ||
532 | .init = rx1950_backlight_init, | ||
533 | .notify = rx1950_backlight_notify, | ||
534 | .exit = rx1950_backlight_exit, | ||
535 | }; | ||
536 | |||
537 | static struct platform_device rx1950_backlight = { | ||
538 | .name = "pwm-backlight", | ||
539 | .dev = { | ||
540 | .parent = &s3c_device_timer[0].dev, | ||
541 | .platform_data = &rx1950_backlight_data, | ||
542 | }, | ||
543 | }; | ||
544 | |||
545 | static void rx1950_set_mmc_power(unsigned char power_mode, unsigned short vdd) | ||
546 | { | ||
547 | switch (power_mode) { | ||
548 | case MMC_POWER_OFF: | ||
549 | gpio_direction_output(S3C2410_GPJ(1), 0); | ||
550 | break; | ||
551 | case MMC_POWER_UP: | ||
552 | case MMC_POWER_ON: | ||
553 | gpio_direction_output(S3C2410_GPJ(1), 1); | ||
554 | break; | ||
555 | default: | ||
556 | break; | ||
557 | } | ||
558 | } | ||
559 | |||
560 | static struct s3c24xx_mci_pdata rx1950_mmc_cfg __initdata = { | ||
561 | .gpio_detect = S3C2410_GPF(5), | ||
562 | .gpio_wprotect = S3C2410_GPH(8), | ||
563 | .set_power = rx1950_set_mmc_power, | ||
564 | .ocr_avail = MMC_VDD_32_33, | ||
565 | }; | ||
566 | |||
567 | static struct mtd_partition rx1950_nand_part[] = { | ||
568 | [0] = { | ||
569 | .name = "Boot0", | ||
570 | .offset = 0, | ||
571 | .size = 0x4000, | ||
572 | .mask_flags = MTD_WRITEABLE, | ||
573 | }, | ||
574 | [1] = { | ||
575 | .name = "Boot1", | ||
576 | .offset = MTDPART_OFS_APPEND, | ||
577 | .size = 0x40000, | ||
578 | .mask_flags = MTD_WRITEABLE, | ||
579 | }, | ||
580 | [2] = { | ||
581 | .name = "Kernel", | ||
582 | .offset = MTDPART_OFS_APPEND, | ||
583 | .size = 0x300000, | ||
584 | .mask_flags = 0, | ||
585 | }, | ||
586 | [3] = { | ||
587 | .name = "Filesystem", | ||
588 | .offset = MTDPART_OFS_APPEND, | ||
589 | .size = MTDPART_SIZ_FULL, | ||
590 | .mask_flags = 0, | ||
591 | }, | ||
592 | }; | ||
593 | |||
594 | static struct s3c2410_nand_set rx1950_nand_sets[] = { | ||
595 | [0] = { | ||
596 | .name = "Internal", | ||
597 | .nr_chips = 1, | ||
598 | .nr_partitions = ARRAY_SIZE(rx1950_nand_part), | ||
599 | .partitions = rx1950_nand_part, | ||
600 | }, | ||
601 | }; | ||
602 | |||
603 | static struct s3c2410_platform_nand rx1950_nand_info = { | ||
604 | .tacls = 25, | ||
605 | .twrph0 = 50, | ||
606 | .twrph1 = 15, | ||
607 | .nr_sets = ARRAY_SIZE(rx1950_nand_sets), | ||
608 | .sets = rx1950_nand_sets, | ||
609 | }; | ||
610 | |||
611 | static struct s3c2410_udc_mach_info rx1950_udc_cfg __initdata = { | ||
612 | .vbus_pin = S3C2410_GPG(5), | ||
613 | .vbus_pin_inverted = 1, | ||
614 | .pullup_pin = S3C2410_GPJ(5), | ||
615 | }; | ||
616 | |||
617 | static struct s3c2410_ts_mach_info rx1950_ts_cfg __initdata = { | ||
618 | .delay = 10000, | ||
619 | .presc = 49, | ||
620 | .oversampling_shift = 3, | ||
621 | }; | ||
622 | |||
623 | static struct gpio_keys_button rx1950_gpio_keys_table[] = { | ||
624 | { | ||
625 | .code = KEY_POWER, | ||
626 | .gpio = S3C2410_GPF(0), | ||
627 | .active_low = 1, | ||
628 | .desc = "Power button", | ||
629 | .wakeup = 1, | ||
630 | }, | ||
631 | { | ||
632 | .code = KEY_F5, | ||
633 | .gpio = S3C2410_GPF(7), | ||
634 | .active_low = 1, | ||
635 | .desc = "Record button", | ||
636 | }, | ||
637 | { | ||
638 | .code = KEY_F1, | ||
639 | .gpio = S3C2410_GPG(0), | ||
640 | .active_low = 1, | ||
641 | .desc = "Calendar button", | ||
642 | }, | ||
643 | { | ||
644 | .code = KEY_F2, | ||
645 | .gpio = S3C2410_GPG(2), | ||
646 | .active_low = 1, | ||
647 | .desc = "Contacts button", | ||
648 | }, | ||
649 | { | ||
650 | .code = KEY_F3, | ||
651 | .gpio = S3C2410_GPG(3), | ||
652 | .active_low = 1, | ||
653 | .desc = "Mail button", | ||
654 | }, | ||
655 | { | ||
656 | .code = KEY_F4, | ||
657 | .gpio = S3C2410_GPG(7), | ||
658 | .active_low = 1, | ||
659 | .desc = "WLAN button", | ||
660 | }, | ||
661 | { | ||
662 | .code = KEY_LEFT, | ||
663 | .gpio = S3C2410_GPG(10), | ||
664 | .active_low = 1, | ||
665 | .desc = "Left button", | ||
666 | }, | ||
667 | { | ||
668 | .code = KEY_RIGHT, | ||
669 | .gpio = S3C2410_GPG(11), | ||
670 | .active_low = 1, | ||
671 | .desc = "Right button", | ||
672 | }, | ||
673 | { | ||
674 | .code = KEY_UP, | ||
675 | .gpio = S3C2410_GPG(4), | ||
676 | .active_low = 1, | ||
677 | .desc = "Up button", | ||
678 | }, | ||
679 | { | ||
680 | .code = KEY_DOWN, | ||
681 | .gpio = S3C2410_GPG(6), | ||
682 | .active_low = 1, | ||
683 | .desc = "Down button", | ||
684 | }, | ||
685 | { | ||
686 | .code = KEY_ENTER, | ||
687 | .gpio = S3C2410_GPG(9), | ||
688 | .active_low = 1, | ||
689 | .desc = "Ok button" | ||
690 | }, | ||
691 | }; | ||
692 | |||
693 | static struct gpio_keys_platform_data rx1950_gpio_keys_data = { | ||
694 | .buttons = rx1950_gpio_keys_table, | ||
695 | .nbuttons = ARRAY_SIZE(rx1950_gpio_keys_table), | ||
696 | }; | ||
697 | |||
698 | static struct platform_device rx1950_device_gpiokeys = { | ||
699 | .name = "gpio-keys", | ||
700 | .dev.platform_data = &rx1950_gpio_keys_data, | ||
701 | }; | ||
702 | |||
703 | static struct uda1380_platform_data uda1380_info = { | ||
704 | .gpio_power = S3C2410_GPJ(0), | ||
705 | .gpio_reset = S3C2410_GPD(0), | ||
706 | .dac_clk = UDA1380_DAC_CLK_SYSCLK, | ||
707 | }; | ||
708 | |||
709 | static struct i2c_board_info rx1950_i2c_devices[] = { | ||
710 | { | ||
711 | I2C_BOARD_INFO("uda1380", 0x1a), | ||
712 | .platform_data = &uda1380_info, | ||
713 | }, | ||
714 | }; | ||
715 | |||
716 | static struct platform_device *rx1950_devices[] __initdata = { | ||
717 | &s3c_device_lcd, | ||
718 | &s3c_device_wdt, | ||
719 | &s3c_device_i2c0, | ||
720 | &s3c_device_iis, | ||
721 | &samsung_asoc_dma, | ||
722 | &s3c_device_usbgadget, | ||
723 | &s3c_device_rtc, | ||
724 | &s3c_device_nand, | ||
725 | &s3c_device_sdi, | ||
726 | &s3c_device_adc, | ||
727 | &s3c_device_ts, | ||
728 | &s3c_device_timer[0], | ||
729 | &s3c_device_timer[1], | ||
730 | &rx1950_backlight, | ||
731 | &rx1950_device_gpiokeys, | ||
732 | &power_supply, | ||
733 | &rx1950_battery, | ||
734 | &rx1950_leds, | ||
735 | }; | ||
736 | |||
737 | static struct clk *rx1950_clocks[] __initdata = { | ||
738 | &s3c24xx_clkout0, | ||
739 | &s3c24xx_clkout1, | ||
740 | }; | ||
741 | |||
742 | static void __init rx1950_map_io(void) | ||
743 | { | ||
744 | s3c24xx_clkout0.parent = &clk_h; | ||
745 | s3c24xx_clkout1.parent = &clk_f; | ||
746 | |||
747 | s3c24xx_register_clocks(rx1950_clocks, ARRAY_SIZE(rx1950_clocks)); | ||
748 | |||
749 | s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc)); | ||
750 | s3c24xx_init_clocks(16934000); | ||
751 | s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs)); | ||
752 | |||
753 | /* setup PM */ | ||
754 | |||
755 | #ifdef CONFIG_PM_H1940 | ||
756 | memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 8); | ||
757 | #endif | ||
758 | |||
759 | s3c_pm_init(); | ||
760 | } | ||
761 | |||
762 | static void __init rx1950_init_machine(void) | ||
763 | { | ||
764 | int i; | ||
765 | |||
766 | s3c24xx_fb_set_platdata(&rx1950_lcd_cfg); | ||
767 | s3c24xx_udc_set_platdata(&rx1950_udc_cfg); | ||
768 | s3c24xx_ts_set_platdata(&rx1950_ts_cfg); | ||
769 | s3c24xx_mci_set_platdata(&rx1950_mmc_cfg); | ||
770 | s3c_i2c0_set_platdata(NULL); | ||
771 | s3c_nand_set_platdata(&rx1950_nand_info); | ||
772 | |||
773 | /* Turn off suspend on both USB ports, and switch the | ||
774 | * selectable USB port to USB device mode. */ | ||
775 | s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST | | ||
776 | S3C2410_MISCCR_USBSUSPND0 | | ||
777 | S3C2410_MISCCR_USBSUSPND1, 0x0); | ||
778 | |||
779 | /* mmc power is disabled by default */ | ||
780 | WARN_ON(gpio_request(S3C2410_GPJ(1), "MMC power")); | ||
781 | gpio_direction_output(S3C2410_GPJ(1), 0); | ||
782 | |||
783 | for (i = 0; i < 8; i++) | ||
784 | WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power")); | ||
785 | |||
786 | for (i = 10; i < 16; i++) | ||
787 | WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power")); | ||
788 | |||
789 | for (i = 2; i < 8; i++) | ||
790 | WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power")); | ||
791 | |||
792 | for (i = 11; i < 16; i++) | ||
793 | WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power")); | ||
794 | |||
795 | WARN_ON(gpio_request(S3C2410_GPB(1), "LCD power")); | ||
796 | |||
797 | WARN_ON(gpio_request(S3C2410_GPA(3), "Red blink")); | ||
798 | WARN_ON(gpio_request(S3C2410_GPA(4), "Green blink")); | ||
799 | WARN_ON(gpio_request(S3C2410_GPJ(6), "LED blink")); | ||
800 | gpio_direction_output(S3C2410_GPA(3), 0); | ||
801 | gpio_direction_output(S3C2410_GPA(4), 0); | ||
802 | gpio_direction_output(S3C2410_GPJ(6), 0); | ||
803 | |||
804 | platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices)); | ||
805 | |||
806 | i2c_register_board_info(0, rx1950_i2c_devices, | ||
807 | ARRAY_SIZE(rx1950_i2c_devices)); | ||
808 | } | ||
809 | |||
810 | /* H1940 and RX3715 need to reserve this for suspend */ | ||
811 | static void __init rx1950_reserve(void) | ||
812 | { | ||
813 | memblock_reserve(0x30003000, 0x1000); | ||
814 | memblock_reserve(0x30081000, 0x1000); | ||
815 | } | ||
816 | |||
817 | MACHINE_START(RX1950, "HP iPAQ RX1950") | ||
818 | /* Maintainers: Vasily Khoruzhick */ | ||
819 | .atag_offset = 0x100, | ||
820 | .map_io = rx1950_map_io, | ||
821 | .reserve = rx1950_reserve, | ||
822 | .init_irq = s3c24xx_init_irq, | ||
823 | .init_machine = rx1950_init_machine, | ||
824 | .timer = &s3c24xx_timer, | ||
825 | .restart = s3c244x_restart, | ||
826 | MACHINE_END | ||