Lines Matching +full:i2s +full:- +full:tx +full:- +full:route
1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
16 #include <sound/hdmi-codec.h>
21 #define HDMI_CODEC_CHMAP_IDX_UNKNOWN -1
64 /* Channel maps for multi-channel playbacks, up to 8 n_ch */
293 SND_SOC_DAPM_OUTPUT("TX"),
305 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; in hdmi_eld_ctl_info()
306 uinfo->count = sizeof_field(struct hdmi_codec_priv, eld); in hdmi_eld_ctl_info()
317 memcpy(ucontrol->value.bytes.data, hcp->eld, sizeof(hcp->eld)); in hdmi_eld_ctl_get()
344 spk_alloc = drm_eld_get_spk_alloc(hcp->eld); in hdmi_codec_eld_chmap()
348 if ((spk_mask & ~(FL | FR)) && hcp->chmap_info->max_channels > 2) in hdmi_codec_eld_chmap()
349 hcp->chmap_info->chmap = hdmi_codec_8ch_chmaps; in hdmi_codec_eld_chmap()
351 hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps; in hdmi_codec_eld_chmap()
362 spk_alloc = drm_eld_get_spk_alloc(hcp->eld); in hdmi_codec_get_ch_alloc_table_idx()
367 if (!spk_alloc && cap->ca_id == 0) in hdmi_codec_get_ch_alloc_table_idx()
369 if (cap->n_ch != channels) in hdmi_codec_get_ch_alloc_table_idx()
371 if (!(cap->mask == (spk_mask & cap->mask))) in hdmi_codec_get_ch_alloc_table_idx()
376 return -EINVAL; in hdmi_codec_get_ch_alloc_table_idx()
384 struct hdmi_codec_priv *hcp = info->private_data; in hdmi_codec_chmap_ctl_get()
386 if (hcp->chmap_idx != HDMI_CODEC_CHMAP_IDX_UNKNOWN) in hdmi_codec_chmap_ctl_get()
387 map = info->chmap[hcp->chmap_idx].map; in hdmi_codec_chmap_ctl_get()
389 for (i = 0; i < info->max_channels; i++) { in hdmi_codec_chmap_ctl_get()
390 if (hcp->chmap_idx == HDMI_CODEC_CHMAP_IDX_UNKNOWN) in hdmi_codec_chmap_ctl_get()
391 ucontrol->value.integer.value[i] = 0; in hdmi_codec_chmap_ctl_get()
393 ucontrol->value.integer.value[i] = map[i]; in hdmi_codec_chmap_ctl_get()
402 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; in hdmi_codec_iec958_info()
403 uinfo->count = 1; in hdmi_codec_iec958_info()
413 memcpy(ucontrol->value.iec958.status, hcp->iec_status, in hdmi_codec_iec958_default_get()
414 sizeof(hcp->iec_status)); in hdmi_codec_iec958_default_get()
425 memcpy(hcp->iec_status, ucontrol->value.iec958.status, in hdmi_codec_iec958_default_put()
426 sizeof(hcp->iec_status)); in hdmi_codec_iec958_default_put()
434 memset(ucontrol->value.iec958.status, 0xff, in hdmi_codec_iec958_mask_get()
444 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; in hdmi_codec_startup() local
445 bool has_capture = !hcp->hcd.no_i2s_capture; in hdmi_codec_startup()
446 bool has_playback = !hcp->hcd.no_i2s_playback; in hdmi_codec_startup()
449 if (!((has_playback && tx) || (has_capture && !tx))) in hdmi_codec_startup()
452 mutex_lock(&hcp->lock); in hdmi_codec_startup()
453 if (hcp->busy) { in hdmi_codec_startup()
454 dev_err(dai->dev, "Only one simultaneous stream supported!\n"); in hdmi_codec_startup()
455 mutex_unlock(&hcp->lock); in hdmi_codec_startup()
456 return -EINVAL; in hdmi_codec_startup()
459 if (hcp->hcd.ops->audio_startup) { in hdmi_codec_startup()
460 ret = hcp->hcd.ops->audio_startup(dai->dev->parent, hcp->hcd.data); in hdmi_codec_startup()
465 if (tx && hcp->hcd.ops->get_eld) { in hdmi_codec_startup()
466 ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->hcd.data, in hdmi_codec_startup()
467 hcp->eld, sizeof(hcp->eld)); in hdmi_codec_startup()
471 ret = snd_pcm_hw_constraint_eld(substream->runtime, hcp->eld); in hdmi_codec_startup()
479 hcp->busy = true; in hdmi_codec_startup()
482 mutex_unlock(&hcp->lock); in hdmi_codec_startup()
490 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; in hdmi_codec_shutdown() local
491 bool has_capture = !hcp->hcd.no_i2s_capture; in hdmi_codec_shutdown()
492 bool has_playback = !hcp->hcd.no_i2s_playback; in hdmi_codec_shutdown()
494 if (!((has_playback && tx) || (has_capture && !tx))) in hdmi_codec_shutdown()
497 hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; in hdmi_codec_shutdown()
498 hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data); in hdmi_codec_shutdown()
500 mutex_lock(&hcp->lock); in hdmi_codec_shutdown()
501 hcp->busy = false; in hdmi_codec_shutdown()
502 mutex_unlock(&hcp->lock); in hdmi_codec_shutdown()
514 bool pcm_audio = !(hcp->iec_status[0] & IEC958_AES0_NONAUDIO); in hdmi_codec_fill_codec_params()
521 dev_err(dai->dev, "Not able to map channels to speakers (%d)\n", in hdmi_codec_fill_codec_params()
523 hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; in hdmi_codec_fill_codec_params()
532 hdmi_audio_infoframe_init(&hp->cea); in hdmi_codec_fill_codec_params()
535 hp->cea.channels = channels; in hdmi_codec_fill_codec_params()
537 hp->cea.channels = 0; in hdmi_codec_fill_codec_params()
539 hp->cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; in hdmi_codec_fill_codec_params()
540 hp->cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; in hdmi_codec_fill_codec_params()
541 hp->cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; in hdmi_codec_fill_codec_params()
542 hp->cea.channel_allocation = ca_id; in hdmi_codec_fill_codec_params()
544 hp->sample_width = sample_width; in hdmi_codec_fill_codec_params()
545 hp->sample_rate = sample_rate; in hdmi_codec_fill_codec_params()
546 hp->channels = channels; in hdmi_codec_fill_codec_params()
549 hcp->chmap_idx = ca_id; in hdmi_codec_fill_codec_params()
551 hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; in hdmi_codec_fill_codec_params()
572 if (!hcp->hcd.ops->hw_params) in hdmi_codec_hw_params()
575 dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__, in hdmi_codec_hw_params()
587 memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status)); in hdmi_codec_hw_params()
591 dev_err(dai->dev, "Creating IEC958 channel status failed %d\n", in hdmi_codec_hw_params()
596 cf->bit_fmt = params_format(params); in hdmi_codec_hw_params()
597 return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data, in hdmi_codec_hw_params()
606 struct snd_pcm_runtime *runtime = substream->runtime; in hdmi_codec_prepare()
607 unsigned int channels = runtime->channels; in hdmi_codec_prepare()
608 unsigned int width = snd_pcm_format_width(runtime->format); in hdmi_codec_prepare()
609 unsigned int rate = runtime->rate; in hdmi_codec_prepare()
613 if (!hcp->hcd.ops->prepare) in hdmi_codec_prepare()
616 dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__, in hdmi_codec_prepare()
623 memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status)); in hdmi_codec_prepare()
627 dev_err(dai->dev, "Creating IEC958 channel status failed %d\n", in hdmi_codec_prepare()
632 cf->bit_fmt = runtime->format; in hdmi_codec_prepare()
633 return hcp->hcd.ops->prepare(dai->dev->parent, hcp->hcd.data, in hdmi_codec_prepare()
647 cf->bit_clk_provider = 1; in hdmi_codec_i2s_set_fmt()
648 cf->frame_clk_provider = 1; in hdmi_codec_i2s_set_fmt()
651 cf->frame_clk_provider = 1; in hdmi_codec_i2s_set_fmt()
654 cf->bit_clk_provider = 1; in hdmi_codec_i2s_set_fmt()
659 return -EINVAL; in hdmi_codec_i2s_set_fmt()
666 cf->frame_clk_inv = 1; in hdmi_codec_i2s_set_fmt()
669 cf->bit_clk_inv = 1; in hdmi_codec_i2s_set_fmt()
672 cf->frame_clk_inv = 1; in hdmi_codec_i2s_set_fmt()
673 cf->bit_clk_inv = 1; in hdmi_codec_i2s_set_fmt()
679 cf->fmt = HDMI_I2S; in hdmi_codec_i2s_set_fmt()
682 cf->fmt = HDMI_DSP_A; in hdmi_codec_i2s_set_fmt()
685 cf->fmt = HDMI_DSP_B; in hdmi_codec_i2s_set_fmt()
688 cf->fmt = HDMI_RIGHT_J; in hdmi_codec_i2s_set_fmt()
691 cf->fmt = HDMI_LEFT_J; in hdmi_codec_i2s_set_fmt()
694 cf->fmt = HDMI_AC97; in hdmi_codec_i2s_set_fmt()
697 dev_err(dai->dev, "Invalid DAI interface format\n"); in hdmi_codec_i2s_set_fmt()
698 return -EINVAL; in hdmi_codec_i2s_set_fmt()
714 if (hcp->hcd.ops->mute_stream && in hdmi_codec_mute()
716 !hcp->hcd.ops->no_capture_mute)) in hdmi_codec_mute()
717 return hcp->hcd.ops->mute_stream(dai->dev->parent, in hdmi_codec_mute()
718 hcp->hcd.data, in hdmi_codec_mute()
721 return -ENOTSUPP; in hdmi_codec_mute()
729 * ${LINUX}/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
752 * This list is only for formats allowed on the I2S bus. So there is
754 * instance allowing the 32-bit formats enables 24-precision with CPU
755 * DAIs that do not support 24-bit formats. If the extra formats cause
791 struct snd_soc_dai_driver *drv = dai->driver; in hdmi_codec_pcm_new()
796 ret = snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK, in hdmi_codec_pcm_new()
797 NULL, drv->playback.channels_max, 0, in hdmi_codec_pcm_new()
798 &hcp->chmap_info); in hdmi_codec_pcm_new()
803 hcp->chmap_info->private_data = hcp; in hdmi_codec_pcm_new()
804 hcp->chmap_info->kctl->get = hdmi_codec_chmap_ctl_get; in hdmi_codec_pcm_new()
807 hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps; in hdmi_codec_pcm_new()
808 hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; in hdmi_codec_pcm_new()
814 kctl = snd_ctl_new1(&hdmi_codec_controls[i], dai->component); in hdmi_codec_pcm_new()
816 return -ENOMEM; in hdmi_codec_pcm_new()
818 kctl->id.device = rtd->pcm->device; in hdmi_codec_pcm_new()
819 ret = snd_ctl_add(rtd->card->snd_card, kctl); in hdmi_codec_pcm_new()
831 struct snd_soc_dapm_route route[] = { in hdmi_dai_probe() local
833 .sink = "TX", in hdmi_dai_probe()
834 .source = dai->driver->playback.stream_name, in hdmi_dai_probe()
837 .sink = dai->driver->capture.stream_name, in hdmi_dai_probe()
843 dapm = snd_soc_component_get_dapm(dai->component); in hdmi_dai_probe()
846 for (i = 0; i < ARRAY_SIZE(route); i++) { in hdmi_dai_probe()
847 if (!route[i].source || !route[i].sink) in hdmi_dai_probe()
850 ret = snd_soc_dapm_add_routes(dapm, &route[i], 1); in hdmi_dai_probe()
855 daifmt = devm_kzalloc(dai->dev, sizeof(*daifmt), GFP_KERNEL); in hdmi_dai_probe()
857 return -ENOMEM; in hdmi_dai_probe()
867 if (jack_status != hcp->jack_status) { in hdmi_codec_jack_report()
868 if (hcp->jack) in hdmi_codec_jack_report()
869 snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT); in hdmi_codec_jack_report()
870 hcp->jack_status = jack_status; in hdmi_codec_jack_report()
879 if (hcp->hcd.ops->get_eld) { in plugged_cb()
880 hcp->hcd.ops->get_eld(dev->parent, hcp->hcd.data, in plugged_cb()
881 hcp->eld, sizeof(hcp->eld)); in plugged_cb()
886 memset(hcp->eld, 0, sizeof(hcp->eld)); in plugged_cb()
896 if (hcp->hcd.ops->hook_plugged_cb) { in hdmi_codec_set_jack()
897 hcp->jack = jack; in hdmi_codec_set_jack()
903 snd_soc_jack_report(jack, hcp->jack_status, SND_JACK_LINEOUT); in hdmi_codec_set_jack()
908 return -ENOTSUPP; in hdmi_codec_set_jack()
921 cf->fmt = HDMI_SPDIF; in hdmi_dai_spdif_probe()
949 .name = "i2s-hifi",
952 .stream_name = "I2S Playback",
971 .name = "spdif-hifi",
994 int ret = -ENOTSUPP; /* see snd_soc_get_dai_id() */ in hdmi_of_xlate_dai_id()
996 if (hcp->hcd.ops->get_dai_id) in hdmi_of_xlate_dai_id()
997 ret = hcp->hcd.ops->get_dai_id(component, endpoint); in hdmi_of_xlate_dai_id()
1007 if (hcp->hcd.ops->hook_plugged_cb) { in hdmi_probe()
1008 ret = hcp->hcd.ops->hook_plugged_cb(component->dev->parent, in hdmi_probe()
1009 hcp->hcd.data, in hdmi_probe()
1011 component->dev); in hdmi_probe()
1021 if (hcp->hcd.ops->hook_plugged_cb) in hdmi_remove()
1022 hcp->hcd.ops->hook_plugged_cb(component->dev->parent, in hdmi_remove()
1023 hcp->hcd.data, NULL, NULL); in hdmi_remove()
1040 struct hdmi_codec_pdata *hcd = pdev->dev.platform_data; in hdmi_codec_probe()
1042 struct device *dev = &pdev->dev; in hdmi_codec_probe()
1049 return -EINVAL; in hdmi_codec_probe()
1052 dai_count = hcd->i2s + hcd->spdif; in hdmi_codec_probe()
1053 if (dai_count < 1 || !hcd->ops || in hdmi_codec_probe()
1054 (!hcd->ops->hw_params && !hcd->ops->prepare) || in hdmi_codec_probe()
1055 !hcd->ops->audio_shutdown) { in hdmi_codec_probe()
1057 return -EINVAL; in hdmi_codec_probe()
1062 return -ENOMEM; in hdmi_codec_probe()
1064 hcp->hcd = *hcd; in hdmi_codec_probe()
1065 mutex_init(&hcp->lock); in hdmi_codec_probe()
1067 ret = snd_pcm_create_iec958_consumer_default(hcp->iec_status, in hdmi_codec_probe()
1068 sizeof(hcp->iec_status)); in hdmi_codec_probe()
1074 return -ENOMEM; in hdmi_codec_probe()
1076 if (hcd->i2s) { in hdmi_codec_probe()
1078 daidrv[i].playback.channels_max = hcd->max_i2s_channels; in hdmi_codec_probe()
1079 if (hcd->no_i2s_playback) in hdmi_codec_probe()
1082 if (hcd->no_i2s_capture) in hdmi_codec_probe()
1088 if (hcd->spdif) { in hdmi_codec_probe()
1090 if (hcd->no_spdif_playback) in hdmi_codec_probe()
1093 if (hcd->no_spdif_capture) in hdmi_codec_probe()