ASoC: wcd9xxx: Update sound card's online/offline state
Update sound card's state when it went to online/offline so application
can monitor and wait for card's online prior to issue command.
Change-Id: I7cfb120e56e97cf743782a8b4b2fcbad242b227b
Signed-off-by: Joonwoo Park <joonwoop@codeaurora.org>
(cherry picked from commit 4aee97adf03305b3896f8e74977ef917c2fd9a32)
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index 6d80ebd..c8255c4 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -1571,16 +1571,28 @@
pr_err("%s: Resetting Codec failed\n", __func__);
wcd9xxx_bring_up(wcd9xxx);
- wcd9xxx->post_reset(wcd9xxx);
+ if (wcd9xxx->post_reset)
+ wcd9xxx->post_reset(wcd9xxx);
return ret;
}
static int wcd9xxx_slim_device_up(struct slim_device *sldev)
{
struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
+ dev_dbg(wcd9xxx->dev, "%s: device up\n", __func__);
return wcd9xxx_device_up(wcd9xxx);
}
+static int wcd9xxx_slim_device_down(struct slim_device *sldev)
+{
+ struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
+
+ if (wcd9xxx->dev_down)
+ wcd9xxx->dev_down(wcd9xxx);
+ dev_dbg(wcd9xxx->dev, "%s: device down\n", __func__);
+ return 0;
+}
+
static int wcd9xxx_slim_resume(struct slim_device *sldev)
{
struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
@@ -1737,6 +1749,7 @@
.resume = wcd9xxx_slim_resume,
.suspend = wcd9xxx_slim_suspend,
.device_up = wcd9xxx_slim_device_up,
+ .device_down = wcd9xxx_slim_device_down,
};
static const struct slim_device_id tapan_slimtest_id[] = {
@@ -1755,6 +1768,7 @@
.resume = wcd9xxx_slim_resume,
.suspend = wcd9xxx_slim_suspend,
.device_up = wcd9xxx_slim_device_up,
+ .device_down = wcd9xxx_slim_device_down,
};
static struct i2c_device_id wcd9xxx_id_table[] = {
diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h
index d54bf42..37fdd4e 100644
--- a/include/linux/mfd/wcd9xxx/core.h
+++ b/include/linux/mfd/wcd9xxx/core.h
@@ -188,10 +188,13 @@
int bytes, void *dest, bool interface_reg);
int (*write_dev)(struct wcd9xxx *wcd9xxx, unsigned short reg,
int bytes, void *src, bool interface_reg);
+ int (*dev_down)(struct wcd9xxx *wcd9xxx);
int (*post_reset)(struct wcd9xxx *wcd9xxx);
void *ssr_priv;
bool slim_device_bootup;
+ /* device down flag by device_down notification */
+ bool device_down;
u32 num_of_supplies;
struct regulator_bulk_data *supplies;
diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
index c0448f2..fc30356 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -4907,6 +4907,16 @@
}
EXPORT_SYMBOL_GPL(tapan_hs_detect);
+static int tapan_device_down(struct wcd9xxx *wcd9xxx)
+{
+ struct snd_soc_codec *codec;
+
+ codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
+ snd_soc_card_change_online_state(codec->card, 0);
+
+ return 0;
+}
+
static int tapan_post_reset_cb(struct wcd9xxx *wcd9xxx)
{
int ret = 0;
@@ -4916,8 +4926,10 @@
codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
tapan = snd_soc_codec_get_drvdata(codec);
- mutex_lock(&codec->mutex);
+ snd_soc_card_change_online_state(codec->card, 1);
+
+ mutex_lock(&codec->mutex);
if (codec->reg_def_copy) {
pr_debug("%s: Update ASOC cache", __func__);
kfree(codec->reg_cache);
@@ -4965,9 +4977,12 @@
};
static int wcd9xxx_ssr_register(struct wcd9xxx *control,
- int (*post_reset_cb)(struct wcd9xxx *wcd9xxx), void *priv)
+ int (*device_down_cb)(struct wcd9xxx *wcd9xxx),
+ int (*device_up_cb)(struct wcd9xxx *wcd9xxx),
+ void *priv)
{
- control->post_reset = post_reset_cb;
+ control->dev_down = device_down_cb;
+ control->post_reset = device_up_cb;
control->ssr_priv = priv;
return 0;
}
@@ -5073,7 +5088,8 @@
codec->control_data = dev_get_drvdata(codec->dev->parent);
control = codec->control_data;
- wcd9xxx_ssr_register(control, tapan_post_reset_cb, (void *)codec);
+ wcd9xxx_ssr_register(control, tapan_device_down,
+ tapan_post_reset_cb, (void *)codec);
dev_info(codec->dev, "%s()\n", __func__);
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index c27e085..9c81cc4 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -6212,6 +6212,16 @@
pr_debug("%s: slimbus logical address 0x%llx\n", __func__, eaddr);
}
+static int taiko_device_down(struct wcd9xxx *wcd9xxx)
+{
+ struct snd_soc_codec *codec;
+
+ codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
+ snd_soc_card_change_online_state(codec->card, 0);
+
+ return 0;
+}
+
static int taiko_post_reset_cb(struct wcd9xxx *wcd9xxx)
{
int ret = 0;
@@ -6221,8 +6231,10 @@
codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
taiko = snd_soc_codec_get_drvdata(codec);
- mutex_lock(&codec->mutex);
+ snd_soc_card_change_online_state(codec->card, 1);
+
+ mutex_lock(&codec->mutex);
if (codec->reg_def_copy) {
pr_debug("%s: Update ASOC cache", __func__);
kfree(codec->reg_cache);
@@ -6309,9 +6321,12 @@
};
static int wcd9xxx_ssr_register(struct wcd9xxx *control,
- int (*post_reset_cb)(struct wcd9xxx *wcd9xxx), void *priv)
+ int (*device_down_cb)(struct wcd9xxx *wcd9xxx),
+ int (*device_up_cb)(struct wcd9xxx *wcd9xxx),
+ void *priv)
{
- control->post_reset = post_reset_cb;
+ control->dev_down = device_down_cb;
+ control->post_reset = device_up_cb;
control->ssr_priv = priv;
return 0;
}
@@ -6396,7 +6411,8 @@
codec->control_data = dev_get_drvdata(codec->dev->parent);
control = codec->control_data;
- wcd9xxx_ssr_register(control, taiko_post_reset_cb, (void *)codec);
+ wcd9xxx_ssr_register(control, taiko_device_down,
+ taiko_post_reset_cb, (void *)codec);
dev_info(codec->dev, "%s()\n", __func__);