suspend: default suspend adc in freeze mode for power consumption [1/1]
authorwenbiao zhang <wenbiao.zhang@amlogic.com>
Tue, 4 Jun 2019 07:20:05 +0000 (15:20 +0800)
committerTao Zeng <tao.zeng@amlogic.com>
Thu, 20 Jun 2019 03:09:15 +0000 (20:09 -0700)
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 <wenbiao.zhang@amlogic.com>
drivers/amlogic/iio/adc/meson_saradc.c
drivers/amlogic/input/keyboard/adc_keypad.c
drivers/amlogic/input/keyboard/gpio_keypad.c
include/linux/amlogic/pm.h

index 9b4ab35..fb318e2 100644 (file)
@@ -1703,9 +1703,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)
@@ -1724,9 +1727,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;
index c1ad720..4f5c53a 100644 (file)
 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) {
index 92c50f1..22c5bc1 100644 (file)
@@ -279,11 +279,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;
@@ -294,10 +300,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));
index dd1d1d3..d4e342b 100644 (file)
@@ -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