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