[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