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 /sound | |
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>
Diffstat (limited to 'sound')
-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, |