ASoC: wsa881x: Fix regcache sync issue during playback
When temperature on a single wsa881x device is being read, then soundwire master wakes up both wsa881x devices but regcache_sync is happening only for one wsa881x device on which the temperature is being read. This results in audio playback mute after temperature read. Fix the regcache sync during temperature read and playback usecase. CRs-Fixed: 2282230 Change-Id: I054f4432d7ae7bce922341ad62b20544cccd5865 Signed-off-by: Sudheer Papothi <spapothi@codeaurora.org> Signed-off-by: Laxminath Kasam <lkasam@codeaurora.org>
This commit is contained in:
parent
6aa022f4eb
commit
e6a032c67e
1 changed files with 31 additions and 12 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2017, 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
|
||||
|
@ -76,6 +76,7 @@ struct swr_port {
|
|||
enum {
|
||||
WSA881X_DEV_DOWN,
|
||||
WSA881X_DEV_UP,
|
||||
WSA881X_DEV_READY,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -99,6 +100,7 @@ struct wsa881x_priv {
|
|||
int version;
|
||||
struct mutex bg_lock;
|
||||
struct mutex res_lock;
|
||||
struct mutex temp_lock;
|
||||
struct snd_info_entry *entry;
|
||||
struct snd_info_entry *version_entry;
|
||||
int state;
|
||||
|
@ -464,6 +466,17 @@ static const struct file_operations codec_debug_ops = {
|
|||
.read = codec_debug_read,
|
||||
};
|
||||
|
||||
static void wsa881x_regcache_sync(struct wsa881x_priv *wsa881x)
|
||||
{
|
||||
mutex_lock(&wsa881x->res_lock);
|
||||
if (wsa881x->state != WSA881X_DEV_READY) {
|
||||
regcache_mark_dirty(wsa881x->regmap);
|
||||
regcache_sync(wsa881x->regmap);
|
||||
wsa881x->state = WSA881X_DEV_READY;
|
||||
}
|
||||
mutex_unlock(&wsa881x->res_lock);
|
||||
}
|
||||
|
||||
static const struct reg_sequence wsa881x_pre_pmu_pa[] = {
|
||||
{WSA881X_SPKR_DRV_GAIN, 0x41, 0},
|
||||
{WSA881X_SPKR_MISC_CTL1, 0x01, 0},
|
||||
|
@ -790,7 +803,9 @@ static int wsa881x_rdac_event(struct snd_soc_dapm_widget *w,
|
|||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
mutex_lock(&wsa881x->temp_lock);
|
||||
wsa881x_resource_acquire(codec, ENABLE);
|
||||
mutex_unlock(&wsa881x->temp_lock);
|
||||
wsa881x_boost_ctrl(codec, ENABLE);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
|
@ -798,7 +813,9 @@ static int wsa881x_rdac_event(struct snd_soc_dapm_widget *w,
|
|||
wsa881x->swr_slave->dev_num,
|
||||
false);
|
||||
wsa881x_boost_ctrl(codec, DISABLE);
|
||||
mutex_lock(&wsa881x->temp_lock);
|
||||
wsa881x_resource_acquire(codec, DISABLE);
|
||||
mutex_unlock(&wsa881x->temp_lock);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
@ -1042,13 +1059,8 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec,
|
|||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
mutex_lock(&wsa881x->res_lock);
|
||||
if (!wsa881x->clk_cnt) {
|
||||
regcache_mark_dirty(wsa881x->regmap);
|
||||
regcache_sync(wsa881x->regmap);
|
||||
}
|
||||
mutex_unlock(&wsa881x->res_lock);
|
||||
|
||||
wsa881x_regcache_sync(wsa881x);
|
||||
mutex_lock(&wsa881x->temp_lock);
|
||||
wsa881x_resource_acquire(codec, ENABLE);
|
||||
|
||||
snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x00);
|
||||
|
@ -1061,6 +1073,7 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec,
|
|||
wsa_temp_reg->d2_lsb = snd_soc_read(codec, WSA881X_OTP_REG_4);
|
||||
|
||||
wsa881x_resource_acquire(codec, DISABLE);
|
||||
mutex_unlock(&wsa881x->temp_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1076,7 +1089,6 @@ static int wsa881x_probe(struct snd_soc_codec *codec)
|
|||
dev = wsa881x->swr_slave;
|
||||
wsa881x->codec = codec;
|
||||
mutex_init(&wsa881x->bg_lock);
|
||||
mutex_init(&wsa881x->res_lock);
|
||||
wsa881x_init(codec);
|
||||
snprintf(wsa881x->tz_pdata.name, sizeof(wsa881x->tz_pdata.name),
|
||||
"%s.%x", "wsatz", (u8)dev->addr);
|
||||
|
@ -1098,7 +1110,6 @@ static int wsa881x_remove(struct snd_soc_codec *codec)
|
|||
if (wsa881x->tz_pdata.tz_dev)
|
||||
wsa881x_deinit_thermal(wsa881x->tz_pdata.tz_dev);
|
||||
mutex_destroy(&wsa881x->bg_lock);
|
||||
mutex_destroy(&wsa881x->res_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1224,6 +1235,8 @@ static int wsa881x_swr_probe(struct swr_device *pdev)
|
|||
if (wsa881x->wsa_rst_np)
|
||||
pin_state_current = msm_cdc_pinctrl_get_state(
|
||||
wsa881x->wsa_rst_np);
|
||||
mutex_init(&wsa881x->res_lock);
|
||||
mutex_init(&wsa881x->temp_lock);
|
||||
wsa881x_gpio_ctrl(wsa881x, true);
|
||||
wsa881x->state = WSA881X_DEV_UP;
|
||||
|
||||
|
@ -1303,6 +1316,8 @@ static int wsa881x_swr_remove(struct swr_device *pdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
debugfs_remove_recursive(debugfs_wsa881x_dent);
|
||||
mutex_destroy(&wsa881x->res_lock);
|
||||
mutex_destroy(&wsa881x->temp_lock);
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
if (wsa881x->pd_gpio)
|
||||
gpio_free(wsa881x->pd_gpio);
|
||||
|
@ -1361,6 +1376,11 @@ static int wsa881x_swr_reset(struct swr_device *pdev)
|
|||
dev_err(&pdev->dev, "%s: wsa881x is NULL\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (wsa881x->state == WSA881X_DEV_READY) {
|
||||
dev_dbg(&pdev->dev, "%s: device already active\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
wsa881x->bg_cnt = 0;
|
||||
wsa881x->clk_cnt = 0;
|
||||
while (swr_get_logical_dev_num(pdev, pdev->addr, &devnum) && retry--) {
|
||||
|
@ -1368,8 +1388,7 @@ static int wsa881x_swr_reset(struct swr_device *pdev)
|
|||
usleep_range(1000, 1100);
|
||||
}
|
||||
pdev->dev_num = devnum;
|
||||
regcache_mark_dirty(wsa881x->regmap);
|
||||
regcache_sync(wsa881x->regmap);
|
||||
wsa881x_regcache_sync(wsa881x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue