ladybird/Kernel/Devices/SB16.h
kleines Filmröllchen d0ceaa24a6 Kernel: Implement ioctl for the SB16 to change sample rate
Two new ioctl requests are used to get and set the sample rate of the
sound card. The SB16 device keeps track of the sample rate separately,
because I don't want to figure out how to read the sample rate from the
device; it's easier that way.

The soundcard write doesn't set the sample rate to 44100 Hz every time
anymore, as we want to change it externally.
2021-08-27 23:35:27 +04:30

67 lines
1.8 KiB
C++

/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <Kernel/Devices/CharacterDevice.h>
#include <Kernel/Interrupts/IRQHandler.h>
#include <Kernel/Memory/PhysicalPage.h>
#include <Kernel/PhysicalAddress.h>
#include <Kernel/WaitQueue.h>
namespace Kernel {
class SB16;
class SB16 final : public IRQHandler
, public CharacterDevice {
public:
SB16();
virtual ~SB16() override;
static void detect();
static void create();
static SB16& the();
// ^CharacterDevice
virtual bool can_read(const FileDescription&, size_t) const override;
virtual KResultOr<size_t> read(FileDescription&, u64, UserOrKernelBuffer&, size_t) override;
virtual KResultOr<size_t> write(FileDescription&, u64, const UserOrKernelBuffer&, size_t) override;
virtual bool can_write(const FileDescription&, size_t) const override { return true; }
virtual StringView purpose() const override { return class_name(); }
// ^Device
virtual mode_t required_mode() const override { return 0220; }
virtual String device_name() const override { return "audio"; }
virtual KResult ioctl(FileDescription&, unsigned, Userspace<void*>) override;
private:
// ^IRQHandler
virtual bool handle_irq(const RegisterState&) override;
// ^CharacterDevice
virtual StringView class_name() const override { return "SB16"; }
void initialize();
void wait_for_irq();
void dma_start(uint32_t length);
void set_sample_rate(uint16_t hz);
void dsp_write(u8 value);
static u8 dsp_read();
u8 get_irq_line();
void set_irq_register(u8 irq_number);
void set_irq_line(u8 irq_number);
OwnPtr<Memory::Region> m_dma_region;
int m_major_version { 0 };
u16 m_sample_rate { 44100 };
WaitQueue m_irq_queue;
};
}