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
parent
56f6e22088
commit
3d435e80a3
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue