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>
This commit is contained in:

committed by
Mark Brown

parent
dad8061494
commit
fb5d11524e
@@ -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);
|
||||
|
Reference in New Issue
Block a user