first commit
This commit is contained in:
commit
8ff56e1c18
4 changed files with 117 additions and 0 deletions
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
*~
|
||||
*.symvers
|
||||
*.ko
|
||||
*.order
|
||||
*.o
|
||||
*.mod.*
|
||||
*.cmd
|
2
.tmp_versions/usbio-led.mod
Normal file
2
.tmp_versions/usbio-led.mod
Normal 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
16
Makefile
Normal 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
92
usbio-led.c
Normal 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");
|
Loading…
Reference in a new issue