• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file.
4  */
5 
6 #include <alsa/asoundlib.h>
7 #include <linux/input.h>
8 #include <regex.h>
9 #include <syslog.h>
10 
11 #include "cras_alsa_jack.h"
12 #include "cras_alsa_mixer.h"
13 #include "cras_alsa_ucm.h"
14 #include "cras_system_state.h"
15 #include "cras_gpio_jack.h"
16 #include "cras_tm.h"
17 #include "cras_util.h"
18 #include "edid_utils.h"
19 #include "utlist.h"
20 
21 static const unsigned int DISPLAY_INFO_RETRY_DELAY_MS = 200;
22 static const unsigned int DISPLAY_INFO_MAX_RETRIES = 10;
23 static const unsigned int DISPLAY_INFO_GPIO_MAX_RETRIES = 25;
24 
25 /* Constants used to retrieve monitor name from ELD buffer. */
26 static const unsigned int ELD_MNL_MASK = 31;
27 static const unsigned int ELD_MNL_OFFSET = 4;
28 static const unsigned int ELD_MONITOR_NAME_OFFSET = 20;
29 
30 /* Keeps an fd that is registered with system settings.  A list of fds must be
31  * kept so that they can be removed when the jack list is destroyed. */
32 struct jack_poll_fd {
33 	int fd;
34 	struct jack_poll_fd *prev, *next;
35 };
36 
37 /* cras_gpio_jack:  Describes headphone & microphone jack connected to GPIO
38  *
39  *   On Arm-based systems, the headphone & microphone jacks are
40  *   connected to GPIOs which are plumbed through the /dev/input/event
41  *   system.  For these jacks, the software is written to open the
42  *   corresponding /dev/input/event file and monitor it for 'insert' &
43  *   'remove' activity.
44  *
45  *   fd           : File descriptor corresponding to the /dev/input/event file.
46  *
47  *   switch_event : Indicates the type of the /dev/input/event file.
48  *                  Either SW_HEADPHONE_INSERT, or SW_MICROPHONE_INSERT.
49  *
50  *   current_state: 0 -> device not plugged in
51  *                  1 -> device plugged in
52  *   device_name  : Device name extracted from /dev/input/event[0..9]+.
53  *                  Allocated on heap; must free.
54  */
55 struct cras_gpio_jack {
56 	int fd;
57 	unsigned switch_event;
58 	unsigned current_state;
59 	char *device_name;
60 };
61 
62 /* Represents a single alsa Jack, e.g. "Headphone Jack" or "Mic Jack".
63  *    is_gpio: 1 -> gpio switch (union field: gpio)
64  *             0 -> Alsa 'jack' (union field: elem)
65  *    elem - alsa hcontrol element for this jack, when is_gpio == 0.
66  *    gpio - description of gpio-based jack, when is_gpio != 0.
67  *    eld_control - mixer control for ELD info buffer.
68  *    jack_list - list of jacks this belongs to.
69  *    mixer_output - mixer output control used to control audio to this jack.
70  *        This will be null for input jacks.
71  *    mixer_input - mixer input control used to control audio to this jack.
72  *        This will be null for output jacks.
73  *    ucm_device - Name of the ucm device if found, otherwise, NULL.
74  *    edid_file - File to read the EDID from (if available, HDMI only).
75  *    display_info_timer - Timer used to poll display info for HDMI jacks.
76  *    display_info_retries - Number of times to retry reading display info.
77  *
78  *    mixer_output/mixer_input fields are only used to find the node for this
79  *    jack. These are not used for setting volume or mute. There should be a
80  *    1:1 map between node and jack. node->jack follows the pointer; jack->node
81  *    is done by either searching node->jack pointers or searching the node that
82  *    has the same mixer_control as the jack.
83  */
84 struct cras_alsa_jack {
85 	unsigned is_gpio; /* !0 -> 'gpio' valid
86 			   *  0 -> 'elem' valid
87 			   */
88 	union {
89 		snd_hctl_elem_t *elem;
90 		struct cras_gpio_jack gpio;
91 	};
92 
93 	snd_hctl_elem_t *eld_control;
94 	struct cras_alsa_jack_list *jack_list;
95 	struct mixer_control *mixer_output;
96 	struct mixer_control *mixer_input;
97 	char *ucm_device;
98 	const char *override_type_name;
99 	const char *edid_file;
100 	struct cras_timer *display_info_timer;
101 	unsigned int display_info_retries;
102 	struct cras_alsa_jack *prev, *next;
103 };
104 
105 /* Contains all Jacks for a given device.
106  *    hctl - alsa hcontrol for this device's card
107  *         - not opened by the jack list.
108  *    mixer - cras mixer for the card providing this device.
109  *    ucm - CRAS use case manager if available.
110  *    card_index - Index ALSA uses to refer to the card.  The X in "hw:X".
111  *    card_name - The name of the card.
112  *    device_index - Index ALSA uses to refer to the device.  The Y in "hw:X,Y".
113  *    is_first_device - whether this device is the first device on the card.
114  *    direction - Input or output.
115  *    change_callback - function to call when the state of a jack changes.
116  *    callback_data - data to pass back to the callback.
117  *    jacks - list of jacks for this device.
118  */
119 struct cras_alsa_jack_list {
120 	snd_hctl_t *hctl;
121 	struct cras_alsa_mixer *mixer;
122 	struct cras_use_case_mgr *ucm;
123 	unsigned int card_index;
124 	const char *card_name;
125 	size_t device_index;
126 	int is_first_device;
127 	enum CRAS_STREAM_DIRECTION direction;
128 	jack_state_change_callback *change_callback;
129 	void *callback_data;
130 	struct cras_alsa_jack *jacks;
131 };
132 
133 /* Used to contain information needed while looking through GPIO jacks.
134  *    jack_list - The current jack_list.
135  *    section - An associated UCM section.
136  *    result_jack - The resulting jack.
137  *    rc - The return code for the operation.
138  */
139 struct gpio_switch_list_data {
140 	struct cras_alsa_jack_list *jack_list;
141 	struct ucm_section *section;
142 	struct cras_alsa_jack *result_jack;
143 	int rc;
144 };
145 
146 /*
147  * Local Helpers.
148  */
149 
150 #define BITS_PER_BYTE (8)
151 #define BITS_PER_LONG (sizeof(long) * BITS_PER_BYTE)
152 #define NBITS(x) ((((x)-1) / BITS_PER_LONG) + 1)
153 #define OFF(x) ((x) % BITS_PER_LONG)
154 #define BIT(x) (1UL << OFF(x))
155 #define LONG(x) ((x) / BITS_PER_LONG)
156 #define IS_BIT_SET(bit, array) !!((array[LONG(bit)]) & (1UL << OFF(bit)))
157 
sys_input_get_switch_state(int fd,unsigned sw,unsigned * state)158 static int sys_input_get_switch_state(int fd, unsigned sw, unsigned *state)
159 {
160 	unsigned long bits[NBITS(SW_CNT)];
161 	const unsigned long switch_no = sw;
162 
163 	memset(bits, '\0', sizeof(bits));
164 	/* If switch event present & supported, get current state. */
165 	if (gpio_switch_eviocgbit(fd, bits, sizeof(bits)) < 0)
166 		return -EIO;
167 
168 	if (IS_BIT_SET(switch_no, bits))
169 		if (gpio_switch_eviocgsw(fd, bits, sizeof(bits)) >= 0) {
170 			*state = IS_BIT_SET(switch_no, bits);
171 			return 0;
172 		}
173 
174 	return -1;
175 }
176 
cras_alloc_jack(int is_gpio)177 static inline struct cras_alsa_jack *cras_alloc_jack(int is_gpio)
178 {
179 	struct cras_alsa_jack *jack = calloc(1, sizeof(*jack));
180 	if (jack == NULL)
181 		return NULL;
182 	jack->is_gpio = is_gpio;
183 	return jack;
184 }
185 
cras_free_jack(struct cras_alsa_jack * jack,int rm_select_fd)186 static void cras_free_jack(struct cras_alsa_jack *jack, int rm_select_fd)
187 {
188 	if (!jack)
189 		return;
190 
191 	free(jack->ucm_device);
192 	free((void *)jack->edid_file);
193 	if (jack->display_info_timer)
194 		cras_tm_cancel_timer(cras_system_state_get_tm(),
195 				     jack->display_info_timer);
196 
197 	if (jack->is_gpio) {
198 		free(jack->gpio.device_name);
199 		if (jack->gpio.fd >= 0) {
200 			if (rm_select_fd)
201 				cras_system_rm_select_fd(jack->gpio.fd);
202 			close(jack->gpio.fd);
203 		}
204 	}
205 
206 	/*
207 	 * Remove the jack callback set on hctl. Otherwise, snd_hctl_close will
208 	 * trigger a callback while iodev might already be destroyed.
209 	 */
210 	if (!jack->is_gpio && jack->elem)
211 		snd_hctl_elem_set_callback(jack->elem, NULL);
212 
213 	free((void *)jack->override_type_name);
214 	free(jack);
215 }
216 
217 /* Gets the current plug state of the jack */
get_jack_current_state(struct cras_alsa_jack * jack)218 static int get_jack_current_state(struct cras_alsa_jack *jack)
219 {
220 	snd_ctl_elem_value_t *elem_value;
221 
222 	if (jack->is_gpio)
223 		return jack->gpio.current_state;
224 
225 	snd_ctl_elem_value_alloca(&elem_value);
226 	snd_hctl_elem_read(jack->elem, elem_value);
227 
228 	return snd_ctl_elem_value_get_boolean(elem_value, 0);
229 }
230 
read_jack_edid(const struct cras_alsa_jack * jack,uint8_t * edid)231 static int read_jack_edid(const struct cras_alsa_jack *jack, uint8_t *edid)
232 {
233 	int fd, nread;
234 
235 	fd = open(jack->edid_file, O_RDONLY);
236 	if (fd < 0)
237 		return -1;
238 
239 	nread = read(fd, edid, EEDID_SIZE);
240 	close(fd);
241 
242 	if (nread < EDID_SIZE || !edid_valid(edid))
243 		return -1;
244 	return 0;
245 }
246 
check_jack_edid(struct cras_alsa_jack * jack)247 static int check_jack_edid(struct cras_alsa_jack *jack)
248 {
249 	uint8_t edid[EEDID_SIZE];
250 
251 	if (read_jack_edid(jack, edid))
252 		return -1;
253 
254 	/* If the jack supports EDID, check that it supports audio, clearing
255 	 * the plugged state if it doesn't.
256 	 */
257 	if (!edid_lpcm_support(edid, edid[EDID_EXT_FLAG]))
258 		jack->gpio.current_state = 0;
259 	return 0;
260 }
261 
get_jack_edid_monitor_name(const struct cras_alsa_jack * jack,char * buf,unsigned int buf_size)262 static int get_jack_edid_monitor_name(const struct cras_alsa_jack *jack,
263 				      char *buf, unsigned int buf_size)
264 {
265 	uint8_t edid[EEDID_SIZE];
266 
267 	if (read_jack_edid(jack, edid))
268 		return -1;
269 
270 	return edid_get_monitor_name(edid, buf, buf_size);
271 }
272 
273 /* Checks the ELD control of the jack to see if the ELD buffer
274  * is ready to read and report the plug status.
275  */
check_jack_eld(struct cras_alsa_jack * jack)276 static int check_jack_eld(struct cras_alsa_jack *jack)
277 {
278 	snd_ctl_elem_info_t *elem_info;
279 	snd_ctl_elem_info_alloca(&elem_info);
280 
281 	/* Poll ELD control by getting the count of ELD buffer.
282 	 * When seeing zero buffer count, retry after a delay until
283 	 * it's ready or reached the max number of retries. */
284 	if (snd_hctl_elem_info(jack->eld_control, elem_info) != 0)
285 		return -1;
286 	if (snd_ctl_elem_info_get_count(elem_info) == 0)
287 		return -1;
288 	return 0;
289 }
290 
291 static void display_info_delay_cb(struct cras_timer *timer, void *arg);
292 
293 /* Callback function doing following things:
294  * 1. Reset timer and update max number of retries.
295  * 2. Check all conditions to see if it's okay or needed to
296  *    report jack status directly. E.g. jack is unplugged or
297  *    EDID is not ready for some reason.
298  * 3. Check if max number of retries is reached and decide
299  *    to set timer for next callback or report jack state.
300  */
jack_state_change_cb(struct cras_alsa_jack * jack,int retry)301 static inline void jack_state_change_cb(struct cras_alsa_jack *jack, int retry)
302 {
303 	struct cras_tm *tm = cras_system_state_get_tm();
304 
305 	if (jack->display_info_timer) {
306 		cras_tm_cancel_timer(tm, jack->display_info_timer);
307 		jack->display_info_timer = NULL;
308 	}
309 	if (retry) {
310 		jack->display_info_retries =
311 			jack->is_gpio ? DISPLAY_INFO_GPIO_MAX_RETRIES :
312 					DISPLAY_INFO_MAX_RETRIES;
313 	}
314 
315 	if (!get_jack_current_state(jack))
316 		goto report_jack_state;
317 
318 	/* If there is an edid file, check it.  If it is ready continue, if we
319 	 * need to try again later, return here as the timer has been armed and
320 	 * will check again later.
321 	 */
322 	if (jack->edid_file == NULL && jack->eld_control == NULL)
323 		goto report_jack_state;
324 	if (jack->edid_file && (check_jack_edid(jack) == 0))
325 		goto report_jack_state;
326 	if (jack->eld_control && (check_jack_eld(jack) == 0))
327 		goto report_jack_state;
328 
329 	if (--jack->display_info_retries == 0) {
330 		if (jack->is_gpio)
331 			jack->gpio.current_state = 0;
332 		if (jack->edid_file)
333 			syslog(LOG_ERR, "Timeout to read EDID from %s",
334 			       jack->edid_file);
335 		goto report_jack_state;
336 	}
337 
338 	jack->display_info_timer = cras_tm_create_timer(
339 		tm, DISPLAY_INFO_RETRY_DELAY_MS, display_info_delay_cb, jack);
340 	return;
341 
342 report_jack_state:
343 	jack->jack_list->change_callback(jack, get_jack_current_state(jack),
344 					 jack->jack_list->callback_data);
345 }
346 
347 /* gpio_switch_initial_state
348  *
349  *   Determines the initial state of a gpio-based switch.
350  */
gpio_switch_initial_state(struct cras_alsa_jack * jack)351 static void gpio_switch_initial_state(struct cras_alsa_jack *jack)
352 {
353 	unsigned v;
354 	int r = sys_input_get_switch_state(jack->gpio.fd,
355 					   jack->gpio.switch_event, &v);
356 	jack->gpio.current_state = r == 0 ? v : 0;
357 	jack_state_change_cb(jack, 1);
358 }
359 
360 /* Check if the input event is an audio switch event. */
is_audio_switch_event(const struct input_event * ev,int sw_code)361 static inline int is_audio_switch_event(const struct input_event *ev,
362 					int sw_code)
363 {
364 	return (ev->type == EV_SW && ev->code == sw_code);
365 }
366 
367 /* Timer callback to read display info after a hotplug event for an HDMI jack.
368  */
display_info_delay_cb(struct cras_timer * timer,void * arg)369 static void display_info_delay_cb(struct cras_timer *timer, void *arg)
370 {
371 	struct cras_alsa_jack *jack = (struct cras_alsa_jack *)arg;
372 
373 	jack->display_info_timer = NULL;
374 	jack_state_change_cb(jack, 0);
375 }
376 
377 /* gpio_switch_callback
378  *
379  *   This callback is invoked whenever the associated /dev/input/event
380  *   file has data to read.  Perform autoswitching to / from the
381  *   associated device when data is available.
382  */
gpio_switch_callback(void * arg,int events)383 static void gpio_switch_callback(void *arg, int events)
384 {
385 	struct cras_alsa_jack *jack = arg;
386 	int i;
387 	int r;
388 	struct input_event ev[64];
389 
390 	r = gpio_switch_read(jack->gpio.fd, ev,
391 			     ARRAY_SIZE(ev) * sizeof(struct input_event));
392 	if (r < 0)
393 		return;
394 
395 	for (i = 0; i < r / sizeof(struct input_event); ++i)
396 		if (is_audio_switch_event(&ev[i], jack->gpio.switch_event)) {
397 			jack->gpio.current_state = ev[i].value;
398 
399 			jack_state_change_cb(jack, 1);
400 		}
401 }
402 
403 /* Determines if the GPIO jack should be associated with the device of the
404  * jack list. If the device name is not specified in UCM (common case),
405  * assume it should be associated with the first input device or the first
406  * output device on the card.
407  */
408 static unsigned int
gpio_jack_match_device(const struct cras_alsa_jack * jack,struct cras_alsa_jack_list * jack_list,enum CRAS_STREAM_DIRECTION direction)409 gpio_jack_match_device(const struct cras_alsa_jack *jack,
410 		       struct cras_alsa_jack_list *jack_list,
411 		       enum CRAS_STREAM_DIRECTION direction)
412 {
413 	int target_dev_idx;
414 
415 	/* If the device name is not specified in UCM, assume it should be
416 	 * associated with device 0. */
417 	if (!jack_list->ucm || !jack->ucm_device)
418 		return jack_list->is_first_device;
419 
420 	/* If jack has valid ucm_device, that means this jack has already been
421 	 * associated to this card. Next step to match device index on this
422 	 * card. */
423 	target_dev_idx = ucm_get_alsa_dev_idx_for_dev(
424 		jack_list->ucm, jack->ucm_device, direction);
425 
426 	if (target_dev_idx < 0)
427 		return jack_list->is_first_device;
428 
429 	syslog(LOG_DEBUG,
430 	       "Matching GPIO jack, target device idx: %d, "
431 	       "current card name: %s, device index: %zu\n",
432 	       target_dev_idx, jack_list->card_name, jack_list->device_index);
433 
434 	return (target_dev_idx == jack_list->device_index);
435 }
436 
create_jack_for_gpio(struct cras_alsa_jack_list * jack_list,const char * pathname,const char * dev_name,unsigned switch_event,struct cras_alsa_jack ** out_jack)437 static int create_jack_for_gpio(struct cras_alsa_jack_list *jack_list,
438 				const char *pathname, const char *dev_name,
439 				unsigned switch_event,
440 				struct cras_alsa_jack **out_jack)
441 {
442 	struct cras_alsa_jack *jack;
443 	unsigned long bits[NBITS(SW_CNT)];
444 	const char *card_name = jack_list->card_name;
445 	int r;
446 
447 	if (!out_jack)
448 		return -EINVAL;
449 	*out_jack = NULL;
450 
451 	jack = cras_alloc_jack(1);
452 	if (jack == NULL)
453 		return -ENOMEM;
454 
455 	jack->gpio.fd = gpio_switch_open(pathname);
456 	if (jack->gpio.fd == -1) {
457 		r = -EIO;
458 		goto error;
459 	}
460 
461 	jack->gpio.switch_event = switch_event;
462 	jack->jack_list = jack_list;
463 	jack->gpio.device_name = strdup(dev_name);
464 	if (!jack->gpio.device_name) {
465 		r = -ENOMEM;
466 		goto error;
467 	}
468 
469 	if (!strstr(jack->gpio.device_name, card_name) ||
470 	    (gpio_switch_eviocgbit(jack->gpio.fd, bits, sizeof(bits)) < 0) ||
471 	    !IS_BIT_SET(switch_event, bits)) {
472 		r = -EIO;
473 		goto error;
474 	}
475 
476 	*out_jack = jack;
477 	return 0;
478 
479 error:
480 	/* Not yet registered with system select. */
481 	cras_free_jack(jack, 0);
482 	return r;
483 }
484 
485 /* Take ownership and finish setup of the jack.
486  * Add the jack to the jack_list if everything goes well, or destroy it.
487  */
cras_complete_gpio_jack(struct gpio_switch_list_data * data,struct cras_alsa_jack * jack,unsigned switch_event)488 static int cras_complete_gpio_jack(struct gpio_switch_list_data *data,
489 				   struct cras_alsa_jack *jack,
490 				   unsigned switch_event)
491 {
492 	struct cras_alsa_jack_list *jack_list = data->jack_list;
493 	int r;
494 
495 	if (jack->ucm_device) {
496 		jack->edid_file = ucm_get_edid_file_for_dev(jack_list->ucm,
497 							    jack->ucm_device);
498 	}
499 
500 	r = sys_input_get_switch_state(jack->gpio.fd, switch_event,
501 				       &jack->gpio.current_state);
502 	if (r < 0) {
503 		cras_free_jack(jack, 0);
504 		return -EIO;
505 	}
506 	r = cras_system_add_select_fd(jack->gpio.fd, gpio_switch_callback, jack,
507 				      POLLIN);
508 	if (r < 0) {
509 		/* Not yet registered with system select. */
510 		cras_free_jack(jack, 0);
511 		return r;
512 	}
513 
514 	DL_APPEND(jack_list->jacks, jack);
515 	if (!data->result_jack)
516 		data->result_jack = jack;
517 	else if (data->section)
518 		syslog(LOG_ERR, "More than one jack for SectionDevice '%s'.",
519 		       data->section->name);
520 	return 0;
521 }
522 
523 /* open_and_monitor_gpio:
524  *
525  *   Opens a /dev/input/event file associated with a headphone /
526  *   microphone jack and watches it for activity.
527  *   Returns 0 when a jack has been successfully added.
528  */
open_and_monitor_gpio(struct gpio_switch_list_data * data,const char * pathname,const char * dev_name,unsigned switch_event)529 static int open_and_monitor_gpio(struct gpio_switch_list_data *data,
530 				 const char *pathname, const char *dev_name,
531 				 unsigned switch_event)
532 {
533 	struct cras_alsa_jack *jack;
534 	struct cras_alsa_jack_list *jack_list = data->jack_list;
535 	enum CRAS_STREAM_DIRECTION direction = jack_list->direction;
536 	int r;
537 
538 	r = create_jack_for_gpio(jack_list, pathname, dev_name, switch_event,
539 				 &jack);
540 	if (r != 0)
541 		return r;
542 
543 	if (jack_list->ucm)
544 		jack->ucm_device = ucm_get_dev_for_jack(
545 			jack_list->ucm, jack->gpio.device_name, direction);
546 
547 	if (!gpio_jack_match_device(jack, jack_list, direction)) {
548 		cras_free_jack(jack, 0);
549 		return -EIO;
550 	}
551 
552 	if (direction == CRAS_STREAM_OUTPUT &&
553 	    (strstr(jack->gpio.device_name, "Headphone") ||
554 	     strstr(jack->gpio.device_name, "Headset")))
555 		jack->mixer_output = cras_alsa_mixer_get_output_matching_name(
556 			jack_list->mixer, "Headphone");
557 	else if (direction == CRAS_STREAM_OUTPUT &&
558 		 strstr(jack->gpio.device_name, "HDMI"))
559 		jack->mixer_output = cras_alsa_mixer_get_output_matching_name(
560 			jack_list->mixer, "HDMI");
561 
562 	if (jack->ucm_device && direction == CRAS_STREAM_INPUT) {
563 		char *control_name;
564 		control_name = ucm_get_cap_control(jack->jack_list->ucm,
565 						   jack->ucm_device);
566 		if (control_name)
567 			jack->mixer_input =
568 				cras_alsa_mixer_get_input_matching_name(
569 					jack_list->mixer, control_name);
570 	}
571 
572 	return cras_complete_gpio_jack(data, jack, switch_event);
573 }
574 
575 static int
open_and_monitor_gpio_with_section(struct gpio_switch_list_data * data,const char * pathname,unsigned switch_event)576 open_and_monitor_gpio_with_section(struct gpio_switch_list_data *data,
577 				   const char *pathname, unsigned switch_event)
578 {
579 	struct cras_alsa_jack *jack;
580 	struct cras_alsa_jack_list *jack_list = data->jack_list;
581 	struct ucm_section *section = data->section;
582 	enum CRAS_STREAM_DIRECTION direction = jack_list->direction;
583 	int r;
584 
585 	r = create_jack_for_gpio(jack_list, pathname, section->jack_name,
586 				 switch_event, &jack);
587 	if (r != 0)
588 		return r;
589 
590 	jack->ucm_device = strdup(section->name);
591 	if (!jack->ucm_device) {
592 		cras_free_jack(jack, 0);
593 		return -ENOMEM;
594 	}
595 
596 	if (direction == CRAS_STREAM_OUTPUT)
597 		jack->mixer_output = cras_alsa_mixer_get_control_for_section(
598 			jack_list->mixer, section);
599 	else if (direction == CRAS_STREAM_INPUT)
600 		jack->mixer_input = cras_alsa_mixer_get_control_for_section(
601 			jack_list->mixer, section);
602 
603 	return cras_complete_gpio_jack(data, jack, switch_event);
604 }
605 
606 /* Monitor GPIO switches for this jack_list.
607  * Args:
608  *    data - Data for GPIO switch search.
609  *    dev_path - Device full path.
610  *    dev_name - Device name.
611  * Returns:
612  *    0 for success, or negative on error. Assumes success if no jack is
613  *    found, or if the jack could not be accessed.
614  */
gpio_switches_monitor_device(struct gpio_switch_list_data * data,const char * dev_path,const char * dev_name)615 static int gpio_switches_monitor_device(struct gpio_switch_list_data *data,
616 					const char *dev_path,
617 					const char *dev_name)
618 {
619 	static const int out_switches[] = { SW_HEADPHONE_INSERT,
620 					    SW_LINEOUT_INSERT };
621 	static const int in_switches[] = { SW_MICROPHONE_INSERT };
622 	int sw;
623 	const int *switches = out_switches;
624 	int num_switches = ARRAY_SIZE(out_switches);
625 	int success = 1;
626 	int rc = 0;
627 
628 	if (data->section && data->section->jack_switch >= 0) {
629 		switches = &data->section->jack_switch;
630 		num_switches = 1;
631 	} else if (data->jack_list->direction == CRAS_STREAM_INPUT) {
632 		switches = in_switches;
633 		num_switches = ARRAY_SIZE(in_switches);
634 	}
635 
636 	/* Assume that -EIO is returned for jacks that we shouldn't
637 	 * be looking at, but stop trying if we run into another
638 	 * type of error.
639 	 */
640 	for (sw = 0; (rc == 0 || rc == -EIO) && sw < num_switches; sw++) {
641 		if (data->section)
642 			rc = open_and_monitor_gpio_with_section(data, dev_path,
643 								switches[sw]);
644 		else
645 			rc = open_and_monitor_gpio(data, dev_path, dev_name,
646 						   switches[sw]);
647 		if (rc != 0 && rc != -EIO)
648 			success = 0;
649 	}
650 
651 	if (success)
652 		return 0;
653 	return rc;
654 }
655 
gpio_switch_list_with_section(const char * dev_path,const char * dev_name,void * arg)656 static int gpio_switch_list_with_section(const char *dev_path,
657 					 const char *dev_name, void *arg)
658 {
659 	struct gpio_switch_list_data *data =
660 		(struct gpio_switch_list_data *)arg;
661 
662 	if (strcmp(dev_name, data->section->jack_name)) {
663 		/* No match: continue searching. */
664 		return 0;
665 	}
666 
667 	data->rc = gpio_switches_monitor_device(data, dev_path, dev_name);
668 	/* Found the only possible match: stop searching. */
669 	return 1;
670 }
671 
672 /* Match the given jack name to the given regular expression.
673  * Args:
674  *    jack_name - The jack's name.
675  *    re - Regular expression string.
676  * Returns:
677  *    Non-zero for success, or 0 for failure.
678  */
jack_matches_regex(const char * jack_name,const char * re)679 static int jack_matches_regex(const char *jack_name, const char *re)
680 {
681 	regmatch_t m[1];
682 	regex_t regex;
683 	int rc;
684 
685 	rc = regcomp(&regex, re, REG_EXTENDED);
686 	if (rc != 0) {
687 		syslog(LOG_ERR, "Failed to compile regular expression: %s", re);
688 		return 0;
689 	}
690 
691 	rc = regexec(&regex, jack_name, ARRAY_SIZE(m), m, 0) == 0;
692 	regfree(&regex);
693 	return rc;
694 }
695 
gpio_switch_list_by_matching(const char * dev_path,const char * dev_name,void * arg)696 static int gpio_switch_list_by_matching(const char *dev_path,
697 					const char *dev_name, void *arg)
698 {
699 	struct gpio_switch_list_data *data =
700 		(struct gpio_switch_list_data *)arg;
701 
702 	if (data->jack_list->direction == CRAS_STREAM_INPUT) {
703 		if (!jack_matches_regex(dev_name, "^.*Mic Jack$") &&
704 		    !jack_matches_regex(dev_name, "^.*Headset Jack$")) {
705 			/* Continue searching. */
706 			return 0;
707 		}
708 	} else if (data->jack_list->direction == CRAS_STREAM_OUTPUT) {
709 		if (!jack_matches_regex(dev_name, "^.*Headphone Jack$") &&
710 		    !jack_matches_regex(dev_name, "^.*Headset Jack$") &&
711 		    !jack_matches_regex(dev_name, "^.*HDMI Jack$")) {
712 			/* Continue searching. */
713 			return 0;
714 		}
715 	}
716 
717 	data->rc = gpio_switches_monitor_device(data, dev_path, dev_name);
718 	/* Stop searching for failure. */
719 	return data->rc;
720 }
721 
722 /* Find ELD control for HDMI/DP gpio jack. */
find_eld_control_by_dev_index(snd_hctl_t * hctl,unsigned int dev_idx)723 static snd_hctl_elem_t *find_eld_control_by_dev_index(snd_hctl_t *hctl,
724 						      unsigned int dev_idx)
725 {
726 	static const char eld_control_name[] = "ELD";
727 	snd_ctl_elem_id_t *elem_id;
728 
729 	snd_ctl_elem_id_alloca(&elem_id);
730 	snd_ctl_elem_id_clear(elem_id);
731 	snd_ctl_elem_id_set_interface(elem_id, SND_CTL_ELEM_IFACE_PCM);
732 	snd_ctl_elem_id_set_device(elem_id, dev_idx);
733 	snd_ctl_elem_id_set_name(elem_id, eld_control_name);
734 	return snd_hctl_find_elem(hctl, elem_id);
735 }
736 
737 /* For non-gpio jack, check if it's of type hdmi/dp by
738  * matching jack name. */
is_jack_hdmi_dp(const char * jack_name)739 static int is_jack_hdmi_dp(const char *jack_name)
740 {
741 	// TODO(hychao): Use the information provided in UCM instead of
742 	// name matching.
743 	static const char *hdmi_dp = "HDMI";
744 	return !!strstr(jack_name, hdmi_dp);
745 }
746 
747 /* Find GPIO jacks for this jack_list.
748  * Args:
749  *    jack_list - Jack list to add to.
750  *    section - UCM section.
751  *    result_jack - Filled with a pointer to the resulting cras_alsa_jack.
752  * Returns:
753  *    0 for success, or negative on error. Assumes success if no jack is
754  *    found, or if the jack could not be accessed.
755  */
find_gpio_jacks(struct cras_alsa_jack_list * jack_list,struct ucm_section * section,struct cras_alsa_jack ** result_jack)756 static int find_gpio_jacks(struct cras_alsa_jack_list *jack_list,
757 			   struct ucm_section *section,
758 			   struct cras_alsa_jack **result_jack)
759 {
760 	/* GPIO switches are on Arm-based machines, and are
761 	 * only associated with on-board devices.
762 	 */
763 	struct gpio_switch_list_data data;
764 	int rc;
765 
766 	rc = wait_for_dev_input_access();
767 	if (rc != 0) {
768 		syslog(LOG_WARNING, "Could not access /dev/input/event0: %s",
769 		       strerror(rc));
770 		return 0;
771 	}
772 
773 	data.jack_list = jack_list;
774 	data.section = section;
775 	data.result_jack = NULL;
776 	data.rc = 0;
777 
778 	if (section)
779 		gpio_switch_list_for_each(gpio_switch_list_with_section, &data);
780 	else
781 		gpio_switch_list_for_each(gpio_switch_list_by_matching, &data);
782 	if (result_jack) {
783 		*result_jack = data.result_jack;
784 
785 		/* Find ELD control only for HDMI/DP gpio jack. */
786 		if (*result_jack &&
787 		    is_jack_hdmi_dp((*result_jack)->gpio.device_name))
788 			(*result_jack)->eld_control =
789 				find_eld_control_by_dev_index(
790 					jack_list->hctl,
791 					jack_list->device_index);
792 	}
793 	return data.rc;
794 }
795 
796 /* Callback from alsa when a jack control changes.  This is registered with
797  * snd_hctl_elem_set_callback in find_jack_controls and run by calling
798  * snd_hctl_handle_events in alsa_control_event_pending below.
799  * Args:
800  *    elem - The ALSA control element that has changed.
801  *    mask - unused.
802  */
hctl_jack_cb(snd_hctl_elem_t * elem,unsigned int mask)803 static int hctl_jack_cb(snd_hctl_elem_t *elem, unsigned int mask)
804 {
805 	const char *name;
806 	snd_ctl_elem_value_t *elem_value;
807 	struct cras_alsa_jack *jack;
808 
809 	jack = snd_hctl_elem_get_callback_private(elem);
810 	if (jack == NULL) {
811 		syslog(LOG_ERR, "Invalid jack from control event.");
812 		return -EINVAL;
813 	}
814 
815 	snd_ctl_elem_value_alloca(&elem_value);
816 	snd_hctl_elem_read(elem, elem_value);
817 	name = snd_hctl_elem_get_name(elem);
818 
819 	syslog(LOG_DEBUG, "Jack %s %s", name,
820 	       snd_ctl_elem_value_get_boolean(elem_value, 0) ? "plugged" :
821 							       "unplugged");
822 	jack_state_change_cb(jack, 1);
823 	return 0;
824 }
825 
826 /* Determines the device associated with this jack if any.  If the device cannot
827  * be determined (common case), assume device 0. */
hctl_jack_device_index(const char * name)828 static unsigned int hctl_jack_device_index(const char *name)
829 {
830 	/* Look for the substring 'pcm=<device number>' in the element name. */
831 	static const char pcm_search[] = "pcm=";
832 	const char *substr;
833 	int device_index;
834 
835 	substr = strstr(name, pcm_search);
836 	if (substr == NULL)
837 		return 0;
838 	substr += ARRAY_SIZE(pcm_search) - 1;
839 	if (*substr == '\0')
840 		return 0;
841 	device_index = atoi(substr);
842 	if (device_index < 0)
843 		return 0;
844 	return (unsigned int)device_index;
845 }
846 
847 /* Checks if the given control name is in the supplied list of possible jack
848  * control base names. */
is_jack_control_in_list(const char * const * list,unsigned int list_length,const char * control_name)849 static int is_jack_control_in_list(const char *const *list,
850 				   unsigned int list_length,
851 				   const char *control_name)
852 {
853 	unsigned int i;
854 
855 	for (i = 0; i < list_length; i++)
856 		if (strncmp(control_name, list[i], strlen(list[i])) == 0)
857 			return 1;
858 	return 0;
859 }
860 
861 /* Check if the given name is a jack created for the connector control of a
862  * input/output terminal entity on a USB Audio Class 2.0 device. */
is_jack_uac2(const char * jack_name,enum CRAS_STREAM_DIRECTION direction)863 static int is_jack_uac2(const char *jack_name,
864 			enum CRAS_STREAM_DIRECTION direction)
865 {
866 	return jack_matches_regex(jack_name, direction == CRAS_STREAM_OUTPUT ?
867 						     "^.* - Output Jack$" :
868 						     "^.* - Input Jack$");
869 }
870 
871 /* Looks for any JACK controls.  Monitors any found controls for changes and
872  * decides to route based on plug/unlpug events. */
find_jack_controls(struct cras_alsa_jack_list * jack_list)873 static int find_jack_controls(struct cras_alsa_jack_list *jack_list)
874 {
875 	snd_hctl_elem_t *elem;
876 	struct cras_alsa_jack *jack;
877 	const char *name;
878 	static const char *const output_jack_base_names[] = {
879 		"Headphone Jack",
880 		"Front Headphone Jack",
881 		"HDMI/DP",
882 		"Speaker Phantom Jack",
883 	};
884 	static const char *const input_jack_base_names[] = {
885 		"Mic Jack",
886 	};
887 	const char *const *jack_names;
888 	unsigned int num_jack_names;
889 
890 	if (!jack_list->hctl) {
891 		syslog(LOG_WARNING, "Can't search hctl for jacks.");
892 		return 0;
893 	}
894 
895 	if (jack_list->direction == CRAS_STREAM_OUTPUT) {
896 		jack_names = output_jack_base_names;
897 		num_jack_names = ARRAY_SIZE(output_jack_base_names);
898 	} else {
899 		jack_names = input_jack_base_names;
900 		num_jack_names = ARRAY_SIZE(input_jack_base_names);
901 	}
902 
903 	for (elem = snd_hctl_first_elem(jack_list->hctl); elem != NULL;
904 	     elem = snd_hctl_elem_next(elem)) {
905 		snd_ctl_elem_iface_t iface;
906 
907 		iface = snd_hctl_elem_get_interface(elem);
908 		if (iface != SND_CTL_ELEM_IFACE_CARD)
909 			continue;
910 		name = snd_hctl_elem_get_name(elem);
911 		if (!is_jack_control_in_list(jack_names, num_jack_names,
912 					     name) &&
913 		    !is_jack_uac2(name, jack_list->direction))
914 			continue;
915 		if (hctl_jack_device_index(name) != jack_list->device_index)
916 			continue;
917 
918 		jack = cras_alloc_jack(0);
919 		if (jack == NULL)
920 			return -ENOMEM;
921 		jack->elem = elem;
922 		jack->jack_list = jack_list;
923 		DL_APPEND(jack_list->jacks, jack);
924 
925 		snd_hctl_elem_set_callback(elem, hctl_jack_cb);
926 		snd_hctl_elem_set_callback_private(elem, jack);
927 
928 		if (jack_list->direction == CRAS_STREAM_OUTPUT)
929 			jack->mixer_output =
930 				cras_alsa_mixer_get_output_matching_name(
931 					jack_list->mixer, name);
932 		if (jack_list->ucm)
933 			jack->ucm_device = ucm_get_dev_for_jack(
934 				jack_list->ucm, name, jack_list->direction);
935 
936 		if (jack->ucm_device &&
937 		    jack_list->direction == CRAS_STREAM_INPUT) {
938 			char *control_name;
939 			control_name = ucm_get_cap_control(jack->jack_list->ucm,
940 							   jack->ucm_device);
941 			if (control_name)
942 				jack->mixer_input =
943 					cras_alsa_mixer_get_input_matching_name(
944 						jack_list->mixer, control_name);
945 		}
946 
947 		if (jack->ucm_device) {
948 			jack->override_type_name = ucm_get_override_type_name(
949 				jack->jack_list->ucm, jack->ucm_device);
950 		}
951 	}
952 
953 	/* Look up ELD controls */
954 	DL_FOREACH (jack_list->jacks, jack) {
955 		if (jack->is_gpio || jack->eld_control)
956 			continue;
957 		name = snd_hctl_elem_get_name(jack->elem);
958 		if (!is_jack_hdmi_dp(name))
959 			continue;
960 
961 		jack->eld_control = find_eld_control_by_dev_index(
962 			jack_list->hctl, jack_list->device_index);
963 	}
964 
965 	return 0;
966 }
967 
968 /*
969  * Exported Interface.
970  */
971 
cras_alsa_jack_list_find_jacks_by_name_matching(struct cras_alsa_jack_list * jack_list)972 int cras_alsa_jack_list_find_jacks_by_name_matching(
973 	struct cras_alsa_jack_list *jack_list)
974 {
975 	int rc;
976 
977 	rc = find_jack_controls(jack_list);
978 	if (rc != 0)
979 		return rc;
980 
981 	return find_gpio_jacks(jack_list, NULL, NULL);
982 }
983 
find_hctl_jack_for_section(struct cras_alsa_jack_list * jack_list,struct ucm_section * section,struct cras_alsa_jack ** result_jack)984 static int find_hctl_jack_for_section(struct cras_alsa_jack_list *jack_list,
985 				      struct ucm_section *section,
986 				      struct cras_alsa_jack **result_jack)
987 {
988 	snd_hctl_elem_t *elem;
989 	snd_ctl_elem_id_t *elem_id;
990 	struct cras_alsa_jack *jack;
991 
992 	if (!jack_list->hctl) {
993 		syslog(LOG_WARNING, "Can't search hctl for jacks.");
994 		return -ENODEV;
995 	}
996 
997 	snd_ctl_elem_id_alloca(&elem_id);
998 	snd_ctl_elem_id_clear(elem_id);
999 	snd_ctl_elem_id_set_interface(elem_id, SND_CTL_ELEM_IFACE_CARD);
1000 	snd_ctl_elem_id_set_device(elem_id, jack_list->device_index);
1001 	snd_ctl_elem_id_set_name(elem_id, section->jack_name);
1002 	elem = snd_hctl_find_elem(jack_list->hctl, elem_id);
1003 	if (!elem)
1004 		return -ENOENT;
1005 
1006 	syslog(LOG_DEBUG, "Found Jack: %s for %s", section->jack_name,
1007 	       section->name);
1008 
1009 	jack = cras_alloc_jack(0);
1010 	if (jack == NULL)
1011 		return -ENOMEM;
1012 	jack->elem = elem;
1013 	jack->jack_list = jack_list;
1014 
1015 	jack->ucm_device = strdup(section->name);
1016 	if (!jack->ucm_device) {
1017 		free(jack);
1018 		return -ENOMEM;
1019 	}
1020 	if (jack_list->direction == CRAS_STREAM_OUTPUT)
1021 		jack->mixer_output = cras_alsa_mixer_get_control_for_section(
1022 			jack_list->mixer, section);
1023 	else if (jack_list->direction == CRAS_STREAM_INPUT)
1024 		jack->mixer_input = cras_alsa_mixer_get_control_for_section(
1025 			jack_list->mixer, section);
1026 
1027 	snd_hctl_elem_set_callback(elem, hctl_jack_cb);
1028 	snd_hctl_elem_set_callback_private(elem, jack);
1029 	DL_APPEND(jack_list->jacks, jack);
1030 	if (result_jack)
1031 		*result_jack = jack;
1032 
1033 	if (!strcmp(jack->ucm_device, "HDMI") ||
1034 	    !strcmp(jack->ucm_device, "DP"))
1035 		return 0;
1036 
1037 	/* Look up ELD control. */
1038 	jack->eld_control = find_eld_control_by_dev_index(
1039 		jack_list->hctl, jack_list->device_index);
1040 	return 0;
1041 }
1042 
1043 /*
1044  * Exported Interface.
1045  */
1046 
cras_alsa_jack_list_add_jack_for_section(struct cras_alsa_jack_list * jack_list,struct ucm_section * ucm_section,struct cras_alsa_jack ** result_jack)1047 int cras_alsa_jack_list_add_jack_for_section(
1048 	struct cras_alsa_jack_list *jack_list, struct ucm_section *ucm_section,
1049 	struct cras_alsa_jack **result_jack)
1050 {
1051 	if (result_jack)
1052 		*result_jack = NULL;
1053 	if (!ucm_section)
1054 		return -EINVAL;
1055 
1056 	if (!ucm_section->jack_name) {
1057 		/* No jacks defined for this device. */
1058 		return 0;
1059 	}
1060 
1061 	if (!ucm_section->jack_type) {
1062 		syslog(LOG_ERR,
1063 		       "Must specify the JackType for jack '%s' in '%s'.",
1064 		       ucm_section->jack_name, ucm_section->name);
1065 		return -EINVAL;
1066 	}
1067 
1068 	if (!strcmp(ucm_section->jack_type, "hctl")) {
1069 		return find_hctl_jack_for_section(jack_list, ucm_section,
1070 						  result_jack);
1071 	} else if (!strcmp(ucm_section->jack_type, "gpio")) {
1072 		return find_gpio_jacks(jack_list, ucm_section, result_jack);
1073 	} else {
1074 		syslog(LOG_ERR, "Invalid JackType '%s' in '%s'.",
1075 		       ucm_section->jack_type, ucm_section->name);
1076 		return -EINVAL;
1077 	}
1078 }
1079 
1080 struct cras_alsa_jack_list *
cras_alsa_jack_list_create(unsigned int card_index,const char * card_name,unsigned int device_index,int is_first_device,struct cras_alsa_mixer * mixer,struct cras_use_case_mgr * ucm,snd_hctl_t * hctl,enum CRAS_STREAM_DIRECTION direction,jack_state_change_callback * cb,void * cb_data)1081 cras_alsa_jack_list_create(unsigned int card_index, const char *card_name,
1082 			   unsigned int device_index, int is_first_device,
1083 			   struct cras_alsa_mixer *mixer,
1084 			   struct cras_use_case_mgr *ucm, snd_hctl_t *hctl,
1085 			   enum CRAS_STREAM_DIRECTION direction,
1086 			   jack_state_change_callback *cb, void *cb_data)
1087 {
1088 	struct cras_alsa_jack_list *jack_list;
1089 
1090 	if (direction != CRAS_STREAM_INPUT && direction != CRAS_STREAM_OUTPUT)
1091 		return NULL;
1092 
1093 	jack_list = (struct cras_alsa_jack_list *)calloc(1, sizeof(*jack_list));
1094 	if (jack_list == NULL)
1095 		return NULL;
1096 
1097 	jack_list->change_callback = cb;
1098 	jack_list->callback_data = cb_data;
1099 	jack_list->mixer = mixer;
1100 	jack_list->ucm = ucm;
1101 	jack_list->hctl = hctl;
1102 	jack_list->card_index = card_index;
1103 	jack_list->card_name = card_name;
1104 	jack_list->device_index = device_index;
1105 	jack_list->is_first_device = is_first_device;
1106 	jack_list->direction = direction;
1107 
1108 	return jack_list;
1109 }
1110 
cras_alsa_jack_list_destroy(struct cras_alsa_jack_list * jack_list)1111 void cras_alsa_jack_list_destroy(struct cras_alsa_jack_list *jack_list)
1112 {
1113 	struct cras_alsa_jack *jack;
1114 
1115 	if (jack_list == NULL)
1116 		return;
1117 	DL_FOREACH (jack_list->jacks, jack) {
1118 		DL_DELETE(jack_list->jacks, jack);
1119 		cras_free_jack(jack, 1);
1120 	}
1121 	free(jack_list);
1122 }
1123 
cras_alsa_jack_list_has_hctl_jacks(struct cras_alsa_jack_list * jack_list)1124 int cras_alsa_jack_list_has_hctl_jacks(struct cras_alsa_jack_list *jack_list)
1125 {
1126 	struct cras_alsa_jack *jack;
1127 
1128 	if (!jack_list)
1129 		return 0;
1130 	DL_FOREACH (jack_list->jacks, jack) {
1131 		if (!jack->is_gpio)
1132 			return 1;
1133 	}
1134 	return 0;
1135 }
1136 
1137 struct mixer_control *
cras_alsa_jack_get_mixer_output(const struct cras_alsa_jack * jack)1138 cras_alsa_jack_get_mixer_output(const struct cras_alsa_jack *jack)
1139 {
1140 	if (jack == NULL)
1141 		return NULL;
1142 	return jack->mixer_output;
1143 }
1144 
1145 struct mixer_control *
cras_alsa_jack_get_mixer_input(const struct cras_alsa_jack * jack)1146 cras_alsa_jack_get_mixer_input(const struct cras_alsa_jack *jack)
1147 {
1148 	return jack ? jack->mixer_input : NULL;
1149 }
1150 
cras_alsa_jack_list_report(const struct cras_alsa_jack_list * jack_list)1151 void cras_alsa_jack_list_report(const struct cras_alsa_jack_list *jack_list)
1152 {
1153 	struct cras_alsa_jack *jack;
1154 
1155 	if (jack_list == NULL)
1156 		return;
1157 
1158 	DL_FOREACH (jack_list->jacks, jack)
1159 		if (jack->is_gpio)
1160 			gpio_switch_initial_state(jack);
1161 		else
1162 			hctl_jack_cb(jack->elem, 0);
1163 }
1164 
cras_alsa_jack_get_name(const struct cras_alsa_jack * jack)1165 const char *cras_alsa_jack_get_name(const struct cras_alsa_jack *jack)
1166 {
1167 	if (jack == NULL)
1168 		return NULL;
1169 	if (jack->is_gpio)
1170 		return jack->gpio.device_name;
1171 	return snd_hctl_elem_get_name(jack->elem);
1172 }
1173 
cras_alsa_jack_get_ucm_device(const struct cras_alsa_jack * jack)1174 const char *cras_alsa_jack_get_ucm_device(const struct cras_alsa_jack *jack)
1175 {
1176 	return jack->ucm_device;
1177 }
1178 
cras_alsa_jack_update_monitor_name(const struct cras_alsa_jack * jack,char * name_buf,unsigned int buf_size)1179 void cras_alsa_jack_update_monitor_name(const struct cras_alsa_jack *jack,
1180 					char *name_buf, unsigned int buf_size)
1181 {
1182 	snd_ctl_elem_value_t *elem_value;
1183 	snd_ctl_elem_info_t *elem_info;
1184 	const char *buf = NULL;
1185 	int count;
1186 	int mnl = 0;
1187 
1188 	if (!jack->eld_control) {
1189 		if (jack->edid_file)
1190 			get_jack_edid_monitor_name(jack, name_buf, buf_size);
1191 		return;
1192 	}
1193 
1194 	snd_ctl_elem_info_alloca(&elem_info);
1195 	if (snd_hctl_elem_info(jack->eld_control, elem_info) < 0)
1196 		goto fallback_jack_name;
1197 
1198 	count = snd_ctl_elem_info_get_count(elem_info);
1199 	if (count <= ELD_MNL_OFFSET)
1200 		goto fallback_jack_name;
1201 
1202 	snd_ctl_elem_value_alloca(&elem_value);
1203 	if (snd_hctl_elem_read(jack->eld_control, elem_value) < 0)
1204 		goto fallback_jack_name;
1205 
1206 	buf = (const char *)snd_ctl_elem_value_get_bytes(elem_value);
1207 	mnl = buf[ELD_MNL_OFFSET] & ELD_MNL_MASK;
1208 
1209 	if (count < ELD_MONITOR_NAME_OFFSET + mnl)
1210 		goto fallback_jack_name;
1211 
1212 	/* Note that monitor name string does not contain terminate character.
1213 	 * Check monitor name length with name buffer size.
1214 	 */
1215 	if (mnl >= buf_size)
1216 		mnl = buf_size - 1;
1217 	strncpy(name_buf, buf + ELD_MONITOR_NAME_OFFSET, mnl);
1218 	name_buf[mnl] = '\0';
1219 
1220 	return;
1221 
1222 fallback_jack_name:
1223 	buf = cras_alsa_jack_get_name(jack);
1224 	strncpy(name_buf, buf, buf_size - 1);
1225 
1226 	return;
1227 }
1228 
cras_alsa_jack_update_node_type(const struct cras_alsa_jack * jack,enum CRAS_NODE_TYPE * type)1229 void cras_alsa_jack_update_node_type(const struct cras_alsa_jack *jack,
1230 				     enum CRAS_NODE_TYPE *type)
1231 {
1232 	if (!jack->override_type_name)
1233 		return;
1234 	if (!strcmp(jack->override_type_name, "Internal Speaker"))
1235 		*type = CRAS_NODE_TYPE_INTERNAL_SPEAKER;
1236 	return;
1237 }
1238 
cras_alsa_jack_enable_ucm(const struct cras_alsa_jack * jack,int enable)1239 void cras_alsa_jack_enable_ucm(const struct cras_alsa_jack *jack, int enable)
1240 {
1241 	if (jack && jack->ucm_device)
1242 		ucm_set_enabled(jack->jack_list->ucm, jack->ucm_device, enable);
1243 }
1244