aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorDavid Henningsson <david.henningsson@canonical.com>2013-02-19 10:11:24 -0500
committerTakashi Iwai <tiwai@suse.de>2013-02-19 12:28:22 -0500
commit1613d6b46b433f07f1d2703e4bd102802dcd75a4 (patch)
treef568efd924a1a70689f79c29f25cceb7c6a6510b /sound
parent68e03de98507065bb5fd1958388974c9bc2cd480 (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.c46
-rw-r--r--sound/pci/hda/hda_local.h27
-rw-r--r--sound/pci/hda/patch_hdmi.c28
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 */
249static int hdmi_update_eld(struct hdmi_eld *e, 249int 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
311out_fail: 309out_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
321int snd_hdmi_get_eld(struct hdmi_eld *eld, 319int 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
377error: 371error:
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
441void snd_hdmi_show_eld(struct hdmi_eld *e) 435void 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,
487static void hdmi_print_eld_info(struct snd_info_entry *entry, 481static 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,
535static void hdmi_write_eld_info(struct snd_info_entry *entry, 530static 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 */
630void snd_hdmi_eld_update_pcm_info(struct hdmi_eld *eld, 626void 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 */
716struct hdmi_eld { 716struct 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 */ 736struct 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
743int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid); 747int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid);
744int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t); 748int snd_hdmi_get_eld(struct hda_codec *codec, hda_nid_t nid,
745void snd_hdmi_show_eld(struct hdmi_eld *eld); 749 unsigned char *buf, int *eld_size);
746void snd_hdmi_eld_update_pcm_info(struct hdmi_eld *eld, 750int snd_hdmi_parse_eld(struct parsed_hdmi_eld *e,
751 const unsigned char *buf, int size);
752void snd_hdmi_show_eld(struct parsed_hdmi_eld *e);
753void 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,