"Fossies" - the Fresh Open Source Software Archive 
Member "alsa-tools-1.2.2/hda-verb/hda-verb.c" (19 Feb 2020, 8781 Bytes) of package /linux/misc/alsa-tools-1.2.2.tar.bz2:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "hda-verb.c" see the
Fossies "Dox" file reference documentation.
1 /*
2 * Accessing HD-audio verbs via hwdep interface
3 * Version 0.3
4 *
5 * Copyright (c) 2008 Takashi Iwai <tiwai@suse.de>
6 *
7 * Licensed under GPL v2 or later.
8 */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <ctype.h>
14 #include <unistd.h>
15 #include <sys/ioctl.h>
16 #include <sys/types.h>
17 #include <sys/fcntl.h>
18
19 #include <stdint.h>
20 typedef uint8_t u8;
21 typedef uint16_t u16;
22 typedef uint32_t u32;
23 typedef uint64_t u64;
24
25 #include "hda_hwdep.h"
26
27 #define AC_VERB_GET_STREAM_FORMAT 0x0a00
28 #define AC_VERB_GET_AMP_GAIN_MUTE 0x0b00
29 #define AC_VERB_GET_PROC_COEF 0x0c00
30 #define AC_VERB_GET_COEF_INDEX 0x0d00
31 #define AC_VERB_PARAMETERS 0x0f00
32 #define AC_VERB_GET_CONNECT_SEL 0x0f01
33 #define AC_VERB_GET_CONNECT_LIST 0x0f02
34 #define AC_VERB_GET_PROC_STATE 0x0f03
35 #define AC_VERB_GET_SDI_SELECT 0x0f04
36 #define AC_VERB_GET_POWER_STATE 0x0f05
37 #define AC_VERB_GET_CONV 0x0f06
38 #define AC_VERB_GET_PIN_WIDGET_CONTROL 0x0f07
39 #define AC_VERB_GET_UNSOLICITED_RESPONSE 0x0f08
40 #define AC_VERB_GET_PIN_SENSE 0x0f09
41 #define AC_VERB_GET_BEEP_CONTROL 0x0f0a
42 #define AC_VERB_GET_EAPD_BTLENABLE 0x0f0c
43 #define AC_VERB_GET_DIGI_CONVERT_1 0x0f0d
44 #define AC_VERB_GET_DIGI_CONVERT_2 0x0f0e
45 #define AC_VERB_GET_VOLUME_KNOB_CONTROL 0x0f0f
46 #define AC_VERB_GET_GPIO_DATA 0x0f15
47 #define AC_VERB_GET_GPIO_MASK 0x0f16
48 #define AC_VERB_GET_GPIO_DIRECTION 0x0f17
49 #define AC_VERB_GET_GPIO_WAKE_MASK 0x0f18
50 #define AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK 0x0f19
51 #define AC_VERB_GET_GPIO_STICKY_MASK 0x0f1a
52 #define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c
53 #define AC_VERB_GET_SUBSYSTEM_ID 0x0f20
54
55 #define AC_VERB_SET_STREAM_FORMAT 0x200
56 #define AC_VERB_SET_AMP_GAIN_MUTE 0x300
57 #define AC_VERB_SET_PROC_COEF 0x400
58 #define AC_VERB_SET_COEF_INDEX 0x500
59 #define AC_VERB_SET_CONNECT_SEL 0x701
60 #define AC_VERB_SET_PROC_STATE 0x703
61 #define AC_VERB_SET_SDI_SELECT 0x704
62 #define AC_VERB_SET_POWER_STATE 0x705
63 #define AC_VERB_SET_CHANNEL_STREAMID 0x706
64 #define AC_VERB_SET_PIN_WIDGET_CONTROL 0x707
65 #define AC_VERB_SET_UNSOLICITED_ENABLE 0x708
66 #define AC_VERB_SET_PIN_SENSE 0x709
67 #define AC_VERB_SET_BEEP_CONTROL 0x70a
68 #define AC_VERB_SET_EAPD_BTLENABLE 0x70c
69 #define AC_VERB_SET_DIGI_CONVERT_1 0x70d
70 #define AC_VERB_SET_DIGI_CONVERT_2 0x70e
71 #define AC_VERB_SET_VOLUME_KNOB_CONTROL 0x70f
72 #define AC_VERB_SET_GPIO_DATA 0x715
73 #define AC_VERB_SET_GPIO_MASK 0x716
74 #define AC_VERB_SET_GPIO_DIRECTION 0x717
75 #define AC_VERB_SET_GPIO_WAKE_MASK 0x718
76 #define AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK 0x719
77 #define AC_VERB_SET_GPIO_STICKY_MASK 0x71a
78 #define AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 0x71c
79 #define AC_VERB_SET_CONFIG_DEFAULT_BYTES_1 0x71d
80 #define AC_VERB_SET_CONFIG_DEFAULT_BYTES_2 0x71e
81 #define AC_VERB_SET_CONFIG_DEFAULT_BYTES_3 0x71f
82 #define AC_VERB_SET_CODEC_RESET 0x7ff
83
84 #define AC_PAR_VENDOR_ID 0x00
85 #define AC_PAR_SUBSYSTEM_ID 0x01
86 #define AC_PAR_REV_ID 0x02
87 #define AC_PAR_NODE_COUNT 0x04
88 #define AC_PAR_FUNCTION_TYPE 0x05
89 #define AC_PAR_AUDIO_FG_CAP 0x08
90 #define AC_PAR_AUDIO_WIDGET_CAP 0x09
91 #define AC_PAR_PCM 0x0a
92 #define AC_PAR_STREAM 0x0b
93 #define AC_PAR_PIN_CAP 0x0c
94 #define AC_PAR_AMP_IN_CAP 0x0d
95 #define AC_PAR_CONNLIST_LEN 0x0e
96 #define AC_PAR_POWER_STATE 0x0f
97 #define AC_PAR_PROC_CAP 0x10
98 #define AC_PAR_GPIO_CAP 0x11
99 #define AC_PAR_AMP_OUT_CAP 0x12
100 #define AC_PAR_VOL_KNB_CAP 0x13
101
102 /*
103 */
104 #define VERBSTR(x) { .val = AC_VERB_##x, .str = #x }
105 #define PARMSTR(x) { .val = AC_PAR_##x, .str = #x }
106
107 struct strtbl {
108 int val;
109 const char *str;
110 };
111
112 static struct strtbl hda_verbs[] = {
113 VERBSTR(GET_STREAM_FORMAT),
114 VERBSTR(GET_AMP_GAIN_MUTE),
115 VERBSTR(GET_PROC_COEF),
116 VERBSTR(GET_COEF_INDEX),
117 VERBSTR(PARAMETERS),
118 VERBSTR(GET_CONNECT_SEL),
119 VERBSTR(GET_CONNECT_LIST),
120 VERBSTR(GET_PROC_STATE),
121 VERBSTR(GET_SDI_SELECT),
122 VERBSTR(GET_POWER_STATE),
123 VERBSTR(GET_CONV),
124 VERBSTR(GET_PIN_WIDGET_CONTROL),
125 VERBSTR(GET_UNSOLICITED_RESPONSE),
126 VERBSTR(GET_PIN_SENSE),
127 VERBSTR(GET_BEEP_CONTROL),
128 VERBSTR(GET_EAPD_BTLENABLE),
129 VERBSTR(GET_DIGI_CONVERT_1),
130 VERBSTR(GET_DIGI_CONVERT_2),
131 VERBSTR(GET_VOLUME_KNOB_CONTROL),
132 VERBSTR(GET_GPIO_DATA),
133 VERBSTR(GET_GPIO_MASK),
134 VERBSTR(GET_GPIO_DIRECTION),
135 VERBSTR(GET_GPIO_WAKE_MASK),
136 VERBSTR(GET_GPIO_UNSOLICITED_RSP_MASK),
137 VERBSTR(GET_GPIO_STICKY_MASK),
138 VERBSTR(GET_CONFIG_DEFAULT),
139 VERBSTR(GET_SUBSYSTEM_ID),
140
141 VERBSTR(SET_STREAM_FORMAT),
142 VERBSTR(SET_AMP_GAIN_MUTE),
143 VERBSTR(SET_PROC_COEF),
144 VERBSTR(SET_COEF_INDEX),
145 VERBSTR(SET_CONNECT_SEL),
146 VERBSTR(SET_PROC_STATE),
147 VERBSTR(SET_SDI_SELECT),
148 VERBSTR(SET_POWER_STATE),
149 VERBSTR(SET_CHANNEL_STREAMID),
150 VERBSTR(SET_PIN_WIDGET_CONTROL),
151 VERBSTR(SET_UNSOLICITED_ENABLE),
152 VERBSTR(SET_PIN_SENSE),
153 VERBSTR(SET_BEEP_CONTROL),
154 VERBSTR(SET_EAPD_BTLENABLE),
155 VERBSTR(SET_DIGI_CONVERT_1),
156 VERBSTR(SET_DIGI_CONVERT_2),
157 VERBSTR(SET_VOLUME_KNOB_CONTROL),
158 VERBSTR(SET_GPIO_DATA),
159 VERBSTR(SET_GPIO_MASK),
160 VERBSTR(SET_GPIO_DIRECTION),
161 VERBSTR(SET_GPIO_WAKE_MASK),
162 VERBSTR(SET_GPIO_UNSOLICITED_RSP_MASK),
163 VERBSTR(SET_GPIO_STICKY_MASK),
164 VERBSTR(SET_CONFIG_DEFAULT_BYTES_0),
165 VERBSTR(SET_CONFIG_DEFAULT_BYTES_1),
166 VERBSTR(SET_CONFIG_DEFAULT_BYTES_2),
167 VERBSTR(SET_CONFIG_DEFAULT_BYTES_3),
168 VERBSTR(SET_CODEC_RESET),
169 { }, /* end */
170 };
171
172 static struct strtbl hda_params[] = {
173 PARMSTR(VENDOR_ID),
174 PARMSTR(SUBSYSTEM_ID),
175 PARMSTR(REV_ID),
176 PARMSTR(NODE_COUNT),
177 PARMSTR(FUNCTION_TYPE),
178 PARMSTR(AUDIO_FG_CAP),
179 PARMSTR(AUDIO_WIDGET_CAP),
180 PARMSTR(PCM),
181 PARMSTR(STREAM),
182 PARMSTR(PIN_CAP),
183 PARMSTR(AMP_IN_CAP),
184 PARMSTR(CONNLIST_LEN),
185 PARMSTR(POWER_STATE),
186 PARMSTR(PROC_CAP),
187 PARMSTR(GPIO_CAP),
188 PARMSTR(AMP_OUT_CAP),
189 PARMSTR(VOL_KNB_CAP),
190 { }, /* end */
191 };
192
193 static void list_keys(struct strtbl *tbl, int one_per_line)
194 {
195 int c = 0;
196 for (; tbl->str; tbl++) {
197 int len = strlen(tbl->str) + 2;
198 if (!one_per_line && c + len >= 80) {
199 fprintf(stderr, "\n");
200 c = 0;
201 }
202 if (one_per_line)
203 fprintf(stderr, " %s\n", tbl->str);
204 else if (!c)
205 fprintf(stderr, " %s", tbl->str);
206 else
207 fprintf(stderr, ", %s", tbl->str);
208 c += 2 + len;
209 }
210 if (!one_per_line)
211 fprintf(stderr, "\n");
212 }
213
214 /* look up a value from the given string table */
215 static int lookup_str(struct strtbl *tbl, const char *str)
216 {
217 struct strtbl *p, *found;
218 int len = strlen(str);
219
220 found = NULL;
221 for (p = tbl; p->str; p++) {
222 if (!strncmp(str, p->str, len)) {
223 if (found) {
224 fprintf(stderr, "No unique key '%s'\n", str);
225 return -1;
226 }
227 found = p;
228 }
229 }
230 if (!found) {
231 fprintf(stderr, "No key matching with '%s'\n", str);
232 return -1;
233 }
234 return found->val;
235 }
236
237 /* convert a string to upper letters */
238 static void strtoupper(char *str)
239 {
240 for (; *str; str++)
241 *str = toupper(*str);
242 }
243
244 static void usage(void)
245 {
246 fprintf(stderr, "usage: hda-verb [option] hwdep-device nid verb param\n");
247 fprintf(stderr, " -l List known verbs and parameters\n");
248 fprintf(stderr, " -L List known verbs and parameters (one per line)\n");
249 }
250
251 static void list_verbs(int one_per_line)
252 {
253 fprintf(stderr, "known verbs:\n");
254 list_keys(hda_verbs, one_per_line);
255 fprintf(stderr, "known parameters:\n");
256 list_keys(hda_params, one_per_line);
257 }
258
259 int main(int argc, char **argv)
260 {
261 int version;
262 int fd;
263 int nid, verb, param;
264 int c;
265 struct hda_verb_ioctl val;
266 char **p;
267
268 while ((c = getopt(argc, argv, "lL")) >= 0) {
269 switch (c) {
270 case 'l':
271 list_verbs(0);
272 return 0;
273 case 'L':
274 list_verbs(1);
275 return 0;
276 default:
277 usage();
278 return 1;
279 }
280 }
281
282 if (argc - optind < 4) {
283 usage();
284 return 1;
285 }
286 p = argv + optind;
287 fd = open(*p, O_RDWR);
288 if (fd < 0) {
289 perror("open");
290 return 1;
291 }
292 version = 0;
293 if (ioctl(fd, HDA_IOCTL_PVERSION, &version) < 0) {
294 perror("ioctl(PVERSION)");
295 fprintf(stderr, "Looks like an invalid hwdep device...\n");
296 return 1;
297 }
298 if (version < HDA_HWDEP_VERSION) {
299 fprintf(stderr, "Invalid version number 0x%x\n", version);
300 fprintf(stderr, "Looks like an invalid hwdep device...\n");
301 return 1;
302 }
303
304 p++;
305 nid = strtol(*p, NULL, 0);
306 if (nid < 0 || nid > 0xff) {
307 fprintf(stderr, "invalid nid %s\n", *p);
308 return 1;
309 }
310
311 p++;
312 if (!isdigit(**p)) {
313 strtoupper(*p);
314 verb = lookup_str(hda_verbs, *p);
315 if (verb < 0)
316 return 1;
317 } else {
318 verb = strtol(*p, NULL, 0);
319 if (verb < 0 || verb > 0xfff) {
320 fprintf(stderr, "invalid verb %s\n", *p);
321 return 1;
322 }
323 }
324 p++;
325 if (!isdigit(**p)) {
326 strtoupper(*p);
327 param = lookup_str(hda_params, *p);
328 if (param < 0)
329 return 1;
330 } else {
331 param = strtol(*p, NULL, 0);
332 if (param < 0 || param > 0xffff) {
333 fprintf(stderr, "invalid param %s\n", *p);
334 return 1;
335 }
336 }
337 fprintf(stderr, "nid = 0x%x, verb = 0x%x, param = 0x%x\n",
338 nid, verb, param);
339
340 val.verb = HDA_VERB(nid, verb, param);
341 if (ioctl(fd, HDA_IOCTL_VERB_WRITE, &val) < 0)
342 perror("ioctl");
343 printf("value = 0x%x\n", val.res);
344 close(fd);
345 return 0;
346 }