summaryrefslogtreecommitdiff
path: root/sound/soc/qcom/lpass-cpu.c
diff options
context:
space:
mode:
authorSrinivas Kandagatla <srinivas.kandagatla@linaro.org>2016-02-11 12:18:33 +0000
committerMark Brown <broonie@kernel.org>2016-02-20 01:20:18 +0900
commitfb5d11524eda5561f6dd8cc03f9dc778027ce907 (patch)
tree9ba4d2867ddbd2539496c35676c82e5888dd7fbc /sound/soc/qcom/lpass-cpu.c
parentdad8061494d2a2ce6edc2ae5ab530b0d330b2685 (diff)
ASoC: qcom: add mic support
This patch adds mic support to the lpass driver, most of the driver is reused as it is, only the register level access is changed depending on te direction of the stream. Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Acked-by: Kenneth Westfield <kwestfie@codeaurora.org> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/qcom/lpass-cpu.c')
-rw-r--r--sound/soc/qcom/lpass-cpu.c113
1 files changed, 83 insertions, 30 deletions
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
index 91774fc87fcc..3cde9fb977fa 100644
--- a/sound/soc/qcom/lpass-cpu.c
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -120,31 +120,60 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- switch (channels) {
- case 1:
- regval |= LPAIF_I2SCTL_SPKMODE_SD0;
- regval |= LPAIF_I2SCTL_SPKMONO_MONO;
- break;
- case 2:
- regval |= LPAIF_I2SCTL_SPKMODE_SD0;
- regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
- break;
- case 4:
- regval |= LPAIF_I2SCTL_SPKMODE_QUAD01;
- regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
- break;
- case 6:
- regval |= LPAIF_I2SCTL_SPKMODE_6CH;
- regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
- break;
- case 8:
- regval |= LPAIF_I2SCTL_SPKMODE_8CH;
- regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
- break;
- default:
- dev_err(dai->dev, "%s() invalid channels given: %u\n",
- __func__, channels);
- return -EINVAL;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (channels) {
+ case 1:
+ regval |= LPAIF_I2SCTL_SPKMODE_SD0;
+ regval |= LPAIF_I2SCTL_SPKMONO_MONO;
+ break;
+ case 2:
+ regval |= LPAIF_I2SCTL_SPKMODE_SD0;
+ regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
+ break;
+ case 4:
+ regval |= LPAIF_I2SCTL_SPKMODE_QUAD01;
+ regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
+ break;
+ case 6:
+ regval |= LPAIF_I2SCTL_SPKMODE_6CH;
+ regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
+ break;
+ case 8:
+ regval |= LPAIF_I2SCTL_SPKMODE_8CH;
+ regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
+ break;
+ default:
+ dev_err(dai->dev, "%s() invalid channels given: %u\n",
+ __func__, channels);
+ return -EINVAL;
+ }
+ } else {
+ switch (channels) {
+ case 1:
+ regval |= LPAIF_I2SCTL_MICMODE_SD0;
+ regval |= LPAIF_I2SCTL_MICMONO_MONO;
+ break;
+ case 2:
+ regval |= LPAIF_I2SCTL_MICMODE_SD0;
+ regval |= LPAIF_I2SCTL_MICMONO_STEREO;
+ break;
+ case 4:
+ regval |= LPAIF_I2SCTL_MICMODE_QUAD01;
+ regval |= LPAIF_I2SCTL_MICMONO_STEREO;
+ break;
+ case 6:
+ regval |= LPAIF_I2SCTL_MICMODE_6CH;
+ regval |= LPAIF_I2SCTL_MICMONO_STEREO;
+ break;
+ case 8:
+ regval |= LPAIF_I2SCTL_MICMODE_8CH;
+ regval |= LPAIF_I2SCTL_MICMONO_STEREO;
+ break;
+ default:
+ dev_err(dai->dev, "%s() invalid channels given: %u\n",
+ __func__, channels);
+ return -EINVAL;
+ }
}
ret = regmap_write(drvdata->lpaif_map,
@@ -188,10 +217,19 @@ static int lpass_cpu_daiops_prepare(struct snd_pcm_substream *substream,
{
struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
int ret;
+ unsigned int val, mask;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ val = LPAIF_I2SCTL_SPKEN_ENABLE;
+ mask = LPAIF_I2SCTL_SPKEN_MASK;
+ } else {
+ val = LPAIF_I2SCTL_MICEN_ENABLE;
+ mask = LPAIF_I2SCTL_MICEN_MASK;
+ }
ret = regmap_update_bits(drvdata->lpaif_map,
LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id),
- LPAIF_I2SCTL_SPKEN_MASK, LPAIF_I2SCTL_SPKEN_ENABLE);
+ mask, val);
if (ret)
dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
__func__, ret);
@@ -204,16 +242,24 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
{
struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
int ret = -EINVAL;
+ unsigned int val, mask;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ val = LPAIF_I2SCTL_SPKEN_ENABLE;
+ mask = LPAIF_I2SCTL_SPKEN_MASK;
+ } else {
+ val = LPAIF_I2SCTL_MICEN_ENABLE;
+ mask = LPAIF_I2SCTL_MICEN_MASK;
+ }
+
ret = regmap_update_bits(drvdata->lpaif_map,
LPAIF_I2SCTL_REG(drvdata->variant,
dai->driver->id),
- LPAIF_I2SCTL_SPKEN_MASK,
- LPAIF_I2SCTL_SPKEN_ENABLE);
+ mask, val);
if (ret)
dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
__func__, ret);
@@ -221,11 +267,18 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ val = LPAIF_I2SCTL_SPKEN_DISABLE;
+ mask = LPAIF_I2SCTL_SPKEN_MASK;
+ } else {
+ val = LPAIF_I2SCTL_MICEN_DISABLE;
+ mask = LPAIF_I2SCTL_MICEN_MASK;
+ }
+
ret = regmap_update_bits(drvdata->lpaif_map,
LPAIF_I2SCTL_REG(drvdata->variant,
dai->driver->id),
- LPAIF_I2SCTL_SPKEN_MASK,
- LPAIF_I2SCTL_SPKEN_DISABLE);
+ mask, val);
if (ret)
dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
__func__, ret);