mirror of
https://github.com/Atmosphere-NX/Atmosphere-libs.git
synced 2025-06-21 11:02:45 +02:00
boot: add rgltr/clkrst overrides, skel I2cBusAccessor
This commit is contained in:
parent
de95812488
commit
f99c30920b
@ -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 {
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
||||
}
|
@ -43,6 +43,7 @@
|
||||
#include <stratosphere/boot2.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>
|
||||
@ -63,6 +64,8 @@
|
||||
#include <stratosphere/pgl.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>
|
||||
|
21
libstratosphere/include/stratosphere/clkrst.hpp
Normal file
21
libstratosphere/include/stratosphere/clkrst.hpp
Normal 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>
|
25
libstratosphere/include/stratosphere/clkrst/clkrst_api.hpp
Normal file
25
libstratosphere/include/stratosphere/clkrst/clkrst_api.hpp
Normal 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();
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
23
libstratosphere/include/stratosphere/clkrst/clkrst_types.hpp
Normal file
23
libstratosphere/include/stratosphere/clkrst/clkrst_types.hpp
Normal 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 {
|
||||
|
||||
/* ... */
|
||||
|
||||
}
|
@ -33,19 +33,19 @@ namespace ams::i2c::driver {
|
||||
virtual void InitializeDriver() = 0;
|
||||
virtual void FinalizeDriver() = 0;
|
||||
|
||||
virtual Result Open() = 0;
|
||||
virtual void Close() = 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();
|
||||
virtual void SuspendPowerBus();
|
||||
virtual void SuspendBus() = 0;
|
||||
virtual void SuspendPowerBus() = 0;
|
||||
|
||||
virtual void ResumeBus();
|
||||
virtual void ResumePowerBus();
|
||||
virtual void ResumeBus() = 0;
|
||||
virtual void ResumePowerBus() = 0;
|
||||
|
||||
virtual const DeviceCode &GetDeviceCode() const = 0;
|
||||
};
|
||||
|
20
libstratosphere/include/stratosphere/pwm.hpp
Normal file
20
libstratosphere/include/stratosphere/pwm.hpp
Normal 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/pwm/pwm_types.hpp>
|
||||
#include <stratosphere/pwm/pwm_select_channel_name.hpp>
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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
|
23
libstratosphere/include/stratosphere/pwm/pwm_types.hpp
Normal file
23
libstratosphere/include/stratosphere/pwm/pwm_types.hpp
Normal 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 {
|
||||
|
||||
/* ... */
|
||||
|
||||
}
|
21
libstratosphere/include/stratosphere/regulator.hpp
Normal file
21
libstratosphere/include/stratosphere/regulator.hpp
Normal 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/regulator/regulator_types.hpp>
|
||||
#include <stratosphere/regulator/regulator_api.hpp>
|
||||
#include <stratosphere/regulator/regulator_session_api.hpp>
|
@ -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/regulator/regulator_types.hpp>
|
||||
|
||||
namespace ams::regulator {
|
||||
|
||||
void Initialize();
|
||||
void Finalize();
|
||||
|
||||
}
|
@ -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/regulator/regulator_types.hpp>
|
||||
|
||||
namespace ams::regulator {
|
||||
|
||||
struct RegulatorSession {
|
||||
void *_session;
|
||||
};
|
||||
|
||||
Result OpenSession(RegulatorSession *out, DeviceCode device_code);
|
||||
void CloseSession(RegulatorSession *session);
|
||||
|
||||
bool GetVoltageEnabled(RegulatorSession *session);
|
||||
Result SetVoltageEnabled(RegulatorSession *session);
|
||||
|
||||
Result SetVoltageValue(RegulatorSession *session, u32 micro_volts);
|
||||
|
||||
}
|
@ -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::regulator {
|
||||
|
||||
/* ... */
|
||||
|
||||
}
|
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* 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 <stratosphere.hpp>
|
||||
#include "i2c_bus_accessor.hpp"
|
||||
|
||||
namespace ams::i2c::driver::board::nintendo_nx::impl {
|
||||
|
||||
void I2cBusAccessor::Initialize(dd::PhysicalAddress reg_paddr, size_t reg_size, os::InterruptName intr, bool pb, SpeedMode sm) {
|
||||
AMS_ASSERT(this->state == State::NotInitialized);
|
||||
|
||||
this->is_power_bus = pb;
|
||||
this->speed_mode = sm;
|
||||
this->interrupt_name = intr;
|
||||
this->registers_phys_addr = reg_paddr;
|
||||
this->registers_size = reg_size;
|
||||
this->state = State::Initializing;
|
||||
}
|
||||
|
||||
void I2cBusAccessor::RegisterDeviceCode(DeviceCode dc) {
|
||||
AMS_ASSERT(this->state == State::Initializing);
|
||||
|
||||
this->device_code = dc;
|
||||
}
|
||||
|
||||
void I2cBusAccessor::InitializeDriver() {
|
||||
AMS_ASSERT(this->state == State::Initializing);
|
||||
|
||||
this->registers = reinterpret_cast<volatile I2cRegisters *>(dd::QueryIoMapping(this->registers_phys_addr, this->registers_size));
|
||||
AMS_ABORT_UNLESS(this->registers != nullptr);
|
||||
|
||||
this->state = State::Initialized;
|
||||
}
|
||||
|
||||
void I2cBusAccessor::FinalizeDriver() {
|
||||
AMS_ASSERT(this->state == State::Initialized);
|
||||
this->state = State::Initializing;
|
||||
}
|
||||
|
||||
Result I2cBusAccessor::InitializeDevice(I2cDeviceProperty *device) {
|
||||
/* Check that the device is valid. */
|
||||
AMS_ASSERT(device != nullptr);
|
||||
AMS_ASSERT(this->state == State::Initialized);
|
||||
|
||||
/* Acquire exclusive access. */
|
||||
std::scoped_lock lk(this->user_count_mutex);
|
||||
|
||||
/* Increment our user count -- if we're already open, we're done. */
|
||||
AMS_ASSERT(this->user_count >= 0);
|
||||
++this->user_count;
|
||||
R_SUCCEED_IF(this->user_count > 1);
|
||||
|
||||
/* Initialize our interrupt event. */
|
||||
os::InitializeInterruptEvent(std::addressof(this->interrupt_event), this->interrupt_name, os::EventClearMode_ManualClear);
|
||||
os::ClearInterruptEvent(std::addressof(this->interrupt_event);
|
||||
|
||||
/* If we're not power bus, perform power management init. */
|
||||
if (!this->is_power_bus) {
|
||||
/* Initialize regulator library. */
|
||||
regulator::Initialize();
|
||||
|
||||
/* Try to open regulator session. */
|
||||
R_TRY(this->TryOpenRegulatorSession());
|
||||
|
||||
/* If we have a regulator session, set voltage to 2.9V. */
|
||||
if (this->has_regulator_session) {
|
||||
/* NOTE: Nintendo does not check the result, here. */
|
||||
regulator::SetVoltageValue(std::addressof(this->regulator_session), 2'900'000u);
|
||||
}
|
||||
|
||||
/* Initialize clock/reset library. */
|
||||
clkrst::Initialize();
|
||||
}
|
||||
|
||||
/* Execute initial config. */
|
||||
this->ExecuteInitialConfig();
|
||||
|
||||
/* If we have a regulator session, enable voltage. */
|
||||
if (!this->is_power_bus && this->has_regulator_session) {
|
||||
/* Check whether voltage was already enabled. */
|
||||
const bool was_enabled = regulator::GetVoltageEnabled(std::addressof(this->regulator_session));
|
||||
|
||||
/* NOTE: Nintendo does not check the result of this call. */
|
||||
regulator::SetVoltageEnabled(std::addressof(this->regulator_session), true);
|
||||
|
||||
/* If we enabled voltage, delay to give our enable time to take. */
|
||||
if (!was_enabled) {
|
||||
os::SleepThread(TimeSpan::FromMicroSeconds(560));
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void I2cBusAccessor::FinalizeDevice(I2cDeviceProperty *device) {
|
||||
/* Check that the device is valid. */
|
||||
AMS_ASSERT(device != nullptr);
|
||||
AMS_ASSERT(this->state == State::Initialized);
|
||||
|
||||
/* Acquire exclusive access. */
|
||||
std::scoped_lock lk(this->user_count_mutex);
|
||||
|
||||
/* Increment our user count -- if we're not the last user, we're done. */
|
||||
AMS_ASSERT(this->user_count > 0);
|
||||
--this->user_count;
|
||||
R_SUCCEED_IF(this->user_count > 0);
|
||||
|
||||
/* Finalize our interrupt event. */
|
||||
os::FinalizeInterruptEvent(std::addressof(this->interrupt_event));
|
||||
|
||||
/* If we have a regulator session, disable voltage. */
|
||||
if (this->has_regulator_session) {
|
||||
/* NOTE: Nintendo does not check the result of this call. */
|
||||
regulator::SetVoltageEnabled(std::addressof(this->regulator_session), false);
|
||||
}
|
||||
|
||||
/* Finalize the clock/reset library. */
|
||||
clkrst::Finalize();
|
||||
|
||||
/* If we have a regulator session, close it. */
|
||||
if (this->has_regulator_session) {
|
||||
regulator::CloseSession(std::addressof(this->regulator_session));
|
||||
this->has_regulator_session = false;
|
||||
}
|
||||
|
||||
/* Finalize the regulator library. */
|
||||
regulator::Finalize();
|
||||
}
|
||||
|
||||
Result I2cBusAccessor::Send(I2cDeviceProperty *device, const void *src, size_t src_size, TransactionOption option) {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
Result I2cBusAccessor::Receive(void *dst, size_t dst_size, I2cDeviceProperty *device, TransactionOption option) {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
void I2cBusAccessor::SuspendBus() {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
void I2cBusAccessor::SuspendPowerBus() {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
void I2cBusAccessor::ResumeBus() {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
void I2cBusAccessor::ResumePowerBus() {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
Result I2cBusAccessor::TryOpenRegulatorSession() {
|
||||
/* Ensure we track the session. */
|
||||
this->has_regulator_session = true;
|
||||
auto s_guard = SCOPE_GUARD { this->has_regulator_session = false; };
|
||||
|
||||
/* Try to open the session. */
|
||||
R_TRY_CATCH(regulator::OpenSession(std::addressof(this->regulator_session), this->device_code)) {
|
||||
R_CATCH(ddsf::ResultDeviceCodeNotFound) {
|
||||
/* It's okay if the device isn't found, but we don't have a session if so. */
|
||||
this->has_regulator_session = false;
|
||||
}
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
/* We opened (or not). */
|
||||
s_guard.Cancel();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void I2cBusAccessor::ExecuteInitialConfig() {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
Result I2cBusAccessor::Send(const u8 *src, size_t src_size, TransactionOption option, u16 slave_address, AddressingMode addressing_mode) {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
Result I2cBusAccessor::Receive(u8 *dst, size_t dst_size, TransactionOption option, u16 slave_address, AddressingMode addressing_mode) {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
void I2cBusAccessor::WriteHeader(Xfer xfer, size_t size, TransactionOption option, u16 slave_address, AddressingMode addressing_mode) {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
void I2cBusAccessor::ResetController() const {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
void I2cBusAccessor::ClearBus() const {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
void I2cBusAccessor::SetClockRegisters(SpeedMode speed_mode) {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
void I2cBusAccessor::SetPacketModeRegisters() {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
Result I2cBusAccessor::FlushFifos() {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
Result I2cBusAccessor::GetTransactionResult() const {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
void I2cBusAccessor::HandleTransactionError(Result result) {
|
||||
/* TODO */
|
||||
AMS_ABORT();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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.hpp>
|
||||
#include "i2c_i2c_registers.hpp"
|
||||
|
||||
namespace ams::i2c::driver::board::nintendo_nx::impl {
|
||||
|
||||
class I2cBusAccessor : public ::ams::i2c::driver::II2cDriver {
|
||||
NON_COPYABLE(I2cBusAccessor);
|
||||
NON_MOVEABLE(I2cBusAccessor);
|
||||
AMS_DDSF_CASTABLE_TRAITS(ams::i2c::driver::board::nintendo_nx::impl::I2cBusAccessor, ::ams::i2c::driver::II2cDriver);
|
||||
private:
|
||||
enum class State {
|
||||
NotInitialized = 0,
|
||||
Initializing = 1,
|
||||
Initialized = 2,
|
||||
Suspended = 3,
|
||||
PowerBusSuspended = 4,
|
||||
};
|
||||
|
||||
enum Xfer {
|
||||
Xfer_Write = 0,
|
||||
Xfer_Read = 1,
|
||||
};
|
||||
private:
|
||||
volatile I2cRegisters *registers;
|
||||
SpeedMode speed_mode;
|
||||
os::InterruptEventType interrupt_event;
|
||||
int user_count;
|
||||
os::SdkMutex user_count_mutex;
|
||||
os::SdkMutex register_mutex;
|
||||
regulator::RegulatorSession regulator_session;
|
||||
bool has_regulator_session;
|
||||
State state;
|
||||
os::SdkMutex transaction_order_mutex;
|
||||
bool is_power_bus;
|
||||
dd::PhysicalAddress registers_phys_addr;
|
||||
size_t registers_size;
|
||||
os::InterruptName interrupt_name;
|
||||
DeviceCode device_code;
|
||||
util::IntrusiveListNode bus_accessor_list_node;
|
||||
public:
|
||||
using BusAccessorListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&I2cBusAccessor::bus_accessor_list_node>;
|
||||
using BusAccessorList = typename BusAccessorListTraits::ListType;
|
||||
friend class util::IntrusiveList<I2cBusAccessor, util::IntrusiveListMemberTraitsDeferredAssert<&I2cBusAccessor::bus_accessor_list_node>>;
|
||||
public:
|
||||
I2cBusAccessor()
|
||||
: registers(nullptr), speed_mode(SpeedMode_Fast), user_count(0), user_count_mutex(),
|
||||
register_mutex(), has_regulator_session(false), state(State::NotInitialized), transaction_order_mutex(),
|
||||
is_power_bus(false), registers_phys_addr(0), registers_size(0), interrupt_name(), device_code(-1), bus_accessor_list_node()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
void Initialize(dd::PhysicalAddress reg_paddr, size_t reg_size, os::InterruptName intr, bool pb, SpeedMode sm);
|
||||
void RegisterDeviceCode(DeviceCode device_code);
|
||||
|
||||
SpeedMode GetSpeedMode() const { return this->speed_mode; }
|
||||
dd::PhysicalAddress GetRegistersPhysicalAddress() const { return this->registers_phys_addr; }
|
||||
size_t GetRegistersSize() const { return this->registers_size; }
|
||||
os::InterruptName GetInterruptName() const { return this->interrupt_name; }
|
||||
|
||||
void RemoveFrom(BusAccessorList &lst) {
|
||||
lst.erase(lst.iterator_to(*this));
|
||||
}
|
||||
|
||||
bool IsLinkedToList() const {
|
||||
return this->bus_accessor_list_node.IsLinked();
|
||||
}
|
||||
private:
|
||||
Result TryOpenRegulatorSession();
|
||||
|
||||
void ExecuteInitialConfig();
|
||||
|
||||
Result Send(const u8 *src, size_t src_size, TransactionOption option, u16 slave_address, AddressingMode addressing_mode);
|
||||
Result Receive(u8 *dst, size_t dst_size, TransactionOption option, u16 slave_address, AddressingMode addressing_mode);
|
||||
|
||||
void WriteHeader(Xfer xfer, size_t size, TransactionOption option, u16 slave_address, AddressingMode addressing_mode);
|
||||
|
||||
void ResetController() const;
|
||||
void ClearBus() const;
|
||||
void SetClockRegisters(SpeedMode speed_mode);
|
||||
void SetPacketModeRegisters();
|
||||
|
||||
Result FlushFifos();
|
||||
|
||||
Result GetTransactionResult() const;
|
||||
void HandleTransactionError(Result result);
|
||||
|
||||
void DisableInterruptMask() {
|
||||
reg::Write(this->registers->interrupt_mask_register, 0);
|
||||
reg::Read(this->registers->interrupt_mask_register);
|
||||
}
|
||||
|
||||
Result CheckAndHandleError() {
|
||||
const Result result = this->GetTransactionResult();
|
||||
this->HandleTransactionError(result);
|
||||
if (R_FAILED(result)) {
|
||||
this->DisableInterruptMask();
|
||||
os::ClearInterruptEvent(std::addressof(this->interrupt_event));
|
||||
return result;
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
public:
|
||||
virtual void InitializeDriver() override;
|
||||
virtual void FinalizeDriver() override;
|
||||
|
||||
virtual Result InitializeDevice(I2cDeviceProperty *device) override;
|
||||
virtual void FinalizeDevice(I2cDeviceProperty *device) override;
|
||||
|
||||
virtual Result Send(I2cDeviceProperty *device, const void *src, size_t src_size, TransactionOption option) override;
|
||||
virtual Result Receive(void *dst, size_t dst_size, I2cDeviceProperty *device, TransactionOption option) override;
|
||||
|
||||
virtual os::SdkMutex &GetTransactionOrderMutex() override {
|
||||
return this->transaction_order_mutex;
|
||||
}
|
||||
|
||||
virtual void SuspendBus() override;
|
||||
virtual void SuspendPowerBus() override;
|
||||
|
||||
virtual void ResumeBus() override;
|
||||
virtual void ResumePowerBus() override;
|
||||
|
||||
virtual const DeviceCode &GetDeviceCode() const override {
|
||||
return this->device_code;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.hpp>
|
||||
|
||||
namespace ams::i2c::driver::board::nintendo_nx::impl {
|
||||
|
||||
struct I2cRegisters {
|
||||
volatile u32 cnfg;
|
||||
volatile u32 cmd_addr0;
|
||||
volatile u32 cmd_addr1;
|
||||
volatile u32 cmd_data1;
|
||||
volatile u32 cmd_data2;
|
||||
volatile u32 _14;
|
||||
volatile u32 _18;
|
||||
volatile u32 status;
|
||||
volatile u32 sl_cnfg;
|
||||
volatile u32 sl_rcvd;
|
||||
volatile u32 sl_status;
|
||||
volatile u32 sl_addr1;
|
||||
volatile u32 sl_addr2;
|
||||
volatile u32 tlow_sext;
|
||||
volatile u32 _38;
|
||||
volatile u32 sl_delay_count;
|
||||
volatile u32 sl_int_mask;
|
||||
volatile u32 sl_int_source;
|
||||
volatile u32 sl_int_set;
|
||||
volatile u32 _4c;
|
||||
volatile u32 tx_packet_fifo;
|
||||
volatile u32 rx_fifo;
|
||||
volatile u32 packet_transfer_status;
|
||||
volatile u32 fifo_control;
|
||||
volatile u32 fifo_status;
|
||||
volatile u32 interrupt_mask_register;
|
||||
volatile u32 interrupt_status_register;
|
||||
volatile u32 clk_divisor_register;
|
||||
volatile u32 interrupt_source_register;
|
||||
volatile u32 interrupt_set_register;
|
||||
volatile u32 slv_tx_packet_fifo;
|
||||
volatile u32 slv_rx_fifo;
|
||||
volatile u32 slv_packet_status;
|
||||
volatile u32 bus_clear_config;
|
||||
volatile u32 bus_clear_status;
|
||||
volatile u32 config_load;
|
||||
volatile u32 _90;
|
||||
volatile u32 interface_timing_0;
|
||||
volatile u32 interface_timing_1;
|
||||
volatile u32 hs_interface_timing_0;
|
||||
volatile u32 hs_interface_timing_1;
|
||||
};
|
||||
static_assert(sizeof(I2cRegisters) == 0xA4);
|
||||
|
||||
}
|
@ -28,6 +28,7 @@
|
||||
#include <vapours/tegra/tegra_emc.hpp>
|
||||
#include <vapours/tegra/tegra_evp.hpp>
|
||||
#include <vapours/tegra/tegra_flow_ctlr.hpp>
|
||||
#include <vapours/tegra/tegra_i2c.hpp>
|
||||
#include <vapours/tegra/tegra_ictlr.hpp>
|
||||
#include <vapours/tegra/tegra_mc.hpp>
|
||||
#include <vapours/tegra/tegra_mselect.hpp>
|
||||
|
@ -107,6 +107,7 @@ DEFINE_CLK_RST_REG_BIT_ENUM(PLLC4_BASE_PLLC4_ENABLE, 30, DISABLE, ENABLE);
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_W (0x364)
|
||||
|
||||
/* CLK_SOURCE */
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_PWM (0x110)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C1 (0x124)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C5 (0x128)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_DISP1 (0x138)
|
||||
@ -115,14 +116,18 @@ DEFINE_CLK_RST_REG_BIT_ENUM(PLLC4_BASE_PLLC4_ENABLE, 30, DISABLE, ENABLE);
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4 (0x164)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTA (0x178)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTB (0x17C)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C2 (0x198)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTC (0x1A0)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C3 (0x1B8)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3 (0x1BC)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_CSITE (0x1D4)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT (0x3B4)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C4 (0x3C4)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON (0x3E8)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP (0x620)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_REF (0x62C)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_SOC (0x630)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 (0x65C)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL (0x66C)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM (0x694)
|
||||
|
||||
@ -156,12 +161,36 @@ DEFINE_CLK_RST_REG_BIT_ENUM(PLLC4_BASE_PLLC4_ENABLE, 30, DISABLE, ENABLE);
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_V_CLR (0x444)
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_W_CLR (0x44C)
|
||||
|
||||
/* RST_*_INDEX */
|
||||
#define CLK_RST_CONTROLLER_RST_I2C1_INDEX (0x0C)
|
||||
#define CLK_RST_CONTROLLER_RST_I2C2_INDEX (0x16)
|
||||
#define CLK_RST_CONTROLLER_RST_I2C3_INDEX (0x03)
|
||||
#define CLK_RST_CONTROLLER_RST_I2C4_INDEX (0x07)
|
||||
#define CLK_RST_CONTROLLER_RST_I2C5_INDEX (0x0F)
|
||||
#define CLK_RST_CONTROLLER_RST_I2C6_INDEX (0x06)
|
||||
|
||||
#define CLK_RST_CONTROLLER_RST_PWM_INDEX (0x11)
|
||||
|
||||
#define CLK_RST_CONTROLLER_RST_UARTA_INDEX (0x06)
|
||||
#define CLK_RST_CONTROLLER_RST_UARTB_INDEX (0x07)
|
||||
#define CLK_RST_CONTROLLER_RST_UARTC_INDEX (0x17)
|
||||
|
||||
#define CLK_RST_CONTROLLER_RST_ACTMON_INDEX (0x17)
|
||||
|
||||
/* CLK_ENB_*_INDEX */
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_I2C1_INDEX (0x0C)
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_I2C2_INDEX (0x16)
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_I2C3_INDEX (0x03)
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_I2C4_INDEX (0x07)
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_I2C5_INDEX (0x0F)
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_I2C6_INDEX (0x06)
|
||||
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_PWM_INDEX (0x11)
|
||||
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_UARTA_INDEX (0x06)
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_UARTB_INDEX (0x07)
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_UARTC_INDEX (0x17)
|
||||
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_ACTMON_INDEX (0x17)
|
||||
|
||||
/* RST_CPUG_CMPLX_* */
|
||||
@ -181,6 +210,9 @@ DEFINE_CLK_RST_REG_BIT_ENUM(LVL2_CLK_GATE_OVRD_SDMMC2_LEGACY_TMCLK_OVR_ON, 29, O
|
||||
DEFINE_CLK_RST_REG_BIT_ENUM(LVL2_CLK_GATE_OVRD_SDMMC3_LEGACY_TMCLK_OVR_ON, 30, OFF, ON);
|
||||
DEFINE_CLK_RST_REG_BIT_ENUM(LVL2_CLK_GATE_OVRD_SDMMC4_LEGACY_TMCLK_OVR_ON, 31, OFF, ON);
|
||||
|
||||
DEFINE_CLK_RST_REG(CLK_SOURCE_CLK_DIVISOR, 0, 8);
|
||||
DEFINE_CLK_RST_REG(CLK_SOURCE_CLK_SOURCE, 29, 3);
|
||||
|
||||
DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_I2C1_I2C1_CLK_SRC, 29, PLLP_OUT0, PLLC2_OUT0, PLLC_OUT0, PLLC4_OUT0, RESERVED4, PLLC4_OUT1, CLK_M, PLLC4_OUT2);
|
||||
DEFINE_CLK_RST_REG(CLK_SOURCE_I2C1_I2C1_CLK_DIVISOR, 0, 8);
|
||||
DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_I2C5_I2C5_CLK_SRC, 29, PLLP_OUT0, PLLC2_OUT0, PLLC_OUT0, PLLC4_OUT0, RESERVED4, PLLC4_OUT1, CLK_M, PLLC4_OUT2);
|
||||
|
78
libvapours/include/vapours/tegra/tegra_i2c.hpp
Normal file
78
libvapours/include/vapours/tegra/tegra_i2c.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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/common.hpp>
|
||||
#include <vapours/assert.hpp>
|
||||
#include <vapours/literals.hpp>
|
||||
#include <vapours/util.hpp>
|
||||
#include <vapours/results.hpp>
|
||||
#include <vapours/reg.hpp>
|
||||
|
||||
#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);
|
@ -42,62 +42,6 @@ namespace ams::sdmmc::impl {
|
||||
constexpr inline const dd::PhysicalAddress I2c5RegistersAddress = UINT64_C(0x7000D000);
|
||||
constexpr inline const size_t I2c5RegistersSize = 4_KB;
|
||||
|
||||
#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);
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline size_t MaxTransferSize = sizeof(u32);
|
||||
|
Loading…
Reference in New Issue
Block a user