From 4db485083b89a0ec6ba4cfe1418e0d4ad6964890 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 5 May 2022 17:45:55 -0700 Subject: [PATCH] strat: update for code changes found in boot (closes #1797) --- .../stratosphere/pwm/driver/pwm_i_pwm_driver.hpp | 1 + .../pwm/sf/pwm_sf_i_channel_session.hpp | 16 ++++++++-------- .../nintendo/nx/impl/pwm_pwm_driver_impl.cpp | 14 +++++++++++--- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/pwm/driver/pwm_i_pwm_driver.hpp b/libraries/libstratosphere/include/stratosphere/pwm/driver/pwm_i_pwm_driver.hpp index 6477f59f5..5ff831a6e 100644 --- a/libraries/libstratosphere/include/stratosphere/pwm/driver/pwm_i_pwm_driver.hpp +++ b/libraries/libstratosphere/include/stratosphere/pwm/driver/pwm_i_pwm_driver.hpp @@ -38,6 +38,7 @@ namespace ams::pwm::driver { virtual Result SetPeriod(IPwmDevice *device, TimeSpan period) = 0; virtual Result GetPeriod(TimeSpan *out, IPwmDevice *device) = 0; + /* TODO: Nintendo removed these in 14.0.0. Should we? */ virtual Result SetDuty(IPwmDevice *device, int duty) = 0; virtual Result GetDuty(int *out, IPwmDevice *device) = 0; diff --git a/libraries/libstratosphere/include/stratosphere/pwm/sf/pwm_sf_i_channel_session.hpp b/libraries/libstratosphere/include/stratosphere/pwm/sf/pwm_sf_i_channel_session.hpp index b09d1155f..98f1c5bab 100644 --- a/libraries/libstratosphere/include/stratosphere/pwm/sf/pwm_sf_i_channel_session.hpp +++ b/libraries/libstratosphere/include/stratosphere/pwm/sf/pwm_sf_i_channel_session.hpp @@ -18,14 +18,14 @@ #include #include -#define AMS_PWM_I_CHANNEL_SESSION_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, SetPeriod, (TimeSpanType period), (period) ) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, GetPeriod, (ams::sf::Out out), (out) ) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, SetDuty, (int duty), (duty) ) \ - AMS_SF_METHOD_INFO(C, H, 3, Result, GetDuty, (ams::sf::Out out), (out) ) \ - AMS_SF_METHOD_INFO(C, H, 4, Result, SetEnabled, (bool enabled), (enabled) ) \ - AMS_SF_METHOD_INFO(C, H, 5, Result, GetEnabled, (ams::sf::Out out), (out) ) \ - AMS_SF_METHOD_INFO(C, H, 6, Result, SetScale, (double scale), (scale), hos::Version_6_0_0) \ +#define AMS_PWM_I_CHANNEL_SESSION_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, SetPeriod, (TimeSpanType period), (period)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, GetPeriod, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, SetDuty, (int duty), (duty), hos::Version_Min, hos::Version_13_2_1) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, GetDuty, (ams::sf::Out out), (out), hos::Version_Min, hos::Version_13_2_1) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, SetEnabled, (bool enabled), (enabled)) \ + AMS_SF_METHOD_INFO(C, H, 5, Result, GetEnabled, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 6, Result, SetScale, (double scale), (scale), hos::Version_6_0_0) \ AMS_SF_METHOD_INFO(C, H, 7, Result, GetScale, (ams::sf::Out out), (out), hos::Version_6_0_0) AMS_SF_DEFINE_INTERFACE(ams::pwm::sf, IChannelSession, AMS_PWM_I_CHANNEL_SESSION_INTERFACE_INFO, 0xAC0A18F9) diff --git a/libraries/libstratosphere/source/pwm/driver/board/nintendo/nx/impl/pwm_pwm_driver_impl.cpp b/libraries/libstratosphere/source/pwm/driver/board/nintendo/nx/impl/pwm_pwm_driver_impl.cpp index e5cd5c820..cc4049e1e 100644 --- a/libraries/libstratosphere/source/pwm/driver/board/nintendo/nx/impl/pwm_pwm_driver_impl.cpp +++ b/libraries/libstratosphere/source/pwm/driver/board/nintendo/nx/impl/pwm_pwm_driver_impl.cpp @@ -79,7 +79,7 @@ namespace ams::pwm::driver::board::nintendo::nx::impl { /* Configure initial settings. */ /* NOTE: None of these results are checked. */ this->SetEnabled(device, false); - this->SetDuty(device, 0); + this->SetScale(device, 0.0); this->SetPeriod(device, DefaultChannelPeriod); R_SUCCEED(); } @@ -169,8 +169,16 @@ namespace ams::pwm::driver::board::nintendo::nx::impl { /* Convert the scale to a duty. */ const int duty = static_cast(((scale * 256.0) / 100.0) + 0.5); - /* Set the duty. */ - R_RETURN(this->SetDuty(device, duty)); + /* Validate the duty. */ + R_UNLESS(0 <= duty && duty <= MaxDuty, pwm::ResultInvalidArgument()); + + /* Acquire exclusive access to the device registers. */ + std::scoped_lock lk(device->SafeCastTo()); + + /* Update the duty. */ + reg::ReadWrite(this->GetRegistersFor(device) + PWM_CONTROLLER_PWM_CSR, PWM_REG_BITS_VALUE(PWM_CSR_PWM, static_cast(duty))); + + R_SUCCEED(); } Result PwmDriverImpl::GetScale(double *out, IPwmDevice *device) {