RK3568 Android12 gpio驱动实现(一)

Platform: RK3568
OS: Android 12
Kernel: v4.19.206
SDK Version:android-12.0-mid-rkr1
Module: gpio


前言

GPIO(General Purpose Input/Output)通用输入/输出,是一种可灵活软件控制的通用数字引脚,在芯片中广泛地使用。通过软件我们可以配置其输入或者输出模式,控制其输出高低电平,还可设置为中断脚。一般简单使用可以通过export方式导出对应引脚节点来控制。

目标

刚开始先设定一个小目标:实现一个简单的gpio驱动,在dts中配置一个gpio的节点属性,在驱动中控制该io口的状态。

步骤

  1. 选取一个空置的gpio,此处以gpio0_c3(gpio0-19)为例,在dts中添加配置:
//terry add for tw-gpio driver test
        tw_gpio: tw-gpio {
                status = "okay";
                compatible = "terrywang,rk356x-gpio";
                tw-gpio = <&gpio0 RK_PC3 GPIO_ACTIVE_LOW>;                
        };  
  1. 在drivers/gpio/目录下添加gpio-tw.c驱动文件,并配置Makefile,Kconfig和rockchip_defconfig
obj-$(CONFIG_GPIO_TW)           += gpio-tw.o

config GPIO_TW
       tristate "Terry.W gpio driver test"
       default y
       help 
         Say Y here if you want to use gpio-tw driver 

CONFIG_GPIO_TW=y

3.gpio-tw.c驱动基于platform_driver框架,主要函数有probe,of_device_id,init,exit等。下面主要分析下probe函数:

struct tw_gpio_info {
	int tw_gpio;
	int gpio_enable_value;
};

static int tw_gpio_probe(struct platform_device *pdev)
{
	
	int gpio;
	enum of_gpio_flags flag;
    struct tw_gpio_info *gpio_info;
    struct device_node *tw_gpio_node = pdev->dev.of_node;
	
	pr_info("%s:terry GPIO TEST Driver Probe",__func__);	
	gpio_info = devm_kzalloc(&pdev->dev,sizeof(struct tw_gpio_info *), GFP_KERNEL);
	if (!gpio_info) {
        dev_err(&pdev->dev, "devm_kzalloc failed!\n");
		return -ENOMEM;
	}

	gpio = of_get_named_gpio_flags(tw_gpio_node, "tw-gpio", 0, &flag);
    if (!gpio_is_valid(gpio)) {
        dev_err(&pdev->dev, "tw-gpio: %d is invalid\n", gpio);
        return -ENODEV;
    }
    if (gpio_request(gpio, "tw-gpio")) {
        dev_err(&pdev->dev, "tw-gpio: %d request failed!\n", gpio);
        gpio_free(gpio);
        return -ENODEV;
    }
    gpio_info->tw_gpio = gpio;
    gpio_info->gpio_enable_value = (flag == OF_GPIO_ACTIVE_LOW) ? 0:1;
    gpio_direction_output(gpio_info->tw_gpio, gpio_info->gpio_enable_value);
    pr_info("terry gpio set output\n");
	
	return 0;
	
}

devm_kzalloc为struct tw_gpio_info分配内存;
of_get_named_gpio_flags从dts中根据配置的name(此处为"tw-gpio")获取对应gpio的id和flag;
gpio_is_valid判断gpio的有效性;
gpio_request申请占用该gpio,若申请失败则用gpio_free释放资源;
flag == OF_GPIO_ACTIVE_LOW 根据dts中设置的GPIO_ACTIVE_HIGH/LOW来判断输出电平高低;
gpio_direction_output设置gpio输出模式,并根据flag值来设置输出电平,如果要设置输入模式可用gpio_direction_input

  1. 测试结果如下,正确配置gpio输出高电平

[0.192309] tw_gpio_probe:terry GPIO TEST Driver Probe
[0.192336] terry gpio set output

gpio-19 ( |tw-gpio ) out hi
pin 19 (gpio0-19): (MUX UNCLAIMED) gpio0:19

小结与展望

参考下列资料已实现了最简单的gpio驱动,可以在驱动中控制单个gpio的状态。接下来想要实现添加sysfs节点,以便上层通过读写节点的方式来控制gpio的direction和value。


如有谬误欢迎指正,感谢阅读~

参考资料

[RK3568 Android11] 教程之platform总线 GPIO简单驱动
GPIO 使用

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值