s5p6818 gpio controller driver implementation analysis
linux version 3.4.39
lable 1:
GPIO platform_device_register();
/* arch/arm/mach-s5p6818/devices.c */
/*------------------------------------------------------------------------------
* register cpu platform devices
*/
void __init nxp_cpu_devs_register(void)
{
#if defined(CONFIG_GPIO_NXP)
printk("mach: add device generic gpio (array:%d)\n", ARRAY_SIZE(gpio_devices));
platform_add_devices(gpio_devices, ARRAY_SIZE(gpio_devices));
#endif
}
/*------------------------------------------------------------------------------
* GPIO device
*/
#if defined(CONFIG_GPIO_NXP)
#if defined(CONFIG_GPIO_NXP_GROUP_A)
static struct resource gpio_resource_A = {
.start = 0,
.end = 32,
.flags = IORESOURCE_IO,
};
static struct platform_device gpio_device_A = {
.name = DEV_NAME_GPIO,
.id = 0,
.resource = &gpio_resource_A,
.num_resources = 1,
};
#endif
#if defined(CONFIG_GPIO_NXP_GROUP_B)
static struct resource gpio_resource_B = {
.start = 0,
.end = 32,
.flags = IORESOURCE_IO,
};
static struct platform_device gpio_device_B = {
.name = DEV_NAME_GPIO,
.id = 1,
.resource = &gpio_resource_B,
.num_resources = 1,
};
#endif
#if defined(CONFIG_GPIO_NXP_GROUP_C)
static struct resource gpio_resource_C = {
.start = 0,
.end = 32,
.flags = IORESOURCE_IO,
};
static struct platform_device gpio_device_C = {
.name = DEV_NAME_GPIO,
.id = 2,
.resource = &gpio_resource_C,
.num_resources = 1,
};
#endif
#if defined(CONFIG_GPIO_NXP_GROUP_D)
static struct resource gpio_resource_D = {
.start = 0,
.end = 32,
.flags = IORESOURCE_IO,
};
static struct platform_device gpio_device_D = {
.name = DEV_NAME_GPIO,
.id = 3,
.resource = &gpio_resource_D,
.num_resources = 1,
};
#endif
#if defined(CONFIG_GPIO_NXP_GROUP_E)
static struct resource gpio_resource_E = {
.start = 0,
.end = 32,
.flags = IORESOURCE_IO,
};
static struct platform_device gpio_device_E = {
.name = DEV_NAME_GPIO,
.id = 4,
.resource = &gpio_resource_E,
.num_resources = 1,
};
#endif
#if defined(CONFIG_GPIO_NXP_GROUP_ALV)
static struct resource gpio_resource_ALV = {
.start = 0,
.end = 6,
.flags = IORESOURCE_IO,
};
static struct platform_device gpio_device_ALV = {
.name = DEV_NAME_GPIO,
.id = 5,
.resource = &gpio_resource_ALV,
.num_resources = 1,
};
#endif
static struct platform_device *gpio_devices[] = {
#if defined(CONFIG_GPIO_NXP_GROUP_A)
&gpio_device_A,
#endif
#if defined(CONFIG_GPIO_NXP_GROUP_B)
&gpio_device_B,
#endif
#if defined(CONFIG_GPIO_NXP_GROUP_C)
&gpio_device_C,
#endif
#if defined(CONFIG_GPIO_NXP_GROUP_D)
&gpio_device_D,
#endif
#if defined(CONFIG_GPIO_NXP_GROUP_E)
&gpio_device_E,
#endif
#if defined(CONFIG_GPIO_NXP_GROUP_ALV)
&gpio_device_ALV,
#endif
};
#endif /* CONFIG_GPIO_NXP */
GPIO platform_driver_register();
probe, gpiochip_add(&gpio->chip);
/* drivers/gpio/gpio-nxp.c */
/*
* Copyright (C) 2008, 2009 Provigent Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Driver for the ARM PrimeCell(tm) General Purpose Input/Output (PL061)
*
* Data sheet: ARM DDI 0190B, September 2000
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/pm.h>
#include <mach/platform.h>
#include <mach/devices.h>
#include <mach/soc.h>
/*
#define pr_debug(msg...) { printk(KERN_INFO "gpio: " msg); }
*/
#if (0)
#define CHECK_ALTFUNC_RET(_gpio, _offs, _ret) do { \
int io = (_gpio->index * GPIO_NUM_PER_BANK) + _offs; \
int cn = nxp_soc_gpio_get_io_func(io); \
int fn = GET_GPIO_ALTFUNC(_gpio->index, _offs); \
if (cn != fn) { \
printk("Fail : io used alt function %d [%s:%u=%d]\n", \
cn, io_name[_gpio->index], _offs, io); \
return _ret; \
} \
} while(0)
#else
#define CHECK_ALTFUNC_RET(_gpio, _offs, _ret) do { } while (0)
#endif
struct nxp_gpio {
int index; /* Bank Index : A(0), B(1), C(2), D(3), E(4), ALIVE(5) */
spinlock_t lock; /* GPIO registers */
struct gpio_chip chip;
};
static const char *io_name[] = { "GPIOA", "GPIOB", "GPIOC", "GPIOD", "GPIOE", "GPIOALV" };
#define GET_GPIO(c) container_of(chip, struct nxp_gpio, chip)
static int nxp_gpio_request(struct gpio_chip *chip, unsigned offset)
{
struct nxp_gpio *gpio = GET_GPIO(chip);
int io, fn;
io = (gpio->index * GPIO_NUM_PER_BANK) + offset;
fn = GET_GPIO_ALTFUNC(gpio->index, offset);
CHECK_ALTFUNC_RET(gpio, offset, EINVAL);
nxp_soc_gpio_set_io_func(io, fn);
pr_debug("%s: io [%s:%d=%d]\n", __func__, io_name[gpio->index], offset, io);
return 0;
}
static int nxp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
struct nxp_gpio *gpio = GET_GPIO(chip);
int io, fn;
io = (gpio->index * GPIO_NUM_PER_BANK) + offset;
fn = GET_GPIO_ALTFUNC(gpio->index, offset);
CHECK_ALTFUNC_RET(gpio, offset, EINVAL);
nxp_soc_gpio_set_io_func(io, fn);
nxp_soc_gpio_set_io_dir(io, 0);
pr_debug("%s: io [%s:%d=%d]\n", __func__, io_name[gpio->index], offset, io);
return 0;
}
static int nxp_gpio_direction_output(struct gpio_chip *chip,
unsigned offset, int value)
{
struct nxp_gpio *gpio = GET_GPIO(chip);
int io, fn;
io = (gpio->index * GPIO_NUM_PER_BANK) + offset;
fn = GET_GPIO_ALTFUNC(gpio->index, offset);
CHECK_ALTFUNC_RET(gpio, offset, EINVAL);
nxp_soc_gpio_set_io_func(io, fn);
nxp_soc_gpio_set_out_value(io, value);
nxp_soc_gpio_set_io_dir(io, 1);
pr_debug("%s: io [%s:%d=%d], val=%d\n",
__func__, io_name[gpio->index], offset, io, value);
return 0;
}
static int nxp_gpio_get_value(struct gpio_chip *chip, unsigned offset)
{
struct nxp_gpio *gpio = GET_GPIO(chip);
int io = gpio->index * GPIO_NUM_PER_BANK + offset;
pr_debug("%s: io [%s:%d=%d]\n", __func__, io_name[gpio->index], offset, io);
return nxp_soc_gpio_get_in_value(io);
}
static void nxp_gpio_set_value(struct gpio_chip *chip, unsigned offset, int value)
{
struct nxp_gpio *gpio = GET_GPIO(chip);
int io, fn, cn;
io = gpio->index * GPIO_NUM_PER_BANK + offset;
fn = GET_GPIO_ALTFUNC(gpio->index, offset);
cn = nxp_soc_gpio_get_io_func(io);
#if (0)
if (cn != fn) {
printk("Fail : io used alt function %d [%s:%u=%d]\n",
cn, io_name[gpio->index], offset, io);
return;
}
#endif
nxp_soc_gpio_set_io_dir(io, 1);
nxp_soc_gpio_set_out_value(io, value);
pr_debug("%s: io [%s:%d=%d], val=%d\n",
__func__, io_name[gpio->index], offset, io, value);
}
static int nxp_gpio_to_irq( struct gpio_chip *chip , unsigned offset )
{
struct nxp_gpio *gpio = GET_GPIO(chip);
unsigned int io = gpio->index * GPIO_NUM_PER_BANK + offset;
/*printk("~~~ %s() offset:%d, io:%d, irq:%d\n", __func__, \
offset, io, io + IRQ_GPIO_START);*/
return (io + IRQ_GPIO_START);
}
#ifdef CONFIG_PM
static int nxp_gpio_suspend(struct platform_device *pdev, pm_message_t state)
{
PM_DBGOUT("%s\n", __func__);
return 0;
}
static int nxp_gpio_resume(struct platform_device *pdev)
{
PM_DBGOUT("%s\n", __func__);
return 0;
}
#else
#define nxp_gpio_suspend NULL
#define nxp_gpio_resume NULL
#endif
static int nxp_gpio_probe(struct platform_device *pdev)
{
struct resource *res = pdev->resource;
struct nxp_gpio *gpio = NULL;
int ret;
pr_debug("%s: %s, %d ~ %2d\n",
__func__, io_name[pdev->id], res->start, res->end);
if (!res) {
printk("Error: not allocated gpio resource [%d]\n", pdev->id);
return -EINVAL;
}
gpio = kzalloc(sizeof(*gpio), GFP_KERNEL);
if (gpio == NULL)
return -ENOMEM;
spin_lock_init(&gpio->lock);
gpio->index = pdev->id;
gpio->chip.request = nxp_gpio_request;
gpio->chip.to_irq = nxp_gpio_to_irq;
gpio->chip.direction_input = nxp_gpio_direction_input;
gpio->chip.direction_output = nxp_gpio_direction_output;
gpio->chip.get = nxp_gpio_get_value;
gpio->chip.set = nxp_gpio_set_value;
gpio->chip.ngpio = res->end - res->start;
gpio->chip.label = io_name[pdev->id];
gpio->chip.dev = &pdev->dev;
gpio->chip.owner = THIS_MODULE;
gpio->chip.base = pdev->id * GPIO_NUM_PER_BANK;
/* register GPIOLib */
ret = gpiochip_add(&gpio->chip);
if (ret)
goto free_mem;
return ret;
free_mem:
kfree(gpio);
return ret;
}
static int nxp_gpio_remove(struct platform_device *pdev)
{
return 0;
}
static struct platform_driver nxp_gpio_driver = {
.probe = nxp_gpio_probe,
.remove = __devexit_p(nxp_gpio_remove),
.suspend = nxp_gpio_suspend,
.resume = nxp_gpio_resume,
.driver = {
.name = DEV_NAME_GPIO,
.owner = THIS_MODULE,
},
};
static int __init nxp_gpio_init(void)
{
return platform_driver_register(&nxp_gpio_driver);
}
subsys_initcall(nxp_gpio_init);
MODULE_DESCRIPTION("GPIO driver for the Nexell");
MODULE_LICENSE("GPL");
/* arch\arm\mach-s5p6818\include\mach\gpio.h */
/*
*/
#include "s5p6818_irq.h"
#define GPIO_NUM_PER_BANK 32
#define ARCH_NR_GPIOS (GPIO_NUM_PER_BANK * 6) /* For GPIO A, B, C, D, E, ALVIE */
extern const unsigned char gpio_alt_no[][GPIO_NUM_PER_BANK];
#define GET_GPIO_ALTFUNC(io,idx) (gpio_alt_no[io][idx])
#include <asm-generic/gpio.h>
struct platform_device gpio_device, id,用來確定io組,io number;
lable 1.1:
gpio_chip ops,實現分析;
static int nxp_gpio_request(struct gpio_chip *chip, unsigned offset)
{
struct nxp_gpio *gpio = GET_GPIO(chip);
int io, fn;
io = (gpio->index * GPIO_NUM_PER_BANK) + offset;
fn = GET_GPIO_ALTFUNC(gpio->index, offset);
CHECK_ALTFUNC_RET(gpio, offset, EINVAL);
nxp_soc_gpio_set_io_func(io, fn);
pr_debug("%s: io [%s:%d=%d]\n", __func__, io_name[gpio->index], offset, io);
return 0;
}
nxp_gpio_request(); 實現分析:
gpio->index = pdev->id;
io number: (gpio->index * GPIO_NUM_PER_BANK) + offset;
配置io為GPIO 功能
fn = CHECK_ALTFUNC_RET(gpio, offset, EINVAL);
nxp_soc_gpio_set_io_func(io, fn);
/*------------------------------------------------------------------------------
* Description : set gpio pad function
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, bit= 0 ~ 32)
* In[mode] : gpio pad function
* : 0 = GPIO mode
* : 1 = Alternate function 1
* : 2 = Alternate function 2
* : 3 = Alternate function 3
* Return : none.
*/
void nxp_soc_gpio_set_io_func(unsigned int io, unsigned int func)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
NX_GPIO_SetPadFunction(grp, bit, func);
IO_UNLOCK(grp);
break;
case PAD_GPIO_ALV:
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return;
}
EXPORT_SYMBOL(nxp_soc_gpio_set_io_func);
nxp_soc_gpio_set_io_func();實現分析:
根據io number計算出 io group, offset,
都是為了確認具體是是操作哪個寄存器,
哪個bit,配置為什么值
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
call NX_GPIO_SetPadFunction(grp, bit, func);
//--------------------------------------------------------------------------
// Pin Configuration
//--------------------------------------------------------------------------
/**
* @brief Set PAD Fuction
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @param[in] padfunc Pad Function
* @return None
* @remarks Each gpio pins can use to GPIO Pin or Alternate Function 0 or Alternate Function 1 or \n
* Alternate Function 2. So This function Sets gpio pin's function.
*/
void NX_GPIO_SetPadFunction( U32 ModuleIndex, U32 BitNumber, NX_GPIO_PADFUNC padfunc )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( 0 != (__g_NX_GPIO_VALID_BIT[ModuleIndex] & (1 << BitNumber)) );
NX_ASSERT( NX_GPIO_PADFUNC_3 >= padfunc );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
NX_GPIO_SetBit2( &pRegister->GPIOxALTFN[BitNumber/16], BitNumber%16, (U32)padfunc );
}
NX_GPIO_SetPadFunction();實現分析:
獲取寄存器地址,配置;
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
寄存器的基地址,__g_ModuleVariables[ModuleIndex].pRegister,是什么時候初始化 和 mmap的?
static struct
{
struct NX_GPIO_RegisterSet *pRegister;
} __g_ModuleVariables[NUMBER_OF_GPIO_MODULE] = { {CNULL,}, };
lable 1.2:
gpio io phy addr mmap;
從start_kernel();開始講起;
start_kernel()
|
...
setup_arch();
|
paging_init(mdesc);
|
mdesc->map_io();
static void __init cpu_map_io(void)
{
int cores = LIVE_NR_CPUS;
printk("~~~ %s()\n", __func__);
/*
* check memory map
*/
unsigned long io_end = cpu_iomap_desc[ARRAY_SIZE(cpu_iomap_desc)-1].virtual +
cpu_iomap_desc[ARRAY_SIZE(cpu_iomap_desc)-1].length;
#if defined(CFG_MEM_PHY_DMAZONE_SIZE)
unsigned long dma_start = CONSISTENT_END - CFG_MEM_PHY_DMAZONE_SIZE;
#else
unsigned long dma_start = CONSISTENT_END - SZ_2M; // refer to dma-mapping.c
#endif
if (io_end > dma_start)
printk(KERN_ERR "\n****** BUG: Overlapped io mmap 0x%lx with dma start 0x%lx ******\n",
io_end, dma_start);
/* debug */
_IOMAP();
/* make iotable */
iotable_init(cpu_iomap_desc, ARRAY_SIZE(cpu_iomap_desc));
#if defined(CFG_MEM_PHY_DMAZONE_SIZE)
printk(KERN_INFO "CPU : DMA Zone Size =%2dM, CORE %d\n", CFG_MEM_PHY_DMAZONE_SIZE>>20, cores);
init_consistent_dma_size(CFG_MEM_PHY_DMAZONE_SIZE);
#else
printk(KERN_INFO "CPU : DMA Zone Size =%2dM, CORE %d\n", SZ_2M>>20, cores);
#endif
nxp_cpu_arch_init();
nxp_board_base_init();
nxp_cpu_clock_init();
nxp_cpu_clock_print();
}
cpu_iomap_desc,:
/* arch/arm/mach-s5p6818/include/mach/s5p6818_iomap.h
/*
* Length must be aligned 1MB
*
* Refer to mach/iomap.h
*
* Physical : __PB_IO_MAP_ ## _n_ ## _PHYS
* Virtual : __PB_IO_MAP_ ## _n_ ## _VIRT
*
* name .virtual, .pfn, .length, .type
*/
PB_IO_MAP( REGS, 0xF0000000, 0xC0000000, 0x00300000, MT_DEVICE ) /* NOMAL IO, Reserved */
PB_IO_MAP( CCI4, 0xF0300000, 0xE0000000, 0x00100000, MT_DEVICE ) /* CCI-400 */
PB_IO_MAP( SRAM, 0xF0400000, 0xFFF00000, 0x00100000, MT_DEVICE ) /* SRAM */
PB_IO_MAP( NAND, 0xF0500000, 0x2C000000, 0x00100000, MT_DEVICE ) /* NAND */
PB_IO_MAP( IROM, 0xF0600000, 0x00000000, 0x00100000, MT_DEVICE ) /* IROM */
/* arch/arm/mach-s5p6818/include/mach/map_desc.h */
/*
* (C) Copyright 2009
* jung hyun kim, Nexell Co, <jhkim@nexell.co.kr>
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __ASM_ARCH_MAP_DESC_H
#define __ASM_ARCH_MAP_DESC_H
#include <asm/mach/map.h>
#ifdef PB_IO_MAP
#undef PB_IO_MAP
#endif
#define PB_IO_MAP(_n_, _v_, _p_, _s_, _t_) \
{ \
.virtual = _v_, \
.pfn = __phys_to_pfn(_p_), \
.length = _s_, \
.type = _t_ \
},
static struct map_desc cpu_iomap_desc[] =
{
#include <mach/s5p6818_iomap.h>
};
#endif /* __ASM_ARCH_MAP_DESC_H */
__init cpu_map_io(void)
|
iotable_init(cpu_iomap_desc, ARRAY_SIZE(cpu_iomap_desc));
|
create_mapping(md, false); /*線性 mmap io phy addreass to virtual address: */
上面io phy address線性mmap 到virt address;映射后即可通過虛擬地址訪問io register;
io phy address 到 virtual address的轉換:
define IO_ADDRESS(x) (x - __PB_IO_MAP_REGS_PHYS + __PB_IO_MAP_REGS_VIRT)
__PB_IO_MAP_REGS_PHYS,哪里定義?
/* arch/arm/mach-s5p6818/include/mach/iomap.h */
#define PB_IO_MAP(_n_, _v_, _p_, _s_, _t_) \
enum { \
__PB_IO_MAP_ ## _n_ ## _VIRT = _v_, \
__PB_IO_MAP_ ## _n_ ## _PHYS = _p_, \
};
展開:
PB_IO_MAP( REGS, 0xF0000000, 0xC0000000, 0x00300000, MT_DEVICE )
enum { \
__PB_IO_MAP_ ## REGS ## _VIRT = _v_, \
__PB_IO_MAP_ ## REGS ## _PHYS = _p_, \
};
->:
enum { \
__PB_IO_MAP_REGS_VIRT = 0xF0000000, \
__PB_IO_MAP_REGS_PHYS = 0xC0000000, \
};
NX_GPIO_SetBaseAddress();中
初始化GPIO controller的base虛擬地址給到全局變量__g_ModuleVariables[ModuleIndex].pRegister;
void nxp_cpu_arch_init(void)
|
cpu_base_init(void) {
...
NX_GPIO_Initialize();
for (i = 0; NX_GPIO_GetNumberOfModule() > i; i++) {
printk("~~~ %s() gpio group %d, io_phy_addr:0x%lx, io_virt_addr:0x%lx\n",
__func__, i,
(unsigned long)NX_GPIO_GetPhysicalAddress(i),
(unsigned long)IO_ADDRESS(NX_GPIO_GetPhysicalAddress(i)) );
NX_GPIO_SetBaseAddress(i, (void*)IO_ADDRESS(NX_GPIO_GetPhysicalAddress(i)));
NX_GPIO_OpenModule(i);
}
...
}
/* arch/arm/plat-s5p6818/nanopi3/board.c */
void nxp_board_base_init(void)
{
if (g_initGpio)
{
bd_gpio_init(); /* board all gpio init */
bd_alive_init();
DBGOUT("%s: Board initialized\n", CFG_SYS_BOARD_NAME);
g_initGpio = 0;
}
}
//------------------------------------------------------------------------------
/**
* @brief Set a base address of register set.
* @param[in] ModuleIndex A index of module.
* @param[in] BaseAddress Module's base address
* @return None.
*/
void NX_GPIO_SetBaseAddress( U32 ModuleIndex, void* BaseAddress )
{
NX_ASSERT( CNULL != BaseAddress );
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
__g_ModuleVariables[ModuleIndex].pRegister = (struct NX_GPIO_RegisterSet *)BaseAddress;
}
NX_GPIO_GetPhysicalAddress(i);獲取GPIO controller的物理base地址
//------------------------------------------------------------------------------
// Basic Interface
//------------------------------------------------------------------------------
/**
* @brief Get module's physical address.
* @param[in] ModuleIndex A index of module.
* @return Module's physical address
*/
U32 NX_GPIO_GetPhysicalAddress( U32 ModuleIndex )
{
static const U32 PhysicalAddr[] = { PHY_BASEADDR_LIST_ALPHA( GPIO ) }; // PHY_BASEADDR_GPIO?_MODULE
NX_CASSERT( NUMBER_OF_GPIO_MODULE == (sizeof(PhysicalAddr)/sizeof(PhysicalAddr[0])) );
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
return (U32)PhysicalAddr[ModuleIndex];
}
static const U32 PhysicalAddr[] = { PHY_BASEADDR_LIST_ALPHA( GPIO ) }; // PHY_BASEADDR_GPIO?_MODULE
PhysicalAddr是個數組;
#define PHY_BASEADDR_LIST_ALPHA(NAME) _GET_MACRO_LIST_ALPHA( NAME, PHY_BASEADDR_ , _MODULE, NUMBER_OF_ ## NAME ## _MODULE )
#define _GET_MACRO_LIST_ALPHA(NAME,PRE,POST,COUNT) CAT( _GET_MACRO_LIST_ALPHA_, COUNT )(NAME,PRE,POST)
#define CAT(a, ...) a ## __VA_ARGS__
#define NUMBER_OF_GPIO_MODULE 5
又:
#define _GET_MACRO_LIST_ALPHA_1(NAME,PRE,POST) PRE ## NAME ## A ## POST
#define _GET_MACRO_LIST_ALPHA_2(NAME,PRE,POST) PRE ## NAME ## A ## POST , PRE ## NAME ## B ## POST
#define _GET_MACRO_LIST_ALPHA_3(NAME,PRE,POST) _GET_MACRO_LIST_ALPHA_2(NAME,PRE,POST) , PRE ## NAME ## C ## POST
#define _GET_MACRO_LIST_ALPHA_4(NAME,PRE,POST) _GET_MACRO_LIST_ALPHA_3(NAME,PRE,POST) , PRE ## NAME ## D ## POST
#define _GET_MACRO_LIST_ALPHA_5(NAME,PRE,POST) _GET_MACRO_LIST_ALPHA_4(NAME,PRE,POST) , PRE ## NAME ## E ## POST
#define _GET_MACRO_LIST_ALPHA_6(NAME,PRE,POST) _GET_MACRO_LIST_ALPHA_5(NAME,PRE,POST) , PRE ## NAME ## F ## POST
宏展開,有:
#define PHY_BASEADDR_LIST_ALPHA(NAME) _GET_MACRO_LIST_ALPHA( NAME, PHY_BASEADDR_ , _MODULE, NUMBER_OF_ ## NAME ## _MODULE )
#define PHY_BASEADDR_LIST_ALPHA(GPIO) _GET_MACRO_LIST_ALPHA(GPIO, PHY_BASEADDR_ , _MODULE, NUMBER_OF_GPIO_MODULE )
#define _GET_MACRO_LIST_ALPHA(NAME,PRE,POST,COUNT) CAT( _GET_MACRO_LIST_ALPHA_, COUNT )(NAME,PRE,POST)
_GET_MACRO_LIST_ALPHA(GPIO, PHY_BASEADDR_ , _MODULE, NUMBER_OF_GPIO_MODULE ) CAT( _GET_MACRO_LIST_ALPHA_, NUMBER_OF_GPIO_MODULE )(GPIO, PHY_BASEADDR_,_MODULE)
#define CAT(a, ...) a ## __VA_ARGS__
CAT( _GET_MACRO_LIST_ALPHA_, NUMBER_OF_GPIO_MODULE )(GPIO, PHY_BASEADDR_,_MODULE) _GET_MACRO_LIST_ALPHA_5(GPIO, PHY_BASEADDR_, _MODULE)
又:
#define _GET_MACRO_LIST_ALPHA_1(NAME,PRE,POST) PRE ## NAME ## A ## POST
#define _GET_MACRO_LIST_ALPHA_2(NAME,PRE,POST) PRE ## NAME ## A ## POST , PRE ## NAME ## B ## POST
#define _GET_MACRO_LIST_ALPHA_3(NAME,PRE,POST) _GET_MACRO_LIST_ALPHA_2(NAME,PRE,POST) , PRE ## NAME ## C ## POST
#define _GET_MACRO_LIST_ALPHA_4(NAME,PRE,POST) _GET_MACRO_LIST_ALPHA_3(NAME,PRE,POST) , PRE ## NAME ## D ## POST
#define _GET_MACRO_LIST_ALPHA_5(NAME,PRE,POST) _GET_MACRO_LIST_ALPHA_4(NAME,PRE,POST) , PRE ## NAME ## E ## POST
所以:
_GET_MACRO_LIST_ALPHA_2(NAME,PRE,POST) PRE ## NAME ## A ## POST
_GET_MACRO_LIST_ALPHA_5(GPIO, PHY_BASEADDR_, _MODULE): PHY_BASEADDR_GPIOA_MODULE,PHY_BASEADDR_GPIOB_MODULE,PHY_BASEADDR_GPIOC_MODULE,PHY_BASEADDR_GPIOD_MODULE,PHY_BASEADDR_GPIOE_MODULE
終於找到,arch/arm/mach-s5p6818/prototype/base/nx_chip.h
#define PHY_BASEADDR_GPIOA_MODULE 0xC001A000
#define PHY_BASEADDR_GPIOB_MODULE 0xC001B000
#define PHY_BASEADDR_GPIOC_MODULE 0xC001C000
#define PHY_BASEADDR_GPIOD_MODULE 0xC001D000
#define PHY_BASEADDR_GPIOE_MODULE 0xC001E000
kernel log 有:
[ 0.000000] ~~~ cpu_map_io()
[ 0.000000] CPU : iomap[ 0]: p 0xc0000000 -> v 0xf0000000 len=0x300000
[ 0.000000] CPU : iomap[ 1]: p 0xe0000000 -> v 0xf0300000 len=0x100000
[ 0.000000] CPU : iomap[ 2]: p 0xfff00000 -> v 0xf0400000 len=0x100000
[ 0.000000] CPU : iomap[ 3]: p 0x2c000000 -> v 0xf0500000 len=0x100000
[ 0.000000] CPU : iomap[ 4]: p 0x00000000 -> v 0xf0600000 len=0x100000
[ 0.000000] memblock_reserve: [0x00000065e3ef60-0x00000065e3f000] memblock_alloc_base_nid+0x4c/0x60
[ 0.000000] ~~~ create_mapping() phys:0xc0000000, pfn:0xc0000, virt:0xf0000000, length:0x300000
[ 0.000000] ~~~ create_mapping() phys:0xe0000000, pfn:0xe0000, virt:0xf0300000, length:0x100000
[ 0.000000] ~~~ create_mapping() phys:0xfff00000, pfn:0xfff00, virt:0xf0400000, length:0x100000
[ 0.000000] ~~~ create_mapping() phys:0x2c000000, pfn:0x2c000, virt:0xf0500000, length:0x100000
[ 0.000000] ~~~ create_mapping() phys:0x0, pfn:0x0, virt:0xf0600000, length:0x100000
[ 0.000000] CPU : DMA Zone Size =16M, CORE 8
[ 0.000000] ~~~ cpu_base_init() gpio group 0, io_phy_addr:0xc001a000, io_virt_addr:0xf001a000
[ 0.000000] ~~~ cpu_base_init() gpio group 1, io_phy_addr:0xc001b000, io_virt_addr:0xf001b000
[ 0.000000] ~~~ cpu_base_init() gpio group 2, io_phy_addr:0xc001c000, io_virt_addr:0xf001c000
[ 0.000000] ~~~ cpu_base_init() gpio group 3, io_phy_addr:0xc001d000, io_virt_addr:0xf001d000
[ 0.000000] ~~~ cpu_base_init() gpio group 4, io_phy_addr:0xc001e000, io_virt_addr:0xf001e000
/* arch\arm\plat-s5p6818\common\cfg_type.h */
/*------------------------------------------------------------------------------
* GPIO function config type
*/
#define PAD_MODE_SHIFT 0
#define PAD_FUNC_SHIFT 8
#define PAD_LEVEL_SHIFT 12
#define PAD_PULLUP_SHIFT 16
#define PAD_STRENGTH_SHIFT 20
#define PAD_GET_GROUP(pad) ((pad >> 0x5) & 0x07) /* Divide 32 */
#define PAD_GET_BITNO(pad) ((pad & 0x1F) >> 0x0)
#define PAD_GET_FUNC(pad) (0xF & (pad >> PAD_FUNC_SHIFT))
#define PAD_GET_MODE(pad) (0xF & (pad >> PAD_MODE_SHIFT))
#define PAD_GET_LEVEL(pad) (0xF & (pad >> PAD_LEVEL_SHIFT))
#define PAD_GET_PULLUP(pad) (0xF & (pad >> PAD_PULLUP_SHIFT))
#define PAD_GET_STRENGTH(pad) (0xF & (pad >> PAD_STRENGTH_SHIFT))
#define PAD_GET_BUSPAD(pad) (pad & 0xFF)
/* gpio group pad start num. */
enum {
PAD_GPIO_A = (0 * 32),
PAD_GPIO_B = (1 * 32),
PAD_GPIO_C = (2 * 32),
PAD_GPIO_D = (3 * 32),
PAD_GPIO_E = (4 * 32),
PAD_GPIO_ALV = (5 * 32),
};
/* gpio mode, altfunction, gpio in/out or interrput */
enum {
PAD_MODE_ALT = (0 << PAD_MODE_SHIFT),
PAD_MODE_IN = (1 << PAD_MODE_SHIFT),
PAD_MODE_OUT = (2 << PAD_MODE_SHIFT),
PAD_MODE_INT = (3 << PAD_MODE_SHIFT),
};
/* gpio altfunction, refer to NX_GPIO_PADFUNC in nx_gpio.h */
enum {
PAD_FUNC_ALT0 = (0 << PAD_FUNC_SHIFT),
PAD_FUNC_ALT1 = (1 << PAD_FUNC_SHIFT),
PAD_FUNC_ALT2 = (2 << PAD_FUNC_SHIFT),
PAD_FUNC_ALT3 = (3 << PAD_FUNC_SHIFT),
};
/* ouput level or interrupt detect mode, refer to NX_GPIO_INTMODE in nx_gpio.h */
enum {
PAD_LEVEL_LOW = (0 << PAD_LEVEL_SHIFT), /* if alive, async lowlevel */
PAD_LEVEL_HIGH = (1 << PAD_LEVEL_SHIFT), /* if alive, async highlevel */
PAD_LEVEL_FALLINGEDGE = (2 << PAD_LEVEL_SHIFT), /* if alive, async fallingedge */
PAD_LEVEL_RISINGEDGE = (3 << PAD_LEVEL_SHIFT), /* if alive, async eisingedge */
PAD_LEVEL_LOW_SYNC = (4 << PAD_LEVEL_SHIFT), /* if gpio , not support */
PAD_LEVEL_HIGH_SYNC = (5 << PAD_LEVEL_SHIFT), /* if gpio , not support */
PAD_LEVEL_BOTHEDGE = (4 << PAD_LEVEL_SHIFT), /* if alive, not support */
PAD_LEVEL_ALT = (6 << PAD_LEVEL_SHIFT), /* if pad function is alt, not set */
};
enum {
PAD_PULL_DN = (0 << PAD_PULLUP_SHIFT), /* Do not support Alive-GPIO */
PAD_PULL_UP = (1 << PAD_PULLUP_SHIFT),
PAD_PULL_OFF = (2 << PAD_PULLUP_SHIFT),
};
enum {
PAD_STRENGTH_0 = (0 << PAD_STRENGTH_SHIFT),
PAD_STRENGTH_1 = (1 << PAD_STRENGTH_SHIFT),
PAD_STRENGTH_2 = (2 << PAD_STRENGTH_SHIFT),
PAD_STRENGTH_3 = (3 << PAD_STRENGTH_SHIFT),
};
/* alive wakeup detect mode */
enum {
PAD_WAKEUP_ASYNC_LOWLEVEL = (0),
PAD_WAKEUP_ASYNC_HIGHLEVEL = (1),
PAD_WAKEUP_FALLINGEDGE = (2),
PAD_WAKEUP_RISINGEDGE = (3),
PAD_WAKEUP_SYNC_LOWLEVEL = (4),
PAD_WAKEUP_SYNC_HIGHLEVEL = (5),
};
lable 2:
上面完成了,GPIO控制器物理地址到虛擬地址mmap的分析,如下,
SOC GPIO控制器 GPIO功能配置 操作接口實現:
/* arch\arm\mach-s5p6818\include\mach\gpio_desc.h */
/*
* (C) Copyright 2009
* jung hyun kim, Nexell Co, <jhkim@nexell.co.kr>
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __MACH_GPIO_DESC_H__
#define __MACH_GPIO_DESC_H__
enum {
ALT_NO_0 = 0,
ALT_NO_1 = 1,
ALT_NO_2 = 2,
ALT_NO_3 = 3,
};
#define ALT_NO_GPIO_A \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 \
#define ALT_NO_GPIO_B \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_2 , ALT_NO_2 , ALT_NO_1 , ALT_NO_2 , ALT_NO_1 , \
ALT_NO_2 , ALT_NO_1 , ALT_NO_2 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , \
ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 \
#define ALT_NO_GPIO_C \
ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , \
ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , \
ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , \
ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1, ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 \
#define ALT_NO_GPIO_D \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 \
#define ALT_NO_GPIO_E \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , \
ALT_NO_0 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 , ALT_NO_1 \
#define ALT_NO_ALIVE \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , \
ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 , ALT_NO_0 \
#endif
/* arch\arm\mach-s5p6818\soc\gpio.c */
/*
* (C) Copyright 2009
* jung hyun kim, Nexell Co, <jhkim@nexell.co.kr>
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <mach/platform.h>
#include <mach/gpio_desc.h>
#include <mach/gpio.h>
#if (0)
#define DBGOUT(msg...) { printk("pio: " msg); }
#else
#define DBGOUT(msg...) do {} while (0)
#endif
const unsigned char gpio_alt_no[][GPIO_NUM_PER_BANK] = {
{ ALT_NO_GPIO_A }, { ALT_NO_GPIO_B }, { ALT_NO_GPIO_C },
{ ALT_NO_GPIO_D }, { ALT_NO_GPIO_E }, { ALT_NO_ALIVE },
};
/*-----------------------------------------------------------------------------*/
#define ALIVE_INDEX NUMBER_OF_GPIO_MODULE
static spinlock_t lock[ALIVE_INDEX + 1]; /* A, B, C, D, E, alive */
static unsigned long lock_flags[ALIVE_INDEX + 1];
#define IO_LOCK_INIT(x) spin_lock_init(&lock[x])
#define IO_LOCK(x) spin_lock_irqsave(&lock[x], lock_flags[x])
#define IO_UNLOCK(x) spin_unlock_irqrestore(&lock[x], lock_flags[x])
/*------------------------------------------------------------------------------
* Description : set gpio pad function
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, bit= 0 ~ 32)
* In[mode] : gpio pad function
* : 0 = GPIO mode
* : 1 = Alternate function 1
* : 2 = Alternate function 2
* : 3 = Alternate function 3
* Return : none.
*/
void nxp_soc_gpio_set_io_func(unsigned int io, unsigned int func)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
NX_GPIO_SetPadFunction(grp, bit, func);
IO_UNLOCK(grp);
break;
case PAD_GPIO_ALV:
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return;
}
EXPORT_SYMBOL(nxp_soc_gpio_set_io_func);
/*------------------------------------------------------------------------------
* Description : set gpio alt function number
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, bit= 0 ~ 32)
* Return : gpio alt function vlaue.
*/
int nxp_soc_gpio_get_altnum(unsigned int io)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
return gpio_alt_no[grp][bit];
}
EXPORT_SYMBOL_GPL(nxp_soc_gpio_get_altnum);
/*------------------------------------------------------------------------------
* Description : get gpio pad function
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, bit= 0 ~ 32)
* Return : -1 = invalid gpio
* : 0 = GPIO mode
* : 1 = Alternate function 1
* : 2 = Alternate function 2
* : 3 = Alternate function 3
*/
unsigned int nxp_soc_gpio_get_io_func(unsigned int io)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
unsigned int fn = -1;
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
fn = NX_GPIO_GetPadFunction(grp, bit);
IO_UNLOCK(grp);
break;
case PAD_GPIO_ALV:
fn = 0;
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return fn;
}
EXPORT_SYMBOL(nxp_soc_gpio_get_io_func);
/*------------------------------------------------------------------------------
* Description : set gpio io direction
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, ALIVE:5, bit= 0 ~ 32)
* In[out] : '1' is output mode, '0' is input mode
* Return : none.
*/
void nxp_soc_gpio_set_io_dir(unsigned int io, int out)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
NX_GPIO_SetOutputEnable(grp, bit, out ? CTRUE : CFALSE);
IO_UNLOCK(grp);
break;
case PAD_GPIO_ALV:
IO_LOCK(grp);
NX_ALIVE_SetOutputEnable(bit, out ? CTRUE : CFALSE);
IO_UNLOCK(grp);
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return;
}
EXPORT_SYMBOL(nxp_soc_gpio_set_io_dir);
/*------------------------------------------------------------------------------
* Description : get gpio io direction
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, ALIVE:5, bit= 0 ~ 32)
* Return : -1 = invalid gpio.
* : 0 = gpio's input mode.
* : 1 = gpio's output mode.
*/
int nxp_soc_gpio_get_io_dir(unsigned int io)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
int dir = -1;
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
dir = NX_GPIO_GetOutputEnable(grp, bit) ? 1 : 0;
IO_UNLOCK(grp);
break;
case PAD_GPIO_ALV:
IO_LOCK(grp);
dir = NX_ALIVE_GetOutputEnable(bit) ? 1 : 0;
IO_UNLOCK(grp);
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return dir;
}
EXPORT_SYMBOL(nxp_soc_gpio_get_io_dir);
/*------------------------------------------------------------------------------
* Description : set pull enb of gpio pin
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, bit= 0 ~ 32)
* In[on] : '1' is pull enable, '0' is pull disable
* Return : none.
*/
void nxp_soc_gpio_set_io_pull_enb(unsigned int io, int on)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
NX_GPIO_SetPullEnable(grp, bit, on ? CTRUE : CFALSE);
IO_UNLOCK(grp);
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return;
}
EXPORT_SYMBOL(nxp_soc_gpio_set_io_pull_enb);
/*------------------------------------------------------------------------------
* Description : get pull enb of gpio pin
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, bit= 0 ~ 32)
* Return : -1 = invalid gpio.
* : 0 = pull disable.
* : 1 = pull enable.
*/
int nxp_soc_gpio_get_io_pull_enb(unsigned int io)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
int enb = -1;
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
enb = NX_GPIO_GetPullEnable(grp, bit) ? 1 : 0;
IO_UNLOCK(grp);
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return enb;
}
EXPORT_SYMBOL(nxp_soc_gpio_get_io_pull_enb);
/*------------------------------------------------------------------------------
* Description : set pull select of gpio pin
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, ALIVE:5, bit= 0 ~ 32)
* In[on] : '1' is pull up, '0' is pull down
* Return : none.
*/
void nxp_soc_gpio_set_io_pull_sel(unsigned int io, int up)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
NX_GPIO_SetPullEnable(grp, bit, up);
IO_UNLOCK(grp);
break;
case PAD_GPIO_ALV:
IO_LOCK(grp);
NX_ALIVE_SetPullUpEnable(bit, up ? CTRUE : CFALSE);
IO_UNLOCK(grp);
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return;
}
EXPORT_SYMBOL(nxp_soc_gpio_set_io_pull_sel);
/*------------------------------------------------------------------------------
* Description : get pull select status
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, ALIVE:5, bit= 0 ~ 32)
* Return : -1 = invalid gpio.
* : 0 = pull down.
* : 1 = pull up.
* : 2 = pull off.
*/
int nxp_soc_gpio_get_io_pull_sel(unsigned int io)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
int up = -1;
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
up = NX_GPIO_GetPullEnable(grp, bit);
IO_UNLOCK(grp);
break;
case PAD_GPIO_ALV:
IO_LOCK(grp);
up = NX_ALIVE_GetPullUpEnable(bit) ? 1 : 0;
IO_UNLOCK(grp);
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return up;
}
EXPORT_SYMBOL(nxp_soc_gpio_get_io_pull_sel);
/*------------------------------------------------------------------------------
* Description : set gpio drive strength
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, bit= 0 ~ 32)
* In[high] : '1' is high level, '0' is low level
* Return : none.
*/
void nxp_soc_gpio_set_io_drv(int gpio, int mode)
{
int grp, bit;
if (gpio > (PAD_GPIO_ALV - 1) )
return;
grp = PAD_GET_GROUP(gpio);
bit = PAD_GET_BITNO(gpio);
NX_GPIO_SetDriveStrength(grp, bit, (NX_GPIO_DRVSTRENGTH)mode); /* pad strength */
}
EXPORT_SYMBOL(nxp_soc_gpio_set_io_drv);
/*------------------------------------------------------------------------------
* Description : get gpio drive strength
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, bit= 0 ~ 32)
* In[high] : '1' is high level, '0' is low level
* Return : none.
*/
int nxp_soc_gpio_get_io_drv(int gpio)
{
int grp, bit;
if (gpio > (PAD_GPIO_ALV - 1) )
return -1;
grp = PAD_GET_GROUP(gpio);
bit = PAD_GET_BITNO(gpio);
return (int)NX_GPIO_GetDriveStrength(grp, bit); /* pad strength */
}
EXPORT_SYMBOL(nxp_soc_gpio_get_io_drv);
/*------------------------------------------------------------------------------
* Description : set gpio output level
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, ALIVE:5, bit= 0 ~ 32)
* In[high] : '1' is high level, '0' is low level
* Return : none.
*/
void nxp_soc_gpio_set_out_value(unsigned int io, int high)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
NX_GPIO_SetOutputValue(grp, bit, high ? CTRUE : CFALSE);
IO_UNLOCK(grp);
break;
case PAD_GPIO_ALV:
IO_LOCK(grp);
NX_ALIVE_SetOutputValue(bit, high ? CTRUE : CFALSE);
IO_UNLOCK(grp);
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return;
}
EXPORT_SYMBOL(nxp_soc_gpio_set_out_value);
/*------------------------------------------------------------------------------
* Description : get gpio output level
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, ALIVE:5, bit= 0 ~ 32)
* Return : -1 = invalid gpio.
* : 0 = gpio's output value is low level.
* : 1 = gpio's output value is high level.
*/
int nxp_soc_gpio_get_out_value(unsigned int io)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
int val = -1;
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
val = NX_GPIO_GetOutputValue(grp, bit) ? 1 : 0;
IO_UNLOCK(grp);
break;
case PAD_GPIO_ALV:
IO_LOCK(grp);
val = NX_ALIVE_GetOutputValue(bit) ? 1 : 0;
IO_UNLOCK(grp);
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return val;
}
EXPORT_SYMBOL(nxp_soc_gpio_get_out_value);
/*------------------------------------------------------------------------------
* Description : get gpio input value
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, ALIVE:5, bit= 0 ~ 32)
* Return : -1 = invalid gpio.
* : 0 = gpio's input value is low level , alive input is low.
* : 1 = gpio's input value is high level, alive input is high.
*/
int nxp_soc_gpio_get_in_value(unsigned int io)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
int val = -1;
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
val = NX_GPIO_GetInputValue(grp, bit) ? 1 : 0;
IO_UNLOCK(grp);
break;
case PAD_GPIO_ALV:
IO_LOCK(grp);
val = NX_ALIVE_GetInputValue(bit) ? 1 : 0;
IO_UNLOCK(grp);
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return val;
}
EXPORT_SYMBOL(nxp_soc_gpio_get_in_value);
/*------------------------------------------------------------------------------
* Description : enable gpio interrupt
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, ALIVE:5, bit= 0 ~ 32)
* In[on] : gpio interrupt enable or disable
* Return : none.
*/
void nxp_soc_gpio_set_int_enable(unsigned int io, int on)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
NX_GPIO_SetInterruptEnable(grp, bit, on ? CTRUE : CFALSE);
IO_UNLOCK(grp);
break;
case PAD_GPIO_ALV:
IO_LOCK(grp);
NX_ALIVE_SetDetectEnable(bit, on ? CTRUE : CFALSE);
NX_ALIVE_SetInterruptEnable(bit, on ? CTRUE : CFALSE);
IO_UNLOCK(grp);
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return;
}
EXPORT_SYMBOL(nxp_soc_gpio_set_int_enable);
/*------------------------------------------------------------------------------
* Description : get gpio interrupt mode
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, ALIVE:5, bit= 0 ~ 32)
* Return : -1 = invalid gpio.
* : 0 = gpio's interrupt disable.
* : 1 = gpio's interrupt enable.
*/
int nxp_soc_gpio_get_int_enable(unsigned int io)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
int enb = -1;
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
enb = NX_GPIO_GetInterruptEnable(grp, bit) ? 1 : 0;
IO_UNLOCK(grp);
break;
case PAD_GPIO_ALV:
IO_LOCK(grp);
enb = NX_ALIVE_GetInterruptEnable(bit) ? 1 : 0;
IO_UNLOCK(grp);
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return enb;
}
EXPORT_SYMBOL(nxp_soc_gpio_get_int_enable);
/*------------------------------------------------------------------------------
* Description : set gpio interrupt mode
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, ALIVE:5, bit= 0 ~ 32)
* In[mode] : gpio interrupt detect mode
* : 0 = Low level detect
* : 1 = High level detect
* : 2 = Falling edge detect
* : 3 = Rising edge detect
* : alive interrupt detect mode
* : 0 = async low level detect mode
* : 1 = async high level detect mode
* : 2 = sync falling edge detect mode
* : 3 = sync rising edge detect mode
* : 4 = sync low level detect mode
* : 5 = sync high level detect mode
* Return : none.
*/
void nxp_soc_gpio_set_int_mode(unsigned int io, unsigned int mode)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
int det = 0;
DBGOUT("%s (%d.%02d, %d)\n", __func__, grp, bit, mode);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
NX_GPIO_SetInterruptMode(grp, bit, mode);
IO_UNLOCK(grp);
break;
case PAD_GPIO_ALV:
IO_LOCK(grp);
/* all disable */
for (det = 0; 6 > det; det++)
NX_ALIVE_SetDetectMode(det, bit, CFALSE);
/* enable */
NX_ALIVE_SetDetectMode(mode, bit, CTRUE);
NX_ALIVE_SetOutputEnable(bit, CFALSE);
IO_UNLOCK(grp);
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return;
}
EXPORT_SYMBOL(nxp_soc_gpio_set_int_mode);
/*------------------------------------------------------------------------------
* Description : get gpio interrupt mode
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, bit= 0 ~ 32)
* Return : -1 = invalid gpio or Not set interrupt mode.
* : 0 = Low level detect
* : 1 = High level detect
* : 2 = Falling edge detect
* : 3 = Rising edge detect
* : alive interrupt detect mode
* : 0 = async low level detect mode
* : 1 = async high level detect mode
* : 2 = sync falling edge detect mode
* : 3 = sync rising edge detect mode
* : 4 = sync low level detect mode
* : 5 = sync high level detect mode
*/
int nxp_soc_gpio_get_int_mode(unsigned int io)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
int mod = -1;
int det = 0;
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
mod = NX_GPIO_GetInterruptMode(grp, bit);
IO_UNLOCK(grp);
break;
case PAD_GPIO_ALV:
IO_LOCK(grp);
for (det = 0; 6 > det; det++) {
if(NX_ALIVE_GetDetectMode(det, bit)) {
mod = det;
break;
}
}
IO_UNLOCK(grp);
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return mod;
}
EXPORT_SYMBOL(nxp_soc_gpio_get_int_mode);
/*------------------------------------------------------------------------------
* Description : indicates whether a specified interrupt is pended or not
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, ALIVE:5, bit= 0 ~ 32)
* Return : -1 = invalid gpio.
* : 0 = interrupt not pend.
* : 1 = interrupt pended.
*/
int nxp_soc_gpio_get_int_pend(unsigned int io)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
int pend = -1;
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
pend = NX_GPIO_GetInterruptPending(grp, bit) ? 1 : 0;
IO_UNLOCK(grp);
break;
case PAD_GPIO_ALV:
IO_LOCK(grp);
pend = NX_ALIVE_GetInterruptPending(bit) ? 1 : 0;
IO_UNLOCK(grp);
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return pend;
}
EXPORT_SYMBOL(nxp_soc_gpio_get_int_pend);
/*------------------------------------------------------------------------------
* Description : clear pending state of gpio interrupts
* In[io] : gpio pad number, 32*n + bit
* : (n= GPIO_A:0, GPIO_B:1, GPIO_C:2, GPIO_D:3, GPIO_E:4, ALIVE:5, bit= 0 ~ 32)
* Return : none.
*/
void nxp_soc_gpio_clr_int_pend(unsigned int io)
{
unsigned int grp = PAD_GET_GROUP(io);
unsigned int bit = PAD_GET_BITNO(io);
DBGOUT("%s (%d.%02d)\n", __func__, grp, bit);
switch (io & ~(32-1)) {
case PAD_GPIO_A:
case PAD_GPIO_B:
case PAD_GPIO_C:
case PAD_GPIO_D:
case PAD_GPIO_E:
IO_LOCK(grp);
NX_GPIO_ClearInterruptPending(grp, bit);
NX_GPIO_GetInterruptPending(grp, bit);
IO_UNLOCK(grp);
break;
case PAD_GPIO_ALV:
IO_LOCK(grp);
NX_ALIVE_ClearInterruptPending(bit);
NX_ALIVE_GetInterruptPending(bit);
IO_UNLOCK(grp);
break;
default:
printk("fail, soc gpio io:%d, group:%d (%s)\n", io, grp, __func__);
break;
};
return;
}
EXPORT_SYMBOL(nxp_soc_gpio_clr_int_pend);
/*------------------------------------------------------------------------------
* Description : enable alive detect mode
* In[io] : alive pad number, 0~7
* In[on] : alive detect mode interrupt enable or disable
* Return : none.
*/
void nxp_soc_alive_set_det_enable(unsigned int io, int on)
{
unsigned int bit = PAD_GET_BITNO(io);
DBGOUT("%s (%d)\n", __func__, bit);
IO_LOCK(ALIVE_INDEX);
NX_ALIVE_SetOutputEnable(bit, CFALSE);
NX_ALIVE_SetDetectEnable(bit, on ? CTRUE : CFALSE);
IO_UNLOCK(ALIVE_INDEX);
return;
}
EXPORT_SYMBOL_GPL(nxp_soc_alive_set_det_enable);
/*------------------------------------------------------------------------------
* Description : get alive detect mode type
* In[io] : alive pad number, 0~7
* Return : 0 = no detect mode.
* : 1 = detect mode.
*/
int nxp_soc_alive_get_det_enable(unsigned int io)
{
unsigned int bit = PAD_GET_BITNO(io);
int mod = 0;
DBGOUT("%s (%d)\n", __func__, bit);
IO_LOCK(ALIVE_INDEX);
mod = NX_ALIVE_GetDetectEnable(bit) ? 1 : 0;
IO_UNLOCK(ALIVE_INDEX);
return mod;
}
EXPORT_SYMBOL_GPL(nxp_soc_alive_get_det_enable);
/*------------------------------------------------------------------------------
* Description : set alive pad detection mode
* In[io] : alive pad number, 0~7
* In[mode] : alive detection mode
* : 0 = async low level detect mode
* : 1 = async high level detect mode
* : 2 = sync falling edge detect mode
* : 3 = sync rising edge detect mode
* : 4 = sync low level detect mode
* : 5 = sync high level detect mode
* In[on] : alive detection mode enable or disable
* Return : none.
*/
void nxp_soc_alive_set_det_mode(unsigned int io, unsigned int mode, int on)
{
unsigned int bit = PAD_GET_BITNO(io);
DBGOUT("%s (%d)\n", __func__, bit);
IO_LOCK(ALIVE_INDEX);
NX_ALIVE_SetDetectMode(mode, bit, on ? CTRUE : CFALSE);
IO_UNLOCK(ALIVE_INDEX);
return;
}
EXPORT_SYMBOL_GPL(nxp_soc_alive_set_det_mode);
/*------------------------------------------------------------------------------
* Description : get alive pad detection mode
* In[io] : alive pad number, 0~7
* Return : 0 = detect mode is disabled.
* : 1 = detect mode is enabled.
*/
int nxp_soc_alive_get_det_mode(unsigned int io, unsigned int mode)
{
unsigned int bit = PAD_GET_BITNO(io);
int mod = 0;
DBGOUT("%s (%d)\n", __func__, bit);
IO_LOCK(ALIVE_INDEX);
mod = NX_ALIVE_GetDetectMode(mode, bit) ? 1 : 0;
IO_UNLOCK(ALIVE_INDEX);
return mod;
}
EXPORT_SYMBOL_GPL(nxp_soc_alive_get_det_mode);
/*------------------------------------------------------------------------------
* Description : get alive pad interrupt pend bit staus
* In[io] : alive pad number, 0~7
* Return : 0 = interrupt not pend.
* : 1 = interrupt pended.
*/
int nxp_soc_alive_get_int_pend(unsigned int io)
{
unsigned int bit = PAD_GET_BITNO(io);
int pend = -1;
DBGOUT("%s (%d)\n", __func__, bit);
IO_LOCK(ALIVE_INDEX);
pend = NX_ALIVE_GetInterruptPending(bit);
IO_UNLOCK(ALIVE_INDEX);
return pend;
}
EXPORT_SYMBOL_GPL(nxp_soc_alive_get_int_pend);
/*------------------------------------------------------------------------------
* Description : clear alive pad interrupt pend bit
* In[io] : alive pad number, 0~7
* Return : none.
*/
void nxp_soc_alive_clr_int_pend(unsigned int io)
{
unsigned int bit = PAD_GET_BITNO(io);
DBGOUT("%s (%d)\n", __func__, bit);
IO_LOCK(ALIVE_INDEX);
NX_ALIVE_ClearInterruptPending(bit);
IO_UNLOCK(ALIVE_INDEX);
return;
}
EXPORT_SYMBOL_GPL(nxp_soc_alive_clr_int_pend);
/*-----------------------------------------------------------------------------*/
static int __init nxp_soc_gpio_device_init(void)
{
int n = ALIVE_INDEX + 1;
int i = 0;
for (; n > i; i++)
IO_LOCK_INIT(i);
return 0;
}
core_initcall(nxp_soc_gpio_device_init);
lable 3:
SOC GPIO 控制器 register 操作接口實現:
/* arch\arm\mach-s5p6818\prototype\module\nx_gpio.h */
//------------------------------------------------------------------------------
//
// Copyright (C) 2009 Nexell Co., All Rights Reserved
// Nexell Co. Proprietary & Confidential
//
// NEXELL INFORMS THAT THIS CODE AND INFORMATION IS PROVIDED "AS IS" BASE
// AND WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS
// FOR A PARTICULAR PURPOSE.
//
// Module : GPIO
// File : nx_gpio.h
// Description:
// Author : Firmware Team
// History :
//
//------------------------------------------------------------------------------
#ifndef __NX_GPIO_H__
#define __NX_GPIO_H__
#include "../base/nx_prototype.h"
#ifdef __cplusplus
extern "C"
{
#endif
//------------------------------------------------------------------------------
/// @defgroup GPIO GPIO
//------------------------------------------------------------------------------
//@{
/// @brief GPIO Module's Register List
struct NX_GPIO_RegisterSet
{
volatile U32 GPIOxOUT; ///< 0x00 : Output Register
volatile U32 GPIOxOUTENB; ///< 0x04 : Output Enable Register
volatile U32 GPIOxDETMODE[2]; ///< 0x08 : Event Detect Mode Register
volatile U32 GPIOxINTENB; ///< 0x10 : Interrupt Enable Register
volatile U32 GPIOxDET; ///< 0x14 : Event Detect Register
volatile U32 GPIOxPAD; ///< 0x18 : PAD Status Register
volatile U32 GPIOxPUENB; ///< 0x1C : Pull Up Enable Register
volatile U32 GPIOxALTFN[2]; ///< 0x20 : Alternate Function Select Register
volatile U32 GPIOxDETMODEEX; ///< 0x28 : Event Detect Mode extended Register
volatile U32 __Reserved[4]; ///< 0x2B :
volatile U32 GPIOxDETENB; ///< 0x3C : IntPend Detect Enable Register
volatile U32 GPIOx_SLEW; ///< 0x40 : Slew Register
volatile U32 GPIOx_SLEW_DISABLE_DEFAULT; ///< 0x44 : Slew set On/Off Register
volatile U32 GPIOx_DRV1; ///< 0x48 : drive strength LSB Register
volatile U32 GPIOx_DRV1_DISABLE_DEFAULT; ///< 0x4C : drive strength LSB set On/Off Register
volatile U32 GPIOx_DRV0; ///< 0x50 : drive strength MSB Register
volatile U32 GPIOx_DRV0_DISABLE_DEFAULT; ///< 0x54 : drive strength MSB set On/Off Register
volatile U32 GPIOx_PULLSEL; ///< 0x58 : Pull UP/DOWN Selection Register
volatile U32 GPIOx_PULLSEL_DISABLE_DEFAULT; ///< 0x5C : Pull UP/DOWN Selection On/Off Register
volatile U32 GPIOx_PULLENB; ///< 0x60 : Pull Enable/Disable Register
volatile U32 GPIOx_PULLENB_DISABLE_DEFAULT; ///< 0x64 : Pull Enable/Disable selection On/Off Register
volatile U32 GPIOx_InputMuxSelect0; ///< 0x68
volatile U32 GPIOx_InputMuxSelect1; ///< 0x6C
U8 __Reserved1[0x1000-0x70];
};
///@brief GPIO Interrupts for interrupt interface
enum
{
NX_GPIO_INT_GPIO0 = 0, ///< GPIO 0 Interrupt
NX_GPIO_INT_GPIO1 = 1, ///< GPIO 1 Interrupt
NX_GPIO_INT_GPIO2 = 2, ///< GPIO 2 Interrupt
NX_GPIO_INT_GPIO3 = 3, ///< GPIO 3 Interrupt
NX_GPIO_INT_GPIO4 = 4, ///< GPIO 4 Interrupt
NX_GPIO_INT_GPIO5 = 5, ///< GPIO 5 Interrupt
NX_GPIO_INT_GPIO6 = 6, ///< GPIO 6 Interrupt
NX_GPIO_INT_GPIO7 = 7, ///< GPIO 7 Interrupt
NX_GPIO_INT_GPIO8 = 8, ///< GPIO 8 Interrupt
NX_GPIO_INT_GPIO9 = 9, ///< GPIO 9 Interrupt
NX_GPIO_INT_GPIO10 = 10, ///< GPIO 10 Interrupt
NX_GPIO_INT_GPIO11 = 11, ///< GPIO 11 Interrupt
NX_GPIO_INT_GPIO12 = 12, ///< GPIO 12 Interrupt
NX_GPIO_INT_GPIO13 = 13, ///< GPIO 13 Interrupt
NX_GPIO_INT_GPIO14 = 14, ///< GPIO 14 Interrupt
NX_GPIO_INT_GPIO15 = 15, ///< GPIO 15 Interrupt
NX_GPIO_INT_GPIO16 = 16, ///< GPIO 16 Interrupt
NX_GPIO_INT_GPIO17 = 17, ///< GPIO 17 Interrupt
NX_GPIO_INT_GPIO18 = 18, ///< GPIO 18 Interrupt
NX_GPIO_INT_GPIO19 = 19, ///< GPIO 19 Interrupt
NX_GPIO_INT_GPIO20 = 20, ///< GPIO 20 Interrupt
NX_GPIO_INT_GPIO21 = 21, ///< GPIO 21 Interrupt
NX_GPIO_INT_GPIO22 = 22, ///< GPIO 22 Interrupt
NX_GPIO_INT_GPIO23 = 23, ///< GPIO 23 Interrupt
NX_GPIO_INT_GPIO24 = 24, ///< GPIO 24 Interrupt
NX_GPIO_INT_GPIO25 = 25, ///< GPIO 25 Interrupt
NX_GPIO_INT_GPIO26 = 26, ///< GPIO 26 Interrupt
NX_GPIO_INT_GPIO27 = 27, ///< GPIO 27 Interrupt
NX_GPIO_INT_GPIO28 = 28, ///< GPIO 28 Interrupt
NX_GPIO_INT_GPIO29 = 29, ///< GPIO 29 Interrupt
NX_GPIO_INT_GPIO30 = 30, ///< GPIO 30 Interrupt
NX_GPIO_INT_GPIO31 = 31 ///< GPIO 31 Interrupt
};
/// @brief GPIO interrupt mode
typedef enum
{
NX_GPIO_INTMODE_LOWLEVEL = 0UL, ///< Low level detect
NX_GPIO_INTMODE_HIGHLEVEL = 1UL, ///< High level detect
NX_GPIO_INTMODE_FALLINGEDGE = 2UL, ///< Falling edge detect
NX_GPIO_INTMODE_RISINGEDGE = 3UL, ///< Rising edge detect
NX_GPIO_INTMODE_BOTHEDGE = 4UL ///< both (rise and falling) edge detect
}NX_GPIO_INTMODE;
/// @brief I/O mode
typedef enum
{
NX_GPIO_PADFUNC_0 = 0UL, ///< Alternate function 0
NX_GPIO_PADFUNC_1 = 1UL, ///< Alternate function 1
NX_GPIO_PADFUNC_2 = 2UL, ///< Alternate function 2
NX_GPIO_PADFUNC_3 = 3UL ///< Alternate function 3
} NX_GPIO_PADFUNC ;
typedef enum
{
NX_GPIO_DRVSTRENGTH_0 = 0UL,
NX_GPIO_DRVSTRENGTH_1 = 1UL,
NX_GPIO_DRVSTRENGTH_2 = 2UL,
NX_GPIO_DRVSTRENGTH_3 = 3UL
}NX_GPIO_DRVSTRENGTH;
typedef enum
{
NX_GPIO_PULL_DOWN = 0UL,
NX_GPIO_PULL_UP = 1UL,
NX_GPIO_PULL_OFF = 2UL
} NX_GPIO_PULL;
//------------------------------------------------------------------------------
/// @name Module Interface
//@{
CBOOL NX_GPIO_Initialize( void );
U32 NX_GPIO_GetNumberOfModule( void );
//@}
//------------------------------------------------------------------------------
/// @name Basic Interface
//@{
U32 NX_GPIO_GetPhysicalAddress( U32 ModuleIndex );
U32 NX_GPIO_GetSizeOfRegisterSet( void );
void NX_GPIO_SetBaseAddress( U32 ModuleIndex, void* BaseAddress );
void* NX_GPIO_GetBaseAddress( U32 ModuleIndex );
CBOOL NX_GPIO_OpenModule( U32 ModuleIndex );
CBOOL NX_GPIO_CloseModule( U32 ModuleIndex );
CBOOL NX_GPIO_CheckBusy( U32 ModuleIndex );
//@}
//------------------------------------------------------------------------------
/// @name Interrupt Interface
//@{
U32 NX_GPIO_GetInterruptNumber( U32 ModuleIndex );
void NX_GPIO_SetInterruptEnable( U32 ModuleIndex, S32 IntNum, CBOOL Enable );
CBOOL NX_GPIO_GetInterruptEnable( U32 ModuleIndex, S32 IntNum );
CBOOL NX_GPIO_GetInterruptPending( U32 ModuleIndex, S32 IntNum );
void NX_GPIO_ClearInterruptPending( U32 ModuleIndex, S32 IntNum );
void NX_GPIO_SetInterruptEnableAll( U32 ModuleIndex, CBOOL Enable );
CBOOL NX_GPIO_GetInterruptEnableAll( U32 ModuleIndex );
CBOOL NX_GPIO_GetInterruptPendingAll( U32 ModuleIndex );
void NX_GPIO_ClearInterruptPendingAll( U32 ModuleIndex );
void NX_GPIO_SetInterruptEnable32( U32 ModuleIndex, U32 EnableFlag );
U32 NX_GPIO_GetInterruptEnable32( U32 ModuleIndex );
U32 NX_GPIO_GetInterruptPending32( U32 ModuleIndex );
void NX_GPIO_ClearInterruptPending32( U32 ModuleIndex, U32 PendingFlag );
S32 NX_GPIO_GetInterruptPendingNumber( U32 ModuleIndex ); // -1 if None
//@}
//------------------------------------------------------------------------------
/// @name GPIO Operation.
//@{
void NX_GPIO_SetInterruptMode( U32 ModuleIndex, U32 BitNumber, NX_GPIO_INTMODE IntMode );
NX_GPIO_INTMODE NX_GPIO_GetInterruptMode( U32 ModuleIndex, U32 BitNumber );
void NX_GPIO_SetDetectEnable ( U32 ModuleIndex, U32 BitNumber, CBOOL DetectEnb );
CBOOL NX_GPIO_GetDetectEnable ( U32 ModuleIndex, U32 BitNumber );
void NX_GPIO_SetDetectEnable32 ( U32 ModuleIndex, U32 EnableFlag );
U32 NX_GPIO_GetDetectEnable32 ( U32 ModuleIndex );
void NX_GPIO_SetOutputEnable ( U32 ModuleIndex, U32 BitNumber, CBOOL OutputEnb );
CBOOL NX_GPIO_GetOutputEnable ( U32 ModuleIndex, U32 BitNumber );
void NX_GPIO_SetOutputEnable32 ( U32 ModuleIndex, CBOOL OutputEnb );
U32 NX_GPIO_GetOutputEnable32 ( U32 ModuleIndex );
void NX_GPIO_SetOutputValue ( U32 ModuleIndex, U32 BitNumber, CBOOL Value );
CBOOL NX_GPIO_GetOutputValue ( U32 ModuleIndex, U32 BitNumber );
void NX_GPIO_SetOutputValue32 ( U32 ModuleIndex, U32 Value );
U32 NX_GPIO_GetOutputValue32 ( U32 ModuleIndex );
CBOOL NX_GPIO_GetInputValue ( U32 ModuleIndex, U32 BitNumber );
void NX_GPIO_SetPadFunction( U32 ModuleIndex, U32 BitNumber, NX_GPIO_PADFUNC padfunc );
void NX_GPIO_SetPadFunction32( U32 ModuleIndex, U32 MSBValue, U32 LSBValue );
NX_GPIO_PADFUNC NX_GPIO_GetPadFunction( U32 ModuleIndex, U32 BitNumber );
//------------------------------------------------------------------------------
/// @name GPIO Operation.
//@{
void NX_GPIO_SetSlew ( U32 ModuleIndex, U32 BitNumber, CBOOL Enable );
CBOOL NX_GPIO_GetSlew ( U32 ModuleIndex, U32 BitNumber );
void NX_GPIO_SetSlewDisableDefault ( U32 ModuleIndex, U32 BitNumber, CBOOL Enable );
void NX_GPIO_SetSlew32 ( U32 ModuleIndex, U32 Value );
U32 NX_GPIO_GetSlew32 ( U32 ModuleIndex );
void NX_GPIO_SetDriveStrength(U32 ModuleIndex, U32 BitNumber, NX_GPIO_DRVSTRENGTH drvstrength);
NX_GPIO_DRVSTRENGTH NX_GPIO_GetDriveStrength(U32 ModuleIndex, U32 BitNumber);
void NX_GPIO_SetDriveStrengthDisableDefault ( U32 ModuleIndex, U32 BitNumber, CBOOL Enable );
void NX_GPIO_SetPullSelect ( U32 ModuleIndex, U32 BitNumber, CBOOL enable);
CBOOL NX_GPIO_GetPullSelect ( U32 ModuleIndex, U32 BitNumber );
void NX_GPIO_SetPullEnable ( U32 ModuleIndex, U32 BitNumber, NX_GPIO_PULL PullSel );
NX_GPIO_PULL NX_GPIO_GetPullEnable ( U32 ModuleIndex, U32 BitNumber );
void NX_GPIO_SetPullEnable32 ( U32 ModuleIndex, U32 PullEnb, U32 PullSel );
void NX_GPIO_GetPullEnable32 ( U32 ModuleIndex, U32* PullEnb, U32* PullSel );
U32 NX_GPIO_GetValidBit( U32 ModuleIndex );
void NX_GPIO_SetPadFunctionEnable ( U32 padInfo );
//@}
//@}
#ifdef __cplusplus
}
#endif
#endif //__NX_GPIO_H__
//------------------------------------------------------------------------------
//
// Copyright (C) Nexell Co. 2012
//
// This confidential and proprietary software may be used only as authorized by a
// licensing agreement from Nexell Co.
// The entire notice above must be reproduced on all authorized copies and copies
// may only be made to the extent permitted by a licensing agreement from Nexell Co.
//
// Module : GPIO
// File : nx_gpio.h
// Description :
// Author : Firmware Team
// History :
//------------------------------------------------------------------------------
#include "nx_gpio.h"
U32 __g_NX_GPIO_VALID_BIT[NUMBER_OF_GPIO_MODULE] =
{
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF // A, B, C, D, E
};
static const U32 __g_GPIO_PAD_INFO[32][NUMBER_OF_GPIO_MODULE] =
{
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_0_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_1_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_2_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_3_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_4_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_5_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_6_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_7_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_8_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_9_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_10_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_11_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_12_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_13_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_14_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_15_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_16_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_17_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_18_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_19_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_20_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_21_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_22_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_23_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_24_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_25_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_26_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_27_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_28_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_29_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_30_) },
{ PADINDEX_WITH_CHANNEL_LIST_ALPHA(GPIO, GPIO_31_) }
};
static struct
{
struct NX_GPIO_RegisterSet *pRegister;
} __g_ModuleVariables[NUMBER_OF_GPIO_MODULE] = { {CNULL,}, };
enum { NX_GPIO_MAX_BIT = 32 };
//------------------------------------------------------------------------------
// inline Function
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/**
* @brief Set 1bit value
* @param[in] Value This Value is changed when SetBit() executed.
* @param[in] Bit Bit number
* @param[in] Enable CTRUE( Set ).\n
* CFALSE( Clear )
* @return None.
* @see NX_GPIO_GetBit
*/
__inline void NX_GPIO_SetBit
(
volatile U32* Value,
U32 Bit,
CBOOL Enable
)
{
register U32 newvalue;
NX_ASSERT( CNULL != Value );
NX_ASSERT( NX_GPIO_MAX_BIT > Bit );
newvalue = *Value;
newvalue &= ~(1UL << Bit );
newvalue |= (U32)Enable << Bit ;
WriteIO32(Value, newvalue);
}
//------------------------------------------------------------------------------
/**
* @brief Get bit value
* @param[in] Value Check this value of 1bit state
* @param[in] Bit Bit number
* @return CTRUE indicate that bit is Seted.\n
* CFALSE indicate that bit is cleared.
* @see NX_GPIO_SetBit
*/
__inline CBOOL NX_GPIO_GetBit
(
U32 Value,
U32 Bit
)
{
NX_ASSERT( NX_GPIO_MAX_BIT > Bit );
return (CBOOL)(( Value >> Bit ) & ( 1UL ) );
}
//------------------------------------------------------------------------------
/**
* @brief Set 2bit value
* @param[in] Value This Value is changed when SetBit2() executed.
* @param[in] Bit Bit number
* @param[in] BitValue Set value of bit
* @return None.
* @see NX_GPIO_GetBit2
*/
__inline void NX_GPIO_SetBit2
(
volatile U32* Value,
U32 Bit,
U32 BitValue
)
{
register U32 newvalue = *Value;
NX_ASSERT( CNULL != Value );
NX_ASSERT( NX_GPIO_MAX_BIT > Bit );
newvalue = (U32)(newvalue & ~(3UL<<(Bit*2)));
newvalue = (U32)(newvalue | (BitValue<<(Bit*2)));
WriteIO32(Value, newvalue);
}
//------------------------------------------------------------------------------
/**
* @brief Get 2bit value
* @param[in] Value Check this value of 2bit state
* @param[in] Bit Bit number
* @return 2bit value
* @see NX_GPIO_SetBit2
*/
__inline U32 NX_GPIO_GetBit2
(
U32 Value,
U32 Bit
)
{
NX_ASSERT( NX_GPIO_MAX_BIT > Bit );
return (U32)((U32)(Value>>(Bit*2)) & 3UL);
}
//------------------------------------------------------------------------------
// Module Interface
//------------------------------------------------------------------------------
/**
* @brief Initialize of prototype enviroment & local variables.
* @return CTRUE indicate that Initialize is successed.\n
* CFALSE indicate that Initialize is failed.\n
*/
CBOOL NX_GPIO_Initialize( void )
{
static CBOOL bInit = CFALSE;
U32 i;
if( CFALSE == bInit )
{
for( i=0; i < NUMBER_OF_GPIO_MODULE; i++ )
{
__g_ModuleVariables[i].pRegister = CNULL;
}
bInit = CTRUE;
}
for( i = 0 ; i < NUMBER_OF_GPIO_MODULE; i++) {
__g_NX_GPIO_VALID_BIT[i] = 0xFFFFFFFF;
// __g_NX_GPIO_VALID_NUM_OF_INT[i] = 32;
// __g_NX_GPIO_VALID_INT_MASK[i] = 0xFFFFFFFF;
};
return CTRUE;
}
//------------------------------------------------------------------------------
/**
* @brief Get number of modules in the chip.
* @return Module's number.
*/
U32 NX_GPIO_GetNumberOfModule( void )
{
return NUMBER_OF_GPIO_MODULE;
}
//------------------------------------------------------------------------------
// Basic Interface
//------------------------------------------------------------------------------
/**
* @brief Get module's physical address.
* @param[in] ModuleIndex A index of module.
* @return Module's physical address
*/
U32 NX_GPIO_GetPhysicalAddress( U32 ModuleIndex )
{
static const U32 PhysicalAddr[] = { PHY_BASEADDR_LIST_ALPHA( GPIO ) }; // PHY_BASEADDR_GPIO?_MODULE
NX_CASSERT( NUMBER_OF_GPIO_MODULE == (sizeof(PhysicalAddr)/sizeof(PhysicalAddr[0])) );
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
return (U32)PhysicalAddr[ModuleIndex];
}
//------------------------------------------------------------------------------
/**
* @brief Get a size, in byte, of register set.
* @return Size of module's register set.
*/
U32 NX_GPIO_GetSizeOfRegisterSet( void )
{
return sizeof( struct NX_GPIO_RegisterSet );
}
//------------------------------------------------------------------------------
/**
* @brief Set a base address of register set.
* @param[in] ModuleIndex A index of module.
* @param[in] BaseAddress Module's base address
* @return None.
*/
void NX_GPIO_SetBaseAddress( U32 ModuleIndex, void* BaseAddress )
{
NX_ASSERT( CNULL != BaseAddress );
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
__g_ModuleVariables[ModuleIndex].pRegister = (struct NX_GPIO_RegisterSet *)BaseAddress;
}
//------------------------------------------------------------------------------
/**
* @brief Get a base address of register set
* @param[in] ModuleIndex A index of module.
* @return Module's base address.
*/
void* NX_GPIO_GetBaseAddress( U32 ModuleIndex )
{
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
return (void*)__g_ModuleVariables[ModuleIndex].pRegister;
}
//------------------------------------------------------------------------------
/**
* @brief Initialize selected modules with default value.
* @param[in] ModuleIndex A index of module.
* @return CTRUE indicate that Initialize is successed. \n
* CFALSE indicate that Initialize is failed.
*/
CBOOL NX_GPIO_OpenModule( U32 ModuleIndex )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
WriteIO32(&pRegister->GPIOx_SLEW_DISABLE_DEFAULT, 0xFFFFFFFF );
WriteIO32(&pRegister->GPIOx_DRV1_DISABLE_DEFAULT, 0xFFFFFFFF );
WriteIO32(&pRegister->GPIOx_DRV0_DISABLE_DEFAULT, 0xFFFFFFFF );
WriteIO32(&pRegister->GPIOx_PULLSEL_DISABLE_DEFAULT, 0xFFFFFFFF );
WriteIO32(&pRegister->GPIOx_PULLENB_DISABLE_DEFAULT, 0xFFFFFFFF );
return CTRUE;
}
//------------------------------------------------------------------------------
/**
* @brief Deinitialize selected module to the proper stage.
* @param[in] ModuleIndex A index of module.
* @return CTRUE indicate that Deinitialize is successed. \n
* CFALSE indicate that Deinitialize is failed.
*/
CBOOL NX_GPIO_CloseModule( U32 ModuleIndex )
{
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
return CTRUE;
}
//------------------------------------------------------------------------------
/**
* @brief Indicates whether the selected modules is busy or not.
* @param[in] ModuleIndex A index of module.
* @return CTRUE indicate that Module is Busy. \n
* CFALSE indicate that Module is NOT Busy.
*/
CBOOL NX_GPIO_CheckBusy( U32 ModuleIndex )
{
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
return CFALSE;
}
//------------------------------------------------------------------------------
// Interrupt Interface
//------------------------------------------------------------------------------
/**
* @brief Get a interrupt number for interrupt controller.
* @return Interrupt number
*/
U32 NX_GPIO_GetInterruptNumber( U32 ModuleIndex )
{
const U32 INTNumber[NUMBER_OF_GPIO_MODULE] =
{
INTNUM_LIST_ALPHA(GPIO)
};
NX_CASSERT( NUMBER_OF_GPIO_MODULE == (sizeof(INTNumber)/sizeof(INTNumber[0])) );
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
return INTNumber[ModuleIndex];
}
//------------------------------------------------------------------------------
/**
* @brief Set a specified interrupt to be enable or disable.
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] IntNum Interrupt Number. ( 0 ~ 31 ), if ModuleIndex is GPIOC then IntNum is only 0 ~ 20.
* @param[in] Enable CTRUE indicate that Interrupt Enable. \n
* CFALSE indicate that Interrupt Disable.
* @return None.
*/
void NX_GPIO_SetInterruptEnable( U32 ModuleIndex, S32 IntNum, CBOOL Enable )
{
register struct NX_GPIO_RegisterSet *pRegister;
register U32 ReadValue ;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( (CFALSE==Enable) || (CTRUE==Enable) );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
ReadValue = ReadIO32(&pRegister->GPIOxINTENB);
ReadValue &= ~( (U32)1 << IntNum);
ReadValue |= ( (U32)Enable << IntNum );
WriteIO32(&pRegister->GPIOxINTENB, ReadValue);
NX_GPIO_SetDetectEnable(ModuleIndex, IntNum, Enable);
}
//------------------------------------------------------------------------------
/**
* @brief Indicates whether a specified interrupt is enabled or disabled.
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] IntNum Interrupt Number.
* @return CTRUE indicate that Interrupt is enabled. \n
* CFALSE indicate that Interrupt is disabled.
*/
CBOOL NX_GPIO_GetInterruptEnable( U32 ModuleIndex, S32 IntNum )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( NX_GPIO_MAX_BIT > (U32)IntNum );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
if( ReadIO32(&pRegister->GPIOxINTENB) & (1UL << IntNum ) )
{
return CTRUE;
}
return CFALSE;
}
//------------------------------------------------------------------------------
/**
* @brief Set a specified interrupt to be enable or disable.
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] EnableFlag Specify interrupt bit for enable of disable. Each bit's meaning is like below \n
* - EnableFlag[0] : Set GPIO0 interrupt enable or disable. \n
* ...
* - EnableFlag[31] : Set GPIO31 interrupt enable or disable. \n
* @return None.
*/
void NX_GPIO_SetInterruptEnable32( U32 ModuleIndex, U32 EnableFlag )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
WriteIO32(&pRegister->GPIOxINTENB, EnableFlag );
NX_GPIO_SetDetectEnable32(ModuleIndex, EnableFlag);
}
//------------------------------------------------------------------------------
/**
* @brief Indicates current setting value of interrupt enable bit.
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @return Current setting value of interrupt. \n
* "1" means interrupt is enabled. \n
* "0" means interrupt is disabled. \n
* - Return Value[0] : GPIO0 interrupt's setting value. \n
* ...
* - Return Value[31] : GPIO31 interrupt's setting value. \n
*/
U32 NX_GPIO_GetInterruptEnable32( U32 ModuleIndex )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
return (U32)ReadIO32(&pRegister->GPIOxINTENB );
}
//------------------------------------------------------------------------------
/**
* @brief Indicates whether a specified interrupt is pended or not
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] IntNum Interrupt Number.
* @return CTRUE indicate that Pending is seted. \n
* CFALSE indicate that Pending is Not Seted.
*/
CBOOL NX_GPIO_GetInterruptPending( U32 ModuleIndex, S32 IntNum )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( NX_GPIO_MAX_BIT > (U32)IntNum );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
if( ReadIO32(&pRegister->GPIOxDET) & (1UL << IntNum ) )
{
return CTRUE;
}
return CFALSE;
}
//------------------------------------------------------------------------------
/**
* @brief Indicates current setting value of interrupt pending bit.
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @return Current setting value of pending bit. \n
* "1" means pend bit is occured. \n
* "0" means pend bit is NOT occured. \n
* - Return Value[0] : GPIO0 pending state. \n
* ...
* - Return Value[31] : GPIO31 pending state. \n
*/
U32 NX_GPIO_GetInterruptPending32( U32 ModuleIndex )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
return(U32)ReadIO32(&pRegister->GPIOxDET);
}
//------------------------------------------------------------------------------
/**
* @brief Clear a pending state of specified interrupt.
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] IntNum Interrupt number.
* @return None.
*/
void NX_GPIO_ClearInterruptPending( U32 ModuleIndex, S32 IntNum )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( NX_GPIO_MAX_BIT > (U32)IntNum );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
WriteIO32(&pRegister->GPIOxDET, 1UL << IntNum);
}
//------------------------------------------------------------------------------
/**
* @brief Clear a pending state of specified interrupt.
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] PendingFlag Specify pend bit to clear. Each bit's meaning is like below \n \n
* - PendingFlag[0] : GPIO0 pending bit. \n
* ...
* - PendingFlag[31] : GPIO31 pending bit. \n
* @return None.
*/
void NX_GPIO_ClearInterruptPending32( U32 ModuleIndex, U32 PendingFlag )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
WriteIO32(&pRegister->GPIOxDET, PendingFlag);
}
//------------------------------------------------------------------------------
/**
* @brief Set all interrupts to be enables or disables.
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] Enable CTRUE indicate that Set to all interrupt enable. \n
* CFALSE indicate that Set to all interrupt disable.
* @return None.
*/
void NX_GPIO_SetInterruptEnableAll( U32 ModuleIndex, CBOOL Enable )
{
register struct NX_GPIO_RegisterSet *pRegister;
register U32 setvalue;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( (CFALSE==Enable) || (CTRUE==Enable) );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
if( Enable )
{ setvalue = 0xFFFFFFFF; }
else
{ setvalue = 0x0; }
WriteIO32(&pRegister->GPIOxINTENB, setvalue);
NX_GPIO_SetInterruptEnable32(ModuleIndex, setvalue);
}
//------------------------------------------------------------------------------
/**
* @brief Indicates whether some of interrupts are enable or not.
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @return CTRUE indicate that At least one( or more ) interrupt is enabled. \n
* CFALSE indicate that All interrupt is disabled.
*/
CBOOL NX_GPIO_GetInterruptEnableAll( U32 ModuleIndex )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
if( ReadIO32(&pRegister->GPIOxINTENB) )
{
return CTRUE;
}
return CFALSE;
}
//------------------------------------------------------------------------------
/**
* @brief Indicates whether some of interrupts are pended or not.
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @return CTRUE indicate that At least one( or more ) pending is seted. \n
* CFALSE indicate that All pending is NOT seted.
*/
CBOOL NX_GPIO_GetInterruptPendingAll( U32 ModuleIndex )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
if( ReadIO32(&pRegister->GPIOxDET) )
{
return CTRUE;
}
return CFALSE;
}
//------------------------------------------------------------------------------
/**
* @brief Clear pending state of all interrupts.
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @return None.
*/
void NX_GPIO_ClearInterruptPendingAll( U32 ModuleIndex )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
WriteIO32(&pRegister->GPIOxDET, (U32)(0xFFFFFFFF));
}
//------------------------------------------------------------------------------
/**
* @brief Get a interrupt number which has the most prority of pended interrupts
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @return Pending Number( If all pending is not set then return -1 ).
*/
S32 NX_GPIO_GetInterruptPendingNumber( U32 ModuleIndex ) // -1 if None
{
register struct NX_GPIO_RegisterSet *pRegister;
register U32 intnum;
register U32 intpend;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
intpend = ReadIO32(&pRegister->GPIOxDET);
for( intnum=0 ; intnum<32 ; intnum++ )
{
if( 0 != (intpend & (1UL<<intnum)) )
{
return intnum;
}
}
return -1;
}
//------------------------------------------------------------------------------
// GPIO Operation.
//------------------------------------------------------------------------------
/**
* @brief Set interrupt mode
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @param[in] IntMode GPIO interrupt detect mode
* @return None.
*/
void NX_GPIO_SetInterruptMode( U32 ModuleIndex, U32 BitNumber, NX_GPIO_INTMODE IntMode )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( 0 != (__g_NX_GPIO_VALID_BIT[ModuleIndex] & (1 << BitNumber)) );
NX_ASSERT( NX_GPIO_INTMODE_BOTHEDGE >= IntMode );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
NX_GPIO_SetBit2( &pRegister->GPIOxDETMODE[BitNumber/16], BitNumber%16, (U32)IntMode & 0x03 );
NX_GPIO_SetBit( &pRegister->GPIOxDETMODEEX, BitNumber, (U32)(IntMode>>2) );
}
//------------------------------------------------------------------------------
/**
* @brief Get interrupt mode
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @return GPIO interrupt detect mode
*/
NX_GPIO_INTMODE NX_GPIO_GetInterruptMode( U32 ModuleIndex, U32 BitNumber )
{
register struct NX_GPIO_RegisterSet *pRegister;
U32 regvalue;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( 0 != (__g_NX_GPIO_VALID_BIT[ModuleIndex] & (1 << BitNumber)) );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
regvalue = NX_GPIO_GetBit2( ReadIO32(&pRegister->GPIOxDETMODE[BitNumber/16]), BitNumber%16 );
regvalue |= (NX_GPIO_GetBit( ReadIO32(&pRegister->GPIOxDETMODEEX), BitNumber)<<2);
return (NX_GPIO_INTMODE)regvalue;
}
//------------------------------------------------------------------------------
/**
* @brief Get gpio output enable
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @param[in] OutputEnb CTRUE indicate that Output Mode. \n
* CFALSE indicate that Input Mode.
* @return None.
*/
void NX_GPIO_SetOutputEnable ( U32 ModuleIndex, U32 BitNumber, CBOOL OutputEnb )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( 0 != (__g_NX_GPIO_VALID_BIT[ModuleIndex] & (1 << BitNumber)) );
NX_ASSERT( (CFALSE==OutputEnb) || (CTRUE==OutputEnb) );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
NX_GPIO_SetBit( &pRegister->GPIOxOUTENB, BitNumber, OutputEnb );
}
//------------------------------------------------------------------------------
/**
* @brief Get gpio Event Detect
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @param[in] OutputEnb CTRUE indicate that Event Detect Enabled. \n
* CFALSE indicate that Event Detect Disabled.
* @return None.
*/
CBOOL NX_GPIO_GetDetectEnable ( U32 ModuleIndex, U32 BitNumber )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( 0 != (__g_NX_GPIO_VALID_BIT[ModuleIndex] & (1 << BitNumber)) );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
return NX_GPIO_GetBit( ReadIO32(&pRegister->GPIOxDETENB), BitNumber );
}
U32 NX_GPIO_GetDetectEnable32 ( U32 ModuleIndex )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
return ReadIO32(&pRegister->GPIOxDETENB);
}
//------------------------------------------------------------------------------
/**
* @brief Set Event Detect Enable
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @return GPIO interrupt detect mode
*/
void NX_GPIO_SetDetectEnable ( U32 ModuleIndex, U32 BitNumber, CBOOL DetectEnb )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( 0 != (__g_NX_GPIO_VALID_BIT[ModuleIndex] & (1 << BitNumber)) );
NX_ASSERT( (CFALSE==DetectEnb) || (CTRUE==DetectEnb) );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
NX_GPIO_SetBit( &pRegister->GPIOxDETENB, BitNumber, DetectEnb );
}
void NX_GPIO_SetDetectEnable32 ( U32 ModuleIndex, U32 EnableFlag )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
WriteIO32(&pRegister->GPIOxDETENB, EnableFlag );
}
//------------------------------------------------------------------------------
/**
* @brief Get gpio output enable
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @return CTRUE indicate that GPIO's current Setting is Output Mode.\n
* CFALSE indicate that GPIO's current Setting is Input Mode.
*/
CBOOL NX_GPIO_GetOutputEnable ( U32 ModuleIndex, U32 BitNumber )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( 0 != (__g_NX_GPIO_VALID_BIT[ModuleIndex] & (1 << BitNumber)) );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
return NX_GPIO_GetBit( ReadIO32(&pRegister->GPIOxOUTENB), BitNumber );
}
//------------------------------------------------------------------------------
/**
* @brief Get gpio output enable
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @param[in] OutputEnb CTRUE indicate that Output Mode. \n
* CFALSE indicate that Input Mode.
* @return None.
*/
void NX_GPIO_SetOutputEnable32 ( U32 ModuleIndex, CBOOL OutputEnb )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( (CFALSE==OutputEnb) || (CTRUE==OutputEnb) );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
if(OutputEnb)
WriteIO32(&pRegister->GPIOxOUTENB, 0xFFFFFFFF );
else
WriteIO32(&pRegister->GPIOxOUTENB, 0x0 );
}
//------------------------------------------------------------------------------
/**
* @brief Get gpio output enable
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @return CTRUE indicate that GPIO's current Setting is Output Mode.\n
* CFALSE indicate that GPIO's current Setting is Input Mode.
*/
U32 NX_GPIO_GetOutputEnable32 ( U32 ModuleIndex )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
return ReadIO32(&pRegister->GPIOxOUTENB);
}
//------------------------------------------------------------------------------
/**
* @brief Set gpio output value
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @param[in] Value CTRUE indicate that High Level. \n
* CFALSE indicate that Low Level.
* @return None.
*/
void NX_GPIO_SetOutputValue ( U32 ModuleIndex, U32 BitNumber, CBOOL Value )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( 0 != (__g_NX_GPIO_VALID_BIT[ModuleIndex] & (1 << BitNumber)) );
NX_ASSERT( (CFALSE==Value) || (CTRUE==Value) );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
NX_GPIO_SetBit( &pRegister->GPIOxOUT, BitNumber, Value );
}
//------------------------------------------------------------------------------
/**
* @brief Get gpio output value
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @return CTRUE indicate that GPIO's output value is High Level.\n
* CFALSE indicate that GPIO's output value is Low Level.
*/
CBOOL NX_GPIO_GetOutputValue ( U32 ModuleIndex, U32 BitNumber )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( 0 != (__g_NX_GPIO_VALID_BIT[ModuleIndex] & (1 << BitNumber)) );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
return NX_GPIO_GetBit( ReadIO32(&pRegister->GPIOxOUT), BitNumber );
}
//------------------------------------------------------------------------------
/**
* @brief Set gpio output value
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @param[in] Value CTRUE indicate that High Level. \n
* CFALSE indicate that Low Level.
* @return None.
*/
void NX_GPIO_SetOutputValue32 ( U32 ModuleIndex, U32 Value )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
WriteIO32(&pRegister->GPIOxOUT, Value );
}
//------------------------------------------------------------------------------
/**
* @brief Get gpio output value
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @return CTRUE indicate that GPIO's output value is High Level.
* CFALSE indicate that GPIO's output value is Low Level.
*/
U32 NX_GPIO_GetOutputValue32 ( U32 ModuleIndex )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
return ReadIO32(&pRegister->GPIOxOUT);
}
//------------------------------------------------------------------------------
/**
* @brief Get gpio input value
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @return CTRUE indicate that GPIO's input value is High Level.
* CFALSE indicate that GPIO's input value is Low Level.
*/
CBOOL NX_GPIO_GetInputValue ( U32 ModuleIndex, U32 BitNumber )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( 0 != (__g_NX_GPIO_VALID_BIT[ModuleIndex] & (1 << BitNumber)) );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
return NX_GPIO_GetBit( ReadIO32(&pRegister->GPIOxPAD), BitNumber );
}
//------------------------------------------------------------------------------
/**
* @brief Set Pull sel of GPIO Pin
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC )
* @param[in] BitNumber Bit number ( 0 ~ 31 ), if ModuleIndex is GPIOC then Bit number is only 0 ~ 20.
* @param[in] enable CTRUE indicate that Pull Up.
* CFALSE indicate that NOT Pull Up.
* @return None.
*/
void NX_GPIO_SetPullSelect ( U32 ModuleIndex, U32 BitNumber, CBOOL enable)
{
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( (0==enable) || (1==enable) );
NX_ASSERT( CNULL != __g_ModuleVariables[ModuleIndex].pRegister );
NX_GPIO_SetBit( &__g_ModuleVariables[ModuleIndex].pRegister->GPIOx_PULLSEL_DISABLE_DEFAULT, BitNumber, CTRUE );
// NX_GPIO_SetBit( &__g_ModuleVariables[ModuleIndex].pRegister->GPIOx_PULLSEL_DISABLE_DEFAULT, BitNumber, enable );
NX_GPIO_SetBit( &__g_ModuleVariables[ModuleIndex].pRegister->GPIOx_PULLSEL, BitNumber, enable );
}
void NX_GPIO_SetPullSelect32 ( U32 ModuleIndex, U32 Value )
{
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( CNULL != __g_ModuleVariables[ModuleIndex].pRegister );
WriteIO32(&__g_ModuleVariables[ModuleIndex].pRegister->GPIOx_PULLSEL, Value );
}
//------------------------------------------------------------------------------
/**
* @brief Get pull sel value of GPIO Pin
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC )
* @param[in] BitNumber Bit number ( 0 ~ 31 ), if ModuleIndex is GPIOC then Bit number is only 0 ~ 20.
* @return GPIO pull up value
*/
CBOOL NX_GPIO_GetPullSelect ( U32 ModuleIndex, U32 BitNumber )
{
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( CNULL != __g_ModuleVariables[ModuleIndex].pRegister );
return NX_GPIO_GetBit( __g_ModuleVariables[ModuleIndex].pRegister->GPIOx_PULLSEL, BitNumber );
}
U32 NX_GPIO_GetPullSelect32 ( U32 ModuleIndex )
{
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( CNULL != __g_ModuleVariables[ModuleIndex].pRegister );
return __g_ModuleVariables[ModuleIndex].pRegister->GPIOx_PULLSEL;
}
void NX_GPIO_SetPullMode ( U32 ModuleIndex, U32 BitNumber, NX_GPIO_PULL mode)
{
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( (0==mode) || (1==mode) || (2==mode) );
NX_ASSERT( CNULL != __g_ModuleVariables[ModuleIndex].pRegister );
NX_GPIO_SetBit( &__g_ModuleVariables[ModuleIndex].pRegister->GPIOx_PULLSEL_DISABLE_DEFAULT, BitNumber, CTRUE );
NX_GPIO_SetBit( &__g_ModuleVariables[ModuleIndex].pRegister->GPIOx_PULLENB_DISABLE_DEFAULT, BitNumber, CTRUE );
if (mode == NX_GPIO_PULL_OFF)
{
//NX_GPIO_SetBit( &__g_ModuleVariables[ModuleIndex].pRegister->GPIOx_PULLENB_DISABLE_DEFAULT, BitNumber, CFALSE );
NX_GPIO_SetBit( &__g_ModuleVariables[ModuleIndex].pRegister->GPIOx_PULLENB, BitNumber, CFALSE );
NX_GPIO_SetBit( &__g_ModuleVariables[ModuleIndex].pRegister->GPIOx_PULLSEL, BitNumber, CFALSE );
}
else
{
//NX_GPIO_SetBit( &__g_ModuleVariables[ModuleIndex].pRegister->GPIOx_PULLENB_DISABLE_DEFAULT, BitNumber, CTRUE );
NX_GPIO_SetBit( &__g_ModuleVariables[ModuleIndex].pRegister->GPIOx_PULLSEL, BitNumber, (mode & 1 ? CTRUE : CFALSE) );
NX_GPIO_SetBit( &__g_ModuleVariables[ModuleIndex].pRegister->GPIOx_PULLENB, BitNumber, CTRUE );
}
}
//--------------------------------------------------------------------------
// Pin Configuration
//--------------------------------------------------------------------------
/**
* @brief Set PAD Fuction
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @param[in] padfunc Pad Function
* @return None
* @remarks Each gpio pins can use to GPIO Pin or Alternate Function 0 or Alternate Function 1 or \n
* Alternate Function 2. So This function Sets gpio pin's function.
*/
void NX_GPIO_SetPadFunction( U32 ModuleIndex, U32 BitNumber, NX_GPIO_PADFUNC padfunc )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( 0 != (__g_NX_GPIO_VALID_BIT[ModuleIndex] & (1 << BitNumber)) );
NX_ASSERT( NX_GPIO_PADFUNC_3 >= padfunc );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
NX_GPIO_SetBit2( &pRegister->GPIOxALTFN[BitNumber/16], BitNumber%16, (U32)padfunc );
}
void NX_GPIO_SetPadFunction32( U32 ModuleIndex, U32 MSBValue, U32 LSBValue )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
WriteIO32(&pRegister->GPIOxALTFN[0], LSBValue );
WriteIO32(&pRegister->GPIOxALTFN[1], MSBValue );
}
//------------------------------------------------------------------------------
/**
* @brief Get PAD Fuction
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @return None
*/
NX_GPIO_PADFUNC NX_GPIO_GetPadFunction( U32 ModuleIndex, U32 BitNumber )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( 0 != (__g_NX_GPIO_VALID_BIT[ModuleIndex] & (1 << BitNumber)) );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
return (NX_GPIO_PADFUNC)NX_GPIO_GetBit2( ReadIO32(&pRegister->GPIOxALTFN[BitNumber/16]), BitNumber%16 );
}
//------------------------------------------------------------------------------
/**
* @brief Get GPIO's valid bit
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @return GPIO's valid bit
* @remarks Each bit's indicate corresponding GPIO pin. If retun value is 0x0FF, then
* This indicate that GPIO have eight pins ( GPIO0 ~ GPIO7 ).
*/
U32 NX_GPIO_GetValidBit( U32 ModuleIndex )
{
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
return __g_NX_GPIO_VALID_BIT[ModuleIndex];
}
//------------------------------------------------------------------------------
/**
* @brief Set GPIO Slew
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @param[in] Enable Slew On/Off
* @return None
*/
void NX_GPIO_SetSlew ( U32 ModuleIndex, U32 BitNumber, CBOOL Enable )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
NX_GPIO_SetBit(&pRegister->GPIOx_SLEW, BitNumber, Enable);
}
void NX_GPIO_SetSlewDisableDefault ( U32 ModuleIndex, U32 BitNumber, CBOOL Enable )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
NX_GPIO_SetBit(&pRegister->GPIOx_SLEW_DISABLE_DEFAULT, BitNumber, Enable);
}
//------------------------------------------------------------------------------
/**
* @brief Get GPIO Slew
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @return CTRUE indicate that GPIO's slew is turned on.
* CFALSE indicate that GPIO's slew is turned off.
*/
CBOOL NX_GPIO_GetSlew ( U32 ModuleIndex, U32 BitNumber )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
return (CBOOL)NX_GPIO_GetBit(ReadIO32(&pRegister->GPIOx_SLEW), BitNumber);
}
//------------------------------------------------------------------------------
/**
* @brief Set GPIO Slew
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] Value 32bit input data
* @return None
*/
void NX_GPIO_SetSlew32 ( U32 ModuleIndex, U32 Value )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
WriteIO32(&pRegister->GPIOx_SLEW, Value );
}
//------------------------------------------------------------------------------
/**
* @brief Get GPIO Slew
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @return GPIO slew value
*/
U32 NX_GPIO_GetSlew32 ( U32 ModuleIndex )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
return ReadIO32(&pRegister->GPIOx_SLEW);
}
//------------------------------------------------------------------------------
/**
* @brief Set GPIO Drive Strength
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @param[in] DriveStrength
* @return None
*/
void NX_GPIO_SetDriveStrength ( U32 ModuleIndex, U32 BitNumber, NX_GPIO_DRVSTRENGTH drvstrength)
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
NX_GPIO_SetBit(&pRegister->GPIOx_DRV1, BitNumber, (CBOOL)(((U32)drvstrength>>0) & 0x1));
NX_GPIO_SetBit(&pRegister->GPIOx_DRV0, BitNumber, (CBOOL)(((U32)drvstrength>>1) & 0x1));
}
void NX_GPIO_SetDriveStrengthDisableDefault ( U32 ModuleIndex, U32 BitNumber, CBOOL Enable )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
NX_GPIO_SetBit(&pRegister->GPIOx_DRV1_DISABLE_DEFAULT, BitNumber, (CBOOL)(Enable) );
NX_GPIO_SetBit(&pRegister->GPIOx_DRV0_DISABLE_DEFAULT, BitNumber, (CBOOL)(Enable) );
}
//------------------------------------------------------------------------------
/**
* @brief Get GPIO Drive Strength
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @return GPIO GPIO Drive Strength
*/
NX_GPIO_DRVSTRENGTH NX_GPIO_GetDriveStrength ( U32 ModuleIndex, U32 BitNumber )
{
register struct NX_GPIO_RegisterSet *pRegister;
register U32 retvalue;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
retvalue = NX_GPIO_GetBit(ReadIO32(&pRegister->GPIOx_DRV0), BitNumber)<<1;
retvalue |= NX_GPIO_GetBit(ReadIO32(&pRegister->GPIOx_DRV1), BitNumber)<<0;
return (NX_GPIO_DRVSTRENGTH)retvalue;
}
//------------------------------------------------------------------------------
/**
* @brief Set GPIO PullEnb
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @param[in] PullEnb CTRUE: pull enable, CFALSE: pull disable
* @parma[in] updown 0 : Pull Down 1: Pull Up 2: PullEnb - Disable
* @return None
*/
void NX_GPIO_SetPullEnable ( U32 ModuleIndex, U32 BitNumber, NX_GPIO_PULL PullSel )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
if( PullSel == NX_GPIO_PULL_DOWN || PullSel == NX_GPIO_PULL_UP )
{
NX_GPIO_SetBit(&pRegister->GPIOx_PULLSEL, BitNumber, (CBOOL)PullSel);
NX_GPIO_SetBit(&pRegister->GPIOx_PULLENB, BitNumber, CTRUE );
}
else
NX_GPIO_SetBit(&pRegister->GPIOx_PULLENB, BitNumber, CFALSE);
}
//------------------------------------------------------------------------------
/**
* @brief Get GPIO PullEnb
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] BitNumber Bit number ( 0 ~ 31 )
* @return GPIO PullUp Enable -> return PullSel
* GPIO PullUp Disble -> return PullEnb
*/
NX_GPIO_PULL NX_GPIO_GetPullEnable ( U32 ModuleIndex, U32 BitNumber )
{
register struct NX_GPIO_RegisterSet *pRegister;
register CBOOL bEnb;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
bEnb = NX_GPIO_GetBit(ReadIO32(&pRegister->GPIOx_PULLENB),BitNumber);
NX_ASSERT( CNULL != pRegister );
if( bEnb == CTRUE )
return (NX_GPIO_PULL)NX_GPIO_GetBit(ReadIO32(&pRegister->GPIOx_PULLSEL), BitNumber);
else
return (NX_GPIO_PULL)(NX_GPIO_PULL_OFF);
}
//------------------------------------------------------------------------------
/**
* @brief Set GPIO PullEnb
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] Value 32bit input data
* @param[in] Value Pull Up/Down ( 0 : Pull Down, 1 : Pull Down )
* @return None
*/
void NX_GPIO_SetPullEnable32 ( U32 ModuleIndex, U32 PullEnb, U32 PullSel )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
WriteIO32(&pRegister->GPIOx_PULLSEL, PullSel );
WriteIO32(&pRegister->GPIOx_PULLENB, PullEnb );
}
//------------------------------------------------------------------------------
/**
* @brief Get GPIO PullEnb
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] PullEnb Pull Enable 32bit Status
* @param[in] PullSel Pull Select 32bit Status
* @return None
*/
void NX_GPIO_GetPullEnable32 ( U32 ModuleIndex, U32* PullEnb, U32* PullSel )
{
register struct NX_GPIO_RegisterSet *pRegister;
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
pRegister = __g_ModuleVariables[ModuleIndex].pRegister;
NX_ASSERT( CNULL != pRegister );
*PullEnb = ReadIO32(&pRegister->GPIOx_PULLENB);
*PullSel = ReadIO32(&pRegister->GPIOx_PULLSEL);
}
//------------------------------------------------------------------------------
/**
* @brief Set Input Mux Select0
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] Value 32bit input data
* @return None
*/
void NX_GPIO_SetInputMuxSelect0 ( U32 ModuleIndex, U32 Value )
{
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( CNULL != __g_ModuleVariables[ModuleIndex].pRegister );
WriteIO32(&__g_ModuleVariables[ModuleIndex].pRegister->GPIOx_InputMuxSelect0, Value );
}
//------------------------------------------------------------------------------
/**
* @brief Set Input Mux Select1
* @param[in] ModuleIndex A index of module. (0:GPIOA, 1:GPIOB, 2:GPIOC, 3:GPIOD, 4:GPIOE )
* @param[in] Value 32bit input data
* @return None
*/
void NX_GPIO_SetInputMuxSelect1 ( U32 ModuleIndex, U32 Value )
{
NX_ASSERT( NUMBER_OF_GPIO_MODULE > ModuleIndex );
NX_ASSERT( CNULL != __g_ModuleVariables[ModuleIndex].pRegister );
WriteIO32(&__g_ModuleVariables[ModuleIndex].pRegister->GPIOx_InputMuxSelect1, Value );
}
//---------------------------------------------------------
/*
pad info
http://nxconfluence.co.kr:8090/pages/editpage.action?pageId=2786185
*/
//---------------------------------------------------------
/*
static CBOOL NX_GPIO_PadInfo_GetGpioUsed( U32 padinfo )
{
return NX_BIT_GETBIT_RANGE32 ( padinfo, 16, 16 );
}
*/
static U32 NX_GPIO_PadInfo_GetModuleIndex( U32 padinfo )
{
return NX_BIT_GETBIT_RANGE32 ( padinfo, 15, 8 );
}
static U32 NX_GPIO_PadInfo_GetBitNumber( U32 padinfo )
{
return NX_BIT_GETBIT_RANGE32 ( padinfo, 7, 3 );
}
static NX_GPIO_PADFUNC NX_GPIO_PadInfo_GetPadFunction( U32 padinfo )
{
return (NX_GPIO_PADFUNC)NX_BIT_GETBIT_RANGE32 ( padinfo, 2, 0 );
}
void NX_GPIO_SetPadFunctionEnable ( U32 padinfo )
{
U32 moduleIndex = NX_GPIO_PadInfo_GetModuleIndex( padinfo );
U32 bitNumber = NX_GPIO_PadInfo_GetBitNumber( padinfo );
NX_GPIO_PADFUNC padFunction = NX_GPIO_PadInfo_GetPadFunction( padinfo );
NX_GPIO_SetPadFunction ( moduleIndex, bitNumber, padFunction );
}
Author: Yangkai Wang
wang_yangkai@163.com
Coding in 2021/05/06
轉載請注明出處。