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