/* * Copyright (c) 2023, Jelle Raaijmakers * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include #include #include namespace Kernel::Audio::IntelHDA { // Specification: https://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/high-definition-audio-specification.pdf class Codec; class Controller final : public AudioController , public PCI::Device { public: static ErrorOr probe(PCI::DeviceIdentifier const&); static ErrorOr> create(PCI::DeviceIdentifier const&); virtual ~Controller() = default; // ^PCI::Device virtual StringView device_name() const override { return "IntelHDA"sv; } ErrorOr send_command(u8 codec_address, u8 node_id, CodecControlVerb verb, u16 payload); private: static constexpr size_t fixed_audio_channel_index = 0; // 3.3: High Definition Audio Controller Register Set enum ControllerRegister : u8 { GlobalCapabilities = 0x00, VersionMinor = 0x02, VersionMajor = 0x03, GlobalControl = 0x08, StateChangeStatus = 0x0e, CommandOutboundRingBufferOffset = 0x40, ResponseInboundRingBufferOffset = 0x50, StreamsOffset = 0x80, }; // 3.3.7: GCTL – Global Control enum GlobalControlFlag : u32 { ControllerReset = 1u << 0, AcceptUnsolicitedResponseEnable = 1u << 8, }; Controller(PCI::DeviceIdentifier const&, NonnullOwnPtr); ErrorOr initialize_codec(u8 codec_address); ErrorOr configure_output_route(); ErrorOr reset(); // ^AudioController virtual RefPtr audio_channel(u32 index) const override; virtual ErrorOr write(size_t channel_index, UserOrKernelBuffer const& data, size_t length) override; virtual ErrorOr initialize(Badge) override; virtual ErrorOr set_pcm_output_sample_rate(size_t channel_index, u32 samples_per_second_rate) override; virtual ErrorOr get_pcm_output_sample_rate(size_t channel_index) override; NonnullOwnPtr m_controller_io_window; u8 m_number_of_output_streams; u8 m_number_of_input_streams; u8 m_number_of_bidirectional_streams; OwnPtr m_command_buffer; OwnPtr m_response_buffer; Vector> m_codecs {}; OwnPtr m_output_path; RefPtr m_audio_channel; }; }