Lines Matching +full:playback +full:- +full:channels

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
63 { .channels = 2,
68 /* Channel maps for multi-channel playbacks, up to 8 n_ch */
70 { .channels = 2, /* CA_ID 0x00 */
72 { .channels = 4, /* CA_ID 0x01 */
75 { .channels = 4, /* CA_ID 0x02 */
78 { .channels = 4, /* CA_ID 0x03 */
81 { .channels = 6, /* CA_ID 0x04 */
84 { .channels = 6, /* CA_ID 0x05 */
87 { .channels = 6, /* CA_ID 0x06 */
90 { .channels = 6, /* CA_ID 0x07 */
93 { .channels = 6, /* CA_ID 0x08 */
96 { .channels = 6, /* CA_ID 0x09 */
99 { .channels = 6, /* CA_ID 0x0A */
102 { .channels = 6, /* CA_ID 0x0B */
105 { .channels = 8, /* CA_ID 0x0C */
109 { .channels = 8, /* CA_ID 0x0D */
113 { .channels = 8, /* CA_ID 0x0E */
117 { .channels = 8, /* CA_ID 0x0F */
121 { .channels = 8, /* CA_ID 0x10 */
125 { .channels = 8, /* CA_ID 0x11 */
129 { .channels = 8, /* CA_ID 0x12 */
133 { .channels = 8, /* CA_ID 0x13 */
137 { .channels = 8, /* CA_ID 0x14 */
141 { .channels = 8, /* CA_ID 0x15 */
145 { .channels = 8, /* CA_ID 0x16 */
149 { .channels = 8, /* CA_ID 0x17 */
153 { .channels = 8, /* CA_ID 0x18 */
157 { .channels = 8, /* CA_ID 0x19 */
161 { .channels = 8, /* CA_ID 0x1A */
165 { .channels = 8, /* CA_ID 0x1B */
169 { .channels = 8, /* CA_ID 0x1C */
173 { .channels = 8, /* CA_ID 0x1D */
177 { .channels = 8, /* CA_ID 0x1E */
181 { .channels = 8, /* CA_ID 0x1F */
298 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; in hdmi_eld_ctl_info()
299 uinfo->count = sizeof_field(struct hdmi_codec_priv, eld); in hdmi_eld_ctl_info()
310 memcpy(ucontrol->value.bytes.data, hcp->eld, sizeof(hcp->eld)); in hdmi_eld_ctl_get()
337 spk_alloc = drm_eld_get_spk_alloc(hcp->eld); in hdmi_codec_eld_chmap()
340 /* Detect if only stereo supported, else return 8 channels mappings */ in hdmi_codec_eld_chmap()
341 if ((spk_mask & ~(FL | FR)) && hcp->chmap_info->max_channels > 2) in hdmi_codec_eld_chmap()
342 hcp->chmap_info->chmap = hdmi_codec_8ch_chmaps; in hdmi_codec_eld_chmap()
344 hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps; in hdmi_codec_eld_chmap()
348 unsigned char channels) in hdmi_codec_get_ch_alloc_table_idx() argument
355 if (hcp->eld_bypass) in hdmi_codec_get_ch_alloc_table_idx()
358 spk_alloc = drm_eld_get_spk_alloc(hcp->eld); in hdmi_codec_get_ch_alloc_table_idx()
363 if (!spk_alloc && cap->ca_id == 0) in hdmi_codec_get_ch_alloc_table_idx()
365 if (cap->n_ch != channels) in hdmi_codec_get_ch_alloc_table_idx()
367 if (!(cap->mask == (spk_mask & cap->mask))) in hdmi_codec_get_ch_alloc_table_idx()
372 return -EINVAL; in hdmi_codec_get_ch_alloc_table_idx()
380 struct hdmi_codec_priv *hcp = info->private_data; in hdmi_codec_chmap_ctl_get()
382 map = info->chmap[hcp->chmap_idx].map; in hdmi_codec_chmap_ctl_get()
384 for (i = 0; i < info->max_channels; i++) { in hdmi_codec_chmap_ctl_get()
385 if (hcp->chmap_idx == HDMI_CODEC_CHMAP_IDX_UNKNOWN) in hdmi_codec_chmap_ctl_get()
386 ucontrol->value.integer.value[i] = 0; in hdmi_codec_chmap_ctl_get()
388 ucontrol->value.integer.value[i] = map[i]; in hdmi_codec_chmap_ctl_get()
397 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; in hdmi_codec_iec958_info()
398 uinfo->count = 1; in hdmi_codec_iec958_info()
408 memcpy(ucontrol->value.iec958.status, hcp->iec_status, in hdmi_codec_iec958_default_get()
409 sizeof(hcp->iec_status)); in hdmi_codec_iec958_default_get()
420 memcpy(hcp->iec_status, ucontrol->value.iec958.status, in hdmi_codec_iec958_default_put()
421 sizeof(hcp->iec_status)); in hdmi_codec_iec958_default_put()
429 memset(ucontrol->value.iec958.status, 0xff, in hdmi_codec_iec958_mask_get()
441 ucontrol->value.integer.value[0] = hcp->eld_bypass; in hdmi_codec_eld_bypass_get()
452 if (hcp->eld_bypass == ucontrol->value.integer.value[0]) in hdmi_codec_eld_bypass_put()
455 hcp->eld_bypass = ucontrol->value.integer.value[0]; in hdmi_codec_eld_bypass_put()
464 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; in hdmi_codec_startup()
467 mutex_lock(&hcp->lock); in hdmi_codec_startup()
468 if (hcp->busy) { in hdmi_codec_startup()
469 dev_err(dai->dev, "Only one simultaneous stream supported!\n"); in hdmi_codec_startup()
470 mutex_unlock(&hcp->lock); in hdmi_codec_startup()
471 return -EINVAL; in hdmi_codec_startup()
474 if (hcp->hcd.ops->audio_startup) { in hdmi_codec_startup()
475 ret = hcp->hcd.ops->audio_startup(dai->dev->parent, hcp->hcd.data); in hdmi_codec_startup()
480 if (tx && !hcp->eld_bypass && hcp->hcd.ops->get_eld) { in hdmi_codec_startup()
481 ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->hcd.data, in hdmi_codec_startup()
482 hcp->eld, sizeof(hcp->eld)); in hdmi_codec_startup()
486 ret = snd_pcm_hw_constraint_eld(substream->runtime, hcp->eld); in hdmi_codec_startup()
494 hcp->busy = true; in hdmi_codec_startup()
495 hcp->substream = substream; in hdmi_codec_startup()
498 mutex_unlock(&hcp->lock); in hdmi_codec_startup()
507 hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; in hdmi_codec_shutdown()
508 hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data); in hdmi_codec_shutdown()
510 mutex_lock(&hcp->lock); in hdmi_codec_shutdown()
511 hcp->substream = NULL; in hdmi_codec_shutdown()
512 hcp->busy = false; in hdmi_codec_shutdown()
513 mutex_unlock(&hcp->lock); in hdmi_codec_shutdown()
519 unsigned int channels, in hdmi_codec_fill_codec_params() argument
525 /* Select a channel allocation that matches with ELD and pcm channels */ in hdmi_codec_fill_codec_params()
526 idx = hdmi_codec_get_ch_alloc_table_idx(hcp, channels); in hdmi_codec_fill_codec_params()
528 dev_err(dai->dev, "Not able to map channels to speakers (%d)\n", in hdmi_codec_fill_codec_params()
530 hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; in hdmi_codec_fill_codec_params()
536 hdmi_audio_infoframe_init(&hp->cea); in hdmi_codec_fill_codec_params()
537 hp->cea.channels = channels; in hdmi_codec_fill_codec_params()
538 hp->cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; in hdmi_codec_fill_codec_params()
539 hp->cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; in hdmi_codec_fill_codec_params()
540 hp->cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; in hdmi_codec_fill_codec_params()
541 hp->cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id; in hdmi_codec_fill_codec_params()
543 hp->sample_width = sample_width; in hdmi_codec_fill_codec_params()
544 hp->sample_rate = sample_rate; in hdmi_codec_fill_codec_params()
545 hp->channels = channels; in hdmi_codec_fill_codec_params()
547 hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id; in hdmi_codec_fill_codec_params()
557 struct hdmi_codec_daifmt *cf = dai->playback_dma_data; in hdmi_codec_hw_params()
568 if (!hcp->hcd.ops->hw_params) in hdmi_codec_hw_params()
571 dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__, in hdmi_codec_hw_params()
583 memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status)); in hdmi_codec_hw_params()
587 dev_err(dai->dev, "Creating IEC958 channel status failed %d\n", in hdmi_codec_hw_params()
592 cf->bit_fmt = params_format(params); in hdmi_codec_hw_params()
593 return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data, in hdmi_codec_hw_params()
601 struct hdmi_codec_daifmt *cf = dai->playback_dma_data; in hdmi_codec_prepare()
602 struct snd_pcm_runtime *runtime = substream->runtime; in hdmi_codec_prepare()
603 unsigned int channels = runtime->channels; in hdmi_codec_prepare() local
604 unsigned int width = snd_pcm_format_width(runtime->format); in hdmi_codec_prepare()
605 unsigned int rate = runtime->rate; in hdmi_codec_prepare()
609 if (!hcp->hcd.ops->prepare) in hdmi_codec_prepare()
612 dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__, in hdmi_codec_prepare()
613 width, rate, channels); in hdmi_codec_prepare()
615 ret = hdmi_codec_fill_codec_params(dai, width, rate, channels, &hp); in hdmi_codec_prepare()
619 memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status)); in hdmi_codec_prepare()
623 dev_err(dai->dev, "Creating IEC958 channel status failed %d\n", in hdmi_codec_prepare()
628 cf->bit_fmt = runtime->format; in hdmi_codec_prepare()
629 return hcp->hcd.ops->prepare(dai->dev->parent, hcp->hcd.data, in hdmi_codec_prepare()
636 struct hdmi_codec_daifmt *cf = dai->playback_dma_data; in hdmi_codec_i2s_set_fmt()
643 cf->bit_clk_master = 1; in hdmi_codec_i2s_set_fmt()
644 cf->frame_clk_master = 1; in hdmi_codec_i2s_set_fmt()
647 cf->frame_clk_master = 1; in hdmi_codec_i2s_set_fmt()
650 cf->bit_clk_master = 1; in hdmi_codec_i2s_set_fmt()
655 return -EINVAL; in hdmi_codec_i2s_set_fmt()
662 cf->frame_clk_inv = 1; in hdmi_codec_i2s_set_fmt()
665 cf->bit_clk_inv = 1; in hdmi_codec_i2s_set_fmt()
668 cf->frame_clk_inv = 1; in hdmi_codec_i2s_set_fmt()
669 cf->bit_clk_inv = 1; in hdmi_codec_i2s_set_fmt()
675 cf->fmt = HDMI_I2S; in hdmi_codec_i2s_set_fmt()
678 cf->fmt = HDMI_DSP_A; in hdmi_codec_i2s_set_fmt()
681 cf->fmt = HDMI_DSP_B; in hdmi_codec_i2s_set_fmt()
684 cf->fmt = HDMI_RIGHT_J; in hdmi_codec_i2s_set_fmt()
687 cf->fmt = HDMI_LEFT_J; in hdmi_codec_i2s_set_fmt()
690 cf->fmt = HDMI_AC97; in hdmi_codec_i2s_set_fmt()
693 dev_err(dai->dev, "Invalid DAI interface format\n"); in hdmi_codec_i2s_set_fmt()
694 return -EINVAL; in hdmi_codec_i2s_set_fmt()
710 if (hcp->hcd.ops->mute_stream && in hdmi_codec_mute()
712 !hcp->hcd.ops->no_capture_mute)) in hdmi_codec_mute()
713 return hcp->hcd.ops->mute_stream(dai->dev->parent, in hdmi_codec_mute()
714 hcp->hcd.data, in hdmi_codec_mute()
717 return -ENOTSUPP; in hdmi_codec_mute()
749 * instance allowing the 32-bit formats enables 24-precision with CPU
750 * DAIs that do not support 24-bit formats. If the extra formats cause
765 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
771 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
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()
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()
850 return -ENOMEM; in hdmi_dai_probe()
852 dai->playback_dma_data = daifmt; in hdmi_dai_probe()
859 if (hcp->jack && jack_status != hcp->jack_status) { in hdmi_codec_jack_report()
860 snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT); in hdmi_codec_jack_report()
861 hcp->jack_status = jack_status; in hdmi_codec_jack_report()
870 if (!hcp->eld_bypass && hcp->hcd.ops->get_eld) { in plugged_cb()
871 hcp->hcd.ops->get_eld(dev->parent, hcp->hcd.data, in plugged_cb()
872 hcp->eld, sizeof(hcp->eld)); in plugged_cb()
877 memset(hcp->eld, 0, sizeof(hcp->eld)); in plugged_cb()
880 mutex_lock(&hcp->lock); in plugged_cb()
881 if (hcp->substream) { in plugged_cb()
883 * Workaround for HDMIIN and HDMIOUT plug-{in,out} when streaming. in plugged_cb()
886 * plug-{out,in} event. but for better experience and depop stream, in plugged_cb()
889 * a) Do stop stream for HDMIIN on plug-out when streaming. in plugged_cb()
894 * b) Do stop stream for HDMIOUT on plug-in when streaming. in plugged_cb()
895 * because HDMIOUT work as MASTER mode, there is no clk-issue like in plugged_cb()
899 * we stop stream to notify user to re-open and configure sound card in plugged_cb()
902 int stream = hcp->substream->stream; in plugged_cb()
905 snd_pcm_stop(hcp->substream, SNDRV_PCM_STATE_SETUP); in plugged_cb()
907 snd_pcm_stop(hcp->substream, SNDRV_PCM_STATE_DISCONNECTED); in plugged_cb()
911 mutex_unlock(&hcp->lock); in plugged_cb()
919 int ret = -ENOTSUPP; in hdmi_codec_set_jack()
921 if (hcp->hcd.ops->hook_plugged_cb) { in hdmi_codec_set_jack()
922 hcp->jack = jack; in hdmi_codec_set_jack()
923 ret = hcp->hcd.ops->hook_plugged_cb(component->dev->parent, in hdmi_codec_set_jack()
924 hcp->hcd.data, in hdmi_codec_set_jack()
926 component->dev); in hdmi_codec_set_jack()
928 hcp->jack = NULL; in hdmi_codec_set_jack()
942 cf = dai->playback_dma_data; in hdmi_dai_spdif_probe()
943 cf->fmt = HDMI_SPDIF; in hdmi_dai_spdif_probe()
950 kfree(dai->playback_dma_data); in hdmi_codec_dai_remove()
955 .name = "i2s-hifi",
959 .playback = {
960 .stream_name = "I2S Playback",
980 .name = "spdif-hifi",
984 .playback = {
985 .stream_name = "SPDIF Playback",
1006 int ret = -ENOTSUPP; /* see snd_soc_get_dai_id() */ in hdmi_of_xlate_dai_id()
1008 if (hcp->hcd.ops->get_dai_id) in hdmi_of_xlate_dai_id()
1009 ret = hcp->hcd.ops->get_dai_id(component, endpoint); in hdmi_of_xlate_dai_id()
1018 if (hcp->hcd.ops->hook_plugged_cb) in hdmi_remove()
1019 hcp->hcd.ops->hook_plugged_cb(component->dev->parent, in hdmi_remove()
1020 hcp->hcd.data, NULL, NULL); in hdmi_remove()
1037 struct hdmi_codec_pdata *hcd = pdev->dev.platform_data; in hdmi_codec_probe()
1039 struct device *dev = &pdev->dev; in hdmi_codec_probe()
1046 return -EINVAL; in hdmi_codec_probe()
1049 dai_count = hcd->i2s + hcd->spdif; in hdmi_codec_probe()
1050 if (dai_count < 1 || !hcd->ops || in hdmi_codec_probe()
1051 (!hcd->ops->hw_params && !hcd->ops->prepare) || in hdmi_codec_probe()
1052 !hcd->ops->audio_shutdown) { in hdmi_codec_probe()
1054 return -EINVAL; in hdmi_codec_probe()
1059 return -ENOMEM; in hdmi_codec_probe()
1061 hcp->hcd = *hcd; in hdmi_codec_probe()
1062 mutex_init(&hcp->lock); in hdmi_codec_probe()
1064 ret = snd_pcm_create_iec958_consumer_default(hcp->iec_status, in hdmi_codec_probe()
1065 sizeof(hcp->iec_status)); in hdmi_codec_probe()
1071 return -ENOMEM; in hdmi_codec_probe()
1073 if (hcd->i2s) { in hdmi_codec_probe()
1075 daidrv[i].playback.channels_max = hcd->max_i2s_channels; in hdmi_codec_probe()
1079 if (hcd->spdif) in hdmi_codec_probe()