硬件平台: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");