linux gpio接口

这篇博客深入探讨了Linux GPIO接口,包括gpio_chip和gpio_desc结构体的定义,gpio资源的请求与释放,以及GPIO的输入/输出设置。同时,文章详细解析了GPIO的API接口,如设置去抖动时间、验证GPIO号、获取和设置GPIO值等,并介绍了sysfs的初始化过程。
摘要由CSDN通过智能技术生成

一.相关结构体

1.gpio_chip代表一个芯片的一个gpio bank

struct gpio_chip {	//gpio bank
	const char	*label;		//bank名
	struct device	*dev;	//设备文件
	struct module	*owner;	//模块所有者
	int		(*request)(struct gpio_chip *chip,unsigned offset);
	void	(*free)(struct gpio_chip *chip,unsigned offset);
	int		(*direction_input)(struct gpio_chip *chip,unsigned offset);	//配置gpio为输入
	int		(*get)(struct gpio_chip *chip,unsigned offset);	//获取值
	int		(*direction_output)(struct gpio_chip *chip,unsigned offset, int value);	//配置gpio为输出
	int		(*direction_output_array)(struct gpio_chip*chip, unsigned value, unsigned mask);
	int		(*set_debounce)(struct gpio_chip *chip,unsigned offset, unsigned debounce);	//去抖动时间
	void	(*set)(struct gpio_chip *chip,unsigned offset, int value);	//设置gpio值
	int		(*to_irq)(struct gpio_chip *chip,unsigned offset);	//中断
	void	(*dbg_show)(struct seq_file *s,struct gpio_chip *chip);
	int	base;	//gpio基数
	u16	ngpio;	//gpio个数
	const char	*const *names;
	unsigned	can_sleep:1;	//能否睡眠
	unsigned	exported:1;
#if defined(CONFIG_OF_GPIO)
	struct device_node *of_node;
	int of_gpio_n_cells;
	int (*of_xlate)(struct gpio_chip *gc, struct device_node *np,const void *gpio_spec, u32 *flags);
#endif
};

2.gpio_desc 代表一个gpio口

struct gpio_desc {	//GPIO描述符 
	struct gpio_chip	*chip;	//所属gpio_chip
	unsigned long	flags;		//gpio标志
#ifdef CONFIG_DEBUG_FS
	const char	*label;
#endif
};

2.1 gpio_desc flags标志

#define FLAG_REQUESTED	0	//已请求资源
#define FLAG_IS_OUT	1	//输出io
#define FLAG_RESERVED	2	//保留
#define FLAG_EXPORT	3	/* protected by sysfs_lock */
#define FLAG_SYSFS		4	/* exported via /sys/class/gpio/control */
#define FLAG_TRIG_FALL	5	/* trigger on falling edge */
#define FLAG_TRIG_RISE	6	/* trigger on rising edge */
#define FLAG_ACTIVE_LOW	7	/* sysfs value has active low */

2.2 全局gpio_desc数组

static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];

3.gpio类

static struct class gpio_class = {
	.name =		"gpio",
	.owner =	THIS_MODULE,
	.class_attrs =	gpio_class_attrs,
};


二.api接口

int gpiochip_add(struct gpio_chip *chip)				//添加初始化gpio_chip管理的gpio_desc
int gpiochip_remove(struct gpio_chip *chip)				//清空gpio_chip管理的全局gpio_desc数组项
struct gpio_chip *gpiochip_find(void *data,int (*match)(struct gpio_chip *chip, void *data))	//查找获取gpio_chip

int gpio_request(unsigned gpio, const char *label)		//请求gpio资源
void gpio_free(unsigned gpio)							//释放gpio资源

int gpio_set_debounce(unsigned gpio, unsigned debounce)	//设置去抖动时间
int gpio_direction_input(unsigned gpio)					//设置gpio为输入io
int gpio_direction_output(unsigned gpio, int value)		//设置gpio为输出io

int gpio_cansleep(unsigned gpio)						//判断gpio可否睡眠
int gpio_get_value_cansleep(unsigned gpio)				//获取gpio值(gpio可睡眠)
void gpio_set_value_cansleep(unsigned gpio, int value)	//设置gpio值(gpio可睡眠)
int gpio_get_value(unsigned gpio)						//获取gpio值(gpio不可睡眠)

int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)	//请求一个gpio资源
int gpio_request_array(struct gpio *array, size_t num)	//请求一组gpio资源
void gpio_free_array(struct gpio *array, size_t num)	//释放一组gpio资源

int gpio_to_irq(unsigned gpio)							//根据gpio号获取对应的中断号

int gpio_export(unsigned gpio, bool direction_may_change)	//gpio创建用户接口
void gpio_unexport(unsigned gpio)						//gpio移除用户接口


三.api及调用到的相关函数解析

1.设置gpio_chip管理的全局gpio_desc数组项

int gpiochip_add(struct gpio_chip *chip)
{
	unsigned long	flags;
	int	status = 0;
	unsigned	id;
	int	base = chip->base;	//获取gpio_chip基数
	//验证gpio的基数,gpio的最后一个io的编号正确性
	if ((!gpio_is_valid(base) || !gpio_is_valid(base + chip->ngpio - 1))&& base >= 0) {	
		status = -EINVAL;
		goto fail;
	}
	spin_lock_irqsave(&gpio_lock, flags);	//上自旋锁
	if (base < 0) {	//若gpio的基数小于0
		base = gpiochip_find_base(chip->ngpio);	//根据gpio个数分配新的基数
		if (base < 0) {
			status = base;
			goto unlock;
		}
		chip->base = base;	//设置新的基数
	}
	for (id = base; id < base + chip->ngpio; id++) {
		if (gpio_desc[id].chip != NULL) {	//判断gpio_desc是否给其他gpio_chip管理
			status = -EBUSY;
			break;
		}
	}
	if (status == 0) {
		for (id = base; id < base + chip->ngpio; id++) {	//填充对应的全局gpio_desc数组项
			gpio_desc[id].chip = chip;	//gpio_chip
			gpio_desc[id].flags = !chip->direction_input?(1 << FLAG_IS_OUT):0;	//设置输入输出标志位
		}
	}
	of_gpiochip_add(chip);
unlock:
	spin_unlock_irqrestore(&gpio_lock, flags);	//解自旋锁
	if (status)
		goto fail;
	status = gpiochip_export(chip);	//gpio_chip创建用户接口
	if (status)
		goto fail;
	return 0;
fail:
	pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n",chip->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值