/*
* 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/delay.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/i2c.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/arch/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
-static void __init nokia_n800_init_irq(void)
+void __init nokia_n800_init_irq(void)
{
omap2_init_common_hw();
omap_init_irq();
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[] = {
+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) */
-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 = {
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");
#endif
};
-static void __init nokia_n800_init(void)
+#ifdef CONFIG_MENELAUS
+static int n800_auto_sleep_regulators(void)
+{
+ u32 val;
+ int ret;
+
+ val = EN_VPLL_SLEEP | EN_VMMC_SLEEP \
+ | EN_VAUX_SLEEP | EN_VIO_SLEEP \
+ | EN_VMEM_SLEEP | EN_DC3_SLEEP \
+ | EN_VC_SLEEP | EN_DC2_SLEEP;
+
+ ret = menelaus_set_regulator_sleep(1, val);
+ if (ret < 0) {
+ printk(KERN_ERR "Could not set regulators to sleep on "
+ "menelaus: %u\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int n800_auto_voltage_scale(void)
+{
+ int ret;
+
+ ret = menelaus_set_vcore_hw(1400, 1050);
+ if (ret < 0) {
+ printk(KERN_ERR "Could not set VCORE voltage on "
+ "menelaus: %u\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int n800_menelaus_init(struct device *dev)
+{
+ int ret;
+
+ ret = n800_auto_voltage_scale();
+ if (ret < 0)
+ return ret;
+ ret = n800_auto_sleep_regulators();
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static struct menelaus_platform_data n800_menelaus_platform_data = {
+ .late_init = n800_menelaus_init,
+};
+#endif
+
+static struct i2c_board_info __initdata n800_i2c_board_info_1[] = {
+ {
+ I2C_BOARD_INFO("menelaus", 0x72),
+ .irq = INT_24XX_SYS_NIRQ,
+ .platform_data = &n800_menelaus_platform_data,
+ },
+};
+
+extern struct tcm825x_platform_data n800_tcm825x_platform_data;
+
+static struct i2c_board_info __initdata n800_i2c_board_info_2[] = {
+#if defined (CONFIG_VIDEO_TCM825X) || defined (CONFIG_VIDEO_TCM825X_MODULE)
+ {
+ I2C_BOARD_INFO(TCM825X_NAME, TCM825X_I2C_ADDR),
+ .platform_data = &n800_tcm825x_platform_data,
+ },
+#endif
+#if defined(CONFIG_RADIO_TEA5761) || defined(CONFIG_RADIO_TEA5761_MODULE)
+ {
+ I2C_BOARD_INFO("tea5761", 0x10),
+ },
+#endif
+};
+
+void __init nokia_n800_common_init(void)
{
platform_add_devices(n800_devices, ARRAY_SIZE(n800_devices));
+
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,
ARRAY_SIZE(n800_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, n800_i2c_board_info_2,
+ ARRAY_SIZE(n800_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));
- n800_pm_init();
}
-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();
}