11
#include <drivers/gpio/gpio_driver.h>
13
#include <kernel/irq.h>
16
#include <drivers/clk/mikron_pm.h>
18
#include <framework/mod/options.h>
20
#define GPIO_CHIP_ID OPTION_GET(NUMBER, gpio_chip_id)
21
#define GPIO_PINS_NUMBER 16
23
#define CONF_GPIO_PORT_0_REGION_BASE 0x00084000
24
#define CONF_GPIO_PORT_1_REGION_BASE 0x00084400
25
#define CONF_GPIO_PORT_2_REGION_BASE 0x00084800
27
#define CONF_GPIO_PORT_0_CLK_ENABLE() "CLK_GPIO_PORT0"
28
#define CONF_GPIO_PORT_1_CLK_ENABLE() "CLK_GPIO_PORT1"
29
#define CONF_GPIO_PORT_2_CLK_ENABLE() "CLK_GPIO_PORT2"
31
#define GPIOA ((volatile struct gpio_reg *)CONF_GPIO_PORT_0_REGION_BASE)
32
#define GPIOB ((volatile struct gpio_reg *)CONF_GPIO_PORT_1_REGION_BASE)
33
#define GPIOC ((volatile struct gpio_reg *)CONF_GPIO_PORT_2_REGION_BASE)
35
extern void mik_pad_cfg_set_func(int port, int pin, int func);
36
extern void mik_pad_cfg_set_ds(int port, int pin, int ds);
37
extern void mik_pad_cfg_set_pupd(int port, int pin, int pupd);
41
volatile uint32_t SET;
42
volatile uint32_t STATE;
44
volatile uint32_t CLEAR;
45
volatile uint32_t DIRECTION_OUT;
46
volatile uint32_t DIRECTION_IN;
47
volatile uint32_t OUTPUT;
48
volatile uint32_t CONTROL;
51
static struct gpio_chip mik_gpio_chip;
54
void mik_gpio_irq_en(volatile struct gpio_reg *gpio_reg,
59
static inline void mik_gpio_irq_dis(volatile struct gpio_reg *gpio_reg,
63
static inline uint32_t mik_gpio_irq_get_status(
64
volatile struct gpio_reg *gpio_reg) {
69
static inline void mik_gpio_irq_clear_status(
70
volatile struct gpio_reg *gpio_reg, uint32_t mask) {
74
static inline volatile struct gpio_reg *mik_gpio_get_gpio_port(
91
irq_return_t mik_gpio_irq_handler(unsigned int irq_nr, void *gpio) {
94
volatile struct gpio_reg *gpio_reg = gpio;
96
mask = mik_gpio_irq_get_status(gpio_reg);
98
mik_gpio_irq_clear_status(gpio_reg, mask);
100
gpio_handle_irq(&mik_gpio_chip, port_num, mask);
105
static int mik_gpio_setup_irq(int port, uint32_t mask, int mode) {
107
volatile struct gpio_reg *gpio_reg;
112
gpio_reg = mik_gpio_get_gpio_port(port);
113
if (gpio_reg == NULL) {
117
res = irq_attach(0, mik_gpio_irq_handler, 0, (void *)gpio_reg, "GPIO Irq");
122
if ((mode & GPIO_MODE_INT_MODE_LEVEL0)
123
|| (mode & GPIO_MODE_INT_MODE_LEVEL1)) {
128
if ((mode & GPIO_MODE_INT_MODE_RISING)
129
&& (mode & GPIO_MODE_INT_MODE_FALLING)) {
134
if ((mode & GPIO_MODE_INT_MODE_RISING)
135
|| (mode & GPIO_MODE_INT_MODE_LEVEL1)) {
141
if (mode & GPIO_MODE_IN_INT_EN) {
142
mik_gpio_irq_en(gpio_reg, mask);
149
static int mik_gpio_setup_mode(unsigned char port, gpio_mask_t pins,
151
volatile struct gpio_reg *gpio_reg;
152
char *clk_name = NULL;
156
gpio_reg = mik_gpio_get_gpio_port(port);
157
if (gpio_reg == NULL) {
163
clk_name = CONF_GPIO_PORT_0_CLK_ENABLE();
166
clk_name = CONF_GPIO_PORT_1_CLK_ENABLE();
169
clk_name = CONF_GPIO_PORT_2_CLK_ENABLE();
176
clk_enable(clk_name);
178
for (int pin = 0; pin < GPIO_PINS_NUMBER; pin++) {
179
if (!(pins & (1 << pin))) {
183
if (mode & GPIO_MODE_IN) {
184
gpio_reg->DIRECTION_IN |= 1 << pin;
188
if (mode & GPIO_MODE_OUT) {
189
gpio_reg->DIRECTION_OUT |= 1 << pin;
193
if (mode & GPIO_MODE_IN_PULL_UP) {
197
if (mode & GPIO_MODE_IN_PULL_DOWN) {
201
if (mode & GPIO_MODE_OUT_ALTERNATE) {
202
alt = GPIO_GET_ALTERNATE(mode);
205
mik_pad_cfg_set_func(port, pin, alt);
206
mik_pad_cfg_set_ds(port, pin, 0);
207
mik_pad_cfg_set_pupd(port, pin, pull);
210
if (mode & GPIO_MODE_INT_SECTION) {
211
mik_gpio_setup_irq(port, pins, mode);
217
static void mik_gpio_set(unsigned char port, gpio_mask_t pins, char level) {
218
volatile struct gpio_reg *gpio_reg;
220
gpio_reg = mik_gpio_get_gpio_port(port);
221
if (gpio_reg == NULL) {
226
gpio_reg->SET |= pins;
229
gpio_reg->CLEAR |= pins;
233
static gpio_mask_t mik_gpio_get(unsigned char port, gpio_mask_t pins) {
234
volatile struct gpio_reg *gpio_reg;
236
gpio_reg = mik_gpio_get_gpio_port(port);
237
if (gpio_reg == NULL) {
241
return gpio_reg->SET & pins;
244
static struct gpio_chip mik_gpio_chip = {
245
.setup_mode = mik_gpio_setup_mode,
251
GPIO_CHIP_DEF(&mik_gpio_chip);