mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
alsa-util: Add a function to read ELD info
Currently, this function only reads the monitor name, but could be extended to read e g supported formats as well. Signed-off-by: David Henningsson <david.henningsson@canonical.com>
This commit is contained in:
parent
a40d83a472
commit
eaa893d7d1
2 changed files with 76 additions and 0 deletions
|
|
@ -1462,6 +1462,20 @@ snd_hctl_elem_t* pa_alsa_find_jack(snd_hctl_t *hctl, const char* jack_name)
|
|||
return snd_hctl_find_elem(hctl, id);
|
||||
}
|
||||
|
||||
snd_hctl_elem_t* pa_alsa_find_eld_ctl(snd_hctl_t *hctl, int device) {
|
||||
snd_ctl_elem_id_t *id;
|
||||
|
||||
/* See if we can find the ELD control */
|
||||
snd_ctl_elem_id_alloca(&id);
|
||||
snd_ctl_elem_id_clear(id);
|
||||
snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_PCM);
|
||||
snd_ctl_elem_id_set_name(id, "ELD");
|
||||
snd_ctl_elem_id_set_device(id, device);
|
||||
|
||||
return snd_hctl_find_elem(hctl, id);
|
||||
}
|
||||
|
||||
|
||||
static int prepare_mixer(snd_mixer_t *mixer, const char *dev, snd_hctl_t **hctl) {
|
||||
int err;
|
||||
|
||||
|
|
@ -1574,3 +1588,57 @@ snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device, snd_h
|
|||
snd_mixer_close(m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int pa_alsa_get_hdmi_eld(snd_hctl_t *hctl, int device, pa_hdmi_eld *eld) {
|
||||
|
||||
/* The ELD format is specific to HDA Intel sound cards and defined in the
|
||||
HDA specification: http://www.intel.com/content/www/us/en/standards/high-definition-audio-specification.html */
|
||||
int err;
|
||||
snd_hctl_elem_t *elem;
|
||||
snd_ctl_elem_info_t *info;
|
||||
snd_ctl_elem_value_t *value;
|
||||
uint8_t *elddata;
|
||||
unsigned int eldsize, mnl;
|
||||
|
||||
pa_assert(eld != NULL);
|
||||
|
||||
/* See if we can find the ELD control */
|
||||
elem = pa_alsa_find_eld_ctl(hctl, device);
|
||||
if (elem == NULL) {
|
||||
pa_log_debug("No ELD info control found (for device=%d)", device);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Does it have any contents? */
|
||||
snd_ctl_elem_info_alloca(&info);
|
||||
snd_ctl_elem_value_alloca(&value);
|
||||
if ((err = snd_hctl_elem_info(elem, info)) < 0 ||
|
||||
(err = snd_hctl_elem_read(elem, value)) < 0) {
|
||||
pa_log_warn("Accessing ELD control failed with error %s", snd_strerror(err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
eldsize = snd_ctl_elem_info_get_count(info);
|
||||
elddata = (unsigned char *) snd_ctl_elem_value_get_bytes(value);
|
||||
if (elddata == NULL || eldsize == 0) {
|
||||
pa_log_debug("ELD info empty (for device=%d)", device);
|
||||
return -1;
|
||||
}
|
||||
if (eldsize < 20 || eldsize > 256) {
|
||||
pa_log_debug("ELD info has wrong size (for device=%d)", device);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try to fetch monitor name */
|
||||
mnl = elddata[4] & 0x1f;
|
||||
if (mnl == 0 || mnl > 16 || 20 + mnl > eldsize) {
|
||||
pa_log_debug("No monitor name in ELD info (for device=%d)", device);
|
||||
mnl = 0;
|
||||
}
|
||||
memcpy(eld->monitor_name, &elddata[20], mnl);
|
||||
eld->monitor_name[mnl] = '\0';
|
||||
if (mnl)
|
||||
pa_log_debug("Monitor name in ELD info is '%s' (for device=%d)", eld->monitor_name, device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,7 +143,15 @@ const char* pa_alsa_strerror(int errnum);
|
|||
pa_bool_t pa_alsa_may_tsched(pa_bool_t want);
|
||||
|
||||
snd_hctl_elem_t* pa_alsa_find_jack(snd_hctl_t *hctl, const char* jack_name);
|
||||
snd_hctl_elem_t* pa_alsa_find_eld_ctl(snd_hctl_t *hctl, int device);
|
||||
|
||||
snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device, snd_hctl_t **hctl);
|
||||
|
||||
typedef struct pa_hdmi_eld pa_hdmi_eld;
|
||||
struct pa_hdmi_eld {
|
||||
char monitor_name[17];
|
||||
};
|
||||
|
||||
int pa_alsa_get_hdmi_eld(snd_hctl_t *hctl, int device, pa_hdmi_eld *eld);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue