diff options
author | Philippe Langlais <philippe.langlais@linaro.org> | 2012-02-15 11:15:20 +0100 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@linaro.org> | 2012-02-15 11:15:20 +0100 |
commit | 3ccc59a697081a8af8a130d05fc4655445ab5b48 (patch) | |
tree | b7af9041482f79bf19a0a6fdef0410b115dc8f60 /arch | |
parent | 7f2f7c67ab6ce79ec76c2def9a322d2badb45df0 (diff) | |
parent | 3e18d1bb698aa4e992e548007c2ca050aeedb2e5 (diff) |
Merge branch 'stable-linux-ux500-3.2' into stable-android-ux500-3.2
Conflicts:
arch/arm/mach-ux500/board-mop500-pins.c
Diffstat (limited to 'arch')
-rwxr-xr-x | arch/arm/configs/u8500_defconfig | 4 | ||||
-rw-r--r-- | arch/arm/mach-ux500/Kconfig | 11 | ||||
-rw-r--r-- | arch/arm/mach-ux500/Makefile | 1 | ||||
-rwxr-xr-x | arch/arm/mach-ux500/board-mop500-cyttsp.c | 56 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-pins.c | 44 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-sensors.c | 33 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-u8500uib.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-uib.c | 102 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500.c | 94 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/sensors1p.h | 24 | ||||
-rw-r--r-- | arch/arm/mach-ux500/pm/context_arm.S | 50 | ||||
-rw-r--r-- | arch/arm/mach-ux500/sensors1p.c | 298 |
12 files changed, 267 insertions, 460 deletions
diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index 491b7b932cc..16fc7d572a4 100755 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -30,6 +30,7 @@ CONFIG_DISPLAY_GENERIC_DSI_PRIMARY_VSYNC=y CONFIG_DISPLAY_SONY_ACX424AKP_DSI_PRIMARY=y CONFIG_DISPLAY_AV8100_TERTIARY=y CONFIG_DISPLAY_AV8100_TRIPPLE_BUFFER=y +CONFIG_UX500_GPIO_KEYS=y CONFIG_UX500_SUSPEND=y CONFIG_UX500_SUSPEND_STANDBY=y CONFIG_UX500_SUSPEND_MEM=y @@ -172,6 +173,7 @@ CONFIG_POWER_SUPPLY=y CONFIG_AB8500_BM=y CONFIG_SENSORS_AB8500=y CONFIG_SENSORS_LSM303DLH=y +CONFIG_SENSORS_LSM303DLHC=y CONFIG_SENSORS_L3G4200D=y CONFIG_WATCHDOG=y CONFIG_U8500_WATCHDOG_DEBUG=y @@ -223,7 +225,7 @@ CONFIG_USB_STORAGE=y CONFIG_USB_LIBUSUAL=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_VBUS_DRAW=500 -CONFIG_USB_GADGET_MUSB_HDRC=m +CONFIG_USB_GADGET_MUSB_HDRC=y CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_FILE_STORAGE=m diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 92a85c202e6..d26d035bedc 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -80,12 +80,11 @@ config UX500_DEBUG_UART Choose the UART on which kernel low-level debug messages should be output. -config SENSORS1P_MOP - tristate "HAL and Proximity sensors support" - depends on REGULATOR && (GPIO_STMPE2401 || GPIO_TC35892) - help - Add support for Osram's SFH7741 Proximity Sensor and Samsumg - HED54XXU11 HAL Switch +config UX500_GPIO_KEYS + bool "Use gpio-keys for proximity and hal sensors" + depends on KEYBOARD_GPIO + help + Add proximity and hal sensors as a gpio keyboard. config U5500_MODEM_IRQ bool "Modem IRQ support" diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 70c483b9dd8..625d22081ce 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile @@ -24,7 +24,6 @@ obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \ board-mop500-u8500uib.o board-mop500-pins.o \ board-mop500-bm.o \ board-pins-sleep-force.o -obj-$(CONFIG_SENSORS1P_MOP) += sensors1p.o obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o \ board-u5500-regulators.o \ board-u5500-pins.o diff --git a/arch/arm/mach-ux500/board-mop500-cyttsp.c b/arch/arm/mach-ux500/board-mop500-cyttsp.c index 2aa27ea9b1f..ca33dfd86ab 100755 --- a/arch/arm/mach-ux500/board-mop500-cyttsp.c +++ b/arch/arm/mach-ux500/board-mop500-cyttsp.c @@ -15,16 +15,60 @@ #include <linux/mfd/tc3589x.h> #include <linux/mfd/dbx500-prcmu.h> #include <linux/amba/pl022.h> +#include <linux/lsm303dlh.h> +#include <linux/l3g4200d.h> #include <plat/pincfg.h> #include <mach/hardware.h> #include <mach/irqs.h> #include <mach/irqs-db8500.h> +#include <asm/mach-types.h> #include "pins-db8500.h" #include "board-mop500.h" #include "devices-db8500.h" #define NUM_SSP_CLIENTS 10 +/* + * LSM303DLH accelerometer + magnetometer & L3G4200D Gyroscope sensors + */ +static struct lsm303dlh_platform_data __initdata lsm303dlh_pdata_u8500_r3 = { + .name_a = "lsm303dlh.0", + .name_m = "lsm303dlh.1", + .axis_map_x = 1, + .axis_map_y = 0, + .axis_map_z = 2, + .negative_x = 0, + .negative_y = 0, + .negative_z = 1, +}; + +static struct l3g4200d_gyr_platform_data __initdata l3g4200d_pdata_u8500_r3 = { + .name_gyr = "l3g4200d", + .axis_map_x = 0, + .axis_map_y = 1, + .axis_map_z = 2, + .negative_x = 1, + .negative_y = 0, + .negative_z = 1, +}; +static struct i2c_board_info __initdata mop500_i2c2_devices_u8500_r3[] = { + { + /* LSM303DLH Accelerometer */ + I2C_BOARD_INFO("lsm303dlhc_a", 0x19), + .platform_data = &lsm303dlh_pdata_u8500_r3, + }, + { + /* LSM303DLH Magnetometer */ + I2C_BOARD_INFO("lsm303dlh_m", 0x1E), + .platform_data = &lsm303dlh_pdata_u8500_r3, + }, + { + /* L3G4200D Gyroscope */ + I2C_BOARD_INFO("l3g4200d", 0x68), + .platform_data = &l3g4200d_pdata_u8500_r3, + }, +}; + /* cyttsp_gpio_board_init : configures the touch panel. */ static int cyttsp_plat_init(int on) { @@ -219,8 +263,20 @@ void __init mop500_u8500uib_r3_init(void) mop500_cyttsp_init(); db8500_add_spi2(&mop500_spi2_data); nmk_config_pin((GPIO64_GPIO | PIN_INPUT_PULLUP), false); + if (machine_is_hrefv60()) { + lsm303dlh_pdata_u8500_r3.irq_a1 = HREFV60_ACCEL_INT1_GPIO; + lsm303dlh_pdata_u8500_r3.irq_a2 = HREFV60_ACCEL_INT2_GPIO; + lsm303dlh_pdata_u8500_r3.irq_m = HREFV60_MAGNET_DRDY_GPIO; + } else { + lsm303dlh_pdata_u8500_r3.irq_a1 = GPIO_ACCEL_INT1; + lsm303dlh_pdata_u8500_r3.irq_a2 = GPIO_ACCEL_INT2; + lsm303dlh_pdata_u8500_r3.irq_m = GPIO_MAGNET_DRDY; + } mop500_uib_i2c_add(0, mop500_i2c0_devices_u8500, ARRAY_SIZE(mop500_i2c0_devices_u8500)); mop500_uib_i2c_add(0, mop500_i2c0_devices_u8500, ARRAY_SIZE(mop500_i2c0_devices_u8500)); + + mop500_uib_i2c_add(2, mop500_i2c2_devices_u8500_r3, + ARRAY_SIZE(mop500_i2c2_devices_u8500_r3)); } diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c index da171115533..96f7b084c73 100644 --- a/arch/arm/mach-ux500/board-mop500-pins.c +++ b/arch/arm/mach-ux500/board-mop500-pins.c @@ -17,7 +17,7 @@ #include "pins-db8500.h" #include "pins.h" - +#include "board-mop500.h" #include "board-pins-sleep-force.h" enum custom_pin_cfg_t { @@ -160,9 +160,6 @@ static pin_cfg_t hrefv60_pins[] = { /* DiPro Sensor Interface */ GPIO139_GPIO | PIN_INPUT_PULLUP, /* DIPRO_INT */ - /* HAL SWITCH INTERFACE */ - GPIO145_GPIO | PIN_INPUT_PULLDOWN,/* HAL_SW */ - /* Audio Amplifier Interface */ GPIO149_GPIO | PIN_OUTPUT_HIGH, /* VAUDIO_HF_EN, enable MAX8968 */ @@ -176,9 +173,6 @@ static pin_cfg_t hrefv60_pins[] = { GPIO82_GPIO | PIN_INPUT_PULLUP, /* ACC_INT1 */ GPIO83_GPIO | PIN_INPUT_PULLUP, /* ACC_INT2 */ - /* Proximity Sensor */ - GPIO217_GPIO | PIN_INPUT_PULLUP, - /* SD card detect */ GPIO95_GPIO | PIN_INPUT_PULLUP, }; @@ -411,7 +405,21 @@ static UX500_PINS(mop500_pins_spi2, GPIO217_SPI2_CLK | PIN_OUTPUT_LOW, ); -static struct ux500_pin_lookup mop500_pins[] = { +static UX500_PINS(mop500_pins_sensors1p, + GPIO217_GPIO| PIN_INPUT_PULLUP | + PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL, + GPIO145_GPIO | PIN_INPUT_PULLDOWN | + PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL, + GPIO139_GPIO | PIN_INPUT_PULLUP | + PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL, +); + +static UX500_PINS(mop500_pins_sensors1p_old, + PIN_CFG_INPUT(GPIO_PROX_SENSOR, GPIO, NOPULL), + PIN_CFG_INPUT(GPIO_HAL_SENSOR, GPIO, NOPULL), +); + +static struct ux500_pin_lookup mop500_runtime_pins[] = { PIN_LOOKUP("mcde-dpi", &mop500_pins_mcde_dpi), PIN_LOOKUP("mcde-tvout", &mop500_pins_mcde_tvout), PIN_LOOKUP("av8100-hdmi", &mop500_pins_mcde_hdmi), @@ -427,6 +435,14 @@ static struct ux500_pin_lookup mop500_pins[] = { PIN_LOOKUP("spi2", &mop500_pins_spi2), }; +static struct ux500_pin_lookup mop500_runtime_pins_v60[] = { + PIN_LOOKUP("gpio-keys.0", &mop500_pins_sensors1p), +}; + +static struct ux500_pin_lookup mop500_runtime_pins_old[] = { + PIN_LOOKUP("gpio-keys.0", &mop500_pins_sensors1p_old), +}; + static struct ux500_pin_lookup mop500_ske_pins[] = { PIN_LOOKUP("ske", &mop500_pins_ske), }; @@ -641,7 +657,9 @@ static pin_cfg_t mop500_pins_common_power_save_bank4[] = { GPIO143_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO144_GPIO | PIN_SLPM_OUTPUT_HIGH | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + /* 145 - HAL sensor (on v60 and later) */ GPIO145_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO146_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO147_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, @@ -769,7 +787,9 @@ static pin_cfg_t mop500_pins_common_power_save_bank6_href60[] = { GPIO215_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO216_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + /* 217 - Proximity */ GPIO217_GPIO | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, + GPIO218_GPIO | PIN_SLPM_DIR_INPUT | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, GPIO219_GPIO | PIN_SLPM_OUTPUT_LOW | PIN_SLPM_WAKEUP_ENABLE | PIN_SLPM_PDIS_DISABLED, @@ -932,8 +952,9 @@ void __init mop500_pins_init(void) nmk_config_pins(mop500_pins_common, ARRAY_SIZE(mop500_pins_common)); - ux500_pins_add(mop500_pins, ARRAY_SIZE(mop500_pins)); + ux500_pins_add(mop500_runtime_pins, ARRAY_SIZE(mop500_runtime_pins)); ux500_pins_add(mop500_ske_pins, ARRAY_SIZE(mop500_ske_pins)); + ux500_pins_add(mop500_runtime_pins_old, ARRAY_SIZE(mop500_runtime_pins_old)); switch (pinsfor) { case PINS_FOR_U9500: @@ -958,7 +979,7 @@ void __init snowball_pins_init(void) nmk_config_pins(mop500_pins_common, ARRAY_SIZE(mop500_pins_common)); - ux500_pins_add(mop500_pins, ARRAY_SIZE(mop500_pins)); + ux500_pins_add(mop500_runtime_pins, ARRAY_SIZE(mop500_runtime_pins)); nmk_config_pins(u8500_pins, ARRAY_SIZE(u8500_pins)); @@ -974,8 +995,9 @@ void __init hrefv60_pins_init(void) nmk_config_pins(mop500_pins_common, ARRAY_SIZE(mop500_pins_common)); - ux500_pins_add(mop500_pins, ARRAY_SIZE(mop500_pins)); + ux500_pins_add(mop500_runtime_pins, ARRAY_SIZE(mop500_runtime_pins)); ux500_pins_add(mop500_ske_pins, ARRAY_SIZE(mop500_ske_pins)); + ux500_pins_add(mop500_runtime_pins_v60, ARRAY_SIZE(mop500_runtime_pins_v60)); nmk_config_pins(hrefv60_pins, ARRAY_SIZE(hrefv60_pins)); diff --git a/arch/arm/mach-ux500/board-mop500-sensors.c b/arch/arm/mach-ux500/board-mop500-sensors.c index bc08e332699..5ee7fec5357 100644 --- a/arch/arm/mach-ux500/board-mop500-sensors.c +++ b/arch/arm/mach-ux500/board-mop500-sensors.c @@ -80,7 +80,7 @@ static struct i2c_board_info __initdata mop500_2_i2c2_devices[] = { static struct i2c_board_info __initdata snowball_i2c2_devices[] = { { /* LSM303DLH Accelerometer */ - I2C_BOARD_INFO("lsm303dlh_a", 0x19), + I2C_BOARD_INFO("lsm303dlhc_a", 0x19), .platform_data = &lsm303dlh_pdata, }, }; @@ -121,6 +121,7 @@ void mop500_sensors_i2c_add(int busnum, struct i2c_board_info const *info, void mop500_sensors_probe_add_lsm303dlh_a(void) { static const int busnum = 2; + int status; struct i2c_adapter *adap; struct i2c_client *client; static const unsigned short i2c_addr_list[] = { @@ -130,6 +131,7 @@ void mop500_sensors_probe_add_lsm303dlh_a(void) I2C_BOARD_INFO("lsm303dlh_a", 0), .platform_data = &lsm303dlh_pdata, }; + union i2c_smbus_data data; adap = i2c_get_adapter(busnum); if (!adap) { @@ -143,6 +145,23 @@ void mop500_sensors_probe_add_lsm303dlh_a(void) pr_err(__FILE__ ": failed to register %s to i2c%d\n", i2c_info.type, busnum); + /* driver is different for LSM3030DLH(0x18) and LSM303DLHC(0x19)*/ + if (i2c_info.addr == 0x19) { + snprintf(i2c_info.type, sizeof(i2c_info.type), "lsm303dlhc_a"); + } + /* + * From the i2c_new_probed_device() function we will come to know + * the adress of the device, so read 0x0F register to get chipID. + * This chipID is used in magnetometer driver to invet co-ordinates. + */ + status = i2c_smbus_xfer(adap, i2c_info.addr , 0 , + I2C_SMBUS_READ, 0x0F , + I2C_SMBUS_BYTE_DATA, &data); + if (status < 0) { + pr_err(__FILE__ ": failed to read 0x0F register\n"); + } + else + lsm303dlh_pdata.chip_id = data.byte; i2c_put_adapter(adap); } @@ -166,20 +185,24 @@ static int __init mop500_sensors_init(void) lsm303dlh_pdata.irq_m = GPIO_MAGNET_DRDY; } - mop500_sensors_i2c_add(2, mop500_i2c2_devices, - ARRAY_SIZE(mop500_i2c2_devices)); - if (machine_is_snowball()) { if (cpu_is_u8500v21()) /* This is ugly but we cant know what address * to use */ mop500_sensors_probe_add_lsm303dlh_a(); - else /* Add the accelerometer with new addr */ + else { + /* Add the accelerometer with new addr */ mop500_sensors_i2c_add(2, snowball_i2c2_devices, ARRAY_SIZE(snowball_i2c2_devices)); + /* For 0x19 accelerometer chip_id is 51*/ + lsm303dlh_pdata.chip_id = 51; + } } else /* none snowball have the old addr */ mop500_sensors_i2c_add(2, mop500_2_i2c2_devices, ARRAY_SIZE(mop500_2_i2c2_devices)); + + mop500_sensors_i2c_add(2, mop500_i2c2_devices, + ARRAY_SIZE(mop500_i2c2_devices)); return 0; } diff --git a/arch/arm/mach-ux500/board-mop500-u8500uib.c b/arch/arm/mach-ux500/board-mop500-u8500uib.c index 20763004c4a..1399c1bcde4 100644 --- a/arch/arm/mach-ux500/board-mop500-u8500uib.c +++ b/arch/arm/mach-ux500/board-mop500-u8500uib.c @@ -42,8 +42,8 @@ static struct lsm303dlh_platform_data __initdata lsm303dlh_pdata_u8500 = { .axis_map_x = 1, .axis_map_y = 0, .axis_map_z = 2, - .negative_x = 1, - .negative_y = 1, + .negative_x = 0, + .negative_y = 0, .negative_z = 1, }; #endif @@ -51,10 +51,10 @@ static struct lsm303dlh_platform_data __initdata lsm303dlh_pdata_u8500 = { #ifdef CONFIG_SENSORS_L3G4200D static struct l3g4200d_gyr_platform_data __initdata l3g4200d_pdata_u8500 = { .name_gyr = "l3g4200d", - .axis_map_x = 1, - .axis_map_y = 0, + .axis_map_x = 0, + .axis_map_y = 1, .axis_map_z = 2, - .negative_x = 0, + .negative_x = 1, .negative_y = 0, .negative_z = 1, }; diff --git a/arch/arm/mach-ux500/board-mop500-uib.c b/arch/arm/mach-ux500/board-mop500-uib.c index 8679b15643c..6dc77d42d86 100644 --- a/arch/arm/mach-ux500/board-mop500-uib.c +++ b/arch/arm/mach-ux500/board-mop500-uib.c @@ -11,9 +11,14 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/i2c.h> -#include <mach/hardware.h> #include <asm/mach-types.h> +#include <linux/platform_device.h> +#include <linux/input.h> +#include <linux/gpio_keys.h> +#include <linux/regulator/consumer.h> +#include <mach/hardware.h> +#include "pins.h" #include "board-mop500.h" enum mop500_uib { @@ -129,6 +134,97 @@ int uib_is_u8500uibr3(void) return (type_of_uib == U8500UIB_R3); } + +#ifdef CONFIG_UX500_GPIO_KEYS +static struct gpio_keys_button mop500_gpio_keys[] = { + { + .desc = "SFH7741 Proximity Sensor", + .type = EV_SW, + .code = SW_FRONT_PROXIMITY, + .active_low = 0, + .can_disable = 1, + }, + { + .desc = "HED54XXU11 Hall Effect Sensor", + .type = EV_SW, + .code = SW_LID, /* FIXME arbitrary usage */ + .active_low = 0, + .can_disable = 1, + } +}; + +static struct regulator *gpio_keys_regulator; +static int mop500_gpio_keys_activate(struct device *dev); +static void mop500_gpio_keys_deactivate(struct device *dev); + +static struct gpio_keys_platform_data mop500_gpio_keys_data = { + .buttons = mop500_gpio_keys, + .nbuttons = ARRAY_SIZE(mop500_gpio_keys), + .enable = mop500_gpio_keys_activate, + .disable = mop500_gpio_keys_deactivate, +}; + +static struct platform_device mop500_gpio_keys_device = { + .name = "gpio-keys", + .id = 0, + .dev = { + .platform_data = &mop500_gpio_keys_data, + }, +}; + +static int mop500_gpio_keys_activate(struct device *dev) +{ + gpio_keys_regulator = regulator_get(&mop500_gpio_keys_device.dev, + "vcc"); + if (IS_ERR(gpio_keys_regulator)) { + dev_err(&mop500_gpio_keys_device.dev, "no regulator\n"); + return PTR_ERR(gpio_keys_regulator); + } + regulator_enable(gpio_keys_regulator); + + /* + * Please be aware that the start-up time of the SFH7741 is + * 120 ms and during that time the output is undefined. + */ + + return 0; +} + +static void mop500_gpio_keys_deactivate(struct device *dev) +{ + if (!IS_ERR(gpio_keys_regulator)) { + regulator_disable(gpio_keys_regulator); + regulator_put(gpio_keys_regulator); + } +} + +static __init void mop500_gpio_keys_init(void) +{ + struct ux500_pins *gpio_keys_pins = ux500_pins_get("gpio-keys.0"); + + if (gpio_keys_pins == NULL) { + pr_err("gpio_keys: Fail to get pins\n"); + return; + } + + ux500_pins_enable(gpio_keys_pins); + if (type_of_uib == U8500UIB_R3) + mop500_gpio_keys[0].gpio = PIN_NUM(gpio_keys_pins->cfg[2]); + else + mop500_gpio_keys[0].gpio = PIN_NUM(gpio_keys_pins->cfg[0]); + mop500_gpio_keys[1].gpio = PIN_NUM(gpio_keys_pins->cfg[1]); +} +#else +static inline void mop500_gpio_keys_init(void) { } +#endif + +/* add any platform devices here - TODO */ +static struct platform_device *mop500_uib_platform_devs[] __initdata = { +#ifdef CONFIG_UX500_GPIO_KEYS + &mop500_gpio_keys_device, +#endif +}; + /* * Detect the UIB attached based on the presence or absence of i2c devices. */ @@ -177,7 +273,9 @@ static int __init mop500_uib_init(void) uib = &mop500_uibs[STUIB]; } __mop500_uib_init(uib, "detected"); - + mop500_gpio_keys_init(); + platform_add_devices(mop500_uib_platform_devs, + ARRAY_SIZE(mop500_uib_platform_devs)); return 0; } diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index ca1677e8b3e..1200db26f75 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -52,7 +52,6 @@ #include <mach/hardware.h> #include <mach/setup.h> #include <mach/devices.h> -#include <mach/sensors1p.h> #ifdef CONFIG_INPUT_AB8500_ACCDET #include <mach/abx500-accdet.h> #endif @@ -654,42 +653,6 @@ static void __init mop500_i2c_init(void) db8500_add_i2c3(&u8500_i2c3_data); } -static struct gpio_keys_button mop500_gpio_keys[] = { - { - .desc = "SFH7741 Proximity Sensor", - .type = EV_SW, - .code = SW_FRONT_PROXIMITY, - .active_low = 0, - .can_disable = 1, - }, - { - .desc = "HED54XXU11 Hall Effect Sensor", - .type = EV_SW, - .code = SW_LID, /* FIXME arbitrary usage */ - .active_low = 0, - .can_disable = 1, - } -}; - -static struct regulator *sensors1p_regulator; -static int mop500_sensors1p_activate(struct device *dev); -static void mop500_sensors1p_deactivate(struct device *dev); - -static struct gpio_keys_platform_data mop500_gpio_keys_data = { - .buttons = mop500_gpio_keys, - .nbuttons = ARRAY_SIZE(mop500_gpio_keys), - .enable = mop500_sensors1p_activate, - .disable = mop500_sensors1p_deactivate, -}; - -static struct platform_device mop500_gpio_keys_device = { - .name = "gpio-keys", - .id = 0, - .dev = { - .platform_data = &mop500_gpio_keys_data, - }, -}; - #ifdef CONFIG_REGULATOR_FIXED_VOLTAGE static struct platform_device snowball_gpio_wlan_vbat_regulator_device = { .name = "reg-fixed-voltage", @@ -708,24 +671,6 @@ static struct platform_device snowball_gpio_en_3v3_regulator_device = { }; #endif -static int mop500_sensors1p_activate(struct device *dev) -{ - sensors1p_regulator = regulator_get(&mop500_gpio_keys_device.dev, - "vcc"); - if (IS_ERR(sensors1p_regulator)) { - dev_err(&mop500_gpio_keys_device.dev, "no regulator\n"); - return PTR_ERR(sensors1p_regulator); - } - regulator_enable(sensors1p_regulator); - return 0; -} - -static void mop500_sensors1p_deactivate(struct device *dev) -{ - regulator_disable(sensors1p_regulator); - regulator_put(sensors1p_regulator); -} - #ifdef CONFIG_LEDS_PWM static struct led_pwm pwm_leds_data[] = { [0] = { @@ -873,30 +818,6 @@ struct platform_device u8500_sim_detect_device = { }; #endif -#ifdef CONFIG_SENSORS1P_MOP -static struct sensors1p_config sensors1p_config = { - /* SFH7741 */ - .proximity = { - .pin = EGPIO_PIN_7, - .startup_time = 120, /* ms */ - .regulator = "v-proximity", - }, - /* HED54XXU11 */ - .hal = { - .pin = EGPIO_PIN_8, - .startup_time = 100, /* Actually, I have no clue. */ - .regulator = "v-hal", - }, -}; - -struct platform_device sensors1p_device = { - .name = "sensors1p", - .dev = { - .platform_data = (void *)&sensors1p_config, - }, -}; -#endif - #ifdef CONFIG_CRYPTO_DEV_UX500 static struct cryp_platform_data u8500_cryp1_platform_data = { .mem_to_engine = { @@ -937,9 +858,6 @@ static struct hash_platform_data u8500_hash1_platform_data = { /* add any platform devices here - TODO */ static struct platform_device *mop500_platform_devs[] __initdata = { -#ifdef CONFIG_SENSORS1P_MOP - &sensors1p_device, -#endif #ifdef CONFIG_U8500_SIM_DETECT &u8500_sim_detect_device, #endif @@ -957,7 +875,6 @@ static struct platform_device *mop500_platform_devs[] __initdata = { #ifdef CONFIG_STE_TRACE_MODEM &u8500_trace_modem, #endif - &mop500_gpio_keys_device, #ifdef CONFIG_LEDS_PWM &ux500_leds_device, #endif @@ -1209,9 +1126,6 @@ static struct platform_device *snowball_platform_devs[] __initdata = { static void __init mop500_init_machine(void) { - mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; - mop500_gpio_keys[1].gpio = GPIO_HAL_SENSOR; - u8500_init_devices(); mop500_pins_init(); @@ -1290,14 +1204,6 @@ static void __init snowball_init_machine(void) static void __init hrefv60_init_machine(void) { - /* - * The HREFv60 board removed a GPIO expander and routed - * all these GPIO pins to the internal GPIO controller - * instead. - */ - mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO; - mop500_gpio_keys[1].gpio = HREFV60_HAL_SW_GPIO; - #ifdef CONFIG_INPUT_AB8500_ACCDET /* * On boards hrefpv60 and later, the accessory insertion/removal, diff --git a/arch/arm/mach-ux500/include/mach/sensors1p.h b/arch/arm/mach-ux500/include/mach/sensors1p.h deleted file mode 100644 index 544e1d8bab5..00000000000 --- a/arch/arm/mach-ux500/include/mach/sensors1p.h +++ /dev/null @@ -1,24 +0,0 @@ - -/* - * Copyright (C) 2009-2010 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * Header file for 1 pin gpio sensors; - * Author: Jonas Aaberg <jonas.aberg@stericsson.com> - * - */ - -#ifndef __ASM_ARCH_SFH7741_H -#define __ASM_ARCH_SFH7741_H - -struct sensor_config { - int pin; - int startup_time; /* in ms */ - char regulator[32]; -}; - -struct sensors1p_config { - struct sensor_config hal; - struct sensor_config proximity; -}; - -#endif diff --git a/arch/arm/mach-ux500/pm/context_arm.S b/arch/arm/mach-ux500/pm/context_arm.S index 55e2accc85f..edb894d6a35 100644 --- a/arch/arm/mach-ux500/pm/context_arm.S +++ b/arch/arm/mach-ux500/pm/context_arm.S @@ -46,10 +46,12 @@ ENTRY(context_save_arm_registers) stmfd sp!, {r1, r2, r3, lr} @ Save on stack ldr r1, [r0] @ Read backup stack pointer - stmia r1, {sp, lr}^ @ Store user mode sp and lr +ARM( stmia r1, {sp, lr}^ ) @ Store user mode sp and lr @ registers - add r1, r1, #8 @ Update backup pointer (not +ARM( add r1, r1, #8 ) @ Update backup pointer (not @ done in previous instruction) +THUMB( str sp, [r1], #+4 ) +THUMB( str lr, [r1], #+4 ) mrs r2, cpsr @ Get CPSR SAVE_AND_INCREMENT r2 r1 @ Save CPSR register @@ -67,23 +69,32 @@ ENTRY(context_save_arm_registers) orr r3, r2, #0x11 @ Save FIQ mode registers msr cpsr_cxsf, r3 mrs r3, spsr - stmia r1!, {r3, r8-r14} +ARM( stmia r1!, {r3, r8-r14} ) +THUMB( stmia r1!, {r3, r8-r12, r14} ) +THUMB( str r13, [r1], #+4 ) + orr r3, r2, #0x12 @ Save IRQ mode registers msr cpsr_cxsf, r3 mrs r3, spsr - stmia r1!, {r3, r13, r14} +ARM( stmia r1!, {r3, r13, r14} ) +THUMB( stmia r1!, {r3, r14} ) +THUMB( str r13, [r1], #+4 ) orr r3, r2, #0x17 @ Save abort mode registers + @ common mode registers msr cpsr_cxsf, r3 mrs r3, spsr - stmia r1!, {r3, r13, r14} +ARM( stmia r1!, {r3, r13, r14} ) +THUMB( stmia r1!, {r3, r14} ) +THUMB( str r13, [r1], #+4 ) orr r3, r2, #0x1B @ Save undef mode registers msr cpsr_cxsf, r3 mrs r3, spsr - stmia r1!, {r3, r13, r14} +ARM( stmia r1!, {r3, r13, r14} ) +THUMB( stmia r1!, {r3, r14} ) +THUMB( str r13, [r1], #+4 ) orr r3, r2, #0x13 @ Return to supervisor mode msr cpsr_cxsf, r3 @@ -120,30 +131,41 @@ ENTRY(context_restore_arm_registers) orr r3, r2, #0x1b @ Restore undef mode registers msr cpsr_cxsf, r3 - ldmdb r1!, {r3, r13, r14} +ARM( ldmdb r1!, {r3, r13, r14} ) +THUMB( ldr r13, [r1], #-4 ) +THUMB( ldmdb r1!, {r3, r14} ) msr spsr_cxsf, r3 orr r3, r2, #0x17 @ Restore abort mode registers msr cpsr_cxsf, r3 - ldmdb r1!, {r3, r13, r14} +ARM( ldmdb r1!, {r3, r13, r14} ) +THUMB( ldr r13, [r1], #-4 ) +THUMB( ldmdb r1!, {r3, r14} ) msr spsr_cxsf, r3 orr r3, r2, #0x12 @ Restore IRQ mode registers msr cpsr_cxsf, r3 - ldmdb r1!, {r3, r13, r14} +ARM( ldmdb r1!, {r3, r13, r14} ) +THUMB( ldr r13, [r1], #-4 ) +THUMB( ldmdb r1!, {r3, r14} ) msr spsr_cxsf, r3 orr r3, r2, #0x11 @ Restore FIQ mode registers msr cpsr_cxsf, r3 - ldmdb r1!, {r3, r8-r14} +ARM( ldmdb r1!, {r3, r8-r14} ) +THUMB( ldr r13, [r1], #-4 ) +THUMB( ldmdb r1!, {r3, r8-r12, r14} ) + msr spsr_cxsf, r3 DECREMENT_AND_RESTORE r1 r3 @ Restore cpsr register msr cpsr_cxsf, r3 - ldmdb r1, {sp, lr}^ @ Restore sp and lr registers - sub r1, r1, #8 @ Update backup pointer (not +ARM( ldmdb r1, {sp, lr}^ ) @ Restore sp and lr registers +ARM( sub r1, r1, #8 ) @ Update backup pointer (not @ done in previous instruction) +THUMB( ldr lr, [r1], #-4 ) +THUMB( ldr sp, [r1], #-4 ) str r1, [r0] @ Write backup stack pointer ldmfd sp!, {r1, r2, r3, pc} @ Restore registers and return @@ -312,7 +334,9 @@ wayLoopL1clean: lineLoopL1clean: mov r2, r1, lsl #30 @ TODO: OK to hard-code @ SoC-specific L1 cache details? - add r2, r0, lsl #5 + mov r3, r0, lsl #5 + add r2, r3 +@ add r2, r0, lsl #5 mcr p15, 0, r2, c7, c10, 2 @ Clean cache by set/way add r0, r0, #1 cmp r0, #256 @ TODO: Ok with hard-coded diff --git a/arch/arm/mach-ux500/sensors1p.c b/arch/arm/mach-ux500/sensors1p.c deleted file mode 100644 index e7f4642b1d9..00000000000 --- a/arch/arm/mach-ux500/sensors1p.c +++ /dev/null @@ -1,298 +0,0 @@ - -/* - * Copyright (C) 2009-2010 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * Simple userspace interface for - * Proximity Sensor Osram SFH 7741 and HAL switch Samsung HED54XXU11 - * Author: Jonas Aaberg <jonas.aberg@stericsson.com> - * - * This driver is only there for making Android happy. It is not ment - * for mainline. - */ - - -#include <linux/platform_device.h> -#include <linux/sysfs.h> -#include <linux/gpio.h> -#include <linux/delay.h> -#include <linux/jiffies.h> -#include <linux/slab.h> -#include <linux/regulator/consumer.h> -#include <linux/err.h> - -#include <mach/sensors1p.h> - -struct sensor { - struct regulator *regulator; - int pin; - int startup_time; - int active; - u64 when_enabled; -}; - -struct sensors1p { - struct sensor hal; - struct sensor proximity; -}; - -static int sensors1p_power_write(struct device *dev, - struct sensor *s, const char *buf) -{ - int val; - - if (sscanf(buf, "%d", &val) != 1) - return -EINVAL; - - if (val != 0 && val != 1) - return -EINVAL; - - if (val != s->active) { - if (val) { - regulator_enable(s->regulator); - s->when_enabled = get_jiffies_64() + - msecs_to_jiffies(s->startup_time); - } else - regulator_disable(s->regulator); - } - s->active = val; - - return strnlen(buf, PAGE_SIZE); - -} - -static ssize_t sensors1p_sysfs_hal_active_set(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - - - struct sensors1p *s = platform_get_drvdata(container_of(dev, - struct platform_device, - dev)); - return sensors1p_power_write(dev, &s->hal, buf); - -} - -static ssize_t sensors1p_sysfs_proximity_active_set(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - - - struct sensors1p *s = platform_get_drvdata(container_of(dev, - struct platform_device, - dev)); - return sensors1p_power_write(dev, &s->proximity, buf); - -} - -static ssize_t sensors1p_sysfs_hal_active_get(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct sensors1p *s = platform_get_drvdata(container_of(dev, - struct platform_device, - dev)); - return sprintf(buf, "%d", s->hal.active); -} - -static ssize_t sensors1p_sysfs_proximity_active_get(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct sensors1p *s = platform_get_drvdata(container_of(dev, - struct platform_device, - dev)); - return sprintf(buf, "%d", s->proximity.active); -} - -static int sensors1p_read(struct device *dev, struct sensor *s, char *buf) -{ - int ret; - - if (!s->active) - return -EINVAL; - - /* Only wait if read() is called before the sensor is up and running - * Since jiffies wraps, always sleep maximum time. - */ - if (time_before64(get_jiffies_64(), s->when_enabled)) - mdelay(s->startup_time); - - /* For some odd reason, setting direction in the probe function fails */ - ret = gpio_direction_input(s->pin); - - if (ret) - dev_err(dev, "Failed to set GPIO pin %d to input.\n", s->pin); - else - ret = gpio_get_value(s->pin); - - return sprintf(buf, "%d", ret); -} - -static ssize_t sensors1p_sysfs_hal_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct sensors1p *s = platform_get_drvdata(container_of(dev, - struct platform_device, - dev)); - return sensors1p_read(dev, &s->hal, buf); -} - -static ssize_t sensors1p_sysfs_proximity_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct sensors1p *s = platform_get_drvdata(container_of(dev, - struct platform_device, - dev)); - return sensors1p_read(dev, &s->proximity, buf); -} - -static DEVICE_ATTR(proximity_activate, 0666, - sensors1p_sysfs_proximity_active_get, - sensors1p_sysfs_proximity_active_set); -static DEVICE_ATTR(hal_activate, 0666, - sensors1p_sysfs_hal_active_get, - sensors1p_sysfs_hal_active_set); -static DEVICE_ATTR(proximity, 0444, sensors1p_sysfs_proximity_show, NULL); -static DEVICE_ATTR(hal, 0444, sensors1p_sysfs_hal_show, NULL); - -static struct attribute *sensors1p_attrs[] = { - &dev_attr_proximity_activate.attr, - &dev_attr_hal_activate.attr, - &dev_attr_proximity.attr, - &dev_attr_hal.attr, - NULL, -}; - -static struct attribute_group sensors1p_attr_group = { - .name = NULL, - .attrs = sensors1p_attrs, -}; - -static int __init sensors1p_probe(struct platform_device *pdev) -{ - int err = -EINVAL; - struct sensors1p_config *c; - struct sensors1p *s = NULL; - - if (!pdev) - goto out; - - c = pdev->dev.platform_data; - - if (c == NULL) { - dev_err(&pdev->dev, "Error: Missconfigured.\n"); - goto out; - } - - s = kzalloc(sizeof(struct sensors1p), GFP_KERNEL); - - if (s == NULL) { - dev_err(&pdev->dev, - "Could not allocate struct memory!\n"); - err = -ENOMEM; - goto out; - } - - s->hal.pin = c->hal.pin; - err = gpio_request(c->hal.pin, "hal sensor"); - if (err < 0) { - dev_err(&pdev->dev, "gpio_request failed with err: %d", err); - goto err_hal_gpio; - } - - s->proximity.pin = c->proximity.pin; - err = gpio_request(c->proximity.pin, "proximity sensor"); - if (err < 0) { - dev_err(&pdev->dev, "gpio_request failed with err: %d", err); - goto err_proximity_gpio; - } - - s->hal.startup_time = c->hal.startup_time; - s->proximity.startup_time = c->proximity.startup_time; - - - s->hal.regulator = regulator_get(&pdev->dev, c->hal.regulator); - - if (IS_ERR(s->hal.regulator)) { - dev_err(&pdev->dev, "regulator_get(\"%s\") failed.\n", - c->hal.regulator); - err = PTR_ERR(s->hal.regulator); - goto err_hal_reg; - } - s->proximity.regulator = regulator_get(&pdev->dev, - c->proximity.regulator); - - if (IS_ERR(s->proximity.regulator)) { - dev_err(&pdev->dev, "regulator_get(\"%s\") failed.\n", - c->proximity.regulator); - err = PTR_ERR(s->proximity.regulator); - goto err_proximity_reg; - } - - err = sysfs_create_group(&pdev->dev.kobj, &sensors1p_attr_group); - - if (err) { - dev_err(&pdev->dev, "Failed to create sysfs entries.\n"); - goto err_sysfs; - } - - platform_set_drvdata(pdev, s); - - return 0; - -err_sysfs: - regulator_put(s->proximity.regulator); -err_proximity_reg: - regulator_put(s->hal.regulator); -err_hal_reg: - gpio_free(s->proximity.pin); -err_proximity_gpio: - gpio_free(s->hal.pin); -err_hal_gpio: - kfree(s); -out: - return err; -} - -static int __exit sensors1p_remove(struct platform_device *pdev) -{ - struct sensors1p *s = platform_get_drvdata(pdev); - - sysfs_remove_group(&pdev->dev.kobj, &sensors1p_attr_group); - gpio_free(s->hal.pin); - gpio_free(s->proximity.pin); - regulator_put(s->hal.regulator); - regulator_put(s->proximity.regulator); - kfree(s); - return 0; -} - -static struct platform_driver sensors1p_driver = { - .remove = __exit_p(sensors1p_remove), - .driver = { - .name = "sensors1p", - .owner = THIS_MODULE, - }, -}; - -static int __init sensors1p_init(void) -{ - return platform_driver_probe(&sensors1p_driver, sensors1p_probe); -} - -static void __exit sensors1p_exit(void) -{ - platform_driver_unregister(&sensors1p_driver); -} - -late_initcall(sensors1p_init); -module_exit(sensors1p_exit); - -MODULE_AUTHOR("Jonas Aaberg <jonas.aberg@stericsson.com>"); -MODULE_DESCRIPTION("One pin gpio sensors driver (Proximity+HAL)"); -MODULE_LICENSE("GPLv2"); |