diff options
author | Liav A <liavalb@gmail.com> | 2020-02-22 20:19:13 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-02-24 11:27:03 +0100 |
commit | c51a57fb320ee3c28bea9ee223decfdd601e7e60 (patch) | |
tree | a7dd516b0bbe14c113bc353044f9b58d0fe1a660 /Kernel | |
parent | 895e874eb482daa14f4cd75afbb1fca6021fd09d (diff) | |
download | serenity-c51a57fb320ee3c28bea9ee223decfdd601e7e60.zip |
Kernel: Update SB16 driver to use the new IRQHandler class
Also, add methods to allow changing of IRQ line in the SB16 card.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Devices/SB16.cpp | 55 | ||||
-rw-r--r-- | Kernel/Devices/SB16.h | 8 |
2 files changed, 58 insertions, 5 deletions
diff --git a/Kernel/Devices/SB16.cpp b/Kernel/Devices/SB16.cpp index e313e1b6e2..5d30d817e2 100644 --- a/Kernel/Devices/SB16.cpp +++ b/Kernel/Devices/SB16.cpp @@ -33,6 +33,7 @@ //#define SB16_DEBUG namespace Kernel { +#define SB16_DEFAULT_IRQ 5 enum class SampleFormat : u8 { Signed = 0x10, @@ -76,7 +77,7 @@ void SB16::set_sample_rate(uint16_t hz) static SB16* s_the; SB16::SB16() - : IRQHandler(5) + : IRQHandler(SB16_DEFAULT_IRQ) , CharacterDevice(42, 42) // ### ? { s_the = this; @@ -112,6 +113,56 @@ void SB16::initialize() auto vmin = dsp_read(); kprintf("SB16: found version %d.%d\n", m_major_version, vmin); + set_irq_register(SB16_DEFAULT_IRQ); + kprintf("SB16: IRQ %d\n", get_irq_line()); +} + +void SB16::set_irq_register(u8 irq_number) +{ + u8 bitmask; + switch (irq_number) { + case 2: + bitmask = 0; + break; + case 5: + bitmask = 0b10; + break; + case 7: + bitmask = 0b100; + break; + case 10: + bitmask = 0b1000; + break; + default: + ASSERT_NOT_REACHED(); + } + IO::out8(0x224, 0x80); + IO::out8(0x225, bitmask); +} + +u8 SB16::get_irq_line() +{ + IO::out8(0x224, 0x80); + u8 bitmask = IO::in8(0x225); + switch (bitmask) { + case 0: + return 2; + case 0b10: + return 5; + case 0b100: + return 7; + case 0b1000: + return 10; + } + return bitmask; +} +void SB16::set_irq_line(u8 irq_number) +{ + InterruptDisabler disabler; + if (irq_number == get_irq_line()) + return; + set_irq_register(irq_number); + change_irq_number(irq_number); } bool SB16::can_read(const FileDescription&) const @@ -155,7 +206,7 @@ void SB16::dma_start(uint32_t length) IO::out8(0xd4, (channel % 4)); } -void SB16::handle_irq() +void SB16::handle_irq(RegisterState&) { // Stop sound output ready for the next block. dsp_write(0xd5); diff --git a/Kernel/Devices/SB16.h b/Kernel/Devices/SB16.h index 7d794a8c35..71dd25c0c8 100644 --- a/Kernel/Devices/SB16.h +++ b/Kernel/Devices/SB16.h @@ -27,7 +27,7 @@ #pragma once #include <Kernel/Devices/CharacterDevice.h> -#include <Kernel/IRQHandler.h> +#include <Kernel/Interrupts/IRQHandler.h> #include <Kernel/VM/PhysicalPage.h> #include <Kernel/WaitQueue.h> #include <LibBareMetal/Memory/PhysicalAddress.h> @@ -52,7 +52,7 @@ public: private: // ^IRQHandler - virtual void handle_irq() override; + virtual void handle_irq(RegisterState&) override; // ^CharacterDevice virtual const char* class_name() const override { return "SB16"; } @@ -63,11 +63,13 @@ private: void set_sample_rate(uint16_t hz); void dsp_write(u8 value); u8 dsp_read(); + u8 get_irq_line(); + void set_irq_register(u8 irq_number); + void set_irq_line(u8 irq_number); OwnPtr<Region> m_dma_region; int m_major_version { 0 }; WaitQueue m_irq_queue; }; - } |