[Feature][T108][task-view-1466][codec] Add codec/PA power hibernation wake up
Only Configure: No
Affected branch:
Affected module: codec
Is it affected on IC: only ASR GSW_V1453
Self-test: yes
Doc Update: no
Change-Id: Iac36f8601f2f1cddbd26946f614a6ef22a576c45
diff --git a/marvell/linux/drivers/mfd/es8311.c b/marvell/linux/drivers/mfd/es8311.c
index e350684..d28a655 100755
--- a/marvell/linux/drivers/mfd/es8311.c
+++ b/marvell/linux/drivers/mfd/es8311.c
@@ -128,6 +128,9 @@
//#define ES8311_DEBUG
//#define ES8311_DEBUG_CLOSE
+#define CONFIG_CODEC_VDDD_EN 1
+static int gpio_codec_vddd_en = -1;
+
#define es8311_reg_NUM 0xFF
/* base functions */
@@ -3077,6 +3080,24 @@
return 0;
}
+#ifdef CONFIG_CODEC_VDDD_EN
+ /* Get CODEC_VDDD_EN GPIO from device tree */
+ gpio_codec_vddd_en = of_get_gpio(g_es8311_node, 0);
+ printk(KERN_INFO"es8311_probe: gpio_codec_vddd_en=%d\n", gpio_codec_vddd_en);
+
+ /* CODEC_VDDD_EN GPIO control from device tree */
+ if (gpio_codec_vddd_en >= 0) {
+ if (gpio_request(gpio_codec_vddd_en, "codec_vddd_en") == 0) {
+ gpio_direction_output(gpio_codec_vddd_en, 1);
+ printk(KERN_EMERG "0624 GPIO%d CODEC_VDDD_EN set to high (from DTS)\n", gpio_codec_vddd_en);
+ } else {
+ printk(KERN_EMERG "GPIO%d request failed\n", gpio_codec_vddd_en);
+ }
+ } else {
+ printk(KERN_EMERG "CODEC_VDDD_EN GPIO not configured in device tree\n");
+ }
+#endif
+
es8311_dump_debugfs_init(NULL);
// es8311_audio_debugfs_init(NULL);
@@ -3194,6 +3215,13 @@
/* Power off for ASR1901 kestrel */
audio_set_codec_vdd(0);
+#ifdef CONFIG_CODEC_VDDD_EN
+ if (gpio_is_valid(gpio_codec_vddd_en)) {
+ gpio_free(gpio_codec_vddd_en);
+ printk(KERN_INFO "es8311: Released gpio_codec_vddd_en\n");
+ }
+#endif
+
#ifdef HEADSET_DETECTION
gpio_free(gpio_CODEC_IRQ);
free_irq(irq_codec, g_es8311_client);
@@ -3219,10 +3247,54 @@
return;
}
+static int es8311_i2c_suspend(struct device *dev)
+{
+ printk(KERN_INFO "es8311: Entering suspend\n");
+
+#ifdef CONFIG_CODEC_VDDD_EN
+ if (gpio_is_valid(gpio_codec_vddd_en)) {
+ gpio_direction_output(gpio_codec_vddd_en, 0);
+ printk(KERN_INFO "es8311: codec_vddd_en set to input (low) for suspend\n");
+ }
+#endif
+
+ audio_set_codec_vdd(0);
+
+ return 0;
+}
+
+static int es8311_i2c_resume(struct device *dev)
+{
+ int ret = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+
+ printk(KERN_INFO "es8311: Exiting suspend\n");
+
+#ifdef CONFIG_CODEC_VDDD_EN
+ if (gpio_is_valid(gpio_codec_vddd_en)) {
+ ret = gpio_direction_output(gpio_codec_vddd_en, 1);
+ if (ret) {
+ printk(KERN_ERR "es8311: Failed to set gpio_codec_vddd_en to output high: %d\n", ret);
+ } else {
+ printk(KERN_INFO "es8311: codec_vddd_en set to output high for resume\n");
+ }
+ }
+#endif
+
+ audio_set_codec_vdd(1);
+
+ return ret;
+}
+
+static const struct dev_pm_ops es8311_dev_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(es8311_i2c_suspend, es8311_i2c_resume)
+};
+
static struct i2c_driver es8311_driver = {
.driver = {
.name = "es8311",
.of_match_table = of_match_ptr(es8311_dt_ids),
+ .pm = &es8311_dev_pm_ops,
},
.probe = es8311_probe,
.remove = es8311_remove,