我是靠谱客的博主 霸气豆芽,最近开发中收集的这篇文章主要介绍linux gpio管脚功能配置API,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

#ifndef NUC970_GPIO_H
#define NUC970_GPIO_H

#include <mach/regs-gcr.h>
#include <mach/regs-gpio.h>
#include <mach/gpio.h>

#define GPIO_R		_IOW('g', 0, char) //申请
#define GPIO_F		_IOW('g', 1, char) //释放	
#define GPIO_L		_IOW('g', 2, char) //低电平输出 
#define GPIO_H 		_IOW('g', 3, char) //高电平输出
#define GPIO_O 	  	_IOW('g', 4, char) //输出模式
#define GPIO_I 	  	_IOW('g', 5, char) //输入模式
#define GPIO_PU    	_IOW('g', 6, char) //配置内部上拉
#define GPIO_PD    	_IOW('g', 7, char) //配置内部下拉
#define GPIO_G		_IOW('g', 8, char) //读取

//管脚控制状态
typedef struct {
	char	pin_class;	//'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'
	unsigned int pin;			//对应GPIO管脚
	char pin_offset;	
	unsigned int pin_mask_type;	//芯唐每4个bit表示1个GPIO管脚的功能,由于gpio管脚存在
							    //复用,如要设置GPA-3为普通GPIO,所以pin_mask_type=0xffff0fff
}Pin_ctrl;

//管脚配置为输出时的默认状态
typedef struct {
	int pin; //管脚
	unsigned char value; //管脚默认状态, 0默认输出低电平、1默认输出高电平
}TCfgPinDefOutputState;

//管脚配置为上拉、下拉的使能和禁止
typedef struct {
	int pin;
	int state:1; //1:enable, 0:disable
}TCfgPinPullState; 


inline void GpioRequest(char pin_class, unsigned int pin, char pin_offset, unsigned int pin_mask_type)
{
	Pin_ctrl pin_ctrl;
	
	pin_ctrl.pin_class = pin_class;
	pin_ctrl.pin = pin;
	pin_ctrl.pin_offset = pin_offset;
	pin_ctrl.pin_mask_type = pin_mask_type;
    

	if (pin_ctrl.pin_class == 'A') {
		if (pin_ctrl.pin_offset <= 7)	//PIN0~7
			__raw_writel(__raw_readl(REG_MFP_GPA_L)&pin_ctrl.pin_mask_type, REG_MFP_GPA_L);	
		else		//PIN8~15
			__raw_writel(__raw_readl(REG_MFP_GPA_H)&pin_ctrl.pin_mask_type, REG_MFP_GPA_H);		

	}else if (pin_ctrl.pin_class == 'B') {
		if (pin_ctrl.pin_offset <= 7)	//PIN0~7
			__raw_writel(__raw_readl(REG_MFP_GPB_L)&pin_ctrl.pin_mask_type, REG_MFP_GPB_L);	
		else		//PIN8~15
			__raw_writel(__raw_readl(REG_MFP_GPB_H)&pin_ctrl.pin_mask_type, REG_MFP_GPB_H);		

	}else if (pin_ctrl.pin_class == 'C') {
		if (pin_ctrl.pin_offset <= 7)	//PIN0~7
			__raw_writel(__raw_readl(REG_MFP_GPC_L)&pin_ctrl.pin_mask_type, REG_MFP_GPC_L);	
		else		//PIN8~15
			__raw_writel(__raw_readl(REG_MFP_GPC_H)&pin_ctrl.pin_mask_type, REG_MFP_GPC_H);

	}else if (pin_ctrl.pin_class == 'D') {
		if (pin_ctrl.pin_offset <= 7)	//PIN0~7
			__raw_writel(__raw_readl(REG_MFP_GPD_L)&pin_ctrl.pin_mask_type, REG_MFP_GPD_L);	
		else		//PIN8~15
			__raw_writel(__raw_readl(REG_MFP_GPD_H)&pin_ctrl.pin_mask_type, REG_MFP_GPD_H);
	}else if (pin_ctrl.pin_class == 'E') {
		if (pin_ctrl.pin_offset <= 7)	//PIN0~7
			__raw_writel(__raw_readl(REG_MFP_GPE_L)&pin_ctrl.pin_mask_type, REG_MFP_GPE_L);	
		else		//PIN8~15
			__raw_writel(__raw_readl(REG_MFP_GPE_H)&pin_ctrl.pin_mask_type, REG_MFP_GPE_H);
	}else if (pin_ctrl.pin_class == 'F') {
		if (pin_ctrl.pin_offset <= 7)	//PIN0~7
			__raw_writel(__raw_readl(REG_MFP_GPF_L)&pin_ctrl.pin_mask_type, REG_MFP_GPF_L);	
		else		//PIN8~15
			__raw_writel(__raw_readl(REG_MFP_GPF_H)&pin_ctrl.pin_mask_type, REG_MFP_GPF_H);
	}else if (pin_ctrl.pin_class == 'G') {
		if (pin_ctrl.pin_offset <= 7)	//PIN0~7
			__raw_writel(__raw_readl(REG_MFP_GPG_L)&pin_ctrl.pin_mask_type, REG_MFP_GPG_L);	
		else		//PIN8~15
			__raw_writel(__raw_readl(REG_MFP_GPG_H)&pin_ctrl.pin_mask_type, REG_MFP_GPG_H);
	}else if  (pin_ctrl.pin_class == 'H') {
		if (pin_ctrl.pin_offset <= 7)	//PIN0~7
			__raw_writel(__raw_readl(REG_MFP_GPH_L)&pin_ctrl.pin_mask_type, REG_MFP_GPH_L);	
		else		//PIN8~15
			__raw_writel(__raw_readl(REG_MFP_GPH_H)&pin_ctrl.pin_mask_type, REG_MFP_GPH_H);

	} else if (pin_ctrl.pin_class == 'I') {
		if (pin_ctrl.pin_offset <= 7)	//PIN0~7
			__raw_writel(__raw_readl(REG_MFP_GPI_L)&pin_ctrl.pin_mask_type, REG_MFP_GPI_L);	
		else		//PIN8~15
			__raw_writel(__raw_readl(REG_MFP_GPI_H)&pin_ctrl.pin_mask_type, REG_MFP_GPI_H);
	} else if (pin_ctrl.pin_class == 'J') {
		if (pin_ctrl.pin_offset <= 7)	//PIN0~7
			__raw_writel(__raw_readl(REG_MFP_GPJ_L)&pin_ctrl.pin_mask_type, REG_MFP_GPJ_L);	
		else		//PIN8~15
		    printk("---Kernel info: invalid  pin_ctrl.pin_class=%c , pin_ctrl.pin=%d, pin_ctrl.pin_offset=%d, pin_ctrl.pin_mask_type=0x%08x, PORT-J Pin<7.n", 
				pin_ctrl.pin_class, pin_ctrl.pin, pin_ctrl.pin_offset, pin_ctrl.pin_mask_type);
			
	}
	else {
		printk("---Kernel info: invalid  pin_ctrl.pin_class=%c , pin_ctrl.pin=%d, pin_ctrl.pin_offset=%d, pin_ctrl.pin_mask_type=0x%08x.n", 
				pin_ctrl.pin_class, pin_ctrl.pin, pin_ctrl.pin_offset, pin_ctrl.pin_mask_type);
	}

	if (gpio_request(pin_ctrl.pin, NULL) < 0) {
		printk("---Kernel info: request pin fail  pin_ctrl.pin_class=%c , pin_ctrl.pin=%d, pin_ctrl.pin_offset=%d, pin_ctrl.pin_mask_type=0x%08x.n", 
				pin_ctrl.pin_class, pin_ctrl.pin, pin_ctrl.pin_offset, pin_ctrl.pin_mask_type);
	}

}

inline void request_pin(int pin)
{
	int class_offset, pin_offset;
	unsigned int mask;
	char class_str; //PIN分类:'A''B''C''D''E''F''H''I'
	
	class_offset = pin/32; //取类(A/B/C/D/E/F...)
	pin_offset = pin%32; //取每类的内部偏移
	class_str = class_offset + 'A';
	
	if (pin_offset < 8) //小于8表示管脚范围为0~7
		pin_offset = pin_offset;
	else //大于等于8表示管脚范围为8~15
		pin_offset = pin_offset - 8;

	mask = ~(0x0f<<(pin_offset*4));

	GpioRequest(class_str, pin, pin_offset, mask);
}

inline void free_pin(int pin)
{
	gpio_free(pin);
}


/****************************pin管脚的上、下拉状态配置****************************
	CLASS: 表示管脚类别,分别为A/B/C...I
	PIN_OFFSET:管脚在每一CLASS内部的偏移
	CHOICE_PULL: 选择上拉(PUEN)、或下拉(PDEN)
	PULL_STATE: 表示管脚的内部上拉、下拉状态, 0-禁止上拉或下拉,1-使能上拉或下拉	
**********************************************************************************/
#define PIN_REG_CFG_PULL_STATE(CLASS, PIN_OFFSET, CHOICE_PULL, PULL_STATE) 
	if (PULL_STATE){ 
		__raw_writel(__raw_readl(REG_GPIO##CLASS##_##CHOICE_PULL) | (1<<PIN_OFFSET), REG_GPIO##CLASS##_##CHOICE_PULL);	
	} else { 
		__raw_writel(__raw_readl(REG_GPIO##CLASS##_##CHOICE_PULL) & ~(1<<PIN_OFFSET), REG_GPIO##CLASS##_##CHOICE_PULL);	
	}

//描述:管脚配置为内部上、下拉
//参数: @pin 管脚
//		@choice_pull 对应上、下拉选择,0-上拉(PUEN),1-下拉(PDEN)
//		@enable_state 表示上、下拉的使能状态,0-禁止,1-使能
inline void pin_cfg_pull_state(int pin, int choice_pull, int enable_state)
{
	int class_offset, pin_offset;
	char class_str; //PIN分类:'A''B''C''D''E''F''H''I'

	class_offset = pin/32; //取类(A/B/C/D/E/F...)
	pin_offset = pin%32; //取每类的内部偏移

	class_str = class_offset + 'A';
	if (class_str == 'A') {
		if (choice_pull) {
			PIN_REG_CFG_PULL_STATE(A, pin_offset, PUEN, enable_state);
		}else{
			PIN_REG_CFG_PULL_STATE(A, pin_offset, PDEN, enable_state);
		}
	} else if (class_str == 'B') {
		if (choice_pull) {
			PIN_REG_CFG_PULL_STATE(B, pin_offset, PUEN, enable_state);
		}else {
			PIN_REG_CFG_PULL_STATE(B, pin_offset, PDEN, enable_state);
		}
	} else if (class_str == 'C') {
		if (choice_pull) {
			PIN_REG_CFG_PULL_STATE(C, pin_offset, PUEN, enable_state);
		}else {
			PIN_REG_CFG_PULL_STATE(C, pin_offset, PDEN, enable_state);
		}
	} else if (class_str == 'D') {
		if (choice_pull) {
			PIN_REG_CFG_PULL_STATE(D, pin_offset, PUEN, enable_state);
		}else {
			PIN_REG_CFG_PULL_STATE(D, pin_offset, PDEN, enable_state);
		}
	} else if (class_str == 'E') {
		if (choice_pull) {
			PIN_REG_CFG_PULL_STATE(E, pin_offset, PUEN, enable_state);
		}else {
			PIN_REG_CFG_PULL_STATE(E, pin_offset, PDEN, enable_state);
		}
	} else if (class_str == 'F') {
		if (choice_pull) {
			PIN_REG_CFG_PULL_STATE(F, pin_offset, PUEN, enable_state);
		}else {
			PIN_REG_CFG_PULL_STATE(F, pin_offset, PDEN, enable_state);
		}
	} else if (class_str == 'G') {
		if (choice_pull) {
			PIN_REG_CFG_PULL_STATE(G, pin_offset, PUEN, enable_state);
		}else {
			PIN_REG_CFG_PULL_STATE(G, pin_offset, PDEN, enable_state);
		}
	} else if (class_str == 'H') {
		if (choice_pull) {
			PIN_REG_CFG_PULL_STATE(H, pin_offset, PUEN, enable_state);
		}else {
			PIN_REG_CFG_PULL_STATE(H, pin_offset, PDEN, enable_state);
		}
	} else if (class_str == 'I') {
		if (choice_pull) {
			PIN_REG_CFG_PULL_STATE(I, pin_offset, PUEN, enable_state);
		}else {
			PIN_REG_CFG_PULL_STATE(I, pin_offset, PDEN, enable_state);
		}
	} else if (class_str == 'J') {
		if (choice_pull) {
			PIN_REG_CFG_PULL_STATE(J, pin_offset, PUEN, enable_state);
		}else {
			PIN_REG_CFG_PULL_STATE(J, pin_offset, PDEN, enable_state);
		}
	}

	printk("pin_cfg_pull_up: pin=%d, pull=%s, %s.n", pin, (choice_pull)? "PUEN":"PDEN", (enable_state==1)? "enable":"disable");
}

#endif /* __ASM_MACH_NUC970_GPIO_H*/

 

最后

以上就是霸气豆芽为你收集整理的linux gpio管脚功能配置API的全部内容,希望文章能够帮你解决linux gpio管脚功能配置API所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部