Compare commits

...

35 Commits

Author SHA1 Message Date
Michael Scire
e6bddf8782 i2c: correct missing destruction 2020-11-14 03:37:17 -08:00
Michael Scire
d8bd3d16bb ams.mitm: provide different boot0-protection for custom public key 2020-11-10 23:25:24 -08:00
Michael Scire
80f567d46a wec: whoops 2020-11-10 18:32:21 -08:00
Michael Scire
b6580b3170 updater: don't overwrite custom-public-key BCTs 2020-11-10 16:53:19 -08:00
Michael Scire
df8ceb9b06 pinmux: whoops 2020-11-10 16:30:36 -08:00
Michael Scire
c5656d39d2 boot/powctl/i2c: more miscellaneous fixes 2020-11-10 05:50:13 -08:00
Michael Scire
62ff502979 boot: various bugfixes (b/w logo displays now) 2020-11-10 05:02:41 -08:00
Michael Scire
f135ee74f8 powctl: implement max17050 driver 2020-11-10 02:23:05 -08:00
Michael Scire
8c3e536e94 powctl: add battery driver logic (missing impl) 2020-11-10 01:27:35 -08:00
Michael Scire
35573c4d85 powctl: implement max17050 custom parameter init 2020-11-09 23:14:31 -08:00
Michael Scire
e6ef753bb6 powctl: implement full bq24193 driver 2020-11-09 21:50:41 -08:00
Michael Scire
eade15b34e i2c: add register acccessor helpers 2020-11-09 17:34:47 -08:00
Michael Scire
b9c5dab18a powctl: add ChargerDriver body (needs impl) 2020-11-09 17:09:25 -08:00
Michael Scire
d0a45b8f21 pinmux: implement updated initial config api 2020-11-09 02:01:29 -08:00
Michael Scire
e0ce035323 boot: update/refactor display management to support hw type 5/display 0x1040/0x2050 2020-11-08 17:56:49 -08:00
Michael Scire
2562700f34 dd: implement DeviceAddressSpaceType api 2020-11-08 15:27:55 -08:00
Michael Scire
e93c3cbf58 boot: refactor battery checking to use new powctl apis 2020-11-08 04:16:50 -08:00
Michael Scire
cd7d7894f1 powctl: implement client api (needs board-specific impl) 2020-11-02 18:13:36 -08:00
Michael Scire
aa63b1eab7 pwm: implement driver for boot sysmodule 2020-11-01 23:04:19 -08:00
Michael Scire
4cc4f5fdb0 gpio: add missing driver functions for boot 2020-11-01 23:04:01 -08:00
Michael Scire
22ae1d5bd3 i2c: implement remaining required driver logic 2020-11-01 00:52:02 -07:00
Michael Scire
43f7b10c0f i2c: command list format, get boot down to linker errors 2020-10-31 22:52:43 -07:00
Michael Scire
48784da42a i2c/gpio: hook up open session for sf interface 2020-10-31 21:50:21 -07:00
Michael Scire
f27d6f2fd8 i2c: implement driver init api 2020-10-31 20:14:41 -07:00
Michael Scire
6f7502dfef i2c: finish I2cBusAccessor 2020-10-31 19:14:43 -07:00
Michael Scire
2d2b11a2d2 i2c: implement BusAccessor::WriteHeader 2020-10-31 18:24:26 -07:00
Michael Scire
2744a614de i2c: implement BusAccessor except Send/Receive/WriteHeader 2020-10-31 17:58:38 -07:00
Michael Scire
27be1a548c boot: add rgltr/clkrst overrides, skel I2cBusAccessor 2020-10-31 16:34:06 -07:00
Michael Scire
91b2a233c4 i2c: add auto-generated bus/device map 2020-10-31 14:20:01 -07:00
Michael Scire
7636dd2d44 i2c: begin skeleton device driver framework 2020-10-31 04:55:11 -07:00
Michael Scire
c867975eb8 gpio: remove copy-pasted unused file 2020-10-31 03:23:30 -07:00
Michael Scire
5bc4abb92f gpio: implement more of server library for boot sysmodule client usage 2020-10-31 03:22:01 -07:00
Michael Scire
e1dccef7d1 wec: implement wec driver components for boot sysmodule 2020-10-31 00:47:45 -07:00
Michael Scire
17fa05a789 gpio: add (most of) driver framework for boot sysmodule usage 2020-10-30 23:57:21 -07:00
Michael Scire
5b617f4d2f ddsf: implement namespace 2020-10-30 15:36:11 -07:00
344 changed files with 23032 additions and 7410 deletions

View File

@@ -14,7 +14,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <exosphere.hpp>
#include "i2c_registers.hpp"
namespace ams::i2c {

View File

@@ -1,77 +0,0 @@
/*
* 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/>.
*/
#include <exosphere.hpp>
namespace ams::i2c {
#define I2C_I2C_CNFG (0x000)
#define I2C_I2C_CMD_ADDR0 (0x004)
#define I2C_I2C_CMD_DATA1 (0x00C)
#define I2C_I2C_STATUS (0x01C)
#define I2C_INTERRUPT_STATUS_REGISTER (0x068)
#define I2C_CLK_DIVISOR_REGISTER (0x06C)
#define I2C_BUS_CLEAR_CONFIG (0x084)
#define I2C_BUS_CLEAR_STATUS (0x088)
#define I2C_CONFIG_LOAD (0x08C)
#define I2C_REG_BITS_MASK(NAME) REG_NAMED_BITS_MASK (I2C, NAME)
#define I2C_REG_BITS_VALUE(NAME, VALUE) REG_NAMED_BITS_VALUE (I2C, NAME, VALUE)
#define I2C_REG_BITS_ENUM(NAME, ENUM) REG_NAMED_BITS_ENUM (I2C, NAME, ENUM)
#define I2C_REG_BITS_ENUM_SEL(NAME, __COND__, TRUE_ENUM, FALSE_ENUM) REG_NAMED_BITS_ENUM_SEL(I2C, NAME, __COND__, TRUE_ENUM, FALSE_ENUM)
#define DEFINE_I2C_REG(NAME, __OFFSET__, __WIDTH__) REG_DEFINE_NAMED_REG (I2C, NAME, __OFFSET__, __WIDTH__)
#define DEFINE_I2C_REG_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE) REG_DEFINE_NAMED_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE)
#define DEFINE_I2C_REG_TWO_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE) REG_DEFINE_NAMED_TWO_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE)
#define DEFINE_I2C_REG_THREE_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN) REG_DEFINE_NAMED_THREE_BIT_ENUM(I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN)
#define DEFINE_I2C_REG_FOUR_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN) REG_DEFINE_NAMED_FOUR_BIT_ENUM (I2C, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN)
/* I2C_CNFG */
DEFINE_I2C_REG(I2C_CNFG_LENGTH, 1, 3);
DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_CMD1, 6, WRITE, READ);
DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_SEND, 9, NOP, GO);
DEFINE_I2C_REG_BIT_ENUM(I2C_CNFG_NEW_MASTER_FSM, 11, DISABLE, ENABLE);
DEFINE_I2C_REG_THREE_BIT_ENUM(I2C_CNFG_DEBOUNCE_CNT, 12, NO_DEBOUNCE, DEBOUNCE_2T, DEBOUNCE_4T, DEBOUNCE_6T, DEBOUNCE_8T, DEBOUNCE_10T, DEBOUNCE_12T, DEBOUNCE_14T);
/* I2C_CMD_ADDR0 */
DEFINE_I2C_REG_BIT_ENUM(I2C_CMD_ADDR0_7BIT_RW, 0, WRITE, READ);
DEFINE_I2C_REG(I2C_CMD_ADDR0_7BIT_ADDR, 1, 7);
/* I2C_STATUS */
DEFINE_I2C_REG_FOUR_BIT_ENUM(I2C_STATUS_CMD1_STAT, 0, SL1_XFER_SUCCESSFUL, SL1_NOACK_FOR_BYTE1, SL1_NOACK_FOR_BYTE2, SL1_NOACK_FOR_BYTE3, SL1_NOACK_FOR_BYTE4, SL1_NOACK_FOR_BYTE5, SL1_NOACK_FOR_BYTE6, SL1_NOACK_FOR_BYTE7, SL1_NOACK_FOR_BYTE8, SL1_NOACK_FOR_BYTE9, SL1_NOACK_FOR_BYTE10, RESERVED11, RESERVED12, RESERVED13, RESERVED14, RESERVED15);
DEFINE_I2C_REG_FOUR_BIT_ENUM(I2C_STATUS_CMD2_STAT, 4, SL2_XFER_SUCCESSFUL, SL2_NOACK_FOR_BYTE1, SL2_NOACK_FOR_BYTE2, SL2_NOACK_FOR_BYTE3, SL2_NOACK_FOR_BYTE4, SL2_NOACK_FOR_BYTE5, SL2_NOACK_FOR_BYTE6, SL2_NOACK_FOR_BYTE7, SL2_NOACK_FOR_BYTE8, SL2_NOACK_FOR_BYTE9, SL2_NOACK_FOR_BYTE10, RESERVED11, RESERVED12, RESERVED13, RESERVED14, RESERVED15);
DEFINE_I2C_REG_BIT_ENUM(I2C_STATUS_BUSY, 8, NOT_BUSY, BUSY);
/* INTERRUPT_STATUS_REGISTER */
DEFINE_I2C_REG_BIT_ENUM(INTERRUPT_STATUS_REGISTER_BUS_CLEAR_DONE, 11, UNSET, SET);
/* CLK_DIVISOR_REGISTER */
DEFINE_I2C_REG(CLK_DIVISOR_REGISTER_HSMODE, 0, 16);
DEFINE_I2C_REG(CLK_DIVISOR_REGISTER_STD_FAST_MODE, 16, 16);
/* BUS_CLEAR_CONFIG */
DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_ENABLE, 0, DISABLE, ENABLE);
DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_TERMINATE, 1, THRESHOLD, IMMEDIATE);
DEFINE_I2C_REG_BIT_ENUM(BUS_CLEAR_CONFIG_BC_STOP_COND, 2, NO_STOP, STOP);
DEFINE_I2C_REG(BUS_CLEAR_CONFIG_BC_SCLK_THRESHOLD, 16, 8);
/* CONFIG_LOAD */
DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_MSTR_CONFIG_LOAD, 0, DISABLE, ENABLE);
DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_SLV_CONFIG_LOAD, 1, DISABLE, ENABLE);
DEFINE_I2C_REG_BIT_ENUM(CONFIG_LOAD_TIMEOUT_CONFIG_LOAD, 2, DISABLE, ENABLE);
DEFINE_I2C_REG(CONFIG_LOAD_RESERVED_BIT_5, 5, 1);
}

View File

@@ -41,8 +41,11 @@
/* At this point, just include the rest alphabetically. */
/* TODO: Figure out optimal order. */
#include <stratosphere/boot2.hpp>
#include <stratosphere/cal.hpp>
#include <stratosphere/capsrv.hpp>
#include <stratosphere/cfg.hpp>
#include <stratosphere/clkrst.hpp>
#include <stratosphere/ddsf.hpp>
#include <stratosphere/dmnt.hpp>
#include <stratosphere/erpt.hpp>
#include <stratosphere/err.hpp>
@@ -50,6 +53,7 @@
#include <stratosphere/gpio.hpp>
#include <stratosphere/hid.hpp>
#include <stratosphere/hos.hpp>
#include <stratosphere/i2c.hpp>
#include <stratosphere/kvdb.hpp>
#include <stratosphere/ldr.hpp>
#include <stratosphere/lr.hpp>
@@ -58,9 +62,14 @@
#include <stratosphere/nim.hpp>
#include <stratosphere/ns.hpp>
#include <stratosphere/patcher.hpp>
#include <stratosphere/pcv.hpp>
#include <stratosphere/pgl.hpp>
#include <stratosphere/pinmux.hpp>
#include <stratosphere/powctl.hpp>
#include <stratosphere/psc.hpp>
#include <stratosphere/pm.hpp>
#include <stratosphere/pwm.hpp>
#include <stratosphere/regulator.hpp>
#include <stratosphere/ro.hpp>
#include <stratosphere/settings.hpp>
#include <stratosphere/sf.hpp>
@@ -68,6 +77,7 @@
#include <stratosphere/spl.hpp>
#include <stratosphere/time.hpp>
#include <stratosphere/updater.hpp>
#include <stratosphere/wec.hpp>
/* Include FS last. */
#include <stratosphere/fs.hpp>

View File

@@ -89,9 +89,15 @@ namespace ams::impl {
/* ro. */
AMS_DEFINE_SYSTEM_THREAD(16, ro, Main);
/* gpio. */
AMS_DEFINE_SYSTEM_THREAD(-12, gpio, InterruptHandler);
/* bpc. */
AMS_DEFINE_SYSTEM_THREAD(4, bpc, IpcServer);
/* powctl. */
AMS_DEFINE_SYSTEM_THREAD(9, powctl, InterruptHandler);
/* hid. */
AMS_DEFINE_SYSTEM_THREAD(-10, hid, IpcServer);

View File

@@ -0,0 +1,19 @@
/*
* 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 <stratosphere/cal/cal_battery_api.hpp>

View File

@@ -0,0 +1,24 @@
/*
* 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.hpp>
namespace ams::cal {
Result GetBatteryVersion(u8 *out);
Result GetBatteryVendor(size_t *out_vendor_size, void *dst, size_t dst_size);
}

View File

@@ -0,0 +1,21 @@
/*
* 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 <stratosphere/clkrst/clkrst_types.hpp>
#include <stratosphere/clkrst/clkrst_api.hpp>
#include <stratosphere/clkrst/clkrst_session_api.hpp>

View File

@@ -0,0 +1,25 @@
/*
* 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.hpp>
#include <stratosphere/clkrst/clkrst_types.hpp>
namespace ams::clkrst {
void Initialize();
void Finalize();
}

View File

@@ -0,0 +1,36 @@
/*
* 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.hpp>
#include <stratosphere/clkrst/clkrst_types.hpp>
namespace ams::clkrst {
struct ClkRstSession {
void *_session;
};
Result OpenSession(ClkRstSession *out, DeviceCode device_code);
void CloseSession(ClkRstSession *session);
void SetResetAsserted(ClkRstSession *session);
void SetResetDeasserted(ClkRstSession *session);
void SetClockRate(ClkRstSession *session, u32 hz);
void SetClockDisabled(ClkRstSession *session);
}

View File

@@ -0,0 +1,23 @@
/*
* 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.hpp>
namespace ams::clkrst {
/* ... */
}

View File

@@ -16,5 +16,7 @@
#pragma once
#include "dd/dd_io_mappings.hpp"
#include "dd/dd_process_handle.hpp"
#include <stratosphere/dd/dd_types.hpp>
#include <stratosphere/dd/dd_device_address_space.hpp>
#include <stratosphere/dd/dd_io_mappings.hpp>
#include <stratosphere/dd/dd_process_handle.hpp>

View File

@@ -0,0 +1,21 @@
/*
* 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.hpp>
#include <stratosphere/dd/dd_device_address_space_common.hpp>
#include <stratosphere/dd/dd_device_address_space_types.hpp>
#include <stratosphere/dd/dd_device_address_space_api.hpp>

View File

@@ -0,0 +1,48 @@
/*
* 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.hpp>
#include <stratosphere/dd/dd_types.hpp>
#include <stratosphere/dd/dd_device_address_space_common.hpp>
#include <stratosphere/dd/dd_device_address_space_types.hpp>
namespace ams::dd {
Result CreateDeviceAddressSpace(DeviceAddressSpaceType *das, u64 address, u64 size);
Result CreateDeviceAddressSpace(DeviceAddressSpaceType *das, u64 size);
void DestroyDeviceAddressSpace(DeviceAddressSpaceType *das);
void AttachDeviceAddressSpaceHandle(DeviceAddressSpaceType *das, Handle handle, bool managed);
Handle GetDeviceAddressSpaceHandle(DeviceAddressSpaceType *das);
Result MapDeviceAddressSpaceAligned(DeviceAddressSpaceType *das, ProcessHandle process_handle, u64 process_address, size_t size, DeviceVirtualAddress device_address, MemoryPermission device_perm);
Result MapDeviceAddressSpaceNotAligned(DeviceAddressSpaceType *das, ProcessHandle process_handle, u64 process_address, size_t size, DeviceVirtualAddress device_address, MemoryPermission device_perm);
void UnmapDeviceAddressSpace(DeviceAddressSpaceType *das, ProcessHandle process_handle, u64 process_address, size_t size, DeviceVirtualAddress device_address);
void InitializeDeviceAddressSpaceMapInfo(DeviceAddressSpaceMapInfo *info, DeviceAddressSpaceType *das, ProcessHandle process_handle, u64 process_address, size_t size, DeviceVirtualAddress device_address, MemoryPermission device_perm);
Result MapNextDeviceAddressSpaceRegion(size_t *out_mapped_size, DeviceAddressSpaceMapInfo *info);
void UnmapDeviceAddressSpaceRegion(DeviceAddressSpaceMapInfo *info);
u64 GetMappedProcessAddress(DeviceAddressSpaceMapInfo *info);
DeviceVirtualAddress GetMappedDeviceVirtualAddress(DeviceAddressSpaceMapInfo *info);
size_t GetMappedSize(DeviceAddressSpaceMapInfo *info);
Result AttachDeviceAddressSpace(DeviceAddressSpaceType *das, DeviceName device_name);
void DetachDeviceAddressSpace(DeviceAddressSpaceType *das, DeviceName device_name);
}

View File

@@ -0,0 +1,26 @@
/*
* 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.hpp>
#include <stratosphere/dd/dd_types.hpp>
namespace ams::dd {
using DeviceName = ::ams::svc::DeviceName;
constexpr inline u64 DeviceAddressSpaceMemoryRegionAlignment = 4_KB;
}

View File

@@ -0,0 +1,49 @@
/*
* 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.hpp>
#include <stratosphere/dd/dd_types.hpp>
namespace ams::dd {
using DeviceVirtualAddress = u64;
using DeviceAddressSpaceHandle = ::Handle;
struct DeviceAddressSpaceType {
enum State {
State_NotInitialized = 0,
State_Initialized = 1,
};
DeviceAddressSpaceHandle device_handle;
u8 state;
bool is_handle_managed;
};
static_assert(std::is_trivial<DeviceAddressSpaceType>::value);
struct DeviceAddressSpaceMapInfo {
size_t last_mapped_size;
size_t size;
u64 process_address;
DeviceVirtualAddress device_start_address;
DeviceVirtualAddress device_end_address;
ProcessHandle process_handle;
MemoryPermission device_permission;
DeviceAddressSpaceType *device_address_space;
};
static_assert(std::is_trivial<DeviceAddressSpaceMapInfo>::value);
}

View File

@@ -19,10 +19,6 @@
namespace ams::dd {
u32 ReadRegister(dd::PhysicalAddress phys_addr);
void WriteRegister(dd::PhysicalAddress phys_addr, u32 value);
u32 ReadWriteRegister(dd::PhysicalAddress phys_addr, u32 value, u32 mask);
/* Convenience Helper. */
inline uintptr_t GetIoMapping(dd::PhysicalAddress phys_addr, size_t size) {
const uintptr_t io_mapping = dd::QueryIoMapping(phys_addr, size);

View File

@@ -13,12 +13,12 @@
* 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.hpp>
#include <stratosphere/dd/dd_types.hpp>
namespace ams::dd {
::Handle GetCurrentProcessHandle();
ProcessHandle GetCurrentProcessHandle();
}

View File

@@ -0,0 +1,33 @@
/*
* 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.hpp>
#include <stratosphere/dd/dd_types.hpp>
namespace ams::dd {
using ProcessHandle = ::Handle;
enum MemoryPermission {
MemoryPermission_None = 0,
MemoryPermission_ReadOnly = (1u << 0),
MemoryPermission_WriteOnly = (1u << 1),
MemoryPermission_ReadWrite = MemoryPermission_ReadOnly | MemoryPermission_WriteOnly,
};
}

View File

@@ -13,7 +13,15 @@
* 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 <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/ddsf/ddsf_i_castable.hpp>
#include <stratosphere/ddsf/ddsf_i_session.hpp>
#include <stratosphere/ddsf/ddsf_i_device.hpp>
#include <stratosphere/ddsf/ddsf_i_driver.hpp>
#include <stratosphere/ddsf/ddsf_device_code_entry.hpp>
#include <stratosphere/ddsf/ddsf_device_code_entry_manager.hpp>
#include <stratosphere/ddsf/ddsf_i_event_handler.hpp>
#include <stratosphere/ddsf/ddsf_event_handler_manager.hpp>
#include <stratosphere/ddsf/ddsf_memory_api.hpp>

View File

@@ -0,0 +1,110 @@
/*
* 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.hpp>
namespace ams::ddsf {
class IDevice;
class DeviceCodeEntry {
NON_COPYABLE(DeviceCodeEntry);
NON_MOVEABLE(DeviceCodeEntry);
private:
ams::DeviceCode device_code = ams::InvalidDeviceCode;
IDevice *device = nullptr;
public:
constexpr DeviceCodeEntry(ams::DeviceCode dc, IDevice *dev) : device_code(dc), device(dev) {
AMS_ASSERT(dev != nullptr);
}
constexpr ams::DeviceCode GetDeviceCode() const {
return this->device_code;
}
constexpr IDevice &GetDevice() {
return *this->device;
}
constexpr const IDevice &GetDevice() const {
return *this->device;
}
};
class DeviceCodeEntryHolder {
NON_COPYABLE(DeviceCodeEntryHolder);
NON_MOVEABLE(DeviceCodeEntryHolder);
private:
util::IntrusiveListNode list_node;
TYPED_STORAGE(DeviceCodeEntry) entry_storage;
bool is_constructed;
public:
using ListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&DeviceCodeEntryHolder::list_node>;
using List = typename ListTraits::ListType;
friend class util::IntrusiveList<DeviceCodeEntryHolder, util::IntrusiveListMemberTraitsDeferredAssert<&DeviceCodeEntryHolder::list_node>>;
public:
DeviceCodeEntryHolder() : list_node(), entry_storage(), is_constructed(false) {
/* ... */
}
~DeviceCodeEntryHolder() {
if (this->IsConstructed()) {
this->Destroy();
}
}
void AddTo(List &list) {
list.push_back(*this);
}
void RemoveFrom(List list) {
list.erase(list.iterator_to(*this));
}
bool IsLinkedToList() const {
return this->list_node.IsLinked();
}
DeviceCodeEntry &Construct(DeviceCode dc, IDevice *dev) {
AMS_ASSERT(!this->IsConstructed());
DeviceCodeEntry *entry = new (GetPointer(this->entry_storage)) DeviceCodeEntry(dc, dev);
this->is_constructed = true;
return *entry;
}
bool IsConstructed() const {
return this->is_constructed;
}
void Destroy() {
AMS_ASSERT(this->IsConstructed());
GetReference(this->entry_storage).~DeviceCodeEntry();
this->is_constructed = false;
}
DeviceCodeEntry &Get() {
AMS_ASSERT(this->IsConstructed());
return GetReference(this->entry_storage);
}
const DeviceCodeEntry &Get() const {
AMS_ASSERT(this->IsConstructed());
return GetReference(this->entry_storage);
}
};
static_assert(DeviceCodeEntryHolder::ListTraits::IsValid());
}

View File

@@ -0,0 +1,84 @@
/*
* 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.hpp>
#include <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/ddsf/impl/ddsf_for_each.hpp>
#include <stratosphere/ddsf/ddsf_device_code_entry.hpp>
namespace ams::ddsf {
class IDevice;
class DeviceCodeEntryManager {
private:
ams::MemoryResource *memory_resource;
ddsf::DeviceCodeEntryHolder::List entry_list;
mutable os::SdkMutex entry_list_lock;
private:
void DestroyAllEntries() {
auto it = this->entry_list.begin();
while (it != this->entry_list.end()) {
ddsf::DeviceCodeEntryHolder *entry = std::addressof(*it);
it = this->entry_list.erase(it);
AMS_ASSERT(entry->IsConstructed());
if (entry->IsConstructed()) {
entry->Destroy();
}
this->memory_resource->Deallocate(entry, sizeof(*entry));
}
}
public:
DeviceCodeEntryManager(ams::MemoryResource *mr) : memory_resource(mr), entry_list(), entry_list_lock() { /* ... */ }
~DeviceCodeEntryManager() {
this->DestroyAllEntries();
}
void Reset() {
std::scoped_lock lk(this->entry_list_lock);
this->DestroyAllEntries();
}
Result Add(DeviceCode device_code, IDevice *device);
bool Remove(DeviceCode device_code);
Result FindDeviceCodeEntry(DeviceCodeEntry **out, DeviceCode device_code);
Result FindDeviceCodeEntry(const DeviceCodeEntry **out, DeviceCode device_code) const;
Result FindDevice(IDevice **out, DeviceCode device_code);
Result FindDevice(const IDevice **out, DeviceCode device_code) const;
template<typename F>
int ForEachEntry(F f) {
return impl::ForEach(this->entry_list_lock, this->entry_list, [&](DeviceCodeEntryHolder &holder) -> bool {
AMS_ASSERT(holder.IsConstructed());
return f(holder.Get());
});
}
template<typename F>
int ForEachEntry(F f) const {
return impl::ForEach(this->entry_list_lock, this->entry_list, [&](const DeviceCodeEntryHolder &holder) -> bool {
AMS_ASSERT(holder.IsConstructed());
return f(holder.Get());
});
}
};
}

View File

@@ -0,0 +1,80 @@
/*
* 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.hpp>
#include <stratosphere/os.hpp>
#include <stratosphere/ddsf/ddsf_i_event_handler.hpp>
namespace ams::ddsf {
class EventHandlerManager;
class EventHandlerManager {
NON_COPYABLE(EventHandlerManager);
NON_MOVEABLE(EventHandlerManager);
private:
struct LoopControlCommandParameters;
private:
bool is_initialized;
bool is_looping;
os::SdkConditionVariable is_looping_cv;
os::WaitableManagerType waitable_manager;
os::ThreadType *loop_thread;
os::Event loop_control_event;
os::WaitableHolderType loop_control_event_holder;
LoopControlCommandParameters *loop_control_command_params;
os::Event loop_control_command_done_event; /* TODO: os::LightEvent, requires mesosphere for < 4.0.0 compat. */
os::SdkMutex loop_control_lock;
private:
void ProcessControlCommand(LoopControlCommandParameters *params);
void ProcessControlCommandImpl(LoopControlCommandParameters *params);
public:
EventHandlerManager()
: is_initialized(false), is_looping(false), is_looping_cv(), waitable_manager(),
loop_thread(), loop_control_event(os::EventClearMode_AutoClear), loop_control_event_holder(),
loop_control_command_params(), loop_control_command_done_event(os::EventClearMode_AutoClear),
loop_control_lock()
{
this->Initialize();
}
~EventHandlerManager() {
if (this->is_looping) {
AMS_ASSERT(!this->IsRunningOnLoopThread());
this->RequestStop();
}
if (this->is_initialized) {
this->Finalize();
}
}
bool IsRunningOnLoopThread() const { return this->loop_thread == os::GetCurrentThread(); }
bool IsLooping() const { return this->is_looping; }
void Initialize();
void Finalize();
void RegisterHandler(IEventHandler *handler);
void UnregisterHandler(IEventHandler *handler);
void WaitLoopEnter();
void WaitLoopExit();
void RequestStop();
void LoopAuto();
};
}

View File

@@ -0,0 +1,88 @@
/*
* 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.hpp>
#include <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/ddsf/impl/ddsf_type_tag.hpp>
namespace ams::ddsf {
#if defined(AMS_BUILD_FOR_DEBUGGING) || defined(AMS_BUILD_FOR_AUDITING)
#define AMS_DDSF_CASTABLE_TRAITS(__CLASS__, __BASE__) \
static_assert(std::convertible_to<__CLASS__ *, __BASE__ *>); \
public: \
static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag{#__CLASS__, __BASE__::s_ams_ddsf_castable_type_tag}; \
constexpr virtual const ::ams::ddsf::impl::TypeTag &GetTypeTag() const override { return s_ams_ddsf_castable_type_tag; }
#else
#define AMS_DDSF_CASTABLE_TRAITS(__CLASS__, __BASE__) \
static_assert(std::convertible_to<__CLASS__ *, __BASE__ *>); \
public: \
static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag{__BASE__::s_ams_ddsf_castable_type_tag}; \
constexpr virtual const ::ams::ddsf::impl::TypeTag &GetTypeTag() const override { return s_ams_ddsf_castable_type_tag; }
#endif
class ICastable {
private:
constexpr virtual const impl::TypeTag &GetTypeTag() const = 0;
template<typename T>
constexpr ALWAYS_INLINE void AssertCastableTo() const {
AMS_ASSERT(this->IsCastableTo<T>());
}
public:
template<typename T>
constexpr bool IsCastableTo() const {
return this->GetTypeTag().DerivesFrom(T::s_ams_ddsf_castable_type_tag);
}
template<typename T>
constexpr T &SafeCastTo() {
this->AssertCastableTo<T>();
return static_cast<T &>(*this);
}
template<typename T>
constexpr const T &SafeCastTo() const {
this->AssertCastableTo<T>();
return static_cast<const T &>(*this);
}
template<typename T>
constexpr T *SafeCastToPointer() {
this->AssertCastableTo<T>();
return static_cast<T *>(this);
}
template<typename T>
constexpr const T *SafeCastToPointer() const {
this->AssertCastableTo<T>();
return static_cast<const T *>(this);
}
#if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING)
constexpr const char *GetClassName() const {
return this->GetTypeTag().GetClassName();
}
#endif
};
}

View File

@@ -0,0 +1,140 @@
/*
* 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.hpp>
#include <stratosphere/os/os_sdk_mutex.hpp>
#include <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/ddsf/impl/ddsf_for_each.hpp>
#include <stratosphere/ddsf/ddsf_i_castable.hpp>
#include <stratosphere/ddsf/ddsf_i_session.hpp>
namespace ams::ddsf {
class IDriver;
class IDevice : public ICastable {
friend Result OpenSession(IDevice *device, ISession *session, AccessMode mode);
friend void CloseSession(ISession *session);
friend class IDriver;
public:
AMS_DDSF_CASTABLE_ROOT_TRAITS(ams::ddsf::IDevice);
private:
util::IntrusiveListNode list_node;
IDriver *driver;
ISession::List session_list;
mutable os::SdkMutex session_list_lock;
bool is_exclusive_write;
public:
using ListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&IDevice::list_node>;
using List = typename ListTraits::ListType;
friend class util::IntrusiveList<IDevice, util::IntrusiveListMemberTraitsDeferredAssert<&IDevice::list_node>>;
private:
Result AttachSession(ISession *session) {
AMS_ASSERT(session != nullptr);
std::scoped_lock lk(this->session_list_lock);
/* Check if we're allowed to attach the session. */
if (this->is_exclusive_write && session->CheckExclusiveWrite()) {
for (const auto &attached : this->session_list) {
R_UNLESS(!attached.CheckAccess(AccessMode_Write), ddsf::ResultAccessModeDenied());
}
}
/* Attach the session. */
this->session_list.push_back(*session);
return ResultSuccess();
}
void DetachSession(ISession *session) {
AMS_ASSERT(session != nullptr);
std::scoped_lock lk(this->session_list_lock);
this->session_list.erase(this->session_list.iterator_to(*session));
}
void AttachDriver(IDriver *drv) {
AMS_ASSERT(drv != nullptr);
AMS_ASSERT(!this->IsDriverAttached());
this->driver = drv;
AMS_ASSERT(this->IsDriverAttached());
}
void DetachDriver() {
AMS_ASSERT(this->IsDriverAttached());
this->driver = nullptr;
AMS_ASSERT(!this->IsDriverAttached());
}
public:
IDevice(bool exclusive_write) : list_node(), driver(nullptr), session_list(), session_list_lock(), is_exclusive_write(exclusive_write) {
this->session_list.clear();
}
protected:
~IDevice() {
this->session_list.clear();
}
public:
void AddTo(List &list) {
list.push_back(*this);
}
void RemoveFrom(List list) {
list.erase(list.iterator_to(*this));
}
bool IsLinkedToList() const {
return this->list_node.IsLinked();
}
IDriver &GetDriver() {
AMS_ASSERT(this->IsDriverAttached());
return *this->driver;
}
const IDriver &GetDriver() const {
AMS_ASSERT(this->IsDriverAttached());
return *this->driver;
}
bool IsDriverAttached() const {
return this->driver != nullptr;
}
template<typename F>
Result ForEachSession(F f, bool return_on_fail) {
return impl::ForEach(this->session_list_lock, this->session_list, f, return_on_fail);
}
template<typename F>
Result ForEachSession(F f, bool return_on_fail) const {
return impl::ForEach(this->session_list_lock, this->session_list, f, return_on_fail);
}
template<typename F>
int ForEachSession(F f) {
return impl::ForEach(this->session_list_lock, this->session_list, f);
}
template<typename F>
int ForEachSession(F f) const {
return impl::ForEach(this->session_list_lock, this->session_list, f);
}
bool HasAnyOpenSession() const {
return !this->session_list.empty();
}
};
static_assert(IDevice::ListTraits::IsValid());
}

View File

@@ -0,0 +1,99 @@
/*
* 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.hpp>
#include <stratosphere/os/os_sdk_mutex.hpp>
#include <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/ddsf/impl/ddsf_for_each.hpp>
#include <stratosphere/ddsf/ddsf_i_castable.hpp>
#include <stratosphere/ddsf/ddsf_i_device.hpp>
namespace ams::ddsf {
class IDriver : public ICastable {
public:
AMS_DDSF_CASTABLE_ROOT_TRAITS(ams::ddsf::IDriver);
private:
util::IntrusiveListNode list_node;
IDevice::List device_list;
mutable os::SdkMutex device_list_lock;
public:
using ListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&IDriver::list_node>;
using List = typename ListTraits::ListType;
friend class util::IntrusiveList<IDriver, util::IntrusiveListMemberTraitsDeferredAssert<&IDriver::list_node>>;
private:
public:
IDriver() : list_node(), device_list(), device_list_lock() {
this->device_list.clear();
}
protected:
~IDriver() {
this->device_list.clear();
}
public:
void AddTo(List &list) {
list.push_back(*this);
}
void RemoveFrom(List list) {
list.erase(list.iterator_to(*this));
}
bool IsLinkedToList() const {
return this->list_node.IsLinked();
}
bool HasAnyDevice() const {
return !this->device_list.empty();
}
void RegisterDevice(IDevice *dev) {
AMS_ASSERT(dev != nullptr);
std::scoped_lock lk(this->device_list_lock);
dev->AttachDriver(this);
this->device_list.push_back(*dev);
}
void UnregisterDevice(IDevice *dev) {
AMS_ASSERT(dev != nullptr);
std::scoped_lock lk(this->device_list_lock);
this->device_list.erase(this->device_list.iterator_to(*dev));
dev->DetachDriver();
}
template<typename F>
Result ForEachDevice(F f, bool return_on_fail) {
return impl::ForEach(this->device_list_lock, this->device_list, f, return_on_fail);
}
template<typename F>
Result ForEachDevice(F f, bool return_on_fail) const {
return impl::ForEach(this->device_list_lock, this->device_list, f, return_on_fail);
}
template<typename F>
int ForEachDevice(F f) {
return impl::ForEach(this->device_list_lock, this->device_list, f);
}
template<typename F>
int ForEachDevice(F f) const {
return impl::ForEach(this->device_list_lock, this->device_list, f);
}
};
static_assert(IDriver::ListTraits::IsValid());
}

View File

@@ -0,0 +1,92 @@
/*
* 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.hpp>
#include <stratosphere/os.hpp>
namespace ams::ddsf {
class EventHandlerManager;
class IEventHandler {
NON_COPYABLE(IEventHandler);
NON_MOVEABLE(IEventHandler);
friend class EventHandlerManager;
private:
os::WaitableHolderType holder;
uintptr_t user_data;
bool is_initialized;
bool is_registered;
private:
void Link(os::WaitableManagerType *manager) {
AMS_ASSERT(this->IsInitialized());
AMS_ASSERT(!this->IsRegistered());
AMS_ASSERT(manager != nullptr);
os::LinkWaitableHolder(manager, std::addressof(this->holder));
}
void Unlink() {
AMS_ASSERT(this->IsInitialized());
AMS_ASSERT(this->IsRegistered());
os::UnlinkWaitableHolder(std::addressof(this->holder));
}
static IEventHandler &ToEventHandler(os::WaitableHolderType *holder) {
AMS_ASSERT(holder != nullptr);
auto &event_handler = *reinterpret_cast<IEventHandler *>(os::GetWaitableHolderUserData(holder));
AMS_ASSERT(event_handler.IsInitialized());
return event_handler;
}
public:
IEventHandler() : holder(), user_data(0), is_initialized(false), is_registered(false) { /* ... */ }
~IEventHandler() {
if (this->IsRegistered()) {
this->Unlink();
}
if (this->IsInitialized()) {
this->Finalize();
}
}
bool IsInitialized() const { return this->is_initialized; }
bool IsRegistered() const { return this->is_registered; }
uintptr_t GetUserData() const { return this->user_data; }
void SetUserData(uintptr_t d) { this->user_data = d; }
template<typename T>
void Initialize(T *object) {
AMS_ASSERT(object != nullptr);
AMS_ASSERT(!this->IsInitialized());
os::InitializeWaitableHolder(std::addressof(this->holder), object);
os::SetWaitableHolderUserData(std::addressof(this->holder), reinterpret_cast<uintptr_t>(this));
this->is_initialized = true;
this->is_registered = false;
}
void Finalize() {
AMS_ASSERT(this->IsInitialized());
AMS_ASSERT(!this->IsRegistered());
os::FinalizeWaitableHolder(std::addressof(this->holder));
this->is_initialized = false;
this->is_registered = false;
}
protected:
virtual void HandleEvent() = 0;
};
}

View File

@@ -0,0 +1,100 @@
/*
* 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.hpp>
#include <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/ddsf/impl/ddsf_for_each.hpp>
#include <stratosphere/ddsf/ddsf_i_castable.hpp>
namespace ams::ddsf {
class ISession;
class IDevice;
Result OpenSession(IDevice *device, ISession *session, AccessMode access_mode);
void CloseSession(ISession *session);
class ISession : public ICastable {
friend Result OpenSession(IDevice *device, ISession *session, AccessMode mode);
friend void CloseSession(ISession *session);
public:
AMS_DDSF_CASTABLE_ROOT_TRAITS(ams::ddsf::IDevice);
private:
util::IntrusiveListNode list_node;
IDevice *device;
AccessMode access_mode;
public:
using ListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&ISession::list_node>;
using List = typename ListTraits::ListType;
friend class util::IntrusiveList<ISession, util::IntrusiveListMemberTraitsDeferredAssert<&ISession::list_node>>;
private:
void AttachDevice(IDevice *dev, AccessMode mode) {
AMS_ASSERT(dev != nullptr);
AMS_ASSERT(!this->IsOpen());
this->device = dev;
this->access_mode = mode;
AMS_ASSERT(this->IsOpen());
}
void DetachDevice() {
AMS_ASSERT(this->IsOpen());
this->device = nullptr;
this->access_mode = AccessMode_None;
AMS_ASSERT(!this->IsOpen());
}
public:
ISession() : list_node(), device(nullptr), access_mode() { /* ... */ }
protected:
~ISession() { this->DetachDevice(); AMS_ASSERT(!this->IsOpen()); }
public:
void AddTo(List &list) {
list.push_back(*this);
}
void RemoveFrom(List list) {
list.erase(list.iterator_to(*this));
}
bool IsLinkedToList() const {
return this->list_node.IsLinked();
}
IDevice &GetDevice() {
AMS_ASSERT(this->IsOpen());
return *this->device;
}
const IDevice &GetDevice() const {
AMS_ASSERT(this->IsOpen());
return *this->device;
}
bool IsOpen() const {
return this->device != nullptr;
}
bool CheckAccess(AccessMode mode) const {
AMS_ASSERT(this->IsOpen());
return ((~this->access_mode) & mode) == 0;
}
bool CheckExclusiveWrite() const {
return this->CheckAccess(AccessMode_Write) && !this->CheckAccess(AccessMode_Shared);
}
};
static_assert(ISession::ListTraits::IsValid());
}

View File

@@ -0,0 +1,31 @@
/*
* 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.hpp>
#include <stratosphere/ddsf/ddsf_device_code_entry.hpp>
namespace ams::ddsf {
void SetMemoryResource(ams::MemoryResource *mr);
ams::MemoryResource *GetMemoryResource();
static constexpr size_t DeviceCodeEntryHolderSize = sizeof(DeviceCodeEntryHolder);
void SetDeviceCodeEntryHolderMemoryResource(ams::MemoryResource *mr);
ams::MemoryResource *GetDeviceCodeEntryHolderMemoryResource();
}

View File

@@ -23,8 +23,11 @@ namespace ams::ddsf {
AccessMode_None = (0u << 0),
AccessMode_Read = (1u << 0),
AccessMode_Write = (1u << 1),
AccessMode_Shared = (1u << 2),
AccessMode_ReadWrite = AccessMode_Read | AccessMode_Write,
AccessMode_WriteShared = AccessMode_Write | AccessMode_Shared,
AccessMode_ReadWriteShared = AccessMode_Read | AccessMode_WriteShared,
};
}

View File

@@ -0,0 +1,52 @@
/*
* 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.hpp>
namespace ams::ddsf::impl {
template<typename Lock, typename List, typename F>
inline Result ForEach(Lock &lock, List &list, F f, bool return_on_fail) {
std::scoped_lock lk(lock);
Result result = ResultSuccess();
for (auto && it : list) {
if (const auto cur_result = f(std::addressof(it)); R_FAILED(cur_result)) {
if (return_on_fail) {
return cur_result;
} else if (R_SUCCEEDED(result)) {
result = cur_result;
}
}
}
return result;
}
template<typename List, typename F, typename Lock>
inline int ForEach(Lock &lock, List &list, F f) {
std::scoped_lock lk(lock);
int success_count = 0;
for (auto && it : list) {
if (!f(it)) {
return success_count;
}
++success_count;
}
return success_count;
}
}

View File

@@ -0,0 +1,70 @@
/*
* 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.hpp>
#include <stratosphere/ddsf/ddsf_types.hpp>
namespace ams::ddsf::impl {
#if defined(AMS_BUILD_FOR_DEBUGGING) || defined(AMS_BUILD_FOR_AUDITING)
#define AMS_DDSF_CASTABLE_ROOT_TRAITS(__CLASS__) \
public: \
static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag{#__CLASS__}; \
constexpr virtual const ::ams::ddsf::impl::TypeTag &GetTypeTag() const override { return s_ams_ddsf_castable_type_tag; }
#else
#define AMS_DDSF_CASTABLE_ROOT_TRAITS(__CLASS__) \
public: \
static constexpr inline ::ams::ddsf::impl::TypeTag s_ams_ddsf_castable_type_tag{}; \
constexpr virtual const ::ams::ddsf::impl::TypeTag &GetTypeTag() const override { return s_ams_ddsf_castable_type_tag; }
#endif
class TypeTag {
private:
const char * const class_name;
const TypeTag * const base;
public:
#if !(defined(AMS_BUILD_FOR_DEBUGGING) || defined(AMS_BUILD_FOR_AUDITING))
constexpr TypeTag() : class_name(nullptr), base(nullptr) { /* ... */}
constexpr TypeTag(const TypeTag &b) : class_name(nullptr), base(std::addressof(b)) { AMS_ASSERT(this != this->base); }
constexpr TypeTag(const char *c) : class_name(nullptr), base(nullptr) { AMS_UNUSED(c); }
constexpr TypeTag(const char *c, const TypeTag &b) : class_name(nullptr), base(std::addressof(b)) { AMS_UNUSED(c); AMS_ASSERT(this != this->base); }
#else
constexpr TypeTag(const char *c) : class_name(c), base(nullptr) { /* ... */ }
constexpr TypeTag(const char *c, const TypeTag &b) : class_name(c), base(std::addressof(b)) { AMS_ASSERT(this != this->base); }
#endif
constexpr const char * GetClassName() const { return this->class_name; }
constexpr bool Is(const TypeTag &rhs) const { return this == std::addressof(rhs); }
constexpr bool DerivesFrom(const TypeTag &rhs) const {
const TypeTag * cur = this;
while (cur != nullptr) {
if (cur == std::addressof(rhs)) {
return true;
}
cur = cur->base;
}
return false;
}
};
}

View File

@@ -20,3 +20,7 @@
#include <stratosphere/gpio/sf/gpio_sf_i_manager.hpp>
#include <stratosphere/gpio/gpio_api.hpp>
#include <stratosphere/gpio/gpio_pad_api.hpp>
#include <stratosphere/gpio/driver/gpio_select_driver_api.hpp>
#include <stratosphere/gpio/driver/gpio_pad_accessor.hpp>
#include <stratosphere/gpio/driver/impl/gpio_pad_session_impl.hpp>
#include <stratosphere/gpio/server/gpio_server_api.hpp>

View File

@@ -0,0 +1,28 @@
/*
* 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.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/driver/gpio_i_gpio_driver.hpp>
namespace ams::gpio::driver::board::nintendo_nx {
void Initialize(bool enable_interrupt_handlers);
void SetInitialGpioConfig();
void SetInitialWakePinConfig();
}

View File

@@ -0,0 +1,26 @@
/*
* 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.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/driver/gpio_i_gpio_driver.hpp>
namespace ams::gpio::driver {
void Initialize();
void Finalize();
}

View File

@@ -0,0 +1,35 @@
/*
* 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.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/driver/gpio_i_gpio_driver.hpp>
namespace ams::gpio::driver {
void RegisterDriver(IGpioDriver *driver);
void UnregisterDriver(IGpioDriver *driver);
Result RegisterDeviceCode(DeviceCode device_code, Pad *pad);
bool UnregisterDeviceCode(DeviceCode device_code);
void RegisterInterruptHandler(ddsf::IEventHandler *handler);
void UnregisterInterruptHandler(ddsf::IEventHandler *handler);
void SetInitialGpioConfig();
void SetInitialWakePinConfig();
}

View File

@@ -0,0 +1,75 @@
/*
* 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.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/ddsf.hpp>
namespace ams::gpio::driver {
class Pad;
class IGpioDriver : public ::ams::ddsf::IDriver {
NON_COPYABLE(IGpioDriver);
NON_MOVEABLE(IGpioDriver);
AMS_DDSF_CASTABLE_TRAITS(ams::gpio::driver::IGpioDriver, ::ams::ddsf::IDriver);
public:
IGpioDriver() : IDriver() { /* ... */ }
virtual ~IGpioDriver() { /* ... */ }
virtual void InitializeDriver() = 0;
virtual void FinalizeDriver() = 0;
virtual Result InitializePad(Pad *pad) = 0;
virtual void FinalizePad(Pad *pad) = 0;
virtual Result GetDirection(Direction *out, Pad *pad) const = 0;
virtual Result SetDirection(Pad *pad, Direction direction) = 0;
virtual Result GetValue(GpioValue *out, Pad *pad) const = 0;
virtual Result SetValue(Pad *pad, GpioValue value) = 0;
virtual Result GetInterruptMode(InterruptMode *out, Pad *pad) const = 0;
virtual Result SetInterruptMode(Pad *pad, InterruptMode mode) = 0;
virtual Result SetInterruptEnabled(Pad *pad, bool en) = 0;
virtual Result GetInterruptStatus(InterruptStatus *out, Pad *pad) = 0;
virtual Result ClearInterruptStatus(Pad *pad) = 0;
virtual os::SdkMutex &GetInterruptControlMutex(const Pad &pad) const = 0;
virtual Result GetDebounceEnabled(bool *out, Pad *pad) const = 0;
virtual Result SetDebounceEnabled(Pad *pad, bool en) = 0;
virtual Result GetDebounceTime(s32 *out_ms, Pad *pad) const = 0;
virtual Result SetDebounceTime(Pad *pad, s32 ms) = 0;
virtual Result GetUnknown22(u32 *out) = 0;
virtual void Unknown23();
virtual Result SetValueForSleepState(Pad *pad, GpioValue value) = 0;
virtual Result IsWakeEventActive(bool *out, Pad *pad) const = 0;
virtual Result SetWakeEventActiveFlagSetForDebug(Pad *pad, bool en) = 0;
virtual Result SetWakePinDebugMode(WakePinDebugMode mode) = 0;
virtual Result Suspend() = 0;
virtual Result SuspendLow() = 0;
virtual Result Resume() = 0;
virtual Result ResumeLow() = 0;
};
}

View File

@@ -0,0 +1,61 @@
/*
* 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.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/ddsf.hpp>
namespace ams::gpio::driver {
class Pad : public ::ams::ddsf::IDevice {
NON_COPYABLE(Pad);
NON_MOVEABLE(Pad);
AMS_DDSF_CASTABLE_TRAITS(ams::gpio::driver::Pad, ::ams::ddsf::IDevice);
private:
int pad_number;
bool is_interrupt_enabled;
public:
explicit Pad(int pad) : IDevice(true), pad_number(pad), is_interrupt_enabled(false) { /* ... */ }
Pad() : Pad(0) { /* ... */ }
virtual ~Pad() { /* ... */ }
int GetPadNumber() const {
return this->pad_number;
}
void SetPadNumber(int p) {
this->pad_number = p;
}
bool IsInterruptEnabled() const {
return this->is_interrupt_enabled;
}
void SetInterruptEnabled(bool en) {
this->is_interrupt_enabled = en;
}
bool IsInterruptRequiredForDriver() const {
return this->IsInterruptEnabled() && this->IsAnySessionBoundToInterrupt();
}
bool IsAnySessionBoundToInterrupt() const;
void SignalInterruptBoundEvent();
};
}

View File

@@ -0,0 +1,45 @@
/*
* 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.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
namespace ams::gpio::driver {
namespace impl {
constexpr inline size_t GpioPadSessionSize = 0x60;
constexpr inline size_t GpioPadSessionAlign = 8;
struct alignas(GpioPadSessionAlign) GpioPadSessionImplPadded;
}
struct GpioPadSession {
util::TypedStorage<impl::GpioPadSessionImplPadded, impl::GpioPadSessionSize, impl::GpioPadSessionAlign> _impl;
};
Result OpenSession(GpioPadSession *out, DeviceCode device_code, ddsf::AccessMode access_mode);
void CloseSession(GpioPadSession *session);
Result SetDirection(GpioPadSession *session, gpio::Direction direction);
Result GetDirection(gpio::Direction *out, GpioPadSession *session);
Result SetValue(GpioPadSession *session, gpio::GpioValue value);
Result GetValue(gpio::GpioValue *out, GpioPadSession *session);
/* TODO */
}

View File

@@ -0,0 +1,38 @@
/*
* 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.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/driver/gpio_i_gpio_driver.hpp>
#include <stratosphere/gpio/driver/gpio_driver_service_api.hpp>
#include <stratosphere/gpio/driver/gpio_driver_client_api.hpp>
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
#include <stratosphere/gpio/driver/board/nintendo_nx/gpio_driver_api.hpp>
namespace ams::gpio::driver::board {
using namespace ams::gpio::driver::board::nintendo_nx;
}
#else
#error "Unknown board for ams::gpio::driver::"
#endif

View File

@@ -0,0 +1,49 @@
/*
* 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.hpp>
#include <stratosphere/os.hpp>
namespace ams::gpio::driver::impl {
class EventHolder {
NON_COPYABLE(EventHolder);
NON_MOVEABLE(EventHolder);
private:
os::SystemEventType *event;
public:
constexpr EventHolder() : event(nullptr) { /* ... */ }
void AttachEvent(os::SystemEventType *event) {
this->event = event;
}
os::SystemEventType *DetachEvent() {
auto ev = this->event;
this->event = nullptr;
return ev;
}
os::SystemEventType *GetSystemEvent() {
return this->event;
}
bool IsBound() const {
return this->event != nullptr;
}
};
}

View File

@@ -0,0 +1,90 @@
/*
* 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.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/driver/gpio_pad_accessor.hpp>
#include <stratosphere/gpio/driver/impl/gpio_event_holder.hpp>
#include <stratosphere/ddsf.hpp>
namespace ams::gpio::driver {
class Pad;
}
namespace ams::gpio::driver::impl {
class PadSessionImpl : public ::ams::ddsf::ISession {
NON_COPYABLE(PadSessionImpl);
NON_MOVEABLE(PadSessionImpl);
AMS_DDSF_CASTABLE_TRAITS(ams::gpio::driver::impl::PadSessionImpl, ::ams::ddsf::ISession);
private:
EventHolder event_holder;
private:
Result UpdateDriverInterruptEnabled();
public:
PadSessionImpl() : event_holder() { /* ... */ }
~PadSessionImpl() {
this->Close();
}
bool IsInterruptBound() const {
return this->event_holder.IsBound();
}
Result Open(Pad *pad, ddsf::AccessMode access_mode);
void Close();
Result BindInterrupt(os::SystemEventType *event);
void UnbindInterrupt();
Result GetInterruptEnabled(bool *out) const;
Result SetInterruptEnabled(bool en);
void SignalInterruptBoundEvent();
};
static_assert( sizeof(PadSessionImpl) <= GpioPadSessionSize);
static_assert(alignof(PadSessionImpl) <= GpioPadSessionAlign);
struct alignas(GpioPadSessionAlign) GpioPadSessionImplPadded {
PadSessionImpl _impl;
u8 _padding[GpioPadSessionSize - sizeof(PadSessionImpl)];
};
static_assert( sizeof(GpioPadSessionImplPadded) == GpioPadSessionSize);
static_assert(alignof(GpioPadSessionImplPadded) == GpioPadSessionAlign);
ALWAYS_INLINE PadSessionImpl &GetPadSessionImpl(GpioPadSession &session) {
return GetReference(session._impl)._impl;
}
ALWAYS_INLINE const PadSessionImpl &GetPadSessionImpl(const GpioPadSession &session) {
return GetReference(session._impl)._impl;
}
ALWAYS_INLINE PadSessionImpl &GetOpenPadSessionImpl(GpioPadSession &session) {
auto &ref = GetReference(session._impl)._impl;
AMS_ASSERT(ref.IsOpen());
return ref;
}
ALWAYS_INLINE const PadSessionImpl &GetOpenPadSessionImpl(const GpioPadSession &session) {
const auto &ref = GetReference(session._impl)._impl;
AMS_ASSERT(ref.IsOpen());
return ref;
}
}

View File

@@ -16,10 +16,13 @@
#pragma once
#include <vapours.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/sf/gpio_sf_i_manager.hpp>
namespace ams::gpio {
void Initialize();
void Finalize();
void InitializeWith(std::shared_ptr<gpio::sf::IManager> &&sp);
}

View File

@@ -18,6 +18,7 @@
#include <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/gpio_select_pad_name.hpp>
#include <stratosphere/gpio/driver/gpio_pad.hpp>
namespace ams::gpio {

View File

@@ -21,23 +21,296 @@ namespace ams::gpio {
enum GpioPadName : u32 {
GpioPadName_CodecLdoEnTemp = 1,
GpioPadName_PowSdEn = 2,
GpioPadName_BtRst = 3,
GpioPadName_RamCode3 = 4,
GpioPadName_GameCardReset = 5,
GpioPadName_CodecAlert = 6,
GpioPadName_PowGc = 7,
GpioPadName_DebugControllerDet = 8,
GpioPadName_BattChgStatus = 9,
GpioPadName_BattChgEnableN = 10,
GpioPadName_FanTach = 11,
GpioPadName_ExtconDetS = 12,
GpioPadName_Vdd50AEn = 13,
GpioPadName_SdevCoaxSel1 = 14,
GpioPadName_GameCardCd = 15,
GpioPadName_ProdType0 = 16,
GpioPadName_ProdType1 = 17,
GpioPadName_ProdType2 = 18,
GpioPadName_ProdType3 = 19,
GpioPadName_TempAlert = 20,
GpioPadName_CodecHpDetIrq = 21,
GpioPadName_MotionInt = 22,
GpioPadName_TpIrq = 23,
GpioPadName_ButtonSleep2 = 24,
GpioPadName_ButtonVolUp = 25,
GpioPadName_ButtonVolDn = 26,
GpioPadName_BattMgicIrq = 27,
GpioPadName_RecoveryKey = 28,
GpioPadName_PowLcdBlEn = 29,
GpioPadName_LcdReset = 30,
GpioPadName_PdVconnEn = 31,
GpioPadName_PdRstN = 32,
GpioPadName_Bq24190Irq = 33,
GpioPadName_SdevCoaxSel0 = 34,
GpioPadName_SdWp = 35,
GpioPadName_TpReset = 36,
GpioPadName_BtGpio2 = 37,
GpioPadName_BtGpio3 = 38,
GpioPadName_BtGpio4 = 39,
GpioPadName_CradleIrq = 40,
GpioPadName_PowVcpuInt = 41,
GpioPadName_Max77621GpuInt = 42,
GpioPadName_ExtconChgU = 43,
GpioPadName_ExtconChgS = 44,
GpioPadName_WifiRfDisable = 45,
GpioPadName_WifiReset = 46,
GpioPadName_ApWakeBt = 47,
GpioPadName_BtWakeAp = 48,
GpioPadName_BtGpio5 = 49,
GpioPadName_PowLcdVddPEn = 50,
GpioPadName_PowLcdVddNEn = 51,
GpioPadName_ExtconDetU = 52,
GpioPadName_RamCode2 = 53,
GpioPadName_Vdd50BEn = 54,
GpioPadName_WifiWakeHost = 55,
GpioPadName_SdCd = 56,
GpioPadName_OtgFet1ForSdev = 57,
GpioPadName_OtgFet2ForSdev = 58,
GpioPadName_ExtConWakeU = 59,
GpioPadName_ExtConWakeS = 60,
GpioPadName_PmuIrq = 61,
GpioPadName_ExtUart2Cts = 62,
GpioPadName_ExtUart3Cts = 63,
GpioPadName_5VStepDownEn = 64,
GpioPadName_UsbSwitchB2Oc = 65,
GpioPadName_5VStepDownPg = 66,
GpioPadName_UsbSwitchAEn = 67,
GpioPadName_UsbSwitchAFlag = 68,
GpioPadName_UsbSwitchB3Oc = 69,
GpioPadName_UsbSwitchB3En = 70,
GpioPadName_UsbSwitchB2En = 71,
GpioPadName_Hdmi5VEn = 72,
GpioPadName_UsbSwitchB1En = 73,
GpioPadName_HdmiPdTrEn = 74,
GpioPadName_FanEn = 75,
GpioPadName_UsbSwitchB1Oc = 76,
GpioPadName_PwmFan = 77,
GpioPadName_HdmiHpd = 78,
GpioPadName_Max77812Irq = 79,
GpioPadName_Debug0 = 80,
GpioPadName_Debug1 = 81,
GpioPadName_Debug2 = 82,
GpioPadName_Debug3 = 83,
GpioPadName_NfcIrq = 84,
GpioPadName_NfcRst = 85,
GpioPadName_McuIrq = 86,
GpioPadName_McuBoot = 87,
GpioPadName_McuRst = 88,
GpioPadName_Vdd5V3En = 89,
GpioPadName_McuPor = 90,
GpioPadName_LcdGpio1 = 91,
GpioPadName_NfcEn = 92,
};
/* TODO: Better place for this? */
constexpr inline const DeviceCode DeviceCode_CodecLdoEnTemp = 0x33000002;
constexpr inline const DeviceCode DeviceCode_PowSdEn = 0x3C000001;
constexpr inline const DeviceCode DeviceCode_BtRst = 0x37000002;
constexpr inline const DeviceCode DeviceCode_RamCode3 = 0xC9000402;
constexpr inline const DeviceCode DeviceCode_GameCardReset = 0x3C000402;
constexpr inline const DeviceCode DeviceCode_CodecAlert = 0x33000003;
constexpr inline const DeviceCode DeviceCode_PowGc = 0x3C000401;
constexpr inline const DeviceCode DeviceCode_DebugControllerDet = 0x350000CA;
constexpr inline const DeviceCode DeviceCode_BattChgStatus = 0x39000407;
constexpr inline const DeviceCode DeviceCode_BattChgEnableN = 0x39000003;
constexpr inline const DeviceCode DeviceCode_FanTach = 0x3D000002;
constexpr inline const DeviceCode DeviceCode_ExtconDetS = 0x3500040B;
constexpr inline const DeviceCode DeviceCode_Vdd50AEn = 0x39000401;
constexpr inline const DeviceCode DeviceCode_SdevCoaxSel1 = 0xCA000402;
constexpr inline const DeviceCode DeviceCode_GameCardCd = 0x3C000403;
constexpr inline const DeviceCode DeviceCode_ProdType0 = 0xC900040B;
constexpr inline const DeviceCode DeviceCode_ProdType1 = 0xC900040C;
constexpr inline const DeviceCode DeviceCode_ProdType2 = 0xC900040D;
constexpr inline const DeviceCode DeviceCode_ProdType3 = 0xC900040E;
constexpr inline const DeviceCode DeviceCode_TempAlert = 0x3E000002;
constexpr inline const DeviceCode DeviceCode_CodecHpDetIrq = 0x33000004;
constexpr inline const DeviceCode DeviceCode_MotionInt = 0x35000041;
constexpr inline const DeviceCode DeviceCode_TpIrq = 0x35000036;
constexpr inline const DeviceCode DeviceCode_ButtonSleep2 = 0x35000001;
constexpr inline const DeviceCode DeviceCode_ButtonVolUp = 0x35000002;
constexpr inline const DeviceCode DeviceCode_ButtonVolDn = 0x35000003;
constexpr inline const DeviceCode DeviceCode_BattMgicIrq = 0x39000034;
constexpr inline const DeviceCode DeviceCode_RecoveryKey = 0x35000004;
constexpr inline const DeviceCode DeviceCode_PowLcdBlEn = 0x3400003E;
constexpr inline const DeviceCode DeviceCode_LcdReset = 0x34000033;
constexpr inline const DeviceCode DeviceCode_PdVconnEn = 0x040000CC;
constexpr inline const DeviceCode DeviceCode_PdRstN = 0x040000CA;
constexpr inline const DeviceCode DeviceCode_Bq24190Irq = 0x39000002;
constexpr inline const DeviceCode DeviceCode_SdevCoaxSel0 = 0xCA000401;
constexpr inline const DeviceCode DeviceCode_SdWp = 0x3C000003;
constexpr inline const DeviceCode DeviceCode_TpReset = 0x35000035;
constexpr inline const DeviceCode DeviceCode_BtGpio2 = 0x37000401;
constexpr inline const DeviceCode DeviceCode_BtGpio3 = 0x37000402;
constexpr inline const DeviceCode DeviceCode_BtGpio4 = 0x37000403;
constexpr inline const DeviceCode DeviceCode_CradleIrq = 0x040000CB;
constexpr inline const DeviceCode DeviceCode_PowVcpuInt = 0x3E000003;
constexpr inline const DeviceCode DeviceCode_Max77621GpuInt = 0x3E000004;
constexpr inline const DeviceCode DeviceCode_ExtconChgU = 0x35000402;
constexpr inline const DeviceCode DeviceCode_ExtconChgS = 0x3500040C;
constexpr inline const DeviceCode DeviceCode_WifiRfDisable = 0x38000003;
constexpr inline const DeviceCode DeviceCode_WifiReset = 0x38000002;
constexpr inline const DeviceCode DeviceCode_ApWakeBt = 0x37000003;
constexpr inline const DeviceCode DeviceCode_BtWakeAp = 0x37000004;
constexpr inline const DeviceCode DeviceCode_BtGpio5 = 0x37000404;
constexpr inline const DeviceCode DeviceCode_PowLcdVddPEn = 0x34000034;
constexpr inline const DeviceCode DeviceCode_PowLcdVddNEn = 0x34000035;
constexpr inline const DeviceCode DeviceCode_ExtconDetU = 0x35000401;
constexpr inline const DeviceCode DeviceCode_RamCode2 = 0xC9000401;
constexpr inline const DeviceCode DeviceCode_Vdd50BEn = 0x39000402;
constexpr inline const DeviceCode DeviceCode_WifiWakeHost = 0x38000004;
constexpr inline const DeviceCode DeviceCode_SdCd = 0x3C000002;
constexpr inline const DeviceCode DeviceCode_OtgFet1ForSdev = 0x39000404;
constexpr inline const DeviceCode DeviceCode_OtgFet2ForSdev = 0x39000405;
constexpr inline const DeviceCode DeviceCode_ExtConWakeU = 0x35000403;
constexpr inline const DeviceCode DeviceCode_ExtConWakeS = 0x3500040D;
constexpr inline const DeviceCode DeviceCode_PmuIrq = 0x39000406;
constexpr inline const DeviceCode DeviceCode_ExtUart2Cts = 0x35000404;
constexpr inline const DeviceCode DeviceCode_ExtUart3Cts = 0x3500040E;
constexpr inline const DeviceCode DeviceCode_5VStepDownEn = 0x39000408;
constexpr inline const DeviceCode DeviceCode_UsbSwitchB2Oc = 0x04000401;
constexpr inline const DeviceCode DeviceCode_5VStepDownPg = 0x39000409;
constexpr inline const DeviceCode DeviceCode_UsbSwitchAEn = 0x04000402;
constexpr inline const DeviceCode DeviceCode_UsbSwitchAFlag = 0x04000403;
constexpr inline const DeviceCode DeviceCode_UsbSwitchB3Oc = 0x04000404;
constexpr inline const DeviceCode DeviceCode_UsbSwitchB3En = 0x04000405;
constexpr inline const DeviceCode DeviceCode_UsbSwitchB2En = 0x04000406;
constexpr inline const DeviceCode DeviceCode_Hdmi5VEn = 0x34000004;
constexpr inline const DeviceCode DeviceCode_UsbSwitchB1En = 0x04000407;
constexpr inline const DeviceCode DeviceCode_HdmiPdTrEn = 0x34000005;
constexpr inline const DeviceCode DeviceCode_FanEn = 0x3D000003;
constexpr inline const DeviceCode DeviceCode_UsbSwitchB1Oc = 0x04000408;
constexpr inline const DeviceCode DeviceCode_PwmFan = 0x3D000001;
constexpr inline const DeviceCode DeviceCode_HdmiHpd = 0x34000006;
constexpr inline const DeviceCode DeviceCode_Max77812Irq = 0x3E000003;
constexpr inline const DeviceCode DeviceCode_Debug0 = 0xCA000001;
constexpr inline const DeviceCode DeviceCode_Debug1 = 0xCA000002;
constexpr inline const DeviceCode DeviceCode_Debug2 = 0xCA000003;
constexpr inline const DeviceCode DeviceCode_Debug3 = 0xCA000004;
constexpr inline const DeviceCode DeviceCode_NfcIrq = 0x36000004;
constexpr inline const DeviceCode DeviceCode_NfcRst = 0x36000003;
constexpr inline const DeviceCode DeviceCode_McuIrq = 0x35000415;
constexpr inline const DeviceCode DeviceCode_McuBoot = 0x35000416;
constexpr inline const DeviceCode DeviceCode_McuRst = 0x35000417;
constexpr inline const DeviceCode DeviceCode_Vdd5V3En = 0x39000403;
constexpr inline const DeviceCode DeviceCode_McuPor = 0x35000418;
constexpr inline const DeviceCode DeviceCode_LcdGpio1 = 0x35000005;
constexpr inline const DeviceCode DeviceCode_NfcEn = 0x36000002;
constexpr inline const DeviceCode DeviceCode_ExtUart2Rts = 0x35000406;
constexpr inline const DeviceCode DeviceCode_ExtUart3Rts = 0x35000410;
constexpr inline const DeviceCode DeviceCode_GpioPortC7 = 0x3500041B;
constexpr inline const DeviceCode DeviceCode_GpioPortD0 = 0x3500041C;
constexpr inline const DeviceCode DeviceCode_GpioPortC5 = 0x3500041D;
constexpr inline const DeviceCode DeviceCode_GpioPortC6 = 0x3500041E;
constexpr inline const DeviceCode DeviceCode_GpioPortY7 = 0x35000065;
constexpr inline const DeviceCode DeviceCode_GpioPortF1 = 0x04000409;
constexpr inline const DeviceCode DeviceCode_GpioPortH0 = 0x34000401;
constexpr inline GpioPadName ConvertToGpioPadName(DeviceCode dc) {
switch (dc.GetInternalValue()) {
case DeviceCode_CodecLdoEnTemp .GetInternalValue(): return GpioPadName_CodecLdoEnTemp;
case DeviceCode_PowSdEn .GetInternalValue(): return GpioPadName_PowSdEn;
case DeviceCode_BtRst .GetInternalValue(): return GpioPadName_BtRst;
case DeviceCode_RamCode3 .GetInternalValue(): return GpioPadName_RamCode3;
case DeviceCode_GameCardReset .GetInternalValue(): return GpioPadName_GameCardReset;
case DeviceCode_CodecAlert .GetInternalValue(): return GpioPadName_CodecAlert;
case DeviceCode_PowGc .GetInternalValue(): return GpioPadName_PowGc;
case DeviceCode_DebugControllerDet.GetInternalValue(): return GpioPadName_DebugControllerDet;
case DeviceCode_BattChgStatus .GetInternalValue(): return GpioPadName_BattChgStatus;
case DeviceCode_BattChgEnableN .GetInternalValue(): return GpioPadName_BattChgEnableN;
case DeviceCode_FanTach .GetInternalValue(): return GpioPadName_FanTach;
case DeviceCode_ExtconDetS .GetInternalValue(): return GpioPadName_ExtconDetS;
case DeviceCode_Vdd50AEn .GetInternalValue(): return GpioPadName_Vdd50AEn;
case DeviceCode_SdevCoaxSel1 .GetInternalValue(): return GpioPadName_SdevCoaxSel1;
case DeviceCode_GameCardCd .GetInternalValue(): return GpioPadName_GameCardCd;
case DeviceCode_ProdType0 .GetInternalValue(): return GpioPadName_ProdType0;
case DeviceCode_ProdType1 .GetInternalValue(): return GpioPadName_ProdType1;
case DeviceCode_ProdType2 .GetInternalValue(): return GpioPadName_ProdType2;
case DeviceCode_ProdType3 .GetInternalValue(): return GpioPadName_ProdType3;
case DeviceCode_TempAlert .GetInternalValue(): return GpioPadName_TempAlert;
case DeviceCode_CodecHpDetIrq .GetInternalValue(): return GpioPadName_CodecHpDetIrq;
case DeviceCode_MotionInt .GetInternalValue(): return GpioPadName_MotionInt;
case DeviceCode_TpIrq .GetInternalValue(): return GpioPadName_TpIrq;
case DeviceCode_ButtonSleep2 .GetInternalValue(): return GpioPadName_ButtonSleep2;
case DeviceCode_ButtonVolUp .GetInternalValue(): return GpioPadName_ButtonVolUp;
case DeviceCode_ButtonVolDn .GetInternalValue(): return GpioPadName_ButtonVolDn;
case DeviceCode_BattMgicIrq .GetInternalValue(): return GpioPadName_BattMgicIrq;
case DeviceCode_RecoveryKey .GetInternalValue(): return GpioPadName_RecoveryKey;
case DeviceCode_PowLcdBlEn .GetInternalValue(): return GpioPadName_PowLcdBlEn;
case DeviceCode_LcdReset .GetInternalValue(): return GpioPadName_LcdReset;
case DeviceCode_PdVconnEn .GetInternalValue(): return GpioPadName_PdVconnEn;
case DeviceCode_PdRstN .GetInternalValue(): return GpioPadName_PdRstN;
case DeviceCode_Bq24190Irq .GetInternalValue(): return GpioPadName_Bq24190Irq;
case DeviceCode_SdevCoaxSel0 .GetInternalValue(): return GpioPadName_SdevCoaxSel0;
case DeviceCode_SdWp .GetInternalValue(): return GpioPadName_SdWp;
case DeviceCode_TpReset .GetInternalValue(): return GpioPadName_TpReset;
case DeviceCode_BtGpio2 .GetInternalValue(): return GpioPadName_BtGpio2;
case DeviceCode_BtGpio3 .GetInternalValue(): return GpioPadName_BtGpio3;
case DeviceCode_BtGpio4 .GetInternalValue(): return GpioPadName_BtGpio4;
case DeviceCode_CradleIrq .GetInternalValue(): return GpioPadName_CradleIrq;
/* case DeviceCode_PowVcpuInt .GetInternalValue(): return GpioPadName_PowVcpuInt; */
case DeviceCode_Max77621GpuInt .GetInternalValue(): return GpioPadName_Max77621GpuInt;
case DeviceCode_ExtconChgU .GetInternalValue(): return GpioPadName_ExtconChgU;
case DeviceCode_ExtconChgS .GetInternalValue(): return GpioPadName_ExtconChgS;
case DeviceCode_WifiRfDisable .GetInternalValue(): return GpioPadName_WifiRfDisable;
case DeviceCode_WifiReset .GetInternalValue(): return GpioPadName_WifiReset;
case DeviceCode_ApWakeBt .GetInternalValue(): return GpioPadName_ApWakeBt;
case DeviceCode_BtWakeAp .GetInternalValue(): return GpioPadName_BtWakeAp;
case DeviceCode_BtGpio5 .GetInternalValue(): return GpioPadName_BtGpio5;
case DeviceCode_PowLcdVddPEn .GetInternalValue(): return GpioPadName_PowLcdVddPEn;
case DeviceCode_PowLcdVddNEn .GetInternalValue(): return GpioPadName_PowLcdVddNEn;
case DeviceCode_ExtconDetU .GetInternalValue(): return GpioPadName_ExtconDetU;
case DeviceCode_RamCode2 .GetInternalValue(): return GpioPadName_RamCode2;
case DeviceCode_Vdd50BEn .GetInternalValue(): return GpioPadName_Vdd50BEn;
case DeviceCode_WifiWakeHost .GetInternalValue(): return GpioPadName_WifiWakeHost;
case DeviceCode_SdCd .GetInternalValue(): return GpioPadName_SdCd;
case DeviceCode_OtgFet1ForSdev .GetInternalValue(): return GpioPadName_OtgFet1ForSdev;
case DeviceCode_OtgFet2ForSdev .GetInternalValue(): return GpioPadName_OtgFet2ForSdev;
case DeviceCode_ExtConWakeU .GetInternalValue(): return GpioPadName_ExtConWakeU;
case DeviceCode_ExtConWakeS .GetInternalValue(): return GpioPadName_ExtConWakeS;
case DeviceCode_PmuIrq .GetInternalValue(): return GpioPadName_PmuIrq;
case DeviceCode_ExtUart2Cts .GetInternalValue(): return GpioPadName_ExtUart2Cts;
case DeviceCode_ExtUart3Cts .GetInternalValue(): return GpioPadName_ExtUart3Cts;
case DeviceCode_5VStepDownEn .GetInternalValue(): return GpioPadName_5VStepDownEn;
case DeviceCode_UsbSwitchB2Oc .GetInternalValue(): return GpioPadName_UsbSwitchB2Oc;
case DeviceCode_5VStepDownPg .GetInternalValue(): return GpioPadName_5VStepDownPg;
case DeviceCode_UsbSwitchAEn .GetInternalValue(): return GpioPadName_UsbSwitchAEn;
case DeviceCode_UsbSwitchAFlag .GetInternalValue(): return GpioPadName_UsbSwitchAFlag;
case DeviceCode_UsbSwitchB3Oc .GetInternalValue(): return GpioPadName_UsbSwitchB3Oc;
case DeviceCode_UsbSwitchB3En .GetInternalValue(): return GpioPadName_UsbSwitchB3En;
case DeviceCode_UsbSwitchB2En .GetInternalValue(): return GpioPadName_UsbSwitchB2En;
case DeviceCode_Hdmi5VEn .GetInternalValue(): return GpioPadName_Hdmi5VEn;
case DeviceCode_UsbSwitchB1En .GetInternalValue(): return GpioPadName_UsbSwitchB1En;
case DeviceCode_HdmiPdTrEn .GetInternalValue(): return GpioPadName_HdmiPdTrEn;
case DeviceCode_FanEn .GetInternalValue(): return GpioPadName_FanEn;
case DeviceCode_UsbSwitchB1Oc .GetInternalValue(): return GpioPadName_UsbSwitchB1Oc;
case DeviceCode_PwmFan .GetInternalValue(): return GpioPadName_PwmFan;
case DeviceCode_HdmiHpd .GetInternalValue(): return GpioPadName_HdmiHpd;
case DeviceCode_Max77812Irq .GetInternalValue(): return GpioPadName_Max77812Irq;
case DeviceCode_Debug0 .GetInternalValue(): return GpioPadName_Debug0;
case DeviceCode_Debug1 .GetInternalValue(): return GpioPadName_Debug1;
case DeviceCode_Debug2 .GetInternalValue(): return GpioPadName_Debug2;
case DeviceCode_Debug3 .GetInternalValue(): return GpioPadName_Debug3;
case DeviceCode_NfcIrq .GetInternalValue(): return GpioPadName_NfcIrq;
case DeviceCode_NfcRst .GetInternalValue(): return GpioPadName_NfcRst;
case DeviceCode_McuIrq .GetInternalValue(): return GpioPadName_McuIrq;
case DeviceCode_McuBoot .GetInternalValue(): return GpioPadName_McuBoot;
case DeviceCode_McuRst .GetInternalValue(): return GpioPadName_McuRst;
case DeviceCode_Vdd5V3En .GetInternalValue(): return GpioPadName_Vdd5V3En;
case DeviceCode_McuPor .GetInternalValue(): return GpioPadName_McuPor;
case DeviceCode_LcdGpio1 .GetInternalValue(): return GpioPadName_LcdGpio1;
case DeviceCode_NfcEn .GetInternalValue(): return GpioPadName_NfcEn;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
@@ -45,9 +318,97 @@ namespace ams::gpio {
constexpr inline DeviceCode ConvertToDeviceCode(GpioPadName gpn) {
switch (gpn) {
case GpioPadName_CodecLdoEnTemp: return DeviceCode_CodecLdoEnTemp;
case GpioPadName_PowSdEn: return DeviceCode_PowSdEn;
case GpioPadName_BtRst: return DeviceCode_BtRst;
case GpioPadName_RamCode3: return DeviceCode_RamCode3;
case GpioPadName_GameCardReset: return DeviceCode_GameCardReset;
case GpioPadName_CodecAlert: return DeviceCode_CodecAlert;
case GpioPadName_PowGc: return DeviceCode_PowGc;
case GpioPadName_DebugControllerDet: return DeviceCode_DebugControllerDet;
case GpioPadName_BattChgStatus: return DeviceCode_BattChgStatus;
case GpioPadName_BattChgEnableN: return DeviceCode_BattChgEnableN;
case GpioPadName_FanTach: return DeviceCode_FanTach;
case GpioPadName_ExtconDetS: return DeviceCode_ExtconDetS;
case GpioPadName_Vdd50AEn: return DeviceCode_Vdd50AEn;
case GpioPadName_SdevCoaxSel1: return DeviceCode_SdevCoaxSel1;
case GpioPadName_GameCardCd: return DeviceCode_GameCardCd;
case GpioPadName_ProdType0: return DeviceCode_ProdType0;
case GpioPadName_ProdType1: return DeviceCode_ProdType1;
case GpioPadName_ProdType2: return DeviceCode_ProdType2;
case GpioPadName_ProdType3: return DeviceCode_ProdType3;
case GpioPadName_TempAlert: return DeviceCode_TempAlert;
case GpioPadName_CodecHpDetIrq: return DeviceCode_CodecHpDetIrq;
case GpioPadName_MotionInt: return DeviceCode_MotionInt;
case GpioPadName_TpIrq: return DeviceCode_TpIrq;
case GpioPadName_ButtonSleep2: return DeviceCode_ButtonSleep2;
case GpioPadName_ButtonVolUp: return DeviceCode_ButtonVolUp;
case GpioPadName_ButtonVolDn: return DeviceCode_ButtonVolDn;
case GpioPadName_BattMgicIrq: return DeviceCode_BattMgicIrq;
case GpioPadName_RecoveryKey: return DeviceCode_RecoveryKey;
case GpioPadName_PowLcdBlEn: return DeviceCode_PowLcdBlEn;
case GpioPadName_LcdReset: return DeviceCode_LcdReset;
case GpioPadName_PdVconnEn: return DeviceCode_PdVconnEn;
case GpioPadName_PdRstN: return DeviceCode_PdRstN;
case GpioPadName_Bq24190Irq: return DeviceCode_Bq24190Irq;
case GpioPadName_SdevCoaxSel0: return DeviceCode_SdevCoaxSel0;
case GpioPadName_SdWp: return DeviceCode_SdWp;
case GpioPadName_TpReset: return DeviceCode_TpReset;
case GpioPadName_BtGpio2: return DeviceCode_BtGpio2;
case GpioPadName_BtGpio3: return DeviceCode_BtGpio3;
case GpioPadName_BtGpio4: return DeviceCode_BtGpio4;
case GpioPadName_CradleIrq: return DeviceCode_CradleIrq;
case GpioPadName_PowVcpuInt: return DeviceCode_PowVcpuInt;
case GpioPadName_Max77621GpuInt: return DeviceCode_Max77621GpuInt;
case GpioPadName_ExtconChgU: return DeviceCode_ExtconChgU;
case GpioPadName_ExtconChgS: return DeviceCode_ExtconChgS;
case GpioPadName_WifiRfDisable: return DeviceCode_WifiRfDisable;
case GpioPadName_WifiReset: return DeviceCode_WifiReset;
case GpioPadName_ApWakeBt: return DeviceCode_ApWakeBt;
case GpioPadName_BtWakeAp: return DeviceCode_BtWakeAp;
case GpioPadName_BtGpio5: return DeviceCode_BtGpio5;
case GpioPadName_PowLcdVddPEn: return DeviceCode_PowLcdVddPEn;
case GpioPadName_PowLcdVddNEn: return DeviceCode_PowLcdVddNEn;
case GpioPadName_ExtconDetU: return DeviceCode_ExtconDetU;
case GpioPadName_RamCode2: return DeviceCode_RamCode2;
case GpioPadName_Vdd50BEn: return DeviceCode_Vdd50BEn;
case GpioPadName_WifiWakeHost: return DeviceCode_WifiWakeHost;
case GpioPadName_SdCd: return DeviceCode_SdCd;
case GpioPadName_OtgFet1ForSdev: return DeviceCode_OtgFet1ForSdev;
case GpioPadName_OtgFet2ForSdev: return DeviceCode_OtgFet2ForSdev;
case GpioPadName_ExtConWakeU: return DeviceCode_ExtConWakeU;
case GpioPadName_ExtConWakeS: return DeviceCode_ExtConWakeS;
case GpioPadName_PmuIrq: return DeviceCode_PmuIrq;
case GpioPadName_ExtUart2Cts: return DeviceCode_ExtUart2Cts;
case GpioPadName_ExtUart3Cts: return DeviceCode_ExtUart3Cts;
case GpioPadName_5VStepDownEn: return DeviceCode_5VStepDownEn;
case GpioPadName_UsbSwitchB2Oc: return DeviceCode_UsbSwitchB2Oc;
case GpioPadName_5VStepDownPg: return DeviceCode_5VStepDownPg;
case GpioPadName_UsbSwitchAEn: return DeviceCode_UsbSwitchAEn;
case GpioPadName_UsbSwitchAFlag: return DeviceCode_UsbSwitchAFlag;
case GpioPadName_UsbSwitchB3Oc: return DeviceCode_UsbSwitchB3Oc;
case GpioPadName_UsbSwitchB3En: return DeviceCode_UsbSwitchB3En;
case GpioPadName_UsbSwitchB2En: return DeviceCode_UsbSwitchB2En;
case GpioPadName_Hdmi5VEn: return DeviceCode_Hdmi5VEn;
case GpioPadName_UsbSwitchB1En: return DeviceCode_UsbSwitchB1En;
case GpioPadName_HdmiPdTrEn: return DeviceCode_HdmiPdTrEn;
case GpioPadName_FanEn: return DeviceCode_FanEn;
case GpioPadName_UsbSwitchB1Oc: return DeviceCode_UsbSwitchB1Oc;
case GpioPadName_PwmFan: return DeviceCode_PwmFan;
case GpioPadName_HdmiHpd: return DeviceCode_HdmiHpd;
case GpioPadName_Max77812Irq: return DeviceCode_Max77812Irq;
case GpioPadName_Debug0: return DeviceCode_Debug0;
case GpioPadName_Debug1: return DeviceCode_Debug1;
case GpioPadName_Debug2: return DeviceCode_Debug2;
case GpioPadName_Debug3: return DeviceCode_Debug3;
case GpioPadName_NfcIrq: return DeviceCode_NfcIrq;
case GpioPadName_NfcRst: return DeviceCode_NfcRst;
case GpioPadName_McuIrq: return DeviceCode_McuIrq;
case GpioPadName_McuBoot: return DeviceCode_McuBoot;
case GpioPadName_McuRst: return DeviceCode_McuRst;
case GpioPadName_Vdd5V3En: return DeviceCode_Vdd5V3En;
case GpioPadName_McuPor: return DeviceCode_McuPor;
case GpioPadName_LcdGpio1: return DeviceCode_LcdGpio1;
case GpioPadName_NfcEn: return DeviceCode_NfcEn;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}

View File

@@ -41,6 +41,11 @@ namespace ams::gpio {
InterruptStatus_Active = 1,
};
enum WakePinDebugMode {
WakePinDebugMode_AutoImmediateWake = 1,
WakePinDebugMode_NoWake = 2,
};
using WakeBitFlag = util::BitFlagSet<128>;
}

View File

@@ -0,0 +1,25 @@
/*
* 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.hpp>
#include <stratosphere/gpio/gpio_types.hpp>
#include <stratosphere/gpio/sf/gpio_sf_i_manager.hpp>
namespace ams::gpio::server {
std::shared_ptr<gpio::sf::IManager> GetServiceObject();
}

View File

@@ -0,0 +1,31 @@
/*
* 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 <stratosphere/i2c/i2c_types.hpp>
#include <stratosphere/i2c/i2c_select_device_name.hpp>
#include <stratosphere/i2c/i2c_command_list_formatter.hpp>
#include <stratosphere/i2c/sf/i2c_sf_i_session.hpp>
#include <stratosphere/i2c/sf/i2c_sf_i_manager.hpp>
#include <stratosphere/i2c/server/i2c_server_api.hpp>
#include <stratosphere/i2c/driver/i2c_select_driver_api.hpp>
#include <stratosphere/i2c/driver/i2c_driver_service_api.hpp>
#include <stratosphere/i2c/driver/i2c_driver_client_api.hpp>
#include <stratosphere/i2c/driver/i2c_bus_api.hpp>
#include <stratosphere/i2c/driver/impl/i2c_i2c_session_impl.hpp>
#include <stratosphere/i2c/i2c_api.hpp>
#include <stratosphere/i2c/i2c_bus_api.hpp>
#include <stratosphere/i2c/i2c_register_accessor.hpp>

View File

@@ -0,0 +1,24 @@
/*
* 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.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
namespace ams::i2c::driver::board::nintendo_nx {
void Initialize();
}

View File

@@ -0,0 +1,45 @@
/*
* 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.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
namespace ams::i2c::driver {
namespace impl {
constexpr inline size_t I2cSessionSize = 0x60;
constexpr inline size_t I2cSessionAlign = 8;
struct alignas(I2cSessionAlign) I2cSessionImplPadded;
}
struct I2cSession {
util::TypedStorage<impl::I2cSessionImplPadded, impl::I2cSessionSize, impl::I2cSessionAlign> _impl;
};
Result OpenSession(I2cSession *out, DeviceCode device_code);
void CloseSession(I2cSession &session);
Result Send(I2cSession &session, const void *src, size_t src_size, TransactionOption option);
Result Receive(void *dst, size_t dst_size, I2cSession &session, TransactionOption option);
Result ExecuteCommandList(void *dst, size_t dst_size, I2cSession &session, const void *src, size_t src_size);
Result SetRetryPolicy(I2cSession &session, int max_retry_count, int retry_interval_us);
}

View File

@@ -0,0 +1,25 @@
/*
* 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.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
namespace ams::i2c::driver {
void Initialize();
void Finalize();
}

View File

@@ -0,0 +1,30 @@
/*
* 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.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
#include <stratosphere/i2c/driver/i2c_i2c_device_property.hpp>
#include <stratosphere/i2c/driver/i2c_i_i2c_driver.hpp>
namespace ams::i2c::driver {
void RegisterDriver(II2cDriver *driver);
void UnregisterDriver(II2cDriver *driver);
Result RegisterDeviceCode(DeviceCode device_code, I2cDeviceProperty *device);
bool UnregisterDeviceCode(DeviceCode device_code);
}

View File

@@ -0,0 +1,50 @@
/*
* 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.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
#include <stratosphere/ddsf.hpp>
namespace ams::i2c::driver {
class I2cDeviceProperty : public ::ams::ddsf::IDevice {
NON_COPYABLE(I2cDeviceProperty);
NON_MOVEABLE(I2cDeviceProperty);
AMS_DDSF_CASTABLE_TRAITS(ams::i2c::driver::I2cDeviceProperty, ::ams::ddsf::IDevice);
private:
u16 address;
AddressingMode addressing_mode;
util::IntrusiveListNode device_property_list_node;
public:
using DevicePropertyListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&I2cDeviceProperty::device_property_list_node>;
using DevicePropertyList = typename DevicePropertyListTraits::ListType;
friend class util::IntrusiveList<I2cDeviceProperty, util::IntrusiveListMemberTraitsDeferredAssert<&I2cDeviceProperty::device_property_list_node>>;
public:
I2cDeviceProperty() : IDevice(false), address(0), addressing_mode(AddressingMode_SevenBit), device_property_list_node() { /* ... */ }
I2cDeviceProperty(u16 addr, AddressingMode m) : IDevice(false), address(addr), addressing_mode(m), device_property_list_node() { /* ... */ }
virtual ~I2cDeviceProperty() { /* ... */ }
u16 GetAddress() const {
return this->address;
}
AddressingMode GetAddressingMode() const {
return this->addressing_mode;
}
};
}

View 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.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
#include <stratosphere/ddsf.hpp>
namespace ams::i2c::driver {
class I2cDeviceProperty;
class II2cDriver : public ::ams::ddsf::IDriver {
NON_COPYABLE(II2cDriver);
NON_MOVEABLE(II2cDriver);
AMS_DDSF_CASTABLE_TRAITS(ams::i2c::driver::II2cDriver, ::ams::ddsf::IDriver);
public:
II2cDriver() : IDriver() { /* ... */ }
virtual ~II2cDriver() { /* ... */ }
virtual void InitializeDriver() = 0;
virtual void FinalizeDriver() = 0;
virtual Result InitializeDevice(I2cDeviceProperty *device) = 0;
virtual void FinalizeDevice(I2cDeviceProperty *device) = 0;
virtual Result Send(I2cDeviceProperty *device, const void *src, size_t src_size, TransactionOption option) = 0;
virtual Result Receive(void *dst, size_t dst_size, I2cDeviceProperty *device, TransactionOption option) = 0;
virtual os::SdkMutex &GetTransactionOrderMutex() = 0;
virtual void SuspendBus() = 0;
virtual void SuspendPowerBus() = 0;
virtual void ResumeBus() = 0;
virtual void ResumePowerBus() = 0;
virtual const DeviceCode &GetDeviceCode() const = 0;
};
}

View File

@@ -0,0 +1,37 @@
/*
* 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.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
#include <stratosphere/i2c/driver/i2c_i_i2c_driver.hpp>
#include <stratosphere/i2c/driver/i2c_i2c_device_property.hpp>
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
#include <stratosphere/i2c/driver/board/nintendo_nx/i2c_driver_api.hpp>
namespace ams::i2c::driver::board {
using namespace ams::i2c::driver::board::nintendo_nx;
}
#else
#error "Unknown board for ams::i2c::driver::"
#endif

View File

@@ -0,0 +1,93 @@
/*
* 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.hpp>
#include <stratosphere/i2c/driver/i2c_bus_api.hpp>
#include <stratosphere/ddsf.hpp>
namespace ams::i2c::driver {
class I2cDeviceProperty;
}
namespace ams::i2c::driver::impl {
class I2cSessionImpl : public ::ams::ddsf::ISession {
NON_COPYABLE(I2cSessionImpl);
NON_MOVEABLE(I2cSessionImpl);
AMS_DDSF_CASTABLE_TRAITS(ams::i2c::driver::impl::I2cSessionImpl, ::ams::ddsf::ISession);
private:
enum class Command {
Send = 0,
Receive = 1,
};
private:
TimeSpan retry_interval;
int max_retry_count;
private:
Result SendHandler(const u8 **cur_cmd, u8 **cur_dst);
Result ReceiveHandler(const u8 **cur_cmd, u8 **cur_dst);
Result ExtensionHandler(const u8 **cur_cmd, u8 **cur_dst);
Result ExecuteTransactionWithRetry(void *dst, Command command, const void *src, size_t size, TransactionOption option);
public:
I2cSessionImpl(int mr, TimeSpan rt) : retry_interval(rt), max_retry_count(mr) { /* ... */ }
~I2cSessionImpl() {
this->Close();
}
Result Open(I2cDeviceProperty *device, ddsf::AccessMode access_mode);
void Close();
Result Send(const void *src, size_t src_size, TransactionOption option);
Result Receive(void *dst, size_t dst_size, TransactionOption option);
Result ExecuteCommandList(void *dst, size_t dst_size, const void *src, size_t src_size);
Result SetRetryPolicy(int mr, int interval_us);
};
static_assert( sizeof(I2cSessionImpl) <= I2cSessionSize);
static_assert(alignof(I2cSessionImpl) <= I2cSessionAlign);
struct alignas(I2cSessionAlign) I2cSessionImplPadded {
I2cSessionImpl _impl;
u8 _padding[I2cSessionSize - sizeof(I2cSessionImpl)];
};
static_assert( sizeof(I2cSessionImplPadded) == I2cSessionSize);
static_assert(alignof(I2cSessionImplPadded) == I2cSessionAlign);
ALWAYS_INLINE I2cSessionImpl &GetI2cSessionImpl(I2cSession &session) {
return GetReference(session._impl)._impl;
}
ALWAYS_INLINE const I2cSessionImpl &GetI2cSessionImpl(const I2cSession &session) {
return GetReference(session._impl)._impl;
}
ALWAYS_INLINE I2cSessionImpl &GetOpenI2cSessionImpl(I2cSession &session) {
auto &ref = GetReference(session._impl)._impl;
AMS_ASSERT(ref.IsOpen());
return ref;
}
ALWAYS_INLINE const I2cSessionImpl &GetOpenI2cSessionImpl(const I2cSession &session) {
const auto &ref = GetReference(session._impl)._impl;
AMS_ASSERT(ref.IsOpen());
return ref;
}
}

View File

@@ -0,0 +1,28 @@
/*
* 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.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
#include <stratosphere/i2c/sf/i2c_sf_i_manager.hpp>
namespace ams::i2c {
void InitializeWith(std::shared_ptr<i2c::sf::IManager> &&sp, std::shared_ptr<i2c::sf::IManager> &&sp_pcv);
void InitializeEmpty();
void Finalize();
}

View File

@@ -0,0 +1,36 @@
/*
* 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.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
namespace ams::i2c {
struct I2cSession {
void *_session;
};
Result OpenSession(I2cSession *out, DeviceCode device_code);
void CloseSession(I2cSession &session);
Result Send(const I2cSession &session, const void *src, size_t src_size, TransactionOption option);
Result Receive(void *dst, size_t dst_size, const I2cSession &session, TransactionOption option);
Result ExecuteCommandList(void *dst, size_t dst_size, const I2cSession &session, const void *src, size_t src_size);
void SetRetryPolicy(const I2cSession &session, int max_retry_count, int retry_interval_us);
}

View File

@@ -0,0 +1,51 @@
/*
* 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.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
namespace ams::i2c {
constexpr inline size_t CommandListLengthMax = 0x100;
constexpr inline size_t CommandListReceiveCommandSize = 2;
constexpr inline size_t CommandListSendCommandSize = 2;
constexpr inline size_t CommandListSleepCommandSize = 2;
class CommandListFormatter {
NON_COPYABLE(CommandListFormatter);
NON_MOVEABLE(CommandListFormatter);
private:
size_t current_index;
size_t command_list_length;
void *command_list;
private:
Result IsEnqueueAble(size_t sz) const;
public:
CommandListFormatter(void *p, size_t sz) : current_index(0), command_list_length(sz), command_list(p) {
AMS_ABORT_UNLESS(this->command_list_length <= CommandListLengthMax);
}
~CommandListFormatter() { this->command_list = nullptr; }
size_t GetCurrentLength() const { return this->current_index; }
const void *GetListHead() const { return this->command_list; }
Result EnqueueReceiveCommand(i2c::TransactionOption option, size_t size);
Result EnqueueSendCommand(i2c::TransactionOption option, const void *src, size_t size);
Result EnqueueSleepCommand(int us);
};
}

View File

@@ -0,0 +1,250 @@
/*
* 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.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
namespace ams::i2c {
enum I2cBus {
I2cBus_I2c1 = 0,
I2cBus_I2c2 = 1,
I2cBus_I2c3 = 2,
I2cBus_I2c4 = 3,
I2cBus_I2c5 = 4,
I2cBus_I2c6 = 5,
};
constexpr inline const DeviceCode DeviceCode_I2c1 = 0x02000001;
constexpr inline const DeviceCode DeviceCode_I2c2 = 0x02000002;
constexpr inline const DeviceCode DeviceCode_I2c3 = 0x02000003;
constexpr inline const DeviceCode DeviceCode_I2c4 = 0x02000004;
constexpr inline const DeviceCode DeviceCode_I2c5 = 0x02000005;
constexpr inline const DeviceCode DeviceCode_I2c6 = 0x02000006;
constexpr inline DeviceCode ConvertToDeviceCode(I2cBus bus) {
switch (bus) {
case I2cBus_I2c1: return DeviceCode_I2c1;
case I2cBus_I2c2: return DeviceCode_I2c2;
case I2cBus_I2c3: return DeviceCode_I2c3;
case I2cBus_I2c4: return DeviceCode_I2c4;
case I2cBus_I2c5: return DeviceCode_I2c5;
case I2cBus_I2c6: return DeviceCode_I2c6;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
constexpr inline DeviceCode ConvertToI2cBus(DeviceCode dc) {
switch (dc.GetInternalValue()) {
case DeviceCode_I2c1.GetInternalValue(): return I2cBus_I2c1;
case DeviceCode_I2c2.GetInternalValue(): return I2cBus_I2c2;
case DeviceCode_I2c3.GetInternalValue(): return I2cBus_I2c3;
case DeviceCode_I2c4.GetInternalValue(): return I2cBus_I2c4;
case DeviceCode_I2c5.GetInternalValue(): return I2cBus_I2c5;
case DeviceCode_I2c6.GetInternalValue(): return I2cBus_I2c6;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
enum I2cDevice : u32 {
I2cDevice_ClassicController = 0,
I2cDevice_Ftm3bd56 = 1,
I2cDevice_Tmp451 = 2,
I2cDevice_Nct72 = 3,
I2cDevice_Alc5639 = 4,
I2cDevice_Max77620Rtc = 5,
I2cDevice_Max77620Pmic = 6,
I2cDevice_Max77621Cpu = 7,
I2cDevice_Max77621Gpu = 8,
I2cDevice_Bq24193 = 9,
I2cDevice_Max17050 = 10,
I2cDevice_Bm92t30mwv = 11,
I2cDevice_Ina226Vdd15v0Hb = 12,
I2cDevice_Ina226VsysCpuDs = 13,
I2cDevice_Ina226VddCpuAp = 13,
I2cDevice_Ina226VsysGpuDs = 14,
I2cDevice_Ina226VddGpuAp = 14,
I2cDevice_Ina226VsysDdrDs = 15,
I2cDevice_Ina226VddDdr1V1Pmic = 15,
I2cDevice_Ina226VsysAp = 16,
I2cDevice_Ina226VsysBlDs = 17,
I2cDevice_Bh1730 = 18,
I2cDevice_Ina226VsysCore = 19,
I2cDevice_Ina226VddCoreAp = 19,
I2cDevice_Ina226Soc1V8 = 20,
I2cDevice_Ina226VddSoc1V8 = 20,
I2cDevice_Ina226Lpddr1V8 = 21,
I2cDevice_Ina226Vdd1V8 = 21,
I2cDevice_Ina226Reg1V32 = 22,
I2cDevice_Ina226Vdd3V3Sys = 23,
I2cDevice_HdmiDdc = 24,
I2cDevice_HdmiScdc = 25,
I2cDevice_HdmiHdcp = 26,
I2cDevice_Fan53528 = 27,
I2cDevice_Max77812_3 = 28,
I2cDevice_Max77812_2 = 29,
I2cDevice_Ina226VddDdr0V6 = 30,
I2cDevice_HoagNfcIc = 31, /* TODO */
};
/* TODO: Better place for this? */
constexpr inline const DeviceCode DeviceCode_ClassicController = 0x350000C9;
constexpr inline const DeviceCode DeviceCode_Ftm3bd56 = 0x35000033;
constexpr inline const DeviceCode DeviceCode_Tmp451 = 0x3E000001;
constexpr inline const DeviceCode DeviceCode_Nct72 = 0x3E000001;
constexpr inline const DeviceCode DeviceCode_Alc5639 = 0x33000001;
constexpr inline const DeviceCode DeviceCode_Max77620Rtc = 0x3B000001;
constexpr inline const DeviceCode DeviceCode_Max77620Pmic = 0x3A000001;
constexpr inline const DeviceCode DeviceCode_Max77621Cpu = 0x3A000003;
constexpr inline const DeviceCode DeviceCode_Max77621Gpu = 0x3A000004;
constexpr inline const DeviceCode DeviceCode_Bq24193 = 0x39000001;
constexpr inline const DeviceCode DeviceCode_Max17050 = 0x39000033;
constexpr inline const DeviceCode DeviceCode_Bm92t30mwv = 0x040000C9;
constexpr inline const DeviceCode DeviceCode_Ina226Vdd15v0Hb = 0x3F000401;
constexpr inline const DeviceCode DeviceCode_Ina226VsysCpuDs = 0x3F000001;
constexpr inline const DeviceCode DeviceCode_Ina226VddCpuAp = 0x3F000001;
constexpr inline const DeviceCode DeviceCode_Ina226VsysGpuDs = 0x3F000002;
constexpr inline const DeviceCode DeviceCode_Ina226VddGpuAp = 0x3F000002;
constexpr inline const DeviceCode DeviceCode_Ina226VsysDdrDs = 0x3F000003;
constexpr inline const DeviceCode DeviceCode_Ina226VddDdr1V1Pmi = 0x3F000003;
constexpr inline const DeviceCode DeviceCode_Ina226VsysAp = 0x3F000402;
constexpr inline const DeviceCode DeviceCode_Ina226VsysBlDs = 0x3F000403;
constexpr inline const DeviceCode DeviceCode_Bh1730 = 0x35000047;
constexpr inline const DeviceCode DeviceCode_Ina226VsysCore = 0x3F000404;
constexpr inline const DeviceCode DeviceCode_Ina226VddCoreAp = 0x3F000404;
constexpr inline const DeviceCode DeviceCode_Ina226Soc1V8 = 0x3F000405;
constexpr inline const DeviceCode DeviceCode_Ina226VddSoc1V8 = 0x3F000405;
constexpr inline const DeviceCode DeviceCode_Ina226Lpddr1V8 = 0x3F000406;
constexpr inline const DeviceCode DeviceCode_Ina226Vdd1V8 = 0x3F000406;
constexpr inline const DeviceCode DeviceCode_Ina226Reg1V32 = 0x3F000407;
constexpr inline const DeviceCode DeviceCode_Ina226Vdd3V3Sys = 0x3F000408;
constexpr inline const DeviceCode DeviceCode_HdmiDdc = 0x34000001;
constexpr inline const DeviceCode DeviceCode_HdmiScdc = 0x34000002;
constexpr inline const DeviceCode DeviceCode_HdmiHdcp = 0x34000003;
constexpr inline const DeviceCode DeviceCode_Fan53528 = 0x3A000005;
constexpr inline const DeviceCode DeviceCode_Max77812_3 = 0x3A000002;
constexpr inline const DeviceCode DeviceCode_Max77812_2 = 0x3A000006;
constexpr inline const DeviceCode DeviceCode_Ina226VddDdr0V6 = 0x3F000409;
constexpr inline const DeviceCode DeviceCode_HoagNfcIc = 0x36000001;
constexpr inline DeviceCode ConvertToDeviceCode(I2cDevice dv) {
switch (dv) {
case I2cDevice_ClassicController: return DeviceCode_ClassicController;
case I2cDevice_Ftm3bd56: return DeviceCode_Ftm3bd56;
case I2cDevice_Tmp451: return DeviceCode_Tmp451;
case I2cDevice_Nct72: return DeviceCode_Nct72;
case I2cDevice_Alc5639: return DeviceCode_Alc5639;
case I2cDevice_Max77620Rtc: return DeviceCode_Max77620Rtc;
case I2cDevice_Max77620Pmic: return DeviceCode_Max77620Pmic;
case I2cDevice_Max77621Cpu: return DeviceCode_Max77621Cpu;
case I2cDevice_Max77621Gpu: return DeviceCode_Max77621Gpu;
case I2cDevice_Bq24193: return DeviceCode_Bq24193;
case I2cDevice_Max17050: return DeviceCode_Max17050;
case I2cDevice_Bm92t30mwv: return DeviceCode_Bm92t30mwv;
case I2cDevice_Ina226Vdd15v0Hb: return DeviceCode_Ina226Vdd15v0Hb;
case I2cDevice_Ina226VsysCpuDs: return DeviceCode_Ina226VsysCpuDs;
case I2cDevice_Ina226VsysGpuDs: return DeviceCode_Ina226VsysGpuDs;
case I2cDevice_Ina226VsysDdrDs: return DeviceCode_Ina226VsysDdrDs;
case I2cDevice_Ina226VsysAp: return DeviceCode_Ina226VsysAp;
case I2cDevice_Ina226VsysBlDs: return DeviceCode_Ina226VsysBlDs;
case I2cDevice_Bh1730: return DeviceCode_Bh1730;
case I2cDevice_Ina226VsysCore: return DeviceCode_Ina226VsysCore;
case I2cDevice_Ina226Soc1V8: return DeviceCode_Ina226Soc1V8;
case I2cDevice_Ina226Lpddr1V8: return DeviceCode_Ina226Lpddr1V8;
case I2cDevice_Ina226Reg1V32: return DeviceCode_Ina226Reg1V32;
case I2cDevice_Ina226Vdd3V3Sys: return DeviceCode_Ina226Vdd3V3Sys;
case I2cDevice_HdmiDdc: return DeviceCode_HdmiDdc;
case I2cDevice_HdmiScdc: return DeviceCode_HdmiScdc;
case I2cDevice_HdmiHdcp: return DeviceCode_HdmiHdcp;
case I2cDevice_Fan53528: return DeviceCode_Fan53528;
case I2cDevice_Max77812_3: return DeviceCode_Max77812_3;
case I2cDevice_Max77812_2: return DeviceCode_Max77812_2;
case I2cDevice_Ina226VddDdr0V6: return DeviceCode_Ina226VddDdr0V6;
case I2cDevice_HoagNfcIc: return DeviceCode_HoagNfcIc;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
constexpr inline I2cDevice ConvertToI2cDevice(DeviceCode dc) {
switch (dc.GetInternalValue()) {
case DeviceCode_ClassicController.GetInternalValue(): return I2cDevice_ClassicController;
case DeviceCode_Ftm3bd56 .GetInternalValue(): return I2cDevice_Ftm3bd56;
case DeviceCode_Tmp451 .GetInternalValue(): return I2cDevice_Tmp451;
/* case DeviceCode_Nct72 .GetInternalValue(): return I2cDevice_Nct72; */
case DeviceCode_Alc5639 .GetInternalValue(): return I2cDevice_Alc5639;
case DeviceCode_Max77620Rtc .GetInternalValue(): return I2cDevice_Max77620Rtc;
case DeviceCode_Max77620Pmic .GetInternalValue(): return I2cDevice_Max77620Pmic;
case DeviceCode_Max77621Cpu .GetInternalValue(): return I2cDevice_Max77621Cpu;
case DeviceCode_Max77621Gpu .GetInternalValue(): return I2cDevice_Max77621Gpu;
case DeviceCode_Bq24193 .GetInternalValue(): return I2cDevice_Bq24193;
case DeviceCode_Max17050 .GetInternalValue(): return I2cDevice_Max17050;
case DeviceCode_Bm92t30mwv .GetInternalValue(): return I2cDevice_Bm92t30mwv;
case DeviceCode_Ina226Vdd15v0Hb .GetInternalValue(): return I2cDevice_Ina226Vdd15v0Hb;
case DeviceCode_Ina226VsysCpuDs .GetInternalValue(): return I2cDevice_Ina226VsysCpuDs;
case DeviceCode_Ina226VsysGpuDs .GetInternalValue(): return I2cDevice_Ina226VsysGpuDs;
case DeviceCode_Ina226VsysDdrDs .GetInternalValue(): return I2cDevice_Ina226VsysDdrDs;
case DeviceCode_Ina226VsysAp .GetInternalValue(): return I2cDevice_Ina226VsysAp;
case DeviceCode_Ina226VsysBlDs .GetInternalValue(): return I2cDevice_Ina226VsysBlDs;
case DeviceCode_Bh1730 .GetInternalValue(): return I2cDevice_Bh1730;
case DeviceCode_Ina226VsysCore .GetInternalValue(): return I2cDevice_Ina226VsysCore;
case DeviceCode_Ina226Soc1V8 .GetInternalValue(): return I2cDevice_Ina226Soc1V8;
case DeviceCode_Ina226Lpddr1V8 .GetInternalValue(): return I2cDevice_Ina226Lpddr1V8;
case DeviceCode_Ina226Reg1V32 .GetInternalValue(): return I2cDevice_Ina226Reg1V32;
case DeviceCode_Ina226Vdd3V3Sys .GetInternalValue(): return I2cDevice_Ina226Vdd3V3Sys;
case DeviceCode_HdmiDdc .GetInternalValue(): return I2cDevice_HdmiDdc;
case DeviceCode_HdmiScdc .GetInternalValue(): return I2cDevice_HdmiScdc;
case DeviceCode_HdmiHdcp .GetInternalValue(): return I2cDevice_HdmiHdcp;
case DeviceCode_Fan53528 .GetInternalValue(): return I2cDevice_Fan53528;
case DeviceCode_Max77812_3 .GetInternalValue(): return I2cDevice_Max77812_3;
case DeviceCode_Max77812_2 .GetInternalValue(): return I2cDevice_Max77812_2;
case DeviceCode_Ina226VddDdr0V6 .GetInternalValue(): return I2cDevice_Ina226VddDdr0V6;
case DeviceCode_HoagNfcIc .GetInternalValue(): return I2cDevice_HoagNfcIc;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
constexpr bool IsPowerBusDeviceCode(DeviceCode device_code) {
switch (device_code.GetInternalValue()) {
case DeviceCode_Max77620Pmic.GetInternalValue():
case DeviceCode_Max77812_3 .GetInternalValue():
case DeviceCode_Max77621Cpu .GetInternalValue():
case DeviceCode_Max77621Gpu .GetInternalValue():
case DeviceCode_Fan53528 .GetInternalValue():
case DeviceCode_Max77812_2 .GetInternalValue():
case DeviceCode_Max77620Rtc .GetInternalValue():
return true;
default:
return false;
}
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
#include <stratosphere/i2c/i2c_command_list_formatter.hpp>
#include <stratosphere/i2c/i2c_bus_api.hpp>
namespace ams::i2c {
template<typename RegType> requires std::unsigned_integral<RegType>
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>(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<typename RegType> requires std::unsigned_integral<RegType>
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>(i2c::TransactionOption_StartCondition | i2c::TransactionOption_StopCondition);
R_TRY(i2c::Send(session, buf, sizeof(buf), StopOption));
return ResultSuccess();
}
}

View File

@@ -0,0 +1,24 @@
/*
* 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.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
#include <stratosphere/i2c/i2c_device_name.board.nintendo_nx.hpp>
#else
/* Error? */
#endif

View File

@@ -0,0 +1,40 @@
/*
* 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.hpp>
namespace ams::i2c {
enum TransactionOption : u32 {
TransactionOption_StartCondition = (1u << 0),
TransactionOption_StopCondition = (1u << 1),
TransactionOption_MaxBits = (1u << 30),
};
enum AddressingMode : u32 {
AddressingMode_SevenBit = 0,
};
enum SpeedMode : u32 {
SpeedMode_Standard = 100000,
SpeedMode_Fast = 400000,
SpeedMode_FastPlus = 1000000,
SpeedMode_HighSpeed = 3400000,
};
using I2cCommand = u8;
}

View File

@@ -0,0 +1,26 @@
/*
* 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.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
#include <stratosphere/i2c/sf/i2c_sf_i_manager.hpp>
namespace ams::i2c::server {
std::shared_ptr<i2c::sf::IManager> GetServiceObject();
std::shared_ptr<i2c::sf::IManager> GetServiceObjectPowerBus();
}

View File

@@ -0,0 +1,34 @@
/*
* 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.hpp>
#include <stratosphere/ddsf/ddsf_types.hpp>
#include <stratosphere/i2c/i2c_select_device_name.hpp>
#include <stratosphere/i2c/sf/i2c_sf_i_session.hpp>
namespace ams::i2c::sf {
#define AMS_I2C_I_MANAGER_INTERFACE_INFO(C, H) \
AMS_SF_METHOD_INFO(C, H, 0, Result, OpenSessionForDev, (ams::sf::Out<std::shared_ptr<i2c::sf::ISession>> out, s32 bus_idx, u16 slave_address, i2c::AddressingMode addressing_mode, i2c::SpeedMode speed_mode) ) \
AMS_SF_METHOD_INFO(C, H, 1, Result, OpenSession, (ams::sf::Out<std::shared_ptr<i2c::sf::ISession>> out, i2c::I2cDevice device) ) \
AMS_SF_METHOD_INFO(C, H, 2, Result, HasDevice, (ams::sf::Out<bool> out, i2c::I2cDevice device), hos::Version_Min, hos::Version_5_1_0) \
AMS_SF_METHOD_INFO(C, H, 3, Result, HasDeviceForDev, (ams::sf::Out<bool> out, i2c::I2cDevice device), hos::Version_Min, hos::Version_5_1_0) \
AMS_SF_METHOD_INFO(C, H, 4, Result, OpenSession2, (ams::sf::Out<std::shared_ptr<i2c::sf::ISession>> out, DeviceCode device_code), hos::Version_6_0_0 )
AMS_SF_DEFINE_INTERFACE(IManager, AMS_I2C_I_MANAGER_INTERFACE_INFO)
}

View File

@@ -0,0 +1,34 @@
/*
* 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.hpp>
#include <stratosphere/i2c/i2c_types.hpp>
namespace ams::i2c::sf {
#define AMS_I2C_I_SESSION_INTERFACE_INFO(C, H) \
AMS_SF_METHOD_INFO(C, H, 0, Result, SendOld, (const ams::sf::InBuffer &in_data, i2c::TransactionOption option), hos::Version_Min, hos::Version_5_1_0) \
AMS_SF_METHOD_INFO(C, H, 1, Result, ReceiveOld, (const ams::sf::OutBuffer &out_data, i2c::TransactionOption option), hos::Version_Min, hos::Version_5_1_0) \
AMS_SF_METHOD_INFO(C, H, 2, Result, ExecuteCommandListOld, (const ams::sf::OutBuffer &rcv_buf, const ams::sf::InPointerArray<i2c::I2cCommand> &command_list), hos::Version_Min, hos::Version_5_1_0) \
AMS_SF_METHOD_INFO(C, H, 10, Result, Send, (const ams::sf::InAutoSelectBuffer &in_data, i2c::TransactionOption option) ) \
AMS_SF_METHOD_INFO(C, H, 11, Result, Receive, (const ams::sf::OutAutoSelectBuffer &out_data, i2c::TransactionOption option) ) \
AMS_SF_METHOD_INFO(C, H, 12, Result, ExecuteCommandList, (const ams::sf::OutAutoSelectBuffer &rcv_buf, const ams::sf::InPointerArray<i2c::I2cCommand> &command_list) ) \
AMS_SF_METHOD_INFO(C, H, 13, Result, SetRetryPolicy, (s32 max_retry_count, s32 retry_interval_us), hos::Version_6_0_0 )
AMS_SF_DEFINE_INTERFACE(ISession, AMS_I2C_I_SESSION_INTERFACE_INFO)
}

View File

@@ -28,6 +28,7 @@
#include <stratosphere/os/os_mutex.hpp>
#include <stratosphere/os/os_condition_variable.hpp>
#include <stratosphere/os/os_sdk_mutex.hpp>
#include <stratosphere/os/os_sdk_condition_variable.hpp>
#include <stratosphere/os/os_rw_lock.hpp>
#include <stratosphere/os/os_transfer_memory.hpp>
#include <stratosphere/os/os_semaphore.hpp>

View File

@@ -0,0 +1,74 @@
/*
* 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.hpp>
#include <stratosphere/os/os_sdk_mutex.hpp>
#include <stratosphere/os/impl/os_internal_condition_variable.hpp>
namespace ams::os {
struct SdkConditionVariableType {
union {
s32 _arr[sizeof(impl::InternalConditionVariableStorage) / sizeof(s32)];
impl::InternalConditionVariableStorage _storage;
};
void Initialize() {
GetReference(this->_storage).Initialize();
}
void Wait(SdkMutexType &mutex);
bool TimedWait(SdkMutexType &mutex, TimeSpan timeout);
/* TODO: SdkRecursiveMutexType */
void Signal() {
GetReference(this->_storage).Signal();
}
void Broadcast() {
GetReference(this->_storage).Broadcast();
}
};
static_assert(std::is_trivial<SdkConditionVariableType>::value);
class SdkConditionVariable {
private:
SdkConditionVariableType cv;
public:
constexpr SdkConditionVariable() : cv{{0}} { /* ... */ }
void Wait(SdkMutex &m) {
return this->cv.Wait(m.mutex);
}
bool TimedWait(SdkMutex &m, TimeSpan timeout) {
return this->cv.TimedWait(m.mutex, timeout);
}
/* TODO: SdkRecursiveMutexType */
void Signal() {
return this->cv.Signal();
}
void Broadcast() {
return this->cv.Broadcast();
}
};
}

View File

@@ -0,0 +1,20 @@
/*
* 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 <stratosphere/pcv/pcv_types.hpp>
#include <stratosphere/pcv/pcv_api.hpp>

View File

@@ -0,0 +1,30 @@
/*
* 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.hpp>
#include <stratosphere/pcv/pcv_types.hpp>
namespace ams::pcv {
void Initialize();
void Finalize();
Result SetClockEnabled(Module module, bool en);
Result SetClockRate(Module module, ClockHz hz);
Result SetReset(Module module, bool en);
}

View File

@@ -0,0 +1,116 @@
/*
* 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.hpp>
namespace ams::pcv {
using ClockHz = u32;
using MicroVolt = s32;
using MilliC = s32;
/* TODO: Device codes? */
enum Module {
Module_Cpu = 0,
Module_Gpu = 1,
Module_I2s1 = 2,
Module_I2s2 = 3,
Module_I2s3 = 4,
Module_Pwm = 5,
Module_I2c1 = 6,
Module_I2c2 = 7,
Module_I2c3 = 8,
Module_I2c4 = 9,
Module_I2c5 = 10,
Module_I2c6 = 11,
Module_Spi1 = 12,
Module_Spi2 = 13,
Module_Spi3 = 14,
Module_Spi4 = 15,
Module_Disp1 = 16,
Module_Disp2 = 17,
Module_Isp = 18,
Module_Vi = 19,
Module_Sdmmc1 = 20,
Module_Sdmmc2 = 21,
Module_Sdmmc3 = 22,
Module_Sdmmc4 = 23,
Module_Owr = 24,
Module_Csite = 25,
Module_Tsec = 26,
Module_Mselect = 27,
Module_Hda2codec2x = 28,
Module_Actmon = 29,
Module_I2cSlow = 30,
Module_Sor1 = 31,
Module_Sata = 32,
Module_Hda = 33,
Module_XusbCoreHostSrc = 34,
Module_XusbFalconSrc = 35,
Module_XusbFsSrc = 36,
Module_XusbCoreDevSrc = 37,
Module_XusbSsSrc = 38,
Module_UartA = 39,
Module_UartB = 40,
Module_UartC = 41,
Module_UartD = 42,
Module_Host1x = 43,
Module_Entropy = 44,
Module_SocTherm = 45,
Module_Vic = 46,
Module_Nvenc = 47,
Module_Nvjpg = 48,
Module_Nvdec = 49,
Module_Qspi = 50,
Module_ViI2c = 51,
Module_Tsecb = 52,
Module_Ape = 53,
Module_AudioDsp = 54,
Module_AudioUart = 55,
Module_Emc = 56,
Module_Plle = 57,
Module_PlleHwSeq = 58,
Module_Dsi = 59,
Module_Maud = 60,
Module_Dpaux1 = 61,
Module_MipiCal = 62,
Module_UartFstMipiCal = 63,
Module_Osc = 64,
Module_SysBus = 65,
Module_SorSafe = 66,
Module_XusbSs = 67,
Module_XusbHost = 68,
Module_XusbDevice = 69,
Module_Extperiph1 = 70,
Module_Ahub = 71,
Module_Hda2hdmicodec = 72,
Module_Gpuaux = 73,
Module_UsbD = 74,
Module_Usb2 = 75,
Module_Pcie = 76,
Module_Afi = 77,
Module_PciExClk = 78,
Module_PExUsbPhy = 79,
Module_XUsbPadCtl = 80,
Module_Apbdma = 81,
Module_Usb2TrkClk = 82,
Module_XUsbIoPll = 83,
Module_XUsbIoPllHwSeq = 84,
Module_Cec = 85,
Module_Extperiph2 = 86,
};
}

View File

@@ -0,0 +1,20 @@
/*
* 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 <stratosphere/pinmux/pinmux_api.hpp>
#include <stratosphere/pinmux/driver/pinmux_driver_api.hpp>

View File

@@ -0,0 +1,27 @@
/*
* 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.hpp>
namespace ams::pinmux::driver {
void Initialize();
void Finalize();
void SetInitialConfig();
void SetInitialDrivePadConfig();
}

View File

@@ -14,10 +14,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere.hpp>
#include <vapours.hpp>
namespace ams::pinmux {
void SetInitialConfiguration();
/* ... */
}

View File

@@ -0,0 +1,26 @@
/*
* 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 <stratosphere/powctl/powctl_types.hpp>
#include <stratosphere/powctl/powctl_select_devices.hpp>
#include <stratosphere/powctl/powctl_session_api.hpp>
#include <stratosphere/powctl/powctl_battery_api.hpp>
#include <stratosphere/powctl/powctl_charger_api.hpp>
#include <stratosphere/powctl/impl/powctl_battery_charge_percentage.hpp>
#include <stratosphere/powctl/driver/powctl_driver_api.hpp>
#include <stratosphere/powctl/driver/impl/powctl_select_charger_parameters.hpp>
#include <stratosphere/powctl/driver/impl/powctl_charge_arbiter.hpp>

View File

@@ -0,0 +1,161 @@
/*
* 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.hpp>
#include <stratosphere/powctl/powctl_types.hpp>
#include <stratosphere/powctl/driver/impl/powctl_select_charger_parameters.hpp>
namespace ams::powctl::driver::impl {
class ChargeArbiter {
private:
const ChargeParametersRule *rules;
size_t num_rules;
int charge_voltage_limit;
BatteryTemperatureLevel temperature_level;
int avg_v_cell;
int open_circuit_voltage;
bool has_battery_done_current;
int battery_done_current;
PowerState power_state;
const ChargeParametersRule *selected_rule;
bool check_battery_done_current;
private:
static constexpr bool IsInRange(int value, int min, int max) {
if (!(min <= value)) {
return false;
}
if (max == std::numeric_limits<int>::max()) {
return value <= max;
} else {
return value < max;
}
}
bool IsAcceptablePowerState(const PowerState *acceptable, size_t num_acceptable) const {
for (size_t i = 0; i < num_acceptable; ++i) {
if (this->power_state == acceptable[i]) {
return true;
}
}
return false;
}
public:
ChargeArbiter(const ChargeParametersRule *r, size_t nr, int cvl)
: rules(r), num_rules(nr), charge_voltage_limit(cvl), temperature_level(BatteryTemperatureLevel::Medium),
avg_v_cell(4080), open_circuit_voltage(4001), has_battery_done_current(false), battery_done_current(0),
power_state(PowerState::FullAwake), selected_rule(nullptr), check_battery_done_current(false)
{
this->UpdateSelectedRule();
}
void SetBatteryTemperatureLevel(BatteryTemperatureLevel btl) {
this->temperature_level = btl;
this->UpdateSelectedRule();
}
void SetBatteryAverageVCell(int avg) {
this->avg_v_cell = avg;
this->UpdateSelectedRule();
}
void SetBatteryOpenCircuitVoltage(int ocv) {
this->open_circuit_voltage = ocv;
this->UpdateSelectedRule();
}
void SetBatteryDoneCurrent(int current) {
this->battery_done_current = current;
this->has_battery_done_current = true;
this->UpdateSelectedRule();
}
void SetPowerState(PowerState ps) {
this->power_state = ps;
this->UpdateSelectedRule();
}
int GetChargeVoltageLimit() const {
return this->charge_voltage_limit;
}
bool IsBatteryDoneCurrentAcceptable(int current) const {
const auto *rule = this->GetSelectedRule();
AMS_ASSERT(rule != nullptr);
return IsInRange(0, rule->min_battery_done_current, rule->max_battery_done_current);
}
const ChargeParametersRule *GetSelectedRule() const {
return this->selected_rule;
}
void UpdateSelectedRule() {
/* Try to find an entry that fits our current requirements. */
const ChargeParametersRule *best_rule = nullptr;
for (size_t i = 0; i < this->num_rules; ++i) {
/* Get the current rule. */
const ChargeParametersRule &cur_rule = this->rules[i];
/* Check the temperature level. */
if (this->temperature_level != cur_rule.temperature_level) {
continue;
}
/* Check that average voltage is in range. */
if (!IsInRange(this->avg_v_cell, cur_rule.min_avg_v_cell, cur_rule.max_avg_v_cell)) {
continue;
}
/* Check that open circuit voltage is in range. */
if (!IsInRange(this->open_circuit_voltage, cur_rule.min_open_circuit_voltage, cur_rule.max_open_circuit_voltage)) {
continue;
}
/* Check if our power state is acceptable. */
if (!this->IsAcceptablePowerState(cur_rule.acceptable_power_states, cur_rule.num_acceptable_power_states)) {
continue;
}
/* The limit is probably acceptable. */
if (this->selected_rule != std::addressof(cur_rule)) {
/* We're selecting a new rule. Check if our need to deal with battery current is acceptable. */
if (cur_rule.check_battery_current && this->check_battery_done_current) {
continue;
}
/* Set whether we need to check the battery done current. */
this->has_battery_done_current = false;
this->check_battery_done_current |= cur_rule.check_battery_current;
} else {
/* We're selecting the currently selected rule. Make sure the battery done current is acceptable if we have one. */
if (this->has_battery_done_current && !IsInRange(this->battery_done_current, cur_rule.min_battery_done_current, cur_rule.max_battery_done_current)) {
continue;
}
}
/* Select the current rule. */
best_rule = std::addressof(cur_rule);
break;
}
/* Update our selected rule. */
this->selected_rule = best_rule;
}
};
}

View File

@@ -0,0 +1,64 @@
/*
* 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.hpp>
#include <stratosphere/powctl/powctl_types.hpp>
namespace ams::powctl::driver::impl {
struct ChargeParametersRule {
BatteryTemperatureLevel temperature_level;
int min_avg_v_cell;
int max_avg_v_cell;
int min_open_circuit_voltage;
int max_open_circuit_voltage;
int min_battery_done_current;
int max_battery_done_current;
const PowerState *acceptable_power_states;
size_t num_acceptable_power_states;
bool check_battery_current;
bool reinitialize_charger;
int charge_voltage_limit;
int fast_charge_current_limit;
int battery_compensation;
int voltage_clamp;
};
struct UnknownParameterX {
int _00;
int _04;
double _08;
double _10;
};
struct ChargeParameters {
int temp_min;
int temp_low;
int temp_high;
int temp_max;
int low_voltage_fast_charge_current_limit;
int default_charge_voltage_limit;
const UnknownParameterX *unknown_x_table;
size_t x_table_size;
double _28;
double _30;
const ChargeParametersRule *rules;
size_t num_rules;
};
const ChargeParameters &GetChargeParameters();
}

View File

@@ -0,0 +1,26 @@
/*
* 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.hpp>
#include <stratosphere/powctl/powctl_types.hpp>
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
#include <stratosphere/powctl/driver/impl/powctl_charger_parameters.board.nintendo_nx.hpp>
#else
#error "unknown board for powctl::driver::impl::ChargerParameters"
#endif

View File

@@ -0,0 +1,25 @@
/*
* 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.hpp>
#include <stratosphere/powctl/powctl_types.hpp>
namespace ams::powctl {
void Initialize(bool enable_interrupt_handlers);
void Finalize();
}

View File

@@ -0,0 +1,65 @@
/*
* 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.hpp>
#include <stratosphere/powctl/powctl_types.hpp>
namespace ams::powctl::impl {
constexpr inline const double MinRawDefaultPercentage = 3.0;
constexpr inline const double MaxRawDefaultPercentage = 99.0;
constexpr inline const double MinRawThresholdPercentage = 11.0;
constexpr inline const int MinDisplayPercentage = 1;
constexpr inline const int MaxDisplayPercentage = 100;
constexpr inline void CalculateMarginatedRawPercentage(double *out_marginated_min, double *out_marginated_max, double min, double max) {
/* Ensure minimum is in correct range. */
min = std::max(std::min(min, MinRawThresholdPercentage), MinRawDefaultPercentage);
/* Calculate the marginated values. */
constexpr const double MinMarginPercentage = 0.93359375;
constexpr const double MaxMarginPercentage = -0.83593750;
const auto margin_factor = (max - min) / (MaxRawDefaultPercentage - MinRawDefaultPercentage);
*out_marginated_min = min + MinMarginPercentage * margin_factor;
*out_marginated_max = max + MaxMarginPercentage * margin_factor;
}
constexpr inline int GetDisplayPercentage(double raw_percentage, double min, double max) {
/* Calculate the display percentage. */
constexpr const double BaseDisplayPercentage = 2.0;
const auto display_percentage = BaseDisplayPercentage + ((static_cast<double>(MaxDisplayPercentage - MinDisplayPercentage) * (raw_percentage - min)) / (max - min));
/* Clamp the display percentage within bounds. */
return std::max(std::min(static_cast<int>(display_percentage), MaxDisplayPercentage), MinDisplayPercentage);
}
constexpr inline int ConvertBatteryChargePercentage(double raw_percentage, double min, double max) {
/* Marginate the min/max. */
double marginated_min = 0.0, marginated_max = 0.0;
CalculateMarginatedRawPercentage(std::addressof(marginated_min), std::addressof(marginated_max), min, max);
/* Convert to display percentage. */
return GetDisplayPercentage(raw_percentage, marginated_min, marginated_max);
}
constexpr inline int ConvertBatteryChargePercentage(double raw_percentage) {
return ConvertBatteryChargePercentage(raw_percentage, MinRawDefaultPercentage, MaxRawDefaultPercentage);
}
}

View File

@@ -0,0 +1,70 @@
/*
* 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.hpp>
#include <stratosphere/powctl/powctl_types.hpp>
#include <stratosphere/powctl/powctl_session_api.hpp>
namespace ams::powctl {
/* Battery API. */
Result GetBatterySocRep(float *out_percent, Session &session);
Result GetBatterySocVf(float *out_percent, Session &session);
Result GetBatteryFullCapacity(int *out_mah, Session &session);
Result GetBatteryRemainingCapacity(int *out_mah, Session &session);
Result SetBatteryPercentageMinimumAlertThreshold(Session &session, float percentage);
Result SetBatteryPercentageMaximumAlertThreshold(Session &session, float percentage);
Result SetBatteryPercentageFullThreshold(Session &session, float percentage);
Result GetBatteryAverageCurrent(int *out_ma, Session &session);
Result GetBatteryCurrent(int *out_ma, Session &session);
Result GetBatteryInternalState(void *dst, size_t *out_size, Session &session, size_t dst_size);
Result SetBatteryInternalState(Session &session, const void *src, size_t src_size);
Result GetBatteryNeedToRestoreParameters(bool *out, Session &session);
Result SetBatteryNeedToRestoreParameters(Session &session, bool en);
Result IsBatteryI2cShutdownEnabled(bool *out, Session &session);
Result SetBatteryI2cShutdownEnabled(Session &session, bool en);
Result IsBatteryPresent(bool *out, Session &session);
Result GetBatteryCycles(int *out, Session &session);
Result SetBatteryCycles(Session &session, int cycles);
Result GetBatteryAge(float *out_percent, Session &session);
Result GetBatteryTemperature(float *out_c, Session &session);
Result GetBatteryMaximumTemperature(float *out_c, Session &session);
Result SetBatteryTemperatureMinimumAlertThreshold(Session &session, float c);
Result SetBatteryTemperatureMaximumAlertThreshold(Session &session, float c);
Result GetBatteryVCell(int *out_mv, Session &session);
Result GetBatteryAverageVCell(int *out_mv, Session &session);
Result GetBatteryAverageVCellTime(TimeSpan *out, Session &session);
Result GetBatteryOpenCircuitVoltage(int *out_mv, Session &session);
Result SetBatteryVoltageMinimumAlertThreshold(Session &session, int mv);
Result SetBatteryVoltageMaximumAlertThreshold(Session &session, int mv);
}

View File

@@ -0,0 +1,59 @@
/*
* 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.hpp>
#include <stratosphere/powctl/powctl_types.hpp>
#include <stratosphere/powctl/powctl_session_api.hpp>
namespace ams::powctl {
/* Charger API. */
Result GetChargerChargeCurrentState(ChargeCurrentState *out, Session &session);
Result SetChargerChargeCurrentState(Session &session, ChargeCurrentState state);
Result GetChargerFastChargeCurrentLimit(int *out_ma, Session &session);
Result SetChargerFastChargeCurrentLimit(Session &session, int ma);
Result GetChargerChargeVoltageLimit(int *out_mv, Session &session);
Result SetChargerChargeVoltageLimit(Session &session, int mv);
Result SetChargerChargerConfiguration(Session &session, ChargerConfiguration cfg);
Result IsChargerHiZEnabled(bool *out, Session &session);
Result SetChargerHiZEnabled(Session &session, bool en);
Result GetChargerInputCurrentLimit(int *out_ma, Session &session);
Result SetChargerInputCurrentLimit(Session &session, int ma);
Result SetChargerInputVoltageLimit(Session &session, int mv);
Result SetChargerBoostModeCurrentLimit(Session &session, int ma);
Result GetChargerChargerStatus(ChargerStatus *out, Session &session);
Result IsChargerWatchdogTimerEnabled(bool *out, Session &session);
Result SetChargerWatchdogTimerEnabled(Session &session, bool en);
Result SetChargerWatchdogTimerTimeout(Session &session, TimeSpan timeout);
Result ResetChargerWatchdogTimer(Session &session);
Result GetChargerBatteryCompensation(int *out_mo, Session &session);
Result SetChargerBatteryCompensation(Session &session, int mo);
Result GetChargerVoltageClamp(int *out_mv, Session &session);
Result SetChargerVoltageClamp(Session &session, int mv);
}

View File

@@ -0,0 +1,29 @@
/*
* 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.hpp>
#include <stratosphere/i2c.hpp>
#include <stratosphere/powctl/powctl_types.hpp>
namespace ams::powctl {
/* Fuel Gauge. */
constexpr inline const DeviceCode DeviceCode_Max17050 = i2c::DeviceCode_Max17050;
/* Charger. */
constexpr inline const DeviceCode DeviceCode_Bq24193 = i2c::DeviceCode_Bq24193;
}

View File

@@ -0,0 +1,24 @@
/*
* 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.hpp>
#include <stratosphere/powctl/powctl_types.hpp>
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
#include <stratosphere/powctl/powctl_devices.board.nintendo_nx.hpp>
#else
/* Error? */
#endif

View File

@@ -0,0 +1,46 @@
/*
* 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.hpp>
#include <stratosphere/powctl/powctl_types.hpp>
namespace ams::powctl {
namespace impl {
class SessionImpl : public ::ams::ddsf::ISession {
NON_COPYABLE(SessionImpl);
NON_MOVEABLE(SessionImpl);
AMS_DDSF_CASTABLE_TRAITS(ams::powctl::impl::SessionImpl, ::ams::ddsf::ISession);
public:
SessionImpl() : ISession() { /* ... */ }
~SessionImpl() { ddsf::CloseSession(this); }
};
}
struct Session {
bool has_session;
TYPED_STORAGE(impl::SessionImpl) impl_storage;
Session() : has_session(false) { /* ... */ }
};
Result OpenSession(Session *out, DeviceCode device_code, ddsf::AccessMode access_mode);
void CloseSession(Session &session);
}

View File

@@ -0,0 +1,58 @@
/*
* 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.hpp>
namespace ams::powctl {
/* Charger types. */
enum ChargerStatus {
ChargerStatus_Charging = 1,
ChargerStatus_NotCharging = 3,
ChargerStatus_ChargeTerminationDone = 4,
};
enum ChargerConfiguration {
ChargerConfiguration_ChargeDisable = 1,
ChargerConfiguration_ChargeBattery = 2,
ChargerConfiguration_Otg = 3,
};
enum ChargeCurrentState {
ChargeCurrentState_Unknown = 0x0,
ChargeCurrentState_NotCharging = 0x1,
ChargeCurrentState_ChargingForce20Percent = 0x2,
ChargeCurrentState_Charging = 0x3,
};
enum class BatteryTemperatureLevel {
TooLow = 0,
Low = 1,
Medium = 2,
High = 3,
TooHigh = 4,
};
enum class PowerState {
FullAwake = 0,
MinimumAwake = 1,
SleepCharge = 2,
SleepDischarge = 3,
ShutdownChargeMain = 4,
};
}

View File

@@ -0,0 +1,28 @@
/*
* 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 <stratosphere/pwm/pwm_types.hpp>
#include <stratosphere/pwm/pwm_select_channel_name.hpp>
#include <stratosphere/pwm/sf/pwm_sf_i_channel_session.hpp>
#include <stratosphere/pwm/sf/pwm_sf_i_manager.hpp>
#include <stratosphere/pwm/server/pwm_server_api.hpp>
#include <stratosphere/pwm/driver/pwm_select_driver_api.hpp>
#include <stratosphere/pwm/driver/pwm_driver_service_api.hpp>
#include <stratosphere/pwm/driver/pwm_driver_client_api.hpp>
#include <stratosphere/pwm/driver/pwm_channel_api.hpp>
#include <stratosphere/pwm/pwm_api.hpp>
#include <stratosphere/pwm/pwm_channel_api.hpp>

View File

@@ -0,0 +1,24 @@
/*
* 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.hpp>
#include <stratosphere/pwm/pwm_types.hpp>
namespace ams::pwm::driver::board::nintendo_nx {
void Initialize();
}

View File

@@ -0,0 +1,50 @@
/*
* 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.hpp>
#include <stratosphere/pwm/pwm_types.hpp>
namespace ams::pwm::driver {
namespace impl {
constexpr inline size_t ChannelSessionSize = 0x60;
constexpr inline size_t ChannelSessionAlign = 8;
struct alignas(ChannelSessionAlign) ChannelSessionImplPadded;
}
struct ChannelSession {
util::TypedStorage<impl::ChannelSessionImplPadded, impl::ChannelSessionSize, impl::ChannelSessionAlign> _impl;
};
Result OpenSession(ChannelSession *out, DeviceCode device_code);
void CloseSession(ChannelSession &session);
void SetPeriod(ChannelSession &session, TimeSpan period);
TimeSpan GetPeriod(ChannelSession &session);
void SetDuty(ChannelSession &session, int duty);
int GetDuty(ChannelSession &session);
void SetEnabled(ChannelSession &session, bool en);
bool GetEnabled(ChannelSession &session);
void SetScale(ChannelSession &session, double scale);
double GetScale(ChannelSession &session);
}

View File

@@ -0,0 +1,25 @@
/*
* 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.hpp>
#include <stratosphere/pwm/pwm_types.hpp>
namespace ams::pwm::driver {
void Initialize();
void Finalize();
}

View File

@@ -0,0 +1,30 @@
/*
* 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.hpp>
#include <stratosphere/pwm/pwm_types.hpp>
#include <stratosphere/pwm/driver/pwm_i_pwm_device.hpp>
#include <stratosphere/pwm/driver/pwm_i_pwm_driver.hpp>
namespace ams::pwm::driver {
void RegisterDriver(IPwmDriver *driver);
void UnregisterDriver(IPwmDriver *driver);
Result RegisterDeviceCode(DeviceCode device_code, IPwmDevice *device);
bool UnregisterDeviceCode(DeviceCode device_code);
}

View File

@@ -0,0 +1,36 @@
/*
* 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.hpp>
#include <stratosphere/pwm/pwm_types.hpp>
#include <stratosphere/ddsf.hpp>
namespace ams::pwm::driver {
class IPwmDevice : public ::ams::ddsf::IDevice {
NON_COPYABLE(IPwmDevice);
NON_MOVEABLE(IPwmDevice);
AMS_DDSF_CASTABLE_TRAITS(ams::pwm::driver::IPwmDevice, ::ams::ddsf::IDevice);
private:
int channel_index;
public:
IPwmDevice(int id) : IDevice(false), channel_index(id) { /* ... */ }
virtual ~IPwmDevice() { /* ... */ }
constexpr int GetChannelIndex() const { return this->channel_index; }
};
}

View File

@@ -0,0 +1,54 @@
/*
* 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.hpp>
#include <stratosphere/pwm/pwm_types.hpp>
#include <stratosphere/pwm/driver/pwm_i_pwm_device.hpp>
#include <stratosphere/ddsf.hpp>
namespace ams::pwm::driver {
class IPwmDriver : public ::ams::ddsf::IDriver {
NON_COPYABLE(IPwmDriver);
NON_MOVEABLE(IPwmDriver);
AMS_DDSF_CASTABLE_TRAITS(ams::pwm::driver::IPwmDriver, ::ams::ddsf::IDriver);
public:
IPwmDriver() : IDriver() { /* ... */ }
virtual ~IPwmDriver() { /* ... */ }
virtual void InitializeDriver() = 0;
virtual void FinalizeDriver() = 0;
virtual Result InitializeDevice(IPwmDevice *device) = 0;
virtual void FinalizeDevice(IPwmDevice *device) = 0;
virtual Result SetPeriod(IPwmDevice *device, TimeSpan period) = 0;
virtual Result GetPeriod(TimeSpan *out, IPwmDevice *device) = 0;
virtual Result SetDuty(IPwmDevice *device, int duty) = 0;
virtual Result GetDuty(int *out, IPwmDevice *device) = 0;
virtual Result SetScale(IPwmDevice *device, double scale) = 0;
virtual Result GetScale(double *out, IPwmDevice *device) = 0;
virtual Result SetEnabled(IPwmDevice *device, bool en) = 0;
virtual Result GetEnabled(bool *out, IPwmDevice *device) = 0;
virtual Result Suspend() = 0;
virtual void Resume() = 0;
};
}

View File

@@ -0,0 +1,36 @@
/*
* 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.hpp>
#include <stratosphere/pwm/pwm_types.hpp>
#include <stratosphere/pwm/driver/pwm_i_pwm_driver.hpp>
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
#include <stratosphere/pwm/driver/board/nintendo_nx/pwm_driver_api.hpp>
namespace ams::pwm::driver::board {
using namespace ams::pwm::driver::board::nintendo_nx;
}
#else
#error "Unknown board for ams::pwm::driver::"
#endif

View File

@@ -0,0 +1,26 @@
/*
* 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.hpp>
#include <stratosphere/pwm/pwm_types.hpp>
#include <stratosphere/pwm/sf/pwm_sf_i_manager.hpp>
namespace ams::pwm {
void InitializeWith(std::shared_ptr<pwm::sf::IManager> &&sp);
void Finalize();
}

View File

@@ -0,0 +1,41 @@
/*
* 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.hpp>
#include <stratosphere/pwm/pwm_types.hpp>
namespace ams::pwm {
struct ChannelSession {
void *_session;
};
Result OpenSession(ChannelSession *out, DeviceCode device_code);
void CloseSession(ChannelSession &session);
void SetPeriod(ChannelSession &session, TimeSpan period);
TimeSpan GetPeriod(ChannelSession &session);
void SetDuty(ChannelSession &session, int duty);
int GetDuty(ChannelSession &session);
void SetEnabled(ChannelSession &session, bool en);
bool GetEnabled(ChannelSession &session);
void SetScale(ChannelSession &session, double scale);
double GetScale(ChannelSession &session);
}

View File

@@ -0,0 +1,51 @@
/*
* 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.hpp>
#include <stratosphere/pwm/pwm_types.hpp>
namespace ams::pwm {
enum ChannelName {
ChannelName_Invalid = 0,
ChannelName_CpuFan = 1,
ChannelName_LcdBacklight = 2,
ChannelName_BlinkLed = 3,
};
constexpr inline const DeviceCode DeviceCode_CpuFan = 0x3D000001;
constexpr inline const DeviceCode DeviceCode_LcdBacklight = 0x3400003D;
constexpr inline const DeviceCode DeviceCode_BlinkLed = 0x35000065;
constexpr inline DeviceCode ConvertToDeviceCode(ChannelName cn) {
switch (cn) {
case ChannelName_CpuFan: return DeviceCode_CpuFan;
case ChannelName_LcdBacklight: return DeviceCode_LcdBacklight;
case ChannelName_BlinkLed: return DeviceCode_BlinkLed;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
constexpr inline ChannelName ConvertToChannelName(DeviceCode dc) {
switch (dc.GetInternalValue()) {
case DeviceCode_CpuFan .GetInternalValue(): return ChannelName_CpuFan;
case DeviceCode_LcdBacklight.GetInternalValue(): return ChannelName_LcdBacklight;
case DeviceCode_BlinkLed .GetInternalValue(): return ChannelName_BlinkLed;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
}

View File

@@ -0,0 +1,24 @@
/*
* 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.hpp>
#include <stratosphere/pwm/pwm_types.hpp>
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
#include <stratosphere/pwm/pwm_channel_name.board.nintendo_nx.hpp>
#else
/* Error? */
#endif

View File

@@ -0,0 +1,23 @@
/*
* 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.hpp>
namespace ams::pwm {
/* ... */
}

View File

@@ -0,0 +1,25 @@
/*
* 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.hpp>
#include <stratosphere/pwm/pwm_types.hpp>
#include <stratosphere/pwm/sf/pwm_sf_i_manager.hpp>
namespace ams::pwm::server {
std::shared_ptr<pwm::sf::IManager> GetServiceObject();
}

View File

@@ -0,0 +1,35 @@
/*
* 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.hpp>
#include <stratosphere/pwm/pwm_types.hpp>
namespace ams::pwm::sf {
#define AMS_PWM_I_CHANNEL_SESSION_INTERFACE_INFO(C, H) \
AMS_SF_METHOD_INFO(C, H, 0, Result, SetPeriod, (TimeSpanType period) ) \
AMS_SF_METHOD_INFO(C, H, 1, Result, GetPeriod, (ams::sf::Out<TimeSpanType> out) ) \
AMS_SF_METHOD_INFO(C, H, 2, Result, SetDuty, (int duty) ) \
AMS_SF_METHOD_INFO(C, H, 3, Result, GetDuty, (ams::sf::Out<int> out) ) \
AMS_SF_METHOD_INFO(C, H, 4, Result, SetEnabled, (bool enabled) ) \
AMS_SF_METHOD_INFO(C, H, 5, Result, GetEnabled, (ams::sf::Out<bool> out) ) \
AMS_SF_METHOD_INFO(C, H, 6, Result, SetScale, (double scale), hos::Version_6_0_0) \
AMS_SF_METHOD_INFO(C, H, 7, Result, GetScale, (ams::sf::Out<double> out), hos::Version_6_0_0)
AMS_SF_DEFINE_INTERFACE(IChannelSession, AMS_PWM_I_CHANNEL_SESSION_INTERFACE_INFO)
}

Some files were not shown because too many files have changed in this diff Show More