diff --git a/libexosphere/source/i2c/i2c_api.cpp b/libexosphere/source/i2c/i2c_api.cpp
index baafacc9..40900ff2 100644
--- a/libexosphere/source/i2c/i2c_api.cpp
+++ b/libexosphere/source/i2c/i2c_api.cpp
@@ -14,7 +14,6 @@
* along with this program. If not, see .
*/
#include
-#include "i2c_registers.hpp"
namespace ams::i2c {
diff --git a/libexosphere/source/i2c/i2c_registers.hpp b/libexosphere/source/i2c/i2c_registers.hpp
deleted file mode 100644
index 48f65957..00000000
--- a/libexosphere/source/i2c/i2c_registers.hpp
+++ /dev/null
@@ -1,77 +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
-
-namespace ams::i2c {
-
- #define I2C_I2C_CNFG (0x000)
- #define I2C_I2C_CMD_ADDR0 (0x004)
- #define I2C_I2C_CMD_DATA1 (0x00C)
- #define I2C_I2C_STATUS (0x01C)
- #define I2C_INTERRUPT_STATUS_REGISTER (0x068)
- #define I2C_CLK_DIVISOR_REGISTER (0x06C)
- #define I2C_BUS_CLEAR_CONFIG (0x084)
- #define I2C_BUS_CLEAR_STATUS (0x088)
- #define I2C_CONFIG_LOAD (0x08C)
-
- #define I2C_REG_BITS_MASK(NAME) REG_NAMED_BITS_MASK (I2C, NAME)
- #define I2C_REG_BITS_VALUE(NAME, VALUE) REG_NAMED_BITS_VALUE (I2C, NAME, VALUE)
- #define I2C_REG_BITS_ENUM(NAME, ENUM) REG_NAMED_BITS_ENUM (I2C, NAME, ENUM)
- #define I2C_REG_BITS_ENUM_SEL(NAME, __COND__, TRUE_ENUM, FALSE_ENUM) REG_NAMED_BITS_ENUM_SEL(I2C, NAME, __COND__, TRUE_ENUM, FALSE_ENUM)
-
- #define DEFINE_I2C_REG(NAME, __OFFSET__, __WIDTH__) REG_DEFINE_NAMED_REG (I2C, NAME, __OFFSET__, __WIDTH__)
- #define DEFINE_I2C_REG_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE) REG_DEFINE_NAMED_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE)
- #define DEFINE_I2C_REG_TWO_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE) REG_DEFINE_NAMED_TWO_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE)
- #define DEFINE_I2C_REG_THREE_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN) REG_DEFINE_NAMED_THREE_BIT_ENUM(I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN)
- #define DEFINE_I2C_REG_FOUR_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN) REG_DEFINE_NAMED_FOUR_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN)
-
- /* I2C_CNFG */
- DEFINE_I2C_REG(I2C_CNFG_LENGTH, 1, 3);
- DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_CMD1, 6, WRITE, READ);
- DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_SEND, 9, NOP, GO);
- DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_NEW_MASTER_FSM, 11, DISABLE, ENABLE);
- DEFINE_I2C_REG_THREE_BIT_ENUM(I2C_CNFG_DEBOUNCE_CNT, 12, NO_DEBOUNCE, DEBOUNCE_2T, DEBOUNCE_4T, DEBOUNCE_6T, DEBOUNCE_8T, DEBOUNCE_10T, DEBOUNCE_12T, DEBOUNCE_14T);
-
- /* I2C_CMD_ADDR0 */
- DEFINE_I2C_REG_BIT_ENUM(I2C_CMD_ADDR0_7BIT_RW, 0, WRITE, READ);
- DEFINE_I2C_REG(I2C_CMD_ADDR0_7BIT_ADDR, 1, 7);
-
- /* I2C_STATUS */
- DEFINE_I2C_REG_FOUR_BIT_ENUM(I2C_STATUS_CMD1_STAT, 0, SL1_XFER_SUCCESSFUL, SL1_NOACK_FOR_BYTE1, SL1_NOACK_FOR_BYTE2, SL1_NOACK_FOR_BYTE3, SL1_NOACK_FOR_BYTE4, SL1_NOACK_FOR_BYTE5, SL1_NOACK_FOR_BYTE6, SL1_NOACK_FOR_BYTE7, SL1_NOACK_FOR_BYTE8, SL1_NOACK_FOR_BYTE9, SL1_NOACK_FOR_BYTE10, RESERVED11, RESERVED12, RESERVED13, RESERVED14, RESERVED15);
- DEFINE_I2C_REG_FOUR_BIT_ENUM(I2C_STATUS_CMD2_STAT, 4, SL2_XFER_SUCCESSFUL, SL2_NOACK_FOR_BYTE1, SL2_NOACK_FOR_BYTE2, SL2_NOACK_FOR_BYTE3, SL2_NOACK_FOR_BYTE4, SL2_NOACK_FOR_BYTE5, SL2_NOACK_FOR_BYTE6, SL2_NOACK_FOR_BYTE7, SL2_NOACK_FOR_BYTE8, SL2_NOACK_FOR_BYTE9, SL2_NOACK_FOR_BYTE10, RESERVED11, RESERVED12, RESERVED13, RESERVED14, RESERVED15);
- DEFINE_I2C_REG_BIT_ENUM(I2C_STATUS_BUSY, 8, NOT_BUSY, BUSY);
-
- /* INTERRUPT_STATUS_REGISTER */
- DEFINE_I2C_REG_BIT_ENUM(INTERRUPT_STATUS_REGISTER_BUS_CLEAR_DONE, 11, UNSET, SET);
-
- /* CLK_DIVISOR_REGISTER */
- DEFINE_I2C_REG(CLK_DIVISOR_REGISTER_HSMODE, 0, 16);
- DEFINE_I2C_REG(CLK_DIVISOR_REGISTER_STD_FAST_MODE, 16, 16);
-
- /* BUS_CLEAR_CONFIG */
- DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_ENABLE, 0, DISABLE, ENABLE);
- DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_TERMINATE, 1, THRESHOLD, IMMEDIATE);
- DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_STOP_COND, 2, NO_STOP, STOP);
- DEFINE_I2C_REG(BUS_CLEAR_CONFIG_BC_SCLK_THRESHOLD, 16, 8);
-
- /* CONFIG_LOAD */
- DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_MSTR_CONFIG_LOAD, 0, DISABLE, ENABLE);
- DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_SLV_CONFIG_LOAD, 1, DISABLE, ENABLE);
- DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_TIMEOUT_CONFIG_LOAD, 2, DISABLE, ENABLE);
- DEFINE_I2C_REG(CONFIG_LOAD_RESERVED_BIT_5, 5, 1);
-
-
-}
diff --git a/libstratosphere/include/stratosphere.hpp b/libstratosphere/include/stratosphere.hpp
index acddbab1..778b186b 100644
--- a/libstratosphere/include/stratosphere.hpp
+++ b/libstratosphere/include/stratosphere.hpp
@@ -43,6 +43,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -63,6 +64,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
diff --git a/libstratosphere/include/stratosphere/clkrst.hpp b/libstratosphere/include/stratosphere/clkrst.hpp
new file mode 100644
index 00000000..45f3d6f0
--- /dev/null
+++ b/libstratosphere/include/stratosphere/clkrst.hpp
@@ -0,0 +1,21 @@
+/*
+ * 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
diff --git a/libstratosphere/include/stratosphere/clkrst/clkrst_api.hpp b/libstratosphere/include/stratosphere/clkrst/clkrst_api.hpp
new file mode 100644
index 00000000..69f4e7cb
--- /dev/null
+++ b/libstratosphere/include/stratosphere/clkrst/clkrst_api.hpp
@@ -0,0 +1,25 @@
+/*
+ * 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::clkrst {
+
+ void Initialize();
+ void Finalize();
+
+}
diff --git a/libstratosphere/include/stratosphere/clkrst/clkrst_session_api.hpp b/libstratosphere/include/stratosphere/clkrst/clkrst_session_api.hpp
new file mode 100644
index 00000000..3ca34615
--- /dev/null
+++ b/libstratosphere/include/stratosphere/clkrst/clkrst_session_api.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
+#include
+
+namespace ams::clkrst {
+
+ struct ClkRstSession {
+ void *_session;
+ };
+
+ Result OpenSession(ClkRstSession *out, DeviceCode device_code);
+ void CloseSession(ClkRstSession *session);
+
+ void SetResetAsserted(ClkRstSession *session);
+ void SetResetDeasserted(ClkRstSession *session);
+
+ void SetClockRate(ClkRstSession *session, u32 hz);
+
+ void SetClockDisabled(ClkRstSession *session);
+
+}
diff --git a/libstratosphere/include/stratosphere/clkrst/clkrst_types.hpp b/libstratosphere/include/stratosphere/clkrst/clkrst_types.hpp
new file mode 100644
index 00000000..7c234ca1
--- /dev/null
+++ b/libstratosphere/include/stratosphere/clkrst/clkrst_types.hpp
@@ -0,0 +1,23 @@
+/*
+ * 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::clkrst {
+
+ /* ... */
+
+}
diff --git a/libstratosphere/include/stratosphere/i2c/driver/i2c_i_i2c_driver.hpp b/libstratosphere/include/stratosphere/i2c/driver/i2c_i_i2c_driver.hpp
index 9343b3f3..867234a5 100644
--- a/libstratosphere/include/stratosphere/i2c/driver/i2c_i_i2c_driver.hpp
+++ b/libstratosphere/include/stratosphere/i2c/driver/i2c_i_i2c_driver.hpp
@@ -33,19 +33,19 @@ namespace ams::i2c::driver {
virtual void InitializeDriver() = 0;
virtual void FinalizeDriver() = 0;
- virtual Result Open() = 0;
- virtual void Close() = 0;
+ virtual Result InitializeDevice(I2cDeviceProperty *device) = 0;
+ virtual void FinalizeDevice(I2cDeviceProperty *device) = 0;
virtual Result Send(I2cDeviceProperty *device, const void *src, size_t src_size, TransactionOption option) = 0;
virtual Result Receive(void *dst, size_t dst_size, I2cDeviceProperty *device, TransactionOption option) = 0;
virtual os::SdkMutex &GetTransactionOrderMutex() = 0;
- virtual void SuspendBus();
- virtual void SuspendPowerBus();
+ virtual void SuspendBus() = 0;
+ virtual void SuspendPowerBus() = 0;
- virtual void ResumeBus();
- virtual void ResumePowerBus();
+ virtual void ResumeBus() = 0;
+ virtual void ResumePowerBus() = 0;
virtual const DeviceCode &GetDeviceCode() const = 0;
};
diff --git a/libstratosphere/include/stratosphere/pwm.hpp b/libstratosphere/include/stratosphere/pwm.hpp
new file mode 100644
index 00000000..6446e5b4
--- /dev/null
+++ b/libstratosphere/include/stratosphere/pwm.hpp
@@ -0,0 +1,20 @@
+/*
+ * 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
diff --git a/libstratosphere/include/stratosphere/pwm/pwm_channel_name.board.nintendo_nx.hpp b/libstratosphere/include/stratosphere/pwm/pwm_channel_name.board.nintendo_nx.hpp
new file mode 100644
index 00000000..a6c3c7e9
--- /dev/null
+++ b/libstratosphere/include/stratosphere/pwm/pwm_channel_name.board.nintendo_nx.hpp
@@ -0,0 +1,51 @@
+/*
+ * 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::pwm {
+
+ enum ChannelName {
+ ChannelName_Invalid = 0,
+ ChannelName_CpuFan = 1,
+ ChannelName_LcdBacklight = 2,
+ ChannelName_BlinkLed = 3,
+ };
+
+ constexpr inline const DeviceCode DeviceCode_CpuFan = 0x3D000001;
+ constexpr inline const DeviceCode DeviceCode_LcdBacklight = 0x3400003D;
+ constexpr inline const DeviceCode DeviceCode_BlinkLed = 0x35000065;
+
+ constexpr inline DeviceCode ConvertToDeviceCode(ChannelName cn) {
+ switch (cn) {
+ case ChannelName_CpuFan: return DeviceCode_CpuFan;
+ case ChannelName_LcdBacklight: return DeviceCode_LcdBacklight;
+ case ChannelName_BlinkLed: return DeviceCode_BlinkLed;
+ AMS_UNREACHABLE_DEFAULT_CASE();
+ }
+ }
+
+ constexpr inline ChannelName ConvertToChannelName(DeviceCode dc) {
+ switch (dc.GetInternalValue()) {
+ case DeviceCode_CpuFan .GetInternalValue(): return ChannelName_CpuFan;
+ case DeviceCode_LcdBacklight.GetInternalValue(): return ChannelName_LcdBacklight;
+ case DeviceCode_BlinkLed .GetInternalValue(): return ChannelName_BlinkLed;
+ AMS_UNREACHABLE_DEFAULT_CASE();
+ }
+ }
+
+}
diff --git a/libstratosphere/include/stratosphere/pwm/pwm_select_channel_name.hpp b/libstratosphere/include/stratosphere/pwm/pwm_select_channel_name.hpp
new file mode 100644
index 00000000..58c63028
--- /dev/null
+++ b/libstratosphere/include/stratosphere/pwm/pwm_select_channel_name.hpp
@@ -0,0 +1,24 @@
+/*
+ * 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
+
+#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
+ #include
+#else
+ /* Error? */
+#endif
diff --git a/libstratosphere/include/stratosphere/pwm/pwm_types.hpp b/libstratosphere/include/stratosphere/pwm/pwm_types.hpp
new file mode 100644
index 00000000..9130e123
--- /dev/null
+++ b/libstratosphere/include/stratosphere/pwm/pwm_types.hpp
@@ -0,0 +1,23 @@
+/*
+ * 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::pwm {
+
+ /* ... */
+
+}
diff --git a/libstratosphere/include/stratosphere/regulator.hpp b/libstratosphere/include/stratosphere/regulator.hpp
new file mode 100644
index 00000000..fbd6c24d
--- /dev/null
+++ b/libstratosphere/include/stratosphere/regulator.hpp
@@ -0,0 +1,21 @@
+/*
+ * 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
diff --git a/libstratosphere/include/stratosphere/regulator/regulator_api.hpp b/libstratosphere/include/stratosphere/regulator/regulator_api.hpp
new file mode 100644
index 00000000..36623c8f
--- /dev/null
+++ b/libstratosphere/include/stratosphere/regulator/regulator_api.hpp
@@ -0,0 +1,25 @@
+/*
+ * 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::regulator {
+
+ void Initialize();
+ void Finalize();
+
+}
diff --git a/libstratosphere/include/stratosphere/regulator/regulator_session_api.hpp b/libstratosphere/include/stratosphere/regulator/regulator_session_api.hpp
new file mode 100644
index 00000000..62c9a6b0
--- /dev/null
+++ b/libstratosphere/include/stratosphere/regulator/regulator_session_api.hpp
@@ -0,0 +1,34 @@
+/*
+ * 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::regulator {
+
+ struct RegulatorSession {
+ void *_session;
+ };
+
+ Result OpenSession(RegulatorSession *out, DeviceCode device_code);
+ void CloseSession(RegulatorSession *session);
+
+ bool GetVoltageEnabled(RegulatorSession *session);
+ Result SetVoltageEnabled(RegulatorSession *session);
+
+ Result SetVoltageValue(RegulatorSession *session, u32 micro_volts);
+
+}
diff --git a/libstratosphere/include/stratosphere/regulator/regulator_types.hpp b/libstratosphere/include/stratosphere/regulator/regulator_types.hpp
new file mode 100644
index 00000000..ad389417
--- /dev/null
+++ b/libstratosphere/include/stratosphere/regulator/regulator_types.hpp
@@ -0,0 +1,23 @@
+/*
+ * 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::regulator {
+
+ /* ... */
+
+}
diff --git a/libstratosphere/source/i2c/driver/board/nintendo_nx/impl/i2c_bus_accessor.cpp b/libstratosphere/source/i2c/driver/board/nintendo_nx/impl/i2c_bus_accessor.cpp
new file mode 100644
index 00000000..430e183a
--- /dev/null
+++ b/libstratosphere/source/i2c/driver/board/nintendo_nx/impl/i2c_bus_accessor.cpp
@@ -0,0 +1,245 @@
+/*
+ * 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 "i2c_bus_accessor.hpp"
+
+namespace ams::i2c::driver::board::nintendo_nx::impl {
+
+ void I2cBusAccessor::Initialize(dd::PhysicalAddress reg_paddr, size_t reg_size, os::InterruptName intr, bool pb, SpeedMode sm) {
+ AMS_ASSERT(this->state == State::NotInitialized);
+
+ this->is_power_bus = pb;
+ this->speed_mode = sm;
+ this->interrupt_name = intr;
+ this->registers_phys_addr = reg_paddr;
+ this->registers_size = reg_size;
+ this->state = State::Initializing;
+ }
+
+ void I2cBusAccessor::RegisterDeviceCode(DeviceCode dc) {
+ AMS_ASSERT(this->state == State::Initializing);
+
+ this->device_code = dc;
+ }
+
+ void I2cBusAccessor::InitializeDriver() {
+ AMS_ASSERT(this->state == State::Initializing);
+
+ this->registers = reinterpret_cast(dd::QueryIoMapping(this->registers_phys_addr, this->registers_size));
+ AMS_ABORT_UNLESS(this->registers != nullptr);
+
+ this->state = State::Initialized;
+ }
+
+ void I2cBusAccessor::FinalizeDriver() {
+ AMS_ASSERT(this->state == State::Initialized);
+ this->state = State::Initializing;
+ }
+
+ Result I2cBusAccessor::InitializeDevice(I2cDeviceProperty *device) {
+ /* Check that the device is valid. */
+ AMS_ASSERT(device != nullptr);
+ AMS_ASSERT(this->state == State::Initialized);
+
+ /* Acquire exclusive access. */
+ std::scoped_lock lk(this->user_count_mutex);
+
+ /* Increment our user count -- if we're already open, we're done. */
+ AMS_ASSERT(this->user_count >= 0);
+ ++this->user_count;
+ R_SUCCEED_IF(this->user_count > 1);
+
+ /* Initialize our interrupt event. */
+ os::InitializeInterruptEvent(std::addressof(this->interrupt_event), this->interrupt_name, os::EventClearMode_ManualClear);
+ os::ClearInterruptEvent(std::addressof(this->interrupt_event);
+
+ /* If we're not power bus, perform power management init. */
+ if (!this->is_power_bus) {
+ /* Initialize regulator library. */
+ regulator::Initialize();
+
+ /* Try to open regulator session. */
+ R_TRY(this->TryOpenRegulatorSession());
+
+ /* If we have a regulator session, set voltage to 2.9V. */
+ if (this->has_regulator_session) {
+ /* NOTE: Nintendo does not check the result, here. */
+ regulator::SetVoltageValue(std::addressof(this->regulator_session), 2'900'000u);
+ }
+
+ /* Initialize clock/reset library. */
+ clkrst::Initialize();
+ }
+
+ /* Execute initial config. */
+ this->ExecuteInitialConfig();
+
+ /* If we have a regulator session, enable voltage. */
+ if (!this->is_power_bus && this->has_regulator_session) {
+ /* Check whether voltage was already enabled. */
+ const bool was_enabled = regulator::GetVoltageEnabled(std::addressof(this->regulator_session));
+
+ /* NOTE: Nintendo does not check the result of this call. */
+ regulator::SetVoltageEnabled(std::addressof(this->regulator_session), true);
+
+ /* If we enabled voltage, delay to give our enable time to take. */
+ if (!was_enabled) {
+ os::SleepThread(TimeSpan::FromMicroSeconds(560));
+ }
+ }
+
+ return ResultSuccess();
+ }
+
+ void I2cBusAccessor::FinalizeDevice(I2cDeviceProperty *device) {
+ /* Check that the device is valid. */
+ AMS_ASSERT(device != nullptr);
+ AMS_ASSERT(this->state == State::Initialized);
+
+ /* Acquire exclusive access. */
+ std::scoped_lock lk(this->user_count_mutex);
+
+ /* Increment our user count -- if we're not the last user, we're done. */
+ AMS_ASSERT(this->user_count > 0);
+ --this->user_count;
+ R_SUCCEED_IF(this->user_count > 0);
+
+ /* Finalize our interrupt event. */
+ os::FinalizeInterruptEvent(std::addressof(this->interrupt_event));
+
+ /* If we have a regulator session, disable voltage. */
+ if (this->has_regulator_session) {
+ /* NOTE: Nintendo does not check the result of this call. */
+ regulator::SetVoltageEnabled(std::addressof(this->regulator_session), false);
+ }
+
+ /* Finalize the clock/reset library. */
+ clkrst::Finalize();
+
+ /* If we have a regulator session, close it. */
+ if (this->has_regulator_session) {
+ regulator::CloseSession(std::addressof(this->regulator_session));
+ this->has_regulator_session = false;
+ }
+
+ /* Finalize the regulator library. */
+ regulator::Finalize();
+ }
+
+ Result I2cBusAccessor::Send(I2cDeviceProperty *device, const void *src, size_t src_size, TransactionOption option) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result I2cBusAccessor::Receive(void *dst, size_t dst_size, I2cDeviceProperty *device, TransactionOption option) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ void I2cBusAccessor::SuspendBus() {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ void I2cBusAccessor::SuspendPowerBus() {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ void I2cBusAccessor::ResumeBus() {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ void I2cBusAccessor::ResumePowerBus() {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result I2cBusAccessor::TryOpenRegulatorSession() {
+ /* Ensure we track the session. */
+ this->has_regulator_session = true;
+ auto s_guard = SCOPE_GUARD { this->has_regulator_session = false; };
+
+ /* Try to open the session. */
+ R_TRY_CATCH(regulator::OpenSession(std::addressof(this->regulator_session), this->device_code)) {
+ R_CATCH(ddsf::ResultDeviceCodeNotFound) {
+ /* It's okay if the device isn't found, but we don't have a session if so. */
+ this->has_regulator_session = false;
+ }
+ } R_END_TRY_CATCH;
+
+ /* We opened (or not). */
+ s_guard.Cancel();
+ return ResultSuccess();
+ }
+
+ void I2cBusAccessor::ExecuteInitialConfig() {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result I2cBusAccessor::Send(const u8 *src, size_t src_size, TransactionOption option, u16 slave_address, AddressingMode addressing_mode) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result I2cBusAccessor::Receive(u8 *dst, size_t dst_size, TransactionOption option, u16 slave_address, AddressingMode addressing_mode) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ void I2cBusAccessor::WriteHeader(Xfer xfer, size_t size, TransactionOption option, u16 slave_address, AddressingMode addressing_mode) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ void I2cBusAccessor::ResetController() const {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ void I2cBusAccessor::ClearBus() const {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ void I2cBusAccessor::SetClockRegisters(SpeedMode speed_mode) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ void I2cBusAccessor::SetPacketModeRegisters() {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result I2cBusAccessor::FlushFifos() {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result I2cBusAccessor::GetTransactionResult() const {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ void I2cBusAccessor::HandleTransactionError(Result result) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+}
diff --git a/libstratosphere/source/i2c/driver/board/nintendo_nx/impl/i2c_bus_accessor.hpp b/libstratosphere/source/i2c/driver/board/nintendo_nx/impl/i2c_bus_accessor.hpp
new file mode 100644
index 00000000..058f8e39
--- /dev/null
+++ b/libstratosphere/source/i2c/driver/board/nintendo_nx/impl/i2c_bus_accessor.hpp
@@ -0,0 +1,145 @@
+/*
+ * 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 "i2c_i2c_registers.hpp"
+
+namespace ams::i2c::driver::board::nintendo_nx::impl {
+
+ class I2cBusAccessor : public ::ams::i2c::driver::II2cDriver {
+ NON_COPYABLE(I2cBusAccessor);
+ NON_MOVEABLE(I2cBusAccessor);
+ AMS_DDSF_CASTABLE_TRAITS(ams::i2c::driver::board::nintendo_nx::impl::I2cBusAccessor, ::ams::i2c::driver::II2cDriver);
+ private:
+ enum class State {
+ NotInitialized = 0,
+ Initializing = 1,
+ Initialized = 2,
+ Suspended = 3,
+ PowerBusSuspended = 4,
+ };
+
+ enum Xfer {
+ Xfer_Write = 0,
+ Xfer_Read = 1,
+ };
+ private:
+ volatile I2cRegisters *registers;
+ SpeedMode speed_mode;
+ os::InterruptEventType interrupt_event;
+ int user_count;
+ os::SdkMutex user_count_mutex;
+ os::SdkMutex register_mutex;
+ regulator::RegulatorSession regulator_session;
+ bool has_regulator_session;
+ State state;
+ os::SdkMutex transaction_order_mutex;
+ bool is_power_bus;
+ dd::PhysicalAddress registers_phys_addr;
+ size_t registers_size;
+ os::InterruptName interrupt_name;
+ DeviceCode device_code;
+ util::IntrusiveListNode bus_accessor_list_node;
+ public:
+ using BusAccessorListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&I2cBusAccessor::bus_accessor_list_node>;
+ using BusAccessorList = typename BusAccessorListTraits::ListType;
+ friend class util::IntrusiveList>;
+ public:
+ I2cBusAccessor()
+ : registers(nullptr), speed_mode(SpeedMode_Fast), user_count(0), user_count_mutex(),
+ register_mutex(), has_regulator_session(false), state(State::NotInitialized), transaction_order_mutex(),
+ is_power_bus(false), registers_phys_addr(0), registers_size(0), interrupt_name(), device_code(-1), bus_accessor_list_node()
+ {
+ /* ... */
+ }
+
+ void Initialize(dd::PhysicalAddress reg_paddr, size_t reg_size, os::InterruptName intr, bool pb, SpeedMode sm);
+ void RegisterDeviceCode(DeviceCode device_code);
+
+ SpeedMode GetSpeedMode() const { return this->speed_mode; }
+ dd::PhysicalAddress GetRegistersPhysicalAddress() const { return this->registers_phys_addr; }
+ size_t GetRegistersSize() const { return this->registers_size; }
+ os::InterruptName GetInterruptName() const { return this->interrupt_name; }
+
+ void RemoveFrom(BusAccessorList &lst) {
+ lst.erase(lst.iterator_to(*this));
+ }
+
+ bool IsLinkedToList() const {
+ return this->bus_accessor_list_node.IsLinked();
+ }
+ private:
+ Result TryOpenRegulatorSession();
+
+ void ExecuteInitialConfig();
+
+ Result Send(const u8 *src, size_t src_size, TransactionOption option, u16 slave_address, AddressingMode addressing_mode);
+ Result Receive(u8 *dst, size_t dst_size, TransactionOption option, u16 slave_address, AddressingMode addressing_mode);
+
+ void WriteHeader(Xfer xfer, size_t size, TransactionOption option, u16 slave_address, AddressingMode addressing_mode);
+
+ void ResetController() const;
+ void ClearBus() const;
+ void SetClockRegisters(SpeedMode speed_mode);
+ void SetPacketModeRegisters();
+
+ Result FlushFifos();
+
+ Result GetTransactionResult() const;
+ void HandleTransactionError(Result result);
+
+ void DisableInterruptMask() {
+ reg::Write(this->registers->interrupt_mask_register, 0);
+ reg::Read(this->registers->interrupt_mask_register);
+ }
+
+ Result CheckAndHandleError() {
+ const Result result = this->GetTransactionResult();
+ this->HandleTransactionError(result);
+ if (R_FAILED(result)) {
+ this->DisableInterruptMask();
+ os::ClearInterruptEvent(std::addressof(this->interrupt_event));
+ return result;
+ }
+
+ return ResultSuccess();
+ }
+ public:
+ virtual void InitializeDriver() override;
+ virtual void FinalizeDriver() override;
+
+ virtual Result InitializeDevice(I2cDeviceProperty *device) override;
+ virtual void FinalizeDevice(I2cDeviceProperty *device) override;
+
+ virtual Result Send(I2cDeviceProperty *device, const void *src, size_t src_size, TransactionOption option) override;
+ virtual Result Receive(void *dst, size_t dst_size, I2cDeviceProperty *device, TransactionOption option) override;
+
+ virtual os::SdkMutex &GetTransactionOrderMutex() override {
+ return this->transaction_order_mutex;
+ }
+
+ virtual void SuspendBus() override;
+ virtual void SuspendPowerBus() override;
+
+ virtual void ResumeBus() override;
+ virtual void ResumePowerBus() override;
+
+ virtual const DeviceCode &GetDeviceCode() const override {
+ return this->device_code;
+ }
+ };
+
+}
diff --git a/libstratosphere/source/i2c/driver/board/nintendo_nx/impl/i2c_i2c_registers.hpp b/libstratosphere/source/i2c/driver/board/nintendo_nx/impl/i2c_i2c_registers.hpp
new file mode 100644
index 00000000..c8925ce6
--- /dev/null
+++ b/libstratosphere/source/i2c/driver/board/nintendo_nx/impl/i2c_i2c_registers.hpp
@@ -0,0 +1,66 @@
+/*
+ * 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::i2c::driver::board::nintendo_nx::impl {
+
+ struct I2cRegisters {
+ volatile u32 cnfg;
+ volatile u32 cmd_addr0;
+ volatile u32 cmd_addr1;
+ volatile u32 cmd_data1;
+ volatile u32 cmd_data2;
+ volatile u32 _14;
+ volatile u32 _18;
+ volatile u32 status;
+ volatile u32 sl_cnfg;
+ volatile u32 sl_rcvd;
+ volatile u32 sl_status;
+ volatile u32 sl_addr1;
+ volatile u32 sl_addr2;
+ volatile u32 tlow_sext;
+ volatile u32 _38;
+ volatile u32 sl_delay_count;
+ volatile u32 sl_int_mask;
+ volatile u32 sl_int_source;
+ volatile u32 sl_int_set;
+ volatile u32 _4c;
+ volatile u32 tx_packet_fifo;
+ volatile u32 rx_fifo;
+ volatile u32 packet_transfer_status;
+ volatile u32 fifo_control;
+ volatile u32 fifo_status;
+ volatile u32 interrupt_mask_register;
+ volatile u32 interrupt_status_register;
+ volatile u32 clk_divisor_register;
+ volatile u32 interrupt_source_register;
+ volatile u32 interrupt_set_register;
+ volatile u32 slv_tx_packet_fifo;
+ volatile u32 slv_rx_fifo;
+ volatile u32 slv_packet_status;
+ volatile u32 bus_clear_config;
+ volatile u32 bus_clear_status;
+ volatile u32 config_load;
+ volatile u32 _90;
+ volatile u32 interface_timing_0;
+ volatile u32 interface_timing_1;
+ volatile u32 hs_interface_timing_0;
+ volatile u32 hs_interface_timing_1;
+ };
+ static_assert(sizeof(I2cRegisters) == 0xA4);
+
+}
diff --git a/libvapours/include/vapours/tegra.hpp b/libvapours/include/vapours/tegra.hpp
index 7d70c4a7..cb4cb4ce 100644
--- a/libvapours/include/vapours/tegra.hpp
+++ b/libvapours/include/vapours/tegra.hpp
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/libvapours/include/vapours/tegra/tegra_clkrst.hpp b/libvapours/include/vapours/tegra/tegra_clkrst.hpp
index a2d9d361..1be60be6 100644
--- a/libvapours/include/vapours/tegra/tegra_clkrst.hpp
+++ b/libvapours/include/vapours/tegra/tegra_clkrst.hpp
@@ -107,6 +107,7 @@ DEFINE_CLK_RST_REG_BIT_ENUM(PLLC4_BASE_PLLC4_ENABLE, 30, DISABLE, ENABLE);
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_W (0x364)
/* CLK_SOURCE */
+#define CLK_RST_CONTROLLER_CLK_SOURCE_PWM (0x110)
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C1 (0x124)
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C5 (0x128)
#define CLK_RST_CONTROLLER_CLK_SOURCE_DISP1 (0x138)
@@ -115,14 +116,18 @@ DEFINE_CLK_RST_REG_BIT_ENUM(PLLC4_BASE_PLLC4_ENABLE, 30, DISABLE, ENABLE);
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4 (0x164)
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTA (0x178)
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTB (0x17C)
+#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C2 (0x198)
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTC (0x1A0)
+#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C3 (0x1B8)
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3 (0x1BC)
#define CLK_RST_CONTROLLER_CLK_SOURCE_CSITE (0x1D4)
#define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT (0x3B4)
+#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C4 (0x3C4)
#define CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON (0x3E8)
#define CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP (0x620)
#define CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_REF (0x62C)
#define CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_SOC (0x630)
+#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 (0x65C)
#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL (0x66C)
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM (0x694)
@@ -156,12 +161,36 @@ DEFINE_CLK_RST_REG_BIT_ENUM(PLLC4_BASE_PLLC4_ENABLE, 30, DISABLE, ENABLE);
#define CLK_RST_CONTROLLER_CLK_ENB_V_CLR (0x444)
#define CLK_RST_CONTROLLER_CLK_ENB_W_CLR (0x44C)
+/* RST_*_INDEX */
+#define CLK_RST_CONTROLLER_RST_I2C1_INDEX (0x0C)
+#define CLK_RST_CONTROLLER_RST_I2C2_INDEX (0x16)
+#define CLK_RST_CONTROLLER_RST_I2C3_INDEX (0x03)
+#define CLK_RST_CONTROLLER_RST_I2C4_INDEX (0x07)
+#define CLK_RST_CONTROLLER_RST_I2C5_INDEX (0x0F)
+#define CLK_RST_CONTROLLER_RST_I2C6_INDEX (0x06)
+
+#define CLK_RST_CONTROLLER_RST_PWM_INDEX (0x11)
+
+#define CLK_RST_CONTROLLER_RST_UARTA_INDEX (0x06)
+#define CLK_RST_CONTROLLER_RST_UARTB_INDEX (0x07)
+#define CLK_RST_CONTROLLER_RST_UARTC_INDEX (0x17)
+
+#define CLK_RST_CONTROLLER_RST_ACTMON_INDEX (0x17)
+
/* CLK_ENB_*_INDEX */
#define CLK_RST_CONTROLLER_CLK_ENB_I2C1_INDEX (0x0C)
+#define CLK_RST_CONTROLLER_CLK_ENB_I2C2_INDEX (0x16)
+#define CLK_RST_CONTROLLER_CLK_ENB_I2C3_INDEX (0x03)
+#define CLK_RST_CONTROLLER_CLK_ENB_I2C4_INDEX (0x07)
#define CLK_RST_CONTROLLER_CLK_ENB_I2C5_INDEX (0x0F)
+#define CLK_RST_CONTROLLER_CLK_ENB_I2C6_INDEX (0x06)
+
+#define CLK_RST_CONTROLLER_CLK_ENB_PWM_INDEX (0x11)
+
#define CLK_RST_CONTROLLER_CLK_ENB_UARTA_INDEX (0x06)
#define CLK_RST_CONTROLLER_CLK_ENB_UARTB_INDEX (0x07)
#define CLK_RST_CONTROLLER_CLK_ENB_UARTC_INDEX (0x17)
+
#define CLK_RST_CONTROLLER_CLK_ENB_ACTMON_INDEX (0x17)
/* RST_CPUG_CMPLX_* */
@@ -181,6 +210,9 @@ DEFINE_CLK_RST_REG_BIT_ENUM(LVL2_CLK_GATE_OVRD_SDMMC2_LEGACY_TMCLK_OVR_ON, 29, O
DEFINE_CLK_RST_REG_BIT_ENUM(LVL2_CLK_GATE_OVRD_SDMMC3_LEGACY_TMCLK_OVR_ON, 30, OFF, ON);
DEFINE_CLK_RST_REG_BIT_ENUM(LVL2_CLK_GATE_OVRD_SDMMC4_LEGACY_TMCLK_OVR_ON, 31, OFF, ON);
+DEFINE_CLK_RST_REG(CLK_SOURCE_CLK_DIVISOR, 0, 8);
+DEFINE_CLK_RST_REG(CLK_SOURCE_CLK_SOURCE, 29, 3);
+
DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_I2C1_I2C1_CLK_SRC, 29, PLLP_OUT0, PLLC2_OUT0, PLLC_OUT0, PLLC4_OUT0, RESERVED4, PLLC4_OUT1, CLK_M, PLLC4_OUT2);
DEFINE_CLK_RST_REG(CLK_SOURCE_I2C1_I2C1_CLK_DIVISOR, 0, 8);
DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_I2C5_I2C5_CLK_SRC, 29, PLLP_OUT0, PLLC2_OUT0, PLLC_OUT0, PLLC4_OUT0, RESERVED4, PLLC4_OUT1, CLK_M, PLLC4_OUT2);
diff --git a/libvapours/include/vapours/tegra/tegra_i2c.hpp b/libvapours/include/vapours/tegra/tegra_i2c.hpp
new file mode 100644
index 00000000..683ebfb1
--- /dev/null
+++ b/libvapours/include/vapours/tegra/tegra_i2c.hpp
@@ -0,0 +1,78 @@
+/*
+ * 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
+#include
+
+#define I2C_I2C_CNFG (0x000)
+#define I2C_I2C_CMD_ADDR0 (0x004)
+#define I2C_I2C_CMD_DATA1 (0x00C)
+#define I2C_I2C_STATUS (0x01C)
+#define I2C_INTERRUPT_STATUS_REGISTER (0x068)
+#define I2C_CLK_DIVISOR_REGISTER (0x06C)
+#define I2C_BUS_CLEAR_CONFIG (0x084)
+#define I2C_BUS_CLEAR_STATUS (0x088)
+#define I2C_CONFIG_LOAD (0x08C)
+
+#define I2C_REG_BITS_MASK(NAME) REG_NAMED_BITS_MASK (I2C, NAME)
+#define I2C_REG_BITS_VALUE(NAME, VALUE) REG_NAMED_BITS_VALUE (I2C, NAME, VALUE)
+#define I2C_REG_BITS_ENUM(NAME, ENUM) REG_NAMED_BITS_ENUM (I2C, NAME, ENUM)
+#define I2C_REG_BITS_ENUM_SEL(NAME, __COND__, TRUE_ENUM, FALSE_ENUM) REG_NAMED_BITS_ENUM_SEL(I2C, NAME, __COND__, TRUE_ENUM, FALSE_ENUM)
+
+#define DEFINE_I2C_REG(NAME, __OFFSET__, __WIDTH__) REG_DEFINE_NAMED_REG (I2C, NAME, __OFFSET__, __WIDTH__)
+#define DEFINE_I2C_REG_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE) REG_DEFINE_NAMED_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE)
+#define DEFINE_I2C_REG_TWO_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE) REG_DEFINE_NAMED_TWO_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE)
+#define DEFINE_I2C_REG_THREE_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN) REG_DEFINE_NAMED_THREE_BIT_ENUM(I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN)
+#define DEFINE_I2C_REG_FOUR_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN) REG_DEFINE_NAMED_FOUR_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN)
+
+/* I2C_CNFG */
+DEFINE_I2C_REG(I2C_CNFG_LENGTH, 1, 3);
+DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_CMD1, 6, WRITE, READ);
+DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_SEND, 9, NOP, GO);
+DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_NEW_MASTER_FSM, 11, DISABLE, ENABLE);
+DEFINE_I2C_REG_THREE_BIT_ENUM(I2C_CNFG_DEBOUNCE_CNT, 12, NO_DEBOUNCE, DEBOUNCE_2T, DEBOUNCE_4T, DEBOUNCE_6T, DEBOUNCE_8T, DEBOUNCE_10T, DEBOUNCE_12T, DEBOUNCE_14T);
+
+/* I2C_CMD_ADDR0 */
+DEFINE_I2C_REG_BIT_ENUM(I2C_CMD_ADDR0_7BIT_RW, 0, WRITE, READ);
+DEFINE_I2C_REG(I2C_CMD_ADDR0_7BIT_ADDR, 1, 7);
+
+/* I2C_STATUS */
+DEFINE_I2C_REG_FOUR_BIT_ENUM(I2C_STATUS_CMD1_STAT, 0, SL1_XFER_SUCCESSFUL, SL1_NOACK_FOR_BYTE1, SL1_NOACK_FOR_BYTE2, SL1_NOACK_FOR_BYTE3, SL1_NOACK_FOR_BYTE4, SL1_NOACK_FOR_BYTE5, SL1_NOACK_FOR_BYTE6, SL1_NOACK_FOR_BYTE7, SL1_NOACK_FOR_BYTE8, SL1_NOACK_FOR_BYTE9, SL1_NOACK_FOR_BYTE10, RESERVED11, RESERVED12, RESERVED13, RESERVED14, RESERVED15);
+DEFINE_I2C_REG_FOUR_BIT_ENUM(I2C_STATUS_CMD2_STAT, 4, SL2_XFER_SUCCESSFUL, SL2_NOACK_FOR_BYTE1, SL2_NOACK_FOR_BYTE2, SL2_NOACK_FOR_BYTE3, SL2_NOACK_FOR_BYTE4, SL2_NOACK_FOR_BYTE5, SL2_NOACK_FOR_BYTE6, SL2_NOACK_FOR_BYTE7, SL2_NOACK_FOR_BYTE8, SL2_NOACK_FOR_BYTE9, SL2_NOACK_FOR_BYTE10, RESERVED11, RESERVED12, RESERVED13, RESERVED14, RESERVED15);
+DEFINE_I2C_REG_BIT_ENUM(I2C_STATUS_BUSY, 8, NOT_BUSY, BUSY);
+
+/* INTERRUPT_STATUS_REGISTER */
+DEFINE_I2C_REG_BIT_ENUM(INTERRUPT_STATUS_REGISTER_BUS_CLEAR_DONE, 11, UNSET, SET);
+
+/* CLK_DIVISOR_REGISTER */
+DEFINE_I2C_REG(CLK_DIVISOR_REGISTER_HSMODE, 0, 16);
+DEFINE_I2C_REG(CLK_DIVISOR_REGISTER_STD_FAST_MODE, 16, 16);
+
+/* BUS_CLEAR_CONFIG */
+DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_ENABLE, 0, DISABLE, ENABLE);
+DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_TERMINATE, 1, THRESHOLD, IMMEDIATE);
+DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_STOP_COND, 2, NO_STOP, STOP);
+DEFINE_I2C_REG(BUS_CLEAR_CONFIG_BC_SCLK_THRESHOLD, 16, 8);
+
+/* CONFIG_LOAD */
+DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_MSTR_CONFIG_LOAD, 0, DISABLE, ENABLE);
+DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_SLV_CONFIG_LOAD, 1, DISABLE, ENABLE);
+DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_TIMEOUT_CONFIG_LOAD, 2, DISABLE, ENABLE);
+DEFINE_I2C_REG(CONFIG_LOAD_RESERVED_BIT_5, 5, 1);
diff --git a/libvapours/source/sdmmc/impl/sdmmc_io_impl.board.nintendo_nx.cpp b/libvapours/source/sdmmc/impl/sdmmc_io_impl.board.nintendo_nx.cpp
index 56f15bcd..bf36180e 100644
--- a/libvapours/source/sdmmc/impl/sdmmc_io_impl.board.nintendo_nx.cpp
+++ b/libvapours/source/sdmmc/impl/sdmmc_io_impl.board.nintendo_nx.cpp
@@ -42,62 +42,6 @@ namespace ams::sdmmc::impl {
constexpr inline const dd::PhysicalAddress I2c5RegistersAddress = UINT64_C(0x7000D000);
constexpr inline const size_t I2c5RegistersSize = 4_KB;
- #define I2C_I2C_CNFG (0x000)
- #define I2C_I2C_CMD_ADDR0 (0x004)
- #define I2C_I2C_CMD_DATA1 (0x00C)
- #define I2C_I2C_STATUS (0x01C)
- #define I2C_INTERRUPT_STATUS_REGISTER (0x068)
- #define I2C_CLK_DIVISOR_REGISTER (0x06C)
- #define I2C_BUS_CLEAR_CONFIG (0x084)
- #define I2C_BUS_CLEAR_STATUS (0x088)
- #define I2C_CONFIG_LOAD (0x08C)
-
- #define I2C_REG_BITS_MASK(NAME) REG_NAMED_BITS_MASK (I2C, NAME)
- #define I2C_REG_BITS_VALUE(NAME, VALUE) REG_NAMED_BITS_VALUE (I2C, NAME, VALUE)
- #define I2C_REG_BITS_ENUM(NAME, ENUM) REG_NAMED_BITS_ENUM (I2C, NAME, ENUM)
- #define I2C_REG_BITS_ENUM_SEL(NAME, __COND__, TRUE_ENUM, FALSE_ENUM) REG_NAMED_BITS_ENUM_SEL(I2C, NAME, __COND__, TRUE_ENUM, FALSE_ENUM)
-
- #define DEFINE_I2C_REG(NAME, __OFFSET__, __WIDTH__) REG_DEFINE_NAMED_REG (I2C, NAME, __OFFSET__, __WIDTH__)
- #define DEFINE_I2C_REG_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE) REG_DEFINE_NAMED_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE)
- #define DEFINE_I2C_REG_TWO_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE) REG_DEFINE_NAMED_TWO_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE)
- #define DEFINE_I2C_REG_THREE_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN) REG_DEFINE_NAMED_THREE_BIT_ENUM(I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN)
- #define DEFINE_I2C_REG_FOUR_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN) REG_DEFINE_NAMED_FOUR_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN)
-
- /* I2C_CNFG */
- DEFINE_I2C_REG(I2C_CNFG_LENGTH, 1, 3);
- DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_CMD1, 6, WRITE, READ);
- DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_SEND, 9, NOP, GO);
- DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_NEW_MASTER_FSM, 11, DISABLE, ENABLE);
- DEFINE_I2C_REG_THREE_BIT_ENUM(I2C_CNFG_DEBOUNCE_CNT, 12, NO_DEBOUNCE, DEBOUNCE_2T, DEBOUNCE_4T, DEBOUNCE_6T, DEBOUNCE_8T, DEBOUNCE_10T, DEBOUNCE_12T, DEBOUNCE_14T);
-
- /* I2C_CMD_ADDR0 */
- DEFINE_I2C_REG_BIT_ENUM(I2C_CMD_ADDR0_7BIT_RW, 0, WRITE, READ);
- DEFINE_I2C_REG(I2C_CMD_ADDR0_7BIT_ADDR, 1, 7);
-
- /* I2C_STATUS */
- DEFINE_I2C_REG_FOUR_BIT_ENUM(I2C_STATUS_CMD1_STAT, 0, SL1_XFER_SUCCESSFUL, SL1_NOACK_FOR_BYTE1, SL1_NOACK_FOR_BYTE2, SL1_NOACK_FOR_BYTE3, SL1_NOACK_FOR_BYTE4, SL1_NOACK_FOR_BYTE5, SL1_NOACK_FOR_BYTE6, SL1_NOACK_FOR_BYTE7, SL1_NOACK_FOR_BYTE8, SL1_NOACK_FOR_BYTE9, SL1_NOACK_FOR_BYTE10, RESERVED11, RESERVED12, RESERVED13, RESERVED14, RESERVED15);
- DEFINE_I2C_REG_FOUR_BIT_ENUM(I2C_STATUS_CMD2_STAT, 4, SL2_XFER_SUCCESSFUL, SL2_NOACK_FOR_BYTE1, SL2_NOACK_FOR_BYTE2, SL2_NOACK_FOR_BYTE3, SL2_NOACK_FOR_BYTE4, SL2_NOACK_FOR_BYTE5, SL2_NOACK_FOR_BYTE6, SL2_NOACK_FOR_BYTE7, SL2_NOACK_FOR_BYTE8, SL2_NOACK_FOR_BYTE9, SL2_NOACK_FOR_BYTE10, RESERVED11, RESERVED12, RESERVED13, RESERVED14, RESERVED15);
- DEFINE_I2C_REG_BIT_ENUM(I2C_STATUS_BUSY, 8, NOT_BUSY, BUSY);
-
- /* INTERRUPT_STATUS_REGISTER */
- DEFINE_I2C_REG_BIT_ENUM(INTERRUPT_STATUS_REGISTER_BUS_CLEAR_DONE, 11, UNSET, SET);
-
- /* CLK_DIVISOR_REGISTER */
- DEFINE_I2C_REG(CLK_DIVISOR_REGISTER_HSMODE, 0, 16);
- DEFINE_I2C_REG(CLK_DIVISOR_REGISTER_STD_FAST_MODE, 16, 16);
-
- /* BUS_CLEAR_CONFIG */
- DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_ENABLE, 0, DISABLE, ENABLE);
- DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_TERMINATE, 1, THRESHOLD, IMMEDIATE);
- DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_STOP_COND, 2, NO_STOP, STOP);
- DEFINE_I2C_REG(BUS_CLEAR_CONFIG_BC_SCLK_THRESHOLD, 16, 8);
-
- /* CONFIG_LOAD */
- DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_MSTR_CONFIG_LOAD, 0, DISABLE, ENABLE);
- DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_SLV_CONFIG_LOAD, 1, DISABLE, ENABLE);
- DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_TIMEOUT_CONFIG_LOAD, 2, DISABLE, ENABLE);
- DEFINE_I2C_REG(CONFIG_LOAD_RESERVED_BIT_5, 5, 1);
-
namespace {
constexpr inline size_t MaxTransferSize = sizeof(u32);