From dabc4d5f197c651a54143d8c9988e4cb4e2f0d49 Mon Sep 17 00:00:00 2001 From: wenbiao zhang Date: Tue, 4 Jun 2019 15:20:05 +0800 Subject: [PATCH] suspend: default suspend adc in freeze mode for power consumption [1/1] PD#SWPL-8587 Problem: in freeze mode detect adc key cause power consumption problem Solution: adckeyswitch from bootargs to decide whether resume by adc key in freeze mode, default set to POWER_WAKEUP_NONE adckeyswitch values POWER_WAKEUP_NONE/POWER_WAKEUP_POWER/POWER_WAKEUP_ANY Verify: X301 Change-Id: I2726c2ec394e1ffa528acb0862ef302983683b3b Signed-off-by: wenbiao zhang --- drivers/amlogic/iio/adc/meson_saradc.c | 14 +++++--- drivers/amlogic/input/keyboard/adc_keypad.c | 34 ++++++++++++++++++-- drivers/amlogic/input/keyboard/gpio_keypad.c | 24 ++++++++++---- include/linux/amlogic/pm.h | 4 ++- 4 files changed, 62 insertions(+), 14 deletions(-) diff --git a/drivers/amlogic/iio/adc/meson_saradc.c b/drivers/amlogic/iio/adc/meson_saradc.c index 1f86a7713a0f..581f1d07af1a 100644 --- a/drivers/amlogic/iio/adc/meson_saradc.c +++ b/drivers/amlogic/iio/adc/meson_saradc.c @@ -1668,9 +1668,12 @@ static int __maybe_unused meson_sar_adc_suspend(struct device *dev) struct iio_dev *indio_dev = dev_get_drvdata(dev); int ret; - if (is_pm_freeze_mode()) +#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND +#ifdef CONFIG_AMLOGIC_ADC_KEYPADS + if (keep_adc_alive()) return 0; - +#endif +#endif if (iio_buffer_enabled(indio_dev)) { ret = meson_sar_adc_buffer_predisable(indio_dev); if (ret) @@ -1689,9 +1692,12 @@ static int __maybe_unused meson_sar_adc_resume(struct device *dev) struct iio_dev *indio_dev = dev_get_drvdata(dev); int ret; - if (is_pm_freeze_mode()) +#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND +#ifdef CONFIG_AMLOGIC_ADC_KEYPADS + if (keep_adc_alive()) return 0; - +#endif +#endif ret = meson_sar_adc_hw_enable(indio_dev); if (ret) return ret; diff --git a/drivers/amlogic/input/keyboard/adc_keypad.c b/drivers/amlogic/input/keyboard/adc_keypad.c index c1ad72014e22..4f5c53ad2eff 100644 --- a/drivers/amlogic/input/keyboard/adc_keypad.c +++ b/drivers/amlogic/input/keyboard/adc_keypad.c @@ -39,12 +39,27 @@ static char adc_key_mode_name[MAX_NAME_LEN] = "abcdef"; static char kernelkey_en_name[MAX_NAME_LEN] = "abcdef"; static bool keypad_enable_flag = true; +static char adc_key_mode = 2; /*no key can resume*/ +static bool has_adc_power_key; +static bool freeze_mode_ignore_key; + +#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND +bool keep_adc_alive(void) +{ + return is_pm_freeze_mode() && ((adc_key_mode == 1) || + ((adc_key_mode == 0) && has_adc_power_key)); +} +EXPORT_SYMBOL(keep_adc_alive); +#endif static int meson_adc_kp_search_key(struct meson_adc_kp *kp) { struct adc_key *key; int value, i; + if (freeze_mode_ignore_key) + return KEY_RESERVED; + mutex_lock(&kp->kp_lock); for (i = 0; i < kp->chan_num; i++) { if (iio_read_channel_processed(kp->pchan[kp->chan[i]], @@ -106,12 +121,15 @@ static void send_data_to_bl301(void) if (!strcmp(adc_key_mode_name, "POWER_WAKEUP_POWER")) { val = 0; /*only power key resume*/ scpi_send_usr_data(SCPI_CL_POWER, &val, sizeof(val)); + adc_key_mode = 0; } else if (!strcmp(adc_key_mode_name, "POWER_WAKEUP_ANY")) { val = 1; /*any key resume*/ scpi_send_usr_data(SCPI_CL_POWER, &val, sizeof(val)); + adc_key_mode = 1; } else if (!strcmp(adc_key_mode_name, "POWER_WAKEUP_NONE")) { val = 2; /*no key can resume*/ scpi_send_usr_data(SCPI_CL_POWER, &val, sizeof(val)); + adc_key_mode = 2; } } @@ -244,6 +262,8 @@ static int meson_adc_kp_get_devtree_pdata(struct platform_device *pdev, state = -EINVAL; goto err; } + if (key->code == KEY_POWER) + has_adc_power_key = true; ret = of_property_read_u32_index(pdev->dev.of_node, "key_chan", cnt, &key->chan); @@ -363,6 +383,7 @@ static ssize_t table_store(struct class *cls, struct class_attribute *attr, /*write "null" or "NULL" to clean up all key table*/ if (strcasecmp("null", nbuf) == 0) { meson_adc_kp_list_free(kp); + has_adc_power_key = false; return count; } @@ -450,6 +471,8 @@ static ssize_t table_store(struct class *cls, struct class_attribute *attr, kfree(key); } } + if (dkey->code == KEY_POWER) + has_adc_power_key = true; set_bit(dkey->code, kp->poll_dev->input->keybit); list_add_tail(&dkey->list, &kp->adckey_head); dev_info(dev, "add newer key => %s:%d:%d:%d:%d\n", dkey->name, @@ -576,8 +599,11 @@ static int meson_adc_kp_remove(struct platform_device *pdev) static int meson_adc_kp_suspend(struct platform_device *pdev, pm_message_t state) { - if (is_pm_freeze_mode()) +#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND + if (keep_adc_alive()) return 0; +#endif + freeze_mode_ignore_key = true; return 0; } @@ -586,9 +612,11 @@ static int meson_adc_kp_resume(struct platform_device *pdev) struct adc_key *key; struct meson_adc_kp *kp = platform_get_drvdata(pdev); - if (is_pm_freeze_mode()) +#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND + if (keep_adc_alive()) return 0; - +#endif + freeze_mode_ignore_key = false; if (get_resume_method() == POWER_KEY_WAKEUP) { list_for_each_entry(key, &kp->adckey_head, list) { if (key->code == KEY_POWER) { diff --git a/drivers/amlogic/input/keyboard/gpio_keypad.c b/drivers/amlogic/input/keyboard/gpio_keypad.c index fd43e6e2748e..0508d441a61e 100644 --- a/drivers/amlogic/input/keyboard/gpio_keypad.c +++ b/drivers/amlogic/input/keyboard/gpio_keypad.c @@ -342,11 +342,17 @@ static int meson_gpio_kp_suspend(struct platform_device *dev, pm_message_t state) { struct gpio_keypad *pdata; - - if (is_pm_freeze_mode()) - return 0; + int i; pdata = (struct gpio_keypad *)platform_get_drvdata(dev); +#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND + if (is_pm_freeze_mode()) { + for (i = 0; i < pdata->key_size; i++) { + if (pdata->key[i].code == KEY_POWER) + return 0; + } + } +#endif if (!pdata->use_irq) del_timer(&(pdata->polling_timer)); return 0; @@ -357,10 +363,16 @@ static int meson_gpio_kp_resume(struct platform_device *dev) int i; struct gpio_keypad *pdata; - if (is_pm_freeze_mode()) - return 0; - pdata = (struct gpio_keypad *)platform_get_drvdata(dev); +#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND + if (is_pm_freeze_mode()) { + for (i = 0; i < pdata->key_size; i++) { + if (pdata->key[i].code == KEY_POWER) + return 0; + } + } +#endif + if (!pdata->use_irq) mod_timer(&(pdata->polling_timer), jiffies+msecs_to_jiffies(5)); diff --git a/include/linux/amlogic/pm.h b/include/linux/amlogic/pm.h index dd1d1d3e108f..d4e342b962df 100644 --- a/include/linux/amlogic/pm.h +++ b/include/linux/amlogic/pm.h @@ -52,7 +52,9 @@ extern void register_early_suspend(struct early_suspend *handler); extern void unregister_early_suspend(struct early_suspend *handler); extern unsigned int lgcy_early_suspend_init(void); extern unsigned int is_pm_freeze_mode(void); - +#ifdef CONFIG_AMLOGIC_ADC_KEYPADS +extern bool keep_adc_alive(void); +#endif #endif //CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND