diff --git a/libraries/libexosphere/source/i2c/i2c_api.cpp b/libraries/libexosphere/source/i2c/i2c_api.cpp
index baafacc93..40900ff25 100644
--- a/libraries/libexosphere/source/i2c/i2c_api.cpp
+++ b/libraries/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/libraries/libexosphere/source/i2c/i2c_registers.hpp b/libraries/libexosphere/source/i2c/i2c_registers.hpp
deleted file mode 100644
index 48f659574..000000000
--- a/libraries/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/libraries/libstratosphere/include/stratosphere.hpp b/libraries/libstratosphere/include/stratosphere.hpp
index acddbab18..778b186bd 100644
--- a/libraries/libstratosphere/include/stratosphere.hpp
+++ b/libraries/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/libraries/libstratosphere/include/stratosphere/clkrst.hpp b/libraries/libstratosphere/include/stratosphere/clkrst.hpp
new file mode 100644
index 000000000..45f3d6f0c
--- /dev/null
+++ b/libraries/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/stratosphere/boot/source/i2c/i2c_types.hpp b/libraries/libstratosphere/include/stratosphere/clkrst/clkrst_api.hpp
similarity index 71%
rename from stratosphere/boot/source/i2c/i2c_types.hpp
rename to libraries/libstratosphere/include/stratosphere/clkrst/clkrst_api.hpp
index 72a30237f..69f4e7cba 100644
--- a/stratosphere/boot/source/i2c/i2c_types.hpp
+++ b/libraries/libstratosphere/include/stratosphere/clkrst/clkrst_api.hpp
@@ -14,19 +14,12 @@
* along with this program. If not, see .
*/
#pragma once
-#include
+#include
+#include
-namespace ams::i2c {
+namespace ams::clkrst {
- enum class AddressingMode {
- SevenBit = 0,
- };
-
- enum class SpeedMode {
- Normal = 100000,
- Fast = 400000,
- FastPlus = 1000000,
- HighSpeed = 3400000,
- };
+ void Initialize();
+ void Finalize();
}
diff --git a/libraries/libstratosphere/include/stratosphere/clkrst/clkrst_session_api.hpp b/libraries/libstratosphere/include/stratosphere/clkrst/clkrst_session_api.hpp
new file mode 100644
index 000000000..3ca34615c
--- /dev/null
+++ b/libraries/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/libraries/libstratosphere/include/stratosphere/clkrst/clkrst_types.hpp b/libraries/libstratosphere/include/stratosphere/clkrst/clkrst_types.hpp
new file mode 100644
index 000000000..7c234ca14
--- /dev/null
+++ b/libraries/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/libraries/libstratosphere/include/stratosphere/i2c/driver/i2c_i_i2c_driver.hpp b/libraries/libstratosphere/include/stratosphere/i2c/driver/i2c_i_i2c_driver.hpp
index 9343b3f30..867234a54 100644
--- a/libraries/libstratosphere/include/stratosphere/i2c/driver/i2c_i_i2c_driver.hpp
+++ b/libraries/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/libraries/libstratosphere/include/stratosphere/pwm.hpp b/libraries/libstratosphere/include/stratosphere/pwm.hpp
new file mode 100644
index 000000000..6446e5b42
--- /dev/null
+++ b/libraries/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/libraries/libstratosphere/include/stratosphere/pwm/pwm_channel_name.board.nintendo_nx.hpp b/libraries/libstratosphere/include/stratosphere/pwm/pwm_channel_name.board.nintendo_nx.hpp
new file mode 100644
index 000000000..a6c3c7e9b
--- /dev/null
+++ b/libraries/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/libraries/libstratosphere/include/stratosphere/pwm/pwm_select_channel_name.hpp b/libraries/libstratosphere/include/stratosphere/pwm/pwm_select_channel_name.hpp
new file mode 100644
index 000000000..58c63028b
--- /dev/null
+++ b/libraries/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/libraries/libstratosphere/include/stratosphere/pwm/pwm_types.hpp b/libraries/libstratosphere/include/stratosphere/pwm/pwm_types.hpp
new file mode 100644
index 000000000..9130e123a
--- /dev/null
+++ b/libraries/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/libraries/libstratosphere/include/stratosphere/regulator.hpp b/libraries/libstratosphere/include/stratosphere/regulator.hpp
new file mode 100644
index 000000000..fbd6c24dc
--- /dev/null
+++ b/libraries/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/stratosphere/boot/source/i2c/driver/impl/i2c_pcv.hpp b/libraries/libstratosphere/include/stratosphere/regulator/regulator_api.hpp
similarity index 59%
rename from stratosphere/boot/source/i2c/driver/impl/i2c_pcv.hpp
rename to libraries/libstratosphere/include/stratosphere/regulator/regulator_api.hpp
index 4af551d41..36623c8fc 100644
--- a/stratosphere/boot/source/i2c/driver/impl/i2c_pcv.hpp
+++ b/libraries/libstratosphere/include/stratosphere/regulator/regulator_api.hpp
@@ -14,18 +14,12 @@
* along with this program. If not, see .
*/
#pragma once
-#include
+#include
+#include
-/* This forward declares the functionality from pcv that i2c::driver uses. */
-/* This allows for overriding at compile-time (e.g., for boot sysmodule). */
-namespace ams::pcv {
+namespace ams::regulator {
void Initialize();
void Finalize();
- Result SetClockRate(PcvModule module, u32 hz);
- Result SetClockEnabled(PcvModule module, bool enabled);
- Result SetVoltageEnabled(u32 domain, bool enabled);
- Result SetVoltageValue(u32 domain, u32 voltage);
- Result SetReset(PcvModule module, bool reset);
}
diff --git a/libraries/libstratosphere/include/stratosphere/regulator/regulator_session_api.hpp b/libraries/libstratosphere/include/stratosphere/regulator/regulator_session_api.hpp
new file mode 100644
index 000000000..62c9a6b01
--- /dev/null
+++ b/libraries/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/libraries/libstratosphere/include/stratosphere/regulator/regulator_types.hpp b/libraries/libstratosphere/include/stratosphere/regulator/regulator_types.hpp
new file mode 100644
index 000000000..ad3894176
--- /dev/null
+++ b/libraries/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/libraries/libstratosphere/source/i2c/driver/board/nintendo_nx/impl/i2c_bus_accessor.cpp b/libraries/libstratosphere/source/i2c/driver/board/nintendo_nx/impl/i2c_bus_accessor.cpp
new file mode 100644
index 000000000..430e183a1
--- /dev/null
+++ b/libraries/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/libraries/libstratosphere/source/i2c/driver/board/nintendo_nx/impl/i2c_bus_accessor.hpp b/libraries/libstratosphere/source/i2c/driver/board/nintendo_nx/impl/i2c_bus_accessor.hpp
new file mode 100644
index 000000000..058f8e39d
--- /dev/null
+++ b/libraries/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/libraries/libstratosphere/source/i2c/driver/board/nintendo_nx/impl/i2c_i2c_registers.hpp b/libraries/libstratosphere/source/i2c/driver/board/nintendo_nx/impl/i2c_i2c_registers.hpp
new file mode 100644
index 000000000..c8925ce6e
--- /dev/null
+++ b/libraries/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/libraries/libvapours/include/vapours/tegra.hpp b/libraries/libvapours/include/vapours/tegra.hpp
index 7d70c4a79..cb4cb4cee 100644
--- a/libraries/libvapours/include/vapours/tegra.hpp
+++ b/libraries/libvapours/include/vapours/tegra.hpp
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp b/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp
index a2d9d3613..1be60be68 100644
--- a/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp
+++ b/libraries/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/libraries/libvapours/include/vapours/tegra/tegra_i2c.hpp b/libraries/libvapours/include/vapours/tegra/tegra_i2c.hpp
new file mode 100644
index 000000000..683ebfb17
--- /dev/null
+++ b/libraries/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/libraries/libvapours/source/sdmmc/impl/sdmmc_io_impl.board.nintendo_nx.cpp b/libraries/libvapours/source/sdmmc/impl/sdmmc_io_impl.board.nintendo_nx.cpp
index 56f15bcd7..bf36180e7 100644
--- a/libraries/libvapours/source/sdmmc/impl/sdmmc_io_impl.board.nintendo_nx.cpp
+++ b/libraries/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);
diff --git a/stratosphere/boot/source/api_overrides/clkrst_api_for_boot.board.nintendo_nx.cpp b/stratosphere/boot/source/api_overrides/clkrst_api_for_boot.board.nintendo_nx.cpp
new file mode 100644
index 000000000..b50c9d8a1
--- /dev/null
+++ b/stratosphere/boot/source/api_overrides/clkrst_api_for_boot.board.nintendo_nx.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
+
+namespace ams::clkrst {
+
+ namespace {
+
+ constexpr inline dd::PhysicalAddress ClkRstRegistersPhysicalAddress = 0x60006000;
+ constexpr inline size_t ClkRstRegistersSize = 0x1000;
+
+ uintptr_t g_clkrst_registers = dd::QueryIoMapping(ClkRstRegistersPhysicalAddress, ClkRstRegistersSize);
+
+ struct ClkRstDefinition {
+ u32 clk_src_ofs;
+ u32 clk_en_ofs;
+ u32 rst_ofs;
+ u32 clk_en_index;
+ u32 rst_index;
+ u8 clk_src;
+ u8 clk_divisor;
+ };
+
+ constexpr inline const ClkRstDefinition Definitions[] = {
+ { CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_ENB_I2C1_INDEX, CLK_RST_CONTROLLER_RST_I2C1_INDEX, 0x00 /* PLLP_OUT0 */, 0x04 },
+ { CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_ENB_I2C2_INDEX, CLK_RST_CONTROLLER_RST_I2C2_INDEX, 0x00 /* PLLP_OUT0 */, 0x04 },
+ { CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_ENB_I2C3_INDEX, CLK_RST_CONTROLLER_RST_I2C3_INDEX, 0x00 /* PLLP_OUT0 */, 0x04 },
+ { CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_ENB_I2C4_INDEX, CLK_RST_CONTROLLER_RST_I2C4_INDEX, 0x00 /* PLLP_OUT0 */, 0x04 },
+ { CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_ENB_I2C5_INDEX, CLK_RST_CONTROLLER_RST_I2C5_INDEX, 0x00 /* PLLP_OUT0 */, 0x04 },
+ { CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_ENB_I2C6_INDEX, CLK_RST_CONTROLLER_RST_I2C6_INDEX, 0x00 /* PLLP_OUT0 */, 0x04 },
+ { CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_ENB_PWM_INDEX, CLK_RST_CONTROLLER_RST_PWM_INDEX, 0x00 /* PLLP_OUT0 */, 0x10 },
+ };
+
+ constexpr inline const struct {
+ const ClkRstDefinition *definition;
+ DeviceCode device_code;
+ } ClkRstDefinitionMap[] = {
+ { std::addressof(Definitions[0]), i2c::DeviceCode_I2c1 },
+ { std::addressof(Definitions[1]), i2c::DeviceCode_I2c2 },
+ { std::addressof(Definitions[2]), i2c::DeviceCode_I2c3 },
+ { std::addressof(Definitions[3]), i2c::DeviceCode_I2c4 },
+ { std::addressof(Definitions[4]), i2c::DeviceCode_I2c5 },
+ { std::addressof(Definitions[5]), i2c::DeviceCode_I2c6 },
+ { std::addressof(Definitions[6]), pwm::DeviceCode_LcdBacklight },
+ };
+
+ ALWAYS_INLINE const ClkRstDefinition *GetDefinition(DeviceCode device_code) {
+ const ClkRstDefinition *def = nullptr;
+
+ for (const auto &entry : ClkRstDefinitionMap) {
+ if (entry.device_code == device_code) {
+ def = entry.definition;
+ break;
+ }
+ }
+
+ AMS_ABORT_UNLESS(def != nullptr);
+ return def;
+ }
+
+ ALWAYS_INLINE const ClkRstDefinition &GetDefinition(ClkRstSession *session) {
+ const ClkRstDefinition *def = nullptr;
+
+ for (const auto &entry : ClkRstDefinitionMap) {
+ if (session->_session == entry.definition) {
+ def = entry.definition;
+ break;
+ }
+ }
+
+ AMS_ABORT_UNLESS(def != nullptr);
+ return *def;
+ }
+
+ }
+
+ void Initialize() {
+ /* ... */
+ }
+
+ void Finalize() {
+ /* ... */
+ }
+
+ Result OpenSession(ClkRstSession *out, DeviceCode device_code) {
+ /* Get the relevant definition. */
+ out->_session = const_cast(GetDefinition(device_code));
+ return ResultSuccess();
+ }
+
+ void CloseSession(ClkRstSession *session) {
+ /* Clear the session. */
+ session->_session = nullptr;
+ }
+
+ void SetResetAsserted(ClkRstSession *session) {
+ /* Get the definition. */
+ const auto &def = GetDefinition(session);
+
+ /* Assert reset. */
+ reg::ReadWrite(g_clkrst_registers + def.rst_ofs, 1u << def.rst_index, 1u << def.rst_index);
+ }
+
+ void SetResetDeasserted(ClkRstSession *session) {
+ /* Get the definition. */
+ const auto &def = GetDefinition(session);
+
+ /* Clear reset. */
+ reg::ReadWrite(g_clkrst_registers + def.rst_ofs, 0, 1u << def.rst_index);
+ }
+
+ void SetClockRate(ClkRstSession *session, u32 hz) {
+ /* Get the definition. */
+ const auto &def = GetDefinition(session);
+
+ /* Enable clock. */
+ reg::ReadWrite(g_clkrst_registers + def.clk_en_ofs, 1u << def.clk_en_index, 1u << def.clk_en_index);
+
+ /* Set the clock divisor. */
+ reg::ReadWrite(g_clkrst_registers + def.clk_src_ofs, CLK_RST_REG_BITS_VALUE(CLK_SOURCE_CLK_DIVISOR, def.clk_divisor));
+
+ /* Wait for 2us for clock setting to take. */
+ os::SleepThread(TimeSpan::FromMicroSeconds(2));
+
+ /* Set the clock source. */
+ reg::ReadWrite(g_clkrst_registers + def.clk_src_ofs, CLK_RST_REG_BITS_VALUE(CLK_SOURCE_CLK_SOURCE, def.clk_src));
+
+ /* Wait for 2us for clock setting to take. */
+ os::SleepThread(TimeSpan::FromMicroSeconds(2));
+ }
+
+ void SetClockDisabled(ClkRstSession *session) {
+ AMS_ABORT("SetClockDisabled not implemented for boot system module");
+ }
+
+}
diff --git a/stratosphere/boot/source/api_overrides/regulator_api_for_boot.cpp b/stratosphere/boot/source/api_overrides/regulator_api_for_boot.cpp
new file mode 100644
index 000000000..37d29fe42
--- /dev/null
+++ b/stratosphere/boot/source/api_overrides/regulator_api_for_boot.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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::regulator {
+
+ void Initialize() {
+ /* ... */
+ }
+
+ void Finalize() {
+ /* ... */
+ }
+
+ Result OpenSession(RegulatorSession *out, DeviceCode device_code) {
+ AMS_UNUSED(out, device_code);
+ return ResultSuccess();
+ }
+
+ void CloseSession(RegulatorSession *session) {
+ AMS_UNUSED(session);
+ }
+
+ bool GetVoltageEnabled(RegulatorSession *session) {
+ AMS_UNUSED(session);
+ return true;
+ }
+
+ Result SetVoltageEnabled(RegulatorSession *session) {
+ AMS_UNUSED(session);
+ return ResultSuccess();
+ }
+
+ Result SetVoltageValue(RegulatorSession *session, u32 micro_volts) {
+ AMS_UNUSED(session, micro_volts);
+ return ResultSuccess();
+ }
+
+}
diff --git a/stratosphere/boot/source/boot_pcv.cpp b/stratosphere/boot/source/boot_pcv.cpp
deleted file mode 100644
index 59212a9aa..000000000
--- a/stratosphere/boot/source/boot_pcv.cpp
+++ /dev/null
@@ -1,74 +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 "i2c/i2c_types.hpp"
-#include "i2c/driver/impl/i2c_pcv.hpp"
-#include "i2c/driver/impl/i2c_registers.hpp"
-
-using namespace ams::i2c::driver::impl;
-
-namespace ams::pcv {
-
- void Initialize() {
- /* Don't do anything. */
- }
-
- void Finalize() {
- /* Don't do anything. */
- }
-
- Result SetClockRate(PcvModule module, u32 hz) {
- /* Get clock/reset registers. */
- ClkRstRegisters regs;
- regs.SetBus(ConvertFromPcvModule(module));
- /* Set clock enabled/source. */
- reg::SetBits(regs.clk_en_reg, regs.mask);
- reg::ReadWrite(regs.clk_src_reg, 0x4, 0xFF);
- svcSleepThread(1000ul);
- reg::ReadWrite(regs.clk_src_reg, 0, 0xE0000000);
- svcSleepThread(2000ul);
-
- return ResultSuccess();
- }
-
- Result SetClockEnabled(PcvModule module, bool enabled) {
- return ResultSuccess();
- }
-
- Result SetVoltageEnabled(u32 domain, bool enabled) {
- return ResultSuccess();
- }
-
- Result SetVoltageValue(u32 domain, u32 voltage) {
- return ResultSuccess();
- }
-
- Result SetReset(PcvModule module, bool reset) {
- /* Get clock/reset registers. */
- ClkRstRegisters regs;
- regs.SetBus(ConvertFromPcvModule(module));
-
- /* Set/clear reset. */
- if (reset) {
- reg::SetBits(regs.rst_reg, regs.mask);
- } else {
- reg::ClearBits(regs.rst_reg, regs.mask);
- }
-
- return ResultSuccess();
- }
-
-}
diff --git a/stratosphere/boot/source/i2c/driver/i2c_api.cpp b/stratosphere/boot/source/i2c/driver/i2c_api.cpp
deleted file mode 100644
index df9a1bda4..000000000
--- a/stratosphere/boot/source/i2c/driver/i2c_api.cpp
+++ /dev/null
@@ -1,175 +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 "i2c_api.hpp"
-#include "impl/i2c_resource_manager.hpp"
-
-namespace ams::i2c::driver {
-
- namespace {
-
- /* For convenience. */
- using CommandHandler = Result (*)(const u8 **cur_cmd, u8 **cur_dst, Session& session);
-
- /* Command handlers. */
- Result SendHandler(const u8 **cur_cmd, u8 **cur_dst, Session& session) {
- I2cTransactionOption option = static_cast(
- (((**cur_cmd) & (1 << 6)) ? I2cTransactionOption_Start : 0) | (((**cur_cmd) & (1 << 7)) ? I2cTransactionOption_Stop : 0)
- );
- (*cur_cmd)++;
-
- size_t num_bytes = (**cur_cmd);
- (*cur_cmd)++;
-
- R_TRY(Send(session, *cur_cmd, num_bytes, option));
- (*cur_cmd) += num_bytes;
-
- return ResultSuccess();
- }
-
- Result ReceiveHandler(const u8 **cur_cmd, u8 **cur_dst, Session& session) {
- I2cTransactionOption option = static_cast(
- (((**cur_cmd) & (1 << 6)) ? I2cTransactionOption_Start : 0) | (((**cur_cmd) & (1 << 7)) ? I2cTransactionOption_Stop : 0)
- );
- (*cur_cmd)++;
-
- size_t num_bytes = (**cur_cmd);
- (*cur_cmd)++;
-
- R_TRY(Receive(session, *cur_dst, num_bytes, option));
- (*cur_dst) += num_bytes;
-
- return ResultSuccess();
- }
-
- Result SubCommandHandler(const u8 **cur_cmd, u8 **cur_dst, Session& session) {
- const SubCommand sub_cmd = static_cast((**cur_cmd) >> 2);
- (*cur_cmd)++;
-
- switch (sub_cmd) {
- case SubCommand::Sleep:
- {
- const size_t us = (**cur_cmd);
- (*cur_cmd)++;
- svcSleepThread(us * 1'000ul);
- }
- break;
- AMS_UNREACHABLE_DEFAULT_CASE();
- }
- return ResultSuccess();
- }
-
- /* Command handler list. */
- constexpr CommandHandler g_cmd_handlers[static_cast(Command::Count)] = {
- SendHandler,
- ReceiveHandler,
- SubCommandHandler,
- };
-
- inline impl::ResourceManager &GetResourceManager() {
- return impl::ResourceManager::GetInstance();
- }
-
- inline void CheckInitialized() {
- AMS_ABORT_UNLESS(GetResourceManager().IsInitialized());
- }
-
- }
-
- /* Initialization. */
- void Initialize() {
- GetResourceManager().Initialize();
- }
-
- void Finalize() {
- GetResourceManager().Finalize();
- }
-
- /* Session management. */
- void OpenSession(Session *out_session, I2cDevice device) {
- CheckInitialized();
- AMS_ABORT_UNLESS(impl::IsDeviceSupported(device));
-
- const auto bus = impl::GetDeviceBus(device);
- const auto slave_address = impl::GetDeviceSlaveAddress(device);
- const auto addressing_mode = impl::GetDeviceAddressingMode(device);
- const auto speed_mode = impl::GetDeviceSpeedMode(device);
- const auto max_retries = impl::GetDeviceMaxRetries(device);
- const auto retry_wait_time = impl::GetDeviceRetryWaitTime(device);
- GetResourceManager().OpenSession(out_session, bus, slave_address, addressing_mode, speed_mode, max_retries, retry_wait_time);
- }
-
- void CloseSession(Session &session) {
- CheckInitialized();
- GetResourceManager().CloseSession(session);
- }
-
- /* Communication. */
- Result Send(Session &session, const void *src, size_t size, I2cTransactionOption option) {
- CheckInitialized();
- AMS_ABORT_UNLESS(src != nullptr);
- AMS_ABORT_UNLESS(size > 0);
-
- std::scoped_lock lk(GetResourceManager().GetTransactionMutex(impl::ConvertFromIndex(session.bus_idx)));
- return GetResourceManager().GetSession(session.session_id).DoTransactionWithRetry(nullptr, src, size, option, impl::Command::Send);
- }
-
- Result Receive(Session &session, void *dst, size_t size, I2cTransactionOption option) {
- CheckInitialized();
- AMS_ABORT_UNLESS(dst != nullptr);
- AMS_ABORT_UNLESS(size > 0);
-
- std::scoped_lock lk(GetResourceManager().GetTransactionMutex(impl::ConvertFromIndex(session.bus_idx)));
- return GetResourceManager().GetSession(session.session_id).DoTransactionWithRetry(dst, nullptr, size, option, impl::Command::Receive);
- }
-
- Result ExecuteCommandList(Session &session, void *dst, size_t size, const void *cmd_list, size_t cmd_list_size) {
- CheckInitialized();
- AMS_ABORT_UNLESS(dst != nullptr && size > 0);
- AMS_ABORT_UNLESS(cmd_list != nullptr && cmd_list_size > 0);
-
- u8 *cur_dst = static_cast(dst);
- const u8 *cur_cmd = static_cast(cmd_list);
- const u8 *cmd_list_end = cur_cmd + cmd_list_size;
-
- while (cur_cmd < cmd_list_end) {
- Command cmd = static_cast((*cur_cmd) & 3);
- AMS_ABORT_UNLESS(cmd < Command::Count);
-
- R_TRY(g_cmd_handlers[static_cast(cmd)](&cur_cmd, &cur_dst, session));
- }
-
- return ResultSuccess();
- }
-
- /* Power management. */
- void SuspendBuses() {
- GetResourceManager().SuspendBuses();
- }
-
- void ResumeBuses() {
- GetResourceManager().ResumeBuses();
- }
-
- void SuspendPowerBus() {
- GetResourceManager().SuspendPowerBus();
- }
-
- void ResumePowerBus() {
- GetResourceManager().ResumePowerBus();
- }
-
-}
diff --git a/stratosphere/boot/source/i2c/driver/i2c_api.hpp b/stratosphere/boot/source/i2c/driver/i2c_api.hpp
deleted file mode 100644
index 899d7d75e..000000000
--- a/stratosphere/boot/source/i2c/driver/i2c_api.hpp
+++ /dev/null
@@ -1,46 +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 .
- */
-#pragma once
-#include "../i2c_types.hpp"
-#include "../i2c_command_list.hpp"
-
-namespace ams::i2c::driver {
-
- struct Session {
- size_t bus_idx;
- size_t session_id;
- };
-
- /* Initialization. */
- void Initialize();
- void Finalize();
-
- /* Session management. */
- void OpenSession(Session *out_session, I2cDevice device);
- void CloseSession(Session &session);
-
- /* Communication. */
- Result Send(Session &session, const void *src, size_t size, I2cTransactionOption option);
- Result Receive(Session &session, void *dst, size_t size, I2cTransactionOption option);
- Result ExecuteCommandList(Session &session, void *dst, size_t size, const void *cmd_list, size_t cmd_list_size);
-
- /* Power management. */
- void SuspendBuses();
- void ResumeBuses();
- void SuspendPowerBus();
- void ResumePowerBus();
-
-}
diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.cpp b/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.cpp
deleted file mode 100644
index fb419af32..000000000
--- a/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.cpp
+++ /dev/null
@@ -1,450 +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 "i2c_pcv.hpp"
-#include "i2c_bus_accessor.hpp"
-
-namespace ams::i2c::driver::impl {
-
- void BusAccessor::Open(Bus bus, SpeedMode speed_mode) {
- std::scoped_lock lk(this->open_mutex);
- /* Open new session. */
- this->open_sessions++;
-
- /* Ensure we're good if this isn't our first session. */
- if (this->open_sessions > 1) {
- AMS_ABORT_UNLESS(this->speed_mode == speed_mode);
- return;
- }
-
- /* Set all members for chosen bus. */
- {
- std::scoped_lock lk(this->register_mutex);
- /* Set bus/registers. */
- this->SetBus(bus);
- /* Set pcv module. */
- this->pcv_module = ConvertToPcvModule(bus);
- /* Set speed mode. */
- this->speed_mode = speed_mode;
- /* Setup interrupt event. */
- this->CreateInterruptEvent(bus);
- }
- }
-
- void BusAccessor::Close() {
- std::scoped_lock lk(this->open_mutex);
- /* Close current session. */
- this->open_sessions--;
- if (this->open_sessions > 0) {
- return;
- }
-
- /* Close interrupt event. */
- os::FinalizeInterruptEvent(std::addressof(this->interrupt_event));
-
- /* Close PCV. */
- pcv::Finalize();
-
- this->suspended = false;
- }
-
- void BusAccessor::Suspend() {
- std::scoped_lock lk(this->open_mutex);
- std::scoped_lock lk_reg(this->register_mutex);
-
- if (!this->suspended) {
- this->suspended = true;
-
- if (this->pcv_module != PcvModule_I2C5) {
- this->DisableClock();
- }
- }
- }
-
- void BusAccessor::Resume() {
- if (this->suspended) {
- this->DoInitialConfig();
- this->suspended = false;
- }
- }
-
- void BusAccessor::DoInitialConfig() {
- std::scoped_lock lk(this->register_mutex);
-
- if (this->pcv_module != PcvModule_I2C5) {
- pcv::Initialize();
- }
-
- this->ResetController();
- this->SetClock(this->speed_mode);
- this->SetPacketMode();
- this->FlushFifos();
- }
-
- size_t BusAccessor::GetOpenSessions() const {
- return this->open_sessions;
- }
-
- bool BusAccessor::GetBusy() const {
- /* Nintendo has a loop here that calls a member function to check if busy, retrying a few times. */
- /* This member function does "return false". */
- /* We will not bother with the loop. */
- return false;
- }
-
- void BusAccessor::OnStartTransaction() const {
- /* Nothing actually happens here. */
- }
-
- void BusAccessor::OnStopTransaction() const {
- /* Nothing actually happens here. */
- }
-
- Result BusAccessor::StartTransaction(Command command, AddressingMode addressing_mode, u32 slave_address) {
- /* Nothing actually happens here... */
- return ResultSuccess();
- }
-
- Result BusAccessor::Send(const u8 *data, size_t num_bytes, I2cTransactionOption option, AddressingMode addressing_mode, u32 slave_address) {
- std::scoped_lock lk(this->register_mutex);
- const u8 *cur_src = data;
- size_t remaining = num_bytes;
-
- /* Set interrupt enable, clear interrupt status. */
- reg::Write(&this->i2c_registers->I2C_INTERRUPT_MASK_REGISTER_0, 0x8E);
- reg::Write(&this->i2c_registers->I2C_INTERRUPT_STATUS_REGISTER_0, 0xFC);
-
- ON_SCOPE_EXIT { this->ClearInterruptMask(); };
-
- /* Send header. */
- this->WriteTransferHeader(TransferMode::Send, option, addressing_mode, slave_address, num_bytes);
-
- /* Send bytes. */
- while (true) {
- const u32 fifo_status = reg::Read(&this->i2c_registers->I2C_FIFO_STATUS_0);
- const size_t fifo_cnt = (fifo_status >> 4);
-
- for (size_t fifo_idx = 0; remaining > 0 && fifo_idx < fifo_cnt; fifo_idx++) {
- const size_t cur_bytes = std::min(remaining, sizeof(u32));
- u32 val = 0;
- for (size_t i = 0; i < cur_bytes; i++) {
- val |= cur_src[i] << (8 * i);
- }
- reg::Write(&this->i2c_registers->I2C_I2C_TX_PACKET_FIFO_0, val);
-
- cur_src += cur_bytes;
- remaining -= cur_bytes;
- }
-
- if (remaining == 0) {
- break;
- }
-
- os::ClearInterruptEvent(std::addressof(this->interrupt_event));
- if (!os::TimedWaitInterruptEvent(std::addressof(this->interrupt_event), InterruptTimeout)) {
- this->HandleTransactionResult(i2c::ResultBusBusy());
- os::ClearInterruptEvent(std::addressof(this->interrupt_event));
- return i2c::ResultTimedOut();
- }
-
- R_TRY(this->GetAndHandleTransactionResult());
- }
-
- reg::Write(&this->i2c_registers->I2C_INTERRUPT_MASK_REGISTER_0, 0x8C);
-
- /* Wait for successful completion. */
- while (true) {
- R_TRY(this->GetAndHandleTransactionResult());
-
- /* Check PACKET_XFER_COMPLETE */
- const u32 interrupt_status = reg::Read(&this->i2c_registers->I2C_INTERRUPT_STATUS_REGISTER_0);
- if (interrupt_status & 0x80) {
- R_TRY(this->GetAndHandleTransactionResult());
- break;
- }
-
- os::ClearInterruptEvent(std::addressof(this->interrupt_event));
- if (!os::TimedWaitInterruptEvent(std::addressof(this->interrupt_event), InterruptTimeout)) {
- this->HandleTransactionResult(i2c::ResultBusBusy());
- os::ClearInterruptEvent(std::addressof(this->interrupt_event));
- return i2c::ResultTimedOut();
- }
- }
-
- return ResultSuccess();
- }
-
- Result BusAccessor::Receive(u8 *out_data, size_t num_bytes, I2cTransactionOption option, AddressingMode addressing_mode, u32 slave_address) {
- std::scoped_lock lk(this->register_mutex);
- u8 *cur_dst = out_data;
- size_t remaining = num_bytes;
-
- /* Set interrupt enable, clear interrupt status. */
- reg::Write(&this->i2c_registers->I2C_INTERRUPT_MASK_REGISTER_0, 0x8D);
- reg::Write(&this->i2c_registers->I2C_INTERRUPT_STATUS_REGISTER_0, 0xFC);
-
- /* Send header. */
- this->WriteTransferHeader(TransferMode::Receive, option, addressing_mode, slave_address, num_bytes);
-
- /* Receive bytes. */
- while (remaining > 0) {
- os::ClearInterruptEvent(std::addressof(this->interrupt_event));
- if (!os::TimedWaitInterruptEvent(std::addressof(this->interrupt_event), InterruptTimeout)) {
- this->HandleTransactionResult(i2c::ResultBusBusy());
- this->ClearInterruptMask();
- os::ClearInterruptEvent(std::addressof(this->interrupt_event));
- return i2c::ResultTimedOut();
- }
-
- R_TRY(this->GetAndHandleTransactionResult());
-
- const u32 fifo_status = reg::Read(&this->i2c_registers->I2C_FIFO_STATUS_0);
- const size_t fifo_cnt = std::min((remaining + 3) >> 2, static_cast(fifo_status & 0xF));
-
- for (size_t fifo_idx = 0; remaining > 0 && fifo_idx < fifo_cnt; fifo_idx++) {
- const u32 val = reg::Read(&this->i2c_registers->I2C_I2C_RX_FIFO_0);
- const size_t cur_bytes = std::min(remaining, sizeof(u32));
- for (size_t i = 0; i < cur_bytes; i++) {
- cur_dst[i] = static_cast((val >> (8 * i)) & 0xFF);
- }
-
- cur_dst += cur_bytes;
- remaining -= cur_bytes;
- }
- }
-
- /* N doesn't do ClearInterruptMask. */
- return ResultSuccess();
- }
-
- void BusAccessor::SetBus(Bus bus) {
- this->bus = bus;
- this->i2c_registers = GetRegisters(bus);
- this->clkrst_registers.SetBus(bus);
- }
-
- void BusAccessor::CreateInterruptEvent(Bus bus) {
- static constexpr u64 s_interrupts[] = {
- 0x46, 0x74, 0x7C, 0x98, 0x55, 0x5F
- };
- const auto index = ConvertToIndex(bus);
- AMS_ABORT_UNLESS(index < util::size(s_interrupts));
- os::InitializeInterruptEvent(std::addressof(this->interrupt_event), s_interrupts[index], os::EventClearMode_ManualClear);
- os::ClearInterruptEvent(std::addressof(this->interrupt_event));
- }
-
- void BusAccessor::SetClock(SpeedMode speed_mode) {
- u32 t_high, t_low;
- u32 clk_div, src_div;
- u32 debounce;
-
- switch (speed_mode) {
- case SpeedMode::Normal:
- t_high = 2;
- t_low = 4;
- clk_div = 0x19;
- src_div = 0x13;
- debounce = 2;
- break;
- case SpeedMode::Fast:
- t_high = 2;
- t_low = 4;
- clk_div = 0x19;
- src_div = 0x04;
- debounce = 2;
- break;
- case SpeedMode::FastPlus:
- t_high = 2;
- t_low = 4;
- clk_div = 0x10;
- src_div = 0x02;
- debounce = 0;
- break;
- case SpeedMode::HighSpeed:
- t_high = 3;
- t_low = 8;
- clk_div = 0x02;
- src_div = 0x02;
- debounce = 0;
- break;
- AMS_UNREACHABLE_DEFAULT_CASE();
- }
-
- if (speed_mode == SpeedMode::HighSpeed) {
- reg::Write(&this->i2c_registers->I2C_I2C_HS_INTERFACE_TIMING_0_0, (t_high << 8) | (t_low));
- reg::Write(&this->i2c_registers->I2C_I2C_CLK_DIVISOR_REGISTER_0, clk_div);
- } else {
- reg::Write(&this->i2c_registers->I2C_I2C_INTERFACE_TIMING_0_0, (t_high << 8) | (t_low));
- reg::Write(&this->i2c_registers->I2C_I2C_CLK_DIVISOR_REGISTER_0, (clk_div << 16));
- }
-
- reg::Write(&this->i2c_registers->I2C_I2C_CNFG_0, debounce);
- reg::Read(&this->i2c_registers->I2C_I2C_CNFG_0);
-
- if (this->pcv_module != PcvModule_I2C5) {
- R_ABORT_UNLESS(pcv::SetReset(this->pcv_module, true));
- R_ABORT_UNLESS(pcv::SetClockRate(this->pcv_module, (408'000'000) / (src_div + 1)));
- R_ABORT_UNLESS(pcv::SetReset(this->pcv_module, false));
- }
- }
-
- void BusAccessor::ResetController() const {
- if (this->pcv_module != PcvModule_I2C5) {
- R_ABORT_UNLESS(pcv::SetReset(this->pcv_module, true));
- R_ABORT_UNLESS(pcv::SetClockRate(this->pcv_module, 81'600'000));
- R_ABORT_UNLESS(pcv::SetReset(this->pcv_module, false));
- }
- }
-
- void BusAccessor::ClearBus() const {
- bool success = false;
- for (size_t i = 0; i < 3 && !success; i++) {
- success = true;
-
- this->ResetController();
-
- reg::Write(&this->i2c_registers->I2C_I2C_BUS_CLEAR_CONFIG_0, 0x90000);
- reg::SetBits(&this->i2c_registers->I2C_I2C_BUS_CLEAR_CONFIG_0, 0x4);
- reg::SetBits(&this->i2c_registers->I2C_I2C_BUS_CLEAR_CONFIG_0, 0x2);
-
- reg::SetBits(&this->i2c_registers->I2C_I2C_CONFIG_LOAD_0, 0x1);
- {
- u64 start_tick = armGetSystemTick();
- while (reg::Read(&this->i2c_registers->I2C_I2C_CONFIG_LOAD_0) & 1) {
- if (armTicksToNs(armGetSystemTick() - start_tick) > 1'000'000) {
- success = false;
- break;
- }
- }
- }
- if (!success) {
- continue;
- }
-
- reg::SetBits(&this->i2c_registers->I2C_I2C_BUS_CLEAR_CONFIG_0, 0x1);
- {
- u64 start_tick = armGetSystemTick();
- while (reg::Read(&this->i2c_registers->I2C_I2C_BUS_CLEAR_CONFIG_0) & 1) {
- if (armTicksToNs(armGetSystemTick() - start_tick) > 1'000'000) {
- success = false;
- break;
- }
- }
- }
- if (!success) {
- continue;
- }
-
- {
- u64 start_tick = armGetSystemTick();
- while (reg::Read(&this->i2c_registers->I2C_I2C_BUS_CLEAR_STATUS_0) & 1) {
- if (armTicksToNs(armGetSystemTick() - start_tick) > 1'000'000) {
- success = false;
- break;
- }
- }
- }
- if (!success) {
- continue;
- }
- }
- }
-
- void BusAccessor::DisableClock() {
- R_ABORT_UNLESS(pcv::SetClockEnabled(this->pcv_module, false));
- }
-
- void BusAccessor::SetPacketMode() {
- /* Set PACKET_MODE_EN, MSTR_CONFIG_LOAD */
- reg::SetBits(&this->i2c_registers->I2C_I2C_CNFG_0, 0x400);
- reg::SetBits(&this->i2c_registers->I2C_I2C_CONFIG_LOAD_0, 0x1);
-
- /* Set TX_FIFO_TRIGGER, RX_FIFO_TRIGGER */
- reg::Write(&this->i2c_registers->I2C_FIFO_CONTROL_0, 0xFC);
- }
-
- Result BusAccessor::FlushFifos() {
- reg::Write(&this->i2c_registers->I2C_FIFO_CONTROL_0, 0xFF);
-
- /* Wait for flush to finish, check every ms for 5 ms. */
- for (size_t i = 0; i < 5; i++) {
- const bool flush_done = (reg::Read(&this->i2c_registers->I2C_FIFO_CONTROL_0) & 3) == 0;
- R_SUCCEED_IF(flush_done);
- svcSleepThread(1'000'000ul);
- }
-
- return i2c::ResultBusBusy();
- }
-
- Result BusAccessor::GetTransactionResult() const {
- const u32 packet_status = reg::Read(&this->i2c_registers->I2C_PACKET_TRANSFER_STATUS_0);
- const u32 interrupt_status = reg::Read(&this->i2c_registers->I2C_INTERRUPT_STATUS_REGISTER_0);
-
- /* Check for no ack. */
- R_UNLESS(!(packet_status & 0xC), i2c::ResultNoAck());
- R_UNLESS(!(interrupt_status & 0x8), i2c::ResultNoAck());
-
- /* Check for arb lost. */
- {
- auto bus_guard = SCOPE_GUARD { this->ClearBus(); };
- R_UNLESS(!(packet_status & 0x2), i2c::ResultBusBusy());
- R_UNLESS(!(interrupt_status & 0x4), i2c::ResultBusBusy());
- bus_guard.Cancel();
- }
-
- return ResultSuccess();
- }
-
- void BusAccessor::HandleTransactionResult(Result result) {
- R_TRY_CATCH(result) {
- R_CATCH(i2c::ResultNoAck, i2c::ResultBusBusy) {
- this->ResetController();
- this->SetClock(this->speed_mode);
- this->SetPacketMode();
- this->FlushFifos();
- }
- } R_END_TRY_CATCH_WITH_ABORT_UNLESS;
- }
-
- Result BusAccessor::GetAndHandleTransactionResult() {
- const auto transaction_result = this->GetTransactionResult();
- R_SUCCEED_IF(R_SUCCEEDED(transaction_result));
-
- this->HandleTransactionResult(transaction_result);
- this->ClearInterruptMask();
- os::ClearInterruptEvent(std::addressof(this->interrupt_event));
- return transaction_result;
- }
-
- void BusAccessor::WriteTransferHeader(TransferMode transfer_mode, I2cTransactionOption option, AddressingMode addressing_mode, u32 slave_address, size_t num_bytes) {
- this->FlushFifos();
-
- reg::Write(&this->i2c_registers->I2C_I2C_TX_PACKET_FIFO_0, 0x10);
- reg::Write(&this->i2c_registers->I2C_I2C_TX_PACKET_FIFO_0, static_cast(num_bytes - 1) & 0xFFF);
-
- const u32 slave_addr_val = ((transfer_mode == TransferMode::Receive) & 1) | ((slave_address & 0x7F) << 1);
- u32 hdr_val = 0;
- hdr_val |= ((this->speed_mode == SpeedMode::HighSpeed) & 1) << 22;
- hdr_val |= ((transfer_mode == TransferMode::Receive) & 1) << 19;
- hdr_val |= ((addressing_mode != AddressingMode::SevenBit) & 1) << 18;
- hdr_val |= (1 << 17);
- hdr_val |= (((option & I2cTransactionOption_Stop) == 0) & 1) << 16;
- hdr_val |= slave_addr_val;
-
- reg::Write(&this->i2c_registers->I2C_I2C_TX_PACKET_FIFO_0, hdr_val);
- }
-
-}
diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.hpp b/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.hpp
deleted file mode 100644
index 8fa682627..000000000
--- a/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.hpp
+++ /dev/null
@@ -1,81 +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 .
- */
-#pragma once
-#include "i2c_driver_types.hpp"
-#include "i2c_registers.hpp"
-
-namespace ams::i2c::driver::impl {
-
- class BusAccessor {
- private:
- enum class TransferMode {
- Send = 0,
- Receive = 1,
- };
- static constexpr TimeSpan InterruptTimeout = TimeSpan::FromMilliSeconds(100);
- private:
- os::InterruptEventType interrupt_event;
- os::Mutex open_mutex;
- os::Mutex register_mutex;
- Registers *i2c_registers = nullptr;
- ClkRstRegisters clkrst_registers;
- SpeedMode speed_mode = SpeedMode::Fast;
- size_t open_sessions = 0;
- Bus bus = Bus::I2C1;
- PcvModule pcv_module = PcvModule_I2C1;
- bool suspended = false;
- public:
- BusAccessor() : open_mutex(false), register_mutex(false) { /* ... */ }
- private:
- inline void ClearInterruptMask() const {
- reg::Write(&i2c_registers->I2C_INTERRUPT_MASK_REGISTER_0, 0);
- reg::Read(&i2c_registers->I2C_INTERRUPT_MASK_REGISTER_0);
- }
-
- void SetBus(Bus bus);
- void CreateInterruptEvent(Bus bus);
- void SetClock(SpeedMode speed_mode);
-
- void ResetController() const;
- void ClearBus() const;
- void DisableClock();
- void SetPacketMode();
- Result FlushFifos();
-
- Result GetTransactionResult() const;
- void HandleTransactionResult(Result result);
- Result GetAndHandleTransactionResult();
-
- void WriteTransferHeader(TransferMode transfer_mode, I2cTransactionOption option, AddressingMode addressing_mode, u32 slave_address, size_t num_bytes);
- public:
- void Open(Bus bus, SpeedMode speed_mode);
- void Close();
- void Suspend();
- void Resume();
- void DoInitialConfig();
-
- size_t GetOpenSessions() const;
- bool GetBusy() const;
-
- void OnStartTransaction() const;
- Result StartTransaction(Command command, AddressingMode addressing_mode, u32 slave_address);
- Result Send(const u8 *data, size_t num_bytes, I2cTransactionOption option, AddressingMode addressing_mode, u32 slave_address);
- Result Receive(u8 *out_data, size_t num_bytes, I2cTransactionOption option, AddressingMode addressing_mode, u32 slave_address);
- void OnStopTransaction() const;
- };
-
-
-}
\ No newline at end of file
diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_device_config.cpp b/stratosphere/boot/source/i2c/driver/impl/i2c_device_config.cpp
deleted file mode 100644
index d6b3f1a5f..000000000
--- a/stratosphere/boot/source/i2c/driver/impl/i2c_device_config.cpp
+++ /dev/null
@@ -1,122 +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 "i2c_driver_types.hpp"
-
-namespace ams::i2c::driver::impl {
-
- namespace {
-
- struct DeviceConfig {
- I2cDevice device;
- Bus bus;
- u32 slave_address;
- AddressingMode addressing_mode;
- SpeedMode speed_mode;
- u32 max_retries;
- u64 retry_wait_time;
- };
-
- constexpr DeviceConfig g_device_configs[I2cDevice_Count] = {
- {I2cDevice_DebugPad, Bus::I2C1, 0x52, AddressingMode::SevenBit, SpeedMode::Normal, 0, 0},
- {I2cDevice_TouchPanel, Bus::I2C3, 0x49, AddressingMode::SevenBit, SpeedMode::Fast, 0, 0},
- {I2cDevice_Tmp451, Bus::I2C1, 0x4c, AddressingMode::SevenBit, SpeedMode::Normal, 0, 0},
- {I2cDevice_Nct72, Bus::I2C1, 0x4c, AddressingMode::SevenBit, SpeedMode::Normal, 0, 0},
- {I2cDevice_Alc5639, Bus::I2C1, 0x1c, AddressingMode::SevenBit, SpeedMode::Normal, 0, 0},
- {I2cDevice_Max77620Rtc, Bus::I2C5, 0x68, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- {I2cDevice_Max77620Pmic, Bus::I2C5, 0x3c, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- {I2cDevice_Max77621Cpu, Bus::I2C5, 0x1b, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- {I2cDevice_Max77621Gpu, Bus::I2C5, 0x1c, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- {I2cDevice_Bq24193, Bus::I2C1, 0x6b, AddressingMode::SevenBit, SpeedMode::Normal, 3, 5'000'000},
- {I2cDevice_Max17050, Bus::I2C1, 0x36, AddressingMode::SevenBit, SpeedMode::Normal, 3, 5'000'000},
- {I2cDevice_Bm92t30mwv, Bus::I2C1, 0x18, AddressingMode::SevenBit, SpeedMode::Normal, 3, 5'000'000},
- {I2cDevice_Ina226Vdd15v0Hb, Bus::I2C2, 0x40, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- {I2cDevice_Ina226VsysCpuDs, Bus::I2C2, 0x41, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- {I2cDevice_Ina226VsysGpuDs, Bus::I2C2, 0x44, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- {I2cDevice_Ina226VsysDdrDs, Bus::I2C2, 0x45, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- {I2cDevice_Ina226VsysAp, Bus::I2C2, 0x46, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- {I2cDevice_Ina226VsysBlDs, Bus::I2C2, 0x47, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- {I2cDevice_Bh1730, Bus::I2C2, 0x29, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- {I2cDevice_Ina226VsysCore, Bus::I2C2, 0x48, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- {I2cDevice_Ina226Soc1V8, Bus::I2C2, 0x49, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- {I2cDevice_Ina226Lpddr1V8, Bus::I2C2, 0x4a, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- {I2cDevice_Ina226Reg1V32, Bus::I2C2, 0x4b, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- {I2cDevice_Ina226Vdd3V3Sys, Bus::I2C2, 0x4d, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- {I2cDevice_HdmiDdc, Bus::I2C4, 0x50, AddressingMode::SevenBit, SpeedMode::Normal, 0, 0},
- {I2cDevice_HdmiScdc, Bus::I2C4, 0x54, AddressingMode::SevenBit, SpeedMode::Normal, 0, 0},
- {I2cDevice_HdmiHdcp, Bus::I2C4, 0x3a, AddressingMode::SevenBit, SpeedMode::Normal, 0, 0},
- {I2cDevice_Fan53528, Bus::I2C5, 0xa4, AddressingMode::SevenBit, SpeedMode::Fast, 0, 0},
- {I2cDevice_Max77812_3, Bus::I2C5, 0x31, AddressingMode::SevenBit, SpeedMode::Fast, 0, 0},
- {I2cDevice_Max77812_2, Bus::I2C5, 0x33, AddressingMode::SevenBit, SpeedMode::Fast, 0, 0},
- {I2cDevice_Ina226VddDdr0V6, Bus::I2C2, 0x4e, AddressingMode::SevenBit, SpeedMode::Fast, 3, 5'000'000},
- };
-
- constexpr size_t NumDeviceConfigs = util::size(g_device_configs);
-
- constexpr size_t DeviceInvalidIndex = static_cast(-1);
-
- size_t GetDeviceIndex(I2cDevice dev) {
- for (size_t i = 0; i < NumDeviceConfigs; i++) {
- if (g_device_configs[i].device == dev) {
- return i;
- }
- }
- return DeviceInvalidIndex;
- }
-
- }
-
- bool IsDeviceSupported(I2cDevice dev) {
- return GetDeviceIndex(dev) != DeviceInvalidIndex;
- }
-
- Bus GetDeviceBus(I2cDevice dev) {
- const size_t dev_idx = GetDeviceIndex(dev);
- AMS_ABORT_UNLESS(dev_idx != DeviceInvalidIndex);
- return g_device_configs[dev_idx].bus;
- }
-
- u32 GetDeviceSlaveAddress(I2cDevice dev) {
- const size_t dev_idx = GetDeviceIndex(dev);
- AMS_ABORT_UNLESS(dev_idx != DeviceInvalidIndex);
- return g_device_configs[dev_idx].slave_address;
- }
-
- AddressingMode GetDeviceAddressingMode(I2cDevice dev) {
- const size_t dev_idx = GetDeviceIndex(dev);
- AMS_ABORT_UNLESS(dev_idx != DeviceInvalidIndex);
- return g_device_configs[dev_idx].addressing_mode;
- }
-
- SpeedMode GetDeviceSpeedMode(I2cDevice dev) {
- const size_t dev_idx = GetDeviceIndex(dev);
- AMS_ABORT_UNLESS(dev_idx != DeviceInvalidIndex);
- return g_device_configs[dev_idx].speed_mode;
- }
-
- u32 GetDeviceMaxRetries(I2cDevice dev) {
- const size_t dev_idx = GetDeviceIndex(dev);
- AMS_ABORT_UNLESS(dev_idx != DeviceInvalidIndex);
- return g_device_configs[dev_idx].max_retries;
- }
-
- u64 GetDeviceRetryWaitTime(I2cDevice dev) {
- const size_t dev_idx = GetDeviceIndex(dev);
- AMS_ABORT_UNLESS(dev_idx != DeviceInvalidIndex);
- return g_device_configs[dev_idx].retry_wait_time;
- }
-
-}
diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_driver_types.hpp b/stratosphere/boot/source/i2c/driver/impl/i2c_driver_types.hpp
deleted file mode 100644
index 43d59cb20..000000000
--- a/stratosphere/boot/source/i2c/driver/impl/i2c_driver_types.hpp
+++ /dev/null
@@ -1,91 +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 .
- */
-#pragma once
-#include "../../i2c_types.hpp"
-
-namespace ams::i2c::driver::impl {
-
- enum class Command {
- Send = 0,
- Receive = 1,
- };
-
- enum class Bus {
- I2C1 = 0,
- I2C2 = 1,
- I2C3 = 2,
- I2C4 = 3,
- I2C5 = 4,
- I2C6 = 5,
- Count,
- };
-
- /* Bus helpers. */
- constexpr inline size_t ConvertToIndex(Bus bus) {
- return static_cast(bus);
- }
-
- constexpr inline Bus ConvertFromIndex(size_t idx) {
- AMS_ABORT_UNLESS(idx < static_cast(Bus::Count));
- return static_cast(idx);
- }
-
- constexpr inline PcvModule ConvertToPcvModule(Bus bus) {
- switch (bus) {
- case Bus::I2C1:
- return PcvModule_I2C1;
- case Bus::I2C2:
- return PcvModule_I2C2;
- case Bus::I2C3:
- return PcvModule_I2C3;
- case Bus::I2C4:
- return PcvModule_I2C4;
- case Bus::I2C5:
- return PcvModule_I2C5;
- case Bus::I2C6:
- return PcvModule_I2C6;
- AMS_UNREACHABLE_DEFAULT_CASE();
- }
- }
-
- constexpr inline Bus ConvertFromPcvModule(PcvModule module) {
- switch (module) {
- case PcvModule_I2C1:
- return Bus::I2C1;
- case PcvModule_I2C2:
- return Bus::I2C2;
- case PcvModule_I2C3:
- return Bus::I2C3;
- case PcvModule_I2C4:
- return Bus::I2C4;
- case PcvModule_I2C5:
- return Bus::I2C5;
- case PcvModule_I2C6:
- return Bus::I2C6;
- AMS_UNREACHABLE_DEFAULT_CASE();
- }
- }
-
- /* Global type functions. */
- bool IsDeviceSupported(I2cDevice dev);
- Bus GetDeviceBus(I2cDevice dev);
- u32 GetDeviceSlaveAddress(I2cDevice dev);
- AddressingMode GetDeviceAddressingMode(I2cDevice dev);
- SpeedMode GetDeviceSpeedMode(I2cDevice dev);
- u32 GetDeviceMaxRetries(I2cDevice dev);
- u64 GetDeviceRetryWaitTime(I2cDevice dev);
-
-}
diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_registers.hpp b/stratosphere/boot/source/i2c/driver/impl/i2c_registers.hpp
deleted file mode 100644
index 4fd094a3f..000000000
--- a/stratosphere/boot/source/i2c/driver/impl/i2c_registers.hpp
+++ /dev/null
@@ -1,104 +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 .
- */
-#pragma once
-#include "i2c_driver_types.hpp"
-
-namespace ams::i2c::driver::impl {
-
- struct Registers {
- volatile u32 I2C_I2C_CNFG_0;
- volatile u32 I2C_I2C_CMD_ADDR0_0;
- volatile u32 I2C_I2C_CMD_ADDR1_0;
- volatile u32 I2C_I2C_CMD_DATA1_0;
- volatile u32 I2C_I2C_CMD_DATA2_0;
- volatile u32 _0x14;
- volatile u32 _0x18;
- volatile u32 I2C_I2C_STATUS_0;
- volatile u32 I2C_I2C_SL_CNFG_0;
- volatile u32 I2C_I2C_SL_RCVD_0;
- volatile u32 I2C_I2C_SL_STATUS_0;
- volatile u32 I2C_I2C_SL_ADDR1_0;
- volatile u32 I2C_I2C_SL_ADDR2_0;
- volatile u32 I2C_I2C_TLOW_SEXT_0;
- volatile u32 _0x38;
- volatile u32 I2C_I2C_SL_DELAY_COUNT_0;
- volatile u32 I2C_I2C_SL_INT_MASK_0;
- volatile u32 I2C_I2C_SL_INT_SOURCE_0;
- volatile u32 I2C_I2C_SL_INT_SET_0;
- volatile u32 _0x4C;
- volatile u32 I2C_I2C_TX_PACKET_FIFO_0;
- volatile u32 I2C_I2C_RX_FIFO_0;
- volatile u32 I2C_PACKET_TRANSFER_STATUS_0;
- volatile u32 I2C_FIFO_CONTROL_0;
- volatile u32 I2C_FIFO_STATUS_0;
- volatile u32 I2C_INTERRUPT_MASK_REGISTER_0;
- volatile u32 I2C_INTERRUPT_STATUS_REGISTER_0;
- volatile u32 I2C_I2C_CLK_DIVISOR_REGISTER_0;
- volatile u32 I2C_I2C_INTERRUPT_SOURCE_REGISTER_0;
- volatile u32 I2C_I2C_INTERRUPT_SET_REGISTER_0;
- volatile u32 I2C_I2C_SLV_TX_PACKET_FIFO_0;
- volatile u32 I2C_I2C_SLV_RX_FIFO_0;
- volatile u32 I2C_I2C_SLV_PACKET_STATUS_0;
- volatile u32 I2C_I2C_BUS_CLEAR_CONFIG_0;
- volatile u32 I2C_I2C_BUS_CLEAR_STATUS_0;
- volatile u32 I2C_I2C_CONFIG_LOAD_0;
- volatile u32 _0x90;
- volatile u32 I2C_I2C_INTERFACE_TIMING_0_0;
- volatile u32 I2C_I2C_INTERFACE_TIMING_1_0;
- volatile u32 I2C_I2C_HS_INTERFACE_TIMING_0_0;
- volatile u32 I2C_I2C_HS_INTERFACE_TIMING_1_0;
- };
-
- struct ClkRstRegisters {
- public:
- uintptr_t clk_src_reg;
- uintptr_t clk_en_reg;
- uintptr_t rst_reg;
- u32 mask;
- public:
- void SetBus(Bus bus) {
- static constexpr uintptr_t s_clk_src_offsets[ConvertToIndex(Bus::Count)] = {
- 0x124, 0x198, 0x1b8, 0x3c4, 0x128, 0x65c
- };
- static constexpr uintptr_t s_clk_en_offsets[ConvertToIndex(Bus::Count)] = {
- 0x010, 0x014, 0x018, 0x360, 0x014, 0x280
- };
- static constexpr uintptr_t s_rst_offsets[ConvertToIndex(Bus::Count)] = {
- 0x004, 0x008, 0x00c, 0x358, 0x008, 0x28c
- };
- static constexpr size_t s_bit_shifts[ConvertToIndex(Bus::Count)] = {
- 12, 22, 3, 7, 15, 6
- };
-
- const uintptr_t registers = dd::GetIoMapping(0x60006000ul, os::MemoryPageSize);
- const size_t idx = ConvertToIndex(bus);
- this->clk_src_reg = registers + s_clk_src_offsets[idx];
- this->clk_en_reg = registers + s_clk_en_offsets[idx];
- this->rst_reg = registers + s_rst_offsets[idx];
- this->mask = (1u << s_bit_shifts[idx]);
- }
- };
-
- inline Registers *GetRegisters(Bus bus) {
- static constexpr uintptr_t s_offsets[ConvertToIndex(Bus::Count)] = {
- 0x0000, 0x0400, 0x0500, 0x0700, 0x1000, 0x1100
- };
-
- const uintptr_t registers = dd::GetIoMapping(0x7000c000ul, 2 * os::MemoryPageSize) + s_offsets[ConvertToIndex(bus)];
- return reinterpret_cast(registers);
- }
-
-}
diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_resource_manager.cpp b/stratosphere/boot/source/i2c/driver/impl/i2c_resource_manager.cpp
deleted file mode 100644
index 627ab3c26..000000000
--- a/stratosphere/boot/source/i2c/driver/impl/i2c_resource_manager.cpp
+++ /dev/null
@@ -1,175 +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 "i2c_pcv.hpp"
-#include "i2c_resource_manager.hpp"
-
-namespace ams::i2c::driver::impl {
-
- void ResourceManager::Initialize() {
- std::scoped_lock lk(this->initialize_mutex);
- this->ref_cnt++;
- }
-
- void ResourceManager::Finalize() {
- std::scoped_lock lk(this->initialize_mutex);
- AMS_ABORT_UNLESS(this->ref_cnt > 0);
- this->ref_cnt--;
- if (this->ref_cnt > 0) {
- return;
- }
-
- {
- std::scoped_lock sess_lk(this->session_open_mutex);
- for (size_t i = 0; i < MaxDriverSessions; i++) {
- this->sessions[i].Close();
- }
- }
- }
-
- size_t ResourceManager::GetFreeSessionId() const {
- for (size_t i = 0; i < MaxDriverSessions; i++) {
- if (!this->sessions[i].IsOpen()) {
- return i;
- }
- }
-
- return InvalidSessionId;
- }
-
- void ResourceManager::OpenSession(driver::Session *out_session, Bus bus, u32 slave_address, AddressingMode addressing_mode, SpeedMode speed_mode, u32 max_retries, u64 retry_wait_time) {
- bool need_enable_ldo6 = false;
- size_t session_id = InvalidSessionId;
- /* Get, open session. */
- {
- std::scoped_lock lk(this->session_open_mutex);
- AMS_ABORT_UNLESS(out_session != nullptr);
- AMS_ABORT_UNLESS(bus < Bus::Count);
-
- session_id = GetFreeSessionId();
- AMS_ABORT_UNLESS(session_id != InvalidSessionId);
-
-
- if ((bus == Bus::I2C2 || bus == Bus::I2C3) && (this->bus_accessors[ConvertToIndex(Bus::I2C2)].GetOpenSessions() == 0 && this->bus_accessors[ConvertToIndex(Bus::I2C3)].GetOpenSessions() == 0)) {
- need_enable_ldo6 = true;
- }
-
- out_session->session_id = session_id;
- out_session->bus_idx = ConvertToIndex(bus);
- this->sessions[session_id].Open(bus, slave_address, addressing_mode, speed_mode, &this->bus_accessors[ConvertToIndex(bus)], max_retries, retry_wait_time);
- }
-
- this->sessions[session_id].Start();
- if (need_enable_ldo6) {
- pcv::Initialize();
- R_ABORT_UNLESS(pcv::SetVoltageValue(10, 2'900'000));
- R_ABORT_UNLESS(pcv::SetVoltageEnabled(10, true));
- pcv::Finalize();
- svcSleepThread(560'000ul);
- }
- }
-
- void ResourceManager::CloseSession(const driver::Session &session) {
- bool need_disable_ldo6 = false;
- /* Get, open session. */
- {
- std::scoped_lock lk(this->session_open_mutex);
- AMS_ABORT_UNLESS(this->sessions[session.session_id].IsOpen());
-
- this->sessions[session.session_id].Close();
-
- if ((ConvertFromIndex(session.bus_idx) == Bus::I2C2 || ConvertFromIndex(session.bus_idx) == Bus::I2C3) &&
- (this->bus_accessors[ConvertToIndex(Bus::I2C2)].GetOpenSessions() == 0 && this->bus_accessors[ConvertToIndex(Bus::I2C3)].GetOpenSessions() == 0)) {
- need_disable_ldo6 = true;
- }
- }
-
- if (need_disable_ldo6) {
- pcv::Initialize();
- R_ABORT_UNLESS(pcv::SetVoltageEnabled(10, false));
- pcv::Finalize();
- }
-
- }
-
- void ResourceManager::SuspendBuses() {
- AMS_ABORT_UNLESS(this->ref_cnt > 0);
-
- if (!this->suspended) {
- {
- std::scoped_lock lk(this->session_open_mutex);
- this->suspended = true;
- for (size_t i = 0; i < ConvertToIndex(Bus::Count); i++) {
- if (i != PowerBusId && this->bus_accessors[i].GetOpenSessions() > 0) {
- this->bus_accessors[i].Suspend();
- }
- }
- }
- pcv::Initialize();
- R_ABORT_UNLESS(pcv::SetVoltageEnabled(10, false));
- pcv::Finalize();
- }
- }
-
- void ResourceManager::ResumeBuses() {
- AMS_ABORT_UNLESS(this->ref_cnt > 0);
-
- if (this->suspended) {
- if (this->bus_accessors[ConvertToIndex(Bus::I2C2)].GetOpenSessions() > 0 || this->bus_accessors[ConvertToIndex(Bus::I2C3)].GetOpenSessions() > 0) {
- pcv::Initialize();
- R_ABORT_UNLESS(pcv::SetVoltageValue(10, 2'900'000));
- R_ABORT_UNLESS(pcv::SetVoltageEnabled(10, true));
- pcv::Finalize();
- svcSleepThread(1'560'000ul);
- }
- {
- std::scoped_lock lk(this->session_open_mutex);
- for (size_t i = 0; i < ConvertToIndex(Bus::Count); i++) {
- if (i != PowerBusId && this->bus_accessors[i].GetOpenSessions() > 0) {
- this->bus_accessors[i].Resume();
- }
- }
- }
- this->suspended = false;
- }
- }
-
- void ResourceManager::SuspendPowerBus() {
- AMS_ABORT_UNLESS(this->ref_cnt > 0);
- std::scoped_lock lk(this->session_open_mutex);
-
- if (!this->power_bus_suspended) {
- this->power_bus_suspended = true;
- if (this->bus_accessors[PowerBusId].GetOpenSessions() > 0) {
- this->bus_accessors[PowerBusId].Suspend();
- }
- }
- }
-
- void ResourceManager::ResumePowerBus() {
- AMS_ABORT_UNLESS(this->ref_cnt > 0);
- std::scoped_lock lk(this->session_open_mutex);
-
- if (this->power_bus_suspended) {
- if (this->bus_accessors[PowerBusId].GetOpenSessions() > 0) {
- this->bus_accessors[PowerBusId].Resume();
- }
- this->power_bus_suspended = false;
- }
- }
-
-}
-
diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_resource_manager.hpp b/stratosphere/boot/source/i2c/driver/impl/i2c_resource_manager.hpp
deleted file mode 100644
index 27465a2fd..000000000
--- a/stratosphere/boot/source/i2c/driver/impl/i2c_resource_manager.hpp
+++ /dev/null
@@ -1,82 +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 .
- */
-#pragma once
-#include "../i2c_api.hpp"
-#include "i2c_driver_types.hpp"
-#include "i2c_bus_accessor.hpp"
-#include "i2c_session.hpp"
-
-namespace ams::i2c::driver::impl {
-
- class ResourceManager {
- public:
- static constexpr size_t MaxDriverSessions = 40;
- static constexpr size_t PowerBusId = ConvertToIndex(Bus::I2C5);
- static constexpr size_t InvalidSessionId = static_cast(-1);
- private:
- os::Mutex initialize_mutex;
- os::Mutex session_open_mutex;
- size_t ref_cnt = 0;
- bool suspended = false;
- bool power_bus_suspended = false;
- Session sessions[MaxDriverSessions];
- BusAccessor bus_accessors[ConvertToIndex(Bus::Count)];
- TYPED_STORAGE(os::Mutex) transaction_mutexes[ConvertToIndex(Bus::Count)];
- public:
- ResourceManager() : initialize_mutex(false), session_open_mutex(false) {
- for (size_t i = 0; i < util::size(this->transaction_mutexes); i++) {
- new (GetPointer(this->transaction_mutexes[i])) os::Mutex(false);
- }
- }
-
- ~ResourceManager() {
- for (size_t i = 0; i < util::size(this->transaction_mutexes); i++) {
- GetReference(this->transaction_mutexes[i]).~Mutex();
- }
- }
- private:
- size_t GetFreeSessionId() const;
- public:
- /* N uses a singleton here, we'll oblige. */
- static ResourceManager &GetInstance() {
- static ResourceManager s_instance;
- return s_instance;
- }
-
- bool IsInitialized() const {
- return this->ref_cnt > 0;
- }
-
- Session& GetSession(size_t id) {
- return this->sessions[id];
- }
-
- os::Mutex& GetTransactionMutex(Bus bus) {
- return GetReference(this->transaction_mutexes[ConvertToIndex(bus)]);
- }
-
- void Initialize();
- void Finalize();
-
- void OpenSession(driver::Session *out_session, Bus bus, u32 slave_address, AddressingMode addressing_mode, SpeedMode speed_mode, u32 max_retries, u64 retry_wait_time);
- void CloseSession(const driver::Session &session);
- void SuspendBuses();
- void ResumeBuses();
- void SuspendPowerBus();
- void ResumePowerBus();
- };
-
-}
diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_session.cpp b/stratosphere/boot/source/i2c/driver/impl/i2c_session.cpp
deleted file mode 100644
index 8e982ec6e..000000000
--- a/stratosphere/boot/source/i2c/driver/impl/i2c_session.cpp
+++ /dev/null
@@ -1,96 +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 "i2c_session.hpp"
-
-namespace ams::i2c::driver::impl {
-
- void Session::Open(Bus bus, u32 slave_address, AddressingMode addr_mode, SpeedMode speed_mode, BusAccessor *bus_accessor, u32 max_retries, u64 retry_wait_time) {
- std::scoped_lock lk(this->bus_accessor_mutex);
- if (!this->open) {
- this->bus_accessor = bus_accessor;
- this->bus = bus;
- this->slave_address = slave_address;
- this->addressing_mode = addr_mode;
- this->max_retries = max_retries;
- this->retry_wait_time = retry_wait_time;
- this->bus_accessor->Open(this->bus, speed_mode);
- this->open = true;
- }
- }
-
- void Session::Start() {
- std::scoped_lock lk(this->bus_accessor_mutex);
- if (this->open) {
- if (this->bus_accessor->GetOpenSessions() == 1) {
- this->bus_accessor->DoInitialConfig();
- }
- }
- }
-
- void Session::Close() {
- std::scoped_lock lk(this->bus_accessor_mutex);
- if (this->open) {
- this->bus_accessor->Close();
- this->bus_accessor = nullptr;
- this->open = false;
- }
- }
-
- bool Session::IsOpen() const {
- return this->open;
- }
-
- Result Session::DoTransaction(void *dst, const void *src, size_t num_bytes, I2cTransactionOption option, Command command) {
- std::scoped_lock lk(this->bus_accessor_mutex);
-
- R_UNLESS(!this->bus_accessor->GetBusy(), i2c::ResultBusBusy());
-
- this->bus_accessor->OnStartTransaction();
- ON_SCOPE_EXIT { this->bus_accessor->OnStopTransaction(); };
-
- R_TRY(this->bus_accessor->StartTransaction(command, this->addressing_mode, this->slave_address));
-
- switch (command) {
- case Command::Send:
- R_TRY(this->bus_accessor->Send(reinterpret_cast(src), num_bytes, option, this->addressing_mode, this->slave_address));
- break;
- case Command::Receive:
- R_TRY(this->bus_accessor->Receive(reinterpret_cast(dst), num_bytes, option, this->addressing_mode, this->slave_address));
- break;
- AMS_UNREACHABLE_DEFAULT_CASE();
- }
-
- return ResultSuccess();
- }
-
- Result Session::DoTransactionWithRetry(void *dst, const void *src, size_t num_bytes, I2cTransactionOption option, Command command) {
- size_t i = 0;
- while (true) {
- R_TRY_CATCH(this->DoTransaction(dst, src, num_bytes, option, command)) {
- R_CATCH(i2c::ResultTimedOut) {
- if ((++i) <= this->max_retries) {
- svcSleepThread(this->retry_wait_time);
- continue;
- }
- return i2c::ResultBusBusy();
- }
- } R_END_TRY_CATCH;
- return ResultSuccess();
- }
- }
-
-}
diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_session.hpp b/stratosphere/boot/source/i2c/driver/impl/i2c_session.hpp
deleted file mode 100644
index 010bd41c6..000000000
--- a/stratosphere/boot/source/i2c/driver/impl/i2c_session.hpp
+++ /dev/null
@@ -1,47 +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 .
- */
-#pragma once
-#include "i2c_driver_types.hpp"
-#include "i2c_bus_accessor.hpp"
-
-namespace ams::i2c::driver::impl {
-
- class Session {
- private:
- os::Mutex bus_accessor_mutex;
- BusAccessor *bus_accessor = nullptr;
- Bus bus = Bus::I2C1;
- u32 slave_address = 0;
- AddressingMode addressing_mode = AddressingMode::SevenBit;
- u32 max_retries = 0;
- u64 retry_wait_time = 0;
- bool open = false;
- public:
- Session() : bus_accessor_mutex(false) { /* ... */ }
- public:
- void Open(Bus bus, u32 slave_address, AddressingMode addr_mode, SpeedMode speed_mode, BusAccessor *bus_accessor, u32 max_retries, u64 retry_wait_time);
- void Start();
- void Close();
-
- bool IsOpen() const;
-
- Result DoTransaction(void *dst, const void *src, size_t num_bytes, I2cTransactionOption option, Command command);
- Result DoTransactionWithRetry(void *dst, const void *src, size_t num_bytes, I2cTransactionOption option, Command command);
- };
-
-}
-
-
diff --git a/stratosphere/boot/source/i2c/i2c_command_list.cpp b/stratosphere/boot/source/i2c/i2c_command_list.cpp
deleted file mode 100644
index 9b44658b4..000000000
--- a/stratosphere/boot/source/i2c/i2c_command_list.cpp
+++ /dev/null
@@ -1,78 +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 "i2c_types.hpp"
-#include "i2c_command_list.hpp"
-
-namespace ams::i2c {
-
- namespace {
-
- /* Useful definitions. */
- constexpr size_t SendCommandSize = 2;
- constexpr size_t ReceiveCommandSize = 2;
- constexpr size_t SleepCommandSize = 2;
-
- }
-
- Result CommandListFormatter::CanEnqueue(size_t size) const {
- R_UNLESS(this->cmd_list_size - this->cur_index >= size, ResultFullCommandList());
- return ResultSuccess();
- }
-
- Result CommandListFormatter::EnqueueSendCommand(I2cTransactionOption option, const void *src, size_t size) {
- R_TRY(this->CanEnqueue(SendCommandSize + size));
-
- this->cmd_list[this->cur_index] = static_cast(Command::Send);
- this->cmd_list[this->cur_index] |= ((option & I2cTransactionOption_Start) != 0) << 6;
- this->cmd_list[this->cur_index] |= ((option & I2cTransactionOption_Stop) != 0) << 7;
- this->cur_index++;
-
- this->cmd_list[this->cur_index++] = size;
-
- const u8 *src_u8 = reinterpret_cast(src);
- for (size_t i = 0; i < size; i++) {
- this->cmd_list[this->cur_index++] = src_u8[i];
- }
- return ResultSuccess();
- }
-
- Result CommandListFormatter::EnqueueReceiveCommand(I2cTransactionOption option, size_t size) {
- R_TRY(this->CanEnqueue(ReceiveCommandSize));
-
- this->cmd_list[this->cur_index] = static_cast(Command::Receive);
- this->cmd_list[this->cur_index] |= ((option & I2cTransactionOption_Start) != 0) << 6;
- this->cmd_list[this->cur_index] |= ((option & I2cTransactionOption_Stop) != 0) << 7;
- this->cur_index++;
-
- this->cmd_list[this->cur_index++] = size;
- return ResultSuccess();
- }
-
- Result CommandListFormatter::EnqueueSleepCommand(size_t us) {
- R_TRY(this->CanEnqueue(SleepCommandSize));
-
- this->cmd_list[this->cur_index] = static_cast(Command::SubCommand);
- this->cmd_list[this->cur_index] |= static_cast(SubCommand::Sleep) << 2;
- this->cur_index++;
-
- this->cmd_list[this->cur_index++] = us;
- return ResultSuccess();
- }
-
-}
-
-
diff --git a/stratosphere/boot/source/i2c/i2c_command_list.hpp b/stratosphere/boot/source/i2c/i2c_command_list.hpp
deleted file mode 100644
index cf904b5b7..000000000
--- a/stratosphere/boot/source/i2c/i2c_command_list.hpp
+++ /dev/null
@@ -1,60 +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 .
- */
-#pragma once
-#include "i2c_types.hpp"
-
-namespace ams::i2c {
-
- enum class Command {
- Send = 0,
- Receive = 1,
- SubCommand = 2,
- Count,
- };
-
- enum class SubCommand {
- Sleep = 0,
- Count,
- };
-
- class CommandListFormatter {
- public:
- static constexpr size_t MaxCommandListSize = 0x100;
- private:
- u8 *cmd_list = nullptr;
- size_t cmd_list_size = 0;
- size_t cur_index = 0;
- public:
- CommandListFormatter(void *cmd_list, size_t cmd_list_size) : cmd_list(static_cast(cmd_list)), cmd_list_size(cmd_list_size) {
- AMS_ABORT_UNLESS(cmd_list_size <= MaxCommandListSize);
- }
- ~CommandListFormatter() {
- this->cmd_list = nullptr;
- }
-
- private:
- Result CanEnqueue(size_t size) const;
- public:
- size_t GetCurrentSize() const {
- return this->cur_index;
- }
-
- Result EnqueueSendCommand(I2cTransactionOption option, const void *src, size_t size);
- Result EnqueueReceiveCommand(I2cTransactionOption option, size_t size);
- Result EnqueueSleepCommand(size_t us);
- };
-
-}