linux内核使用pinctrl子系统实现操作gpio输出高低电平的实现

硬件平台:rv1108


在内核中实现使用pinctrl子系统控制gpio主要实在两个方面:dts文件的节点的添加和驱动代码的编写。

1.dts文件的修改

在kernel/arch/arm/boot/dts/rv1108-evb-v12.dts中添加如下信息:

mz391_gpio_rst:mz391_gpio_rst {
    compatible = "rk,mz391-rst";
    pinctrl-names = "mz391-rst-on", "mz391-rst-off";
    pinctrl-0 = <&mz391_resetpin_on>;
    pinctrl-1 = <&mz391_resetpin_off>;
};

在 kernel/arch/arm/boot/dts/rv1108.dtsi

gpio3a3_low {                                                                                                  
    mz391_resetpin_on: pin_gpio3a3_low {                                                                       
        rockchip,pins = <3 GPIO_A3 RK_FUNC_GPIO &pcfg_output_low>;                                             
    };                                                                                                         
    mz391_resetpin_off: pin_gpio3a3_high {                                                                     
        rockchip,pins = <3 GPIO_A3 RK_FUNC_GPIO &pcfg_output_high>;                                            
    };                                                                                                         
}; 

2.驱动代码

包括makefile和Kconfig的编写。

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/delay.h>


#define MZ391_RESET_NAME "mz391_reset_gpio3a3"

static struct pinctrl *mz391rst_pin_ctrl = NULL;

static int gpio_reset_probe(struct platform_device *pdev)
{
	struct pinctrl_state  *mz391rst_on = NULL, *mz391rst_off = NULL;
	int ret = 0;

	printk("now is %s %d\n", __FUNCTION__, __LINE__);
	mz391rst_pin_ctrl = devm_pinctrl_get(&pdev->dev);
	if(IS_ERR(mz391rst_pin_ctrl))
	{
		printk("devm_pinctrl_get is error\n");
		ret = PTR_ERR(mz391rst_pin_ctrl);
		return ret;
	}
	
	mz391rst_on = pinctrl_lookup_state(mz391rst_pin_ctrl, "mz391-rst-on");
	if(IS_ERR(mz391rst_on))
	{
		printk("get the state of the mz391-rst-on is fail\n");
		ret = PTR_ERR(mz391rst_on);
		return ret;
	}

	mz391rst_off = pinctrl_lookup_state(mz391rst_pin_ctrl, "mz391-rst-off");
	if(IS_ERR(mz391rst_off))
	{
		printk("get the state of the mz391-rst-off fail\n");
		ret = PTR_ERR(mz391rst_off);
		return ret;
	}

	pinctrl_select_state(mz391rst_pin_ctrl, mz391rst_on);
	printk("now gpio3a3 is low\n");
	mdelay(5000);
	pinctrl_select_state(mz391rst_pin_ctrl, mz391rst_off);
	printk("now gpio3a3 is high\n");

	return ret;
}

static int gpio_reset_remove(struct platform_device *pdev)
{
	return 0;	
}

static const struct of_device_id  gpio_reset_of_id[] = {
	{.compatible = "rk,mz391-rst",},
	{}
};

static struct platform_driver mz391rst_platform_driver = {
	.probe = gpio_reset_probe,
	.remove = gpio_reset_remove,
	.driver = {
		.name = MZ391_RESET_NAME,
		.owner = THIS_MODULE,
		.of_match_table = gpio_reset_of_id,
	},
};

static int __init mz391_reset_init(void)
{
	printk("%s is called\n", __func__);
	platform_driver_register(&mz391rst_platform_driver);
	return 0;
}

static void __exit mz391_reset_exit(void)
{
	platform_driver_unregister(&mz391rst_platform_driver);
}

module_init(mz391_reset_init);
module_exit(mz391_reset_exit);

MODULE_AUTHOR("xyw");
MODULE_DESCRIPTION("the reset pin of the mz391 ");
MODULE_LICENSE("DUAL BSD/GPL");

 

上一篇:pinctrl驱动----驱动/设备侧


下一篇:Linux下如何使用X86 CPU的GPIO