📄 hi_gpio.c
字号:
/* extdrv/peripheral/keypad/hi_gpio.c * * Copyright (c) 2006 Hisilicon Co., Ltd. * * 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 * * History: * 10-April-2006 create this file */ #include <linux/config.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/delay.h>#include <linux/string.h>#include <linux/poll.h>#include <linux/interrupt.h>#include <asm/hardware.h>#include <asm/irq.h>#include <asm/uaccess.h>#include<asm/io.h>#include "hi_gpio.h"void __iomem * GPIO_BASE;static int HAVE_MAPED=0;/* * Free GPIO virtual addr */int gpio_unmap(void){ HAVE_MAPED--; if(!HAVE_MAPED) iounmap((void *)GPIO_BASE); return 0;}/* * Get virtual addr for GPIO */int gpio_remap(void){ if(!HAVE_MAPED) { GPIO_BASE=ioremap(GPIO_PHY_BASE,GPIO_MAP_SIZE); if(!GPIO_BASE) { printk("No MEM allocat for GPIO\n"); return -EFAULT; } } HAVE_MAPED++; return 0;}/* * set the mode of the gpio path pins * 1:hardware control; * 0:software control,reset default. */ int gpio_modeset(unsigned int gpio_pathnum , unsigned int mode){ unsigned int modeValue; if (gpio_pathnum >= GPIO_GROUP_NUMBER) return -1; modeValue = mode; writew( modeValue,(GPIO_BASE + (gpio_pathnum) * GPIO_SPACE_SIZE + GPIO_AFSEL)); return 0;}/* * Get the mode of the gpio path pins */int gpio_modeget(unsigned int gpio_pathnum ,unsigned int * mode ){ unsigned int returnmode; if (gpio_pathnum >= GPIO_GROUP_NUMBER) return -1; returnmode=readw(GPIO_BASE + (gpio_pathnum) * GPIO_SPACE_SIZE + GPIO_AFSEL); *mode = returnmode; return 0;}/* * Set the direction of the single bit for the specific path * dirbit=1 means output * dirbit=0 means input */int gpio_dirsetbit(unsigned int gpio_pathnum , unsigned int bitx ,unsigned int dirbit){ unsigned int dirvalue; if (gpio_pathnum >= GPIO_GROUP_NUMBER) return -1; dirvalue=readw(GPIO_BASE + (gpio_pathnum) * GPIO_SPACE_SIZE + GPIO_DIR); if (dirbit == DIRECTION_OUTPUT) { dirvalue |= (DIRECTION_OUTPUT << bitx); writew(dirvalue,(GPIO_BASE + (gpio_pathnum) * GPIO_SPACE_SIZE + GPIO_DIR)); return 0; } else if(dirbit == DIRECTION_INPUT) { dirvalue &= (~(1 << bitx)); writew(dirvalue,(GPIO_BASE+(gpio_pathnum) * GPIO_SPACE_SIZE + GPIO_DIR)); return 0; } else return -1; }/* * Set the input or output direction for the total path */int gpio_dirsetbyte(unsigned int gpio_pathnum , unsigned int dirbyte){ unsigned int dirvalue; if (gpio_pathnum >= GPIO_GROUP_NUMBER) return -1; dirvalue = dirbyte; writew(dirvalue,(GPIO_BASE + (gpio_pathnum) * GPIO_SPACE_SIZE + GPIO_DIR)); return 0;}/* * Get the input or output direction for the total path */int gpio_dirgetbyte(unsigned int gpio_pathnum , unsigned int *dirbyte){ unsigned int dirvalue; if (gpio_pathnum >= GPIO_GROUP_NUMBER ) return -1; dirvalue=readw(GPIO_BASE + (gpio_pathnum) * GPIO_SPACE_SIZE + GPIO_DIR); *dirbyte = dirvalue; return 0;}/* * Get the input or output direction for a specific pin of a port */int gpio_dirgetbit(unsigned int gpio_pathnum , unsigned int bitx ,unsigned int *dirbit){ unsigned int dirvalue; if (gpio_pathnum >= GPIO_GROUP_NUMBER) return -1; dirvalue=readw(GPIO_BASE + (gpio_pathnum) * GPIO_SPACE_SIZE + GPIO_DIR); dirvalue &= (1 << bitx); if(dirvalue == 0) dirvalue = DIRECTION_INPUT; else dirvalue = DIRECTION_OUTPUT; *dirbit = dirvalue; return 0;} /* * Bit write the value from a specific bit of a gpio path */int gpio_writebit(unsigned int gpio_pathnum , unsigned int bitx , unsigned int bitvalue){ unsigned int bitnum = bitx; unsigned int dirbyte; if (gpio_pathnum >= GPIO_GROUP_NUMBER) return -1; if (bitnum > 7) return -1; if (gpio_dirgetbyte(gpio_pathnum , &dirbyte) == -1) return -1; if((dirbyte & (1<<bitnum)) == DIRECTION_INPUT) return -1; if (bitvalue == 1) writew((1<<(bitnum)),(GPIO_BASE + (gpio_pathnum) * GPIO_SPACE_SIZE + (4<<bitnum))); else if(bitvalue == 0) writew( 0,(GPIO_BASE + (gpio_pathnum) * GPIO_SPACE_SIZE + (4<<bitnum))); else return -1; return 0;}/* * byte write the value of a specific gpio path */int gpio_writebyte(unsigned int gpio_pathnum , unsigned int bytevalue){ unsigned int dirbyte; if (gpio_pathnum >= GPIO_GROUP_NUMBER) return -1; if (gpio_dirgetbyte(gpio_pathnum , &dirbyte) == -1) return -1; if(dirbyte != 0xFF) return -1; writew(bytevalue,(GPIO_BASE + (gpio_pathnum) * GPIO_SPACE_SIZE + 0x3FC)); return 0;}/* * Bit read the value from a specific bit of a gpio path */int gpio_readbit(unsigned int gpio_pathnum , unsigned int bitx , unsigned int * readbit){ unsigned int readvalue; unsigned int bitnum = bitx; unsigned int dirbyte; if (gpio_pathnum >= GPIO_GROUP_NUMBER) return -1; if (bitnum > 7) return -1; if (gpio_dirgetbyte(gpio_pathnum , &dirbyte) == -1) return -1; if((dirbyte & (1<<bitnum)) != DIRECTION_INPUT) return -1; readvalue=readw(GPIO_BASE + (gpio_pathnum) * GPIO_SPACE_SIZE + (4<<bitnum)); readvalue >>= bitnum; readvalue &= 0x01; *readbit = readvalue; return 0;}/* * byte read the value of a specific gpio path */int gpio_readbyte (unsigned int gpio_pathnum , unsigned int * readbyte){ unsigned int readvalue; unsigned int dirbyte; if (gpio_pathnum >= GPIO_GROUP_NUMBER) return -1; if (gpio_dirgetbyte(gpio_pathnum , &dirbyte) == -1) return -1; if(dirbyte != 0x00) return -1; readvalue=readw(GPIO_BASE + (gpio_pathnum) * GPIO_SPACE_SIZE + 0x3FC); *readbyte = readvalue; return 0; }/* * Enable single interrupt bit */int gpio_interruptenable(unsigned int gpio_pathnum ,unsigned int bitx){ unsigned int regvalue; int status; if (gpio_pathnum >= GPIO_GROUP_NUMBER) return -1; if (bitx > 7) { return -1; } else { status = gpio_dirsetbit(gpio_pathnum , bitx , DIRECTION_INPUT); regvalue=readw(GPIO_BASE + (gpio_pathnum) * GPIO_SPACE_SIZE + GPIO_IE); regvalue |= (1<<(bitx)); writew(regvalue,(GPIO_BASE + (gpio_pathnum) * GPIO_SPACE_SIZE + GPIO_IE)); return 0; } }/* * Disable single interrupt bit */int gpio_interruptdisable (unsigned int gpio_pathnum ,unsigned int bitx){ unsigned int regvalue; if (gpio_pathnum >= GPIO_GROUP_NUMBER) return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -