| /* |
| * Board support file for OMAP4430 based NotleBoard. |
| * |
| * Copyright (C) 2010 Texas Instruments |
| * |
| * Author: David Anders <x0132446@ti.com> |
| * |
| * Based on mach-omap2/board-4430sdp.c |
| * |
| * Author: Santosh Shilimkar <santosh.shilimkar@ti.com> |
| * |
| * Based on mach-omap2/board-3430sdp.c |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| */ |
| |
| #include "board-notle.h" |
| #include "notle-usb-mux.h" |
| |
| #include <linux/kernel.h> |
| #include <linux/init.h> |
| #include <linux/platform_device.h> |
| #include <linux/clk.h> |
| #include <linux/io.h> |
| #include <linux/ioport.h> |
| #include <linux/leds.h> |
| #include <linux/gpio.h> |
| #include <linux/gpio_keys.h> |
| #include <linux/hwspinlock.h> |
| #include <linux/usb/otg.h> |
| #include <linux/i2c.h> |
| #include <linux/i2c/twl.h> |
| #include <linux/memblock.h> |
| #include <linux/omapfb.h> |
| #include <linux/omap4_duty_cycle_governor.h> |
| #include <linux/reboot.h> |
| #include <linux/spi/spi.h> |
| #include <plat/mcspi.h> |
| |
| #include <linux/gps_elton.h> |
| |
| #ifdef CONFIG_INPUT_LTR506ALS |
| #include <linux/i2c/ltr506als.h> |
| #endif |
| #include <linux/mpu.h> |
| |
| #ifdef CONFIG_INPUT_GLASSHUB |
| #include <linux/i2c/glasshub.h> |
| #endif |
| |
| #include <linux/mpu.h> |
| #include <linux/regulator/fixed.h> |
| #include <linux/regulator/machine.h> |
| |
| /* Version 1 Touchpad driver */ |
| #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C |
| #include "../../../drivers/input/touchscreen/rmi_i2c.h" |
| #endif |
| /* Version 2 and 3 touchpad drivers. */ |
| #if defined(CONFIG_TOUCHPAD_SYNAPTICS_RMI4_I2C) || defined(CONFIG_RMI4_BUS) |
| #include <linux/rmi.h> |
| #endif |
| |
| #include <mach/hardware.h> |
| #include <mach/omap4-common.h> |
| #include <mach/emif.h> |
| #include <mach/lpddr2-elpida.h> |
| #include <mach/dmm.h> |
| #include <mach/omap4_ion.h> |
| |
| #include <asm/mach-types.h> |
| #include <asm/mach/arch.h> |
| #include <asm/mach/map.h> |
| |
| #include <plat/android-display.h> |
| #include <plat/board.h> |
| #include <plat/common.h> |
| #include <plat/usb.h> |
| #include <plat/mmc.h> |
| #include <plat/remoteproc.h> |
| #include <plat/vram.h> |
| #include <plat/omap-pm.h> |
| #include <plat/omap-serial.h> |
| |
| #include <mach/omap_fiq_debugger.h> |
| |
| #include <linux/power/bq27x00_battery.h> |
| |
| #include <video/omapdss.h> |
| #include <video/omap-panel-generic-dpi.h> |
| #include <video/omap-panel-tc358762.h> |
| #include <video/omap-panel-notle.h> |
| |
| #include "timer-gp.h" |
| #include "omap_ram_console.h" |
| #include "hsmmc.h" |
| #include "control.h" |
| #include "pm.h" |
| #include "common-board-devices.h" |
| #include "prm-regbits-44xx.h" |
| #include "prm44xx.h" |
| #include "cm1_44xx.h" |
| |
| static notle_version NOTLE_VERSION = UNVERSIONED; |
| |
| static int notle_gpio_board_evt1[GPIO_MAX_INDEX] = { |
| [GPIO_MPU9000_INT_TIMER_INDEX] = GPIO_MPU9000_INT_TIMER_EVT1, |
| [GPIO_MPU9000_INT_INDEX] = GPIO_MPU9000_INT_EVT1, |
| [GPIO_USB_MUX_CB0_INDEX] = GPIO_USB_MUX_CB0_EVT1, |
| [GPIO_USB_MUX_CB1_INDEX] = GPIO_USB_MUX_CB1, |
| [GPIO_GPS_ON_OFF_INDEX] = GPIO_GPS_ON_OFF_EVT1, |
| [GPIO_GPS_RESET_N_INDEX] = GPIO_GPS_RESET_N_EVT1, |
| [GPIO_LCD_RST_N_INDEX] = GPIO_LCD_RST_N_EVT1, |
| [GPIO_DISP_ENB_INDEX] = GPIO_DISP_ENB, |
| [GPIO_BT_RST_N_INDEX] = GPIO_BT_RST_N_EVT1, |
| [GPIO_CAM_PWDN_INDEX] = GPIO_CAM_PWDN_EVT1, |
| [GPIO_TOUCHPAD_INT_N_INDEX] = GPIO_TOUCHPAD_INT_N_EVT1, |
| [GPIO_PROX_INT_INDEX] = GPIO_PROX_INT_EVT1, |
| [GPIO_BLINK_INT_INDEX] = GPIO_PROX_INT_EVT1, // shared in evt1 |
| [GPIO_BT_RST_N_INDEX] = GPIO_BT_RST_N_EVT1, |
| [GPIO_BCM_BT_HOST_WAKE_INDEX] = GPIO_BCM_BT_HOST_WAKE_EVT1, |
| [GPIO_BCM_WLAN_HOST_WAKE_INDEX] = GPIO_BCM_WLAN_HOST_WAKE_EVT, |
| }; |
| static int notle_gpio_board_evt2[GPIO_MAX_INDEX] = { |
| [GPIO_MPU9000_INT_INDEX] = GPIO_MPU9000_INT_EVT2, |
| [GPIO_USB_MUX_CB0_INDEX] = GPIO_USB_MUX_CB0_EVT2, |
| [GPIO_USB_MUX_CB1_INDEX] = GPIO_USB_MUX_CB1, |
| [GPIO_GPS_ON_OFF_INDEX] = GPIO_GPS_ON_OFF_EVT2, |
| [GPIO_GPS_RESET_N_INDEX] = GPIO_GPS_RESET_N_EVT2, |
| [GPIO_GPS_AWAKE_INDEX] = GPIO_GPS_AWAKE_EVT2, |
| [GPIO_LCD_RST_N_INDEX] = GPIO_LCD_RST_N_EVT2, |
| [GPIO_FPGA_CDONE_INDEX] = GPIO_FPGA_CDONE, |
| [GPIO_FPGA_CRESET_B_INDEX] = GPIO_FPGA_CRESET_B, |
| [GPIO_BT_RST_N_INDEX] = GPIO_BT_RST_N_EVT2, |
| [GPIO_CAM_PWDN_INDEX] = GPIO_CAM_PWDN_EVT2, |
| [GPIO_TOUCHPAD_INT_N_INDEX] = GPIO_TOUCHPAD_INT_N_EVT2, |
| [GPIO_PROX_INT_INDEX] = GPIO_PROX_INT_EVT2, |
| [GPIO_BT_RST_N_INDEX] = GPIO_BT_RST_N_EVT2, |
| [GPIO_BCM_BT_HOST_WAKE_INDEX] = GPIO_BCM_BT_HOST_WAKE_EVT2, |
| [GPIO_BCM_WLAN_HOST_WAKE_INDEX] = GPIO_BCM_WLAN_HOST_WAKE_EVT, |
| [GPIO_BLINK_INT_INDEX] = GPIO_BLINK_INT_EVT2, |
| [GPIO_SOC_INT_INDEX] = GPIO_SOC_INT_EVT2, |
| [GPIO_BAT_LOW_INDEX] = GPIO_BAT_LOW_EVT2, |
| }; |
| |
| /* Read board version from GPIO. Result in NOTLE_VERSION. */ |
| static void notle_version_init(void) |
| { |
| int r; |
| |
| // mux board version gpio's |
| // use low level interface since omap_mux_init has not been called yet |
| __raw_writew(OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP, |
| CORE_BASE_ADDR + MUX_ID2); |
| __raw_writew(OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP, |
| CORE_BASE_ADDR + MUX_ID1); |
| __raw_writew(OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP, |
| CORE_BASE_ADDR + MUX_ID0); |
| |
| r = gpio_request_one(GPIO_BOARD_ID2, GPIOF_IN, "id2"); |
| if (r) { |
| pr_err("Failed to get gpio %d for id2 pin of board version\n", GPIO_BOARD_ID2); |
| } |
| |
| r = gpio_request_one(GPIO_BOARD_ID1, GPIOF_IN, "id1"); |
| if (r) { |
| pr_err("Failed to get gpio %d for id1 pin of board version\n", GPIO_BOARD_ID1); |
| } |
| |
| r = gpio_request_one(GPIO_BOARD_ID0, GPIOF_IN, "id0"); |
| if (r) { |
| pr_err("Failed to get gpio %d for id0 pin of board version\n", GPIO_BOARD_ID0); |
| } |
| NOTLE_VERSION = gpio_get_value(GPIO_BOARD_ID0) | (gpio_get_value(GPIO_BOARD_ID1) << 1) |
| | (gpio_get_value(GPIO_BOARD_ID2) << 2); |
| |
| gpio_free(GPIO_BOARD_ID0); |
| gpio_free(GPIO_BOARD_ID1); |
| gpio_free(GPIO_BOARD_ID2); |
| } |
| |
| |
| static char * notle_version_str(notle_version board_ver) |
| { |
| switch (board_ver) |
| { |
| case V1_EVT1: |
| return "V1 EVT1"; |
| case V1_EVT2: |
| return "V1 EVT2"; |
| case V1_EVT3: |
| return "V1 EVT3"; |
| case V1_DVT1: |
| return "V1 DVT1"; |
| default: |
| return "UNVERSIONED"; |
| } |
| return "UNVERSIONED"; |
| } |
| |
| int notle_version_supported() { |
| return ( (NOTLE_VERSION>=SUPPORTED_FROM) && (NOTLE_VERSION<=SUPPORTED_TO) ); |
| } |
| |
| int notle_version_before( notle_version then ) { |
| return ( then > NOTLE_VERSION ); |
| } |
| |
| int notle_version_after( notle_version then ) { |
| return ( then < NOTLE_VERSION ); |
| } |
| |
| int notle_version_support_battery_temperature() { |
| return (NOTLE_VERSION >= V1_EVT2); |
| } |
| |
| #ifdef CONFIG_OMAP4_DUTY_CYCLE_GOVERNOR |
| |
| static struct pcb_section omap4_duty_governor_pcb_sections[] = { |
| { |
| .pcb_temp_level = 25000, |
| .max_opp = 1008000, |
| .duty_cycle_enabled = false, |
| .tduty_params = { |
| .nitro_rate = 1008000, |
| .cooling_rate = 800000, |
| .nitro_interval = 20000, |
| .nitro_percentage = 80, |
| }, |
| }, |
| { |
| .pcb_temp_level = 30000, |
| .max_opp = 1008000, |
| .duty_cycle_enabled = true, |
| .tduty_params = { |
| .nitro_rate = 1008000, |
| .cooling_rate = 800000, |
| .nitro_interval = 20000, |
| .nitro_percentage = 37, |
| }, |
| }, |
| { |
| .pcb_temp_level = 35000, |
| .max_opp = 1008000, |
| .duty_cycle_enabled = true, |
| .tduty_params = { |
| .nitro_rate = 1008000, |
| .cooling_rate = 800000, |
| .nitro_interval = 20000, |
| .nitro_percentage = 24, |
| }, |
| }, |
| { |
| .pcb_temp_level = 40000, |
| .max_opp = 800000, |
| .duty_cycle_enabled = true, |
| .tduty_params = { |
| .nitro_rate = 800000, |
| .cooling_rate = 600000, |
| .nitro_interval = 20000, |
| .nitro_percentage = 19, |
| }, |
| }, |
| { |
| .pcb_temp_level = 55000, |
| .max_opp = 800000, |
| .duty_cycle_enabled = true, |
| .tduty_params = { |
| .nitro_rate = 800000, |
| .cooling_rate = 600000, |
| .nitro_interval = 20000, |
| .nitro_percentage = 14, |
| }, |
| }, |
| { |
| .pcb_temp_level = 70000, |
| .max_opp = 600000, |
| .duty_cycle_enabled = true, |
| .tduty_params = { |
| .nitro_rate = 600000, |
| .cooling_rate = 300000, |
| .nitro_interval = 20000, |
| .nitro_percentage = 6, |
| }, |
| }, |
| { |
| .pcb_temp_level = 75000, |
| .max_opp = 600000, |
| .duty_cycle_enabled = true, |
| .tduty_params = { |
| .nitro_rate = 600000, |
| .cooling_rate = 300000, |
| .nitro_interval = 20000, |
| .nitro_percentage = 3, |
| }, |
| }, |
| { |
| .pcb_temp_level = 80000, |
| .max_opp = 600000, |
| .duty_cycle_enabled = true, |
| .tduty_params = { |
| .nitro_rate = 600000, |
| .cooling_rate = 300000, |
| .nitro_interval = 20000, |
| .nitro_percentage = 2, |
| }, |
| }, |
| |
| { |
| .pcb_temp_level = 85000, |
| .max_opp = 600000, |
| .duty_cycle_enabled = true, |
| .tduty_params = { |
| .nitro_rate = 600000, |
| .cooling_rate = 300000, |
| .nitro_interval = 20000, |
| .nitro_percentage = 1, |
| }, |
| }, |
| }; |
| |
| static struct pcb_section omap4_duty_governor_turbo_sprint_pcb_sections[] = { |
| { |
| .pcb_temp_level = 65000, |
| .max_opp = 1008000, |
| .duty_cycle_enabled = false, |
| .tduty_params = { |
| .nitro_rate = 1008000, |
| .cooling_rate = 800000, |
| .nitro_interval = 20000, |
| .nitro_percentage = 80, |
| }, |
| }, |
| { |
| .pcb_temp_level = 70000, |
| .max_opp = 600000, |
| .duty_cycle_enabled = true, |
| .tduty_params = { |
| .nitro_rate = 800000, |
| .cooling_rate = 600000, |
| .nitro_interval = 20000, |
| .nitro_percentage = 80, |
| }, |
| }, |
| { |
| .pcb_temp_level = 75000, |
| .max_opp = 600000, |
| .duty_cycle_enabled = true, |
| .tduty_params = { |
| .nitro_rate = 600000, |
| .cooling_rate = 300000, |
| .nitro_interval = 20000, |
| .nitro_percentage = 3, |
| }, |
| }, |
| { |
| .pcb_temp_level = 80000, |
| .max_opp = 600000, |
| .duty_cycle_enabled = true, |
| .tduty_params = { |
| .nitro_rate = 600000, |
| .cooling_rate = 300000, |
| .nitro_interval = 20000, |
| .nitro_percentage = 2, |
| }, |
| }, |
| |
| { |
| .pcb_temp_level = 85000, |
| .max_opp = 600000, |
| .duty_cycle_enabled = true, |
| .tduty_params = { |
| .nitro_rate = 600000, |
| .cooling_rate = 300000, |
| .nitro_interval = 20000, |
| .nitro_percentage = 1, |
| }, |
| }, |
| }; |
| |
| void init_duty_governor(void) |
| { |
| omap4_duty_pcb_section_reg(omap4_duty_governor_pcb_sections, |
| ARRAY_SIZE(omap4_duty_governor_pcb_sections)); |
| omap4_duty_turbo_sprint_pcb_section_reg(omap4_duty_governor_turbo_sprint_pcb_sections, |
| ARRAY_SIZE(omap4_duty_governor_turbo_sprint_pcb_sections)); |
| } |
| #else |
| void init_duty_governor(void){} |
| #endif /*CONFIG_OMAP4_DUTY_CYCLE*/ |
| |
| int |
| notle_get_gpio(int gpio_index) |
| { |
| int ret = -1; |
| |
| if (!notle_version_supported()) { |
| return ret; |
| } |
| |
| switch (NOTLE_VERSION) { |
| case V1_EVT1: |
| ret = notle_gpio_board_evt1[gpio_index]; |
| break; |
| default: |
| ret = notle_gpio_board_evt2[gpio_index]; |
| break; |
| } |
| |
| // Special case gpio_wk0 |
| if (ret == 0 && gpio_index != GPIO_BCM_WLAN_HOST_WAKE_INDEX) { |
| pr_err("%s:Uninitialized index %d\n", __FUNCTION__, gpio_index); |
| ret = -1; |
| } |
| return(ret); |
| } |
| |
| static struct gpio_led gpio_leds[] = { |
| { |
| .name = "notleboard::status1", |
| .default_trigger = "heartbeat", |
| .gpio = 7, |
| }, |
| { |
| .name = "notleboard::status2", |
| .default_trigger = "mmc0", |
| .gpio = 8, |
| }, |
| }; |
| |
| static struct gpio_led_platform_data gpio_led_info = { |
| .leds = gpio_leds, |
| .num_leds = ARRAY_SIZE(gpio_leds), |
| }; |
| |
| static struct platform_device leds_gpio = { |
| .name = "leds-gpio", |
| .id = -1, |
| .dev = { |
| .platform_data = &gpio_led_info, |
| }, |
| }; |
| |
| static void __init notle_init_early(void) |
| { |
| omap2_init_common_infrastructure(); |
| omap2_init_common_devices(NULL, NULL); |
| init_duty_governor(); |
| } |
| |
| static int notle_enable_dpi(struct omap_dss_device *dssdev) { |
| gpio_set_value(dssdev->reset_gpio, 1); |
| return 0; |
| } |
| |
| static void notle_disable_dpi(struct omap_dss_device *dssdev) { |
| gpio_set_value(dssdev->reset_gpio, 0); |
| } |
| |
| static int notle_enable_panel(void) { |
| if (NOTLE_VERSION == V1_EVT1) { |
| gpio_set_value(GPIO_DISP_ENB, 1); |
| } |
| return 0; |
| }; |
| |
| static void notle_disable_panel(void) { |
| if (NOTLE_VERSION == V1_EVT1) { |
| gpio_set_value(GPIO_DISP_ENB, 0); |
| } |
| }; |
| |
| /* |
| * Gamma table where output = input ^ gamma |
| * Format of entries is 0xiirrggbb (ii is the index) |
| * Hardware and image experiments determined that our default |
| * gamma should be set at 1.1 |
| */ |
| static u32 gamma_11[OMAP_DSS_GAMMA_TABLE_SIZE] = { |
| 0x00000000, 0x01010101, 0x02010101, 0x03020202, |
| 0x04030303, 0x05030303, 0x06040404, 0x07050505, |
| 0x08060606, 0x09060606, 0x0a070707, 0x0b080808, |
| 0x0c090909, 0x0d0a0a0a, 0x0e0a0a0a, 0x0f0b0b0b, |
| 0x100c0c0c, 0x110d0d0d, 0x120e0e0e, 0x130f0f0f, |
| 0x14101010, 0x15101010, 0x16111111, 0x17121212, |
| 0x18131313, 0x19141414, 0x1a151515, 0x1b161616, |
| 0x1c161616, 0x1d171717, 0x1e181818, 0x1f191919, |
| 0x201a1a1a, 0x211b1b1b, 0x221c1c1c, 0x231d1d1d, |
| 0x241e1e1e, 0x251f1f1f, 0x261f1f1f, 0x27202020, |
| 0x28212121, 0x29222222, 0x2a232323, 0x2b242424, |
| 0x2c252525, 0x2d262626, 0x2e272727, 0x2f282828, |
| 0x30292929, 0x312a2a2a, 0x322a2a2a, 0x332b2b2b, |
| 0x342c2c2c, 0x352d2d2d, 0x362e2e2e, 0x372f2f2f, |
| 0x38303030, 0x39313131, 0x3a323232, 0x3b333333, |
| 0x3c343434, 0x3d353535, 0x3e363636, 0x3f373737, |
| 0x40383838, 0x41393939, 0x423a3a3a, 0x433b3b3b, |
| 0x443c3c3c, 0x453d3d3d, 0x463e3e3e, 0x473e3e3e, |
| 0x483f3f3f, 0x49404040, 0x4a414141, 0x4b424242, |
| 0x4c434343, 0x4d444444, 0x4e454545, 0x4f464646, |
| 0x50474747, 0x51484848, 0x52494949, 0x534a4a4a, |
| 0x544b4b4b, 0x554c4c4c, 0x564d4d4d, 0x574e4e4e, |
| 0x584f4f4f, 0x59505050, 0x5a515151, 0x5b525252, |
| 0x5c535353, 0x5d545454, 0x5e555555, 0x5f565656, |
| 0x60575757, 0x61585858, 0x62595959, 0x635a5a5a, |
| 0x645b5b5b, 0x655c5c5c, 0x665d5d5d, 0x675e5e5e, |
| 0x685f5f5f, 0x69606060, 0x6a616161, 0x6b626262, |
| 0x6c636363, 0x6d646464, 0x6e656565, 0x6f666666, |
| 0x70676767, 0x71686868, 0x72696969, 0x736a6a6a, |
| 0x746b6b6b, 0x756c6c6c, 0x766d6d6d, 0x776e6e6e, |
| 0x786f6f6f, 0x79707070, 0x7a717171, 0x7b727272, |
| 0x7c737373, 0x7d747474, 0x7e757575, 0x7f767676, |
| 0x80777777, 0x81797979, 0x827a7a7a, 0x837b7b7b, |
| 0x847c7c7c, 0x857d7d7d, 0x867e7e7e, 0x877f7f7f, |
| 0x88808080, 0x89818181, 0x8a828282, 0x8b838383, |
| 0x8c848484, 0x8d858585, 0x8e868686, 0x8f878787, |
| 0x90888888, 0x91898989, 0x928a8a8a, 0x938b8b8b, |
| 0x948c8c8c, 0x958d8d8d, 0x968e8e8e, 0x978f8f8f, |
| 0x98909090, 0x99919191, 0x9a929292, 0x9b939393, |
| 0x9c959595, 0x9d969696, 0x9e979797, 0x9f989898, |
| 0xa0999999, 0xa19a9a9a, 0xa29b9b9b, 0xa39c9c9c, |
| 0xa49d9d9d, 0xa59e9e9e, 0xa69f9f9f, 0xa7a0a0a0, |
| 0xa8a1a1a1, 0xa9a2a2a2, 0xaaa3a3a3, 0xaba4a4a4, |
| 0xaca5a5a5, 0xada6a6a6, 0xaea7a7a7, 0xafa9a9a9, |
| 0xb0aaaaaa, 0xb1ababab, 0xb2acacac, 0xb3adadad, |
| 0xb4aeaeae, 0xb5afafaf, 0xb6b0b0b0, 0xb7b1b1b1, |
| 0xb8b2b2b2, 0xb9b3b3b3, 0xbab4b4b4, 0xbbb5b5b5, |
| 0xbcb6b6b6, 0xbdb7b7b7, 0xbeb8b8b8, 0xbfbababa, |
| 0xc0bbbbbb, 0xc1bcbcbc, 0xc2bdbdbd, 0xc3bebebe, |
| 0xc4bfbfbf, 0xc5c0c0c0, 0xc6c1c1c1, 0xc7c2c2c2, |
| 0xc8c3c3c3, 0xc9c4c4c4, 0xcac5c5c5, 0xcbc6c6c6, |
| 0xccc7c7c7, 0xcdc9c9c9, 0xcecacaca, 0xcfcbcbcb, |
| 0xd0cccccc, 0xd1cdcdcd, 0xd2cecece, 0xd3cfcfcf, |
| 0xd4d0d0d0, 0xd5d1d1d1, 0xd6d2d2d2, 0xd7d3d3d3, |
| 0xd8d4d4d4, 0xd9d6d6d6, 0xdad7d7d7, 0xdbd8d8d8, |
| 0xdcd9d9d9, 0xdddadada, 0xdedbdbdb, 0xdfdcdcdc, |
| 0xe0dddddd, 0xe1dedede, 0xe2dfdfdf, 0xe3e0e0e0, |
| 0xe4e1e1e1, 0xe5e3e3e3, 0xe6e4e4e4, 0xe7e5e5e5, |
| 0xe8e6e6e6, 0xe9e7e7e7, 0xeae8e8e8, 0xebe9e9e9, |
| 0xeceaeaea, 0xedebebeb, 0xeeececec, 0xefededed, |
| 0xf0efefef, 0xf1f0f0f0, 0xf2f1f1f1, 0xf3f2f2f2, |
| 0xf4f3f3f3, 0xf5f4f4f4, 0xf6f5f5f5, 0xf7f6f6f6, |
| 0xf8f7f7f7, 0xf9f8f8f8, 0xfafafafa, 0xfbfbfbfb, |
| 0xfcfcfcfc, 0xfdfdfdfd, 0xfefefefe, 0xffffffff |
| }; |
| |
| /* Using the panel-notle-dpi driver, we only specify enable/disable. */ |
| static struct panel_notle_data panel_notle_preevt2 = { |
| .platform_enable = notle_enable_dpi, |
| .platform_disable = notle_disable_dpi, |
| .panel_enable = notle_enable_panel, |
| .panel_disable = notle_disable_panel, |
| .red_max_mw = 63, |
| .green_max_mw = 192, |
| .blue_max_mw = 96, |
| .limit_mw = 80, |
| .red_percent = 1667, |
| .green_percent = 5416, |
| .blue_percent = 2917, |
| .cpr_enable = 0, |
| .gamma_table = NULL, |
| .gamma_enable = 0, |
| }; |
| |
| static struct panel_notle_data panel_notle = { |
| .platform_enable = notle_enable_dpi, |
| .platform_disable = notle_disable_dpi, |
| .panel_enable = notle_enable_panel, |
| .panel_disable = notle_disable_panel, |
| .red_max_mw = 63, |
| .green_max_mw = 96, |
| .blue_max_mw = 96, |
| .limit_mw = 76, |
| .red_percent = 2444, |
| .green_percent = 4444, |
| .blue_percent = 3111, |
| .cpr_enable = 1, |
| .cpr_coefs = { |
| 205, 9, 17, 25, 209, 11, 9, -1, 247 |
| }, |
| .gamma_table = gamma_11, |
| .gamma_enable = 1, |
| }; |
| |
| // gpio line set in board specific code |
| struct omap_dss_device panel_notle_device = { |
| .type = OMAP_DISPLAY_TYPE_DPI, |
| .name = "notle_nhd_panel", |
| .driver_name = "panel_notle", |
| .data = &panel_notle, |
| .phy.dpi.data_lines = 24, |
| .channel = OMAP_DSS_CHANNEL_LCD2, |
| .vsync_gpio = -1, |
| .panel = { |
| .timings = { |
| .x_res = 640, |
| .y_res = 360, |
| }, |
| }, |
| }; |
| |
| static struct omap2_mcspi_device_config ice40_mcspi_config = { |
| .turbo_mode = 0, |
| .single_channel = 1, /* 0: slave, 1: master */ |
| }; |
| |
| static struct spi_board_info ice40_spi_board_info[] __initdata = { |
| [0] = { |
| .modalias = "ice40-spi", |
| .bus_num = 1, |
| .chip_select = 0, |
| .max_speed_hz = 48000000, |
| .controller_data = &ice40_mcspi_config, |
| }, |
| }; |
| |
| int __init notle_dpi_init(void) |
| { |
| int r; |
| |
| if (notle_version_before(V1_EVT2)) { |
| r = gpio_request_one(GPIO_DISP_ENB, GPIOF_OUT_INIT_LOW, "disp_enable"); |
| if (r) { |
| pr_err("Failed to get display enable gpio\n"); |
| return r; |
| } |
| } |
| |
| panel_notle_device.reset_gpio = notle_get_gpio(GPIO_LCD_RST_N_INDEX); |
| r = gpio_request_one(panel_notle_device.reset_gpio, |
| GPIOF_OUT_INIT_HIGH, "panel_reset"); |
| if (r) { |
| pr_err("Failed to get panel reset powerdown GPIO\n"); |
| if (notle_version_before(V1_EVT2)) { |
| gpio_free(GPIO_DISP_ENB); |
| } |
| return r; |
| } |
| |
| if (notle_version_after(V1_EVT1)) { |
| struct panel_notle_data *panel_data = &panel_notle; |
| |
| panel_data->gpio_fpga_cdone = notle_get_gpio(GPIO_FPGA_CDONE_INDEX); |
| r = gpio_request_one(panel_data->gpio_fpga_cdone, |
| GPIOF_IN, "fpga_cdone"); |
| if (r) { |
| pr_err("Failed to get fpga_cdone GPIO\n"); |
| gpio_free(panel_notle_device.reset_gpio); |
| if (notle_version_before(V1_EVT2)) { |
| gpio_free(GPIO_DISP_ENB); |
| } |
| return r; |
| } |
| |
| panel_data->gpio_fpga_creset_b = notle_get_gpio(GPIO_FPGA_CRESET_B_INDEX); |
| r = gpio_request_one(panel_data->gpio_fpga_creset_b, |
| GPIOF_OUT_INIT_HIGH, "fpga_creset_b"); |
| if (r) { |
| pr_err("Failed to get fpga_creset_b GPIO\n"); |
| gpio_free(panel_data->gpio_fpga_cdone); |
| gpio_free(panel_notle_device.reset_gpio); |
| if (notle_version_before(V1_EVT2)) { |
| gpio_free(GPIO_DISP_ENB); |
| } |
| return r; |
| } |
| } |
| |
| if (notle_version_supported()) { |
| spi_register_board_info(ice40_spi_board_info, |
| ARRAY_SIZE(ice40_spi_board_info)); |
| } |
| |
| return 0; |
| } |
| |
| static struct omap_dss_device *panel_notle_dss_devices[] = { |
| &panel_notle_device, |
| }; |
| |
| static struct omap_dss_board_info panel_notle_dss_data = { |
| .num_devices = ARRAY_SIZE(panel_notle_dss_devices), |
| .devices = panel_notle_dss_devices, |
| .default_device = &panel_notle_device, |
| }; |
| |
| static struct omap_musb_board_data musb_board_data = { |
| .interface_type = MUSB_INTERFACE_UTMI, |
| #ifdef CONFIG_USB_GADGET_MUSB_HDRC |
| .mode = MUSB_PERIPHERAL, |
| #else |
| .mode = MUSB_OTG, |
| #endif |
| .power = 100, |
| }; |
| |
| static struct twl4030_usb_data omap4_usbphy_data = { |
| .phy_init = omap4430_phy_init, |
| .phy_exit = omap4430_phy_exit, |
| .phy_power = omap4430_phy_power, |
| .phy_set_clock = omap4430_phy_set_clk, |
| .phy_suspend = omap4430_phy_suspend, |
| }; |
| |
| static struct omap2_hsmmc_info mmc[] = { |
| { |
| .mmc = 2, |
| .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA | MMC_CAP_1_8V_DDR, |
| .gpio_cd = -EINVAL, |
| .gpio_wp = -EINVAL, |
| .nonremovable = true, |
| .ocr_mask = MMC_VDD_29_30, |
| .no_off_init = true, |
| // TODO(rocky): Experiment with turning this off to see if |
| // it improves hsmmc suspend/resume problem. Measured |
| // effect on current draw is zero. |
| .power_saving = false, |
| }, |
| { |
| .name = "bcm4329", |
| .mmc = 5, |
| .caps = MMC_CAP_4_BIT_DATA, |
| // TODO(abliss): | MMC_CAP_POWER_OFF_CARD, |
| .gpio_wp = -EINVAL, |
| .gpio_cd = -EINVAL, |
| .ocr_mask = MMC_VDD_165_195 | MMC_VDD_20_21, |
| .nonremovable = true, |
| .mmc_data = &tuna_wifi_data, |
| }, |
| /* This device is only present on Dog devices. It will be blanked out |
| * below (by setting .mmc to 0) for other versions. |
| */ |
| { |
| .mmc = 1, |
| .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, |
| .gpio_wp = -EINVAL, |
| .ocr_mask = MMC_VDD_29_30, |
| .no_off_init = true, |
| .power_saving = true, |
| }, |
| {} /* Terminator */ |
| }; |
| |
| #ifdef CONFIG_MMC_NOTLE |
| static struct regulator_consumer_supply notle_vmmc_supply[] = { |
| { |
| .supply = "vmmc", |
| .dev_name = "omap_hsmmc.0", |
| }, |
| }; |
| #endif |
| static struct regulator_consumer_supply notle_vaux_supply[] = { |
| { |
| .supply = "vmmc", |
| .dev_name = "omap_hsmmc.1", |
| }, |
| }; |
| |
| static int omap4_twl6030_hsmmc_late_init(struct device *dev) |
| { |
| int ret = 0; |
| struct platform_device *pdev = container_of(dev, |
| struct platform_device, dev); |
| struct omap_mmc_platform_data *pdata = dev->platform_data; |
| |
| if (!pdata) { |
| dev_err(dev, "%s: NULL platform data\n", __func__); |
| return -EINVAL; |
| } |
| /* Setting MMC1 Card detect Irq */ |
| if (pdev->id == 0) { |
| ret = twl6030_mmc_card_detect_config(); |
| if (ret) |
| dev_err(dev, "%s: Error card detect config(%d)\n", |
| __func__, ret); |
| else |
| pdata->slots[0].card_detect = twl6030_mmc_card_detect; |
| } |
| return ret; |
| } |
| |
| static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev) |
| { |
| struct omap_mmc_platform_data *pdata; |
| |
| /* dev can be null if CONFIG_MMC_OMAP_HS is not set */ |
| if (!dev) { |
| pr_err("Failed omap4_twl6030_hsmmc_set_late_init\n"); |
| return; |
| } |
| pdata = dev->platform_data; |
| |
| pdata->init = omap4_twl6030_hsmmc_late_init; |
| } |
| |
| static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) |
| { |
| struct omap2_hsmmc_info *c; |
| omap2_hsmmc_init(controllers); |
| for (c = controllers; c->mmc; c++) { |
| omap4_twl6030_hsmmc_set_late_init(c->dev); |
| } |
| |
| return 0; |
| } |
| |
| // Voltage for eMMC flash |
| static struct regulator_init_data notle_vaux1 = { |
| .constraints = { |
| .min_uV = 2900000, |
| .max_uV = 2900000, |
| .apply_uV = true, |
| .valid_modes_mask = REGULATOR_MODE_NORMAL |
| | REGULATOR_MODE_STANDBY, |
| .valid_ops_mask = REGULATOR_CHANGE_MODE |
| | REGULATOR_CHANGE_STATUS, |
| .always_on = true, |
| .state_mem = { |
| .enabled = true, |
| }, |
| .initial_state = PM_SUSPEND_MEM, |
| |
| }, |
| .num_consumer_supplies = 1, |
| .consumer_supplies = notle_vaux_supply, |
| }; |
| |
| |
| static struct regulator_consumer_supply notle_cam2_supply[] = { |
| { |
| .supply = "cam2pwr", |
| }, |
| }; |
| |
| // Voltage for sensors (mag, acc, gyro, light sensor, camera) |
| static struct regulator_init_data notle_vaux2 = { |
| .constraints = { |
| .min_uV = 2800000, |
| .max_uV = 2800000, |
| .apply_uV = true, |
| .valid_modes_mask = REGULATOR_MODE_NORMAL |
| | REGULATOR_MODE_STANDBY, |
| .valid_ops_mask = REGULATOR_CHANGE_MODE |
| | REGULATOR_CHANGE_STATUS |
| | REGULATOR_CHANGE_VOLTAGE, |
| .always_on = true, |
| .state_mem = { |
| .enabled = true, |
| }, |
| .initial_state = PM_SUSPEND_MEM, |
| }, |
| .num_consumer_supplies = 1, |
| .consumer_supplies = notle_cam2_supply, |
| }; |
| |
| static struct regulator_init_data notle_vaux3 = { |
| .constraints = { |
| .min_uV = 1200000, |
| .max_uV = 1200000, |
| .apply_uV = true, |
| .valid_modes_mask = REGULATOR_MODE_NORMAL |
| | REGULATOR_MODE_STANDBY, |
| .valid_ops_mask = REGULATOR_CHANGE_MODE |
| | REGULATOR_CHANGE_STATUS, |
| .always_on = true, |
| .state_mem = { |
| .enabled = true, |
| }, |
| .initial_state = PM_SUSPEND_MEM, |
| }, |
| }; |
| |
| #ifdef CONFIG_MMC_NOTLE |
| /* Voltage for SD card */ |
| static struct regulator_init_data notle_vmmc = { |
| .constraints = { |
| .min_uV = 2900000, |
| .max_uV = 2900000, |
| .apply_uV = true, |
| .valid_modes_mask = REGULATOR_MODE_NORMAL |
| | REGULATOR_MODE_STANDBY, |
| .valid_ops_mask = REGULATOR_CHANGE_MODE |
| | REGULATOR_CHANGE_STATUS, |
| .always_on = true, |
| .state_mem = { |
| .enabled = true, |
| }, |
| .initial_state = PM_SUSPEND_MEM, |
| }, |
| .num_consumer_supplies = 1, |
| .consumer_supplies = notle_vmmc_supply, |
| }; |
| #else |
| /* gpio_100 camera power-down */ |
| static struct regulator_init_data notle_vmmc = { |
| .constraints = { |
| .min_uV = 1800000, |
| .max_uV = 1800000, |
| .apply_uV = true, |
| .valid_modes_mask = REGULATOR_MODE_NORMAL |
| | REGULATOR_MODE_STANDBY, |
| .valid_ops_mask = REGULATOR_CHANGE_MODE |
| | REGULATOR_CHANGE_STATUS, |
| .state_mem = { |
| .disabled = true, |
| }, |
| .initial_state = PM_SUSPEND_MEM, |
| }, |
| }; |
| #endif |
| |
| /* unused */ |
| static struct regulator_init_data notle_vpp = { |
| .constraints = { |
| .min_uV = 1800000, |
| .max_uV = 2500000, |
| .apply_uV = true, |
| .valid_modes_mask = REGULATOR_MODE_NORMAL |
| | REGULATOR_MODE_STANDBY, |
| .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
| | REGULATOR_CHANGE_MODE |
| | REGULATOR_CHANGE_STATUS, |
| .state_mem = { |
| .disabled = true, |
| }, |
| .initial_state = PM_SUSPEND_MEM, |
| }, |
| }; |
| |
| /* Voltage for the touchpad */ |
| static struct regulator_init_data notle_vusim = { |
| .constraints = { |
| .min_uV = 3000000, |
| .max_uV = 3000000, |
| .apply_uV = true, |
| .valid_modes_mask = REGULATOR_MODE_NORMAL |
| | REGULATOR_MODE_STANDBY, |
| .valid_ops_mask = REGULATOR_CHANGE_MODE |
| | REGULATOR_CHANGE_STATUS, |
| .always_on = true, |
| .state_mem = { |
| .enabled = true, |
| }, |
| .initial_state = PM_SUSPEND_MEM, |
| }, |
| }; |
| |
| /* unused */ |
| static struct regulator_init_data notle_vana = { |
| .constraints = { |
| .min_uV = 2100000, |
| .max_uV = 2100000, |
| /* Fixed voltage regulators do not have a set_voltage() hook |
| * therefore cannot have the voltage set. */ |
| .apply_uV = false, |
| .valid_modes_mask = REGULATOR_MODE_NORMAL |
| | REGULATOR_MODE_STANDBY, |
| .valid_ops_mask = REGULATOR_CHANGE_MODE |
| | REGULATOR_CHANGE_STATUS, |
| .state_mem = { |
| .disabled = true, |
| }, |
| .initial_state = PM_SUSPEND_MEM, |
| }, |
| }; |
| |
| /* 1.8V for "lots of important stuff" - clocks, plls, etc. */ |
| static struct regulator_init_data notle_vcxio = { |
| .constraints = { |
| .min_uV = 1800000, |
| .max_uV = 1800000, |
| /* Fixed voltage regulators do not have a set_voltage() hook |
| * therefore cannot have the voltage set. */ |
| .apply_uV = false, |
| .valid_modes_mask = REGULATOR_MODE_NORMAL |
| | REGULATOR_MODE_STANDBY, |
| .valid_ops_mask = REGULATOR_CHANGE_MODE |
| | REGULATOR_CHANGE_STATUS, |
| .always_on = true, |
| .state_mem = { |
| .enabled = true, |
| }, |
| .initial_state = PM_SUSPEND_MEM, |
| }, |
| }; |
| |
| /* A/D convertor? */ |
| static struct regulator_init_data notle_vdac = { |
| .constraints = { |
| .min_uV = 1800000, |
| .max_uV = 1800000, |
| /* Fixed voltage regulators do not have a set_voltage() hook |
| * therefore cannot have the voltage set. */ |
| .apply_uV = false, |
| .valid_modes_mask = REGULATOR_MODE_NORMAL |
| | REGULATOR_MODE_STANDBY, |
| .valid_ops_mask = REGULATOR_CHANGE_MODE |
| | REGULATOR_CHANGE_STATUS, |
| .state_mem = { |
| .disabled = true, |
| }, |
| .initial_state = PM_SUSPEND_MEM, |
| }, |
| }; |
| |
| static struct regulator_consumer_supply notle_vusb_supply[] = { |
| REGULATOR_SUPPLY("vusb", "twl6030_usb"), |
| }; |
| |
| /* Powers OMAP's USB controller */ |
| /* TODO(rocky): This still doesn't seem to get hooked up properly with the |
| * twl6030 driver. i.e. I still see these in the kernel log: |
| * [ 77.002502] suspend_set_state: VUSB: No configuration |
| */ |
| static struct regulator_init_data notle_vusb = { |
| .constraints = { |
| .min_uV = 3300000, |
| .max_uV = 3300000, |
| .valid_modes_mask = REGULATOR_MODE_NORMAL |
| | REGULATOR_MODE_STANDBY, |
| .valid_ops_mask = REGULATOR_CHANGE_MODE |
| | REGULATOR_CHANGE_STATUS, |
| .state_mem = { |
| .disabled = true, |
| }, |
| .initial_state = PM_SUSPEND_MEM, |
| }, |
| .num_consumer_supplies = ARRAY_SIZE(notle_vusb_supply), |
| .consumer_supplies = notle_vusb_supply, |
| }; |
| |
| static struct regulator_consumer_supply notle_clk32kg_supply[] = { |
| REGULATOR_SUPPLY("clk32kg", NULL), |
| }; |
| |
| static struct regulator_init_data omap4_notle_clk32kg = { |
| .constraints = { |
| .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
| .always_on = true, |
| }, |
| .num_consumer_supplies = ARRAY_SIZE(notle_clk32kg_supply), |
| .consumer_supplies = notle_clk32kg_supply, |
| }; |
| |
| // TODO(eieio): revisit these when we optimize sleep current |
| |
| /* ttyO0 unused */ |
| static struct omap_device_pad notle_uart1_pads[] __initdata = { |
| { |
| // fails on first with repeat |
| //.name = "mcspi1_cs2.uart1_cts", |
| .name = ".uart1_cts", |
| .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, |
| }, |
| { |
| .name = "uart1_rts.uart1_rts", |
| .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, |
| }, |
| { |
| .name = "uart1_tx.uart1_tx", |
| .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, |
| }, |
| { |
| .name = "uart1_rx.uart1_rx", |
| .flags = OMAP_DEVICE_PAD_REMUX, |
| .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, |
| .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, |
| }, |
| }; |
| |
| /* ttyO1 bluetooth */ |
| static struct omap_device_pad notle_uart2_pads[] __initdata = { |
| { |
| .name = "uart2_cts.uart2_cts", |
| .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, |
| }, |
| { |
| .name = "uart2_rts.uart2_rts", |
| .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, |
| }, |
| { |
| .name = "uart2_tx.uart2_tx", |
| .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, |
| }, |
| { |
| .name = "uart2_rx.uart2_rx", |
| .flags = OMAP_DEVICE_PAD_REMUX, |
| .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, |
| .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, |
| }, |
| }; |
| |
| /* ttyO2 console port */ |
| static struct omap_device_pad notle_uart3_pads[] __initdata = { |
| { |
| .name = "uart3_cts_rctx.uart3_cts_rctx", |
| .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, |
| }, |
| { |
| .name = "uart3_rts_sd.uart3_rts_sd", |
| .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, |
| }, |
| { |
| .name = "uart3_tx_irtx.uart3_tx_irtx", |
| .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, |
| }, |
| { |
| .name = "uart3_rx_irrx.uart3_rx_irrx", |
| .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, |
| .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0, |
| .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0, |
| }, |
| }; |
| |
| /* ttyO3 GPS */ |
| static struct omap_device_pad notle_uart4_pads[] __initdata = { |
| { |
| .name = "uart4_tx.uart4_tx", |
| .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, |
| }, |
| { |
| .name = "uart4_rx.uart4_rx", |
| .flags = OMAP_DEVICE_PAD_REMUX, |
| .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0, |
| .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0, |
| }, |
| }; |
| |
| static struct omap_uart_port_info omap_serial_port_info[] __initdata = { |
| { /* ttyO0 unused */ |
| .use_dma = 0, |
| .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE, |
| .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE, |
| .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT, |
| .auto_sus_timeout = DEFAULT_AUTOSUSPEND_DELAY, |
| .wer = 0, |
| }, |
| { /* ttyO1 bluetooth */ |
| .use_dma = 0, |
| .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE, |
| .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE, |
| .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT, |
| .auto_sus_timeout = DEFAULT_AUTOSUSPEND_DELAY, |
| .wake_peer = bcm_bt_lpm_exit_lpm_locked, |
| .rts_mux_driver_control = 1, |
| .wer = (OMAP_UART_WER_TX | OMAP_UART_WER_RX | OMAP_UART_WER_CTS), |
| }, |
| { /* ttyO2 console port */ |
| .use_dma = 0, |
| .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE, |
| .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE, |
| .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT, |
| .auto_sus_timeout = DEFAULT_AUTOSUSPEND_DELAY, |
| .wer = (OMAP_UART_WER_TX | OMAP_UART_WER_RX | OMAP_UART_WER_CTS), |
| }, |
| { /* ttyO3 GPS */ |
| .use_dma = 0, |
| .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE, |
| .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE, |
| .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT, |
| .auto_sus_timeout = DEFAULT_AUTOSUSPEND_DELAY, |
| .wer = (OMAP_UART_WER_TX | OMAP_UART_WER_RX | OMAP_UART_WER_CTS), |
| }, |
| }; |
| |
| void __init notle_serial_init(void) |
| { |
| omap_serial_init_port_pads(0, notle_uart1_pads, |
| ARRAY_SIZE(notle_uart1_pads), &omap_serial_port_info[0]); |
| omap_serial_init_port_pads(1, notle_uart2_pads, |
| ARRAY_SIZE(notle_uart2_pads), &omap_serial_port_info[1]); |
| omap_serial_init_port_pads(3, notle_uart4_pads, |
| ARRAY_SIZE(notle_uart4_pads), &omap_serial_port_info[3]); |
| } |
| |
| /* Initialize FIQ Debugger */ |
| static int __init board_serial_debug_init(void) |
| { |
| /* 3rd UART is now owned by fiq debugger */ |
| return omap_serial_debug_init(2, false, true, |
| notle_uart3_pads, ARRAY_SIZE(notle_uart3_pads)); |
| } |
| device_initcall(board_serial_debug_init); |
| |
| static struct platform_device bcm4330_bluetooth_device = { |
| .name = "bcm4330_bluetooth", |
| .id = -1, |
| }; |
| |
| |
| // Translate hardware buttons to keys -- we have only one. Note that |
| static struct gpio_keys_button notle_button_table[] = { |
| [0] = { |
| .code = KEY_CAMERA, \ |
| .gpio = GPIO_CAMERA, \ |
| .desc = "Camera", \ |
| .type = EV_KEY, \ |
| .wakeup = 1, \ |
| .debounce_interval = 10, \ |
| .active_low = 1, \ |
| }, |
| }; |
| |
| static struct gpio_keys_platform_data gpio_keys_data = { |
| .buttons = notle_button_table, |
| .nbuttons = ARRAY_SIZE(notle_button_table), |
| }; |
| |
| static struct platform_device gpio_keys = { |
| .name = "gpio-keys", |
| .dev = { |
| .platform_data = &gpio_keys_data, |
| }, |
| .id = -1, |
| }; |
| |
| /* These gpios get set dynamically when we determine the platform */ |
| static struct gps_elton_platform_data_s gps_elton_platform_data = { |
| .gpio_reset = -1, |
| .gpio_on_off = -1, |
| .gpio_awake = -1, |
| }; |
| |
| static struct platform_device gps_elton_platform_device = { |
| .name = "gps_elton", |
| .id = -1, |
| .dev = { |
| .platform_data = &gps_elton_platform_data, |
| }, |
| }; |
| |
| static struct platform_device *notle_devices[] __initdata = { |
| &leds_gpio, |
| &gpio_keys, |
| &bcm4330_bluetooth_device, |
| &gps_elton_platform_device, |
| }; |
| |
| static struct platform_device notle_pcb_temp_sensor = { |
| .name = "notle_pcb_sensor", |
| }; |
| |
| static char *notle_charger_supplicants_evt1[] = { |
| "twl6030_battery", |
| }; |
| |
| static char *notle_charger_supplicants_evt2[] = { |
| "bq27520-0", |
| }; |
| |
| static struct twl4030_charger_platform_data notle_charger_data = { |
| .monitor_interval_seconds = 15, |
| .max_charger_current_mA = 1500, |
| .max_charger_voltage_mV = 4560, |
| .max_bat_voltage_mV = 4200, |
| .low_bat_voltage_mV = 3300, |
| /* Fill in supplied_to/num_supplicants based on board revisions */ |
| }; |
| |
| static int notle_batt_table[] = { |
| /* adc code for temperature in degree C */ |
| 929, 925, /* -2 ,-1 */ |
| 920, 917, 912, 908, 904, 899, 895, 890, 885, 880, /* 00 - 09 */ |
| 875, 869, 864, 858, 853, 847, 841, 835, 829, 823, /* 10 - 19 */ |
| 816, 810, 804, 797, 790, 783, 776, 769, 762, 755, /* 20 - 29 */ |
| 748, 740, 732, 725, 718, 710, 703, 695, 687, 679, /* 30 - 39 */ |
| 671, 663, 655, 647, 639, 631, 623, 615, 607, 599, /* 40 - 49 */ |
| 591, 583, 575, 567, 559, 551, 543, 535, 527, 519, /* 50 - 59 */ |
| 511, 504, 496 /* 60 - 62 */ |
| }; |
| |
| static struct twl4030_battery_platform_data notle_battery_data = { |
| .monitoring_interval_seconds = 15, |
| .battery_tmp_tbl = notle_batt_table, |
| .tblsize = ARRAY_SIZE(notle_batt_table), |
| }; |
| |
| |
| static struct twl4030_codec_audio_data twl6040_audio = { |
| .hs_left_step = 0x0f, |
| .hs_right_step = 0x0f, |
| .hf_left_step = 0x1d, |
| .hf_right_step = 0x1d, |
| .ep_step = 0x0f, |
| }; |
| |
| static struct twl4030_codec_vibra_data twl6040_vibra = { |
| }; |
| |
| static struct twl4030_codec_data twl6040_codec = { |
| .audio = &twl6040_audio, |
| .vibra = &twl6040_vibra, |
| .audpwron_gpio = 127, |
| .naudint_irq = OMAP44XX_IRQ_SYS_2N, |
| .irq_base = TWL6040_CODEC_IRQ_BASE, |
| }; |
| |
| static struct twl4030_madc_platform_data notle_gpadc_data = { |
| .irq_line = 1, |
| }; |
| |
| static struct twl4030_platform_data notle_twldata = { |
| .irq_base = TWL6030_IRQ_BASE, |
| .irq_end = TWL6030_IRQ_END, |
| |
| /* Regulators */ |
| .vmmc = ¬le_vmmc, |
| .vpp = ¬le_vpp, |
| .vusim = ¬le_vusim, |
| .vana = ¬le_vana, |
| .vcxio = ¬le_vcxio, |
| .vdac = ¬le_vdac, |
| .vusb = ¬le_vusb, |
| .vaux1 = ¬le_vaux1, |
| .vaux2 = ¬le_vaux2, |
| .vaux3 = ¬le_vaux3, |
| .clk32kg = &omap4_notle_clk32kg, |
| .usb = &omap4_usbphy_data, |
| |
| /* children */ |
| .charger = ¬le_charger_data, |
| .battery = NULL, // fill this in conditionally for EVT1 |
| .codec = &twl6040_codec, |
| .madc = ¬le_gpadc_data, |
| }; |
| |
| #if defined(CONFIG_TOUCHPAD_SYNAPTICS_RMI4_I2C) && defined(CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C) |
| #error "Can only define touchpad (v2) or touchscreen (v1) Synaptics touchpad" |
| #endif |
| |
| #ifdef CONFIG_TOUCHPAD_SYNAPTICS_RMI4_I2C |
| |
| static union rmi_f11_2d_ctrl0 f11_ctrl0 = { |
| { |
| /* ReportingMode = ‘000’: Continuous, when finger present. |
| * ReportingMode = ‘001’: Reduced reporting mode. |
| * ReportingMode = ‘010’: Finger-state change reporting mode. |
| * ReportingMode = ‘011’: Finger-presence change reporting mode. */ |
| .reporting_mode = 1, |
| /* Enable filtering of the reported absolute positioning. */ |
| .abs_pos_filt = 0, |
| /* Enable filtering of the reported relative positioning. */ |
| .rel_pos_filt = 0, |
| /* Enable ballistics processing for relative finger motion. */ |
| .rel_ballistics = 0, |
| .dribble = 0, |
| .report_beyond_clip = 0, |
| }, |
| }; |
| |
| static union rmi_f11_2d_ctrl1 f11_ctrl1 = { |
| { |
| /* Specifies threshold at which a finger is considered a palm. |
| * Zero disables. */ |
| .palm_detect_thres = 0, |
| /* Motion sensitivity. |
| * '00': Low |
| * '01': Medium |
| * '10': High |
| * '11': Infinite */ |
| .motion_sensitivity = 0, |
| /* '0': Firmware determines tracked finger. |
| * '1': Host determines tracked finger. */ |
| .man_track_en = 0, |
| /* Which finger being tracked. |
| * '0': Track finger 0 |
| * '1': Track finger 1 */ |
| .man_tracked_finger = 0, |
| }, |
| }; |
| |
| static union rmi_f11_2d_ctrl2__3 f11_ctrl2__3 = { |
| { |
| .delta_x_threshold = 1, |
| .delta_y_threshold = 1, |
| }, |
| }; |
| |
| static union rmi_f11_2d_ctrl4 f11_ctrl4 = { |
| { |
| /* Define velocity ballistic parameter to all relative |
| * motion events. Zero disables. */ |
| .velocity = 0, |
| }, |
| }; |
| |
| static union rmi_f11_2d_ctrl5 f11_ctrl5 = { |
| { |
| /* Define acceleration ballistic parameter to all relative |
| * motion events. Zero disables. */ |
| .acceleration = 0, |
| }, |
| }; |
| |
| static union rmi_f11_2d_ctrl6__7 f11_ctrl6__7 = { |
| { |
| /* Maximum sensor X position. */ |
| .sensor_max_x_pos = 0x0490, |
| }, |
| }; |
| |
| static union rmi_f11_2d_ctrl8__9 f11_ctrl8__9 = { |
| { |
| /* Maximum sensor Y position. */ |
| .sensor_max_y_pos = 0x00b8, |
| }, |
| }; |
| |
| static union rmi_f11_2d_ctrl10 f11_ctrl10 = { |
| { |
| /* These bits enable the feature iff the corresponding bit |
| * is set in the query register. */ |
| .single_tap_int_enable = 1, |
| .tap_n_hold_int_enable = 1, |
| .double_tap_int_enable = 1, |
| .early_tap_int_enable = 1, |
| .flick_int_enable = 1, |
| .press_int_enable = 1, |
| .pinch_int_enable = 1, |
| }, |
| }; |
| |
| static union rmi_f11_2d_ctrl11 f11_ctrl11 = { |
| { |
| /* These bits enable the feature iff the corresponding bit |
| * is set in the query register. */ |
| .palm_detect_int_enable = 1, |
| .rotate_int_enable = 1, |
| .touch_shape_int_enable = 1, |
| .scroll_zone_int_enable = 1, |
| .multi_finger_scroll_int_enable = 1, |
| }, |
| }; |
| |
| /* All the bits of this data structures must have accurate default |
| * control data because of the way the rmi driver writes the control |
| * registers to the device. */ |
| static struct rmi_f11_2d_ctrl f11_ctrl = { |
| .ctrl0 = &f11_ctrl0, |
| .ctrl1 = &f11_ctrl1, |
| .ctrl2__3 = &f11_ctrl2__3, |
| .ctrl4 = &f11_ctrl4, |
| .ctrl5 = &f11_ctrl5, |
| .ctrl6__7 = &f11_ctrl6__7, |
| .ctrl8__9 = &f11_ctrl8__9, |
| .ctrl10 = &f11_ctrl10, |
| .ctrl11 = &f11_ctrl11, |
| }; |
| |
| #endif /* CONFIG_TOUCHPAD_SYNAPTICS_RMI4_I2C */ |
| |
| #ifdef CONFIG_TOUCHPAD_SYNAPTICS_RMI4_I2C |
| static struct rmi_device_platform_data synaptics_platformdata = { |
| .driver_name = "rmi-generic", |
| |
| .irq_polarity = RMI_IRQ_ACTIVE_LOW, |
| .gpio_config = NULL, |
| |
| /* function handler pdata */ |
| .f11_ctrl = &f11_ctrl, |
| .axis_align = { |
| .swap_axes = false, |
| .flip_x = false, |
| .flip_y = true, |
| .clip_X_low = 0, |
| .clip_Y_low = 0, |
| .clip_X_high = 0, |
| .clip_Y_high = 0, |
| .offset_X = 0, |
| .offset_Y = 0, |
| .rel_report_enabled = 0, |
| }, |
| .button_map = NULL, |
| #ifdef CONFIG_PM |
| .pm_data = NULL, |
| .pre_suspend = NULL, |
| .post_resume = NULL, |
| #endif |
| }; |
| #ifndef RMI_F11_INDEX |
| #define RMI_F11_INDEX 0x11 |
| #endif // RMI_F11_INDEX |
| #endif /* CONFIG_TOUCHPAD_SYNAPTICS_RMI4_I2C */ |
| |
| #ifdef CONFIG_RMI4_BUS |
| struct notle_gpio_data_s { |
| int gpio_num; |
| const char *name; |
| }; |
| |
| // Need to dynamically set gpio_num based on board type |
| static struct notle_gpio_data_s notle_touchpad_gpio_data = { |
| .name = "touchpad", |
| }; |
| |
| static int synaptics_touchpad_gpio_setup(void *gpio_data, bool configure) |
| { |
| int retval = 0; |
| struct notle_gpio_data_s *data = gpio_data; |
| |
| if (configure) { |
| /* Enable the interrupt */ |
| enable_irq(gpio_to_irq(data->gpio_num)); |
| printk(KERN_INFO "%s Callback to setup touchpad gpio %d %s\n", |
| __func__, data->gpio_num, data->name); |
| } else { |
| pr_warn("%s: No way to deconfigure gpio %d.", |
| __func__, data->gpio_num); |
| } |
| return retval; |
| } |
| |
| static struct rmi_f11_sensor_data rmi_device_platform_data_f11 = { |
| .axis_align = { |
| .swap_axes = false, |
| .flip_x = false, |
| .flip_y = true, |
| |
| .clip_X_low = 0, |
| .clip_Y_low = 0, |
| .clip_X_high = 0, |
| .clip_Y_high = 0, |
| |
| .offset_X = 0, |
| .offset_Y = 0, |
| .rel_report_enabled = 0, |
| .delta_x_threshold = 2, |
| .delta_y_threshold = 2, |
| }, |
| |
| .virtual_buttons = { |
| .buttons = 0, |
| .map = NULL, |
| }, |
| /* We are using touchpad type A protocol. */ |
| .type_a = 1, |
| }; |
| |
| static struct rmi_device_platform_data synaptics_platformdata = { |
| .driver_name = "rmi", |
| .sensor_name = "tm2240", |
| |
| .attn_polarity = RMI_ATTN_ACTIVE_LOW, |
| .level_triggered = true, |
| .gpio_data = ¬le_touchpad_gpio_data, |
| .gpio_config = synaptics_touchpad_gpio_setup, |
| |
| .reset_delay_ms = 100, |
| |
| .f11_sensor_data = &rmi_device_platform_data_f11, |
| .f11_sensor_count = 1, |
| |
| /* function handler pdata */ |
| .power_management = { |
| .nosleep = RMI_F01_NOSLEEP_OFF, |
| .wakeup_threshold = 0, |
| .doze_holdoff = 0, |
| .doze_interval = 0, |
| }, |
| |
| #ifdef CONFIG_RMI4_FWLIB |
| .firmware_name = "firmware_name", |
| #endif |
| #ifdef CONFIG_PM |
| .pm_data = NULL, |
| .pre_suspend = NULL, |
| .post_suspend = NULL, |
| .pre_resume = NULL, |
| .post_resume = NULL, |
| #endif |
| }; |
| |
| #endif /* CONFIG_RMI4_BUS */ |
| |
| |
| #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C |
| static struct rmi_sensor_suspend_custom_ops synaptics_custom_ops = { |
| .rmi_sensor_custom_suspend = 0, |
| .rmi_sensor_custom_resume = 0, |
| .delay_resume = 0, |
| }; |
| |
| static struct rmi_f11_functiondata synaptics_f11_data = { |
| /* flip_X, flip_Y, and swap_axes will be set based on NOTLE_VERSION */ |
| }; |
| |
| static struct rmi_functiondata synaptics_fndata = { |
| .function_index = RMI_F11_INDEX, |
| .data = &synaptics_f11_data, |
| }; |
| |
| static struct rmi_functiondata_list synaptics_fndatalist = { |
| .count = 1, |
| .functiondata = &synaptics_fndata, |
| }; |
| |
| // attn_gpio_number assignment is board specific |
| static struct rmi_sensordata __initdata synaptics_sensordata = { |
| .rmi_sensor_setup = 0, |
| .rmi_sensor_teardown = 0, |
| .attn_polarity = 0, |
| .custom_suspend_ops = &synaptics_custom_ops, |
| .perfunctiondata = &synaptics_fndatalist, |
| }; |
| |
| static struct rmi_i2c_platformdata __initdata synaptics_platformdata = { |
| // same address here as in I2C_BOARD_INFO |
| .i2c_address = 0x20, |
| // .irq = 0x00, |
| .sensordata = &synaptics_sensordata, |
| }; |
| #endif |
| |
| static struct usb_mux_platform_data usb_mux_platformdata = { |
| // .gpio_cb0 configured in omap_usb_mux_init |
| .gpio_cb0_flags = GPIOF_OUT_INIT_LOW, |
| .gpio_cb0_label = "gpio_usb_mux_cb0", |
| |
| // .gpio_cb1 configured in omap_usb_mux_init |
| .gpio_cb1_flags = GPIOF_OUT_INIT_HIGH, |
| .gpio_cb1_label = "gpio_usb_mux_cb1", |
| }; |
| |
| static struct platform_device notle_usb_mux = { |
| .name = "usb_mux", |
| .dev = { |
| .platform_data = &usb_mux_platformdata, |
| }, |
| }; |
| |
| /* |
| * Translate temperatures to compensate for thermistor circuit problem (EVT2). |
| * Precision is limited but should provide accurate values. |
| */ |
| static int notle_translate_temp(int temperature) |
| { |
| if (temperature <= 980) |
| /* |
| * This indicates that the thermistor is disconnected on EVT2. Return the same |
| * value as would be measured on EVT3 in case of missing thermistor so that the |
| * gas gauge driver can recognize the disconnected state. |
| */ |
| temperature = -408; |
| else if (temperature <= 986) |
| temperature = 0; |
| else if (temperature <= 989) |
| temperature = 50; |
| else if (temperature <= 993) |
| temperature = 100; |
| else if (temperature <= 998) |
| temperature = 150; |
| else if (temperature <= 1003) |
| temperature = 200; |
| else if (temperature <= 1009) |
| temperature = 250; |
| else if (temperature <= 1016) |
| temperature = 300; |
| else if (temperature <= 1024) |
| temperature = 350; |
| else if (temperature <= 1044) |
| temperature = 400; |
| else if (temperature <= 1055) |
| temperature = 450; |
| else if (temperature <= 1067) |
| temperature = 500; |
| else if (temperature <= 1080) |
| temperature = 550; |
| else if (temperature <= 1095) |
| temperature = 600; |
| else if (temperature <= 1116) |
| temperature = 650; |
| else |
| temperature = 700; |
| |
| return temperature; |
| } |
| |
| /* Gas gauge board specific configuration filled in at board init */ |
| static struct bq27x00_platform_data notle_gasgauge_platform_data; |
| |
| static struct i2c_board_info __initdata notle_i2c_1_boardinfo[] = { |
| #ifdef CONFIG_BATTERY_BQ27x00 |
| { |
| I2C_BOARD_INFO("bq27520", 0x55), |
| .platform_data = ¬le_gasgauge_platform_data, |
| }, |
| #endif |
| }; |
| |
| static struct i2c_board_info __initdata notle_i2c_3_boardinfo[] = { |
| #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C |
| { |
| I2C_BOARD_INFO("rmi4_ts", 0x20), |
| .platform_data = &synaptics_platformdata, |
| }, |
| #endif |
| #if defined(CONFIG_TOUCHPAD_SYNAPTICS_RMI4_I2C) || defined(CONFIG_RMI4_BUS) |
| { |
| I2C_BOARD_INFO("rmi_i2c", 0x20), |
| .platform_data = &synaptics_platformdata, |
| }, |
| #endif /* CONFIG_TOUCHPAD_SYNAPTICS_RMI4_I2C || CONFIG_RMI4_BUS */ |
| }; |
| |
| /* |
| * i2c-4 |
| */ |
| /* MPU */ |
| static struct mpu_platform_data mpu9150_notle_data = { |
| .int_config = 0x10, |
| .orientation = { 0, 1, 0, |
| 0, 0, 1, |
| 1, 0, 0 }, |
| .level_shifter = 1, |
| .sec_slave_type = SECONDARY_SLAVE_TYPE_COMPASS, |
| .sec_slave_id = COMPASS_ID_AK8975, |
| .secondary_i2c_addr = 0x0C, |
| .key = {221, 22, 205, 7, 217, 186, 151, 55, |
| 206, 254, 35, 144, 225, 102, 47, 50}, |
| .secondary_orientation = { 1, 0, 0, |
| 0, 0, -1, |
| 0, 1, 0 }, |
| }; |
| |
| // gpio_int_no is board specific |
| #ifdef CONFIG_INPUT_LTR506ALS |
| static struct ltr506_platform_data notle_ltr506als_data = { |
| /* Boolean to allow interrupt to wake device or not */ |
| .pfd_gpio_int_wake_dev = 0, |
| |
| /* Disable als on suspend flag */ |
| .pfd_disable_als_on_suspend = 0, |
| |
| /* ALS enable filtering interrupts |
| * by suppressing interrupts when measured value |
| * falls within some driver calculated threshold. This |
| * can be manually set by setting a '0' here and writing |
| * to the sysfs threshold file. |
| * e.g. |
| * echo "1000 1020" > /sys/class/input/input7/als_threshold |
| */ |
| .pfd_als_filter_interrupts = 0, |
| |
| /* ALS measurement repeat rate |
| * '000: 100ms |
| * '001: 200ms |
| * '010: 500ms |
| * '011: 1000ms |
| * '1xx: 2000ms */ |
| .pfd_als_meas_rate = 3, |
| |
| /* ALS gain. |
| * '00: 1 lux/count (1-64k lux) |
| * '01: 0.5 lux/count (0.5-32k lux) |
| * '10: 0.01 lux/count (0.02-640 lux) |
| * '11: 0.005 lux/count (0.01-32.0 lux) */ |
| .pfd_als_gain = 2, |
| |
| /* Disable ps on suspend flag */ |
| .pfd_disable_ps_on_suspend = 0, |
| |
| /* PS enable filtering interrupts |
| * by suppressing interrupts when measured value |
| * falls within some driver calculated threshold. This |
| * can be manually set by setting a '0' here and writing |
| * to the sysfs threshold file. |
| * e.g. |
| * echo "1000 1020" > /sys/class/input/input7/als_threshold |
| */ |
| .pfd_ps_filter_interrupts = 0, |
| |
| /* PS measurement repeate rate |
| * '000: 12.5ms (ALS auto-disabled) |
| * '001: 50ms |
| * '010: 70ms |
| * '011: 100ms |
| * '100: 200ms |
| * '101: 500ms |
| * '110: 1000ms |
| * '111: 2000ms */ |
| .pfd_ps_meas_rate = 1, |
| |
| /* PS gain. NOTE(CMM) This is must write to '3' |
| * '00: x8 gain |
| * '01: x16 gain |
| * '10: x32 gain |
| * '11: x64 gain ## */ |
| .pfd_ps_gain = 3, |
| |
| /* LED pulse frequency. |
| * '000: 30kHz |
| * '001: 40kHz |
| * '010: 50kHz |
| * '011: 60kHz |
| * '100: 70kHz |
| * '101: 80kHz |
| * '110: 90kHz |
| * '111: 100kHz */ |
| .pfd_led_pulse_freq = 3, |
| |
| /* LED Duty cycle. NOTE(CMM) This is must write to '1' |
| * '00: 25% |
| * '01: 50% ## |
| * '10: 75% |
| * '11: 100% */ |
| .pfd_led_duty_cyc = 1, |
| |
| /* LED peak current. |
| * '000: 5mA |
| * '001: 10mA |
| * '010: 20mA |
| * '011: 50mA |
| * '1xx: 100mA */ |
| .pfd_led_peak_curr = 0, |
| |
| /* LED Pulse count. Number of LED pulses to be |
| * emitted for a measurement. */ |
| .pfd_led_pulse_count = 127, |
| }; |
| #endif |
| |
| #ifdef CONFIG_INPUT_GLASSHUB |
| static struct glasshub_platform_data notle_glasshub_data; |
| #endif /* CONFIG_INPUT_GLASSHUB */ |
| |
| static struct i2c_board_info __initdata notle_i2c_4_boardinfo[] = { |
| { |
| I2C_BOARD_INFO("panel-notle-panel", 0x49), |
| }, |
| { |
| I2C_BOARD_INFO("mpu9150", 0x68), |
| .platform_data = &mpu9150_notle_data, |
| }, |
| #ifdef CONFIG_INPUT_LTR506ALS |
| { |
| I2C_BOARD_INFO("ltr506als", 0x3a), |
| .flags = I2C_CLIENT_WAKE, |
| .platform_data = ¬le_ltr506als_data, |
| }, |
| #endif |
| |
| /* dls: slave address of 0x35 is chosen not to conflict and |
| * easy to see on i2c bus. Can be changed by modifying the |
| * code in the Glass hub MCU. |
| */ |
| #ifdef CONFIG_INPUT_GLASSHUB |
| { |
| I2C_BOARD_INFO("glasshub", 0x35), |
| .platform_data = ¬le_glasshub_data, |
| }, |
| #endif |
| }; |
| |
| static void __init notle_pmic_mux_init(void) |
| { |
| |
| omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | |
| OMAP_WAKEUP_EN); |
| } |
| |
| static void __init omap_i2c_hwspinlock_init(int bus_id, int spinlock_id, |
| struct omap_i2c_bus_board_data *pdata) |
| { |
| /* spinlock_id should be -1 for a generic lock request */ |
| if (spinlock_id < 0) |
| pdata->handle = hwspin_lock_request(); |
| else |
| pdata->handle = hwspin_lock_request_specific(spinlock_id); |
| |
| if (pdata->handle != NULL) { |
| pdata->hwspin_lock_timeout = hwspin_lock_timeout; |
| pdata->hwspin_unlock = hwspin_unlock; |
| } else { |
| pr_err("I2C hwspinlock request failed for bus %d\n", \ |
| bus_id); |
| } |
| } |
| |
| static struct omap_i2c_bus_board_data __initdata notle_i2c_1_bus_pdata; |
| static struct omap_i2c_bus_board_data __initdata notle_i2c_2_bus_pdata; |
| static struct omap_i2c_bus_board_data __initdata notle_i2c_3_bus_pdata; |
| static struct omap_i2c_bus_board_data __initdata notle_i2c_4_bus_pdata; |
| |
| static void __init notle_i2c_irq_fixup(void) |
| { |
| int i; |
| int gpio_mpu, gpio_prox, gpio_touchpad, gpio_blink; |
| struct i2c_board_info *pinfo; |
| |
| gpio_prox = notle_get_gpio(GPIO_PROX_INT_INDEX); |
| gpio_mpu = notle_get_gpio(GPIO_MPU9000_INT_INDEX); |
| gpio_touchpad = notle_get_gpio(GPIO_TOUCHPAD_INT_N_INDEX); |
| gpio_blink = notle_get_gpio(GPIO_BLINK_INT_INDEX); |
| |
| // XXX TODO(jscarr) REMOVE this when pre EVT2 units are destroyed |
| // first batch of evt2 had prox_int on blink_int |
| if ( notle_version_after(V1_EVT1) ) { |
| pr_err("Forcing prox_int to %d instead of %d\n", gpio_blink, gpio_prox); |
| gpio_prox = gpio_blink; |
| } |
| |
| // Fix up the global device data structures |
| #ifdef CONFIG_TOUCHPAD_SYNAPTICS_RMI4_I2C |
| synaptics_platformdata.irq = gpio_touchpad; |
| #endif |
| |
| #ifdef CONFIG_RMI4_BUS |
| synaptics_platformdata.attn_gpio = gpio_touchpad; |
| #endif |
| |
| #ifdef CONFIG_INPUT_LTR506ALS |
| notle_ltr506als_data.pfd_gpio_int_no = gpio_prox; |
| #endif |
| |
| #ifdef CONFIG_INPUT_GLASSHUB |
| notle_glasshub_data.gpio_int_no = gpio_blink; |
| #endif |
| |
| #ifdef CONFIG_RMI4_BUS |
| notle_touchpad_gpio_data.gpio_num = gpio_touchpad; |
| #endif |
| |
| // Now fixup the irqs set in the various 2c boardinfo structs |
| pinfo = notle_i2c_4_boardinfo; |
| for (i = 0; i < ARRAY_SIZE(notle_i2c_4_boardinfo); i++) { |
| if (!strcmp("mpu9150", pinfo->type) || !strcmp("ak8975", pinfo->type)) { |
| pinfo->irq = OMAP_GPIO_IRQ(gpio_mpu); |
| } |
| if (!strcmp("ltr506als", pinfo->type)) { |
| pinfo->irq = OMAP_GPIO_IRQ(gpio_prox); |
| } |
| if (!strcmp("glasshub", pinfo->type)) { |
| pinfo->irq = OMAP_GPIO_IRQ(gpio_blink); |
| } |
| pinfo++; |
| } |
| } |
| |
| static int __init notle_i2c_init(void) |
| { |
| omap_i2c_hwspinlock_init(1, 0, ¬le_i2c_1_bus_pdata); |
| omap_i2c_hwspinlock_init(2, 1, ¬le_i2c_2_bus_pdata); |
| omap_i2c_hwspinlock_init(3, 2, ¬le_i2c_3_bus_pdata); |
| omap_i2c_hwspinlock_init(4, 3, ¬le_i2c_4_bus_pdata); |
| |
| omap_register_i2c_bus_board_data(1, ¬le_i2c_1_bus_pdata); |
| omap_register_i2c_bus_board_data(2, ¬le_i2c_2_bus_pdata); |
| omap_register_i2c_bus_board_data(3, ¬le_i2c_3_bus_pdata); |
| omap_register_i2c_bus_board_data(4, ¬le_i2c_4_bus_pdata); |
| |
| /* setup the charger/battery platform data based on board revision */ |
| switch (NOTLE_VERSION) { |
| case V1_EVT1: |
| notle_charger_data.supplied_to = notle_charger_supplicants_evt1; |
| notle_charger_data.num_supplicants = |
| ARRAY_SIZE(notle_charger_supplicants_evt1); |
| |
| /* EVT1 uses the PMIC gas gauge to poorly monitory the state of charge */ |
| notle_twldata.battery = ¬le_battery_data; |
| break; |
| |
| case V1_EVT2: |
| notle_gasgauge_platform_data.translate_temp = notle_translate_temp; |
| |
| notle_charger_data.supplied_to = notle_charger_supplicants_evt2; |
| notle_charger_data.num_supplicants = |
| ARRAY_SIZE(notle_charger_supplicants_evt2); |
| |
| /* gas gauge is on i2c1, which is registered in the pmic init */ |
| i2c_register_board_info(1, notle_i2c_1_boardinfo, |
| ARRAY_SIZE(notle_i2c_1_boardinfo)); |
| break; |
| |
| case V1_EVT3: |
| case V1_DVT1: |
| default: |
| notle_gasgauge_platform_data.translate_temp = NULL; |
| |
| notle_charger_data.supplied_to = notle_charger_supplicants_evt2; |
| notle_charger_data.num_supplicants = |
| ARRAY_SIZE(notle_charger_supplicants_evt2); |
| |
| /* gas gauge is on i2c1, which is registered in the pmic init */ |
| i2c_register_board_info(1, notle_i2c_1_boardinfo, |
| ARRAY_SIZE(notle_i2c_1_boardinfo)); |
| break; |
| |
| } |
| |
| if (!notle_version_supported()) { |
| pr_err("Unrecognized Notle version: %i\n", NOTLE_VERSION); |
| return -1; |
| } |
| |
| #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C |
| synaptics_f11_data.flip_X = false; |
| synaptics_f11_data.flip_Y = true; |
| synaptics_f11_data.swap_axes = false; |
| synaptics_sensordata.attn_gpio_number = notle_get_gpio(GPIO_TOUCHPAD_INT_N_INDEX); |
| #endif /* CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C */ |
| omap4_pmic_init("twl6030", ¬le_twldata); |
| notle_i2c_irq_fixup(); |
| omap_register_i2c_bus(2, 400, NULL, 0); |
| omap_register_i2c_bus(3, 400, notle_i2c_3_boardinfo, |
| ARRAY_SIZE(notle_i2c_3_boardinfo)); |
| omap_register_i2c_bus(4, 400, notle_i2c_4_boardinfo, |
| ARRAY_SIZE(notle_i2c_4_boardinfo)); |
| return 0; |
| } |
| |
| #ifdef CONFIG_OMAP_MUX |
| // Board specific MUX settings |
| // EVT1 Core: |
| static struct omap_board_mux evt1_board_mux[] __initdata = { |
| OMAP4_MUX(GPMC_AD12, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // BCM_BT_WAKE |
| OMAP4_MUX(GPMC_A19, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // WL_RST_N |
| OMAP4_MUX(GPMC_A20, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // USB_MUX_CB0 |
| OMAP4_MUX(GPMC_A21, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // USB_MUX_CB1 |
| OMAP4_MUX(GPMC_A24, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // WL_BT_REG_ON |
| OMAP4_MUX(GPMC_A25, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // GPS_ON_OFF |
| OMAP4_MUX(GPMC_NCS2, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // GPS_RESET_N |
| OMAP4_MUX(GPMC_NCS3, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // LCD_RST_N |
| OMAP4_MUX(USBB1_ULPITLL_CLK, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // DISP_ENB |
| OMAP4_MUX(USBB2_HSIC_STROBE, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // BCM_WLAN_WAKE |
| OMAP4_MUX(MCSPI4_CLK, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // BT_RST_N |
| OMAP4_MUX(MCSPI4_CS0, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), // BCM_BT_HOST_WAKE |
| OMAP4_MUX(USBB1_ULPITLL_DAT3, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // CAM_PWDN |
| OMAP4_MUX(USBB1_ULPITLL_DAT5, OMAP_MUX_MODE7 | OMAP_PULL_ENA), // BACKLIGHT XXX Remove? NC on EVT1 |
| OMAP4_MUX(ABE_DMIC_DIN2, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP | OMAP_WAKEUP_EN), // CAMERA, TOP_SW |
| OMAP4_MUX(GPMC_AD8, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP | OMAP_WAKEUP_EN), // TOUCHPAD_INT_N |
| OMAP4_MUX(USBB1_ULPITLL_DAT2, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP), // PROX_INT |
| OMAP4_MUX(USBB1_ULPITLL_DAT7, OMAP_MUX_MODE3 | OMAP_PIN_INPUT | OMAP_WAKEUP_EN), // MPU9000_INT |
| OMAP4_MUX(USBB1_ULPITLL_DAT4, OMAP_MUX_MODE3 | OMAP_PIN_INPUT | OMAP_WAKEUP_EN), // MPU9000_INT_TIMER |
| OMAP4_MUX(USBB1_ULPITLL_STP, OMAP_MUX_MODE7 ), // FPGA_CDONE |
| OMAP4_MUX(USBB1_ULPITLL_DIR, OMAP_MUX_MODE7 ), // FPGA_CRESET_B |
| { .reg_offset = OMAP_MUX_TERMINATOR }, |
| }; |
| // EVT1 WakeUp: |
| static struct omap_board_mux evt1_board_wkup_mux[] __initdata = { |
| OMAP4_MUX(SIM_IO, OMAP_MUX_MODE3 | OMAP_PIN_INPUT | OMAP_WAKEUP_EN), // BCM_WLAN_HOST_WAKE |
| OMAP4_MUX(FREF_CLK4_REQ, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // GREEN_LED |
| OMAP4_MUX(FREF_CLK4_OUT, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // YELLOW_LED |
| OMAP4_MUX(SIM_CLK, OMAP_MUX_MODE7 ), // FPGA_CBSEL0 |
| OMAP4_MUX(SIM_CD, OMAP_MUX_MODE7 ), // FPGA_CBSEL1 |
| { .reg_offset = OMAP_MUX_TERMINATOR }, |
| }; |
| |
| // EVT2 Core: |
| static struct omap_board_mux evt2_board_mux[] __initdata = { |
| OMAP4_MUX(GPMC_AD12, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // BCM_BT_WAKE |
| OMAP4_MUX(GPMC_A19, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // WL_RST_N |
| OMAP4_MUX(GPMC_A22, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // USB_MUX_CB0 |
| OMAP4_MUX(GPMC_A21, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // USB_MUX_CB1 |
| OMAP4_MUX(GPMC_A24, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // WL_BT_REG_ON |
| OMAP4_MUX(MCSPI1_CS1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), // GPS_AWAKE |
| OMAP4_MUX(MCSPI1_CS2, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // GPS_ON_OFF |
| OMAP4_MUX(MCSPI1_CS3, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // GPS_RESET_N |
| OMAP4_MUX(USBB1_ULPITLL_DAT6, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // LCD_RST_N |
| OMAP4_MUX(USBB2_HSIC_STROBE, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // BCM_WLAN_WAKE |
| OMAP4_MUX(ABE_MCBSP2_FSX, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // BT_RST_N |
| OMAP4_MUX(SDMMC1_CLK, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // CAM_PWDN |
| OMAP4_MUX(C2C_DATA14, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP), // PROX_INT |
| OMAP4_MUX(ABE_DMIC_DIN2, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP | OMAP_WAKEUP_EN), // CAMERA, TOP_SW |
| OMAP4_MUX(DPM_EMU2, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP), // SOC_INT |
| OMAP4_MUX(USBB1_ULPITLL_STP, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), // FPGA_CDONE |
| OMAP4_MUX(USBB1_ULPITLL_NXT, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), // FPGA_CRESET_B |
| OMAP4_MUX(USBB1_ULPITLL_DAT7, OMAP_MUX_MODE7 ), // FPGA_CBSEL1 |
| { .reg_offset = OMAP_MUX_TERMINATOR }, |
| }; |
| // EVT2 WakeUp: |
| static struct omap_board_mux evt2_board_wkup_mux[] __initdata = { |
| OMAP4_MUX(SIM_IO, OMAP_MUX_MODE3 | OMAP_PIN_INPUT | OMAP_WAKEUP_EN), // BCM_WLAN_HOST_WAKE |
| OMAP4_MUX(FREF_CLK3_REQ, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP | OMAP_WAKEUP_EN), // CAMERA, TOP_SW |
| OMAP4_MUX(SIM_CD, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP | OMAP_WAKEUP_EN), // TOUCHPAD_INT_N |
| OMAP4_MUX(SIM_CLK, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP), // BLINK_INT |
| OMAP4_MUX(SIM_PWRCTRL, OMAP_MUX_MODE3 | OMAP_PIN_INPUT | OMAP_WAKEUP_EN), // MPU9000_INT_TIMER |
| OMAP4_MUX(SIM_RESET, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), // BCM_BT_HOST_WAKE |
| OMAP4_MUX(FREF_CLK3_OUT, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), // BAT_LOW |
| OMAP4_MUX(SYS_PWRON_RESET_OUT, OMAP_MUX_MODE7 ), // FPGA_CBSEL0 |
| { .reg_offset = OMAP_MUX_TERMINATOR }, |
| }; |
| #else |
| #define emtpy_board_mux NULL |
| #endif |
| |
| static int omap_audio_init(void) |
| { |
| int audio_power_on_gpio = GPIO_AUDIO_POWERON; |
| twl6040_codec.audpwron_gpio = audio_power_on_gpio; |
| |
| omap_mux_init_signal("sys_nirq2.sys_nirq2", OMAP_PIN_INPUT_PULLUP); |
| return 0; |
| } |
| |
| static int omap_usb_mux_init(void) |
| { |
| int err; |
| |
| usb_mux_platformdata.gpio_cb0 = notle_get_gpio(GPIO_USB_MUX_CB0_INDEX); |
| usb_mux_platformdata.gpio_cb1 = GPIO_USB_MUX_CB1; |
| |
| err = platform_device_register(¬le_usb_mux); |
| if (err) |
| pr_err("notle_usb_mux registration failed: %d\n", err); |
| |
| return err; |
| } |
| |
| static int notle_gps_init(void) { |
| int r; |
| int gpio_gps_reset, gpio_gps_on_off; |
| |
| /* Tell the driver the gpio pins to access the GPS chip */ |
| gps_elton_platform_data.gpio_reset = notle_get_gpio(GPIO_GPS_RESET_N_INDEX); |
| gps_elton_platform_data.gpio_on_off = notle_get_gpio(GPIO_GPS_ON_OFF_INDEX); |
| /* An uninialized index returns -1 indicating non existant gpio */ |
| gps_elton_platform_data.gpio_awake = notle_get_gpio(GPIO_GPS_AWAKE_INDEX); |
| |
| /* Configuration of requested GPIO lines */ |
| gpio_gps_reset = notle_get_gpio(GPIO_GPS_RESET_N_INDEX); |
| gpio_gps_on_off = notle_get_gpio(GPIO_GPS_ON_OFF_INDEX); |
| |
| r = gpio_request_one(gpio_gps_reset, GPIOF_OUT_INIT_HIGH, |
| "gps_reset_n"); |
| if (r) { |
| pr_err("Failed to get gps_reset_n gpio\n"); |
| goto error; |
| } |
| |
| r = gpio_export(gpio_gps_reset, false); |
| if (r) { |
| pr_err("Unable to export gps_reset_n gpio\n"); |
| } |
| |
| r = gpio_sysfs_set_active_low(gpio_gps_reset, 0); |
| if (r) { |
| pr_err("Unable to set sysfs gps_reset_n active low\n"); |
| } |
| |
| /* Need a rising edge to turn device on. */ |
| r = gpio_request_one(gpio_gps_on_off, GPIOF_OUT_INIT_LOW, |
| "gps_on_off"); |
| if (r) { |
| pr_err("Failed to get gps_on_off gpio\n"); |
| goto error; |
| } |
| |
| r = gpio_export(gpio_gps_on_off, false); |
| if (r) { |
| pr_err("Unable to export gps_on_off gpio\n"); |
| } |
| |
| /* EVT2 added the GPS_AWAKE connection, was NC in EVT1 */ |
| if ( notle_version_after(V1_EVT1) ) { |
| r = gpio_request_one(GPIO_GPS_AWAKE_EVT2, GPIOF_IN, "gps_awake"); |
| if (r) { |
| pr_err("Failed to get gps_awake gpio\n"); |
| goto error; |
| } |
| |
| r = gpio_export(GPIO_GPS_AWAKE_EVT2, false); |
| if (r) { |
| pr_err("Unable to export gps_awake gpio\n"); |
| } |
| } |
| return 0; |
| |
| error: |
| return r; |
| } |
| |
| /* XXX Turning on GPS currently costs us ~50mA of current draw. |
| static int __init notle_gps_start(void) { |
| gpio_set_value(GPIO_GPS_ON_OFF, 1); |
| pr_info("Turning on GPS chip\n"); |
| return 0; |
| } |
| late_initcall(notle_gps_start); |
| */ |
| |
| static int __init notle_touchpad_init(void) { |
| int r; |
| int gpio_touchpad_int; |
| |
| pr_info("%s()+\n", __func__); |
| |
| /* Configuration of requested GPIO line */ |
| gpio_touchpad_int = notle_get_gpio(GPIO_TOUCHPAD_INT_N_INDEX); |
| |
| r = gpio_request_one(gpio_touchpad_int, GPIOF_IN, "touchpad_int_n"); |
| if (r) { |
| pr_err("Failed to get touchpad_int_n gpio\n"); |
| } |
| /* Allow this interrupt to wake the system */ |
| r = irq_set_irq_wake(gpio_to_irq(gpio_touchpad_int), 1); |
| if (r) { |
| pr_err("%s Unable to set irq to wake device\n", __FUNCTION__); |
| } |
| return r; |
| } |
| |
| static int __init notle_imu_init(void) { |
| int r; |
| int gpio_mpu9000_int_timer, gpio_mpu9000_int; |
| |
| pr_info("%s()+\n", __func__); |
| gpio_mpu9000_int = notle_get_gpio(GPIO_MPU9000_INT_INDEX); |
| |
| /* Configuration of requested GPIO line */ |
| |
| if (NOTLE_VERSION == V1_EVT1) { |
| gpio_mpu9000_int_timer = notle_get_gpio(GPIO_MPU9000_INT_TIMER_INDEX); |
| r = gpio_request_one(gpio_mpu9000_int_timer, GPIOF_IN, "mpuirq_timer"); |
| if (r) { |
| pr_err("Failed to get mpu9000_int_timer gpio\n"); |
| } else { |
| pr_err("got the mpu9000 timer gpio!!!\n"); |
| } |
| } |
| |
| r = gpio_request(gpio_mpu9000_int, "mpuirq"); |
| if (r) { |
| pr_err("Failed to get mpu9000_int gpio\n"); |
| } |
| r = gpio_direction_input(gpio_mpu9000_int); |
| if (r) { |
| pr_err("Failed to get mpu9000_int gpio\n"); |
| } |
| /* Allow this interrupt to wake the system */ |
| r = irq_set_irq_wake(gpio_to_irq(gpio_mpu9000_int), 1); |
| if (r) { |
| pr_err("%s Unable to set irq to wake device\n", __FUNCTION__); |
| } |
| return r; |
| } |
| |
| #ifdef CONFIG_INPUT_GLASSHUB |
| static int __init notle_glasshub_init(void) { |
| int r; |
| |
| pr_info("%s()+\n", __func__); |
| |
| notle_glasshub_data.irq = gpio_to_irq(notle_glasshub_data.gpio_int_no); |
| |
| /* Configuration of requested GPIO line */ |
| r = gpio_request_one(notle_glasshub_data.gpio_int_no, GPIOF_IN, "glasshub_int"); |
| if (r) { |
| pr_err("Failed to get glasshub gpio\n"); |
| } |
| |
| return r; |
| } |
| #endif |
| |
| /* TODO: This is copied from panda board file. What size should we use? */ |
| #define NOTLE_FB_RAM_SIZE SZ_16M /* 1920x1080*4 * 2 */ |
| static struct omapfb_platform_data notle_fb_pdata = { |
| .mem_desc = { |
| .region_cnt = 1, |
| .region = { |
| [0] = { |
| .size = NOTLE_FB_RAM_SIZE, |
| }, |
| }, |
| }, |
| }; |
| |
| /* |
| * LPDDR2 Configeration Data: |
| * The memory organisation is as below : |
| * EMIF1 - CS0 - 2 Gb |
| * CS1 - 2 Gb |
| * EMIF2 - CS0 - 2 Gb |
| * CS1 - 2 Gb |
| * -------------------- |
| * TOTAL - 8 Gb |
| * |
| * Same devices installed on EMIF1 and EMIF2 |
| */ |
| static __initdata struct emif_device_details emif_devices_evt1 = { |
| .cs0_device = &lpddr2_elpida_2G_S4_dev, |
| .cs1_device = &lpddr2_elpida_2G_S4_dev |
| }; |
| |
| static __initdata struct emif_device_details emif_devices_evt2 = { |
| .cs0_device = &lpddr2_elpida_4G_S4_dev, |
| }; |
| |
| |
| static void __init notle_init(void) |
| { |
| int package = OMAP_PACKAGE_CBS; |
| int err; |
| u32 omap_reg; |
| |
| if (omap_rev() == OMAP4430_REV_ES1_0) |
| package = OMAP_PACKAGE_CBL; |
| notle_version_init(); |
| |
| if (!notle_version_supported()) { |
| omap_emif_setup_device_details(&emif_devices_evt1, &emif_devices_evt1); |
| pr_err("No mux init for Notle version: %s\n", |
| notle_version_str(NOTLE_VERSION)); |
| } |
| |
| if ( notle_version_before(V1_EVT2) ) { |
| omap_emif_setup_device_details(&emif_devices_evt1, &emif_devices_evt1); |
| omap4_mux_init(evt1_board_mux, evt1_board_wkup_mux, package); |
| |
| // Additional mux/pad settings |
| |
| // The GPIOWK_IO_PWRDNZ bit needs to be set after muxing |
| //and before you set it to input |
| omap4_ctrl_wk_pad_writel(OMAP4_USIM_PWRDNZ_MASK, |
| OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_USIMIO); |
| } else { |
| omap_emif_setup_device_details(&emif_devices_evt2, &emif_devices_evt2); |
| omap4_mux_init(evt2_board_mux, evt2_board_wkup_mux, package); |
| |
| // Additional mux/pad settings |
| |
| // The GPIOWK_IO_PWRDNZ bit needs to be set after muxing |
| //and before you set it to input |
| omap4_ctrl_wk_pad_writel(OMAP4_USIM_PWRDNZ_MASK, |
| OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_USIMIO); |
| |
| // Camera power down on gpio_100 needs the correct voltage of 1.8V |
| // wk1 needs correct magic bias settings |
| omap_reg = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PBIASLITE); |
| omap_reg |= OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK | OMAP4_MMC1_PWRDNZ_MASK; |
| omap_reg &= ~OMAP4_MMC1_PBIASLITE_VMODE_MASK; |
| omap_reg |= OMAP4_USIM_PBIASLITE_PWRDNZ_MASK; |
| omap_reg &= ~OMAP4_USIM_PBIASLITE_VMODE_MASK; |
| omap4_ctrl_pad_writel(omap_reg, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PBIASLITE); |
| } |
| notle_pmic_mux_init(); |
| |
| printk("Notle board revision: %s(%d)", notle_version_str(NOTLE_VERSION), NOTLE_VERSION); |
| |
| err = omap_usb_mux_init(); |
| if (err) { |
| pr_err("USB MUX intitialization failed: %d\n", err); |
| } |
| |
| err = omap_audio_init(); |
| if (err) { |
| pr_err("Audio initialization failed: %d\n", err); |
| } |
| |
| #ifndef CONFIG_MMC_NOTLE |
| // Disable support for sd card: |
| mmc[2].mmc = 0; |
| #endif |
| |
| err = notle_imu_init(); |
| if (err) { |
| pr_err("IMU initialization failed: %d\n", err); |
| } |
| notle_i2c_init(); |
| omap4_register_ion(); |
| |
| notle_serial_init(); |
| |
| err = notle_wlan_init(); |
| if (err) { |
| pr_err("Wifi initialization failed: %d\n", err); |
| } |
| |
| omap4_twl6030_hsmmc_init(mmc); |
| usb_musb_init(&musb_board_data); |
| omap_dmm_init(); |
| |
| omapfb_set_platform_data(¬le_fb_pdata); |
| |
| err = notle_gps_init(); |
| if (err) { |
| pr_err("GPS initialization failed: %d\n", err); |
| } |
| |
| // Do this after the wlan_init, which inits the regulator shared |
| // with the bluetooth device and muxes the bt signals. |
| platform_add_devices(notle_devices, ARRAY_SIZE(notle_devices)); |
| |
| err = platform_device_register(¬le_pcb_temp_sensor); |
| if (err) { |
| pr_err("notle_pcb_temp_sensor registration failed: %d\n", err); |
| } |
| |
| err = notle_touchpad_init(); |
| if (err) { |
| pr_err("Touchpad initialization failed: %d\n", err); |
| } |
| |
| #ifdef CONFIG_INPUT_GLASSHUB |
| err = notle_glasshub_init(); |
| if (err) { |
| pr_err("Glass hub initialization failed: %d\n", err); |
| } |
| #endif |
| |
| if ( notle_version_before(V1_EVT2) ) { |
| panel_notle_device.data = &panel_notle_preevt2; |
| } |
| err = notle_dpi_init(); |
| if (!err) { |
| ((struct panel_notle_data *)panel_notle_device.data)->notle_version = NOTLE_VERSION; |
| omap_display_init(&panel_notle_dss_data); |
| } else { |
| pr_err("DPI initialization failed: %d\n", err); |
| } |
| |
| omap_enable_smartreflex_on_init(); |
| omap_pm_enable_off_mode(); |
| } |
| |
| static void __init notle_map_io(void) |
| { |
| omap2_set_globals_443x(); |
| omap44xx_map_common_io(); |
| } |
| |
| static void __init notle_reserve(void) |
| { |
| omap_init_ram_size(); |
| |
| #ifdef CONFIG_ION_OMAP |
| omap_android_display_setup(&panel_notle_dss_data, |
| NULL, |
| NULL, |
| ¬le_fb_pdata, |
| get_omap_ion_platform_data()); |
| omap_ion_init(); |
| #else |
| omap_android_display_setup(&panel_notle_dss_data, |
| NULL, |
| NULL, |
| ¬le_fb_pdata, |
| NULL); |
| #endif |
| |
| omap_ram_console_init(OMAP_RAM_CONSOLE_START_DEFAULT, |
| OMAP_RAM_CONSOLE_SIZE_DEFAULT); |
| |
| /* do the static reservations first */ |
| memblock_remove(PHYS_ADDR_SMC_MEM, PHYS_ADDR_SMC_SIZE); |
| memblock_remove(PHYS_ADDR_DUCATI_MEM, PHYS_ADDR_DUCATI_SIZE); |
| /* ipu needs to recognize secure input buffer area as well */ |
| omap_ipu_set_static_mempool(PHYS_ADDR_DUCATI_MEM, PHYS_ADDR_DUCATI_SIZE + |
| OMAP4_ION_HEAP_SECURE_INPUT_SIZE + |
| OMAP4_ION_HEAP_SECURE_OUTPUT_WFDHDCP_SIZE); |
| |
| omap_reserve(); |
| } |
| |
| MACHINE_START(NOTLE, "OMAP4430") |
| /* Maintainer: David Anders - Texas Instruments Inc */ |
| .boot_params = 0x80000100, |
| .reserve = notle_reserve, |
| .map_io = notle_map_io, |
| .init_early = notle_init_early, |
| .init_irq = gic_init_irq, |
| .init_machine = notle_init, |
| .timer = &omap_timer, |
| MACHINE_END |