GPIO子系统层次与数据结构

一、GPIO子系统的层次

1.1 层次

在这里插入图片描述

中间层有gpio lib

1.2 GPIOLIB向上提供的接口

descriptor-basedlegacy说明
gpiod_getgpio_request获得GPIO
gpiod_get_index
gpiod_get_arraygpio_request_array
devm_gpiod_get
devm_gpiod_get_index
devm_gpiod_get_array
gpiod_direction_inputgpio_direction_input设置方向
gpiod_direction_outputgpio_direction_output
gpiod_get_valuegpio_get_value读值、写值
gpiod_set_valuegpio_set_value
gpio_freegpio_free释放GPIO
gpio_putgpio_free_array
gpiod_put_array
devm_gpiod_put
devm_gpiod_put_array

1.3 GPIOLIB向下提供的接口

//用来注册gpio_chip
int gpiochip_add_data(struct gpio_chip *chip, void *data)

二、重要的3个核心数据结构

在了解GPIO Controller驱动程序的结构时,有必要了解它的大致的信息:

  • 一个GPIO Controller里有多少个引脚?有哪些引脚?
  • 哪些函数,能够设置引脚方向、读取、设置引脚数值
  • 哪些函数,把引脚转换为中断
    以LInux面向对象编程的思想,一个GPIO Controller必定有对应的结构体,必定包含信息:
  • GPIO引脚信息
  • 控制引脚的函数
  • 中断相关的函数

2.1 gpio_device

每个GPIO Controller用一个gpio_device来表示:

  • 每个gpio引脚用一个gpio_desc来表示
  • gpio引脚的函数,都放在gpio_chip
    在这里插入图片描述

一个GPIO Controller用gpio_device来描述,每个其中每个引脚,有用gpio_desc来描述。

//drivers/gpio/gpiolib.h
struct gpio_device {
	int			id;					//它是系统中第几个gpio controller
	struct device		dev;
	struct cdev		chrdev;
	struct device		*mockdev;
	struct module		*owner;
	struct gpio_chip	*chip;			//含有各类操作函数
	struct gpio_desc	*descs;		//用来描述引脚,每个引脚对应一个gpio_desc
	int			base;		//这些GPIO的号码基值
	u16			ngpio;		//这些GPIO Controller支持多少个GPIO
	char			*label;		//标签、名字
	void			*data;
	struct list_head        list;

#ifdef CONFIG_PINCTRL
	/*
	 * If CONFIG_PINCTRL is enabled, then gpio controllers can optionally
	 * describe the actual pin range which they serve in an SoC. This
	 * information would be used by pinctrl subsystem to configure
	 * corresponding pins for gpio usage.
	 */
	struct list_head pin_ranges;
#endif
};

2.2 gpio_chip

编写驱动时需要创建gpio_chip

  • 控制引脚的函数
  • 中断相关的函数
  • 引脚信息:支持多少引脚?各引脚名字?
struct gpio_chip {
	const char		*label;
	struct gpio_device	*gpiodev;
	struct device		*parent;
	struct module		*owner;

//相关函数
	int			(*request)(struct gpio_chip *chip,
						unsigned offset);
	void			(*free)(struct gpio_chip *chip,
						unsigned offset);
	int			(*get_direction)(struct gpio_chip *chip,
						unsigned offset);
	int			(*direction_input)(struct gpio_chip *chip,
						unsigned offset);
	int			(*direction_output)(struct gpio_chip *chip,
						unsigned offset, int value);
	int			(*get)(struct gpio_chip *chip,
						unsigned offset);
	void			(*set)(struct gpio_chip *chip,
						unsigned offset, int value);
	void			(*set_multiple)(struct gpio_chip *chip,
						unsigned long *mask,
						unsigned long *bits);
	int			(*set_config)(struct gpio_chip *chip,
					      unsigned offset,
					      unsigned long config);
	int			(*to_irq)(struct gpio_chip *chip,
						unsigned offset);

	void			(*dbg_show)(struct seq_file *s,
						struct gpio_chip *chip);
	int			base;		//GPIO Controller中引脚的号码基值
	u16			ngpio;		//个数
	const char		*const *names; //每个引脚的名字
	bool			can_sleep;

	//....
};

2.3 gpio_desc

使用GPIO子系统时,先获得某个引脚对应的gpio_desc
gpio_device表示一个GPIO Controller,里面支持多个GPIO
在gpio_device中有一个gpio_desc数组,每一个引脚有一项gpio_desc

struct gpio_desc {
	struct gpio_device	*gdev;		//属于哪个GPIO Controller
	unsigned long		flags;
/* flag symbols are bit numbers */
#define FLAG_REQUESTED	0
#define FLAG_IS_OUT	1
#define FLAG_EXPORT	2	/* protected by sysfs_lock */
#define FLAG_SYSFS	3	/* exported via /sys/class/gpio/control */
#define FLAG_ACTIVE_LOW	6	/* value has active low */
#define FLAG_OPEN_DRAIN	7	/* Gpio is open drain type */
#define FLAG_OPEN_SOURCE 8	/* Gpio is open source type */
#define FLAG_USED_AS_IRQ 9	/* GPIO is connected to an IRQ */
#define FLAG_IS_HOGGED	11	/* GPIO is hogged */
#define FLAG_SLEEP_MAY_LOOSE_VALUE 12	/* GPIO may loose value in sleep */

	/* Connection label */
	const char		*label;		//一般等于gpio_chip的label
	/* Name of the GPIO */
	const char		*name;			//引脚名
};

三、怎么编写GPIO Controller驱动程序

//1. gpiod_get获得一个gpiod指针
//2. 根据gpiod找到GPIO控制器,使用gpiod_set_value来设置输出的高低电平
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

习惯就好zz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值