initial commit
This commit is contained in:
4
Kconfig
Normal file
4
Kconfig
Normal file
@@ -0,0 +1,4 @@
|
||||
config GPIO_KEYBOARD_DRIVER
|
||||
tristate "gpio-keyboard-driver"
|
||||
help
|
||||
TODO write this
|
||||
13
Makefile
Normal file
13
Makefile
Normal file
@@ -0,0 +1,13 @@
|
||||
# Makefile for building my_driver kernel module
|
||||
|
||||
KERNEL_DIR ?= $(PWD)
|
||||
KERNEL_BUILD ?= $(KERNEL_DIR)/build
|
||||
|
||||
obj-m += gpio-keyboard-driver.o
|
||||
|
||||
# The default target
|
||||
all:
|
||||
$(MAKE) -C $(KERNEL_BUILD) M=$(PWD) modules
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(KERNEL_BUILD) M=$(PWD) clean
|
||||
117
gpio-keyboard-driver.c
Normal file
117
gpio-keyboard-driver.c
Normal file
@@ -0,0 +1,117 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
|
||||
static struct input_dev *input_device;
|
||||
static int gpio_button = -1;
|
||||
static int irq_number;
|
||||
|
||||
// Interrupt handler when GPIO is asserted
|
||||
static irqreturn_t gpio_isr(int irq, void *dev_id)
|
||||
{
|
||||
// Simulate keypress for the letter 'a'
|
||||
input_report_key(input_device, KEY_A, 1); // KEY_A is the keycode for 'a'
|
||||
input_sync(input_device); // Sync the event
|
||||
input_report_key(input_device, KEY_A, 0); // KEY_A release
|
||||
input_sync(input_device); // Sync again
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int __init gpio_key_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
// Parse the device tree to get the GPIO pin
|
||||
struct device_node *node = of_find_node_by_path("/gpio_keys/button");
|
||||
if (!node) {
|
||||
pr_err("Device tree node not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
gpio_button = of_get_named_gpio(node, "gpio", 0);
|
||||
if (gpio_button < 0) {
|
||||
pr_err("Failed to get GPIO from device tree\n");
|
||||
return gpio_button;
|
||||
}
|
||||
|
||||
// Request the GPIO
|
||||
ret = gpio_request(gpio_button, "gpio_key");
|
||||
if (ret) {
|
||||
pr_err("Failed to request GPIO\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Set the GPIO as input
|
||||
ret = gpio_direction_input(gpio_button);
|
||||
if (ret) {
|
||||
pr_err("Failed to set GPIO as input\n");
|
||||
gpio_free(gpio_button);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get the interrupt number associated with this GPIO
|
||||
irq_number = gpio_to_irq(gpio_button);
|
||||
if (irq_number < 0) {
|
||||
pr_err("Failed to get IRQ number for GPIO\n");
|
||||
gpio_free(gpio_button);
|
||||
return irq_number;
|
||||
}
|
||||
|
||||
// Request IRQ
|
||||
ret = request_irq(irq_number, gpio_isr, IRQF_TRIGGER_FALLING, "gpio_key_isr", NULL);
|
||||
if (ret) {
|
||||
pr_err("Failed to request IRQ\n");
|
||||
gpio_free(gpio_button);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Register input device (keyboard emulator)
|
||||
input_device = input_allocate_device();
|
||||
if (!input_device) {
|
||||
pr_err("Failed to allocate input device\n");
|
||||
free_irq(irq_number, NULL);
|
||||
gpio_free(gpio_button);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
input_device->name = "GPIO Keyboard";
|
||||
input_device->id.bustype = BUS_USB;
|
||||
input_device->evbit[0] = BIT(EV_KEY);
|
||||
input_device->keybit[BIT_WORD(KEY_A)] = BIT(KEY_A);
|
||||
|
||||
ret = input_register_device(input_device);
|
||||
if (ret) {
|
||||
pr_err("Failed to register input device\n");
|
||||
input_free_device(input_device);
|
||||
free_irq(irq_number, NULL);
|
||||
gpio_free(gpio_button);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pr_info("GPIO keyboard driver loaded\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit gpio_key_exit(void)
|
||||
{
|
||||
// Free resources
|
||||
input_unregister_device(input_device);
|
||||
free_irq(irq_number, NULL);
|
||||
gpio_free(gpio_button);
|
||||
|
||||
pr_info("GPIO keyboard driver unloaded\n");
|
||||
}
|
||||
|
||||
module_init(gpio_key_init);
|
||||
module_exit(gpio_key_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Nicholas Mello");
|
||||
MODULE_DESCRIPTION("GPIO Keyboard Driver");
|
||||
Reference in New Issue
Block a user