Home | History | Annotate | Download | only in server
      1 /* Copyright 2016 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 <stdlib.h>
      7 #include <string.h>
      8 #include <syslog.h>
      9 
     10 #include "cras_alsa_ucm_section.h"
     11 #include "cras_alsa_mixer_name.h"
     12 #include "utlist.h"
     13 
     14 static void ucm_section_free(struct ucm_section *section) {
     15 	if (section->name)
     16 		free((void *)section->name);
     17 	if (section->jack_name)
     18 		free((void *)section->jack_name);
     19 	if (section->jack_type)
     20 		free((void *)section->jack_type);
     21 	if (section->mixer_name)
     22 		free((void *)section->mixer_name);
     23 	mixer_name_free(section->coupled);
     24 	free(section);
     25 }
     26 
     27 void ucm_section_free_list(struct ucm_section *sections)
     28 {
     29 	struct ucm_section *section;
     30 	DL_FOREACH(sections, section) {
     31 		DL_DELETE(sections, section);
     32 		ucm_section_free(section);
     33 	}
     34 }
     35 
     36 struct ucm_section *ucm_section_create(const char *name,
     37 				       int dev_idx,
     38 				       enum CRAS_STREAM_DIRECTION dir,
     39 				       const char *jack_name,
     40 				       const char *jack_type)
     41 {
     42 	struct ucm_section *section_list = NULL;
     43 	struct ucm_section *section;
     44 
     45 	if (!name)
     46 		return NULL;
     47 
     48 	section = (struct ucm_section *)
     49 		  calloc(1, sizeof(struct ucm_section));
     50 	if (!section)
     51 		return NULL;
     52 
     53 	section->dev_idx = dev_idx;
     54 	section->dir = dir;
     55 	section->name = strdup(name);
     56 	if (!section->name)
     57 		goto error;
     58 
     59 	if (jack_name) {
     60 		section->jack_name = strdup(jack_name);
     61 		if (!section->jack_name)
     62 			goto error;
     63 	}
     64 	if (jack_type) {
     65 		section->jack_type = strdup(jack_type);
     66 		if (!section->jack_type)
     67 			goto error;
     68 	}
     69 	/* Default to -1 which means auto-detect. */
     70 	section->jack_switch = -1;
     71 
     72 	/* Make sure to initialize this item as a list. */
     73 	DL_APPEND(section_list, section);
     74 	return section_list;
     75 
     76 error:
     77 	ucm_section_free(section);
     78 	return NULL;
     79 }
     80 
     81 int ucm_section_set_mixer_name(struct ucm_section *section,
     82 			       const char *name)
     83 {
     84 	if (!section || !name)
     85 		return -EINVAL;
     86 
     87 	if (section->mixer_name)
     88 		free((void *)section->mixer_name);
     89 	section->mixer_name = strdup(name);
     90 	if (!section->mixer_name)
     91 		return -ENOMEM;
     92 	return 0;
     93 }
     94 
     95 int ucm_section_add_coupled(struct ucm_section *section,
     96 			    const char *name,
     97 			    mixer_name_type type)
     98 {
     99 	struct mixer_name *m_name;
    100 
    101 	if (!section || !name || type == MIXER_NAME_UNDEFINED)
    102 		return -EINVAL;
    103 
    104 	m_name = mixer_name_add(NULL, name, section->dir, type);
    105 	if (!m_name)
    106 		return -ENOMEM;
    107 	DL_APPEND(section->coupled, m_name);
    108 	return 0;
    109 }
    110 
    111 int ucm_section_concat_coupled(struct ucm_section *section,
    112 			       struct mixer_name *coupled)
    113 {
    114 	if (!section || !coupled)
    115 		return -EINVAL;
    116 	DL_CONCAT(section->coupled, coupled);
    117 	return 0;
    118 }
    119 
    120 void ucm_section_dump(struct ucm_section *section)
    121 {
    122 	syslog(LOG_DEBUG, "section: %s [%d] (%s)",
    123 		section->name, section->dev_idx,
    124 		section->dir == CRAS_STREAM_OUTPUT ? "output" : "input");
    125 	syslog(LOG_DEBUG, "  jack: %s %s",
    126 		section->jack_name, section->jack_type);
    127 	syslog(LOG_DEBUG, "  mixer_name: %s", section->mixer_name);
    128 	mixer_name_dump(section->coupled, "  coupled");
    129 }
    130