pinctrl系统(pidmux)与gpio子系统

1.pinctrl系统是什么?

pinctrl 子系统主要完成以下工作:

(1)获取设备树中pin信息

(2)设置pin的复用功能

(3)设置pin的上下拉/速度/驱动能力等。

2.gpio子系统是什么?

就是用于初始化 GPIO 并且提供相应的 API 函数,比如设置 GPIO为输入输出,读取 GPIO 的值等。其主要目的是方便开发者使用gpio。

3.pinctrl系统和gpio子系统的关系

pinctrl 子系统重点是设置 PIN(有的 SOC 叫做 PAD)的复用和电气属性,如果 pinctrl 子系统将一个 PIN 复用为 GPIO 的话,那么接下来就要用到 gpio 子系统了。

4.gpio子系统的设备树配置

gpio1: gpio@0209c000 {
 compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
 reg = <0x0209c000 0x4000>;
 interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
 <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
 gpio-controller;
 #gpio-cells = <2>;
 interrupt-controller;
 #interrupt-cells = <2>;
 };

reg表示gpio1的基地址和范围,“gpio-controller”表示 gpio1 节点是个 GPIO 控制器,#gpio-cells 应该为 2,表示一共有两个 cell,第一个 cell 为 GPIO 编号,

如下是gpio的节点配置

gpioled {
 #address-cells = <1>;
 #size-cells = <1>;
 compatible = "atkalpha-gpioled";
 led-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
 status = "okay";
 }

“&gpio1 3”就表示 GPIO1_IO03。第二个 cell 表示GPIO 极 性 , 如 果 为 0(GPIO_ACTIVE_HIGH) 的 话 表 示 高 电 平 有 效 , 如 果 为1(GPIO_ACTIVE_LOW)的话表示低电平有效。

5.gpio_get_value 与gpio_set_value函数实现

头文件 include/linux.h/gipio.h

gpio_get_value->

        __gpio_get_value->

                gpiod_get_raw_value(gpio_to_desc(gpio))->

                        gpiod_get_raw_value_commit(desc)->

                                value = chip->get ? chip->get(chip, offset) : -EIO

 其中chip->get是在gpio子系统驱动中注册的回调函数,一般有芯片厂家实现

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);
	int			(*get_multiple)(struct gpio_chip *chip,
						unsigned long *mask,
						unsigned long *bits);
	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;
	u16			ngpio;
	const char		*const *names;
	bool			can_sleep;

#if IS_ENABLED(CONFIG_GPIO_GENERIC)
	unsigned long (*read_reg)(void __iomem *reg);
	void (*write_reg)(void __iomem *reg, unsigned long data);
	bool be_bits;
	void __iomem *reg_dat;
	void __iomem *reg_set;
	void __iomem *reg_clr;
	void __iomem *reg_dir;
	bool bgpio_dir_inverted;
	int bgpio_bits;
	spinlock_t bgpio_lock;
	unsigned long bgpio_data;
	unsigned long bgpio_dir;
#endif

#ifdef CONFIG_GPIOLIB_IRQCHIP
	/*
	 * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib
	 * to handle IRQs for most practical cases.
	 */

	/**
	 * @irq:
	 *
	 * Integrates interrupt chip functionality with the GPIO chip. Can be
	 * used to handle IRQs for most practical cases.
	 */
	struct gpio_irq_chip irq;
#endif

	/**
	 * @need_valid_mask:
	 *
	 * If set core allocates @valid_mask with all bits set to one.
	 */
	bool need_valid_mask;

	/**
	 * @valid_mask:
	 *
	 * If not %NULL holds bitmask of GPIOs which are valid to be used
	 * from the chip.
	 */
	unsigned long *valid_mask;

#if defined(CONFIG_OF_GPIO)
	/*
	 * If CONFIG_OF is enabled, then all GPIO controllers described in the
	 * device tree automatically may have an OF translation
	 */

	/**
	 * @of_node:
	 *
	 * Pointer to a device tree node representing this GPIO controller.
	 */
	struct device_node *of_node;

	/**
	 * @of_gpio_n_cells:
	 *
	 * Number of cells used to form the GPIO specifier.
	 */
	unsigned int of_gpio_n_cells;

	/**
	 * @of_xlate:
	 *
	 * Callback to translate a device tree GPIO specifier into a chip-
	 * relative GPIO number and flags.
	 */
	int (*of_xlate)(struct gpio_chip *gc,
			const struct of_phandle_args *gpiospec, u32 *flags);
#endif
};

联咏厂家的gpio_chip初始化如下:

	nvt_gpio_chip_ptr->gpio_chip.get = nvt_gpio_get;
	nvt_gpio_chip_ptr->gpio_chip.set = nvt_gpio_set;
	nvt_gpio_chip_ptr->gpio_chip.direction_input = nvt_gpio_dir_input;
	nvt_gpio_chip_ptr->gpio_chip.direction_output = nvt_gpio_dir_output;
	nvt_gpio_chip_ptr->gpio_chip.get_direction = nvt_gpio_get_dir;
	nvt_gpio_chip_ptr->gpio_chip.ngpio = NVT_GPIO_NUMBER;
	nvt_gpio_chip_ptr->gpio_chip.to_irq = nvt_gpio_to_irq;
	nvt_gpio_chip_ptr->gpio_chip.base = 0;

gpio_set_value->

        __gpio_set_value->

                gpiod_set_raw_value->

                        gpiod_set_raw_value_commit(desc, value)->

                                chip->set(chip, gpio_chip_hwgpio(desc), value)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值