From 6ff58fa4b3832c95b419c5f0bf8b8c0e51245f56 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 31 Oct 2020 17:58:38 -0700 Subject: [PATCH] i2c: implement BusAccessor except Send/Receive/WriteHeader --- .../regulator/regulator_session_api.hpp | 2 +- .../nintendo_nx/impl/i2c_bus_accessor.cpp | 363 ++++++++++++++++-- .../include/vapours/tegra/tegra_i2c.hpp | 36 ++ .../api_overrides/regulator_api_for_boot.cpp | 4 +- 4 files changed, 372 insertions(+), 33 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/regulator/regulator_session_api.hpp b/libraries/libstratosphere/include/stratosphere/regulator/regulator_session_api.hpp index 62c9a6b01..cdd278ad4 100644 --- a/libraries/libstratosphere/include/stratosphere/regulator/regulator_session_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/regulator/regulator_session_api.hpp @@ -27,7 +27,7 @@ namespace ams::regulator { void CloseSession(RegulatorSession *session); bool GetVoltageEnabled(RegulatorSession *session); - Result SetVoltageEnabled(RegulatorSession *session); + Result SetVoltageEnabled(RegulatorSession *session, bool enabled); Result SetVoltageValue(RegulatorSession *session, u32 micro_volts); 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 index 430e183a1..beb0f5292 100644 --- 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 @@ -64,7 +64,7 @@ namespace ams::i2c::driver::board::nintendo_nx::impl { /* Initialize our interrupt event. */ os::InitializeInterruptEvent(std::addressof(this->interrupt_event), this->interrupt_name, os::EventClearMode_ManualClear); - os::ClearInterruptEvent(std::addressof(this->interrupt_event); + os::ClearInterruptEvent(std::addressof(this->interrupt_event)); /* If we're not power bus, perform power management init. */ if (!this->is_power_bus) { @@ -115,7 +115,9 @@ namespace ams::i2c::driver::board::nintendo_nx::impl { /* 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); + if (this->user_count > 0) { + return; + } /* Finalize our interrupt event. */ os::FinalizeInterruptEvent(std::addressof(this->interrupt_event)); @@ -140,33 +142,129 @@ namespace ams::i2c::driver::board::nintendo_nx::impl { } Result I2cBusAccessor::Send(I2cDeviceProperty *device, const void *src, size_t src_size, TransactionOption option) { - /* TODO */ - AMS_ABORT(); + /* Check pre-conditions. */ + AMS_ASSERT(device != nullptr); + AMS_ASSERT(src != nullptr); + AMS_ASSERT(src_size > 0); + + if (this->is_power_bus) { + AMS_ASSERT(this->state == State::Initialized || this->state == State::Suspended); + } else { + AMS_ASSERT(this->state == State::Initialized); + } + + /* Send the data. */ + return this->Send(static_cast(src), src_size, option, device->GetAddress(), device->GetAddressingMode()); } Result I2cBusAccessor::Receive(void *dst, size_t dst_size, I2cDeviceProperty *device, TransactionOption option) { - /* TODO */ - AMS_ABORT(); + /* Check pre-conditions. */ + AMS_ASSERT(device != nullptr); + AMS_ASSERT(dst != nullptr); + AMS_ASSERT(dst_size > 0); + + if (this->is_power_bus) { + AMS_ASSERT(this->state == State::Initialized || this->state == State::Suspended); + } else { + AMS_ASSERT(this->state == State::Initialized); + } + + /* Send the data. */ + return this->Receive(static_cast(dst), dst_size, option, device->GetAddress(), device->GetAddressingMode()); } void I2cBusAccessor::SuspendBus() { - /* TODO */ - AMS_ABORT(); + /* Check that state is valid. */ + AMS_ASSERT(this->state == State::Initialized); + + /* Acquire exclusive access. */ + std::scoped_lock lk(this->user_count_mutex); + + /* If we need to, disable clock/voltage appropriately. */ + if (!this->is_power_bus && this->user_count > 0) { + /* Disable clock. */ + { + /* Open a clkrst session. */ + clkrst::ClkRstSession clkrst_session; + R_ABORT_UNLESS(clkrst::OpenSession(std::addressof(clkrst_session), this->device_code)); + ON_SCOPE_EXIT { clkrst::CloseSession(std::addressof(clkrst_session)); }; + + /* Set clock disabled for the session. */ + clkrst::SetClockDisabled(std::addressof(clkrst_session)); + } + + /* Disable voltage. */ + if (this->has_regulator_session) { + regulator::SetVoltageEnabled(std::addressof(this->regulator_session), false); + } + } + + /* Update state. */ + this->state = State::Suspended; } void I2cBusAccessor::SuspendPowerBus() { - /* TODO */ - AMS_ABORT(); + /* Check that state is valid. */ + AMS_ASSERT(this->state == State::Suspended); + + /* Acquire exclusive access. */ + std::scoped_lock lk(this->user_count_mutex); + + /* If we need to, disable clock/voltage appropriately. */ + if (this->is_power_bus && this->user_count > 0) { + /* Nothing should actually be done here. */ + } + + /* Update state. */ + this->state = State::PowerBusSuspended; } void I2cBusAccessor::ResumeBus() { - /* TODO */ - AMS_ABORT(); + /* Check that state is valid. */ + AMS_ASSERT(this->state == State::Suspended); + + /* Acquire exclusive access. */ + std::scoped_lock lk(this->user_count_mutex); + + /* If we need to, enable clock/voltage appropriately. */ + if (!this->is_power_bus && this->user_count > 0) { + /* Enable voltage. */ + if (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)); + } + } + + /* Execute initial config, which will enable clock as relevant. */ + this->ExecuteInitialConfig(); + } + + /* Update state. */ + this->state = State::Initialized; } void I2cBusAccessor::ResumePowerBus() { - /* TODO */ - AMS_ABORT(); + /* Check that state is valid. */ + AMS_ASSERT(this->state == State::PowerBusSuspended); + + /* Acquire exclusive access. */ + std::scoped_lock lk(this->user_count_mutex); + + /* If we need to, enable clock/voltage appropriately. */ + if (this->is_power_bus && this->user_count > 0) { + /* Execute initial config, which will enable clock as relevant. */ + this->ExecuteInitialConfig(); + } + + /* Update state. */ + this->state = State::Suspended; } Result I2cBusAccessor::TryOpenRegulatorSession() { @@ -188,8 +286,20 @@ namespace ams::i2c::driver::board::nintendo_nx::impl { } void I2cBusAccessor::ExecuteInitialConfig() { - /* TODO */ - AMS_ABORT(); + /* Lock exclusive access to registers. */ + std::scoped_lock lk(this->register_mutex); + + /* Reset the controller. */ + this->ResetController(); + + /* Set clock registers. */ + this->SetClockRegisters(this->speed_mode); + + /* Set packet mode registers. */ + this->SetPacketModeRegisters(); + + /* Flush fifos. */ + this->FlushFifos(); } Result I2cBusAccessor::Send(const u8 *src, size_t src_size, TransactionOption option, u16 slave_address, AddressingMode addressing_mode) { @@ -208,38 +318,231 @@ namespace ams::i2c::driver::board::nintendo_nx::impl { } void I2cBusAccessor::ResetController() const { - /* TODO */ - AMS_ABORT(); + /* Reset the controller. */ + if (!this->is_power_bus) { + /* Open a clkrst session. */ + clkrst::ClkRstSession clkrst_session; + R_ABORT_UNLESS(clkrst::OpenSession(std::addressof(clkrst_session), this->device_code)); + ON_SCOPE_EXIT { clkrst::CloseSession(std::addressof(clkrst_session)); }; + + /* Reset the controller, setting clock rate to 408 MHz / 5 (to account for clock divisor). */ + /* NOTE: Nintendo does not check result for any of these calls. */ + clkrst::SetResetAsserted(std::addressof(clkrst_session)); + clkrst::SetClockRate(std::addressof(clkrst_session), 408'000'000 / (4 + 1)); + clkrst::SetResetDeasserted(std::addressof(clkrst_session)); + } } void I2cBusAccessor::ClearBus() const { - /* TODO */ - AMS_ABORT(); + /* Try to clear the bus up to three times. */ + constexpr int MaxRetryCount = 3; + constexpr int BusyLoopMicroSeconds = 1000; + + int try_count = 0; + bool need_retry; + do { + /* Update trackers. */ + ++try_count; + need_retry = false; + + /* Reset the controller. */ + this->ResetController(); + + /* Configure the sclk threshold for bus clear config. */ + reg::Write(this->registers->bus_clear_config, I2C_REG_BITS_VALUE(BUS_CLEAR_CONFIG_BC_SCLK_THRESHOLD, 9)); + + /* Set stop cond and terminate in bus clear config. */ + reg::ReadWrite(this->registers->bus_clear_config, I2C_REG_BITS_ENUM(BUS_CLEAR_CONFIG_BC_STOP_COND, STOP)); + reg::ReadWrite(this->registers->bus_clear_config, I2C_REG_BITS_ENUM(BUS_CLEAR_CONFIG_BC_TERMINATE, IMMEDIATE)); + + /* Set master config load, busy loop up to 1ms for it to take. */ + reg::ReadWrite(this->registers->config_load, I2C_REG_BITS_ENUM(CONFIG_LOAD_MSTR_CONFIG_LOAD, ENABLE)); + + const os::Tick start_tick_a = os::GetSystemTick(); + while (reg::HasValue(this->registers->config_load, I2C_REG_BITS_ENUM(CONFIG_LOAD_MSTR_CONFIG_LOAD, ENABLE))) { + if ((os::GetSystemTick() - start_tick_a).ToTimeSpan().GetMicroSeconds() > BusyLoopMicroSeconds) { + need_retry = true; + break; + } + } + + if (need_retry) { + continue; + } + + /* Set bus clear enable, wait up to 1ms for it to take. */ + reg::ReadWrite(this->registers->bus_clear_config, I2C_REG_BITS_ENUM(BUS_CLEAR_CONFIG_BC_ENABLE, ENABLE)); + + const os::Tick start_tick_b = os::GetSystemTick(); + while (reg::HasValue(this->registers->bus_clear_config, I2C_REG_BITS_ENUM(BUS_CLEAR_CONFIG_BC_ENABLE, ENABLE))) { + if ((os::GetSystemTick() - start_tick_b).ToTimeSpan().GetMicroSeconds() > BusyLoopMicroSeconds) { + need_retry = true; + break; + } + } + + if (need_retry) { + continue; + } + + /* Wait up to 1ms for the bus clear to complete. */ + const os::Tick start_tick_c = os::GetSystemTick(); + while (reg::HasValue(this->registers->bus_clear_status, I2C_REG_BITS_ENUM(BUS_CLEAR_STATUS_BC_STATUS, NOT_CLEARED))) { + if ((os::GetSystemTick() - start_tick_c).ToTimeSpan().GetMicroSeconds() > BusyLoopMicroSeconds) { + need_retry = true; + break; + } + } + + if (need_retry) { + continue; + } + } while (try_count < MaxRetryCount && need_retry); } void I2cBusAccessor::SetClockRegisters(SpeedMode speed_mode) { - /* TODO */ - AMS_ABORT(); + /* Determine parameters for the speed mode. */ + u32 t_high, t_low, clk_div, debounce, src_div; + bool high_speed = false; + + if (this->is_power_bus) { + t_high = 0x02; + t_low = 0x04; + clk_div = 0x05; + debounce = 0x02; + } else { + switch (speed_mode) { + case SpeedMode_Standard: + t_high = 0x02; + t_low = 0x04; + clk_div = 0x19; + debounce = 0x02; + src_div = 0x13; + break; + case SpeedMode_Fast: + t_high = 0x02; + t_low = 0x04; + clk_div = 0x19; + debounce = 0x02; + src_div = 0x04; + break; + case SpeedMode_FastPlus: + t_high = 0x02; + t_low = 0x04; + clk_div = 0x10; + debounce = 0x00; + src_div = 0x02; + break; + case SpeedMode_HighSpeed: + t_high = 0x03; + t_low = 0x08; + clk_div = 0x02; + debounce = 0x00; + src_div = 0x02; + high_speed = true; + break; + AMS_UNREACHABLE_DEFAULT_CASE(); + } + } + + /* Write the clock divisors. */ + if (high_speed) { + reg::Write(this->registers->hs_interface_timing_0, I2C_REG_BITS_VALUE(HS_INTERFACE_TIMING_0_HS_THIGH, t_high), + I2C_REG_BITS_VALUE(HS_INTERFACE_TIMING_0_HS_TLOW, t_low)); + + reg::Write(this->registers->clk_divisor_register, I2C_REG_BITS_VALUE(CLK_DIVISOR_REGISTER_HSMODE, clk_div)); + } else { + reg::Write(this->registers->interface_timing_0, I2C_REG_BITS_VALUE(INTERFACE_TIMING_0_THIGH, t_high), + I2C_REG_BITS_VALUE(INTERFACE_TIMING_0_TLOW, t_low)); + + reg::Write(this->registers->clk_divisor_register, I2C_REG_BITS_VALUE(CLK_DIVISOR_REGISTER_STD_FAST_MODE, clk_div)); + } + + /* Configure debounce. */ + reg::Write(this->registers->cnfg, I2C_REG_BITS_VALUE(I2C_CNFG_DEBOUNCE_CNT, debounce)); + reg::Read(this->registers->cnfg); + + /* Set the clock rate, if we should. */ + if (!this->is_power_bus) { + /* Open a clkrst session. */ + clkrst::ClkRstSession clkrst_session; + R_ABORT_UNLESS(clkrst::OpenSession(std::addressof(clkrst_session), this->device_code)); + ON_SCOPE_EXIT { clkrst::CloseSession(std::addressof(clkrst_session)); }; + + /* Reset the controller, setting clock rate to 408 MHz / (src_div + 1). */ + /* NOTE: Nintendo does not check result for any of these calls. */ + clkrst::SetResetAsserted(std::addressof(clkrst_session)); + clkrst::SetClockRate(std::addressof(clkrst_session), 408'000'000 / (src_div + 1)); + clkrst::SetResetDeasserted(std::addressof(clkrst_session)); + } } void I2cBusAccessor::SetPacketModeRegisters() { - /* TODO */ - AMS_ABORT(); + /* Set packet mode enable. */ + reg::ReadWrite(this->registers->cnfg, I2C_REG_BITS_ENUM(I2C_CNFG_PACKET_MODE_EN, GO)); + + /* Set master config load. */ + reg::ReadWrite(this->registers->config_load, I2C_REG_BITS_ENUM(CONFIG_LOAD_MSTR_CONFIG_LOAD, ENABLE)); + + /* Set tx/fifo triggers to default (maximum values). */ + reg::Write(this->registers->fifo_control, I2C_REG_BITS_VALUE(FIFO_CONTROL_RX_FIFO_TRIG, 7), + I2C_REG_BITS_VALUE(FIFO_CONTROL_TX_FIFO_TRIG, 7)); } Result I2cBusAccessor::FlushFifos() { - /* TODO */ - AMS_ABORT(); + /* Flush the fifo. */ + reg::Write(this->registers->fifo_control, I2C_REG_BITS_VALUE(FIFO_CONTROL_RX_FIFO_TRIG, 7), + I2C_REG_BITS_VALUE(FIFO_CONTROL_TX_FIFO_TRIG, 7), + I2C_REG_BITS_ENUM (FIFO_CONTROL_RX_FIFO_FLUSH, SET), + I2C_REG_BITS_ENUM (FIFO_CONTROL_TX_FIFO_FLUSH, SET)); + + /* Wait up to 5 ms for the flush to complete. */ + int count = 0; + while (!reg::HasValue(this->registers->fifo_control, I2C_REG_BITS_ENUM(FIFO_CONTROL_FIFO_FLUSH, RX_UNSET_TX_UNSET))) { + R_UNLESS((++count < 5), i2c::ResultBusBusy()); + os::SleepThread(TimeSpan::FromMilliSeconds(1)); + } + + return ResultSuccess(); } Result I2cBusAccessor::GetTransactionResult() const { - /* TODO */ - AMS_ABORT(); + /* Get packet status/interrupt status. */ + volatile u32 packet_status = reg::Read(this->registers->packet_transfer_status); + volatile u32 interrupt_status = reg::Read(this->registers->interrupt_status_register); + + /* Check for ack. */ + R_UNLESS(reg::HasValue(packet_status, I2C_REG_BITS_ENUM(PACKET_TRANSFER_STATUS_NOACK_FOR_DATA, UNSET)), i2c::ResultNoAck()); + R_UNLESS(reg::HasValue(packet_status, I2C_REG_BITS_ENUM(PACKET_TRANSFER_STATUS_NOACK_FOR_ADDR, UNSET)), i2c::ResultNoAck()); + R_UNLESS(reg::HasValue(interrupt_status, I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_NOACK, UNSET)), i2c::ResultNoAck()); + + /* If we lost arbitration, we'll need to clear the bus. */ + auto clear_guard = SCOPE_GUARD { this->ClearBus(); }; + + /* Check for arb lost. */ + R_UNLESS(reg::HasValue(packet_status, I2C_REG_BITS_ENUM(PACKET_TRANSFER_STATUS_ARB_LOST, UNSET)), i2c::ResultBusBusy()); + R_UNLESS(reg::HasValue(interrupt_status, I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_ARB_LOST, UNSET)), i2c::ResultBusBusy()); + + clear_guard.Cancel(); + return ResultSuccess(); } void I2cBusAccessor::HandleTransactionError(Result result) { - /* TODO */ - AMS_ABORT(); + R_TRY_CATCH(result) { + R_CATCH(i2c::ResultNoAck, i2c::ResultBusBusy) { + /* Reset the controller. */ + this->ResetController(); + + /* Set clock registers. */ + this->SetClockRegisters(this->speed_mode); + + /* Set packet mode registers. */ + this->SetPacketModeRegisters(); + + /* Flush fifos. */ + this->FlushFifos(); + } + } R_END_TRY_CATCH_WITH_ABORT_UNLESS; } } diff --git a/libraries/libvapours/include/vapours/tegra/tegra_i2c.hpp b/libraries/libvapours/include/vapours/tegra/tegra_i2c.hpp index 683ebfb17..23cf5ba12 100644 --- a/libraries/libvapours/include/vapours/tegra/tegra_i2c.hpp +++ b/libraries/libvapours/include/vapours/tegra/tegra_i2c.hpp @@ -25,11 +25,17 @@ #define I2C_I2C_CMD_ADDR0 (0x004) #define I2C_I2C_CMD_DATA1 (0x00C) #define I2C_I2C_STATUS (0x01C) +#define I2C_PACKET_TRANSFER_STATUS (0x058) +#define I2C_FIFO_CONTROL (0x05C) #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_INTERFACE_TIMING_0 (0x094) +#define I2C_INTERFACE_TIMING_1 (0x098) +#define I2C_HS_INTERFACE_TIMING_0 (0x094) +#define I2C_HS_INTERFACE_TIMING_1 (0x098) #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) @@ -46,6 +52,7 @@ 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_PACKET_MODE_EN, 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); @@ -58,7 +65,24 @@ DEFINE_I2C_REG_FOUR_BIT_ENUM(I2C_STATUS_CMD1_STAT, 0, SL1_XFER_SUCCESSFUL, SL1_N 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); +/* PACKET_TRANSFER_STATUS */ +DEFINE_I2C_REG_BIT_ENUM(PACKET_TRANSFER_STATUS_CONTROLLER_BUSY, 0, UNSET, SET); +DEFINE_I2C_REG_BIT_ENUM(PACKET_TRANSFER_STATUS_ARB_LOST, 1, UNSET, SET); +DEFINE_I2C_REG_BIT_ENUM(PACKET_TRANSFER_STATUS_NOACK_FOR_DATA, 2, UNSET, SET); +DEFINE_I2C_REG_BIT_ENUM(PACKET_TRANSFER_STATUS_NOACK_FOR_ADDR, 3, UNSET, SET); + +/* FIFO_CONTROL */ +DEFINE_I2C_REG_BIT_ENUM(FIFO_CONTROL_RX_FIFO_FLUSH, 0, UNSET, SET); +DEFINE_I2C_REG_BIT_ENUM(FIFO_CONTROL_TX_FIFO_FLUSH, 1, UNSET, SET); + +DEFINE_I2C_REG_TWO_BIT_ENUM(FIFO_CONTROL_FIFO_FLUSH, 0, RX_UNSET_TX_UNSET, RX_SET_TX_UNSET, RX_UNSET_TX_SET, RX_SET_TX_SET); + +DEFINE_I2C_REG(FIFO_CONTROL_RX_FIFO_TRIG, 2, 3); +DEFINE_I2C_REG(FIFO_CONTROL_TX_FIFO_TRIG, 5, 3); + /* INTERRUPT_STATUS_REGISTER */ +DEFINE_I2C_REG_BIT_ENUM(INTERRUPT_STATUS_REGISTER_ARB_LOST, 2, UNSET, SET); +DEFINE_I2C_REG_BIT_ENUM(INTERRUPT_STATUS_REGISTER_NOACK, 3, UNSET, SET); DEFINE_I2C_REG_BIT_ENUM(INTERRUPT_STATUS_REGISTER_BUS_CLEAR_DONE, 11, UNSET, SET); /* CLK_DIVISOR_REGISTER */ @@ -71,8 +95,20 @@ 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); +/* BUS_CLEAR_STATUS */ +DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_STATUS_BC_STATUS, 0, NOT_CLEARED, CLEARED); + /* 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); + +/* INTERFACE_TIMING_0 */ +DEFINE_I2C_REG(INTERFACE_TIMING_0_TLOW, 0, 6); +DEFINE_I2C_REG(INTERFACE_TIMING_0_THIGH, 8, 6); + +/* HS_INTERFACE_TIMING_0 */ +DEFINE_I2C_REG(HS_INTERFACE_TIMING_0_HS_TLOW, 0, 6); +DEFINE_I2C_REG(HS_INTERFACE_TIMING_0_HS_THIGH, 8, 6); + diff --git a/stratosphere/boot/source/api_overrides/regulator_api_for_boot.cpp b/stratosphere/boot/source/api_overrides/regulator_api_for_boot.cpp index 37d29fe42..4db3e7bfa 100644 --- a/stratosphere/boot/source/api_overrides/regulator_api_for_boot.cpp +++ b/stratosphere/boot/source/api_overrides/regulator_api_for_boot.cpp @@ -39,8 +39,8 @@ namespace ams::regulator { return true; } - Result SetVoltageEnabled(RegulatorSession *session) { - AMS_UNUSED(session); + Result SetVoltageEnabled(RegulatorSession *session, bool enabled) { + AMS_UNUSED(session, enabled); return ResultSuccess(); }