boot: split out gpio, pinmux.
This commit is contained in:
103
stratosphere/boot/source/gpio/gpio_initial_configuration.cpp
Normal file
103
stratosphere/boot/source/gpio/gpio_initial_configuration.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "gpio_initial_configuration.hpp"
|
||||
#include "gpio_utils.hpp"
|
||||
|
||||
/* TODO: Better way? */
|
||||
#include "../boot_spl_utils.hpp"
|
||||
|
||||
namespace sts::gpio {
|
||||
|
||||
namespace {
|
||||
|
||||
struct InitialConfig {
|
||||
u32 pad_name;
|
||||
GpioDirection direction;
|
||||
GpioValue value;
|
||||
};
|
||||
|
||||
/* Include all initial configuration definitions. */
|
||||
#include "gpio_initial_configuration_icosa.inc"
|
||||
#include "gpio_initial_configuration_copper.inc"
|
||||
#include "gpio_initial_configuration_hoag.inc"
|
||||
#include "gpio_initial_configuration_iowa.inc"
|
||||
|
||||
}
|
||||
|
||||
void SetInitialConfiguration() {
|
||||
const InitialConfig *configs = nullptr;
|
||||
size_t num_configs = 0;
|
||||
const auto hw_type = spl::GetHardwareType();
|
||||
const FirmwareVersion fw_ver = GetRuntimeFirmwareVersion();
|
||||
|
||||
/* Choose GPIO map. */
|
||||
if (fw_ver >= FirmwareVersion_200) {
|
||||
switch (hw_type) {
|
||||
case spl::HardwareType::Icosa:
|
||||
{
|
||||
if (fw_ver >= FirmwareVersion_400) {
|
||||
configs = InitialConfigsIcosa4x;
|
||||
num_configs = NumInitialConfigsIcosa4x;
|
||||
} else {
|
||||
configs = InitialConfigsIcosa;
|
||||
num_configs = NumInitialConfigsIcosa;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case spl::HardwareType::Copper:
|
||||
configs = InitialConfigsCopper;
|
||||
num_configs = NumInitialConfigsCopper;
|
||||
break;
|
||||
case spl::HardwareType::Hoag:
|
||||
configs = InitialConfigsHoag;
|
||||
num_configs = NumInitialConfigsHoag;
|
||||
break;
|
||||
case spl::HardwareType::Iowa:
|
||||
configs = InitialConfigsIowa;
|
||||
num_configs = NumInitialConfigsIowa;
|
||||
break;
|
||||
default:
|
||||
/* Unknown hardware type, we can't proceed. */
|
||||
std::abort();
|
||||
}
|
||||
} else {
|
||||
/* Until 2.0.0, the GPIO map for Icosa was used for all hardware types. */
|
||||
configs = InitialConfigsIcosa;
|
||||
num_configs = NumInitialConfigsIcosa;
|
||||
}
|
||||
|
||||
/* Ensure we found an appropriate config. */
|
||||
if (configs == nullptr) {
|
||||
std::abort();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < num_configs; i++) {
|
||||
/* Configure the GPIO. */
|
||||
Configure(configs[i].pad_name);
|
||||
|
||||
/* Set the GPIO's direction. */
|
||||
SetDirection(configs[i].pad_name, configs[i].direction);
|
||||
|
||||
if (configs[i].direction == GpioDirection_Output) {
|
||||
/* Set the GPIO's value. */
|
||||
SetValue(configs[i].pad_name, configs[i].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
25
stratosphere/boot/source/gpio/gpio_initial_configuration.hpp
Normal file
25
stratosphere/boot/source/gpio/gpio_initial_configuration.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace sts::gpio {
|
||||
|
||||
void SetInitialConfiguration();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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/>.
|
||||
*/
|
||||
|
||||
constexpr InitialConfig InitialConfigsCopper[] = {
|
||||
{0x40, GpioDirection_Output, GpioValue_Low},
|
||||
{0x05, GpioDirection_Output, GpioValue_Low},
|
||||
{0x41, GpioDirection_Input, GpioValue_High},
|
||||
{0x42, GpioDirection_Input, GpioValue_Low},
|
||||
{0x43, GpioDirection_Output, GpioValue_Low},
|
||||
{0x02, GpioDirection_Output, GpioValue_Low},
|
||||
{0x07, GpioDirection_Output, GpioValue_Low},
|
||||
{0x44, GpioDirection_Input, GpioValue_High},
|
||||
{0x45, GpioDirection_Input, GpioValue_High},
|
||||
{0x0F, GpioDirection_Input, GpioValue_High},
|
||||
{0x46, GpioDirection_Output, GpioValue_Low},
|
||||
{0x47, GpioDirection_Output, GpioValue_Low},
|
||||
{0x10, GpioDirection_Input, GpioValue_Low},
|
||||
{0x11, GpioDirection_Input, GpioValue_Low},
|
||||
{0x12, GpioDirection_Input, GpioValue_Low},
|
||||
{0x13, GpioDirection_Input, GpioValue_Low},
|
||||
{0x14, GpioDirection_Input, GpioValue_High},
|
||||
{0x18, GpioDirection_Input, GpioValue_Low},
|
||||
{0x19, GpioDirection_Input, GpioValue_High},
|
||||
{0x1A, GpioDirection_Input, GpioValue_High},
|
||||
{0x1C, GpioDirection_Input, GpioValue_High},
|
||||
{0x4D, GpioDirection_Output, GpioValue_Low},
|
||||
{0x20, GpioDirection_Output, GpioValue_Low},
|
||||
{0x38, GpioDirection_Input, GpioValue_High},
|
||||
{0x23, GpioDirection_Input, GpioValue_High},
|
||||
{0x25, GpioDirection_Input, GpioValue_Low},
|
||||
{0x26, GpioDirection_Input, GpioValue_Low},
|
||||
{0x27, GpioDirection_Input, GpioValue_Low},
|
||||
{0x28, GpioDirection_Input, GpioValue_High},
|
||||
{0x29, GpioDirection_Input, GpioValue_High},
|
||||
{0x2A, GpioDirection_Input, GpioValue_High},
|
||||
{0x48, GpioDirection_Output, GpioValue_Low},
|
||||
{0x49, GpioDirection_Output, GpioValue_Low},
|
||||
{0x4A, GpioDirection_Output, GpioValue_Low},
|
||||
{0x2D, GpioDirection_Output, GpioValue_Low},
|
||||
{0x2E, GpioDirection_Output, GpioValue_Low},
|
||||
{0x37, GpioDirection_Input, GpioValue_Low},
|
||||
{0x2F, GpioDirection_Output, GpioValue_Low},
|
||||
{0x03, GpioDirection_Output, GpioValue_Low},
|
||||
{0x30, GpioDirection_Input, GpioValue_Low},
|
||||
{0x31, GpioDirection_Output, GpioValue_Low},
|
||||
{0x4B, GpioDirection_Output, GpioValue_Low},
|
||||
{0x4C, GpioDirection_Input, GpioValue_High},
|
||||
{0x4E, GpioDirection_Input, GpioValue_Low},
|
||||
};
|
||||
|
||||
constexpr u32 NumInitialConfigsCopper = (sizeof(InitialConfigsCopper) / sizeof(InitialConfigsCopper[0]));
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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/>.
|
||||
*/
|
||||
|
||||
constexpr InitialConfig InitialConfigsHoag[] = {
|
||||
{0x04, GpioDirection_Input, GpioValue_High},
|
||||
{0x05, GpioDirection_Output, GpioValue_Low},
|
||||
{0x06, GpioDirection_Input, GpioValue_Low},
|
||||
{0x02, GpioDirection_Output, GpioValue_Low},
|
||||
{0x3C, GpioDirection_Input, GpioValue_Low},
|
||||
{0x0F, GpioDirection_Input, GpioValue_High},
|
||||
{0x08, GpioDirection_Input, GpioValue_Low},
|
||||
{0x09, GpioDirection_Input, GpioValue_Low},
|
||||
{0x0A, GpioDirection_Output, GpioValue_Low},
|
||||
{0x0B, GpioDirection_Input, GpioValue_Low},
|
||||
{0x0D, GpioDirection_Output, GpioValue_Low},
|
||||
{0x0E, GpioDirection_Input, GpioValue_Low},
|
||||
{0x10, GpioDirection_Input, GpioValue_Low},
|
||||
{0x11, GpioDirection_Input, GpioValue_Low},
|
||||
{0x12, GpioDirection_Input, GpioValue_Low},
|
||||
{0x13, GpioDirection_Input, GpioValue_Low},
|
||||
{0x14, GpioDirection_Input, GpioValue_High},
|
||||
{0x16, GpioDirection_Input, GpioValue_Low},
|
||||
{0x15, GpioDirection_Input, GpioValue_Low},
|
||||
{0x17, GpioDirection_Input, GpioValue_High},
|
||||
{0x18, GpioDirection_Input, GpioValue_Low},
|
||||
{0x19, GpioDirection_Input, GpioValue_High},
|
||||
{0x1A, GpioDirection_Input, GpioValue_High},
|
||||
{0x1B, GpioDirection_Input, GpioValue_Low},
|
||||
{0x1C, GpioDirection_Input, GpioValue_Low},
|
||||
{0x1D, GpioDirection_Output, GpioValue_Low},
|
||||
{0x1E, GpioDirection_Output, GpioValue_Low},
|
||||
{0x20, GpioDirection_Output, GpioValue_Low},
|
||||
{0x21, GpioDirection_Input, GpioValue_Low},
|
||||
{0x38, GpioDirection_Input, GpioValue_High},
|
||||
{0x22, GpioDirection_Input, GpioValue_Low},
|
||||
{0x23, GpioDirection_Input, GpioValue_High},
|
||||
{0x01, GpioDirection_Output, GpioValue_Low},
|
||||
{0x39, GpioDirection_Output, GpioValue_Low},
|
||||
{0x24, GpioDirection_Output, GpioValue_Low},
|
||||
{0x34, GpioDirection_Input, GpioValue_Low},
|
||||
{0x25, GpioDirection_Input, GpioValue_Low},
|
||||
{0x26, GpioDirection_Input, GpioValue_Low},
|
||||
{0x27, GpioDirection_Input, GpioValue_Low},
|
||||
{0x2B, GpioDirection_Output, GpioValue_Low},
|
||||
{0x28, GpioDirection_Input, GpioValue_High},
|
||||
{0x1F, GpioDirection_Output, GpioValue_Low},
|
||||
{0x29, GpioDirection_Input, GpioValue_High},
|
||||
{0x3A, GpioDirection_Output, GpioValue_Low},
|
||||
{0x0C, GpioDirection_Input, GpioValue_Low},
|
||||
{0x2D, GpioDirection_Output, GpioValue_Low},
|
||||
{0x2E, GpioDirection_Output, GpioValue_Low},
|
||||
{0x37, GpioDirection_Input, GpioValue_Low},
|
||||
{0x2F, GpioDirection_Output, GpioValue_Low},
|
||||
{0x03, GpioDirection_Output, GpioValue_Low},
|
||||
{0x30, GpioDirection_Input, GpioValue_Low},
|
||||
{0x3B, GpioDirection_Input, GpioValue_Low},
|
||||
{0x31, GpioDirection_Output, GpioValue_Low},
|
||||
{0x32, GpioDirection_Output, GpioValue_Low},
|
||||
{0x33, GpioDirection_Output, GpioValue_Low},
|
||||
{0x35, GpioDirection_Input, GpioValue_High},
|
||||
{0x2C, GpioDirection_Output, GpioValue_Low},
|
||||
{0x36, GpioDirection_Output, GpioValue_Low},
|
||||
};
|
||||
|
||||
constexpr u32 NumInitialConfigsHoag = (sizeof(InitialConfigsHoag) / sizeof(InitialConfigsHoag[0]));
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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/>.
|
||||
*/
|
||||
|
||||
constexpr InitialConfig InitialConfigsIcosa[] = {
|
||||
{0x04, GpioDirection_Input, GpioValue_High},
|
||||
{0x05, GpioDirection_Output, GpioValue_Low},
|
||||
{0x06, GpioDirection_Input, GpioValue_Low},
|
||||
{0x02, GpioDirection_Output, GpioValue_Low},
|
||||
{0x07, GpioDirection_Output, GpioValue_Low},
|
||||
{0x3C, GpioDirection_Input, GpioValue_Low},
|
||||
{0x0F, GpioDirection_Input, GpioValue_High},
|
||||
{0x08, GpioDirection_Input, GpioValue_Low},
|
||||
{0x09, GpioDirection_Input, GpioValue_Low},
|
||||
{0x0A, GpioDirection_Output, GpioValue_Low},
|
||||
{0x0B, GpioDirection_Input, GpioValue_High},
|
||||
{0x0D, GpioDirection_Output, GpioValue_Low},
|
||||
{0x0E, GpioDirection_Input, GpioValue_Low},
|
||||
{0x10, GpioDirection_Input, GpioValue_Low},
|
||||
{0x11, GpioDirection_Input, GpioValue_Low},
|
||||
{0x12, GpioDirection_Input, GpioValue_Low},
|
||||
{0x13, GpioDirection_Input, GpioValue_Low},
|
||||
{0x14, GpioDirection_Input, GpioValue_High},
|
||||
{0x16, GpioDirection_Input, GpioValue_Low},
|
||||
{0x15, GpioDirection_Input, GpioValue_Low},
|
||||
{0x17, GpioDirection_Input, GpioValue_High},
|
||||
{0x18, GpioDirection_Input, GpioValue_Low},
|
||||
{0x19, GpioDirection_Input, GpioValue_High},
|
||||
{0x1A, GpioDirection_Input, GpioValue_High},
|
||||
{0x1B, GpioDirection_Input, GpioValue_High},
|
||||
{0x1C, GpioDirection_Input, GpioValue_Low},
|
||||
{0x1D, GpioDirection_Output, GpioValue_Low},
|
||||
{0x1E, GpioDirection_Output, GpioValue_Low},
|
||||
{0x20, GpioDirection_Output, GpioValue_Low},
|
||||
{0x21, GpioDirection_Input, GpioValue_High},
|
||||
{0x38, GpioDirection_Input, GpioValue_High},
|
||||
{0x22, GpioDirection_Input, GpioValue_Low},
|
||||
{0x23, GpioDirection_Input, GpioValue_High},
|
||||
{0x01, GpioDirection_Output, GpioValue_Low},
|
||||
{0x39, GpioDirection_Output, GpioValue_Low},
|
||||
{0x24, GpioDirection_Output, GpioValue_Low},
|
||||
{0x34, GpioDirection_Input, GpioValue_Low},
|
||||
{0x25, GpioDirection_Input, GpioValue_Low},
|
||||
{0x26, GpioDirection_Input, GpioValue_Low},
|
||||
{0x27, GpioDirection_Input, GpioValue_Low},
|
||||
{0x2B, GpioDirection_Output, GpioValue_Low},
|
||||
{0x28, GpioDirection_Input, GpioValue_High},
|
||||
{0x1F, GpioDirection_Output, GpioValue_Low},
|
||||
{0x29, GpioDirection_Input, GpioValue_High},
|
||||
{0x2A, GpioDirection_Input, GpioValue_High},
|
||||
{0x3A, GpioDirection_Output, GpioValue_Low},
|
||||
{0x0C, GpioDirection_Input, GpioValue_Low},
|
||||
{0x2D, GpioDirection_Output, GpioValue_Low},
|
||||
{0x2E, GpioDirection_Output, GpioValue_Low},
|
||||
{0x37, GpioDirection_Input, GpioValue_Low},
|
||||
{0x2F, GpioDirection_Output, GpioValue_Low},
|
||||
{0x03, GpioDirection_Output, GpioValue_Low},
|
||||
{0x30, GpioDirection_Input, GpioValue_Low},
|
||||
{0x3B, GpioDirection_Input, GpioValue_Low},
|
||||
{0x31, GpioDirection_Output, GpioValue_Low},
|
||||
{0x32, GpioDirection_Output, GpioValue_Low},
|
||||
{0x33, GpioDirection_Output, GpioValue_Low},
|
||||
{0x35, GpioDirection_Input, GpioValue_High},
|
||||
{0x2C, GpioDirection_Output, GpioValue_Low},
|
||||
{0x36, GpioDirection_Output, GpioValue_Low},
|
||||
};
|
||||
|
||||
constexpr u32 NumInitialConfigsIcosa = (sizeof(InitialConfigsIcosa) / sizeof(InitialConfigsIcosa[0]));
|
||||
|
||||
constexpr InitialConfig InitialConfigsIcosa4x[] = {
|
||||
{0x04, GpioDirection_Input, GpioValue_High},
|
||||
{0x05, GpioDirection_Output, GpioValue_Low},
|
||||
{0x06, GpioDirection_Input, GpioValue_Low},
|
||||
{0x02, GpioDirection_Output, GpioValue_Low},
|
||||
{0x07, GpioDirection_Output, GpioValue_Low},
|
||||
{0x3C, GpioDirection_Input, GpioValue_Low},
|
||||
{0x0F, GpioDirection_Input, GpioValue_High},
|
||||
{0x08, GpioDirection_Input, GpioValue_Low},
|
||||
{0x09, GpioDirection_Input, GpioValue_Low},
|
||||
{0x0A, GpioDirection_Output, GpioValue_Low},
|
||||
{0x0B, GpioDirection_Input, GpioValue_High},
|
||||
{0x0D, GpioDirection_Output, GpioValue_Low},
|
||||
{0x0E, GpioDirection_Input, GpioValue_Low},
|
||||
{0x10, GpioDirection_Input, GpioValue_Low},
|
||||
{0x11, GpioDirection_Input, GpioValue_Low},
|
||||
{0x12, GpioDirection_Input, GpioValue_Low},
|
||||
{0x13, GpioDirection_Input, GpioValue_Low},
|
||||
{0x14, GpioDirection_Input, GpioValue_High},
|
||||
{0x16, GpioDirection_Input, GpioValue_Low},
|
||||
{0x15, GpioDirection_Input, GpioValue_Low},
|
||||
{0x17, GpioDirection_Input, GpioValue_High},
|
||||
{0x18, GpioDirection_Input, GpioValue_High},
|
||||
{0x19, GpioDirection_Input, GpioValue_High},
|
||||
{0x1A, GpioDirection_Input, GpioValue_High},
|
||||
{0x1B, GpioDirection_Input, GpioValue_High},
|
||||
{0x1C, GpioDirection_Input, GpioValue_Low},
|
||||
{0x1D, GpioDirection_Output, GpioValue_Low},
|
||||
{0x1E, GpioDirection_Output, GpioValue_Low},
|
||||
{0x20, GpioDirection_Output, GpioValue_Low},
|
||||
{0x21, GpioDirection_Input, GpioValue_High},
|
||||
{0x38, GpioDirection_Input, GpioValue_High},
|
||||
{0x22, GpioDirection_Input, GpioValue_Low},
|
||||
{0x23, GpioDirection_Input, GpioValue_High},
|
||||
{0x01, GpioDirection_Output, GpioValue_Low},
|
||||
{0x39, GpioDirection_Output, GpioValue_Low},
|
||||
{0x24, GpioDirection_Output, GpioValue_Low},
|
||||
{0x34, GpioDirection_Input, GpioValue_Low},
|
||||
{0x25, GpioDirection_Input, GpioValue_Low},
|
||||
{0x26, GpioDirection_Input, GpioValue_Low},
|
||||
{0x27, GpioDirection_Input, GpioValue_Low},
|
||||
{0x2B, GpioDirection_Output, GpioValue_Low},
|
||||
{0x28, GpioDirection_Input, GpioValue_High},
|
||||
{0x1F, GpioDirection_Output, GpioValue_Low},
|
||||
{0x29, GpioDirection_Input, GpioValue_High},
|
||||
{0x2A, GpioDirection_Input, GpioValue_High},
|
||||
{0x3A, GpioDirection_Output, GpioValue_Low},
|
||||
{0x0C, GpioDirection_Input, GpioValue_Low},
|
||||
{0x2D, GpioDirection_Output, GpioValue_Low},
|
||||
{0x2E, GpioDirection_Output, GpioValue_Low},
|
||||
{0x37, GpioDirection_Input, GpioValue_Low},
|
||||
{0x2F, GpioDirection_Output, GpioValue_Low},
|
||||
{0x03, GpioDirection_Output, GpioValue_Low},
|
||||
{0x30, GpioDirection_Input, GpioValue_Low},
|
||||
{0x3B, GpioDirection_Input, GpioValue_Low},
|
||||
{0x31, GpioDirection_Output, GpioValue_Low},
|
||||
{0x32, GpioDirection_Output, GpioValue_Low},
|
||||
{0x33, GpioDirection_Output, GpioValue_Low},
|
||||
{0x35, GpioDirection_Input, GpioValue_High},
|
||||
{0x2C, GpioDirection_Output, GpioValue_Low},
|
||||
{0x36, GpioDirection_Output, GpioValue_Low},
|
||||
};
|
||||
|
||||
constexpr u32 NumInitialConfigsIcosa4x = (sizeof(InitialConfigsIcosa4x) / sizeof(InitialConfigsIcosa4x[0]));
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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/>.
|
||||
*/
|
||||
|
||||
constexpr InitialConfig InitialConfigsIowa[] = {
|
||||
{0x04, GpioDirection_Input, GpioValue_High},
|
||||
{0x05, GpioDirection_Output, GpioValue_Low},
|
||||
{0x06, GpioDirection_Input, GpioValue_Low},
|
||||
{0x02, GpioDirection_Output, GpioValue_Low},
|
||||
{0x3C, GpioDirection_Input, GpioValue_Low},
|
||||
{0x0F, GpioDirection_Input, GpioValue_High},
|
||||
{0x08, GpioDirection_Input, GpioValue_Low},
|
||||
{0x09, GpioDirection_Input, GpioValue_Low},
|
||||
{0x0A, GpioDirection_Output, GpioValue_Low},
|
||||
{0x0B, GpioDirection_Input, GpioValue_Low},
|
||||
{0x0D, GpioDirection_Output, GpioValue_Low},
|
||||
{0x0E, GpioDirection_Input, GpioValue_Low},
|
||||
{0x10, GpioDirection_Input, GpioValue_Low},
|
||||
{0x11, GpioDirection_Input, GpioValue_Low},
|
||||
{0x12, GpioDirection_Input, GpioValue_Low},
|
||||
{0x13, GpioDirection_Input, GpioValue_Low},
|
||||
{0x14, GpioDirection_Input, GpioValue_High},
|
||||
{0x16, GpioDirection_Input, GpioValue_Low},
|
||||
{0x15, GpioDirection_Input, GpioValue_Low},
|
||||
{0x17, GpioDirection_Input, GpioValue_High},
|
||||
{0x18, GpioDirection_Input, GpioValue_Low},
|
||||
{0x19, GpioDirection_Input, GpioValue_High},
|
||||
{0x1A, GpioDirection_Input, GpioValue_High},
|
||||
{0x1B, GpioDirection_Input, GpioValue_Low},
|
||||
{0x1C, GpioDirection_Input, GpioValue_Low},
|
||||
{0x1D, GpioDirection_Output, GpioValue_Low},
|
||||
{0x1E, GpioDirection_Output, GpioValue_Low},
|
||||
{0x20, GpioDirection_Output, GpioValue_Low},
|
||||
{0x21, GpioDirection_Input, GpioValue_Low},
|
||||
{0x38, GpioDirection_Input, GpioValue_High},
|
||||
{0x22, GpioDirection_Input, GpioValue_Low},
|
||||
{0x23, GpioDirection_Input, GpioValue_High},
|
||||
{0x01, GpioDirection_Output, GpioValue_Low},
|
||||
{0x39, GpioDirection_Output, GpioValue_Low},
|
||||
{0x24, GpioDirection_Output, GpioValue_Low},
|
||||
{0x34, GpioDirection_Input, GpioValue_Low},
|
||||
{0x25, GpioDirection_Input, GpioValue_Low},
|
||||
{0x26, GpioDirection_Input, GpioValue_Low},
|
||||
{0x27, GpioDirection_Input, GpioValue_Low},
|
||||
{0x2B, GpioDirection_Output, GpioValue_Low},
|
||||
{0x28, GpioDirection_Input, GpioValue_High},
|
||||
{0x1F, GpioDirection_Output, GpioValue_Low},
|
||||
{0x29, GpioDirection_Input, GpioValue_High},
|
||||
{0x3A, GpioDirection_Output, GpioValue_Low},
|
||||
{0x0C, GpioDirection_Input, GpioValue_Low},
|
||||
{0x2D, GpioDirection_Output, GpioValue_Low},
|
||||
{0x2E, GpioDirection_Output, GpioValue_Low},
|
||||
{0x37, GpioDirection_Input, GpioValue_Low},
|
||||
{0x2F, GpioDirection_Output, GpioValue_Low},
|
||||
{0x03, GpioDirection_Output, GpioValue_Low},
|
||||
{0x30, GpioDirection_Input, GpioValue_Low},
|
||||
{0x3B, GpioDirection_Input, GpioValue_Low},
|
||||
{0x31, GpioDirection_Output, GpioValue_Low},
|
||||
{0x32, GpioDirection_Output, GpioValue_Low},
|
||||
{0x33, GpioDirection_Output, GpioValue_Low},
|
||||
{0x35, GpioDirection_Input, GpioValue_High},
|
||||
{0x2C, GpioDirection_Output, GpioValue_Low},
|
||||
{0x36, GpioDirection_Output, GpioValue_Low},
|
||||
};
|
||||
|
||||
constexpr u32 NumInitialConfigsIowa = (sizeof(InitialConfigsIowa) / sizeof(InitialConfigsIowa[0]));
|
||||
108
stratosphere/boot/source/gpio/gpio_map.inc
Normal file
108
stratosphere/boot/source/gpio/gpio_map.inc
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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/>.
|
||||
*/
|
||||
|
||||
constexpr u32 InvalidPadName = UINT32_MAX;
|
||||
|
||||
constexpr u32 Map[] = {
|
||||
InvalidPadName, /* Invalid */
|
||||
0x000000CC, /* Port Z, Pin 4 */
|
||||
0x00000024, /* Port E, Pin 4 */
|
||||
0x0000003C, /* Port H, Pin 4 */
|
||||
0x000000DA, /* Port BB, Pin 2 */
|
||||
0x000000DB, /* Port BB, Pin 3 */
|
||||
0x000000DC, /* Port BB, Pin 4 */
|
||||
0x00000025, /* Port E, Pin 5 */
|
||||
0x00000090, /* Port S, Pin 0 */
|
||||
0x00000091, /* Port S, Pin 1 */
|
||||
0x00000096, /* Port S, Pin 6 */
|
||||
0x00000097, /* Port S, Pin 7 */
|
||||
0x00000026, /* Port E, Pin 6 */
|
||||
0x00000005, /* Port A, Pin 5 */
|
||||
0x00000078, /* Port P, Pin 0 */
|
||||
0x00000093, /* Port S, Pin 3 */
|
||||
0x0000007D, /* Port P, Pin 5 */
|
||||
0x0000007C, /* Port P, Pin 4 */
|
||||
0x0000007B, /* Port P, Pin 3 */
|
||||
0x0000007A, /* Port P, Pin 2 */
|
||||
0x000000BC, /* Port X, Pin 4 */
|
||||
0x000000AE, /* Port V, Pin 6 */
|
||||
0x000000BA, /* Port X, Pin 2 */
|
||||
0x000000B9, /* Port X, Pin 1 */
|
||||
0x000000BD, /* Port X, Pin 5 */
|
||||
0x000000BE, /* Port X, Pin 6 */
|
||||
0x000000BF, /* Port X, Pin 7 */
|
||||
0x000000C0, /* Port Y, Pin 0 */
|
||||
0x000000C1, /* Port Y, Pin 1 */
|
||||
0x000000A9, /* Port V, Pin 1 */
|
||||
0x000000AA, /* Port V, Pin 2 */
|
||||
0x00000055, /* Port K, Pin 5 */
|
||||
0x000000AD, /* Port V, Pin 5 */
|
||||
0x000000C8, /* Port Z, Pin 0 */
|
||||
0x000000CA, /* Port Z, Pin 2 */
|
||||
0x000000CB, /* Port Z, Pin 3 */
|
||||
0x0000004F, /* Port J, Pin 7 */
|
||||
0x00000050, /* Port K, Pin 0 */
|
||||
0x00000051, /* Port K, Pin 1 */
|
||||
0x00000052, /* Port K, Pin 2 */
|
||||
0x00000054, /* Port K, Pin 4 */
|
||||
0x00000056, /* Port K, Pin 6 */
|
||||
0x00000057, /* Port K, Pin 7 */
|
||||
0x00000053, /* Port K, Pin 3 */
|
||||
0x000000E3, /* Port CC, Pin 3 */
|
||||
0x00000038, /* Port H, Pin 0 */
|
||||
0x00000039, /* Port H, Pin 1 */
|
||||
0x0000003B, /* Port H, Pin 3 */
|
||||
0x0000003D, /* Port H, Pin 5 */
|
||||
0x0000003F, /* Port H, Pin 7 */
|
||||
0x00000040, /* Port I, Pin 0 */
|
||||
0x00000041, /* Port I, Pin 1 */
|
||||
0x0000003E, /* Port H, Pin 6 */
|
||||
0x000000E2, /* Port CC, Pin 2 */
|
||||
0x000000E4, /* Port CC, Pin 4 */
|
||||
0x0000003A, /* Port H, Pin 2 */
|
||||
0x000000C9, /* Port Z, Pin 1 */
|
||||
0x0000004D, /* Port J, Pin 5 */
|
||||
0x00000058, /* Port L, Pin 0 */
|
||||
0x0000003E, /* Port H, Pin 6 */
|
||||
0x00000026, /* Port E, Pin 6 */
|
||||
|
||||
/* Copper only */
|
||||
InvalidPadName, /* Invalid */
|
||||
0x00000033, /* Port G, Pin 3 */
|
||||
0x0000001C, /* Port D, Pin 4 */
|
||||
0x000000D9, /* Port BB, Pin 1 */
|
||||
0x0000000C, /* Port B, Pin 4 */
|
||||
0x0000000D, /* Port B, Pin 5 */
|
||||
0x00000021, /* Port E, Pin 1 */
|
||||
0x00000027, /* Port E, Pin 7 */
|
||||
0x00000092, /* Port S, Pin 2 */
|
||||
0x00000095, /* Port S, Pin 5 */
|
||||
0x00000098, /* Port T, Pin 0 */
|
||||
0x00000010, /* Port C, Pin 0 */
|
||||
0x00000011, /* Port C, Pin 1 */
|
||||
0x00000012, /* Port C, Pin 2 */
|
||||
0x00000042, /* Port I, Pin 2 */
|
||||
0x000000E6, /* Port CC, Pin 6 */
|
||||
|
||||
/* 2.0.0+ Copper only */
|
||||
0x000000AC, /* Port V, Pin 4 */
|
||||
0x000000E1, /* Port CC, Pin 1 */
|
||||
|
||||
/* 5.0.0+ Copper only (unused) */
|
||||
0x00000056, /* Port K, Pin 6 */
|
||||
};
|
||||
|
||||
static constexpr u32 PadNameMax = (sizeof(Map) / sizeof(Map[0]));
|
||||
132
stratosphere/boot/source/gpio/gpio_utils.cpp
Normal file
132
stratosphere/boot/source/gpio/gpio_utils.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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/reg.hpp>
|
||||
|
||||
#include "gpio_utils.hpp"
|
||||
|
||||
namespace sts::gpio {
|
||||
|
||||
namespace {
|
||||
|
||||
/* Pull in GPIO map definitions. */
|
||||
#include "gpio_map.inc"
|
||||
|
||||
constexpr u32 PhysicalBase = 0x6000D000;
|
||||
|
||||
/* Globals. */
|
||||
bool g_initialized_gpio_vaddr = false;
|
||||
uintptr_t g_gpio_vaddr = 0;
|
||||
|
||||
/* Helpers. */
|
||||
inline u32 GetPadDescriptor(u32 gpio_pad_name) {
|
||||
if (gpio_pad_name >= PadNameMax) {
|
||||
std::abort();
|
||||
}
|
||||
|
||||
return Map[gpio_pad_name];
|
||||
}
|
||||
|
||||
uintptr_t GetBaseAddress() {
|
||||
if (!g_initialized_gpio_vaddr) {
|
||||
g_gpio_vaddr = GetIoMapping(PhysicalBase, 0x1000);
|
||||
g_initialized_gpio_vaddr = true;
|
||||
}
|
||||
return g_gpio_vaddr;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
u32 Configure(u32 gpio_pad_name) {
|
||||
uintptr_t gpio_base_vaddr = GetBaseAddress();
|
||||
|
||||
/* Fetch this GPIO's pad descriptor */
|
||||
const u32 gpio_pad_desc = GetPadDescriptor(gpio_pad_name);
|
||||
|
||||
/* Discard invalid GPIOs */
|
||||
if (gpio_pad_desc == InvalidPadName) {
|
||||
return InvalidPadName;
|
||||
}
|
||||
|
||||
/* Convert the GPIO pad descriptor into its register offset */
|
||||
u32 gpio_reg_offset = (((gpio_pad_desc << 0x03) & 0xFFFFFF00) | ((gpio_pad_desc >> 0x01) & 0x0C));
|
||||
|
||||
/* Extract the bit and lock values from the GPIO pad descriptor */
|
||||
u32 gpio_cnf_val = ((0x01 << ((gpio_pad_desc & 0x07) | 0x08)) | (0x01 << (gpio_pad_desc & 0x07)));
|
||||
|
||||
/* Write to the appropriate GPIO_CNF_x register (upper offset) */
|
||||
reg::Write(gpio_base_vaddr + gpio_reg_offset + 0x80, gpio_cnf_val);
|
||||
|
||||
/* Do a dummy read from GPIO_CNF_x register (lower offset) */
|
||||
gpio_cnf_val = reg::Read(gpio_base_vaddr + gpio_reg_offset + 0x00);
|
||||
|
||||
return gpio_cnf_val;
|
||||
}
|
||||
|
||||
u32 SetDirection(u32 gpio_pad_name, GpioDirection dir) {
|
||||
uintptr_t gpio_base_vaddr = GetBaseAddress();
|
||||
|
||||
/* Fetch this GPIO's pad descriptor */
|
||||
const u32 gpio_pad_desc = GetPadDescriptor(gpio_pad_name);
|
||||
|
||||
/* Discard invalid GPIOs */
|
||||
if (gpio_pad_desc == InvalidPadName) {
|
||||
return InvalidPadName;
|
||||
}
|
||||
|
||||
/* Convert the GPIO pad descriptor into its register offset */
|
||||
u32 gpio_reg_offset = (((gpio_pad_desc << 0x03) & 0xFFFFFF00) | ((gpio_pad_desc >> 0x01) & 0x0C));
|
||||
|
||||
/* Set the direction bit and lock values */
|
||||
u32 gpio_oe_val = ((0x01 << ((gpio_pad_desc & 0x07) | 0x08)) | (static_cast<u32>(dir) << (gpio_pad_desc & 0x07)));
|
||||
|
||||
/* Write to the appropriate GPIO_OE_x register (upper offset) */
|
||||
reg::Write(gpio_base_vaddr + gpio_reg_offset + 0x90, gpio_oe_val);
|
||||
|
||||
/* Do a dummy read from GPIO_OE_x register (lower offset) */
|
||||
gpio_oe_val = reg::Read(gpio_base_vaddr + gpio_reg_offset + 0x10);
|
||||
|
||||
return gpio_oe_val;
|
||||
}
|
||||
|
||||
u32 SetValue(u32 gpio_pad_name, GpioValue val) {
|
||||
uintptr_t gpio_base_vaddr = GetBaseAddress();
|
||||
|
||||
/* Fetch this GPIO's pad descriptor */
|
||||
const u32 gpio_pad_desc = GetPadDescriptor(gpio_pad_name);
|
||||
|
||||
/* Discard invalid GPIOs */
|
||||
if (gpio_pad_desc == InvalidPadName) {
|
||||
return InvalidPadName;
|
||||
}
|
||||
|
||||
/* Convert the GPIO pad descriptor into its register offset */
|
||||
u32 gpio_reg_offset = (((gpio_pad_desc << 0x03) & 0xFFFFFF00) | ((gpio_pad_desc >> 0x01) & 0x0C));
|
||||
|
||||
/* Set the output bit and lock values */
|
||||
u32 gpio_out_val = ((0x01 << ((gpio_pad_desc & 0x07) | 0x08)) | (static_cast<u32>(val) << (gpio_pad_desc & 0x07)));
|
||||
|
||||
/* Write to the appropriate GPIO_OUT_x register (upper offset) */
|
||||
reg::Write(gpio_base_vaddr + gpio_reg_offset + 0xA0, gpio_out_val);
|
||||
|
||||
/* Do a dummy read from GPIO_OUT_x register (lower offset) */
|
||||
gpio_out_val = reg::Read(gpio_base_vaddr + gpio_reg_offset + 0x20);
|
||||
|
||||
return gpio_out_val;
|
||||
}
|
||||
|
||||
}
|
||||
28
stratosphere/boot/source/gpio/gpio_utils.hpp
Normal file
28
stratosphere/boot/source/gpio/gpio_utils.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace sts::gpio {
|
||||
|
||||
/* GPIO Utilities. */
|
||||
u32 Configure(u32 gpio_pad_name);
|
||||
u32 SetDirection(u32 gpio_pad_name, GpioDirection dir);
|
||||
u32 SetValue(u32 gpio_pad_name, GpioValue val);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user