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/i2c/pxa-i2c.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};
 144
 145static struct platform_device smc91x_device = {
 146        .name           = "smc91x",
 147        .id             = 0,
 148        .num_resources  = ARRAY_SIZE(smc91x_resources),
 149        .resource       = smc91x_resources,
 150        .dev            = {
 151                .platform_data = &mainstone_smc91x_info,
 152        },
 153};
 154
 155static int mst_audio_startup(struct snd_pcm_substream *substream, void *priv)
 156{
 157        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 158                MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF;
 159        return 0;
 160}
 161
 162static void mst_audio_shutdown(struct snd_pcm_substream *substream, void *priv)
 163{
 164        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 165                MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
 166}
 167
 168static long mst_audio_suspend_mask;
 169
 170static void mst_audio_suspend(void *priv)
 171{
 172        mst_audio_suspend_mask = MST_MSCWR2;
 173        MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
 174}
 175
 176static void mst_audio_resume(void *priv)
 177{
 178        MST_MSCWR2 &= mst_audio_suspend_mask | ~MST_MSCWR2_AC97_SPKROFF;
 179}
 180
 181static pxa2xx_audio_ops_t mst_audio_ops = {
 182        .startup        = mst_audio_startup,
 183        .shutdown       = mst_audio_shutdown,
 184        .suspend        = mst_audio_suspend,
 185        .resume         = mst_audio_resume,
 186};
 187
 188static struct resource flash_resources[] = {
 189        [0] = {
 190                .start  = PXA_CS0_PHYS,
 191                .end    = PXA_CS0_PHYS + SZ_64M - 1,
 192                .flags  = IORESOURCE_MEM,
 193        },
 194        [1] = {
 195                .start  = PXA_CS1_PHYS,
 196                .end    = PXA_CS1_PHYS + SZ_64M - 1,
 197                .flags  = IORESOURCE_MEM,
 198        },
 199};
 200
 201static struct mtd_partition mainstoneflash0_partitions[] = {
 202        {
 203                .name =         "Bootloader",
 204                .size =         0x00040000,
 205                .offset =       0,
 206                .mask_flags =   MTD_WRITEABLE  /* force read-only */
 207        },{
 208                .name =         "Kernel",
 209                .size =         0x00400000,
 210                .offset =       0x00040000,
 211        },{
 212                .name =         "Filesystem",
 213                .size =         MTDPART_SIZ_FULL,
 214                .offset =       0x00440000
 215        }
 216};
 217
 218static struct flash_platform_data mst_flash_data[2] = {
 219        {
 220                .map_name       = "cfi_probe",
 221                .parts          = mainstoneflash0_partitions,
 222                .nr_parts       = ARRAY_SIZE(mainstoneflash0_partitions),
 223        }, {
 224                .map_name       = "cfi_probe",
 225                .parts          = NULL,
 226                .nr_parts       = 0,
 227        }
 228};
 229
 230static struct platform_device mst_flash_device[2] = {
 231        {
 232                .name           = "pxa2xx-flash",
 233                .id             = 0,
 234                .dev = {
 235                        .platform_data = &mst_flash_data[0],
 236                },
 237                .resource = &flash_resources[0],
 238                .num_resources = 1,
 239        },
 240        {
 241                .name           = "pxa2xx-flash",
 242                .id             = 1,
 243                .dev = {
 244                        .platform_data = &mst_flash_data[1],
 245                },
 246                .resource = &flash_resources[1],
 247                .num_resources = 1,
 248        },
 249};
 250
 251#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
 252static struct pwm_lookup mainstone_pwm_lookup[] = {
 253        PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78770,
 254                   PWM_POLARITY_NORMAL),
 255};
 256
 257static struct platform_pwm_backlight_data mainstone_backlight_data = {
 258        .max_brightness = 1023,
 259        .dft_brightness = 1023,
 260        .enable_gpio    = -1,
 261};
 262
 263static struct platform_device mainstone_backlight_device = {
 264        .name           = "pwm-backlight",
 265        .dev            = {
 266                .parent = &pxa27x_device_pwm0.dev,
 267                .platform_data = &mainstone_backlight_data,
 268        },
 269};
 270
 271static void __init mainstone_backlight_register(void)
 272{
 273        int ret;
 274
 275        pwm_add_table(mainstone_pwm_lookup, ARRAY_SIZE(mainstone_pwm_lookup));
 276
 277        ret = platform_device_register(&mainstone_backlight_device);
 278        if (ret) {
 279                printk(KERN_ERR "mainstone: failed to register backlight device: %d\n", ret);
 280                pwm_remove_table(mainstone_pwm_lookup,
 281                                 ARRAY_SIZE(mainstone_pwm_lookup));
 282        }
 283}
 284#else
 285#define mainstone_backlight_register()  do { } while (0)
 286#endif
 287
 288static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
 289        .pixclock               = 50000,
 290        .xres                   = 640,
 291        .yres                   = 480,
 292        .bpp                    = 16,
 293        .hsync_len              = 1,
 294        .left_margin            = 0x9f,
 295        .right_margin           = 1,
 296        .vsync_len              = 44,
 297        .upper_margin           = 0,
 298        .lower_margin           = 0,
 299        .sync                   = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
 300};
 301
 302static struct pxafb_mode_info toshiba_ltm035a776c_mode = {
 303        .pixclock               = 110000,
 304        .xres                   = 240,
 305        .yres                   = 320,
 306        .bpp                    = 16,
 307        .hsync_len              = 4,
 308        .left_margin            = 8,
 309        .right_margin           = 20,
 310        .vsync_len              = 3,
 311        .upper_margin           = 1,
 312        .lower_margin           = 10,
 313        .sync                   = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
 314};
 315
 316static struct pxafb_mach_info mainstone_pxafb_info = {
 317        .num_modes              = 1,
 318        .lcd_conn               = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
 319};
 320
 321static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_int, void *data)
 322{
 323        int err;
 324
 325        /* make sure SD/Memory Stick multiplexer's signals
 326         * are routed to MMC controller
 327         */
 328        MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;
 329
 330        err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, 0,
 331                             "MMC card detect", data);
 332        if (err)
 333                printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
 334
 335        return err;
 336}
 337
 338static int mainstone_mci_setpower(struct device *dev, unsigned int vdd)
 339{
 340        struct pxamci_platform_data* p_d = dev->platform_data;
 341
 342        if (( 1 << vdd) & p_d->ocr_mask) {
 343                printk(KERN_DEBUG "%s: on\n", __func__);
 344                MST_MSCWR1 |= MST_MSCWR1_MMC_ON;
 345                MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;
 346        } else {
 347                printk(KERN_DEBUG "%s: off\n", __func__);
 348                MST_MSCWR1 &= ~MST_MSCWR1_MMC_ON;
 349        }
 350        return 0;
 351}
 352
 353static void mainstone_mci_exit(struct device *dev, void *data)
 354{
 355        free_irq(MAINSTONE_MMC_IRQ, data);
 356}
 357
 358static struct pxamci_platform_data mainstone_mci_platform_data = {
 359        .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
 360        .init                   = mainstone_mci_init,
 361        .setpower               = mainstone_mci_setpower,
 362        .exit                   = mainstone_mci_exit,
 363        .gpio_card_detect       = -1,
 364        .gpio_card_ro           = -1,
 365        .gpio_power             = -1,
 366};
 367
 368static void mainstone_irda_transceiver_mode(struct device *dev, int mode)
 369{
 370        unsigned long flags;
 371
 372        local_irq_save(flags);
 373        if (mode & IR_SIRMODE) {
 374                MST_MSCWR1 &= ~MST_MSCWR1_IRDA_FIR;
 375        } else if (mode & IR_FIRMODE) {
 376                MST_MSCWR1 |= MST_MSCWR1_IRDA_FIR;
 377        }
 378        pxa2xx_transceiver_mode(dev, mode);
 379        if (mode & IR_OFF) {
 380                MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_OFF;
 381        } else {
 382                MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_FULL;
 383        }
 384        local_irq_restore(flags);
 385}
 386
 387static struct pxaficp_platform_data mainstone_ficp_platform_data = {
 388        .gpio_pwdown            = -1,
 389        .transceiver_cap        = IR_SIRMODE | IR_FIRMODE | IR_OFF,
 390        .transceiver_mode       = mainstone_irda_transceiver_mode,
 391};
 392
 393static struct gpio_keys_button gpio_keys_button[] = {
 394        [0] = {
 395                .desc   = "wakeup",
 396                .code   = KEY_SUSPEND,
 397                .type   = EV_KEY,
 398                .gpio   = 1,
 399                .wakeup = 1,
 400        },
 401};
 402
 403static struct gpio_keys_platform_data mainstone_gpio_keys = {
 404        .buttons        = gpio_keys_button,
 405        .nbuttons       = 1,
 406};
 407
 408static struct platform_device mst_gpio_keys_device = {
 409        .name           = "gpio-keys",
 410        .id             = -1,
 411        .dev            = {
 412                .platform_data  = &mainstone_gpio_keys,
 413        },
 414};
 415
 416static struct resource mst_cplds_resources[] = {
 417        [0] = {
 418                .start  = MST_FPGA_PHYS + 0xc0,
 419                .end    = MST_FPGA_PHYS + 0xe0 - 1,
 420                .flags  = IORESOURCE_MEM,
 421        },
 422        [1] = {
 423                .start  = PXA_GPIO_TO_IRQ(0),
 424                .end    = PXA_GPIO_TO_IRQ(0),
 425                .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
 426        },
 427        [2] = {
 428                .start  = MAINSTONE_IRQ(0),
 429                .end    = MAINSTONE_IRQ(15),
 430                .flags  = IORESOURCE_IRQ,
 431        },
 432};
 433
 434static struct platform_device mst_cplds_device = {
 435        .name           = "pxa_cplds_irqs",
 436        .id             = -1,
 437        .resource       = &mst_cplds_resources[0],
 438        .num_resources  = 3,
 439};
 440
 441static struct platform_device *platform_devices[] __initdata = {
 442        &smc91x_device,
 443        &mst_flash_device[0],
 444        &mst_flash_device[1],
 445        &mst_gpio_keys_device,
 446        &mst_cplds_device,
 447};
 448
 449static struct pxaohci_platform_data mainstone_ohci_platform_data = {
 450        .port_mode      = PMM_PERPORT_MODE,
 451        .flags          = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
 452};
 453
 454#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
 455static const unsigned int mainstone_matrix_keys[] = {
 456        KEY(0, 0, KEY_A), KEY(1, 0, KEY_B), KEY(2, 0, KEY_C),
 457        KEY(3, 0, KEY_D), KEY(4, 0, KEY_E), KEY(5, 0, KEY_F),
 458        KEY(0, 1, KEY_G), KEY(1, 1, KEY_H), KEY(2, 1, KEY_I),
 459        KEY(3, 1, KEY_J), KEY(4, 1, KEY_K), KEY(5, 1, KEY_L),
 460        KEY(0, 2, KEY_M), KEY(1, 2, KEY_N), KEY(2, 2, KEY_O),
 461        KEY(3, 2, KEY_P), KEY(4, 2, KEY_Q), KEY(5, 2, KEY_R),
 462        KEY(0, 3, KEY_S), KEY(1, 3, KEY_T), KEY(2, 3, KEY_U),
 463        KEY(3, 3, KEY_V), KEY(4, 3, KEY_W), KEY(5, 3, KEY_X),
 464        KEY(2, 4, KEY_Y), KEY(3, 4, KEY_Z),
 465
 466        KEY(0, 4, KEY_DOT),     /* . */
 467        KEY(1, 4, KEY_CLOSE),   /* @ */
 468        KEY(4, 4, KEY_SLASH),
 469        KEY(5, 4, KEY_BACKSLASH),
 470        KEY(0, 5, KEY_HOME),
 471        KEY(1, 5, KEY_LEFTSHIFT),
 472        KEY(2, 5, KEY_SPACE),
 473        KEY(3, 5, KEY_SPACE),
 474        KEY(4, 5, KEY_ENTER),
 475        KEY(5, 5, KEY_BACKSPACE),
 476
 477        KEY(0, 6, KEY_UP),
 478        KEY(1, 6, KEY_DOWN),
 479        KEY(2, 6, KEY_LEFT),
 480        KEY(3, 6, KEY_RIGHT),
 481        KEY(4, 6, KEY_SELECT),
 482};
 483
 484static struct matrix_keymap_data mainstone_matrix_keymap_data = {
 485        .keymap                 = mainstone_matrix_keys,
 486        .keymap_size            = ARRAY_SIZE(mainstone_matrix_keys),
 487};
 488
 489struct pxa27x_keypad_platform_data mainstone_keypad_info = {
 490        .matrix_key_rows        = 6,
 491        .matrix_key_cols        = 7,
 492        .matrix_keymap_data     = &mainstone_matrix_keymap_data,
 493
 494        .enable_rotary0         = 1,
 495        .rotary0_up_key         = KEY_UP,
 496        .rotary0_down_key       = KEY_DOWN,
 497
 498        .debounce_interval      = 30,
 499};
 500
 501static void __init mainstone_init_keypad(void)
 502{
 503        pxa_set_keypad_info(&mainstone_keypad_info);
 504}
 505#else
 506static inline void mainstone_init_keypad(void) {}
 507#endif
 508
 509static void __init mainstone_init(void)
 510{
 511        int SW7 = 0;  /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
 512
 513        pxa2xx_mfp_config(ARRAY_AND_SIZE(mainstone_pin_config));
 514
 515        pxa_set_ffuart_info(NULL);
 516        pxa_set_btuart_info(NULL);
 517        pxa_set_stuart_info(NULL);
 518
 519        mst_flash_data[0].width = (__raw_readl(BOOT_DEF) & 1) ? 2 : 4;
 520        mst_flash_data[1].width = 4;
 521
 522        /* Compensate for SW7 which swaps the flash banks */
 523        mst_flash_data[SW7].name = "processor-flash";
 524        mst_flash_data[SW7 ^ 1].name = "mainboard-flash";
 525
 526        printk(KERN_NOTICE "Mainstone configured to boot from %s\n",
 527               mst_flash_data[0].name);
 528
 529        /* system bus arbiter setting
 530         * - Core_Park
 531         * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4
 532         */
 533        ARB_CNTRL = ARB_CORE_PARK | 0x234;
 534
 535        platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
 536
 537        /* reading Mainstone's "Virtual Configuration Register"
 538           might be handy to select LCD type here */
 539        if (0)
 540                mainstone_pxafb_info.modes = &toshiba_ltm04c380k_mode;
 541        else
 542                mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode;
 543
 544        pxa_set_fb_info(NULL, &mainstone_pxafb_info);
 545        mainstone_backlight_register();
 546
 547        pxa_set_mci_info(&mainstone_mci_platform_data);
 548        pxa_set_ficp_info(&mainstone_ficp_platform_data);
 549        pxa_set_ohci_info(&mainstone_ohci_platform_data);
 550        pxa_set_i2c_info(NULL);
 551        pxa_set_ac97_info(&mst_audio_ops);
 552
 553        mainstone_init_keypad();
 554}
 555
 556
 557static struct map_desc mainstone_io_desc[] __initdata = {
 558        {       /* CPLD */
 559                .virtual        =  MST_FPGA_VIRT,
 560                .pfn            = __phys_to_pfn(MST_FPGA_PHYS),
 561                .length         = 0x00100000,
 562                .type           = MT_DEVICE
 563        }
 564};
 565
 566static void __init mainstone_map_io(void)
 567{
 568        pxa27x_map_io();
 569        iotable_init(mainstone_io_desc, ARRAY_SIZE(mainstone_io_desc));
 570
 571        /*      for use I SRAM as framebuffer.  */
 572        PSLR |= 0xF04;
 573        PCFR = 0x66;
 574}
 575
 576/*
 577 * Driver for the 8 discrete LEDs available for general use:
 578 * Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays
 579 * so be sure to not monkey with them here.
 580 */
 581
 582#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
 583struct mainstone_led {
 584        struct led_classdev     cdev;
 585        u8                      mask;
 586};
 587
 588/*
 589 * The triggers lines up below will only be used if the
 590 * LED triggers are compiled in.
 591 */
 592static const struct {
 593        const char *name;
 594        const char *trigger;
 595} mainstone_leds[] = {
 596        { "mainstone:D28", "default-on", },
 597        { "mainstone:D27", "cpu0", },
 598        { "mainstone:D26", "heartbeat" },
 599        { "mainstone:D25", },
 600        { "mainstone:D24", },
 601        { "mainstone:D23", },
 602        { "mainstone:D22", },
 603        { "mainstone:D21", },
 604};
 605
 606static void mainstone_led_set(struct led_classdev *cdev,
 607                              enum led_brightness b)
 608{
 609        struct mainstone_led *led = container_of(cdev,
 610                                         struct mainstone_led, cdev);
 611        u32 reg = MST_LEDCTRL;
 612
 613        if (b != LED_OFF)
 614                reg |= led->mask;
 615        else
 616                reg &= ~led->mask;
 617
 618        MST_LEDCTRL = reg;
 619}
 620
 621static enum led_brightness mainstone_led_get(struct led_classdev *cdev)
 622{
 623        struct mainstone_led *led = container_of(cdev,
 624                                         struct mainstone_led, cdev);
 625        u32 reg = MST_LEDCTRL;
 626
 627        return (reg & led->mask) ? LED_FULL : LED_OFF;
 628}
 629
 630static int __init mainstone_leds_init(void)
 631{
 632        int i;
 633
 634        if (!machine_is_mainstone())
 635                return -ENODEV;
 636
 637        /* All ON */
 638        MST_LEDCTRL |= 0xff;
 639        for (i = 0; i < ARRAY_SIZE(mainstone_leds); i++) {
 640                struct mainstone_led *led;
 641
 642                led = kzalloc(sizeof(*led), GFP_KERNEL);
 643                if (!led)
 644                        break;
 645
 646                led->cdev.name = mainstone_leds[i].name;
 647                led->cdev.brightness_set = mainstone_led_set;
 648                led->cdev.brightness_get = mainstone_led_get;
 649                led->cdev.default_trigger = mainstone_leds[i].trigger;
 650                led->mask = BIT(i);
 651
 652                if (led_classdev_register(NULL, &led->cdev) < 0) {
 653                        kfree(led);
 654                        break;
 655                }
 656        }
 657
 658        return 0;
 659}
 660
 661/*
 662 * Since we may have triggers on any subsystem, defer registration
 663 * until after subsystem_init.
 664 */
 665fs_initcall(mainstone_leds_init);
 666#endif
 667
 668MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
 669        /* Maintainer: MontaVista Software Inc. */
 670        .atag_offset    = 0x100,        /* BLOB boot parameter setting */
 671        .map_io         = mainstone_map_io,
 672        .nr_irqs        = MAINSTONE_NR_IRQS,
 673        .init_irq       = pxa27x_init_irq,
 674        .handle_irq     = pxa27x_handle_irq,
 675        .init_time      = pxa_timer_init,
 676        .init_machine   = mainstone_init,
 677        .restart        = pxa_restart,
 678MACHINE_END
 679