mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 07:24:58 +00:00
65 lines
1.9 KiB
C++
65 lines
1.9 KiB
C++
/*
|
|
* Copyright (c) 2023, Liav A. <liavalb@hotmail.co.il>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <Kernel/API/BeepInstruction.h>
|
|
#if ARCH(X86_64)
|
|
# include <Kernel/Arch/x86_64/PCSpeaker.h>
|
|
#endif
|
|
#include <Kernel/Boot/CommandLine.h>
|
|
#include <Kernel/Devices/DeviceManagement.h>
|
|
#include <Kernel/Devices/Generic/PCSpeakerDevice.h>
|
|
#include <Kernel/Sections.h>
|
|
|
|
namespace Kernel {
|
|
|
|
UNMAP_AFTER_INIT NonnullRefPtr<PCSpeakerDevice> PCSpeakerDevice::must_create()
|
|
{
|
|
auto device = MUST(DeviceManagement::try_create_device<PCSpeakerDevice>());
|
|
return *device;
|
|
}
|
|
|
|
UNMAP_AFTER_INIT PCSpeakerDevice::PCSpeakerDevice()
|
|
: CharacterDevice(1, 10)
|
|
{
|
|
}
|
|
|
|
UNMAP_AFTER_INIT PCSpeakerDevice::~PCSpeakerDevice() = default;
|
|
|
|
bool PCSpeakerDevice::can_read(OpenFileDescription const&, u64) const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
ErrorOr<size_t> PCSpeakerDevice::read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t)
|
|
{
|
|
return Error::from_errno(ENOTIMPL);
|
|
}
|
|
|
|
ErrorOr<size_t> PCSpeakerDevice::write(OpenFileDescription&, u64, UserOrKernelBuffer const& buffer, size_t buffer_size)
|
|
{
|
|
if (!kernel_command_line().is_pc_speaker_enabled())
|
|
return Error::from_errno(ENOTSUP);
|
|
if (buffer_size % sizeof(BeepInstruction) != 0)
|
|
return Error::from_errno(EINVAL);
|
|
BeepInstruction instruction {};
|
|
TRY(buffer.read(&instruction, sizeof(BeepInstruction)));
|
|
if (instruction.tone < 20 || instruction.tone > 20000)
|
|
return Error::from_errno(EINVAL);
|
|
if (instruction.milliseconds_duration == 0)
|
|
return Error::from_errno(EINVAL);
|
|
#if ARCH(X86_64)
|
|
PCSpeaker::tone_on(instruction.tone);
|
|
auto result = Thread::current()->sleep(Duration::from_milliseconds(instruction.milliseconds_duration));
|
|
PCSpeaker::tone_off();
|
|
if (result.was_interrupted())
|
|
return Error::from_errno(EINTR);
|
|
return sizeof(BeepInstruction);
|
|
#else
|
|
return Error::from_errno(ENOTIMPL);
|
|
#endif
|
|
}
|
|
|
|
}
|