1
0
Fork 0
mirror of https://github.com/Atmosphere-NX/Atmosphere.git synced 2024-11-05 19:51:45 +00:00

Boot: Implement PMC wake pin events

This commit is contained in:
hexkyz 2018-05-21 21:32:57 +01:00 committed by GitHub
parent a4b1cf8b50
commit b777844d2d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -10,10 +10,12 @@
#define APB_MISC_BASE 0x70000000 #define APB_MISC_BASE 0x70000000
#define PINMUX_BASE (APB_MISC_BASE + 0x3000) #define PINMUX_BASE (APB_MISC_BASE + 0x3000)
#define PMC_BASE 0x7000E400 #define PMC_BASE 0x7000E400
#define MAX_GPIOS 0x3D #define MAX_GPIO 0x3D
#define MAX_PINMUX 0xA2 #define MAX_PINMUX 0xA2
#define MAX_PINMUX_5X 0xAF #define MAX_PINMUX_5X 0xAF
#define MAX_PINMUX_DRIVEPAD 0x2F #define MAX_PINMUX_DRIVEPAD 0x2F
#define MAX_PMC_CONTROL 0x09
#define MAX_PMC_WAKE_PIN 0x31
extern "C" { extern "C" {
extern u32 __start__; extern u32 __start__;
@ -1355,6 +1357,536 @@ static int pinmux_update_drivepad(u64 pinmux_base_vaddr, unsigned int pinmux_dri
return pinmux_drivepad_val; return pinmux_drivepad_val;
} }
static const std::tuple<u32, u32, u32> g_pmc_control_map[] = {
{0x000, 0x0800, 0x01},
{0x000, 0x0400, 0x00},
{0x000, 0x0200, 0x01},
{0x000, 0x0100, 0x00},
{0x000, 0x0040, 0x00},
{0x000, 0x0020, 0x00},
{0x440, 0x4000, 0x01},
{0x440, 0x0200, 0x00},
{0x440, 0x0001, 0x01},
};
static int pmc_init_wake_events(u64 pmc_base_vaddr, bool is_blink) {
Result rc;
u32 pmc_wake_debounce_val = 0;
u32 pmc_blink_timer_val = 0x08008800;
u32 pmc_cntrl_val = 0;
u32 pmc_dpd_pads_oride_val = 0;
if (kernelAbove200()) {
/* Use svcReadWriteRegister to write APBDEV_PMC_WAKE_DEBOUNCE_EN_0 */
rc = svcReadWriteRegister(&pmc_wake_debounce_val, PMC_BASE + 0x4D8, 0xFFFFFFFF, pmc_wake_debounce_val);
if (R_FAILED(rc)) {
return rc;
}
/* Use svcReadWriteRegister to do a dummy read from APBDEV_PMC_WAKE_DEBOUNCE_EN_0 */
rc = svcReadWriteRegister(&pmc_wake_debounce_val, PMC_BASE + 0x4D8, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
/* Use svcReadWriteRegister to write APBDEV_PMC_BLINK_TIMER_0 */
rc = svcReadWriteRegister(&pmc_blink_timer_val, PMC_BASE + 0x40, 0xFFFFFFFF, pmc_blink_timer_val);
if (R_FAILED(rc)) {
return rc;
}
/* Use svcReadWriteRegister to do a dummy read from APBDEV_PMC_BLINK_TIMER_0 */
rc = svcReadWriteRegister(&pmc_blink_timer_val, PMC_BASE + 0x40, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
for (unsigned int i = 0; i < MAX_PMC_CONTROL; i++) {
/* Fetch this PMC register offset */
u32 pmc_control_reg_offset = std::get<0>(g_pmc_control_map[i]);
/* Fetch this PMC mask value */
u32 pmc_control_mask_val = std::get<1>(g_pmc_control_map[i]);
/* Fetch this PMC flag value */
u32 pmc_control_flag_val = std::get<2>(g_pmc_control_map[i]);
u32 pmc_control_val = 0;
/* Use svcReadWriteRegister to read from the PMC register */
rc = svcReadWriteRegister(&pmc_control_val, PMC_BASE + pmc_control_reg_offset, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
pmc_control_val &= ~(pmc_control_mask_val);
pmc_control_val |= ((pmc_control_flag_val & 0x01) ? pmc_control_mask_val : 0);
/* Use svcReadWriteRegister to write to the PMC register */
rc = svcReadWriteRegister(&pmc_control_val, PMC_BASE + pmc_control_reg_offset, 0xFFFFFFFF, pmc_control_val);
if (R_FAILED(rc)) {
return rc;
}
/* Use svcReadWriteRegister to do a dummy read from the PMC register */
rc = svcReadWriteRegister(&pmc_control_val, PMC_BASE + pmc_control_reg_offset, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
}
/* Use svcReadWriteRegister to read from APBDEV_PMC_CNTRL_0 */
rc = svcReadWriteRegister(&pmc_cntrl_val, PMC_BASE + 0, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
pmc_cntrl_val &= ~(0x80);
pmc_cntrl_val |= (is_blink ? 0x80 : 0);
/* Use svcReadWriteRegister to write to APBDEV_PMC_CNTRL_0 */
rc = svcReadWriteRegister(&pmc_cntrl_val, PMC_BASE + 0, 0xFFFFFFFF, pmc_cntrl_val);
if (R_FAILED(rc)) {
return rc;
}
/* Use svcReadWriteRegister to do a dummy read from APBDEV_PMC_CNTRL_0 */
rc = svcReadWriteRegister(&pmc_cntrl_val, PMC_BASE + 0, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
/* Use svcReadWriteRegister to read from APBDEV_PMC_DPD_PADS_ORIDE_0 */
rc = svcReadWriteRegister(&pmc_dpd_pads_oride_val, PMC_BASE + 0x1C, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
pmc_dpd_pads_oride_val &= ~(0x100000);
pmc_dpd_pads_oride_val |= (is_blink ? 0x100000 : 0);
/* Use svcReadWriteRegister to write to APBDEV_PMC_DPD_PADS_ORIDE_0 */
rc = svcReadWriteRegister(&pmc_dpd_pads_oride_val, PMC_BASE + 0x1C, 0xFFFFFFFF, pmc_dpd_pads_oride_val);
if (R_FAILED(rc)) {
return rc;
}
/* Use svcReadWriteRegister to do a dummy read from APBDEV_PMC_DPD_PADS_ORIDE_0 */
rc = svcReadWriteRegister(&pmc_dpd_pads_oride_val, PMC_BASE + 0x1C, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
} else {
/* Write to APBDEV_PMC_WAKE_DEBOUNCE_EN_0 */
*((u32 *)pmc_base_vaddr + 0x4D8) = pmc_wake_debounce_val;
/* Do a dummy read from APBDEV_PMC_WAKE_DEBOUNCE_EN_0 */
pmc_wake_debounce_val = *((u32 *)pmc_base_vaddr + 0x4D8);
/* Write to APBDEV_PMC_BLINK_TIMER_0 */
*((u32 *)pmc_base_vaddr + 0x40) = pmc_blink_timer_val;
/* Do a dummy read from APBDEV_PMC_BLINK_TIMER_0 */
pmc_blink_timer_val = *((u32 *)pmc_base_vaddr + 0x40);
for (unsigned int i = 0; i < MAX_PMC_CONTROL; i++) {
/* Fetch this PMC register offset */
u32 pmc_control_reg_offset = std::get<0>(g_pmc_control_map[i]);
/* Fetch this PMC mask value */
u32 pmc_control_mask_val = std::get<1>(g_pmc_control_map[i]);
/* Fetch this PMC flag value */
u32 pmc_control_flag_val = std::get<2>(g_pmc_control_map[i]);
/* Read from the PMC register */
u32 pmc_control_val = *((u32 *)pmc_base_vaddr + pmc_control_reg_offset);
pmc_control_val &= ~(pmc_control_mask_val);
pmc_control_val |= ((pmc_control_flag_val & 0x01) ? pmc_control_mask_val : 0);
/* Write to the PMC register */
*((u32 *)pmc_base_vaddr + pmc_control_reg_offset) = pmc_control_val;
/* Do a dummy read from the PMC register */
pmc_control_val = *((u32 *)pmc_base_vaddr + pmc_control_reg_offset);
}
/* Read from APBDEV_PMC_CNTRL_0 */
pmc_cntrl_val = *((u32 *)pmc_base_vaddr + 0);
pmc_cntrl_val &= ~(0x80);
pmc_cntrl_val |= (is_blink ? 0x80 : 0);
/* Write to APBDEV_PMC_CNTRL_0 */
*((u32 *)pmc_base_vaddr + 0) = pmc_cntrl_val;
/* Do a dummy read from APBDEV_PMC_CNTRL_0 */
pmc_cntrl_val = *((u32 *)pmc_base_vaddr + 0);
/* Read from APBDEV_PMC_DPD_PADS_ORIDE_0 */
pmc_dpd_pads_oride_val = *((u32 *)pmc_base_vaddr + 0x1C);
pmc_dpd_pads_oride_val &= ~(0x100000);
pmc_dpd_pads_oride_val |= (is_blink ? 0x100000 : 0);
/* Write to APBDEV_PMC_DPD_PADS_ORIDE_0 */
*((u32 *)pmc_base_vaddr + 0x1C) = pmc_dpd_pads_oride_val;
/* Do a dummy read from APBDEV_PMC_DPD_PADS_ORIDE_0 */
pmc_dpd_pads_oride_val = *((u32 *)pmc_base_vaddr + 0x1C);
}
rc = 0;
return rc;
}
static const std::tuple<u32, u32, u32> g_pmc_wake_pin_map_icosa[] = {
{0x00, 0x00, 0x02},
{0x01, 0x00, 0x02},
{0x02, 0x00, 0x02},
{0x03, 0x00, 0x02},
{0x04, 0x01, 0x02},
{0x05, 0x00, 0x02},
{0x06, 0x01, 0x02},
{0x07, 0x01, 0x02},
{0x08, 0x00, 0x02},
{0x0A, 0x01, 0x02},
{0x0B, 0x00, 0x02},
{0x0C, 0x00, 0x02},
{0x0D, 0x00, 0x02},
{0x0E, 0x01, 0x00},
{0x0F, 0x00, 0x02},
{0x11, 0x00, 0x02},
{0x12, 0x00, 0x02},
{0x13, 0x00, 0x02},
{0x14, 0x00, 0x02},
{0x15, 0x00, 0x02},
{0x16, 0x00, 0x02},
{0x17, 0x00, 0x02},
{0x18, 0x00, 0x02},
{0x19, 0x00, 0x02},
{0x1A, 0x00, 0x02},
{0x1B, 0x01, 0x00},
{0x1C, 0x00, 0x02},
{0x21, 0x00, 0x02},
{0x22, 0x01, 0x00},
{0x23, 0x01, 0x02},
{0x24, 0x00, 0x02},
{0x2D, 0x00, 0x02},
{0x2E, 0x00, 0x02},
{0x2F, 0x00, 0x02},
{0x30, 0x01, 0x02},
{0x31, 0x00, 0x02},
{0x32, 0x00, 0x02},
{0x33, 0x01, 0x00},
{0x34, 0x01, 0x00},
{0x35, 0x00, 0x02},
{0x36, 0x00, 0x02},
{0x37, 0x00, 0x02},
{0x38, 0x00, 0x02},
{0x39, 0x00, 0x02},
{0x3A, 0x00, 0x02},
{0x3B, 0x00, 0x02},
{0x3D, 0x00, 0x02},
{0x3E, 0x00, 0x02},
{0x3F, 0x00, 0x02},
};
static const std::tuple<u32, u32, u32> g_pmc_wake_pin_map_copper[] = {
{0x00, 0x01, 0x02},
{0x01, 0x00, 0x02},
{0x02, 0x00, 0x02},
{0x03, 0x01, 0x02},
{0x04, 0x00, 0x02},
{0x05, 0x01, 0x02},
{0x06, 0x00, 0x02},
{0x07, 0x00, 0x02},
{0x08, 0x01, 0x02},
{0x0A, 0x00, 0x02},
{0x0B, 0x00, 0x02},
{0x0C, 0x00, 0x02},
{0x0D, 0x00, 0x02},
{0x0E, 0x01, 0x00},
{0x0F, 0x00, 0x02},
{0x11, 0x00, 0x02},
{0x12, 0x00, 0x02},
{0x13, 0x00, 0x02},
{0x14, 0x00, 0x02},
{0x15, 0x00, 0x02},
{0x16, 0x00, 0x02},
{0x17, 0x00, 0x02},
{0x18, 0x01, 0x02},
{0x19, 0x00, 0x02},
{0x1A, 0x00, 0x02},
{0x1B, 0x00, 0x00},
{0x1C, 0x00, 0x02},
{0x21, 0x00, 0x02},
{0x22, 0x00, 0x00},
{0x23, 0x00, 0x02},
{0x24, 0x00, 0x02},
{0x2D, 0x00, 0x02},
{0x2E, 0x00, 0x02},
{0x2F, 0x01, 0x02},
{0x30, 0x01, 0x02},
{0x31, 0x00, 0x02},
{0x32, 0x01, 0x02},
{0x33, 0x01, 0x00},
{0x34, 0x01, 0x00},
{0x35, 0x00, 0x02},
{0x36, 0x00, 0x02},
{0x37, 0x00, 0x02},
{0x38, 0x00, 0x02},
{0x39, 0x00, 0x02},
{0x3A, 0x00, 0x02},
{0x3B, 0x00, 0x02},
{0x3D, 0x00, 0x02},
{0x3E, 0x00, 0x02},
{0x3F, 0x00, 0x02},
};
static int pmc_set_wake_event_level(u64 pmc_base_vaddr, unsigned int wake_pin_idx, unsigned int wake_pin_mode) {
Result rc;
/* Invalid pin index */
if (wake_pin_idx > 0x3F) {
return -1;
}
u32 pmc_wake_level_reg_offset = 0;
u32 pmc_wake_level_mask_reg_offset = 0;
u32 pmc_wake_level_val = 0;
u32 pmc_wake_level_mask_val = 0;
/* Pins up to 0x1F use APBDEV_PMC_WAKE_LVL_0 and APBDEV_PMC_AUTO_WAKE_LVL_MASK_0, */
/* while others use APBDEV_PMC_WAKE2_LVL_0 and APBDEV_PMC_AUTO_WAKE2_LVL_MASK_0 */
if (wake_pin_idx <= 0x1F) {
pmc_wake_level_reg_offset = 0x10;
pmc_wake_level_mask_reg_offset = 0xDC;
} else {
pmc_wake_level_reg_offset = 0x164;
pmc_wake_level_mask_reg_offset = 0x170;
}
if (wake_pin_mode < 0x02) {
if (kernelAbove200()) {
/* Use svcReadWriteRegister to read from the PMC register */
rc = svcReadWriteRegister(&pmc_wake_level_mask_val, PMC_BASE + pmc_wake_level_mask_reg_offset, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
/* Mask with the wake pin index */
pmc_wake_level_mask_val &= ~(0x01 << (wake_pin_idx & 0x1F));
/* Use svcReadWriteRegister to write to the PMC register */
rc = svcReadWriteRegister(&pmc_wake_level_mask_val, PMC_BASE + pmc_wake_level_mask_reg_offset, 0xFFFFFFFF, pmc_wake_level_mask_val);
if (R_FAILED(rc)) {
return rc;
}
/* Use svcReadWriteRegister to do a dummy read from the PMC register */
rc = svcReadWriteRegister(&pmc_wake_level_mask_val, PMC_BASE + pmc_wake_level_mask_reg_offset, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
/* Use svcReadWriteRegister to read from the PMC register */
rc = svcReadWriteRegister(&pmc_wake_level_val, PMC_BASE + pmc_wake_level_reg_offset, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
/* Mask with the wake pin index */
pmc_wake_level_val &= ~(0x01 << (wake_pin_idx & 0x1F));
/* Set or clear the wake level */
pmc_wake_level_val |= (wake_pin_mode ? (0x01 << (wake_pin_idx & 0x1F)) : 0);
/* Use svcReadWriteRegister to write to the PMC register */
rc = svcReadWriteRegister(&pmc_wake_level_val, PMC_BASE + pmc_wake_level_reg_offset, 0xFFFFFFFF, pmc_wake_level_val);
if (R_FAILED(rc)) {
return rc;
}
/* Use svcReadWriteRegister to do a dummy read from the PMC register */
rc = svcReadWriteRegister(&pmc_wake_level_val, PMC_BASE + pmc_wake_level_reg_offset, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
} else {
/* Read from the PMC register */
pmc_wake_level_mask_val = *((u32 *)pmc_base_vaddr + pmc_wake_level_mask_reg_offset);
/* Mask with the wake pin index */
pmc_wake_level_mask_val &= ~(0x01 << (wake_pin_idx & 0x1F));
/* Write to the PMC register */
*((u32 *)pmc_base_vaddr + pmc_wake_level_mask_reg_offset) = pmc_wake_level_mask_val;
/* Do a dummy read from the PMC register */
pmc_wake_level_mask_val = *((u32 *)pmc_base_vaddr + pmc_wake_level_mask_reg_offset);
/* Read from the PMC register */
pmc_wake_level_val = *((u32 *)pmc_base_vaddr + pmc_wake_level_reg_offset);
/* Mask with the wake pin index */
pmc_wake_level_val &= ~(0x01 << (wake_pin_idx & 0x1F));
/* Set or clear the wake level */
pmc_wake_level_val |= (wake_pin_mode ? (0x01 << (wake_pin_idx & 0x1F)) : 0);
/* Write to the PMC register */
*((u32 *)pmc_base_vaddr + pmc_wake_level_reg_offset) = pmc_wake_level_val;
/* Do a dummy read from the PMC register */
pmc_wake_level_val = *((u32 *)pmc_base_vaddr + pmc_wake_level_reg_offset);
}
} else if (wake_pin_mode == 0x02) {
if (kernelAbove200()) {
/* Use svcReadWriteRegister to read from the PMC register */
rc = svcReadWriteRegister(&pmc_wake_level_val, PMC_BASE + pmc_wake_level_reg_offset, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
/* Mask with the wake pin index */
pmc_wake_level_val &= ~(0x01 << (wake_pin_idx & 0x1F));
/* Use svcReadWriteRegister to write to the PMC register */
rc = svcReadWriteRegister(&pmc_wake_level_val, PMC_BASE + pmc_wake_level_reg_offset, 0xFFFFFFFF, pmc_wake_level_val);
if (R_FAILED(rc)) {
return rc;
}
/* Use svcReadWriteRegister to do a dummy read from the PMC register */
rc = svcReadWriteRegister(&pmc_wake_level_val, PMC_BASE + pmc_wake_level_reg_offset, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
/* Use svcReadWriteRegister to read from the PMC register */
rc = svcReadWriteRegister(&pmc_wake_level_mask_val, PMC_BASE + pmc_wake_level_mask_reg_offset, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
/* Mask with the wake pin index */
pmc_wake_level_mask_val &= ~(0x01 << (wake_pin_idx & 0x1F));
/* Set the wake level mask */
pmc_wake_level_mask_val |= (0x01 << (wake_pin_idx & 0x1F));
/* Use svcReadWriteRegister to write to the PMC register */
rc = svcReadWriteRegister(&pmc_wake_level_mask_val, PMC_BASE + pmc_wake_level_mask_reg_offset, 0xFFFFFFFF, pmc_wake_level_mask_val);
if (R_FAILED(rc)) {
return rc;
}
/* Use svcReadWriteRegister to do a dummy read from the PMC register */
rc = svcReadWriteRegister(&pmc_wake_level_mask_val, PMC_BASE + pmc_wake_level_mask_reg_offset, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
} else {
/* Read from the PMC register */
pmc_wake_level_val = *((u32 *)pmc_base_vaddr + pmc_wake_level_reg_offset);
/* Mask with the wake pin index */
pmc_wake_level_val &= ~(0x01 << (wake_pin_idx & 0x1F));
/* Write to the PMC register */
*((u32 *)pmc_base_vaddr + pmc_wake_level_reg_offset) = pmc_wake_level_val;
/* Do a dummy read from the PMC register */
pmc_wake_level_val = *((u32 *)pmc_base_vaddr + pmc_wake_level_reg_offset);
/* Read from the PMC register */
pmc_wake_level_mask_val = *((u32 *)pmc_base_vaddr + pmc_wake_level_mask_reg_offset);
/* Mask with the wake pin index */
pmc_wake_level_mask_val &= ~(0x01 << (wake_pin_idx & 0x1F));
/* Set the wake level mask */
pmc_wake_level_mask_val |= (0x01 << (wake_pin_idx & 0x1F));
/* Write to the PMC register */
*((u32 *)pmc_base_vaddr + pmc_wake_level_mask_reg_offset) = pmc_wake_level_mask_val;
/* Do a dummy read from the PMC register */
pmc_wake_level_mask_val = *((u32 *)pmc_base_vaddr + pmc_wake_level_mask_reg_offset);
}
} else {
/* Invalid */
}
rc = 0;
return rc;
}
static int pmc_set_wake_event_enabled(u64 pmc_base_vaddr, unsigned int wake_pin_idx, bool is_enabled) {
Result rc;
/* Invalid pin index */
if (wake_pin_idx > 0x3F) {
return -1;
}
u32 pmc_wake_mask_reg_offset = 0;
u32 pmc_wake_mask_val = 0;
/* Pins up to 0x1F use APBDEV_PMC_WAKE_MASK_0, while others use APBDEV_PMC_WAKE2_MASK_0 */
if (wake_pin_idx <= 0x1F)
pmc_wake_mask_reg_offset = 0x0C;
else
pmc_wake_mask_reg_offset = 0x160;
if (kernelAbove200()) {
/* Use svcReadWriteRegister to read from the PMC register */
rc = svcReadWriteRegister(&pmc_wake_mask_val, PMC_BASE + pmc_wake_mask_reg_offset, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
/* Mask with the wake pin index */
pmc_wake_mask_val &= ~(0x01 << (wake_pin_idx & 0x1F));
/* Set the wake mask */
pmc_wake_mask_val |= (is_enabled ? (0x01 << (wake_pin_idx & 0x1F)) : 0);
/* Use svcReadWriteRegister to write to the PMC register */
rc = svcReadWriteRegister(&pmc_wake_mask_val, PMC_BASE + pmc_wake_mask_reg_offset, 0xFFFFFFFF, pmc_wake_mask_val);
if (R_FAILED(rc)) {
return rc;
}
/* Use svcReadWriteRegister to do a dummy read from the PMC register */
rc = svcReadWriteRegister(&pmc_wake_mask_val, PMC_BASE + pmc_wake_mask_reg_offset, 0, 0);
if (R_FAILED(rc)) {
return rc;
}
} else {
/* Read from the PMC register */
pmc_wake_mask_val = *((u32 *)pmc_base_vaddr + pmc_wake_mask_reg_offset);
/* Mask with the wake pin index */
pmc_wake_mask_val &= ~(0x01 << (wake_pin_idx & 0x1F));
/* Set the wake mask */
pmc_wake_mask_val |= (is_enabled ? (0x01 << (wake_pin_idx & 0x1F)) : 0);
/* Write to the PMC register */
*((u32 *)pmc_base_vaddr + pmc_wake_mask_reg_offset) = pmc_wake_mask_val;
/* Do a dummy read from the PMC register */
pmc_wake_mask_val = *((u32 *)pmc_base_vaddr + pmc_wake_mask_reg_offset);
}
rc = 0;
return rc;
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
consoleDebugInit(debugDevice_SVC); consoleDebugInit(debugDevice_SVC);
@ -1421,7 +1953,7 @@ int main(int argc, char **argv)
svcSleepThread(100000); svcSleepThread(100000);
/* Setup all GPIOs from 0x01 to 0x3C */ /* Setup all GPIOs from 0x01 to 0x3C */
for (unsigned int i = 1; i < MAX_GPIOS; i++) { for (unsigned int i = 1; i < MAX_GPIO; i++) {
gpio_configure(gpio_base_vaddr, i); gpio_configure(gpio_base_vaddr, i);
gpio_set_direction(gpio_base_vaddr, i); gpio_set_direction(gpio_base_vaddr, i);
gpio_set_value(gpio_base_vaddr, i); gpio_set_value(gpio_base_vaddr, i);
@ -1466,7 +1998,42 @@ int main(int argc, char **argv)
pinmux_update_drivepad(pinmux_base_vaddr, std::get<0>(g_pinmux_drivepad_config_map[i]), std::get<1>(g_pinmux_drivepad_config_map[i]), std::get<2>(g_pinmux_drivepad_config_map[i])); pinmux_update_drivepad(pinmux_base_vaddr, std::get<0>(g_pinmux_drivepad_config_map[i]), std::get<1>(g_pinmux_drivepad_config_map[i]), std::get<2>(g_pinmux_drivepad_config_map[i]));
} }
/* TODO: Set initial wake pin configuration */ /* Initialize PMC for configuring wake pin events */
pmc_init_wake_events(pmc_base_vaddr, false);
/* Configure all wake pin events */
for (unsigned int i = 0; i < MAX_PMC_WAKE_PIN; i++) {
if (kernelAbove200()) {
if (hardware_type == 0x01) {
/* Set wake event levels for Copper hardware */
pmc_set_wake_event_level(pmc_base_vaddr, std::get<0>(g_pmc_wake_pin_map_copper[i]), std::get<2>(g_pmc_wake_pin_map_copper[i]));
/* Enable or disable wake events for Copper hardware */
pmc_set_wake_event_enabled(pmc_base_vaddr, std::get<0>(g_pmc_wake_pin_map_copper[i]), std::get<1>(g_pmc_wake_pin_map_copper[i]));
} else {
/* Manually set pin 8 values which changed on 2.0.0+ */
if (i == 0x08) {
/* Set pin 8's wake event level for Icosa hardware */
pmc_set_wake_event_level(pmc_base_vaddr, std::get<0>(g_pmc_wake_pin_map_icosa[i]), 1);
/* Enable or disable pin 8's wake event for Icosa hardware */
pmc_set_wake_event_enabled(pmc_base_vaddr, std::get<0>(g_pmc_wake_pin_map_icosa[i]), 1);
} else {
/* Set wake event levels for Icosa hardware */
pmc_set_wake_event_level(pmc_base_vaddr, std::get<0>(g_pmc_wake_pin_map_icosa[i]), std::get<2>(g_pmc_wake_pin_map_icosa[i]));
/* Enable or disable wake events for Icosa hardware */
pmc_set_wake_event_enabled(pmc_base_vaddr, std::get<0>(g_pmc_wake_pin_map_icosa[i]), std::get<1>(g_pmc_wake_pin_map_icosa[i]));
}
}
} else {
/* Set wake event levels for Icosa hardware */
pmc_set_wake_event_level(pmc_base_vaddr, std::get<0>(g_pmc_wake_pin_map_icosa[i]), std::get<2>(g_pmc_wake_pin_map_icosa[i]));
/* Enable or disable wake events for Icosa hardware */
pmc_set_wake_event_enabled(pmc_base_vaddr, std::get<0>(g_pmc_wake_pin_map_icosa[i]), std::get<1>(g_pmc_wake_pin_map_icosa[i]));
}
}
/* This is ignored in Copper hardware */ /* This is ignored in Copper hardware */
if (hardware_type != 0x01) { if (hardware_type != 0x01) {