blob: 60d34ff667401091281e513cf0a92060e4a115fc [file] [log] [blame]
// Copyright 2020 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.
#ifndef SRC_MEDIA_AUDIO_DRIVERS_AML_G12_TDM_DAI_H_
#define SRC_MEDIA_AUDIO_DRIVERS_AML_G12_TDM_DAI_H_
#include <fidl/fuchsia.hardware.audio/cpp/wire.h>
#include <fuchsia/hardware/audio/cpp/banjo.h>
#include <fuchsia/hardware/audio/cpp/fidl.h>
#include <fuchsia/hardware/platform/device/c/banjo.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/cpp/task.h>
#include <lib/device-protocol/pdev-fidl.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fzl/pinned-vmo.h>
#include <lib/zx/bti.h>
#include <lib/zx/vmo.h>
#include <memory>
#include <optional>
#include <ddktl/device-internal.h>
#include <ddktl/device.h>
#include <ddktl/fidl.h>
#include <ddktl/metadata/audio.h>
#include <soc/aml-common/aml-tdm-audio.h>
#include "aml-tdm-config-device.h"
namespace audio::aml_g12 {
class AmlG12TdmDai;
using AmlG12TdmDaiDeviceType =
ddk::Device<AmlG12TdmDai, ddk::Messageable<fuchsia_hardware_audio::DaiConnector>::Mixin>;
class AmlG12TdmDai : public AmlG12TdmDaiDeviceType,
public ddk::DaiProtocol<AmlG12TdmDai, ddk::base_protocol>,
public ::fuchsia::hardware::audio::RingBuffer,
public ::fuchsia::hardware::audio::Dai {
public:
AmlG12TdmDai(zx_device_t* parent, ddk::PDevFidl pdev);
void DdkRelease();
zx_status_t DaiConnect(zx::channel channel);
zx_status_t InitPDev();
void Shutdown();
protected:
// FIDL HLCPP methods for fuchsia.hardware.audio.ringbuffer.
void Stop(StopCallback callback) override; // Protected for unit test.
private:
// FIDL LLCPP method for fuchsia.hardware.audio.DaiConnector.
void Connect(ConnectRequestView request, ConnectCompleter::Sync& completer) override;
// FIDL HLCPP methods for fuchsia.hardware.audio.Dai.
void Reset(ResetCallback callback) override;
void GetProperties(::fuchsia::hardware::audio::Dai::GetPropertiesCallback callback) override;
void GetHealthState(::fuchsia::hardware::audio::Dai::GetHealthStateCallback callback) override {
callback({});
}
void SignalProcessingConnect(
fidl::InterfaceRequest<fuchsia::hardware::audio::signalprocessing::SignalProcessing>
signal_processing) override {
signal_processing.Close(ZX_ERR_NOT_SUPPORTED);
}
void GetRingBufferFormats(GetRingBufferFormatsCallback callback) override;
void GetDaiFormats(GetDaiFormatsCallback callback) override;
void CreateRingBuffer(
::fuchsia::hardware::audio::DaiFormat dai_format,
::fuchsia::hardware::audio::Format ring_buffer_format,
::fidl::InterfaceRequest<::fuchsia::hardware::audio::RingBuffer> ring_buffer) override;
// FIDL HLCPP methods for fuchsia.hardware.audio.ringbuffer.
void GetProperties(
::fuchsia::hardware::audio::RingBuffer::GetPropertiesCallback callback) override;
void WatchClockRecoveryPositionInfo(WatchClockRecoveryPositionInfoCallback callback) override;
void WatchDelayInfo(WatchDelayInfoCallback callback) override;
void GetVmo(uint32_t min_frames, uint32_t clock_recovery_notifications_per_ring,
GetVmoCallback callback) override;
void Start(StartCallback callback) override;
void SetActiveChannels(uint64_t active_channels_bitmask,
SetActiveChannelsCallback callback) override {
callback(fpromise::error(ZX_ERR_NOT_SUPPORTED));
}
zx_status_t InitBuffer(size_t size);
void ProcessRingNotification();
void InitDaiFormats();
void ResetRingBuffer();
virtual bool AllowNonContiguousRingBuffer() { return false; } // For unit testing.
std::unique_ptr<AmlTdmConfigDevice> aml_audio_;
metadata::AmlConfig metadata_ = {};
uint32_t us_per_notification_ = 0;
::fuchsia::hardware::audio::DaiFormat dai_format_ = {};
bool rb_started_ = false;
bool rb_fetched_ = false;
int64_t internal_delay_nsec_ = 0;
bool delay_info_sent_ = false;
async::TaskClosureMethod<AmlG12TdmDai, &AmlG12TdmDai::ProcessRingNotification> notify_timer_{
this};
zx::vmo ring_buffer_vmo_;
fzl::PinnedVmo pinned_ring_buffer_;
zx::bti bti_;
std::optional<fidl::Binding<::fuchsia::hardware::audio::Dai>> dai_binding_;
std::optional<fidl::Binding<::fuchsia::hardware::audio::RingBuffer>> ringbuffer_binding_;
async::Loop loop_;
uint32_t frame_size_ = 0;
std::atomic<uint32_t> expected_notifications_per_ring_{0};
std::optional<WatchClockRecoveryPositionInfoCallback> position_callback_;
ddk::PDevFidl pdev_;
};
} // namespace audio::aml_g12
#endif // SRC_MEDIA_AUDIO_DRIVERS_AML_G12_TDM_DAI_H_