4 * Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk>
5 * Copyright (c) 2009 Jared D. McNeill <jmcneill@invisible.ca>
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
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
32 #include <sys/types.h>
33 #include <sys/ioctl.h>
35 #include <prop/proplib.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"
56 hdaudioctl_graph(int fd
, int argc
, char *argv
[])
58 prop_dictionary_t request
, response
;
59 prop_object_iterator_t iter
;
61 prop_array_t connlist
;
65 uint16_t reqnid
, reqcodecid
;
66 uint16_t vendor
, product
;
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");
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
);
88 perror("HDAUDIO_FGRP_CODEC_INFO failed");
89 prop_object_release(request
);
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",
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
);
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
);
114 case COP_AWCAP_TYPE_AUDIO_OUTPUT
:
115 printf(" %s [shape=box,style=filled,fillcolor=\""
116 "#88ff88\"];\n", buf
);
118 case COP_AWCAP_TYPE_AUDIO_INPUT
:
119 printf(" %s [shape=box,style=filled,fillcolor=\""
120 "#ff8888\"];\n", buf
);
122 case COP_AWCAP_TYPE_AUDIO_MIXER
:
123 printf(" %s [shape=invhouse];\n", buf
);
125 case COP_AWCAP_TYPE_AUDIO_SELECTOR
:
126 printf(" %s [shape=invtrapezium];\n", buf
);
128 case COP_AWCAP_TYPE_PIN_COMPLEX
:
129 printf(" %s [label=\"%s\\ndevice=%s\",style=filled",
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=\""
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");
141 printf(",shape=circle,fillcolor=\"#888888\"];\n");
144 connlist
= prop_dictionary_get(response
, "connlist");
145 if (connlist
== NULL
)
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",
154 prop_object_iterator_release(iter
);
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
);
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
);
173 case COP_AWCAP_TYPE_AUDIO_OUTPUT
:
174 case COP_AWCAP_TYPE_AUDIO_INPUT
:
178 prop_object_release(response
);
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
);
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
);
196 case COP_AWCAP_TYPE_PIN_COMPLEX
:
200 prop_object_release(response
);
206 prop_object_release(request
);