mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 04:29:30 -10:00
Kernel/aarch64: Add a very basic driver for the BCM2712 GPIO controllers
Next to the GPIO controller in the RP1, the Pi 5 also has two GPIO controllers in the SoC itself. The driver is named after their devicetree compatible string "brcm,brcmstb-gpio".
This commit is contained in:
1 parent
e1fd729c8b
commit
2986c7d6b6
3 files changed
+123
No files matched your search
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Sönke Holz <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Error.h>
|
||||
#include <AK/FixedArray.h>
|
||||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <Kernel/Arch/aarch64/RPi/BroadcomSTBGPIOController.h>
|
||||
|
||||
namespace Kernel::RPi {
|
||||
|
||||
struct BroadcomSTBGPIOController::BankRegisters {
|
||||
u32 _;
|
||||
u32 pin_levels;
|
||||
u32 pin_directions;
|
||||
u32 _[5];
|
||||
};
|
||||
|
||||
static_assert(AssertSize<BroadcomSTBGPIOController::BankRegisters, 8 * sizeof(u32)>());
|
||||
|
||||
ErrorOr<NonnullOwnPtr<BroadcomSTBGPIOController>> Kernel::RPi::BroadcomSTBGPIOController::create(PhysicalAddress paddr, Span<size_t> bank_pin_counts)
|
||||
{
|
||||
for (auto bank_pin_count : bank_pin_counts) {
|
||||
if (bank_pin_count > 32) {
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
auto bank_count = bank_pin_counts.size();
|
||||
auto registers = TRY(Memory::map_typed_array<BankRegisters volatile>(paddr, bank_count, Memory::Region::Access::ReadWrite));
|
||||
|
||||
auto bank_pin_counts_array = TRY(FixedArray<size_t>::create(bank_pin_counts));
|
||||
return adopt_nonnull_own_or_enomem(new (nothrow) BroadcomSTBGPIOController(move(registers), move(bank_pin_counts_array)));
|
||||
}
|
||||
|
||||
ErrorOr<void> Kernel::RPi::BroadcomSTBGPIOController::set_pin_output_level(u32 pin_number, LogicLevel level)
|
||||
{
|
||||
auto bank_number = pin_number / 32;
|
||||
auto pin_number_in_bank = pin_number % 32;
|
||||
|
||||
if (bank_number >= m_bank_pin_counts.size())
|
||||
return EINVAL;
|
||||
|
||||
if (pin_number_in_bank >= m_bank_pin_counts[bank_number])
|
||||
return EINVAL;
|
||||
|
||||
if (level == LogicLevel::High)
|
||||
m_bank_registers[bank_number].pin_levels |= 1u << pin_number_in_bank;
|
||||
else
|
||||
m_bank_registers[bank_number].pin_levels &= ~(1u << pin_number_in_bank);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> Kernel::RPi::BroadcomSTBGPIOController::set_pin_direction(u32 pin_number, PinDirection direction)
|
||||
{
|
||||
auto bank_number = pin_number / 32;
|
||||
auto pin_number_in_bank = pin_number % 32;
|
||||
|
||||
if (bank_number >= m_bank_pin_counts.size())
|
||||
return EINVAL;
|
||||
|
||||
if (pin_number_in_bank >= m_bank_pin_counts[bank_number])
|
||||
return EINVAL;
|
||||
|
||||
if (direction == PinDirection::Input)
|
||||
m_bank_registers[bank_number].pin_directions |= 1u << pin_number_in_bank;
|
||||
else
|
||||
m_bank_registers[bank_number].pin_directions &= ~(1u << pin_number_in_bank);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
BroadcomSTBGPIOController::BroadcomSTBGPIOController(Memory::TypedMapping<BankRegisters volatile[]> bank_registers, FixedArray<size_t> bank_pin_counts)
|
||||
: m_bank_registers(move(bank_registers))
|
||||
, m_bank_pin_counts(move(bank_pin_counts))
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Sönke Holz <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Forward.h>
|
||||
#include <Kernel/Memory/TypedMapping.h>
|
||||
|
||||
namespace Kernel::RPi {
|
||||
|
||||
class BroadcomSTBGPIOController {
|
||||
public:
|
||||
static ErrorOr<NonnullOwnPtr<BroadcomSTBGPIOController>> create(PhysicalAddress, Span<size_t> bank_pin_counts);
|
||||
|
||||
enum class LogicLevel : bool {
|
||||
Low = 0,
|
||||
High = 1,
|
||||
};
|
||||
|
||||
enum class PinDirection : u8 {
|
||||
Input = 0,
|
||||
Output = 1,
|
||||
};
|
||||
|
||||
ErrorOr<void> set_pin_output_level(u32 pin_number, LogicLevel);
|
||||
ErrorOr<void> set_pin_direction(u32 pin_number, PinDirection);
|
||||
|
||||
struct BankRegisters;
|
||||
|
||||
private:
|
||||
BroadcomSTBGPIOController(Memory::TypedMapping<BankRegisters volatile[]>, FixedArray<size_t> bank_pin_counts);
|
||||
|
||||
Memory::TypedMapping<BankRegisters volatile[]> m_bank_registers;
|
||||
FixedArray<size_t> m_bank_pin_counts;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -490,6 +490,7 @@ elseif("${SERENITY_ARCH}" STREQUAL "aarch64")
|
||||
Arch/aarch64/RPi/RP1/RP1.cpp
|
||||
Arch/aarch64/RPi/RP1/xHCI.cpp
|
||||
Arch/aarch64/RPi/SDHostController.cpp
|
||||
Arch/aarch64/RPi/BroadcomSTBGPIOController.cpp
|
||||
Arch/aarch64/RPi/Timer.cpp
|
||||
Arch/aarch64/RPi/V3D/DeviceNode.cpp
|
||||
Arch/aarch64/RPi/V3D/PageTable.cpp
|
||||
|
||||
Reference in new issue
Block a user