diff --git a/nx/include/switch.h b/nx/include/switch.h index 973473a1..e170d43c 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -50,6 +50,7 @@ extern "C" { #include "switch/services/auddev.h" #include "switch/services/hwopus.h" #include "switch/services/csrng.h" +#include "switch/services/lbl.h" #include "switch/services/bpc.h" #include "switch/services/pcv.h" #include "switch/services/psm.h" diff --git a/nx/include/switch/services/lbl.h b/nx/include/switch/services/lbl.h new file mode 100644 index 00000000..04062b2b --- /dev/null +++ b/nx/include/switch/services/lbl.h @@ -0,0 +1,14 @@ +/** + * @file lbl.h + * @brief LBL service IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +Result lblInitialize(void); +void lblExit(void); + +Result lblSwitchBacklightOn(u64 fade_time); +Result lblSwitchBacklightOff(u64 fade_time); diff --git a/nx/source/services/lbl.c b/nx/source/services/lbl.c new file mode 100644 index 00000000..cdeafbb6 --- /dev/null +++ b/nx/source/services/lbl.c @@ -0,0 +1,73 @@ +#include "types.h" +#include "result.h" +#include "arm/atomics.h" +#include "kernel/ipc.h" +#include "kernel/detect.h" +#include "services/lbl.h" +#include "services/sm.h" + +static Service g_lblSrv; +static u64 g_refCnt; + +Result lblInitialize(void) { + Result rc = 0; + + atomicIncrement64(&g_refCnt); + + if (serviceIsActive(&g_lblSrv)) + return 0; + + rc = smGetService(&g_lblSrv, "lbl"); + + if (R_FAILED(rc)) lblExit(); + + return rc; +} + +void lblExit(void) { + if (atomicDecrement64(&g_refCnt) == 0) { + serviceClose(&g_lblSrv); + } +} + +static Result _lblSwitchBacklight(u32 cmd_id, u64 fade_time) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u64 fade_time; + } *raw; + + raw = serviceIpcPrepareHeader(&g_lblSrv, &c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = cmd_id; + raw->fade_time = fade_time; + + Result rc = serviceIpcDispatch(&g_lblSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + struct { + u64 magic; + u64 result; + } *resp; + + serviceIpcParse(&g_lblSrv, &r, sizeof(*resp)); + resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result lblSwitchBacklightOn(u64 fade_time) { + return _lblSwitchBacklight(6, fade_time); +} + +Result lblSwitchBacklightOff(u64 fade_time) { + return _lblSwitchBacklight(7, fade_time); +}