mirror of
https://github.com/CTCaer/hekate
synced 2024-12-22 19:31:12 +00:00
gpio: Upgrade GPIO driver
Use macros to get bank addresses and add full configuration support.
This commit is contained in:
parent
cb3b1bf6e1
commit
9a5cfdff4c
4 changed files with 272 additions and 104 deletions
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
|
* Copyright (c) 2019 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -14,81 +15,146 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../soc/gpio.h"
|
#include "gpio.h"
|
||||||
#include "../soc/t210.h"
|
#include "irq.h"
|
||||||
|
#include "t210.h"
|
||||||
|
|
||||||
static const u16 _gpio_cnf[31] = {
|
#define GPIO_BANK_IDX(port) (port >> 2)
|
||||||
0x000, 0x004, 0x008, 0x00C,
|
|
||||||
0x100, 0x104, 0x108, 0x10C,
|
|
||||||
0x200, 0x204, 0x208, 0x20C,
|
|
||||||
0x300, 0x304, 0x308, 0x30C,
|
|
||||||
0x400, 0x404, 0x408, 0x40C,
|
|
||||||
0x500, 0x504, 0x508, 0x50C,
|
|
||||||
0x600, 0x604, 0x608, 0x60C,
|
|
||||||
0x700, 0x704, 0x708
|
|
||||||
};
|
|
||||||
|
|
||||||
static const u16 _gpio_oe[31] = {
|
#define GPIO_CNF_OFFSET(port) (0x00 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x010, 0x014, 0x018, 0x01C,
|
#define GPIO_OE_OFFSET(port) (0x10 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x110, 0x114, 0x118, 0x11C,
|
#define GPIO_OUT_OFFSET(port) (0x20 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x210, 0x214, 0x218, 0x21C,
|
#define GPIO_IN_OFFSET(port) (0x30 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x310, 0x314, 0x318, 0x31C,
|
#define GPIO_INT_STA_OFFSET(port) (0x40 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x410, 0x414, 0x418, 0x41C,
|
#define GPIO_INT_ENB_OFFSET(port) (0x50 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x510, 0x514, 0x518, 0x51C,
|
#define GPIO_INT_LVL_OFFSET(port) (0x60 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x610, 0x614, 0x618, 0x61C,
|
#define GPIO_INT_CLR_OFFSET(port) (0x70 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x710, 0x714, 0x718
|
|
||||||
};
|
|
||||||
|
|
||||||
static const u16 _gpio_out[31] = {
|
#define GPIO_CNF_MASKED_OFFSET(port) (0x80 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x020, 0x024, 0x028, 0x02C,
|
#define GPIO_OE_MASKED_OFFSET(port) (0x90 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x120, 0x124, 0x128, 0x12C,
|
#define GPIO_OUT_MASKED_OFFSET(port) (0xA0 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x220, 0x224, 0x228, 0x22C,
|
#define GPIO_INT_STA_MASKED_OFFSET(port) (0xC0 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x320, 0x324, 0x328, 0x32C,
|
#define GPIO_INT_ENB_MASKED_OFFSET(port) (0xD0 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x420, 0x424, 0x428, 0x42C,
|
#define GPIO_INT_LVL_MASKED_OFFSET(port) (0xE0 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x520, 0x524, 0x528, 0x52C,
|
|
||||||
0x620, 0x624, 0x628, 0x62C,
|
|
||||||
0x720, 0x724, 0x728
|
|
||||||
};
|
|
||||||
|
|
||||||
static const u16 _gpio_in[31] = {
|
static u8 gpio_bank_irq_ids[8] = {
|
||||||
0x030, 0x034, 0x038, 0x03C,
|
IRQ_GPIO1, IRQ_GPIO2, IRQ_GPIO3, IRQ_GPIO4,
|
||||||
0x130, 0x134, 0x138, 0x13C,
|
IRQ_GPIO5, IRQ_GPIO6, IRQ_GPIO7, IRQ_GPIO8
|
||||||
0x230, 0x234, 0x238, 0x23C,
|
|
||||||
0x330, 0x334, 0x338, 0x33C,
|
|
||||||
0x430, 0x434, 0x438, 0x43C,
|
|
||||||
0x530, 0x534, 0x538, 0x53C,
|
|
||||||
0x630, 0x634, 0x638, 0x63C,
|
|
||||||
0x730, 0x734, 0x738
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void gpio_config(u32 port, u32 pins, int mode)
|
void gpio_config(u32 port, u32 pins, int mode)
|
||||||
{
|
{
|
||||||
|
u32 offset = GPIO_CNF_OFFSET(port);
|
||||||
|
|
||||||
if (mode)
|
if (mode)
|
||||||
GPIO(_gpio_cnf[port]) |= pins;
|
GPIO(offset) |= pins;
|
||||||
else
|
else
|
||||||
GPIO(_gpio_cnf[port]) &= ~pins;
|
GPIO(offset) &= ~pins;
|
||||||
(void)GPIO(_gpio_cnf[port]);
|
|
||||||
|
(void)GPIO(offset); // Commit the write.
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpio_output_enable(u32 port, u32 pins, int enable)
|
void gpio_output_enable(u32 port, u32 pins, int enable)
|
||||||
{
|
{
|
||||||
|
u32 port_offset = GPIO_OE_OFFSET(port);
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
GPIO(_gpio_oe[port]) |= pins;
|
GPIO(port_offset) |= pins;
|
||||||
else
|
else
|
||||||
GPIO(_gpio_oe[port]) &= ~pins;
|
GPIO(port_offset) &= ~pins;
|
||||||
(void)GPIO(_gpio_oe[port]);
|
|
||||||
|
(void)GPIO(port_offset); // Commit the write.
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpio_write(u32 port, u32 pins, int high)
|
void gpio_write(u32 port, u32 pins, int high)
|
||||||
{
|
{
|
||||||
|
u32 port_offset = GPIO_OUT_OFFSET(port);
|
||||||
|
|
||||||
if (high)
|
if (high)
|
||||||
GPIO(_gpio_out[port]) |= pins;
|
GPIO(port_offset) |= pins;
|
||||||
else
|
else
|
||||||
GPIO(_gpio_out[port]) &= ~pins;
|
GPIO(port_offset) &= ~pins;
|
||||||
(void)GPIO(_gpio_out[port]);
|
|
||||||
|
(void)GPIO(port_offset); // Commit the write.
|
||||||
}
|
}
|
||||||
|
|
||||||
int gpio_read(u32 port, u32 pins)
|
int gpio_read(u32 port, u32 pins)
|
||||||
{
|
{
|
||||||
return (GPIO(_gpio_in[port]) & pins) ? 1 : 0;
|
u32 port_offset = GPIO_IN_OFFSET(port);
|
||||||
|
|
||||||
|
return (GPIO(port_offset) & pins) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _gpio_interrupt_clear(u32 port, u32 pins)
|
||||||
|
{
|
||||||
|
u32 port_offset = GPIO_INT_CLR_OFFSET(port);
|
||||||
|
|
||||||
|
GPIO(port_offset) |= pins;
|
||||||
|
|
||||||
|
(void)GPIO(port_offset); // Commit the write.
|
||||||
|
}
|
||||||
|
|
||||||
|
int gpio_interrupt_status(u32 port, u32 pins)
|
||||||
|
{
|
||||||
|
u32 port_offset = GPIO_INT_STA_OFFSET(port);
|
||||||
|
u32 enabled = GPIO(GPIO_INT_ENB_OFFSET(port)) & pins;
|
||||||
|
|
||||||
|
int status = ((GPIO(port_offset) & pins) && enabled) ? 1 : 0;
|
||||||
|
|
||||||
|
// Clear the interrupt status.
|
||||||
|
if (status)
|
||||||
|
_gpio_interrupt_clear(port, pins);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpio_interrupt_enable(u32 port, u32 pins, int enable)
|
||||||
|
{
|
||||||
|
u32 port_offset = GPIO_INT_ENB_OFFSET(port);
|
||||||
|
|
||||||
|
// Clear any possible stray interrupt.
|
||||||
|
_gpio_interrupt_clear(port, pins);
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
GPIO(port_offset) |= pins;
|
||||||
|
else
|
||||||
|
GPIO(port_offset) &= ~pins;
|
||||||
|
|
||||||
|
(void)GPIO(port_offset); // Commit the write.
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta)
|
||||||
|
{
|
||||||
|
u32 port_offset = GPIO_INT_LVL_OFFSET(port);
|
||||||
|
|
||||||
|
u32 val = GPIO(port_offset);
|
||||||
|
|
||||||
|
if (high)
|
||||||
|
val |= pins;
|
||||||
|
else
|
||||||
|
val &= ~pins;
|
||||||
|
|
||||||
|
if (edge)
|
||||||
|
val |= pins << 8;
|
||||||
|
else
|
||||||
|
val &= ~(pins << 8);
|
||||||
|
|
||||||
|
if (delta)
|
||||||
|
val |= pins << 16;
|
||||||
|
else
|
||||||
|
val &= ~(pins << 16);
|
||||||
|
|
||||||
|
GPIO(port_offset) = val;
|
||||||
|
|
||||||
|
(void)GPIO(port_offset); // Commit the write.
|
||||||
|
|
||||||
|
// Clear any possible stray interrupt.
|
||||||
|
_gpio_interrupt_clear(port, pins);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 gpio_get_bank_irq_id(u32 port)
|
||||||
|
{
|
||||||
|
u32 bank_idx = GPIO_BANK_IDX(port);
|
||||||
|
|
||||||
|
return gpio_bank_irq_ids[bank_idx];
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
|
* Copyright (c) 2019 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -21,10 +22,23 @@
|
||||||
|
|
||||||
#define GPIO_MODE_SPIO 0
|
#define GPIO_MODE_SPIO 0
|
||||||
#define GPIO_MODE_GPIO 1
|
#define GPIO_MODE_GPIO 1
|
||||||
|
|
||||||
#define GPIO_OUTPUT_DISABLE 0
|
#define GPIO_OUTPUT_DISABLE 0
|
||||||
#define GPIO_OUTPUT_ENABLE 1
|
#define GPIO_OUTPUT_ENABLE 1
|
||||||
|
|
||||||
|
#define GPIO_IRQ_DISABLE 0
|
||||||
|
#define GPIO_IRQ_ENABLE 1
|
||||||
|
|
||||||
#define GPIO_LOW 0
|
#define GPIO_LOW 0
|
||||||
#define GPIO_HIGH 1
|
#define GPIO_HIGH 1
|
||||||
|
#define GPIO_FALLING 0
|
||||||
|
#define GPIO_RISING 1
|
||||||
|
|
||||||
|
#define GPIO_LEVEL 0
|
||||||
|
#define GPIO_EDGE 1
|
||||||
|
|
||||||
|
#define GPIO_CONFIGURED_EDGE 0
|
||||||
|
#define GPIO_ANY_EDGE_CHANGE 1
|
||||||
|
|
||||||
/*! GPIO pins (0-7 for each port). */
|
/*! GPIO pins (0-7 for each port). */
|
||||||
#define GPIO_PIN_0 (1 << 0)
|
#define GPIO_PIN_0 (1 << 0)
|
||||||
|
@ -73,5 +87,9 @@ void gpio_config(u32 port, u32 pins, int mode);
|
||||||
void gpio_output_enable(u32 port, u32 pins, int enable);
|
void gpio_output_enable(u32 port, u32 pins, int enable);
|
||||||
void gpio_write(u32 port, u32 pins, int high);
|
void gpio_write(u32 port, u32 pins, int high);
|
||||||
int gpio_read(u32 port, u32 pins);
|
int gpio_read(u32 port, u32 pins);
|
||||||
|
int gpio_interrupt_status(u32 port, u32 pins);
|
||||||
|
void gpio_interrupt_enable(u32 port, u32 pins, int enable);
|
||||||
|
void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta);
|
||||||
|
u32 gpio_get_bank_irq_id(u32 port);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
|
* Copyright (c) 2019 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -14,81 +15,146 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../soc/gpio.h"
|
#include "gpio.h"
|
||||||
#include "../soc/t210.h"
|
#include "irq.h"
|
||||||
|
#include "t210.h"
|
||||||
|
|
||||||
static const u16 _gpio_cnf[31] = {
|
#define GPIO_BANK_IDX(port) (port >> 2)
|
||||||
0x000, 0x004, 0x008, 0x00C,
|
|
||||||
0x100, 0x104, 0x108, 0x10C,
|
|
||||||
0x200, 0x204, 0x208, 0x20C,
|
|
||||||
0x300, 0x304, 0x308, 0x30C,
|
|
||||||
0x400, 0x404, 0x408, 0x40C,
|
|
||||||
0x500, 0x504, 0x508, 0x50C,
|
|
||||||
0x600, 0x604, 0x608, 0x60C,
|
|
||||||
0x700, 0x704, 0x708
|
|
||||||
};
|
|
||||||
|
|
||||||
static const u16 _gpio_oe[31] = {
|
#define GPIO_CNF_OFFSET(port) (0x00 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x010, 0x014, 0x018, 0x01C,
|
#define GPIO_OE_OFFSET(port) (0x10 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x110, 0x114, 0x118, 0x11C,
|
#define GPIO_OUT_OFFSET(port) (0x20 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x210, 0x214, 0x218, 0x21C,
|
#define GPIO_IN_OFFSET(port) (0x30 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x310, 0x314, 0x318, 0x31C,
|
#define GPIO_INT_STA_OFFSET(port) (0x40 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x410, 0x414, 0x418, 0x41C,
|
#define GPIO_INT_ENB_OFFSET(port) (0x50 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x510, 0x514, 0x518, 0x51C,
|
#define GPIO_INT_LVL_OFFSET(port) (0x60 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x610, 0x614, 0x618, 0x61C,
|
#define GPIO_INT_CLR_OFFSET(port) (0x70 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x710, 0x714, 0x718
|
|
||||||
};
|
|
||||||
|
|
||||||
static const u16 _gpio_out[31] = {
|
#define GPIO_CNF_MASKED_OFFSET(port) (0x80 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x020, 0x024, 0x028, 0x02C,
|
#define GPIO_OE_MASKED_OFFSET(port) (0x90 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x120, 0x124, 0x128, 0x12C,
|
#define GPIO_OUT_MASKED_OFFSET(port) (0xA0 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x220, 0x224, 0x228, 0x22C,
|
#define GPIO_INT_STA_MASKED_OFFSET(port) (0xC0 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x320, 0x324, 0x328, 0x32C,
|
#define GPIO_INT_ENB_MASKED_OFFSET(port) (0xD0 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x420, 0x424, 0x428, 0x42C,
|
#define GPIO_INT_LVL_MASKED_OFFSET(port) (0xE0 + ((port >> 2) << 8) + ((port % 4) << 2))
|
||||||
0x520, 0x524, 0x528, 0x52C,
|
|
||||||
0x620, 0x624, 0x628, 0x62C,
|
|
||||||
0x720, 0x724, 0x728
|
|
||||||
};
|
|
||||||
|
|
||||||
static const u16 _gpio_in[31] = {
|
static u8 gpio_bank_irq_ids[8] = {
|
||||||
0x030, 0x034, 0x038, 0x03C,
|
IRQ_GPIO1, IRQ_GPIO2, IRQ_GPIO3, IRQ_GPIO4,
|
||||||
0x130, 0x134, 0x138, 0x13C,
|
IRQ_GPIO5, IRQ_GPIO6, IRQ_GPIO7, IRQ_GPIO8
|
||||||
0x230, 0x234, 0x238, 0x23C,
|
|
||||||
0x330, 0x334, 0x338, 0x33C,
|
|
||||||
0x430, 0x434, 0x438, 0x43C,
|
|
||||||
0x530, 0x534, 0x538, 0x53C,
|
|
||||||
0x630, 0x634, 0x638, 0x63C,
|
|
||||||
0x730, 0x734, 0x738
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void gpio_config(u32 port, u32 pins, int mode)
|
void gpio_config(u32 port, u32 pins, int mode)
|
||||||
{
|
{
|
||||||
|
u32 offset = GPIO_CNF_OFFSET(port);
|
||||||
|
|
||||||
if (mode)
|
if (mode)
|
||||||
GPIO(_gpio_cnf[port]) |= pins;
|
GPIO(offset) |= pins;
|
||||||
else
|
else
|
||||||
GPIO(_gpio_cnf[port]) &= ~pins;
|
GPIO(offset) &= ~pins;
|
||||||
(void)GPIO(_gpio_cnf[port]);
|
|
||||||
|
(void)GPIO(offset); // Commit the write.
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpio_output_enable(u32 port, u32 pins, int enable)
|
void gpio_output_enable(u32 port, u32 pins, int enable)
|
||||||
{
|
{
|
||||||
|
u32 port_offset = GPIO_OE_OFFSET(port);
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
GPIO(_gpio_oe[port]) |= pins;
|
GPIO(port_offset) |= pins;
|
||||||
else
|
else
|
||||||
GPIO(_gpio_oe[port]) &= ~pins;
|
GPIO(port_offset) &= ~pins;
|
||||||
(void)GPIO(_gpio_oe[port]);
|
|
||||||
|
(void)GPIO(port_offset); // Commit the write.
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpio_write(u32 port, u32 pins, int high)
|
void gpio_write(u32 port, u32 pins, int high)
|
||||||
{
|
{
|
||||||
|
u32 port_offset = GPIO_OUT_OFFSET(port);
|
||||||
|
|
||||||
if (high)
|
if (high)
|
||||||
GPIO(_gpio_out[port]) |= pins;
|
GPIO(port_offset) |= pins;
|
||||||
else
|
else
|
||||||
GPIO(_gpio_out[port]) &= ~pins;
|
GPIO(port_offset) &= ~pins;
|
||||||
(void)GPIO(_gpio_out[port]);
|
|
||||||
|
(void)GPIO(port_offset); // Commit the write.
|
||||||
}
|
}
|
||||||
|
|
||||||
int gpio_read(u32 port, u32 pins)
|
int gpio_read(u32 port, u32 pins)
|
||||||
{
|
{
|
||||||
return (GPIO(_gpio_in[port]) & pins) ? 1 : 0;
|
u32 port_offset = GPIO_IN_OFFSET(port);
|
||||||
|
|
||||||
|
return (GPIO(port_offset) & pins) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _gpio_interrupt_clear(u32 port, u32 pins)
|
||||||
|
{
|
||||||
|
u32 port_offset = GPIO_INT_CLR_OFFSET(port);
|
||||||
|
|
||||||
|
GPIO(port_offset) |= pins;
|
||||||
|
|
||||||
|
(void)GPIO(port_offset); // Commit the write.
|
||||||
|
}
|
||||||
|
|
||||||
|
int gpio_interrupt_status(u32 port, u32 pins)
|
||||||
|
{
|
||||||
|
u32 port_offset = GPIO_INT_STA_OFFSET(port);
|
||||||
|
u32 enabled = GPIO(GPIO_INT_ENB_OFFSET(port)) & pins;
|
||||||
|
|
||||||
|
int status = ((GPIO(port_offset) & pins) && enabled) ? 1 : 0;
|
||||||
|
|
||||||
|
// Clear the interrupt status.
|
||||||
|
if (status)
|
||||||
|
_gpio_interrupt_clear(port, pins);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpio_interrupt_enable(u32 port, u32 pins, int enable)
|
||||||
|
{
|
||||||
|
u32 port_offset = GPIO_INT_ENB_OFFSET(port);
|
||||||
|
|
||||||
|
// Clear any possible stray interrupt.
|
||||||
|
_gpio_interrupt_clear(port, pins);
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
GPIO(port_offset) |= pins;
|
||||||
|
else
|
||||||
|
GPIO(port_offset) &= ~pins;
|
||||||
|
|
||||||
|
(void)GPIO(port_offset); // Commit the write.
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta)
|
||||||
|
{
|
||||||
|
u32 port_offset = GPIO_INT_LVL_OFFSET(port);
|
||||||
|
|
||||||
|
u32 val = GPIO(port_offset);
|
||||||
|
|
||||||
|
if (high)
|
||||||
|
val |= pins;
|
||||||
|
else
|
||||||
|
val &= ~pins;
|
||||||
|
|
||||||
|
if (edge)
|
||||||
|
val |= pins << 8;
|
||||||
|
else
|
||||||
|
val &= ~(pins << 8);
|
||||||
|
|
||||||
|
if (delta)
|
||||||
|
val |= pins << 16;
|
||||||
|
else
|
||||||
|
val &= ~(pins << 16);
|
||||||
|
|
||||||
|
GPIO(port_offset) = val;
|
||||||
|
|
||||||
|
(void)GPIO(port_offset); // Commit the write.
|
||||||
|
|
||||||
|
// Clear any possible stray interrupt.
|
||||||
|
_gpio_interrupt_clear(port, pins);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 gpio_get_bank_irq_id(u32 port)
|
||||||
|
{
|
||||||
|
u32 bank_idx = GPIO_BANK_IDX(port);
|
||||||
|
|
||||||
|
return gpio_bank_irq_ids[bank_idx];
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
|
* Copyright (c) 2019 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -21,10 +22,23 @@
|
||||||
|
|
||||||
#define GPIO_MODE_SPIO 0
|
#define GPIO_MODE_SPIO 0
|
||||||
#define GPIO_MODE_GPIO 1
|
#define GPIO_MODE_GPIO 1
|
||||||
|
|
||||||
#define GPIO_OUTPUT_DISABLE 0
|
#define GPIO_OUTPUT_DISABLE 0
|
||||||
#define GPIO_OUTPUT_ENABLE 1
|
#define GPIO_OUTPUT_ENABLE 1
|
||||||
|
|
||||||
|
#define GPIO_IRQ_DISABLE 0
|
||||||
|
#define GPIO_IRQ_ENABLE 1
|
||||||
|
|
||||||
#define GPIO_LOW 0
|
#define GPIO_LOW 0
|
||||||
#define GPIO_HIGH 1
|
#define GPIO_HIGH 1
|
||||||
|
#define GPIO_FALLING 0
|
||||||
|
#define GPIO_RISING 1
|
||||||
|
|
||||||
|
#define GPIO_LEVEL 0
|
||||||
|
#define GPIO_EDGE 1
|
||||||
|
|
||||||
|
#define GPIO_CONFIGURED_EDGE 0
|
||||||
|
#define GPIO_ANY_EDGE_CHANGE 1
|
||||||
|
|
||||||
/*! GPIO pins (0-7 for each port). */
|
/*! GPIO pins (0-7 for each port). */
|
||||||
#define GPIO_PIN_0 (1 << 0)
|
#define GPIO_PIN_0 (1 << 0)
|
||||||
|
@ -73,5 +87,9 @@ void gpio_config(u32 port, u32 pins, int mode);
|
||||||
void gpio_output_enable(u32 port, u32 pins, int enable);
|
void gpio_output_enable(u32 port, u32 pins, int enable);
|
||||||
void gpio_write(u32 port, u32 pins, int high);
|
void gpio_write(u32 port, u32 pins, int high);
|
||||||
int gpio_read(u32 port, u32 pins);
|
int gpio_read(u32 port, u32 pins);
|
||||||
|
int gpio_interrupt_status(u32 port, u32 pins);
|
||||||
|
void gpio_interrupt_enable(u32 port, u32 pins, int enable);
|
||||||
|
void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta);
|
||||||
|
u32 gpio_get_bank_irq_id(u32 port);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue