linux/arch/arm/mach-omap1/board-nokia770.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/mach-omap1/board-nokia770.c
   3 *
   4 * Modified from board-generic.c
   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 version 2 as
   8 * published by the Free Software Foundation.
   9 */
  10
  11#include <linux/kernel.h>
  12#include <linux/init.h>
  13#include <linux/mutex.h>
  14#include <linux/platform_device.h>
  15#include <linux/input.h>
  16#include <linux/clk.h>
  17
  18#include <linux/spi/spi.h>
  19#include <linux/spi/ads7846.h>
  20#include <linux/workqueue.h>
  21#include <linux/delay.h>
  22
  23#include <mach/hardware.h>
  24#include <asm/mach-types.h>
  25#include <asm/mach/arch.h>
  26#include <asm/mach/map.h>
  27
  28#include <mach/gpio.h>
  29#include <mach/mux.h>
  30#include <mach/usb.h>
  31#include <mach/board.h>
  32#include <mach/keypad.h>
  33#include <mach/common.h>
  34#include <mach/dsp_common.h>
  35#include <mach/omapfb.h>
  36#include <mach/hwa742.h>
  37#include <mach/lcd_mipid.h>
  38#include <mach/mmc.h>
  39#include <mach/clock.h>
  40
  41#define ADS7846_PENDOWN_GPIO    15
  42
  43static void __init omap_nokia770_init_irq(void)
  44{
  45        /* On Nokia 770, the SleepX signal is masked with an
  46         * MPUIO line by default.  It has to be unmasked for it
  47         * to become functional */
  48
  49        /* SleepX mask direction */
  50        omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008);
  51        /* Unmask SleepX signal */
  52        omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004);
  53
  54        omap1_init_common_hw();
  55        omap_init_irq();
  56}
  57
  58static int nokia770_keymap[] = {
  59        KEY(0, 1, GROUP_0 | KEY_UP),
  60        KEY(0, 2, GROUP_1 | KEY_F5),
  61        KEY(1, 0, GROUP_0 | KEY_LEFT),
  62        KEY(1, 1, GROUP_0 | KEY_ENTER),
  63        KEY(1, 2, GROUP_0 | KEY_RIGHT),
  64        KEY(2, 0, GROUP_1 | KEY_ESC),
  65        KEY(2, 1, GROUP_0 | KEY_DOWN),
  66        KEY(2, 2, GROUP_1 | KEY_F4),
  67        KEY(3, 0, GROUP_2 | KEY_F7),
  68        KEY(3, 1, GROUP_2 | KEY_F8),
  69        KEY(3, 2, GROUP_2 | KEY_F6),
  70        0
  71};
  72
  73static struct resource nokia770_kp_resources[] = {
  74        [0] = {
  75                .start  = INT_KEYBOARD,
  76                .end    = INT_KEYBOARD,
  77                .flags  = IORESOURCE_IRQ,
  78        },
  79};
  80
  81static struct omap_kp_platform_data nokia770_kp_data = {
  82        .rows           = 8,
  83        .cols           = 8,
  84        .keymap         = nokia770_keymap,
  85        .keymapsize     = ARRAY_SIZE(nokia770_keymap),
  86        .delay          = 4,
  87};
  88
  89static struct platform_device nokia770_kp_device = {
  90        .name           = "omap-keypad",
  91        .id             = -1,
  92        .dev            = {
  93                .platform_data = &nokia770_kp_data,
  94        },
  95        .num_resources  = ARRAY_SIZE(nokia770_kp_resources),
  96        .resource       = nokia770_kp_resources,
  97};
  98
  99static struct platform_device *nokia770_devices[] __initdata = {
 100        &nokia770_kp_device,
 101};
 102
 103static void mipid_shutdown(struct mipid_platform_data *pdata)
 104{
 105        if (pdata->nreset_gpio != -1) {
 106                printk(KERN_INFO "shutdown LCD\n");
 107                gpio_set_value(pdata->nreset_gpio, 0);
 108                msleep(120);
 109        }
 110}
 111
 112static struct mipid_platform_data nokia770_mipid_platform_data = {
 113        .shutdown = mipid_shutdown,
 114};
 115
 116static void mipid_dev_init(void)
 117{
 118        const struct omap_lcd_config *conf;
 119
 120        conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
 121        if (conf != NULL) {
 122                nokia770_mipid_platform_data.nreset_gpio = conf->nreset_gpio;
 123                nokia770_mipid_platform_data.data_lines = conf->data_lines;
 124        }
 125}
 126
 127static void ads7846_dev_init(void)
 128{
 129        if (gpio_request(ADS7846_PENDOWN_GPIO, "ADS7846 pendown") < 0)
 130                printk(KERN_ERR "can't get ads7846 pen down GPIO\n");
 131}
 132
 133static int ads7846_get_pendown_state(void)
 134{
 135        return !gpio_get_value(ADS7846_PENDOWN_GPIO);
 136}
 137
 138static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = {
 139        .x_max          = 0x0fff,
 140        .y_max          = 0x0fff,
 141        .x_plate_ohms   = 180,
 142        .pressure_max   = 255,
 143        .debounce_max   = 10,
 144        .debounce_tol   = 3,
 145        .debounce_rep   = 1,
 146        .get_pendown_state      = ads7846_get_pendown_state,
 147};
 148
 149static struct spi_board_info nokia770_spi_board_info[] __initdata = {
 150        [0] = {
 151                .modalias       = "lcd_mipid",
 152                .bus_num        = 2,
 153                .chip_select    = 3,
 154                .max_speed_hz   = 12000000,
 155                .platform_data  = &nokia770_mipid_platform_data,
 156        },
 157        [1] = {
 158                .modalias       = "ads7846",
 159                .bus_num        = 2,
 160                .chip_select    = 0,
 161                .max_speed_hz   = 2500000,
 162                .irq            = OMAP_GPIO_IRQ(15),
 163                .platform_data  = &nokia770_ads7846_platform_data,
 164        },
 165};
 166
 167static struct hwa742_platform_data nokia770_hwa742_platform_data = {
 168        .te_connected           = 1,
 169};
 170
 171static void hwa742_dev_init(void)
 172{
 173        clk_add_alias("hwa_sys_ck", NULL, "bclk", NULL);
 174        omapfb_set_ctrl_platform_data(&nokia770_hwa742_platform_data);
 175}
 176
 177/* assume no Mini-AB port */
 178
 179static struct omap_usb_config nokia770_usb_config __initdata = {
 180        .otg            = 1,
 181        .register_host  = 1,
 182        .register_dev   = 1,
 183        .hmc_mode       = 16,
 184        .pins[0]        = 6,
 185};
 186
 187#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
 188
 189#define NOKIA770_GPIO_MMC_POWER         41
 190#define NOKIA770_GPIO_MMC_SWITCH        23
 191
 192static int nokia770_mmc_set_power(struct device *dev, int slot, int power_on,
 193                                int vdd)
 194{
 195        gpio_set_value(NOKIA770_GPIO_MMC_POWER, power_on);
 196        return 0;
 197}
 198
 199static int nokia770_mmc_get_cover_state(struct device *dev, int slot)
 200{
 201        return gpio_get_value(NOKIA770_GPIO_MMC_SWITCH);
 202}
 203
 204static struct omap_mmc_platform_data nokia770_mmc2_data = {
 205        .nr_slots                       = 1,
 206        .dma_mask                       = 0xffffffff,
 207        .max_freq                       = 12000000,
 208        .slots[0]       = {
 209                .set_power              = nokia770_mmc_set_power,
 210                .get_cover_state        = nokia770_mmc_get_cover_state,
 211                .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
 212                .name                   = "mmcblk",
 213        },
 214};
 215
 216static struct omap_mmc_platform_data *nokia770_mmc_data[OMAP16XX_NR_MMC];
 217
 218static void __init nokia770_mmc_init(void)
 219{
 220        int ret;
 221
 222        ret = gpio_request(NOKIA770_GPIO_MMC_POWER, "MMC power");
 223        if (ret < 0)
 224                return;
 225        gpio_direction_output(NOKIA770_GPIO_MMC_POWER, 0);
 226
 227        ret = gpio_request(NOKIA770_GPIO_MMC_SWITCH, "MMC cover");
 228        if (ret < 0) {
 229                gpio_free(NOKIA770_GPIO_MMC_POWER);
 230                return;
 231        }
 232        gpio_direction_input(NOKIA770_GPIO_MMC_SWITCH);
 233
 234        /* Only the second MMC controller is used */
 235        nokia770_mmc_data[1] = &nokia770_mmc2_data;
 236        omap1_init_mmc(nokia770_mmc_data, OMAP16XX_NR_MMC);
 237}
 238
 239#else
 240static inline void nokia770_mmc_init(void)
 241{
 242}
 243#endif
 244
 245#if     defined(CONFIG_OMAP_DSP)
 246/*
 247 * audio power control
 248 */
 249#define HEADPHONE_GPIO          14
 250#define AMPLIFIER_CTRL_GPIO     58
 251
 252static struct clk *dspxor_ck;
 253static DEFINE_MUTEX(audio_pwr_lock);
 254/*
 255 * audio_pwr_state
 256 * +--+-------------------------+---------------------------------------+
 257 * |-1|down                     |power-up request -> 0                  |
 258 * +--+-------------------------+---------------------------------------+
 259 * | 0|up                       |power-down(1) request -> 1             |
 260 * |  |                         |power-down(2) request -> (ignore)      |
 261 * +--+-------------------------+---------------------------------------+
 262 * | 1|up,                      |power-up request -> 0                  |
 263 * |  |received down(1) request |power-down(2) request -> -1            |
 264 * +--+-------------------------+---------------------------------------+
 265 */
 266static int audio_pwr_state = -1;
 267
 268static inline void aic23_power_up(void)
 269{
 270}
 271static inline void aic23_power_down(void)
 272{
 273}
 274
 275/*
 276 * audio_pwr_up / down should be called under audio_pwr_lock
 277 */
 278static void nokia770_audio_pwr_up(void)
 279{
 280        clk_enable(dspxor_ck);
 281
 282        /* Turn on codec */
 283        aic23_power_up();
 284
 285        if (gpio_get_value(HEADPHONE_GPIO))
 286                /* HP not connected, turn on amplifier */
 287                gpio_set_value(AMPLIFIER_CTRL_GPIO, 1);
 288        else
 289                /* HP connected, do not turn on amplifier */
 290                printk("HP connected\n");
 291}
 292
 293static void codec_delayed_power_down(struct work_struct *work)
 294{
 295        mutex_lock(&audio_pwr_lock);
 296        if (audio_pwr_state == -1)
 297                aic23_power_down();
 298        clk_disable(dspxor_ck);
 299        mutex_unlock(&audio_pwr_lock);
 300}
 301
 302static DECLARE_DELAYED_WORK(codec_power_down_work, codec_delayed_power_down);
 303
 304static void nokia770_audio_pwr_down(void)
 305{
 306        /* Turn off amplifier */
 307        gpio_set_value(AMPLIFIER_CTRL_GPIO, 0);
 308
 309        /* Turn off codec: schedule delayed work */
 310        schedule_delayed_work(&codec_power_down_work, HZ / 20); /* 50ms */
 311}
 312
 313static int
 314nokia770_audio_pwr_up_request(struct dsp_kfunc_device *kdev, int stage)
 315{
 316        mutex_lock(&audio_pwr_lock);
 317        if (audio_pwr_state == -1)
 318                nokia770_audio_pwr_up();
 319        /* force audio_pwr_state = 0, even if it was 1. */
 320        audio_pwr_state = 0;
 321        mutex_unlock(&audio_pwr_lock);
 322        return 0;
 323}
 324
 325static int
 326nokia770_audio_pwr_down_request(struct dsp_kfunc_device *kdev, int stage)
 327{
 328        mutex_lock(&audio_pwr_lock);
 329        switch (stage) {
 330        case 1:
 331                if (audio_pwr_state == 0)
 332                        audio_pwr_state = 1;
 333                break;
 334        case 2:
 335                if (audio_pwr_state == 1) {
 336                        nokia770_audio_pwr_down();
 337                        audio_pwr_state = -1;
 338                }
 339                break;
 340        }
 341        mutex_unlock(&audio_pwr_lock);
 342        return 0;
 343}
 344
 345static struct dsp_kfunc_device nokia770_audio_device = {
 346        .name    = "audio",
 347        .type    = DSP_KFUNC_DEV_TYPE_AUDIO,
 348        .enable  = nokia770_audio_pwr_up_request,
 349        .disable = nokia770_audio_pwr_down_request,
 350};
 351
 352static __init int omap_dsp_init(void)
 353{
 354        int ret;
 355
 356        dspxor_ck = clk_get(0, "dspxor_ck");
 357        if (IS_ERR(dspxor_ck)) {
 358                printk(KERN_ERR "couldn't acquire dspxor_ck\n");
 359                return PTR_ERR(dspxor_ck);
 360        }
 361
 362        ret = dsp_kfunc_device_register(&nokia770_audio_device);
 363        if (ret) {
 364                printk(KERN_ERR
 365                       "KFUNC device registration faild: %s\n",
 366                       nokia770_audio_device.name);
 367                goto out;
 368        }
 369        return 0;
 370 out:
 371        return ret;
 372}
 373#else
 374#define omap_dsp_init()         do {} while (0)
 375#endif  /* CONFIG_OMAP_DSP */
 376
 377static void __init omap_nokia770_init(void)
 378{
 379        platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices));
 380        spi_register_board_info(nokia770_spi_board_info,
 381                                ARRAY_SIZE(nokia770_spi_board_info));
 382        omap_gpio_init();
 383        omap_serial_init();
 384        omap_register_i2c_bus(1, 100, NULL, 0);
 385        omap_dsp_init();
 386        hwa742_dev_init();
 387        ads7846_dev_init();
 388        mipid_dev_init();
 389        omap_usb_init(&nokia770_usb_config);
 390        nokia770_mmc_init();
 391}
 392
 393static void __init omap_nokia770_map_io(void)
 394{
 395        omap1_map_common_io();
 396}
 397
 398MACHINE_START(NOKIA770, "Nokia 770")
 399        .phys_io        = 0xfff00000,
 400        .io_pg_offst    = ((0xfef00000) >> 18) & 0xfffc,
 401        .boot_params    = 0x10000100,
 402        .map_io         = omap_nokia770_map_io,
 403        .init_irq       = omap_nokia770_init_irq,
 404        .init_machine   = omap_nokia770_init,
 405        .timer          = &omap_timer,
 406MACHINE_END
 407
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.