diff --git a/08_gpio_led/Makefile b/08_gpio_led/Makefile new file mode 100644 index 0000000..b909b3c --- /dev/null +++ b/08_gpio_led/Makefile @@ -0,0 +1,7 @@ +obj-m += test_module.o + +all: + make -C $(LINUX_MODULES_FOLDER)/build M=$(PWD) modules + +clean: + make -C $(LINUX_MODULES_FOLDER)/build M=$(PWD) clean diff --git a/08_gpio_led/test_module.c b/08_gpio_led/test_module.c new file mode 100644 index 0000000..cc73a7b --- /dev/null +++ b/08_gpio_led/test_module.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include + +static char *device_label = ""; +module_param(device_label, charp, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); +MODULE_PARM_DESC(device_label, "GPIO Device Label"); + +static char *gpio_pin_id = ""; +module_param(gpio_pin_id, charp, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); +MODULE_PARM_DESC(gpio_pin_id, "GPIO Pin ID"); + +struct gpio_device *device; +struct gpio_desc *led_desc; + +// Copied from https://elixir.bootlin.com/linux/v6.6.79/source/drivers/gpio/gpiolib.c#L1085 +// gpio_device_find_by_label it's not available on Linux Kernel 6.6 but only with Linux Kernel 6.7+ +static int gpiochip_match_name(struct gpio_chip *gc, void *data) +{ + const char *name = data; + + return !strcmp(gc->label, name); +} + +static int __init gpio_led_init(void) { + int ret; + + device = gpio_device_find(device_label, gpiochip_match_name); + if (!device) { + pr_err("Failed to get device"); + return -ENODEV; + } + + led_desc = gpiod_get(device, gpio_pin_id, GPIOD_OUT_LOW); + if (IS_ERR(led_desc)) { + pr_err("Failed to get GPIO: %ld\n", PTR_ERR(led_desc)); + ret = PTR_ERR(led_desc); + goto fail; + } + + gpiod_set_value(led_desc, 1); + + pr_info("Bonjour! Le module est chargé.\n"); + return 0; + +fail: + gpio_device_put(device); + return -ENODEV; +} + +static void __exit gpio_led_exit(void) { + gpiod_set_value(led_desc, 0); + + gpiod_put(led_desc); + gpio_device_put(device); + + pr_info("Au revoir! Le module est déchargé.\n"); +} + +module_init(gpio_led_init); +module_exit(gpio_led_exit); + +MODULE_LICENSE("MIT License"); +MODULE_AUTHOR("Florian RICHER"); +MODULE_DESCRIPTION("Un module noyau pour utiliser un PIN GPIO d'une RPI en tant que LED"); +MODULE_VERSION("1.0");