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