Fix invalid format string
[platform/adaptation/samsung_exynos/audio-hal-wm1831.git] / tizen-audio-impl-ctrl.c
1 /*
2  * audio-hal
3  *
4  * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <pthread.h>
28
29 #include "tizen-audio-internal.h"
30
31 #ifdef __MIXER_PARAM_DUMP
32 static void __dump_mixer_param(char *dump, long *param, int size)
33 {
34     int i, len;
35
36     for (i = 0; i < size; i++) {
37         len = sprintf(dump, "%ld", *param);
38         if (len > 0)
39             dump += len;
40         if (i != size -1) {
41             *dump++ = ',';
42         }
43
44         param++;
45     }
46     *dump = '\0';
47 }
48 #endif
49
50 audio_return_t _control_init(audio_hal_t *ah)
51 {
52     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
53
54     pthread_mutex_init(&(ah->mixer.mutex), NULL);
55     return AUDIO_RET_OK;
56 }
57
58 audio_return_t _control_deinit(audio_hal_t *ah)
59 {
60     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
61
62     pthread_mutex_destroy(&(ah->mixer.mutex));
63     return AUDIO_RET_OK;
64 }
65
66 audio_return_t _mixer_control_set_param(audio_hal_t *ah, const char* ctl_name, snd_ctl_elem_value_t* param, int size)
67 {
68     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
69
70     /* TODO. */
71     return AUDIO_RET_OK;
72 }
73
74 audio_return_t _mixer_control_get_value(audio_hal_t *ah, const char *ctl_name, int *val)
75 {
76     snd_ctl_t *handle;
77     snd_ctl_elem_value_t *control;
78     snd_ctl_elem_id_t *id;
79     snd_ctl_elem_info_t *info;
80     snd_ctl_elem_type_t type;
81
82     int ret = 0, count = 0, i = 0;
83
84     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
85
86     pthread_mutex_lock(&(ah->mixer.mutex));
87
88     ret = snd_ctl_open(&handle, ALSA_DEFAULT_CARD, 0);
89     if (ret < 0) {
90         AUDIO_LOG_ERROR("snd_ctl_open error, %s\n", snd_strerror(ret));
91         pthread_mutex_unlock(&(ah->mixer.mutex));
92         return AUDIO_ERR_IOCTL;
93     }
94
95     // Get Element Info
96
97     snd_ctl_elem_id_alloca(&id);
98     snd_ctl_elem_info_alloca(&info);
99     snd_ctl_elem_value_alloca(&control);
100
101     snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
102     snd_ctl_elem_id_set_name(id, ctl_name);
103
104     snd_ctl_elem_info_set_id(info, id);
105     if (snd_ctl_elem_info(handle, info) < 0) {
106         AUDIO_LOG_ERROR("Cannot find control element: %s\n", ctl_name);
107         goto close;
108     }
109     snd_ctl_elem_info_get_id(info, id);
110
111     type = snd_ctl_elem_info_get_type(info);
112     count = snd_ctl_elem_info_get_count(info);
113
114     snd_ctl_elem_value_set_id(control, id);
115
116     if (snd_ctl_elem_read(handle, control) < 0) {
117         AUDIO_LOG_ERROR("snd_ctl_elem_read failed \n");
118         goto close;
119 }
120
121     switch (type) {
122     case SND_CTL_ELEM_TYPE_BOOLEAN:
123         *val = snd_ctl_elem_value_get_boolean(control, i);
124         break;
125     case SND_CTL_ELEM_TYPE_INTEGER:
126         for (i = 0; i < count; i++)
127         *val = snd_ctl_elem_value_get_integer(control, i);
128         break;
129     case SND_CTL_ELEM_TYPE_ENUMERATED:
130         for (i = 0; i < count; i++)
131         *val = snd_ctl_elem_value_get_enumerated(control, i);
132         break;
133     default:
134         AUDIO_LOG_WARN("unsupported control element type\n");
135         goto close;
136     }
137
138     snd_ctl_close(handle);
139
140 #ifdef AUDIO_DEBUG
141     AUDIO_LOG_INFO("get mixer(%s) = %d success", ctl_name, *val);
142 #endif
143
144     pthread_mutex_unlock(&(ah->mixer.mutex));
145     return AUDIO_RET_OK;
146
147 close:
148     AUDIO_LOG_ERROR("Error\n");
149     snd_ctl_close(handle);
150     pthread_mutex_unlock(&(ah->mixer.mutex));
151     return AUDIO_ERR_UNDEFINED;
152 }
153
154 audio_return_t _mixer_control_set_value(audio_hal_t *ah, const char *ctl_name, int val)
155 {
156     snd_ctl_t *handle;
157     snd_ctl_elem_value_t *control;
158     snd_ctl_elem_id_t *id;
159     snd_ctl_elem_info_t *info;
160     snd_ctl_elem_type_t type;
161     int ret = 0, count = 0, i = 0;
162
163     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
164     AUDIO_RETURN_VAL_IF_FAIL(ctl_name, AUDIO_ERR_PARAMETER);
165
166     pthread_mutex_lock(&(ah->mixer.mutex));
167
168     ret = snd_ctl_open(&handle, ALSA_DEFAULT_CARD, 0);
169     if (ret < 0) {
170         AUDIO_LOG_ERROR("snd_ctl_open error, card: %s: %s", ALSA_DEFAULT_CARD, snd_strerror(ret));
171         pthread_mutex_unlock(&(ah->mixer.mutex));
172         return AUDIO_ERR_IOCTL;
173     }
174
175     // Get Element Info
176
177     snd_ctl_elem_id_alloca(&id);
178     snd_ctl_elem_info_alloca(&info);
179     snd_ctl_elem_value_alloca(&control);
180
181     snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
182     snd_ctl_elem_id_set_name(id, ctl_name);
183
184     snd_ctl_elem_info_set_id(info, id);
185     if (snd_ctl_elem_info(handle, info) < 0) {
186         AUDIO_LOG_ERROR("Cannot find control element: %s", ctl_name);
187         goto close;
188     }
189     snd_ctl_elem_info_get_id(info, id);
190
191     type = snd_ctl_elem_info_get_type(info);
192     count = snd_ctl_elem_info_get_count(info);
193
194     snd_ctl_elem_value_set_id(control, id);
195
196     snd_ctl_elem_read(handle, control);
197
198     switch (type) {
199     case SND_CTL_ELEM_TYPE_BOOLEAN:
200         for (i = 0; i < count; i++)
201             snd_ctl_elem_value_set_boolean(control, i, val);
202         break;
203     case SND_CTL_ELEM_TYPE_INTEGER:
204         for (i = 0; i < count; i++)
205             snd_ctl_elem_value_set_integer(control, i, val);
206         break;
207     case SND_CTL_ELEM_TYPE_ENUMERATED:
208         for (i = 0; i < count; i++)
209             snd_ctl_elem_value_set_enumerated(control, i, val);
210         break;
211
212     default:
213         AUDIO_LOG_WARN("unsupported control element type");
214         goto close;
215     }
216
217     snd_ctl_elem_write(handle, control);
218
219     snd_ctl_close(handle);
220
221     AUDIO_LOG_INFO("set mixer(%s) = %d success", ctl_name, val);
222
223     pthread_mutex_unlock(&(ah->mixer.mutex));
224     return AUDIO_RET_OK;
225
226 close:
227     AUDIO_LOG_ERROR("Error");
228     snd_ctl_close(handle);
229     pthread_mutex_unlock(&(ah->mixer.mutex));
230     return AUDIO_ERR_UNDEFINED;
231 }
232
233 audio_return_t _mixer_control_set_value_string(audio_hal_t *ah, const char* ctl_name, const char* value)
234 {
235     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
236     AUDIO_RETURN_VAL_IF_FAIL(ctl_name, AUDIO_ERR_PARAMETER);
237
238     /* TODO. */
239     return AUDIO_RET_OK;
240 }
241
242
243 audio_return_t _mixer_control_get_element(audio_hal_t *ah, const char *ctl_name, snd_hctl_elem_t **elem)
244 {
245     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
246     AUDIO_RETURN_VAL_IF_FAIL(ctl_name, AUDIO_ERR_PARAMETER);
247     AUDIO_RETURN_VAL_IF_FAIL(elem, AUDIO_ERR_PARAMETER);
248
249     /* TODO. */
250     return AUDIO_RET_OK;
251 }