Skip to content

Commit

Permalink
ASoC: hdmi-codec: Add iec958 controls
Browse files Browse the repository at this point in the history
The IEC958 status bits can be exposed and modified by the userspace
through dedicated ALSA controls.

This patch implements those controls for the hdmi-codec driver. It
relies on a default value being setup at probe time that can later be
overridden by the control put.

The hw_params callback is then called with a buffer filled with the
proper bits for the current parameters being passed on so the underlying
driver can just reuse those bits as is.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Acked-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20210525132354.297468-5-maxime@cerno.tech
  • Loading branch information
Maxime Ripard committed Jun 10, 2021
1 parent 366b45b commit 7a8e1d4
Showing 1 changed file with 64 additions and 2 deletions.
66 changes: 64 additions & 2 deletions sound/soc/codecs/hdmi-codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ struct hdmi_codec_priv {
bool busy;
struct snd_soc_jack *jack;
unsigned int jack_status;
u8 iec_status[5];
};

static const struct snd_soc_dapm_widget hdmi_widgets[] = {
Expand Down Expand Up @@ -385,6 +386,47 @@ static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol,
return 0;
}

static int hdmi_codec_iec958_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
uinfo->count = 1;
return 0;
}

static int hdmi_codec_iec958_default_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);

memcpy(ucontrol->value.iec958.status, hcp->iec_status,
sizeof(hcp->iec_status));

return 0;
}

static int hdmi_codec_iec958_default_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);

memcpy(hcp->iec_status, ucontrol->value.iec958.status,
sizeof(hcp->iec_status));

return 0;
}

static int hdmi_codec_iec958_mask_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
memset(ucontrol->value.iec958.status, 0xff,
sizeof_field(struct hdmi_codec_priv, iec_status));

return 0;
}

static int hdmi_codec_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
Expand Down Expand Up @@ -459,8 +501,9 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
params_width(params), params_rate(params),
params_channels(params));

ret = snd_pcm_create_iec958_consumer_hw_params(params, hp.iec.status,
sizeof(hp.iec.status));
memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status));
ret = snd_pcm_fill_iec958_consumer_hw_params(params, hp.iec.status,
sizeof(hp.iec.status));
if (ret < 0) {
dev_err(dai->dev, "Creating IEC958 channel status failed %d\n",
ret);
Expand Down Expand Up @@ -621,6 +664,20 @@ static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = {
SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)

struct snd_kcontrol_new hdmi_codec_controls[] = {
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
.info = hdmi_codec_iec958_info,
.get = hdmi_codec_iec958_mask_get,
},
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
.info = hdmi_codec_iec958_info,
.get = hdmi_codec_iec958_default_get,
.put = hdmi_codec_iec958_default_put,
},
{
.access = (SNDRV_CTL_ELEM_ACCESS_READ |
SNDRV_CTL_ELEM_ACCESS_VOLATILE),
Expand Down Expand Up @@ -873,6 +930,11 @@ static int hdmi_codec_probe(struct platform_device *pdev)
hcp->hcd = *hcd;
mutex_init(&hcp->lock);

ret = snd_pcm_create_iec958_consumer_default(hcp->iec_status,
sizeof(hcp->iec_status));
if (ret < 0)
return ret;

daidrv = devm_kcalloc(dev, dai_count, sizeof(*daidrv), GFP_KERNEL);
if (!daidrv)
return -ENOMEM;
Expand Down

0 comments on commit 7a8e1d4

Please sign in to comment.