Lines Matching +full:0 +full:- +full:7 +full:a +full:- +full:e
1 // SPDX-License-Identifier: GPL-2.0-or-later
26 CEA_EDID_VER_NONE = 0,
36 "2-reserved",
37 "3-reserved"
41 AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0,
48 AUDIO_CODING_TYPE_DTS = 7,
64 AUDIO_CODING_XTYPE_HE_REF_CT = 0,
72 /* 0 */ "undefined",
74 /* 2 */ "AC-3",
78 /* 6 */ "AAC-LC",
79 /* 7 */ "DTS",
82 /* 10 */ "E-AC-3/DD+ (Dolby Digital Plus)",
83 /* 11 */ "DTS-HD",
87 /* 15 */ "HE-AAC",
88 /* 16 */ "HE-AACv2",
94 * - HDMI audio InfoFrame (source to sink)
95 * - CEA E-EDID Extension (sink to source)
102 0, /* 0: Refer to Stream Header */
112 0, /* 0: Refer to Stream Header */
119 SNDRV_PCM_RATE_192000, /* 7: 192000Hz */
127 val = snd_hda_codec_read(codec, nid, 0, in hdmi_get_eld_data()
130 codec_info(codec, "HDMI: ELD data byte %d: 0x%x\n", byte_index, val); in hdmi_get_eld_data()
137 BUILD_BUG_ON(lowbit > 7); \
139 BUILD_BUG_ON(bits <= 0); \
141 (buf[byte] >> (lowbit)) & ((1 << (bits)) - 1); \
145 struct cea_sad *a, in hdmi_update_short_audio_desc() argument
151 val = GRAB_BITS(buf, 1, 0, 7); in hdmi_update_short_audio_desc()
152 a->rates = 0; in hdmi_update_short_audio_desc()
153 for (i = 0; i < 7; i++) in hdmi_update_short_audio_desc()
155 a->rates |= cea_sampling_frequencies[i + 1]; in hdmi_update_short_audio_desc()
157 a->channels = GRAB_BITS(buf, 0, 0, 3); in hdmi_update_short_audio_desc()
158 a->channels++; in hdmi_update_short_audio_desc()
160 a->sample_bits = 0; in hdmi_update_short_audio_desc()
161 a->max_bitrate = 0; in hdmi_update_short_audio_desc()
163 a->format = GRAB_BITS(buf, 0, 3, 4); in hdmi_update_short_audio_desc()
164 switch (a->format) { in hdmi_update_short_audio_desc()
166 codec_info(codec, "HDMI: audio coding type 0 not expected\n"); in hdmi_update_short_audio_desc()
170 val = GRAB_BITS(buf, 2, 0, 3); in hdmi_update_short_audio_desc()
171 for (i = 0; i < 3; i++) in hdmi_update_short_audio_desc()
173 a->sample_bits |= cea_sample_sizes[i + 1]; in hdmi_update_short_audio_desc()
183 a->max_bitrate = GRAB_BITS(buf, 2, 0, 8); in hdmi_update_short_audio_desc()
184 a->max_bitrate *= 8000; in hdmi_update_short_audio_desc()
203 a->profile = GRAB_BITS(buf, 2, 0, 3); in hdmi_update_short_audio_desc()
207 a->format = GRAB_BITS(buf, 2, 3, 5); in hdmi_update_short_audio_desc()
208 if (a->format == AUDIO_CODING_XTYPE_HE_REF_CT || in hdmi_update_short_audio_desc()
209 a->format >= AUDIO_CODING_XTYPE_FIRST_RESERVED) { in hdmi_update_short_audio_desc()
212 a->format); in hdmi_update_short_audio_desc()
213 a->format = 0; in hdmi_update_short_audio_desc()
215 a->format += AUDIO_CODING_TYPE_HE_AAC - in hdmi_update_short_audio_desc()
224 int snd_hdmi_parse_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e, in snd_hdmi_parse_eld() argument
230 memset(e, 0, sizeof(*e)); in snd_hdmi_parse_eld()
231 e->eld_ver = GRAB_BITS(buf, 0, 3, 5); in snd_hdmi_parse_eld()
232 if (e->eld_ver != ELD_VER_CEA_861D && in snd_hdmi_parse_eld()
233 e->eld_ver != ELD_VER_PARTIAL) { in snd_hdmi_parse_eld()
234 codec_info(codec, "HDMI: Unknown ELD version %d\n", e->eld_ver); in snd_hdmi_parse_eld()
238 e->baseline_len = GRAB_BITS(buf, 2, 0, 8); in snd_hdmi_parse_eld()
239 mnl = GRAB_BITS(buf, 4, 0, 5); in snd_hdmi_parse_eld()
240 e->cea_edid_ver = GRAB_BITS(buf, 4, 5, 3); in snd_hdmi_parse_eld()
242 e->support_hdcp = GRAB_BITS(buf, 5, 0, 1); in snd_hdmi_parse_eld()
243 e->support_ai = GRAB_BITS(buf, 5, 1, 1); in snd_hdmi_parse_eld()
244 e->conn_type = GRAB_BITS(buf, 5, 2, 2); in snd_hdmi_parse_eld()
245 e->sad_count = GRAB_BITS(buf, 5, 4, 4); in snd_hdmi_parse_eld()
247 e->aud_synch_delay = GRAB_BITS(buf, 6, 0, 8) * 2; in snd_hdmi_parse_eld()
248 e->spk_alloc = GRAB_BITS(buf, 7, 0, 7); in snd_hdmi_parse_eld()
250 e->port_id = get_unaligned_le64(buf + 8); in snd_hdmi_parse_eld()
253 e->manufacture_id = get_unaligned_le16(buf + 16); in snd_hdmi_parse_eld()
254 e->product_id = get_unaligned_le16(buf + 18); in snd_hdmi_parse_eld()
263 strscpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl + 1); in snd_hdmi_parse_eld()
265 for (i = 0; i < e->sad_count; i++) { in snd_hdmi_parse_eld()
270 hdmi_update_short_audio_desc(codec, e->sad + i, in snd_hdmi_parse_eld()
275 * HDMI sink's ELD info cannot always be retrieved for now, e.g. in snd_hdmi_parse_eld()
277 * configuration, to _not_ prohibit multi-channel audio playback. in snd_hdmi_parse_eld()
279 if (!e->spk_alloc) in snd_hdmi_parse_eld()
280 e->spk_alloc = 0xffff; in snd_hdmi_parse_eld()
282 return 0; in snd_hdmi_parse_eld()
285 return -EINVAL; in snd_hdmi_parse_eld()
290 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE, in snd_hdmi_get_eld_size()
298 int ret = 0; in snd_hdmi_get_eld()
307 if (size == 0) { in snd_hdmi_get_eld()
308 /* wfg: workaround for ASUS P5E-VM HDMI board */ in snd_hdmi_get_eld()
309 codec_info(codec, "HDMI: ELD buf size is 0, force 128\n"); in snd_hdmi_get_eld()
314 return -ERANGE; in snd_hdmi_get_eld()
318 for (i = 0; i < size; i++) { in snd_hdmi_get_eld()
322 * Just abort. The caller will repoll after a while. in snd_hdmi_get_eld()
326 ret = -EINVAL; in snd_hdmi_get_eld()
333 * to return non-zero ELD data, even when the graphics driver in snd_hdmi_get_eld()
337 codec_dbg(codec, "HDMI: 0 ELD data\n"); in snd_hdmi_get_eld()
338 ret = -EINVAL; in snd_hdmi_get_eld()
351 * hdmi-specific routine.
361 for (i = 0, j = 0; i < ARRAY_SIZE(alsa_rates); i++) in hdmi_print_pcm_rates()
363 j += scnprintf(buf + j, buflen - j, " %d", in hdmi_print_pcm_rates()
366 buf[j] = '\0'; /* necessary when j == 0 */ in hdmi_print_pcm_rates()
372 struct cea_sad *a) in hdmi_show_short_audio_desc() argument
377 if (!a->format) in hdmi_show_short_audio_desc()
380 hdmi_print_pcm_rates(a->rates, buf, sizeof(buf)); in hdmi_show_short_audio_desc()
382 if (a->format == AUDIO_CODING_TYPE_LPCM) in hdmi_show_short_audio_desc()
383 snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2) - 8); in hdmi_show_short_audio_desc()
384 else if (a->max_bitrate) in hdmi_show_short_audio_desc()
386 ", max bitrate = %d", a->max_bitrate); in hdmi_show_short_audio_desc()
388 buf2[0] = '\0'; in hdmi_show_short_audio_desc()
392 cea_audio_coding_type_names[a->format], in hdmi_show_short_audio_desc()
393 a->channels, buf, buf2); in hdmi_show_short_audio_desc()
396 void snd_hdmi_show_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e) in snd_hdmi_show_eld() argument
401 e->monitor_name, in snd_hdmi_show_eld()
402 eld_connection_type_names[e->conn_type]); in snd_hdmi_show_eld()
404 if (e->spk_alloc) { in snd_hdmi_show_eld()
406 snd_hdac_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); in snd_hdmi_show_eld()
410 for (i = 0; i < e->sad_count; i++) in snd_hdmi_show_eld()
411 hdmi_show_short_audio_desc(codec, e->sad + i); in snd_hdmi_show_eld()
416 static void hdmi_print_sad_info(int i, struct cea_sad *a, in hdmi_print_sad_info() argument
421 snd_iprintf(buffer, "sad%d_coding_type\t[0x%x] %s\n", in hdmi_print_sad_info()
422 i, a->format, cea_audio_coding_type_names[a->format]); in hdmi_print_sad_info()
423 snd_iprintf(buffer, "sad%d_channels\t\t%d\n", i, a->channels); in hdmi_print_sad_info()
425 hdmi_print_pcm_rates(a->rates, buf, sizeof(buf)); in hdmi_print_sad_info()
426 snd_iprintf(buffer, "sad%d_rates\t\t[0x%x]%s\n", i, a->rates, buf); in hdmi_print_sad_info()
428 if (a->format == AUDIO_CODING_TYPE_LPCM) { in hdmi_print_sad_info()
429 snd_print_pcm_bits(a->sample_bits, buf, sizeof(buf)); in hdmi_print_sad_info()
430 snd_iprintf(buffer, "sad%d_bits\t\t[0x%x]%s\n", in hdmi_print_sad_info()
431 i, a->sample_bits, buf); in hdmi_print_sad_info()
434 if (a->max_bitrate) in hdmi_print_sad_info()
436 i, a->max_bitrate); in hdmi_print_sad_info()
438 if (a->profile) in hdmi_print_sad_info()
439 snd_iprintf(buffer, "sad%d_profile\t\t%d\n", i, a->profile); in hdmi_print_sad_info()
446 struct parsed_hdmi_eld *e = &eld->info; in snd_hdmi_print_eld_info() local
452 "CEA-861D or below", in snd_hdmi_print_eld_info()
458 "CEA-861", in snd_hdmi_print_eld_info()
459 "CEA-861-A", in snd_hdmi_print_eld_info()
460 "CEA-861-B, C or D", in snd_hdmi_print_eld_info()
461 [4 ... 7] = "reserved" in snd_hdmi_print_eld_info()
464 snd_iprintf(buffer, "monitor_present\t\t%d\n", eld->monitor_present); in snd_hdmi_print_eld_info()
465 snd_iprintf(buffer, "eld_valid\t\t%d\n", eld->eld_valid); in snd_hdmi_print_eld_info()
469 if (!eld->eld_valid) in snd_hdmi_print_eld_info()
471 snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); in snd_hdmi_print_eld_info()
473 eld_connection_type_names[e->conn_type]); in snd_hdmi_print_eld_info()
474 snd_iprintf(buffer, "eld_version\t\t[0x%x] %s\n", e->eld_ver, in snd_hdmi_print_eld_info()
475 eld_version_names[e->eld_ver]); in snd_hdmi_print_eld_info()
476 snd_iprintf(buffer, "edid_version\t\t[0x%x] %s\n", e->cea_edid_ver, in snd_hdmi_print_eld_info()
477 cea_edid_version_names[e->cea_edid_ver]); in snd_hdmi_print_eld_info()
478 snd_iprintf(buffer, "manufacture_id\t\t0x%x\n", e->manufacture_id); in snd_hdmi_print_eld_info()
479 snd_iprintf(buffer, "product_id\t\t0x%x\n", e->product_id); in snd_hdmi_print_eld_info()
480 snd_iprintf(buffer, "port_id\t\t\t0x%llx\n", (long long)e->port_id); in snd_hdmi_print_eld_info()
481 snd_iprintf(buffer, "support_hdcp\t\t%d\n", e->support_hdcp); in snd_hdmi_print_eld_info()
482 snd_iprintf(buffer, "support_ai\t\t%d\n", e->support_ai); in snd_hdmi_print_eld_info()
483 snd_iprintf(buffer, "audio_sync_delay\t%d\n", e->aud_synch_delay); in snd_hdmi_print_eld_info()
485 snd_hdac_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); in snd_hdmi_print_eld_info()
486 snd_iprintf(buffer, "speakers\t\t[0x%x]%s\n", e->spk_alloc, buf); in snd_hdmi_print_eld_info()
488 snd_iprintf(buffer, "sad_count\t\t%d\n", e->sad_count); in snd_hdmi_print_eld_info()
490 for (i = 0; i < e->sad_count; i++) in snd_hdmi_print_eld_info()
491 hdmi_print_sad_info(i, e->sad + i, buffer); in snd_hdmi_print_eld_info()
497 struct parsed_hdmi_eld *e = &eld->info; in snd_hdmi_write_eld_info() local
513 eld->monitor_present = val; in snd_hdmi_write_eld_info()
515 eld->eld_valid = val; in snd_hdmi_write_eld_info()
517 e->conn_type = val; in snd_hdmi_write_eld_info()
519 e->port_id = val; in snd_hdmi_write_eld_info()
521 e->support_hdcp = val; in snd_hdmi_write_eld_info()
523 e->support_ai = val; in snd_hdmi_write_eld_info()
525 e->aud_synch_delay = val; in snd_hdmi_write_eld_info()
527 e->spk_alloc = val; in snd_hdmi_write_eld_info()
529 e->sad_count = val; in snd_hdmi_write_eld_info()
532 n = name[3] - '0'; in snd_hdmi_write_eld_info()
533 if (name[4] >= '0' && name[4] <= '9') { in snd_hdmi_write_eld_info()
535 n = 10 * n + name[4] - '0'; in snd_hdmi_write_eld_info()
540 e->sad[n].format = val; in snd_hdmi_write_eld_info()
542 e->sad[n].channels = val; in snd_hdmi_write_eld_info()
544 e->sad[n].rates = val; in snd_hdmi_write_eld_info()
546 e->sad[n].sample_bits = val; in snd_hdmi_write_eld_info()
548 e->sad[n].max_bitrate = val; in snd_hdmi_write_eld_info()
550 e->sad[n].profile = val; in snd_hdmi_write_eld_info()
551 if (n >= e->sad_count) in snd_hdmi_write_eld_info()
552 e->sad_count = n + 1; in snd_hdmi_write_eld_info()
559 void snd_hdmi_eld_update_pcm_info(struct parsed_hdmi_eld *e, in snd_hdmi_eld_update_pcm_info() argument
576 for (i = 0; i < e->sad_count; i++) { in snd_hdmi_eld_update_pcm_info()
577 struct cea_sad *a = &e->sad[i]; in snd_hdmi_eld_update_pcm_info() local
578 rates |= a->rates; in snd_hdmi_eld_update_pcm_info()
579 if (a->channels > channels_max) in snd_hdmi_eld_update_pcm_info()
580 channels_max = a->channels; in snd_hdmi_eld_update_pcm_info()
581 if (a->format == AUDIO_CODING_TYPE_LPCM) { in snd_hdmi_eld_update_pcm_info()
582 if (a->sample_bits & AC_SUPPCM_BITS_20) { in snd_hdmi_eld_update_pcm_info()
587 if (a->sample_bits & AC_SUPPCM_BITS_24) { in snd_hdmi_eld_update_pcm_info()
596 hinfo->rates &= rates; in snd_hdmi_eld_update_pcm_info()
597 hinfo->formats &= formats; in snd_hdmi_eld_update_pcm_info()
598 hinfo->maxbps = min(hinfo->maxbps, maxbps); in snd_hdmi_eld_update_pcm_info()
599 hinfo->channels_max = min(hinfo->channels_max, channels_max); in snd_hdmi_eld_update_pcm_info()
605 #define ATI_VERB_SET_AUDIO_DESCRIPTOR 0x776
606 #define ATI_VERB_SET_SINK_INFO_INDEX 0x780
607 #define ATI_VERB_GET_SPEAKER_ALLOCATION 0xf70
608 #define ATI_VERB_GET_AUDIO_DESCRIPTOR 0xf76
609 #define ATI_VERB_GET_AUDIO_VIDEO_DELAY 0xf7b
610 #define ATI_VERB_GET_SINK_INFO_INDEX 0xf80
611 #define ATI_VERB_GET_SINK_INFO_DATA 0xf81
613 #define ATI_SPKALLOC_SPKALLOC 0x007f
614 #define ATI_SPKALLOC_TYPE_HDMI 0x0100
615 #define ATI_SPKALLOC_TYPE_DISPLAYPORT 0x0200
618 #define ATI_AUDIODESC_CHANNELS 0x00000007
619 #define ATI_AUDIODESC_RATES 0x0000ff00
620 #define ATI_AUDIODESC_LPCM_STEREO_RATES 0xff000000
623 #define ATI_DELAY_VIDEO_LATENCY 0x000000ff
624 #define ATI_DELAY_AUDIO_LATENCY 0x0000ff00
627 ATI_INFO_IDX_MANUFACTURER_ID = 0,
640 int sink_desc_len = 0; in snd_hdmi_get_eld_ati()
645 spkalloc = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_SPEAKER_ALLOCATION, 0); in snd_hdmi_get_eld_ati()
647 if (spkalloc <= 0) { in snd_hdmi_get_eld_ati()
649 return -EINVAL; in snd_hdmi_get_eld_ati()
652 memset(buf, 0, ELD_FIXED_BYTES + ELD_MAX_MNL + ELD_MAX_SAD * 3); in snd_hdmi_get_eld_ati()
655 buf[0] = ELD_VER_CEA_861D << 3; in snd_hdmi_get_eld_ati()
658 buf[7] = spkalloc & ATI_SPKALLOC_SPKALLOC; in snd_hdmi_get_eld_ati()
662 buf[5] |= 0x04; in snd_hdmi_get_eld_ati()
669 snd_hda_codec_write(codec, nid, 0, ATI_VERB_SET_SINK_INFO_INDEX, ATI_INFO_IDX_PORT_ID_LOW); in snd_hdmi_get_eld_ati()
670 sink_info = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_SINK_INFO_DATA, 0); in snd_hdmi_get_eld_ati()
673 snd_hda_codec_write(codec, nid, 0, ATI_VERB_SET_SINK_INFO_INDEX, ATI_INFO_IDX_PORT_ID_HIGH); in snd_hdmi_get_eld_ati()
674 sink_info = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_SINK_INFO_DATA, 0); in snd_hdmi_get_eld_ati()
677 snd_hda_codec_write(codec, nid, 0, ATI_VERB_SET_SINK_INFO_INDEX, ATI_INFO_IDX_MANUFACTURER_ID); in snd_hdmi_get_eld_ati()
678 sink_info = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_SINK_INFO_DATA, 0); in snd_hdmi_get_eld_ati()
681 snd_hda_codec_write(codec, nid, 0, ATI_VERB_SET_SINK_INFO_INDEX, ATI_INFO_IDX_PRODUCT_ID); in snd_hdmi_get_eld_ati()
682 sink_info = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_SINK_INFO_DATA, 0); in snd_hdmi_get_eld_ati()
685 snd_hda_codec_write(codec, nid, 0, ATI_VERB_SET_SINK_INFO_INDEX, ATI_INFO_IDX_SINK_DESC_LEN); in snd_hdmi_get_eld_ati()
686 sink_desc_len = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_SINK_INFO_DATA, 0); in snd_hdmi_get_eld_ati()
696 for (i = 0; i < sink_desc_len; i++) { in snd_hdmi_get_eld_ati()
697 …snd_hda_codec_write(codec, nid, 0, ATI_VERB_SET_SINK_INFO_INDEX, ATI_INFO_IDX_SINK_DESC_FIRST + i); in snd_hdmi_get_eld_ati()
698 buf[pos++] = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_SINK_INFO_DATA, 0); in snd_hdmi_get_eld_ati()
706 snd_hda_codec_write(codec, nid, 0, ATI_VERB_SET_AUDIO_DESCRIPTOR, i << 3); in snd_hdmi_get_eld_ati()
707 ati_sad = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_AUDIO_DESCRIPTOR, 0); in snd_hdmi_get_eld_ati()
709 if (ati_sad <= 0) in snd_hdmi_get_eld_ati()
713 /* format is supported, copy SAD as-is */ in snd_hdmi_get_eld_ati()
714 buf[pos++] = (ati_sad & 0x0000ff) >> 0; in snd_hdmi_get_eld_ati()
715 buf[pos++] = (ati_sad & 0x00ff00) >> 8; in snd_hdmi_get_eld_ati()
716 buf[pos++] = (ati_sad & 0xff0000) >> 16; in snd_hdmi_get_eld_ati()
722 /* for PCM there is a separate stereo rate mask */ in snd_hdmi_get_eld_ati()
723 buf[pos++] = ((ati_sad & 0x000000ff) & ~ATI_AUDIODESC_CHANNELS) | 0x1; in snd_hdmi_get_eld_ati()
725 buf[pos++] = (ati_sad & 0xff000000) >> 24; in snd_hdmi_get_eld_ati()
726 buf[pos++] = (ati_sad & 0x00ff0000) >> 16; in snd_hdmi_get_eld_ati()
732 return -EINVAL; in snd_hdmi_get_eld_ati()
738 * 0 field not valid or unknown latency in snd_hdmi_get_eld_ati()
739 * [1..251] msecs = (x-1)*2 (max 500ms with x = 251 = 0xfb) in snd_hdmi_get_eld_ati()
744 * 0 unknown or 0ms in snd_hdmi_get_eld_ati()
745 * [1..250] msecs = x*2 (max 500ms with x = 250 = 0xfa) in snd_hdmi_get_eld_ati()
748 aud_synch = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_AUDIO_VIDEO_DELAY, 0); in snd_hdmi_get_eld_ati()
753 if (video_latency_hdmi <= 0xfb && audio_latency_hdmi <= 0xfb && in snd_hdmi_get_eld_ati()
755 buf[6] = video_latency_hdmi - audio_latency_hdmi; in snd_hdmi_get_eld_ati()
756 /* else unknown/invalid or 0ms or video ahead of audio, so use zero */ in snd_hdmi_get_eld_ati()
760 buf[5] |= ((pos - ELD_FIXED_BYTES - sink_desc_len) / 3) << 4; in snd_hdmi_get_eld_ati()
762 /* Baseline ELD block length is 4-byte aligned */ in snd_hdmi_get_eld_ati()
765 /* Baseline ELD length (4-byte header is not counted in) */ in snd_hdmi_get_eld_ati()
766 buf[2] = (pos - 4) / 4; in snd_hdmi_get_eld_ati()
770 return 0; in snd_hdmi_get_eld_ati()