1// Copyright 2018 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 <ddk/protocol/usb.h> 8#include <ddktl/device.h> 9#include <fbl/array.h> 10#include <fbl/intrusive_double_list.h> 11#include <fbl/mutex.h> 12#include <fbl/ref_counted.h> 13#include <fbl/ref_ptr.h> 14#include <zircon/thread_annotations.h> 15 16#include "usb-audio-control-interface.h" 17#include "usb-audio-descriptors.h" 18#include "debug-logging.h" 19 20namespace audio { 21namespace usb { 22 23class UsbAudioStream; 24 25class UsbAudioDevice; 26using UsbAudioDeviceBase = ddk::Device<UsbAudioDevice, ddk::Unbindable>; 27 28class UsbAudioDevice : public UsbAudioDeviceBase, 29 public fbl::RefCounted<UsbAudioDevice> { 30public: 31 static zx_status_t DriverBind(zx_device_t* parent); 32 void DdkUnbind(); 33 void DdkRelease(); 34 35 void RemoveAudioStream(const fbl::RefPtr<UsbAudioStream>& stream); 36 37 const char* log_prefix() const { return log_prefix_; } 38 const usb_device_descriptor_t& desc() const { return usb_dev_desc_; } 39 const fbl::RefPtr<DescriptorListMemory>& desc_list() const { return desc_list_; } 40 const usb_protocol_t& usb_proto() const { return usb_proto_; } 41 uint16_t vid() const { return usb_dev_desc_.idVendor; } 42 uint16_t pid() const { return usb_dev_desc_.idProduct; } 43 const fbl::Array<uint8_t>& mfr_name() const { return mfr_name_; } 44 const fbl::Array<uint8_t>& prod_name() const { return prod_name_; } 45 const fbl::Array<uint8_t>& serial_num() const { return serial_num_; } 46 47private: 48 explicit UsbAudioDevice(zx_device_t* parent); 49 50 // A small struct used when searching descriptors for midi streaming 51 // interfaces. 52 // 53 // TODO(johngro) : Someday, turn this into something more like 54 // UsbAudioStreamingInterface and give it the ability to parse and 55 // understand its class specific interfaces, class specific endpoints, and 56 // manage multiple alternate interface settings. 57 struct MidiStreamingInfo { 58 explicit MidiStreamingInfo(const usb_interface_descriptor_t* i) : ifc(i) {} 59 const usb_interface_descriptor_t* ifc; 60 const usb_endpoint_descriptor_t* in_ep = nullptr; 61 const usb_endpoint_descriptor_t* out_ep = nullptr; 62 }; 63 64 zx_status_t Bind(); 65 void Probe(); 66 void ParseMidiStreamingIfc(DescriptorListMemory::Iterator* iter, 67 MidiStreamingInfo* inout_info); 68 69 char log_prefix_[LOG_PREFIX_STORAGE] = { 0 }; 70 71 usb_protocol_t usb_proto_; 72 fbl::Mutex lock_; 73 usb_device_descriptor_t usb_dev_desc_; 74 fbl::Array<uint8_t> mfr_name_; 75 fbl::Array<uint8_t> prod_name_; 76 fbl::Array<uint8_t> serial_num_; 77 fbl::RefPtr<DescriptorListMemory> desc_list_; 78 fbl::DoublyLinkedList<fbl::RefPtr<UsbAudioStream>> streams_ TA_GUARDED(lock_); 79 80 int midi_sink_index_ = 0; 81 int midi_source_index_ = 0; 82}; 83 84} // namespace usb 85} // namespace audio 86