blob: 8fb65def8293ce8aab49faf625ec057d367c5f4d [file] [log] [blame]
// Copyright 2019 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 <memory>
#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/driver.h>
#include <ddk/platform-defs.h>
#include <ddk/protocol/platform/device.h>
#include <ddktl/device.h>
#include <ddktl/protocol/codec.h>
#define DRIVER_NAME "test-codec"
namespace codec {
class TestAudioCodecDevice;
using DeviceType = ddk::Device<TestAudioCodecDevice, ddk::Unbindable>;
class TestAudioCodecDevice : public DeviceType,
public ddk::CodecProtocol<TestAudioCodecDevice, ddk::base_protocol> {
public:
static zx_status_t Create(zx_device_t* parent);
explicit TestAudioCodecDevice(zx_device_t* parent)
: DeviceType(parent) {}
zx_status_t Create(std::unique_ptr<TestAudioCodecDevice>* out);
void CodecReset(codec_reset_callback callback, void* cookie) {
callback(cookie, ZX_OK);
}
void CodecGetInfo(codec_get_info_callback callback, void* cookie) {
info_t info = {};
info.unique_id = "test_id";
info.manufacturer = "test_man";
info.product_name = "test_product";
callback(cookie, &info);
}
void CodecIsBridgeable(codec_is_bridgeable_callback callback, void* cookie) {
callback(cookie, true);
}
void CodecSetBridgedMode(bool enable_bridged_mode, codec_set_bridged_mode_callback callback,
void* cookie) {
callback(cookie);
}
void CodecGetDaiFormats(codec_get_dai_formats_callback callback, void* cookie) {
dai_supported_formats_t formats[3] = {};
uint8_t bits_per_sample[3] = {1, 99, 253};
formats[0].bits_per_sample_list = bits_per_sample;
formats[0].bits_per_sample_count = 3;
uint32_t number_of_channels[3] = {0, 1, 200};
formats[1].number_of_channels_list = number_of_channels;
formats[1].number_of_channels_count = 3;
uint32_t frame_rates[1] = {48000};
formats[2].frame_rates_list = frame_rates;
formats[2].frame_rates_count = 1;
callback(cookie, ZX_OK, formats, 3);
}
void CodecSetDaiFormat(const dai_format_t* format, codec_set_dai_format_callback callback,
void* cookie) {
callback(cookie, ZX_OK);
}
void CodecGetGainFormat(codec_get_gain_format_callback callback, void* cookie) {
gain_format_t format = {};
format.can_agc = true;
format.min_gain = -99.99f;
callback(cookie, &format);
}
void CodecGetGainState(codec_get_gain_state_callback callback, void* cookie) {
gain_state_t gain_state = {};
gain_state.gain = 123.456f;
gain_state.muted = true;
gain_state.agc_enable = false;
callback(cookie, &gain_state);
}
void CodecSetGainState(const gain_state_t* gain_state, codec_set_gain_state_callback callback,
void* cookie) {
callback(cookie);
}
void CodecGetPlugState(codec_get_plug_state_callback callback, void* cookie) {
plug_state_t plug_state = {};
plug_state.hardwired = false;
plug_state.plugged = true;
callback(cookie, &plug_state);
}
// Methods required by the ddk mixins
void DdkUnbind();
void DdkRelease();
};
zx_status_t TestAudioCodecDevice::Create(zx_device_t* parent) {
auto dev = std::make_unique<TestAudioCodecDevice>(parent);
zxlogf(INFO, "TestAudioCodecDevice::Create: %s \n", DRIVER_NAME);
auto status = dev->DdkAdd("test-codec");
if (status != ZX_OK) {
zxlogf(ERROR, "%s: DdkAdd failed: %d\n", __func__, status);
return status;
}
// devmgr is now in charge of dev.
__UNUSED auto ptr = dev.release();
return ZX_OK;
}
void TestAudioCodecDevice::DdkUnbind() {
DdkRemove();
}
void TestAudioCodecDevice::DdkRelease() {
delete this;
}
zx_status_t test_codec_bind(void* ctx, zx_device_t* parent) {
return TestAudioCodecDevice::Create(parent);
}
constexpr zx_driver_ops_t driver_ops = []() {
zx_driver_ops_t driver_ops = {};
driver_ops.version = DRIVER_OPS_VERSION;
driver_ops.bind = test_codec_bind;
return driver_ops;
}();
} // namespace codec
ZIRCON_DRIVER_BEGIN(test_codec, codec::driver_ops, "zircon", "0.1", 4)
BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PDEV),
BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_TEST),
BI_ABORT_IF(NE, BIND_PLATFORM_DEV_PID, PDEV_PID_PBUS_TEST),
BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_TEST_AUDIO_CODEC),
ZIRCON_DRIVER_END(test_codec)