2220a4b695
Fix stuff that was bugging me about the way I did it at first. While messing around I found RDS code wasn't masking its GPIO ISR as it should, which might lead to two different interrupts messing with the static data. Change-Id: I54626809ea3039a842af0cc9e3e42853326c4193
218 lines
6 KiB
C
218 lines
6 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (c) 2008 by Michael Sevakis
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
#ifndef GPIO_IMX31_H
|
|
#define GPIO_IMX31_H
|
|
|
|
/* Static registration mechanism for imx31 GPIO interrupts */
|
|
#define USE_GPIO1_EVENTS (1 << 0)
|
|
#define USE_GPIO2_EVENTS (1 << 1)
|
|
#define USE_GPIO3_EVENTS (1 << 2)
|
|
|
|
/* Module logical indexes */
|
|
enum gpio_module_number
|
|
{
|
|
GPIO1_NUM, /* ID 0..31 */
|
|
GPIO2_NUM, /* ID 32..63 */
|
|
GPIO3_NUM, /* ID 64..95 */
|
|
GPIO_NUM_GPIO,
|
|
};
|
|
|
|
enum gpio_id
|
|
{
|
|
/* GPIO1 */
|
|
GPIO1_0_ID = 0,
|
|
GPIO1_1_ID,
|
|
GPIO1_2_ID,
|
|
GPIO1_3_ID,
|
|
GPIO1_4_ID,
|
|
GPIO1_5_ID,
|
|
GPIO1_6_ID,
|
|
GPIO1_7_ID,
|
|
GPIO1_8_ID,
|
|
GPIO1_9_ID,
|
|
GPIO1_10_ID,
|
|
GPIO1_11_ID,
|
|
GPIO1_12_ID,
|
|
GPIO1_13_ID,
|
|
GPIO1_14_ID,
|
|
GPIO1_15_ID,
|
|
GPIO1_16_ID,
|
|
GPIO1_17_ID,
|
|
GPIO1_18_ID,
|
|
GPIO1_19_ID,
|
|
GPIO1_20_ID,
|
|
GPIO1_21_ID,
|
|
GPIO1_22_ID,
|
|
GPIO1_23_ID,
|
|
GPIO1_24_ID,
|
|
GPIO1_25_ID,
|
|
GPIO1_26_ID,
|
|
GPIO1_27_ID,
|
|
GPIO1_28_ID,
|
|
GPIO1_29_ID,
|
|
GPIO1_30_ID,
|
|
GPIO1_31_ID,
|
|
/* GPIO2 */
|
|
GPIO2_0_ID = 32,
|
|
GPIO2_1_ID,
|
|
GPIO2_2_ID,
|
|
GPIO2_3_ID,
|
|
GPIO2_4_ID,
|
|
GPIO2_5_ID,
|
|
GPIO2_6_ID,
|
|
GPIO2_7_ID,
|
|
GPIO2_8_ID,
|
|
GPIO2_9_ID,
|
|
GPIO2_10_ID,
|
|
GPIO2_11_ID,
|
|
GPIO2_12_ID,
|
|
GPIO2_13_ID,
|
|
GPIO2_14_ID,
|
|
GPIO2_15_ID,
|
|
GPIO2_16_ID,
|
|
GPIO2_17_ID,
|
|
GPIO2_18_ID,
|
|
GPIO2_19_ID,
|
|
GPIO2_20_ID,
|
|
GPIO2_21_ID,
|
|
GPIO2_22_ID,
|
|
GPIO2_23_ID,
|
|
GPIO2_24_ID,
|
|
GPIO2_25_ID,
|
|
GPIO2_26_ID,
|
|
GPIO2_27_ID,
|
|
GPIO2_28_ID,
|
|
GPIO2_29_ID,
|
|
GPIO2_30_ID,
|
|
GPIO2_31_ID,
|
|
/* GPIO3 */
|
|
GPIO3_0_ID = 64,
|
|
GPIO3_1_ID,
|
|
GPIO3_2_ID,
|
|
GPIO3_3_ID,
|
|
GPIO3_4_ID,
|
|
GPIO3_5_ID,
|
|
GPIO3_6_ID,
|
|
GPIO3_7_ID,
|
|
GPIO3_8_ID,
|
|
GPIO3_9_ID,
|
|
GPIO3_10_ID,
|
|
GPIO3_11_ID,
|
|
GPIO3_12_ID,
|
|
GPIO3_13_ID,
|
|
GPIO3_14_ID,
|
|
GPIO3_15_ID,
|
|
GPIO3_16_ID,
|
|
GPIO3_17_ID,
|
|
GPIO3_18_ID,
|
|
GPIO3_19_ID,
|
|
GPIO3_20_ID,
|
|
GPIO3_21_ID,
|
|
GPIO3_22_ID,
|
|
GPIO3_23_ID,
|
|
GPIO3_24_ID,
|
|
GPIO3_25_ID,
|
|
GPIO3_26_ID,
|
|
GPIO3_27_ID,
|
|
GPIO3_28_ID,
|
|
GPIO3_29_ID,
|
|
GPIO3_30_ID,
|
|
GPIO3_31_ID,
|
|
};
|
|
|
|
/* Possible values for gpio interrupt line config */
|
|
enum gpio_int_sense
|
|
{
|
|
GPIO_SENSE_LOW_LEVEL, /* High-level sensitive */
|
|
GPIO_SENSE_HIGH_LEVEL, /* Low-level sensitive */
|
|
GPIO_SENSE_RISING, /* Rising-edge sensitive */
|
|
GPIO_SENSE_FALLING, /* Falling-edge sensitive */
|
|
GPIO_SENSE_EDGE_SEL, /* Detect any edge */
|
|
};
|
|
|
|
/* Handlers will be called in declared order for a given module
|
|
Handlers of same module should be grouped together; module order
|
|
doesn't matter */
|
|
#ifdef DEFINE_GPIO_VECTOR_TABLE
|
|
|
|
/* Describes a single event for a pin */
|
|
struct gpio_event
|
|
{
|
|
uint8_t id; /* GPIOx_y_ID */
|
|
uint8_t sense; /* GPIO_SENSE_x */
|
|
void (*callback)(void); /* GPIOx_y_EVENT_CB */
|
|
};
|
|
|
|
#define GPIO_VECTOR_TBL_START() \
|
|
static FORCE_INLINE uintptr_t __gpio_event_vector_tbl(int __what) \
|
|
{ \
|
|
static const struct gpio_event __tbl[] = {
|
|
|
|
#define GPIO_EVENT_VECTOR(__name, __sense) \
|
|
{ .id = (__name##_ID), \
|
|
.sense = (__sense), \
|
|
.callback = ({ void __name##_EVENT_CB(void); \
|
|
__name##_EVENT_CB; }) },
|
|
|
|
#define GPIO_VECTOR_TBL_END() \
|
|
}; \
|
|
switch (__what) \
|
|
{ \
|
|
default: return (uintptr_t)__tbl; \
|
|
case 1: return (uintptr_t)ARRAYLEN(__tbl); \
|
|
} \
|
|
}
|
|
|
|
#define gpio_event_vector_tbl \
|
|
((const struct gpio_event *)__gpio_event_vector_tbl(0))
|
|
|
|
#define gpio_event_vector_tbl_len \
|
|
((unsigned int)__gpio_event_vector_tbl(1))
|
|
|
|
#endif /* DEFINE_GPIO_VECTOR_TABLE */
|
|
|
|
#define GPIO_BASE_ADDR \
|
|
(volatile unsigned long * const [GPIO_NUM_GPIO]) { \
|
|
(volatile unsigned long *)GPIO1_BASE_ADDR, \
|
|
(volatile unsigned long *)GPIO2_BASE_ADDR, \
|
|
(volatile unsigned long *)GPIO3_BASE_ADDR }
|
|
|
|
#define GPIO_DR (0x00 / sizeof (unsigned long)) /* 00h */
|
|
#define GPIO_GDIR (0x04 / sizeof (unsigned long)) /* 04h */
|
|
#define GPIO_PSR (0x08 / sizeof (unsigned long)) /* 08h */
|
|
#define GPIO_ICR (0x0C / sizeof (unsigned long)) /* 0Ch ICR1,2 */
|
|
#define GPIO_IMR (0x14 / sizeof (unsigned long)) /* 14h */
|
|
#define GPIO_ISR (0x18 / sizeof (unsigned long)) /* 18h */
|
|
#define GPIO_EDGE_SEL (0x1C / sizeof (unsigned long)) /* 1Ch */
|
|
|
|
void gpio_init(void);
|
|
bool gpio_enable_event(enum gpio_id id, bool enable);
|
|
|
|
static FORCE_INLINE void gpio_int_clear(enum gpio_id id)
|
|
{ GPIO_BASE_ADDR[id / 32][GPIO_ISR] = 1ul << (id % 32); }
|
|
|
|
static FORCE_INLINE void gpio_int_enable(enum gpio_id id)
|
|
{ bitset32(&GPIO_BASE_ADDR[id / 32][GPIO_IMR], 1ul << (id % 32)); }
|
|
|
|
static FORCE_INLINE void gpio_int_disable(enum gpio_id id)
|
|
{ bitclr32(&GPIO_BASE_ADDR[id / 32][GPIO_IMR], 1ul << (id % 32)); }
|
|
|
|
#endif /* GPIO_IMX31_H */
|