diff options
| author | Amit Jain <ajain@motorola.com> | 2014-10-02 11:11:23 -0500 |
|---|---|---|
| committer | Amit Jain <ajain@motorola.com> | 2014-10-03 13:37:12 +0000 |
| commit | 58efe519a5477c70a184cdf376520122127f69f0 (patch) | |
| tree | 597aef9bad8256e13a695b110888ac697b8c9589 | |
| parent | 079a36c83139757332cde9a8a588d7249645283b (diff) | |
| download | olio-linux-3.10-58efe519a5477c70a184cdf376520122127f69f0.tar.xz olio-linux-3.10-58efe519a5477c70a184cdf376520122127f69f0.zip | |
IKXCLOCK-4061: power key behavior change
| -rw-r--r-- | arch/arm/configs/minnow_defconfig | 1 | ||||
| -rw-r--r-- | drivers/mfd/tps65912-irq.c | 30 | ||||
| -rw-r--r-- | drivers/mfd/tps65912-key.c | 47 | ||||
| -rw-r--r-- | drivers/misc/Kconfig | 5 | ||||
| -rw-r--r-- | drivers/misc/Makefile | 2 | ||||
| -rw-r--r-- | drivers/misc/bq5105x_detect.c | 9 | ||||
| -rw-r--r-- | drivers/misc/charger_notify.c | 50 | ||||
| -rw-r--r-- | drivers/misc/display_notify.c | 50 | ||||
| -rw-r--r-- | drivers/video/omap2/displays/panel-minnow.c | 20 | ||||
| -rw-r--r-- | include/linux/charger_notify.h | 34 | ||||
| -rw-r--r-- | include/linux/display_notify.h | 34 | ||||
| -rw-r--r-- | include/linux/mfd/tps65912.h | 11 | ||||
| -rw-r--r-- | include/linux/wakeup_source_notify.h | 2 |
13 files changed, 292 insertions, 3 deletions
diff --git a/arch/arm/configs/minnow_defconfig b/arch/arm/configs/minnow_defconfig index fa1a3eb44af..96cf883e0d6 100644 --- a/arch/arm/configs/minnow_defconfig +++ b/arch/arm/configs/minnow_defconfig @@ -1154,6 +1154,7 @@ CONFIG_MOT_UTAG=y CONFIG_BQ5105X_CTRL=y CONFIG_BQ5105X_DETECT=y CONFIG_WAKEUP_SOURCE_NOTIFY=y +CONFIG_POWER_KEY_OVERRIDE=y # CONFIG_C2PORT is not set # diff --git a/drivers/mfd/tps65912-irq.c b/drivers/mfd/tps65912-irq.c index 766ed7dd8f5..9637a632e19 100644 --- a/drivers/mfd/tps65912-irq.c +++ b/drivers/mfd/tps65912-irq.c @@ -34,6 +34,7 @@ static inline int irq_to_tps65912_irq(struct tps65912 *tps65912, static irqreturn_t powerkey_handler(int irq, void *irq_data) { struct tps65912 *tps65912 = irq_data; + unsigned int code = tps65912->powerkey_code; u32 new_state; if (irq - tps65912->irq_base == tps65912->powerkey_up_irq) { @@ -47,9 +48,36 @@ static irqreturn_t powerkey_handler(int irq, void *irq_data) } mutex_lock(&tps65912->irq_lock); + +#ifdef CONFIG_POWER_KEY_OVERRIDE + /* if we are not on dock, send the sleep key*/ + /* this logic is a bit tricky, notifier from + display driver will trigger on keypress which will + interfere with the logic for keyrelease. we will + see key press sent for KEY_POWER, but key release + for KEY_SLEEP. To fix this, we cache the event code + being sent out for keypress and we always send the + cached event code for key release */ + + if (new_state == PWRKEY_PRESS) { + if (tps65912->dockstatus == false && + tps65912->displaystatus == true) + code = KEY_SLEEP; + + tps65912->lastkeyevent = code; + } + + if (new_state == PWRKEY_RELEASE) { + code = tps65912->lastkeyevent; + /* Deliberately setting to -1, to catch + errors */ + tps65912->lastkeyevent = -1; + } +#endif + if (new_state != tps65912->powerkey_state) { tps65912_broadcast_key_event(tps65912, - tps65912->powerkey_code, + code, new_state); tps65912->powerkey_state = new_state; } diff --git a/drivers/mfd/tps65912-key.c b/drivers/mfd/tps65912-key.c index 3f389039405..308f5c97921 100644 --- a/drivers/mfd/tps65912-key.c +++ b/drivers/mfd/tps65912-key.c @@ -23,13 +23,42 @@ #include <linux/input.h> #include <linux/gpio.h> #include <linux/mfd/tps65912.h> +#ifdef CONFIG_WAKEUP_SOURCE_NOTIFY #include <linux/wakeup_source_notify.h> +#endif +#ifdef CONFIG_POWER_KEY_OVERRIDE +#include <linux/charger_notify.h> +#include <linux/display_notify.h> +#endif struct tps65912_key_data { struct input_dev *input_dev; struct tps65912 *tps65912; }; +#ifdef CONFIG_POWER_KEY_OVERRIDE +static int charger_notify(struct notifier_block *self, + unsigned long action, void *dev) +{ + struct tps65912 *tps65912 = + container_of(self, struct tps65912, charger_nb); + tps65912->dockstatus = (action == EVENT_DOCKON); + pr_info("%s: dockstatus is %d\n", __func__, tps65912->dockstatus); + return NOTIFY_OK; +} + +static int display_notify(struct notifier_block *self, + unsigned long action, void *dev) +{ + struct tps65912 *tps65912 = + container_of(self, struct tps65912, display_nb); + + tps65912->displaystatus = (action == DISPLAY_EVENT_DISPLAYON); + pr_info("%s: displaystatus is %d\n", __func__, tps65912->displaystatus); + return NOTIFY_OK; +} +#endif + static int tps65912_key_probe(struct platform_device *pdev) { int err; @@ -57,6 +86,9 @@ static int tps65912_key_probe(struct platform_device *pdev) set_bit(EV_KEY, key->input_dev->evbit); set_bit(key->tps65912->powerkey_code, key->input_dev->keybit); +#ifdef CONFIG_POWER_KEY_OVERRIDE + set_bit(KEY_SLEEP, key->input_dev->keybit); +#endif key->input_dev->name = "tps65912-key"; @@ -69,6 +101,17 @@ static int tps65912_key_probe(struct platform_device *pdev) platform_set_drvdata(pdev, key); tps65912_set_keydata(key->tps65912, key); +#ifdef CONFIG_POWER_KEY_OVERRIDE + key->tps65912->charger_nb.notifier_call = charger_notify; + charger_register_notify(&key->tps65912->charger_nb); + key->tps65912->dockstatus = false; + + key->tps65912->display_nb.notifier_call = display_notify; + display_register_notify(&key->tps65912->display_nb); + key->tps65912->displaystatus = true; + key->tps65912->lastkeyevent = -1; +#endif + dev_info(&pdev->dev, "tps65912 key device probed\n"); return 0; @@ -86,6 +129,10 @@ static int __exit tps65912_key_remove(struct platform_device *pdev) input_unregister_device(key->input_dev); input_free_device(key->input_dev); +#ifdef CONFIG_POWER_KEY_OVERRIDE + charger_unregister_notify(&key->tps65912->charger_nb); + display_unregister_notify(&key->tps65912->display_nb); +#endif kfree(key); return 0; diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 5b96da5fda8..2b3fbb02f2a 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -586,6 +586,11 @@ config WAKEUP_SOURCE_NOTIFY help Driver to allow early notification of wakeups +config POWER_KEY_OVERRIDE + tristate "dynamically switch between generating KEY_SLEEP and KEY_POWER" + help + controls key code to be generated from power key + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 2f57dbac599..684e5a88236 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -68,3 +68,5 @@ obj-$(CONFIG_MOT_UTAG) += utag/ obj-$(CONFIG_BQ5105X_CTRL) += bq5105x_ctrl.o obj-$(CONFIG_BQ5105X_DETECT) += bq5105x_detect.o obj-$(CONFIG_WAKEUP_SOURCE_NOTIFY) += wakeup_source_notify.o +obj-$(CONFIG_POWER_KEY_OVERRIDE) += charger_notify.o +obj-$(CONFIG_POWER_KEY_OVERRIDE) += display_notify.o diff --git a/drivers/misc/bq5105x_detect.c b/drivers/misc/bq5105x_detect.c index 37cbdcaa11c..4c01828f5ca 100644 --- a/drivers/misc/bq5105x_detect.c +++ b/drivers/misc/bq5105x_detect.c @@ -31,7 +31,12 @@ #include <linux/switch.h> #include <linux/wakelock.h> #include <linux/workqueue.h> +#ifdef CONFIG_WAKEUP_SOURCE_NOTIFY #include <linux/wakeup_source_notify.h> +#endif +#ifdef CONFIG_POWER_KEY_OVERRIDE +#include <linux/charger_notify.h> +#endif /* * Detect when a device is placed on a wireless charger and report this to user @@ -215,6 +220,10 @@ static void bq5105x_detect_report(struct bq5105x_detect *chip, bool docked) { if (chip->reported_docked != docked) { dev_dbg(&chip->pdev->dev, "report docked=%d\n", docked); +#ifdef CONFIG_POWER_KEY_OVERRIDE + charger_notify_subscriber(docked + ? EVENT_DOCKON : EVENT_DOCKOFF); +#endif #ifdef CONFIG_WAKEUP_SOURCE_NOTIFY wakeup_source_notify_subscriber(docked ? DISPLAY_WAKE_EVENT_DOCKON diff --git a/drivers/misc/charger_notify.c b/drivers/misc/charger_notify.c new file mode 100644 index 00000000000..79f9e726f87 --- /dev/null +++ b/drivers/misc/charger_notify.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2014 Motorola Mobility LLC. + * + * 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/notifier.h> +#include <linux/charger_notify.h> + +static BLOCKING_NOTIFIER_HEAD(charger_notifier_list); + +/** + * charger_register_notify - register a notifier callback for triggering display init + * @nb: pointer to the notifier block for the callback events. + * + */ +void charger_register_notify(struct notifier_block *nb) +{ + blocking_notifier_chain_register(&charger_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(charger_register_notify); + +/** + * charger_unregister_notify - unregister a notifier callback + * @nb: pointer to the notifier block for the callback events. + * + * charger_register_notify() must have been previously called + * for this function to work properly. + */ +void charger_unregister_notify(struct notifier_block *nb) +{ + blocking_notifier_chain_unregister(&charger_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(charger_unregister_notify); + +void charger_notify_subscriber(unsigned long event) +{ + blocking_notifier_call_chain(&charger_notifier_list, event, NULL); +} +EXPORT_SYMBOL_GPL(charger_notify_subscriber); diff --git a/drivers/misc/display_notify.c b/drivers/misc/display_notify.c new file mode 100644 index 00000000000..e243058fc4e --- /dev/null +++ b/drivers/misc/display_notify.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2014 Motorola Mobility LLC. + * + * 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/notifier.h> +#include <linux/display_notify.h> + +static BLOCKING_NOTIFIER_HEAD(display_notifier_list); + +/** + * display_register_notify - register a notifier callback for triggering display init + * @nb: pointer to the notifier block for the callback events. + * + */ +void display_register_notify(struct notifier_block *nb) +{ + blocking_notifier_chain_register(&display_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(display_register_notify); + +/** + * display_unregister_notify - unregister a notifier callback + * @nb: pointer to the notifier block for the callback events. + * + * display_register_notify() must have been previously called + * for this function to work properly. + */ +void display_unregister_notify(struct notifier_block *nb) +{ + blocking_notifier_chain_unregister(&display_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(display_unregister_notify); + +void display_notify_subscriber(unsigned long event) +{ + blocking_notifier_call_chain(&display_notifier_list, event, NULL); +} +EXPORT_SYMBOL_GPL(display_notify_subscriber); diff --git a/drivers/video/omap2/displays/panel-minnow.c b/drivers/video/omap2/displays/panel-minnow.c index cc231d4da58..e05806626e1 100644 --- a/drivers/video/omap2/displays/panel-minnow.c +++ b/drivers/video/omap2/displays/panel-minnow.c @@ -44,7 +44,12 @@ #include <video/omap-panel-data.h> #include <video/mipi_display.h> #include <linux/notifier.h> +#ifdef CONFIG_WAKEUP_SOURCE_NOTIFY #include <linux/wakeup_source_notify.h> +#endif +#ifdef CONFIG_POWER_KEY_OVERRIDE +#include <linux/display_notify.h> +#endif #include "../dss/dss.h" @@ -3281,8 +3286,12 @@ static int minnow_panel_change_state_mlocked(struct minnow_panel_data *mpd, switch (state) { case DISPLAY_DISABLE: - if (mpd->enabled) + if (mpd->enabled) { minnow_panel_disable_mlocked(mpd); +#ifdef CONFIG_POWER_KEY_OVERRIDE + display_notify_subscriber(DISPLAY_EVENT_DISPLAYOFF); +#endif + } break; case DISPLAY_ENABLE: if (!mpd->enabled) @@ -3293,6 +3302,9 @@ static int minnow_panel_change_state_mlocked(struct minnow_panel_data *mpd, */ else if (mpd->state == DISPLAY_AMBIENT_ON) minnow_panel_set_default_fps(mpd); +#ifdef CONFIG_POWER_KEY_OVERRIDE + display_notify_subscriber(DISPLAY_EVENT_DISPLAYON); +#endif #endif break; #ifdef CONFIG_HAS_AMBIENTMODE @@ -3307,6 +3319,9 @@ static int minnow_panel_change_state_mlocked(struct minnow_panel_data *mpd, /* Turn off the back light */ led_set_brightness(led_get_default_dev(), 0); minnow_panel_disable_mlocked(mpd); +#ifdef CONFIG_POWER_KEY_OVERRIDE + display_notify_subscriber(DISPLAY_EVENT_DISPLAYOFF); +#endif } break; case DISPLAY_AMBIENT_ON: @@ -3329,6 +3344,9 @@ static int minnow_panel_change_state_mlocked(struct minnow_panel_data *mpd, if (!mpd->enabled) r = minnow_panel_enable_mlocked(mpd); if (!r) { +#ifdef CONFIG_POWER_KEY_OVERRIDE + display_notify_subscriber(DISPLAY_EVENT_DISPLAYOFF); +#endif /* switch to lowest refresh rate */ minnow_panel_set_lowest_fps(mpd); /* Dim the back light */ diff --git a/include/linux/charger_notify.h b/include/linux/charger_notify.h new file mode 100644 index 00000000000..49bd6cb07be --- /dev/null +++ b/include/linux/charger_notify.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2014 Motorola Mobility LLC. + * + * 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef CHARGER_NOTIFY_H +#define CHARGER_NOTIFY_H + +#ifdef __KERNEL__ + +enum charger_event { + EVENT_DOCKON, + EVENT_DOCKOFF, + EVENT_END +}; + + +extern void charger_register_notify(struct notifier_block *nb); +extern void charger_unregister_notify(struct notifier_block *nb); +extern void charger_notify_subscriber(unsigned long event); +#endif /* __KERNEL__ */ + +#endif /* CHARGER_NOTIFY_H */ diff --git a/include/linux/display_notify.h b/include/linux/display_notify.h new file mode 100644 index 00000000000..3dbb6128c4b --- /dev/null +++ b/include/linux/display_notify.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2014 Motorola Mobility LLC. + * + * 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef DISPLAY_NOTIFY_H +#define DISPLAY_NOTIFY_H + +#ifdef __KERNEL__ + +enum display_event { + DISPLAY_EVENT_DISPLAYON, + DISPLAY_EVENT_DISPLAYOFF, + DISPLAY_EVENT_END +}; + + +extern void display_register_notify(struct notifier_block *nb); +extern void display_unregister_notify(struct notifier_block *nb); +extern void display_notify_subscriber(unsigned long event); +#endif /* __KERNEL__ */ + +#endif /* DISPLAY_NOTIFY_H */ diff --git a/include/linux/mfd/tps65912.h b/include/linux/mfd/tps65912.h index 426f5e5e08f..6452efcdd8c 100644 --- a/include/linux/mfd/tps65912.h +++ b/include/linux/mfd/tps65912.h @@ -15,6 +15,10 @@ #ifndef __LINUX_MFD_TPS65912_H #define __LINUX_MFD_TPS65912_H +#ifdef CONFIG_POWER_KEY_OVERRIDE +#include <linux/notifier.h> +#endif + /* TPS regulator type list */ #define REGULATOR_LDO 0 #define REGULATOR_DCDC 1 @@ -341,6 +345,13 @@ struct tps65912 { u32 powerkey_up_irq; u32 powerkey_down_irq; struct mutex pm_lock; /* guard access to spi bus from irq */ +#ifdef CONFIG_POWER_KEY_OVERRIDE + struct notifier_block charger_nb; + bool dockstatus; + struct notifier_block display_nb; + bool displaystatus; + int lastkeyevent; +#endif }; struct tps65912_platform_data { diff --git a/include/linux/wakeup_source_notify.h b/include/linux/wakeup_source_notify.h index 98db849d13d..2681835738d 100644 --- a/include/linux/wakeup_source_notify.h +++ b/include/linux/wakeup_source_notify.h @@ -14,7 +14,7 @@ * this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef WAKEUP_SOURCEE_NOTIFY_H +#ifndef WAKEUP_SOURCE_NOTIFY_H #define WAKEUP_SOURCE_NOTIFY_H #ifdef __KERNEL__ |