[feat] add gpio_virtual_driver

This commit is contained in:
zhji 2026-02-08 21:56:09 +08:00
parent 625060cc20
commit e0db96f183
3 changed files with 128 additions and 0 deletions

View File

@ -0,0 +1,12 @@
ARCH ?= arm
CROSS_COMPILE ?= /home/jzh/work/study/weidongshan/100ask_stm32mp157_pro-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin/arm-linux-
KERN_DIR ?= /home/jzh/work/study/weidongshan/100ask_stm32mp157_pro-sdk/Linux-5.4
all:
make -C $(KERN_DIR) M=`pwd` ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
clean:
make -C $(KERN_DIR) M=`pwd` ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules clean
rm -rf modules.order
obj-m += gpio_virtual_driver.o

View File

@ -0,0 +1,10 @@
gpio_virtual: gpio_virtual_controller {
compatible = "jzh,gpio_virtual";
gpio-controller;
#gpio-cells = <2>;
ngpios = <4>;
};
myled {
compatible = "jzh,led_driver";
led-gpios = <&gpio_virtual 0 GPIO_ACTIVE_LOW>;
};

View File

@ -0,0 +1,106 @@
#include <linux/module.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/gpio/driver.h>
#include <linux/slab.h>
#include <linux/regmap.h>
static struct gpio_chip *g_gpio_virtual;
static int g_gpio_val = 0;
static int gpio_virtual_direction_output(struct gpio_chip *gc, unsigned offset, int val)
{
printk("set pin %d as output %s\r\n", offset, val ? "high" : "low");
return 0;
}
static int gpio_virtual_direction_input(struct gpio_chip *gc, unsigned offset)
{
printk("set pin %d as input\r\n", offset);
return 0;
}
static int gpio_virtual_get_value(struct gpio_chip *gc, unsigned offset)
{
int val = (g_gpio_val & (1 << offset)) ? 1 : 0;
printk("get pin %d value %d\r\n", offset, val);
return val;
}
static void gpio_virtual_set_value(struct gpio_chip *gc, unsigned offset, int val)
{
if (val) {
g_gpio_val |= (1 << offset);
} else {
g_gpio_val &= ~(1 << offset);
}
printk("set pin %d value %d\r\n", offset, val);
}
static int gpio_virtual_probe(struct platform_device *pdev)
{
int ret;
uint32_t val;
printk("%s %s %d\r\n", __FILE__, __FUNCTION__, __LINE__);
g_gpio_virtual = devm_kzalloc(&pdev->dev, sizeof(*g_gpio_virtual), GFP_KERNEL);
g_gpio_virtual->label = pdev->name;
g_gpio_virtual->direction_output = gpio_virtual_direction_output;
g_gpio_virtual->direction_input = gpio_virtual_direction_input;
g_gpio_virtual->get = gpio_virtual_get_value;
g_gpio_virtual->set = gpio_virtual_set_value;
g_gpio_virtual->parent = &pdev->dev;
g_gpio_virtual->owner = THIS_MODULE;
g_gpio_virtual->base = -1;
ret = of_property_read_u32(pdev->dev.of_node, "ngpios", &val);
g_gpio_virtual->ngpio = val;
ret = devm_gpiochip_add_data(&pdev->dev, g_gpio_virtual, NULL);
return 0;
}
static int gpio_virtual_remove(struct platform_device *pdev)
{
printk("%s %s %d\r\n", __FILE__, __FUNCTION__, __LINE__);
return 0;
}
static const struct of_device_id gpio_virtual_of_match[] = {
{ .compatible = "jzh,gpio-virtual", },
{ },
};
static struct platform_driver gpio_virtual_driver = {
.probe = gpio_virtual_probe,
.remove = gpio_virtual_remove,
.driver = {
.name = "gpio-virtual",
.of_match_table = of_match_ptr(gpio_virtual_of_match),
},
};
static int __init gpio_virtual_init(void)
{
printk("%s %s %d\r\n", __FILE__, __FUNCTION__, __LINE__);
return platform_driver_register(&gpio_virtual_driver);
}
static void __exit gpio_virtual_exit(void)
{
printk("%s %s %d\r\n", __FILE__, __FUNCTION__, __LINE__);
platform_driver_unregister(&gpio_virtual_driver);
}
module_init(gpio_virtual_init);
module_exit(gpio_virtual_exit);
MODULE_DESCRIPTION("Virtual GPIO Driver");
MODULE_AUTHOR("jzhgonha@163.com");
MODULE_LICENSE("GPL");