summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/igt_alsa.c93
1 files changed, 81 insertions, 12 deletions
diff --git a/lib/igt_alsa.c b/lib/igt_alsa.c
index 5b5980a94..e1836be7c 100644
--- a/lib/igt_alsa.c
+++ b/lib/igt_alsa.c
@@ -31,6 +31,7 @@
#include "igt_alsa.h"
#include "igt_aux.h"
#include "igt_core.h"
+#include "igt_eld.h"
#define HANDLES_MAX 8
@@ -105,6 +106,68 @@ struct alsa *alsa_init(void)
return alsa;
}
+static bool alsa_dev_has_igt_eld(snd_ctl_t *ctl, int dev)
+{
+ snd_hctl_t *handle;
+ snd_hctl_elem_t *elem;
+ snd_ctl_elem_info_t *info;
+ snd_ctl_elem_value_t *value;
+ const char *name;
+ snd_ctl_elem_type_t type;
+ unsigned int count;
+ const char *eld;
+ bool is_igt, eld_found;
+
+ igt_assert(snd_hctl_open_ctl(&handle, ctl) == 0);
+ igt_assert(snd_hctl_load(handle) == 0);
+ igt_assert(snd_ctl_elem_info_malloc(&info) == 0);
+ igt_assert(snd_ctl_elem_value_malloc(&value) == 0);
+
+ is_igt = eld_found = false;
+ for (elem = snd_hctl_first_elem(handle); elem;
+ elem = snd_hctl_elem_next(elem)) {
+ igt_assert(snd_hctl_elem_info(elem, info) == 0);
+ name = snd_ctl_elem_info_get_name(info);
+ type = snd_ctl_elem_info_get_type(info);
+ count = snd_ctl_elem_info_get_count(info);
+
+ if (strcmp(name, "ELD") != 0)
+ continue;
+ igt_assert(type == SND_CTL_ELEM_TYPE_BYTES);
+ if (snd_ctl_elem_info_get_device(info) != dev)
+ continue;
+
+ eld_found = true;
+
+ igt_assert(snd_hctl_elem_read(elem, value) == 0);
+ if (count == 0) {
+ igt_debug("ELD found for device %s,%d, but it's empty "
+ "(the screen is probably disconnected)\n",
+ snd_hctl_name(handle), dev);
+ break;
+ }
+
+ igt_debug("ELD found for device %s,%d\n",
+ snd_hctl_name(handle), dev);
+ eld = snd_ctl_elem_value_get_bytes(value);
+ is_igt = eld_is_igt(eld, count);
+ break;
+ }
+
+ if (!eld_found) {
+ /* ELDs are probably not supported */
+ igt_debug("ELD not found for device %s,%d, skipping ELD check\n",
+ snd_hctl_name(handle), dev);
+ is_igt = true;
+ }
+
+ snd_ctl_elem_info_free(info);
+ snd_ctl_elem_value_free(value);
+ snd_hctl_free(handle);
+
+ return is_igt;
+}
+
static char *alsa_resolve_indentifier(const char *device_name, int skip)
{
snd_ctl_card_info_t *card_info;
@@ -148,7 +211,6 @@ static char *alsa_resolve_indentifier(const char *device_name, int skip)
}
dev = -1;
-
do {
ret = snd_ctl_pcm_next_device(handle, &dev);
if (ret < 0 || dev < 0)
@@ -167,21 +229,28 @@ static char *alsa_resolve_indentifier(const char *device_name, int skip)
ret = strncmp(device_name, pcm_name,
strlen(device_name));
+ if (ret != 0)
+ continue;
- if (ret == 0) {
- if (skip > 0) {
- skip--;
- continue;
- }
+ if (!alsa_dev_has_igt_eld(handle, dev)) {
+ igt_debug("Device hw:%d,%d matches the name "
+ "but doesn't have an IGT ELD\n",
+ card, dev);
+ continue;
+ }
- igt_debug("Matched device \"%s\"\n", pcm_name);
+ if (skip > 0) {
+ skip--;
+ continue;
+ }
- snprintf(name, sizeof(name), "hw:%d,%d", card,
- dev);
+ igt_debug("Matched device \"%s\" (hw:%d,%d)\n",
+ pcm_name, card, dev);
- identifier = strdup(name);
- goto resolved;
- }
+ snprintf(name, sizeof(name), "hw:%d,%d", card,
+ dev);
+ identifier = strdup(name);
+ goto resolved;
} while (dev >= 0);
snd_ctl_close(handle);