mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-06-03 08:08:39 -04:00
strat: use m_ for member variables
This commit is contained in:
parent
ce28591ab2
commit
a595c232b9
425 changed files with 8531 additions and 8484 deletions
|
@ -55,56 +55,56 @@ 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);
|
||||
AMS_ASSERT(m_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;
|
||||
m_is_power_bus = pb;
|
||||
m_speed_mode = sm;
|
||||
m_interrupt_name = intr;
|
||||
m_registers_phys_addr = reg_paddr;
|
||||
m_registers_size = reg_size;
|
||||
m_state = State::Initializing;
|
||||
}
|
||||
|
||||
void I2cBusAccessor::RegisterDeviceCode(DeviceCode dc) {
|
||||
AMS_ASSERT(this->state == State::Initializing);
|
||||
AMS_ASSERT(m_state == State::Initializing);
|
||||
|
||||
this->device_code = dc;
|
||||
m_device_code = dc;
|
||||
}
|
||||
|
||||
void I2cBusAccessor::InitializeDriver() {
|
||||
AMS_ASSERT(this->state == State::Initializing);
|
||||
AMS_ASSERT(m_state == State::Initializing);
|
||||
|
||||
this->registers = reinterpret_cast<volatile I2cRegisters *>(dd::QueryIoMapping(this->registers_phys_addr, this->registers_size));
|
||||
AMS_ABORT_UNLESS(this->registers != nullptr);
|
||||
m_registers = reinterpret_cast<volatile I2cRegisters *>(dd::QueryIoMapping(m_registers_phys_addr, m_registers_size));
|
||||
AMS_ABORT_UNLESS(m_registers != nullptr);
|
||||
|
||||
this->state = State::Initialized;
|
||||
m_state = State::Initialized;
|
||||
}
|
||||
|
||||
void I2cBusAccessor::FinalizeDriver() {
|
||||
AMS_ASSERT(this->state == State::Initialized);
|
||||
this->state = State::Initializing;
|
||||
AMS_ASSERT(m_state == State::Initialized);
|
||||
m_state = State::Initializing;
|
||||
}
|
||||
|
||||
Result I2cBusAccessor::InitializeDevice(I2cDeviceProperty *device) {
|
||||
/* Check that the device is valid. */
|
||||
AMS_ASSERT(device != nullptr);
|
||||
AMS_ASSERT(this->state == State::Initialized);
|
||||
AMS_ASSERT(m_state == State::Initialized);
|
||||
AMS_UNUSED(device);
|
||||
|
||||
/* Acquire exclusive access. */
|
||||
std::scoped_lock lk(this->user_count_mutex);
|
||||
std::scoped_lock lk(m_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);
|
||||
AMS_ASSERT(m_user_count >= 0);
|
||||
++m_user_count;
|
||||
R_SUCCEED_IF(m_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));
|
||||
os::InitializeInterruptEvent(std::addressof(m_interrupt_event), m_interrupt_name, os::EventClearMode_ManualClear);
|
||||
os::ClearInterruptEvent(std::addressof(m_interrupt_event));
|
||||
|
||||
/* If we're not power bus, perform power management init. */
|
||||
if (!this->is_power_bus) {
|
||||
if (!m_is_power_bus) {
|
||||
/* Initialize regulator library. */
|
||||
regulator::Initialize();
|
||||
|
||||
|
@ -112,9 +112,9 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
R_TRY(this->TryOpenRegulatorSession());
|
||||
|
||||
/* If we have a regulator session, set voltage to 2.9V. */
|
||||
if (this->has_regulator_session) {
|
||||
if (m_has_regulator_session) {
|
||||
/* NOTE: Nintendo does not check the result, here. */
|
||||
regulator::SetVoltageValue(std::addressof(this->regulator_session), 2'900'000u);
|
||||
regulator::SetVoltageValue(std::addressof(m_regulator_session), 2'900'000u);
|
||||
}
|
||||
|
||||
/* Initialize clock/reset library. */
|
||||
|
@ -125,12 +125,12 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
this->ExecuteInitialConfig();
|
||||
|
||||
/* If we have a regulator session, enable voltage. */
|
||||
if (!this->is_power_bus && this->has_regulator_session) {
|
||||
if (!m_is_power_bus && m_has_regulator_session) {
|
||||
/* Check whether voltage was already enabled. */
|
||||
const bool was_enabled = regulator::GetVoltageEnabled(std::addressof(this->regulator_session));
|
||||
const bool was_enabled = regulator::GetVoltageEnabled(std::addressof(m_regulator_session));
|
||||
|
||||
/* NOTE: Nintendo does not check the result of this call. */
|
||||
regulator::SetVoltageEnabled(std::addressof(this->regulator_session), true);
|
||||
regulator::SetVoltageEnabled(std::addressof(m_regulator_session), true);
|
||||
|
||||
/* If we enabled voltage, delay to give our enable time to take. */
|
||||
if (!was_enabled) {
|
||||
|
@ -144,35 +144,35 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
void I2cBusAccessor::FinalizeDevice(I2cDeviceProperty *device) {
|
||||
/* Check that the device is valid. */
|
||||
AMS_ASSERT(device != nullptr);
|
||||
AMS_ASSERT(this->state == State::Initialized);
|
||||
AMS_ASSERT(m_state == State::Initialized);
|
||||
AMS_UNUSED(device);
|
||||
|
||||
/* Acquire exclusive access. */
|
||||
std::scoped_lock lk(this->user_count_mutex);
|
||||
std::scoped_lock lk(m_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;
|
||||
if (this->user_count > 0) {
|
||||
AMS_ASSERT(m_user_count > 0);
|
||||
--m_user_count;
|
||||
if (m_user_count > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Finalize our interrupt event. */
|
||||
os::FinalizeInterruptEvent(std::addressof(this->interrupt_event));
|
||||
os::FinalizeInterruptEvent(std::addressof(m_interrupt_event));
|
||||
|
||||
/* If we have a regulator session, disable voltage. */
|
||||
if (this->has_regulator_session) {
|
||||
if (m_has_regulator_session) {
|
||||
/* NOTE: Nintendo does not check the result of this call. */
|
||||
regulator::SetVoltageEnabled(std::addressof(this->regulator_session), false);
|
||||
regulator::SetVoltageEnabled(std::addressof(m_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;
|
||||
if (m_has_regulator_session) {
|
||||
regulator::CloseSession(std::addressof(m_regulator_session));
|
||||
m_has_regulator_session = false;
|
||||
}
|
||||
|
||||
/* Finalize the regulator library. */
|
||||
|
@ -185,10 +185,10 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
AMS_ASSERT(src != nullptr);
|
||||
AMS_ASSERT(src_size > 0);
|
||||
|
||||
if (this->is_power_bus) {
|
||||
AMS_ASSERT(this->state == State::Initialized || this->state == State::Suspended);
|
||||
if (m_is_power_bus) {
|
||||
AMS_ASSERT(m_state == State::Initialized || m_state == State::Suspended);
|
||||
} else {
|
||||
AMS_ASSERT(this->state == State::Initialized);
|
||||
AMS_ASSERT(m_state == State::Initialized);
|
||||
}
|
||||
|
||||
/* Send the data. */
|
||||
|
@ -201,10 +201,10 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
AMS_ASSERT(dst != nullptr);
|
||||
AMS_ASSERT(dst_size > 0);
|
||||
|
||||
if (this->is_power_bus) {
|
||||
AMS_ASSERT(this->state == State::Initialized || this->state == State::Suspended);
|
||||
if (m_is_power_bus) {
|
||||
AMS_ASSERT(m_state == State::Initialized || m_state == State::Suspended);
|
||||
} else {
|
||||
AMS_ASSERT(this->state == State::Initialized);
|
||||
AMS_ASSERT(m_state == State::Initialized);
|
||||
}
|
||||
|
||||
/* Send the data. */
|
||||
|
@ -213,18 +213,18 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
|
||||
void I2cBusAccessor::SuspendBus() {
|
||||
/* Check that state is valid. */
|
||||
AMS_ASSERT(this->state == State::Initialized);
|
||||
AMS_ASSERT(m_state == State::Initialized);
|
||||
|
||||
/* Acquire exclusive access. */
|
||||
std::scoped_lock lk(this->user_count_mutex);
|
||||
std::scoped_lock lk(m_user_count_mutex);
|
||||
|
||||
/* If we need to, disable clock/voltage appropriately. */
|
||||
if (!this->is_power_bus && this->user_count > 0) {
|
||||
if (!m_is_power_bus && m_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));
|
||||
R_ABORT_UNLESS(clkrst::OpenSession(std::addressof(clkrst_session), m_device_code));
|
||||
ON_SCOPE_EXIT { clkrst::CloseSession(std::addressof(clkrst_session)); };
|
||||
|
||||
/* Set clock disabled for the session. */
|
||||
|
@ -232,47 +232,47 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
}
|
||||
|
||||
/* Disable voltage. */
|
||||
if (this->has_regulator_session) {
|
||||
regulator::SetVoltageEnabled(std::addressof(this->regulator_session), false);
|
||||
if (m_has_regulator_session) {
|
||||
regulator::SetVoltageEnabled(std::addressof(m_regulator_session), false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update state. */
|
||||
this->state = State::Suspended;
|
||||
m_state = State::Suspended;
|
||||
}
|
||||
|
||||
void I2cBusAccessor::SuspendPowerBus() {
|
||||
/* Check that state is valid. */
|
||||
AMS_ASSERT(this->state == State::Suspended);
|
||||
AMS_ASSERT(m_state == State::Suspended);
|
||||
|
||||
/* Acquire exclusive access. */
|
||||
std::scoped_lock lk(this->user_count_mutex);
|
||||
std::scoped_lock lk(m_user_count_mutex);
|
||||
|
||||
/* If we need to, disable clock/voltage appropriately. */
|
||||
if (this->is_power_bus && this->user_count > 0) {
|
||||
if (m_is_power_bus && m_user_count > 0) {
|
||||
/* Nothing should actually be done here. */
|
||||
}
|
||||
|
||||
/* Update state. */
|
||||
this->state = State::PowerBusSuspended;
|
||||
m_state = State::PowerBusSuspended;
|
||||
}
|
||||
|
||||
void I2cBusAccessor::ResumeBus() {
|
||||
/* Check that state is valid. */
|
||||
AMS_ASSERT(this->state == State::Suspended);
|
||||
AMS_ASSERT(m_state == State::Suspended);
|
||||
|
||||
/* Acquire exclusive access. */
|
||||
std::scoped_lock lk(this->user_count_mutex);
|
||||
std::scoped_lock lk(m_user_count_mutex);
|
||||
|
||||
/* If we need to, enable clock/voltage appropriately. */
|
||||
if (!this->is_power_bus && this->user_count > 0) {
|
||||
if (!m_is_power_bus && m_user_count > 0) {
|
||||
/* Enable voltage. */
|
||||
if (this->has_regulator_session) {
|
||||
if (m_has_regulator_session) {
|
||||
/* Check whether voltage was already enabled. */
|
||||
const bool was_enabled = regulator::GetVoltageEnabled(std::addressof(this->regulator_session));
|
||||
const bool was_enabled = regulator::GetVoltageEnabled(std::addressof(m_regulator_session));
|
||||
|
||||
/* NOTE: Nintendo does not check the result of this call. */
|
||||
regulator::SetVoltageEnabled(std::addressof(this->regulator_session), true);
|
||||
regulator::SetVoltageEnabled(std::addressof(m_regulator_session), true);
|
||||
|
||||
/* If we enabled voltage, delay to give our enable time to take. */
|
||||
if (!was_enabled) {
|
||||
|
@ -285,36 +285,36 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
}
|
||||
|
||||
/* Update state. */
|
||||
this->state = State::Initialized;
|
||||
m_state = State::Initialized;
|
||||
}
|
||||
|
||||
void I2cBusAccessor::ResumePowerBus() {
|
||||
/* Check that state is valid. */
|
||||
AMS_ASSERT(this->state == State::PowerBusSuspended);
|
||||
AMS_ASSERT(m_state == State::PowerBusSuspended);
|
||||
|
||||
/* Acquire exclusive access. */
|
||||
std::scoped_lock lk(this->user_count_mutex);
|
||||
std::scoped_lock lk(m_user_count_mutex);
|
||||
|
||||
/* If we need to, enable clock/voltage appropriately. */
|
||||
if (this->is_power_bus && this->user_count > 0) {
|
||||
if (m_is_power_bus && m_user_count > 0) {
|
||||
/* Execute initial config, which will enable clock as relevant. */
|
||||
this->ExecuteInitialConfig();
|
||||
}
|
||||
|
||||
/* Update state. */
|
||||
this->state = State::Suspended;
|
||||
m_state = State::Suspended;
|
||||
}
|
||||
|
||||
Result I2cBusAccessor::TryOpenRegulatorSession() {
|
||||
/* Ensure we track the session. */
|
||||
this->has_regulator_session = true;
|
||||
auto s_guard = SCOPE_GUARD { this->has_regulator_session = false; };
|
||||
m_has_regulator_session = true;
|
||||
auto s_guard = SCOPE_GUARD { m_has_regulator_session = false; };
|
||||
|
||||
/* Try to open the session. */
|
||||
R_TRY_CATCH(regulator::OpenSession(std::addressof(this->regulator_session), this->device_code)) {
|
||||
R_TRY_CATCH(regulator::OpenSession(std::addressof(m_regulator_session), m_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;
|
||||
m_has_regulator_session = false;
|
||||
}
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
|
@ -325,13 +325,13 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
|
||||
void I2cBusAccessor::ExecuteInitialConfig() {
|
||||
/* Lock exclusive access to registers. */
|
||||
std::scoped_lock lk(this->register_mutex);
|
||||
std::scoped_lock lk(m_register_mutex);
|
||||
|
||||
/* Reset the controller. */
|
||||
this->ResetController();
|
||||
|
||||
/* Set clock registers. */
|
||||
this->SetClockRegisters(this->speed_mode);
|
||||
this->SetClockRegisters(m_speed_mode);
|
||||
|
||||
/* Set packet mode registers. */
|
||||
this->SetPacketModeRegisters();
|
||||
|
@ -342,20 +342,20 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
|
||||
Result I2cBusAccessor::Send(const u8 *src, size_t src_size, TransactionOption option, u16 slave_address, AddressingMode addressing_mode) {
|
||||
/* Acquire exclusive access to the registers. */
|
||||
std::scoped_lock lk(this->register_mutex);
|
||||
std::scoped_lock lk(m_register_mutex);
|
||||
|
||||
/* Configure interrupt mask, clear interrupt status. */
|
||||
reg::Write(this->registers->interrupt_mask_register, I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_TFIFO_DATA_REQ_INT_EN, ENABLE),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_ARB_LOST_INT_EN, ENABLE),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_NOACK_INT_EN, ENABLE),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_PACKET_XFER_COMPLETE_INT_EN, ENABLE));
|
||||
reg::Write(m_registers->interrupt_mask_register, I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_TFIFO_DATA_REQ_INT_EN, ENABLE),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_ARB_LOST_INT_EN, ENABLE),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_NOACK_INT_EN, ENABLE),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_PACKET_XFER_COMPLETE_INT_EN, ENABLE));
|
||||
|
||||
reg::Write(this->registers->interrupt_status_register, I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_ARB_LOST, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_NOACK, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_RFIFO_UNF, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_TFIFO_OVF, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_PACKET_XFER_COMPLETE, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_ALL_PACKETS_XFER_COMPLETE, SET));
|
||||
reg::Write(m_registers->interrupt_status_register, I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_ARB_LOST, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_NOACK, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_RFIFO_UNF, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_TFIFO_OVF, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_PACKET_XFER_COMPLETE, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_ALL_PACKETS_XFER_COMPLETE, SET));
|
||||
|
||||
/* Write the header. */
|
||||
this->WriteHeader(Xfer_Write, src_size, option, slave_address, addressing_mode);
|
||||
|
@ -366,7 +366,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
|
||||
while (true) {
|
||||
/* Get the number of empty bytes in the fifo status. */
|
||||
const u32 empty = reg::GetValue(this->registers->fifo_status, I2C_REG_BITS_MASK(FIFO_STATUS_TX_FIFO_EMPTY_CNT));
|
||||
const u32 empty = reg::GetValue(m_registers->fifo_status, I2C_REG_BITS_MASK(FIFO_STATUS_TX_FIFO_EMPTY_CNT));
|
||||
|
||||
/* Write up to (empty) bytes to the fifo. */
|
||||
for (u32 i = 0; remaining > 0 && i < empty; ++i) {
|
||||
|
@ -379,7 +379,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
}
|
||||
|
||||
/* Write the data word. */
|
||||
reg::Write(this->registers->tx_packet_fifo, word);
|
||||
reg::Write(m_registers->tx_packet_fifo, word);
|
||||
|
||||
/* Advance. */
|
||||
cur += cur_bytes;
|
||||
|
@ -392,13 +392,13 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
}
|
||||
|
||||
/* Wait for our current data to send. */
|
||||
os::ClearInterruptEvent(std::addressof(this->interrupt_event));
|
||||
if (!os::TimedWaitInterruptEvent(std::addressof(this->interrupt_event), Timeout)) {
|
||||
os::ClearInterruptEvent(std::addressof(m_interrupt_event));
|
||||
if (!os::TimedWaitInterruptEvent(std::addressof(m_interrupt_event), Timeout)) {
|
||||
/* We timed out. */
|
||||
this->HandleTransactionError(i2c::ResultBusBusy());
|
||||
|
||||
this->DisableInterruptMask();
|
||||
os::ClearInterruptEvent(std::addressof(this->interrupt_event));
|
||||
os::ClearInterruptEvent(std::addressof(m_interrupt_event));
|
||||
return i2c::ResultTimeout();
|
||||
}
|
||||
|
||||
|
@ -407,9 +407,9 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
}
|
||||
|
||||
/* Configure interrupt mask to not care about tfifo data req. */
|
||||
reg::Write(this->registers->interrupt_mask_register, I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_ARB_LOST_INT_EN, ENABLE),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_NOACK_INT_EN, ENABLE),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_PACKET_XFER_COMPLETE_INT_EN, ENABLE));
|
||||
reg::Write(m_registers->interrupt_mask_register, I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_ARB_LOST_INT_EN, ENABLE),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_NOACK_INT_EN, ENABLE),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_PACKET_XFER_COMPLETE_INT_EN, ENABLE));
|
||||
|
||||
/* Wait for the packet transfer to complete. */
|
||||
while (true) {
|
||||
|
@ -417,18 +417,18 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
R_TRY(this->CheckAndHandleError());
|
||||
|
||||
/* Check if packet transfer is done. */
|
||||
if (reg::HasValue(this->registers->interrupt_status_register, I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_PACKET_XFER_COMPLETE, SET))) {
|
||||
if (reg::HasValue(m_registers->interrupt_status_register, I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_PACKET_XFER_COMPLETE, SET))) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Wait for our the packet to transfer. */
|
||||
os::ClearInterruptEvent(std::addressof(this->interrupt_event));
|
||||
if (!os::TimedWaitInterruptEvent(std::addressof(this->interrupt_event), Timeout)) {
|
||||
os::ClearInterruptEvent(std::addressof(m_interrupt_event));
|
||||
if (!os::TimedWaitInterruptEvent(std::addressof(m_interrupt_event), Timeout)) {
|
||||
/* We timed out. */
|
||||
this->HandleTransactionError(i2c::ResultBusBusy());
|
||||
|
||||
this->DisableInterruptMask();
|
||||
os::ClearInterruptEvent(std::addressof(this->interrupt_event));
|
||||
os::ClearInterruptEvent(std::addressof(m_interrupt_event));
|
||||
return i2c::ResultTimeout();
|
||||
}
|
||||
}
|
||||
|
@ -443,20 +443,20 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
|
||||
Result I2cBusAccessor::Receive(u8 *dst, size_t dst_size, TransactionOption option, u16 slave_address, AddressingMode addressing_mode) {
|
||||
/* Acquire exclusive access to the registers. */
|
||||
std::scoped_lock lk(this->register_mutex);
|
||||
std::scoped_lock lk(m_register_mutex);
|
||||
|
||||
/* Configure interrupt mask, clear interrupt status. */
|
||||
reg::Write(this->registers->interrupt_mask_register, I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_RFIFO_DATA_REQ_INT_EN, ENABLE),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_ARB_LOST_INT_EN, ENABLE),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_NOACK_INT_EN, ENABLE),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_PACKET_XFER_COMPLETE_INT_EN, ENABLE));
|
||||
reg::Write(m_registers->interrupt_mask_register, I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_RFIFO_DATA_REQ_INT_EN, ENABLE),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_ARB_LOST_INT_EN, ENABLE),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_NOACK_INT_EN, ENABLE),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_MASK_REGISTER_PACKET_XFER_COMPLETE_INT_EN, ENABLE));
|
||||
|
||||
reg::Write(this->registers->interrupt_status_register, I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_ARB_LOST, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_NOACK, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_RFIFO_UNF, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_TFIFO_OVF, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_PACKET_XFER_COMPLETE, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_ALL_PACKETS_XFER_COMPLETE, SET));
|
||||
reg::Write(m_registers->interrupt_status_register, I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_ARB_LOST, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_NOACK, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_RFIFO_UNF, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_TFIFO_OVF, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_PACKET_XFER_COMPLETE, SET),
|
||||
I2C_REG_BITS_ENUM(INTERRUPT_STATUS_REGISTER_ALL_PACKETS_XFER_COMPLETE, SET));
|
||||
|
||||
/* Write the header. */
|
||||
this->WriteHeader(Xfer_Read, dst_size, option, slave_address, addressing_mode);
|
||||
|
@ -467,13 +467,13 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
|
||||
while (remaining > 0) {
|
||||
/* Wait for data to come in. */
|
||||
os::ClearInterruptEvent(std::addressof(this->interrupt_event));
|
||||
if (!os::TimedWaitInterruptEvent(std::addressof(this->interrupt_event), Timeout)) {
|
||||
os::ClearInterruptEvent(std::addressof(m_interrupt_event));
|
||||
if (!os::TimedWaitInterruptEvent(std::addressof(m_interrupt_event), Timeout)) {
|
||||
/* We timed out. */
|
||||
this->HandleTransactionError(i2c::ResultBusBusy());
|
||||
|
||||
this->DisableInterruptMask();
|
||||
os::ClearInterruptEvent(std::addressof(this->interrupt_event));
|
||||
os::ClearInterruptEvent(std::addressof(m_interrupt_event));
|
||||
return i2c::ResultTimeout();
|
||||
}
|
||||
|
||||
|
@ -481,7 +481,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
R_TRY(this->CheckAndHandleError());
|
||||
|
||||
/* Get the number of full bytes in the fifo status. */
|
||||
const u32 full = reg::GetValue(this->registers->fifo_status, I2C_REG_BITS_MASK(FIFO_STATUS_RX_FIFO_FULL_CNT));
|
||||
const u32 full = reg::GetValue(m_registers->fifo_status, I2C_REG_BITS_MASK(FIFO_STATUS_RX_FIFO_FULL_CNT));
|
||||
|
||||
/* Determine how many words we can read. */
|
||||
const size_t cur_words = std::min(util::DivideUp(remaining, sizeof(u32)), static_cast<size_t>(full));
|
||||
|
@ -489,7 +489,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
/* Read the correct number of words from the fifo. */
|
||||
for (size_t i = 0; i < cur_words; ++i) {
|
||||
/* Read the word from the fifo. */
|
||||
const u32 word = reg::Read(this->registers->rx_fifo);
|
||||
const u32 word = reg::Read(m_registers->rx_fifo);
|
||||
|
||||
/* Copy bytes from the word. */
|
||||
const size_t cur_bytes = std::min(remaining, sizeof(u32));
|
||||
|
@ -512,41 +512,41 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
const bool is_read = xfer == Xfer_Read;
|
||||
const bool is_7_bit = addressing_mode == AddressingMode_SevenBit;
|
||||
const bool is_stop = (option & TransactionOption_StopCondition) != 0;
|
||||
const bool is_hs = this->speed_mode == SpeedMode_HighSpeed;
|
||||
const bool is_hs = m_speed_mode == SpeedMode_HighSpeed;
|
||||
const u32 slave_addr = ((static_cast<u32>(slave_address) & 0x7F) << 1) | (is_read ? 1 : 0);
|
||||
|
||||
/* Flush fifos. */
|
||||
this->FlushFifos();
|
||||
|
||||
/* Enqueue the first header word. */
|
||||
reg::Write(this->registers->tx_packet_fifo, IO_PACKET_BITS_ENUM (HEADER_WORD0_PROT_HDR_SZ, 1_WORD),
|
||||
IO_PACKET_BITS_VALUE(HEADER_WORD0_PKT_ID, 0),
|
||||
IO_PACKET_BITS_VALUE(HEADER_WORD0_CONTROLLER_ID, 0),
|
||||
IO_PACKET_BITS_ENUM (HEADER_WORD0_PROTOCOL, I2C),
|
||||
IO_PACKET_BITS_ENUM (HEADER_WORD0_PKT_TYPE, REQUEST));
|
||||
reg::Write(m_registers->tx_packet_fifo, IO_PACKET_BITS_ENUM (HEADER_WORD0_PROT_HDR_SZ, 1_WORD),
|
||||
IO_PACKET_BITS_VALUE(HEADER_WORD0_PKT_ID, 0),
|
||||
IO_PACKET_BITS_VALUE(HEADER_WORD0_CONTROLLER_ID, 0),
|
||||
IO_PACKET_BITS_ENUM (HEADER_WORD0_PROTOCOL, I2C),
|
||||
IO_PACKET_BITS_ENUM (HEADER_WORD0_PKT_TYPE, REQUEST));
|
||||
|
||||
/* Enqueue the second header word. */
|
||||
reg::Write(this->registers->tx_packet_fifo, IO_PACKET_BITS_VALUE(HEADER_WORD1_PAYLOAD_SIZE, static_cast<u32>(size - 1)));
|
||||
reg::Write(m_registers->tx_packet_fifo, IO_PACKET_BITS_VALUE(HEADER_WORD1_PAYLOAD_SIZE, static_cast<u32>(size - 1)));
|
||||
|
||||
/* Enqueue the protocol header word. */
|
||||
reg::Write(this->registers->tx_packet_fifo, IO_PACKET_BITS_ENUM_SEL(PROTOCOL_HEADER_HS_MODE, is_hs, ENABLE, DISABLE),
|
||||
IO_PACKET_BITS_ENUM (PROTOCOL_HEADER_CONTINUE_ON_NACK, DISABLE),
|
||||
IO_PACKET_BITS_ENUM (PROTOCOL_HEADER_SEND_START_BYTE, DISABLE),
|
||||
IO_PACKET_BITS_ENUM_SEL(PROTOCOL_HEADER_READ_WRITE, is_read, READ, WRITE),
|
||||
IO_PACKET_BITS_ENUM_SEL(PROTOCOL_HEADER_ADDRESS_MODE, is_7_bit, SEVEN_BIT, TEN_BIT),
|
||||
IO_PACKET_BITS_ENUM (PROTOCOL_HEADER_IE, ENABLE),
|
||||
IO_PACKET_BITS_ENUM_SEL(PROTOCOL_HEADER_REPEAT_START_STOP, is_stop, STOP_CONDITION, REPEAT_START_CONDITION),
|
||||
IO_PACKET_BITS_ENUM (PROTOCOL_HEADER_CONTINUE_XFER, USE_REPEAT_START_TOP),
|
||||
IO_PACKET_BITS_VALUE (PROTOCOL_HEADER_HS_MASTER_ADDR, 0),
|
||||
IO_PACKET_BITS_VALUE (PROTOCOL_HEADER_SLAVE_ADDR, slave_addr));
|
||||
reg::Write(m_registers->tx_packet_fifo, IO_PACKET_BITS_ENUM_SEL(PROTOCOL_HEADER_HS_MODE, is_hs, ENABLE, DISABLE),
|
||||
IO_PACKET_BITS_ENUM (PROTOCOL_HEADER_CONTINUE_ON_NACK, DISABLE),
|
||||
IO_PACKET_BITS_ENUM (PROTOCOL_HEADER_SEND_START_BYTE, DISABLE),
|
||||
IO_PACKET_BITS_ENUM_SEL(PROTOCOL_HEADER_READ_WRITE, is_read, READ, WRITE),
|
||||
IO_PACKET_BITS_ENUM_SEL(PROTOCOL_HEADER_ADDRESS_MODE, is_7_bit, SEVEN_BIT, TEN_BIT),
|
||||
IO_PACKET_BITS_ENUM (PROTOCOL_HEADER_IE, ENABLE),
|
||||
IO_PACKET_BITS_ENUM_SEL(PROTOCOL_HEADER_REPEAT_START_STOP, is_stop, STOP_CONDITION, REPEAT_START_CONDITION),
|
||||
IO_PACKET_BITS_ENUM (PROTOCOL_HEADER_CONTINUE_XFER, USE_REPEAT_START_TOP),
|
||||
IO_PACKET_BITS_VALUE (PROTOCOL_HEADER_HS_MASTER_ADDR, 0),
|
||||
IO_PACKET_BITS_VALUE (PROTOCOL_HEADER_SLAVE_ADDR, slave_addr));
|
||||
}
|
||||
|
||||
void I2cBusAccessor::ResetController() const {
|
||||
/* Reset the controller. */
|
||||
if (!this->is_power_bus) {
|
||||
if (!m_is_power_bus) {
|
||||
/* Open a clkrst session. */
|
||||
clkrst::ClkRstSession clkrst_session;
|
||||
R_ABORT_UNLESS(clkrst::OpenSession(std::addressof(clkrst_session), this->device_code));
|
||||
R_ABORT_UNLESS(clkrst::OpenSession(std::addressof(clkrst_session), m_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). */
|
||||
|
@ -573,17 +573,17 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
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));
|
||||
reg::Write(m_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));
|
||||
reg::ReadWrite(m_registers->bus_clear_config, I2C_REG_BITS_ENUM(BUS_CLEAR_CONFIG_BC_STOP_COND, STOP));
|
||||
reg::ReadWrite(m_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));
|
||||
reg::ReadWrite(m_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))) {
|
||||
while (reg::HasValue(m_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;
|
||||
|
@ -595,10 +595,10 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
}
|
||||
|
||||
/* 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));
|
||||
reg::ReadWrite(m_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))) {
|
||||
while (reg::HasValue(m_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;
|
||||
|
@ -611,7 +611,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
|
||||
/* 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))) {
|
||||
while (reg::HasValue(m_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;
|
||||
|
@ -629,7 +629,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
u32 t_high, t_low, clk_div, debounce, src_div;
|
||||
bool high_speed = false;
|
||||
|
||||
if (this->is_power_bus) {
|
||||
if (m_is_power_bus) {
|
||||
t_high = 0x02;
|
||||
t_low = 0x04;
|
||||
clk_div = 0x05;
|
||||
|
@ -672,26 +672,26 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
|
||||
/* 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(m_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));
|
||||
reg::Write(m_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(m_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));
|
||||
reg::Write(m_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);
|
||||
reg::Write(m_registers->cnfg, I2C_REG_BITS_VALUE(I2C_CNFG_DEBOUNCE_CNT, debounce));
|
||||
reg::Read(m_registers->cnfg);
|
||||
|
||||
/* Set the clock rate, if we should. */
|
||||
if (!this->is_power_bus) {
|
||||
if (!m_is_power_bus) {
|
||||
/* Open a clkrst session. */
|
||||
clkrst::ClkRstSession clkrst_session;
|
||||
R_ABORT_UNLESS(clkrst::OpenSession(std::addressof(clkrst_session), this->device_code));
|
||||
R_ABORT_UNLESS(clkrst::OpenSession(std::addressof(clkrst_session), m_device_code));
|
||||
ON_SCOPE_EXIT { clkrst::CloseSession(std::addressof(clkrst_session)); };
|
||||
|
||||
/* Reset the controller, setting clock rate to 408 MHz / (src_div + 1). */
|
||||
|
@ -704,26 +704,26 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
|
||||
void I2cBusAccessor::SetPacketModeRegisters() {
|
||||
/* Set packet mode enable. */
|
||||
reg::ReadWrite(this->registers->cnfg, I2C_REG_BITS_ENUM(I2C_CNFG_PACKET_MODE_EN, GO));
|
||||
reg::ReadWrite(m_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));
|
||||
reg::ReadWrite(m_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));
|
||||
reg::Write(m_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() {
|
||||
/* 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));
|
||||
reg::Write(m_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))) {
|
||||
while (!reg::HasValue(m_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));
|
||||
}
|
||||
|
@ -733,8 +733,8 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
|
||||
Result I2cBusAccessor::GetTransactionResult() const {
|
||||
/* 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);
|
||||
volatile u32 packet_status = reg::Read(m_registers->packet_transfer_status);
|
||||
volatile u32 interrupt_status = reg::Read(m_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());
|
||||
|
@ -759,7 +759,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
this->ResetController();
|
||||
|
||||
/* Set clock registers. */
|
||||
this->SetClockRegisters(this->speed_mode);
|
||||
this->SetClockRegisters(m_speed_mode);
|
||||
|
||||
/* Set packet mode registers. */
|
||||
this->SetPacketModeRegisters();
|
||||
|
|
|
@ -37,31 +37,31 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
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;
|
||||
volatile I2cRegisters *m_registers;
|
||||
SpeedMode m_speed_mode;
|
||||
os::InterruptEventType m_interrupt_event;
|
||||
int m_user_count;
|
||||
os::SdkMutex m_user_count_mutex;
|
||||
os::SdkMutex m_register_mutex;
|
||||
regulator::RegulatorSession m_regulator_session;
|
||||
bool m_has_regulator_session;
|
||||
State m_state;
|
||||
os::SdkMutex m_transaction_order_mutex;
|
||||
bool m_is_power_bus;
|
||||
dd::PhysicalAddress m_registers_phys_addr;
|
||||
size_t m_registers_size;
|
||||
os::InterruptName m_interrupt_name;
|
||||
DeviceCode m_device_code;
|
||||
util::IntrusiveListNode m_bus_accessor_list_node;
|
||||
public:
|
||||
using BusAccessorListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&I2cBusAccessor::bus_accessor_list_node>;
|
||||
using BusAccessorListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&I2cBusAccessor::m_bus_accessor_list_node>;
|
||||
using BusAccessorList = typename BusAccessorListTraits::ListType;
|
||||
friend class util::IntrusiveList<I2cBusAccessor, util::IntrusiveListMemberTraitsDeferredAssert<&I2cBusAccessor::bus_accessor_list_node>>;
|
||||
friend class util::IntrusiveList<I2cBusAccessor, util::IntrusiveListMemberTraitsDeferredAssert<&I2cBusAccessor::m_bus_accessor_list_node>>;
|
||||
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()
|
||||
: m_registers(nullptr), m_speed_mode(SpeedMode_Fast), m_user_count(0), m_user_count_mutex(),
|
||||
m_register_mutex(), m_has_regulator_session(false), m_state(State::NotInitialized), m_transaction_order_mutex(),
|
||||
m_is_power_bus(false), m_registers_phys_addr(0), m_registers_size(0), m_interrupt_name(), m_device_code(-1), m_bus_accessor_list_node()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
@ -69,10 +69,10 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
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; }
|
||||
SpeedMode GetSpeedMode() const { return m_speed_mode; }
|
||||
dd::PhysicalAddress GetRegistersPhysicalAddress() const { return m_registers_phys_addr; }
|
||||
size_t GetRegistersSize() const { return m_registers_size; }
|
||||
os::InterruptName GetInterruptName() const { return m_interrupt_name; }
|
||||
private:
|
||||
Result TryOpenRegulatorSession();
|
||||
|
||||
|
@ -94,8 +94,8 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
void HandleTransactionError(Result result);
|
||||
|
||||
void DisableInterruptMask() {
|
||||
reg::Write(this->registers->interrupt_mask_register, 0);
|
||||
reg::Read(this->registers->interrupt_mask_register);
|
||||
reg::Write(m_registers->interrupt_mask_register, 0);
|
||||
reg::Read(m_registers->interrupt_mask_register);
|
||||
}
|
||||
|
||||
Result CheckAndHandleError() {
|
||||
|
@ -103,7 +103,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
this->HandleTransactionError(result);
|
||||
if (R_FAILED(result)) {
|
||||
this->DisableInterruptMask();
|
||||
os::ClearInterruptEvent(std::addressof(this->interrupt_event));
|
||||
os::ClearInterruptEvent(std::addressof(m_interrupt_event));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
virtual Result Receive(void *dst, size_t dst_size, I2cDeviceProperty *device, TransactionOption option) override;
|
||||
|
||||
virtual os::SdkMutex &GetTransactionOrderMutex() override {
|
||||
return this->transaction_order_mutex;
|
||||
return m_transaction_order_mutex;
|
||||
}
|
||||
|
||||
virtual void SuspendBus() override;
|
||||
|
@ -130,7 +130,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
virtual void ResumePowerBus() override;
|
||||
|
||||
virtual const DeviceCode &GetDeviceCode() const override {
|
||||
return this->device_code;
|
||||
return m_device_code;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -25,48 +25,48 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
|
|||
private:
|
||||
using T = typename ListType::value_type;
|
||||
private:
|
||||
ams::MemoryResource *memory_resource;
|
||||
ListType list;
|
||||
mutable os::SdkMutex list_lock;
|
||||
ams::MemoryResource *m_memory_resource;
|
||||
ListType m_list;
|
||||
mutable os::SdkMutex m_list_lock;
|
||||
public:
|
||||
IAllocator(ams::MemoryResource *mr) : memory_resource(mr), list(), list_lock() { /* ... */ }
|
||||
IAllocator(ams::MemoryResource *mr) : m_memory_resource(mr), m_list(), m_list_lock() { /* ... */ }
|
||||
|
||||
~IAllocator() {
|
||||
std::scoped_lock lk(this->list_lock);
|
||||
std::scoped_lock lk(m_list_lock);
|
||||
|
||||
/* Remove all entries. */
|
||||
auto it = this->list.begin();
|
||||
while (it != this->list.end()) {
|
||||
auto it = m_list.begin();
|
||||
while (it != m_list.end()) {
|
||||
T *obj = std::addressof(*it);
|
||||
it = this->list.erase(it);
|
||||
it = m_list.erase(it);
|
||||
|
||||
std::destroy_at(obj);
|
||||
this->memory_resource->Deallocate(obj, sizeof(T));
|
||||
m_memory_resource->Deallocate(obj, sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
T *Allocate(Args &&...args) {
|
||||
std::scoped_lock lk(this->list_lock);
|
||||
std::scoped_lock lk(m_list_lock);
|
||||
|
||||
/* Allocate space for the object. */
|
||||
void *storage = this->memory_resource->Allocate(sizeof(T), alignof(T));
|
||||
void *storage = m_memory_resource->Allocate(sizeof(T), alignof(T));
|
||||
AMS_ABORT_UNLESS(storage != nullptr);
|
||||
|
||||
/* Construct the object. */
|
||||
T *t = std::construct_at(static_cast<T *>(storage), std::forward<Args>(args)...);
|
||||
|
||||
/* Link the object into our list. */
|
||||
this->list.push_back(*t);
|
||||
m_list.push_back(*t);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
T *Find(F f) {
|
||||
std::scoped_lock lk(this->list_lock);
|
||||
std::scoped_lock lk(m_list_lock);
|
||||
|
||||
for (T &it : this->list) {
|
||||
for (T &it : m_list) {
|
||||
if (f(static_cast<const T &>(it))) {
|
||||
return std::addressof(it);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue