mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-07-07 10:02:14 +02:00
sdmmc: SdCardDeviceAccessor impl
This commit is contained in:
parent
e3900de6c0
commit
4586dce57b
@ -21,8 +21,8 @@ namespace ams::sdmmc_test {
|
|||||||
|
|
||||||
constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc.GetAddress();
|
constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc.GetAddress();
|
||||||
|
|
||||||
constexpr inline auto Port = sdmmc::Port_Mmc0;
|
constexpr inline auto Port = sdmmc::Port_SdCard0;
|
||||||
alignas(8) constinit u8 g_mmc_work_buffer[sdmmc::MmcWorkBufferSize];
|
alignas(8) constinit u8 g_sd_work_buffer[sdmmc::SdCardWorkBufferSize];
|
||||||
|
|
||||||
constexpr inline u32 SectorIndex = 0;
|
constexpr inline u32 SectorIndex = 0;
|
||||||
constexpr inline u32 SectorCount = 2;
|
constexpr inline u32 SectorCount = 2;
|
||||||
@ -55,31 +55,28 @@ namespace ams::sdmmc_test {
|
|||||||
sdmmc::Initialize(Port);
|
sdmmc::Initialize(Port);
|
||||||
DEBUG[0] = 1;
|
DEBUG[0] = 1;
|
||||||
|
|
||||||
sdmmc::SetMmcWorkBuffer(Port, g_mmc_work_buffer, sizeof(g_mmc_work_buffer));
|
sdmmc::SetSdCardWorkBuffer(Port, g_sd_work_buffer, sizeof(g_sd_work_buffer));
|
||||||
DEBUG[0] = 2;
|
DEBUG[0] = 2;
|
||||||
|
|
||||||
Result result = sdmmc::Activate(Port);
|
Result result = sdmmc::Activate(Port);
|
||||||
DEBUG[0] = 3;
|
DEBUG[0] = 3;
|
||||||
CheckResult(result);
|
CheckResult(result);
|
||||||
|
|
||||||
/* Select user data partition. */
|
PmcMainReboot();
|
||||||
result = sdmmc::SelectMmcPartition(Port, sdmmc::MmcPartition_UserData);
|
|
||||||
DEBUG[0] = 4;
|
|
||||||
CheckResult(result);
|
|
||||||
|
|
||||||
/* Read the first two sectors from disk. */
|
/* Read the first two sectors from disk. */
|
||||||
void * const sector_dst = reinterpret_cast<void *>(0x40038000);
|
void * const sector_dst = reinterpret_cast<void *>(0x40038000);
|
||||||
result = sdmmc::Read(sector_dst, SectorCount * sdmmc::SectorSize, Port, SectorIndex, SectorCount);
|
result = sdmmc::Read(sector_dst, SectorCount * sdmmc::SectorSize, Port, SectorIndex, SectorCount);
|
||||||
DEBUG[0] = 5;
|
DEBUG[0] = 4;
|
||||||
CheckResult(result);
|
CheckResult(result);
|
||||||
|
|
||||||
/* Get the connection status. */
|
/* Get the connection status. */
|
||||||
sdmmc::SpeedMode speed_mode;
|
sdmmc::SpeedMode speed_mode;
|
||||||
sdmmc::BusWidth bus_width;
|
sdmmc::BusWidth bus_width;
|
||||||
result = sdmmc::CheckMmcConnection(std::addressof(speed_mode), std::addressof(bus_width), Port);
|
result = sdmmc::CheckSdCardConnection(std::addressof(speed_mode), std::addressof(bus_width), Port);
|
||||||
|
|
||||||
/* Save status for debug. */
|
/* Save status for debug. */
|
||||||
DEBUG[0] = 6;
|
DEBUG[0] = 5;
|
||||||
DEBUG[1] = result.GetValue();
|
DEBUG[1] = result.GetValue();
|
||||||
DEBUG[2] = static_cast<u32>(speed_mode);
|
DEBUG[2] = static_cast<u32>(speed_mode);
|
||||||
DEBUG[3] = static_cast<u32>(bus_width);
|
DEBUG[3] = static_cast<u32>(bus_width);
|
||||||
|
@ -140,9 +140,9 @@ ATMOSPHERE_GCH_IDENTIFIER ?= ams_placeholder_gch_identifier
|
|||||||
# Rules for compiling pre-compiled headers
|
# Rules for compiling pre-compiled headers
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
%.hpp.gch/$(ATMOSPHERE_GCH_IDENTIFIER): %.hpp | %.hpp.gch
|
%.hpp.gch/$(ATMOSPHERE_GCH_IDENTIFIER): %.hpp | %.hpp.gch
|
||||||
$(SILENTMSG) Precompiling $(notdir $<) for $(ATMOSPHERE_GCH_IDENTIFIER)
|
@echo Precompiling $(notdir $<) for $(ATMOSPHERE_GCH_IDENTIFIER)
|
||||||
$(SILENTCMD)$(CXX) -w -x c++-header -MMD -MP -MQ$@ -MF $(DEPSDIR)/$(notdir $*).d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)
|
$(SILENTCMD)$(CXX) -w -x c++-header -MMD -MP -MQ$@ -MF $(DEPSDIR)/$(notdir $*).d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)
|
||||||
|
|
||||||
%.hpp.gch: %.hpp
|
%.hpp.gch: %.hpp
|
||||||
$(SILENTMSG) Precompiling $(notdir $<)
|
@echo Precompiling $(notdir $<)
|
||||||
$(SILENTCMD)$(CXX) -w -x c++-header -MMD -MP -MQ$@ -MF $(DEPSDIR)/$(notdir $*).d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)
|
$(SILENTCMD)$(CXX) -w -x c++-header -MMD -MP -MQ$@ -MF $(DEPSDIR)/$(notdir $*).d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)
|
||||||
|
@ -21,6 +21,7 @@ namespace ams::sdmmc {
|
|||||||
|
|
||||||
R_DEFINE_NAMESPACE_RESULT_MODULE(24);
|
R_DEFINE_NAMESPACE_RESULT_MODULE(24);
|
||||||
|
|
||||||
|
R_DEFINE_ERROR_RESULT(NoDevice, 1);
|
||||||
R_DEFINE_ERROR_RESULT(NotActivated, 2);
|
R_DEFINE_ERROR_RESULT(NotActivated, 2);
|
||||||
R_DEFINE_ERROR_RESULT(DeviceRemoved, 3);
|
R_DEFINE_ERROR_RESULT(DeviceRemoved, 3);
|
||||||
R_DEFINE_ERROR_RESULT(NotAwakened, 4);
|
R_DEFINE_ERROR_RESULT(NotAwakened, 4);
|
||||||
@ -69,6 +70,18 @@ namespace ams::sdmmc {
|
|||||||
R_DEFINE_ERROR_RESULT(MmcNotSupportExtendedCsd, 81);
|
R_DEFINE_ERROR_RESULT(MmcNotSupportExtendedCsd, 81);
|
||||||
R_DEFINE_ERROR_RESULT(UnexpectedMmcExtendedCsdValue, 82);
|
R_DEFINE_ERROR_RESULT(UnexpectedMmcExtendedCsdValue, 82);
|
||||||
R_DEFINE_ERROR_RESULT(MmcEraseSoftwareTimeout, 83);
|
R_DEFINE_ERROR_RESULT(MmcEraseSoftwareTimeout, 83);
|
||||||
|
R_DEFINE_ERROR_RESULT(SdCardValidationError, 84);
|
||||||
|
R_DEFINE_ERROR_RESULT(SdCardInitializationSoftwareTimeout, 85);
|
||||||
|
R_DEFINE_ERROR_RESULT(SdCardGetValidRcaSoftwareTimeout, 86);
|
||||||
|
R_DEFINE_ERROR_RESULT(UnexpectedSdCardAcmdDisabled, 87);
|
||||||
|
R_DEFINE_ERROR_RESULT(SdCardNotSupportSwitchFunctionStatus, 88);
|
||||||
|
R_DEFINE_ERROR_RESULT(UnexpectedSdCardSwitchFunctionStatus, 89);
|
||||||
|
R_DEFINE_ERROR_RESULT(SdCardNotSupportAccessMode, 90);
|
||||||
|
R_DEFINE_ERROR_RESULT(SdCardNot4BitBusWidthAtUhsIMode, 91);
|
||||||
|
R_DEFINE_ERROR_RESULT(SdCardNotSupportSdr104AndSdr50, 92);
|
||||||
|
R_DEFINE_ERROR_RESULT(SdCardCannotSwitchAccessMode, 93);
|
||||||
|
R_DEFINE_ERROR_RESULT(SdCardFailedSwitchAccessMode, 94);
|
||||||
|
R_DEFINE_ERROR_RESULT(SdCardUnacceptableCurrentConsumption, 95);
|
||||||
R_DEFINE_ERROR_RESULT(SdCardNotReadyToVoltageSwitch, 96);
|
R_DEFINE_ERROR_RESULT(SdCardNotReadyToVoltageSwitch, 96);
|
||||||
R_DEFINE_ERROR_RESULT(SdCardNotCompleteVoltageSwitch, 97);
|
R_DEFINE_ERROR_RESULT(SdCardNotCompleteVoltageSwitch, 97);
|
||||||
|
|
||||||
|
@ -24,3 +24,4 @@
|
|||||||
#include <vapours/sdmmc/sdmmc_build_config.hpp>
|
#include <vapours/sdmmc/sdmmc_build_config.hpp>
|
||||||
#include <vapours/sdmmc/sdmmc_common.hpp>
|
#include <vapours/sdmmc/sdmmc_common.hpp>
|
||||||
#include <vapours/sdmmc/sdmmc_mmc.hpp>
|
#include <vapours/sdmmc/sdmmc_mmc.hpp>
|
||||||
|
#include <vapours/sdmmc/sdmmc_sd_card.hpp>
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
//#define AMS_SDMMC_USE_OS_TIMER
|
//#define AMS_SDMMC_USE_OS_TIMER
|
||||||
#define AMS_SDMMC_USE_UTIL_TIMER
|
#define AMS_SDMMC_USE_UTIL_TIMER
|
||||||
//#define AMS_SDMMC_ENABLE_MMC_HS400
|
//#define AMS_SDMMC_ENABLE_MMC_HS400
|
||||||
|
//#define AMS_SDMMC_ENABLE_SD_UHS_I
|
||||||
//#define AMS_SDMMC_SET_PLLC4_BASE
|
//#define AMS_SDMMC_SET_PLLC4_BASE
|
||||||
//#define AMS_SDMMC_USE_SD_CARD_DETECTOR
|
//#define AMS_SDMMC_USE_SD_CARD_DETECTOR
|
||||||
|
|
||||||
@ -47,6 +48,7 @@
|
|||||||
//#define AMS_SDMMC_USE_OS_TIMER
|
//#define AMS_SDMMC_USE_OS_TIMER
|
||||||
#define AMS_SDMMC_USE_UTIL_TIMER
|
#define AMS_SDMMC_USE_UTIL_TIMER
|
||||||
//#define AMS_SDMMC_ENABLE_MMC_HS400
|
//#define AMS_SDMMC_ENABLE_MMC_HS400
|
||||||
|
//#define AMS_SDMMC_ENABLE_SD_UHS_I
|
||||||
//#define AMS_SDMMC_SET_PLLC4_BASE
|
//#define AMS_SDMMC_SET_PLLC4_BASE
|
||||||
//#define AMS_SDMMC_USE_SD_CARD_DETECTOR
|
//#define AMS_SDMMC_USE_SD_CARD_DETECTOR
|
||||||
|
|
||||||
@ -61,6 +63,7 @@
|
|||||||
#define AMS_SDMMC_USE_OS_TIMER
|
#define AMS_SDMMC_USE_OS_TIMER
|
||||||
//#define AMS_SDMMC_USE_UTIL_TIMER
|
//#define AMS_SDMMC_USE_UTIL_TIMER
|
||||||
#define AMS_SDMMC_ENABLE_MMC_HS400
|
#define AMS_SDMMC_ENABLE_MMC_HS400
|
||||||
|
#define AMS_SDMMC_ENABLE_SD_UHS_I
|
||||||
#define AMS_SDMMC_SET_PLLC4_BASE
|
#define AMS_SDMMC_SET_PLLC4_BASE
|
||||||
#define AMS_SDMMC_USE_SD_CARD_DETECTOR
|
#define AMS_SDMMC_USE_SD_CARD_DETECTOR
|
||||||
|
|
||||||
|
53
libraries/libvapours/include/vapours/sdmmc/sdmmc_sd_card.hpp
Normal file
53
libraries/libvapours/include/vapours/sdmmc/sdmmc_sd_card.hpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <vapours/sdmmc/sdmmc_build_config.hpp>
|
||||||
|
|
||||||
|
namespace ams::sdmmc {
|
||||||
|
|
||||||
|
enum SdCardSwitchFunction {
|
||||||
|
SdCardSwitchFunction_CheckSupportedFunction = 0,
|
||||||
|
SdCardSwitchFunction_CheckDefault = 1,
|
||||||
|
SdCardSwitchFunction_CheckHighSpeed = 2,
|
||||||
|
SdCardSwitchFunction_CheckSdr50 = 3,
|
||||||
|
SdCardSwitchFunction_CheckSdr104 = 4,
|
||||||
|
SdCardSwitchFunction_CheckDdr50 = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr inline size_t SdCardScrSize = 0x08;
|
||||||
|
constexpr inline size_t SdCardSwitchFunctionStatusSize = 0x40;
|
||||||
|
constexpr inline size_t SdCardSdStatusSize = 0x40;
|
||||||
|
|
||||||
|
constexpr inline size_t SdCardWorkBufferSize = SdCardSdStatusSize;
|
||||||
|
|
||||||
|
void SetSdCardWorkBuffer(Port port, void *buffer, size_t buffer_size);
|
||||||
|
void PutSdCardToSleep(Port port);
|
||||||
|
void AwakenSdCard(Port port);
|
||||||
|
Result GetSdCardProtectedAreaCapacity(u32 *out_num_sectors, Port port);
|
||||||
|
Result GetSdCardScr(void *dst, size_t dst_size, Port port);
|
||||||
|
Result GetSdCardSwitchFunctionStatus(void *dst, size_t dst_size, Port port, SdCardSwitchFunction switch_function);
|
||||||
|
Result GetSdCardCurrentConsumption(u16 *out_current_consumption, Port port, SpeedMode speed_mode);
|
||||||
|
Result GetSdCardSdStatus(void *dst, size_t dst_size, Port port);
|
||||||
|
|
||||||
|
Result CheckSdCardConnection(SpeedMode *out_speed_mode, BusWidth *out_bus_width, Port port);
|
||||||
|
|
||||||
|
bool IsSdCardInserted(Port port);
|
||||||
|
bool IsSdCardRemoved(Port port);
|
||||||
|
|
||||||
|
void RegisterSdCardDetectionEventCallback(Port port, DeviceDetectionEventCallback callback, void *arg);
|
||||||
|
void UnregisterSdCardDetectionEventCallback(Port port);
|
||||||
|
|
||||||
|
}
|
@ -15,6 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
|
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_MESOSPHERE)
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_EXOSPHERE)
|
||||||
|
#include <exosphere.hpp>
|
||||||
#else
|
#else
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
|
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_MESOSPHERE)
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_EXOSPHERE)
|
||||||
|
#include <exosphere.hpp>
|
||||||
#else
|
#else
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
@ -13,7 +13,15 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_MESOSPHERE)
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_EXOSPHERE)
|
||||||
|
#include <exosphere.hpp>
|
||||||
|
#else
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
|
#endif
|
||||||
#include "sdmmc_base_device_accessor.hpp"
|
#include "sdmmc_base_device_accessor.hpp"
|
||||||
|
|
||||||
namespace ams::sdmmc::impl {
|
namespace ams::sdmmc::impl {
|
||||||
|
@ -13,7 +13,15 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_MESOSPHERE)
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_EXOSPHERE)
|
||||||
|
#include <exosphere.hpp>
|
||||||
|
#else
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
|
#endif
|
||||||
#if defined(AMS_SDMMC_USE_SD_CARD_DETECTOR)
|
#if defined(AMS_SDMMC_USE_SD_CARD_DETECTOR)
|
||||||
#include "sdmmc_device_detector.hpp"
|
#include "sdmmc_device_detector.hpp"
|
||||||
|
|
||||||
|
@ -13,7 +13,15 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_MESOSPHERE)
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_EXOSPHERE)
|
||||||
|
#include <exosphere.hpp>
|
||||||
|
#else
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
|
#endif
|
||||||
#include "sdmmc_mmc_device_accessor.hpp"
|
#include "sdmmc_mmc_device_accessor.hpp"
|
||||||
#include "sdmmc_timer.hpp"
|
#include "sdmmc_timer.hpp"
|
||||||
|
|
||||||
@ -231,7 +239,7 @@ namespace ams::sdmmc::impl {
|
|||||||
/* Be prepared to wait up to 1.5 seconds to change state. */
|
/* Be prepared to wait up to 1.5 seconds to change state. */
|
||||||
ManualTimer timer(1500);
|
ManualTimer timer(1500);
|
||||||
while (true) {
|
while (true) {
|
||||||
/* Gte the ocr, and check if we're done. */
|
/* Get the ocr, and check if we're done. */
|
||||||
u32 ocr;
|
u32 ocr;
|
||||||
R_TRY(this->IssueCommandSendOpCond(std::addressof(ocr), bus_power));
|
R_TRY(this->IssueCommandSendOpCond(std::addressof(ocr), bus_power));
|
||||||
if ((ocr & OcrCardPowerUpStatus) != 0) {
|
if ((ocr & OcrCardPowerUpStatus) != 0) {
|
||||||
@ -467,7 +475,7 @@ namespace ams::sdmmc::impl {
|
|||||||
if (R_SUCCEEDED(result)) {
|
if (R_SUCCEEDED(result)) {
|
||||||
/* If we previously failed to start up the device, log the error correction. */
|
/* If we previously failed to start up the device, log the error correction. */
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
BaseDeviceAccessor::PushErrorLog(true, "S %d %d:0", this->max_bus_width, this->max_speed_mode, 0);
|
BaseDeviceAccessor::PushErrorLog(true, "S %d %d:0", this->max_bus_width, this->max_speed_mode);
|
||||||
BaseDeviceAccessor::IncrementNumActivationErrorCorrections();
|
BaseDeviceAccessor::IncrementNumActivationErrorCorrections();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,7 +594,7 @@ namespace ams::sdmmc::impl {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wake the device, it we need to.*/
|
/* Wake the host controller, if we need to.*/
|
||||||
if (this->mmc_device.IsActive()) {
|
if (this->mmc_device.IsActive()) {
|
||||||
const Result result = BaseDeviceAccessor::GetHostController()->Awaken();
|
const Result result = BaseDeviceAccessor::GetHostController()->Awaken();
|
||||||
if (R_FAILED(result)) {
|
if (R_FAILED(result)) {
|
||||||
@ -594,6 +602,7 @@ namespace ams::sdmmc::impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Wake the device. */
|
||||||
this->mmc_device.Awaken();
|
this->mmc_device.Awaken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,15 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_MESOSPHERE)
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_EXOSPHERE)
|
||||||
|
#include <exosphere.hpp>
|
||||||
|
#else
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
|
#endif
|
||||||
#include "sdmmc_port_mmc0.hpp"
|
#include "sdmmc_port_mmc0.hpp"
|
||||||
#include "sdmmc_select_sdmmc_controller.hpp"
|
#include "sdmmc_select_sdmmc_controller.hpp"
|
||||||
|
|
||||||
|
@ -13,7 +13,15 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_MESOSPHERE)
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_EXOSPHERE)
|
||||||
|
#include <exosphere.hpp>
|
||||||
|
#else
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
|
#endif
|
||||||
#include "sdmmc_port_mmc0.hpp"
|
#include "sdmmc_port_mmc0.hpp"
|
||||||
#include "sdmmc_select_sdmmc_controller.hpp"
|
#include "sdmmc_select_sdmmc_controller.hpp"
|
||||||
#include "sdmmc_base_device_accessor.hpp"
|
#include "sdmmc_base_device_accessor.hpp"
|
||||||
|
@ -13,8 +13,16 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_MESOSPHERE)
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_EXOSPHERE)
|
||||||
|
#include <exosphere.hpp>
|
||||||
|
#else
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
#include "sdmmc_port_mmc0.hpp"
|
#endif
|
||||||
|
#include "sdmmc_port_sd_card0.hpp"
|
||||||
#include "sdmmc_select_sdmmc_controller.hpp"
|
#include "sdmmc_select_sdmmc_controller.hpp"
|
||||||
|
|
||||||
|
|
||||||
@ -24,6 +32,19 @@ namespace ams::sdmmc::impl {
|
|||||||
|
|
||||||
SdmmcControllerForPortSdCard0 g_sd_card0_host_controller;
|
SdmmcControllerForPortSdCard0 g_sd_card0_host_controller;
|
||||||
|
|
||||||
|
#if defined(AMS_SDMMC_USE_SD_CARD_DETECTOR)
|
||||||
|
|
||||||
|
constexpr inline u32 SdCard0DebounceMilliSeconds = 128;
|
||||||
|
DeviceDetector g_sd_card0_detector(gpio::DeviceCode_SdCd, gpio::GpioValue_Low, SdCard0DebounceMilliSeconds);
|
||||||
|
|
||||||
|
SdCardDeviceAccessor g_sd_card0_device_accessor(std::addressof(g_sd_card0_host_controller), std::addressof(g_sd_card0_detector));
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
SdCardDeviceAccessor g_sd_card0_device_accessor(std::addressof(g_sd_card0_host_controller));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,4 +52,12 @@ namespace ams::sdmmc::impl {
|
|||||||
return std::addressof(g_sd_card0_host_controller);
|
return std::addressof(g_sd_card0_host_controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IDeviceAccessor *GetDeviceAccessorOfPortSdCard0() {
|
||||||
|
return std::addressof(g_sd_card0_device_accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
SdCardDeviceAccessor *GetSdCardDeviceAccessorOfPortSdCard0() {
|
||||||
|
return std::addressof(g_sd_card0_device_accessor);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -17,9 +17,206 @@
|
|||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
#include "sdmmc_base_device_accessor.hpp"
|
#include "sdmmc_base_device_accessor.hpp"
|
||||||
|
|
||||||
|
#if defined(AMS_SDMMC_USE_SD_CARD_DETECTOR)
|
||||||
|
#include "sdmmc_device_detector.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ams::sdmmc::impl {
|
namespace ams::sdmmc::impl {
|
||||||
|
|
||||||
/* TODO */
|
class SdCardDevice : public BaseDevice {
|
||||||
struct SdCardDeviceAccessor;
|
private:
|
||||||
|
#if defined(AMS_SDMMC_USE_SD_CARD_DETECTOR)
|
||||||
|
mutable os::EventType removed_event;
|
||||||
|
#endif
|
||||||
|
u16 rca;
|
||||||
|
bool is_valid_rca;
|
||||||
|
bool is_uhs_i_mode;
|
||||||
|
public:
|
||||||
|
SdCardDevice() : rca(0) {
|
||||||
|
this->OnDeactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Deactivate() override {
|
||||||
|
this->OnDeactivate();
|
||||||
|
BaseDevice::Deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(AMS_SDMMC_USE_SD_CARD_DETECTOR)
|
||||||
|
virtual os::EventType *GetRemovedEvent() const override {
|
||||||
|
return std::addressof(this->removed_event);
|
||||||
|
}
|
||||||
|
#elif defined(AMS_SDMMC_USE_OS_EVENTS)
|
||||||
|
virtual os::EventType *GetRemovedEvent() const override {
|
||||||
|
/* Mmc can't be removed. */
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
virtual DeviceType GetDeviceType() const override {
|
||||||
|
return DeviceType_SdCard;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual u16 GetRca() const override {
|
||||||
|
AMS_ABORT_UNLESS(this->is_valid_rca);
|
||||||
|
return this->rca;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDeactivate() {
|
||||||
|
this->is_valid_rca = false;
|
||||||
|
this->is_uhs_i_mode = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetRca(u16 v) {
|
||||||
|
this->rca = v;
|
||||||
|
this->is_valid_rca = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetOcrAndHighCapacity(u32 ocr);
|
||||||
|
|
||||||
|
void SetUhsIMode(bool en) {
|
||||||
|
this->is_uhs_i_mode = en;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsUhsIMode() const {
|
||||||
|
return this->is_uhs_i_mode;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SdCardApplicationCommandIndex : std::underlying_type<CommandIndex>::type {
|
||||||
|
SdApplicationCommandIndex_SetBusWidth = 6,
|
||||||
|
|
||||||
|
SdApplicationCommandIndex_SdStatus = 13,
|
||||||
|
|
||||||
|
SdApplicationCommandIndex_SendNumWriteBlocks = 22,
|
||||||
|
SdApplicationCommandIndex_SetWriteBlockEraseCount = 23,
|
||||||
|
|
||||||
|
SdApplicationCommandIndex_SdSendOpCond = 41,
|
||||||
|
SdApplicationCommandIndex_SetClearCardDetect = 42,
|
||||||
|
|
||||||
|
SdApplicationCommandIndex_SendScr = 51,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SwitchFunctionAccessMode {
|
||||||
|
SwitchFunctionAccessMode_Default = 0,
|
||||||
|
SwitchFunctionAccessMode_HighSpeed = 1,
|
||||||
|
SwitchFunctionAccessMode_Sdr50 = 2,
|
||||||
|
SwitchFunctionAccessMode_Sdr104 = 3,
|
||||||
|
SwitchFunctionAccessMode_Ddr50 = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
class SdCardDeviceAccessor : public BaseDeviceAccessor {
|
||||||
|
private:
|
||||||
|
SdCardDevice sd_card_device;
|
||||||
|
void *work_buffer;
|
||||||
|
size_t work_buffer_size;
|
||||||
|
#if defined(AMS_SDMMC_USE_SD_CARD_DETECTOR)
|
||||||
|
DeviceDetector *sd_card_detector;
|
||||||
|
#endif
|
||||||
|
BusWidth max_bus_width;
|
||||||
|
SpeedMode max_speed_mode;
|
||||||
|
bool is_initialized;
|
||||||
|
private:
|
||||||
|
#if defined(AMS_SDMMC_USE_SD_CARD_DETECTOR)
|
||||||
|
void RemovedCallback();
|
||||||
|
|
||||||
|
static void RemovedCallbackEntry(void *arg) {
|
||||||
|
static_cast<SdCardDeviceAccessor *>(arg)->RemovedCallback();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Result IssueCommandSendRelativeAddr(u16 *out_rca) const;
|
||||||
|
Result IssueCommandSendIfCond() const;
|
||||||
|
Result IssueCommandCheckSupportedFunction(void *dst, size_t dst_size) const;
|
||||||
|
Result IssueCommandSwitchAccessMode(void *dst, size_t dst_size, bool set_function, SwitchFunctionAccessMode access_mode) const;
|
||||||
|
Result IssueCommandVoltageSwitch() const;
|
||||||
|
Result IssueCommandAppCmd(DeviceState expected_state, u32 ignore_mask = 0) const;
|
||||||
|
Result IssueCommandSetBusWidth4Bit() const;
|
||||||
|
Result IssueCommandSdStatus(void *dst, size_t dst_size) const;
|
||||||
|
Result IssueCommandSendOpCond(u32 *out_ocr, bool spec_under_2, bool uhs_i_supported) const;
|
||||||
|
Result IssueCommandClearCardDetect() const;
|
||||||
|
Result IssueCommandSendScr(void *dst, size_t dst_size) const;
|
||||||
|
|
||||||
|
Result EnterUhsIMode();
|
||||||
|
Result ChangeToReadyState(bool spec_under_2, bool uhs_i_supported);
|
||||||
|
Result ChangeToStbyStateAndGetRca();
|
||||||
|
Result SetMemoryCapacity(const void *csd);
|
||||||
|
Result GetScr(void *dst, size_t dst_size) const;
|
||||||
|
Result ExtendBusWidth(BusWidth max_bw, u8 sd_bw);
|
||||||
|
Result SwitchAccessMode(SwitchFunctionAccessMode access_mode, void *wb, size_t wb_size);
|
||||||
|
Result ExtendBusSpeedAtUhsIMode(SpeedMode max_sm, void *wb, size_t wb_size);
|
||||||
|
Result ExtendBusSpeedAtNonUhsIMode(SpeedMode max_sm, bool spec_under_1_1, void *wb, size_t wb_size);
|
||||||
|
Result GetSdStatus(void *dst, size_t dst_size) const;
|
||||||
|
Result StartupSdCardDevice(BusWidth max_bw, SpeedMode max_sm, void *wb, size_t wb_size);
|
||||||
|
|
||||||
|
void TryDisconnectDat3PullUpResistor() const;
|
||||||
|
protected:
|
||||||
|
virtual Result OnActivate() override;
|
||||||
|
virtual Result OnReadWrite(u32 sector_index, u32 num_sectors, void *buf, size_t buf_size, bool is_read) override;
|
||||||
|
virtual Result ReStartup() override;
|
||||||
|
public:
|
||||||
|
virtual void Initialize() override;
|
||||||
|
virtual void Finalize() override;
|
||||||
|
virtual Result Activate() override;
|
||||||
|
virtual Result GetSpeedMode(SpeedMode *out_speed_mode) const override;
|
||||||
|
public:
|
||||||
|
#if defined(AMS_SDMMC_USE_SD_CARD_DETECTOR)
|
||||||
|
explicit SdCardDeviceAccessor(IHostController *hc, DeviceDetector *dd) : BaseDeviceAccessor(hc), sd_card_detector(dd)
|
||||||
|
#else
|
||||||
|
explicit SdCardDeviceAccessor(IHostController *hc) : BaseDeviceAccessor(hc)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
this->work_buffer = nullptr;
|
||||||
|
this->work_buffer_size = 0;
|
||||||
|
this->max_bus_width = BusWidth_4Bit;
|
||||||
|
this->max_speed_mode = SpeedMode_SdCardSdr104;
|
||||||
|
this->is_initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSdCardWorkBuffer(void *wb, size_t wb_size) {
|
||||||
|
this->work_buffer = wb;
|
||||||
|
this->work_buffer_size = wb_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PutSdCardToSleep();
|
||||||
|
void AwakenSdCard();
|
||||||
|
Result GetSdCardProtectedAreaCapacity(u32 *out_num_sectors) const;
|
||||||
|
Result GetSdCardScr(void *dst, size_t dst_size) const;
|
||||||
|
Result GetSdCardSwitchFunctionStatus(void *dst, size_t dst_size, SdCardSwitchFunction switch_function) const;
|
||||||
|
Result GetSdCardCurrentConsumption(u16 *out_current_consumption, SpeedMode speed_mode) const;
|
||||||
|
Result GetSdCardSdStatus(void *dst, size_t dst_size) const;
|
||||||
|
|
||||||
|
bool IsSdCardInserted() {
|
||||||
|
#if defined(AMS_SDMMC_USE_SD_CARD_DETECTOR)
|
||||||
|
return this->sd_card_detector->IsInserted();
|
||||||
|
#else
|
||||||
|
AMS_ABORT("IsSdCardInserted without SdCardDetector");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsSdCardRemoved() {
|
||||||
|
#if defined(AMS_SDMMC_USE_SD_CARD_DETECTOR)
|
||||||
|
return this->sd_card_device.IsRemoved();
|
||||||
|
#else
|
||||||
|
AMS_ABORT("IsSdCardRemoved without SdCardDetector");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterSdCardDetectionEventCallback(DeviceDetectionEventCallback cb, void *arg) {
|
||||||
|
#if defined(AMS_SDMMC_USE_SD_CARD_DETECTOR)
|
||||||
|
return this->sd_card_detector->RegisterDetectionEventCallback(cb, arg);
|
||||||
|
#else
|
||||||
|
AMS_UNUSED(cb, arg);
|
||||||
|
AMS_ABORT("RegisterSdCardDetectionEventCallback without SdCardDetector");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnregisterSdCardDetectionEventCallback() {
|
||||||
|
#if defined(AMS_SDMMC_USE_SD_CARD_DETECTOR)
|
||||||
|
return this->sd_card_detector->UnregisterDetectionEventCallback();
|
||||||
|
#else
|
||||||
|
AMS_ABORT("UnregisterSdCardDetectionEventCallback without SdCardDetector");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,15 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_MESOSPHERE)
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_EXOSPHERE)
|
||||||
|
#include <exosphere.hpp>
|
||||||
|
#else
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
|
#endif
|
||||||
#include "sdmmc_sd_host_standard_controller.hpp"
|
#include "sdmmc_sd_host_standard_controller.hpp"
|
||||||
#include "sdmmc_timer.hpp"
|
#include "sdmmc_timer.hpp"
|
||||||
|
|
||||||
@ -392,9 +400,9 @@ namespace ams::sdmmc::impl {
|
|||||||
|
|
||||||
Result SdHostStandardController::CheckAndClearInterruptStatus(volatile u16 *out_normal_int_status, u16 wait_mask) {
|
Result SdHostStandardController::CheckAndClearInterruptStatus(volatile u16 *out_normal_int_status, u16 wait_mask) {
|
||||||
/* Read the statuses. */
|
/* Read the statuses. */
|
||||||
volatile u16 normal_int_status = this->registers->normal_int_status;
|
volatile u16 normal_int_status = reg::Read(this->registers->normal_int_status);
|
||||||
volatile u16 error_int_status = this->registers->error_int_status;
|
volatile u16 error_int_status = reg::Read(this->registers->error_int_status);
|
||||||
volatile u16 auto_cmd_err_status = this->registers->acmd12_err;
|
volatile u16 auto_cmd_err_status = reg::Read(this->registers->acmd12_err);
|
||||||
|
|
||||||
/* Set the output status, if necessary. */
|
/* Set the output status, if necessary. */
|
||||||
if (out_normal_int_status != nullptr) {
|
if (out_normal_int_status != nullptr) {
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
|
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_MESOSPHERE)
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_EXOSPHERE)
|
||||||
|
#include <exosphere.hpp>
|
||||||
#else
|
#else
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
@ -13,7 +13,15 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_MESOSPHERE)
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_EXOSPHERE)
|
||||||
|
#include <exosphere.hpp>
|
||||||
|
#else
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
|
#endif
|
||||||
#include "impl/sdmmc_i_host_controller.hpp"
|
#include "impl/sdmmc_i_host_controller.hpp"
|
||||||
#include "impl/sdmmc_i_device_accessor.hpp"
|
#include "impl/sdmmc_i_device_accessor.hpp"
|
||||||
#include "impl/sdmmc_clock_reset_controller.hpp"
|
#include "impl/sdmmc_clock_reset_controller.hpp"
|
||||||
@ -30,7 +38,7 @@ namespace ams::sdmmc {
|
|||||||
impl::IHostController *host_controller = nullptr;
|
impl::IHostController *host_controller = nullptr;
|
||||||
switch (port) {
|
switch (port) {
|
||||||
case Port_Mmc0: host_controller = impl::GetHostControllerOfPortMmc0(); break;
|
case Port_Mmc0: host_controller = impl::GetHostControllerOfPortMmc0(); break;
|
||||||
//TODO: case Port_SdCard0: host_controller = impl::GetHostControllerOfPortSdCard0(); break;
|
case Port_SdCard0: host_controller = impl::GetHostControllerOfPortSdCard0(); break;
|
||||||
//TODO: case Port_GcAsic0: host_controller = impl::GetHostControllerOfPortGcAsic0(); break;
|
//TODO: case Port_GcAsic0: host_controller = impl::GetHostControllerOfPortGcAsic0(); break;
|
||||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||||
}
|
}
|
||||||
@ -45,7 +53,7 @@ namespace ams::sdmmc {
|
|||||||
impl::IDeviceAccessor *device_accessor = nullptr;
|
impl::IDeviceAccessor *device_accessor = nullptr;
|
||||||
switch (port) {
|
switch (port) {
|
||||||
case Port_Mmc0: device_accessor = impl::GetDeviceAccessorOfPortMmc0(); break;
|
case Port_Mmc0: device_accessor = impl::GetDeviceAccessorOfPortMmc0(); break;
|
||||||
//TODO: case Port_SdCard0: device_accessor = impl::GetDeviceAccessorOfPortSdCard0(); break;
|
case Port_SdCard0: device_accessor = impl::GetDeviceAccessorOfPortSdCard0(); break;
|
||||||
//TODO: case Port_GcAsic0: device_accessor = impl::GetDeviceAccessorOfPortGcAsic0(); break;
|
//TODO: case Port_GcAsic0: device_accessor = impl::GetDeviceAccessorOfPortGcAsic0(); break;
|
||||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,15 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_MESOSPHERE)
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_EXOSPHERE)
|
||||||
|
#include <exosphere.hpp>
|
||||||
|
#else
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
|
#endif
|
||||||
#include "impl/sdmmc_mmc_device_accessor.hpp"
|
#include "impl/sdmmc_mmc_device_accessor.hpp"
|
||||||
#include "impl/sdmmc_port_mmc0.hpp"
|
#include "impl/sdmmc_port_mmc0.hpp"
|
||||||
#include "impl/sdmmc_port_sd_card0.hpp"
|
#include "impl/sdmmc_port_sd_card0.hpp"
|
||||||
|
103
libraries/libvapours/source/sdmmc/sdmmc_sd_card.cpp
Normal file
103
libraries/libvapours/source/sdmmc/sdmmc_sd_card.cpp
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_MESOSPHERE)
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
#elif defined(ATMOSPHERE_IS_EXOSPHERE)
|
||||||
|
#include <exosphere.hpp>
|
||||||
|
#else
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#endif
|
||||||
|
#include "impl/sdmmc_sd_card_device_accessor.hpp"
|
||||||
|
#include "impl/sdmmc_port_mmc0.hpp"
|
||||||
|
#include "impl/sdmmc_port_sd_card0.hpp"
|
||||||
|
#include "impl/sdmmc_port_gc_asic0.hpp"
|
||||||
|
|
||||||
|
namespace ams::sdmmc {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
impl::SdCardDeviceAccessor *GetSdCardDeviceAccessor(Port port) {
|
||||||
|
/* Get the accessor. */
|
||||||
|
impl::SdCardDeviceAccessor *sd_card_device_accessor = nullptr;
|
||||||
|
switch (port) {
|
||||||
|
case Port_SdCard0: sd_card_device_accessor = impl::GetSdCardDeviceAccessorOfPortSdCard0(); break;
|
||||||
|
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure it's valid */
|
||||||
|
AMS_ABORT_UNLESS(sd_card_device_accessor != nullptr);
|
||||||
|
return sd_card_device_accessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSdCardWorkBuffer(Port port, void *buffer, size_t buffer_size) {
|
||||||
|
return GetSdCardDeviceAccessor(port)->SetSdCardWorkBuffer(buffer, buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PutSdCardToSleep(Port port) {
|
||||||
|
return GetSdCardDeviceAccessor(port)->PutSdCardToSleep();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AwakenSdCard(Port port) {
|
||||||
|
return GetSdCardDeviceAccessor(port)->AwakenSdCard();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result GetSdCardProtectedAreaCapacity(u32 *out_num_sectors, Port port) {
|
||||||
|
return GetSdCardDeviceAccessor(port)->GetSdCardProtectedAreaCapacity(out_num_sectors);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result GetSdCardScr(void *dst, size_t dst_size, Port port) {
|
||||||
|
return GetSdCardDeviceAccessor(port)->GetSdCardScr(dst, dst_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result GetSdCardSwitchFunctionStatus(void *dst, size_t dst_size, Port port, SdCardSwitchFunction switch_function) {
|
||||||
|
return GetSdCardDeviceAccessor(port)->GetSdCardSwitchFunctionStatus(dst, dst_size, switch_function);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result GetSdCardCurrentConsumption(u16 *out_current_consumption, Port port, SpeedMode speed_mode) {
|
||||||
|
return GetSdCardDeviceAccessor(port)->GetSdCardCurrentConsumption(out_current_consumption, speed_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result GetSdCardSdStatus(void *dst, size_t dst_size, Port port) {
|
||||||
|
return GetSdCardDeviceAccessor(port)->GetSdCardSdStatus(dst, dst_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result CheckSdCardConnection(SpeedMode *out_speed_mode, BusWidth *out_bus_width, Port port) {
|
||||||
|
return GetSdCardDeviceAccessor(port)->CheckConnection(out_speed_mode, out_bus_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsSdCardInserted(Port port) {
|
||||||
|
return GetSdCardDeviceAccessor(port)->IsSdCardInserted();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsSdCardRemoved(Port port) {
|
||||||
|
return GetSdCardDeviceAccessor(port)->IsSdCardRemoved();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RegisterSdCardDetectionEventCallback(Port port, DeviceDetectionEventCallback callback, void *arg) {
|
||||||
|
return GetSdCardDeviceAccessor(port)->RegisterSdCardDetectionEventCallback(callback, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnregisterSdCardDetectionEventCallback(Port port) {
|
||||||
|
return GetSdCardDeviceAccessor(port)->UnregisterSdCardDetectionEventCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user