编写虚拟GPIO控制器的驱动程序

一、硬件功能

假设这个虚拟的GPIO Controller有4个引脚:
在这里插入图片描述

二、编写设备树文件

gpio_virt: virtual_gpiocontroller {
	compatible = "100ask,virtual_gpio";
    gpio-controller;
    #gpio-cells = <2>;
    ngpios = <4>;
};

三、编写驱动程序

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/gpio/driver.h>
#include <linux/gpio.h>

static struct gpio_chip *g_virt_gpio;
static int g_gpio_val = 0;

static const struct of_device_id virtual_gpio_of_match[] = {
        { .compatible = "100ask,virtual_gpio", },
        { /* sentinel */ }
};

static int virt_gpio_direction_output(struct gpio_chip *gc,
                unsigned offset, int val)
{
        printk("%s %d\n", __FUNCTION__, __LINE__);
        printk("set pin %d as output %s\n", offset, val ? "high" : "low");
        return 0;
}

static int virt_gpio_direction_input(struct gpio_chip *gc,
                unsigned offset)
{
        printk("%s %d\n", __FUNCTION__, __LINE__);
        printk("set pin %d as input\n", offset);
        return 0;
}

static int virt_gpio_get_value(struct gpio_chip *gc, unsigned offset)
{
        printk("%s %d\n", __FUNCTION__, __LINE__);
        return (g_gpio_val & (1<<offset)) ? 1: 0;
}

static void virt_gpio_set_value(struct gpio_chip *gc,
                unsigned offset, int val)
{
        printk("%s %d val:%d\n", __FUNCTION__, __LINE__, val);
        if(val) {
                g_gpio_val |= (1<<offset);
        } else {
                g_gpio_val &= ~(1<<offset);
        }
}

static int virtual_gpio_probe(struct platform_device *pdev)
{
        int ret = 0;
        unsigned int val;
        printk("%s %d\n", __FUNCTION__, __LINE__);
        g_virt_gpio = devm_kzalloc(&pdev->dev, sizeof(*g_virt_gpio), GFP_KERNEL);

        g_virt_gpio->label = pdev->name;
        g_virt_gpio->direction_output = virt_gpio_direction_output;
        g_virt_gpio->direction_input = virt_gpio_direction_input;
        g_virt_gpio->get = virt_gpio_get_value;
        g_virt_gpio->set = virt_gpio_set_value;

        g_virt_gpio->parent = &pdev->dev;
        g_virt_gpio->owner = THIS_MODULE;

        g_virt_gpio->base = -1;
        ret = of_property_read_u32(pdev->dev.of_node, "ngpios", &val);
        g_virt_gpio->ngpio = val;

        ret = devm_gpiochip_add_data(&pdev->dev, g_virt_gpio, NULL);

        return 0;
}

static int virtual_gpio_remove(struct platform_device *pdev)
{
        printk("%s %d\n", __FUNCTION__, __LINE__);
        return 0;
}

static struct platform_driver virtual_gpio_driver = {
        .driver = {
                .name = "vitual-gpio",
                .of_match_table = of_match_ptr(virtual_gpio_of_match),
        },
        .probe = virtual_gpio_probe,
        .remove = virtual_gpio_remove,
};

static int virtual_gpio_init(void)
{
        printk("%s %d\n", __FUNCTION__, __LINE__);
        return platform_driver_register(&virtual_gpio_driver);
}

static void virtual_gpio_exit(void)
{
        printk("%s %d\n", __FUNCTION__, __LINE__);
        platform_driver_unregister(&virtual_gpio_driver);
}

module_init(virtual_gpio_init);
module_exit(virtual_gpio_exit);
MODULE_LICENSE("GPL");
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

习惯就好zz

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

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

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

打赏作者

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

抵扣说明:

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

余额充值