• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef fooalsaucmhfoo
2 #define fooalsaucmhfoo
3 
4 /***
5   This file is part of PulseAudio.
6 
7   Copyright 2011 Wolfson Microelectronics PLC
8   Author Margarita Olaya <magi@slimlogic.co.uk>
9   Copyright 2012 Feng Wei <wei.feng@freescale.com>, Freescale Ltd.
10 
11   PulseAudio is free software; you can redistribute it and/or modify
12   it under the terms of the GNU Lesser General Public License as published
13   by the Free Software Foundation; either version 2.1 of the License,
14   or (at your option) any later version.
15 
16   PulseAudio is distributed in the hope that it will be useful, but
17   WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19   General Public License for more details.
20 
21   You should have received a copy of the GNU Lesser General Public License
22   along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
23 ***/
24 
25 #ifdef HAVE_ALSA_UCM
26 #include <alsa/use-case.h>
27 #else
28 typedef void snd_use_case_mgr_t;
29 #endif
30 
31 #include "alsa-mixer.h"
32 
33 /** For devices: List of verbs, devices or modifiers available */
34 #define PA_ALSA_PROP_UCM_NAME                       "alsa.ucm.name"
35 
36 /** For devices: List of supported devices per verb*/
37 #define PA_ALSA_PROP_UCM_DESCRIPTION                "alsa.ucm.description"
38 
39 /** For devices: Playback device name e.g PlaybackPCM */
40 #define PA_ALSA_PROP_UCM_SINK                       "alsa.ucm.sink"
41 
42 /** For devices: Capture device name e.g CapturePCM*/
43 #define PA_ALSA_PROP_UCM_SOURCE                     "alsa.ucm.source"
44 
45 /** For devices: Playback roles */
46 #define PA_ALSA_PROP_UCM_PLAYBACK_ROLES             "alsa.ucm.playback.roles"
47 
48 /** For devices: Playback control device name  */
49 #define PA_ALSA_PROP_UCM_PLAYBACK_CTL_DEVICE        "alsa.ucm.playback.ctldev"
50 
51 /** For devices: Playback control volume ID string. e.g PlaybackVolume */
52 #define PA_ALSA_PROP_UCM_PLAYBACK_VOLUME            "alsa.ucm.playback.volume"
53 
54 /** For devices: Playback switch e.g PlaybackSwitch */
55 #define PA_ALSA_PROP_UCM_PLAYBACK_SWITCH            "alsa.ucm.playback.switch"
56 
57 /** For devices: Playback mixer device name  */
58 #define PA_ALSA_PROP_UCM_PLAYBACK_MIXER_DEVICE      "alsa.ucm.playback.mixer.device"
59 
60 /** For devices: Playback mixer identifier */
61 #define PA_ALSA_PROP_UCM_PLAYBACK_MIXER_ELEM        "alsa.ucm.playback.mixer.element"
62 
63 /** For devices: Playback mixer master identifier */
64 #define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_ELEM       "alsa.ucm.playback.master.element"
65 
66 /** For devices: Playback mixer master type */
67 #define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_TYPE       "alsa.ucm.playback.master.type"
68 
69 /** For devices: Playback mixer master identifier */
70 #define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_ID         "alsa.ucm.playback.master.id"
71 
72 /** For devices: Playback mixer master type */
73 #define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_TYPE       "alsa.ucm.playback.master.type"
74 
75 /** For devices: Playback priority */
76 #define PA_ALSA_PROP_UCM_PLAYBACK_PRIORITY          "alsa.ucm.playback.priority"
77 
78 /** For devices: Playback rate */
79 #define PA_ALSA_PROP_UCM_PLAYBACK_RATE              "alsa.ucm.playback.rate"
80 
81 /** For devices: Playback channels */
82 #define PA_ALSA_PROP_UCM_PLAYBACK_CHANNELS          "alsa.ucm.playback.channels"
83 
84 /** For devices: Capture roles */
85 #define PA_ALSA_PROP_UCM_CAPTURE_ROLES              "alsa.ucm.capture.roles"
86 
87 /** For devices: Capture control device name  */
88 #define PA_ALSA_PROP_UCM_CAPTURE_CTL_DEVICE         "alsa.ucm.capture.ctldev"
89 
90 /** For devices: Capture controls volume ID string. e.g CaptureVolume */
91 #define PA_ALSA_PROP_UCM_CAPTURE_VOLUME             "alsa.ucm.capture.volume"
92 
93 /** For devices: Capture switch e.g CaptureSwitch */
94 #define PA_ALSA_PROP_UCM_CAPTURE_SWITCH             "alsa.ucm.capture.switch"
95 
96 /** For devices: Capture mixer device name  */
97 #define PA_ALSA_PROP_UCM_CAPTURE_MIXER_DEVICE       "alsa.ucm.capture.mixer.device"
98 
99 /** For devices: Capture mixer identifier */
100 #define PA_ALSA_PROP_UCM_CAPTURE_MIXER_ELEM         "alsa.ucm.capture.mixer.element"
101 
102 /** For devices: Capture mixer identifier */
103 #define PA_ALSA_PROP_UCM_CAPTURE_MASTER_ELEM        "alsa.ucm.capture.master.element"
104 
105 /** For devices: Capture mixer identifier */
106 #define PA_ALSA_PROP_UCM_CAPTURE_MASTER_TYPE        "alsa.ucm.capture.master.type"
107 
108 /** For devices: Capture mixer identifier */
109 #define PA_ALSA_PROP_UCM_CAPTURE_MASTER_ID          "alsa.ucm.capture.master.id"
110 
111 /** For devices: Capture mixer identifier */
112 #define PA_ALSA_PROP_UCM_CAPTURE_MASTER_TYPE        "alsa.ucm.capture.master.type"
113 
114 /** For devices: Capture priority */
115 #define PA_ALSA_PROP_UCM_CAPTURE_PRIORITY           "alsa.ucm.capture.priority"
116 
117 /** For devices: Capture rate */
118 #define PA_ALSA_PROP_UCM_CAPTURE_RATE               "alsa.ucm.capture.rate"
119 
120 /** For devices: Capture channels */
121 #define PA_ALSA_PROP_UCM_CAPTURE_CHANNELS           "alsa.ucm.capture.channels"
122 
123 /** For devices: Quality of Service */
124 #define PA_ALSA_PROP_UCM_QOS                        "alsa.ucm.qos"
125 
126 /** For devices: The modifier (if any) that this device corresponds to */
127 #define PA_ALSA_PROP_UCM_MODIFIER "alsa.ucm.modifier"
128 
129 /* Corresponds to the "JackCTL" UCM value. */
130 #define PA_ALSA_PROP_UCM_JACK_DEVICE		    "alsa.ucm.jack_device"
131 
132 /* Corresponds to the "JackControl" UCM value. */
133 #define PA_ALSA_PROP_UCM_JACK_CONTROL               "alsa.ucm.jack_control"
134 
135 /* Corresponds to the "JackHWMute" UCM value. */
136 #define PA_ALSA_PROP_UCM_JACK_HW_MUTE               "alsa.ucm.jack_hw_mute"
137 
138 typedef struct pa_alsa_ucm_verb pa_alsa_ucm_verb;
139 typedef struct pa_alsa_ucm_modifier pa_alsa_ucm_modifier;
140 typedef struct pa_alsa_ucm_device pa_alsa_ucm_device;
141 typedef struct pa_alsa_ucm_config pa_alsa_ucm_config;
142 typedef struct pa_alsa_ucm_mapping_context pa_alsa_ucm_mapping_context;
143 typedef struct pa_alsa_ucm_profile_context pa_alsa_ucm_profile_context;
144 typedef struct pa_alsa_ucm_port_data pa_alsa_ucm_port_data;
145 typedef struct pa_alsa_ucm_volume pa_alsa_ucm_volume;
146 
147 int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index);
148 pa_alsa_profile_set* pa_alsa_ucm_add_profile_set(pa_alsa_ucm_config *ucm, pa_channel_map *default_channel_map);
149 int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, pa_alsa_profile *new_profile, pa_alsa_profile *old_profile);
150 
151 int pa_alsa_ucm_get_verb(snd_use_case_mgr_t *uc_mgr, const char *verb_name, const char *verb_desc, pa_alsa_ucm_verb **p_verb);
152 
153 void pa_alsa_ucm_add_ports(
154         pa_hashmap **hash,
155         pa_proplist *proplist,
156         pa_alsa_ucm_mapping_context *context,
157         bool is_sink,
158         pa_card *card,
159         snd_pcm_t *pcm_handle,
160         bool ignore_dB);
161 void pa_alsa_ucm_add_port(
162         pa_hashmap *hash,
163         pa_alsa_ucm_mapping_context *context,
164         bool is_sink,
165         pa_hashmap *ports,
166         pa_card_profile *cp,
167         pa_core *core);
168 int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port);
169 
170 void pa_alsa_ucm_free(pa_alsa_ucm_config *ucm);
171 void pa_alsa_ucm_mapping_context_free(pa_alsa_ucm_mapping_context *context);
172 
173 void pa_alsa_ucm_roled_stream_begin(pa_alsa_ucm_config *ucm, const char *role, pa_direction_t dir);
174 void pa_alsa_ucm_roled_stream_end(pa_alsa_ucm_config *ucm, const char *role, pa_direction_t dir);
175 
176 /* UCM - Use Case Manager is available on some audio cards */
177 
178 struct pa_alsa_ucm_device {
179     PA_LLIST_FIELDS(pa_alsa_ucm_device);
180 
181     pa_proplist *proplist;
182 
183     pa_device_port_type_t type;
184 
185     unsigned playback_priority;
186     unsigned capture_priority;
187 
188     unsigned playback_rate;
189     unsigned capture_rate;
190 
191     unsigned playback_channels;
192     unsigned capture_channels;
193 
194     /* These may be different per verb, so we store this as a hashmap of verb -> volume_control. We might eventually want to
195      * make this a hashmap of verb -> per-verb-device-properties-struct. */
196     pa_hashmap *playback_volumes;
197     pa_hashmap *capture_volumes;
198 
199     pa_alsa_mapping *playback_mapping;
200     pa_alsa_mapping *capture_mapping;
201 
202     pa_idxset *conflicting_devices;
203     pa_idxset *supported_devices;
204 
205     /* One device may be part of multiple ports, since each device has
206      * a dedicated port, and in addition to that we sometimes generate ports
207      * that represent combinations of devices. */
208     pa_dynarray *ucm_ports; /* struct ucm_port */
209 
210     pa_alsa_jack *jack;
211     pa_dynarray *hw_mute_jacks; /* pa_alsa_jack */
212     pa_available_t available;
213 
214     char *eld_mixer_device_name;
215     int eld_device;
216 };
217 
218 void pa_alsa_ucm_device_update_available(pa_alsa_ucm_device *device);
219 
220 struct pa_alsa_ucm_modifier {
221     PA_LLIST_FIELDS(pa_alsa_ucm_modifier);
222 
223     pa_proplist *proplist;
224 
225     pa_idxset *conflicting_devices;
226     pa_idxset *supported_devices;
227 
228     pa_direction_t action_direction;
229 
230     char *media_role;
231 
232     /* Non-NULL if the modifier has its own PlaybackPCM/CapturePCM */
233     pa_alsa_mapping *playback_mapping;
234     pa_alsa_mapping *capture_mapping;
235 
236     /* Count how many role matched streams are running */
237     int enabled_counter;
238 };
239 
240 struct pa_alsa_ucm_verb {
241     PA_LLIST_FIELDS(pa_alsa_ucm_verb);
242 
243     pa_proplist *proplist;
244     unsigned priority;
245 
246     PA_LLIST_HEAD(pa_alsa_ucm_device, devices);
247     PA_LLIST_HEAD(pa_alsa_ucm_modifier, modifiers);
248 };
249 
250 struct pa_alsa_ucm_config {
251     pa_core *core;
252     snd_use_case_mgr_t *ucm_mgr;
253     pa_alsa_ucm_verb *active_verb;
254     char *alib_prefix;
255 
256     pa_hashmap *mixers;
257     PA_LLIST_HEAD(pa_alsa_ucm_verb, verbs);
258     PA_LLIST_HEAD(pa_alsa_jack, jacks);
259 };
260 
261 struct pa_alsa_ucm_mapping_context {
262     pa_alsa_ucm_config *ucm;
263     pa_direction_t direction;
264 
265     pa_alsa_ucm_device *ucm_device;
266     pa_alsa_ucm_modifier *ucm_modifier;
267 };
268 
269 struct pa_alsa_ucm_profile_context {
270     pa_alsa_ucm_verb *verb;
271 };
272 
273 struct pa_alsa_ucm_port_data {
274     pa_alsa_ucm_config *ucm;
275     pa_device_port *core_port;
276 
277     pa_alsa_ucm_device *device;
278 
279     /* verb name -> pa_alsa_path for volume control */
280     pa_hashmap *paths;
281     /* Current path, set when activating verb */
282     pa_alsa_path *path;
283 
284     /* ELD info */
285     char *eld_mixer_device_name;
286     int eld_device; /* PCM device number */
287 };
288 
289 struct pa_alsa_ucm_volume {
290     char *mixer_elem;	/* mixer element identifier */
291     char *master_elem;	/* master mixer element identifier */
292     char *master_type;
293 };
294 
295 #endif
296