first commit

This commit is contained in:
encrypt 2016-01-05 19:40:45 +01:00
commit 8ff56e1c18
4 changed files with 117 additions and 0 deletions

7
.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
*~
*.symvers
*.ko
*.order
*.o
*.mod.*
*.cmd

View file

@ -0,0 +1,2 @@
/home/marco/projects/usbio-led-lkm/usbio-led.ko
/home/marco/projects/usbio-led-lkm/usbio-led.o

16
Makefile Normal file
View file

@ -0,0 +1,16 @@
obj-m := usbio-led.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
DEPMOD:=$(shell which depmod)
# possible bug: maybe this will work only on debian based systems
SYSMAP:= /boot/System.map-$(shell uname -r)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
install:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules_install
$(DEPMOD) -ae -F $(SYSMAP)
clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean

92
usbio-led.c Normal file
View file

@ -0,0 +1,92 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb.h>
#include <linux/slab.h>
#define USBIO_VENDOR_ID 0x04d8
#define USBIO_PRODUCT_ID 0x003f
struct usbio_led {
struct usb_device *udev;
struct led_classdev ldev;
struct mutex lock;
};
static void usbio_led_set(struct led_classdev *ldev, enum led_brightness brightness) {
u8 data[] = { 0x80 };
struct usbio_led *led = container_of(ldev, struct usbio_led, ldev);
int actual_len = 1;
mutex_lock(&led->lock);
usb_interrupt_msg(led->udev,
usb_sndintpipe(led->udev, 1),
data, sizeof(data), &actual_len, USB_CTRL_SET_TIMEOUT);
mutex_unlock(&led->lock);
}
static int usbio_led_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(interface);
struct usbio_led *led = NULL;
int retval = -ENOMEM;
led = kzalloc(sizeof(struct usbio_led), GFP_KERNEL);
if(led == NULL) {
dev_err(&interface->dev, "Out of memory");
goto error;
}
led->udev = usb_get_dev(udev);
usb_set_intfdata(interface, led);
dev_info(&interface->dev, "USBIO LED attached\n");
mutex_init(&led->lock);
led->ldev.name = "usbio_led";
led->ldev.max_brightness = 1;
led->ldev.brightness = LED_OFF;
led->ldev.brightness_set = usbio_led_set;
retval = led_classdev_register(&led->udev->dev, &led->ldev);
if(retval < 0) {
printk("whoops");
goto error;
}
return 0;
error:
printk("errors");
kfree(led);
return retval;
}
static void usbio_led_disconnect(struct usb_interface *interface)
{
struct usbio_led *led;
led = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);
usb_put_dev(led->udev);
led_classdev_unregister(&led->ldev);
kfree(led);
dev_info(&interface->dev, "USBIO disconnected");
}
static struct usb_device_id usbio_id_table[] = {
{ USB_DEVICE(USBIO_VENDOR_ID, USBIO_PRODUCT_ID) },
{}
};
MODULE_DEVICE_TABLE(usb, usbio_id_table);
static struct usb_driver usbio_led_driver = {
.name = "usbio_led",
.probe = usbio_led_probe,
.disconnect = usbio_led_disconnect,
.id_table = usbio_id_table
};
module_usb_driver(usbio_led_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("encrypt <encrypt@labr.xyz>");
MODULE_DESCRIPTION("USBIO led");