blob: cc7750a06050f2a0a96fe05985e275f95b08e28f [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdio.h>
#include <zircon/types.h>
#include "intel_hda_codec.h"
#include "intel_hda_controller.h"
#include "zircon_device.h"
namespace audio {
namespace intel_hda {
static IntelHDAController::ControllerTree::iterator GetController(int id) {
return (id < 0) ? IntelHDAController::controllers().begin()
: IntelHDAController::controllers().find(id);
}
static IntelHDACodec::CodecTree::iterator GetCodec(int id) {
return (id < 0) ? IntelHDACodec::codecs().begin() : IntelHDACodec::codecs().find(id);
}
int main(int argc, const char** argv) {
int arg = 1;
int32_t dev_id = 0;
int32_t codec_id = 0;
zx_status_t res;
while (arg < argc) {
if (!strcmp("-d", argv[arg])) {
if ((++arg >= argc) || sscanf(argv[arg++], "%d", &dev_id) != 1)
goto usage;
if (dev_id < 0)
goto usage;
} else if (!strcmp("-c", argv[arg])) {
if ((++arg >= argc) || sscanf(argv[arg++], "%d", &codec_id) != 1)
goto usage;
if (codec_id < 0)
goto usage;
} else
break;
}
if (arg >= argc)
goto usage;
res = IntelHDAController::Enumerate();
if (res != ZX_OK) {
printf("Failed to enumerate controller devices (%d)\n", res);
return res;
}
res = IntelHDACodec::Enumerate();
if (res != ZX_OK) {
printf("Failed to enumerate codec devices (%d)\n", res);
return res;
}
if (!strcmp("list", argv[arg])) {
printf("Found %zu Intel HDA Controllers\n", IntelHDAController::controllers().size());
for (auto& controller : IntelHDAController::controllers()) {
IntelHDADevice device;
res = controller.Probe(&device);
if (res != ZX_OK) {
printf("Failed to probe controller at \"%s\" (res %d)\n", controller.dev_name().c_str(),
res);
return res;
}
controller.Disconnect();
printf("device %u [%04hx:%04hx %u.%u] : %s\n", controller.id(), device.vid, device.did,
device.ihda_vmaj, device.ihda_vmin, controller.dev_name().c_str());
}
printf("Found %zu Intel HDA Codecs\n", IntelHDACodec::codecs().size());
for (auto& codec : IntelHDACodec::codecs()) {
IntelHDADevice device;
res = codec.Probe(&device);
if (res != ZX_OK) {
printf("Failed to probe codec at \"%s\" (res %d)\n", codec.dev_name().c_str(), res);
return res;
}
printf(" Codec %u [%04hx:%04hx] : %s\n", codec.id(), device.vid, device.did,
codec.dev_name().c_str());
codec.Disconnect();
}
return 0;
}
static const struct {
const char* name;
zx_status_t (IntelHDAController::*cmd)(int, const char**);
} CONTROLLER_CMDS[] = {
{"regs", &IntelHDAController::DumpRegs},
};
for (const auto& cmd : CONTROLLER_CMDS) {
if (strcmp(cmd.name, argv[arg]))
continue;
auto iter = GetController(dev_id);
if (!iter.IsValid()) {
printf("Intel HDA controller not found!\n");
return ZX_ERR_NOT_FOUND;
}
arg++;
return ((*iter).*cmd.cmd)(argc - arg, argv + arg);
}
static const struct {
const char* name;
zx_status_t (IntelHDACodec::*cmd)(int, const char**);
} CODEC_CMDS[] = {
{"codec", &IntelHDACodec::DumpCodec},
};
for (const auto& cmd : CODEC_CMDS) {
if (strcmp(cmd.name, argv[arg]))
continue;
auto iter = GetCodec(codec_id);
if (!iter.IsValid()) {
printf("Intel HDA codec not found!\n");
return ZX_ERR_NOT_FOUND;
}
arg++;
return ((*iter).*cmd.cmd)(argc - arg, argv + arg);
}
usage:
printf(
"usage: %s [-d <dev_id>] [-c <codec_id>] <cmd>\n"
"Valid cmds are...\n"
"\thelp : Show this message\n"
"\tlist : List currently active devices and codecs.\n"
"\tregs : Dump the registers for the specified device ID\n"
"\tcodec : Dump the internal structure of a codec\n",
argv[0]);
return -1;
}
} // namespace intel_hda
} // namespace audio
int main(int argc, const char** argv) { return ::audio::intel_hda::main(argc, argv); }