1
0
Fork 0

MLK-19741 sound: asoc: add micfil hwvad alsamixer rate selection

Add alsamixer control for selecting the default voice activity detection
rate. This is a prerequisite for supporting hwvad and recording in parallel
or you will restrict the user to do the recording only at the hardcoded
hwvad rate (when hwvad is enabled).

Signed-off-by: Cosmin-Gabriel Samoila <cosmin.samoila@nxp.com>
Reviewed-by: Shengjiu Wang <shengjiu.wang@nxp.com>
pull/10/head
Cosmin-Gabriel Samoila 2018-09-26 15:58:29 +03:00 committed by Jason Liu
parent 56f6e22088
commit 3d435e80a3
1 changed files with 55 additions and 2 deletions

View File

@ -61,6 +61,7 @@ struct fsl_micfil {
int vad_zcd_auto;
int vad_zcd_en;
int vad_zcd_adj;
int vad_rate_index;
atomic_t state;
atomic_t voice_detected;
atomic_t init_hwvad_done;
@ -129,6 +130,16 @@ static const char * const micfil_hwvad_noise_decimation[] = {
"Disabled", "Enabled",
};
/* when adding new rate text, also add it to the
* micfil_hwvad_rate_ints
*/
static const char * const micfil_hwvad_rate[] = {
"48KHz", "44.1KHz",
};
static const int micfil_hwvad_rate_ints[] = {
48000, 44100,
};
static const struct soc_enum fsl_micfil_enum[] = {
SOC_ENUM_SINGLE(REG_MICFIL_CTRL2,
@ -147,6 +158,8 @@ static const struct soc_enum fsl_micfil_enum[] = {
MICFIL_VAD0_NCONFIG_NOREN_SHIFT,
ARRAY_SIZE(micfil_hwvad_noise_decimation),
micfil_hwvad_noise_decimation),
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(micfil_hwvad_rate),
micfil_hwvad_rate),
};
static int hwvad_put_init_mode(struct snd_kcontrol *kcontrol,
@ -231,6 +244,31 @@ static int hwvad_get_zcd_en(struct snd_kcontrol *kcontrol,
return 0;
}
static int hwvad_put_rate(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int *item = ucontrol->value.enumerated.item;
struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
int val = snd_soc_enum_item_to_val(e, item[0]);
micfil->vad_rate_index = val;
return 0;
}
static int hwvad_get_rate(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
ucontrol->value.enumerated.item[0] = micfil->vad_rate_index;
return 0;
}
static int hwvad_put_zcd_auto(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@ -594,6 +632,8 @@ static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {
hwvad_get_zcd_auto, hwvad_put_zcd_auto),
SOC_ENUM_EXT("HWVAD Noise OR Enable", fsl_micfil_enum[5],
snd_soc_get_enum_double, snd_soc_put_enum_double),
SOC_ENUM_EXT("HWVAD Sampling Rate", fsl_micfil_enum[6],
hwvad_get_rate, hwvad_put_rate),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "HWVAD Input Gain",
@ -1864,6 +1904,7 @@ static int enable_hwvad(struct device *dev)
struct fsl_micfil *micfil = dev_get_drvdata(dev);
int ret;
int old_state;
int rate;
/* go further with enablement only if both recording and
* hwvad are not on
@ -1876,6 +1917,14 @@ static int enable_hwvad(struct device *dev)
return -EBUSY;
}
if (micfil->vad_rate_index >= ARRAY_SIZE(micfil_hwvad_rate_ints)) {
dev_err(dev, "There are more select texts than rates\n");
ret = -EINVAL;
goto enable_err;
}
rate = micfil_hwvad_rate_ints[micfil->vad_rate_index];
/* This is required because if an arecord was done,
* suspend function will mark regmap as cache only
* and reads/writes in volatile regs will fail
@ -1887,7 +1936,7 @@ static int enable_hwvad(struct device *dev)
/* clear voice detected flag */
atomic_set(&micfil->voice_detected, 0);
ret = fsl_set_clock_params(dev, MICFIL_DEFAULT_RATE);
ret = fsl_set_clock_params(dev, rate);
if (ret)
goto enable_err;
@ -1988,7 +2037,8 @@ static ssize_t micfil_hwvad_handler(struct kobject *kobj,
if (enabled_channels > 0 && enabled_channels <= 8) {
dev_info(dev,
"enabling hwvad with %lu channels at rate %d\n",
enabled_channels, MICFIL_DEFAULT_RATE);
enabled_channels,
micfil_hwvad_rate_ints[micfil->vad_rate_index]);
micfil->channels = enabled_channels;
ret = enable_hwvad(dev);
} else if (!enabled_channels) {
@ -2133,6 +2183,9 @@ static int fsl_micfil_probe(struct platform_device *pdev)
micfil->dma_params_rx.addr = res->start + REG_MICFIL_DATACH0;
micfil->dma_params_rx.maxburst = MICFIL_DMA_MAXBURST_RX;
/* set default rate to first value in available vad rates */
micfil->vad_rate_index = 0;
platform_set_drvdata(pdev, micfil);
pm_runtime_enable(&pdev->dev);