initial commit

This commit is contained in:
2026-02-07 00:21:31 -06:00
commit ec5f3d9134
3 changed files with 134 additions and 0 deletions

4
Kconfig Normal file
View File

@@ -0,0 +1,4 @@
config GPIO_KEYBOARD_DRIVER
tristate "gpio-keyboard-driver"
help
TODO write this

13
Makefile Normal file
View 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
View 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");