Sync usage with man page.
[netbsd-mini2440.git] / usr.sbin / hdaudioctl / graph.c
blobfa365c3cd158f537dc2975f16fc054332bfae5c4
1 /* $NetBSD$ */
3 /*
4 * Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk>
5 * Copyright (c) 2009 Jared D. McNeill <jmcneill@invisible.ca>
6 * All rights reserved.
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Precedence Technologies Ltd
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
32 #include <sys/types.h>
33 #include <sys/ioctl.h>
35 #include <prop/proplib.h>
37 #include <errno.h>
38 #include <fcntl.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <unistd.h>
43 #include <dev/pci/hdaudio/hdaudioio.h>
44 #include <dev/pci/hdaudio/hdaudioreg.h>
46 #include "hdaudioctl.h"
48 static const char *pin_devices[16] = {
49 "Line Out", "Speaker", "HP Out", "CD",
50 "SPDIF Out", "Digital Out", "Modem Line", "Modem Handset",
51 "Line In", "AUX", "Mic In", "Telephony",
52 "SPDIF In", "Digital In", "Reserved", "Other"
55 int
56 hdaudioctl_graph(int fd, int argc, char *argv[])
58 prop_dictionary_t request, response;
59 prop_object_iterator_t iter;
60 prop_number_t nnid;
61 prop_array_t connlist;
62 const char *name;
63 int error, index;
64 uint32_t cap, config;
65 uint16_t reqnid, reqcodecid;
66 uint16_t vendor, product;
67 uint8_t type, nid;
68 char buf[10] = "??h";
70 if (argc != 2)
71 usage();
73 reqcodecid = strtol(argv[0], NULL, 0);
74 reqnid = strtol(argv[1], NULL, 0);
76 request = prop_dictionary_create();
77 if (request == NULL) {
78 fprintf(stderr, "out of memory\n");
79 return ENOMEM;
82 prop_dictionary_set_uint16(request, "codecid", reqcodecid);
83 prop_dictionary_set_uint16(request, "nid", reqnid);
85 error = prop_dictionary_sendrecv_ioctl(request, fd,
86 HDAUDIO_FGRP_CODEC_INFO, &response);
87 if (error != 0) {
88 perror("HDAUDIO_FGRP_CODEC_INFO failed");
89 prop_object_release(request);
90 return error;
93 prop_dictionary_get_uint16(response, "vendor-id", &vendor);
94 prop_dictionary_get_uint16(response, "product-id", &product);
96 printf("digraph \"HD Audio %04X:%04X\" {\n",
97 vendor, product);
99 for (index = 0;; index++) {
100 prop_dictionary_set_uint16(request, "index", index);
101 error = prop_dictionary_sendrecv_ioctl(request, fd,
102 HDAUDIO_FGRP_WIDGET_INFO, &response);
103 if (error != 0)
104 break;
105 prop_dictionary_get_cstring_nocopy(response, "name", &name);
106 prop_dictionary_get_uint32(response, "cap", &cap);
107 prop_dictionary_get_uint32(response, "config", &config);
108 prop_dictionary_get_uint8(response, "type", &type);
109 prop_dictionary_get_uint8(response, "nid", &nid);
111 sprintf(buf, "widget%02Xh", nid);
113 switch (type) {
114 case COP_AWCAP_TYPE_AUDIO_OUTPUT:
115 printf(" %s [shape=box,style=filled,fillcolor=\""
116 "#88ff88\"];\n", buf);
117 break;
118 case COP_AWCAP_TYPE_AUDIO_INPUT:
119 printf(" %s [shape=box,style=filled,fillcolor=\""
120 "#ff8888\"];\n", buf);
121 break;
122 case COP_AWCAP_TYPE_AUDIO_MIXER:
123 printf(" %s [shape=invhouse];\n", buf);
124 break;
125 case COP_AWCAP_TYPE_AUDIO_SELECTOR:
126 printf(" %s [shape=invtrapezium];\n", buf);
127 break;
128 case COP_AWCAP_TYPE_PIN_COMPLEX:
129 printf(" %s [label=\"%s\\ndevice=%s\",style=filled",
130 buf, buf,
131 pin_devices[COP_CFG_DEFAULT_DEVICE(config)]);
132 if (cap & COP_PINCAP_OUTPUT_CAPABLE &&
133 cap & COP_PINCAP_INPUT_CAPABLE)
134 printf(",shape=doublecircle,fillcolor=\""
135 "#ffff88\"];\n");
136 else if (cap & COP_PINCAP_OUTPUT_CAPABLE)
137 printf(",shape=circle,fillcolor=\"#88ff88\"];\n");
138 else if (cap & COP_PINCAP_INPUT_CAPABLE)
139 printf(",shape=circle,fillcolor=\"#ff8888\"];\n");
140 else
141 printf(",shape=circle,fillcolor=\"#888888\"];\n");
142 break;
144 connlist = prop_dictionary_get(response, "connlist");
145 if (connlist == NULL)
146 goto next;
147 iter = prop_array_iterator(connlist);
148 prop_object_iterator_reset(iter);
149 while ((nnid = prop_object_iterator_next(iter)) != NULL) {
150 nid = prop_number_unsigned_integer_value(nnid);
151 printf(" widget%02Xh -> %s [sametail=widget%02Xh];\n",
152 nid, buf, nid);
154 prop_object_iterator_release(iter);
155 next:
156 prop_object_release(response);
159 printf(" {rank=min;");
160 for (index = 0;; index++) {
161 prop_dictionary_set_uint16(request, "index", index);
162 error = prop_dictionary_sendrecv_ioctl(request, fd,
163 HDAUDIO_AFG_WIDGET_INFO, &response);
164 if (error != 0)
165 break;
166 prop_dictionary_get_cstring_nocopy(response, "name", &name);
167 prop_dictionary_get_uint8(response, "type", &type);
168 prop_dictionary_get_uint8(response, "nid", &nid);
170 sprintf(buf, "widget%02Xh", nid);
172 switch (type) {
173 case COP_AWCAP_TYPE_AUDIO_OUTPUT:
174 case COP_AWCAP_TYPE_AUDIO_INPUT:
175 printf(" %s;", buf);
176 break;
178 prop_object_release(response);
180 printf("}\n");
182 printf(" {rank=max;");
183 for (index = 0;; index++) {
184 prop_dictionary_set_uint16(request, "index", index);
185 error = prop_dictionary_sendrecv_ioctl(request, fd,
186 HDAUDIO_AFG_WIDGET_INFO, &response);
187 if (error != 0)
188 break;
189 prop_dictionary_get_cstring_nocopy(response, "name", &name);
190 prop_dictionary_get_uint8(response, "type", &type);
191 prop_dictionary_get_uint8(response, "nid", &nid);
193 sprintf(buf, "widget%02Xh", nid);
195 switch (type) {
196 case COP_AWCAP_TYPE_PIN_COMPLEX:
197 printf(" %s;", buf);
198 break;
200 prop_object_release(response);
202 printf("}\n");
204 printf("}\n");
206 prop_object_release(request);
208 return 0;