From 8ce747aebf231b3d8ae066f5693cd329f7bf6e62 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Tue, 27 Aug 2019 21:16:41 +0800 Subject: [PATCH] ASoC: codec: hdmi-codec: add support for audio mode config Change-Id: I4813e6204fee894ef4f40b3e3b768a1ad94d0a29 Signed-off-by: Sugar Zhang --- include/sound/hdmi-codec.h | 7 +++++ sound/soc/codecs/hdmi-codec.c | 51 +++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h index 9483c55f871b..52d16ded8c21 100644 --- a/include/sound/hdmi-codec.h +++ b/include/sound/hdmi-codec.h @@ -53,6 +53,13 @@ struct hdmi_codec_params { int sample_rate; int sample_width; int channels; + int mode; +}; + +enum { + LPCM = 0, + NLPCM, + HBR, }; struct hdmi_codec_pdata; diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 7994e8ddc7d2..77203706c2d5 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -285,6 +285,7 @@ struct hdmi_codec_priv { uint8_t eld[MAX_ELD_BYTES]; struct snd_pcm_chmap *chmap_info; unsigned int chmap_idx; + unsigned int mode; }; static const struct snd_soc_dapm_widget hdmi_widgets[] = { @@ -316,6 +317,36 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, return 0; } +static int hdmi_audio_mode_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = HBR; + return 0; +} + +static int hdmi_audio_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = hcp->mode; + return 0; +} + +static int hdmi_audio_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component); + + hcp->mode = ucontrol->value.integer.value[0]; + return 0; +} + static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc) { int i; @@ -523,6 +554,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, hp.sample_width = params_width(params); hp.sample_rate = params_rate(params); hp.channels = params_channels(params); + hp.mode = hcp->mode; return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data, &hcp->daifmt[dai->id], &hp); @@ -661,6 +693,16 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, .get = hdmi_eld_ctl_get, .device = rtd->pcm->device, }; + struct snd_kcontrol_new hdmi_mode_ctl = { + .access = SNDRV_CTL_ELEM_ACCESS_READ | + SNDRV_CTL_ELEM_ACCESS_WRITE | + SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "AUDIO MODE", + .info = hdmi_audio_mode_info, + .get = hdmi_audio_mode_get, + .put = hdmi_audio_mode_put, + }; int ret; dev_dbg(dai->dev, "%s()\n", __func__); @@ -684,6 +726,15 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, if (!kctl) return -ENOMEM; + ret = snd_ctl_add(rtd->card->snd_card, kctl); + if (ret < 0) + return ret; + + /* add MODE ctl with the device number corresponding to the PCM stream */ + kctl = snd_ctl_new1(&hdmi_mode_ctl, dai->component); + if (!kctl) + return -ENOMEM; + return snd_ctl_add(rtd->card->snd_card, kctl); }