Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: hda/hdmi: extract common interface for ELD handling

Other HDMI-related cards (e.g. hdmi-codec) are also using the ELD.
Exrtact common set of interfaces for handling the ELD.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20250124-alsa-hdmi-codec-eld-v1-1-bad045cfaeac@linaro.org

authored by

Dmitry Baryshkov and committed by
Takashi Iwai
1b0e9d7f e8d04a92

+493 -424
+91
include/sound/pcm_drm_eld.h
··· 2 2 #ifndef __SOUND_PCM_DRM_ELD_H 3 3 #define __SOUND_PCM_DRM_ELD_H 4 4 5 + enum eld_versions { 6 + ELD_VER_CEA_861D = 2, 7 + ELD_VER_PARTIAL = 31, 8 + }; 9 + 10 + enum cea_audio_coding_types { 11 + AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0, 12 + AUDIO_CODING_TYPE_LPCM = 1, 13 + AUDIO_CODING_TYPE_AC3 = 2, 14 + AUDIO_CODING_TYPE_MPEG1 = 3, 15 + AUDIO_CODING_TYPE_MP3 = 4, 16 + AUDIO_CODING_TYPE_MPEG2 = 5, 17 + AUDIO_CODING_TYPE_AACLC = 6, 18 + AUDIO_CODING_TYPE_DTS = 7, 19 + AUDIO_CODING_TYPE_ATRAC = 8, 20 + AUDIO_CODING_TYPE_SACD = 9, 21 + AUDIO_CODING_TYPE_EAC3 = 10, 22 + AUDIO_CODING_TYPE_DTS_HD = 11, 23 + AUDIO_CODING_TYPE_MLP = 12, 24 + AUDIO_CODING_TYPE_DST = 13, 25 + AUDIO_CODING_TYPE_WMAPRO = 14, 26 + AUDIO_CODING_TYPE_REF_CXT = 15, 27 + /* also include valid xtypes below */ 28 + AUDIO_CODING_TYPE_HE_AAC = 15, 29 + AUDIO_CODING_TYPE_HE_AAC2 = 16, 30 + AUDIO_CODING_TYPE_MPEG_SURROUND = 17, 31 + }; 32 + 33 + enum cea_audio_coding_xtypes { 34 + AUDIO_CODING_XTYPE_HE_REF_CT = 0, 35 + AUDIO_CODING_XTYPE_HE_AAC = 1, 36 + AUDIO_CODING_XTYPE_HE_AAC2 = 2, 37 + AUDIO_CODING_XTYPE_MPEG_SURROUND = 3, 38 + AUDIO_CODING_XTYPE_FIRST_RESERVED = 4, 39 + }; 40 + 41 + /* 42 + * CEA Short Audio Descriptor data 43 + */ 44 + struct snd_cea_sad { 45 + int channels; 46 + int format; /* (format == 0) indicates invalid SAD */ 47 + int rates; 48 + int sample_bits; /* for LPCM */ 49 + int max_bitrate; /* for AC3...ATRAC */ 50 + int profile; /* for WMAPRO */ 51 + }; 52 + 53 + #define ELD_FIXED_BYTES 20 54 + #define ELD_MAX_SIZE 256 55 + #define ELD_MAX_MNL 16 56 + #define ELD_MAX_SAD 16 57 + 58 + #define ELD_PCM_BITS_8 BIT(0) 59 + #define ELD_PCM_BITS_16 BIT(1) 60 + #define ELD_PCM_BITS_20 BIT(2) 61 + #define ELD_PCM_BITS_24 BIT(3) 62 + #define ELD_PCM_BITS_32 BIT(4) 63 + 64 + /* 65 + * ELD: EDID Like Data 66 + */ 67 + struct snd_parsed_hdmi_eld { 68 + /* 69 + * all fields will be cleared before updating ELD 70 + */ 71 + int baseline_len; 72 + int eld_ver; 73 + int cea_edid_ver; 74 + char monitor_name[ELD_MAX_MNL + 1]; 75 + int manufacture_id; 76 + int product_id; 77 + u64 port_id; 78 + int support_hdcp; 79 + int support_ai; 80 + int conn_type; 81 + int aud_synch_delay; 82 + int spk_alloc; 83 + int sad_count; 84 + struct snd_cea_sad sad[ELD_MAX_SAD]; 85 + }; 86 + 5 87 int snd_pcm_hw_constraint_eld(struct snd_pcm_runtime *runtime, void *eld); 88 + 89 + int snd_parse_eld(struct device *dev, struct snd_parsed_hdmi_eld *e, 90 + const unsigned char *buf, int size); 91 + void snd_show_eld(struct device *dev, struct snd_parsed_hdmi_eld *e); 92 + 93 + #ifdef CONFIG_SND_PROC_FS 94 + void snd_print_eld_info(struct snd_parsed_hdmi_eld *eld, 95 + struct snd_info_buffer *buffer); 96 + #endif 6 97 7 98 #endif
+387
sound/core/pcm_drm_eld.c
··· 5 5 #include <linux/bitfield.h> 6 6 #include <linux/export.h> 7 7 #include <linux/hdmi.h> 8 + #include <linux/unaligned.h> 8 9 #include <drm/drm_edid.h> 9 10 #include <drm/drm_eld.h> 11 + #include <sound/info.h> 10 12 #include <sound/pcm.h> 11 13 #include <sound/pcm_drm_eld.h> 12 14 ··· 164 162 return ret; 165 163 } 166 164 EXPORT_SYMBOL_GPL(snd_pcm_hw_constraint_eld); 165 + 166 + #define SND_PRINT_RATES_ADVISED_BUFSIZE 80 167 + #define SND_PRINT_BITS_ADVISED_BUFSIZE 16 168 + #define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80 169 + 170 + static const char * const eld_connection_type_names[4] = { 171 + "HDMI", 172 + "DisplayPort", 173 + "2-reserved", 174 + "3-reserved" 175 + }; 176 + 177 + static const char * const cea_audio_coding_type_names[] = { 178 + /* 0 */ "undefined", 179 + /* 1 */ "LPCM", 180 + /* 2 */ "AC-3", 181 + /* 3 */ "MPEG1", 182 + /* 4 */ "MP3", 183 + /* 5 */ "MPEG2", 184 + /* 6 */ "AAC-LC", 185 + /* 7 */ "DTS", 186 + /* 8 */ "ATRAC", 187 + /* 9 */ "DSD (One Bit Audio)", 188 + /* 10 */ "E-AC-3/DD+ (Dolby Digital Plus)", 189 + /* 11 */ "DTS-HD", 190 + /* 12 */ "MLP (Dolby TrueHD)", 191 + /* 13 */ "DST", 192 + /* 14 */ "WMAPro", 193 + /* 15 */ "HE-AAC", 194 + /* 16 */ "HE-AACv2", 195 + /* 17 */ "MPEG Surround", 196 + }; 197 + 198 + static const char * const cea_speaker_allocation_names[] = { 199 + /* 0 */ "FL/FR", 200 + /* 1 */ "LFE", 201 + /* 2 */ "FC", 202 + /* 3 */ "RL/RR", 203 + /* 4 */ "RC", 204 + /* 5 */ "FLC/FRC", 205 + /* 6 */ "RLC/RRC", 206 + /* 7 */ "FLW/FRW", 207 + /* 8 */ "FLH/FRH", 208 + /* 9 */ "TC", 209 + /* 10 */ "FCH", 210 + }; 211 + 212 + /* 213 + * SS1:SS0 index => sample size 214 + */ 215 + static const int cea_sample_sizes[4] = { 216 + 0, /* 0: Refer to Stream Header */ 217 + ELD_PCM_BITS_16, /* 1: 16 bits */ 218 + ELD_PCM_BITS_20, /* 2: 20 bits */ 219 + ELD_PCM_BITS_24, /* 3: 24 bits */ 220 + }; 221 + 222 + /* 223 + * SF2:SF1:SF0 index => sampling frequency 224 + */ 225 + static const int cea_sampling_frequencies[8] = { 226 + 0, /* 0: Refer to Stream Header */ 227 + SNDRV_PCM_RATE_32000, /* 1: 32000Hz */ 228 + SNDRV_PCM_RATE_44100, /* 2: 44100Hz */ 229 + SNDRV_PCM_RATE_48000, /* 3: 48000Hz */ 230 + SNDRV_PCM_RATE_88200, /* 4: 88200Hz */ 231 + SNDRV_PCM_RATE_96000, /* 5: 96000Hz */ 232 + SNDRV_PCM_RATE_176400, /* 6: 176400Hz */ 233 + SNDRV_PCM_RATE_192000, /* 7: 192000Hz */ 234 + }; 235 + 236 + #define GRAB_BITS(buf, byte, lowbit, bits) \ 237 + ({ \ 238 + BUILD_BUG_ON(lowbit > 7); \ 239 + BUILD_BUG_ON(bits > 8); \ 240 + BUILD_BUG_ON(bits <= 0); \ 241 + \ 242 + (buf[byte] >> (lowbit)) & ((1 << (bits)) - 1); \ 243 + }) 244 + 245 + static void hdmi_update_short_audio_desc(struct device *dev, 246 + struct snd_cea_sad *a, 247 + const unsigned char *buf) 248 + { 249 + int i; 250 + int val; 251 + 252 + val = GRAB_BITS(buf, 1, 0, 7); 253 + a->rates = 0; 254 + for (i = 0; i < 7; i++) 255 + if (val & (1 << i)) 256 + a->rates |= cea_sampling_frequencies[i + 1]; 257 + 258 + a->channels = GRAB_BITS(buf, 0, 0, 3); 259 + a->channels++; 260 + 261 + a->sample_bits = 0; 262 + a->max_bitrate = 0; 263 + 264 + a->format = GRAB_BITS(buf, 0, 3, 4); 265 + switch (a->format) { 266 + case AUDIO_CODING_TYPE_REF_STREAM_HEADER: 267 + dev_info(dev, "HDMI: audio coding type 0 not expected\n"); 268 + break; 269 + 270 + case AUDIO_CODING_TYPE_LPCM: 271 + val = GRAB_BITS(buf, 2, 0, 3); 272 + for (i = 0; i < 3; i++) 273 + if (val & (1 << i)) 274 + a->sample_bits |= cea_sample_sizes[i + 1]; 275 + break; 276 + 277 + case AUDIO_CODING_TYPE_AC3: 278 + case AUDIO_CODING_TYPE_MPEG1: 279 + case AUDIO_CODING_TYPE_MP3: 280 + case AUDIO_CODING_TYPE_MPEG2: 281 + case AUDIO_CODING_TYPE_AACLC: 282 + case AUDIO_CODING_TYPE_DTS: 283 + case AUDIO_CODING_TYPE_ATRAC: 284 + a->max_bitrate = GRAB_BITS(buf, 2, 0, 8); 285 + a->max_bitrate *= 8000; 286 + break; 287 + 288 + case AUDIO_CODING_TYPE_SACD: 289 + break; 290 + 291 + case AUDIO_CODING_TYPE_EAC3: 292 + break; 293 + 294 + case AUDIO_CODING_TYPE_DTS_HD: 295 + break; 296 + 297 + case AUDIO_CODING_TYPE_MLP: 298 + break; 299 + 300 + case AUDIO_CODING_TYPE_DST: 301 + break; 302 + 303 + case AUDIO_CODING_TYPE_WMAPRO: 304 + a->profile = GRAB_BITS(buf, 2, 0, 3); 305 + break; 306 + 307 + case AUDIO_CODING_TYPE_REF_CXT: 308 + a->format = GRAB_BITS(buf, 2, 3, 5); 309 + if (a->format == AUDIO_CODING_XTYPE_HE_REF_CT || 310 + a->format >= AUDIO_CODING_XTYPE_FIRST_RESERVED) { 311 + dev_info(dev, 312 + "HDMI: audio coding xtype %d not expected\n", 313 + a->format); 314 + a->format = 0; 315 + } else 316 + a->format += AUDIO_CODING_TYPE_HE_AAC - 317 + AUDIO_CODING_XTYPE_HE_AAC; 318 + break; 319 + } 320 + } 321 + 322 + /* 323 + * Be careful, ELD buf could be totally rubbish! 324 + */ 325 + int snd_parse_eld(struct device *dev, struct snd_parsed_hdmi_eld *e, 326 + const unsigned char *buf, int size) 327 + { 328 + int mnl; 329 + int i; 330 + 331 + memset(e, 0, sizeof(*e)); 332 + e->eld_ver = GRAB_BITS(buf, 0, 3, 5); 333 + if (e->eld_ver != ELD_VER_CEA_861D && 334 + e->eld_ver != ELD_VER_PARTIAL) { 335 + dev_info(dev, "HDMI: Unknown ELD version %d\n", e->eld_ver); 336 + goto out_fail; 337 + } 338 + 339 + e->baseline_len = GRAB_BITS(buf, 2, 0, 8); 340 + mnl = GRAB_BITS(buf, 4, 0, 5); 341 + e->cea_edid_ver = GRAB_BITS(buf, 4, 5, 3); 342 + 343 + e->support_hdcp = GRAB_BITS(buf, 5, 0, 1); 344 + e->support_ai = GRAB_BITS(buf, 5, 1, 1); 345 + e->conn_type = GRAB_BITS(buf, 5, 2, 2); 346 + e->sad_count = GRAB_BITS(buf, 5, 4, 4); 347 + 348 + e->aud_synch_delay = GRAB_BITS(buf, 6, 0, 8) * 2; 349 + e->spk_alloc = GRAB_BITS(buf, 7, 0, 7); 350 + 351 + e->port_id = get_unaligned_le64(buf + 8); 352 + 353 + /* not specified, but the spec's tendency is little endian */ 354 + e->manufacture_id = get_unaligned_le16(buf + 16); 355 + e->product_id = get_unaligned_le16(buf + 18); 356 + 357 + if (mnl > ELD_MAX_MNL) { 358 + dev_info(dev, "HDMI: MNL is reserved value %d\n", mnl); 359 + goto out_fail; 360 + } else if (ELD_FIXED_BYTES + mnl > size) { 361 + dev_info(dev, "HDMI: out of range MNL %d\n", mnl); 362 + goto out_fail; 363 + } else 364 + strscpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl + 1); 365 + 366 + for (i = 0; i < e->sad_count; i++) { 367 + if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) { 368 + dev_info(dev, "HDMI: out of range SAD %d\n", i); 369 + goto out_fail; 370 + } 371 + hdmi_update_short_audio_desc(dev, e->sad + i, 372 + buf + ELD_FIXED_BYTES + mnl + 3 * i); 373 + } 374 + 375 + /* 376 + * HDMI sink's ELD info cannot always be retrieved for now, e.g. 377 + * in console or for audio devices. Assume the highest speakers 378 + * configuration, to _not_ prohibit multi-channel audio playback. 379 + */ 380 + if (!e->spk_alloc) 381 + e->spk_alloc = 0xffff; 382 + 383 + return 0; 384 + 385 + out_fail: 386 + return -EINVAL; 387 + } 388 + EXPORT_SYMBOL_GPL(snd_parse_eld); 389 + 390 + /* 391 + * SNDRV_PCM_RATE_* and AC_PAR_PCM values don't match, print correct rates with 392 + * hdmi-specific routine. 393 + */ 394 + static void hdmi_print_pcm_rates(int pcm, char *buf, int buflen) 395 + { 396 + static const unsigned int alsa_rates[] = { 397 + 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 398 + 88200, 96000, 176400, 192000, 384000 399 + }; 400 + int i, j; 401 + 402 + for (i = 0, j = 0; i < ARRAY_SIZE(alsa_rates); i++) 403 + if (pcm & (1 << i)) 404 + j += scnprintf(buf + j, buflen - j, " %d", 405 + alsa_rates[i]); 406 + 407 + buf[j] = '\0'; /* necessary when j == 0 */ 408 + } 409 + 410 + static void eld_print_pcm_bits(int pcm, char *buf, int buflen) 411 + { 412 + static const unsigned int bits[] = { 8, 16, 20, 24, 32 }; 413 + int i, j; 414 + 415 + for (i = 0, j = 0; i < ARRAY_SIZE(bits); i++) 416 + if (pcm & (ELD_PCM_BITS_8 << i)) 417 + j += scnprintf(buf + j, buflen - j, " %d", bits[i]); 418 + 419 + buf[j] = '\0'; /* necessary when j == 0 */ 420 + } 421 + 422 + static void hdmi_show_short_audio_desc(struct device *dev, 423 + struct snd_cea_sad *a) 424 + { 425 + char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; 426 + char buf2[8 + SND_PRINT_BITS_ADVISED_BUFSIZE] = ", bits ="; 427 + 428 + if (!a->format) 429 + return; 430 + 431 + hdmi_print_pcm_rates(a->rates, buf, sizeof(buf)); 432 + 433 + if (a->format == AUDIO_CODING_TYPE_LPCM) 434 + eld_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2) - 8); 435 + else if (a->max_bitrate) 436 + snprintf(buf2, sizeof(buf2), 437 + ", max bitrate = %d", a->max_bitrate); 438 + else 439 + buf2[0] = '\0'; 440 + 441 + dev_dbg(dev, 442 + "HDMI: supports coding type %s: channels = %d, rates =%s%s\n", 443 + cea_audio_coding_type_names[a->format], 444 + a->channels, buf, buf2); 445 + } 446 + 447 + static void snd_eld_print_channel_allocation(int spk_alloc, char *buf, int buflen) 448 + { 449 + int i, j; 450 + 451 + for (i = 0, j = 0; i < ARRAY_SIZE(cea_speaker_allocation_names); i++) { 452 + if (spk_alloc & (1 << i)) 453 + j += scnprintf(buf + j, buflen - j, " %s", 454 + cea_speaker_allocation_names[i]); 455 + } 456 + buf[j] = '\0'; /* necessary when j == 0 */ 457 + } 458 + 459 + void snd_show_eld(struct device *dev, struct snd_parsed_hdmi_eld *e) 460 + { 461 + int i; 462 + 463 + dev_dbg(dev, "HDMI: detected monitor %s at connection type %s\n", 464 + e->monitor_name, 465 + eld_connection_type_names[e->conn_type]); 466 + 467 + if (e->spk_alloc) { 468 + char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; 469 + 470 + snd_eld_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); 471 + dev_dbg(dev, "HDMI: available speakers:%s\n", buf); 472 + } 473 + 474 + for (i = 0; i < e->sad_count; i++) 475 + hdmi_show_short_audio_desc(dev, e->sad + i); 476 + } 477 + EXPORT_SYMBOL_GPL(snd_show_eld); 478 + 479 + #ifdef CONFIG_SND_PROC_FS 480 + static void hdmi_print_sad_info(int i, struct snd_cea_sad *a, 481 + struct snd_info_buffer *buffer) 482 + { 483 + char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; 484 + 485 + snd_iprintf(buffer, "sad%d_coding_type\t[0x%x] %s\n", 486 + i, a->format, cea_audio_coding_type_names[a->format]); 487 + snd_iprintf(buffer, "sad%d_channels\t\t%d\n", i, a->channels); 488 + 489 + hdmi_print_pcm_rates(a->rates, buf, sizeof(buf)); 490 + snd_iprintf(buffer, "sad%d_rates\t\t[0x%x]%s\n", i, a->rates, buf); 491 + 492 + if (a->format == AUDIO_CODING_TYPE_LPCM) { 493 + eld_print_pcm_bits(a->sample_bits, buf, sizeof(buf)); 494 + snd_iprintf(buffer, "sad%d_bits\t\t[0x%x]%s\n", 495 + i, a->sample_bits, buf); 496 + } 497 + 498 + if (a->max_bitrate) 499 + snd_iprintf(buffer, "sad%d_max_bitrate\t%d\n", 500 + i, a->max_bitrate); 501 + 502 + if (a->profile) 503 + snd_iprintf(buffer, "sad%d_profile\t\t%d\n", i, a->profile); 504 + } 505 + 506 + void snd_print_eld_info(struct snd_parsed_hdmi_eld *e, 507 + struct snd_info_buffer *buffer) 508 + { 509 + char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; 510 + int i; 511 + static const char * const eld_version_names[32] = { 512 + "reserved", 513 + "reserved", 514 + "CEA-861D or below", 515 + [3 ... 30] = "reserved", 516 + [31] = "partial" 517 + }; 518 + static const char * const cea_edid_version_names[8] = { 519 + "no CEA EDID Timing Extension block present", 520 + "CEA-861", 521 + "CEA-861-A", 522 + "CEA-861-B, C or D", 523 + [4 ... 7] = "reserved" 524 + }; 525 + 526 + snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); 527 + snd_iprintf(buffer, "connection_type\t\t%s\n", 528 + eld_connection_type_names[e->conn_type]); 529 + snd_iprintf(buffer, "eld_version\t\t[0x%x] %s\n", e->eld_ver, 530 + eld_version_names[e->eld_ver]); 531 + snd_iprintf(buffer, "edid_version\t\t[0x%x] %s\n", e->cea_edid_ver, 532 + cea_edid_version_names[e->cea_edid_ver]); 533 + snd_iprintf(buffer, "manufacture_id\t\t0x%x\n", e->manufacture_id); 534 + snd_iprintf(buffer, "product_id\t\t0x%x\n", e->product_id); 535 + snd_iprintf(buffer, "port_id\t\t\t0x%llx\n", (long long)e->port_id); 536 + snd_iprintf(buffer, "support_hdcp\t\t%d\n", e->support_hdcp); 537 + snd_iprintf(buffer, "support_ai\t\t%d\n", e->support_ai); 538 + snd_iprintf(buffer, "audio_sync_delay\t%d\n", e->aud_synch_delay); 539 + 540 + snd_eld_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); 541 + snd_iprintf(buffer, "speakers\t\t[0x%x]%s\n", e->spk_alloc, buf); 542 + 543 + snd_iprintf(buffer, "sad_count\t\t%d\n", e->sad_count); 544 + 545 + for (i = 0; i < e->sad_count; i++) 546 + hdmi_print_sad_info(i, e->sad + i, buffer); 547 + } 548 + EXPORT_SYMBOL_GPL(snd_print_eld_info); 549 + #endif /* CONFIG_SND_PROC_FS */
+1
sound/pci/hda/Kconfig
··· 266 266 config SND_HDA_CODEC_HDMI 267 267 tristate "Build HDMI/DisplayPort HD-audio codec support" 268 268 select SND_DYNAMIC_MINORS 269 + select SND_PCM_ELD 269 270 help 270 271 Say Y or M here to include HDMI and DisplayPort HD-audio codec 271 272 support in snd-hda-intel driver. This includes all AMD/ATI,
+7 -376
sound/pci/hda/hda_eld.c
··· 17 17 #include <sound/hda_codec.h> 18 18 #include "hda_local.h" 19 19 20 - enum eld_versions { 21 - ELD_VER_CEA_861D = 2, 22 - ELD_VER_PARTIAL = 31, 23 - }; 24 - 25 20 enum cea_edid_versions { 26 21 CEA_EDID_VER_NONE = 0, 27 22 CEA_EDID_VER_CEA861 = 1, ··· 25 30 CEA_EDID_VER_RESERVED = 4, 26 31 }; 27 32 28 - static const char * const eld_connection_type_names[4] = { 29 - "HDMI", 30 - "DisplayPort", 31 - "2-reserved", 32 - "3-reserved" 33 - }; 34 - 35 - enum cea_audio_coding_types { 36 - AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0, 37 - AUDIO_CODING_TYPE_LPCM = 1, 38 - AUDIO_CODING_TYPE_AC3 = 2, 39 - AUDIO_CODING_TYPE_MPEG1 = 3, 40 - AUDIO_CODING_TYPE_MP3 = 4, 41 - AUDIO_CODING_TYPE_MPEG2 = 5, 42 - AUDIO_CODING_TYPE_AACLC = 6, 43 - AUDIO_CODING_TYPE_DTS = 7, 44 - AUDIO_CODING_TYPE_ATRAC = 8, 45 - AUDIO_CODING_TYPE_SACD = 9, 46 - AUDIO_CODING_TYPE_EAC3 = 10, 47 - AUDIO_CODING_TYPE_DTS_HD = 11, 48 - AUDIO_CODING_TYPE_MLP = 12, 49 - AUDIO_CODING_TYPE_DST = 13, 50 - AUDIO_CODING_TYPE_WMAPRO = 14, 51 - AUDIO_CODING_TYPE_REF_CXT = 15, 52 - /* also include valid xtypes below */ 53 - AUDIO_CODING_TYPE_HE_AAC = 15, 54 - AUDIO_CODING_TYPE_HE_AAC2 = 16, 55 - AUDIO_CODING_TYPE_MPEG_SURROUND = 17, 56 - }; 57 - 58 - enum cea_audio_coding_xtypes { 59 - AUDIO_CODING_XTYPE_HE_REF_CT = 0, 60 - AUDIO_CODING_XTYPE_HE_AAC = 1, 61 - AUDIO_CODING_XTYPE_HE_AAC2 = 2, 62 - AUDIO_CODING_XTYPE_MPEG_SURROUND = 3, 63 - AUDIO_CODING_XTYPE_FIRST_RESERVED = 4, 64 - }; 65 - 66 - static const char * const cea_audio_coding_type_names[] = { 67 - /* 0 */ "undefined", 68 - /* 1 */ "LPCM", 69 - /* 2 */ "AC-3", 70 - /* 3 */ "MPEG1", 71 - /* 4 */ "MP3", 72 - /* 5 */ "MPEG2", 73 - /* 6 */ "AAC-LC", 74 - /* 7 */ "DTS", 75 - /* 8 */ "ATRAC", 76 - /* 9 */ "DSD (One Bit Audio)", 77 - /* 10 */ "E-AC-3/DD+ (Dolby Digital Plus)", 78 - /* 11 */ "DTS-HD", 79 - /* 12 */ "MLP (Dolby TrueHD)", 80 - /* 13 */ "DST", 81 - /* 14 */ "WMAPro", 82 - /* 15 */ "HE-AAC", 83 - /* 16 */ "HE-AACv2", 84 - /* 17 */ "MPEG Surround", 85 - }; 86 - 87 33 /* 88 34 * The following two lists are shared between 89 35 * - HDMI audio InfoFrame (source to sink) 90 36 * - CEA E-EDID Extension (sink to source) 91 37 */ 92 - 93 - /* 94 - * SS1:SS0 index => sample size 95 - */ 96 - static const int cea_sample_sizes[4] = { 97 - 0, /* 0: Refer to Stream Header */ 98 - AC_SUPPCM_BITS_16, /* 1: 16 bits */ 99 - AC_SUPPCM_BITS_20, /* 2: 20 bits */ 100 - AC_SUPPCM_BITS_24, /* 3: 24 bits */ 101 - }; 102 - 103 - /* 104 - * SF2:SF1:SF0 index => sampling frequency 105 - */ 106 - static const int cea_sampling_frequencies[8] = { 107 - 0, /* 0: Refer to Stream Header */ 108 - SNDRV_PCM_RATE_32000, /* 1: 32000Hz */ 109 - SNDRV_PCM_RATE_44100, /* 2: 44100Hz */ 110 - SNDRV_PCM_RATE_48000, /* 3: 48000Hz */ 111 - SNDRV_PCM_RATE_88200, /* 4: 88200Hz */ 112 - SNDRV_PCM_RATE_96000, /* 5: 96000Hz */ 113 - SNDRV_PCM_RATE_176400, /* 6: 176400Hz */ 114 - SNDRV_PCM_RATE_192000, /* 7: 192000Hz */ 115 - }; 116 38 117 39 static unsigned int hdmi_get_eld_data(struct hda_codec *codec, hda_nid_t nid, 118 40 int byte_index) ··· 42 130 codec_info(codec, "HDMI: ELD data byte %d: 0x%x\n", byte_index, val); 43 131 #endif 44 132 return val; 45 - } 46 - 47 - #define GRAB_BITS(buf, byte, lowbit, bits) \ 48 - ({ \ 49 - BUILD_BUG_ON(lowbit > 7); \ 50 - BUILD_BUG_ON(bits > 8); \ 51 - BUILD_BUG_ON(bits <= 0); \ 52 - \ 53 - (buf[byte] >> (lowbit)) & ((1 << (bits)) - 1); \ 54 - }) 55 - 56 - static void hdmi_update_short_audio_desc(struct hda_codec *codec, 57 - struct cea_sad *a, 58 - const unsigned char *buf) 59 - { 60 - int i; 61 - int val; 62 - 63 - val = GRAB_BITS(buf, 1, 0, 7); 64 - a->rates = 0; 65 - for (i = 0; i < 7; i++) 66 - if (val & (1 << i)) 67 - a->rates |= cea_sampling_frequencies[i + 1]; 68 - 69 - a->channels = GRAB_BITS(buf, 0, 0, 3); 70 - a->channels++; 71 - 72 - a->sample_bits = 0; 73 - a->max_bitrate = 0; 74 - 75 - a->format = GRAB_BITS(buf, 0, 3, 4); 76 - switch (a->format) { 77 - case AUDIO_CODING_TYPE_REF_STREAM_HEADER: 78 - codec_info(codec, "HDMI: audio coding type 0 not expected\n"); 79 - break; 80 - 81 - case AUDIO_CODING_TYPE_LPCM: 82 - val = GRAB_BITS(buf, 2, 0, 3); 83 - for (i = 0; i < 3; i++) 84 - if (val & (1 << i)) 85 - a->sample_bits |= cea_sample_sizes[i + 1]; 86 - break; 87 - 88 - case AUDIO_CODING_TYPE_AC3: 89 - case AUDIO_CODING_TYPE_MPEG1: 90 - case AUDIO_CODING_TYPE_MP3: 91 - case AUDIO_CODING_TYPE_MPEG2: 92 - case AUDIO_CODING_TYPE_AACLC: 93 - case AUDIO_CODING_TYPE_DTS: 94 - case AUDIO_CODING_TYPE_ATRAC: 95 - a->max_bitrate = GRAB_BITS(buf, 2, 0, 8); 96 - a->max_bitrate *= 8000; 97 - break; 98 - 99 - case AUDIO_CODING_TYPE_SACD: 100 - break; 101 - 102 - case AUDIO_CODING_TYPE_EAC3: 103 - break; 104 - 105 - case AUDIO_CODING_TYPE_DTS_HD: 106 - break; 107 - 108 - case AUDIO_CODING_TYPE_MLP: 109 - break; 110 - 111 - case AUDIO_CODING_TYPE_DST: 112 - break; 113 - 114 - case AUDIO_CODING_TYPE_WMAPRO: 115 - a->profile = GRAB_BITS(buf, 2, 0, 3); 116 - break; 117 - 118 - case AUDIO_CODING_TYPE_REF_CXT: 119 - a->format = GRAB_BITS(buf, 2, 3, 5); 120 - if (a->format == AUDIO_CODING_XTYPE_HE_REF_CT || 121 - a->format >= AUDIO_CODING_XTYPE_FIRST_RESERVED) { 122 - codec_info(codec, 123 - "HDMI: audio coding xtype %d not expected\n", 124 - a->format); 125 - a->format = 0; 126 - } else 127 - a->format += AUDIO_CODING_TYPE_HE_AAC - 128 - AUDIO_CODING_XTYPE_HE_AAC; 129 - break; 130 - } 131 - } 132 - 133 - /* 134 - * Be careful, ELD buf could be totally rubbish! 135 - */ 136 - int snd_hdmi_parse_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e, 137 - const unsigned char *buf, int size) 138 - { 139 - int mnl; 140 - int i; 141 - 142 - memset(e, 0, sizeof(*e)); 143 - e->eld_ver = GRAB_BITS(buf, 0, 3, 5); 144 - if (e->eld_ver != ELD_VER_CEA_861D && 145 - e->eld_ver != ELD_VER_PARTIAL) { 146 - codec_info(codec, "HDMI: Unknown ELD version %d\n", e->eld_ver); 147 - goto out_fail; 148 - } 149 - 150 - e->baseline_len = GRAB_BITS(buf, 2, 0, 8); 151 - mnl = GRAB_BITS(buf, 4, 0, 5); 152 - e->cea_edid_ver = GRAB_BITS(buf, 4, 5, 3); 153 - 154 - e->support_hdcp = GRAB_BITS(buf, 5, 0, 1); 155 - e->support_ai = GRAB_BITS(buf, 5, 1, 1); 156 - e->conn_type = GRAB_BITS(buf, 5, 2, 2); 157 - e->sad_count = GRAB_BITS(buf, 5, 4, 4); 158 - 159 - e->aud_synch_delay = GRAB_BITS(buf, 6, 0, 8) * 2; 160 - e->spk_alloc = GRAB_BITS(buf, 7, 0, 7); 161 - 162 - e->port_id = get_unaligned_le64(buf + 8); 163 - 164 - /* not specified, but the spec's tendency is little endian */ 165 - e->manufacture_id = get_unaligned_le16(buf + 16); 166 - e->product_id = get_unaligned_le16(buf + 18); 167 - 168 - if (mnl > ELD_MAX_MNL) { 169 - codec_info(codec, "HDMI: MNL is reserved value %d\n", mnl); 170 - goto out_fail; 171 - } else if (ELD_FIXED_BYTES + mnl > size) { 172 - codec_info(codec, "HDMI: out of range MNL %d\n", mnl); 173 - goto out_fail; 174 - } else 175 - strscpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl + 1); 176 - 177 - for (i = 0; i < e->sad_count; i++) { 178 - if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) { 179 - codec_info(codec, "HDMI: out of range SAD %d\n", i); 180 - goto out_fail; 181 - } 182 - hdmi_update_short_audio_desc(codec, e->sad + i, 183 - buf + ELD_FIXED_BYTES + mnl + 3 * i); 184 - } 185 - 186 - /* 187 - * HDMI sink's ELD info cannot always be retrieved for now, e.g. 188 - * in console or for audio devices. Assume the highest speakers 189 - * configuration, to _not_ prohibit multi-channel audio playback. 190 - */ 191 - if (!e->spk_alloc) 192 - e->spk_alloc = 0xffff; 193 - 194 - return 0; 195 - 196 - out_fail: 197 - return -EINVAL; 198 133 } 199 134 200 135 int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid) ··· 105 346 return ret; 106 347 } 107 348 108 - /* 109 - * SNDRV_PCM_RATE_* and AC_PAR_PCM values don't match, print correct rates with 110 - * hdmi-specific routine. 111 - */ 112 - static void hdmi_print_pcm_rates(int pcm, char *buf, int buflen) 113 - { 114 - static const unsigned int alsa_rates[] = { 115 - 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 116 - 88200, 96000, 176400, 192000, 384000 117 - }; 118 - int i, j; 119 - 120 - for (i = 0, j = 0; i < ARRAY_SIZE(alsa_rates); i++) 121 - if (pcm & (1 << i)) 122 - j += scnprintf(buf + j, buflen - j, " %d", 123 - alsa_rates[i]); 124 - 125 - buf[j] = '\0'; /* necessary when j == 0 */ 126 - } 127 - 128 - #define SND_PRINT_RATES_ADVISED_BUFSIZE 80 129 - 130 - static void hdmi_show_short_audio_desc(struct hda_codec *codec, 131 - struct cea_sad *a) 132 - { 133 - char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; 134 - char buf2[8 + SND_PRINT_BITS_ADVISED_BUFSIZE] = ", bits ="; 135 - 136 - if (!a->format) 137 - return; 138 - 139 - hdmi_print_pcm_rates(a->rates, buf, sizeof(buf)); 140 - 141 - if (a->format == AUDIO_CODING_TYPE_LPCM) 142 - snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2) - 8); 143 - else if (a->max_bitrate) 144 - snprintf(buf2, sizeof(buf2), 145 - ", max bitrate = %d", a->max_bitrate); 146 - else 147 - buf2[0] = '\0'; 148 - 149 - codec_dbg(codec, 150 - "HDMI: supports coding type %s: channels = %d, rates =%s%s\n", 151 - cea_audio_coding_type_names[a->format], 152 - a->channels, buf, buf2); 153 - } 154 - 155 - void snd_hdmi_show_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e) 156 - { 157 - int i; 158 - 159 - codec_dbg(codec, "HDMI: detected monitor %s at connection type %s\n", 160 - e->monitor_name, 161 - eld_connection_type_names[e->conn_type]); 162 - 163 - if (e->spk_alloc) { 164 - char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; 165 - snd_hdac_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); 166 - codec_dbg(codec, "HDMI: available speakers:%s\n", buf); 167 - } 168 - 169 - for (i = 0; i < e->sad_count; i++) 170 - hdmi_show_short_audio_desc(codec, e->sad + i); 171 - } 172 - 173 349 #ifdef CONFIG_SND_PROC_FS 174 - 175 - static void hdmi_print_sad_info(int i, struct cea_sad *a, 176 - struct snd_info_buffer *buffer) 177 - { 178 - char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; 179 - 180 - snd_iprintf(buffer, "sad%d_coding_type\t[0x%x] %s\n", 181 - i, a->format, cea_audio_coding_type_names[a->format]); 182 - snd_iprintf(buffer, "sad%d_channels\t\t%d\n", i, a->channels); 183 - 184 - hdmi_print_pcm_rates(a->rates, buf, sizeof(buf)); 185 - snd_iprintf(buffer, "sad%d_rates\t\t[0x%x]%s\n", i, a->rates, buf); 186 - 187 - if (a->format == AUDIO_CODING_TYPE_LPCM) { 188 - snd_print_pcm_bits(a->sample_bits, buf, sizeof(buf)); 189 - snd_iprintf(buffer, "sad%d_bits\t\t[0x%x]%s\n", 190 - i, a->sample_bits, buf); 191 - } 192 - 193 - if (a->max_bitrate) 194 - snd_iprintf(buffer, "sad%d_max_bitrate\t%d\n", 195 - i, a->max_bitrate); 196 - 197 - if (a->profile) 198 - snd_iprintf(buffer, "sad%d_profile\t\t%d\n", i, a->profile); 199 - } 200 - 201 350 void snd_hdmi_print_eld_info(struct hdmi_eld *eld, 202 351 struct snd_info_buffer *buffer, 203 352 hda_nid_t pin_nid, int dev_id, hda_nid_t cvt_nid) 204 353 { 205 - struct parsed_hdmi_eld *e = &eld->info; 206 - char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; 207 - int i; 208 - static const char * const eld_version_names[32] = { 209 - "reserved", 210 - "reserved", 211 - "CEA-861D or below", 212 - [3 ... 30] = "reserved", 213 - [31] = "partial" 214 - }; 215 - static const char * const cea_edid_version_names[8] = { 216 - "no CEA EDID Timing Extension block present", 217 - "CEA-861", 218 - "CEA-861-A", 219 - "CEA-861-B, C or D", 220 - [4 ... 7] = "reserved" 221 - }; 222 - 223 354 snd_iprintf(buffer, "monitor_present\t\t%d\n", eld->monitor_present); 224 355 snd_iprintf(buffer, "eld_valid\t\t%d\n", eld->eld_valid); 225 356 snd_iprintf(buffer, "codec_pin_nid\t\t0x%x\n", pin_nid); 226 357 snd_iprintf(buffer, "codec_dev_id\t\t0x%x\n", dev_id); 227 358 snd_iprintf(buffer, "codec_cvt_nid\t\t0x%x\n", cvt_nid); 359 + 228 360 if (!eld->eld_valid) 229 361 return; 230 - snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); 231 - snd_iprintf(buffer, "connection_type\t\t%s\n", 232 - eld_connection_type_names[e->conn_type]); 233 - snd_iprintf(buffer, "eld_version\t\t[0x%x] %s\n", e->eld_ver, 234 - eld_version_names[e->eld_ver]); 235 - snd_iprintf(buffer, "edid_version\t\t[0x%x] %s\n", e->cea_edid_ver, 236 - cea_edid_version_names[e->cea_edid_ver]); 237 - snd_iprintf(buffer, "manufacture_id\t\t0x%x\n", e->manufacture_id); 238 - snd_iprintf(buffer, "product_id\t\t0x%x\n", e->product_id); 239 - snd_iprintf(buffer, "port_id\t\t\t0x%llx\n", (long long)e->port_id); 240 - snd_iprintf(buffer, "support_hdcp\t\t%d\n", e->support_hdcp); 241 - snd_iprintf(buffer, "support_ai\t\t%d\n", e->support_ai); 242 - snd_iprintf(buffer, "audio_sync_delay\t%d\n", e->aud_synch_delay); 243 362 244 - snd_hdac_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); 245 - snd_iprintf(buffer, "speakers\t\t[0x%x]%s\n", e->spk_alloc, buf); 246 - 247 - snd_iprintf(buffer, "sad_count\t\t%d\n", e->sad_count); 248 - 249 - for (i = 0; i < e->sad_count; i++) 250 - hdmi_print_sad_info(i, e->sad + i, buffer); 363 + snd_print_eld_info(&eld->info, buffer); 251 364 } 252 365 253 366 void snd_hdmi_write_eld_info(struct hdmi_eld *eld, 254 367 struct snd_info_buffer *buffer) 255 368 { 256 - struct parsed_hdmi_eld *e = &eld->info; 369 + struct snd_parsed_hdmi_eld *e = &eld->info; 257 370 char line[64]; 258 371 char name[64]; 259 372 char *sname; ··· 187 556 #endif /* CONFIG_SND_PROC_FS */ 188 557 189 558 /* update PCM info based on ELD */ 190 - void snd_hdmi_eld_update_pcm_info(struct parsed_hdmi_eld *e, 559 + void snd_hdmi_eld_update_pcm_info(struct snd_parsed_hdmi_eld *e, 191 560 struct hda_pcm_stream *hinfo) 192 561 { 193 562 u32 rates; ··· 205 574 maxbps = 16; 206 575 channels_max = 2; 207 576 for (i = 0; i < e->sad_count; i++) { 208 - struct cea_sad *a = &e->sad[i]; 577 + struct snd_cea_sad *a = &e->sad[i]; 209 578 rates |= a->rates; 210 579 if (a->channels > channels_max) 211 580 channels_max = a->channels; 212 581 if (a->format == AUDIO_CODING_TYPE_LPCM) { 213 - if (a->sample_bits & AC_SUPPCM_BITS_20) { 582 + if (a->sample_bits & ELD_PCM_BITS_20) { 214 583 formats |= SNDRV_PCM_FMTBIT_S32_LE; 215 584 if (maxbps < 20) 216 585 maxbps = 20; 217 586 } 218 - if (a->sample_bits & AC_SUPPCM_BITS_24) { 587 + if (a->sample_bits & ELD_PCM_BITS_24) { 219 588 formats |= SNDRV_PCM_FMTBIT_S32_LE; 220 589 if (maxbps < 24) 221 590 maxbps = 24;
+4 -45
sound/pci/hda/hda_local.h
··· 10 10 #ifndef __SOUND_HDA_LOCAL_H 11 11 #define __SOUND_HDA_LOCAL_H 12 12 13 + #include <sound/pcm_drm_eld.h> 14 + 13 15 /* We abuse kcontrol_new.subdev field to pass the NID corresponding to 14 16 * the given new control. If id.subdev has a bit flag HDA_SUBDEV_NID_FLAG, 15 17 * snd_hda_ctl_add() takes the lower-bit subdev value as a valid NID. ··· 677 675 #define snd_hda_enum_bool_helper_info(kcontrol, uinfo) \ 678 676 snd_hda_enum_helper_info(kcontrol, uinfo, 0, NULL) 679 677 680 - /* 681 - * CEA Short Audio Descriptor data 682 - */ 683 - struct cea_sad { 684 - int channels; 685 - int format; /* (format == 0) indicates invalid SAD */ 686 - int rates; 687 - int sample_bits; /* for LPCM */ 688 - int max_bitrate; /* for AC3...ATRAC */ 689 - int profile; /* for WMAPRO */ 690 - }; 691 - 692 - #define ELD_FIXED_BYTES 20 693 - #define ELD_MAX_SIZE 256 694 - #define ELD_MAX_MNL 16 695 - #define ELD_MAX_SAD 16 696 - 697 - /* 698 - * ELD: EDID Like Data 699 - */ 700 - struct parsed_hdmi_eld { 701 - /* 702 - * all fields will be cleared before updating ELD 703 - */ 704 - int baseline_len; 705 - int eld_ver; 706 - int cea_edid_ver; 707 - char monitor_name[ELD_MAX_MNL + 1]; 708 - int manufacture_id; 709 - int product_id; 710 - u64 port_id; 711 - int support_hdcp; 712 - int support_ai; 713 - int conn_type; 714 - int aud_synch_delay; 715 - int spk_alloc; 716 - int sad_count; 717 - struct cea_sad sad[ELD_MAX_SAD]; 718 - }; 719 - 720 678 struct hdmi_eld { 721 679 bool monitor_present; 722 680 bool eld_valid; 723 681 int eld_size; 724 682 char eld_buffer[ELD_MAX_SIZE]; 725 - struct parsed_hdmi_eld info; 683 + struct snd_parsed_hdmi_eld info; 726 684 }; 727 685 728 686 int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid); 729 687 int snd_hdmi_get_eld(struct hda_codec *codec, hda_nid_t nid, 730 688 unsigned char *buf, int *eld_size); 731 - int snd_hdmi_parse_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e, 732 - const unsigned char *buf, int size); 733 - void snd_hdmi_show_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e); 734 - void snd_hdmi_eld_update_pcm_info(struct parsed_hdmi_eld *e, 689 + void snd_hdmi_eld_update_pcm_info(struct snd_parsed_hdmi_eld *e, 735 690 struct hda_pcm_stream *hinfo); 736 691 737 692 int snd_hdmi_get_eld_ati(struct hda_codec *codec, hda_nid_t nid,
+3 -3
sound/pci/hda/patch_hdmi.c
··· 1511 1511 1512 1512 if (eld->eld_valid) { 1513 1513 if (eld->eld_size <= 0 || 1514 - snd_hdmi_parse_eld(codec, &eld->info, eld->eld_buffer, 1515 - eld->eld_size) < 0) { 1514 + snd_parse_eld(hda_codec_dev(codec), &eld->info, 1515 + eld->eld_buffer, eld->eld_size) < 0) { 1516 1516 eld->eld_valid = false; 1517 1517 if (repoll) { 1518 1518 schedule_delayed_work(&per_pin->work, ··· 1555 1555 pcm_jack = pin_idx_to_pcm_jack(codec, per_pin); 1556 1556 1557 1557 if (eld->eld_valid) 1558 - snd_hdmi_show_eld(codec, &eld->info); 1558 + snd_show_eld(hda_codec_dev(codec), &eld->info); 1559 1559 1560 1560 eld_changed = (pin_eld->eld_valid != eld->eld_valid); 1561 1561 eld_changed |= (pin_eld->monitor_present != eld->monitor_present);