diff --git a/nx/include/switch/services/gpio.h b/nx/include/switch/services/gpio.h index 63749f73..8d3d6263 100644 --- a/nx/include/switch/services/gpio.h +++ b/nx/include/switch/services/gpio.h @@ -6,7 +6,7 @@ */ #pragma once #include "../types.h" -#include "sm.h" +#include "../sf/service.h" typedef enum { GpioPadName_AudioCodec = 1, diff --git a/nx/source/services/gpio.c b/nx/source/services/gpio.c index 2091a815..d8d45740 100644 --- a/nx/source/services/gpio.c +++ b/nx/source/services/gpio.c @@ -1,217 +1,55 @@ -#include "types.h" -#include "result.h" -#include "arm/atomics.h" -#include "kernel/ipc.h" +#define NX_SERVICE_ASSUME_NON_DOMAIN +#include "service_guard.h" #include "services/gpio.h" -#include "services/sm.h" static Service g_gpioSrv; -static u64 g_refCnt; -Result gpioInitialize(void) { - Result rc = 0; - - atomicIncrement64(&g_refCnt); +NX_GENERATE_SERVICE_GUARD(gpio); - if (serviceIsActive(&g_gpioSrv)) - return 0; - - rc = smGetService(&g_gpioSrv, "gpio"); - - if (R_FAILED(rc)) gpioExit(); - - return rc; +Result _gpioInitialize(void) { + return smGetService(&g_gpioSrv, "gpio"); } -void gpioExit(void) { - if (atomicDecrement64(&g_refCnt) == 0) { - serviceClose(&g_gpioSrv); - } +void _gpioCleanup(void) { + serviceClose(&g_gpioSrv); } Service* gpioGetServiceSession(void) { return &g_gpioSrv; } +static Result _gpioCmdInU32NoOut(Service *srv, u32 value, u32 cmd_id) { + return serviceDispatchIn(srv, cmd_id, value); +} + +static Result _gpioCmdNoInOutU32(Service *srv, u32 *out_value, u32 cmd_id) { + return serviceDispatchOut(srv, cmd_id, *out_value); +} + Result gpioOpenSession(GpioPadSession *out, GpioPadName name) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u32 name; - } *raw; - - raw = serviceIpcPrepareHeader(&g_gpioSrv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 1; - raw->name = name; - - Result rc = serviceIpcDispatch(&g_gpioSrv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&g_gpioSrv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - serviceCreateSubservice(&out->s, &g_gpioSrv, &r, 0); - } - } - - return rc; + _Static_assert(sizeof(name) == sizeof(u32), "GpioPadName size"); + return serviceDispatchIn(&g_gpioSrv, 1, name, + .out_num_objects = 1, + .out_objects = &out->s, + ); } Result gpioPadSetDirection(GpioPadSession *p, GpioDirection dir) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u32 dir; - } *raw; - - raw = serviceIpcPrepareHeader(&p->s, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 0; - raw->dir = dir; - - Result rc = serviceIpcDispatch(&p->s); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&p->s, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; + return _gpioCmdInU32NoOut(&p->s, dir, 0); } Result gpioPadGetDirection(GpioPadSession *p, GpioDirection *out) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = serviceIpcPrepareHeader(&p->s, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 1; - - Result rc = serviceIpcDispatch(&p->s); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u8 dir; - } *resp; - - serviceIpcParse(&p->s, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - *out = (GpioDirection)resp->dir; - } - } - - return rc; + _Static_assert(sizeof(*out) == sizeof(u32), "GpioDirection size"); + return _gpioCmdNoInOutU32(&p->s, (u32 *)out, 1); } Result gpioPadSetValue(GpioPadSession *p, GpioValue val) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u32 val; - } *raw; - - raw = serviceIpcPrepareHeader(&p->s, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 8; - raw->val = val; - - Result rc = serviceIpcDispatch(&p->s); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u8 val; - } *resp; - - serviceIpcParse(&p->s, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; + return _gpioCmdInU32NoOut(&p->s, val, 8); } Result gpioPadGetValue(GpioPadSession *p, GpioValue *out) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = serviceIpcPrepareHeader(&p->s, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 9; - - Result rc = serviceIpcDispatch(&p->s); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u8 val; - } *resp; - - serviceIpcParse(&p->s, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - *out = (GpioValue)resp->val; - } - } - - return rc; + _Static_assert(sizeof(*out) == sizeof(u32), "GpioValue size"); + return _gpioCmdNoInOutU32(&p->s, (u32 *)out, 9); } void gpioPadClose(GpioPadSession *p) {