aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2020-12-17 17:05:48 +0000
committerMark Brown <broonie@kernel.org>2020-12-17 17:05:48 +0000
commitcda91206dc45257ba0c4d8acb6eeebfec8b2b9bc (patch)
treefd9e07a462148cebc70cd399d3b40a48ac153f5d /sound/soc
parentASoC: max98373: don't access volatile registers in bias level off (diff)
parentASoC: qcom: Add support for playback recover after resume (diff)
downloadlinux-dev-cda91206dc45257ba0c4d8acb6eeebfec8b2b9bc.tar.xz
linux-dev-cda91206dc45257ba0c4d8acb6eeebfec8b2b9bc.zip
Merge series "Platform driver update to support playback recover after resume" from Srinivasa Rao Mandadapu <srivasam@codeaurora.org>:
This patch set is to add support for playback recover after hard suspend and resume. It includes: 1. Reverting part of previous commit, which is for handling registers invalid state after hard suspend. 2. Adding pm ops in component driver and do regcache sync. Changes Since v1 and v2: -- Subject lines changed Changes Since v3: -- Patch is splitted into 2 patches Changes Since v4: -- Subject lines changed Changes Since v5: -- Removed redundant initialization of map variable in lpass-platform.c Srinivasa Rao Mandadapu (2): ASoC: qcom: Fix incorrect volatile registers ASoC: qcom: Add support for playback recover after resume sound/soc/qcom/lpass-cpu.c | 20 ++--------------- sound/soc/qcom/lpass-platform.c | 50 ++++++++++++++++++++++++++++------------- 2 files changed, 37 insertions(+), 33 deletions(-) -- Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/qcom/lpass-cpu.c20
-rw-r--r--sound/soc/qcom/lpass-platform.c50
2 files changed, 37 insertions, 33 deletions
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
index af684fd19ab9..c5e99c2d89c7 100644
--- a/sound/soc/qcom/lpass-cpu.c
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -270,18 +270,6 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
struct lpaif_i2sctl *i2sctl = drvdata->i2sctl;
unsigned int id = dai->driver->id;
int ret = -EINVAL;
- unsigned int val = 0;
-
- ret = regmap_read(drvdata->lpaif_map,
- LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id), &val);
- if (ret) {
- dev_err(dai->dev, "error reading from i2sctl reg: %d\n", ret);
- return ret;
- }
- if (val == LPAIF_I2SCTL_RESET_STATE) {
- dev_err(dai->dev, "error in i2sctl register state\n");
- return -ENOTRECOVERABLE;
- }
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -454,20 +442,16 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg)
struct lpass_variant *v = drvdata->variant;
int i;
- for (i = 0; i < v->i2s_ports; ++i)
- if (reg == LPAIF_I2SCTL_REG(v, i))
- return true;
for (i = 0; i < v->irq_ports; ++i)
if (reg == LPAIF_IRQSTAT_REG(v, i))
return true;
for (i = 0; i < v->rdma_channels; ++i)
- if (reg == LPAIF_RDMACURR_REG(v, i) || reg == LPAIF_RDMACTL_REG(v, i))
+ if (reg == LPAIF_RDMACURR_REG(v, i))
return true;
for (i = 0; i < v->wrdma_channels; ++i)
- if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start) ||
- reg == LPAIF_WRDMACTL_REG(v, i + v->wrdma_channel_start))
+ if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start))
return true;
return false;
diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c
index 80b09dede5f9..d1c248590f3a 100644
--- a/sound/soc/qcom/lpass-platform.c
+++ b/sound/soc/qcom/lpass-platform.c
@@ -452,7 +452,6 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
unsigned int reg_irqclr = 0, val_irqclr = 0;
unsigned int reg_irqen = 0, val_irqen = 0, val_mask = 0;
unsigned int dai_id = cpu_dai->driver->id;
- unsigned int dma_ctrl_reg = 0;
ch = pcm_data->dma_ch;
if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -469,17 +468,7 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
id = pcm_data->dma_ch - v->wrdma_channel_start;
map = drvdata->lpaif_map;
}
- ret = regmap_read(map, LPAIF_DMACTL_REG(v, ch, dir, dai_id), &dma_ctrl_reg);
- if (ret) {
- dev_err(soc_runtime->dev, "error reading from rdmactl reg: %d\n", ret);
- return ret;
- }
- if (dma_ctrl_reg == LPAIF_DMACTL_RESET_STATE ||
- dma_ctrl_reg == LPAIF_DMACTL_RESET_STATE + 1) {
- dev_err(soc_runtime->dev, "error in rdmactl register state\n");
- return -ENOTRECOVERABLE;
- }
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
@@ -500,7 +489,6 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
"error writing to rdmactl reg: %d\n", ret);
return ret;
}
- map = drvdata->hdmiif_map;
reg_irqclr = LPASS_HDMITX_APP_IRQCLEAR_REG(v);
val_irqclr = (LPAIF_IRQ_ALL(ch) |
LPAIF_IRQ_HDMI_REQ_ON_PRELOAD(ch) |
@@ -519,7 +507,6 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
break;
case MI2S_PRIMARY:
case MI2S_SECONDARY:
- map = drvdata->lpaif_map;
reg_irqclr = LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST);
val_irqclr = LPAIF_IRQ_ALL(ch);
@@ -563,7 +550,6 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
"error writing to rdmactl reg: %d\n", ret);
return ret;
}
- map = drvdata->hdmiif_map;
reg_irqen = LPASS_HDMITX_APP_IRQEN_REG(v);
val_mask = (LPAIF_IRQ_ALL(ch) |
LPAIF_IRQ_HDMI_REQ_ON_PRELOAD(ch) |
@@ -573,7 +559,6 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
break;
case MI2S_PRIMARY:
case MI2S_SECONDARY:
- map = drvdata->lpaif_map;
reg_irqen = LPAIF_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST);
val_mask = LPAIF_IRQ_ALL(ch);
val_irqen = 0;
@@ -838,6 +823,39 @@ static void lpass_platform_pcm_free(struct snd_soc_component *component,
}
}
+static int lpass_platform_pcmops_suspend(struct snd_soc_component *component)
+{
+ struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
+ struct regmap *map;
+ unsigned int dai_id = component->id;
+
+ if (dai_id == LPASS_DP_RX)
+ map = drvdata->hdmiif_map;
+ else
+ map = drvdata->lpaif_map;
+
+ regcache_cache_only(map, true);
+ regcache_mark_dirty(map);
+
+ return 0;
+}
+
+static int lpass_platform_pcmops_resume(struct snd_soc_component *component)
+{
+ struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
+ struct regmap *map;
+ unsigned int dai_id = component->id;
+
+ if (dai_id == LPASS_DP_RX)
+ map = drvdata->hdmiif_map;
+ else
+ map = drvdata->lpaif_map;
+
+ regcache_cache_only(map, false);
+ return regcache_sync(map);
+}
+
+
static const struct snd_soc_component_driver lpass_component_driver = {
.name = DRV_NAME,
.open = lpass_platform_pcmops_open,
@@ -850,6 +868,8 @@ static const struct snd_soc_component_driver lpass_component_driver = {
.mmap = lpass_platform_pcmops_mmap,
.pcm_construct = lpass_platform_pcm_new,
.pcm_destruct = lpass_platform_pcm_free,
+ .suspend = lpass_platform_pcmops_suspend,
+ .resume = lpass_platform_pcmops_resume,
};