| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- #include "FreeRTOS.h"
- #include "chip.h"
- #define GPIO_SWPORTA_DR 0x00
- #define GPIO_SWPORTA_DDR 0x04
- #define GPIO_SWPORTA_CTL 0x08
- #define GPIO_SWPORTA_INTEN 0x30
- #define GPIO_SWPORTA_INTMASK 0x34
- #define GPIO_SWPORTA_INTTYPE_LEVEL 0x38
- #define GPIO_SWPORTA_INT_POLARITY 0x3c
- #define GPIO_SWPORTA_INTSTATUS 0x40
- #define GPIO_SWPORTA_RAW_INTSTATUS 0x44
- #define GPIO_SWPORTA_DEBOUNCE 0x48
- #define GPIO_SWPORTA_EOI 0x4c
- #define GPIO_SWPORTA_EXT_PORTA 0x50
- #define GPIO_SWPORTA_EXT_PORTB 0x54
- #define GPIO_SWPORTA_EXT_PORTC 0x58
- #define GPIO_SWPORTA_EXT_PORTD 0x5c
- #define GPIO_SWPORTA_LS_SYNC 0x60
- #define GPIO_SWPORTA_ID_CODE 0x64
- #define GPIO_SWPORTA_INT_BOTHEDGE 0x68
- #define GPIO_SWPORTA_VER_ID_CODE 0x6C
- #define GPIO_SWPORTA_CONFIG_REG2 0x70
- #define GPIO_SWPORTA_CONFIG_REG1 0x74
- #define GPIO_BANK 5
- #define GPIO_NUM 144
- typedef struct {
- ISRFunction_t handler;
- void *handler_param;
- int irq_type;
- } GpioIrqDesc_t;
- static GpioIrqDesc_t gpio_irq_descs[GPIO_NUM];
- static __INLINE uint32_t gpio_get_regbase(int gpio)
- {
- int gpiox = (gpio >> 5) & 0x7;
- return REGS_GPIO_BASE + 0x80 * gpiox;
- }
- /* static __INLINE int GPIO_BANK(unsigned gpio)
- {
- return gpio >> 5;
- } */
- static __INLINE int GPIO_OFFSET(unsigned gpio)
- {
- return gpio & 0x1F;
- }
- static __INLINE void *GPIO_MODREG(unsigned gpio)
- {
- return (void*)(gpio_get_regbase(gpio) + GPIO_SWPORTA_DDR);
- }
- static __INLINE void *GPIO_WDATAREG(unsigned gpio)
- {
- return (void*)(gpio_get_regbase(gpio) + GPIO_SWPORTA_DR);
- }
- static __INLINE void *GPIO_RDATAREG(unsigned gpio)
- {
- return (void*)(gpio_get_regbase(gpio) + GPIO_SWPORTA_EXT_PORTA);
- }
- static __INLINE void *GPIO_INTENREG(unsigned gpio)
- {
- return (void*)(gpio_get_regbase(gpio) + GPIO_SWPORTA_INTEN);
- }
- static __INLINE void *GPIO_INTMASKREG(unsigned gpio)
- {
- return (void*)(gpio_get_regbase(gpio) + GPIO_SWPORTA_INTMASK);
- }
- static __INLINE void *GPIO_INTLVLREG(unsigned gpio)
- {
- return (void*)(gpio_get_regbase(gpio) + GPIO_SWPORTA_INTTYPE_LEVEL);
- }
- static __INLINE void *GPIO_INTPOLREG(unsigned gpio)
- {
- return (void*)(gpio_get_regbase(gpio) + GPIO_SWPORTA_INT_POLARITY);
- }
- static __INLINE void *GPIO_DEBOUNCEREG(unsigned gpio)
- {
- return (void*)(gpio_get_regbase(gpio) + GPIO_SWPORTA_DEBOUNCE);
- }
- void gpio_request(unsigned gpio)
- {
- pinctrl_gpio_request(gpio);
- }
- void gpio_direction_output(unsigned gpio, int value)
- {
- configASSERT(gpio < GPIO_NUM);
- gpio_request(gpio);
- if ((gpio >= 111) && (gpio <= 126)) {
- writel(readl(GPIO_MODREG(gpio)) & ~(1 << GPIO_OFFSET(gpio)), GPIO_MODREG(gpio));
- } else {
- writel(readl(GPIO_MODREG(gpio)) | (1 << GPIO_OFFSET(gpio)), GPIO_MODREG(gpio));
- }
- if (value)
- writel(readl(GPIO_WDATAREG(gpio)) | (1 << GPIO_OFFSET(gpio)), GPIO_WDATAREG(gpio));
- else
- writel(readl(GPIO_WDATAREG(gpio)) & ~(1 << GPIO_OFFSET(gpio)), GPIO_WDATAREG(gpio));
- }
- void gpio_debouncereg_enable(unsigned gpio, int enable)
- {
- if(enable)
- writel(readl(GPIO_DEBOUNCEREG(gpio)) | (1 << GPIO_OFFSET(gpio)), GPIO_DEBOUNCEREG(gpio));
- else
- writel(readl(GPIO_DEBOUNCEREG(gpio)) & (~(1 << GPIO_OFFSET(gpio))), GPIO_DEBOUNCEREG(gpio));
- }
- void gpio_direction_input(unsigned gpio)
- {
- configASSERT(gpio < GPIO_NUM);
- gpio_request(gpio);
- if ((gpio >= 111) && (gpio <= 126)) {
- writel(readl(GPIO_MODREG(gpio)) | (1 << GPIO_OFFSET(gpio)), GPIO_MODREG(gpio));
- writel(readl(REGS_SYSCTL_BASE + SYS_PAD_PUDCTL14) | (1 << (gpio - 111)), \
- REGS_SYSCTL_BASE + SYS_PAD_PUDCTL14);
- } else {
- writel(readl(GPIO_MODREG(gpio)) & ~(1 << GPIO_OFFSET(gpio)), GPIO_MODREG(gpio));
- }
- }
- void gpio_set_value(unsigned gpio, int value)
- {
- configASSERT(gpio < GPIO_NUM);
- if (value)
- writel(readl(GPIO_WDATAREG(gpio)) | (1 << GPIO_OFFSET(gpio)), GPIO_WDATAREG(gpio));
- else
- writel(readl(GPIO_WDATAREG(gpio)) & ~(1 << GPIO_OFFSET(gpio)), GPIO_WDATAREG(gpio));
- }
- int gpio_get_value(unsigned gpio)
- {
- configASSERT(gpio < GPIO_NUM);
- return !!(readl(GPIO_RDATAREG(gpio)) & (1 << GPIO_OFFSET(gpio)));
- }
- static void gpio_toggle_trigger(unsigned gpio)
- {
- u32 pol;
- pol = readl(GPIO_INTPOLREG(gpio));
- if (pol & (1 << GPIO_OFFSET(gpio)))
- pol &= ~(1 << GPIO_OFFSET(gpio));
- else
- pol |= (1 << GPIO_OFFSET(gpio));
- writel(pol, GPIO_INTPOLREG(gpio));
- }
- static void gpio_irq_enable(unsigned gpio)
- {
- writel(readl(GPIO_INTENREG(gpio)) | (1 << GPIO_OFFSET(gpio)), GPIO_INTENREG(gpio));
- writel(readl(GPIO_INTMASKREG(gpio)) & ~(1 << GPIO_OFFSET(gpio)), GPIO_INTMASKREG(gpio));
- }
- static void gpio_irq_disable(unsigned gpio)
- {
- writel(readl(GPIO_INTENREG(gpio)) & ~(1 << GPIO_OFFSET(gpio)), GPIO_INTENREG(gpio));
- writel(readl(GPIO_INTMASKREG(gpio)) | (1 << GPIO_OFFSET(gpio)), GPIO_INTMASKREG(gpio));
- }
- static int gpio_irq_set_irq_type(unsigned gpio, int type)
- {
- unsigned long level, polarity;
- level = readl(GPIO_INTLVLREG(gpio));
- polarity = readl(GPIO_INTPOLREG(gpio));
- switch (type) {
- case IRQ_TYPE_EDGE_BOTH:
- level |= (1 << GPIO_OFFSET(gpio));
- gpio_toggle_trigger(gpio);
- break;
- case IRQ_TYPE_EDGE_RISING:
- level |= (1 << GPIO_OFFSET(gpio));
- polarity |= (1 << GPIO_OFFSET(gpio));
- break;
- case IRQ_TYPE_EDGE_FALLING:
- level |= (1 << GPIO_OFFSET(gpio));
- polarity &= ~(1 << GPIO_OFFSET(gpio));
- break;
- case IRQ_TYPE_LEVEL_HIGH:
- level &= ~(1 << GPIO_OFFSET(gpio));
- polarity |= (1 << GPIO_OFFSET(gpio));
- break;
- case IRQ_TYPE_LEVEL_LOW:
- level &= ~(1 << GPIO_OFFSET(gpio));
- polarity &= ~(1 << GPIO_OFFSET(gpio));
- break;
- }
- writel(level, GPIO_INTLVLREG(gpio));
- if (type != IRQ_TYPE_EDGE_BOTH)
- writel(polarity, GPIO_INTPOLREG(gpio));
- return 0;
- }
- static void gpio_irq_handler(void *param)
- {
- u32 status;
- int i, j;
- for (i = 0; i < GPIO_BANK; i++) {
- status = readl(REGS_GPIO_BASE + 0x80 * i + GPIO_SWPORTA_INTSTATUS);
- for (j = 0; j < 32; j++) {
- if (status & (1 << j)) {
- u32 gpio = i * 32 + j;
- /* clear interrupt */
- writel(1 << j, REGS_GPIO_BASE + 0x80 * i + GPIO_SWPORTA_EOI);
- if (gpio_irq_descs[gpio].handler != NULL) {
- gpio_irq_descs[gpio].handler(gpio_irq_descs[gpio].handler_param);
- if (gpio_irq_descs[gpio].irq_type == IRQ_TYPE_EDGE_BOTH)
- gpio_toggle_trigger(gpio);
- }
- }
- }
- }
- }
- int gpio_irq_request(unsigned gpio, int irq_type, ISRFunction_t irq_handler, void *param)
- {
- configASSERT(gpio < GPIO_NUM);
- portENTER_CRITICAL();
- gpio_request(gpio);
- gpio_irq_descs[gpio].handler = irq_handler;
- gpio_irq_descs[gpio].handler_param = param;
- gpio_irq_descs[gpio].irq_type = irq_type;
- gpio_irq_set_irq_type(gpio, irq_type);
- if(gpio >= 128)
- request_irq(GPIOE_IRQn, 0, gpio_irq_handler,NULL);
- else
- request_irq(GPIOA_IRQn + ((gpio >> 5) & 0x3), 0, gpio_irq_handler,NULL);
- gpio_irq_enable(gpio);
- portEXIT_CRITICAL();
- return 0;
- }
- int gpio_irq_free(unsigned gpio)
- {
- configASSERT(gpio < GPIO_NUM);
- portENTER_CRITICAL();
- gpio_irq_disable(gpio);
- gpio_irq_descs[gpio].handler = NULL;
- gpio_irq_descs[gpio].handler_param = NULL;
- portEXIT_CRITICAL();
- return 0;
- }
|