linux/arch/arm/mach-omap1/board-sx1.c
<<
>>
Prefs
   1/*
   2* linux/arch/arm/mach-omap1/board-sx1.c
   3*
   4* Modified from board-generic.c
   5*
   6* Support for the Siemens SX1 mobile phone.
   7*
   8* Original version : Vladimir Ananiev (Vovan888-at-gmail com)
   9*
  10* Maintainters : Vladimir Ananiev (aka Vovan888), Sergge
  11*               oslik.ru
  12*
  13* This program is free software; you can redistribute it and/or modify
  14* it under the terms of the GNU General Public License version 2 as
  15* published by the Free Software Foundation.
  16*/
  17#include <linux/gpio.h>
  18#include <linux/kernel.h>
  19#include <linux/init.h>
  20#include <linux/input.h>
  21#include <linux/platform_device.h>
  22#include <linux/notifier.h>
  23#include <linux/mtd/mtd.h>
  24#include <linux/mtd/partitions.h>
  25#include <linux/mtd/physmap.h>
  26#include <linux/types.h>
  27#include <linux/i2c.h>
  28#include <linux/errno.h>
  29#include <linux/export.h>
  30#include <linux/omapfb.h>
  31#include <linux/platform_data/keypad-omap.h>
  32
  33#include <asm/mach-types.h>
  34#include <asm/mach/arch.h>
  35#include <asm/mach/map.h>
  36
  37#include <mach/flash.h>
  38#include <mach/mux.h>
  39#include <linux/omap-dma.h>
  40#include <mach/irda.h>
  41#include <mach/tc.h>
  42#include <mach/board-sx1.h>
  43
  44#include <mach/hardware.h>
  45#include <mach/usb.h>
  46
  47#include "common.h"
  48#include "dma.h"
  49
  50/* Write to I2C device */
  51int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value)
  52{
  53        struct i2c_adapter *adap;
  54        int err;
  55        struct i2c_msg msg[1];
  56        unsigned char data[2];
  57
  58        adap = i2c_get_adapter(0);
  59        if (!adap)
  60                return -ENODEV;
  61        msg->addr = devaddr;    /* I2C address of chip */
  62        msg->flags = 0;
  63        msg->len = 2;
  64        msg->buf = data;
  65        data[0] = regoffset;    /* register num */
  66        data[1] = value;                /* register data */
  67        err = i2c_transfer(adap, msg, 1);
  68        i2c_put_adapter(adap);
  69        if (err >= 0)
  70                return 0;
  71        return err;
  72}
  73
  74/* Read from I2C device */
  75int sx1_i2c_read_byte(u8 devaddr, u8 regoffset, u8 *value)
  76{
  77        struct i2c_adapter *adap;
  78        int err;
  79        struct i2c_msg msg[1];
  80        unsigned char data[2];
  81
  82        adap = i2c_get_adapter(0);
  83        if (!adap)
  84                return -ENODEV;
  85
  86        msg->addr = devaddr;    /* I2C address of chip */
  87        msg->flags = 0;
  88        msg->len = 1;
  89        msg->buf = data;
  90        data[0] = regoffset;    /* register num */
  91        err = i2c_transfer(adap, msg, 1);
  92
  93        msg->addr = devaddr;    /* I2C address */
  94        msg->flags = I2C_M_RD;
  95        msg->len = 1;
  96        msg->buf = data;
  97        err = i2c_transfer(adap, msg, 1);
  98        *value = data[0];
  99        i2c_put_adapter(adap);
 100
 101        if (err >= 0)
 102                return 0;
 103        return err;
 104}
 105/* set keyboard backlight intensity */
 106int sx1_setkeylight(u8 keylight)
 107{
 108        if (keylight > SOFIA_MAX_LIGHT_VAL)
 109                keylight = SOFIA_MAX_LIGHT_VAL;
 110        return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_KEYLIGHT_REG, keylight);
 111}
 112/* get current keylight intensity */
 113int sx1_getkeylight(u8 * keylight)
 114{
 115        return sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_KEYLIGHT_REG, keylight);
 116}
 117/* set LCD backlight intensity */
 118int sx1_setbacklight(u8 backlight)
 119{
 120        if (backlight > SOFIA_MAX_LIGHT_VAL)
 121                backlight = SOFIA_MAX_LIGHT_VAL;
 122        return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_BACKLIGHT_REG,
 123                                  backlight);
 124}
 125/* get current LCD backlight intensity */
 126int sx1_getbacklight (u8 * backlight)
 127{
 128        return sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_BACKLIGHT_REG,
 129                                 backlight);
 130}
 131/* set LCD backlight power on/off */
 132int sx1_setmmipower(u8 onoff)
 133{
 134        int err;
 135        u8 dat = 0;
 136        err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
 137        if (err < 0)
 138                return err;
 139        if (onoff)
 140                dat |= SOFIA_MMILIGHT_POWER;
 141        else
 142                dat &= ~SOFIA_MMILIGHT_POWER;
 143        return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
 144}
 145
 146/* set USB power on/off */
 147int sx1_setusbpower(u8 onoff)
 148{
 149        int err;
 150        u8 dat = 0;
 151        err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
 152        if (err < 0)
 153                return err;
 154        if (onoff)
 155                dat |= SOFIA_USB_POWER;
 156        else
 157                dat &= ~SOFIA_USB_POWER;
 158        return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
 159}
 160
 161EXPORT_SYMBOL(sx1_setkeylight);
 162EXPORT_SYMBOL(sx1_getkeylight);
 163EXPORT_SYMBOL(sx1_setbacklight);
 164EXPORT_SYMBOL(sx1_getbacklight);
 165EXPORT_SYMBOL(sx1_setmmipower);
 166EXPORT_SYMBOL(sx1_setusbpower);
 167
 168/*----------- Keypad -------------------------*/
 169
 170static const unsigned int sx1_keymap[] = {
 171        KEY(3, 5, GROUP_0 | 117), /* camera Qt::Key_F17 */
 172        KEY(4, 0, GROUP_0 | 114), /* voice memo Qt::Key_F14 */
 173        KEY(4, 1, GROUP_2 | 114), /* voice memo */
 174        KEY(4, 2, GROUP_3 | 114), /* voice memo */
 175        KEY(0, 0, GROUP_1 | KEY_F12),   /* red button Qt::Key_Hangup */
 176        KEY(3, 4, GROUP_1 | KEY_LEFT),
 177        KEY(3, 2, GROUP_1 | KEY_DOWN),
 178        KEY(3, 1, GROUP_1 | KEY_RIGHT),
 179        KEY(3, 0, GROUP_1 | KEY_UP),
 180        KEY(3, 3, GROUP_1 | KEY_POWER), /* joystick press or Qt::Key_Select */
 181        KEY(0, 5, GROUP_1 | KEY_1),
 182        KEY(0, 4, GROUP_1 | KEY_2),
 183        KEY(0, 3, GROUP_1 | KEY_3),
 184        KEY(4, 3, GROUP_1 | KEY_4),
 185        KEY(4, 4, GROUP_1 | KEY_5),
 186        KEY(4, 5, GROUP_1 | KEY_KPASTERISK),/* "*" */
 187        KEY(1, 4, GROUP_1 | KEY_6),
 188        KEY(1, 5, GROUP_1 | KEY_7),
 189        KEY(1, 3, GROUP_1 | KEY_8),
 190        KEY(2, 3, GROUP_1 | KEY_9),
 191        KEY(2, 5, GROUP_1 | KEY_0),
 192        KEY(2, 4, GROUP_1 | 113), /* # F13 Toggle input method Qt::Key_F13 */
 193        KEY(1, 0, GROUP_1 | KEY_F11),   /* green button Qt::Key_Call */
 194        KEY(2, 1, GROUP_1 | KEY_YEN),   /* left soft Qt::Key_Context1 */
 195        KEY(2, 2, GROUP_1 | KEY_F8),    /* right soft Qt::Key_Back */
 196        KEY(1, 2, GROUP_1 | KEY_LEFTSHIFT), /* shift */
 197        KEY(1, 1, GROUP_1 | KEY_BACKSPACE), /* C (clear) */
 198        KEY(2, 0, GROUP_1 | KEY_F7),    /* menu Qt::Key_Menu */
 199};
 200
 201static struct resource sx1_kp_resources[] = {
 202        [0] = {
 203                .start  = INT_KEYBOARD,
 204                .end    = INT_KEYBOARD,
 205                .flags  = IORESOURCE_IRQ,
 206        },
 207};
 208
 209static const struct matrix_keymap_data sx1_keymap_data = {
 210        .keymap         = sx1_keymap,
 211        .keymap_size    = ARRAY_SIZE(sx1_keymap),
 212};
 213
 214static struct omap_kp_platform_data sx1_kp_data = {
 215        .rows           = 6,
 216        .cols           = 6,
 217        .keymap_data    = &sx1_keymap_data,
 218        .delay  = 80,
 219};
 220
 221static struct platform_device sx1_kp_device = {
 222        .name           = "omap-keypad",
 223        .id             = -1,
 224        .dev            = {
 225                .platform_data = &sx1_kp_data,
 226        },
 227        .num_resources  = ARRAY_SIZE(sx1_kp_resources),
 228        .resource       = sx1_kp_resources,
 229};
 230
 231/*----------- IRDA -------------------------*/
 232
 233static struct omap_irda_config sx1_irda_data = {
 234        .transceiver_cap        = IR_SIRMODE,
 235        .rx_channel             = OMAP_DMA_UART3_RX,
 236        .tx_channel             = OMAP_DMA_UART3_TX,
 237        .dest_start             = UART3_THR,
 238        .src_start              = UART3_RHR,
 239        .tx_trigger             = 0,
 240        .rx_trigger             = 0,
 241};
 242
 243static struct resource sx1_irda_resources[] = {
 244        [0] = {
 245                .start  = INT_UART3,
 246                .end    = INT_UART3,
 247                .flags  = IORESOURCE_IRQ,
 248        },
 249};
 250
 251static u64 irda_dmamask = 0xffffffff;
 252
 253static struct platform_device sx1_irda_device = {
 254        .name           = "omapirda",
 255        .id             = 0,
 256        .dev            = {
 257                .platform_data  = &sx1_irda_data,
 258                .dma_mask       = &irda_dmamask,
 259        },
 260        .num_resources  = ARRAY_SIZE(sx1_irda_resources),
 261        .resource       = sx1_irda_resources,
 262};
 263
 264/*----------- MTD -------------------------*/
 265
 266static struct mtd_partition sx1_partitions[] = {
 267        /* bootloader (U-Boot, etc) in first sector */
 268        {
 269                .name           = "bootloader",
 270                .offset         = 0x01800000,
 271                .size           = SZ_128K,
 272                .mask_flags     = MTD_WRITEABLE, /* force read-only */
 273        },
 274        /* bootloader params in the next sector */
 275        {
 276                .name           = "params",
 277                .offset         = MTDPART_OFS_APPEND,
 278                .size           = SZ_128K,
 279                .mask_flags     = 0,
 280        },
 281        /* kernel */
 282        {
 283                .name           = "kernel",
 284                .offset         = MTDPART_OFS_APPEND,
 285                .size           = SZ_2M - 2 * SZ_128K,
 286                .mask_flags     = 0
 287        },
 288        /* file system */
 289        {
 290                .name           = "filesystem",
 291                .offset         = MTDPART_OFS_APPEND,
 292                .size           = MTDPART_SIZ_FULL,
 293                .mask_flags     = 0
 294        }
 295};
 296
 297static struct physmap_flash_data sx1_flash_data = {
 298        .width          = 2,
 299        .set_vpp        = omap1_set_vpp,
 300        .parts          = sx1_partitions,
 301        .nr_parts       = ARRAY_SIZE(sx1_partitions),
 302};
 303
 304#ifdef CONFIG_SX1_OLD_FLASH
 305/* MTD Intel StrataFlash - old flashes */
 306static struct resource sx1_old_flash_resource[] = {
 307        [0] = {
 308                .start  = OMAP_CS0_PHYS,        /* Physical */
 309                .end    = OMAP_CS0_PHYS + SZ_16M - 1,,
 310                .flags  = IORESOURCE_MEM,
 311        },
 312        [1] = {
 313                .start  = OMAP_CS1_PHYS,
 314                .end    = OMAP_CS1_PHYS + SZ_8M - 1,
 315                .flags  = IORESOURCE_MEM,
 316        },
 317};
 318
 319static struct platform_device sx1_flash_device = {
 320        .name           = "physmap-flash",
 321        .id             = 0,
 322        .dev            = {
 323                .platform_data  = &sx1_flash_data,
 324        },
 325        .num_resources  = 2,
 326        .resource       = &sx1_old_flash_resource,
 327};
 328#else
 329/* MTD Intel 4000 flash - new flashes */
 330static struct resource sx1_new_flash_resource = {
 331        .start          = OMAP_CS0_PHYS,
 332        .end            = OMAP_CS0_PHYS + SZ_32M - 1,
 333        .flags          = IORESOURCE_MEM,
 334};
 335
 336static struct platform_device sx1_flash_device = {
 337        .name           = "physmap-flash",
 338        .id             = 0,
 339        .dev            = {
 340                .platform_data  = &sx1_flash_data,
 341        },
 342        .num_resources  = 1,
 343        .resource       = &sx1_new_flash_resource,
 344};
 345#endif
 346
 347/*----------- USB -------------------------*/
 348
 349static struct omap_usb_config sx1_usb_config __initdata = {
 350        .otg            = 0,
 351        .register_dev   = 1,
 352        .register_host  = 0,
 353        .hmc_mode       = 0,
 354        .pins[0]        = 2,
 355        .pins[1]        = 0,
 356        .pins[2]        = 0,
 357};
 358
 359/*----------- LCD -------------------------*/
 360
 361static struct omap_lcd_config sx1_lcd_config __initdata = {
 362        .ctrl_name      = "internal",
 363};
 364
 365/*-----------------------------------------*/
 366static struct platform_device *sx1_devices[] __initdata = {
 367        &sx1_flash_device,
 368        &sx1_kp_device,
 369        &sx1_irda_device,
 370};
 371
 372/*-----------------------------------------*/
 373
 374static void __init omap_sx1_init(void)
 375{
 376        /* mux pins for uarts */
 377        omap_cfg_reg(UART1_TX);
 378        omap_cfg_reg(UART1_RTS);
 379        omap_cfg_reg(UART2_TX);
 380        omap_cfg_reg(UART2_RTS);
 381        omap_cfg_reg(UART3_TX);
 382        omap_cfg_reg(UART3_RX);
 383
 384        platform_add_devices(sx1_devices, ARRAY_SIZE(sx1_devices));
 385
 386        omap_serial_init();
 387        omap_register_i2c_bus(1, 100, NULL, 0);
 388        omap1_usb_init(&sx1_usb_config);
 389        sx1_mmc_init();
 390
 391        /* turn on USB power */
 392        /* sx1_setusbpower(1); can't do it here because i2c is not ready */
 393        gpio_request(1, "A_IRDA_OFF");
 394        gpio_request(11, "A_SWITCH");
 395        gpio_request(15, "A_USB_ON");
 396        gpio_direction_output(1, 1);    /*A_IRDA_OFF = 1 */
 397        gpio_direction_output(11, 0);   /*A_SWITCH = 0 */
 398        gpio_direction_output(15, 0);   /*A_USB_ON = 0 */
 399
 400        omapfb_set_lcd_config(&sx1_lcd_config);
 401}
 402
 403MACHINE_START(SX1, "OMAP310 based Siemens SX1")
 404        .atag_offset    = 0x100,
 405        .map_io         = omap15xx_map_io,
 406        .init_early     = omap1_init_early,
 407        .init_irq       = omap1_init_irq,
 408        .init_machine   = omap_sx1_init,
 409        .init_late      = omap1_init_late,
 410        .init_time      = omap1_timer_init,
 411        .restart        = omap1_restart,
 412MACHINE_END
 413