diff --git a/libraries/libstratosphere/include/stratosphere/i2c.hpp b/libraries/libstratosphere/include/stratosphere/i2c.hpp index cff61261d..fc65c1a83 100644 --- a/libraries/libstratosphere/include/stratosphere/i2c.hpp +++ b/libraries/libstratosphere/include/stratosphere/i2c.hpp @@ -28,3 +28,4 @@ #include #include #include +#include diff --git a/libraries/libstratosphere/include/stratosphere/i2c/i2c_register_accessor.hpp b/libraries/libstratosphere/include/stratosphere/i2c/i2c_register_accessor.hpp new file mode 100644 index 000000000..6ca145c56 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/i2c/i2c_register_accessor.hpp @@ -0,0 +1,56 @@ +/* + * 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 + +namespace ams::i2c { + + template requires std::unsigned_integral + Result ReadSingleRegister(const I2cSession &session, u8 address, RegType *out) { + /* Check pre-conditions. */ + AMS_ABORT_UNLESS(out != nullptr); + + constexpr i2c::TransactionOption StartOption = i2c::TransactionOption_StartCondition; + constexpr i2c::TransactionOption StopOption = static_cast(i2c::TransactionOption_StartCondition | i2c::TransactionOption_StopCondition); + + u8 cmd_list[CommandListLengthMax]; + i2c::CommandListFormatter formatter(cmd_list, sizeof(cmd_list)); + + R_TRY(formatter.EnqueueSendCommand(StartOption, std::addressof(address), sizeof(address))); + R_TRY(formatter.EnqueueReceiveCommand(StopOption, sizeof(*out))); + + R_TRY(i2c::ExecuteCommandList(out, sizeof(*out), session, cmd_list, formatter.GetCurrentLength())); + + return ResultSuccess(); + } + + template requires std::unsigned_integral + Result WriteSingleRegister(const I2cSession &session, u8 address, RegType value) { + /* Prepare buffer. */ + u8 buf[sizeof(address) + sizeof(value)]; + std::memcpy(buf + 0, std::addressof(address), sizeof(address)); + std::memcpy(buf + sizeof(address), std::addressof(value), sizeof(value)); + + constexpr i2c::TransactionOption StopOption = static_cast(i2c::TransactionOption_StartCondition | i2c::TransactionOption_StopCondition); + R_TRY(i2c::Send(session, buf, sizeof(buf), StopOption)); + + return ResultSuccess(); + } + +} diff --git a/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_bq24193_driver.cpp b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_bq24193_driver.cpp new file mode 100644 index 000000000..773a1b35e --- /dev/null +++ b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_bq24193_driver.cpp @@ -0,0 +1,169 @@ +/* + * 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 "powctl_bq24193_driver.hpp" + +namespace ams::powctl::impl::board::nintendo_nx { + + Result Bq24193Driver::InitializeSession() { + /* Set fast charge current limit. */ + R_TRY(this->SetFastChargeCurrentLimit(512)); + + /* Disable force 20 percent charge. */ + R_TRY(this->SetForce20PercentChargeCurrent(false)); + + /* Set pre-charge current limit. */ + R_TRY(this->SetPreChargeCurrentLimit(128)); + + /* Set termination current limit. */ + R_TRY(this->SetTerminationCurrentLimit(128)); + + /* Set minimum system voltage limit. */ + R_TRY(this->SetMinimumSystemVoltageLimit(3000)); + + /* Set watchdog timer setting. */ + R_TRY(this->SetWatchdogTimerSetting(0)); + + /* Disable charging safety timer. */ + R_TRY(this->SetChargingSafetyTimerEnabled(false)); + + /* Reset the watchdog timer. */ + R_TRY(this->ResetWatchdogTimer()); + + return ResultSuccess(); + } + + Result Bq24193Driver::SetPreChargeCurrentLimit(int ma) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::SetTerminationCurrentLimit(int ma) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::SetMinimumSystemVoltageLimit(int mv) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::SetChargingSafetyTimerEnabled(bool en) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::GetForce20PercentChargeCurrent(bool *out) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::SetForce20PercentChargeCurrent(bool en) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::GetFastChargeCurrentLimit(int *out_ma) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::SetFastChargeCurrentLimit(int ma) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::GetChargeVoltageLimit(int *out_mv) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::SetChargeVoltageLimit(int mv) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::SetChargerConfiguration(bq24193::ChargerConfiguration cfg) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::IsHiZEnabled(bool *out) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::SetHiZEnabled(bool en) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::GetInputCurrentLimit(int *out_ma) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::SetInputCurrentLimit(int ma) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::GetInputVoltageLimit(int *out_mv) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::SetInputVoltageLimit(int mv) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::GetChargerStatus(bq24193::ChargerStatus *out) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::ResetWatchdogTimer() { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::SetWatchdogTimerSetting(int seconds) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::GetBatteryCompensation(int *out_mo) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::SetBatteryCompensation(int mo) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::GetVoltageClamp(int *out_mv) { + /* TODO */ + AMS_ABORT(); + } + + Result Bq24193Driver::SetVoltageClamp(int mv) { + /* TODO */ + AMS_ABORT(); + } + +} \ No newline at end of file diff --git a/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_bq24193_driver.hpp b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_bq24193_driver.hpp index 655a4de46..e19fa0b3c 100644 --- a/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_bq24193_driver.hpp +++ b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_bq24193_driver.hpp @@ -52,6 +52,13 @@ namespace ams::powctl::impl::board::nintendo_nx { R_ABORT_UNLESS(this->InitializeSession()); } + Result SetPreChargeCurrentLimit(int ma); + Result SetTerminationCurrentLimit(int ma); + + Result SetMinimumSystemVoltageLimit(int mv); + + Result SetChargingSafetyTimerEnabled(bool en); + Result GetForce20PercentChargeCurrent(bool *out); Result SetForce20PercentChargeCurrent(bool en); diff --git a/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_charger_driver.cpp b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_charger_driver.cpp index 71ddd59b1..42588d864 100644 --- a/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_charger_driver.cpp +++ b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_charger_driver.cpp @@ -32,6 +32,19 @@ namespace ams::powctl::impl::board::nintendo_nx { } + ChargerDevice::ChargerDevice(bool ev) : gpio_pad_session(), watchdog_timer_enabled(false), watchdog_timer_timeout(0), use_event_handler(ev), event_handler() { + if (this->use_event_handler) { + /* Create the system event. */ + os::CreateSystemEvent(std::addressof(this->system_event), os::EventClearMode_ManualClear, true); + + /* Create the handler. */ + this->event_handler.emplace(this); + + /* Register the event handler. */ + powctl::impl::RegisterInterruptHandler(std::addressof(*this->event_handler)); + } + } + /* Generic API. */ void ChargerDriver::InitializeDriver() { /* Initialize Bq24193Driver */ diff --git a/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_interrupt_event_handler.hpp b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_interrupt_event_handler.hpp index 17c83bb9a..40be3dc32 100644 --- a/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_interrupt_event_handler.hpp +++ b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_interrupt_event_handler.hpp @@ -77,6 +77,8 @@ namespace ams::powctl::impl::board::nintendo_nx { } void SignalEvent(IDevice *device); + public: + ChargerInterruptEventHandler(IDevice *dv) : InterruptEventHandler(dv) { /* ... */ } }; class BatteryInterruptEventHandler : public InterruptEventHandler { @@ -95,6 +97,8 @@ namespace ams::powctl::impl::board::nintendo_nx { } void SignalEvent(IDevice *device); + public: + BatteryInterruptEventHandler(IDevice *dv) : InterruptEventHandler(dv) { /* ... */ } }; } \ No newline at end of file