]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/mach-omap2/board-n800.c
Merge current mainline tree into linux-omap tree
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / board-n800.c
index e2447fcddf620c53e496f0fdce018db040306cf1..95cc84ab42c8d7a2dc4adcd08aaec38c965f6aab 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * linux/arch/arm/mach-omap2/board-n800.c
  *
- * Copyright (C) 2005 Nokia Corporation
+ * Copyright (C) 2005-2007 Nokia Corporation
  * Author: Juha Yrjola <juha.yrjola@nokia.com>
  *
  * Modified from mach-omap2/board-generic.c
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/tsc2301.h>
+#include <linux/spi/tsc2005.h>
 #include <linux/input.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/i2c.h>
-#include <asm/hardware.h>
+#include <linux/i2c/lm8323.h>
+#include <linux/i2c/menelaus.h>
+#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include <asm/arch/gpio.h>
-#include <asm/arch/usb.h>
-#include <asm/arch/board.h>
-#include <asm/arch/common.h>
-#include <asm/arch/mcspi.h>
-#include <asm/arch/menelaus.h>
-#include <asm/arch/lcd_mipid.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/gpio-switch.h>
-#include <asm/arch/omapfb.h>
-#include <asm/arch/blizzard.h>
+#include <mach/gpio.h>
+#include <mach/usb.h>
+#include <mach/board.h>
+#include <mach/common.h>
+#include <mach/mcspi.h>
+#include <mach/lcd_mipid.h>
+#include <mach/clock.h>
+#include <mach/gpio-switch.h>
+#include <mach/omapfb.h>
+#include <mach/blizzard.h>
 
 #include <../drivers/cbus/tahvo.h>
+#include <../drivers/media/video/tcm825x.h>
 
-#define N800_BLIZZARD_POWERDOWN_GPIO 15
-#define N800_STI_GPIO          62
-#define N800_CAM_SENSOR_RESET_GPIO     53
+#define N800_BLIZZARD_POWERDOWN_GPIO   15
+#define N800_STI_GPIO                  62
 #define N800_KEYB_IRQ_GPIO             109
+#define N800_DAV_IRQ_GPIO              103
+#define N800_TSC2301_RESET_GPIO                118
+
+#ifdef CONFIG_MACH_NOKIA_N810
+static s16 rx44_keymap[LM8323_KEYMAP_SIZE] = {
+       [0x01] = KEY_Q,
+       [0x02] = KEY_K,
+       [0x03] = KEY_O,
+       [0x04] = KEY_P,
+       [0x05] = KEY_BACKSPACE,
+       [0x06] = KEY_A,
+       [0x07] = KEY_S,
+       [0x08] = KEY_D,
+       [0x09] = KEY_F,
+       [0x0a] = KEY_G,
+       [0x0b] = KEY_H,
+       [0x0c] = KEY_J,
+
+       [0x11] = KEY_W,
+       [0x12] = KEY_F4,
+       [0x13] = KEY_L,
+       [0x14] = KEY_APOSTROPHE,
+       [0x16] = KEY_Z,
+       [0x17] = KEY_X,
+       [0x18] = KEY_C,
+       [0x19] = KEY_V,
+       [0x1a] = KEY_B,
+       [0x1b] = KEY_N,
+       [0x1c] = KEY_LEFTSHIFT, /* Actually, this is both shift keys */
+       [0x1f] = KEY_F7,
+
+       [0x21] = KEY_E,
+       [0x22] = KEY_SEMICOLON,
+       [0x23] = KEY_MINUS,
+       [0x24] = KEY_EQUAL,
+       [0x2b] = KEY_FN,
+       [0x2c] = KEY_M,
+       [0x2f] = KEY_F8,
+
+       [0x31] = KEY_R,
+       [0x32] = KEY_RIGHTCTRL,
+       [0x34] = KEY_SPACE,
+       [0x35] = KEY_COMMA,
+       [0x37] = KEY_UP,
+       [0x3c] = KEY_COMPOSE,
+       [0x3f] = KEY_F6,
+
+       [0x41] = KEY_T,
+       [0x44] = KEY_DOT,
+       [0x46] = KEY_RIGHT,
+       [0x4f] = KEY_F5,
+       [0x51] = KEY_Y,
+       [0x53] = KEY_DOWN,
+       [0x55] = KEY_ENTER,
+       [0x5f] = KEY_ESC,
+
+       [0x61] = KEY_U,
+       [0x64] = KEY_LEFT,
+
+       [0x71] = KEY_I,
+       [0x75] = KEY_KPENTER,
+};
+
+static struct lm8323_platform_data lm8323_pdata = {
+       .repeat = 0, /* Repeat is handled in userspace for now. */
+       .keymap = rx44_keymap,
+
+       .name = "Internal keyboard",
+       .pwm1_name = "keyboard",
+       .pwm2_name = "cover",
+};
+#endif
 
-static void __init nokia_n800_init_irq(void)
+void __init nokia_n800_init_irq(void)
 {
-       omap2_init_common_hw();
+       omap2_init_common_hw(NULL);
        omap_init_irq();
        omap_gpio_init();
 
@@ -191,122 +265,26 @@ static void __init blizzard_dev_init(void)
        omapfb_set_ctrl_platform_data(&n800_blizzard_data);
 }
 
-#if defined(CONFIG_CBUS_RETU) && defined(CONFIG_VIDEO_CAMERA_SENSOR_TCM825X) && \
-       defined(CONFIG_MENELAUS)
-#define SUPPORT_SENSOR
-#endif
-
-#ifdef SUPPORT_SENSOR
-
-static int sensor_okay;
-
-/*
- * VSIM1       --> CAM_IOVDD   --> IOVDD (1.8 V)
- */
-static int tcm825x_sensor_power_on(void *data)
-{
-       int ret;
-
-       if (!sensor_okay)
-               return -ENODEV;
-
-       /* Set VMEM to 1.5V and VIO to 2.5V */
-       ret = menelaus_set_vmem(1500);
-       if (ret < 0) {
-               /* Try once more, it seems the sensor power up causes
-                * some problems on the I2C bus. */
-               ret = menelaus_set_vmem(1500);
-               if (ret < 0)
-                       return ret;
-       }
-       msleep(1);
-
-       ret = menelaus_set_vio(2500);
-       if (ret < 0)
-               return ret;
-
-       /* Set VSim1 on */
-       retu_write_reg(RETU_REG_CTRL_SET, 0x0080);
-       msleep(100);
-
-       omap_set_gpio_dataout(N800_CAM_SENSOR_RESET_GPIO, 1);
-       msleep(1);
-
-       return 0;
-}
-
-static int tcm825x_sensor_power_off(void * data)
-{
-       int ret;
-
-       omap_set_gpio_dataout(N800_CAM_SENSOR_RESET_GPIO, 0);
-       msleep(1);
-
-       /* Set VSim1 off */
-       retu_write_reg(RETU_REG_CTRL_CLR, 0x0080);
-       msleep(1);
-
-       /* Set VIO_MODE to off */
-       ret = menelaus_set_vio(0);
-       if (ret < 0)
-               return ret;
-       msleep(1);
-
-       /* Set VMEM_MODE to off */
-       ret = menelaus_set_vmem(0);
-       if (ret < 0)
-               return ret;
-       msleep(1);
-
-       return 0;
-}
-
-static struct omap_camera_sensor_config n800_sensor_config = {
-       .power_on   = tcm825x_sensor_power_on,
-       .power_off  = tcm825x_sensor_power_off,
+static struct omap_mmc_config n800_mmc_config __initdata = {
+       .mmc [0] = {
+               .enabled                = 1,
+               .wire4                  = 1,
+       },
 };
 
-static void __init n800_cam_init(void)
-{
-       int r;
-
-       r = omap_request_gpio(N800_CAM_SENSOR_RESET_GPIO);
-       if (r < 0)
-               return;
-
-       omap_set_gpio_dataout(N800_CAM_SENSOR_RESET_GPIO, 0);
-       omap_set_gpio_direction(N800_CAM_SENSOR_RESET_GPIO, 0);
-
-       sensor_okay = 1;
-}
-
-#else
-
-static inline void n800_cam_init(void) {}
-
-#endif
+extern struct omap_mmc_platform_data n800_mmc_data;
 
 static struct omap_board_config_kernel n800_config[] __initdata = {
        { OMAP_TAG_UART,                        &n800_uart_config },
-#ifdef SUPPORT_SENSOR
-       { OMAP_TAG_CAMERA_SENSOR,               &n800_sensor_config },
-#endif
        { OMAP_TAG_FBMEM,                       &n800_fbmem0_config },
        { OMAP_TAG_FBMEM,                       &n800_fbmem1_config },
        { OMAP_TAG_FBMEM,                       &n800_fbmem2_config },
        { OMAP_TAG_TMP105,                      &n800_tmp105_config },
+       { OMAP_TAG_MMC,                         &n800_mmc_config },
 };
 
-
-static int n800_get_keyb_irq_state(struct device *dev)
-{
-       return !omap_get_gpio_datain(N800_KEYB_IRQ_GPIO);
-}
-
 static struct tsc2301_platform_data tsc2301_config = {
-       .reset_gpio     = 118,
-       .dav_gpio       = 103,
-       .pen_int_gpio   = 106,
+       .reset_gpio     = N800_TSC2301_RESET_GPIO,
        .keymap = {
                -1,             /* Event for bit 0 */
                KEY_UP,         /* Event for bit 1 (up) */
@@ -326,19 +304,57 @@ static struct tsc2301_platform_data tsc2301_config = {
                -1,             /* Event for bit 15 */
        },
        .kp_rep         = 0,
-       .get_keyb_irq_state = n800_get_keyb_irq_state,
+       .keyb_name      = "Internal keypad",
 };
 
 static void tsc2301_dev_init(void)
 {
+       int r;
        int gpio = N800_KEYB_IRQ_GPIO;
 
-       if (omap_request_gpio(gpio) < 0) {
-               printk(KERN_ERR "can't get KBIRQ GPIO\n");
-               return;
+       r = gpio_request(gpio, "tsc2301 KBD IRQ");
+       if (r >= 0) {
+               gpio_direction_input(gpio);
+               tsc2301_config.keyb_int = OMAP_GPIO_IRQ(gpio);
+       } else {
+               printk(KERN_ERR "unable to get KBD GPIO");
+       }
+
+       gpio = N800_DAV_IRQ_GPIO;
+       r = gpio_request(gpio, "tsc2301 DAV IRQ");
+       if (r >= 0) {
+               gpio_direction_input(gpio);
+               tsc2301_config.dav_int = OMAP_GPIO_IRQ(gpio);
+       } else {
+               printk(KERN_ERR "unable to get DAV GPIO");
        }
-       omap_set_gpio_direction(gpio, 1);
-       tsc2301_config.keyb_int = OMAP_GPIO_IRQ(gpio);
+}
+
+static int __init tea5761_dev_init(void)
+{
+       const struct omap_tea5761_config *info;
+       int enable_gpio = 0;
+
+       info = omap_get_config(OMAP_TAG_TEA5761, struct omap_tea5761_config);
+       if (info)
+               enable_gpio = info->enable_gpio;
+
+       if (enable_gpio) {
+               pr_debug("Enabling tea5761 at GPIO %d\n",
+                        enable_gpio);
+
+               if (omap_request_gpio(enable_gpio) < 0) {
+                       printk(KERN_ERR "Can't request GPIO %d\n",
+                              enable_gpio);
+                       return -ENODEV;
+               }
+
+               omap_set_gpio_direction(enable_gpio, 0);
+               udelay(50);
+               omap_set_gpio_dataout(enable_gpio, 1);
+       }
+
+       return 0;
 }
 
 static struct omap2_mcspi_device_config tsc2301_mcspi_config = {
@@ -356,21 +372,34 @@ static struct omap2_mcspi_device_config cx3110x_mcspi_config = {
        .single_channel = 1,
 };
 
+#ifdef CONFIG_TOUCHSCREEN_TSC2005
+static struct tsc2005_platform_data tsc2005_config = {
+       .reset_gpio = 94,
+       .dav_gpio = 106
+};
+
+static struct omap2_mcspi_device_config tsc2005_mcspi_config = {
+       .turbo_mode     = 0,
+       .single_channel = 1,
+};
+#endif
+
 static struct spi_board_info n800_spi_board_info[] __initdata = {
-       [0] = {
+       {
                .modalias       = "lcd_mipid",
                .bus_num        = 1,
                .chip_select    = 1,
                .max_speed_hz   = 4000000,
                .controller_data= &mipid_mcspi_config,
                .platform_data  = &n800_mipid_platform_data,
-       }, [1] = {
+       }, {
                .modalias       = "cx3110x",
                .bus_num        = 2,
                .chip_select    = 0,
                .max_speed_hz   = 48000000,
                .controller_data= &cx3110x_mcspi_config,
-       }, [2] = {
+       },
+       {
                .modalias       = "tsc2301",
                .bus_num        = 1,
                .chip_select    = 0,
@@ -380,6 +409,73 @@ static struct spi_board_info n800_spi_board_info[] __initdata = {
        },
 };
 
+static struct spi_board_info n810_spi_board_info[] __initdata = {
+       {
+               .modalias        = "lcd_mipid",
+               .bus_num         = 1,
+               .chip_select     = 1,
+               .max_speed_hz    = 4000000,
+               .controller_data = &mipid_mcspi_config,
+               .platform_data   = &n800_mipid_platform_data,
+       },
+       {
+               .modalias        = "cx3110x",
+               .bus_num         = 2,
+               .chip_select     = 0,
+               .max_speed_hz    = 48000000,
+               .controller_data = &cx3110x_mcspi_config,
+       },
+       {
+               .modalias        = "tsc2005",
+               .bus_num         = 1,
+               .chip_select     = 0,
+               .max_speed_hz    = 6000000,
+               .controller_data = &tsc2005_mcspi_config,
+               .platform_data   = &tsc2005_config,
+       },
+};
+
+static void __init tsc2005_set_config(void)
+{
+       const struct omap_lcd_config *conf;
+
+       conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
+       if (conf != NULL) {
+#ifdef CONFIG_TOUCHSCREEN_TSC2005
+               if (strcmp(conf->panel_name, "lph8923") == 0) {
+                       tsc2005_config.ts_x_plate_ohm = 180;
+                       tsc2005_config.ts_hw_avg = 0;
+                       tsc2005_config.ts_ignore_last = 0;
+                       tsc2005_config.ts_touch_pressure = 1500;
+                       tsc2005_config.ts_stab_time = 100;
+                       tsc2005_config.ts_pressure_max = 2048;
+                       tsc2005_config.ts_pressure_fudge = 2;
+                       tsc2005_config.ts_x_max = 4096;
+                       tsc2005_config.ts_x_fudge = 4;
+                       tsc2005_config.ts_y_max = 4096;
+                       tsc2005_config.ts_y_fudge = 7;
+               } else if (strcmp(conf->panel_name, "ls041y3") == 0) {
+                       tsc2005_config.ts_x_plate_ohm = 280;
+                       tsc2005_config.ts_hw_avg = 0;
+                       tsc2005_config.ts_ignore_last = 0;
+                       tsc2005_config.ts_touch_pressure = 1500;
+                       tsc2005_config.ts_stab_time = 1000;
+                       tsc2005_config.ts_pressure_max = 2048;
+                       tsc2005_config.ts_pressure_fudge = 2;
+                       tsc2005_config.ts_x_max = 4096;
+                       tsc2005_config.ts_x_fudge = 4;
+                       tsc2005_config.ts_y_max = 4096;
+                       tsc2005_config.ts_y_fudge = 7;
+               } else {
+                       printk(KERN_ERR "Unknown panel type, set default "
+                              "touchscreen configuration\n");
+                       tsc2005_config.ts_x_plate_ohm = 200;
+                       tsc2005_config.ts_stab_time = 100;
+               }
+#endif
+       }
+}
+
 #if defined(CONFIG_CBUS_RETU) && defined(CONFIG_LEDS_OMAP_PWM)
 
 void retu_keypad_led_set_power(struct omap_pwm_led_platform_data *self,
@@ -419,16 +515,26 @@ static void __init n800_ts_set_config(void)
        if (conf != NULL) {
                if (strcmp(conf->panel_name, "lph8923") == 0) {
                        tsc2301_config.ts_x_plate_ohm   = 180;
-                       tsc2301_config.ts_hw_avg        = 4;
-                       tsc2301_config.ts_ignore_last   = 1;
-                       tsc2301_config.ts_max_pressure  = 255;
+                       tsc2301_config.ts_hw_avg        = 8;
+                       tsc2301_config.ts_max_pressure  = 2048;
+                       tsc2301_config.ts_touch_pressure = 400;
                        tsc2301_config.ts_stab_time     = 100;
+                       tsc2301_config.ts_pressure_fudge = 2;
+                       tsc2301_config.ts_x_max         = 4096;
+                       tsc2301_config.ts_x_fudge       = 4;
+                       tsc2301_config.ts_y_max         = 4096;
+                       tsc2301_config.ts_y_fudge       = 7;
                } else if (strcmp(conf->panel_name, "ls041y3") == 0) {
                        tsc2301_config.ts_x_plate_ohm   = 280;
-                       tsc2301_config.ts_hw_avg        = 16;
-                       tsc2301_config.ts_touch_pressure= 215;
-                       tsc2301_config.ts_max_pressure  = 255;
-                       tsc2301_config.ts_ignore_last   = 1;
+                       tsc2301_config.ts_hw_avg        = 8;
+                       tsc2301_config.ts_touch_pressure = 400;
+                       tsc2301_config.ts_max_pressure  = 2048;
+                       tsc2301_config.ts_stab_time     = 1000;
+                       tsc2301_config.ts_pressure_fudge = 2;
+                       tsc2301_config.ts_x_max         = 4096;
+                       tsc2301_config.ts_x_fudge       = 4;
+                       tsc2301_config.ts_y_max         = 4096;
+                       tsc2301_config.ts_y_fudge       = 7;
                } else {
                        printk(KERN_ERR "Unknown panel type, set default "
                               "touchscreen configuration\n");
@@ -526,7 +632,7 @@ static struct menelaus_platform_data n800_menelaus_platform_data = {
 };
 #endif
 
-static struct i2c_board_info __initdata n800_i2c_board_info[] = {
+static struct i2c_board_info __initdata n800_i2c_board_info_1[] = {
        {
                I2C_BOARD_INFO("menelaus", 0x72),
                .irq = INT_24XX_SYS_NIRQ,
@@ -534,36 +640,90 @@ static struct i2c_board_info __initdata n800_i2c_board_info[] = {
        },
 };
 
-static void __init nokia_n800_init(void)
+extern struct tcm825x_platform_data n800_tcm825x_platform_data;
+
+static struct i2c_board_info __initdata_or_module n8x0_i2c_board_info_2[] = {
+       {
+               I2C_BOARD_INFO(TCM825X_NAME, TCM825X_I2C_ADDR),
+#if defined (CONFIG_VIDEO_TCM825X) || defined (CONFIG_VIDEO_TCM825X_MODULE)
+               .platform_data = &n800_tcm825x_platform_data,
+#endif
+       },
+       {
+               I2C_BOARD_INFO("tsl2563", 0x29),
+       },
+       {
+               I2C_BOARD_INFO("lp5521", 0x32),
+       },
+};
+
+
+static struct i2c_board_info __initdata_or_module n800_i2c_board_info_2[] = {
+       {
+               I2C_BOARD_INFO("tea5761", 0x10),
+       },
+};
+
+static struct i2c_board_info __initdata_or_module n810_i2c_board_info_2[] = {
+       {
+               I2C_BOARD_INFO("lm8323", 0x45),
+               .irq            = OMAP_GPIO_IRQ(109),
+               .platform_data  = &lm8323_pdata,
+       },
+};
+
+void __init nokia_n800_common_init(void)
 {
        platform_add_devices(n800_devices, ARRAY_SIZE(n800_devices));
 
-       i2c_register_board_info(1, n800_i2c_board_info,
-                       ARRAY_SIZE(n800_i2c_board_info));
-
        n800_flash_init();
        n800_mmc_init();
        n800_bt_init();
-       n800_audio_init(&tsc2301_config);
        n800_dsp_init();
        n800_usb_init();
        n800_cam_init();
-       n800_ts_set_config();
-       spi_register_board_info(n800_spi_board_info,
+       if (machine_is_nokia_n800())
+               spi_register_board_info(n800_spi_board_info,
                                ARRAY_SIZE(n800_spi_board_info));
+       if (machine_is_nokia_n810()) {
+               tsc2005_set_config();
+               spi_register_board_info(n810_spi_board_info,
+                               ARRAY_SIZE(n810_spi_board_info));
+       }
        omap_serial_init();
+       omap_register_i2c_bus(1, 400, n800_i2c_board_info_1,
+                             ARRAY_SIZE(n800_i2c_board_info_1));
+       omap_register_i2c_bus(2, 400, n8x0_i2c_board_info_2,
+                             ARRAY_SIZE(n800_i2c_board_info_2));
+       if (machine_is_nokia_n800())
+               i2c_register_board_info(2, n800_i2c_board_info_2,
+                       ARRAY_SIZE(n800_i2c_board_info_2));
+       if (machine_is_nokia_n810())
+               i2c_register_board_info(2, n810_i2c_board_info_2,
+                       ARRAY_SIZE(n810_i2c_board_info_2));
+               
        mipid_dev_init();
        blizzard_dev_init();
+}
+
+static void __init nokia_n800_init(void)
+{
+       nokia_n800_common_init();
+
+       n800_audio_init(&tsc2301_config);
+       n800_ts_set_config();
        tsc2301_dev_init();
+       tea5761_dev_init();
        omap_register_gpio_switches(n800_gpio_switches,
                                    ARRAY_SIZE(n800_gpio_switches));
 }
 
-static void __init nokia_n800_map_io(void)
+void __init nokia_n800_map_io(void)
 {
        omap_board_config = n800_config;
        omap_board_config_size = ARRAY_SIZE(n800_config);
 
+       omap2_set_globals_242x();
        omap2_map_common_io();
 }