diff --git a/interrupt/interrupt_01/Makefile b/interrupt/interrupt_01/Makefile new file mode 100644 index 0000000..0fd1177 --- /dev/null +++ b/interrupt/interrupt_01/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 += interrupt_01.o diff --git a/interrupt/interrupt_01/interrupt_01.c b/interrupt/interrupt_01/interrupt_01.c new file mode 100644 index 0000000..2b5621d --- /dev/null +++ b/interrupt/interrupt_01/interrupt_01.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct gpio_key { + int gpio; + struct gpio_desc *gpiod; + int flag; + int irq; +}; + +static struct gpio_key *gpio_keys; + +static irqreturn_t gpio_key_isr(int irq, void *dev_id) +{ + struct gpio_key *key = dev_id; + int value = gpiod_get_value(key->gpiod); + printk("%s %s line %d: key %d is %d\r\n", __FILE__, __FUNCTION__, __LINE__, key->gpio, value); + return IRQ_HANDLED; +} + +static int interrupt_key_probe(struct platform_device *pdev) +{ + int err; + struct device_node *node = pdev->dev.of_node; + int count; + int i; + enum of_gpio_flags flag; + unsigned flags = GPIOF_IN; + + printk("%s %s %d\r\n", __FILE__, __FUNCTION__, __LINE__); + + count = of_gpio_count(node); + if (count == 0) { + printk("%s %s line %d: no gpio\r\n", __FILE__, __FUNCTION__, __LINE__); + return -1; + } + gpio_keys = kzalloc(sizeof(struct gpio_key) * count, GFP_KERNEL); + for (i = 0; i < count; i++) { + gpio_keys[i].gpio = of_get_gpio_flags(node, i, &flag); + if (gpio_keys[i].gpio < 0) { + printk("%s %s line %d: of_get_gpio_flags failed\r\n", __FILE__, __FUNCTION__, __LINE__); + return -1; + } + gpio_keys[i].gpiod = gpio_to_desc(gpio_keys[i].gpio); + gpio_keys[i].flag = flag & OF_GPIO_ACTIVE_LOW; + if (flag & OF_GPIO_ACTIVE_LOW) { + flags |= GPIOF_ACTIVE_LOW; + } + err = devm_gpio_request_one(&pdev->dev, gpio_keys[i].gpio, flags, NULL); + gpio_keys[i].irq = gpio_to_irq(gpio_keys[i].gpio); + } + + for (i = 0; i < count; i++) { + err = request_irq(gpio_keys[i].irq, gpio_key_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "gpio_key", &gpio_keys[i]); + } + + return 0; +} + +static int interrupt_key_remove(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + int count; + int i; + + count = of_gpio_count(node); + for (i = 0; i < count; i++) { + free_irq(gpio_keys[i].irq, &gpio_keys[i]); + } + kfree(gpio_keys); + + printk("%s %s %d\r\n", __FILE__, __FUNCTION__, __LINE__); + return 0; +} + +static const struct of_device_id interrupt_key_of_match[] = { + { .compatible = "jzh,interrupt-key", }, + { }, +}; + +static struct platform_driver interrupt_key_driver = { + .probe = interrupt_key_probe, + .remove = interrupt_key_remove, + .driver = { + .name = "interrupt-key", + .of_match_table = of_match_ptr(interrupt_key_of_match), + }, +}; + +static int __init interrupt_key_init(void) +{ + printk("%s %s %d\r\n", __FILE__, __FUNCTION__, __LINE__); + return platform_driver_register(&interrupt_key_driver); +} + +static void __exit interrupt_key_exit(void) +{ + printk("%s %s %d\r\n", __FILE__, __FUNCTION__, __LINE__); + platform_driver_unregister(&interrupt_key_driver); +} + +module_init(interrupt_key_init); +module_exit(interrupt_key_exit); +MODULE_DESCRIPTION("Interrupt Key Driver"); +MODULE_AUTHOR("jzhgonha@163.com"); +MODULE_LICENSE("GPL"); diff --git a/interrupt/interrupt_01/interrupt_01.dts b/interrupt/interrupt_01/interrupt_01.dts new file mode 100644 index 0000000..a0dc8af --- /dev/null +++ b/interrupt/interrupt_01/interrupt_01.dts @@ -0,0 +1,25 @@ +interrupt_keys { + compatible = "jzh,interrupt-key"; + gpios = <&gpiog 3 GPIO_ACTIVE_LOW + &gpiog 2 GPIO_ACTIVE_LOW>; +}; + + +joystick { + compatible = "gpio-keys"; + #size-cells = <0>; + status = "disabled"; + button-0 { + label = "usr_button0"; + linux,code = ; + interrupt-parent = <&gpiog>; + interrupts = <3 IRQ_TYPE_EDGE_RISING>; + }; + button-1 { + label = "usr_button1"; + linux,code = ; + interrupt-parent = <&gpiog>; + interrupts = <2 IRQ_TYPE_EDGE_RISING>; + }; + +};