blob: 770e2e8c5a719a17618d4fd1340e763db3d1abd5 [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#include "dev_string.h"
42#define STR_SIZE 128
43
44//mixer control structure for sound card
45static snd_mixer_t *g_all_mixer_handler;
46
47static snd_mixer_elem_t *get_mixer_item_handler(const char *mixer_ctrl_name)
48{
49 snd_mixer_selem_id_t *mixer_select = NULL;
50 snd_mixer_elem_t *mixer_item_handler = NULL;
51 int ret = 0;
52
53
54 ret = snd_mixer_selem_id_malloc(&mixer_select);
55 if (ret) {
56 printf("%s, snd_mixer_open failed: %d\n", __func__, ret);
57 goto MIXER_ITEM_CREATE_ERROR;
58 }
59
60 snd_mixer_selem_id_set_index(mixer_select, 0);
61 if (ret) {
62 printf("%s, snd_mixer_selem_id_set_index failed: %d\n",
63 __func__, ret);
64 goto MIXER_ITEM_CREATE_ERROR;
65 }
66
67 snd_mixer_selem_id_set_name(mixer_select, mixer_ctrl_name);
68 if (ret) {
69 printf("%s, snd_mixer_selem_id_set_name failed: %d\n",
70 __func__, ret);
71 goto MIXER_ITEM_CREATE_ERROR;
72 }
73
74 mixer_item_handler = snd_mixer_find_selem(g_all_mixer_handler,
75 mixer_select);
76
77 if (!mixer_item_handler) {
78 printf("%s, snd_mixer_find_selem not found\n", __func__);
79 }
80
81 snd_mixer_selem_id_free(mixer_select);
82 return mixer_item_handler;
83
84MIXER_ITEM_CREATE_ERROR:
85 snd_mixer_selem_id_free(mixer_select);
86 return NULL;
87}
88
89static int initial_all_mixer_handler()
90{
91 int ret = 0;
92 ret = snd_mixer_open(&g_all_mixer_handler, 0);
93 if (ret) {
94 printf("%s, snd_mixer_open failed: %d\n", __func__, ret);
95 goto ALL_MIXER_CREATE_ERROR;
96 }
97
98 ret = snd_mixer_attach(g_all_mixer_handler, CARD_NAME);
99 if (ret) {
100 printf("%s, snd_mixer_attach failed: %d\n", __func__, ret);
101 goto ALL_MIXER_CREATE_ERROR;
102 }
103
104 ret = snd_mixer_selem_register(g_all_mixer_handler, NULL, NULL);
105 if (ret) {
106 printf("%s, snd_mixer_selem_register failed: %d\n", __func__,
107 ret);
108 goto ALL_MIXER_CREATE_ERROR;
109 }
110
111 ret = snd_mixer_load(g_all_mixer_handler);
112 if (ret) {
113 printf("%s, snd_mixer_load failed: %d\n", __func__, ret);
114 goto ALL_MIXER_CREATE_ERROR;
115 }
116 return 0;
117
118ALL_MIXER_CREATE_ERROR:
119 snd_mixer_close(g_all_mixer_handler);
120 return ret;
121}
122
123
124int set_mixer_ctrl_value_int(const char *mixer_ctrl_name,
125 const int option_int)
126{
127 snd_mixer_elem_t *mixer_item_handler = NULL;
128 int ret;
129
130 if (!g_all_mixer_handler)
131 initial_all_mixer_handler();
132
133 /* mixer control item */
134 mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
135 if (!mixer_item_handler) {
136 printf("%s, get_mixer_item_handler failed!\n", __func__);
137 return -EINVAL;
138 }
139
140 ret = snd_mixer_selem_set_enum_item(mixer_item_handler, 0, option_int);
141 if (ret) {
142 printf("%s, set_enum_item failed: %d, option_int: %d\n",
143 __func__, ret, option_int);
144 return ret;
145 }
146
147 return 0;
148}
149
150int set_mixer_ctrl_value_string(const char *mixer_ctrl_name,
151 const char *option_name)
152{
153 snd_mixer_elem_t *mixer_item_handler = NULL;
154 int mixer_item_option_num = 0;
155 int i, ret;
156 char item_name[STR_SIZE];
157
158 if (!g_all_mixer_handler)
159 initial_all_mixer_handler();
160
161 /* mixer control item */
162 mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
163 if (!mixer_item_handler) {
164 printf("%s, get_mixer_item_handler failed!\n", __func__);
165 return -EINVAL;
166 }
167 mixer_item_option_num =
168 snd_mixer_selem_get_enum_items(mixer_item_handler);
169
170 /* if failed, get_enum_items return nagetive error num. */
171 if (mixer_item_option_num < 0) {
172 printf("%s, snd_mixer_selem_get_enum_items failed: %d\n",
173 __func__, mixer_item_option_num);
174 return mixer_item_option_num;
175 }
176
177 /* find option_name index */
178 for (i = 0; i < mixer_item_option_num; i++) {
179 ret = snd_mixer_selem_get_enum_item_name(mixer_item_handler, i,
180 STR_SIZE, item_name);
181 if (ret)
182 printf("%s, get_enum_item_name failed: %d, i: %d\n",
183 __func__, ret, i);
184 if (!strcmp(option_name, item_name))
185 break;
186 }
187
188 /* not found */
189 if (i == mixer_item_option_num) {
190 printf("%s, option_name (%s) not found in mixerctrl (%s)!\n",
191 __func__, option_name, mixer_ctrl_name);
192 return -EINVAL;
193 }
194
195 /* found: the index is 'i' */
196 ret = snd_mixer_selem_set_enum_item(mixer_item_handler, 0, i);
197 if (ret) {
198 printf("%s, set_enum_item failed: %d, i: %d\n",
199 __func__, ret, i);
200 return ret;
201 }
202
203 return 0;
204}
205
206int get_mixer_ctrl_value_int(const char *mixer_ctrl_name)
207{
208 snd_mixer_elem_t *mixer_item_handler = NULL;
209 unsigned int mixer_item_value[1];
210 int ret;
211
212 if (!g_all_mixer_handler)
213 initial_all_mixer_handler();
214
215 mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
216 if (!mixer_item_handler) {
217 printf("%s, get_mixer_item_handler failed!\n", __func__);
218 return -EINVAL;
219 }
220
221 ret = snd_mixer_selem_get_enum_item(mixer_item_handler, 0,
222 mixer_item_value);
223
224 if (ret) {
225 printf("%s, selem_get_enum_item failed: %d\n", __func__, ret);
226 return ret;
227 }
228
229 return mixer_item_value[0];
230}
231
232char *get_mixer_ctrl_value_string(const char *mixer_ctrl_name,
233 char *returned_value_name,
234 int value_name_size)
235{
236 snd_mixer_elem_t *mixer_item_handler =
237 get_mixer_item_handler(mixer_ctrl_name);
238 int mixer_value_int = get_mixer_ctrl_value_int(mixer_ctrl_name);
239 int ret;
240 char item_name[STR_SIZE];
241
242 ret = snd_mixer_selem_get_enum_item_name(mixer_item_handler,
243 mixer_value_int,
244 STR_SIZE, item_name);
245 if (ret) {
246 printf("%s, get_enum_item_name failed: %d, mixer_value_int: %d\n",
247 __func__, ret, mixer_value_int);
248 return NULL;
249 }
250
251 return strncpy(returned_value_name, item_name, value_name_size);
252}
253