diff options
| author | David Henningsson <david.henningsson@canonical.com> | 2013-02-19 10:11:24 -0500 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2013-02-19 12:28:22 -0500 |
| commit | 1613d6b46b433f07f1d2703e4bd102802dcd75a4 (patch) | |
| tree | f568efd924a1a70689f79c29f25cceb7c6a6510b | |
| parent | 68e03de98507065bb5fd1958388974c9bc2cd480 (diff) | |
ALSA: hda - hdmi: Refactor hdmi_eld into parsed_hdmi_eld
For better readability, the information that is parsed out of the
ELD data is now put into a separate parsed_hdmi_eld struct.
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
| -rw-r--r-- | sound/pci/hda/hda_eld.c | 46 | ||||
| -rw-r--r-- | sound/pci/hda/hda_local.h | 27 | ||||
| -rw-r--r-- | sound/pci/hda/patch_hdmi.c | 28 |
3 files changed, 57 insertions, 44 deletions
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 4c054f4486b9..16066d7763ec 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c | |||
| @@ -246,8 +246,8 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a, | |||
| 246 | /* | 246 | /* |
| 247 | * Be careful, ELD buf could be totally rubbish! | 247 | * Be careful, ELD buf could be totally rubbish! |
| 248 | */ | 248 | */ |
| 249 | static int hdmi_update_eld(struct hdmi_eld *e, | 249 | int snd_hdmi_parse_eld(struct parsed_hdmi_eld *e, |
| 250 | const unsigned char *buf, int size) | 250 | const unsigned char *buf, int size) |
| 251 | { | 251 | { |
| 252 | int mnl; | 252 | int mnl; |
| 253 | int i; | 253 | int i; |
| @@ -260,7 +260,6 @@ static int hdmi_update_eld(struct hdmi_eld *e, | |||
| 260 | goto out_fail; | 260 | goto out_fail; |
| 261 | } | 261 | } |
| 262 | 262 | ||
| 263 | e->eld_size = size; | ||
| 264 | e->baseline_len = GRAB_BITS(buf, 2, 0, 8); | 263 | e->baseline_len = GRAB_BITS(buf, 2, 0, 8); |
| 265 | mnl = GRAB_BITS(buf, 4, 0, 5); | 264 | mnl = GRAB_BITS(buf, 4, 0, 5); |
| 266 | e->cea_edid_ver = GRAB_BITS(buf, 4, 5, 3); | 265 | e->cea_edid_ver = GRAB_BITS(buf, 4, 5, 3); |
| @@ -305,7 +304,6 @@ static int hdmi_update_eld(struct hdmi_eld *e, | |||
| 305 | if (!e->spk_alloc) | 304 | if (!e->spk_alloc) |
| 306 | e->spk_alloc = 0xffff; | 305 | e->spk_alloc = 0xffff; |
| 307 | 306 | ||
| 308 | e->eld_valid = true; | ||
| 309 | return 0; | 307 | return 0; |
| 310 | 308 | ||
| 311 | out_fail: | 309 | out_fail: |
| @@ -318,17 +316,16 @@ int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid) | |||
| 318 | AC_DIPSIZE_ELD_BUF); | 316 | AC_DIPSIZE_ELD_BUF); |
| 319 | } | 317 | } |
| 320 | 318 | ||
| 321 | int snd_hdmi_get_eld(struct hdmi_eld *eld, | 319 | int snd_hdmi_get_eld(struct hda_codec *codec, hda_nid_t nid, |
| 322 | struct hda_codec *codec, hda_nid_t nid) | 320 | unsigned char *buf, int *eld_size) |
| 323 | { | 321 | { |
| 324 | int i; | 322 | int i; |
| 325 | int ret; | 323 | int ret; |
| 326 | int size; | 324 | int size; |
| 327 | unsigned char *buf; | ||
| 328 | 325 | ||
| 329 | /* | 326 | /* |
| 330 | * ELD size is initialized to zero in caller function. If no errors and | 327 | * ELD size is initialized to zero in caller function. If no errors and |
| 331 | * ELD is valid, actual eld_size is assigned in hdmi_update_eld() | 328 | * ELD is valid, actual eld_size is assigned. |
| 332 | */ | 329 | */ |
| 333 | 330 | ||
| 334 | size = snd_hdmi_get_eld_size(codec, nid); | 331 | size = snd_hdmi_get_eld_size(codec, nid); |
| @@ -343,8 +340,6 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, | |||
| 343 | } | 340 | } |
| 344 | 341 | ||
| 345 | /* set ELD buffer */ | 342 | /* set ELD buffer */ |
| 346 | buf = eld->eld_buffer; | ||
| 347 | |||
| 348 | for (i = 0; i < size; i++) { | 343 | for (i = 0; i < size; i++) { |
| 349 | unsigned int val = hdmi_get_eld_data(codec, nid, i); | 344 | unsigned int val = hdmi_get_eld_data(codec, nid, i); |
| 350 | /* | 345 | /* |
| @@ -372,8 +367,7 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, | |||
| 372 | buf[i] = val; | 367 | buf[i] = val; |
| 373 | } | 368 | } |
| 374 | 369 | ||
| 375 | ret = hdmi_update_eld(eld, buf, size); | 370 | *eld_size = size; |
| 376 | |||
| 377 | error: | 371 | error: |
| 378 | return ret; | 372 | return ret; |
| 379 | } | 373 | } |
| @@ -438,7 +432,7 @@ void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen) | |||
| 438 | buf[j] = '\0'; /* necessary when j == 0 */ | 432 | buf[j] = '\0'; /* necessary when j == 0 */ |
| 439 | } | 433 | } |
| 440 | 434 | ||
| 441 | void snd_hdmi_show_eld(struct hdmi_eld *e) | 435 | void snd_hdmi_show_eld(struct parsed_hdmi_eld *e) |
| 442 | { | 436 | { |
| 443 | int i; | 437 | int i; |
| 444 | 438 | ||
| @@ -487,10 +481,11 @@ static void hdmi_print_sad_info(int i, struct cea_sad *a, | |||
| 487 | static void hdmi_print_eld_info(struct snd_info_entry *entry, | 481 | static void hdmi_print_eld_info(struct snd_info_entry *entry, |
| 488 | struct snd_info_buffer *buffer) | 482 | struct snd_info_buffer *buffer) |
| 489 | { | 483 | { |
| 490 | struct hdmi_eld *e = entry->private_data; | 484 | struct hdmi_eld *eld = entry->private_data; |
| 485 | struct parsed_hdmi_eld *e = &eld->info; | ||
| 491 | char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; | 486 | char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; |
| 492 | int i; | 487 | int i; |
| 493 | static char *eld_versoin_names[32] = { | 488 | static char *eld_version_names[32] = { |
| 494 | "reserved", | 489 | "reserved", |
| 495 | "reserved", | 490 | "reserved", |
| 496 | "CEA-861D or below", | 491 | "CEA-861D or below", |
| @@ -505,15 +500,15 @@ static void hdmi_print_eld_info(struct snd_info_entry *entry, | |||
| 505 | [4 ... 7] = "reserved" | 500 | [4 ... 7] = "reserved" |
| 506 | }; | 501 | }; |
| 507 | 502 | ||
| 508 | snd_iprintf(buffer, "monitor_present\t\t%d\n", e->monitor_present); | 503 | snd_iprintf(buffer, "monitor_present\t\t%d\n", eld->monitor_present); |
| 509 | snd_iprintf(buffer, "eld_valid\t\t%d\n", e->eld_valid); | 504 | snd_iprintf(buffer, "eld_valid\t\t%d\n", eld->eld_valid); |
| 510 | if (!e->eld_valid) | 505 | if (!eld->eld_valid) |
| 511 | return; | 506 | return; |
| 512 | snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); | 507 | snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); |
| 513 | snd_iprintf(buffer, "connection_type\t\t%s\n", | 508 | snd_iprintf(buffer, "connection_type\t\t%s\n", |
| 514 | eld_connection_type_names[e->conn_type]); | 509 | eld_connection_type_names[e->conn_type]); |
| 515 | snd_iprintf(buffer, "eld_version\t\t[0x%x] %s\n", e->eld_ver, | 510 | snd_iprintf(buffer, "eld_version\t\t[0x%x] %s\n", e->eld_ver, |
| 516 | eld_versoin_names[e->eld_ver]); | 511 | eld_version_names[e->eld_ver]); |
| 517 | snd_iprintf(buffer, "edid_version\t\t[0x%x] %s\n", e->cea_edid_ver, | 512 | snd_iprintf(buffer, "edid_version\t\t[0x%x] %s\n", e->cea_edid_ver, |
| 518 | cea_edid_version_names[e->cea_edid_ver]); | 513 | cea_edid_version_names[e->cea_edid_ver]); |
| 519 | snd_iprintf(buffer, "manufacture_id\t\t0x%x\n", e->manufacture_id); | 514 | snd_iprintf(buffer, "manufacture_id\t\t0x%x\n", e->manufacture_id); |
| @@ -535,7 +530,8 @@ static void hdmi_print_eld_info(struct snd_info_entry *entry, | |||
| 535 | static void hdmi_write_eld_info(struct snd_info_entry *entry, | 530 | static void hdmi_write_eld_info(struct snd_info_entry *entry, |
| 536 | struct snd_info_buffer *buffer) | 531 | struct snd_info_buffer *buffer) |
| 537 | { | 532 | { |
| 538 | struct hdmi_eld *e = entry->private_data; | 533 | struct hdmi_eld *eld = entry->private_data; |
| 534 | struct parsed_hdmi_eld *e = &eld->info; | ||
| 539 | char line[64]; | 535 | char line[64]; |
| 540 | char name[64]; | 536 | char name[64]; |
| 541 | char *sname; | 537 | char *sname; |
| @@ -551,9 +547,9 @@ static void hdmi_write_eld_info(struct snd_info_entry *entry, | |||
| 551 | * eld_version edid_version | 547 | * eld_version edid_version |
| 552 | */ | 548 | */ |
| 553 | if (!strcmp(name, "monitor_present")) | 549 | if (!strcmp(name, "monitor_present")) |
| 554 | e->monitor_present = val; | 550 | eld->monitor_present = val; |
| 555 | else if (!strcmp(name, "eld_valid")) | 551 | else if (!strcmp(name, "eld_valid")) |
| 556 | e->eld_valid = val; | 552 | eld->eld_valid = val; |
| 557 | else if (!strcmp(name, "connection_type")) | 553 | else if (!strcmp(name, "connection_type")) |
| 558 | e->conn_type = val; | 554 | e->conn_type = val; |
| 559 | else if (!strcmp(name, "port_id")) | 555 | else if (!strcmp(name, "port_id")) |
| @@ -627,7 +623,7 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld) | |||
| 627 | #endif /* CONFIG_PROC_FS */ | 623 | #endif /* CONFIG_PROC_FS */ |
| 628 | 624 | ||
| 629 | /* update PCM info based on ELD */ | 625 | /* update PCM info based on ELD */ |
| 630 | void snd_hdmi_eld_update_pcm_info(struct hdmi_eld *eld, | 626 | void snd_hdmi_eld_update_pcm_info(struct parsed_hdmi_eld *e, |
| 631 | struct hda_pcm_stream *hinfo) | 627 | struct hda_pcm_stream *hinfo) |
| 632 | { | 628 | { |
| 633 | u32 rates; | 629 | u32 rates; |
| @@ -644,8 +640,8 @@ void snd_hdmi_eld_update_pcm_info(struct hdmi_eld *eld, | |||
| 644 | formats = SNDRV_PCM_FMTBIT_S16_LE; | 640 | formats = SNDRV_PCM_FMTBIT_S16_LE; |
| 645 | maxbps = 16; | 641 | maxbps = 16; |
| 646 | channels_max = 2; | 642 | channels_max = 2; |
| 647 | for (i = 0; i < eld->sad_count; i++) { | 643 | for (i = 0; i < e->sad_count; i++) { |
| 648 | struct cea_sad *a = &eld->sad[i]; | 644 | struct cea_sad *a = &e->sad[i]; |
| 649 | rates |= a->rates; | 645 | rates |= a->rates; |
| 650 | if (a->channels > channels_max) | 646 | if (a->channels > channels_max) |
| 651 | channels_max = a->channels; | 647 | channels_max = a->channels; |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 05f1d594d17b..363cd487266b 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
| @@ -713,10 +713,10 @@ struct cea_sad { | |||
| 713 | /* | 713 | /* |
| 714 | * ELD: EDID Like Data | 714 | * ELD: EDID Like Data |
| 715 | */ | 715 | */ |
| 716 | struct hdmi_eld { | 716 | struct parsed_hdmi_eld { |
| 717 | bool monitor_present; | 717 | /* |
| 718 | bool eld_valid; | 718 | * all fields will be cleared before updating ELD |
| 719 | int eld_size; | 719 | */ |
| 720 | int baseline_len; | 720 | int baseline_len; |
| 721 | int eld_ver; | 721 | int eld_ver; |
| 722 | int cea_edid_ver; | 722 | int cea_edid_ver; |
| @@ -731,19 +731,26 @@ struct hdmi_eld { | |||
| 731 | int spk_alloc; | 731 | int spk_alloc; |
| 732 | int sad_count; | 732 | int sad_count; |
| 733 | struct cea_sad sad[ELD_MAX_SAD]; | 733 | struct cea_sad sad[ELD_MAX_SAD]; |
| 734 | /* | 734 | }; |
| 735 | * all fields above eld_buffer will be cleared before updating ELD | 735 | |
| 736 | */ | 736 | struct hdmi_eld { |
| 737 | bool monitor_present; | ||
| 738 | bool eld_valid; | ||
| 739 | int eld_size; | ||
| 737 | char eld_buffer[ELD_MAX_SIZE]; | 740 | char eld_buffer[ELD_MAX_SIZE]; |
| 741 | struct parsed_hdmi_eld info; | ||
| 738 | #ifdef CONFIG_PROC_FS | 742 | #ifdef CONFIG_PROC_FS |
| 739 | struct snd_info_entry *proc_entry; | 743 | struct snd_info_entry *proc_entry; |
| 740 | #endif | 744 | #endif |
| 741 | }; | 745 | }; |
| 742 | 746 | ||
| 743 | int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid); | 747 | int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid); |
| 744 | int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t); | 748 | int snd_hdmi_get_eld(struct hda_codec *codec, hda_nid_t nid, |
| 745 | void snd_hdmi_show_eld(struct hdmi_eld *eld); | 749 | unsigned char *buf, int *eld_size); |
| 746 | void snd_hdmi_eld_update_pcm_info(struct hdmi_eld *eld, | 750 | int snd_hdmi_parse_eld(struct parsed_hdmi_eld *e, |
| 751 | const unsigned char *buf, int size); | ||
| 752 | void snd_hdmi_show_eld(struct parsed_hdmi_eld *e); | ||
| 753 | void snd_hdmi_eld_update_pcm_info(struct parsed_hdmi_eld *e, | ||
| 747 | struct hda_pcm_stream *hinfo); | 754 | struct hda_pcm_stream *hinfo); |
| 748 | 755 | ||
| 749 | #ifdef CONFIG_PROC_FS | 756 | #ifdef CONFIG_PROC_FS |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 6bcdd667f514..1e381918eb82 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
| @@ -531,7 +531,7 @@ static int hdmi_channel_allocation(struct hdmi_eld *eld, int channels) | |||
| 531 | * expand ELD's notions to match the ones used by Audio InfoFrame. | 531 | * expand ELD's notions to match the ones used by Audio InfoFrame. |
| 532 | */ | 532 | */ |
| 533 | for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) { | 533 | for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) { |
| 534 | if (eld->spk_alloc & (1 << i)) | 534 | if (eld->info.spk_alloc & (1 << i)) |
| 535 | spk_mask |= eld_speaker_allocation_bits[i]; | 535 | spk_mask |= eld_speaker_allocation_bits[i]; |
| 536 | } | 536 | } |
| 537 | 537 | ||
| @@ -545,7 +545,7 @@ static int hdmi_channel_allocation(struct hdmi_eld *eld, int channels) | |||
| 545 | } | 545 | } |
| 546 | } | 546 | } |
| 547 | 547 | ||
| 548 | snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf)); | 548 | snd_print_channel_allocation(eld->info.spk_alloc, buf, sizeof(buf)); |
| 549 | snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n", | 549 | snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n", |
| 550 | ca, channels, buf); | 550 | ca, channels, buf); |
| 551 | 551 | ||
| @@ -886,7 +886,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, | |||
| 886 | ca = 0; | 886 | ca = 0; |
| 887 | 887 | ||
| 888 | memset(&ai, 0, sizeof(ai)); | 888 | memset(&ai, 0, sizeof(ai)); |
| 889 | if (eld->conn_type == 0) { /* HDMI */ | 889 | if (eld->info.conn_type == 0) { /* HDMI */ |
| 890 | struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi; | 890 | struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi; |
| 891 | 891 | ||
| 892 | hdmi_ai->type = 0x84; | 892 | hdmi_ai->type = 0x84; |
| @@ -895,7 +895,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, | |||
| 895 | hdmi_ai->CC02_CT47 = channels - 1; | 895 | hdmi_ai->CC02_CT47 = channels - 1; |
| 896 | hdmi_ai->CA = ca; | 896 | hdmi_ai->CA = ca; |
| 897 | hdmi_checksum_audio_infoframe(hdmi_ai); | 897 | hdmi_checksum_audio_infoframe(hdmi_ai); |
| 898 | } else if (eld->conn_type == 1) { /* DisplayPort */ | 898 | } else if (eld->info.conn_type == 1) { /* DisplayPort */ |
| 899 | struct dp_audio_infoframe *dp_ai = &ai.dp; | 899 | struct dp_audio_infoframe *dp_ai = &ai.dp; |
| 900 | 900 | ||
| 901 | dp_ai->type = 0x84; | 901 | dp_ai->type = 0x84; |
| @@ -1116,7 +1116,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, | |||
| 1116 | 1116 | ||
| 1117 | /* Restrict capabilities by ELD if this isn't disabled */ | 1117 | /* Restrict capabilities by ELD if this isn't disabled */ |
| 1118 | if (!static_hdmi_pcm && eld->eld_valid) { | 1118 | if (!static_hdmi_pcm && eld->eld_valid) { |
| 1119 | snd_hdmi_eld_update_pcm_info(eld, hinfo); | 1119 | snd_hdmi_eld_update_pcm_info(&eld->info, hinfo); |
| 1120 | if (hinfo->channels_min > hinfo->channels_max || | 1120 | if (hinfo->channels_min > hinfo->channels_max || |
| 1121 | !hinfo->rates || !hinfo->formats) { | 1121 | !hinfo->rates || !hinfo->formats) { |
| 1122 | per_cvt->assigned = 0; | 1122 | per_cvt->assigned = 0; |
| @@ -1177,8 +1177,6 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) | |||
| 1177 | int present = snd_hda_pin_sense(codec, pin_nid); | 1177 | int present = snd_hda_pin_sense(codec, pin_nid); |
| 1178 | bool eld_valid = false; | 1178 | bool eld_valid = false; |
| 1179 | 1179 | ||
| 1180 | memset(eld, 0, offsetof(struct hdmi_eld, eld_buffer)); | ||
| 1181 | |||
| 1182 | eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); | 1180 | eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); |
| 1183 | if (eld->monitor_present) | 1181 | if (eld->monitor_present) |
| 1184 | eld_valid = !!(present & AC_PINSENSE_ELDV); | 1182 | eld_valid = !!(present & AC_PINSENSE_ELDV); |
| @@ -1189,8 +1187,20 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) | |||
| 1189 | 1187 | ||
| 1190 | eld->eld_valid = false; | 1188 | eld->eld_valid = false; |
| 1191 | if (eld_valid) { | 1189 | if (eld_valid) { |
| 1192 | if (!snd_hdmi_get_eld(eld, codec, pin_nid)) | 1190 | if (snd_hdmi_get_eld(codec, pin_nid, eld->eld_buffer, |
| 1193 | snd_hdmi_show_eld(eld); | 1191 | &eld->eld_size) < 0) |
| 1192 | eld_valid = false; | ||
| 1193 | else { | ||
| 1194 | memset(&eld->info, 0, sizeof(struct parsed_hdmi_eld)); | ||
| 1195 | if (snd_hdmi_parse_eld(&eld->info, eld->eld_buffer, | ||
| 1196 | eld->eld_size) < 0) | ||
| 1197 | eld_valid = false; | ||
| 1198 | } | ||
| 1199 | |||
| 1200 | if (eld_valid) { | ||
| 1201 | snd_hdmi_show_eld(&eld->info); | ||
| 1202 | eld->eld_valid = true; | ||
| 1203 | } | ||
| 1194 | else if (repoll) { | 1204 | else if (repoll) { |
| 1195 | queue_delayed_work(codec->bus->workq, | 1205 | queue_delayed_work(codec->bus->workq, |
| 1196 | &per_pin->work, | 1206 | &per_pin->work, |
