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