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