又做了一下改动,添加了class方面节点和功能
https://blog.csdn.net/longmin96/article/details/131304207http://SSD202D-GPIO调试驱动-一
其中难点在于读GPIO的模式是需要函数读取寄存器
static U16 HalPadGetMode(U32 u32PadID, U32 u32Mode)
{
U32 u32RegAddr = 0;
U16 u16RegVal = 0;
U16 i = 0,j=0;
for (i = 0; i < g_u32Padmux_cnt; i++)
{
if (u32PadID == m_stPadMuxTbl[i].padID)
{
j++;
u32RegAddr = _RIUA_16BIT(m_stPadMuxTbl[i].base, m_stPadMuxTbl[i].offset);
u16RegVal = _GPIO_R_WORD_MASK(u32RegAddr, m_stPadMuxTbl[i].mask);
if(u16RegVal!=0)
{
return j;
}
}
}
return 0;
}
涉及了一个数组的译码配置
还有通过模式转换成译码表函数
static U32 MDrv_GPIO_Mode_Set(U32 u32PadID, U32 u32Mode)//拿到一个模式码
{
//u32Mode需要又范围校准
U32 data;
U16 i = 0;
U16 pinMODE=(U32)u32Mode-1;//u32Mode的0留给GPIO了,所以要-1
u16 nummax=0;
......
printk("MDrv_GPIO_Mode_Set:pinMODE= %d.nummax=%d\n",pinMODE,nummax);
if(pinMODE>nummax){
data=PINMUX_FOR_GPIO_MODE;
}
else{
for (i = 0; i < g_u32Padmux_cnt; i++)
{
if (u32PadID == m_stPadMuxTbl[i].padID)
{
data=m_stPadMuxTbl[i+pinMODE].mode;
printk("MDrv_GPIO_Mode_Set:u32PadID= %d.pinMODE=%d.data=%d\n", u32PadID,u32Mode,data);
break;
}
}
}
return data;
}
改进代码如下
//gpio_lonbon.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/version.h>
#include <linux/pagemap.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/slab.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/proc_fs.h>
#include <linux/sysfs.h>
#include <linux/export.h>
#include "gpio.h"
#include "gpio_lonbon.h"
#define GPIO_LB_NAME "gpio-lb"
static DEFINE_MUTEX(gpio_lb_mutex);
struct gpio_lb_debugfs_data *dbg = NULL;
static struct class *gpio_lb_class = NULL;
static struct proc_dir_entry* proc_class=NULL;
static struct device *gpio_lb_class_device_pin8 = NULL;
static struct device *gpio_lb_class_device_pin9 = NULL;
static struct device *gpio_lb_class_device_help = NULL;
static long gpio_lb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
// void __user *argp = (void __user *)arg;
int err = 0;
int ret = 0;
int io = cmd%1000%128;
int mode =cmd/1000;
cmd=cmd%1000/128;
mutex_lock(&gpio_lb_mutex);
switch(cmd) {
case MDRV_GPIO_PAD_SET:
printk("MDRV_GPIO_PAD_SET:cmd= %d.io=%d\n", cmd,io);
MDrv_GPIO_Pad_Set(io);
break;
case MDRV_GPIO_SET_LOW:
printk("MDRV_GPIO_SET_LOW:cmd= %d.io=%d\n", cmd,io);
MDrv_GPIO_Set_Low(io);
break;
case MDRV_GPIO_SET_HIGH:
printk("MDRV_GPIO_SET_HIGH:cmd= %d.io=%d\n", cmd,io);
MDrv_GPIO_Set_High(io);
break;
case MDRV_GPIO_PADVAL_SET:
printk("MDRV_GPIO_PADVAL_SET:cmd= %d.io=%d\n", cmd,io);
if(mode==0){
MDrv_GPIO_Pad_Set(io);
printk("gpio_mode=GPIO!\n");
}else{
ret=MDrv_GPIO_PadVal_Set(io, MDrv_GPIO_Mode_Set(io,mode));
printk("gpio_mode=%d!ret=%d.\n",mode,ret);
}
break;
default:
printk("default= %d.\n", 0);
err = -EINVAL;
break;
}
mutex_unlock(&gpio_lb_mutex);
return 0;
}
static int gpio_lb_open(struct inode *inode, struct file *file)
{
return nonseekable_open(inode, file);
//return 0;
}
static int gpio_lb_close(struct inode *inode, struct file *file)
{
return 0;
}
static ssize_t gpio_lb_dbg_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
int ret = 0;
U8 ret1,ret2;
char buf[24];
ssize_t len = 0;
if (dbg && (dbg->command != 0)) {
switch (dbg->command) {
case LBK_GET_KERNEL_VERSION:
len = snprintf(buf, sizeof(buf), "%s\n", LB_KERNEL_VERSION);
break;
default:
ret = -EINVAL;
break;
}
dbg->command = 0;
}
printk("Usage: [h help] [a io-set-gpio] [b io-set-low] [d io-set-high] [d io-set-uart2]\n"
"[e io-set-gpio] [f io-set-low] [g io-set-high] [i io-set-mode]\n"
"\th: show this help\n\ta: MDRV_GPIO_PAD_SET-UART2\n\tb: MDRV_GPIO_SET_LOW-UART2\n"
"\tc: MDRV_GPIO_SET_HIGH-UART2\n\td: MDRV_GPIO_PADVAL_SET-UART2\n\te: MDRV_GPIO_PAD_SET to 'echo e001 >' \n\tf: MDrv_GPIO_Set_Low to 'echo f001 >'\n\tg: MDrv_GPIO_Set_High to 'echo g001 >'\n\ti: MDrv_GPIO_PadVal_Set to 'echo ixx001 >' xx=gpiomode.uart2=3,i3008/i3009; \n\n");
ret1=HalPadGetMode(UART_RX,PINMUX_FOR_GPIO_MODE);
ret2=HalPadGetMode(UART_TX,PINMUX_FOR_GPIO_MODE);
printk("GPIO_PIN8=");
switch(ret1){
case 0 :printk("GPIO_MODE\n"); break;
case 1 :printk("SPI0_MODE\n"); break;
case 2 :printk("UART0_MODE\n"); break;
case 3 :printk("UART2_MODE\n"); break;
case 4 :printk("SDIO_MODE\n"); break;
default:break;
}
printk("GPIO_PIN9=");
switch(ret2){
case 0 :printk("GPIO_MODE\n"); break;
case 1 :printk("SPI0_MODE\n"); break;
case 2 :printk("UART0_MODE\n"); break;
case 3 :printk("UART2_MODE\n"); break;
case 4 :printk("SDIO_MODE\n"); break;
default:break;
}
return ret ? ret : simple_read_from_buffer(userbuf, count, ppos, buf, len);
}
static ssize_t gpio_lb_dbg_write(struct file *file,
const char __user *ubuf, size_t count, loff_t *ppos)
{
char *pb;
char buf[24];
int ret = 0;
unsigned int val;
unsigned int val1,val2;
memset(buf, 0 , sizeof buf);
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
return -EFAULT;
mutex_lock(&gpio_lb_mutex);
if (count > 1) {
pb = buf + 1;
switch (buf[0]) {
case 'h':
printk("Usage: [hkusplrfc] [t timeout] [j jiffies] [m msec]\n"
"\th: show this help\n\ta: MDRV_GPIO_PAD_SET-UART2\n\tb: MDRV_GPIO_SET_LOW-UART2\n"
"\tc: MDRV_GPIO_SET_HIGH-UART2\n\td: MDRV_GPIO_PADVAL_SET-UART2\n\te: MDRV_GPIO_PAD_SET to 'echo e001 >' \n\tf: MDrv_GPIO_Set_Low to 'echo f001 >'\n\tg: MDrv_GPIO_Set_High to 'echo gxx001 >'\n\ti: MDrv_GPIO_PadVal_Set to 'echo ixx001 >' xx=gpiomode.uart2=3,i3008/i3009; \n\n");
break;
case 'k':
if (dbg) dbg->command = LBK_GET_KERNEL_VERSION;
printk("kernel version: %s\n", LB_KERNEL_VERSION);
break;
case 'a':
printk("MDRV_GPIO_PAD_SET:cmd= %d.io=%d\n", MDRV_GPIO_PAD_SET,UART_RX);
MDrv_GPIO_Pad_Set(UART_TX);
printk("MDRV_GPIO_PAD_SET:cmd= %d.io=%d\n", MDRV_GPIO_PAD_SET,UART_TX);
MDrv_GPIO_Pad_Set(UART_TX);
break;
case 'b':
printk("MDRV_GPIO_SET_LOW:cmd= %d.io=%d\n", MDRV_GPIO_SET_LOW,UART_RX);
MDrv_GPIO_Set_Low(UART_TX);
printk("MDRV_GPIO_SET_LOW:cmd= %d.io=%d\n", MDRV_GPIO_SET_LOW,UART_TX);
MDrv_GPIO_Set_Low(UART_TX);
break;
case 'c':
printk("MDRV_GPIO_SET_HIGH:cmd= %d.io=%d\n", MDRV_GPIO_SET_HIGH,UART_RX);
MDrv_GPIO_Set_High(UART_RX);
printk("MDRV_GPIO_SET_HIGH:cmd= %d.io=%d\n", MDRV_GPIO_SET_HIGH,UART_TX);
MDrv_GPIO_Set_High(UART_TX);
break;
case 'd':
ret=MDrv_GPIO_PadVal_Set(UART_RX, PINMUX_FOR_UART2_MODE_2);
printk("MDRV_GPIO_PADVAL_SET:cmd= %d.io=%d.ret=%d\n", MDRV_GPIO_PADVAL_SET,UART_RX,ret);
ret=MDrv_GPIO_PadVal_Set(UART_TX, PINMUX_FOR_UART2_MODE_2);
printk("MDRV_GPIO_PADVAL_SET:cmd= %d.io=%d.ret=%d\n", MDRV_GPIO_PADVAL_SET,UART_TX,ret);
break;
case 'e':
val = (u32)simple_strtol(pb, NULL, 10);
printk("MDRV_GPIO_PAD_SET:io=%d\n",val);
MDrv_GPIO_Pad_Set(val);
break;
case 'f':
val = (u32)simple_strtol(pb, NULL, 10);
printk("MDRV_GPIO_SET_LOW:io=%d\n",val);
MDrv_GPIO_Set_Low(val);
break;
case 'g':
val = (u32)simple_strtol(pb, NULL, 10);
printk("MDRV_GPIO_SET_HIGH:io=%d\n",val);
MDrv_GPIO_Set_High(val);
break;
case 'i':
val = (u32)simple_strtol(pb, NULL, 10);
val1=val%1000;
val2=val/1000;
printk("MDRV_GPIO_PADVAL_SET:val2=%d.val1=%d\n",val2,val1);
if(val2==0){
MDrv_GPIO_Pad_Set(val1);
printk("gpio_mode=GPIO!\n");
}else{
MDrv_GPIO_PadVal_Set(val1, MDrv_GPIO_Mode_Set(val1,val2));
if(val2==3)
printk("gpio_mode=UART2!\n");
else printk("gpio_mode=%d!\n",val2);
}
// ret=MDrv_GPIO_PadVal_Set(val1,val2);
printk("MDRV_GPIO_PADVAL_SET:io=%d.ret=%d\n",val,ret);
break;
default:
pr_err("%s: Invalid command!\n", __func__);
ret = -EINVAL;
break;
}
}
mutex_unlock(&gpio_lb_mutex);
return ret ? ret : count;
}
static const struct file_operations gpio_lb_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = gpio_lb_ioctl,
.compat_ioctl = gpio_lb_ioctl,
.open = gpio_lb_open,
.release = gpio_lb_close,
.write = gpio_lb_dbg_write,
.read = gpio_lb_dbg_read,
};
static struct miscdevice gpio_lb_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = GPIO_LB_NAME,
.fops = &gpio_lb_fops,
};
static int gpio_lb_debugfs_init(void)
{
int ret = 0;
dbg = kzalloc(sizeof(struct gpio_lb_debugfs_data), GFP_KERNEL);
if (!dbg) {
pr_err("Alloc debugfs data memory failed!\n");
return -ENOMEM;
}
dbg->dir = debugfs_create_dir(GPIO_LB_NAME, NULL); // the dir name is same with this file.
if (IS_ERR(dbg->dir)) {
ret = PTR_ERR(dbg->dir);
pr_err("failed to create debugfs dir! error: %d.\n", ret);
return ret;
} else {
dbg->dbg = debugfs_create_file("debug", S_IRUGO | S_IWUSR, dbg->dir, NULL, &gpio_lb_fops);
if (!dbg->dbg) {
ret = -ENOMEM;
goto err0;
}
}
return 0;
err0:
debugfs_remove_recursive(dbg->dir);
kfree(dbg);
dbg = NULL;
return ret;
}
static void gpio_lb_debugfs_exit(void)
{
if (dbg) {
if (dbg->dir)
debugfs_remove_recursive(dbg->dir);
kfree(dbg);
dbg = NULL;
}
}
static void gpio_lb_class_init(void)
{
//add class
gpio_lb_class = class_create(THIS_MODULE,GPIO_LB_NAME);
if (!gpio_lb_class){
printk("failed register class device : %s.\n", GPIO_LB_NAME);
}
gpio_lb_class_device_pin8=device_create(gpio_lb_class,NULL,MKDEV(MAJOR_GPIO_NUM, 8),NULL,"pin8");
if(NULL == gpio_lb_class_device_pin8){
printk("failed gpio_lb_dev device_create error : pin8.\r\n");
}
gpio_lb_class_device_pin9=device_create(gpio_lb_class,NULL,MKDEV(MAJOR_GPIO_NUM, 9),NULL,"pin9");
if(NULL == gpio_lb_class_device_pin9){
printk("failed gpio_lb_dev device_create error : pin9.\r\n");
}
gpio_lb_class_device_help=device_create(gpio_lb_class,NULL,MKDEV(MAJOR_GPIO_NUM, 255),NULL,"help");
if(NULL == gpio_lb_class_device_help){
printk("failed gpio_lb_dev device_create error : help.\r\n");
}
device_create_file(gpio_lb_class_device_pin8, &dev_attr_gpio8_mode);
device_create_file(gpio_lb_class_device_pin8, &dev_attr_gpio8_set);
device_create_file(gpio_lb_class_device_pin9, &dev_attr_gpio9_mode);
device_create_file(gpio_lb_class_device_pin9, &dev_attr_gpio9_set);
device_create_file(gpio_lb_class_device_help, &dev_attr_help);
//end class
}
static void gpio_lb_class_exit(void)
{
device_remove_file(gpio_lb_class_device_pin8, &dev_attr_gpio8_mode);
device_remove_file(gpio_lb_class_device_pin8, &dev_attr_gpio8_set);
device_remove_file(gpio_lb_class_device_pin9, &dev_attr_gpio9_mode);
device_remove_file(gpio_lb_class_device_pin9, &dev_attr_gpio9_set);
device_remove_file(gpio_lb_class_device_help, &dev_attr_help);
device_destroy(gpio_lb_class,MKDEV(MAJOR_GPIO_NUM, 8));
device_destroy(gpio_lb_class,MKDEV(MAJOR_GPIO_NUM, 9));
device_destroy(gpio_lb_class,MKDEV(MAJOR_GPIO_NUM, 255));
class_destroy(gpio_lb_class);
}
static int __init gpio_lb_init(void)
{
int ret;
ret = misc_register(&gpio_lb_dev); //add dev/gpio-lb
if(ret) {
printk("cannot register misc device %s.\n", GPIO_LB_NAME);
return ret;
}
gpio_lb_class_init(); //add class/gpio-lb/
proc_class=proc_mkdir(GPIO_LB_NAME,NULL); //add proc/gpio-lb/
proc_create("dbg",0666,proc_class,&gpio_lb_fops);//add proc/gpio-lb/dbg
#if defined(CONFIG_DEBUG_FS)
gpio_lb_debugfs_init(); //add sys/kernel/debug/gpio-lb/debug
#endif
return ret;
}
static void __exit gpio_lb_exit(void)
{
misc_deregister(&gpio_lb_dev);
gpio_lb_class_exit();
remove_proc_entry("dbg",NULL);
proc_remove(proc_class);
#if defined(CONFIG_DEBUG_FS)
gpio_lb_debugfs_exit();
#endif
return;
}
module_init(gpio_lb_init);
module_exit(gpio_lb_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("LonBon");
MODULE_AUTHOR("Offen Hwang <hhf@lonbon.com>");
MODULE_DESCRIPTION("Lonbon Kernel gpio Driver");
//gpio_lonbon.h
/*
* padmux_tables.h- Sigmastar
*
* Copyright (c) [2019~2020] SigmaStar Technology.
*
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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 version 2 for more details.
*
*/
#ifndef __GPIO_LONBON_H__
#define __GPIO_LONBON_H__
//==============================================================================
//
// STRUCTURE
//
//==============================================================================
#include <asm/io.h>
#include <asm/uaccess.h>
#include <generated/compile.h>
#include "mdrv_gpio_io.h"
#include "mhal_gpio.h"
#include "mdrv_gpio.h"
#include "ms_platform.h"
#include "infinity2m/padmux.h"
#include "infinity2m/padmux_tables.h"
#include "infinity2m/chiptop_reg.h"
#include "infinity2m/pmsleep_reg.h"
#include "infinity2m/mhal_gpio.h"
#define LBK_IOCTL_MAGIC 'L'
#define LBK_GET_KERNEL_VERSION _IO(LBK_IOCTL_MAGIC, 100)
#define LBK_GET_UUID _IO(LBK_IOCTL_MAGIC, 101)
#define LBK_GET_KERNEL_COMMAND _IO(LBK_IOCTL_MAGIC, 102)
#define LBK_SET_WDT_STOP _IO(LBK_IOCTL_MAGIC, 120)
#define LBK_SET_WDT_SHUTDOWN _IO(LBK_IOCTL_MAGIC, 121)
#define LBK_IOC_APP_WDT_SET _IOW(LBK_IOCTL_MAGIC, 125, u32)
#define LBK_IOC_APP_WDT_CANCEL _IO(LBK_IOCTL_MAGIC, 126)
#define LBK_IOC_APP_WDT_FEED _IO(LBK_IOCTL_MAGIC, 127)
#define LBK_IOC_APP_WDT_REQ_RESTART _IO(LBK_IOCTL_MAGIC, 128)
#define LBK_SET_WDT_DBG_PNT _IO(LBK_IOCTL_MAGIC, 200)
#define UART_TX 9
#define UART_RX 8
#define MDRV_GPIO_PAD_SET 1
#define MDRV_GPIO_SET_LOW 2
#define MDRV_GPIO_SET_HIGH 3
#define MDRV_GPIO_PADVAL_SET 4
#define PINMUX_FOR_GPIO_MODE 0x00
#define PINMUX_FOR_UART2_MODE_2 0x2d
#define BASE_RIU_PA 0xFD000000
#define _GPIO_R_WORD_MASK(addr,mask) ((*(volatile u16*)(addr)) & (mask))
#define GET_BASE_ADDR_BY_BANK(x, y) ((x) + ((y) << 1))
#define _RIUA_16BIT(bank , offset) GET_BASE_ADDR_BY_BANK(BASE_RIU_PA, bank) + ((offset)<<2)
#define LBK_IOC_APP_WDT_SET_TIMEOUT_MSEC _IOW(LBK_IOCTL_MAGIC, 129, u32)
#define LBK_SET_WDT_SLAVER_RST _IO(LBK_IOCTL_MAGIC, 130)
#define MINOR_GPIO_NUM 128
#define MAJOR_GPIO_NUM 232
struct gpio_lb_debugfs_data {
struct dentry *dir;
struct dentry *dbg;
u32 command;
};
const ST_PadMuxInfo m_stPadMuxTbl[] =
{
{PAD_GPIO0, CHIPTOP_BANK, REG_SPI0_MODE, REG_SPI0_MODE_MASK, BIT2|BIT1, PINMUX_FOR_SPI0_MODE_6},
{PAD_GPIO0, CHIPTOP_BANK, REG_FUART_MODE, REG_FUART_MODE_MASK, BIT2|BIT0, PINMUX_FOR_FUART_MODE_5},
{PAD_GPIO0, CHIPTOP_BANK, REG_PWM0_MODE, REG_PWM0_MODE_MASK, BIT0, PINMUX_FOR_PWM0_MODE_1},
{PAD_GPIO0, CHIPTOP_BANK, REG_ETH1_MODE, REG_ETH1_MODE_MASK, BIT10, PINMUX_FOR_ETH1_MODE_4},
{PAD_GPIO0, CHIPTOP_BANK, REG_ETH1_MODE, REG_ETH1_MODE_MASK, BIT10|BIT8, PINMUX_FOR_ETH1_MODE_5},
{PAD_GPIO0, CHIPTOP_BANK, REG_ETH1_MODE, REG_ETH1_MODE_MASK, BIT11, PINMUX_FOR_ETH1_MODE_8},
{PAD_GPIO0, CHIPTOP_BANK, REG_I2S_MODE, REG_I2S_MODE_MASK, BIT12, PINMUX_FOR_I2S_MODE_1},
{PAD_GPIO1, CHIPTOP_BANK, REG_SPI0_MODE, REG_SPI0_MODE_MASK, BIT2|BIT1, PINMUX_FOR_SPI0_MODE_6},
{PAD_GPIO1, CHIPTOP_BANK, REG_FUART_MODE, REG_FUART_MODE_MASK, BIT2|BIT0, PINMUX_FOR_FUART_MODE_5},
{PAD_GPIO1, CHIPTOP_BANK, REG_PWM1_MODE, REG_PWM1_MODE_MASK, BIT3, PINMUX_FOR_PWM1_MODE_1},
{PAD_GPIO1, CHIPTOP_BANK, REG_ETH1_MODE, REG_ETH1_MODE_MASK, BIT10, PINMUX_FOR_ETH1_MODE_4},
{PAD_GPIO1, CHIPTOP_BANK, REG_ETH1_MODE, REG_ETH1_MODE_MASK, BIT10|BIT8, PINMUX_FOR_ETH1_MODE_5},
{PAD_GPIO1, CHIPTOP_BANK, REG_ETH1_MODE, REG_ETH1_MODE_MASK, BIT11, PINMUX_FOR_ETH1_MODE_8},
{PAD_GPIO1, CHIPTOP_BANK, REG_I2S_MODE, REG_I2S_MODE_MASK, BIT12, PINMUX_FOR_I2S_MODE_1},
{PAD_GPIO2, CHIPTOP_BANK, REG_I2C1_MODE, REG_I2C1_MODE_MASK, BIT4, PINMUX_FOR_I2C1_MODE_1},
{PAD_GPIO2, CHIPTOP_BANK, REG_SPI0_MODE, REG_SPI0_MODE_MASK, BIT2|BIT1, PINMUX_FOR_SPI0_MODE_6},
{PAD_GPIO2, CHIPTOP_BANK, REG_FUART_MODE, REG_FUART_MODE_MASK, BIT2|BIT0, PINMUX_FOR_FUART_MODE_5},
{PAD_GPIO2, CHIPTOP_BANK, REG_PWM2_MODE, REG_PWM2_MODE_MASK, BIT6, PINMUX_FOR_PWM2_MODE_1},
{PAD_GPIO2, CHIPTOP_BANK, REG_I2S_MODE, REG_I2S_MODE_MASK, BIT12, PINMUX_FOR_I2S_MODE_1},
{PAD_GPIO3, CHIPTOP_BANK, REG_I2C1_MODE, REG_I2C1_MODE_MASK, BIT4, PINMUX_FOR_I2C1_MODE_1},
{PAD_GPIO3, CHIPTOP_BANK, REG_SPI0_MODE, REG_SPI0_MODE_MASK, BIT2|BIT1, PINMUX_FOR_SPI0_MODE_6},
{PAD_GPIO3, CHIPTOP_BANK, REG_FUART_MODE, REG_FUART_MODE_MASK, BIT2|BIT0, PINMUX_FOR_FUART_MODE_5},
{PAD_GPIO3, CHIPTOP_BANK, REG_PWM3_MODE, REG_PWM3_MODE_MASK, BIT9, PINMUX_FOR_PWM3_MODE_1},
{PAD_GPIO3, CHIPTOP_BANK, REG_I2S_MODE, REG_I2S_MODE_MASK, BIT12, PINMUX_FOR_I2S_MODE_1},
{PAD_GPIO4, CHIPTOP_BANK, REG_EJ_MODE, REG_EJ_MODE_MASK, BIT1|BIT0, PINMUX_FOR_EJ_MODE_3},
{PAD_GPIO4, CHIPTOP_BANK, REG_PM_SPICZ2_MODE, REG_PM_SPICZ2_MODE_MASK, BIT4, PINMUX_FOR_PM_SPICZ2_MODE_1},
{PAD_GPIO4, CHIPTOP_BANK, REG_SPI0_MODE, REG_SPI0_MODE_MASK, BIT1|BIT0, PINMUX_FOR_SPI0_MODE_3},
{PAD_GPIO4, CHIPTOP_BANK, REG_FUART_MODE, REG_FUART_MODE_MASK, BIT2|BIT1, PINMUX_FOR_FUART_MODE_6},
{PAD_GPIO4, CHIPTOP_BANK, REG_SDIO_MODE, REG_SDIO_MODE_MASK, BIT9, PINMUX_FOR_SDIO_MODE_2},
{PAD_GPIO4, CHIPTOP_BANK, REG_PWM0_MODE, REG_PWM0_MODE_MASK, BIT1|BIT0, PINMUX_FOR_PWM0_MODE_3},
{PAD_GPIO4, CHIPTOP_BANK, REG_DMIC_MODE, REG_DMIC_MODE_MASK, BIT9|BIT8, PINMUX_FOR_DMIC_MODE_3},
{PAD_GPIO5, CHIPTOP_BANK, REG_EJ_MODE, REG_EJ_MODE_MASK, BIT1|BIT0, PINMUX_FOR_EJ_MODE_3},
{PAD_GPIO5, CHIPTOP_BANK, REG_SPI0_MODE, REG_SPI0_MODE_MASK, BIT1|BIT0, PINMUX_FOR_SPI0_MODE_3},
{PAD_GPIO5, CHIPTOP_BANK, REG_FUART_MODE, REG_FUART_MODE_MASK, BIT2|BIT1, PINMUX_FOR_FUART_MODE_6},
{PAD_GPIO5, CHIPTOP_BANK, REG_SDIO_MODE, REG_SDIO_MODE_MASK, BIT9, PINMUX_FOR_SDIO_MODE_2},
{PAD_GPIO5, CHIPTOP_BANK, REG_PWM1_MODE, REG_PWM1_MODE_MASK, BIT5, PINMUX_FOR_PWM1_MODE_4},
{PAD_GPIO5, CHIPTOP_BANK, REG_DMIC_MODE, REG_DMIC_MODE_MASK, BIT9|BIT8, PINMUX_FOR_DMIC_MODE_3},
{PAD_GPIO6, CHIPTOP_BANK, REG_EJ_MODE, REG_EJ_MODE_MASK, BIT1|BIT0, PINMUX_FOR_EJ_MODE_3},
{PAD_GPIO6, CHIPTOP_BANK, REG_I2C0_MODE, REG_I2C0_MODE_MASK, BIT2, PINMUX_FOR_I2C0_MODE_4},
{PAD_GPIO6, CHIPTOP_BANK, REG_SPI0_MODE, REG_SPI0_MODE_MASK, BIT1|BIT0, PINMUX_FOR_SPI0_MODE_3},
{PAD_GPIO6, CHIPTOP_BANK, REG_SDIO_MODE, REG_SDIO_MODE_MASK, BIT9, PINMUX_FOR_SDIO_MODE_2},
{PAD_GPIO6, CHIPTOP_BANK, REG_DMIC_MODE, REG_DMIC_MODE_MASK, BIT9|BIT8, PINMUX_FOR_DMIC_MODE_3},
{PAD_GPIO7, CHIPTOP_BANK, REG_EJ_MODE, REG_EJ_MODE_MASK, BIT1|BIT0, PINMUX_FOR_EJ_MODE_3},
{PAD_GPIO7, CHIPTOP_BANK, REG_I2C0_MODE, REG_I2C0_MODE_MASK, BIT2, PINMUX_FOR_I2C0_MODE_4},
{PAD_GPIO7, CHIPTOP_BANK, REG_SPI0_MODE, REG_SPI0_MODE_MASK, BIT1|BIT0, PINMUX_FOR_SPI0_MODE_3},
{PAD_GPIO7, CHIPTOP_BANK, REG_SDIO_MODE, REG_SDIO_MODE_MASK, BIT9, PINMUX_FOR_SDIO_MODE_2},
{PAD_GPIO7, CHIPTOP_BANK, REG_PWM3_MODE, REG_PWM3_MODE_MASK, BIT10, PINMUX_FOR_PWM3_MODE_2},
{PAD_GPIO8, CHIPTOP_BANK, REG_SPI0_MODE, REG_SPI0_MODE_MASK, BIT2|BIT0, PINMUX_FOR_SPI0_MODE_5},
{PAD_GPIO8, CHIPTOP_BANK, REG_UART0_MODE, REG_UART0_MODE_MASK, BIT6, PINMUX_FOR_UART0_MODE_4},
{PAD_GPIO8, CHIPTOP_BANK, REG_UART2_MODE, REG_UART2_MODE_MASK, BIT13, PINMUX_FOR_UART2_MODE_2},
{PAD_GPIO8, CHIPTOP_BANK, REG_SDIO_MODE, REG_SDIO_MODE_MASK, BIT9, PINMUX_FOR_SDIO_MODE_2},
{PAD_GPIO9, CHIPTOP_BANK, REG_SPI0_MODE, REG_SPI0_MODE_MASK, BIT2|BIT0, PINMUX_FOR_SPI0_MODE_5},
{PAD_GPIO9, CHIPTOP_BANK, REG_UART0_MODE, REG_UART0_MODE_MASK, BIT6, PINMUX_FOR_UART0_MODE_4},
{PAD_GPIO9, CHIPTOP_BANK, REG_UART2_MODE, REG_UART2_MODE_MASK, BIT13, PINMUX_FOR_UART2_MODE_2},
{PAD_GPIO9, CHIPTOP_BANK, REG_SDIO_MODE, REG_SDIO_MODE_MASK, BIT9, PINMUX_FOR_SDIO_MODE_2},
{P