summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2020-02-22 20:19:13 +0200
committerAndreas Kling <kling@serenityos.org>2020-02-24 11:27:03 +0100
commitc51a57fb320ee3c28bea9ee223decfdd601e7e60 (patch)
treea7dd516b0bbe14c113bc353044f9b58d0fe1a660 /Kernel
parent895e874eb482daa14f4cd75afbb1fca6021fd09d (diff)
downloadserenity-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.cpp55
-rw-r--r--Kernel/Devices/SB16.h8
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;
};
-
}