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)383 static void gpio_switch_callback(void *arg)
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,const char * card_name,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 const char *card_name,
412 enum CRAS_STREAM_DIRECTION direction)
413 {
414 const char *target_device_name = NULL;
415 char current_device_name[CRAS_IODEV_NAME_BUFFER_SIZE];
416 unsigned int rc;
417
418 /* If the device name is not specified in UCM, assume it should be
419 * associated with device 0. */
420 if (!jack_list->ucm || !jack->ucm_device)
421 return jack_list->is_first_device;
422
423 /* Look for device name specified in a device section of UCM. */
424 target_device_name = ucm_get_device_name_for_dev(
425 jack_list->ucm, jack->ucm_device, direction);
426
427 if (!target_device_name)
428 return jack_list->is_first_device;
429
430 syslog(LOG_DEBUG,
431 "Matching GPIO jack, target device name: %s, "
432 "current card name: %s, device index: %zu\n",
433 target_device_name, card_name, jack_list->device_index);
434
435 /* Device name of format "hw:<card_name>,<device_index>", should fit
436 * in the string of size CRAS_IODEV_NAME_BUFFER_SIZE.*/
437 snprintf(current_device_name, sizeof(current_device_name), "hw:%s,%zu",
438 card_name, jack_list->device_index);
439
440 rc = !strcmp(current_device_name, target_device_name);
441 free((void *)target_device_name);
442 return rc;
443 }
444
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)445 static int create_jack_for_gpio(struct cras_alsa_jack_list *jack_list,
446 const char *pathname, const char *dev_name,
447 unsigned switch_event,
448 struct cras_alsa_jack **out_jack)
449 {
450 struct cras_alsa_jack *jack;
451 unsigned long bits[NBITS(SW_CNT)];
452 const char *card_name = jack_list->card_name;
453 int r;
454
455 if (!out_jack)
456 return -EINVAL;
457 *out_jack = NULL;
458
459 jack = cras_alloc_jack(1);
460 if (jack == NULL)
461 return -ENOMEM;
462
463 jack->gpio.fd = gpio_switch_open(pathname);
464 if (jack->gpio.fd == -1) {
465 r = -EIO;
466 goto error;
467 }
468
469 jack->gpio.switch_event = switch_event;
470 jack->jack_list = jack_list;
471 jack->gpio.device_name = strdup(dev_name);
472 if (!jack->gpio.device_name) {
473 r = -ENOMEM;
474 goto error;
475 }
476
477 if (!strstr(jack->gpio.device_name, card_name) ||
478 (gpio_switch_eviocgbit(jack->gpio.fd, bits, sizeof(bits)) < 0) ||
479 !IS_BIT_SET(switch_event, bits)) {
480 r = -EIO;
481 goto error;
482 }
483
484 *out_jack = jack;
485 return 0;
486
487 error:
488 /* Not yet registered with system select. */
489 cras_free_jack(jack, 0);
490 return r;
491 }
492
493 /* Take ownership and finish setup of the jack.
494 * Add the jack to the jack_list if everything goes well, or destroy it.
495 */
cras_complete_gpio_jack(struct gpio_switch_list_data * data,struct cras_alsa_jack * jack,unsigned switch_event)496 static int cras_complete_gpio_jack(struct gpio_switch_list_data *data,
497 struct cras_alsa_jack *jack,
498 unsigned switch_event)
499 {
500 struct cras_alsa_jack_list *jack_list = data->jack_list;
501 int r;
502
503 if (jack->ucm_device) {
504 jack->edid_file = ucm_get_edid_file_for_dev(jack_list->ucm,
505 jack->ucm_device);
506 }
507
508 r = sys_input_get_switch_state(jack->gpio.fd, switch_event,
509 &jack->gpio.current_state);
510 if (r < 0) {
511 cras_free_jack(jack, 0);
512 return -EIO;
513 }
514 r = cras_system_add_select_fd(jack->gpio.fd, gpio_switch_callback,
515 jack);
516 if (r < 0) {
517 /* Not yet registered with system select. */
518 cras_free_jack(jack, 0);
519 return r;
520 }
521
522 DL_APPEND(jack_list->jacks, jack);
523 if (!data->result_jack)
524 data->result_jack = jack;
525 else if (data->section)
526 syslog(LOG_ERR, "More than one jack for SectionDevice '%s'.",
527 data->section->name);
528 return 0;
529 }
530
531 /* open_and_monitor_gpio:
532 *
533 * Opens a /dev/input/event file associated with a headphone /
534 * microphone jack and watches it for activity.
535 * Returns 0 when a jack has been successfully added.
536 */
open_and_monitor_gpio(struct gpio_switch_list_data * data,const char * pathname,const char * dev_name,unsigned switch_event)537 static int open_and_monitor_gpio(struct gpio_switch_list_data *data,
538 const char *pathname, const char *dev_name,
539 unsigned switch_event)
540 {
541 struct cras_alsa_jack *jack;
542 struct cras_alsa_jack_list *jack_list = data->jack_list;
543 const char *card_name = jack_list->card_name;
544 enum CRAS_STREAM_DIRECTION direction = jack_list->direction;
545 int r;
546
547 r = create_jack_for_gpio(jack_list, pathname, dev_name, switch_event,
548 &jack);
549 if (r != 0)
550 return r;
551
552 if (jack_list->ucm)
553 jack->ucm_device = ucm_get_dev_for_jack(
554 jack_list->ucm, jack->gpio.device_name, direction);
555
556 if (!gpio_jack_match_device(jack, jack_list, card_name, direction)) {
557 cras_free_jack(jack, 0);
558 return -EIO;
559 }
560
561 if (direction == CRAS_STREAM_OUTPUT &&
562 (strstr(jack->gpio.device_name, "Headphone") ||
563 strstr(jack->gpio.device_name, "Headset")))
564 jack->mixer_output = cras_alsa_mixer_get_output_matching_name(
565 jack_list->mixer, "Headphone");
566 else if (direction == CRAS_STREAM_OUTPUT &&
567 strstr(jack->gpio.device_name, "HDMI"))
568 jack->mixer_output = cras_alsa_mixer_get_output_matching_name(
569 jack_list->mixer, "HDMI");
570
571 if (jack->ucm_device && direction == CRAS_STREAM_INPUT) {
572 char *control_name;
573 control_name = ucm_get_cap_control(jack->jack_list->ucm,
574 jack->ucm_device);
575 if (control_name)
576 jack->mixer_input =
577 cras_alsa_mixer_get_input_matching_name(
578 jack_list->mixer, control_name);
579 }
580
581 return cras_complete_gpio_jack(data, jack, switch_event);
582 }
583
584 static int
open_and_monitor_gpio_with_section(struct gpio_switch_list_data * data,const char * pathname,unsigned switch_event)585 open_and_monitor_gpio_with_section(struct gpio_switch_list_data *data,
586 const char *pathname, unsigned switch_event)
587 {
588 struct cras_alsa_jack *jack;
589 struct cras_alsa_jack_list *jack_list = data->jack_list;
590 struct ucm_section *section = data->section;
591 enum CRAS_STREAM_DIRECTION direction = jack_list->direction;
592 int r;
593
594 r = create_jack_for_gpio(jack_list, pathname, section->jack_name,
595 switch_event, &jack);
596 if (r != 0)
597 return r;
598
599 jack->ucm_device = strdup(section->name);
600 if (!jack->ucm_device) {
601 cras_free_jack(jack, 0);
602 return -ENOMEM;
603 }
604
605 if (direction == CRAS_STREAM_OUTPUT)
606 jack->mixer_output = cras_alsa_mixer_get_control_for_section(
607 jack_list->mixer, section);
608 else if (direction == CRAS_STREAM_INPUT)
609 jack->mixer_input = cras_alsa_mixer_get_control_for_section(
610 jack_list->mixer, section);
611
612 return cras_complete_gpio_jack(data, jack, switch_event);
613 }
614
615 /* Monitor GPIO switches for this jack_list.
616 * Args:
617 * data - Data for GPIO switch search.
618 * dev_path - Device full path.
619 * dev_name - Device name.
620 * Returns:
621 * 0 for success, or negative on error. Assumes success if no jack is
622 * found, or if the jack could not be accessed.
623 */
gpio_switches_monitor_device(struct gpio_switch_list_data * data,const char * dev_path,const char * dev_name)624 static int gpio_switches_monitor_device(struct gpio_switch_list_data *data,
625 const char *dev_path,
626 const char *dev_name)
627 {
628 static const int out_switches[] = { SW_HEADPHONE_INSERT,
629 SW_LINEOUT_INSERT };
630 static const int in_switches[] = { SW_MICROPHONE_INSERT };
631 int sw;
632 const int *switches = out_switches;
633 int num_switches = ARRAY_SIZE(out_switches);
634 int success = 1;
635 int rc = 0;
636
637 if (data->section && data->section->jack_switch >= 0) {
638 switches = &data->section->jack_switch;
639 num_switches = 1;
640 } else if (data->jack_list->direction == CRAS_STREAM_INPUT) {
641 switches = in_switches;
642 num_switches = ARRAY_SIZE(in_switches);
643 }
644
645 /* Assume that -EIO is returned for jacks that we shouldn't
646 * be looking at, but stop trying if we run into another
647 * type of error.
648 */
649 for (sw = 0; (rc == 0 || rc == -EIO) && sw < num_switches; sw++) {
650 if (data->section)
651 rc = open_and_monitor_gpio_with_section(data, dev_path,
652 switches[sw]);
653 else
654 rc = open_and_monitor_gpio(data, dev_path, dev_name,
655 switches[sw]);
656 if (rc != 0 && rc != -EIO)
657 success = 0;
658 }
659
660 if (success)
661 return 0;
662 return rc;
663 }
664
gpio_switch_list_with_section(const char * dev_path,const char * dev_name,void * arg)665 static int gpio_switch_list_with_section(const char *dev_path,
666 const char *dev_name, void *arg)
667 {
668 struct gpio_switch_list_data *data =
669 (struct gpio_switch_list_data *)arg;
670
671 if (strcmp(dev_name, data->section->jack_name)) {
672 /* No match: continue searching. */
673 return 0;
674 }
675
676 data->rc = gpio_switches_monitor_device(data, dev_path, dev_name);
677 /* Found the only possible match: stop searching. */
678 return 1;
679 }
680
681 /* Match the given jack name to the given regular expression.
682 * Args:
683 * jack_name - The jack's name.
684 * re - Regular expression string.
685 * Returns:
686 * Non-zero for success, or 0 for failure.
687 */
jack_matches_regex(const char * jack_name,const char * re)688 static int jack_matches_regex(const char *jack_name, const char *re)
689 {
690 regmatch_t m[1];
691 regex_t regex;
692 int rc;
693
694 rc = regcomp(®ex, re, REG_EXTENDED);
695 if (rc != 0) {
696 syslog(LOG_ERR, "Failed to compile regular expression: %s", re);
697 return 0;
698 }
699
700 rc = regexec(®ex, jack_name, ARRAY_SIZE(m), m, 0) == 0;
701 regfree(®ex);
702 return rc;
703 }
704
gpio_switch_list_by_matching(const char * dev_path,const char * dev_name,void * arg)705 static int gpio_switch_list_by_matching(const char *dev_path,
706 const char *dev_name, void *arg)
707 {
708 struct gpio_switch_list_data *data =
709 (struct gpio_switch_list_data *)arg;
710
711 if (data->jack_list->direction == CRAS_STREAM_INPUT) {
712 if (!jack_matches_regex(dev_name, "^.*Mic Jack$") &&
713 !jack_matches_regex(dev_name, "^.*Headset Jack$")) {
714 /* Continue searching. */
715 return 0;
716 }
717 } else if (data->jack_list->direction == CRAS_STREAM_OUTPUT) {
718 if (!jack_matches_regex(dev_name, "^.*Headphone Jack$") &&
719 !jack_matches_regex(dev_name, "^.*Headset Jack$") &&
720 !jack_matches_regex(dev_name, "^.*HDMI Jack$")) {
721 /* Continue searching. */
722 return 0;
723 }
724 }
725
726 data->rc = gpio_switches_monitor_device(data, dev_path, dev_name);
727 /* Stop searching for failure. */
728 return data->rc;
729 }
730
731 /* Find GPIO jacks for this jack_list.
732 * Args:
733 * jack_list - Jack list to add to.
734 * section - UCM section.
735 * result_jack - Filled with a pointer to the resulting cras_alsa_jack.
736 * Returns:
737 * 0 for success, or negative on error. Assumes success if no jack is
738 * found, or if the jack could not be accessed.
739 */
find_gpio_jacks(struct cras_alsa_jack_list * jack_list,struct ucm_section * section,struct cras_alsa_jack ** result_jack)740 static int find_gpio_jacks(struct cras_alsa_jack_list *jack_list,
741 struct ucm_section *section,
742 struct cras_alsa_jack **result_jack)
743 {
744 /* GPIO switches are on Arm-based machines, and are
745 * only associated with on-board devices.
746 */
747 struct gpio_switch_list_data data;
748 int rc;
749
750 rc = wait_for_dev_input_access();
751 if (rc != 0) {
752 syslog(LOG_WARNING, "Could not access /dev/input/event0: %s",
753 strerror(rc));
754 return 0;
755 }
756
757 data.jack_list = jack_list;
758 data.section = section;
759 data.result_jack = NULL;
760 data.rc = 0;
761
762 if (section)
763 gpio_switch_list_for_each(gpio_switch_list_with_section, &data);
764 else
765 gpio_switch_list_for_each(gpio_switch_list_by_matching, &data);
766 if (result_jack)
767 *result_jack = data.result_jack;
768 return data.rc;
769 }
770
771 /* Callback from alsa when a jack control changes. This is registered with
772 * snd_hctl_elem_set_callback in find_jack_controls and run by calling
773 * snd_hctl_handle_events in alsa_control_event_pending below.
774 * Args:
775 * elem - The ALSA control element that has changed.
776 * mask - unused.
777 */
hctl_jack_cb(snd_hctl_elem_t * elem,unsigned int mask)778 static int hctl_jack_cb(snd_hctl_elem_t *elem, unsigned int mask)
779 {
780 const char *name;
781 snd_ctl_elem_value_t *elem_value;
782 struct cras_alsa_jack *jack;
783
784 jack = snd_hctl_elem_get_callback_private(elem);
785 if (jack == NULL) {
786 syslog(LOG_ERR, "Invalid jack from control event.");
787 return -EINVAL;
788 }
789
790 snd_ctl_elem_value_alloca(&elem_value);
791 snd_hctl_elem_read(elem, elem_value);
792 name = snd_hctl_elem_get_name(elem);
793
794 syslog(LOG_DEBUG, "Jack %s %s", name,
795 snd_ctl_elem_value_get_boolean(elem_value, 0) ? "plugged" :
796 "unplugged");
797 jack_state_change_cb(jack, 1);
798 return 0;
799 }
800
801 /* Determines the device associated with this jack if any. If the device cannot
802 * be determined (common case), assume device 0. */
hctl_jack_device_index(const char * name)803 static unsigned int hctl_jack_device_index(const char *name)
804 {
805 /* Look for the substring 'pcm=<device number>' in the element name. */
806 static const char pcm_search[] = "pcm=";
807 const char *substr;
808 int device_index;
809
810 substr = strstr(name, pcm_search);
811 if (substr == NULL)
812 return 0;
813 substr += ARRAY_SIZE(pcm_search) - 1;
814 if (*substr == '\0')
815 return 0;
816 device_index = atoi(substr);
817 if (device_index < 0)
818 return 0;
819 return (unsigned int)device_index;
820 }
821
822 /* For non-gpio jack, check if it's of type hdmi/dp by
823 * matching jack name. */
is_jack_hdmi_dp(const char * jack_name)824 static int is_jack_hdmi_dp(const char *jack_name)
825 {
826 static const char *hdmi_dp = "HDMI/DP";
827 return strncmp(jack_name, hdmi_dp, strlen(hdmi_dp)) == 0;
828 }
829
830 /* Checks if the given control name is in the supplied list of possible jack
831 * control base names. */
is_jack_control_in_list(const char * const * list,unsigned int list_length,const char * control_name)832 static int is_jack_control_in_list(const char *const *list,
833 unsigned int list_length,
834 const char *control_name)
835 {
836 unsigned int i;
837
838 for (i = 0; i < list_length; i++)
839 if (strncmp(control_name, list[i], strlen(list[i])) == 0)
840 return 1;
841 return 0;
842 }
843
844 /* Check if the given name is a jack created for the connector control of a
845 * input/output terminal entity on a USB Audio Class 2.0 device. */
is_jack_uac2(const char * jack_name,enum CRAS_STREAM_DIRECTION direction)846 static int is_jack_uac2(const char *jack_name,
847 enum CRAS_STREAM_DIRECTION direction)
848 {
849 return jack_matches_regex(jack_name, direction == CRAS_STREAM_OUTPUT ?
850 "^.* - Output Jack$" :
851 "^.* - Input Jack$");
852 }
853
854 /* Looks for any JACK controls. Monitors any found controls for changes and
855 * decides to route based on plug/unlpug events. */
find_jack_controls(struct cras_alsa_jack_list * jack_list)856 static int find_jack_controls(struct cras_alsa_jack_list *jack_list)
857 {
858 snd_hctl_elem_t *elem;
859 struct cras_alsa_jack *jack;
860 const char *name;
861 static const char *const output_jack_base_names[] = {
862 "Headphone Jack",
863 "Front Headphone Jack",
864 "HDMI/DP",
865 "Speaker Phantom Jack",
866 };
867 static const char *const input_jack_base_names[] = {
868 "Mic Jack",
869 };
870 static const char eld_control_name[] = "ELD";
871 const char *const *jack_names;
872 unsigned int num_jack_names;
873
874 if (!jack_list->hctl) {
875 syslog(LOG_WARNING, "Can't search hctl for jacks.");
876 return 0;
877 }
878
879 if (jack_list->direction == CRAS_STREAM_OUTPUT) {
880 jack_names = output_jack_base_names;
881 num_jack_names = ARRAY_SIZE(output_jack_base_names);
882 } else {
883 jack_names = input_jack_base_names;
884 num_jack_names = ARRAY_SIZE(input_jack_base_names);
885 }
886
887 for (elem = snd_hctl_first_elem(jack_list->hctl); elem != NULL;
888 elem = snd_hctl_elem_next(elem)) {
889 snd_ctl_elem_iface_t iface;
890
891 iface = snd_hctl_elem_get_interface(elem);
892 if (iface != SND_CTL_ELEM_IFACE_CARD)
893 continue;
894 name = snd_hctl_elem_get_name(elem);
895 if (!is_jack_control_in_list(jack_names, num_jack_names,
896 name) &&
897 !is_jack_uac2(name, jack_list->direction))
898 continue;
899 if (hctl_jack_device_index(name) != jack_list->device_index)
900 continue;
901
902 jack = cras_alloc_jack(0);
903 if (jack == NULL)
904 return -ENOMEM;
905 jack->elem = elem;
906 jack->jack_list = jack_list;
907 DL_APPEND(jack_list->jacks, jack);
908
909 snd_hctl_elem_set_callback(elem, hctl_jack_cb);
910 snd_hctl_elem_set_callback_private(elem, jack);
911
912 if (jack_list->direction == CRAS_STREAM_OUTPUT)
913 jack->mixer_output =
914 cras_alsa_mixer_get_output_matching_name(
915 jack_list->mixer, name);
916 if (jack_list->ucm)
917 jack->ucm_device = ucm_get_dev_for_jack(
918 jack_list->ucm, name, jack_list->direction);
919
920 if (jack->ucm_device &&
921 jack_list->direction == CRAS_STREAM_INPUT) {
922 char *control_name;
923 control_name = ucm_get_cap_control(jack->jack_list->ucm,
924 jack->ucm_device);
925 if (control_name)
926 jack->mixer_input =
927 cras_alsa_mixer_get_input_matching_name(
928 jack_list->mixer, control_name);
929 }
930
931 if (jack->ucm_device) {
932 jack->override_type_name = ucm_get_override_type_name(
933 jack->jack_list->ucm, jack->ucm_device);
934 }
935 }
936
937 /* Look up ELD controls */
938 DL_FOREACH (jack_list->jacks, jack) {
939 if (jack->is_gpio || jack->eld_control)
940 continue;
941 name = snd_hctl_elem_get_name(jack->elem);
942 if (!is_jack_hdmi_dp(name))
943 continue;
944 for (elem = snd_hctl_first_elem(jack_list->hctl); elem != NULL;
945 elem = snd_hctl_elem_next(elem)) {
946 if (strcmp(snd_hctl_elem_get_name(elem),
947 eld_control_name))
948 continue;
949 if (snd_hctl_elem_get_device(elem) !=
950 jack_list->device_index)
951 continue;
952 jack->eld_control = elem;
953 break;
954 }
955 }
956
957 return 0;
958 }
959
960 /*
961 * Exported Interface.
962 */
963
cras_alsa_jack_list_find_jacks_by_name_matching(struct cras_alsa_jack_list * jack_list)964 int cras_alsa_jack_list_find_jacks_by_name_matching(
965 struct cras_alsa_jack_list *jack_list)
966 {
967 int rc;
968
969 rc = find_jack_controls(jack_list);
970 if (rc != 0)
971 return rc;
972
973 return find_gpio_jacks(jack_list, NULL, NULL);
974 }
975
find_hctl_jack_for_section(struct cras_alsa_jack_list * jack_list,struct ucm_section * section,struct cras_alsa_jack ** result_jack)976 static int find_hctl_jack_for_section(struct cras_alsa_jack_list *jack_list,
977 struct ucm_section *section,
978 struct cras_alsa_jack **result_jack)
979 {
980 static const char eld_control_name[] = "ELD";
981 snd_hctl_elem_t *elem;
982 snd_ctl_elem_id_t *elem_id;
983 struct cras_alsa_jack *jack;
984
985 if (!jack_list->hctl) {
986 syslog(LOG_WARNING, "Can't search hctl for jacks.");
987 return -ENODEV;
988 }
989
990 snd_ctl_elem_id_alloca(&elem_id);
991 snd_ctl_elem_id_clear(elem_id);
992 snd_ctl_elem_id_set_interface(elem_id, SND_CTL_ELEM_IFACE_CARD);
993 snd_ctl_elem_id_set_device(elem_id, jack_list->device_index);
994 snd_ctl_elem_id_set_name(elem_id, section->jack_name);
995 elem = snd_hctl_find_elem(jack_list->hctl, elem_id);
996 if (!elem)
997 return -ENOENT;
998
999 syslog(LOG_DEBUG, "Found Jack: %s for %s", section->jack_name,
1000 section->name);
1001
1002 jack = cras_alloc_jack(0);
1003 if (jack == NULL)
1004 return -ENOMEM;
1005 jack->elem = elem;
1006 jack->jack_list = jack_list;
1007
1008 jack->ucm_device = strdup(section->name);
1009 if (!jack->ucm_device) {
1010 free(jack);
1011 return -ENOMEM;
1012 }
1013 if (jack_list->direction == CRAS_STREAM_OUTPUT)
1014 jack->mixer_output = cras_alsa_mixer_get_control_for_section(
1015 jack_list->mixer, section);
1016 else if (jack_list->direction == CRAS_STREAM_INPUT)
1017 jack->mixer_input = cras_alsa_mixer_get_control_for_section(
1018 jack_list->mixer, section);
1019
1020 snd_hctl_elem_set_callback(elem, hctl_jack_cb);
1021 snd_hctl_elem_set_callback_private(elem, jack);
1022 DL_APPEND(jack_list->jacks, jack);
1023 if (result_jack)
1024 *result_jack = jack;
1025
1026 if (!strcmp(jack->ucm_device, "HDMI") ||
1027 !strcmp(jack->ucm_device, "DP"))
1028 return 0;
1029
1030 /* Look up ELD control. */
1031 snd_ctl_elem_id_set_name(elem_id, eld_control_name);
1032 elem = snd_hctl_find_elem(jack_list->hctl, elem_id);
1033 if (elem)
1034 jack->eld_control = elem;
1035 return 0;
1036 }
1037
1038 /*
1039 * Exported Interface.
1040 */
1041
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)1042 int cras_alsa_jack_list_add_jack_for_section(
1043 struct cras_alsa_jack_list *jack_list, struct ucm_section *ucm_section,
1044 struct cras_alsa_jack **result_jack)
1045 {
1046 if (result_jack)
1047 *result_jack = NULL;
1048 if (!ucm_section)
1049 return -EINVAL;
1050
1051 if (!ucm_section->jack_name) {
1052 /* No jacks defined for this device. */
1053 return 0;
1054 }
1055
1056 if (!ucm_section->jack_type) {
1057 syslog(LOG_ERR,
1058 "Must specify the JackType for jack '%s' in '%s'.",
1059 ucm_section->jack_name, ucm_section->name);
1060 return -EINVAL;
1061 }
1062
1063 if (!strcmp(ucm_section->jack_type, "hctl")) {
1064 return find_hctl_jack_for_section(jack_list, ucm_section,
1065 result_jack);
1066 } else if (!strcmp(ucm_section->jack_type, "gpio")) {
1067 return find_gpio_jacks(jack_list, ucm_section, result_jack);
1068 } else {
1069 syslog(LOG_ERR, "Invalid JackType '%s' in '%s'.",
1070 ucm_section->jack_type, ucm_section->name);
1071 return -EINVAL;
1072 }
1073 }
1074
1075 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)1076 cras_alsa_jack_list_create(unsigned int card_index, const char *card_name,
1077 unsigned int device_index, int is_first_device,
1078 struct cras_alsa_mixer *mixer,
1079 struct cras_use_case_mgr *ucm, snd_hctl_t *hctl,
1080 enum CRAS_STREAM_DIRECTION direction,
1081 jack_state_change_callback *cb, void *cb_data)
1082 {
1083 struct cras_alsa_jack_list *jack_list;
1084
1085 if (direction != CRAS_STREAM_INPUT && direction != CRAS_STREAM_OUTPUT)
1086 return NULL;
1087
1088 jack_list = (struct cras_alsa_jack_list *)calloc(1, sizeof(*jack_list));
1089 if (jack_list == NULL)
1090 return NULL;
1091
1092 jack_list->change_callback = cb;
1093 jack_list->callback_data = cb_data;
1094 jack_list->mixer = mixer;
1095 jack_list->ucm = ucm;
1096 jack_list->hctl = hctl;
1097 jack_list->card_index = card_index;
1098 jack_list->card_name = card_name;
1099 jack_list->device_index = device_index;
1100 jack_list->is_first_device = is_first_device;
1101 jack_list->direction = direction;
1102
1103 return jack_list;
1104 }
1105
cras_alsa_jack_list_destroy(struct cras_alsa_jack_list * jack_list)1106 void cras_alsa_jack_list_destroy(struct cras_alsa_jack_list *jack_list)
1107 {
1108 struct cras_alsa_jack *jack;
1109
1110 if (jack_list == NULL)
1111 return;
1112 DL_FOREACH (jack_list->jacks, jack) {
1113 DL_DELETE(jack_list->jacks, jack);
1114 cras_free_jack(jack, 1);
1115 }
1116 free(jack_list);
1117 }
1118
cras_alsa_jack_list_has_hctl_jacks(struct cras_alsa_jack_list * jack_list)1119 int cras_alsa_jack_list_has_hctl_jacks(struct cras_alsa_jack_list *jack_list)
1120 {
1121 struct cras_alsa_jack *jack;
1122
1123 if (!jack_list)
1124 return 0;
1125 DL_FOREACH (jack_list->jacks, jack) {
1126 if (!jack->is_gpio)
1127 return 1;
1128 }
1129 return 0;
1130 }
1131
1132 struct mixer_control *
cras_alsa_jack_get_mixer_output(const struct cras_alsa_jack * jack)1133 cras_alsa_jack_get_mixer_output(const struct cras_alsa_jack *jack)
1134 {
1135 if (jack == NULL)
1136 return NULL;
1137 return jack->mixer_output;
1138 }
1139
1140 struct mixer_control *
cras_alsa_jack_get_mixer_input(const struct cras_alsa_jack * jack)1141 cras_alsa_jack_get_mixer_input(const struct cras_alsa_jack *jack)
1142 {
1143 return jack ? jack->mixer_input : NULL;
1144 }
1145
cras_alsa_jack_list_report(const struct cras_alsa_jack_list * jack_list)1146 void cras_alsa_jack_list_report(const struct cras_alsa_jack_list *jack_list)
1147 {
1148 struct cras_alsa_jack *jack;
1149
1150 if (jack_list == NULL)
1151 return;
1152
1153 DL_FOREACH (jack_list->jacks, jack)
1154 if (jack->is_gpio)
1155 gpio_switch_initial_state(jack);
1156 else
1157 hctl_jack_cb(jack->elem, 0);
1158 }
1159
cras_alsa_jack_get_name(const struct cras_alsa_jack * jack)1160 const char *cras_alsa_jack_get_name(const struct cras_alsa_jack *jack)
1161 {
1162 if (jack == NULL)
1163 return NULL;
1164 if (jack->is_gpio)
1165 return jack->gpio.device_name;
1166 return snd_hctl_elem_get_name(jack->elem);
1167 }
1168
cras_alsa_jack_get_ucm_device(const struct cras_alsa_jack * jack)1169 const char *cras_alsa_jack_get_ucm_device(const struct cras_alsa_jack *jack)
1170 {
1171 return jack->ucm_device;
1172 }
1173
cras_alsa_jack_update_monitor_name(const struct cras_alsa_jack * jack,char * name_buf,unsigned int buf_size)1174 void cras_alsa_jack_update_monitor_name(const struct cras_alsa_jack *jack,
1175 char *name_buf, unsigned int buf_size)
1176 {
1177 snd_ctl_elem_value_t *elem_value;
1178 snd_ctl_elem_info_t *elem_info;
1179 const char *buf = NULL;
1180 int count;
1181 int mnl = 0;
1182
1183 if (!jack->eld_control) {
1184 if (jack->edid_file)
1185 get_jack_edid_monitor_name(jack, name_buf, buf_size);
1186 return;
1187 }
1188
1189 snd_ctl_elem_info_alloca(&elem_info);
1190 if (snd_hctl_elem_info(jack->eld_control, elem_info) < 0)
1191 goto fallback_jack_name;
1192
1193 count = snd_ctl_elem_info_get_count(elem_info);
1194 if (count <= ELD_MNL_OFFSET)
1195 goto fallback_jack_name;
1196
1197 snd_ctl_elem_value_alloca(&elem_value);
1198 if (snd_hctl_elem_read(jack->eld_control, elem_value) < 0)
1199 goto fallback_jack_name;
1200
1201 buf = (const char *)snd_ctl_elem_value_get_bytes(elem_value);
1202 mnl = buf[ELD_MNL_OFFSET] & ELD_MNL_MASK;
1203
1204 if (count < ELD_MONITOR_NAME_OFFSET + mnl)
1205 goto fallback_jack_name;
1206
1207 /* Note that monitor name string does not contain terminate character.
1208 * Check monitor name length with name buffer size.
1209 */
1210 if (mnl >= buf_size)
1211 mnl = buf_size - 1;
1212 strncpy(name_buf, buf + ELD_MONITOR_NAME_OFFSET, mnl);
1213 name_buf[mnl] = '\0';
1214
1215 return;
1216
1217 fallback_jack_name:
1218 buf = cras_alsa_jack_get_name(jack);
1219 strncpy(name_buf, buf, buf_size - 1);
1220
1221 return;
1222 }
1223
cras_alsa_jack_update_node_type(const struct cras_alsa_jack * jack,enum CRAS_NODE_TYPE * type)1224 void cras_alsa_jack_update_node_type(const struct cras_alsa_jack *jack,
1225 enum CRAS_NODE_TYPE *type)
1226 {
1227 if (!jack->override_type_name)
1228 return;
1229 if (!strcmp(jack->override_type_name, "Internal Speaker"))
1230 *type = CRAS_NODE_TYPE_INTERNAL_SPEAKER;
1231 return;
1232 }
1233
cras_alsa_jack_enable_ucm(const struct cras_alsa_jack * jack,int enable)1234 void cras_alsa_jack_enable_ucm(const struct cras_alsa_jack *jack, int enable)
1235 {
1236 if (jack && jack->ucm_device)
1237 ucm_set_enabled(jack->jack_list->ucm, jack->ucm_device, enable);
1238 }
1239