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