blob: 223d5969e9b43d2913a8e31e3fff579afafe9c8b [file] [log] [blame]
xjb04a4022021-11-25 15:01:52 +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 } else {
315 if (!strcmp(option_name, item_name))
316 break;
317 }
318 }
319
320 /* not found */
321 if (i == mixer_item_option_num) {
322 printf("%s, option_name (%s) not found in mixerctrl (%s)!\n",
323 __func__, option_name, mixer_ctrl_name);
324 return -EINVAL;
325 }
326
327 /* found: the index is 'i' */
328 ret = snd_mixer_selem_set_enum_item(mixer_item_handler, 0, i);
329 if (ret) {
330 printf("%s, set_enum_item failed: %d, i: %d\n",
331 __func__, ret, i);
332 return ret;
333 }
334
335 return 0;
336}
337
338int get_mixer_ctrl_value_int(const char *mixer_ctrl_name)
339{
340 snd_mixer_elem_t *mixer_item_handler = NULL;
341 unsigned int mixer_item_value[1];
342 int ret;
343
344 if (!g_all_mixer_handler)
345 initial_all_mixer_handler();
346
347 mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
348 if (!mixer_item_handler) {
349 printf("%s, get_mixer_item_handler failed!\n", __func__);
350 return -EINVAL;
351 }
352
353 ret = snd_mixer_selem_get_enum_item(mixer_item_handler, 0,
354 mixer_item_value);
355
356 if (ret) {
357 printf("%s, selem_get_enum_item failed: %d\n", __func__, ret);
358 return ret;
359 }
360
361 return mixer_item_value[0];
362}
363
364char *get_mixer_ctrl_value_string(const char *mixer_ctrl_name,
365 char *returned_value_name,
366 int value_name_size)
367{
368 snd_mixer_elem_t *mixer_item_handler =
369 get_mixer_item_handler(mixer_ctrl_name);
370 int mixer_value_int = get_mixer_ctrl_value_int(mixer_ctrl_name);
371 int ret;
372 char item_name[STR_SIZE];
373
374 ret = snd_mixer_selem_get_enum_item_name(mixer_item_handler,
375 mixer_value_int,
376 STR_SIZE, item_name);
377 if (ret) {
378 printf("%s, get_enum_item_name failed: %d, mixer_value_int: %d\n",
379 __func__, ret, mixer_value_int);
380 return NULL;
381 }
382
383 return strncpy(returned_value_name, item_name, value_name_size);
384}
385