0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/kernel.h>
0015 #include <linux/types.h>
0016
0017 #include <linux/gpio_keys.h>
0018 #include <linux/init.h>
0019 #include <linux/gpio.h>
0020 #include <linux/gpio/machine.h>
0021 #include <linux/input.h>
0022 #include <linux/interrupt.h>
0023 #include <linux/platform_device.h>
0024 #include <linux/serial_core.h>
0025 #include <linux/serial_s3c.h>
0026 #include <linux/timer.h>
0027 #include <linux/io.h>
0028 #include <linux/mmc/host.h>
0029
0030 #include "hardware-s3c24xx.h"
0031 #include <asm/irq.h>
0032 #include <asm/mach-types.h>
0033
0034 #include <linux/platform_data/fb-s3c2410.h>
0035 #include <linux/platform_data/leds-s3c24xx.h>
0036 #include "regs-gpio.h"
0037 #include "gpio-samsung.h"
0038 #include "gpio-cfg.h"
0039
0040 #include <asm/mach/arch.h>
0041 #include <asm/mach/irq.h>
0042 #include <asm/mach/map.h>
0043
0044 #include <linux/platform_data/i2c-s3c2410.h>
0045
0046 #include "cpu.h"
0047 #include "devs.h"
0048 #include <linux/platform_data/mmc-s3cmci.h>
0049 #include <linux/platform_data/usb-s3c2410_udc.h>
0050
0051 #include "s3c24xx.h"
0052
0053 static struct map_desc n30_iodesc[] __initdata = {
0054
0055 };
0056
0057 static struct s3c2410_uartcfg n30_uartcfgs[] = {
0058
0059 [0] = {
0060 .hwport = 0,
0061 .flags = 0,
0062 .ucon = 0x2c5,
0063 .ulcon = 0x03,
0064 .ufcon = 0x51,
0065 },
0066
0067 [1] = {
0068 .hwport = 1,
0069 .flags = 0,
0070 .uart_flags = UPF_CONS_FLOW,
0071 .ucon = 0x2c5,
0072 .ulcon = 0x43,
0073 .ufcon = 0x51,
0074 },
0075
0076
0077 [2] = {
0078 .hwport = 2,
0079 .flags = 0,
0080 .ucon = 0x2c5,
0081 .ulcon = 0x03,
0082 .ufcon = 0x51,
0083 },
0084 };
0085
0086 static struct s3c2410_udc_mach_info n30_udc_cfg __initdata = {
0087 .vbus_pin = S3C2410_GPG(1),
0088 .vbus_pin_inverted = 0,
0089 .pullup_pin = S3C2410_GPB(3),
0090 };
0091
0092 static struct gpio_keys_button n30_buttons[] = {
0093 {
0094 .gpio = S3C2410_GPF(0),
0095 .code = KEY_POWER,
0096 .desc = "Power",
0097 .active_low = 0,
0098 },
0099 {
0100 .gpio = S3C2410_GPG(9),
0101 .code = KEY_UP,
0102 .desc = "Thumbwheel Up",
0103 .active_low = 0,
0104 },
0105 {
0106 .gpio = S3C2410_GPG(8),
0107 .code = KEY_DOWN,
0108 .desc = "Thumbwheel Down",
0109 .active_low = 0,
0110 },
0111 {
0112 .gpio = S3C2410_GPG(7),
0113 .code = KEY_ENTER,
0114 .desc = "Thumbwheel Press",
0115 .active_low = 0,
0116 },
0117 {
0118 .gpio = S3C2410_GPF(7),
0119 .code = KEY_HOMEPAGE,
0120 .desc = "Home",
0121 .active_low = 0,
0122 },
0123 {
0124 .gpio = S3C2410_GPF(6),
0125 .code = KEY_CALENDAR,
0126 .desc = "Calendar",
0127 .active_low = 0,
0128 },
0129 {
0130 .gpio = S3C2410_GPF(5),
0131 .code = KEY_ADDRESSBOOK,
0132 .desc = "Contacts",
0133 .active_low = 0,
0134 },
0135 {
0136 .gpio = S3C2410_GPF(4),
0137 .code = KEY_MAIL,
0138 .desc = "Mail",
0139 .active_low = 0,
0140 },
0141 };
0142
0143 static struct gpio_keys_platform_data n30_button_data = {
0144 .buttons = n30_buttons,
0145 .nbuttons = ARRAY_SIZE(n30_buttons),
0146 };
0147
0148 static struct platform_device n30_button_device = {
0149 .name = "gpio-keys",
0150 .id = -1,
0151 .dev = {
0152 .platform_data = &n30_button_data,
0153 }
0154 };
0155
0156 static struct gpio_keys_button n35_buttons[] = {
0157 {
0158 .gpio = S3C2410_GPF(0),
0159 .code = KEY_POWER,
0160 .type = EV_PWR,
0161 .desc = "Power",
0162 .active_low = 0,
0163 .wakeup = 1,
0164 },
0165 {
0166 .gpio = S3C2410_GPG(9),
0167 .code = KEY_UP,
0168 .desc = "Joystick Up",
0169 .active_low = 0,
0170 },
0171 {
0172 .gpio = S3C2410_GPG(8),
0173 .code = KEY_DOWN,
0174 .desc = "Joystick Down",
0175 .active_low = 0,
0176 },
0177 {
0178 .gpio = S3C2410_GPG(6),
0179 .code = KEY_DOWN,
0180 .desc = "Joystick Left",
0181 .active_low = 0,
0182 },
0183 {
0184 .gpio = S3C2410_GPG(5),
0185 .code = KEY_DOWN,
0186 .desc = "Joystick Right",
0187 .active_low = 0,
0188 },
0189 {
0190 .gpio = S3C2410_GPG(7),
0191 .code = KEY_ENTER,
0192 .desc = "Joystick Press",
0193 .active_low = 0,
0194 },
0195 {
0196 .gpio = S3C2410_GPF(7),
0197 .code = KEY_HOMEPAGE,
0198 .desc = "Home",
0199 .active_low = 0,
0200 },
0201 {
0202 .gpio = S3C2410_GPF(6),
0203 .code = KEY_CALENDAR,
0204 .desc = "Calendar",
0205 .active_low = 0,
0206 },
0207 {
0208 .gpio = S3C2410_GPF(5),
0209 .code = KEY_ADDRESSBOOK,
0210 .desc = "Contacts",
0211 .active_low = 0,
0212 },
0213 {
0214 .gpio = S3C2410_GPF(4),
0215 .code = KEY_MAIL,
0216 .desc = "Mail",
0217 .active_low = 0,
0218 },
0219 {
0220 .gpio = S3C2410_GPF(3),
0221 .code = SW_RADIO,
0222 .desc = "GPS Antenna",
0223 .active_low = 0,
0224 },
0225 {
0226 .gpio = S3C2410_GPG(2),
0227 .code = SW_HEADPHONE_INSERT,
0228 .desc = "Headphone",
0229 .active_low = 0,
0230 },
0231 };
0232
0233 static struct gpio_keys_platform_data n35_button_data = {
0234 .buttons = n35_buttons,
0235 .nbuttons = ARRAY_SIZE(n35_buttons),
0236 };
0237
0238 static struct platform_device n35_button_device = {
0239 .name = "gpio-keys",
0240 .id = -1,
0241 .num_resources = 0,
0242 .dev = {
0243 .platform_data = &n35_button_data,
0244 }
0245 };
0246
0247
0248
0249 static struct gpiod_lookup_table n30_blue_led_gpio_table = {
0250 .dev_id = "s3c24xx_led.1",
0251 .table = {
0252 GPIO_LOOKUP("GPG", 6, NULL, GPIO_ACTIVE_HIGH),
0253 { },
0254 },
0255 };
0256
0257 static struct s3c24xx_led_platdata n30_blue_led_pdata = {
0258 .name = "blue_led",
0259 .def_trigger = "",
0260 };
0261
0262
0263
0264
0265 static struct gpiod_lookup_table n35_blue_led_gpio_table = {
0266 .dev_id = "s3c24xx_led.1",
0267 .table = {
0268 GPIO_LOOKUP("GPD", 8, NULL, GPIO_ACTIVE_HIGH),
0269 { },
0270 },
0271 };
0272
0273 static struct s3c24xx_led_platdata n35_blue_led_pdata = {
0274 .name = "blue_led",
0275 .def_trigger = "",
0276 };
0277
0278
0279
0280
0281
0282
0283 static struct gpiod_lookup_table n30_warning_led_gpio_table = {
0284 .dev_id = "s3c24xx_led.2",
0285 .table = {
0286 GPIO_LOOKUP("GPD", 9, NULL, GPIO_ACTIVE_LOW),
0287 { },
0288 },
0289 };
0290
0291 static struct s3c24xx_led_platdata n30_warning_led_pdata = {
0292 .name = "warning_led",
0293 .def_trigger = "",
0294 };
0295
0296 static struct gpiod_lookup_table n35_warning_led_gpio_table = {
0297 .dev_id = "s3c24xx_led.2",
0298 .table = {
0299 GPIO_LOOKUP("GPD", 9, NULL, GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN),
0300 { },
0301 },
0302 };
0303
0304 static struct s3c24xx_led_platdata n35_warning_led_pdata = {
0305 .name = "warning_led",
0306 .def_trigger = "",
0307 };
0308
0309 static struct platform_device n30_blue_led = {
0310 .name = "s3c24xx_led",
0311 .id = 1,
0312 .dev = {
0313 .platform_data = &n30_blue_led_pdata,
0314 },
0315 };
0316
0317 static struct platform_device n35_blue_led = {
0318 .name = "s3c24xx_led",
0319 .id = 1,
0320 .dev = {
0321 .platform_data = &n35_blue_led_pdata,
0322 },
0323 };
0324
0325 static struct platform_device n30_warning_led = {
0326 .name = "s3c24xx_led",
0327 .id = 2,
0328 .dev = {
0329 .platform_data = &n30_warning_led_pdata,
0330 },
0331 };
0332
0333 static struct platform_device n35_warning_led = {
0334 .name = "s3c24xx_led",
0335 .id = 2,
0336 .dev = {
0337 .platform_data = &n35_warning_led_pdata,
0338 },
0339 };
0340
0341 static struct s3c2410fb_display n30_display __initdata = {
0342 .type = S3C2410_LCDCON1_TFT,
0343 .width = 240,
0344 .height = 320,
0345 .pixclock = 170000,
0346
0347 .xres = 240,
0348 .yres = 320,
0349 .bpp = 16,
0350 .left_margin = 3,
0351 .right_margin = 40,
0352 .hsync_len = 40,
0353 .upper_margin = 2,
0354 .lower_margin = 3,
0355 .vsync_len = 2,
0356
0357 .lcdcon5 = S3C2410_LCDCON5_INVVLINE | S3C2410_LCDCON5_INVVFRAME,
0358 };
0359
0360 static struct s3c2410fb_mach_info n30_fb_info __initdata = {
0361 .displays = &n30_display,
0362 .num_displays = 1,
0363 .default_display = 0,
0364 .lpcsel = 0x06,
0365 };
0366
0367 static void n30_sdi_set_power(unsigned char power_mode, unsigned short vdd)
0368 {
0369 s3c24xx_mci_def_set_power(power_mode, vdd);
0370
0371 switch (power_mode) {
0372 case MMC_POWER_ON:
0373 case MMC_POWER_UP:
0374 gpio_set_value(S3C2410_GPG(4), 1);
0375 break;
0376 case MMC_POWER_OFF:
0377 default:
0378 gpio_set_value(S3C2410_GPG(4), 0);
0379 break;
0380 }
0381 }
0382
0383 static struct s3c24xx_mci_pdata n30_mci_cfg __initdata = {
0384 .ocr_avail = MMC_VDD_32_33,
0385 .set_power = n30_sdi_set_power,
0386 };
0387
0388 static struct gpiod_lookup_table n30_mci_gpio_table = {
0389 .dev_id = "s3c2410-sdi",
0390 .table = {
0391
0392 GPIO_LOOKUP("GPIOF", 1, "cd", GPIO_ACTIVE_LOW),
0393
0394 GPIO_LOOKUP("GPIOG", 10, "wp", GPIO_ACTIVE_LOW),
0395 { },
0396
0397 GPIO_LOOKUP_IDX("GPIOE", 5, "bus", 0, GPIO_ACTIVE_HIGH),
0398 GPIO_LOOKUP_IDX("GPIOE", 6, "bus", 1, GPIO_ACTIVE_HIGH),
0399 GPIO_LOOKUP_IDX("GPIOE", 7, "bus", 2, GPIO_ACTIVE_HIGH),
0400 GPIO_LOOKUP_IDX("GPIOE", 8, "bus", 3, GPIO_ACTIVE_HIGH),
0401 GPIO_LOOKUP_IDX("GPIOE", 9, "bus", 4, GPIO_ACTIVE_HIGH),
0402 GPIO_LOOKUP_IDX("GPIOE", 10, "bus", 5, GPIO_ACTIVE_HIGH),
0403 },
0404 };
0405
0406 static struct platform_device *n30_devices[] __initdata = {
0407 &s3c_device_lcd,
0408 &s3c_device_wdt,
0409 &s3c_device_i2c0,
0410 &s3c_device_iis,
0411 &s3c_device_ohci,
0412 &s3c_device_rtc,
0413 &s3c_device_usbgadget,
0414 &s3c_device_sdi,
0415 &n30_button_device,
0416 &n30_blue_led,
0417 &n30_warning_led,
0418 };
0419
0420 static struct platform_device *n35_devices[] __initdata = {
0421 &s3c_device_lcd,
0422 &s3c_device_wdt,
0423 &s3c_device_i2c0,
0424 &s3c_device_iis,
0425 &s3c_device_rtc,
0426 &s3c_device_usbgadget,
0427 &s3c_device_sdi,
0428 &n35_button_device,
0429 &n35_blue_led,
0430 &n35_warning_led,
0431 };
0432
0433 static struct s3c2410_platform_i2c __initdata n30_i2ccfg = {
0434 .flags = 0,
0435 .slave_addr = 0x10,
0436 .frequency = 10*1000,
0437 };
0438
0439
0440
0441 static void __init n30_hwinit(void)
0442 {
0443
0444
0445
0446
0447
0448
0449
0450
0451 if (machine_is_n30())
0452 __raw_writel(0x007fffff, S3C2410_GPACON);
0453 if (machine_is_n35())
0454 __raw_writel(0x007fefff, S3C2410_GPACON);
0455 __raw_writel(0x00000000, S3C2410_GPADAT);
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470 __raw_writel(0x00154556, S3C2410_GPBCON);
0471 __raw_writel(0x00000750, S3C2410_GPBDAT);
0472 __raw_writel(0x00000073, S3C2410_GPBUP);
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489 __raw_writel(0xaaa80618, S3C2410_GPCCON);
0490 __raw_writel(0x0000014c, S3C2410_GPCDAT);
0491 __raw_writel(0x0000fef2, S3C2410_GPCUP);
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501 __raw_writel(0xaa95aaa4, S3C2410_GPDCON);
0502 __raw_writel(0x00000601, S3C2410_GPDDAT);
0503 __raw_writel(0x0000fbfe, S3C2410_GPDUP);
0504
0505
0506
0507
0508
0509
0510 __raw_writel(0xa56aaaaa, S3C2410_GPECON);
0511 __raw_writel(0x0000efc5, S3C2410_GPEDAT);
0512 __raw_writel(0x0000f81f, S3C2410_GPEUP);
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525 __raw_writel(0x0000aaaa, S3C2410_GPFCON);
0526 __raw_writel(0x00000000, S3C2410_GPFDAT);
0527 __raw_writel(0x000000ff, S3C2410_GPFUP);
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552 if (machine_is_n30())
0553 __raw_writel(0xff0a956a, S3C2410_GPGCON);
0554 if (machine_is_n35())
0555 __raw_writel(0xff4aa92a, S3C2410_GPGCON);
0556 __raw_writel(0x0000e800, S3C2410_GPGDAT);
0557 __raw_writel(0x0000f86f, S3C2410_GPGUP);
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572 __raw_writel(0x0028aaaa, S3C2410_GPHCON);
0573 __raw_writel(0x000005ef, S3C2410_GPHDAT);
0574 __raw_writel(0x0000063f, S3C2410_GPHUP);
0575 }
0576
0577 static void __init n30_map_io(void)
0578 {
0579 s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
0580 n30_hwinit();
0581 s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
0582 s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4);
0583 }
0584
0585 static void __init n30_init_time(void)
0586 {
0587 s3c2410_init_clocks(12000000);
0588 s3c24xx_timer_init();
0589 }
0590
0591
0592
0593 static void __init n30_init(void)
0594 {
0595 WARN_ON(gpio_request(S3C2410_GPG(4), "mmc power"));
0596
0597 s3c24xx_fb_set_platdata(&n30_fb_info);
0598 s3c24xx_udc_set_platdata(&n30_udc_cfg);
0599 gpiod_add_lookup_table(&n30_mci_gpio_table);
0600 s3c24xx_mci_set_platdata(&n30_mci_cfg);
0601 s3c_i2c0_set_platdata(&n30_i2ccfg);
0602
0603
0604
0605
0606 s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
0607 S3C2410_MISCCR_USBSUSPND0 |
0608 S3C2410_MISCCR_USBSUSPND1, 0x0);
0609
0610
0611 s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2),
0612 S3C_GPIO_PULL_NONE);
0613
0614 if (machine_is_n30()) {
0615
0616
0617 s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
0618 S3C2410_MISCCR_USBSUSPND0 |
0619 S3C2410_MISCCR_USBSUSPND1, 0x0);
0620
0621
0622 s3c_gpio_setpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE);
0623 s3c_gpio_setpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE);
0624 gpiod_add_lookup_table(&n30_blue_led_gpio_table);
0625 gpiod_add_lookup_table(&n30_warning_led_gpio_table);
0626
0627 platform_add_devices(n30_devices, ARRAY_SIZE(n30_devices));
0628 }
0629
0630 if (machine_is_n35()) {
0631
0632
0633
0634
0635
0636
0637
0638
0639 s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
0640 S3C2410_MISCCR_USBSUSPND0 |
0641 S3C2410_MISCCR_USBSUSPND1,
0642 S3C2410_MISCCR_USBSUSPND0);
0643
0644
0645 s3c_gpio_setpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE);
0646 s3c_gpio_setpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE);
0647 gpiod_add_lookup_table(&n35_blue_led_gpio_table);
0648 gpiod_add_lookup_table(&n35_warning_led_gpio_table);
0649
0650 platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices));
0651 }
0652 }
0653
0654 MACHINE_START(N30, "Acer-N30")
0655
0656
0657
0658 .atag_offset = 0x100,
0659 .nr_irqs = NR_IRQS_S3C2410,
0660 .init_time = n30_init_time,
0661 .init_machine = n30_init,
0662 .init_irq = s3c2410_init_irq,
0663 .map_io = n30_map_io,
0664 MACHINE_END
0665
0666 MACHINE_START(N35, "Acer-N35")
0667
0668
0669 .atag_offset = 0x100,
0670 .nr_irqs = NR_IRQS_S3C2410,
0671 .init_time = n30_init_time,
0672 .init_machine = n30_init,
0673 .init_irq = s3c2410_init_irq,
0674 .map_io = n30_map_io,
0675 MACHINE_END