ASoC: rockchip: vad: add vad switch

This patch add the vad switch control for on/off vad function.

/ # amixer contents
numid=47,iface=MIXER,name='vad switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off

/ # amixer cset numid=47 1
numid=47,iface=MIXER,name='vad switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
/ #
/ # amixer cset numid=47 0
numid=47,iface=MIXER,name='vad switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off

Change-Id: Id50c021cc581a8371c680b9d180e56ac6a12cf4e
Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com>
This commit is contained in:
Sugar Zhang
2018-08-28 10:33:44 +08:00
committed by Tao Huang
parent fdb1de7cdc
commit 108ca254dc

View File

@@ -57,6 +57,8 @@ struct rockchip_vad {
struct vad_buf vbuf;
struct vad_params params;
struct vad_uparams uparams;
struct snd_soc_dai *cpu_dai;
struct snd_pcm_substream *substream;
int mode;
u32 audio_src;
u32 audio_src_addr;
@@ -66,6 +68,7 @@ struct rockchip_vad {
struct dentry *debugfs_dir;
void *buf;
bool acodec_cfg;
bool vswitch;
};
struct audio_src_addr_map {
@@ -315,7 +318,10 @@ bool snd_pcm_vad_attached(struct snd_pcm_substream *substream)
if (vad_substream == substream)
vad = substream_get_drvdata(substream);
return vad ? true : false;
if (vad && vad->vswitch)
return true;
else
return false;
}
EXPORT_SYMBOL(snd_pcm_vad_attached);
@@ -535,6 +541,8 @@ static void rockchip_vad_params_fixup(struct snd_pcm_substream *substream,
int i;
cpu_dai = rtd->cpu_dai;
vad->cpu_dai = cpu_dai;
vad->substream = substream;
np = cpu_dai->dev->of_node;
if (of_device_is_compatible(np, "rockchip,multi-dais")) {
audio_src_dai = rockchip_vad_find_dai(vad->audio_node);
@@ -627,18 +635,17 @@ static int rockchip_vad_hw_params(struct snd_pcm_substream *substream,
return 0;
}
static int rockchip_vad_enable_cpudai(struct snd_pcm_substream *substream)
static int rockchip_vad_enable_cpudai(struct rockchip_vad *vad)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai;
struct snd_pcm_substream *substream;
int ret = 0;
if (PCM_RUNTIME_CHECK(substream))
return -EFAULT;
if (!rtd)
return -EFAULT;
cpu_dai = vad->cpu_dai;
substream = vad->substream;
cpu_dai = rtd->cpu_dai;
if (!cpu_dai || !substream)
return 0;
pm_runtime_get_sync(cpu_dai->dev);
@@ -650,6 +657,29 @@ static int rockchip_vad_enable_cpudai(struct snd_pcm_substream *substream)
return ret;
}
static int rockchip_vad_disable_cpudai(struct rockchip_vad *vad)
{
struct snd_soc_dai *cpu_dai;
struct snd_pcm_substream *substream;
int ret = 0;
cpu_dai = vad->cpu_dai;
substream = vad->substream;
if (!cpu_dai || !substream)
return 0;
pm_runtime_get_sync(cpu_dai->dev);
if (cpu_dai->driver->ops && cpu_dai->driver->ops->trigger)
ret = cpu_dai->driver->ops->trigger(substream,
SNDRV_PCM_TRIGGER_STOP,
cpu_dai);
pm_runtime_put(cpu_dai->dev);
return ret;
}
static int rockchip_vad_pcm_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@@ -670,8 +700,10 @@ static void rockchip_vad_pcm_shutdown(struct snd_pcm_substream *substream,
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
return;
rockchip_vad_enable_cpudai(substream);
rockchip_vad_setup(vad);
if (vad->vswitch) {
rockchip_vad_enable_cpudai(vad);
rockchip_vad_setup(vad);
}
vad_substream = NULL;
}
@@ -727,7 +759,68 @@ static struct snd_soc_dai_driver vad_dai = {
.ops = &rockchip_vad_dai_ops,
};
static struct snd_soc_codec_driver soc_vad_codec;
static int rockchip_vad_switch_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->count = 1;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 1;
return 0;
}
static int rockchip_vad_switch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct rockchip_vad *vad = snd_soc_component_get_drvdata(component);
ucontrol->value.integer.value[0] = vad->vswitch;
return 0;
}
static int rockchip_vad_switch_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct rockchip_vad *vad = snd_soc_component_get_drvdata(component);
int val;
val = ucontrol->value.integer.value[0];
if (val && !vad->vswitch) {
vad->vswitch = true;
} else if (!val && vad->vswitch) {
vad->vswitch = false;
regmap_read(vad->regmap, VAD_CTRL, &val);
if ((val & VAD_EN_MASK) == VAD_DISABLE)
return 0;
rockchip_vad_stop(vad);
rockchip_vad_disable_cpudai(vad);
/* this case we don't need vad data */
vad->vbuf.size = 0;
}
return 0;
}
#define SOC_ROCKCHIP_VAD_SWITCH_DECL(xname) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = rockchip_vad_switch_info, .get = rockchip_vad_switch_get, \
.put = rockchip_vad_switch_put, }
static const struct snd_kcontrol_new rockchip_vad_dapm_controls[] = {
SOC_ROCKCHIP_VAD_SWITCH_DECL("vad switch"),
};
static struct snd_soc_codec_driver soc_vad_codec = {
.component_driver = {
.controls = rockchip_vad_dapm_controls,
.num_controls = ARRAY_SIZE(rockchip_vad_dapm_controls),
},
};
#if defined(CONFIG_DEBUG_FS)
#include <linux/fs.h>