[feat] add gpio_virtual_driver
This commit is contained in:
parent
625060cc20
commit
e0db96f183
12
gpio/gpio_virtual/Makefile
Normal file
12
gpio/gpio_virtual/Makefile
Normal 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
|
||||||
10
gpio/gpio_virtual/gpio_virtual.dts
Normal file
10
gpio/gpio_virtual/gpio_virtual.dts
Normal 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>;
|
||||||
|
};
|
||||||
106
gpio/gpio_virtual/gpio_virtual_driver.c
Normal file
106
gpio/gpio_virtual/gpio_virtual_driver.c
Normal 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");
|
||||||
Loading…
Reference in New Issue
Block a user