Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003 * linux/arch/arm/mach-omap1/board-sx1.c
0004 *
0005 * Modified from board-generic.c
0006 *
0007 * Support for the Siemens SX1 mobile phone.
0008 *
0009 * Original version : Vladimir Ananiev (Vovan888-at-gmail com)
0010 *
0011 * Maintainters : Vladimir Ananiev (aka Vovan888), Sergge
0012 *       oslik.ru
0013 */
0014 #include <linux/gpio.h>
0015 #include <linux/kernel.h>
0016 #include <linux/init.h>
0017 #include <linux/input.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/notifier.h>
0020 #include <linux/mtd/mtd.h>
0021 #include <linux/mtd/partitions.h>
0022 #include <linux/mtd/physmap.h>
0023 #include <linux/types.h>
0024 #include <linux/i2c.h>
0025 #include <linux/errno.h>
0026 #include <linux/export.h>
0027 #include <linux/omapfb.h>
0028 #include <linux/platform_data/keypad-omap.h>
0029 #include <linux/omap-dma.h>
0030 #include "tc.h"
0031 
0032 #include <asm/mach-types.h>
0033 #include <asm/mach/arch.h>
0034 #include <asm/mach/map.h>
0035 
0036 #include "flash.h"
0037 #include "mux.h"
0038 #include "board-sx1.h"
0039 #include "hardware.h"
0040 #include "usb.h"
0041 #include "common.h"
0042 
0043 /* Write to I2C device */
0044 int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value)
0045 {
0046     struct i2c_adapter *adap;
0047     int err;
0048     struct i2c_msg msg[1];
0049     unsigned char data[2];
0050 
0051     adap = i2c_get_adapter(0);
0052     if (!adap)
0053         return -ENODEV;
0054     msg->addr = devaddr;    /* I2C address of chip */
0055     msg->flags = 0;
0056     msg->len = 2;
0057     msg->buf = data;
0058     data[0] = regoffset;    /* register num */
0059     data[1] = value;        /* register data */
0060     err = i2c_transfer(adap, msg, 1);
0061     i2c_put_adapter(adap);
0062     if (err >= 0)
0063         return 0;
0064     return err;
0065 }
0066 
0067 /* Read from I2C device */
0068 int sx1_i2c_read_byte(u8 devaddr, u8 regoffset, u8 *value)
0069 {
0070     struct i2c_adapter *adap;
0071     int err;
0072     struct i2c_msg msg[1];
0073     unsigned char data[2];
0074 
0075     adap = i2c_get_adapter(0);
0076     if (!adap)
0077         return -ENODEV;
0078 
0079     msg->addr = devaddr;    /* I2C address of chip */
0080     msg->flags = 0;
0081     msg->len = 1;
0082     msg->buf = data;
0083     data[0] = regoffset;    /* register num */
0084     err = i2c_transfer(adap, msg, 1);
0085 
0086     msg->addr = devaddr;    /* I2C address */
0087     msg->flags = I2C_M_RD;
0088     msg->len = 1;
0089     msg->buf = data;
0090     err = i2c_transfer(adap, msg, 1);
0091     *value = data[0];
0092     i2c_put_adapter(adap);
0093 
0094     if (err >= 0)
0095         return 0;
0096     return err;
0097 }
0098 /* set keyboard backlight intensity */
0099 int sx1_setkeylight(u8 keylight)
0100 {
0101     if (keylight > SOFIA_MAX_LIGHT_VAL)
0102         keylight = SOFIA_MAX_LIGHT_VAL;
0103     return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_KEYLIGHT_REG, keylight);
0104 }
0105 /* get current keylight intensity */
0106 int sx1_getkeylight(u8 * keylight)
0107 {
0108     return sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_KEYLIGHT_REG, keylight);
0109 }
0110 /* set LCD backlight intensity */
0111 int sx1_setbacklight(u8 backlight)
0112 {
0113     if (backlight > SOFIA_MAX_LIGHT_VAL)
0114         backlight = SOFIA_MAX_LIGHT_VAL;
0115     return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_BACKLIGHT_REG,
0116                   backlight);
0117 }
0118 /* get current LCD backlight intensity */
0119 int sx1_getbacklight (u8 * backlight)
0120 {
0121     return sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_BACKLIGHT_REG,
0122                  backlight);
0123 }
0124 /* set LCD backlight power on/off */
0125 int sx1_setmmipower(u8 onoff)
0126 {
0127     int err;
0128     u8 dat = 0;
0129     err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
0130     if (err < 0)
0131         return err;
0132     if (onoff)
0133         dat |= SOFIA_MMILIGHT_POWER;
0134     else
0135         dat &= ~SOFIA_MMILIGHT_POWER;
0136     return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
0137 }
0138 
0139 /* set USB power on/off */
0140 int sx1_setusbpower(u8 onoff)
0141 {
0142     int err;
0143     u8 dat = 0;
0144     err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
0145     if (err < 0)
0146         return err;
0147     if (onoff)
0148         dat |= SOFIA_USB_POWER;
0149     else
0150         dat &= ~SOFIA_USB_POWER;
0151     return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
0152 }
0153 
0154 EXPORT_SYMBOL(sx1_setkeylight);
0155 EXPORT_SYMBOL(sx1_getkeylight);
0156 EXPORT_SYMBOL(sx1_setbacklight);
0157 EXPORT_SYMBOL(sx1_getbacklight);
0158 EXPORT_SYMBOL(sx1_setmmipower);
0159 EXPORT_SYMBOL(sx1_setusbpower);
0160 
0161 /*----------- Keypad -------------------------*/
0162 
0163 static const unsigned int sx1_keymap[] = {
0164     KEY(3, 5, GROUP_0 | 117), /* camera Qt::Key_F17 */
0165     KEY(4, 0, GROUP_0 | 114), /* voice memo Qt::Key_F14 */
0166     KEY(4, 1, GROUP_2 | 114), /* voice memo */
0167     KEY(4, 2, GROUP_3 | 114), /* voice memo */
0168     KEY(0, 0, GROUP_1 | KEY_F12),   /* red button Qt::Key_Hangup */
0169     KEY(3, 4, GROUP_1 | KEY_LEFT),
0170     KEY(3, 2, GROUP_1 | KEY_DOWN),
0171     KEY(3, 1, GROUP_1 | KEY_RIGHT),
0172     KEY(3, 0, GROUP_1 | KEY_UP),
0173     KEY(3, 3, GROUP_1 | KEY_POWER), /* joystick press or Qt::Key_Select */
0174     KEY(0, 5, GROUP_1 | KEY_1),
0175     KEY(0, 4, GROUP_1 | KEY_2),
0176     KEY(0, 3, GROUP_1 | KEY_3),
0177     KEY(4, 3, GROUP_1 | KEY_4),
0178     KEY(4, 4, GROUP_1 | KEY_5),
0179     KEY(4, 5, GROUP_1 | KEY_KPASTERISK),/* "*" */
0180     KEY(1, 4, GROUP_1 | KEY_6),
0181     KEY(1, 5, GROUP_1 | KEY_7),
0182     KEY(1, 3, GROUP_1 | KEY_8),
0183     KEY(2, 3, GROUP_1 | KEY_9),
0184     KEY(2, 5, GROUP_1 | KEY_0),
0185     KEY(2, 4, GROUP_1 | 113), /* # F13 Toggle input method Qt::Key_F13 */
0186     KEY(1, 0, GROUP_1 | KEY_F11),   /* green button Qt::Key_Call */
0187     KEY(2, 1, GROUP_1 | KEY_YEN),   /* left soft Qt::Key_Context1 */
0188     KEY(2, 2, GROUP_1 | KEY_F8),    /* right soft Qt::Key_Back */
0189     KEY(1, 2, GROUP_1 | KEY_LEFTSHIFT), /* shift */
0190     KEY(1, 1, GROUP_1 | KEY_BACKSPACE), /* C (clear) */
0191     KEY(2, 0, GROUP_1 | KEY_F7),    /* menu Qt::Key_Menu */
0192 };
0193 
0194 static struct resource sx1_kp_resources[] = {
0195     [0] = {
0196         .start  = INT_KEYBOARD,
0197         .end    = INT_KEYBOARD,
0198         .flags  = IORESOURCE_IRQ,
0199     },
0200 };
0201 
0202 static const struct matrix_keymap_data sx1_keymap_data = {
0203     .keymap     = sx1_keymap,
0204     .keymap_size    = ARRAY_SIZE(sx1_keymap),
0205 };
0206 
0207 static struct omap_kp_platform_data sx1_kp_data = {
0208     .rows       = 6,
0209     .cols       = 6,
0210     .keymap_data    = &sx1_keymap_data,
0211     .delay  = 80,
0212 };
0213 
0214 static struct platform_device sx1_kp_device = {
0215     .name       = "omap-keypad",
0216     .id     = -1,
0217     .dev        = {
0218         .platform_data = &sx1_kp_data,
0219     },
0220     .num_resources  = ARRAY_SIZE(sx1_kp_resources),
0221     .resource   = sx1_kp_resources,
0222 };
0223 
0224 /*----------- MTD -------------------------*/
0225 
0226 static struct mtd_partition sx1_partitions[] = {
0227     /* bootloader (U-Boot, etc) in first sector */
0228     {
0229         .name       = "bootloader",
0230         .offset     = 0x01800000,
0231         .size       = SZ_128K,
0232         .mask_flags = MTD_WRITEABLE, /* force read-only */
0233     },
0234     /* bootloader params in the next sector */
0235     {
0236         .name       = "params",
0237         .offset     = MTDPART_OFS_APPEND,
0238         .size       = SZ_128K,
0239         .mask_flags = 0,
0240     },
0241     /* kernel */
0242     {
0243         .name       = "kernel",
0244         .offset     = MTDPART_OFS_APPEND,
0245         .size       = SZ_2M - 2 * SZ_128K,
0246         .mask_flags = 0
0247     },
0248     /* file system */
0249     {
0250         .name       = "filesystem",
0251         .offset     = MTDPART_OFS_APPEND,
0252         .size       = MTDPART_SIZ_FULL,
0253         .mask_flags = 0
0254     }
0255 };
0256 
0257 static struct physmap_flash_data sx1_flash_data = {
0258     .width      = 2,
0259     .set_vpp    = omap1_set_vpp,
0260     .parts      = sx1_partitions,
0261     .nr_parts   = ARRAY_SIZE(sx1_partitions),
0262 };
0263 
0264 /* MTD Intel 4000 flash - new flashes */
0265 static struct resource sx1_new_flash_resource = {
0266     .start      = OMAP_CS0_PHYS,
0267     .end        = OMAP_CS0_PHYS + SZ_32M - 1,
0268     .flags      = IORESOURCE_MEM,
0269 };
0270 
0271 static struct platform_device sx1_flash_device = {
0272     .name       = "physmap-flash",
0273     .id     = 0,
0274     .dev        = {
0275         .platform_data  = &sx1_flash_data,
0276     },
0277     .num_resources  = 1,
0278     .resource   = &sx1_new_flash_resource,
0279 };
0280 
0281 /*----------- USB -------------------------*/
0282 
0283 static struct omap_usb_config sx1_usb_config __initdata = {
0284     .otg        = 0,
0285     .register_dev   = 1,
0286     .register_host  = 0,
0287     .hmc_mode   = 0,
0288     .pins[0]    = 2,
0289     .pins[1]    = 0,
0290     .pins[2]    = 0,
0291 };
0292 
0293 /*----------- LCD -------------------------*/
0294 
0295 static const struct omap_lcd_config sx1_lcd_config __initconst = {
0296     .ctrl_name  = "internal",
0297 };
0298 
0299 /*-----------------------------------------*/
0300 static struct platform_device *sx1_devices[] __initdata = {
0301     &sx1_flash_device,
0302     &sx1_kp_device,
0303 };
0304 
0305 /*-----------------------------------------*/
0306 
0307 static void __init omap_sx1_init(void)
0308 {
0309     /* mux pins for uarts */
0310     omap_cfg_reg(UART1_TX);
0311     omap_cfg_reg(UART1_RTS);
0312     omap_cfg_reg(UART2_TX);
0313     omap_cfg_reg(UART2_RTS);
0314     omap_cfg_reg(UART3_TX);
0315     omap_cfg_reg(UART3_RX);
0316 
0317     platform_add_devices(sx1_devices, ARRAY_SIZE(sx1_devices));
0318 
0319     omap_serial_init();
0320     omap_register_i2c_bus(1, 100, NULL, 0);
0321     omap1_usb_init(&sx1_usb_config);
0322     sx1_mmc_init();
0323 
0324     /* turn on USB power */
0325     /* sx1_setusbpower(1); can't do it here because i2c is not ready */
0326     gpio_request(1, "A_IRDA_OFF");
0327     gpio_request(11, "A_SWITCH");
0328     gpio_request(15, "A_USB_ON");
0329     gpio_direction_output(1, 1);    /*A_IRDA_OFF = 1 */
0330     gpio_direction_output(11, 0);   /*A_SWITCH = 0 */
0331     gpio_direction_output(15, 0);   /*A_USB_ON = 0 */
0332 
0333     omapfb_set_lcd_config(&sx1_lcd_config);
0334 }
0335 
0336 MACHINE_START(SX1, "OMAP310 based Siemens SX1")
0337     .atag_offset    = 0x100,
0338     .map_io     = omap15xx_map_io,
0339     .init_early     = omap1_init_early,
0340     .init_irq   = omap1_init_irq,
0341     .handle_irq = omap1_handle_irq,
0342     .init_machine   = omap_sx1_init,
0343     .init_late  = omap1_init_late,
0344     .init_time  = omap1_timer_init,
0345     .restart    = omap1_restart,
0346 MACHINE_END