1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <zircon/types.h>
6 #include <stdio.h>
7
8 #include "intel_hda_codec.h"
9 #include "intel_hda_controller.h"
10 #include "zircon_device.h"
11
12 namespace audio {
13 namespace intel_hda {
14
GetController(int id)15 static IntelHDAController::ControllerTree::iterator GetController(int id) {
16 return (id < 0)
17 ? IntelHDAController::controllers().begin()
18 : IntelHDAController::controllers().find(id);
19 }
20
GetCodec(int id)21 static IntelHDACodec::CodecTree::iterator GetCodec(int id) {
22 return (id < 0)
23 ? IntelHDACodec::codecs().begin()
24 : IntelHDACodec::codecs().find(id);
25 }
26
main(int argc,const char ** argv)27 int main(int argc, const char** argv) {
28 int arg = 1;
29 int32_t dev_id = 0;
30 int32_t codec_id = 0;
31 zx_status_t res;
32
33 while (arg < argc) {
34 if (!strcmp("-d", argv[arg])) {
35 if ((++arg >= argc) || sscanf(argv[arg++], "%d", &dev_id) != 1)
36 goto usage;
37
38 if (dev_id < 0)
39 goto usage;
40 } else
41 if (!strcmp("-c", argv[arg])) {
42 if ((++arg >= argc) || sscanf(argv[arg++], "%d", &codec_id) != 1)
43 goto usage;
44
45 if (codec_id < 0)
46 goto usage;
47 } else
48 break;
49 }
50
51 if (arg >= argc)
52 goto usage;
53
54 res = IntelHDAController::Enumerate();
55 if (res != ZX_OK) {
56 printf("Failed to enumerate controller devices (%d)\n", res);
57 return res;
58 }
59
60 res = IntelHDACodec::Enumerate();
61 if (res != ZX_OK) {
62 printf("Failed to enumerate codec devices (%d)\n", res);
63 return res;
64 }
65
66 if (!strcmp("list", argv[arg])) {
67 printf("Found %zu Intel HDA Controllers\n", IntelHDAController::controllers().size());
68 for (auto& controller : IntelHDAController::controllers()) {
69 res = controller.Probe();
70
71 if (res != ZX_OK) {
72 printf("Failed to probe controller at \"%s\" (res %d)\n",
73 controller.dev_name(), res);
74 return res;
75 }
76
77 controller.Disconnect();
78
79 printf("Controller %u [%04hx:%04hx %u.%u] : %s\n",
80 controller.id(),
81 controller.vid(),
82 controller.did(),
83 controller.ihda_vmaj(),
84 controller.ihda_vmin(),
85 controller.dev_name());
86 }
87
88 printf("Found %zu Intel HDA Codecs\n", IntelHDACodec::codecs().size());
89 for (auto& codec : IntelHDACodec::codecs()) {
90 res = codec.Probe();
91
92 if (res != ZX_OK) {
93 printf("Failed to probe codec at \"%s\" (res %d)\n",
94 codec.dev_name(), res);
95 return res;
96 }
97
98 printf(" Codec %u [%04hx:%04hx] : %s\n",
99 codec.id(),
100 codec.vid(),
101 codec.did(),
102 codec.dev_name());
103
104 codec.Disconnect();
105 }
106
107 return 0;
108 }
109
110 static const struct {
111 const char* name;
112 zx_status_t (IntelHDAController::*cmd)(int, const char**);
113 } CONTROLLER_CMDS[] = {
114 { "regs", &IntelHDAController::DumpRegs },
115 };
116
117 for (const auto& cmd : CONTROLLER_CMDS) {
118 if (strcmp(cmd.name, argv[arg]))
119 continue;
120
121 auto iter = GetController(dev_id);
122
123 if (!iter.IsValid()) {
124 printf("Intel HDA controller not found!\n");
125 return ZX_ERR_NOT_FOUND;
126 }
127
128 arg++;
129 return ((*iter).*cmd.cmd)(argc - arg, argv + arg);
130 }
131
132 static const struct {
133 const char* name;
134 zx_status_t (IntelHDACodec::*cmd)(int, const char**);
135 } CODEC_CMDS[] = {
136 { "codec", &IntelHDACodec::DumpCodec },
137 };
138
139 for (const auto& cmd : CODEC_CMDS) {
140 if (strcmp(cmd.name, argv[arg]))
141 continue;
142
143 auto iter = GetCodec(codec_id);
144
145 if (!iter.IsValid()) {
146 printf("Intel HDA codec not found!\n");
147 return ZX_ERR_NOT_FOUND;
148 }
149
150 arg++;
151 return ((*iter).*cmd.cmd)(argc - arg, argv + arg);
152 }
153
154 usage:
155 printf("usage: %s [-d <dev_id>] [-c <codec_id>] <cmd>\n"
156 "Valid cmds are...\n"
157 "\thelp : Show this message\n"
158 "\tlist : List currently active devices and codecs.\n"
159 "\tregs : Dump the registers for the specified device ID\n"
160 "\tcodec : Dump the internal structure of a codec\n",
161 argv[0]);
162
163 return -1;
164 }
165
166 } // namespace audio
167 } // namespace intel_hda
168
main(int argc,const char ** argv)169 int main(int argc, const char** argv) {
170 return ::audio::intel_hda::main(argc, argv);
171 }
172