From e0db96f183258ef21bd088e56162093eb2ff7612 Mon Sep 17 00:00:00 2001 From: zhji Date: Sun, 8 Feb 2026 21:56:09 +0800 Subject: [PATCH] [feat] add gpio_virtual_driver --- gpio/gpio_virtual/Makefile | 12 +++ gpio/gpio_virtual/gpio_virtual.dts | 10 +++ gpio/gpio_virtual/gpio_virtual_driver.c | 106 ++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 gpio/gpio_virtual/Makefile create mode 100644 gpio/gpio_virtual/gpio_virtual.dts create mode 100644 gpio/gpio_virtual/gpio_virtual_driver.c diff --git a/gpio/gpio_virtual/Makefile b/gpio/gpio_virtual/Makefile new file mode 100644 index 0000000..e5304fa --- /dev/null +++ b/gpio/gpio_virtual/Makefile @@ -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 diff --git a/gpio/gpio_virtual/gpio_virtual.dts b/gpio/gpio_virtual/gpio_virtual.dts new file mode 100644 index 0000000..be20aa0 --- /dev/null +++ b/gpio/gpio_virtual/gpio_virtual.dts @@ -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>; +}; diff --git a/gpio/gpio_virtual/gpio_virtual_driver.c b/gpio/gpio_virtual/gpio_virtual_driver.c new file mode 100644 index 0000000..2fd7640 --- /dev/null +++ b/gpio/gpio_virtual/gpio_virtual_driver.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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");