linux/arch/arm/mach-pxa/mioa701.c
<<
>>
Prefs
   1/*
   2 * Handles the Mitac Mio A701 Board
   3 *
   4 * Copyright (C) 2008 Robert Jarzmik
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19 *
  20 */
  21
  22#include <linux/kernel.h>
  23#include <linux/init.h>
  24#include <linux/platform_device.h>
  25#include <linux/sysdev.h>
  26#include <linux/input.h>
  27#include <linux/delay.h>
  28#include <linux/gpio_keys.h>
  29#include <linux/pwm_backlight.h>
  30#include <linux/rtc.h>
  31#include <linux/leds.h>
  32#include <linux/gpio.h>
  33#include <linux/interrupt.h>
  34#include <linux/irq.h>
  35#include <linux/pda_power.h>
  36#include <linux/power_supply.h>
  37#include <linux/wm97xx.h>
  38#include <linux/mtd/physmap.h>
  39
  40#include <asm/mach-types.h>
  41#include <asm/mach/arch.h>
  42#include <mach/mfp-pxa27x.h>
  43#include <mach/pxa27x_keypad.h>
  44#include <mach/pxafb.h>
  45#include <mach/pxa2xx-regs.h>
  46#include <mach/mmc.h>
  47#include <mach/udc.h>
  48#include <mach/pxa27x-udc.h>
  49
  50#include <mach/mioa701.h>
  51
  52#include "generic.h"
  53#include "devices.h"
  54
  55static unsigned long mioa701_pin_config[] = {
  56        /* Mio global */
  57        MIO_CFG_OUT(GPIO9_CHARGE_nEN, AF0, DRIVE_LOW),
  58        MIO_CFG_OUT(GPIO18_POWEROFF, AF0, DRIVE_LOW),
  59        MFP_CFG_OUT(GPIO3, AF0, DRIVE_HIGH),
  60        MFP_CFG_OUT(GPIO4, AF0, DRIVE_HIGH),
  61
  62        /* Backlight PWM 0 */
  63        GPIO16_PWM0_OUT,
  64
  65        /* MMC */
  66        GPIO32_MMC_CLK,
  67        GPIO92_MMC_DAT_0,
  68        GPIO109_MMC_DAT_1,
  69        GPIO110_MMC_DAT_2,
  70        GPIO111_MMC_DAT_3,
  71        GPIO112_MMC_CMD,
  72        MIO_CFG_IN(GPIO78_SDIO_RO, AF0),
  73        MIO_CFG_IN(GPIO15_SDIO_INSERT, AF0),
  74        MIO_CFG_OUT(GPIO91_SDIO_EN, AF0, DRIVE_LOW),
  75
  76        /* USB */
  77        MIO_CFG_IN(GPIO13_USB_DETECT, AF0),
  78        MIO_CFG_OUT(GPIO22_USB_ENABLE, AF0, DRIVE_LOW),
  79
  80        /* LCD */
  81        GPIO58_LCD_LDD_0,
  82        GPIO59_LCD_LDD_1,
  83        GPIO60_LCD_LDD_2,
  84        GPIO61_LCD_LDD_3,
  85        GPIO62_LCD_LDD_4,
  86        GPIO63_LCD_LDD_5,
  87        GPIO64_LCD_LDD_6,
  88        GPIO65_LCD_LDD_7,
  89        GPIO66_LCD_LDD_8,
  90        GPIO67_LCD_LDD_9,
  91        GPIO68_LCD_LDD_10,
  92        GPIO69_LCD_LDD_11,
  93        GPIO70_LCD_LDD_12,
  94        GPIO71_LCD_LDD_13,
  95        GPIO72_LCD_LDD_14,
  96        GPIO73_LCD_LDD_15,
  97        GPIO74_LCD_FCLK,
  98        GPIO75_LCD_LCLK,
  99        GPIO76_LCD_PCLK,
 100
 101        /* Bluetooth */
 102        GPIO44_BTUART_CTS,
 103        GPIO42_BTUART_RXD,
 104        GPIO45_BTUART_RTS,
 105        GPIO43_BTUART_TXD,
 106        MIO_CFG_OUT(GPIO83_BT_ON, AF0, DRIVE_LOW),
 107
 108        /* GPS */
 109        MIO_CFG_OUT(GPIO23_GPS_UNKNOWN1, AF0, DRIVE_LOW),
 110        MIO_CFG_OUT(GPIO26_GPS_ON, AF0, DRIVE_LOW),
 111        MIO_CFG_OUT(GPIO27_GPS_RESET, AF0, DRIVE_LOW),
 112        MIO_CFG_OUT(GPIO106_GPS_UNKNOWN2, AF0, DRIVE_LOW),
 113        MIO_CFG_OUT(GPIO107_GPS_UNKNOWN3, AF0, DRIVE_LOW),
 114        GPIO46_STUART_RXD,
 115        GPIO47_STUART_TXD,
 116
 117        /* GSM */
 118        MIO_CFG_OUT(GPIO24_GSM_MOD_RESET_CMD, AF0, DRIVE_LOW),
 119        MIO_CFG_OUT(GPIO88_GSM_nMOD_ON_CMD, AF0, DRIVE_HIGH),
 120        MIO_CFG_OUT(GPIO90_GSM_nMOD_OFF_CMD, AF0, DRIVE_HIGH),
 121        MIO_CFG_OUT(GPIO114_GSM_nMOD_DTE_UART_STATE, AF0, DRIVE_HIGH),
 122        MIO_CFG_IN(GPIO25_GSM_MOD_ON_STATE, AF0),
 123        MIO_CFG_IN(GPIO113_GSM_EVENT, AF0) | WAKEUP_ON_EDGE_BOTH,
 124        GPIO34_FFUART_RXD,
 125        GPIO35_FFUART_CTS,
 126        GPIO36_FFUART_DCD,
 127        GPIO37_FFUART_DSR,
 128        GPIO39_FFUART_TXD,
 129        GPIO40_FFUART_DTR,
 130        GPIO41_FFUART_RTS,
 131
 132        /* Sound */
 133        GPIO89_AC97_SYSCLK,
 134        MIO_CFG_IN(GPIO12_HPJACK_INSERT, AF0),
 135
 136        /* Leds */
 137        MIO_CFG_OUT(GPIO10_LED_nCharging, AF0, DRIVE_HIGH),
 138        MIO_CFG_OUT(GPIO97_LED_nBlue, AF0, DRIVE_HIGH),
 139        MIO_CFG_OUT(GPIO98_LED_nOrange, AF0, DRIVE_HIGH),
 140        MIO_CFG_OUT(GPIO82_LED_nVibra, AF0, DRIVE_HIGH),
 141        MIO_CFG_OUT(GPIO115_LED_nKeyboard, AF0, DRIVE_HIGH),
 142
 143        /* Keyboard */
 144        MIO_CFG_IN(GPIO0_KEY_POWER, AF0) | WAKEUP_ON_EDGE_BOTH,
 145        MIO_CFG_IN(GPIO93_KEY_VOLUME_UP, AF0),
 146        MIO_CFG_IN(GPIO94_KEY_VOLUME_DOWN, AF0),
 147        GPIO100_KP_MKIN_0,
 148        GPIO101_KP_MKIN_1,
 149        GPIO102_KP_MKIN_2,
 150        GPIO103_KP_MKOUT_0,
 151        GPIO104_KP_MKOUT_1,
 152        GPIO105_KP_MKOUT_2,
 153
 154        /* Unknown */
 155        MFP_CFG_IN(GPIO14, AF0),
 156        MFP_CFG_IN(GPIO20, AF0),
 157        MFP_CFG_IN(GPIO21, AF0),
 158        MFP_CFG_IN(GPIO33, AF0),
 159        MFP_CFG_OUT(GPIO49, AF0, DRIVE_HIGH),
 160        MFP_CFG_OUT(GPIO57, AF0, DRIVE_HIGH),
 161        MFP_CFG_OUT(GPIO77, AF0, DRIVE_HIGH),
 162        MFP_CFG_IN(GPIO80, AF0),
 163        MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH),
 164        MFP_CFG_IN(GPIO96, AF0),
 165        MFP_CFG_OUT(GPIO116, AF0, DRIVE_HIGH),
 166};
 167
 168#define MIO_GPIO_IN(num, _desc) \
 169        { .gpio = (num), .dir = 0, .desc = (_desc) }
 170#define MIO_GPIO_OUT(num, _init, _desc) \
 171        { .gpio = (num), .dir = 1, .init = (_init), .desc = (_desc) }
 172struct gpio_ress {
 173        unsigned gpio : 8;
 174        unsigned dir : 1;
 175        unsigned init : 1;
 176        char *desc;
 177};
 178
 179static int mio_gpio_request(struct gpio_ress *gpios, int size)
 180{
 181        int i, rc = 0;
 182        int gpio;
 183        int dir;
 184
 185        for (i = 0; (!rc) && (i < size); i++) {
 186                gpio = gpios[i].gpio;
 187                dir = gpios[i].dir;
 188                rc = gpio_request(gpio, gpios[i].desc);
 189                if (rc) {
 190                        printk(KERN_ERR "Error requesting GPIO %d(%s) : %d\n",
 191                               gpio, gpios[i].desc, rc);
 192                        continue;
 193                }
 194                if (dir)
 195                        gpio_direction_output(gpio, gpios[i].init);
 196                else
 197                        gpio_direction_input(gpio);
 198        }
 199        while ((rc) && (--i >= 0))
 200                gpio_free(gpios[i].gpio);
 201        return rc;
 202}
 203
 204static void mio_gpio_free(struct gpio_ress *gpios, int size)
 205{
 206        int i;
 207
 208        for (i = 0; i < size; i++)
 209                gpio_free(gpios[i].gpio);
 210}
 211
 212/* LCD Screen and Backlight */
 213static struct platform_pwm_backlight_data mioa701_backlight_data = {
 214        .pwm_id         = 0,
 215        .max_brightness = 100,
 216        .dft_brightness = 50,
 217        .pwm_period_ns  = 4000 * 1024,  /* Fl = 250kHz */
 218};
 219
 220/*
 221 * LTM0305A776C LCD panel timings
 222 *
 223 * see:
 224 *  - the LTM0305A776C datasheet,
 225 *  - and the PXA27x Programmers' manual
 226 */
 227static struct pxafb_mode_info mioa701_ltm0305a776c = {
 228        .pixclock               = 220000,       /* CLK=4.545 MHz */
 229        .xres                   = 240,
 230        .yres                   = 320,
 231        .bpp                    = 16,
 232        .hsync_len              = 4,
 233        .vsync_len              = 2,
 234        .left_margin            = 6,
 235        .right_margin           = 4,
 236        .upper_margin           = 5,
 237        .lower_margin           = 3,
 238};
 239
 240static void mioa701_lcd_power(int on, struct fb_var_screeninfo *si)
 241{
 242        gpio_set_value(GPIO87_LCD_POWER, on);
 243}
 244
 245static struct pxafb_mach_info mioa701_pxafb_info = {
 246        .modes                  = &mioa701_ltm0305a776c,
 247        .num_modes              = 1,
 248        .lcd_conn               = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
 249        .pxafb_lcd_power        = mioa701_lcd_power,
 250};
 251
 252/*
 253 * Keyboard configuration
 254 */
 255static unsigned int mioa701_matrix_keys[] = {
 256        KEY(0, 0, KEY_UP),
 257        KEY(0, 1, KEY_RIGHT),
 258        KEY(0, 2, KEY_MEDIA),
 259        KEY(1, 0, KEY_DOWN),
 260        KEY(1, 1, KEY_ENTER),
 261        KEY(1, 2, KEY_CONNECT), /* GPS key */
 262        KEY(2, 0, KEY_LEFT),
 263        KEY(2, 1, KEY_PHONE),   /* Phone Green key */
 264        KEY(2, 2, KEY_CAMERA)   /* Camera key */
 265};
 266static struct pxa27x_keypad_platform_data mioa701_keypad_info = {
 267        .matrix_key_rows = 3,
 268        .matrix_key_cols = 3,
 269        .matrix_key_map = mioa701_matrix_keys,
 270        .matrix_key_map_size = ARRAY_SIZE(mioa701_matrix_keys),
 271};
 272
 273/*
 274 * GPIO Key Configuration
 275 */
 276#define MIO_KEY(key, _gpio, _desc, _wakeup) \
 277        { .code = (key), .gpio = (_gpio), .active_low = 0, \
 278        .desc = (_desc), .type = EV_KEY, .wakeup = (_wakeup) }
 279static struct gpio_keys_button mioa701_button_table[] = {
 280        MIO_KEY(KEY_EXIT, GPIO0_KEY_POWER, "Power button", 1),
 281        MIO_KEY(KEY_VOLUMEUP, GPIO93_KEY_VOLUME_UP, "Volume up", 0),
 282        MIO_KEY(KEY_VOLUMEDOWN, GPIO94_KEY_VOLUME_DOWN, "Volume down", 0),
 283        MIO_KEY(KEY_HP, GPIO12_HPJACK_INSERT, "HP jack detect", 0)
 284};
 285
 286static struct gpio_keys_platform_data mioa701_gpio_keys_data = {
 287        .buttons  = mioa701_button_table,
 288        .nbuttons = ARRAY_SIZE(mioa701_button_table),
 289};
 290
 291/*
 292 * Leds and vibrator
 293 */
 294#define ONE_LED(_gpio, _name) \
 295{ .gpio = (_gpio), .name = (_name), .active_low = true }
 296static struct gpio_led gpio_leds[] = {
 297        ONE_LED(GPIO10_LED_nCharging, "mioa701:charging"),
 298        ONE_LED(GPIO97_LED_nBlue, "mioa701:blue"),
 299        ONE_LED(GPIO98_LED_nOrange, "mioa701:orange"),
 300        ONE_LED(GPIO82_LED_nVibra, "mioa701:vibra"),
 301        ONE_LED(GPIO115_LED_nKeyboard, "mioa701:keyboard")
 302};
 303
 304static struct gpio_led_platform_data gpio_led_info = {
 305        .leds = gpio_leds,
 306        .num_leds = ARRAY_SIZE(gpio_leds),
 307};
 308
 309/*
 310 * GSM Sagem XS200 chip
 311 *
 312 * GSM handling was purged from kernel. For history, this is the way to go :
 313 *   - init : GPIO24_GSM_MOD_RESET_CMD = 0, GPIO114_GSM_nMOD_DTE_UART_STATE = 1
 314 *            GPIO88_GSM_nMOD_ON_CMD = 1, GPIO90_GSM_nMOD_OFF_CMD = 1
 315 *   - reset : GPIO24_GSM_MOD_RESET_CMD = 1, msleep(100),
 316 *             GPIO24_GSM_MOD_RESET_CMD = 0
 317 *   - turn on  : GPIO88_GSM_nMOD_ON_CMD = 0, msleep(1000),
 318 *                GPIO88_GSM_nMOD_ON_CMD = 1
 319 *   - turn off : GPIO90_GSM_nMOD_OFF_CMD = 0, msleep(1000),
 320 *                GPIO90_GSM_nMOD_OFF_CMD = 1
 321 */
 322static int is_gsm_on(void)
 323{
 324        int is_on;
 325
 326        is_on = !!gpio_get_value(GPIO25_GSM_MOD_ON_STATE);
 327        return is_on;
 328}
 329
 330irqreturn_t gsm_on_irq(int irq, void *p)
 331{
 332        printk(KERN_DEBUG "Mioa701: GSM status changed to %s\n",
 333               is_gsm_on() ? "on" : "off");
 334        return IRQ_HANDLED;
 335}
 336
 337struct gpio_ress gsm_gpios[] = {
 338        MIO_GPIO_IN(GPIO25_GSM_MOD_ON_STATE, "GSM state"),
 339        MIO_GPIO_IN(GPIO113_GSM_EVENT, "GSM event"),
 340};
 341
 342static int __init gsm_init(void)
 343{
 344        int rc;
 345
 346        rc = mio_gpio_request(ARRAY_AND_SIZE(gsm_gpios));
 347        if (rc)
 348                goto err_gpio;
 349        rc = request_irq(gpio_to_irq(GPIO25_GSM_MOD_ON_STATE), gsm_on_irq,
 350                         IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 351                         "GSM XS200 Power Irq", NULL);
 352        if (rc)
 353                goto err_irq;
 354
 355        gpio_set_wake(GPIO113_GSM_EVENT, 1);
 356        return 0;
 357
 358err_irq:
 359        printk(KERN_ERR "Mioa701: Can't request GSM_ON irq\n");
 360        mio_gpio_free(ARRAY_AND_SIZE(gsm_gpios));
 361err_gpio:
 362        printk(KERN_ERR "Mioa701: gsm not available\n");
 363        return rc;
 364}
 365
 366static void gsm_exit(void)
 367{
 368        free_irq(gpio_to_irq(GPIO25_GSM_MOD_ON_STATE), NULL);
 369        mio_gpio_free(ARRAY_AND_SIZE(gsm_gpios));
 370}
 371
 372/*
 373 * Bluetooth BRF6150 chip
 374 *
 375 * BT handling was purged from kernel. For history, this is the way to go :
 376 * - turn on  : GPIO83_BT_ON = 1
 377 * - turn off : GPIO83_BT_ON = 0
 378 */
 379
 380/*
 381 * GPS Sirf Star III chip
 382 *
 383 * GPS handling was purged from kernel. For history, this is the way to go :
 384 * - init : GPIO23_GPS_UNKNOWN1 = 1, GPIO26_GPS_ON = 0, GPIO27_GPS_RESET = 0
 385 *          GPIO106_GPS_UNKNOWN2 = 0, GPIO107_GPS_UNKNOWN3 = 0
 386 * - turn on  : GPIO27_GPS_RESET = 1, GPIO26_GPS_ON = 1
 387 * - turn off : GPIO26_GPS_ON = 0, GPIO27_GPS_RESET = 0
 388 */
 389
 390/*
 391 * USB UDC
 392 */
 393static void udc_power_command(int cmd)
 394{
 395        switch (cmd) {
 396        case PXA2XX_UDC_CMD_DISCONNECT:
 397                gpio_set_value(GPIO22_USB_ENABLE, 0);
 398                break;
 399        case PXA2XX_UDC_CMD_CONNECT:
 400                gpio_set_value(GPIO22_USB_ENABLE, 1);
 401                break;
 402        default:
 403                printk(KERN_INFO "udc_control: unknown command (0x%x)!\n", cmd);
 404                break;
 405        }
 406}
 407
 408static int is_usb_connected(void)
 409{
 410        return !!gpio_get_value(GPIO13_USB_DETECT);
 411}
 412
 413static struct pxa2xx_udc_mach_info mioa701_udc_info = {
 414        .udc_is_connected = is_usb_connected,
 415        .udc_command      = udc_power_command,
 416};
 417
 418struct gpio_ress udc_gpios[] = {
 419        MIO_GPIO_OUT(GPIO22_USB_ENABLE, 0, "USB Vbus enable")
 420};
 421
 422static int __init udc_init(void)
 423{
 424        pxa_set_udc_info(&mioa701_udc_info);
 425        return mio_gpio_request(ARRAY_AND_SIZE(udc_gpios));
 426}
 427
 428static void udc_exit(void)
 429{
 430        mio_gpio_free(ARRAY_AND_SIZE(udc_gpios));
 431}
 432
 433/*
 434 * SDIO/MMC Card controller
 435 */
 436static void mci_setpower(struct device *dev, unsigned int vdd)
 437{
 438        struct pxamci_platform_data *p_d = dev->platform_data;
 439
 440        if ((1 << vdd) & p_d->ocr_mask)
 441                gpio_set_value(GPIO91_SDIO_EN, 1);      /* enable SDIO power */
 442        else
 443                gpio_set_value(GPIO91_SDIO_EN, 0);      /* disable SDIO power */
 444}
 445
 446static int mci_get_ro(struct device *dev)
 447{
 448        return gpio_get_value(GPIO78_SDIO_RO);
 449}
 450
 451struct gpio_ress mci_gpios[] = {
 452        MIO_GPIO_IN(GPIO78_SDIO_RO,     "SDIO readonly detect"),
 453        MIO_GPIO_IN(GPIO15_SDIO_INSERT, "SDIO insertion detect"),
 454        MIO_GPIO_OUT(GPIO91_SDIO_EN, 0, "SDIO power enable")
 455};
 456
 457static void mci_exit(struct device *dev, void *data)
 458{
 459        mio_gpio_free(ARRAY_AND_SIZE(mci_gpios));
 460        free_irq(gpio_to_irq(GPIO15_SDIO_INSERT), data);
 461}
 462
 463static struct pxamci_platform_data mioa701_mci_info;
 464
 465/**
 466 * The card detect interrupt isn't debounced so we delay it by 250ms
 467 * to give the card a chance to fully insert/eject.
 468 */
 469static int mci_init(struct device *dev, irq_handler_t detect_int, void *data)
 470{
 471        int rc;
 472        int irq = gpio_to_irq(GPIO15_SDIO_INSERT);
 473
 474        rc = mio_gpio_request(ARRAY_AND_SIZE(mci_gpios));
 475        if (rc)
 476                goto err_gpio;
 477        /* enable RE/FE interrupt on card insertion and removal */
 478        rc = request_irq(irq, detect_int,
 479                         IRQF_DISABLED | IRQF_TRIGGER_RISING |
 480                         IRQF_TRIGGER_FALLING,
 481                         "MMC card detect", data);
 482        if (rc)
 483                goto err_irq;
 484
 485        mioa701_mci_info.detect_delay = msecs_to_jiffies(250);
 486        return 0;
 487
 488err_irq:
 489        dev_err(dev, "mioa701_mci_init: MMC/SD:"
 490                " can't request MMC card detect IRQ\n");
 491        mio_gpio_free(ARRAY_AND_SIZE(mci_gpios));
 492err_gpio:
 493        return rc;
 494}
 495
 496static struct pxamci_platform_data mioa701_mci_info = {
 497        .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
 498        .init     = mci_init,
 499        .get_ro   = mci_get_ro,
 500        .setpower = mci_setpower,
 501        .exit     = mci_exit,
 502};
 503
 504/* FlashRAM */
 505static struct resource strataflash_resource = {
 506        .start = PXA_CS0_PHYS,
 507        .end   = PXA_CS0_PHYS + SZ_64M - 1,
 508        .flags = IORESOURCE_MEM,
 509};
 510
 511static struct physmap_flash_data strataflash_data = {
 512        .width = 2,
 513        /* .set_vpp = mioa701_set_vpp, */
 514};
 515
 516static struct platform_device strataflash = {
 517        .name          = "physmap-flash",
 518        .id            = -1,
 519        .resource      = &strataflash_resource,
 520        .num_resources = 1,
 521        .dev = {
 522                .platform_data = &strataflash_data,
 523        },
 524};
 525
 526/*
 527 * Suspend/Resume bootstrap management
 528 *
 529 * MIO A701 reboot sequence is highly ROM dependant. From the one dissassembled,
 530 * this sequence is as follows :
 531 *   - disables interrupts
 532 *   - initialize SDRAM (self refresh RAM into active RAM)
 533 *   - initialize GPIOs (depends on value at 0xa020b020)
 534 *   - initialize coprossessors
 535 *   - if edge detect on PWR_SCL(GPIO3), then proceed to cold start
 536 *   - or if value at 0xa020b000 not equal to 0x0f0f0f0f, proceed to cold start
 537 *   - else do a resume, ie. jump to addr 0xa0100000
 538 */
 539#define RESUME_ENABLE_ADDR      0xa020b000
 540#define RESUME_ENABLE_VAL       0x0f0f0f0f
 541#define RESUME_BT_ADDR          0xa020b020
 542#define RESUME_UNKNOWN_ADDR     0xa020b024
 543#define RESUME_VECTOR_ADDR      0xa0100000
 544#define BOOTSTRAP_WORDS         mioa701_bootstrap_lg/4
 545
 546static u32 *save_buffer;
 547
 548static void install_bootstrap(void)
 549{
 550        int i;
 551        u32 *rom_bootstrap  = phys_to_virt(RESUME_VECTOR_ADDR);
 552        u32 *src = &mioa701_bootstrap;
 553
 554        for (i = 0; i < BOOTSTRAP_WORDS; i++)
 555                rom_bootstrap[i] = src[i];
 556}
 557
 558
 559static int mioa701_sys_suspend(struct sys_device *sysdev, pm_message_t state)
 560{
 561        int i = 0, is_bt_on;
 562        u32 *mem_resume_vector  = phys_to_virt(RESUME_VECTOR_ADDR);
 563        u32 *mem_resume_enabler = phys_to_virt(RESUME_ENABLE_ADDR);
 564        u32 *mem_resume_bt      = phys_to_virt(RESUME_BT_ADDR);
 565        u32 *mem_resume_unknown = phys_to_virt(RESUME_UNKNOWN_ADDR);
 566
 567        /* Devices prepare suspend */
 568        is_bt_on = !!gpio_get_value(GPIO83_BT_ON);
 569        pxa2xx_mfp_set_lpm(GPIO83_BT_ON,
 570                           is_bt_on ? MFP_LPM_DRIVE_HIGH : MFP_LPM_DRIVE_LOW);
 571
 572        for (i = 0; i < BOOTSTRAP_WORDS; i++)
 573                save_buffer[i] = mem_resume_vector[i];
 574        save_buffer[i++] = *mem_resume_enabler;
 575        save_buffer[i++] = *mem_resume_bt;
 576        save_buffer[i++] = *mem_resume_unknown;
 577
 578        *mem_resume_enabler = RESUME_ENABLE_VAL;
 579        *mem_resume_bt      = is_bt_on;
 580
 581        install_bootstrap();
 582        return 0;
 583}
 584
 585static int mioa701_sys_resume(struct sys_device *sysdev)
 586{
 587        int i = 0;
 588        u32 *mem_resume_vector  = phys_to_virt(RESUME_VECTOR_ADDR);
 589        u32 *mem_resume_enabler = phys_to_virt(RESUME_ENABLE_ADDR);
 590        u32 *mem_resume_bt      = phys_to_virt(RESUME_BT_ADDR);
 591        u32 *mem_resume_unknown = phys_to_virt(RESUME_UNKNOWN_ADDR);
 592
 593        for (i = 0; i < BOOTSTRAP_WORDS; i++)
 594                mem_resume_vector[i] = save_buffer[i];
 595        *mem_resume_enabler = save_buffer[i++];
 596        *mem_resume_bt      = save_buffer[i++];
 597        *mem_resume_unknown = save_buffer[i++];
 598
 599        return 0;
 600}
 601
 602static struct sysdev_class mioa701_sysclass = {
 603        .name = "mioa701",
 604};
 605
 606static struct sys_device sysdev_bootstrap = {
 607        .cls            = &mioa701_sysclass,
 608};
 609
 610static struct sysdev_driver driver_bootstrap = {
 611        .suspend        = &mioa701_sys_suspend,
 612        .resume         = &mioa701_sys_resume,
 613};
 614
 615static int __init bootstrap_init(void)
 616{
 617        int rc;
 618        int save_size = mioa701_bootstrap_lg + (sizeof(u32) * 3);
 619
 620        rc = sysdev_class_register(&mioa701_sysclass);
 621        if (rc) {
 622                printk(KERN_ERR "Failed registering mioa701 sys class\n");
 623                return -ENODEV;
 624        }
 625        rc = sysdev_register(&sysdev_bootstrap);
 626        if (rc) {
 627                printk(KERN_ERR "Failed registering mioa701 sys device\n");
 628                return -ENODEV;
 629        }
 630        rc = sysdev_driver_register(&mioa701_sysclass, &driver_bootstrap);
 631        if (rc) {
 632                printk(KERN_ERR "Failed registering PMU sys driver\n");
 633                return -ENODEV;
 634        }
 635
 636        save_buffer = kmalloc(save_size, GFP_KERNEL);
 637        if (!save_buffer)
 638                return -ENOMEM;
 639        printk(KERN_INFO "MioA701: allocated %d bytes for bootstrap\n",
 640               save_size);
 641        return 0;
 642}
 643
 644static void bootstrap_exit(void)
 645{
 646        kfree(save_buffer);
 647        sysdev_driver_unregister(&mioa701_sysclass, &driver_bootstrap);
 648        sysdev_unregister(&sysdev_bootstrap);
 649        sysdev_class_unregister(&mioa701_sysclass);
 650
 651        printk(KERN_CRIT "Unregistering mioa701 suspend will hang next"
 652               "resume !!!\n");
 653}
 654
 655/*
 656 * Power Supply
 657 */
 658static char *supplicants[] = {
 659        "mioa701_battery"
 660};
 661
 662static void mioa701_set_charge(int flags)
 663{
 664        gpio_set_value(GPIO9_CHARGE_nEN, !flags);
 665}
 666
 667static struct pda_power_pdata power_pdata = {
 668        .is_ac_online   = is_usb_connected,
 669        .set_charge = mioa701_set_charge,
 670        .supplied_to = supplicants,
 671        .num_supplicants = ARRAY_SIZE(supplicants),
 672};
 673
 674static struct resource power_resources[] = {
 675        [0] = {
 676                .name   = "ac",
 677                .start  = gpio_to_irq(GPIO13_USB_DETECT),
 678                .end    = gpio_to_irq(GPIO13_USB_DETECT),
 679                .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
 680                IORESOURCE_IRQ_LOWEDGE,
 681        },
 682};
 683
 684static struct platform_device power_dev = {
 685        .name           = "pda-power",
 686        .id             = -1,
 687        .resource       = power_resources,
 688        .num_resources  = ARRAY_SIZE(power_resources),
 689        .dev = {
 690                .platform_data  = &power_pdata,
 691        },
 692};
 693
 694#if defined(CONFIG_PDA_POWER) && defined(CONFIG_TOUCHSCREEN_WM97XX)
 695static struct wm97xx *battery_wm;
 696
 697static enum power_supply_property battery_props[] = {
 698        POWER_SUPPLY_PROP_STATUS,
 699        POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
 700        POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
 701        POWER_SUPPLY_PROP_VOLTAGE_NOW,
 702        POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,   /* Necessary for apm */
 703};
 704
 705static int get_battery_voltage(void)
 706{
 707        int adc = -1;
 708
 709        if (battery_wm)
 710                adc = wm97xx_read_aux_adc(battery_wm, WM97XX_AUX_ID1);
 711        return adc;
 712}
 713
 714static int get_battery_status(struct power_supply *b)
 715{
 716        int status;
 717
 718        if (is_usb_connected())
 719                status = POWER_SUPPLY_STATUS_CHARGING;
 720        else
 721                status = POWER_SUPPLY_STATUS_DISCHARGING;
 722
 723        return status;
 724}
 725
 726static int get_property(struct power_supply *b,
 727                        enum power_supply_property psp,
 728                        union power_supply_propval *val)
 729{
 730        int rc = 0;
 731
 732        switch (psp) {
 733        case POWER_SUPPLY_PROP_STATUS:
 734                val->intval = get_battery_status(b);
 735                break;
 736        case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
 737                val->intval = 0xfd0;
 738                break;
 739        case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
 740                val->intval = 0xc00;
 741                break;
 742        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 743                val->intval = get_battery_voltage();
 744                break;
 745        case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
 746                val->intval = 100;
 747                break;
 748        default:
 749                val->intval = -1;
 750                rc = -1;
 751        }
 752
 753        return rc;
 754};
 755
 756static struct power_supply battery_ps = {
 757        .name = "mioa701_battery",
 758        .type = POWER_SUPPLY_TYPE_BATTERY,
 759        .get_property = get_property,
 760        .properties = battery_props,
 761        .num_properties = ARRAY_SIZE(battery_props),
 762};
 763
 764static int battery_probe(struct platform_device *pdev)
 765{
 766        struct wm97xx *wm = platform_get_drvdata(pdev);
 767        int rc;
 768
 769        battery_wm = wm;
 770
 771        rc = power_supply_register(NULL, &battery_ps);
 772        if (rc)
 773                dev_err(&pdev->dev,
 774                "Could not register mioa701 battery -> %d\n", rc);
 775        return rc;
 776}
 777
 778static int battery_remove(struct platform_device *pdev)
 779{
 780        battery_wm = NULL;
 781        return 0;
 782}
 783
 784static struct platform_driver mioa701_battery_driver = {
 785        .driver = {
 786                .name = "wm97xx-battery",
 787        },
 788        .probe = battery_probe,
 789        .remove = battery_remove
 790};
 791
 792static int __init mioa701_battery_init(void)
 793{
 794        int rc;
 795
 796        rc = platform_driver_register(&mioa701_battery_driver);
 797        if (rc)
 798                printk(KERN_ERR "Could not register mioa701 battery driver\n");
 799        return rc;
 800}
 801
 802#else
 803static int __init mioa701_battery_init(void)
 804{
 805        return 0;
 806}
 807#endif
 808
 809/*
 810 * Mio global
 811 */
 812
 813/* Devices */
 814#define MIO_PARENT_DEV(var, strname, tparent, pdata)    \
 815static struct platform_device var = {                   \
 816        .name           = strname,                      \
 817        .id             = -1,                           \
 818        .dev            = {                             \
 819                .platform_data = pdata,                 \
 820                .parent = tparent,                      \
 821        },                                              \
 822};
 823#define MIO_SIMPLE_DEV(var, strname, pdata)     \
 824        MIO_PARENT_DEV(var, strname, NULL, pdata)
 825
 826MIO_SIMPLE_DEV(mioa701_gpio_keys, "gpio-keys",      &mioa701_gpio_keys_data)
 827MIO_PARENT_DEV(mioa701_backlight, "pwm-backlight",  &pxa27x_device_pwm0.dev,
 828                &mioa701_backlight_data);
 829MIO_SIMPLE_DEV(mioa701_led,       "leds-gpio",      &gpio_led_info)
 830MIO_SIMPLE_DEV(pxa2xx_pcm,        "pxa2xx-pcm",     NULL)
 831MIO_SIMPLE_DEV(pxa2xx_ac97,       "pxa2xx-ac97",    NULL)
 832MIO_PARENT_DEV(mio_wm9713_codec,  "wm9713-codec",   &pxa2xx_ac97.dev, NULL)
 833MIO_SIMPLE_DEV(mioa701_sound,     "mioa701-wm9713", NULL)
 834MIO_SIMPLE_DEV(mioa701_board,     "mioa701-board",  NULL)
 835
 836static struct platform_device *devices[] __initdata = {
 837        &mioa701_gpio_keys,
 838        &mioa701_backlight,
 839        &mioa701_led,
 840        &pxa2xx_pcm,
 841        &pxa2xx_ac97,
 842        &mio_wm9713_codec,
 843        &mioa701_sound,
 844        &power_dev,
 845        &strataflash,
 846        &mioa701_board
 847};
 848
 849static void mioa701_machine_exit(void);
 850
 851static void mioa701_poweroff(void)
 852{
 853        mioa701_machine_exit();
 854        gpio_set_value(GPIO18_POWEROFF, 1);
 855}
 856
 857static void mioa701_restart(char c)
 858{
 859        mioa701_machine_exit();
 860        arm_machine_restart(c);
 861}
 862
 863struct gpio_ress global_gpios[] = {
 864        MIO_GPIO_OUT(GPIO9_CHARGE_nEN, 1, "Charger enable"),
 865        MIO_GPIO_OUT(GPIO18_POWEROFF, 0, "Power Off"),
 866        MIO_GPIO_OUT(GPIO87_LCD_POWER, 0, "LCD Power")
 867};
 868
 869static void __init mioa701_machine_init(void)
 870{
 871        PSLR  = 0xff100000; /* SYSDEL=125ms, PWRDEL=125ms, PSLR_SL_ROD=1 */
 872        PCFR = PCFR_DC_EN | PCFR_GPR_EN | PCFR_OPDE;
 873        RTTR = 32768 - 1; /* Reset crazy WinCE value */
 874        UP2OCR = UP2OCR_HXOE;
 875
 876        pxa2xx_mfp_config(ARRAY_AND_SIZE(mioa701_pin_config));
 877        mio_gpio_request(ARRAY_AND_SIZE(global_gpios));
 878        bootstrap_init();
 879        set_pxa_fb_info(&mioa701_pxafb_info);
 880        pxa_set_mci_info(&mioa701_mci_info);
 881        pxa_set_keypad_info(&mioa701_keypad_info);
 882        udc_init();
 883        pm_power_off = mioa701_poweroff;
 884        arm_pm_restart = mioa701_restart;
 885        platform_add_devices(devices, ARRAY_SIZE(devices));
 886        gsm_init();
 887        mioa701_battery_init();
 888}
 889
 890static void mioa701_machine_exit(void)
 891{
 892        udc_exit();
 893        bootstrap_exit();
 894        gsm_exit();
 895}
 896
 897MACHINE_START(MIOA701, "MIO A701")
 898        .phys_io        = 0x40000000,
 899        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
 900        .boot_params    = 0xa0000100,
 901        .map_io         = &pxa_map_io,
 902        .init_irq       = &pxa27x_init_irq,
 903        .init_machine   = mioa701_machine_init,
 904        .timer          = &pxa_timer,
 905MACHINE_END
 906
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.