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#pragma once 6 7#include <ddktl/device-internal.h> 8#include <ddktl/device.h> 9#include <fbl/mutex.h> 10#include <fbl/vector.h> 11 12#include "a113-ddr.h" 13#include "a113-pdm.h" 14#include "audio-proto/audio-proto.h" 15#include "dispatcher-pool/dispatcher-channel.h" 16#include "dispatcher-pool/dispatcher-execution-domain.h" 17 18#include "a113-ddr.h" 19#include "a113-pdm.h" 20#include "vmo_helper.h" 21 22namespace audio { 23namespace gauss { 24 25struct PdmInputStreamProtocol : public ddk::internal::base_protocol { 26 explicit PdmInputStreamProtocol() { 27 ddk_proto_id_ = ZX_PROTOCOL_AUDIO_INPUT; 28 } 29}; 30 31class GaussPdmInputStream; 32using GaussPdmInputStreamBase = 33 ddk::Device<GaussPdmInputStream, ddk::Ioctlable, ddk::Unbindable>; 34 35class GaussPdmInputStream : public GaussPdmInputStreamBase, 36 public PdmInputStreamProtocol, 37 public fbl::RefCounted<GaussPdmInputStream> { 38public: 39 static zx_status_t Create(zx_device_t* parent); 40 41 // DDK device implementation 42 void DdkUnbind(); 43 void DdkRelease(); 44 zx_status_t DdkIoctl(uint32_t op, const void* in_buf, size_t in_len, 45 void* out_buf, size_t out_len, size_t* out_actual); 46 47private: 48 friend class fbl::RefPtr<GaussPdmInputStream>; 49 50 GaussPdmInputStream( 51 zx_device_t* parent, 52 fbl::RefPtr<dispatcher::ExecutionDomain>&& default_domain) 53 : GaussPdmInputStreamBase(parent), 54 default_domain_(fbl::move(default_domain)) {} 55 56 virtual ~GaussPdmInputStream(); 57 58 int IrqThread(); 59 60 zx_status_t Bind(const char* devname, zx_device_t* parent); 61 62 // Thunks for dispatching stream channel events. 63 zx_status_t ProcessStreamChannel(dispatcher::Channel* channel, 64 bool privileged); 65 66 void DeactivateStreamChannel(const dispatcher::Channel* channel); 67 68 zx_status_t OnGetStreamFormats(dispatcher::Channel* channel, 69 const audio_proto::StreamGetFmtsReq& req); 70 71 zx_status_t OnSetStreamFormat(dispatcher::Channel* channel, 72 const audio_proto::StreamSetFmtReq& req, 73 bool privileged); 74 75 zx_status_t OnGetGain(dispatcher::Channel* channel, 76 const audio_proto::GetGainReq& req); 77 78 zx_status_t OnSetGain(dispatcher::Channel* channel, 79 const audio_proto::SetGainReq& req); 80 81 zx_status_t OnPlugDetect(dispatcher::Channel* channel, 82 const audio_proto::PlugDetectReq& req); 83 84 zx_status_t OnGetUniqueId(dispatcher::Channel* channel, const audio_proto::GetUniqueIdReq& req); 85 zx_status_t OnGetString(dispatcher::Channel* channel, const audio_proto::GetStringReq& req); 86 87 // Thunks for dispatching ring buffer channel events. 88 zx_status_t ProcessRingBufferChannel(dispatcher::Channel* channel); 89 90 void DeactivateRingBufferChannel(const dispatcher::Channel* channel); 91 92 // Stream command handlers 93 // Ring buffer command handlers 94 zx_status_t OnGetFifoDepth(dispatcher::Channel* channel, 95 const audio_proto::RingBufGetFifoDepthReq& req) 96 __TA_REQUIRES(lock_); 97 98 zx_status_t OnGetBuffer(dispatcher::Channel* channel, 99 const audio_proto::RingBufGetBufferReq& req) 100 __TA_REQUIRES(lock_); 101 102 zx_status_t OnStart(dispatcher::Channel* channel, 103 const audio_proto::RingBufStartReq& req) 104 __TA_REQUIRES(lock_); 105 106 zx_status_t OnStop(dispatcher::Channel* channel, 107 const audio_proto::RingBufStopReq& req) 108 __TA_REQUIRES(lock_); 109 110 fbl::Mutex lock_; 111 112 // Dispatcher framework state 113 fbl::RefPtr<dispatcher::Channel> stream_channel_; 114 fbl::RefPtr<dispatcher::Channel> rb_channel_ __TA_GUARDED(lock_); 115 fbl::RefPtr<dispatcher::ExecutionDomain> default_domain_; 116 117 fbl::Vector<audio_stream_format_range_t> supported_formats_; 118 119 uint32_t frame_size_; 120 121 VmoHelper<false> vmo_helper_; 122 123 // TODO(almasrymina): hardcoded. 124 uint32_t frame_rate_ = 48000; 125 126 a113_audio_device_t audio_device_; 127 thrd_t irqthrd_; 128 129 uint32_t fifo_depth_ = 0x200; 130 131 fbl::atomic<size_t> ring_buffer_size_; 132 fbl::atomic<uint32_t> notifications_per_ring_; 133}; 134 135} // namespace gauss 136} // namespace audio 137