5
* @author Andrew Bursian
11
#include <kernel/irq.h>
13
#include <drivers/gpio/gpio_driver.h>
15
#include <drivers/clk/k1921vg015_rcu.h>
17
#include <config/board_config.h>
19
#include <framework/mod/options.h>
21
#define GPIO_CHIP_ID OPTION_GET(NUMBER,gpio_chip_id)
22
#define GPIO_PINS_NUMBER 16
24
#define GPIOA ((volatile struct gpio_reg *)CONF_GPIO_PORT_A_REGION_BASE)
25
#define GPIOB ((volatile struct gpio_reg *)CONF_GPIO_PORT_B_REGION_BASE)
26
#if defined(CONF_GPIO_PORT_C_REGION_BASE)
27
# define GPIOC ((volatile struct gpio_reg *)CONF_GPIO_PORT_C_REGION_BASE)
28
#endif /* defined(CONF_GPIO_PORT_C_REGION_BASE) */
31
uint32_t GPIO_DATA_reg; /* 0x00 */
32
uint32_t GPIO_DATAOUT_reg; /* 0x04 */
33
uint32_t GPIO_DATAOUTSET_reg; /* 0x08 */
34
uint32_t GPIO_DATAOUTCLR_reg; /* 0x0C */
35
uint32_t GPIO_DATAOUTTGL_reg; /* 0x10 */
36
uint32_t GPIO_DENSET_reg; /* 0x14 */
37
uint32_t GPIO_DENCLR_reg; /* 0x18 */
38
uint32_t GPIO_INMODE_reg; /* 0x1C */
39
uint32_t GPIO_PULLMODE_reg; /* 0x20 */
40
uint32_t GPIO_OUTMODE_reg; /* 0x24 */
41
uint32_t GPIO_DRIVEMODE_reg; /* 0x28 */
42
uint32_t GPIO_OUTENSET_reg; /* 0x2C */
43
uint32_t GPIO_OUTENCLR_reg; /* 0x30 */
44
uint32_t GPIO_ALTFUNCSET_reg; /* 0x34 */
45
uint32_t GPIO_ALTFUNCCLR_reg; /* 0x38 */
46
uint32_t GPIO_ALTFUNCNUM_reg; /* 0x3C */
47
uint32_t reserved2[1];
48
uint32_t GPIO_SYNCSET_reg; /* 0x44 */
49
uint32_t GPIO_SYNCCLR_reg; /* 0x48 */
50
uint32_t GPIO_QUALSET_reg; /* 0x4C */
51
uint32_t GPIO_QUALCLR_reg; /* 0x50 */
52
uint32_t GPIO_QUALMODESET_reg; /* 0x54 */
53
uint32_t GPIO_QUALMODECLR_reg; /* 0x58 */
54
uint32_t GPIO_QUALSAMPLE_reg; /* 0x5C */
55
uint32_t GPIO_INTENSET_reg; /* 0x60 */
56
uint32_t GPIO_INTENCLR_reg; /* 0x64 */
57
uint32_t GPIO_INTTYPESET_reg; /* 0x68 */
58
uint32_t GPIO_INTTYPECLR_reg; /* 0x6C */
59
uint32_t GPIO_INTPOLSET_reg; /* 0x70 */
60
uint32_t GPIO_INTPOLCLR_reg; /* 0x74 */
61
uint32_t GPIO_INTEDGESET_reg; /* 0x78 */
62
uint32_t GPIO_INTEDGECLR_reg; /* 0x7C */
63
uint32_t GPIO_INTSTATUS_reg; /* 0x80 */
64
uint32_t GPIO_DMAREQSET_reg; /* 0x84 */
65
uint32_t GPIO_DMAREQCLR_reg; /* 0x88 */
66
uint32_t GPIO_ADCSOCSET_reg; /* 0x8C */
67
uint32_t GPIO_ADCSOCCLR_reg; /* 0x90 */
68
uint32_t reserved3[2];
69
uint32_t GPIO_LOCKKEY_reg; /* 0x9C */
70
uint32_t GPIO_LOCKSET_reg; /* 0xA0 */
71
uint32_t GPIO_LOCKCLR_reg; /* 0xA4 */
74
static struct gpio_chip niiet_gpio_chip;
77
niiet_gpio_irq_conf_type(volatile struct gpio_reg *gpio_reg, uint32_t mask, int type) {
79
gpio_reg->GPIO_INTTYPESET_reg = mask;
81
gpio_reg->GPIO_INTTYPECLR_reg = mask;
86
niiet_gpio_irq_conf_pol(volatile struct gpio_reg *gpio_reg, uint32_t mask, int pol) {
88
gpio_reg->GPIO_INTPOLSET_reg = mask;
90
gpio_reg->GPIO_INTPOLCLR_reg = mask;
95
niiet_gpio_irq_conf_edge(volatile struct gpio_reg *gpio_reg, uint32_t mask, int edge) {
97
gpio_reg->GPIO_INTEDGESET_reg = mask;
99
gpio_reg->GPIO_INTEDGECLR_reg = mask;
104
niiet_gpio_irq_en(volatile struct gpio_reg *gpio_reg, uint32_t mask) {
105
gpio_reg->GPIO_INTENSET_reg = mask;
109
niiet_gpio_irq_dis(volatile struct gpio_reg *gpio_reg, uint32_t mask) {
110
gpio_reg->GPIO_INTENCLR_reg = mask;
113
static inline uint32_t
114
niiet_gpio_irq_get_status(volatile struct gpio_reg *gpio_reg) {
115
return gpio_reg->GPIO_INTSTATUS_reg;
119
niiet_gpio_irq_clear_status(volatile struct gpio_reg *gpio_reg, uint32_t mask) {
120
gpio_reg->GPIO_INTSTATUS_reg = mask;
123
static inline volatile struct gpio_reg *niiet_gpio_get_gpio_port(unsigned char port) {
129
#if defined (CONF_GPIO_PORT_C_REGION_BASE)
133
#endif /* defined (PORTC) */
141
irq_return_t niiet_gpio_irq_handler(unsigned int irq_nr, void *gpio) {
143
uint8_t port_num = 0;
144
volatile struct gpio_reg *gpio_reg = gpio;
146
mask = niiet_gpio_irq_get_status(gpio_reg);
148
niiet_gpio_irq_clear_status(gpio_reg, mask);
150
gpio_handle_irq(&niiet_gpio_chip, port_num, mask);
155
static int niiet_gpio_setup_irq(int port, uint32_t mask, int mode) {
157
volatile struct gpio_reg *gpio_reg;
162
gpio_reg = niiet_gpio_get_gpio_port(port);
163
if (gpio_reg == NULL) {
167
res = irq_attach(0, niiet_gpio_irq_handler, 0, (void*)gpio_reg, "GPIO Irq");
172
if ( (mode & GPIO_MODE_INT_MODE_LEVEL0)
173
|| (mode & GPIO_MODE_INT_MODE_LEVEL1) ) {
179
if ((mode & GPIO_MODE_INT_MODE_RISING)
180
&& (mode & GPIO_MODE_INT_MODE_FALLING)) {
186
if ((mode & GPIO_MODE_INT_MODE_RISING)
187
|| (mode & GPIO_MODE_INT_MODE_LEVEL1)) {
193
niiet_gpio_irq_conf_pol(gpio_reg, mask, pol);
194
niiet_gpio_irq_conf_edge(gpio_reg, mask, edge);
195
niiet_gpio_irq_conf_type(gpio_reg, mask, type);
197
if (mode & GPIO_MODE_IN_INT_EN) {
198
niiet_gpio_irq_en(gpio_reg, mask);
204
static int niiet_gpio_setup_mode(unsigned char port, gpio_mask_t pins, int mode) {
205
volatile struct gpio_reg *gpio_reg;
208
gpio_reg = niiet_gpio_get_gpio_port(port);
209
if (gpio_reg == NULL) {
215
clk_name = CONF_GPIO_PORT_A_CLK_ENABLE();
218
clk_name = CONF_GPIO_PORT_B_CLK_ENABLE();
221
#if defined CONF_GPIO_PORT_C_CLK_ENABLE
222
clk_name = CONF_GPIO_PORT_C_CLK_ENABLE();
223
#endif /* defined CONF_GPIO_PORT_C_CLK_ENABLE */
230
clk_enable(clk_name);
232
gpio_reg->GPIO_DENSET_reg |= pins;
234
if (mode & GPIO_MODE_IN) {
235
gpio_reg->GPIO_OUTENCLR_reg |= pins;
238
if (mode & GPIO_MODE_IN_PULL_UP) {
239
gpio_reg->GPIO_PULLMODE_reg |= pins;
242
if (mode & GPIO_MODE_OUT) {
243
gpio_reg->GPIO_OUTENSET_reg |= pins;
246
if (mode & GPIO_MODE_INT_SECTION) {
247
niiet_gpio_setup_irq(port, pins, mode);
250
if (mode & GPIO_MODE_OUT_ALTERNATE) {
252
gpio_reg->GPIO_ALTFUNCSET_reg |= pins;
254
for (int i = 0; i < GPIO_PINS_NUMBER; i++) {
255
if (pins & (1 << i)) {
256
uint32_t alt = GPIO_GET_ALTERNATE(mode);
258
gpio_reg->GPIO_ALTFUNCNUM_reg &= ~(0x3 << i * 2);
259
gpio_reg->GPIO_ALTFUNCNUM_reg |= alt << i * 2;
267
static void niiet_gpio_set(unsigned char port, gpio_mask_t pins, char level) {
268
volatile struct gpio_reg *gpio_reg;
270
gpio_reg = niiet_gpio_get_gpio_port(port);
271
if (gpio_reg == NULL) {
276
gpio_reg->GPIO_DATAOUTSET_reg |= pins;
278
gpio_reg->GPIO_DATAOUTCLR_reg |= pins;
282
static gpio_mask_t niiet_gpio_get(unsigned char port, gpio_mask_t pins) {
283
volatile struct gpio_reg *gpio_reg;
285
gpio_reg = niiet_gpio_get_gpio_port(port);
286
if (gpio_reg == NULL) {
290
return gpio_reg->GPIO_DATA_reg & pins;
293
static struct gpio_chip niiet_gpio_chip = {
294
.setup_mode = niiet_gpio_setup_mode,
295
.get = niiet_gpio_get,
296
.set = niiet_gpio_set,
297
#if defined (CONF_GPIO_PORT_C_REGION_BASE)
304
GPIO_CHIP_DEF(&niiet_gpio_chip);
306
STATIC_IRQ_ATTACH(GPIO_IRQ, gpio_irq_handler, NULL);