linux/arch/arm/mach-pxa/mainstone.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mach-pxa/mainstone.c
   3 *
   4 *  Support for the Intel HCDDBBVA0 Development Platform.
   5 *  (go figure how they came up with such name...)
   6 *
   7 *  Author:     Nicolas Pitre
   8 *  Created:    Nov 05, 2002
   9 *  Copyright:  MontaVista Software Inc.
  10 *
  11 *  This program is free software; you can redistribute it and/or modify
  12 *  it under the terms of the GNU General Public License version 2 as
  13 *  published by the Free Software Foundation.
  14 */
  15#include <linux/gpio.h>
  16#include <linux/gpio/machine.h>
  17#include <linux/init.h>
  18#include <linux/platform_device.h>
  19#include <linux/syscore_ops.h>
  20#include <linux/interrupt.h>
  21#include <linux/sched.h>
  22#include <linux/bitops.h>
  23#include <linux/fb.h>
  24#include <linux/ioport.h>
  25#include <linux/mtd/mtd.h>
  26#include <linux/mtd/partitions.h>
  27#include <linux/input.h>
  28#include <linux/gpio_keys.h>
  29#include <linux/pwm.h>
  30#include <linux/pwm_backlight.h>
  31#include <linux/smc91x.h>
  32#include <linux/platform_data/i2c-pxa.h>
  33#include <linux/slab.h>
  34#include <linux/leds.h>
  35
  36#include <asm/types.h>
  37#include <asm/setup.h>
  38#include <asm/memory.h>
  39#include <asm/mach-types.h>
  40#include <mach/hardware.h>
  41#include <asm/irq.h>
  42#include <asm/sizes.h>
  43
  44#include <asm/mach/arch.h>
  45#include <asm/mach/map.h>
  46#include <asm/mach/irq.h>
  47#include <asm/mach/flash.h>
  48
  49#include "pxa27x.h"
  50#include <mach/mainstone.h>
  51#include <mach/audio.h>
  52#include <linux/platform_data/video-pxafb.h>
  53#include <linux/platform_data/mmc-pxamci.h>
  54#include <linux/platform_data/irda-pxaficp.h>
  55#include <linux/platform_data/usb-ohci-pxa27x.h>
  56#include <linux/platform_data/keypad-pxa27x.h>
  57#include <mach/smemc.h>
  58
  59#include "generic.h"
  60#include "devices.h"
  61
  62static unsigned long mainstone_pin_config[] = {
  63        /* Chip Select */
  64        GPIO15_nCS_1,
  65
  66        /* LCD - 16bpp Active TFT */
  67        GPIOxx_LCD_TFT_16BPP,
  68        GPIO16_PWM0_OUT,        /* Backlight */
  69
  70        /* MMC */
  71        GPIO32_MMC_CLK,
  72        GPIO112_MMC_CMD,
  73        GPIO92_MMC_DAT_0,
  74        GPIO109_MMC_DAT_1,
  75        GPIO110_MMC_DAT_2,
  76        GPIO111_MMC_DAT_3,
  77
  78        /* USB Host Port 1 */
  79        GPIO88_USBH1_PWR,
  80        GPIO89_USBH1_PEN,
  81
  82        /* PC Card */
  83        GPIO48_nPOE,
  84        GPIO49_nPWE,
  85        GPIO50_nPIOR,
  86        GPIO51_nPIOW,
  87        GPIO85_nPCE_1,
  88        GPIO54_nPCE_2,
  89        GPIO79_PSKTSEL,
  90        GPIO55_nPREG,
  91        GPIO56_nPWAIT,
  92        GPIO57_nIOIS16,
  93
  94        /* AC97 */
  95        GPIO28_AC97_BITCLK,
  96        GPIO29_AC97_SDATA_IN_0,
  97        GPIO30_AC97_SDATA_OUT,
  98        GPIO31_AC97_SYNC,
  99        GPIO45_AC97_SYSCLK,
 100
 101        /* Keypad */
 102        GPIO93_KP_DKIN_0,
 103        GPIO94_KP_DKIN_1,
 104        GPIO95_KP_DKIN_2,
 105        GPIO100_KP_MKIN_0       | WAKEUP_ON_LEVEL_HIGH,
 106        GPIO101_KP_MKIN_1       | WAKEUP_ON_LEVEL_HIGH,
 107        GPIO102_KP_MKIN_2       | WAKEUP_ON_LEVEL_HIGH,
 108        GPIO97_KP_MKIN_3        | WAKEUP_ON_LEVEL_HIGH,
 109        GPIO98_KP_MKIN_4        | WAKEUP_ON_LEVEL_HIGH,
 110        GPIO99_KP_MKIN_5        | WAKEUP_ON_LEVEL_HIGH,
 111        GPIO103_KP_MKOUT_0,
 112        GPIO104_KP_MKOUT_1,
 113        GPIO105_KP_MKOUT_2,
 114        GPIO106_KP_MKOUT_3,
 115        GPIO107_KP_MKOUT_4,
 116        GPIO108_KP_MKOUT_5,
 117        GPIO96_KP_MKOUT_6,
 118
 119        /* I2C */
 120        GPIO117_I2C_SCL,
 121        GPIO118_I2C_SDA,
 122
 123        /* GPIO */
 124        GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
 125};
 126
 127static struct resource smc91x_resources[] = {
 128        [0] = {
 129                .start  = (MST_ETH_PHYS + 0x300),
 130                .end    = (MST_ETH_PHYS + 0xfffff),
 131                .flags  = IORESOURCE_MEM,
 132        },
 133        [1] = {
 134                .start  = MAINSTONE_IRQ(3),
 135                .end    = MAINSTONE_IRQ(3),
 136                .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 137        }
 138};
 139
 140static struct smc91x_platdata mainstone_smc91x_info = {
 141        .flags  = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
 142                  SMC91X_NOWAIT | SMC91X_USE_DMA,
 143        .pxa_u16_align4 = true,
 144};
 145
 146static struct platform_device smc91x_device = {
 147        .name           = "smc91x",
 148        .id             = 0,
 149        .num_resources  = ARRAY_SIZE(smc91x_resources),
 150        .resource       = smc91x_resources,
 151        .dev            = {
 152                .platform_data = &mainstone_smc91x_info,
 153        },
 154};
 155
 156static int mst_audio_startup(struct snd_pcm_substream *substream, void *priv)
 157{
 158        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 159                MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF;
 160        return 0;
 161}
 162
 163static void mst_audio_shutdown(struct snd_pcm_substream *substream, void *priv)
 164{
 165        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 166                MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
 167}
 168
 169static long mst_audio_suspend_mask;
 170
 171static void mst_audio_suspend(void *priv)
 172{
 173        mst_audio_suspend_mask = MST_MSCWR2;
 174        MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
 175}
 176
 177static void mst_audio_resume(void *priv)
 178{
 179        MST_MSCWR2 &= mst_audio_suspend_mask | ~MST_MSCWR2_AC97_SPKROFF;
 180}
 181
 182static pxa2xx_audio_ops_t mst_audio_ops = {
 183        .startup        = mst_audio_startup,
 184        .shutdown       = mst_audio_shutdown,
 185        .suspend        = mst_audio_suspend,
 186        .resume         = mst_audio_resume,
 187};
 188
 189static struct resource flash_resources[] = {
 190        [0] = {
 191                .start  = PXA_CS0_PHYS,
 192                .end    = PXA_CS0_PHYS + SZ_64M - 1,
 193                .flags  = IORESOURCE_MEM,
 194        },
 195        [1] = {
 196                .start  = PXA_CS1_PHYS,
 197                .end    = PXA_CS1_PHYS + SZ_64M - 1,
 198                .flags  = IORESOURCE_MEM,
 199        },
 200};
 201
 202static struct mtd_partition mainstoneflash0_partitions[] = {
 203        {
 204                .name =         "Bootloader",
 205                .size =         0x00040000,
 206                .offset =       0,
 207                .mask_flags =   MTD_WRITEABLE  /* force read-only */
 208        },{
 209                .name =         "Kernel",
 210                .size =         0x00400000,
 211                .offset =       0x00040000,
 212        },{
 213                .name =         "Filesystem",
 214                .size =         MTDPART_SIZ_FULL,
 215                .offset =       0x00440000
 216        }
 217};
 218
 219static struct flash_platform_data mst_flash_data[2] = {
 220        {
 221                .map_name       = "cfi_probe",
 222                .parts          = mainstoneflash0_partitions,
 223                .nr_parts       = ARRAY_SIZE(mainstoneflash0_partitions),
 224        }, {
 225                .map_name       = "cfi_probe",
 226                .parts          = NULL,
 227                .nr_parts       = 0,
 228        }
 229};
 230
 231static struct platform_device mst_flash_device[2] = {
 232        {
 233                .name           = "pxa2xx-flash",
 234                .id             = 0,
 235                .dev = {
 236                        .platform_data = &mst_flash_data[0],
 237                },
 238                .resource = &flash_resources[0],
 239                .num_resources = 1,
 240        },
 241        {
 242                .name           = "pxa2xx-flash",
 243                .id             = 1,
 244                .dev = {
 245                        .platform_data = &mst_flash_data[1],
 246                },
 247                .resource = &flash_resources[1],
 248                .num_resources = 1,
 249        },
 250};
 251
 252#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
 253static struct pwm_lookup mainstone_pwm_lookup[] = {
 254        PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78770,
 255                   PWM_POLARITY_NORMAL),
 256};
 257
 258static struct platform_pwm_backlight_data mainstone_backlight_data = {
 259        .max_brightness = 1023,
 260        .dft_brightness = 1023,
 261        .enable_gpio    = -1,
 262};
 263
 264static struct platform_device mainstone_backlight_device = {
 265        .name           = "pwm-backlight",
 266        .dev            = {
 267                .parent = &pxa27x_device_pwm0.dev,
 268                .platform_data = &mainstone_backlight_data,
 269        },
 270};
 271
 272static void __init mainstone_backlight_register(void)
 273{
 274        int ret;
 275
 276        pwm_add_table(mainstone_pwm_lookup, ARRAY_SIZE(mainstone_pwm_lookup));
 277
 278        ret = platform_device_register(&mainstone_backlight_device);
 279        if (ret) {
 280                printk(KERN_ERR "mainstone: failed to register backlight device: %d\n", ret);
 281                pwm_remove_table(mainstone_pwm_lookup,
 282                                 ARRAY_SIZE(mainstone_pwm_lookup));
 283        }
 284}
 285#else
 286#define mainstone_backlight_register()  do { } while (0)
 287#endif
 288
 289static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
 290        .pixclock               = 50000,
 291        .xres                   = 640,
 292        .yres                   = 480,
 293        .bpp                    = 16,
 294        .hsync_len              = 1,
 295        .left_margin            = 0x9f,
 296        .right_margin           = 1,
 297        .vsync_len              = 44,
 298        .upper_margin           = 0,
 299        .lower_margin           = 0,
 300        .sync                   = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
 301};
 302
 303static struct pxafb_mode_info toshiba_ltm035a776c_mode = {
 304        .pixclock               = 110000,
 305        .xres                   = 240,
 306        .yres                   = 320,
 307        .bpp                    = 16,
 308        .hsync_len              = 4,
 309        .left_margin            = 8,
 310        .right_margin           = 20,
 311        .vsync_len              = 3,
 312        .upper_margin           = 1,
 313        .lower_margin           = 10,
 314        .sync                   = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
 315};
 316
 317static struct pxafb_mach_info mainstone_pxafb_info = {
 318        .num_modes              = 1,
 319        .lcd_conn               = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
 320};
 321
 322static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_int, void *data)
 323{
 324        int err;
 325
 326        /* make sure SD/Memory Stick multiplexer's signals
 327         * are routed to MMC controller
 328         */
 329        MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;
 330
 331        err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, 0,
 332                             "MMC card detect", data);
 333        if (err)
 334                printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
 335
 336        return err;
 337}
 338
 339static int mainstone_mci_setpower(struct device *dev, unsigned int vdd)
 340{
 341        struct pxamci_platform_data* p_d = dev->platform_data;
 342
 343        if (( 1 << vdd) & p_d->ocr_mask) {
 344                printk(KERN_DEBUG "%s: on\n", __func__);
 345                MST_MSCWR1 |= MST_MSCWR1_MMC_ON;
 346                MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;
 347        } else {
 348                printk(KERN_DEBUG "%s: off\n", __func__);
 349                MST_MSCWR1 &= ~MST_MSCWR1_MMC_ON;
 350        }
 351        return 0;
 352}
 353
 354static void mainstone_mci_exit(struct device *dev, void *data)
 355{
 356        free_irq(MAINSTONE_MMC_IRQ, data);
 357}
 358
 359static struct pxamci_platform_data mainstone_mci_platform_data = {
 360        .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
 361        .init                   = mainstone_mci_init,
 362        .setpower               = mainstone_mci_setpower,
 363        .exit                   = mainstone_mci_exit,
 364        .gpio_card_detect       = -1,
 365        .gpio_card_ro           = -1,
 366        .gpio_power             = -1,
 367};
 368
 369static void mainstone_irda_transceiver_mode(struct device *dev, int mode)
 370{
 371        unsigned long flags;
 372
 373        local_irq_save(flags);
 374        if (mode & IR_SIRMODE) {
 375                MST_MSCWR1 &= ~MST_MSCWR1_IRDA_FIR;
 376        } else if (mode & IR_FIRMODE) {
 377                MST_MSCWR1 |= MST_MSCWR1_IRDA_FIR;
 378        }
 379        pxa2xx_transceiver_mode(dev, mode);
 380        if (mode & IR_OFF) {
 381                MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_OFF;
 382        } else {
 383                MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_FULL;
 384        }
 385        local_irq_restore(flags);
 386}
 387
 388static struct pxaficp_platform_data mainstone_ficp_platform_data = {
 389        .gpio_pwdown            = -1,
 390        .transceiver_cap        = IR_SIRMODE | IR_FIRMODE | IR_OFF,
 391        .transceiver_mode       = mainstone_irda_transceiver_mode,
 392};
 393
 394static struct gpio_keys_button gpio_keys_button[] = {
 395        [0] = {
 396                .desc   = "wakeup",
 397                .code   = KEY_SUSPEND,
 398                .type   = EV_KEY,
 399                .gpio   = 1,
 400                .wakeup = 1,
 401        },
 402};
 403
 404static struct gpio_keys_platform_data mainstone_gpio_keys = {
 405        .buttons        = gpio_keys_button,
 406        .nbuttons       = 1,
 407};
 408
 409static struct platform_device mst_gpio_keys_device = {
 410        .name           = "gpio-keys",
 411        .id             = -1,
 412        .dev            = {
 413                .platform_data  = &mainstone_gpio_keys,
 414        },
 415};
 416
 417static struct resource mst_cplds_resources[] = {
 418        [0] = {
 419                .start  = MST_FPGA_PHYS + 0xc0,
 420                .end    = MST_FPGA_PHYS + 0xe0 - 1,
 421                .flags  = IORESOURCE_MEM,
 422        },
 423        [1] = {
 424                .start  = PXA_GPIO_TO_IRQ(0),
 425                .end    = PXA_GPIO_TO_IRQ(0),
 426                .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
 427        },
 428        [2] = {
 429                .start  = MAINSTONE_IRQ(0),
 430                .end    = MAINSTONE_IRQ(15),
 431                .flags  = IORESOURCE_IRQ,
 432        },
 433};
 434
 435static struct platform_device mst_cplds_device = {
 436        .name           = "pxa_cplds_irqs",
 437        .id             = -1,
 438        .resource       = &mst_cplds_resources[0],
 439        .num_resources  = 3,
 440};
 441
 442static struct platform_device *platform_devices[] __initdata = {
 443        &smc91x_device,
 444        &mst_flash_device[0],
 445        &mst_flash_device[1],
 446        &mst_gpio_keys_device,
 447        &mst_cplds_device,
 448};
 449
 450static struct pxaohci_platform_data mainstone_ohci_platform_data = {
 451        .port_mode      = PMM_PERPORT_MODE,
 452        .flags          = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
 453};
 454
 455#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
 456static const unsigned int mainstone_matrix_keys[] = {
 457        KEY(0, 0, KEY_A), KEY(1, 0, KEY_B), KEY(2, 0, KEY_C),
 458        KEY(3, 0, KEY_D), KEY(4, 0, KEY_E), KEY(5, 0, KEY_F),
 459        KEY(0, 1, KEY_G), KEY(1, 1, KEY_H), KEY(2, 1, KEY_I),
 460        KEY(3, 1, KEY_J), KEY(4, 1, KEY_K), KEY(5, 1, KEY_L),
 461        KEY(0, 2, KEY_M), KEY(1, 2, KEY_N), KEY(2, 2, KEY_O),
 462        KEY(3, 2, KEY_P), KEY(4, 2, KEY_Q), KEY(5, 2, KEY_R),
 463        KEY(0, 3, KEY_S), KEY(1, 3, KEY_T), KEY(2, 3, KEY_U),
 464        KEY(3, 3, KEY_V), KEY(4, 3, KEY_W), KEY(5, 3, KEY_X),
 465        KEY(2, 4, KEY_Y), KEY(3, 4, KEY_Z),
 466
 467        KEY(0, 4, KEY_DOT),     /* . */
 468        KEY(1, 4, KEY_CLOSE),   /* @ */
 469        KEY(4, 4, KEY_SLASH),
 470        KEY(5, 4, KEY_BACKSLASH),
 471        KEY(0, 5, KEY_HOME),
 472        KEY(1, 5, KEY_LEFTSHIFT),
 473        KEY(2, 5, KEY_SPACE),
 474        KEY(3, 5, KEY_SPACE),
 475        KEY(4, 5, KEY_ENTER),
 476        KEY(5, 5, KEY_BACKSPACE),
 477
 478        KEY(0, 6, KEY_UP),
 479        KEY(1, 6, KEY_DOWN),
 480        KEY(2, 6, KEY_LEFT),
 481        KEY(3, 6, KEY_RIGHT),
 482        KEY(4, 6, KEY_SELECT),
 483};
 484
 485static struct matrix_keymap_data mainstone_matrix_keymap_data = {
 486        .keymap                 = mainstone_matrix_keys,
 487        .keymap_size            = ARRAY_SIZE(mainstone_matrix_keys),
 488};
 489
 490struct pxa27x_keypad_platform_data mainstone_keypad_info = {
 491        .matrix_key_rows        = 6,
 492        .matrix_key_cols        = 7,
 493        .matrix_keymap_data     = &mainstone_matrix_keymap_data,
 494
 495        .enable_rotary0         = 1,
 496        .rotary0_up_key         = KEY_UP,
 497        .rotary0_down_key       = KEY_DOWN,
 498
 499        .debounce_interval      = 30,
 500};
 501
 502static void __init mainstone_init_keypad(void)
 503{
 504        pxa_set_keypad_info(&mainstone_keypad_info);
 505}
 506#else
 507static inline void mainstone_init_keypad(void) {}
 508#endif
 509
 510static void __init mainstone_init(void)
 511{
 512        int SW7 = 0;  /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
 513
 514        pxa2xx_mfp_config(ARRAY_AND_SIZE(mainstone_pin_config));
 515
 516        pxa_set_ffuart_info(NULL);
 517        pxa_set_btuart_info(NULL);
 518        pxa_set_stuart_info(NULL);
 519
 520        mst_flash_data[0].width = (__raw_readl(BOOT_DEF) & 1) ? 2 : 4;
 521        mst_flash_data[1].width = 4;
 522
 523        /* Compensate for SW7 which swaps the flash banks */
 524        mst_flash_data[SW7].name = "processor-flash";
 525        mst_flash_data[SW7 ^ 1].name = "mainboard-flash";
 526
 527        printk(KERN_NOTICE "Mainstone configured to boot from %s\n",
 528               mst_flash_data[0].name);
 529
 530        /* system bus arbiter setting
 531         * - Core_Park
 532         * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4
 533         */
 534        ARB_CNTRL = ARB_CORE_PARK | 0x234;
 535
 536        platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
 537
 538        /* reading Mainstone's "Virtual Configuration Register"
 539           might be handy to select LCD type here */
 540        if (0)
 541                mainstone_pxafb_info.modes = &toshiba_ltm04c380k_mode;
 542        else
 543                mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode;
 544
 545        pxa_set_fb_info(NULL, &mainstone_pxafb_info);
 546        mainstone_backlight_register();
 547
 548        pxa_set_mci_info(&mainstone_mci_platform_data);
 549        pxa_set_ficp_info(&mainstone_ficp_platform_data);
 550        pxa_set_ohci_info(&mainstone_ohci_platform_data);
 551        pxa_set_i2c_info(NULL);
 552        pxa_set_ac97_info(&mst_audio_ops);
 553
 554        mainstone_init_keypad();
 555}
 556
 557
 558static struct map_desc mainstone_io_desc[] __initdata = {
 559        {       /* CPLD */
 560                .virtual        =  MST_FPGA_VIRT,
 561                .pfn            = __phys_to_pfn(MST_FPGA_PHYS),
 562                .length         = 0x00100000,
 563                .type           = MT_DEVICE
 564        }
 565};
 566
 567static void __init mainstone_map_io(void)
 568{
 569        pxa27x_map_io();
 570        iotable_init(mainstone_io_desc, ARRAY_SIZE(mainstone_io_desc));
 571
 572        /*      for use I SRAM as framebuffer.  */
 573        PSLR |= 0xF04;
 574        PCFR = 0x66;
 575}
 576
 577/*
 578 * Driver for the 8 discrete LEDs available for general use:
 579 * Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays
 580 * so be sure to not monkey with them here.
 581 */
 582
 583#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
 584struct mainstone_led {
 585        struct led_classdev     cdev;
 586        u8                      mask;
 587};
 588
 589/*
 590 * The triggers lines up below will only be used if the
 591 * LED triggers are compiled in.
 592 */
 593static const struct {
 594        const char *name;
 595        const char *trigger;
 596} mainstone_leds[] = {
 597        { "mainstone:D28", "default-on", },
 598        { "mainstone:D27", "cpu0", },
 599        { "mainstone:D26", "heartbeat" },
 600        { "mainstone:D25", },
 601        { "mainstone:D24", },
 602        { "mainstone:D23", },
 603        { "mainstone:D22", },
 604        { "mainstone:D21", },
 605};
 606
 607static void mainstone_led_set(struct led_classdev *cdev,
 608                              enum led_brightness b)
 609{
 610        struct mainstone_led *led = container_of(cdev,
 611                                         struct mainstone_led, cdev);
 612        u32 reg = MST_LEDCTRL;
 613
 614        if (b != LED_OFF)
 615                reg |= led->mask;
 616        else
 617                reg &= ~led->mask;
 618
 619        MST_LEDCTRL = reg;
 620}
 621
 622static enum led_brightness mainstone_led_get(struct led_classdev *cdev)
 623{
 624        struct mainstone_led *led = container_of(cdev,
 625                                         struct mainstone_led, cdev);
 626        u32 reg = MST_LEDCTRL;
 627
 628        return (reg & led->mask) ? LED_FULL : LED_OFF;
 629}
 630
 631static int __init mainstone_leds_init(void)
 632{
 633        int i;
 634
 635        if (!machine_is_mainstone())
 636                return -ENODEV;
 637
 638        /* All ON */
 639        MST_LEDCTRL |= 0xff;
 640        for (i = 0; i < ARRAY_SIZE(mainstone_leds); i++) {
 641                struct mainstone_led *led;
 642
 643                led = kzalloc(sizeof(*led), GFP_KERNEL);
 644                if (!led)
 645                        break;
 646
 647                led->cdev.name = mainstone_leds[i].name;
 648                led->cdev.brightness_set = mainstone_led_set;
 649                led->cdev.brightness_get = mainstone_led_get;
 650                led->cdev.default_trigger = mainstone_leds[i].trigger;
 651                led->mask = BIT(i);
 652
 653                if (led_classdev_register(NULL, &led->cdev) < 0) {
 654                        kfree(led);
 655                        break;
 656                }
 657        }
 658
 659        return 0;
 660}
 661
 662/*
 663 * Since we may have triggers on any subsystem, defer registration
 664 * until after subsystem_init.
 665 */
 666fs_initcall(mainstone_leds_init);
 667#endif
 668
 669MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
 670        /* Maintainer: MontaVista Software Inc. */
 671        .atag_offset    = 0x100,        /* BLOB boot parameter setting */
 672        .map_io         = mainstone_map_io,
 673        .nr_irqs        = MAINSTONE_NR_IRQS,
 674        .init_irq       = pxa27x_init_irq,
 675        .handle_irq     = pxa27x_handle_irq,
 676        .init_time      = pxa_timer_init,
 677        .init_machine   = mainstone_init,
 678        .restart        = pxa_restart,
 679MACHINE_END
 680