blob: c2e4e66332767df6201cbf19f042baf7c6518f31 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2Copyright Statement:
3
4This software/firmware and related documentation ("MediaTek Software") are
5protected under relevant copyright laws. The information contained herein is
6confidential and proprietary to MediaTek Inc. and/or its licensors. Without
7the prior written permission of MediaTek inc. and/or its licensors, any
8reproduction, modification, use or disclosure of MediaTek Software, and
9information contained herein, in whole or in part, shall be strictly
10prohibited.
11
12MediaTek Inc. (C) 2016. All rights reserved.
13
14BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
15THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
16RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
17ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
18WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
19WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
20NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
21RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
22INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
23TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
24RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
25OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
26SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
27RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
28STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
29ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
30RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
31MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
32CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
33
34Auther: Garlic Tseng <garlic.tseng@mediatek.com>
35*/
36
37#include <stdlib.h>
38#include <errno.h>
39#include <stdio.h>
40#include <alsa/asoundlib.h>
41#define STR_SIZE 128
42#define DEFAULT_CARD_NAME "hw:0"
43
44//mixer control structure for sound card
45static snd_mixer_t *g_all_mixer_handler;
46static char g_customize_card_name[STR_SIZE] = {'\0'};
47
48static snd_mixer_elem_t *get_mixer_item_handler(const char *mixer_ctrl_name)
49{
50 snd_mixer_selem_id_t *mixer_select = NULL;
51 snd_mixer_elem_t *mixer_item_handler = NULL;
52 int ret = 0;
53
54
55 ret = snd_mixer_selem_id_malloc(&mixer_select);
56 if (ret) {
57 printf("%s, snd_mixer_open failed: %d\n", __func__, ret);
58 goto MIXER_ITEM_CREATE_ERROR;
59 }
60
61 snd_mixer_selem_id_set_index(mixer_select, 0);
62 if (ret) {
63 printf("%s, snd_mixer_selem_id_set_index failed: %d\n",
64 __func__, ret);
65 goto MIXER_ITEM_CREATE_ERROR;
66 }
67
68 snd_mixer_selem_id_set_name(mixer_select, mixer_ctrl_name);
69 if (ret) {
70 printf("%s, snd_mixer_selem_id_set_name failed: %d\n",
71 __func__, ret);
72 goto MIXER_ITEM_CREATE_ERROR;
73 }
74
75 mixer_item_handler = snd_mixer_find_selem(g_all_mixer_handler,
76 mixer_select);
77
78 if (!mixer_item_handler) {
79 printf("%s, snd_mixer_find_selem not found\n", __func__);
80 }
81
82 snd_mixer_selem_id_free(mixer_select);
83 return mixer_item_handler;
84
85MIXER_ITEM_CREATE_ERROR:
86 snd_mixer_selem_id_free(mixer_select);
87 return NULL;
88}
89
90int set_card_name(const char *mixer_ctrl_name)
91{
92 if (g_all_mixer_handler) {
93 snd_mixer_close(g_all_mixer_handler);
94 g_all_mixer_handler = 0;
95 }
96
97 strncpy(g_customize_card_name, mixer_ctrl_name, STR_SIZE);
98 return 0;
99}
100
101static int initial_all_mixer_handler()
102{
103 int ret = 0;
104 ret = snd_mixer_open(&g_all_mixer_handler, 0);
105 if (ret) {
106 printf("%s, snd_mixer_open failed: %d\n", __func__, ret);
107 goto ALL_MIXER_CREATE_ERROR;
108 }
109
110 if (g_customize_card_name[0] == '\0')
111 ret = snd_mixer_attach(g_all_mixer_handler, DEFAULT_CARD_NAME);
112 else
113 ret = snd_mixer_attach(g_all_mixer_handler, g_customize_card_name);
114
115 if (ret) {
116 printf("%s, snd_mixer_attach failed: %d\n", __func__, ret);
117 goto ALL_MIXER_CREATE_ERROR;
118 }
119
120 ret = snd_mixer_selem_register(g_all_mixer_handler, NULL, NULL);
121 if (ret) {
122 printf("%s, snd_mixer_selem_register failed: %d\n", __func__,
123 ret);
124 goto ALL_MIXER_CREATE_ERROR;
125 }
126
127 ret = snd_mixer_load(g_all_mixer_handler);
128 if (ret) {
129 printf("%s, snd_mixer_load failed: %d\n", __func__, ret);
130 /* goto ALL_MIXER_CREATE_ERROR; */
131 }
132 return 0;
133
134ALL_MIXER_CREATE_ERROR:
135 snd_mixer_close(g_all_mixer_handler);
136 g_all_mixer_handler = 0;
137 return ret;
138}
139
140
141int set_mixer_ctrl_value_int(const char *mixer_ctrl_name,
142 const int option_int)
143{
144 snd_mixer_elem_t *mixer_item_handler = NULL;
145 int ret;
146
147 if (!g_all_mixer_handler)
148 initial_all_mixer_handler();
149
150 /* mixer control item */
151 mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
152 if (!mixer_item_handler) {
153 printf("%s, get_mixer_item_handler failed!\n", __func__);
154 return -EINVAL;
155 }
156
157 ret = snd_mixer_selem_set_enum_item(mixer_item_handler, 0, option_int);
158 if (ret) {
159 printf("%s, set_enum_item failed: %d, option_int: %d\n",
160 __func__, ret, option_int);
161 return ret;
162 }
163
164 return 0;
165}
166
167int set_mixer_ctrl_volume_value(const char *mixer_ctrl_name,
168 const long volume)
169{
170 snd_mixer_elem_t *mixer_item_handler = NULL;
171 int ret;
172
173 if (!g_all_mixer_handler)
174 initial_all_mixer_handler();
175
176 /* mixer control item */
177 mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
178 if (!mixer_item_handler) {
179 printf("%s, get_mixer_item_handler failed!\n", __func__);
180 return -EINVAL;
181 }
182
183 ret = snd_mixer_selem_set_playback_volume(mixer_item_handler, 0, volume);
184 if (ret) {
185 printf("%s, set_enum_item failed: %d, volume: %ld\n",
186 __func__, ret, volume);
187 return ret;
188 }
189
190 return 0;
191}
192
193long get_mixer_ctrl_volume_value(const char *mixer_ctrl_name)
194{
195 snd_mixer_elem_t *mixer_item_handler = NULL;
196 long mixer_item_value[1];
197 int ret;
198
199 if (!g_all_mixer_handler)
200 initial_all_mixer_handler();
201
202 mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
203 if (!mixer_item_handler) {
204 printf("%s, get_mixer_item_handler failed!\n", __func__);
205 return -EINVAL;
206 }
207
208 ret = snd_mixer_selem_get_playback_volume(mixer_item_handler, 0,
209 mixer_item_value);
210
211 if (ret) {
212 printf("%s, snd_mixer_selem_get_playback_volume failed: %d\n",
213 __func__, ret);
214 return ret;
215 }
216
217 return mixer_item_value[0];
218}
219
220int set_mixer_ctrl_interconn_value(const char *mixer_ctrl_name,
221 int is_on)
222{
223 snd_mixer_elem_t *mixer_item_handler = NULL;
224 int ret = 0;
225
226 if (!g_all_mixer_handler)
227 initial_all_mixer_handler();
228
229 /*printf("%s, mixerctrl (%s) is_on (%d)!\n", __func__, mixer_ctrl_name, is_on); */
230
231 /* mixer control item */
232 mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
233 if (!mixer_item_handler) {
234 printf("%s, get_mixer_item_handler failed!\n", __func__);
235 return -EINVAL;
236 }
237
238 ret =
239 snd_mixer_selem_set_playback_switch(mixer_item_handler, SND_MIXER_SCHN_MONO , is_on);
240 /* printf("%s, snd_mixer_selem_set_playback_switch: %d\n", __func__, ret); */
241
242 /* if failed, get_enum_items return nagetive error num. */
243 if (ret < 0) {
244 printf("%s, snd_mixer_selem_set_playback_switch failed: %d\n",
245 __func__, ret);
246 }
247
248 return ret;
249}
250
251int get_mixer_ctrl_interconn_value(const char *mixer_ctrl_name)
252{
253 snd_mixer_elem_t *mixer_item_handler = NULL;
254 unsigned int mixer_item_value;
255 int ret;
256 if (!g_all_mixer_handler)
257 initial_all_mixer_handler();
258
259 /* mixer control item */
260 mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
261 if (!mixer_item_handler) {
262 printf("%s, get_mixer_item_handler failed!\n", __func__);
263 return -EINVAL;
264 }
265 ret =
266 snd_mixer_selem_get_playback_switch(mixer_item_handler, SND_MIXER_SCHN_MONO, &mixer_item_value);
267 /* printf("%s, snd_mixer_selem_get_playback_switch: %d\n", __func__, ret); */
268
269 /* if failed, get_enum_items return nagetive error num. */
270 if (ret < 0) {
271 printf("%s, snd_mixer_selem_get_playback_switch failed: %d\n",
272 __func__, ret);
273 }
274
275 /* printf("%s, mixerctrl (%s) mixer_item_value (%d)!\n", __func__, mixer_ctrl_name, mixer_item_value[0]); */
276
277 return mixer_item_value;
278}
279
280int set_mixer_ctrl_value_string(const char *mixer_ctrl_name,
281 const char *option_name)
282{
283 snd_mixer_elem_t *mixer_item_handler = NULL;
284 int mixer_item_option_num = 0;
285 int i, ret;
286 char item_name[STR_SIZE];
287
288 if (!g_all_mixer_handler)
289 initial_all_mixer_handler();
290
291 /* mixer control item */
292 mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
293 if (!mixer_item_handler) {
294 printf("%s, get_mixer_item_handler failed!\n", __func__);
295 return -EINVAL;
296 }
297 mixer_item_option_num =
298 snd_mixer_selem_get_enum_items(mixer_item_handler);
299
300 /* if failed, get_enum_items return nagetive error num. */
301 if (mixer_item_option_num < 0) {
302 printf("%s, snd_mixer_selem_get_enum_items failed: %d\n",
303 __func__, mixer_item_option_num);
304 return mixer_item_option_num;
305 }
306
307 /* find option_name index */
308 for (i = 0; i < mixer_item_option_num; i++) {
309 ret = snd_mixer_selem_get_enum_item_name(mixer_item_handler, i,
310 STR_SIZE, item_name);
311 if (ret)
312 printf("%s, get_enum_item_name failed: %d, i: %d\n",
313 __func__, ret, i);
314 if (!strcmp(option_name, item_name))
315 break;
316 }
317
318 /* not found */
319 if (i == mixer_item_option_num) {
320 printf("%s, option_name (%s) not found in mixerctrl (%s)!\n",
321 __func__, option_name, mixer_ctrl_name);
322 return -EINVAL;
323 }
324
325 /* found: the index is 'i' */
326 ret = snd_mixer_selem_set_enum_item(mixer_item_handler, 0, i);
327 if (ret) {
328 printf("%s, set_enum_item failed: %d, i: %d\n",
329 __func__, ret, i);
330 return ret;
331 }
332
333 return 0;
334}
335
336int get_mixer_ctrl_value_int(const char *mixer_ctrl_name)
337{
338 snd_mixer_elem_t *mixer_item_handler = NULL;
339 unsigned int mixer_item_value[1];
340 int ret;
341
342 if (!g_all_mixer_handler)
343 initial_all_mixer_handler();
344
345 mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
346 if (!mixer_item_handler) {
347 printf("%s, get_mixer_item_handler failed!\n", __func__);
348 return -EINVAL;
349 }
350
351 ret = snd_mixer_selem_get_enum_item(mixer_item_handler, 0,
352 mixer_item_value);
353
354 if (ret) {
355 printf("%s, selem_get_enum_item failed: %d\n", __func__, ret);
356 return ret;
357 }
358
359 return mixer_item_value[0];
360}
361
362char *get_mixer_ctrl_value_string(const char *mixer_ctrl_name,
363 char *returned_value_name,
364 int value_name_size)
365{
366 snd_mixer_elem_t *mixer_item_handler =
367 get_mixer_item_handler(mixer_ctrl_name);
368 int mixer_value_int = get_mixer_ctrl_value_int(mixer_ctrl_name);
369 int ret;
370 char item_name[STR_SIZE];
371
372 ret = snd_mixer_selem_get_enum_item_name(mixer_item_handler,
373 mixer_value_int,
374 STR_SIZE, item_name);
375 if (ret) {
376 printf("%s, get_enum_item_name failed: %d, mixer_value_int: %d\n",
377 __func__, ret, mixer_value_int);
378 return NULL;
379 }
380
381 return strncpy(returned_value_name, item_name, value_name_size);
382}
383