From 5e4a3b642d15d34f354acfc27b9b8b2f2a7f29cc Mon Sep 17 00:00:00 2001 From: TIBERGHIEN corentin Date: Tue, 3 Feb 2026 10:33:52 +0100 Subject: [PATCH] driver base --- Makefile | 7 +++ driver.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 Makefile create mode 100644 driver.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c9498e9 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +obj-m += driver.o + +all: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules + +clean: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean diff --git a/driver.c b/driver.c new file mode 100644 index 0000000..1814b15 --- /dev/null +++ b/driver.c @@ -0,0 +1,147 @@ +/* + * dependencies: + * + * libusb-dev + * + */ + +#include +#include +#include +#include +#include + +#define CH349_VENDOR_ID 0x1a86 +#define CH349_PRODUCT_ID 0xe349 + +struct ch349_device { + struct usb_device *udev; + struct usb_interface *interface; + struct mutex io_mutex; + + __u8 bulk_in_endpointAddr; + __u8 bulk_out_endpointAddr; + size_t bulk_in_size; + unsigned char *bulk_in_buffer; +}; + +static const struct usb_device_id ch349_table[] = { + { USB_DEVICE(CH349_VENDOR_ID, CH349_PRODUCT_ID) }, + { } +}; +MODULE_DEVICE_TABLE(usb, ch349_table); + +static int ch349_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct ch349_device *dev; + struct usb_endpoint_descriptor *endpoint; + size_t buffer_size; + int i; + int retval = -ENOMEM; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + dev_err(&interface->dev, "Out of memory\n"); + goto error; + } + + mutex_init(&dev->io_mutex); + dev->udev = usb_get_dev(interface_to_usbdev(interface)); + dev->interface = interface; + + for (i = 0; i < interface->cur_altsetting->desc.bNumEndpoints; i++) { + endpoint = &interface->cur_altsetting->endpoint[i].desc; + + if (!dev->bulk_in_endpointAddr && + usb_endpoint_is_bulk_in(endpoint)) { + buffer_size = usb_endpoint_maxp(endpoint); + dev->bulk_in_size = buffer_size; + dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; + dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); + if (!dev->bulk_in_buffer) { + dev_err(&interface->dev, + "Could not allocate bulk_in_buffer\n"); + goto error; + } + } + + if (!dev->bulk_out_endpointAddr && + usb_endpoint_is_bulk_out(endpoint)) { + dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; + } + } + + if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) { + dev_err(&interface->dev, + "Could not find both bulk-in and bulk-out endpoints\n"); + goto error; + } + + usb_set_intfdata(interface, dev); + + dev_info(&interface->dev, + "CH349 device now attached\n"); + + return 0; + +error: + if (dev) + kfree(dev->bulk_in_buffer); + kfree(dev); + return retval; +} + +static void ch349_disconnect(struct usb_interface *interface) +{ + struct ch349_device *dev; + + dev = usb_get_intfdata(interface); + usb_set_intfdata(interface, NULL); + + kfree(dev->bulk_in_buffer); + usb_put_dev(dev->udev); + kfree(dev); + + dev_info(&interface->dev, "CH349 device now disconnected\n"); +} + +static int ch349_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct ch349_device *dev = usb_get_intfdata(intf); + + if (!dev) + return 0; + + mutex_lock(&dev->io_mutex); + mutex_unlock(&dev->io_mutex); + + return 0; +} + +static int ch349_resume(struct usb_interface *intf) +{ + struct ch349_device *dev = usb_get_intfdata(intf); + + if (!dev) + return 0; + + + return 0; +} + +static struct usb_driver ch349_driver = { + .name = "ch349", + .probe = ch349_probe, + .disconnect = ch349_disconnect, + .suspend = ch349_suspend, + .resume = ch349_resume, + .id_table = ch349_table, + .supports_autosuspend = 1, +}; + +module_usb_driver(ch349_driver); + +MODULE_AUTHOR("Votre Nom"); +MODULE_DESCRIPTION("Driver USB pour CH349A"); +MODULE_LICENSE("GPL");