From e8fcbb61405997f03b9e127806db620c7cfb9909 Mon Sep 17 00:00:00 2001 From: Christian Vogel Date: Mon, 10 Feb 2014 18:49:43 +0100 Subject: [PATCH] usb/misc/usbled: Add Riso Kagaku Webmail Notifier Add support for the "Webmail Notifier" (USB powered LED for signaling new emails) made by Riso Kagaku Corp. which displays 7 distinct colors. USB Protocol initially reverse engineered by https://code.google.com/p/usbmailnotifier/. Signed-off-by: Christian Vogel Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbled.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c index 78eb4ff33269..bdef0d6eb91d 100644 --- a/drivers/usb/misc/usbled.c +++ b/drivers/usb/misc/usbled.c @@ -22,8 +22,27 @@ enum led_type { DELCOM_VISUAL_SIGNAL_INDICATOR, DREAM_CHEEKY_WEBMAIL_NOTIFIER, + RISO_KAGAKU_LED }; +/* the Webmail LED made by RISO KAGAKU CORP. decodes a color index + internally, we want to keep the red+green+blue sysfs api, so we decode + from 1-bit RGB to the riso kagaku color index according to this table... */ + +static unsigned const char riso_kagaku_tbl[] = { +/* R+2G+4B -> riso kagaku color index */ + [0] = 0, /* black */ + [1] = 2, /* red */ + [2] = 1, /* green */ + [3] = 5, /* yellow */ + [4] = 3, /* blue */ + [5] = 6, /* magenta */ + [6] = 4, /* cyan */ + [7] = 7 /* white */ +}; + +#define RISO_KAGAKU_IX(r,g,b) riso_kagaku_tbl[((r)?1:0)+((g)?2:0)+((b)?4:0)] + /* table of devices that work with this driver */ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x0fc5, 0x1223), @@ -32,6 +51,8 @@ static const struct usb_device_id id_table[] = { .driver_info = DREAM_CHEEKY_WEBMAIL_NOTIFIER }, { USB_DEVICE(0x1d34, 0x000a), .driver_info = DREAM_CHEEKY_WEBMAIL_NOTIFIER }, + { USB_DEVICE(0x1294, 0x1320), + .driver_info = RISO_KAGAKU_LED }, { }, }; MODULE_DEVICE_TABLE(usb, id_table); @@ -48,6 +69,7 @@ static void change_color(struct usb_led *led) { int retval = 0; unsigned char *buffer; + int actlength; buffer = kmalloc(8, GFP_KERNEL); if (!buffer) { @@ -104,6 +126,18 @@ static void change_color(struct usb_led *led) 2000); break; + case RISO_KAGAKU_LED: + buffer[0] = RISO_KAGAKU_IX(led->red, led->green, led->blue); + buffer[1] = 0; + buffer[2] = 0; + buffer[3] = 0; + buffer[4] = 0; + + retval = usb_interrupt_msg(led->udev, + usb_sndctrlpipe(led->udev, 2), + buffer, 5, &actlength, 1000 /*ms timeout*/); + break; + default: dev_err(&led->udev->dev, "unknown device type %d\n", led->type); }