Merge "asoc: codecs: add wcd9360 objects for kernel build option" into audio-drivers.lnx.3.0
diff --git a/asoc/codecs/wsa881x-temp-sensor.c b/asoc/codecs/wsa881x-temp-sensor.c
index 5ab0ecf..b2ed963 100644
--- a/asoc/codecs/wsa881x-temp-sensor.c
+++ b/asoc/codecs/wsa881x-temp-sensor.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -12,6 +12,7 @@
#include <linux/bitops.h>
#include <linux/kernel.h>
+#include <linux/suspend.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/thermal.h>
@@ -61,6 +62,20 @@
pr_err("%s: pdata is NULL\n", __func__);
return -EINVAL;
}
+ if (atomic_cmpxchg(&pdata->is_suspend_spk, 1, 0)) {
+ /*
+ * get_temp query happens as part of POST_PM_SUSPEND
+ * from thermal core. To avoid calls to slimbus
+ * as part of this thermal query, return default temp
+ * and reset the suspend flag.
+ */
+ if (!pdata->t0_init) {
+ if (temp)
+ *temp = pdata->curr_temp;
+ return 0;
+ }
+ }
+
temp_retry:
if (pdata->wsa_temp_reg_read) {
ret = pdata->wsa_temp_reg_read(codec, ®);
@@ -108,6 +123,8 @@
goto temp_retry;
}
}
+ pdata->curr_temp = temp_val;
+
if (temp)
*temp = temp_val;
pr_debug("%s: t0 measured: %d dmeas = %d, d1 = %d, d2 = %d\n",
@@ -120,6 +137,23 @@
.get_temp = wsa881x_get_temp,
};
+
+static int wsa881x_pm_notify(struct notifier_block *nb,
+ unsigned long mode, void *_unused)
+{
+ struct wsa881x_tz_priv *pdata =
+ container_of(nb, struct wsa881x_tz_priv, pm_nb);
+
+ switch (mode) {
+ case PM_SUSPEND_PREPARE:
+ atomic_set(&pdata->is_suspend_spk, 1);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata)
{
struct thermal_zone_device *tz_dev;
@@ -137,12 +171,23 @@
return -EINVAL;
}
tz_pdata->tz_dev = tz_dev;
+ tz_pdata->pm_nb.notifier_call = wsa881x_pm_notify;
+ register_pm_notifier(&tz_pdata->pm_nb);
+ atomic_set(&tz_pdata->is_suspend_spk, 0);
+
return 0;
}
EXPORT_SYMBOL(wsa881x_init_thermal);
void wsa881x_deinit_thermal(struct thermal_zone_device *tz_dev)
{
+ struct wsa881x_tz_priv *pdata;
+
+ if (tz_dev && tz_dev->devdata) {
+ pdata = tz_dev->devdata;
+ if (pdata)
+ unregister_pm_notifier(&pdata->pm_nb);
+ }
if (tz_dev)
thermal_zone_device_unregister(tz_dev);
}
diff --git a/asoc/codecs/wsa881x-temp-sensor.h b/asoc/codecs/wsa881x-temp-sensor.h
index d6c1eb7..26828b7 100644
--- a/asoc/codecs/wsa881x-temp-sensor.h
+++ b/asoc/codecs/wsa881x-temp-sensor.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -31,6 +31,10 @@
struct wsa_temp_register *wsa_temp_reg;
char name[80];
wsa_temp_register_read wsa_temp_reg_read;
+ struct notifier_block pm_nb;
+ atomic_t is_suspend_spk;
+ int t0_init;
+ int curr_temp;
};
int wsa881x_get_temp(struct thermal_zone_device *tz_dev, int *temp);
diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c
index 0755cdc..2ef9e0a 100644
--- a/asoc/codecs/wsa881x.c
+++ b/asoc/codecs/wsa881x.c
@@ -200,12 +200,40 @@
return 0;
}
+static int wsa881x_get_t0_init(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec);
+ struct wsa881x_tz_priv *pdata = &wsa881x->tz_pdata;
+
+ ucontrol->value.integer.value[0] = pdata->t0_init;
+ dev_dbg(codec->dev, "%s: t0 init %d\n", __func__, pdata->t0_init);
+
+ return 0;
+}
+
+static int wsa881x_set_t0_init(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec);
+ struct wsa881x_tz_priv *pdata = &wsa881x->tz_pdata;
+
+ pdata->t0_init = ucontrol->value.integer.value[0];
+ dev_dbg(codec->dev, "%s: t0 init %d\n", __func__, pdata->t0_init);
+
+ return 0;
+}
static const struct snd_kcontrol_new wsa_snd_controls[] = {
SOC_ENUM_EXT("WSA PA Gain", wsa_pa_gain_enum,
wsa_pa_gain_get, wsa_pa_gain_put),
SOC_SINGLE_EXT("WSA PA Mute", SND_SOC_NOPM, 0, 1, 0,
wsa881x_get_mute, wsa881x_set_mute),
+ SOC_SINGLE_EXT("WSA T0 Init", SND_SOC_NOPM, 0, 1, 0,
+ wsa881x_get_t0_init, wsa881x_set_t0_init),
};
static int codec_debug_open(struct inode *inode, struct file *file)