From 4b4f05b4a68c3e6eee2c536941b4e36b521b132f Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 30 Oct 2020 23:57:21 -0700 Subject: [PATCH] gpio: add (most of) driver framework for boot sysmodule usage --- .../libstratosphere/include/stratosphere.hpp | 1 + .../impl/ams_system_thread_definitions.hpp | 3 + .../ddsf/ddsf_event_handler_manager.hpp | 2 +- .../stratosphere/ddsf/ddsf_i_castable.hpp | 4 +- .../stratosphere/ddsf/impl/ddsf_type_tag.hpp | 2 +- .../include/stratosphere/gpio.hpp | 1 + .../board/nintendo_nx/gpio_driver_api.hpp | 28 ++ .../gpio/driver/gpio_driver_client_api.hpp | 26 ++ .../gpio/driver/gpio_driver_service_api.hpp | 35 ++ .../gpio/driver/gpio_i_gpio_driver.hpp | 75 ++++ .../stratosphere/gpio/driver/gpio_pad.hpp | 61 +++ .../gpio/driver/gpio_select_driver_api.hpp | 38 ++ .../stratosphere/gpio/gpio_pad_api.hpp | 1 + .../gpio/gpio_pad_name.board.nintendo_nx.hpp | 393 +++++++++++++++++- .../include/stratosphere/gpio/gpio_types.hpp | 5 + .../include/stratosphere/wec.hpp | 10 +- .../include/stratosphere/wec/wec_api.hpp | 30 ++ .../include/stratosphere/wec/wec_types.hpp | 37 ++ .../wec/wec_wake_event.board.nintendo_nx.hpp | 86 ++++ .../source/ddsf/ddsf_event_handler.cpp | 1 - .../board/nintendo_nx/gpio_driver_api.cpp | 88 ++++ .../nintendo_nx/impl/gpio_driver_impl.cpp | 277 ++++++++++++ .../nintendo_nx/impl/gpio_driver_impl.hpp | 101 +++++ .../nintendo_nx/impl/gpio_initial_config.cpp | 172 ++++++++ .../nintendo_nx/impl/gpio_initial_config.hpp | 30 ++ .../impl/gpio_initial_config_calcio.inc | 54 +++ .../impl/gpio_initial_config_five.inc | 70 ++++ .../impl/gpio_initial_config_hoag.inc | 82 ++++ .../impl/gpio_initial_config_icosa.inc | 82 ++++ .../impl/gpio_initial_config_iowa.inc | 81 ++++ .../gpio_initial_wake_pin_config_calcio.inc | 80 ++++ .../gpio_initial_wake_pin_config_five.inc | 80 ++++ .../gpio_initial_wake_pin_config_hoag.inc | 80 ++++ .../gpio_initial_wake_pin_config_icosa.inc | 80 ++++ .../gpio_initial_wake_pin_config_iowa.inc | 80 ++++ .../gpio_internal_pad_map_combination.inc | 112 +++++ .../impl/gpio_register_accessor.hpp | 135 ++++++ .../nintendo_nx/impl/gpio_suspend_handler.cpp | 69 +++ .../nintendo_nx/impl/gpio_suspend_handler.hpp | 89 ++++ .../board/nintendo_nx/impl/gpio_tegra_pad.hpp | 377 +++++++++++++++++ .../nintendo_nx/impl/gpio_wake_pin_config.hpp | 13 +- .../gpio/driver/gpio_driver_client_api.cpp | 30 ++ .../gpio/driver/gpio_driver_service_api.cpp | 54 +++ .../gpio/driver/impl/gpio_driver_core.cpp | 149 +++++++ .../gpio/driver/impl/gpio_driver_core.hpp | 36 ++ .../libstratosphere/source/spl/spl_api.cpp | 2 +- .../boot/source/boot_charger_driver.cpp | 4 +- .../boot/source/boot_charger_driver.hpp | 6 +- stratosphere/boot/source/boot_fan_enable.cpp | 16 +- stratosphere/boot/source/boot_main.cpp | 69 ++- .../gpio/gpio_initial_configuration.cpp | 102 ----- .../gpio_initial_configuration_calcio.inc | 51 --- .../gpio_initial_configuration_copper.inc | 64 --- .../gpio/gpio_initial_configuration_hoag.inc | 79 ---- .../gpio/gpio_initial_configuration_icosa.inc | 145 ------- .../gpio/gpio_initial_configuration_iowa.inc | 79 ---- stratosphere/boot/source/gpio/gpio_map.inc | 132 ------ stratosphere/boot/source/gpio/gpio_utils.cpp | 127 ------ 58 files changed, 3380 insertions(+), 836 deletions(-) create mode 100644 libraries/libstratosphere/include/stratosphere/gpio/driver/board/nintendo_nx/gpio_driver_api.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_driver_client_api.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_driver_service_api.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_i_gpio_driver.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_pad.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_select_driver_api.hpp rename stratosphere/boot/source/gpio/gpio_initial_configuration.hpp => libraries/libstratosphere/include/stratosphere/wec.hpp (84%) create mode 100644 libraries/libstratosphere/include/stratosphere/wec/wec_api.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/wec/wec_types.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/wec/wec_wake_event.board.nintendo_nx.hpp create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/gpio_driver_api.cpp create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_driver_impl.cpp create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_driver_impl.hpp create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config.cpp create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config.hpp create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_calcio.inc create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_five.inc create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_hoag.inc create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_icosa.inc create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_iowa.inc create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_calcio.inc create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_five.inc create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_hoag.inc create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_icosa.inc create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_iowa.inc create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_internal_pad_map_combination.inc create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_register_accessor.hpp create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_suspend_handler.cpp create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_suspend_handler.hpp create mode 100644 libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_tegra_pad.hpp rename stratosphere/boot/source/gpio/gpio_utils.hpp => libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_wake_pin_config.hpp (75%) create mode 100644 libraries/libstratosphere/source/gpio/driver/gpio_driver_client_api.cpp create mode 100644 libraries/libstratosphere/source/gpio/driver/gpio_driver_service_api.cpp create mode 100644 libraries/libstratosphere/source/gpio/driver/impl/gpio_driver_core.cpp create mode 100644 libraries/libstratosphere/source/gpio/driver/impl/gpio_driver_core.hpp delete mode 100644 stratosphere/boot/source/gpio/gpio_initial_configuration.cpp delete mode 100644 stratosphere/boot/source/gpio/gpio_initial_configuration_calcio.inc delete mode 100644 stratosphere/boot/source/gpio/gpio_initial_configuration_copper.inc delete mode 100644 stratosphere/boot/source/gpio/gpio_initial_configuration_hoag.inc delete mode 100644 stratosphere/boot/source/gpio/gpio_initial_configuration_icosa.inc delete mode 100644 stratosphere/boot/source/gpio/gpio_initial_configuration_iowa.inc delete mode 100644 stratosphere/boot/source/gpio/gpio_map.inc delete mode 100644 stratosphere/boot/source/gpio/gpio_utils.cpp diff --git a/libraries/libstratosphere/include/stratosphere.hpp b/libraries/libstratosphere/include/stratosphere.hpp index a2af48d3a..b3db46b41 100644 --- a/libraries/libstratosphere/include/stratosphere.hpp +++ b/libraries/libstratosphere/include/stratosphere.hpp @@ -69,6 +69,7 @@ #include #include #include +#include /* Include FS last. */ #include diff --git a/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp b/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp index 837598518..5b755098e 100644 --- a/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp +++ b/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp @@ -89,6 +89,9 @@ namespace ams::impl { /* ro. */ AMS_DEFINE_SYSTEM_THREAD(16, ro, Main); + /* gpio. */ + AMS_DEFINE_SYSTEM_THREAD(-12, gpio, InterruptHandler); + /* bpc. */ AMS_DEFINE_SYSTEM_THREAD(4, bpc, IpcServer); diff --git a/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_event_handler_manager.hpp b/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_event_handler_manager.hpp index 1b1dca9b1..0226b18b7 100644 --- a/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_event_handler_manager.hpp +++ b/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_event_handler_manager.hpp @@ -48,7 +48,7 @@ namespace ams::ddsf { loop_control_command_params(), loop_control_command_done_event(os::EventClearMode_AutoClear), loop_control_lock() { - /* ... */ + this->Initialize(); } ~EventHandlerManager() { diff --git a/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_castable.hpp b/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_castable.hpp index 6707f5230..adec2cc5e 100644 --- a/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_castable.hpp +++ b/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_castable.hpp @@ -24,14 +24,14 @@ namespace ams::ddsf { #define AMS_DDSF_CASTABLE_TRAITS(__CLASS__, __BASE__) \ public: \ - static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag(#__CLASS__, __BASE__::s_ams_ddsf_castable_type_tag); \ + static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag{#__CLASS__, __BASE__::s_ams_ddsf_castable_type_tag}; \ constexpr virtual const ::ams::ddsf::impl::TypeTag &GetTypeTag() const override { return s_ams_ddsf_castable_type_tag; } #else #define AMS_DDSF_CASTABLE_TRAITS(__CLASS__, __BASE__) \ public: \ - static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag(__BASE__::s_ams_ddsf_castable_type_tag); \ + static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag{__BASE__::s_ams_ddsf_castable_type_tag}; \ constexpr virtual const ::ams::ddsf::impl::TypeTag &GetTypeTag() const override { return s_ams_ddsf_castable_type_tag; } #endif diff --git a/libraries/libstratosphere/include/stratosphere/ddsf/impl/ddsf_type_tag.hpp b/libraries/libstratosphere/include/stratosphere/ddsf/impl/ddsf_type_tag.hpp index a5b5371db..4d91ac04c 100644 --- a/libraries/libstratosphere/include/stratosphere/ddsf/impl/ddsf_type_tag.hpp +++ b/libraries/libstratosphere/include/stratosphere/ddsf/impl/ddsf_type_tag.hpp @@ -23,7 +23,7 @@ namespace ams::ddsf::impl { #define AMS_DDSF_CASTABLE_ROOT_TRAITS(__CLASS__) \ public: \ - static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag(#__CLASS__); \ + static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag{#__CLASS__}; \ constexpr virtual const ::ams::ddsf::impl::TypeTag &GetTypeTag() const override { return s_ams_ddsf_castable_type_tag; } #else diff --git a/libraries/libstratosphere/include/stratosphere/gpio.hpp b/libraries/libstratosphere/include/stratosphere/gpio.hpp index 02175345f..e82c2336c 100644 --- a/libraries/libstratosphere/include/stratosphere/gpio.hpp +++ b/libraries/libstratosphere/include/stratosphere/gpio.hpp @@ -20,3 +20,4 @@ #include #include #include +#include diff --git a/libraries/libstratosphere/include/stratosphere/gpio/driver/board/nintendo_nx/gpio_driver_api.hpp b/libraries/libstratosphere/include/stratosphere/gpio/driver/board/nintendo_nx/gpio_driver_api.hpp new file mode 100644 index 000000000..4245007bc --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/gpio/driver/board/nintendo_nx/gpio_driver_api.hpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include + +namespace ams::gpio::driver::board::nintendo_nx { + + void Initialize(bool enable_interrupt_handlers); + + void SetInitialGpioConfig(); + void SetInitialWakePinConfig(); + +} diff --git a/libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_driver_client_api.hpp b/libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_driver_client_api.hpp new file mode 100644 index 000000000..54e76211e --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_driver_client_api.hpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include + +namespace ams::gpio::driver { + + void Initialize(); + void Finalize(); + +} diff --git a/libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_driver_service_api.hpp b/libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_driver_service_api.hpp new file mode 100644 index 000000000..39f62270b --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_driver_service_api.hpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include + +namespace ams::gpio::driver { + + void RegisterDriver(IGpioDriver *driver); + void UnregisterDriver(IGpioDriver *driver); + + Result RegisterDeviceCode(DeviceCode device_code, Pad *pad); + bool UnregisterDeviceCode(DeviceCode device_code); + + void RegisterInterruptHandler(ddsf::IEventHandler *handler); + void UnregisterInterruptHandler(ddsf::IEventHandler *handler); + + void SetInitialGpioConfig(); + void SetInitialWakePinConfig(); + +} diff --git a/libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_i_gpio_driver.hpp b/libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_i_gpio_driver.hpp new file mode 100644 index 000000000..e9e1ae892 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_i_gpio_driver.hpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include + +namespace ams::gpio::driver { + + class Pad; + + class IGpioDriver : public ::ams::ddsf::IDriver { + NON_COPYABLE(IGpioDriver); + NON_MOVEABLE(IGpioDriver); + AMS_DDSF_CASTABLE_TRAITS(ams::gpio::IGpioDriver, ::ams::ddsf::IDriver); + public: + IGpioDriver() : IDriver() { /* ... */ } + virtual ~IGpioDriver() { /* ... */ } + + virtual void InitializeDriver() = 0; + virtual void FinalizeDriver() = 0; + + virtual Result InitializePad(Pad *pad) = 0; + virtual void FinalizePad(Pad *pad) = 0; + + virtual Result GetDirection(Direction *out, Pad *pad) const = 0; + virtual Result SetDirection(Pad *pad, Direction direction) = 0; + + virtual Result GetValue(GpioValue *out, Pad *pad) const = 0; + virtual Result SetValue(Pad *pad, GpioValue value) = 0; + + virtual Result GetInterruptMode(InterruptMode *out, Pad *pad) const = 0; + virtual Result SetInterruptMode(Pad *pad, InterruptMode mode) = 0; + + virtual Result SetInterruptEnabled(Pad *pad, bool en) = 0; + + virtual Result GetInterruptStatus(InterruptStatus *out, Pad *pad) = 0; + virtual Result ClearInterruptStatus(Pad *pad) = 0; + + virtual os::SdkMutex &GetInterruptControlMutex(const Pad &pad) const = 0; + + virtual Result GetDebounceEnabled(bool *out, Pad *pad) const = 0; + virtual Result SetDebounceEnabled(Pad *pad, bool en) = 0; + + virtual Result GetDebounceTime(s32 *out_ms, Pad *pad) const = 0; + virtual Result SetDebounceTime(Pad *pad, s32 ms) = 0; + + virtual Result GetUnknown22(u32 *out) = 0; + virtual void Unknown23(); + + virtual Result SetValueForSleepState(Pad *pad, GpioValue value) = 0; + virtual Result IsWakeEventActive(bool *out, Pad *pad) const = 0; + virtual Result SetWakeEventActiveFlagSetForDebug(Pad *pad, bool en) = 0; + virtual Result SetWakePinDebugMode(WakePinDebugMode mode) = 0; + + virtual Result Suspend() = 0; + virtual Result SuspendLow() = 0; + virtual Result Resume() = 0; + virtual Result ResumeLow() = 0; + }; + +} diff --git a/libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_pad.hpp b/libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_pad.hpp new file mode 100644 index 000000000..b724ec039 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_pad.hpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include + +namespace ams::gpio::driver { + + class Pad : public ::ams::ddsf::IDevice { + NON_COPYABLE(Pad); + NON_MOVEABLE(Pad); + AMS_DDSF_CASTABLE_TRAITS(ams::gpio::Pad, ::ams::ddsf::IDevice); + private: + int pad_number; + bool is_interrupt_enabled; + public: + explicit Pad(int pad) : IDevice(true), pad_number(pad), is_interrupt_enabled(false) { /* ... */ } + + Pad() : Pad(0) { /* ... */ } + + virtual ~Pad() { /* ... */ } + + int GetPadNumber() const { + return this->pad_number; + } + + void SetPadNumber(int p) { + this->pad_number = p; + } + + bool IsInterruptEnabled() const { + return this->is_interrupt_enabled; + } + + void SetInterruptEnabled(bool en) { + this->is_interrupt_enabled = en; + } + + bool IsInterruptRequiredForDriver() const { + return this->IsInterruptEnabled() && this->IsAnySessionBoundToInterrupt(); + } + + bool IsAnySessionBoundToInterrupt() const; + void SignalInterruptBoundEvent(); + }; + +} diff --git a/libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_select_driver_api.hpp b/libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_select_driver_api.hpp new file mode 100644 index 000000000..602571623 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/gpio/driver/gpio_select_driver_api.hpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include +#include +#include + +#if defined(ATMOSPHERE_BOARD_NINTENDO_NX) + + #include + + namespace ams::gpio::driver::board { + + using namespace ams::gpio::driver::board::nintendo_nx; + + } + +#else + + #error "Unknown board for ams::gpio::driver::" + +#endif + diff --git a/libraries/libstratosphere/include/stratosphere/gpio/gpio_pad_api.hpp b/libraries/libstratosphere/include/stratosphere/gpio/gpio_pad_api.hpp index a02d34884..600de33ed 100644 --- a/libraries/libstratosphere/include/stratosphere/gpio/gpio_pad_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/gpio/gpio_pad_api.hpp @@ -18,6 +18,7 @@ #include #include #include +#include namespace ams::gpio { diff --git a/libraries/libstratosphere/include/stratosphere/gpio/gpio_pad_name.board.nintendo_nx.hpp b/libraries/libstratosphere/include/stratosphere/gpio/gpio_pad_name.board.nintendo_nx.hpp index c1c816c95..98208c5f2 100644 --- a/libraries/libstratosphere/include/stratosphere/gpio/gpio_pad_name.board.nintendo_nx.hpp +++ b/libraries/libstratosphere/include/stratosphere/gpio/gpio_pad_name.board.nintendo_nx.hpp @@ -20,34 +20,395 @@ namespace ams::gpio { enum GpioPadName : u32 { - GpioPadName_CodecLdoEnTemp = 1, - GpioPadName_ButtonVolUp = 25, - GpioPadName_ButtonVolDn = 26, - GpioPadName_SdCd = 56, + GpioPadName_CodecLdoEnTemp = 1, + GpioPadName_PowSdEn = 2, + GpioPadName_BtRst = 3, + GpioPadName_RamCode3 = 4, + GpioPadName_GameCardReset = 5, + GpioPadName_CodecAlert = 6, + GpioPadName_PowGc = 7, + GpioPadName_DebugControllerDet = 8, + GpioPadName_BattChgStatus = 9, + GpioPadName_BattChgEnableN = 10, + GpioPadName_FanTach = 11, + GpioPadName_ExtconDetS = 12, + GpioPadName_Vdd50AEn = 13, + GpioPadName_SdevCoaxSel1 = 14, + GpioPadName_GameCardCd = 15, + GpioPadName_ProdType0 = 16, + GpioPadName_ProdType1 = 17, + GpioPadName_ProdType2 = 18, + GpioPadName_ProdType3 = 19, + GpioPadName_TempAlert = 20, + GpioPadName_CodecHpDetIrq = 21, + GpioPadName_MotionInt = 22, + GpioPadName_TpIrq = 23, + GpioPadName_ButtonSleep2 = 24, + GpioPadName_ButtonVolUp = 25, + GpioPadName_ButtonVolDn = 26, + GpioPadName_BattMgicIrq = 27, + GpioPadName_RecoveryKey = 28, + GpioPadName_PowLcdBlEn = 29, + GpioPadName_LcdReset = 30, + GpioPadName_PdVconnEn = 31, + GpioPadName_PdRstN = 32, + GpioPadName_Bq24190Irq = 33, + GpioPadName_SdevCoaxSel0 = 34, + GpioPadName_SdWp = 35, + GpioPadName_TpReset = 36, + GpioPadName_BtGpio2 = 37, + GpioPadName_BtGpio3 = 38, + GpioPadName_BtGpio4 = 39, + GpioPadName_CradleIrq = 40, + GpioPadName_PowVcpuInt = 41, + GpioPadName_Max77621GpuInt = 42, + GpioPadName_ExtconChgU = 43, + GpioPadName_ExtconChgS = 44, + GpioPadName_WifiRfDisable = 45, + GpioPadName_WifiReset = 46, + GpioPadName_ApWakeBt = 47, + GpioPadName_BtWakeAp = 48, + GpioPadName_BtGpio5 = 49, + GpioPadName_PowLcdVddPEn = 50, + GpioPadName_PowLcdVddNEn = 51, + GpioPadName_ExtconDetU = 52, + GpioPadName_RamCode2 = 53, + GpioPadName_Vdd50BEn = 54, + GpioPadName_WifiWakeHost = 55, + GpioPadName_SdCd = 56, + GpioPadName_OtgFet1ForSdev = 57, + GpioPadName_OtgFet2ForSdev = 58, + GpioPadName_ExtConWakeU = 59, + GpioPadName_ExtConWakeS = 60, + GpioPadName_PmuIrq = 61, + GpioPadName_ExtUart2Cts = 62, + GpioPadName_ExtUart3Cts = 63, + GpioPadName_5VStepDownEn = 64, + GpioPadName_UsbSwitchB2Oc = 65, + GpioPadName_5VStepDownPg = 66, + GpioPadName_UsbSwitchAEn = 67, + GpioPadName_UsbSwitchAFlag = 68, + GpioPadName_UsbSwitchB3Oc = 69, + GpioPadName_UsbSwitchB3En = 70, + GpioPadName_UsbSwitchB2En = 71, + GpioPadName_Hdmi5VEn = 72, + GpioPadName_UsbSwitchB1En = 73, + GpioPadName_HdmiPdTrEn = 74, + GpioPadName_FanEn = 75, + GpioPadName_UsbSwitchB1Oc = 76, + GpioPadName_PwmFan = 77, + GpioPadName_HdmiHpd = 78, + GpioPadName_Max77812Irq = 79, + GpioPadName_Debug0 = 80, + GpioPadName_Debug1 = 81, + GpioPadName_Debug2 = 82, + GpioPadName_Debug3 = 83, + GpioPadName_NfcIrq = 84, + GpioPadName_NfcRst = 85, + GpioPadName_McuIrq = 86, + GpioPadName_McuBoot = 87, + GpioPadName_McuRst = 88, + GpioPadName_Vdd5V3En = 89, + GpioPadName_McuPor = 90, + GpioPadName_LcdGpio1 = 91, + GpioPadName_NfcEn = 92, }; /* TODO: Better place for this? */ - constexpr inline const DeviceCode DeviceCode_CodecLdoEnTemp = 0x33000002; - constexpr inline const DeviceCode DeviceCode_ButtonVolUp = 0x35000002; - constexpr inline const DeviceCode DeviceCode_ButtonVolDn = 0x35000003; - constexpr inline const DeviceCode DeviceCode_SdCd = 0x3C000002; + constexpr inline const DeviceCode DeviceCode_CodecLdoEnTemp = 0x33000002; + constexpr inline const DeviceCode DeviceCode_PowSdEn = 0x3C000001; + constexpr inline const DeviceCode DeviceCode_BtRst = 0x37000002; + constexpr inline const DeviceCode DeviceCode_RamCode3 = 0xC9000402; + constexpr inline const DeviceCode DeviceCode_GameCardReset = 0x3C000402; + constexpr inline const DeviceCode DeviceCode_CodecAlert = 0x33000003; + constexpr inline const DeviceCode DeviceCode_PowGc = 0x3C000401; + constexpr inline const DeviceCode DeviceCode_DebugControllerDet = 0x350000CA; + constexpr inline const DeviceCode DeviceCode_BattChgStatus = 0x39000407; + constexpr inline const DeviceCode DeviceCode_BattChgEnableN = 0x39000003; + constexpr inline const DeviceCode DeviceCode_FanTach = 0x3D000002; + constexpr inline const DeviceCode DeviceCode_ExtconDetS = 0x3500040B; + constexpr inline const DeviceCode DeviceCode_Vdd50AEn = 0x39000401; + constexpr inline const DeviceCode DeviceCode_SdevCoaxSel1 = 0xCA000402; + constexpr inline const DeviceCode DeviceCode_GameCardCd = 0x3C000403; + constexpr inline const DeviceCode DeviceCode_ProdType0 = 0xC900040B; + constexpr inline const DeviceCode DeviceCode_ProdType1 = 0xC900040C; + constexpr inline const DeviceCode DeviceCode_ProdType2 = 0xC900040D; + constexpr inline const DeviceCode DeviceCode_ProdType3 = 0xC900040E; + constexpr inline const DeviceCode DeviceCode_TempAlert = 0x3E000002; + constexpr inline const DeviceCode DeviceCode_CodecHpDetIrq = 0x33000004; + constexpr inline const DeviceCode DeviceCode_MotionInt = 0x35000041; + constexpr inline const DeviceCode DeviceCode_TpIrq = 0x35000036; + constexpr inline const DeviceCode DeviceCode_ButtonSleep2 = 0x35000001; + constexpr inline const DeviceCode DeviceCode_ButtonVolUp = 0x35000002; + constexpr inline const DeviceCode DeviceCode_ButtonVolDn = 0x35000003; + constexpr inline const DeviceCode DeviceCode_BattMgicIrq = 0x39000034; + constexpr inline const DeviceCode DeviceCode_RecoveryKey = 0x35000004; + constexpr inline const DeviceCode DeviceCode_PowLcdBlEn = 0x3400003E; + constexpr inline const DeviceCode DeviceCode_LcdReset = 0x34000033; + constexpr inline const DeviceCode DeviceCode_PdVconnEn = 0x040000CC; + constexpr inline const DeviceCode DeviceCode_PdRstN = 0x040000CA; + constexpr inline const DeviceCode DeviceCode_Bq24190Irq = 0x39000002; + constexpr inline const DeviceCode DeviceCode_SdevCoaxSel0 = 0xCA000401; + constexpr inline const DeviceCode DeviceCode_SdWp = 0x3C000003; + constexpr inline const DeviceCode DeviceCode_TpReset = 0x35000035; + constexpr inline const DeviceCode DeviceCode_BtGpio2 = 0x37000401; + constexpr inline const DeviceCode DeviceCode_BtGpio3 = 0x37000402; + constexpr inline const DeviceCode DeviceCode_BtGpio4 = 0x37000403; + constexpr inline const DeviceCode DeviceCode_CradleIrq = 0x040000CB; + constexpr inline const DeviceCode DeviceCode_PowVcpuInt = 0x3E000003; + constexpr inline const DeviceCode DeviceCode_Max77621GpuInt = 0x3E000004; + constexpr inline const DeviceCode DeviceCode_ExtconChgU = 0x35000402; + constexpr inline const DeviceCode DeviceCode_ExtconChgS = 0x3500040C; + constexpr inline const DeviceCode DeviceCode_WifiRfDisable = 0x38000003; + constexpr inline const DeviceCode DeviceCode_WifiReset = 0x38000002; + constexpr inline const DeviceCode DeviceCode_ApWakeBt = 0x37000003; + constexpr inline const DeviceCode DeviceCode_BtWakeAp = 0x37000004; + constexpr inline const DeviceCode DeviceCode_BtGpio5 = 0x37000404; + constexpr inline const DeviceCode DeviceCode_PowLcdVddPEn = 0x34000034; + constexpr inline const DeviceCode DeviceCode_PowLcdVddNEn = 0x34000035; + constexpr inline const DeviceCode DeviceCode_ExtconDetU = 0x35000401; + constexpr inline const DeviceCode DeviceCode_RamCode2 = 0xC9000401; + constexpr inline const DeviceCode DeviceCode_Vdd50BEn = 0x39000402; + constexpr inline const DeviceCode DeviceCode_WifiWakeHost = 0x38000004; + constexpr inline const DeviceCode DeviceCode_SdCd = 0x3C000002; + constexpr inline const DeviceCode DeviceCode_OtgFet1ForSdev = 0x39000404; + constexpr inline const DeviceCode DeviceCode_OtgFet2ForSdev = 0x39000405; + constexpr inline const DeviceCode DeviceCode_ExtConWakeU = 0x35000403; + constexpr inline const DeviceCode DeviceCode_ExtConWakeS = 0x3500040D; + constexpr inline const DeviceCode DeviceCode_PmuIrq = 0x39000406; + constexpr inline const DeviceCode DeviceCode_ExtUart2Cts = 0x35000404; + constexpr inline const DeviceCode DeviceCode_ExtUart3Cts = 0x3500040E; + constexpr inline const DeviceCode DeviceCode_5VStepDownEn = 0x39000408; + constexpr inline const DeviceCode DeviceCode_UsbSwitchB2Oc = 0x04000401; + constexpr inline const DeviceCode DeviceCode_5VStepDownPg = 0x39000409; + constexpr inline const DeviceCode DeviceCode_UsbSwitchAEn = 0x04000402; + constexpr inline const DeviceCode DeviceCode_UsbSwitchAFlag = 0x04000403; + constexpr inline const DeviceCode DeviceCode_UsbSwitchB3Oc = 0x04000404; + constexpr inline const DeviceCode DeviceCode_UsbSwitchB3En = 0x04000405; + constexpr inline const DeviceCode DeviceCode_UsbSwitchB2En = 0x04000406; + constexpr inline const DeviceCode DeviceCode_Hdmi5VEn = 0x34000004; + constexpr inline const DeviceCode DeviceCode_UsbSwitchB1En = 0x04000407; + constexpr inline const DeviceCode DeviceCode_HdmiPdTrEn = 0x34000005; + constexpr inline const DeviceCode DeviceCode_FanEn = 0x3D000003; + constexpr inline const DeviceCode DeviceCode_UsbSwitchB1Oc = 0x04000408; + constexpr inline const DeviceCode DeviceCode_PwmFan = 0x3D000001; + constexpr inline const DeviceCode DeviceCode_HdmiHpd = 0x34000006; + constexpr inline const DeviceCode DeviceCode_Max77812Irq = 0x3E000003; + constexpr inline const DeviceCode DeviceCode_Debug0 = 0xCA000001; + constexpr inline const DeviceCode DeviceCode_Debug1 = 0xCA000002; + constexpr inline const DeviceCode DeviceCode_Debug2 = 0xCA000003; + constexpr inline const DeviceCode DeviceCode_Debug3 = 0xCA000004; + constexpr inline const DeviceCode DeviceCode_NfcIrq = 0x36000004; + constexpr inline const DeviceCode DeviceCode_NfcRst = 0x36000003; + constexpr inline const DeviceCode DeviceCode_McuIrq = 0x35000415; + constexpr inline const DeviceCode DeviceCode_McuBoot = 0x35000416; + constexpr inline const DeviceCode DeviceCode_McuRst = 0x35000417; + constexpr inline const DeviceCode DeviceCode_Vdd5V3En = 0x39000403; + constexpr inline const DeviceCode DeviceCode_McuPor = 0x35000418; + constexpr inline const DeviceCode DeviceCode_LcdGpio1 = 0x35000005; + constexpr inline const DeviceCode DeviceCode_NfcEn = 0x36000002; + constexpr inline const DeviceCode DeviceCode_ExtUart2Rts = 0x35000406; + constexpr inline const DeviceCode DeviceCode_ExtUart3Rts = 0x35000410; + constexpr inline const DeviceCode DeviceCode_GpioPortC7 = 0x3500041B; + constexpr inline const DeviceCode DeviceCode_GpioPortD0 = 0x3500041C; + constexpr inline const DeviceCode DeviceCode_GpioPortC5 = 0x3500041D; + constexpr inline const DeviceCode DeviceCode_GpioPortC6 = 0x3500041E; + constexpr inline const DeviceCode DeviceCode_GpioPortY7 = 0x35000065; + constexpr inline const DeviceCode DeviceCode_GpioPortF1 = 0x04000409; + constexpr inline const DeviceCode DeviceCode_GpioPortH0 = 0x34000401; constexpr inline GpioPadName ConvertToGpioPadName(DeviceCode dc) { switch (dc.GetInternalValue()) { - case DeviceCode_CodecLdoEnTemp.GetInternalValue(): return GpioPadName_CodecLdoEnTemp; - case DeviceCode_ButtonVolUp .GetInternalValue(): return GpioPadName_ButtonVolUp; - case DeviceCode_ButtonVolDn .GetInternalValue(): return GpioPadName_ButtonVolDn; - case DeviceCode_SdCd .GetInternalValue(): return GpioPadName_SdCd; + case DeviceCode_CodecLdoEnTemp .GetInternalValue(): return GpioPadName_CodecLdoEnTemp; + case DeviceCode_PowSdEn .GetInternalValue(): return GpioPadName_PowSdEn; + case DeviceCode_BtRst .GetInternalValue(): return GpioPadName_BtRst; + case DeviceCode_RamCode3 .GetInternalValue(): return GpioPadName_RamCode3; + case DeviceCode_GameCardReset .GetInternalValue(): return GpioPadName_GameCardReset; + case DeviceCode_CodecAlert .GetInternalValue(): return GpioPadName_CodecAlert; + case DeviceCode_PowGc .GetInternalValue(): return GpioPadName_PowGc; + case DeviceCode_DebugControllerDet.GetInternalValue(): return GpioPadName_DebugControllerDet; + case DeviceCode_BattChgStatus .GetInternalValue(): return GpioPadName_BattChgStatus; + case DeviceCode_BattChgEnableN .GetInternalValue(): return GpioPadName_BattChgEnableN; + case DeviceCode_FanTach .GetInternalValue(): return GpioPadName_FanTach; + case DeviceCode_ExtconDetS .GetInternalValue(): return GpioPadName_ExtconDetS; + case DeviceCode_Vdd50AEn .GetInternalValue(): return GpioPadName_Vdd50AEn; + case DeviceCode_SdevCoaxSel1 .GetInternalValue(): return GpioPadName_SdevCoaxSel1; + case DeviceCode_GameCardCd .GetInternalValue(): return GpioPadName_GameCardCd; + case DeviceCode_ProdType0 .GetInternalValue(): return GpioPadName_ProdType0; + case DeviceCode_ProdType1 .GetInternalValue(): return GpioPadName_ProdType1; + case DeviceCode_ProdType2 .GetInternalValue(): return GpioPadName_ProdType2; + case DeviceCode_ProdType3 .GetInternalValue(): return GpioPadName_ProdType3; + case DeviceCode_TempAlert .GetInternalValue(): return GpioPadName_TempAlert; + case DeviceCode_CodecHpDetIrq .GetInternalValue(): return GpioPadName_CodecHpDetIrq; + case DeviceCode_MotionInt .GetInternalValue(): return GpioPadName_MotionInt; + case DeviceCode_TpIrq .GetInternalValue(): return GpioPadName_TpIrq; + case DeviceCode_ButtonSleep2 .GetInternalValue(): return GpioPadName_ButtonSleep2; + case DeviceCode_ButtonVolUp .GetInternalValue(): return GpioPadName_ButtonVolUp; + case DeviceCode_ButtonVolDn .GetInternalValue(): return GpioPadName_ButtonVolDn; + case DeviceCode_BattMgicIrq .GetInternalValue(): return GpioPadName_BattMgicIrq; + case DeviceCode_RecoveryKey .GetInternalValue(): return GpioPadName_RecoveryKey; + case DeviceCode_PowLcdBlEn .GetInternalValue(): return GpioPadName_PowLcdBlEn; + case DeviceCode_LcdReset .GetInternalValue(): return GpioPadName_LcdReset; + case DeviceCode_PdVconnEn .GetInternalValue(): return GpioPadName_PdVconnEn; + case DeviceCode_PdRstN .GetInternalValue(): return GpioPadName_PdRstN; + case DeviceCode_Bq24190Irq .GetInternalValue(): return GpioPadName_Bq24190Irq; + case DeviceCode_SdevCoaxSel0 .GetInternalValue(): return GpioPadName_SdevCoaxSel0; + case DeviceCode_SdWp .GetInternalValue(): return GpioPadName_SdWp; + case DeviceCode_TpReset .GetInternalValue(): return GpioPadName_TpReset; + case DeviceCode_BtGpio2 .GetInternalValue(): return GpioPadName_BtGpio2; + case DeviceCode_BtGpio3 .GetInternalValue(): return GpioPadName_BtGpio3; + case DeviceCode_BtGpio4 .GetInternalValue(): return GpioPadName_BtGpio4; + case DeviceCode_CradleIrq .GetInternalValue(): return GpioPadName_CradleIrq; + /* case DeviceCode_PowVcpuInt .GetInternalValue(): return GpioPadName_PowVcpuInt; */ + case DeviceCode_Max77621GpuInt .GetInternalValue(): return GpioPadName_Max77621GpuInt; + case DeviceCode_ExtconChgU .GetInternalValue(): return GpioPadName_ExtconChgU; + case DeviceCode_ExtconChgS .GetInternalValue(): return GpioPadName_ExtconChgS; + case DeviceCode_WifiRfDisable .GetInternalValue(): return GpioPadName_WifiRfDisable; + case DeviceCode_WifiReset .GetInternalValue(): return GpioPadName_WifiReset; + case DeviceCode_ApWakeBt .GetInternalValue(): return GpioPadName_ApWakeBt; + case DeviceCode_BtWakeAp .GetInternalValue(): return GpioPadName_BtWakeAp; + case DeviceCode_BtGpio5 .GetInternalValue(): return GpioPadName_BtGpio5; + case DeviceCode_PowLcdVddPEn .GetInternalValue(): return GpioPadName_PowLcdVddPEn; + case DeviceCode_PowLcdVddNEn .GetInternalValue(): return GpioPadName_PowLcdVddNEn; + case DeviceCode_ExtconDetU .GetInternalValue(): return GpioPadName_ExtconDetU; + case DeviceCode_RamCode2 .GetInternalValue(): return GpioPadName_RamCode2; + case DeviceCode_Vdd50BEn .GetInternalValue(): return GpioPadName_Vdd50BEn; + case DeviceCode_WifiWakeHost .GetInternalValue(): return GpioPadName_WifiWakeHost; + case DeviceCode_SdCd .GetInternalValue(): return GpioPadName_SdCd; + case DeviceCode_OtgFet1ForSdev .GetInternalValue(): return GpioPadName_OtgFet1ForSdev; + case DeviceCode_OtgFet2ForSdev .GetInternalValue(): return GpioPadName_OtgFet2ForSdev; + case DeviceCode_ExtConWakeU .GetInternalValue(): return GpioPadName_ExtConWakeU; + case DeviceCode_ExtConWakeS .GetInternalValue(): return GpioPadName_ExtConWakeS; + case DeviceCode_PmuIrq .GetInternalValue(): return GpioPadName_PmuIrq; + case DeviceCode_ExtUart2Cts .GetInternalValue(): return GpioPadName_ExtUart2Cts; + case DeviceCode_ExtUart3Cts .GetInternalValue(): return GpioPadName_ExtUart3Cts; + case DeviceCode_5VStepDownEn .GetInternalValue(): return GpioPadName_5VStepDownEn; + case DeviceCode_UsbSwitchB2Oc .GetInternalValue(): return GpioPadName_UsbSwitchB2Oc; + case DeviceCode_5VStepDownPg .GetInternalValue(): return GpioPadName_5VStepDownPg; + case DeviceCode_UsbSwitchAEn .GetInternalValue(): return GpioPadName_UsbSwitchAEn; + case DeviceCode_UsbSwitchAFlag .GetInternalValue(): return GpioPadName_UsbSwitchAFlag; + case DeviceCode_UsbSwitchB3Oc .GetInternalValue(): return GpioPadName_UsbSwitchB3Oc; + case DeviceCode_UsbSwitchB3En .GetInternalValue(): return GpioPadName_UsbSwitchB3En; + case DeviceCode_UsbSwitchB2En .GetInternalValue(): return GpioPadName_UsbSwitchB2En; + case DeviceCode_Hdmi5VEn .GetInternalValue(): return GpioPadName_Hdmi5VEn; + case DeviceCode_UsbSwitchB1En .GetInternalValue(): return GpioPadName_UsbSwitchB1En; + case DeviceCode_HdmiPdTrEn .GetInternalValue(): return GpioPadName_HdmiPdTrEn; + case DeviceCode_FanEn .GetInternalValue(): return GpioPadName_FanEn; + case DeviceCode_UsbSwitchB1Oc .GetInternalValue(): return GpioPadName_UsbSwitchB1Oc; + case DeviceCode_PwmFan .GetInternalValue(): return GpioPadName_PwmFan; + case DeviceCode_HdmiHpd .GetInternalValue(): return GpioPadName_HdmiHpd; + case DeviceCode_Max77812Irq .GetInternalValue(): return GpioPadName_Max77812Irq; + case DeviceCode_Debug0 .GetInternalValue(): return GpioPadName_Debug0; + case DeviceCode_Debug1 .GetInternalValue(): return GpioPadName_Debug1; + case DeviceCode_Debug2 .GetInternalValue(): return GpioPadName_Debug2; + case DeviceCode_Debug3 .GetInternalValue(): return GpioPadName_Debug3; + case DeviceCode_NfcIrq .GetInternalValue(): return GpioPadName_NfcIrq; + case DeviceCode_NfcRst .GetInternalValue(): return GpioPadName_NfcRst; + case DeviceCode_McuIrq .GetInternalValue(): return GpioPadName_McuIrq; + case DeviceCode_McuBoot .GetInternalValue(): return GpioPadName_McuBoot; + case DeviceCode_McuRst .GetInternalValue(): return GpioPadName_McuRst; + case DeviceCode_Vdd5V3En .GetInternalValue(): return GpioPadName_Vdd5V3En; + case DeviceCode_McuPor .GetInternalValue(): return GpioPadName_McuPor; + case DeviceCode_LcdGpio1 .GetInternalValue(): return GpioPadName_LcdGpio1; + case DeviceCode_NfcEn .GetInternalValue(): return GpioPadName_NfcEn; AMS_UNREACHABLE_DEFAULT_CASE(); } } constexpr inline DeviceCode ConvertToDeviceCode(GpioPadName gpn) { switch (gpn) { - case GpioPadName_CodecLdoEnTemp: return DeviceCode_CodecLdoEnTemp; - case GpioPadName_ButtonVolUp: return DeviceCode_ButtonVolUp; - case GpioPadName_ButtonVolDn: return DeviceCode_ButtonVolDn; - case GpioPadName_SdCd: return DeviceCode_SdCd; + case GpioPadName_CodecLdoEnTemp: return DeviceCode_CodecLdoEnTemp; + case GpioPadName_PowSdEn: return DeviceCode_PowSdEn; + case GpioPadName_BtRst: return DeviceCode_BtRst; + case GpioPadName_RamCode3: return DeviceCode_RamCode3; + case GpioPadName_GameCardReset: return DeviceCode_GameCardReset; + case GpioPadName_CodecAlert: return DeviceCode_CodecAlert; + case GpioPadName_PowGc: return DeviceCode_PowGc; + case GpioPadName_DebugControllerDet: return DeviceCode_DebugControllerDet; + case GpioPadName_BattChgStatus: return DeviceCode_BattChgStatus; + case GpioPadName_BattChgEnableN: return DeviceCode_BattChgEnableN; + case GpioPadName_FanTach: return DeviceCode_FanTach; + case GpioPadName_ExtconDetS: return DeviceCode_ExtconDetS; + case GpioPadName_Vdd50AEn: return DeviceCode_Vdd50AEn; + case GpioPadName_SdevCoaxSel1: return DeviceCode_SdevCoaxSel1; + case GpioPadName_GameCardCd: return DeviceCode_GameCardCd; + case GpioPadName_ProdType0: return DeviceCode_ProdType0; + case GpioPadName_ProdType1: return DeviceCode_ProdType1; + case GpioPadName_ProdType2: return DeviceCode_ProdType2; + case GpioPadName_ProdType3: return DeviceCode_ProdType3; + case GpioPadName_TempAlert: return DeviceCode_TempAlert; + case GpioPadName_CodecHpDetIrq: return DeviceCode_CodecHpDetIrq; + case GpioPadName_MotionInt: return DeviceCode_MotionInt; + case GpioPadName_TpIrq: return DeviceCode_TpIrq; + case GpioPadName_ButtonSleep2: return DeviceCode_ButtonSleep2; + case GpioPadName_ButtonVolUp: return DeviceCode_ButtonVolUp; + case GpioPadName_ButtonVolDn: return DeviceCode_ButtonVolDn; + case GpioPadName_BattMgicIrq: return DeviceCode_BattMgicIrq; + case GpioPadName_RecoveryKey: return DeviceCode_RecoveryKey; + case GpioPadName_PowLcdBlEn: return DeviceCode_PowLcdBlEn; + case GpioPadName_LcdReset: return DeviceCode_LcdReset; + case GpioPadName_PdVconnEn: return DeviceCode_PdVconnEn; + case GpioPadName_PdRstN: return DeviceCode_PdRstN; + case GpioPadName_Bq24190Irq: return DeviceCode_Bq24190Irq; + case GpioPadName_SdevCoaxSel0: return DeviceCode_SdevCoaxSel0; + case GpioPadName_SdWp: return DeviceCode_SdWp; + case GpioPadName_TpReset: return DeviceCode_TpReset; + case GpioPadName_BtGpio2: return DeviceCode_BtGpio2; + case GpioPadName_BtGpio3: return DeviceCode_BtGpio3; + case GpioPadName_BtGpio4: return DeviceCode_BtGpio4; + case GpioPadName_CradleIrq: return DeviceCode_CradleIrq; + case GpioPadName_PowVcpuInt: return DeviceCode_PowVcpuInt; + case GpioPadName_Max77621GpuInt: return DeviceCode_Max77621GpuInt; + case GpioPadName_ExtconChgU: return DeviceCode_ExtconChgU; + case GpioPadName_ExtconChgS: return DeviceCode_ExtconChgS; + case GpioPadName_WifiRfDisable: return DeviceCode_WifiRfDisable; + case GpioPadName_WifiReset: return DeviceCode_WifiReset; + case GpioPadName_ApWakeBt: return DeviceCode_ApWakeBt; + case GpioPadName_BtWakeAp: return DeviceCode_BtWakeAp; + case GpioPadName_BtGpio5: return DeviceCode_BtGpio5; + case GpioPadName_PowLcdVddPEn: return DeviceCode_PowLcdVddPEn; + case GpioPadName_PowLcdVddNEn: return DeviceCode_PowLcdVddNEn; + case GpioPadName_ExtconDetU: return DeviceCode_ExtconDetU; + case GpioPadName_RamCode2: return DeviceCode_RamCode2; + case GpioPadName_Vdd50BEn: return DeviceCode_Vdd50BEn; + case GpioPadName_WifiWakeHost: return DeviceCode_WifiWakeHost; + case GpioPadName_SdCd: return DeviceCode_SdCd; + case GpioPadName_OtgFet1ForSdev: return DeviceCode_OtgFet1ForSdev; + case GpioPadName_OtgFet2ForSdev: return DeviceCode_OtgFet2ForSdev; + case GpioPadName_ExtConWakeU: return DeviceCode_ExtConWakeU; + case GpioPadName_ExtConWakeS: return DeviceCode_ExtConWakeS; + case GpioPadName_PmuIrq: return DeviceCode_PmuIrq; + case GpioPadName_ExtUart2Cts: return DeviceCode_ExtUart2Cts; + case GpioPadName_ExtUart3Cts: return DeviceCode_ExtUart3Cts; + case GpioPadName_5VStepDownEn: return DeviceCode_5VStepDownEn; + case GpioPadName_UsbSwitchB2Oc: return DeviceCode_UsbSwitchB2Oc; + case GpioPadName_5VStepDownPg: return DeviceCode_5VStepDownPg; + case GpioPadName_UsbSwitchAEn: return DeviceCode_UsbSwitchAEn; + case GpioPadName_UsbSwitchAFlag: return DeviceCode_UsbSwitchAFlag; + case GpioPadName_UsbSwitchB3Oc: return DeviceCode_UsbSwitchB3Oc; + case GpioPadName_UsbSwitchB3En: return DeviceCode_UsbSwitchB3En; + case GpioPadName_UsbSwitchB2En: return DeviceCode_UsbSwitchB2En; + case GpioPadName_Hdmi5VEn: return DeviceCode_Hdmi5VEn; + case GpioPadName_UsbSwitchB1En: return DeviceCode_UsbSwitchB1En; + case GpioPadName_HdmiPdTrEn: return DeviceCode_HdmiPdTrEn; + case GpioPadName_FanEn: return DeviceCode_FanEn; + case GpioPadName_UsbSwitchB1Oc: return DeviceCode_UsbSwitchB1Oc; + case GpioPadName_PwmFan: return DeviceCode_PwmFan; + case GpioPadName_HdmiHpd: return DeviceCode_HdmiHpd; + case GpioPadName_Max77812Irq: return DeviceCode_Max77812Irq; + case GpioPadName_Debug0: return DeviceCode_Debug0; + case GpioPadName_Debug1: return DeviceCode_Debug1; + case GpioPadName_Debug2: return DeviceCode_Debug2; + case GpioPadName_Debug3: return DeviceCode_Debug3; + case GpioPadName_NfcIrq: return DeviceCode_NfcIrq; + case GpioPadName_NfcRst: return DeviceCode_NfcRst; + case GpioPadName_McuIrq: return DeviceCode_McuIrq; + case GpioPadName_McuBoot: return DeviceCode_McuBoot; + case GpioPadName_McuRst: return DeviceCode_McuRst; + case GpioPadName_Vdd5V3En: return DeviceCode_Vdd5V3En; + case GpioPadName_McuPor: return DeviceCode_McuPor; + case GpioPadName_LcdGpio1: return DeviceCode_LcdGpio1; + case GpioPadName_NfcEn: return DeviceCode_NfcEn; AMS_UNREACHABLE_DEFAULT_CASE(); } } diff --git a/libraries/libstratosphere/include/stratosphere/gpio/gpio_types.hpp b/libraries/libstratosphere/include/stratosphere/gpio/gpio_types.hpp index 8d456c547..76f1768e5 100644 --- a/libraries/libstratosphere/include/stratosphere/gpio/gpio_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/gpio/gpio_types.hpp @@ -41,6 +41,11 @@ namespace ams::gpio { InterruptStatus_Active = 1, }; + enum WakePinDebugMode { + WakePinDebugMode_AutoImmediateWake = 1, + WakePinDebugMode_NoWake = 2, + }; + using WakeBitFlag = util::BitFlagSet<128>; } diff --git a/stratosphere/boot/source/gpio/gpio_initial_configuration.hpp b/libraries/libstratosphere/include/stratosphere/wec.hpp similarity index 84% rename from stratosphere/boot/source/gpio/gpio_initial_configuration.hpp rename to libraries/libstratosphere/include/stratosphere/wec.hpp index 0a1c5e65d..fb0cda14e 100644 --- a/stratosphere/boot/source/gpio/gpio_initial_configuration.hpp +++ b/libraries/libstratosphere/include/stratosphere/wec.hpp @@ -15,11 +15,5 @@ */ #pragma once -#include -#include - -namespace ams::boot::gpio { - - void SetInitialConfiguration(); - -} +#include +#include diff --git a/libraries/libstratosphere/include/stratosphere/wec/wec_api.hpp b/libraries/libstratosphere/include/stratosphere/wec/wec_api.hpp new file mode 100644 index 000000000..22b85f845 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/wec/wec_api.hpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include + +namespace ams::wec { + + void Initialize(); + void ClearWakeEvents(); + + void WecRestoreForExitSuspend(); + + void SetWakeEventLevel(wec::WakeEvent event, wec::WakeEventLevel level); + void SetWakeEventEnabled(wec::WakeEvent event, bool en); + +} diff --git a/libraries/libstratosphere/include/stratosphere/wec/wec_types.hpp b/libraries/libstratosphere/include/stratosphere/wec/wec_types.hpp new file mode 100644 index 000000000..7185a73b3 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/wec/wec_types.hpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +#if defined(ATMOSPHERE_BOARD_NINTENDO_NX) + + #include + +#else + + #error "Unknown board for ams::wec::WakeEvent" + +#endif + +namespace ams::wec { + + enum WakeEventLevel { + WakeEventLevel_Low = 0, + WakeEventLevel_High = 1, + WakeEventLevel_Auto = 2, + }; + +} diff --git a/libraries/libstratosphere/include/stratosphere/wec/wec_wake_event.board.nintendo_nx.hpp b/libraries/libstratosphere/include/stratosphere/wec/wec_wake_event.board.nintendo_nx.hpp new file mode 100644 index 000000000..afee37412 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/wec/wec_wake_event.board.nintendo_nx.hpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::wec { + + enum WakeEvent { + WakeEvent_PexWakeN = 0x00, + WakeEvent_GpioPortA6 = 0x01, + WakeEvent_QspiCsN = 0x02, + WakeEvent_Spi2Mosi = 0x03, + WakeEvent_ExtconDetS = 0x04, + WakeEvent_McuIrq = 0x05, + WakeEvent_Uart2Cts = 0x06, + WakeEvent_Uart3Cts = 0x07, + WakeEvent_WifiWakeAp = 0x08, + WakeEvent_AoTag2Pmc = 0x09, + WakeEvent_ExtconDetU = 0x0A, + WakeEvent_NfcInt = 0x0B, + WakeEvent_Gen1I2cSda = 0x0C, + WakeEvent_Gen2I2cSda = 0x0D, + WakeEvent_CradleIrq = 0x0E, + WakeEvent_GpioPortK6 = 0x0F, + WakeEvent_RtcIrq = 0x10, + WakeEvent_Sdmmc1Dat1 = 0x11, + WakeEvent_Sdmmc2Dat1 = 0x12, + WakeEvent_HdmiCec = 0x13, + WakeEvent_Gen3I2cSda = 0x14, + WakeEvent_GpioPortL1 = 0x15, + WakeEvent_Clk_32kOut = 0x16, + WakeEvent_PwrI2cSda = 0x17, + WakeEvent_ButtonPowerOn = 0x18, + WakeEvent_ButtonVolUp = 0x19, + WakeEvent_ButtonVolDown = 0x1A, + WakeEvent_ButtonSlideSw = 0x1B, + WakeEvent_ButtonHome = 0x1C, + /* ... */ + WakeEvent_AlsProxInt = 0x20, + WakeEvent_TempAlert = 0x21, + WakeEvent_Bq24190Irq = 0x22, + WakeEvent_SdCd = 0x23, + WakeEvent_GpioPortZ2 = 0x24, + /* ... */ + WakeEvent_Utmip0 = 0x27, + WakeEvent_Utmip1 = 0x28, + WakeEvent_Utmip2 = 0x29, + WakeEvent_Utmip3 = 0x2A, + WakeEvent_Uhsic = 0x2B, + WakeEvent_Wake2PmcXusbSystem = 0x2C, + WakeEvent_Sdmmc3Dat1 = 0x2D, + WakeEvent_Sdmmc4Dat1 = 0x2E, + WakeEvent_CamI2cScl = 0x2F, + WakeEvent_CamI2cSda = 0x30, + WakeEvent_GpioPortZ5 = 0x31, + WakeEvent_DpHpd0 = 0x32, + WakeEvent_PwrIntN = 0x33, + WakeEvent_BtWakeAp = 0x34, + WakeEvent_HdmiIntDpHpd = 0x35, + WakeEvent_UsbVbusEn0 = 0x36, + WakeEvent_UsbVbusEn1 = 0x37, + WakeEvent_LcdRst = 0x38, + WakeEvent_LcdGpio1 = 0x39, + WakeEvent_LcdGpio2 = 0x3A, + WakeEvent_Uart4Cts = 0x3B, + WakeEvent_ModemWakeAp = 0x3D, + WakeEvent_TouchInt = 0x3E, + WakeEvent_MotionInt = 0x3F, + }; + + constexpr inline WakeEvent WakeEvent_None = static_cast(-1); + +} diff --git a/libraries/libstratosphere/source/ddsf/ddsf_event_handler.cpp b/libraries/libstratosphere/source/ddsf/ddsf_event_handler.cpp index 7672011db..490d26f2e 100644 --- a/libraries/libstratosphere/source/ddsf/ddsf_event_handler.cpp +++ b/libraries/libstratosphere/source/ddsf/ddsf_event_handler.cpp @@ -38,7 +38,6 @@ namespace ams::ddsf { void EventHandlerManager::Initialize() { /* Check that we're not already initialized. */ - AMS_ASSERT(!this->is_initialized); if (this->is_initialized) { return; } diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/gpio_driver_api.cpp b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/gpio_driver_api.cpp new file mode 100644 index 000000000..513add686 --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/gpio_driver_api.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "impl/gpio_driver_impl.hpp" +#include "impl/gpio_initial_config.hpp" +#include "impl/gpio_tegra_pad.hpp" + +namespace ams::gpio::driver::board::nintendo_nx { + + namespace { + + ams::gpio::driver::board::nintendo_nx::impl::DriverImpl *g_driver_impl = nullptr; + + } + + void Initialize(bool enable_interrupt_handlers) { + /* Check that we haven't previously initialized. */ + AMS_ABORT_UNLESS(g_driver_impl == nullptr); + + /* Get the device driver subsystem framework memory resource. */ + auto *memory_resource = ddsf::GetMemoryResource(); + + /* Allocate a new driver. */ + auto *driver_storage = static_cast(memory_resource->Allocate(sizeof(*g_driver_impl))); + AMS_ABORT_UNLESS(driver_storage != nullptr); + + /* Construct the new driver. */ + g_driver_impl = new (driver_storage) ams::gpio::driver::board::nintendo_nx::impl::DriverImpl(impl::GpioRegistersPhysicalAddress, impl::GpioRegistersSize); + + /* Register the driver. */ + gpio::driver::RegisterDriver(g_driver_impl); + + /* Register interrupt handlers, if we should. */ + if (enable_interrupt_handlers) { + for (size_t i = 0; i < util::size(impl::InterruptNameTable); ++i) { + /* Allocate a handler. */ + impl::InterruptEventHandler *handler_storage = static_cast(memory_resource->Allocate(sizeof(impl::InterruptEventHandler))); + AMS_ABORT_UNLESS(handler_storage != nullptr); + + /* Initialize the handler. */ + impl::InterruptEventHandler *handler = new (handler_storage) impl::InterruptEventHandler; + handler->Initialize(g_driver_impl, impl::InterruptNameTable[i], static_cast(i)); + + /* Register the handler. */ + gpio::driver::RegisterInterruptHandler(handler); + } + } + + /* Create and register all pads. */ + for (const auto &entry : impl::PadMapCombinationList) { + /* Allocate a pad for our device. */ + impl::TegraPad *pad_storage = static_cast(memory_resource->Allocate(sizeof(impl::TegraPad))); + AMS_ABORT_UNLESS(pad_storage != nullptr); + + /* Create a pad for our device. */ + impl::TegraPad *pad = new (pad_storage) impl::TegraPad; + pad->SetParameters(entry.internal_number, impl::PadInfo{entry.wake_event}); + + /* Register the pad with our driver. */ + g_driver_impl->RegisterDevice(pad); + + /* Register the device code with our driver. */ + R_ABORT_UNLESS(gpio::driver::RegisterDeviceCode(entry.device_code, pad)); + } + } + + void SetInitialGpioConfig() { + return impl::SetInitialGpioConfig(); + } + + void SetInitialWakePinConfig() { + return impl::SetInitialWakePinConfig(); + } + +} diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_driver_impl.cpp b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_driver_impl.cpp new file mode 100644 index 000000000..bd9150d49 --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_driver_impl.cpp @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "gpio_driver_impl.hpp" +#include "gpio_register_accessor.hpp" + +namespace ams::gpio::driver::board::nintendo_nx::impl { + + DriverImpl::DriverImpl(dd::PhysicalAddress reg_paddr, size_t size) : gpio_physical_address(reg_paddr), gpio_virtual_address(), suspend_handler(this), interrupt_pad_list(), interrupt_control_mutex() { + /* Get the corresponding virtual address for our physical address. */ + this->gpio_virtual_address = dd::QueryIoMapping(reg_paddr, size); + AMS_ABORT_UNLESS(this->gpio_virtual_address != 0); + } + + void DriverImpl::InitializeDriver() { + /* Initialize our suspend handler. */ + this->suspend_handler.Initialize(this->gpio_virtual_address); + } + + void DriverImpl::FinalizeDriver() { + /* ... */ + } + + Result DriverImpl::InitializePad(Pad *pad) { + /* Validate arguments. */ + AMS_ASSERT(pad != nullptr); + + /* Convert the pad to an internal number. */ + const InternalGpioPadNumber pad_number = pad->GetPadNumber(); + + /* Configure the pad as GPIO by modifying the appropriate bit in CNF. */ + const uintptr_t pad_address = GetGpioRegisterAddress(this->gpio_virtual_address, GpioRegisterType_GPIO_CNF, pad_number); + const uintptr_t pad_index = ConvertInternalGpioPadNumberToBitIndex(pad_number); + SetMaskedBit(pad_address, pad_index, 1); + + /* Read the pad address to make sure our configuration takes. */ + reg::Read(pad_address); + + return ResultSuccess(); + } + + void DriverImpl::FinalizePad(Pad *pad) { + /* Validate arguments. */ + AMS_ASSERT(pad != nullptr); + + /* Nothing to do. */ + AMS_UNUSED(pad); + } + + Result DriverImpl::GetDirection(Direction *out, Pad *pad) const { + /* Validate arguments. */ + AMS_ASSERT(out != nullptr); + AMS_ASSERT(pad != nullptr); + + /* Convert the pad to an internal number. */ + const InternalGpioPadNumber pad_number = pad->GetPadNumber(); + + /* Get the pad direction by reading the appropriate bit in OE */ + const uintptr_t pad_address = GetGpioRegisterAddress(this->gpio_virtual_address, GpioRegisterType_GPIO_OE, pad_number); + const uintptr_t pad_index = ConvertInternalGpioPadNumberToBitIndex(pad_number); + + if (reg::Read(pad_address, 1u << pad_index) != 0) { + *out = Direction_Output; + } else { + *out = Direction_Input; + } + + return ResultSuccess(); + + } + + Result DriverImpl::SetDirection(Pad *pad, Direction direction) { + /* Validate arguments. */ + AMS_ASSERT(pad != nullptr); + + /* Convert the pad to an internal number. */ + const InternalGpioPadNumber pad_number = pad->GetPadNumber(); + + /* Configure the pad direction by modifying the appropriate bit in OE */ + const uintptr_t pad_address = GetGpioRegisterAddress(this->gpio_virtual_address, GpioRegisterType_GPIO_OE, pad_number); + const uintptr_t pad_index = ConvertInternalGpioPadNumberToBitIndex(pad_number); + SetMaskedBit(pad_address, pad_index, direction); + + /* Read the pad address to make sure our configuration takes. */ + reg::Read(pad_address); + + return ResultSuccess(); + } + + Result DriverImpl::GetValue(GpioValue *out, Pad *pad) const { + /* Validate arguments. */ + AMS_ASSERT(out != nullptr); + AMS_ASSERT(pad != nullptr); + + /* Convert the pad to an internal number. */ + const InternalGpioPadNumber pad_number = pad->GetPadNumber(); + + /* Get the pad value by reading the appropriate bit in IN */ + const uintptr_t pad_address = GetGpioRegisterAddress(this->gpio_virtual_address, GpioRegisterType_GPIO_IN, pad_number); + const uintptr_t pad_index = ConvertInternalGpioPadNumberToBitIndex(pad_number); + + if (reg::Read(pad_address, 1u << pad_index) != 0) { + *out = GpioValue_High; + } else { + *out = GpioValue_Low; + } + + return ResultSuccess(); + } + + Result DriverImpl::SetValue(Pad *pad, GpioValue value) { + /* Validate arguments. */ + AMS_ASSERT(pad != nullptr); + + /* Convert the pad to an internal number. */ + const InternalGpioPadNumber pad_number = pad->GetPadNumber(); + + /* Configure the pad value by modifying the appropriate bit in IN */ + const uintptr_t pad_address = GetGpioRegisterAddress(this->gpio_virtual_address, GpioRegisterType_GPIO_IN, pad_number); + const uintptr_t pad_index = ConvertInternalGpioPadNumberToBitIndex(pad_number); + SetMaskedBit(pad_address, pad_index, value); + + /* Read the pad address to make sure our configuration takes. */ + reg::Read(pad_address); + + return ResultSuccess(); + } + + Result DriverImpl::GetInterruptMode(InterruptMode *out, Pad *pad) const { + /* Validate arguments. */ + AMS_ASSERT(out != nullptr); + AMS_ASSERT(pad != nullptr); + + /* Convert the pad to an internal number. */ + const InternalGpioPadNumber pad_number = pad->GetPadNumber(); + + /* Get the pad mode by reading the appropriate bits in INT_LVL */ + const uintptr_t pad_address = GetGpioRegisterAddress(this->gpio_virtual_address, GpioRegisterType_GPIO_INT_LVL, pad_number); + const uintptr_t pad_index = ConvertInternalGpioPadNumberToBitIndex(pad_number); + + switch ((reg::Read(pad_address) >> pad_index) & InternalInterruptMode_Mask) { + case InternalInterruptMode_LowLevel: *out = InterruptMode_LowLevel; break; + case InternalInterruptMode_HighLevel: *out = InterruptMode_HighLevel; break; + case InternalInterruptMode_RisingEdge: *out = InterruptMode_RisingEdge; break; + case InternalInterruptMode_FallingEdge: *out = InterruptMode_FallingEdge; break; + case InternalInterruptMode_AnyEdge: *out = InterruptMode_AnyEdge; break; + AMS_UNREACHABLE_DEFAULT_CASE(); + } + + return ResultSuccess(); + } + + Result DriverImpl::SetInterruptMode(Pad *pad, InterruptMode mode) { + /* Validate arguments. */ + AMS_ASSERT(pad != nullptr); + + /* Convert the pad to an internal number. */ + const InternalGpioPadNumber pad_number = pad->GetPadNumber(); + + /* Configure the pad mode by modifying the appropriate bits in INT_LVL */ + const uintptr_t pad_address = GetGpioRegisterAddress(this->gpio_virtual_address, GpioRegisterType_GPIO_INT_LVL, pad_number); + const uintptr_t pad_index = ConvertInternalGpioPadNumberToBitIndex(pad_number); + + switch (mode) { + case InterruptMode_LowLevel: reg::ReadWrite(pad_address, InternalInterruptMode_LowLevel << pad_index, InternalInterruptMode_Mask << pad_index); break; + case InterruptMode_HighLevel: reg::ReadWrite(pad_address, InternalInterruptMode_HighLevel << pad_index, InternalInterruptMode_Mask << pad_index); break; + case InterruptMode_RisingEdge: reg::ReadWrite(pad_address, InternalInterruptMode_RisingEdge << pad_index, InternalInterruptMode_Mask << pad_index); break; + case InterruptMode_FallingEdge: reg::ReadWrite(pad_address, InternalInterruptMode_FallingEdge << pad_index, InternalInterruptMode_Mask << pad_index); break; + case InterruptMode_AnyEdge: reg::ReadWrite(pad_address, InternalInterruptMode_AnyEdge << pad_index, InternalInterruptMode_Mask << pad_index); break; + AMS_UNREACHABLE_DEFAULT_CASE(); + } + + /* Read the pad address to make sure our configuration takes. */ + reg::Read(pad_address); + + return ResultSuccess(); + } + + Result DriverImpl::SetInterruptEnabled(Pad *pad, bool en) { + /* TODO */ + AMS_ABORT(); + } + + Result DriverImpl::GetInterruptStatus(InterruptStatus *out, Pad *pad) { + /* TODO */ + AMS_ABORT(); + } + + Result DriverImpl::ClearInterruptStatus(Pad *pad) { + /* TODO */ + AMS_ABORT(); + } + + Result DriverImpl::GetDebounceEnabled(bool *out, Pad *pad) const { + /* TODO */ + AMS_ABORT(); + } + + Result DriverImpl::SetDebounceEnabled(Pad *pad, bool en) { + /* TODO */ + AMS_ABORT(); + } + + Result DriverImpl::GetDebounceTime(s32 *out_ms, Pad *pad) const { + /* TODO */ + AMS_ABORT(); + } + + Result DriverImpl::SetDebounceTime(Pad *pad, s32 ms) { + /* TODO */ + AMS_ABORT(); + } + + Result DriverImpl::GetUnknown22(u32 *out) { + /* TODO */ + AMS_ABORT(); + } + + void DriverImpl::Unknown23() { + /* TODO */ + AMS_ABORT(); + } + + Result DriverImpl::SetValueForSleepState(Pad *pad, GpioValue value) { + /* TODO */ + AMS_ABORT(); + } + + Result DriverImpl::IsWakeEventActive(bool *out, Pad *pad) const { + /* TODO */ + AMS_ABORT(); + } + + Result DriverImpl::SetWakeEventActiveFlagSetForDebug(Pad *pad, bool en) { + /* TODO */ + AMS_ABORT(); + } + + Result DriverImpl::SetWakePinDebugMode(WakePinDebugMode mode) { + /* TODO */ + AMS_ABORT(); + } + + Result DriverImpl::Suspend() { + /* TODO */ + AMS_ABORT(); + } + + Result DriverImpl::SuspendLow() { + /* TODO */ + AMS_ABORT(); + } + + Result DriverImpl::Resume() { + /* TODO */ + AMS_ABORT(); + } + + Result DriverImpl::ResumeLow() { + /* TODO */ + AMS_ABORT(); + } + +} diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_driver_impl.hpp b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_driver_impl.hpp new file mode 100644 index 000000000..cd1add92f --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_driver_impl.hpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +#include "gpio_tegra_pad.hpp" +#include "gpio_register_accessor.hpp" +#include "gpio_suspend_handler.hpp" + +namespace ams::gpio::driver::board::nintendo_nx::impl { + + class DriverImpl; + + class InterruptEventHandler : public ddsf::IEventHandler { + private: + DriverImpl *driver; + os::InterruptName interrupt_name; + os::InterruptEventType interrupt_event; + int port_number; + private: + void CheckAndHandleInterrupt(TegraPad *pad); + public: + InterruptEventHandler() : IEventHandler(), driver(nullptr), interrupt_name(), interrupt_event(), port_number() { /* ... */ } + + void Initialize(DriverImpl *driver, os::InterruptName intr, int port); + + virtual void HandleEvent() override; + }; + + class DriverImpl : public ::ams::gpio::driver::IGpioDriver { + NON_COPYABLE(DriverImpl); + NON_MOVEABLE(DriverImpl); + AMS_DDSF_CASTABLE_TRAITS(ams::gpio::driver::board::nintendo_nx::impl::DriverImpl, ::ams::gpio::driver::IGpioDriver); + private: + dd::PhysicalAddress gpio_physical_address; + uintptr_t gpio_virtual_address; + SuspendHandler suspend_handler; + TegraPad::List interrupt_pad_list; + mutable os::SdkMutex interrupt_control_mutex; + public: + DriverImpl(dd::PhysicalAddress reg_paddr, size_t size); + + virtual void InitializeDriver() override; + virtual void FinalizeDriver() override; + + virtual Result InitializePad(Pad *pad) override; + virtual void FinalizePad(Pad *pad) override; + + virtual Result GetDirection(Direction *out, Pad *pad) const override; + virtual Result SetDirection(Pad *pad, Direction direction) override; + + virtual Result GetValue(GpioValue *out, Pad *pad) const override; + virtual Result SetValue(Pad *pad, GpioValue value) override; + + virtual Result GetInterruptMode(InterruptMode *out, Pad *pad) const override; + virtual Result SetInterruptMode(Pad *pad, InterruptMode mode) override; + + virtual Result SetInterruptEnabled(Pad *pad, bool en) override; + + virtual Result GetInterruptStatus(InterruptStatus *out, Pad *pad) override; + virtual Result ClearInterruptStatus(Pad *pad) override; + + virtual os::SdkMutex &GetInterruptControlMutex(const Pad &pad) const override { + AMS_UNUSED(pad); + return this->interrupt_control_mutex; + } + + virtual Result GetDebounceEnabled(bool *out, Pad *pad) const override; + virtual Result SetDebounceEnabled(Pad *pad, bool en) override; + + virtual Result GetDebounceTime(s32 *out_ms, Pad *pad) const override; + virtual Result SetDebounceTime(Pad *pad, s32 ms) override; + + virtual Result GetUnknown22(u32 *out) override; + virtual void Unknown23() override; + + virtual Result SetValueForSleepState(Pad *pad, GpioValue value) override; + virtual Result IsWakeEventActive(bool *out, Pad *pad) const override; + virtual Result SetWakeEventActiveFlagSetForDebug(Pad *pad, bool en) override; + virtual Result SetWakePinDebugMode(WakePinDebugMode mode) override; + + virtual Result Suspend() override; + virtual Result SuspendLow() override; + virtual Result Resume() override; + virtual Result ResumeLow() override; + }; + +} diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config.cpp b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config.cpp new file mode 100644 index 000000000..d229ea01e --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "gpio_driver_impl.hpp" +#include "gpio_initial_config.hpp" +#include "gpio_wake_pin_config.hpp" + +namespace ams::gpio::driver::board::nintendo_nx::impl { + + namespace { + + spl::HardwareType GetHardwareType() { + /* Acquire access to spl: */ + sm::ScopedServiceHolder spl_holder; + AMS_ABORT_UNLESS(static_cast(spl_holder)); + + /* Get config. */ + return ::ams::spl::GetHardwareType(); + } + + #include "gpio_initial_wake_pin_config_icosa.inc" + /* #include "gpio_initial_wake_pin_config_copper.inc" */ + #include "gpio_initial_wake_pin_config_hoag.inc" + #include "gpio_initial_wake_pin_config_iowa.inc" + #include "gpio_initial_wake_pin_config_calcio.inc" + #include "gpio_initial_wake_pin_config_five.inc" + + #include "gpio_initial_config_icosa.inc" + /* #include "gpio_initial_config_copper.inc" */ + #include "gpio_initial_config_hoag.inc" + #include "gpio_initial_config_iowa.inc" + #include "gpio_initial_config_calcio.inc" + #include "gpio_initial_config_five.inc" + + } + + void SetInitialGpioConfig() { + /* Set wake event levels, wake event enables. */ + const GpioInitialConfig *configs = nullptr; + size_t num_configs = 0; + + /* Select the correct config. */ + switch (GetHardwareType()) { + case spl::HardwareType::Icosa: + configs = InitialGpioConfigsIcosa; + num_configs = NumInitialGpioConfigsIcosa; + break; + case spl::HardwareType::Hoag: + configs = InitialGpioConfigsHoag; + num_configs = NumInitialGpioConfigsHoag; + break; + case spl::HardwareType::Iowa: + configs = InitialGpioConfigsIowa; + num_configs = NumInitialGpioConfigsIowa; + break; + case spl::HardwareType::Calcio: + configs = InitialGpioConfigsCalcio; + num_configs = NumInitialGpioConfigsCalcio; + break; + case spl::HardwareType::_Five_: + configs = InitialGpioConfigsFive; + num_configs = NumInitialGpioConfigsFive; + break; + case spl::HardwareType::Copper: + AMS_UNREACHABLE_DEFAULT_CASE(); + } + + /* Check we can use our config. */ + AMS_ABORT_UNLESS(configs != nullptr); + + /* Apply the configs. */ + { + /* Create a driver to use for the duration of our application. */ + DriverImpl driver(GpioRegistersPhysicalAddress, GpioRegistersSize); + driver.InitializeDriver(); + + for (size_t i = 0; i < num_configs; ++i) { + /* Find the internal pad number for our device. */ + bool found = false; + for (const auto &entry : PadMapCombinationList) { + if (entry.device_code == configs[i].device_code) { + /* We found an entry. */ + found = true; + + /* Create a pad for our device. */ + TegraPad pad; + pad.SetParameters(entry.internal_number, PadInfo{entry.wake_event}); + + /* Initialize the pad. */ + R_ABORT_UNLESS(driver.InitializePad(std::addressof(pad))); + + /* Set the direction. */ + R_ABORT_UNLESS(driver.SetDirection(std::addressof(pad), configs[i].direction)); + + /* If the direction is output, set the value. */ + if (configs[i].direction == Direction_Output) { + R_ABORT_UNLESS(driver.SetValue(std::addressof(pad), configs[i].value)); + } + + /* Finalize the pad we made. */ + driver.FinalizePad(std::addressof(pad)); + break; + } + } + + /* Ensure that we applied the config for the pad we wanted. */ + AMS_ABORT_UNLESS(found); + } + + /* Finalize the driver. */ + driver.FinalizeDriver(); + } + } + + void SetInitialWakePinConfig() { + /* Ensure the wec driver is initialized. */ + ams::wec::Initialize(); + + /* Set wake event levels, wake event enables. */ + const WakePinConfig *configs = nullptr; + size_t num_configs = 0; + + /* Select the correct config. */ + switch (GetHardwareType()) { + case spl::HardwareType::Icosa: + configs = InitialWakePinConfigsIcosa; + num_configs = NumInitialWakePinConfigsIcosa; + break; + case spl::HardwareType::Hoag: + configs = InitialWakePinConfigsHoag; + num_configs = NumInitialWakePinConfigsHoag; + break; + case spl::HardwareType::Iowa: + configs = InitialWakePinConfigsIowa; + num_configs = NumInitialWakePinConfigsIowa; + break; + case spl::HardwareType::Calcio: + configs = InitialWakePinConfigsCalcio; + num_configs = NumInitialWakePinConfigsCalcio; + break; + case spl::HardwareType::_Five_: + configs = InitialWakePinConfigsFive; + num_configs = NumInitialWakePinConfigsFive; + break; + case spl::HardwareType::Copper: + AMS_UNREACHABLE_DEFAULT_CASE(); + } + + /* Check we can use our config. */ + AMS_ABORT_UNLESS(configs != nullptr); + + /* Apply the config. */ + for (size_t i = 0; i < num_configs; ++i) { + wec::SetWakeEventLevel(configs[i].wake_event, configs[i].level); + wec::SetWakeEventEnabled(configs[i].wake_event, configs[i].enable); + } + } + +} diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config.hpp b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config.hpp new file mode 100644 index 000000000..d577ccc34 --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config.hpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::gpio::driver::board::nintendo_nx::impl { + + struct GpioInitialConfig { + DeviceCode device_code; + gpio::Direction direction; + gpio::GpioValue value; + }; + + void SetInitialGpioConfig(); + void SetInitialWakePinConfig(); + +} diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_calcio.inc b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_calcio.inc new file mode 100644 index 000000000..e20acc0ae --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_calcio.inc @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* NOTE: This file is auto-generated by gpio_pad_gen.py, do not edit manually. */ + +constexpr inline const GpioInitialConfig InitialGpioConfigsCalcio[] = { + { DeviceCode_Debug0, Direction_Output, GpioValue_Low }, + { DeviceCode_Debug1, Direction_Output, GpioValue_Low }, + { DeviceCode_Debug2, Direction_Output, GpioValue_Low }, + { DeviceCode_Debug3, Direction_Output, GpioValue_Low }, + { DeviceCode_PowSdEn, Direction_Output, GpioValue_Low }, + { DeviceCode_GpioPortF1, Direction_Output, GpioValue_Low }, + { DeviceCode_FanTach, Direction_Input, GpioValue_Low }, + { DeviceCode_TempAlert, Direction_Input, GpioValue_High }, + { DeviceCode_ButtonSleep2, Direction_Input, GpioValue_Low }, + { DeviceCode_ButtonVolUp, Direction_Input, GpioValue_High }, + { DeviceCode_ButtonVolDn, Direction_Input, GpioValue_High }, + { DeviceCode_RecoveryKey, Direction_Input, GpioValue_High }, + { DeviceCode_PdRstN, Direction_Output, GpioValue_Low }, + { DeviceCode_SdCd, Direction_Input, GpioValue_High }, + { DeviceCode_SdWp, Direction_Input, GpioValue_High }, + { DeviceCode_BtGpio2, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio3, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio4, Direction_Input, GpioValue_Low }, + { DeviceCode_CradleIrq, Direction_Input, GpioValue_High }, + { DeviceCode_PowVcpuInt, Direction_Input, GpioValue_High }, + { DeviceCode_Hdmi5VEn, Direction_Output, GpioValue_Low }, + { DeviceCode_UsbSwitchB1Oc, Direction_Input, GpioValue_High }, + { DeviceCode_HdmiPdTrEn, Direction_Output, GpioValue_Low }, + { DeviceCode_WifiRfDisable, Direction_Output, GpioValue_Low }, + { DeviceCode_WifiReset, Direction_Output, GpioValue_Low }, + { DeviceCode_WifiWakeHost, Direction_Input, GpioValue_Low }, + { DeviceCode_ApWakeBt, Direction_Output, GpioValue_Low }, + { DeviceCode_BtRst, Direction_Output, GpioValue_Low }, + { DeviceCode_BtWakeAp, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio5, Direction_Output, GpioValue_Low }, + { DeviceCode_UsbSwitchB1En, Direction_Output, GpioValue_Low }, + { DeviceCode_HdmiHpd, Direction_Input, GpioValue_Low }, +}; + +constexpr inline size_t NumInitialGpioConfigsCalcio = util::size(InitialGpioConfigsCalcio); diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_five.inc b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_five.inc new file mode 100644 index 000000000..bc86cb937 --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_five.inc @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* NOTE: This file is auto-generated by gpio_pad_gen.py, do not edit manually. */ + +constexpr inline const GpioInitialConfig InitialGpioConfigsFive[] = { + { DeviceCode_GameCardReset, Direction_Output, GpioValue_Low }, + { DeviceCode_CodecAlert, Direction_Input, GpioValue_Low }, + { DeviceCode_Debug0, Direction_Output, GpioValue_Low }, + { DeviceCode_Debug1, Direction_Output, GpioValue_Low }, + { DeviceCode_Debug2, Direction_Output, GpioValue_Low }, + { DeviceCode_Debug3, Direction_Output, GpioValue_Low }, + { DeviceCode_PowSdEn, Direction_Output, GpioValue_Low }, + { DeviceCode_ExtConWakeS, Direction_Input, GpioValue_Low }, + { DeviceCode_GameCardCd, Direction_Input, GpioValue_High }, + { DeviceCode_BattChgStatus, Direction_Input, GpioValue_Low }, + { DeviceCode_BattChgEnableN, Direction_Output, GpioValue_Low }, + { DeviceCode_FanTach, Direction_Input, GpioValue_Low }, + { DeviceCode_Vdd50AEn, Direction_Output, GpioValue_Low }, + { DeviceCode_Vdd5V3En, Direction_Output, GpioValue_Low }, + { DeviceCode_TempAlert, Direction_Input, GpioValue_High }, + { DeviceCode_MotionInt, Direction_Input, GpioValue_Low }, + { DeviceCode_CodecHpDetIrq, Direction_Input, GpioValue_Low }, + { DeviceCode_TpIrq, Direction_Input, GpioValue_High }, + { DeviceCode_ButtonSleep2, Direction_Input, GpioValue_Low }, + { DeviceCode_ButtonVolUp, Direction_Input, GpioValue_High }, + { DeviceCode_ButtonVolDn, Direction_Input, GpioValue_High }, + { DeviceCode_BattMgicIrq, Direction_Input, GpioValue_Low }, + { DeviceCode_RecoveryKey, Direction_Input, GpioValue_Low }, + { DeviceCode_LcdReset, Direction_Output, GpioValue_Low }, + { DeviceCode_PdRstN, Direction_Output, GpioValue_Low }, + { DeviceCode_Bq24190Irq, Direction_Input, GpioValue_Low }, + { DeviceCode_SdCd, Direction_Input, GpioValue_High }, + { DeviceCode_SdWp, Direction_Input, GpioValue_High }, + { DeviceCode_CodecLdoEnTemp, Direction_Output, GpioValue_Low }, + { DeviceCode_TpReset, Direction_Output, GpioValue_Low }, + { DeviceCode_ExtconDetU, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio2, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio3, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio4, Direction_Input, GpioValue_Low }, + { DeviceCode_ExtconChgU, Direction_Output, GpioValue_Low }, + { DeviceCode_CradleIrq, Direction_Input, GpioValue_High }, + { DeviceCode_PdVconnEn, Direction_Output, GpioValue_Low }, + { DeviceCode_PowVcpuInt, Direction_Input, GpioValue_High }, + { DeviceCode_ExtconDetS, Direction_Input, GpioValue_Low }, + { DeviceCode_GpioPortH0, Direction_Input, GpioValue_Low }, + { DeviceCode_WifiReset, Direction_Output, GpioValue_Low }, + { DeviceCode_WifiWakeHost, Direction_Input, GpioValue_Low }, + { DeviceCode_ApWakeBt, Direction_Output, GpioValue_Low }, + { DeviceCode_BtRst, Direction_Output, GpioValue_Low }, + { DeviceCode_BtWakeAp, Direction_Input, GpioValue_Low }, + { DeviceCode_ExtConWakeU, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio5, Direction_Output, GpioValue_Low }, + { DeviceCode_ExtconChgS, Direction_Output, GpioValue_Low }, +}; + +constexpr inline size_t NumInitialGpioConfigsFive = util::size(InitialGpioConfigsFive); diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_hoag.inc b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_hoag.inc new file mode 100644 index 000000000..97a45b211 --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_hoag.inc @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* NOTE: This file is auto-generated by gpio_pad_gen.py, do not edit manually. */ + +constexpr inline const GpioInitialConfig InitialGpioConfigsHoag[] = { + { DeviceCode_GameCardReset, Direction_Output, GpioValue_Low }, + { DeviceCode_CodecAlert, Direction_Input, GpioValue_Low }, + { DeviceCode_Debug0, Direction_Output, GpioValue_Low }, + { DeviceCode_Debug1, Direction_Output, GpioValue_Low }, + { DeviceCode_Debug2, Direction_Output, GpioValue_Low }, + { DeviceCode_Debug3, Direction_Output, GpioValue_Low }, + { DeviceCode_PowSdEn, Direction_Output, GpioValue_Low }, + { DeviceCode_ExtConWakeS, Direction_Input, GpioValue_Low }, + { DeviceCode_McuIrq, Direction_Input, GpioValue_High }, + { DeviceCode_GameCardCd, Direction_Input, GpioValue_High }, + { DeviceCode_BattChgStatus, Direction_Input, GpioValue_Low }, + { DeviceCode_BattChgEnableN, Direction_Output, GpioValue_Low }, + { DeviceCode_FanTach, Direction_Input, GpioValue_Low }, + { DeviceCode_McuBoot, Direction_Output, GpioValue_Low }, + { DeviceCode_McuRst, Direction_Output, GpioValue_Low }, + { DeviceCode_Vdd50AEn, Direction_Output, GpioValue_Low }, + { DeviceCode_Vdd5V3En, Direction_Output, GpioValue_Low }, + { DeviceCode_TempAlert, Direction_Input, GpioValue_High }, + { DeviceCode_MotionInt, Direction_Input, GpioValue_Low }, + { DeviceCode_CodecHpDetIrq, Direction_Input, GpioValue_Low }, + { DeviceCode_TpIrq, Direction_Input, GpioValue_High }, + { DeviceCode_ButtonSleep2, Direction_Input, GpioValue_Low }, + { DeviceCode_ButtonVolUp, Direction_Input, GpioValue_High }, + { DeviceCode_ButtonVolDn, Direction_Input, GpioValue_High }, + { DeviceCode_BattMgicIrq, Direction_Input, GpioValue_Low }, + { DeviceCode_RecoveryKey, Direction_Input, GpioValue_High }, + { DeviceCode_PowLcdBlEn, Direction_Output, GpioValue_Low }, + { DeviceCode_LcdReset, Direction_Output, GpioValue_Low }, + { DeviceCode_LcdGpio1, Direction_Input, GpioValue_High }, + { DeviceCode_PdRstN, Direction_Output, GpioValue_Low }, + { DeviceCode_Bq24190Irq, Direction_Input, GpioValue_Low }, + { DeviceCode_SdCd, Direction_Input, GpioValue_High }, + { DeviceCode_SdWp, Direction_Input, GpioValue_High }, + { DeviceCode_CodecLdoEnTemp, Direction_Output, GpioValue_Low }, + { DeviceCode_NfcEn, Direction_Output, GpioValue_Low }, + { DeviceCode_NfcIrq, Direction_Input, GpioValue_Low }, + { DeviceCode_TpReset, Direction_Output, GpioValue_Low }, + { DeviceCode_BtGpio2, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio3, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio4, Direction_Input, GpioValue_Low }, + { DeviceCode_CradleIrq, Direction_Input, GpioValue_High }, + { DeviceCode_PdVconnEn, Direction_Output, GpioValue_Low }, + { DeviceCode_PowVcpuInt, Direction_Input, GpioValue_High }, + { DeviceCode_NfcRst, Direction_Output, GpioValue_Low }, + { DeviceCode_GpioPortC7, Direction_Input, GpioValue_Low }, + { DeviceCode_GpioPortD0, Direction_Input, GpioValue_Low }, + { DeviceCode_GpioPortC5, Direction_Input, GpioValue_Low }, + { DeviceCode_GpioPortC6, Direction_Input, GpioValue_Low }, + { DeviceCode_GpioPortY7, Direction_Output, GpioValue_Low }, + { DeviceCode_WifiRfDisable, Direction_Output, GpioValue_Low }, + { DeviceCode_WifiReset, Direction_Output, GpioValue_Low }, + { DeviceCode_WifiWakeHost, Direction_Input, GpioValue_Low }, + { DeviceCode_ApWakeBt, Direction_Output, GpioValue_Low }, + { DeviceCode_BtRst, Direction_Output, GpioValue_Low }, + { DeviceCode_BtWakeAp, Direction_Input, GpioValue_Low }, + { DeviceCode_ExtConWakeU, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio5, Direction_Output, GpioValue_Low }, + { DeviceCode_PowLcdVddPEn, Direction_Output, GpioValue_Low }, + { DeviceCode_PowLcdVddNEn, Direction_Output, GpioValue_Low }, + { DeviceCode_McuPor, Direction_Output, GpioValue_Low }, +}; + +constexpr inline size_t NumInitialGpioConfigsHoag = util::size(InitialGpioConfigsHoag); diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_icosa.inc b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_icosa.inc new file mode 100644 index 000000000..85800f547 --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_icosa.inc @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* NOTE: This file is auto-generated by gpio_pad_gen.py, do not edit manually. */ + +constexpr inline const GpioInitialConfig InitialGpioConfigsIcosa[] = { + { DeviceCode_RamCode3, Direction_Input, GpioValue_High }, + { DeviceCode_GameCardReset, Direction_Output, GpioValue_Low }, + { DeviceCode_CodecAlert, Direction_Input, GpioValue_Low }, + { DeviceCode_PowSdEn, Direction_Output, GpioValue_Low }, + { DeviceCode_PowGc, Direction_Output, GpioValue_Low }, + { DeviceCode_ExtConWakeS, Direction_Input, GpioValue_Low }, + { DeviceCode_GameCardCd, Direction_Input, GpioValue_High }, + { DeviceCode_DebugControllerDet, Direction_Input, GpioValue_Low }, + { DeviceCode_BattChgStatus, Direction_Input, GpioValue_Low }, + { DeviceCode_BattChgEnableN, Direction_Output, GpioValue_Low }, + { DeviceCode_FanTach, Direction_Input, GpioValue_High }, + { DeviceCode_Vdd50AEn, Direction_Output, GpioValue_Low }, + { DeviceCode_SdevCoaxSel1, Direction_Input, GpioValue_Low }, + { DeviceCode_ProdType0, Direction_Input, GpioValue_Low }, + { DeviceCode_ProdType1, Direction_Input, GpioValue_Low }, + { DeviceCode_ProdType2, Direction_Input, GpioValue_Low }, + { DeviceCode_ProdType3, Direction_Input, GpioValue_Low }, + { DeviceCode_TempAlert, Direction_Input, GpioValue_High }, + { DeviceCode_MotionInt, Direction_Input, GpioValue_Low }, + { DeviceCode_CodecHpDetIrq, Direction_Input, GpioValue_Low }, + { DeviceCode_TpIrq, Direction_Input, GpioValue_High }, + { DeviceCode_ButtonSleep2, Direction_Input, GpioValue_High }, + { DeviceCode_ButtonVolUp, Direction_Input, GpioValue_High }, + { DeviceCode_ButtonVolDn, Direction_Input, GpioValue_High }, + { DeviceCode_BattMgicIrq, Direction_Input, GpioValue_High }, + { DeviceCode_RecoveryKey, Direction_Input, GpioValue_Low }, + { DeviceCode_PowLcdBlEn, Direction_Output, GpioValue_Low }, + { DeviceCode_LcdReset, Direction_Output, GpioValue_Low }, + { DeviceCode_PdRstN, Direction_Output, GpioValue_Low }, + { DeviceCode_Bq24190Irq, Direction_Input, GpioValue_High }, + { DeviceCode_SdCd, Direction_Input, GpioValue_High }, + { DeviceCode_SdevCoaxSel0, Direction_Input, GpioValue_Low }, + { DeviceCode_SdWp, Direction_Input, GpioValue_High }, + { DeviceCode_CodecLdoEnTemp, Direction_Output, GpioValue_Low }, + { DeviceCode_OtgFet1ForSdev, Direction_Output, GpioValue_Low }, + { DeviceCode_TpReset, Direction_Output, GpioValue_Low }, + { DeviceCode_ExtconDetU, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio2, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio3, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio4, Direction_Input, GpioValue_Low }, + { DeviceCode_ExtconChgU, Direction_Output, GpioValue_Low }, + { DeviceCode_CradleIrq, Direction_Input, GpioValue_High }, + { DeviceCode_PdVconnEn, Direction_Output, GpioValue_Low }, + { DeviceCode_PowVcpuInt, Direction_Input, GpioValue_High }, + { DeviceCode_Max77621GpuInt, Direction_Input, GpioValue_High }, + { DeviceCode_OtgFet2ForSdev, Direction_Output, GpioValue_Low }, + { DeviceCode_ExtconDetS, Direction_Input, GpioValue_Low }, + { DeviceCode_WifiRfDisable, Direction_Output, GpioValue_Low }, + { DeviceCode_WifiReset, Direction_Output, GpioValue_Low }, + { DeviceCode_WifiWakeHost, Direction_Input, GpioValue_Low }, + { DeviceCode_ApWakeBt, Direction_Output, GpioValue_Low }, + { DeviceCode_BtRst, Direction_Output, GpioValue_Low }, + { DeviceCode_BtWakeAp, Direction_Input, GpioValue_Low }, + { DeviceCode_ExtConWakeU, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio5, Direction_Output, GpioValue_Low }, + { DeviceCode_PowLcdVddPEn, Direction_Output, GpioValue_Low }, + { DeviceCode_PowLcdVddNEn, Direction_Output, GpioValue_Low }, + { DeviceCode_RamCode2, Direction_Input, GpioValue_High }, + { DeviceCode_ExtconChgS, Direction_Output, GpioValue_Low }, + { DeviceCode_Vdd50BEn, Direction_Output, GpioValue_Low }, +}; + +constexpr inline size_t NumInitialGpioConfigsIcosa = util::size(InitialGpioConfigsIcosa); diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_iowa.inc b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_iowa.inc new file mode 100644 index 000000000..1b71bd7d8 --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_config_iowa.inc @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* NOTE: This file is auto-generated by gpio_pad_gen.py, do not edit manually. */ + +constexpr inline const GpioInitialConfig InitialGpioConfigsIowa[] = { + { DeviceCode_RamCode3, Direction_Input, GpioValue_High }, + { DeviceCode_GameCardReset, Direction_Output, GpioValue_Low }, + { DeviceCode_CodecAlert, Direction_Input, GpioValue_Low }, + { DeviceCode_PowSdEn, Direction_Output, GpioValue_Low }, + { DeviceCode_ExtConWakeS, Direction_Input, GpioValue_Low }, + { DeviceCode_GameCardCd, Direction_Input, GpioValue_High }, + { DeviceCode_DebugControllerDet, Direction_Input, GpioValue_Low }, + { DeviceCode_BattChgStatus, Direction_Input, GpioValue_Low }, + { DeviceCode_BattChgEnableN, Direction_Output, GpioValue_Low }, + { DeviceCode_FanTach, Direction_Input, GpioValue_Low }, + { DeviceCode_Vdd50AEn, Direction_Output, GpioValue_Low }, + { DeviceCode_SdevCoaxSel1, Direction_Input, GpioValue_Low }, + { DeviceCode_ProdType0, Direction_Input, GpioValue_Low }, + { DeviceCode_ProdType1, Direction_Input, GpioValue_Low }, + { DeviceCode_ProdType2, Direction_Input, GpioValue_Low }, + { DeviceCode_ProdType3, Direction_Input, GpioValue_Low }, + { DeviceCode_Vdd5V3En, Direction_Output, GpioValue_Low }, + { DeviceCode_TempAlert, Direction_Input, GpioValue_High }, + { DeviceCode_MotionInt, Direction_Input, GpioValue_Low }, + { DeviceCode_CodecHpDetIrq, Direction_Input, GpioValue_Low }, + { DeviceCode_TpIrq, Direction_Input, GpioValue_High }, + { DeviceCode_ButtonSleep2, Direction_Input, GpioValue_Low }, + { DeviceCode_ButtonVolUp, Direction_Input, GpioValue_High }, + { DeviceCode_ButtonVolDn, Direction_Input, GpioValue_High }, + { DeviceCode_BattMgicIrq, Direction_Input, GpioValue_Low }, + { DeviceCode_RecoveryKey, Direction_Input, GpioValue_Low }, + { DeviceCode_PowLcdBlEn, Direction_Output, GpioValue_Low }, + { DeviceCode_LcdReset, Direction_Output, GpioValue_Low }, + { DeviceCode_PdRstN, Direction_Output, GpioValue_Low }, + { DeviceCode_Bq24190Irq, Direction_Input, GpioValue_Low }, + { DeviceCode_SdCd, Direction_Input, GpioValue_High }, + { DeviceCode_SdevCoaxSel0, Direction_Input, GpioValue_Low }, + { DeviceCode_SdWp, Direction_Input, GpioValue_High }, + { DeviceCode_CodecLdoEnTemp, Direction_Output, GpioValue_Low }, + { DeviceCode_OtgFet1ForSdev, Direction_Output, GpioValue_Low }, + { DeviceCode_TpReset, Direction_Output, GpioValue_Low }, + { DeviceCode_ExtconDetU, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio2, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio3, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio4, Direction_Input, GpioValue_Low }, + { DeviceCode_ExtconChgU, Direction_Output, GpioValue_Low }, + { DeviceCode_CradleIrq, Direction_Input, GpioValue_High }, + { DeviceCode_PdVconnEn, Direction_Output, GpioValue_Low }, + { DeviceCode_PowVcpuInt, Direction_Input, GpioValue_High }, + { DeviceCode_OtgFet2ForSdev, Direction_Output, GpioValue_Low }, + { DeviceCode_ExtconDetS, Direction_Input, GpioValue_Low }, + { DeviceCode_WifiRfDisable, Direction_Output, GpioValue_Low }, + { DeviceCode_WifiReset, Direction_Output, GpioValue_Low }, + { DeviceCode_WifiWakeHost, Direction_Input, GpioValue_Low }, + { DeviceCode_ApWakeBt, Direction_Output, GpioValue_Low }, + { DeviceCode_BtRst, Direction_Output, GpioValue_Low }, + { DeviceCode_BtWakeAp, Direction_Input, GpioValue_Low }, + { DeviceCode_ExtConWakeU, Direction_Input, GpioValue_Low }, + { DeviceCode_BtGpio5, Direction_Output, GpioValue_Low }, + { DeviceCode_PowLcdVddPEn, Direction_Output, GpioValue_Low }, + { DeviceCode_PowLcdVddNEn, Direction_Output, GpioValue_Low }, + { DeviceCode_RamCode2, Direction_Input, GpioValue_High }, + { DeviceCode_ExtconChgS, Direction_Output, GpioValue_Low }, + { DeviceCode_Vdd50BEn, Direction_Output, GpioValue_Low }, +}; + +constexpr inline size_t NumInitialGpioConfigsIowa = util::size(InitialGpioConfigsIowa); diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_calcio.inc b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_calcio.inc new file mode 100644 index 000000000..6cdd662fa --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_calcio.inc @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* NOTE: This file is auto-generated by wake_pin_gen.py, do not edit manually. */ + +constexpr inline const WakePinConfig InitialWakePinConfigsCalcio[] = { + { ams::wec::WakeEvent_PexWakeN, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortA6, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_QspiCsN, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Spi2Mosi, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ExtconDetS, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_McuIrq, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Uart2Cts, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Uart3Cts, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_WifiWakeAp, true, ams::wec::WakeEventLevel_High }, + /* { ams::wec::WakeEvent_AoTag2Pmc, }, */ + { ams::wec::WakeEvent_ExtconDetU, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_NfcInt, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Gen1I2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Gen2I2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_CradleIrq, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_GpioPortK6, false, ams::wec::WakeEventLevel_Auto }, + /* { ams::wec::WakeEvent_RtcIrq, }, */ + { ams::wec::WakeEvent_Sdmmc1Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Sdmmc2Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_HdmiCec, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Gen3I2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortL1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Clk_32kOut, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_PwrI2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonPowerOn, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonVolUp, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonVolDown, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonSlideSw, false, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_ButtonHome, false, ams::wec::WakeEventLevel_Auto }, + /* { ams::wec::WakeEvent_AlsProxInt, }, */ + { ams::wec::WakeEvent_TempAlert, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Bq24190Irq, false, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_SdCd, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortZ2, false, ams::wec::WakeEventLevel_Auto }, + /* { ams::wec::WakeEvent_Utmip0, }, */ + /* { ams::wec::WakeEvent_Utmip1, }, */ + /* { ams::wec::WakeEvent_Utmip2, }, */ + /* { ams::wec::WakeEvent_Utmip3, }, */ + /* { ams::wec::WakeEvent_Uhsic, }, */ + /* { ams::wec::WakeEvent_Wake2PmcXusbSystem, }, */ + { ams::wec::WakeEvent_Sdmmc3Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Sdmmc4Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_CamI2cScl, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_CamI2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortZ5, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_DpHpd0, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_PwrIntN, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_BtWakeAp, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_HdmiIntDpHpd, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_UsbVbusEn0, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_UsbVbusEn1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_LcdRst, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_LcdGpio1, false, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_LcdGpio2, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Uart4Cts, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ModemWakeAp, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_TouchInt, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_MotionInt, false, ams::wec::WakeEventLevel_Auto }, +}; + +constexpr inline size_t NumInitialWakePinConfigsCalcio = util::size(InitialWakePinConfigsCalcio); diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_five.inc b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_five.inc new file mode 100644 index 000000000..809cbf591 --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_five.inc @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* NOTE: This file is auto-generated by wake_pin_gen.py, do not edit manually. */ + +constexpr inline const WakePinConfig InitialWakePinConfigsFive[] = { + { ams::wec::WakeEvent_PexWakeN, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortA6, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_QspiCsN, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Spi2Mosi, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ExtconDetS, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_McuIrq, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Uart2Cts, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Uart3Cts, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_WifiWakeAp, true, ams::wec::WakeEventLevel_High }, + /* { ams::wec::WakeEvent_AoTag2Pmc, }, */ + { ams::wec::WakeEvent_ExtconDetU, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_NfcInt, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Gen1I2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Gen2I2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_CradleIrq, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_GpioPortK6, false, ams::wec::WakeEventLevel_Auto }, + /* { ams::wec::WakeEvent_RtcIrq, }, */ + { ams::wec::WakeEvent_Sdmmc1Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Sdmmc2Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_HdmiCec, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Gen3I2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortL1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Clk_32kOut, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_PwrI2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonPowerOn, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonVolUp, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonVolDown, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonSlideSw, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_ButtonHome, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_AlsProxInt, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_TempAlert, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Bq24190Irq, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_SdCd, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortZ2, false, ams::wec::WakeEventLevel_Auto }, + /* { ams::wec::WakeEvent_Utmip0, }, */ + /* { ams::wec::WakeEvent_Utmip1, }, */ + /* { ams::wec::WakeEvent_Utmip2, }, */ + /* { ams::wec::WakeEvent_Utmip3, }, */ + /* { ams::wec::WakeEvent_Uhsic, }, */ + /* { ams::wec::WakeEvent_Wake2PmcXusbSystem, }, */ + { ams::wec::WakeEvent_Sdmmc3Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Sdmmc4Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_CamI2cScl, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_CamI2cSda, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortZ5, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_DpHpd0, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_PwrIntN, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_BtWakeAp, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_HdmiIntDpHpd, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_UsbVbusEn0, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_UsbVbusEn1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_LcdRst, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_LcdGpio1, false, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_LcdGpio2, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Uart4Cts, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ModemWakeAp, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_TouchInt, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_MotionInt, false, ams::wec::WakeEventLevel_Auto }, +}; + +constexpr inline size_t NumInitialWakePinConfigsFive = util::size(InitialWakePinConfigsFive); diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_hoag.inc b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_hoag.inc new file mode 100644 index 000000000..177fcc5e9 --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_hoag.inc @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* NOTE: This file is auto-generated by wake_pin_gen.py, do not edit manually. */ + +constexpr inline const WakePinConfig InitialWakePinConfigsHoag[] = { + { ams::wec::WakeEvent_PexWakeN, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortA6, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_QspiCsN, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Spi2Mosi, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ExtconDetS, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_McuIrq, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Uart2Cts, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Uart3Cts, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_WifiWakeAp, true, ams::wec::WakeEventLevel_High }, + /* { ams::wec::WakeEvent_AoTag2Pmc, }, */ + { ams::wec::WakeEvent_ExtconDetU, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_NfcInt, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Gen1I2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Gen2I2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_CradleIrq, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_GpioPortK6, false, ams::wec::WakeEventLevel_Auto }, + /* { ams::wec::WakeEvent_RtcIrq, }, */ + { ams::wec::WakeEvent_Sdmmc1Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Sdmmc2Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_HdmiCec, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Gen3I2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortL1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Clk_32kOut, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_PwrI2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonPowerOn, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonVolUp, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonVolDown, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonSlideSw, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_ButtonHome, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_AlsProxInt, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_TempAlert, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Bq24190Irq, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_SdCd, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortZ2, false, ams::wec::WakeEventLevel_Auto }, + /* { ams::wec::WakeEvent_Utmip0, }, */ + /* { ams::wec::WakeEvent_Utmip1, }, */ + /* { ams::wec::WakeEvent_Utmip2, }, */ + /* { ams::wec::WakeEvent_Utmip3, }, */ + /* { ams::wec::WakeEvent_Uhsic, }, */ + /* { ams::wec::WakeEvent_Wake2PmcXusbSystem, }, */ + { ams::wec::WakeEvent_Sdmmc3Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Sdmmc4Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_CamI2cScl, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_CamI2cSda, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortZ5, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_DpHpd0, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_PwrIntN, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_BtWakeAp, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_HdmiIntDpHpd, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_UsbVbusEn0, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_UsbVbusEn1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_LcdRst, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_LcdGpio1, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_LcdGpio2, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Uart4Cts, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ModemWakeAp, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_TouchInt, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_MotionInt, false, ams::wec::WakeEventLevel_Auto }, +}; + +constexpr inline size_t NumInitialWakePinConfigsHoag = util::size(InitialWakePinConfigsHoag); diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_icosa.inc b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_icosa.inc new file mode 100644 index 000000000..19c40e646 --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_icosa.inc @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* NOTE: This file is auto-generated by wake_pin_gen.py, do not edit manually. */ + +constexpr inline const WakePinConfig InitialWakePinConfigsIcosa[] = { + { ams::wec::WakeEvent_PexWakeN, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortA6, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_QspiCsN, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Spi2Mosi, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ExtconDetS, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_McuIrq, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Uart2Cts, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Uart3Cts, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_WifiWakeAp, true, ams::wec::WakeEventLevel_High }, + /* { ams::wec::WakeEvent_AoTag2Pmc, }, */ + { ams::wec::WakeEvent_ExtconDetU, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_NfcInt, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Gen1I2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Gen2I2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_CradleIrq, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_GpioPortK6, false, ams::wec::WakeEventLevel_Auto }, + /* { ams::wec::WakeEvent_RtcIrq, }, */ + { ams::wec::WakeEvent_Sdmmc1Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Sdmmc2Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_HdmiCec, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Gen3I2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortL1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Clk_32kOut, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_PwrI2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonPowerOn, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonVolUp, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonVolDown, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonSlideSw, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_ButtonHome, false, ams::wec::WakeEventLevel_Auto }, + /* { ams::wec::WakeEvent_AlsProxInt, }, */ + { ams::wec::WakeEvent_TempAlert, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Bq24190Irq, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_SdCd, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortZ2, false, ams::wec::WakeEventLevel_Auto }, + /* { ams::wec::WakeEvent_Utmip0, }, */ + /* { ams::wec::WakeEvent_Utmip1, }, */ + /* { ams::wec::WakeEvent_Utmip2, }, */ + /* { ams::wec::WakeEvent_Utmip3, }, */ + /* { ams::wec::WakeEvent_Uhsic, }, */ + /* { ams::wec::WakeEvent_Wake2PmcXusbSystem, }, */ + { ams::wec::WakeEvent_Sdmmc3Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Sdmmc4Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_CamI2cScl, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_CamI2cSda, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortZ5, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_DpHpd0, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_PwrIntN, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_BtWakeAp, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_HdmiIntDpHpd, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_UsbVbusEn0, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_UsbVbusEn1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_LcdRst, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_LcdGpio1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_LcdGpio2, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Uart4Cts, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ModemWakeAp, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_TouchInt, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_MotionInt, false, ams::wec::WakeEventLevel_Auto }, +}; + +constexpr inline size_t NumInitialWakePinConfigsIcosa = util::size(InitialWakePinConfigsIcosa); diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_iowa.inc b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_iowa.inc new file mode 100644 index 000000000..ebd8016ad --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_initial_wake_pin_config_iowa.inc @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* NOTE: This file is auto-generated by wake_pin_gen.py, do not edit manually. */ + +constexpr inline const WakePinConfig InitialWakePinConfigsIowa[] = { + { ams::wec::WakeEvent_PexWakeN, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortA6, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_QspiCsN, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Spi2Mosi, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ExtconDetS, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_McuIrq, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Uart2Cts, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Uart3Cts, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_WifiWakeAp, true, ams::wec::WakeEventLevel_High }, + /* { ams::wec::WakeEvent_AoTag2Pmc, }, */ + { ams::wec::WakeEvent_ExtconDetU, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_NfcInt, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Gen1I2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Gen2I2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_CradleIrq, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_GpioPortK6, false, ams::wec::WakeEventLevel_Auto }, + /* { ams::wec::WakeEvent_RtcIrq, }, */ + { ams::wec::WakeEvent_Sdmmc1Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Sdmmc2Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_HdmiCec, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Gen3I2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortL1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Clk_32kOut, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_PwrI2cSda, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonPowerOn, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonVolUp, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonVolDown, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ButtonSlideSw, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_ButtonHome, false, ams::wec::WakeEventLevel_Auto }, + /* { ams::wec::WakeEvent_AlsProxInt, }, */ + { ams::wec::WakeEvent_TempAlert, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Bq24190Irq, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_SdCd, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortZ2, false, ams::wec::WakeEventLevel_Auto }, + /* { ams::wec::WakeEvent_Utmip0, }, */ + /* { ams::wec::WakeEvent_Utmip1, }, */ + /* { ams::wec::WakeEvent_Utmip2, }, */ + /* { ams::wec::WakeEvent_Utmip3, }, */ + /* { ams::wec::WakeEvent_Uhsic, }, */ + /* { ams::wec::WakeEvent_Wake2PmcXusbSystem, }, */ + { ams::wec::WakeEvent_Sdmmc3Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Sdmmc4Dat1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_CamI2cScl, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_CamI2cSda, true, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_GpioPortZ5, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_DpHpd0, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_PwrIntN, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_BtWakeAp, true, ams::wec::WakeEventLevel_Low }, + { ams::wec::WakeEvent_HdmiIntDpHpd, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_UsbVbusEn0, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_UsbVbusEn1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_LcdRst, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_LcdGpio1, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_LcdGpio2, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_Uart4Cts, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_ModemWakeAp, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_TouchInt, false, ams::wec::WakeEventLevel_Auto }, + { ams::wec::WakeEvent_MotionInt, false, ams::wec::WakeEventLevel_Auto }, +}; + +constexpr inline size_t NumInitialWakePinConfigsIowa = util::size(InitialWakePinConfigsIowa); diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_internal_pad_map_combination.inc b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_internal_pad_map_combination.inc new file mode 100644 index 000000000..a9ff37256 --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_internal_pad_map_combination.inc @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* NOTE: This file is auto-generated by gpio_pad_gen.py, do not edit manually. */ + +constexpr inline const PadMapCombination PadMapCombinationList[] = { + { DeviceCode_CodecLdoEnTemp, InternalGpioPadNumber_Port_Z_4, ams::wec::WakeEvent_None }, + { DeviceCode_PowSdEn, InternalGpioPadNumber_Port_E_4, ams::wec::WakeEvent_None }, + { DeviceCode_BtRst, InternalGpioPadNumber_Port_H_4, ams::wec::WakeEvent_None }, + { DeviceCode_RamCode3, InternalGpioPadNumber_Port_BB_2, ams::wec::WakeEvent_None }, + { DeviceCode_GameCardReset, InternalGpioPadNumber_Port_BB_3, ams::wec::WakeEvent_None }, + { DeviceCode_CodecAlert, InternalGpioPadNumber_Port_BB_4, ams::wec::WakeEvent_None }, + { DeviceCode_PowGc, InternalGpioPadNumber_Port_E_5, ams::wec::WakeEvent_None }, + { DeviceCode_DebugControllerDet, InternalGpioPadNumber_Port_S_0, ams::wec::WakeEvent_None }, + { DeviceCode_BattChgStatus, InternalGpioPadNumber_Port_S_1, ams::wec::WakeEvent_None }, + { DeviceCode_BattChgEnableN, InternalGpioPadNumber_Port_S_6, ams::wec::WakeEvent_None }, + { DeviceCode_FanTach, InternalGpioPadNumber_Port_S_7, ams::wec::WakeEvent_None }, + { DeviceCode_Vdd50AEn, InternalGpioPadNumber_Port_A_5, ams::wec::WakeEvent_None }, + { DeviceCode_SdevCoaxSel1, InternalGpioPadNumber_Port_P_0, ams::wec::WakeEvent_None }, + { DeviceCode_ProdType0, InternalGpioPadNumber_Port_P_5, ams::wec::WakeEvent_None }, + { DeviceCode_ProdType1, InternalGpioPadNumber_Port_P_4, ams::wec::WakeEvent_None }, + { DeviceCode_ProdType2, InternalGpioPadNumber_Port_P_3, ams::wec::WakeEvent_None }, + { DeviceCode_ProdType3, InternalGpioPadNumber_Port_P_2, ams::wec::WakeEvent_None }, + { DeviceCode_TempAlert, InternalGpioPadNumber_Port_X_4, ams::wec::WakeEvent_None }, + { DeviceCode_CodecHpDetIrq, InternalGpioPadNumber_Port_V_6, ams::wec::WakeEvent_None }, + { DeviceCode_MotionInt, InternalGpioPadNumber_Port_X_2, ams::wec::WakeEvent_None }, + { DeviceCode_TpIrq, InternalGpioPadNumber_Port_X_1, ams::wec::WakeEvent_None }, + { DeviceCode_ButtonSleep2, InternalGpioPadNumber_Port_X_5, ams::wec::WakeEvent_None }, + { DeviceCode_ButtonVolUp, InternalGpioPadNumber_Port_X_6, ams::wec::WakeEvent_None }, + { DeviceCode_ButtonVolDn, InternalGpioPadNumber_Port_X_7, ams::wec::WakeEvent_None }, + { DeviceCode_RecoveryKey, InternalGpioPadNumber_Port_Y_1, ams::wec::WakeEvent_None }, + { DeviceCode_PowLcdBlEn, InternalGpioPadNumber_Port_V_1, ams::wec::WakeEvent_None }, + { DeviceCode_LcdReset, InternalGpioPadNumber_Port_V_2, ams::wec::WakeEvent_None }, + { DeviceCode_PdVconnEn, InternalGpioPadNumber_Port_K_5, ams::wec::WakeEvent_None }, + { DeviceCode_PdRstN, InternalGpioPadNumber_Port_V_5, ams::wec::WakeEvent_None }, + { DeviceCode_SdevCoaxSel0, InternalGpioPadNumber_Port_Z_2, ams::wec::WakeEvent_None }, + { DeviceCode_SdWp, InternalGpioPadNumber_Port_Z_3, ams::wec::WakeEvent_None }, + { DeviceCode_TpReset, InternalGpioPadNumber_Port_J_7, ams::wec::WakeEvent_None }, + { DeviceCode_BtGpio2, InternalGpioPadNumber_Port_K_0, ams::wec::WakeEvent_None }, + { DeviceCode_BtGpio3, InternalGpioPadNumber_Port_K_1, ams::wec::WakeEvent_None }, + { DeviceCode_BtGpio4, InternalGpioPadNumber_Port_K_2, ams::wec::WakeEvent_None }, + { DeviceCode_PowVcpuInt, InternalGpioPadNumber_Port_K_6, ams::wec::WakeEvent_None }, + { DeviceCode_Max77621GpuInt, InternalGpioPadNumber_Port_K_7, ams::wec::WakeEvent_None }, + { DeviceCode_ExtconChgU, InternalGpioPadNumber_Port_K_3, ams::wec::WakeEvent_None }, + { DeviceCode_ExtconChgS, InternalGpioPadNumber_Port_CC_3, ams::wec::WakeEvent_None }, + { DeviceCode_WifiRfDisable, InternalGpioPadNumber_Port_H_0, ams::wec::WakeEvent_None }, + { DeviceCode_WifiReset, InternalGpioPadNumber_Port_H_1, ams::wec::WakeEvent_None }, + { DeviceCode_ApWakeBt, InternalGpioPadNumber_Port_H_3, ams::wec::WakeEvent_None }, + { DeviceCode_BtGpio5, InternalGpioPadNumber_Port_H_7, ams::wec::WakeEvent_None }, + { DeviceCode_PowLcdVddPEn, InternalGpioPadNumber_Port_I_0, ams::wec::WakeEvent_None }, + { DeviceCode_PowLcdVddNEn, InternalGpioPadNumber_Port_I_1, ams::wec::WakeEvent_None }, + { DeviceCode_RamCode2, InternalGpioPadNumber_Port_CC_2, ams::wec::WakeEvent_None }, + { DeviceCode_Vdd50BEn, InternalGpioPadNumber_Port_CC_4, ams::wec::WakeEvent_None }, + { DeviceCode_OtgFet1ForSdev, InternalGpioPadNumber_Port_J_5, ams::wec::WakeEvent_None }, + { DeviceCode_OtgFet2ForSdev, InternalGpioPadNumber_Port_L_0, ams::wec::WakeEvent_None }, + { DeviceCode_ExtConWakeU, InternalGpioPadNumber_Port_H_6, ams::wec::WakeEvent_None }, + { DeviceCode_ExtConWakeS, InternalGpioPadNumber_Port_E_6, ams::wec::WakeEvent_None }, + { DeviceCode_ExtUart2Rts, InternalGpioPadNumber_Port_G_2, ams::wec::WakeEvent_None }, + { DeviceCode_ExtUart3Rts, InternalGpioPadNumber_Port_D_3, ams::wec::WakeEvent_None }, + { DeviceCode_Debug0, InternalGpioPadNumber_Port_E_0, ams::wec::WakeEvent_None }, + { DeviceCode_Debug1, InternalGpioPadNumber_Port_E_1, ams::wec::WakeEvent_None }, + { DeviceCode_Debug2, InternalGpioPadNumber_Port_E_2, ams::wec::WakeEvent_None }, + { DeviceCode_Debug3, InternalGpioPadNumber_Port_E_3, ams::wec::WakeEvent_None }, + { DeviceCode_NfcIrq, InternalGpioPadNumber_Port_J_4, ams::wec::WakeEvent_None }, + { DeviceCode_NfcRst, InternalGpioPadNumber_Port_K_7, ams::wec::WakeEvent_None }, + { DeviceCode_McuIrq, InternalGpioPadNumber_Port_E_7, ams::wec::WakeEvent_McuIrq }, + { DeviceCode_McuBoot, InternalGpioPadNumber_Port_T_0, ams::wec::WakeEvent_None }, + { DeviceCode_McuRst, InternalGpioPadNumber_Port_T_1, ams::wec::WakeEvent_None }, + { DeviceCode_Vdd5V3En, InternalGpioPadNumber_Port_X_3, ams::wec::WakeEvent_None }, + { DeviceCode_McuPor, InternalGpioPadNumber_Port_CC_5, ams::wec::WakeEvent_None }, + { DeviceCode_NfcEn, InternalGpioPadNumber_Port_J_6, ams::wec::WakeEvent_None }, + { DeviceCode_GpioPortC7, InternalGpioPadNumber_Port_C_7, ams::wec::WakeEvent_None }, + { DeviceCode_GpioPortD0, InternalGpioPadNumber_Port_D_0, ams::wec::WakeEvent_None }, + { DeviceCode_GpioPortC5, InternalGpioPadNumber_Port_C_5, ams::wec::WakeEvent_None }, + { DeviceCode_GpioPortC6, InternalGpioPadNumber_Port_C_6, ams::wec::WakeEvent_None }, + { DeviceCode_GpioPortY7, InternalGpioPadNumber_Port_Y_5, ams::wec::WakeEvent_None }, + { DeviceCode_Hdmi5VEn, InternalGpioPadNumber_Port_C_0, ams::wec::WakeEvent_None }, + { DeviceCode_UsbSwitchB1En, InternalGpioPadNumber_Port_C_1, ams::wec::WakeEvent_None }, + { DeviceCode_HdmiPdTrEn, InternalGpioPadNumber_Port_C_2, ams::wec::WakeEvent_None }, + { DeviceCode_UsbSwitchB1Oc, InternalGpioPadNumber_Port_CC_6, ams::wec::WakeEvent_None }, + { DeviceCode_HdmiHpd, InternalGpioPadNumber_Port_CC_1, ams::wec::WakeEvent_None }, + { DeviceCode_GpioPortF1, InternalGpioPadNumber_Port_F_1, ams::wec::WakeEvent_None }, + { DeviceCode_GpioPortH0, InternalGpioPadNumber_Port_H_0, ams::wec::WakeEvent_None }, + { DeviceCode_ExtconDetS, InternalGpioPadNumber_Port_E_6, ams::wec::WakeEvent_ExtconDetS }, + { DeviceCode_GameCardCd, InternalGpioPadNumber_Port_S_3, ams::wec::WakeEvent_CamI2cSda }, + { DeviceCode_BattMgicIrq, InternalGpioPadNumber_Port_Y_0, ams::wec::WakeEvent_ButtonSlideSw }, + { DeviceCode_Bq24190Irq, InternalGpioPadNumber_Port_Z_0, ams::wec::WakeEvent_Bq24190Irq }, + { DeviceCode_CradleIrq, InternalGpioPadNumber_Port_K_4, ams::wec::WakeEvent_CradleIrq }, + { DeviceCode_BtWakeAp, InternalGpioPadNumber_Port_H_5, ams::wec::WakeEvent_BtWakeAp }, + { DeviceCode_ExtconDetU, InternalGpioPadNumber_Port_H_6, ams::wec::WakeEvent_ExtconDetU }, + { DeviceCode_WifiWakeHost, InternalGpioPadNumber_Port_H_2, ams::wec::WakeEvent_WifiWakeAp }, + { DeviceCode_SdCd, InternalGpioPadNumber_Port_Z_1, ams::wec::WakeEvent_SdCd }, + { DeviceCode_ExtUart2Cts, InternalGpioPadNumber_Port_G_3, ams::wec::WakeEvent_Uart2Cts }, + { DeviceCode_ExtUart3Cts, InternalGpioPadNumber_Port_D_4, ams::wec::WakeEvent_Uart3Cts }, + { DeviceCode_LcdGpio1, InternalGpioPadNumber_Port_V_3, ams::wec::WakeEvent_LcdGpio1 }, + { DeviceCode_PmuIrq, InternalGpioPadNumber_None, ams::wec::WakeEvent_PwrIntN }, +}; + +constexpr inline size_t PadMapCombinationListSize = util::size(PadMapCombinationList); diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_register_accessor.hpp b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_register_accessor.hpp new file mode 100644 index 000000000..c9b2f6e6f --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_register_accessor.hpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +#include "gpio_tegra_pad.hpp" + +namespace ams::gpio::driver::board::nintendo_nx::impl { + + constexpr inline dd::PhysicalAddress GpioRegistersPhysicalAddress = 0x6000D000; + constexpr inline size_t GpioRegistersSize = 4_KB; + + constexpr inline int GpioPerControllerBitWidth = 5; + constexpr inline int GpioControllerBitWidth = 3; + + constexpr inline int PortPerControllerBitWidth = 2; + constexpr inline int PortPerController = (1 << PortPerControllerBitWidth); + + constexpr inline int GpioPerPortBitWidth = 3; + constexpr inline int GpioPerPort = (1 << GpioPerPortBitWidth); + + static_assert(PortPerControllerBitWidth + GpioPerPortBitWidth == GpioPerControllerBitWidth); + static_assert(PortPerController * GpioPerPort == (1 << GpioPerControllerBitWidth)); + + constexpr int ConvertInternalGpioPadNumberToController(InternalGpioPadNumber number) { + return (number >> GpioPerControllerBitWidth); + } + + constexpr int ConvertInternalGpioPadNumberToPort(InternalGpioPadNumber number) { + return (number >> GpioControllerBitWidth); + } + + constexpr InternalGpioPadNumber ConvertPortToInternalGpioPadNumber(int port) { + return static_cast(port << GpioControllerBitWidth); + } + + constexpr int ConvertInternalGpioPadNumberToBitIndex(InternalGpioPadNumber number) { + return (number & (GpioPerPort - 1)); + } + + constexpr int ConvertPortNumberToOffset(int port_number) { + return (port_number & (PortPerController - 1)); + } + + enum GpioController { + GpioController_1 = 0, + GpioController_2 = 1, + GpioController_3 = 2, + GpioController_4 = 3, + GpioController_5 = 4, + GpioController_6 = 5, + GpioController_7 = 6, + GpioController_8 = 7, + GpioController_Count = 8, + }; + static_assert(GpioController_Count == static_cast(1 << GpioControllerBitWidth)); + + constexpr inline os::InterruptName InterruptNameTable[GpioController_Count] = { + 64, /* GpioController_1 */ + 65, /* GpioController_2 */ + 66, /* GpioController_3 */ + 67, /* GpioController_4 */ + 87, /* GpioController_5 */ + 119, /* GpioController_6 */ + 121, /* GpioController_7 */ + 157, /* GpioController_8 */ + }; + + enum InternalInterruptMode { + InternalInterruptMode_LowLevel = 0x000000, + InternalInterruptMode_HighLevel = 0x000001, + InternalInterruptMode_RisingEdge = 0x000101, + InternalInterruptMode_FallingEdge = 0x000100, + InternalInterruptMode_AnyEdge = 0x010100, + + InternalInterruptMode_Mask = 0x010101, + }; + + enum GpioRegisterType { + GpioRegisterType_GPIO_CNF = 0, + GpioRegisterType_GPIO_OE = 1, + GpioRegisterType_GPIO_OUT = 2, + GpioRegisterType_GPIO_IN = 3, + GpioRegisterType_GPIO_INT_STA = 4, + GpioRegisterType_GPIO_INT_ENB = 5, + GpioRegisterType_GPIO_INT_LVL = 6, + GpioRegisterType_GPIO_INT_CLR = 7, + GpioRegisterType_GPIO_DB_CTRL = 8, + GpioRegisterType_GPIO_DB_CNT = 9, + }; + + constexpr inline uintptr_t MaskedWriteAddressOffset = 0x80; + constexpr inline int MaskedWriteBitOffset = 8; + + constexpr inline uintptr_t GetGpioRegisterAddress(uintptr_t gpio_address, GpioRegisterType reg_type, InternalGpioPadNumber pad_number) { + const auto controller = ConvertInternalGpioPadNumberToController(pad_number); + const auto port = ConvertInternalGpioPadNumberToPort(pad_number); + const auto offset = ConvertPortNumberToOffset(port); + + switch (reg_type) { + default: + return gpio_address + (0x100 * controller) + (0x10 * reg_type) + (0x4 * offset); + case GpioRegisterType_GPIO_DB_CTRL: + return gpio_address + (0x100 * controller) + (0x10 * GpioRegisterType_GPIO_IN) + (0x4 * offset); + case GpioRegisterType_GPIO_DB_CNT: + return gpio_address + (0x100 * controller) + MaskedWriteAddressOffset + (0x10 * GpioRegisterType_GPIO_INT_CLR) + (0x4 * offset); + } + } + + inline void SetMaskedBit(uintptr_t pad_address, int index, int value) { + const uintptr_t mask_address = pad_address + MaskedWriteAddressOffset; + + reg::Write(mask_address, (1u << (MaskedWriteBitOffset + index)) | (static_cast(value) << index)); + } + + inline void SetMaskedBits(uintptr_t pad_address, unsigned int mask, unsigned int value) { + const uintptr_t mask_address = pad_address + MaskedWriteAddressOffset; + + reg::Write(mask_address, (mask << MaskedWriteBitOffset) | (value)); + } + +} diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_suspend_handler.cpp b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_suspend_handler.cpp new file mode 100644 index 000000000..a922b2128 --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_suspend_handler.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "gpio_suspend_handler.hpp" + +namespace ams::gpio::driver::board::nintendo_nx::impl { + + void SuspendHandler::Initialize(uintptr_t gpio_vaddr) { + /* Set our gpio virtual address. */ + this->gpio_virtual_address = gpio_vaddr; + + /* Ensure that we can use the wec library. */ + ams::wec::Initialize(); + } + + void SuspendHandler::SetValueForSleepState(TegraPad *pad, GpioValue value) { + /* TODO */ + AMS_ABORT(); + } + + Result SuspendHandler::IsWakeEventActive(bool *out, TegraPad *pad) const { + /* TODO */ + AMS_ABORT(); + } + + Result SuspendHandler::SetWakeEventActiveFlagSetForDebug(TegraPad *pad, bool en) { + /* TODO */ + AMS_ABORT(); + } + + void SuspendHandler::SetWakePinDebugMode(WakePinDebugMode mode) { + /* TODO */ + AMS_ABORT(); + } + + void SuspendHandler::Suspend() { + /* TODO */ + AMS_ABORT(); + } + + void SuspendHandler::SuspendLow() { + /* TODO */ + AMS_ABORT(); + } + + void SuspendHandler::Resume() { + /* TODO */ + AMS_ABORT(); + } + + void SuspendHandler::ResumeLow() { + /* TODO */ + AMS_ABORT(); + } + +} diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_suspend_handler.hpp b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_suspend_handler.hpp new file mode 100644 index 000000000..faaf59b07 --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_suspend_handler.hpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +#include "gpio_tegra_pad.hpp" + +namespace ams::gpio::driver::board::nintendo_nx::impl { + + class SuspendHandler { + NON_COPYABLE(SuspendHandler); + NON_MOVEABLE(SuspendHandler); + private: + struct RegisterValues { + u16 conf; + u8 oe; + u8 out; + u8 int_enb; + u32 int_lvl; + u8 db_ctrl; + u8 db_cnt; + + void Reset() { + this->conf = 0; + this->oe = 0; + this->out = 0; + this->int_enb = 0; + this->int_lvl = 0; + this->db_ctrl = 0; + this->db_cnt = 0; + } + }; + + struct ValuesForSleepState { + u8 force_set; + u8 out; + + void Reset() { + this->force_set = 0; + this->out = 0; + } + }; + private: + ddsf::IDriver &driver; + uintptr_t gpio_virtual_address; + RegisterValues register_values[GpioPadPort_Count]; + ValuesForSleepState values_for_sleep_state[GpioPadPort_Count]; + private: + uintptr_t GetGpioVirtualAddress() const { + AMS_ASSERT(this->gpio_virtual_address != 0); + return this->gpio_virtual_address; + } + public: + explicit SuspendHandler(ddsf::IDriver *drv) : driver(*drv), gpio_virtual_address(0) { + for (auto &rv : this->register_values) { + rv.Reset(); + } + for (auto &v : this->values_for_sleep_state) { + v.Reset(); + } + } + + void Initialize(uintptr_t gpio_vaddr); + + void SetValueForSleepState(TegraPad *pad, GpioValue value); + Result IsWakeEventActive(bool *out, TegraPad *pad) const; + Result SetWakeEventActiveFlagSetForDebug(TegraPad *pad, bool en); + void SetWakePinDebugMode(WakePinDebugMode mode); + + void Suspend(); + void SuspendLow(); + void Resume(); + void ResumeLow(); + }; + +} diff --git a/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_tegra_pad.hpp b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_tegra_pad.hpp new file mode 100644 index 000000000..67c093906 --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_tegra_pad.hpp @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::gpio::driver::board::nintendo_nx::impl { + + enum GpioPadPort { + GpioPadPort_A = 0, + GpioPadPort_B = 1, + GpioPadPort_C = 2, + GpioPadPort_D = 3, + GpioPadPort_E = 4, + GpioPadPort_F = 5, + GpioPadPort_G = 6, + GpioPadPort_H = 7, + GpioPadPort_I = 8, + GpioPadPort_J = 9, + GpioPadPort_K = 10, + GpioPadPort_L = 11, + GpioPadPort_M = 12, + GpioPadPort_N = 13, + GpioPadPort_O = 14, + GpioPadPort_P = 15, + GpioPadPort_Q = 16, + GpioPadPort_R = 17, + GpioPadPort_S = 18, + GpioPadPort_T = 19, + GpioPadPort_U = 20, + GpioPadPort_V = 21, + GpioPadPort_W = 22, + GpioPadPort_X = 23, + GpioPadPort_Y = 24, + GpioPadPort_Z = 25, + GpioPadPort_AA = 26, + GpioPadPort_BB = 27, + GpioPadPort_CC = 28, + GpioPadPort_DD = 29, + GpioPadPort_EE = 30, + GpioPadPort_FF = 31, + GpioPadPort_Count = 32, + }; + + using InternalGpioPadNumber = int; + + constexpr unsigned int GetInternalGpioPadNumber(GpioPadPort port, unsigned int which) { + AMS_ASSERT(which < 8); + + return (static_cast(port) * 8) + which; + } + + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_None = -1; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_A_0 = 0x00; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_A_1 = 0x01; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_A_2 = 0x02; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_A_3 = 0x03; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_A_4 = 0x04; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_A_5 = 0x05; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_A_6 = 0x06; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_A_7 = 0x07; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_B_0 = 0x08; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_B_1 = 0x09; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_B_2 = 0x0A; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_B_3 = 0x0B; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_B_4 = 0x0C; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_B_5 = 0x0D; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_B_6 = 0x0E; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_B_7 = 0x0F; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_C_0 = 0x10; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_C_1 = 0x11; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_C_2 = 0x12; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_C_3 = 0x13; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_C_4 = 0x14; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_C_5 = 0x15; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_C_6 = 0x16; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_C_7 = 0x17; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_D_0 = 0x18; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_D_1 = 0x19; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_D_2 = 0x1A; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_D_3 = 0x1B; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_D_4 = 0x1C; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_D_5 = 0x1D; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_D_6 = 0x1E; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_D_7 = 0x1F; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_E_0 = 0x20; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_E_1 = 0x21; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_E_2 = 0x22; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_E_3 = 0x23; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_E_4 = 0x24; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_E_5 = 0x25; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_E_6 = 0x26; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_E_7 = 0x27; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_F_0 = 0x28; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_F_1 = 0x29; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_F_2 = 0x2A; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_F_3 = 0x2B; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_F_4 = 0x2C; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_F_5 = 0x2D; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_F_6 = 0x2E; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_F_7 = 0x2F; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_G_0 = 0x30; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_G_1 = 0x31; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_G_2 = 0x32; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_G_3 = 0x33; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_G_4 = 0x34; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_G_5 = 0x35; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_G_6 = 0x36; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_G_7 = 0x37; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_H_0 = 0x38; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_H_1 = 0x39; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_H_2 = 0x3A; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_H_3 = 0x3B; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_H_4 = 0x3C; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_H_5 = 0x3D; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_H_6 = 0x3E; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_H_7 = 0x3F; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_I_0 = 0x40; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_I_1 = 0x41; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_I_2 = 0x42; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_I_3 = 0x43; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_I_4 = 0x44; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_I_5 = 0x45; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_I_6 = 0x46; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_I_7 = 0x47; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_J_0 = 0x48; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_J_1 = 0x49; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_J_2 = 0x4A; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_J_3 = 0x4B; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_J_4 = 0x4C; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_J_5 = 0x4D; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_J_6 = 0x4E; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_J_7 = 0x4F; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_K_0 = 0x50; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_K_1 = 0x51; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_K_2 = 0x52; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_K_3 = 0x53; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_K_4 = 0x54; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_K_5 = 0x55; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_K_6 = 0x56; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_K_7 = 0x57; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_L_0 = 0x58; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_L_1 = 0x59; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_L_2 = 0x5A; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_L_3 = 0x5B; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_L_4 = 0x5C; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_L_5 = 0x5D; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_L_6 = 0x5E; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_L_7 = 0x5F; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_M_0 = 0x60; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_M_1 = 0x61; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_M_2 = 0x62; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_M_3 = 0x63; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_M_4 = 0x64; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_M_5 = 0x65; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_M_6 = 0x66; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_M_7 = 0x67; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_N_0 = 0x68; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_N_1 = 0x69; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_N_2 = 0x6A; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_N_3 = 0x6B; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_N_4 = 0x6C; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_N_5 = 0x6D; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_N_6 = 0x6E; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_N_7 = 0x6F; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_O_0 = 0x70; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_O_1 = 0x71; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_O_2 = 0x72; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_O_3 = 0x73; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_O_4 = 0x74; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_O_5 = 0x75; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_O_6 = 0x76; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_O_7 = 0x77; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_P_0 = 0x78; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_P_1 = 0x79; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_P_2 = 0x7A; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_P_3 = 0x7B; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_P_4 = 0x7C; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_P_5 = 0x7D; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_P_6 = 0x7E; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_P_7 = 0x7F; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Q_0 = 0x80; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Q_1 = 0x81; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Q_2 = 0x82; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Q_3 = 0x83; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Q_4 = 0x84; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Q_5 = 0x85; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Q_6 = 0x86; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Q_7 = 0x87; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_R_0 = 0x88; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_R_1 = 0x89; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_R_2 = 0x8A; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_R_3 = 0x8B; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_R_4 = 0x8C; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_R_5 = 0x8D; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_R_6 = 0x8E; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_R_7 = 0x8F; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_S_0 = 0x90; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_S_1 = 0x91; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_S_2 = 0x92; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_S_3 = 0x93; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_S_4 = 0x94; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_S_5 = 0x95; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_S_6 = 0x96; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_S_7 = 0x97; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_T_0 = 0x98; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_T_1 = 0x99; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_T_2 = 0x9A; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_T_3 = 0x9B; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_T_4 = 0x9C; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_T_5 = 0x9D; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_T_6 = 0x9E; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_T_7 = 0x9F; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_U_0 = 0xA0; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_U_1 = 0xA1; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_U_2 = 0xA2; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_U_3 = 0xA3; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_U_4 = 0xA4; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_U_5 = 0xA5; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_U_6 = 0xA6; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_U_7 = 0xA7; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_V_0 = 0xA8; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_V_1 = 0xA9; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_V_2 = 0xAA; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_V_3 = 0xAB; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_V_4 = 0xAC; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_V_5 = 0xAD; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_V_6 = 0xAE; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_V_7 = 0xAF; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_W_0 = 0xB0; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_W_1 = 0xB1; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_W_2 = 0xB2; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_W_3 = 0xB3; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_W_4 = 0xB4; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_W_5 = 0xB5; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_W_6 = 0xB6; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_W_7 = 0xB7; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_X_0 = 0xB8; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_X_1 = 0xB9; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_X_2 = 0xBA; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_X_3 = 0xBB; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_X_4 = 0xBC; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_X_5 = 0xBD; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_X_6 = 0xBE; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_X_7 = 0xBF; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Y_0 = 0xC0; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Y_1 = 0xC1; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Y_2 = 0xC2; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Y_3 = 0xC3; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Y_4 = 0xC4; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Y_5 = 0xC5; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Y_6 = 0xC6; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Y_7 = 0xC7; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Z_0 = 0xC8; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Z_1 = 0xC9; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Z_2 = 0xCA; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Z_3 = 0xCB; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Z_4 = 0xCC; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Z_5 = 0xCD; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Z_6 = 0xCE; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_Z_7 = 0xCF; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_AA_0 = 0xD0; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_AA_1 = 0xD1; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_AA_2 = 0xD2; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_AA_3 = 0xD3; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_AA_4 = 0xD4; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_AA_5 = 0xD5; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_AA_6 = 0xD6; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_AA_7 = 0xD7; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_BB_0 = 0xD8; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_BB_1 = 0xD9; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_BB_2 = 0xDA; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_BB_3 = 0xDB; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_BB_4 = 0xDC; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_BB_5 = 0xDD; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_BB_6 = 0xDE; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_BB_7 = 0xDF; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_CC_0 = 0xE0; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_CC_1 = 0xE1; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_CC_2 = 0xE2; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_CC_3 = 0xE3; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_CC_4 = 0xE4; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_CC_5 = 0xE5; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_CC_6 = 0xE6; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_CC_7 = 0xE7; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_DD_0 = 0xE8; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_DD_1 = 0xE9; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_DD_2 = 0xEA; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_DD_3 = 0xEB; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_DD_4 = 0xEC; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_DD_5 = 0xED; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_DD_6 = 0xEE; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_DD_7 = 0xEF; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_EE_0 = 0xF0; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_EE_1 = 0xF1; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_EE_2 = 0xF2; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_EE_3 = 0xF3; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_EE_4 = 0xF4; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_EE_5 = 0xF5; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_EE_6 = 0xF6; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_EE_7 = 0xF7; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_FF_0 = 0xF8; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_FF_1 = 0xF9; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_FF_2 = 0xFA; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_FF_3 = 0xFB; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_FF_4 = 0xFC; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_FF_5 = 0xFD; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_FF_6 = 0xFE; + constexpr inline InternalGpioPadNumber InternalGpioPadNumber_Port_FF_7 = 0xFF; + + struct PadMapCombination { + DeviceCode device_code; + InternalGpioPadNumber internal_number; + wec::WakeEvent wake_event; + }; + + #include "gpio_internal_pad_map_combination.inc" + + struct PadInfo { + wec::WakeEvent wake_event; + + constexpr PadInfo() : wake_event(wec::WakeEvent_None) { /* ... */ } + + constexpr explicit PadInfo(wec::WakeEvent we) : wake_event(we) { /* ... */ } + + constexpr bool operator ==(const PadInfo &rhs) const { return this->wake_event == rhs.wake_event; } + constexpr bool operator !=(const PadInfo &rhs) const { return !(*this == rhs); } + }; + + struct PadStatus { + bool is_wake_active; + bool is_wake_active_debug; + + constexpr PadStatus() : is_wake_active(false), is_wake_active_debug(false) { /* ... */ } + }; + + class TegraPad : public ::ams::gpio::driver::Pad { + AMS_DDSF_CASTABLE_TRAITS(ams::gpio::driver::board::nintendo_nx::impl::TegraPad, ::ams::gpio::driver::Pad); + private: + using Base = ::ams::gpio::driver::Pad; + private: + util::IntrusiveListNode interrupt_list_node; + PadInfo info; + PadStatus status; + public: + using InterruptListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&TegraPad::interrupt_list_node>; + using InterruptList = typename InterruptListTraits::ListType; + friend class util::IntrusiveList>; + public: + TegraPad() : Pad(), interrupt_list_node(), info(), status() { /* ... */ } + + const PadInfo &GetInfo() const { return this->info; } + PadStatus &GetStatus() { return this->status; } + + void SetParameters(int pad, const PadInfo &i) { + Base::SetPadNumber(pad); + this->info = info; + } + + bool IsLinkedToInterruptBoundPadList() const { + return this->interrupt_list_node.IsLinked(); + } + }; + +} diff --git a/stratosphere/boot/source/gpio/gpio_utils.hpp b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_wake_pin_config.hpp similarity index 75% rename from stratosphere/boot/source/gpio/gpio_utils.hpp rename to libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_wake_pin_config.hpp index 19a6131a5..9b251437a 100644 --- a/stratosphere/boot/source/gpio/gpio_utils.hpp +++ b/libraries/libstratosphere/source/gpio/driver/board/nintendo_nx/impl/gpio_wake_pin_config.hpp @@ -13,16 +13,15 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #pragma once -#include #include -namespace ams::boot::gpio { +namespace ams::gpio::driver::board::nintendo_nx::impl { - /* GPIO Utilities. */ - u32 Configure(u32 gpio_pad_name); - u32 SetDirection(u32 gpio_pad_name, GpioDirection dir); - u32 SetValue(u32 gpio_pad_name, GpioValue val); + struct WakePinConfig { + wec::WakeEvent wake_event; + bool enable; + wec::WakeEventLevel level; + }; } diff --git a/libraries/libstratosphere/source/gpio/driver/gpio_driver_client_api.cpp b/libraries/libstratosphere/source/gpio/driver/gpio_driver_client_api.cpp new file mode 100644 index 000000000..8bbe1dec9 --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/gpio_driver_client_api.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +#include "impl/gpio_driver_core.hpp" + +namespace ams::gpio::driver { + + void Initialize() { + return impl::InitializeDrivers(); + } + + void Finalize() { + return impl::FinalizeDrivers(); + } + +} diff --git a/libraries/libstratosphere/source/gpio/driver/gpio_driver_service_api.cpp b/libraries/libstratosphere/source/gpio/driver/gpio_driver_service_api.cpp new file mode 100644 index 000000000..3542bde8e --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/gpio_driver_service_api.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +#include "impl/gpio_driver_core.hpp" + +namespace ams::gpio::driver { + + void RegisterDriver(IGpioDriver *driver) { + return impl::RegisterDriver(driver); + } + + void UnregisterDriver(IGpioDriver *driver) { + return impl::UnregisterDriver(driver); + } + + Result RegisterDeviceCode(DeviceCode device_code, Pad *pad) { + return impl::RegisterDeviceCode(device_code, pad); + } + + bool UnregisterDeviceCode(DeviceCode device_code) { + return impl::UnregisterDeviceCode(device_code); + } + + void RegisterInterruptHandler(ddsf::IEventHandler *handler) { + return impl::RegisterInterruptHandler(handler); + } + + void UnregisterInterruptHandler(ddsf::IEventHandler *handler) { + return impl::UnregisterInterruptHandler(handler); + } + + void SetInitialGpioConfig() { + return board::SetInitialGpioConfig(); + } + + void SetInitialWakePinConfig() { + return board::SetInitialWakePinConfig(); + } + +} diff --git a/libraries/libstratosphere/source/gpio/driver/impl/gpio_driver_core.cpp b/libraries/libstratosphere/source/gpio/driver/impl/gpio_driver_core.cpp new file mode 100644 index 000000000..8da4abde0 --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/impl/gpio_driver_core.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "gpio_driver_core.hpp" + +namespace ams::gpio::driver::impl { + + namespace { + + os::ThreadType g_interrupt_thread; + + constexpr inline size_t InterruptThreadStackSize = os::MemoryPageSize; + alignas(os::MemoryPageSize) u8 g_interrupt_thread_stack[InterruptThreadStackSize]; + + gpio::driver::IGpioDriver::List &GetGpioDriverList() { + static gpio::driver::IGpioDriver::List s_gpio_driver_list; + return s_gpio_driver_list; + } + + ddsf::EventHandlerManager &GetInterruptHandlerManager() { + static ddsf::EventHandlerManager s_interrupt_handler_manager; + return s_interrupt_handler_manager; + } + + ddsf::DeviceCodeEntryManager &GetDeviceCodeEntryManager() { + static ddsf::DeviceCodeEntryManager s_device_code_entry_manager(ddsf::GetDeviceCodeEntryHolderMemoryResource()); + return s_device_code_entry_manager; + } + + void InterruptThreadFunction(void *arg) { + AMS_UNUSED(arg); + GetInterruptHandlerManager().LoopAuto(); + } + + } + + void InitializeDrivers() { + /* Ensure the event handler manager is initialized. */ + GetInterruptHandlerManager().Initialize(); + + /* Initialize all registered drivers. */ + for (auto &driver : GetGpioDriverList()) { + driver.SafeCastTo().InitializeDriver(); + } + + /* Create the interrupt thread. */ + R_ABORT_UNLESS(os::CreateThread(std::addressof(g_interrupt_thread), InterruptThreadFunction, nullptr, g_interrupt_thread_stack, InterruptThreadStackSize, AMS_GET_SYSTEM_THREAD_PRIORITY(gpio, InterruptHandler))); + os::SetThreadNamePointer(std::addressof(g_interrupt_thread), AMS_GET_SYSTEM_THREAD_NAME(gpio, InterruptHandler)); + os::StartThread(std::addressof(g_interrupt_thread)); + + /* Wait for the interrupt thread to enter the loop. */ + GetInterruptHandlerManager().WaitLoopEnter(); + } + + void FinalizeDrivers() { + /* Request the interrupt thread stop. */ + GetInterruptHandlerManager().RequestStop(); + os::WaitThread(std::addressof(g_interrupt_thread)); + os::DestroyThread(std::addressof(g_interrupt_thread)); + + /* TODO: What else? */ + AMS_ABORT(); + } + + void RegisterDriver(IGpioDriver *driver) { + AMS_ASSERT(driver != nullptr); + GetGpioDriverList().push_back(*driver); + } + + void UnregisterDriver(IGpioDriver *driver) { + AMS_ASSERT(driver != nullptr); + if (driver->IsLinkedToList()) { + auto &list = GetGpioDriverList(); + list.erase(list.iterator_to(*driver)); + } + } + + Result RegisterDeviceCode(DeviceCode device_code, Pad *pad) { + AMS_ASSERT(pad != nullptr); + R_TRY(GetDeviceCodeEntryManager().Add(device_code, pad)); + return ResultSuccess(); + } + + bool UnregisterDeviceCode(DeviceCode device_code) { + return GetDeviceCodeEntryManager().Remove(device_code); + } + + void RegisterInterruptHandler(ddsf::IEventHandler *handler) { + AMS_ASSERT(handler != nullptr); + GetInterruptHandlerManager().RegisterHandler(handler); + } + + void UnregisterInterruptHandler(ddsf::IEventHandler *handler) { + AMS_ASSERT(handler != nullptr); + GetInterruptHandlerManager().UnregisterHandler(handler); + } + + Result FindPad(Pad **out, DeviceCode device_code) { + /* Validate output. */ + AMS_ASSERT(out != nullptr); + + /* Find the device. */ + ddsf::IDevice *device; + R_TRY(GetDeviceCodeEntryManager().FindDevice(std::addressof(device), device_code)); + + /* Set output. */ + *out = device->SafeCastToPointer(); + return ResultSuccess(); + } + + Result FindPadByNumber(Pad **out, int pad_number) { + /* Validate output. */ + AMS_ASSERT(out != nullptr); + + /* Find the pad. */ + bool found = false; + GetDeviceCodeEntryManager().ForEachEntry([&](ddsf::DeviceCodeEntry &entry) -> bool { + /* Convert the entry to a pad. */ + auto &pad = entry.GetDevice().SafeCastTo(); + + /* Check if the pad is the one we're looking for. */ + if (pad.GetPadNumber() == pad_number) { + found = true; + *out = std::addressof(pad); + return false; + } + return true; + }); + + /* Check that we found the pad. */ + R_UNLESS(found, ddsf::ResultDeviceCodeNotFound()); + + return ResultSuccess(); + } + +} diff --git a/libraries/libstratosphere/source/gpio/driver/impl/gpio_driver_core.hpp b/libraries/libstratosphere/source/gpio/driver/impl/gpio_driver_core.hpp new file mode 100644 index 000000000..dbf169e5e --- /dev/null +++ b/libraries/libstratosphere/source/gpio/driver/impl/gpio_driver_core.hpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::gpio::driver::impl { + + void InitializeDrivers(); + void FinalizeDrivers(); + + void RegisterDriver(IGpioDriver *driver); + void UnregisterDriver(IGpioDriver *driver); + + Result RegisterDeviceCode(DeviceCode device_code, Pad *pad); + bool UnregisterDeviceCode(DeviceCode device_code); + + void RegisterInterruptHandler(ddsf::IEventHandler *handler); + void UnregisterInterruptHandler(ddsf::IEventHandler *handler); + + Result FindPad(Pad **out, DeviceCode device_code); + Result FindPadByNumber(Pad **out, int pad_number); + +} diff --git a/libraries/libstratosphere/source/spl/spl_api.cpp b/libraries/libstratosphere/source/spl/spl_api.cpp index f53b75379..ed5de7854 100644 --- a/libraries/libstratosphere/source/spl/spl_api.cpp +++ b/libraries/libstratosphere/source/spl/spl_api.cpp @@ -29,7 +29,7 @@ namespace ams::spl { Manu }; - os::Mutex g_mutex(false); + os::SdkMutex g_mutex; s32 g_initialize_count = 0; InitializeMode g_initialize_mode = InitializeMode::None; diff --git a/stratosphere/boot/source/boot_charger_driver.cpp b/stratosphere/boot/source/boot_charger_driver.cpp index 7bd8e87da..be8015818 100644 --- a/stratosphere/boot/source/boot_charger_driver.cpp +++ b/stratosphere/boot/source/boot_charger_driver.cpp @@ -60,7 +60,9 @@ namespace ams::boot { } Result ChargerDriver::SetChargeEnabled(bool enabled) { - boot::gpio::SetValue(GpioPadName_Bq24193Charger, enabled ? GpioValue_Low : GpioValue_High); + /* TODO */ + AMS_ABORT(); + /* boot::gpio::SetValue(GpioPadName_Bq24193Charger, enabled ? GpioValue_Low : GpioValue_High); */ return this->SetChargerConfiguration(bq24193::ChargerConfiguration_ChargeBattery); } diff --git a/stratosphere/boot/source/boot_charger_driver.hpp b/stratosphere/boot/source/boot_charger_driver.hpp index 54acb6f3c..758b0d4a9 100644 --- a/stratosphere/boot/source/boot_charger_driver.hpp +++ b/stratosphere/boot/source/boot_charger_driver.hpp @@ -17,8 +17,6 @@ #include "boot_bq24193_charger.hpp" #include "boot_i2c_utils.hpp" -#include "gpio/gpio_utils.hpp" - namespace ams::boot { class ChargerDriver { @@ -31,8 +29,8 @@ namespace ams::boot { i2c::driver::Initialize(); i2c::driver::OpenSession(&this->i2c_session, I2cDevice_Bq24193); - boot::gpio::Configure(GpioPadName_Bq24193Charger); - boot::gpio::SetDirection(GpioPadName_Bq24193Charger, GpioDirection_Output); + //boot::gpio::Configure(GpioPadName_Bq24193Charger); + //boot::gpio::SetDirection(GpioPadName_Bq24193Charger, GpioDirection_Output); } ~ChargerDriver() { diff --git a/stratosphere/boot/source/boot_fan_enable.cpp b/stratosphere/boot/source/boot_fan_enable.cpp index c0c2b947c..2a6b58ef9 100644 --- a/stratosphere/boot/source/boot_fan_enable.cpp +++ b/stratosphere/boot/source/boot_fan_enable.cpp @@ -16,22 +16,14 @@ #include #include "boot_fan_enable.hpp" -#include "gpio/gpio_utils.hpp" - namespace ams::boot { - namespace { - - /* Convenience definitions. */ - constexpr u32 GpioPadName_FanEnable = 0x4B; - - } - void SetFanEnabled() { if (spl::GetHardwareType() == spl::HardwareType::Copper) { - boot::gpio::Configure(GpioPadName_FanEnable); - boot::gpio::SetDirection(GpioPadName_FanEnable, GpioDirection_Output); - boot::gpio::SetValue(GpioPadName_FanEnable, GpioValue_High); + /* TODO */ + /* boot::gpio::Configure(GpioPadName_FanEnable); */ + /* boot::gpio::SetDirection(GpioPadName_FanEnable, GpioDirection_Output); */ + /* boot::gpio::SetValue(GpioPadName_FanEnable, GpioValue_High); */ } } diff --git a/stratosphere/boot/source/boot_main.cpp b/stratosphere/boot/source/boot_main.cpp index b04f3d2a2..2a5fd2c3f 100644 --- a/stratosphere/boot/source/boot_main.cpp +++ b/stratosphere/boot/source/boot_main.cpp @@ -24,7 +24,6 @@ #include "boot_splash_screen.hpp" #include "boot_wake_pins.hpp" -#include "gpio/gpio_initial_configuration.hpp" #include "pinmux/pinmux_initial_configuration.hpp" #include "boot_power_utils.hpp" @@ -38,7 +37,7 @@ extern "C" { u32 __nx_fs_num_sessions = 1; /* TODO: Evaluate to what extent this can be reduced further. */ - #define INNER_HEAP_SIZE 0x20000 + #define INNER_HEAP_SIZE 0x1000 size_t nx_inner_heap_size = INNER_HEAP_SIZE; char nx_inner_heap[INNER_HEAP_SIZE]; @@ -71,6 +70,42 @@ namespace ams { using namespace ams; +namespace { + + u8 g_exp_heap_memory[20_KB]; + u8 g_unit_heap_memory[5_KB]; + lmem::HeapHandle g_exp_heap_handle; + lmem::HeapHandle g_unit_heap_handle; + + std::optional g_exp_heap_memory_resource; + std::optional g_unit_heap_memory_resource; + + void *Allocate(size_t size) { + void *mem = lmem::AllocateFromExpHeap(g_exp_heap_handle, size); + return mem; + } + + void Deallocate(void *p, size_t size) { + AMS_UNUSED(size); + lmem::FreeToExpHeap(g_exp_heap_handle, p); + } + + void InitializeHeaps() { + /* Create the heaps. */ + g_exp_heap_handle = lmem::CreateExpHeap(g_exp_heap_memory, sizeof(g_exp_heap_memory), lmem::CreateOption_ThreadSafe); + g_unit_heap_handle = lmem::CreateUnitHeap(g_unit_heap_memory, sizeof(g_unit_heap_memory), sizeof(ddsf::DeviceCodeEntryHolder), lmem::CreateOption_ThreadSafe); + + /* Create the memory resources. */ + g_exp_heap_memory_resource.emplace(g_exp_heap_handle); + g_unit_heap_memory_resource.emplace(g_unit_heap_handle); + + /* Register with ddsf. */ + ddsf::SetMemoryResource(std::addressof(*g_exp_heap_memory_resource)); + ddsf::SetDeviceCodeEntryHolderMemoryResource(std::addressof(*g_unit_heap_memory_resource)); + } + +} + void __libnx_exception_handler(ThreadExceptionDump *ctx) { ams::CrashHandler(ctx); } @@ -85,11 +120,15 @@ void __libnx_initheap(void) { fake_heap_start = (char*)addr; fake_heap_end = (char*)addr + size; + + InitializeHeaps(); } void __appInit(void) { hos::InitializeForStratosphere(); + fs::SetAllocator(Allocate, Deallocate); + /* Initialize services we need (TODO: NCM) */ sm::DoWithSession([&]() { R_ABORT_UNLESS(fsInitialize()); @@ -107,6 +146,30 @@ void __appExit(void) { fsExit(); } +void *operator new(size_t size) { + return Allocate(size); +} + +void *operator new(size_t size, const std::nothrow_t &) { + return Allocate(size); +} + +void operator delete(void *p) { + return Deallocate(p, 0); +} + +void *operator new[](size_t size) { + return Allocate(size); +} + +void *operator new[](size_t size, const std::nothrow_t &) { + return Allocate(size); +} + +void operator delete[](void *p) { + return Deallocate(p, 0); +} + int main(int argc, char **argv) { /* Set thread name. */ @@ -123,7 +186,7 @@ int main(int argc, char **argv) boot::ChangeGpioVoltageTo1_8v(); /* Setup GPIO. */ - boot::gpio::SetInitialConfiguration(); + gpio::driver::SetInitialGpioConfig(); /* Check USB PLL/UTMIP clock. */ boot::CheckClock(); diff --git a/stratosphere/boot/source/gpio/gpio_initial_configuration.cpp b/stratosphere/boot/source/gpio/gpio_initial_configuration.cpp deleted file mode 100644 index b6525907b..000000000 --- a/stratosphere/boot/source/gpio/gpio_initial_configuration.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2018-2020 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include -#include "gpio_initial_configuration.hpp" -#include "gpio_utils.hpp" - -namespace ams::boot::gpio { - - namespace { - - struct InitialConfig { - u32 pad_name; - GpioDirection direction; - GpioValue value; - }; - - /* Include all initial configuration definitions. */ -#include "gpio_initial_configuration_icosa.inc" -#include "gpio_initial_configuration_copper.inc" -#include "gpio_initial_configuration_hoag.inc" -#include "gpio_initial_configuration_iowa.inc" -#include "gpio_initial_configuration_calcio.inc" - - } - - void SetInitialConfiguration() { - const InitialConfig *configs = nullptr; - size_t num_configs = 0; - const auto hw_type = spl::GetHardwareType(); - const auto hos_ver = hos::GetVersion(); - - /* Choose GPIO map. */ - if (hos_ver >= hos::Version_2_0_0) { - switch (hw_type) { - case spl::HardwareType::Icosa: - { - if (hos_ver >= hos::Version_4_0_0) { - configs = InitialConfigsIcosa4x; - num_configs = NumInitialConfigsIcosa4x; - } else { - configs = InitialConfigsIcosa; - num_configs = NumInitialConfigsIcosa; - } - } - break; - case spl::HardwareType::Copper: - configs = InitialConfigsCopper; - num_configs = NumInitialConfigsCopper; - break; - case spl::HardwareType::Hoag: - configs = InitialConfigsHoag; - num_configs = NumInitialConfigsHoag; - break; - case spl::HardwareType::Iowa: - configs = InitialConfigsIowa; - num_configs = NumInitialConfigsIowa; - break; - case spl::HardwareType::Calcio: - configs = InitialConfigsCalcio; - num_configs = NumInitialConfigsCalcio; - break; - /* Unknown hardware type, we can't proceed. */ - AMS_UNREACHABLE_DEFAULT_CASE(); - } - } else { - /* Until 2.0.0, the GPIO map for Icosa was used for all hardware types. */ - configs = InitialConfigsIcosa; - num_configs = NumInitialConfigsIcosa; - } - - /* Ensure we found an appropriate config. */ - AMS_ABORT_UNLESS(configs != nullptr); - - for (size_t i = 0; i < num_configs; i++) { - /* Configure the GPIO. */ - Configure(configs[i].pad_name); - - /* Set the GPIO's direction. */ - SetDirection(configs[i].pad_name, configs[i].direction); - - if (configs[i].direction == GpioDirection_Output) { - /* Set the GPIO's value. */ - SetValue(configs[i].pad_name, configs[i].value); - } - } - } - -} - diff --git a/stratosphere/boot/source/gpio/gpio_initial_configuration_calcio.inc b/stratosphere/boot/source/gpio/gpio_initial_configuration_calcio.inc deleted file mode 100644 index 0a2f72d5b..000000000 --- a/stratosphere/boot/source/gpio/gpio_initial_configuration_calcio.inc +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2018-2020 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -constexpr InitialConfig InitialConfigsCalcio[] = { - {0x50, GpioDirection_Output, GpioValue_Low}, - {0x51, GpioDirection_Output, GpioValue_Low}, - {0x52, GpioDirection_Output, GpioValue_Low}, - {0x53, GpioDirection_Output, GpioValue_Low}, - {0x02, GpioDirection_Output, GpioValue_Low}, - {0x0B, GpioDirection_Input, GpioValue_Low}, - {0x14, GpioDirection_Input, GpioValue_High}, - {0x18, GpioDirection_Input, GpioValue_Low}, - {0x19, GpioDirection_Input, GpioValue_High}, - {0x1A, GpioDirection_Input, GpioValue_High}, - {0x1C, GpioDirection_Input, GpioValue_High}, - {0x20, GpioDirection_Output, GpioValue_Low}, - {0x38, GpioDirection_Input, GpioValue_High}, - {0x23, GpioDirection_Input, GpioValue_High}, - {0x25, GpioDirection_Input, GpioValue_Low}, - {0x26, GpioDirection_Input, GpioValue_Low}, - {0x27, GpioDirection_Input, GpioValue_Low}, - {0x28, GpioDirection_Input, GpioValue_High}, - {0x4F, GpioDirection_Input, GpioValue_High}, - {0x48, GpioDirection_Output, GpioValue_Low}, - {0x4C, GpioDirection_Input, GpioValue_High}, - {0x4A, GpioDirection_Output, GpioValue_Low}, - {0x2D, GpioDirection_Output, GpioValue_Low}, - {0x2E, GpioDirection_Output, GpioValue_Low}, - {0x37, GpioDirection_Input, GpioValue_Low}, - {0x2F, GpioDirection_Output, GpioValue_Low}, - {0x03, GpioDirection_Output, GpioValue_Low}, - {0x30, GpioDirection_Input, GpioValue_Low}, - {0x31, GpioDirection_Output, GpioValue_Low}, - {0x49, GpioDirection_Output, GpioValue_Low}, - {0x4E, GpioDirection_Input, GpioValue_Low}, -}; - -constexpr u32 NumInitialConfigsCalcio = util::size(InitialConfigsCalcio); diff --git a/stratosphere/boot/source/gpio/gpio_initial_configuration_copper.inc b/stratosphere/boot/source/gpio/gpio_initial_configuration_copper.inc deleted file mode 100644 index 70771f22a..000000000 --- a/stratosphere/boot/source/gpio/gpio_initial_configuration_copper.inc +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2018-2020 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -constexpr InitialConfig InitialConfigsCopper[] = { - {0x40, GpioDirection_Output, GpioValue_Low}, - {0x05, GpioDirection_Output, GpioValue_Low}, - {0x41, GpioDirection_Input, GpioValue_High}, - {0x42, GpioDirection_Input, GpioValue_Low}, - {0x43, GpioDirection_Output, GpioValue_Low}, - {0x02, GpioDirection_Output, GpioValue_Low}, - {0x07, GpioDirection_Output, GpioValue_Low}, - {0x44, GpioDirection_Input, GpioValue_High}, - {0x45, GpioDirection_Input, GpioValue_High}, - {0x0F, GpioDirection_Input, GpioValue_High}, - {0x46, GpioDirection_Output, GpioValue_Low}, - {0x47, GpioDirection_Output, GpioValue_Low}, - {0x10, GpioDirection_Input, GpioValue_Low}, - {0x11, GpioDirection_Input, GpioValue_Low}, - {0x12, GpioDirection_Input, GpioValue_Low}, - {0x13, GpioDirection_Input, GpioValue_Low}, - {0x14, GpioDirection_Input, GpioValue_High}, - {0x18, GpioDirection_Input, GpioValue_Low}, - {0x19, GpioDirection_Input, GpioValue_High}, - {0x1A, GpioDirection_Input, GpioValue_High}, - {0x1C, GpioDirection_Input, GpioValue_High}, - {0x4D, GpioDirection_Output, GpioValue_Low}, - {0x20, GpioDirection_Output, GpioValue_Low}, - {0x38, GpioDirection_Input, GpioValue_High}, - {0x23, GpioDirection_Input, GpioValue_High}, - {0x25, GpioDirection_Input, GpioValue_Low}, - {0x26, GpioDirection_Input, GpioValue_Low}, - {0x27, GpioDirection_Input, GpioValue_Low}, - {0x28, GpioDirection_Input, GpioValue_High}, - {0x29, GpioDirection_Input, GpioValue_High}, - {0x2A, GpioDirection_Input, GpioValue_High}, - {0x48, GpioDirection_Output, GpioValue_Low}, - {0x49, GpioDirection_Output, GpioValue_Low}, - {0x4A, GpioDirection_Output, GpioValue_Low}, - {0x2D, GpioDirection_Output, GpioValue_Low}, - {0x2E, GpioDirection_Output, GpioValue_Low}, - {0x37, GpioDirection_Input, GpioValue_Low}, - {0x2F, GpioDirection_Output, GpioValue_Low}, - {0x03, GpioDirection_Output, GpioValue_Low}, - {0x30, GpioDirection_Input, GpioValue_Low}, - {0x31, GpioDirection_Output, GpioValue_Low}, - {0x4B, GpioDirection_Output, GpioValue_Low}, - {0x4C, GpioDirection_Input, GpioValue_High}, - {0x4E, GpioDirection_Input, GpioValue_Low}, -}; - -constexpr u32 NumInitialConfigsCopper = util::size(InitialConfigsCopper); diff --git a/stratosphere/boot/source/gpio/gpio_initial_configuration_hoag.inc b/stratosphere/boot/source/gpio/gpio_initial_configuration_hoag.inc deleted file mode 100644 index 8e18daf4b..000000000 --- a/stratosphere/boot/source/gpio/gpio_initial_configuration_hoag.inc +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2018-2020 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -constexpr InitialConfig InitialConfigsHoag[] = { - {0x05, GpioDirection_Output, GpioValue_Low}, - {0x06, GpioDirection_Input, GpioValue_Low}, - {0x50, GpioDirection_Output, GpioValue_Low}, - {0x51, GpioDirection_Output, GpioValue_Low}, - {0x52, GpioDirection_Output, GpioValue_Low}, - {0x53, GpioDirection_Output, GpioValue_Low}, - {0x02, GpioDirection_Output, GpioValue_Low}, - {0x3C, GpioDirection_Input, GpioValue_Low}, - {0x56, GpioDirection_Input, GpioValue_High}, - {0x0F, GpioDirection_Input, GpioValue_High}, - {0x09, GpioDirection_Input, GpioValue_Low}, - {0x0A, GpioDirection_Output, GpioValue_Low}, - {0x0B, GpioDirection_Input, GpioValue_Low}, - {0x57, GpioDirection_Output, GpioValue_Low}, - {0x58, GpioDirection_Output, GpioValue_Low}, - {0x0D, GpioDirection_Output, GpioValue_Low}, - {0x59, GpioDirection_Output, GpioValue_Low}, - {0x14, GpioDirection_Input, GpioValue_High}, - {0x16, GpioDirection_Input, GpioValue_Low}, - {0x15, GpioDirection_Input, GpioValue_Low}, - {0x17, GpioDirection_Input, GpioValue_High}, - {0x18, GpioDirection_Input, GpioValue_Low}, - {0x19, GpioDirection_Input, GpioValue_High}, - {0x1A, GpioDirection_Input, GpioValue_High}, - {0x1B, GpioDirection_Input, GpioValue_Low}, - {0x1C, GpioDirection_Input, GpioValue_High}, - {0x1D, GpioDirection_Output, GpioValue_Low}, - {0x1E, GpioDirection_Output, GpioValue_Low}, - {0x5B, GpioDirection_Input, GpioValue_High}, - {0x20, GpioDirection_Output, GpioValue_Low}, - {0x21, GpioDirection_Input, GpioValue_Low}, - {0x38, GpioDirection_Input, GpioValue_High}, - {0x23, GpioDirection_Input, GpioValue_High}, - {0x01, GpioDirection_Output, GpioValue_Low}, - {0x5C, GpioDirection_Output, GpioValue_Low}, - {0x54, GpioDirection_Input, GpioValue_Low}, - {0x24, GpioDirection_Output, GpioValue_Low}, - {0x25, GpioDirection_Input, GpioValue_Low}, - {0x26, GpioDirection_Input, GpioValue_Low}, - {0x27, GpioDirection_Input, GpioValue_Low}, - {0x28, GpioDirection_Input, GpioValue_High}, - {0x1F, GpioDirection_Output, GpioValue_Low}, - {0x4F, GpioDirection_Input, GpioValue_High}, - {0x55, GpioDirection_Output, GpioValue_Low}, - {0x5F, GpioDirection_Input, GpioValue_Low}, - {0x60, GpioDirection_Input, GpioValue_Low}, - {0x61, GpioDirection_Input, GpioValue_Low}, - {0x62, GpioDirection_Input, GpioValue_Low}, - {0x2D, GpioDirection_Output, GpioValue_Low}, - {0x2E, GpioDirection_Output, GpioValue_Low}, - {0x37, GpioDirection_Input, GpioValue_Low}, - {0x2F, GpioDirection_Output, GpioValue_Low}, - {0x03, GpioDirection_Output, GpioValue_Low}, - {0x30, GpioDirection_Input, GpioValue_Low}, - {0x3B, GpioDirection_Input, GpioValue_Low}, - {0x31, GpioDirection_Output, GpioValue_Low}, - {0x32, GpioDirection_Output, GpioValue_Low}, - {0x33, GpioDirection_Output, GpioValue_Low}, - {0x5A, GpioDirection_Output, GpioValue_Low}, -}; - -constexpr u32 NumInitialConfigsHoag = util::size(InitialConfigsHoag); diff --git a/stratosphere/boot/source/gpio/gpio_initial_configuration_icosa.inc b/stratosphere/boot/source/gpio/gpio_initial_configuration_icosa.inc deleted file mode 100644 index 06a80f49e..000000000 --- a/stratosphere/boot/source/gpio/gpio_initial_configuration_icosa.inc +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2018-2020 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -constexpr InitialConfig InitialConfigsIcosa[] = { - {0x04, GpioDirection_Input, GpioValue_High}, - {0x05, GpioDirection_Output, GpioValue_Low}, - {0x06, GpioDirection_Input, GpioValue_Low}, - {0x02, GpioDirection_Output, GpioValue_Low}, - {0x07, GpioDirection_Output, GpioValue_Low}, - {0x3C, GpioDirection_Input, GpioValue_Low}, - {0x0F, GpioDirection_Input, GpioValue_High}, - {0x08, GpioDirection_Input, GpioValue_Low}, - {0x09, GpioDirection_Input, GpioValue_Low}, - {0x0A, GpioDirection_Output, GpioValue_Low}, - {0x0B, GpioDirection_Input, GpioValue_High}, - {0x0D, GpioDirection_Output, GpioValue_Low}, - {0x0E, GpioDirection_Input, GpioValue_Low}, - {0x10, GpioDirection_Input, GpioValue_Low}, - {0x11, GpioDirection_Input, GpioValue_Low}, - {0x12, GpioDirection_Input, GpioValue_Low}, - {0x13, GpioDirection_Input, GpioValue_Low}, - {0x14, GpioDirection_Input, GpioValue_High}, - {0x16, GpioDirection_Input, GpioValue_Low}, - {0x15, GpioDirection_Input, GpioValue_Low}, - {0x17, GpioDirection_Input, GpioValue_High}, - {0x18, GpioDirection_Input, GpioValue_Low}, - {0x19, GpioDirection_Input, GpioValue_High}, - {0x1A, GpioDirection_Input, GpioValue_High}, - {0x1B, GpioDirection_Input, GpioValue_High}, - {0x1C, GpioDirection_Input, GpioValue_Low}, - {0x1D, GpioDirection_Output, GpioValue_Low}, - {0x1E, GpioDirection_Output, GpioValue_Low}, - {0x20, GpioDirection_Output, GpioValue_Low}, - {0x21, GpioDirection_Input, GpioValue_High}, - {0x38, GpioDirection_Input, GpioValue_High}, - {0x22, GpioDirection_Input, GpioValue_Low}, - {0x23, GpioDirection_Input, GpioValue_High}, - {0x01, GpioDirection_Output, GpioValue_Low}, - {0x39, GpioDirection_Output, GpioValue_Low}, - {0x24, GpioDirection_Output, GpioValue_Low}, - {0x34, GpioDirection_Input, GpioValue_Low}, - {0x25, GpioDirection_Input, GpioValue_Low}, - {0x26, GpioDirection_Input, GpioValue_Low}, - {0x27, GpioDirection_Input, GpioValue_Low}, - {0x2B, GpioDirection_Output, GpioValue_Low}, - {0x28, GpioDirection_Input, GpioValue_High}, - {0x1F, GpioDirection_Output, GpioValue_Low}, - {0x29, GpioDirection_Input, GpioValue_High}, - {0x2A, GpioDirection_Input, GpioValue_High}, - {0x3A, GpioDirection_Output, GpioValue_Low}, - {0x0C, GpioDirection_Input, GpioValue_Low}, - {0x2D, GpioDirection_Output, GpioValue_Low}, - {0x2E, GpioDirection_Output, GpioValue_Low}, - {0x37, GpioDirection_Input, GpioValue_Low}, - {0x2F, GpioDirection_Output, GpioValue_Low}, - {0x03, GpioDirection_Output, GpioValue_Low}, - {0x30, GpioDirection_Input, GpioValue_Low}, - {0x3B, GpioDirection_Input, GpioValue_Low}, - {0x31, GpioDirection_Output, GpioValue_Low}, - {0x32, GpioDirection_Output, GpioValue_Low}, - {0x33, GpioDirection_Output, GpioValue_Low}, - {0x35, GpioDirection_Input, GpioValue_High}, - {0x2C, GpioDirection_Output, GpioValue_Low}, - {0x36, GpioDirection_Output, GpioValue_Low}, -}; - -constexpr u32 NumInitialConfigsIcosa = util::size(InitialConfigsIcosa); - -constexpr InitialConfig InitialConfigsIcosa4x[] = { - {0x04, GpioDirection_Input, GpioValue_High}, - {0x05, GpioDirection_Output, GpioValue_Low}, - {0x06, GpioDirection_Input, GpioValue_Low}, - {0x02, GpioDirection_Output, GpioValue_Low}, - {0x07, GpioDirection_Output, GpioValue_Low}, - {0x3C, GpioDirection_Input, GpioValue_Low}, - {0x0F, GpioDirection_Input, GpioValue_High}, - {0x08, GpioDirection_Input, GpioValue_Low}, - {0x09, GpioDirection_Input, GpioValue_Low}, - {0x0A, GpioDirection_Output, GpioValue_Low}, - {0x0B, GpioDirection_Input, GpioValue_High}, - {0x0D, GpioDirection_Output, GpioValue_Low}, - {0x0E, GpioDirection_Input, GpioValue_Low}, - {0x10, GpioDirection_Input, GpioValue_Low}, - {0x11, GpioDirection_Input, GpioValue_Low}, - {0x12, GpioDirection_Input, GpioValue_Low}, - {0x13, GpioDirection_Input, GpioValue_Low}, - {0x14, GpioDirection_Input, GpioValue_High}, - {0x16, GpioDirection_Input, GpioValue_Low}, - {0x15, GpioDirection_Input, GpioValue_Low}, - {0x17, GpioDirection_Input, GpioValue_High}, - {0x18, GpioDirection_Input, GpioValue_High}, - {0x19, GpioDirection_Input, GpioValue_High}, - {0x1A, GpioDirection_Input, GpioValue_High}, - {0x1B, GpioDirection_Input, GpioValue_High}, - {0x1C, GpioDirection_Input, GpioValue_Low}, - {0x1D, GpioDirection_Output, GpioValue_Low}, - {0x1E, GpioDirection_Output, GpioValue_Low}, - {0x20, GpioDirection_Output, GpioValue_Low}, - {0x21, GpioDirection_Input, GpioValue_High}, - {0x38, GpioDirection_Input, GpioValue_High}, - {0x22, GpioDirection_Input, GpioValue_Low}, - {0x23, GpioDirection_Input, GpioValue_High}, - {0x01, GpioDirection_Output, GpioValue_Low}, - {0x39, GpioDirection_Output, GpioValue_Low}, - {0x24, GpioDirection_Output, GpioValue_Low}, - {0x34, GpioDirection_Input, GpioValue_Low}, - {0x25, GpioDirection_Input, GpioValue_Low}, - {0x26, GpioDirection_Input, GpioValue_Low}, - {0x27, GpioDirection_Input, GpioValue_Low}, - {0x2B, GpioDirection_Output, GpioValue_Low}, - {0x28, GpioDirection_Input, GpioValue_High}, - {0x1F, GpioDirection_Output, GpioValue_Low}, - {0x29, GpioDirection_Input, GpioValue_High}, - {0x2A, GpioDirection_Input, GpioValue_High}, - {0x3A, GpioDirection_Output, GpioValue_Low}, - {0x0C, GpioDirection_Input, GpioValue_Low}, - {0x2D, GpioDirection_Output, GpioValue_Low}, - {0x2E, GpioDirection_Output, GpioValue_Low}, - {0x37, GpioDirection_Input, GpioValue_Low}, - {0x2F, GpioDirection_Output, GpioValue_Low}, - {0x03, GpioDirection_Output, GpioValue_Low}, - {0x30, GpioDirection_Input, GpioValue_Low}, - {0x3B, GpioDirection_Input, GpioValue_Low}, - {0x31, GpioDirection_Output, GpioValue_Low}, - {0x32, GpioDirection_Output, GpioValue_Low}, - {0x33, GpioDirection_Output, GpioValue_Low}, - {0x35, GpioDirection_Input, GpioValue_High}, - {0x2C, GpioDirection_Output, GpioValue_Low}, - {0x36, GpioDirection_Output, GpioValue_Low}, -}; - -constexpr u32 NumInitialConfigsIcosa4x = util::size(InitialConfigsIcosa4x); diff --git a/stratosphere/boot/source/gpio/gpio_initial_configuration_iowa.inc b/stratosphere/boot/source/gpio/gpio_initial_configuration_iowa.inc deleted file mode 100644 index f0a017897..000000000 --- a/stratosphere/boot/source/gpio/gpio_initial_configuration_iowa.inc +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2018-2020 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -constexpr InitialConfig InitialConfigsIowa[] = { - {0x04, GpioDirection_Input, GpioValue_High}, - {0x05, GpioDirection_Output, GpioValue_Low}, - {0x06, GpioDirection_Input, GpioValue_Low}, - {0x02, GpioDirection_Output, GpioValue_Low}, - {0x3C, GpioDirection_Input, GpioValue_Low}, - {0x0F, GpioDirection_Input, GpioValue_High}, - {0x08, GpioDirection_Input, GpioValue_Low}, - {0x09, GpioDirection_Input, GpioValue_Low}, - {0x0A, GpioDirection_Output, GpioValue_Low}, - {0x0B, GpioDirection_Input, GpioValue_Low}, - {0x0D, GpioDirection_Output, GpioValue_Low}, - {0x0E, GpioDirection_Input, GpioValue_Low}, - {0x10, GpioDirection_Input, GpioValue_Low}, - {0x11, GpioDirection_Input, GpioValue_Low}, - {0x12, GpioDirection_Input, GpioValue_Low}, - {0x13, GpioDirection_Input, GpioValue_Low}, - {0x59, GpioDirection_Output, GpioValue_Low}, - {0x14, GpioDirection_Input, GpioValue_High}, - {0x16, GpioDirection_Input, GpioValue_Low}, - {0x15, GpioDirection_Input, GpioValue_Low}, - {0x17, GpioDirection_Input, GpioValue_High}, - {0x18, GpioDirection_Input, GpioValue_Low}, - {0x19, GpioDirection_Input, GpioValue_High}, - {0x1A, GpioDirection_Input, GpioValue_High}, - {0x1B, GpioDirection_Input, GpioValue_Low}, - {0x1C, GpioDirection_Input, GpioValue_Low}, - {0x1D, GpioDirection_Output, GpioValue_Low}, - {0x1E, GpioDirection_Output, GpioValue_Low}, - {0x20, GpioDirection_Output, GpioValue_Low}, - {0x21, GpioDirection_Input, GpioValue_Low}, - {0x38, GpioDirection_Input, GpioValue_High}, - {0x22, GpioDirection_Input, GpioValue_Low}, - {0x23, GpioDirection_Input, GpioValue_High}, - {0x01, GpioDirection_Output, GpioValue_Low}, - {0x39, GpioDirection_Output, GpioValue_Low}, - {0x24, GpioDirection_Output, GpioValue_Low}, - {0x34, GpioDirection_Input, GpioValue_Low}, - {0x25, GpioDirection_Input, GpioValue_Low}, - {0x26, GpioDirection_Input, GpioValue_Low}, - {0x27, GpioDirection_Input, GpioValue_Low}, - {0x2B, GpioDirection_Output, GpioValue_Low}, - {0x28, GpioDirection_Input, GpioValue_High}, - {0x1F, GpioDirection_Output, GpioValue_Low}, - {0x4F, GpioDirection_Input, GpioValue_High}, - {0x3A, GpioDirection_Output, GpioValue_Low}, - {0x0C, GpioDirection_Input, GpioValue_Low}, - {0x2D, GpioDirection_Output, GpioValue_Low}, - {0x2E, GpioDirection_Output, GpioValue_Low}, - {0x37, GpioDirection_Input, GpioValue_Low}, - {0x2F, GpioDirection_Output, GpioValue_Low}, - {0x03, GpioDirection_Output, GpioValue_Low}, - {0x30, GpioDirection_Input, GpioValue_Low}, - {0x3B, GpioDirection_Input, GpioValue_Low}, - {0x31, GpioDirection_Output, GpioValue_Low}, - {0x32, GpioDirection_Output, GpioValue_Low}, - {0x33, GpioDirection_Output, GpioValue_Low}, - {0x35, GpioDirection_Input, GpioValue_High}, - {0x2C, GpioDirection_Output, GpioValue_Low}, - {0x36, GpioDirection_Output, GpioValue_Low}, -}; - -constexpr u32 NumInitialConfigsIowa = util::size(InitialConfigsIowa); diff --git a/stratosphere/boot/source/gpio/gpio_map.inc b/stratosphere/boot/source/gpio/gpio_map.inc deleted file mode 100644 index d4c9397e3..000000000 --- a/stratosphere/boot/source/gpio/gpio_map.inc +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2018-2020 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -constexpr u32 InvalidPadName = std::numeric_limits::max(); - -constexpr u32 Map[] = { - InvalidPadName, /* Invalid */ - 0x000000CC, /* Port Z, Pin 4 */ - 0x00000024, /* Port E, Pin 4 */ - 0x0000003C, /* Port H, Pin 4 */ - 0x000000DA, /* Port BB, Pin 2 */ - 0x000000DB, /* Port BB, Pin 3 */ - 0x000000DC, /* Port BB, Pin 4 */ - 0x00000025, /* Port E, Pin 5 */ - 0x00000090, /* Port S, Pin 0 */ - 0x00000091, /* Port S, Pin 1 */ - 0x00000096, /* Port S, Pin 6 */ - 0x00000097, /* Port S, Pin 7 */ - 0x00000026, /* Port E, Pin 6 */ - 0x00000005, /* Port A, Pin 5 */ - 0x00000078, /* Port P, Pin 0 */ - 0x00000093, /* Port S, Pin 3 */ - 0x0000007D, /* Port P, Pin 5 */ - 0x0000007C, /* Port P, Pin 4 */ - 0x0000007B, /* Port P, Pin 3 */ - 0x0000007A, /* Port P, Pin 2 */ - 0x000000BC, /* Port X, Pin 4 */ - 0x000000AE, /* Port V, Pin 6 */ - 0x000000BA, /* Port X, Pin 2 */ - 0x000000B9, /* Port X, Pin 1 */ - 0x000000BD, /* Port X, Pin 5 */ - 0x000000BE, /* Port X, Pin 6 */ - 0x000000BF, /* Port X, Pin 7 */ - 0x000000C0, /* Port Y, Pin 0 */ - 0x000000C1, /* Port Y, Pin 1 */ - 0x000000A9, /* Port V, Pin 1 */ - 0x000000AA, /* Port V, Pin 2 */ - 0x00000055, /* Port K, Pin 5 */ - 0x000000AD, /* Port V, Pin 5 */ - 0x000000C8, /* Port Z, Pin 0 */ - 0x000000CA, /* Port Z, Pin 2 */ - 0x000000CB, /* Port Z, Pin 3 */ - 0x0000004F, /* Port J, Pin 7 */ - 0x00000050, /* Port K, Pin 0 */ - 0x00000051, /* Port K, Pin 1 */ - 0x00000052, /* Port K, Pin 2 */ - 0x00000054, /* Port K, Pin 4 */ - 0x00000056, /* Port K, Pin 6 */ - 0x00000057, /* Port K, Pin 7 */ - 0x00000053, /* Port K, Pin 3 */ - 0x000000E3, /* Port CC, Pin 3 */ - 0x00000038, /* Port H, Pin 0 */ - 0x00000039, /* Port H, Pin 1 */ - 0x0000003B, /* Port H, Pin 3 */ - 0x0000003D, /* Port H, Pin 5 */ - 0x0000003F, /* Port H, Pin 7 */ - 0x00000040, /* Port I, Pin 0 */ - 0x00000041, /* Port I, Pin 1 */ - 0x0000003E, /* Port H, Pin 6 */ - 0x000000E2, /* Port CC, Pin 2 */ - 0x000000E4, /* Port CC, Pin 4 */ - 0x0000003A, /* Port H, Pin 2 */ - 0x000000C9, /* Port Z, Pin 1 */ - 0x0000004D, /* Port J, Pin 5 */ - 0x00000058, /* Port L, Pin 0 */ - 0x0000003E, /* Port H, Pin 6 */ - 0x00000026, /* Port E, Pin 6 */ - - /* Copper only */ - InvalidPadName, /* Invalid */ - 0x00000033, /* Port G, Pin 3 */ - 0x0000001C, /* Port D, Pin 4 */ - 0x000000D9, /* Port BB, Pin 1 */ - 0x0000000C, /* Port B, Pin 4 */ - 0x0000000D, /* Port B, Pin 5 */ - 0x00000021, /* Port E, Pin 1 */ - 0x00000027, /* Port E, Pin 7 */ - 0x00000092, /* Port S, Pin 2 */ - 0x00000095, /* Port S, Pin 5 */ - 0x00000098, /* Port T, Pin 0 */ - 0x00000010, /* Port C, Pin 0 */ - 0x00000011, /* Port C, Pin 1 */ - 0x00000012, /* Port C, Pin 2 */ - 0x00000042, /* Port I, Pin 2 */ - 0x000000E6, /* Port CC, Pin 6 */ - - /* 2.0.0+ Copper only */ - 0x000000AC, /* Port V, Pin 4 */ - 0x000000E1, /* Port CC, Pin 1 */ - - /* 5.0.0+ Copper only (unused) */ - 0x00000056, /* Port K, Pin 6 */ - - /* 6.0.0+ */ - 0x00000020, /* Port E, Pin 0 */ - 0x00000021, /* Port E, Pin 1 */ - 0x00000022, /* Port E, Pin 2 */ - 0x00000023, /* Port E, Pin 3 */ - 0x0000004C, /* Port J, Pin 4 */ - 0x00000057, /* Port K, Pin 7 */ - 0x00000027, /* Port S, Pin 4 */ - 0x00000098, /* Port T, Pin 0 */ - 0x00000099, /* Port T, Pin 1 */ - 0x000000BB, /* Port X, Pin 3 */ - 0x000000E5, /* Port CC, Pin 5 */ - 0x000000AB, /* Port V, Pin 3 */ - 0x0000004E, /* Port J, Pin 6 */ - - /* 7.0.0+ */ - 0x00000032, /* Port G, Pin 2 */ - 0x0000001B, /* Port D, Pin 3 */ - 0x00000017, /* Port C, Pin 7 */ - 0x00000018, /* Port D, Pin 0 */ - 0x00000015, /* Port C, Pin 5 */ - 0x00000016, /* Port C, Pin 6 */ - -}; - -static constexpr u32 PadNameMax = util::size(Map); diff --git a/stratosphere/boot/source/gpio/gpio_utils.cpp b/stratosphere/boot/source/gpio/gpio_utils.cpp deleted file mode 100644 index 4bd21f1b9..000000000 --- a/stratosphere/boot/source/gpio/gpio_utils.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2018-2020 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include -#include "gpio_utils.hpp" - -namespace ams::boot::gpio { - - namespace { - - /* Pull in GPIO map definitions. */ -#include "gpio_map.inc" - - constexpr u32 PhysicalBase = 0x6000D000; - - /* Globals. */ - bool g_initialized_gpio_vaddr = false; - uintptr_t g_gpio_vaddr = 0; - - /* Helpers. */ - inline u32 GetPadDescriptor(u32 gpio_pad_name) { - AMS_ABORT_UNLESS(gpio_pad_name < PadNameMax); - return Map[gpio_pad_name]; - } - - uintptr_t GetBaseAddress() { - if (!g_initialized_gpio_vaddr) { - g_gpio_vaddr = dd::GetIoMapping(PhysicalBase, os::MemoryPageSize); - g_initialized_gpio_vaddr = true; - } - return g_gpio_vaddr; - } - - - } - - u32 Configure(u32 gpio_pad_name) { - uintptr_t gpio_base_vaddr = GetBaseAddress(); - - /* Fetch this GPIO's pad descriptor */ - const u32 gpio_pad_desc = GetPadDescriptor(gpio_pad_name); - - /* Discard invalid GPIOs */ - if (gpio_pad_desc == InvalidPadName) { - return InvalidPadName; - } - - /* Convert the GPIO pad descriptor into its register offset */ - u32 gpio_reg_offset = (((gpio_pad_desc << 0x03) & 0xFFFFFF00) | ((gpio_pad_desc >> 0x01) & 0x0C)); - - /* Extract the bit and lock values from the GPIO pad descriptor */ - u32 gpio_cnf_val = ((0x01 << ((gpio_pad_desc & 0x07) | 0x08)) | (0x01 << (gpio_pad_desc & 0x07))); - - /* Write to the appropriate GPIO_CNF_x register (upper offset) */ - reg::Write(gpio_base_vaddr + gpio_reg_offset + 0x80, gpio_cnf_val); - - /* Do a dummy read from GPIO_CNF_x register (lower offset) */ - gpio_cnf_val = reg::Read(gpio_base_vaddr + gpio_reg_offset + 0x00); - - return gpio_cnf_val; - } - - u32 SetDirection(u32 gpio_pad_name, GpioDirection dir) { - uintptr_t gpio_base_vaddr = GetBaseAddress(); - - /* Fetch this GPIO's pad descriptor */ - const u32 gpio_pad_desc = GetPadDescriptor(gpio_pad_name); - - /* Discard invalid GPIOs */ - if (gpio_pad_desc == InvalidPadName) { - return InvalidPadName; - } - - /* Convert the GPIO pad descriptor into its register offset */ - u32 gpio_reg_offset = (((gpio_pad_desc << 0x03) & 0xFFFFFF00) | ((gpio_pad_desc >> 0x01) & 0x0C)); - - /* Set the direction bit and lock values */ - u32 gpio_oe_val = ((0x01 << ((gpio_pad_desc & 0x07) | 0x08)) | (static_cast(dir) << (gpio_pad_desc & 0x07))); - - /* Write to the appropriate GPIO_OE_x register (upper offset) */ - reg::Write(gpio_base_vaddr + gpio_reg_offset + 0x90, gpio_oe_val); - - /* Do a dummy read from GPIO_OE_x register (lower offset) */ - gpio_oe_val = reg::Read(gpio_base_vaddr + gpio_reg_offset + 0x10); - - return gpio_oe_val; - } - - u32 SetValue(u32 gpio_pad_name, GpioValue val) { - uintptr_t gpio_base_vaddr = GetBaseAddress(); - - /* Fetch this GPIO's pad descriptor */ - const u32 gpio_pad_desc = GetPadDescriptor(gpio_pad_name); - - /* Discard invalid GPIOs */ - if (gpio_pad_desc == InvalidPadName) { - return InvalidPadName; - } - - /* Convert the GPIO pad descriptor into its register offset */ - u32 gpio_reg_offset = (((gpio_pad_desc << 0x03) & 0xFFFFFF00) | ((gpio_pad_desc >> 0x01) & 0x0C)); - - /* Set the output bit and lock values */ - u32 gpio_out_val = ((0x01 << ((gpio_pad_desc & 0x07) | 0x08)) | (static_cast(val) << (gpio_pad_desc & 0x07))); - - /* Write to the appropriate GPIO_OUT_x register (upper offset) */ - reg::Write(gpio_base_vaddr + gpio_reg_offset + 0xA0, gpio_out_val); - - /* Do a dummy read from GPIO_OUT_x register (lower offset) */ - gpio_out_val = reg::Read(gpio_base_vaddr + gpio_reg_offset + 0x20); - - return gpio_out_val; - } - -}