Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: add support for Dream Cheeky DL100B Webmail Notifier (1d34:0004)

So far the USBLED driver only supports Delcom's "USB Visual Signal
Indicator" (http://www.delcomproducts.com/products_USBLMP.asp). The
driver generates virtual files "red", "green", and "blue" under the
device's /sys/ directory, where color values can be read from and
written to.

This patch adds support for Dream Cheeky's "DL100B Webmail Notifier"
(http://www.dreamcheeky.com/webmail-notifier -- available from several
shops, such as http://www.conrad.at/ce/de/product/777048/USB-WEBMAIL).
This device isn't as pretty as Delcom's, but it's *far* cheaper, and
its 3 LEDs can be set in 32 brightness steps each. The grey envelope
contour can easily be removed, leaving a rather neutral white box (with
a few small holes), which is useful for generic signalling purposes.
Of course, the small circuit board can easily be put into a prettier
case.

The DL100B device pretends to be a HID, but the HID descriptor shows
that it's not overly useful as such (see below). The patch therefore
removes the "HID-ness" (hid-core.c, hid-ids.h), and adds the necessary
commands to usbled.c. The protocol info comes from the developer's
manual that Dream Cheeky kindly provided (815DeveloperManual.pdf).

HID descriptor:

0: 05 01 Usage Page 'Generic Desktop Controls'
2: 09 10 Usage 'Reserved'
4: a1 01 Collection 'Application (mouse, keyboard)'
6: 05 00 Usage Page 'Undefined'
8: 19 10 Usage Minimum = 16
10: 29 11 Usage Maximum = 17
12: 15 00 Logical Minimum = 0
14: 25 0f Logical Maximum = 15
16: 75 08 Report Size = 8
18: 95 08 Report Count = 8
20: 91 02 Output data *var abs lin pref-state null-pos non-vol bit-field
22: 19 10 Usage Minimum = 16
24: 29 11 Usage Maximum = 17
26: 15 00 Logical Minimum = 0
28: 25 0f Logical Maximum = 15
30: 75 08 Report Size = 8
32: 95 08 Report Count = 8
34: 81 00 Input data array abs lin pref-state null-pos non-vol bit-field
36: c0 End Collection

Signed-off-by: Melchior FRANZ <mfranz@aon.at>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Melchior FRANZ and committed by
Greg Kroah-Hartman
73bc7d31 c466cd2b

+92 -27
+1
drivers/hid/hid-core.c
··· 1604 1604 { HID_USB_DEVICE(USB_VENDOR_ID_DEALEXTREAME, USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701) }, 1605 1605 { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, 1606 1606 { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, 1607 + { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, 0x0004) }, 1607 1608 { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, 1608 1609 { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) }, 1609 1610 { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) },
+2
drivers/hid/hid-ids.h
··· 200 200 #define USB_VENDOR_ID_ELECOM 0x056e 201 201 #define USB_DEVICE_ID_ELECOM_BM084 0x0061 202 202 203 + #define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34 204 + 203 205 #define USB_VENDOR_ID_ELO 0x04E7 204 206 #define USB_DEVICE_ID_ELO_TS2700 0x0020 205 207
+89 -27
drivers/usb/misc/usbled.c
··· 1 1 /* 2 - * USB LED driver - 1.1 2 + * USB LED driver 3 3 * 4 4 * Copyright (C) 2004 Greg Kroah-Hartman (greg@kroah.com) 5 5 * ··· 20 20 #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com" 21 21 #define DRIVER_DESC "USB LED Driver" 22 22 23 - #define VENDOR_ID 0x0fc5 24 - #define PRODUCT_ID 0x1223 23 + enum led_type { 24 + DELCOM_VISUAL_SIGNAL_INDICATOR, 25 + DREAM_CHEEKY_WEBMAIL_NOTIFIER, 26 + }; 25 27 26 28 /* table of devices that work with this driver */ 27 29 static const struct usb_device_id id_table[] = { 28 - { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, 30 + { USB_DEVICE(0x0fc5, 0x1223), 31 + .driver_info = DELCOM_VISUAL_SIGNAL_INDICATOR }, 32 + { USB_DEVICE(0x1d34, 0x0004), 33 + .driver_info = DREAM_CHEEKY_WEBMAIL_NOTIFIER }, 29 34 { }, 30 35 }; 31 36 MODULE_DEVICE_TABLE (usb, id_table); ··· 40 35 unsigned char blue; 41 36 unsigned char red; 42 37 unsigned char green; 38 + enum led_type type; 43 39 }; 44 40 45 - #define BLUE 0x04 46 - #define RED 0x02 47 - #define GREEN 0x01 48 41 static void change_color(struct usb_led *led) 49 42 { 50 43 int retval; 51 - unsigned char color = 0x07; 52 44 unsigned char *buffer; 53 45 54 46 buffer = kmalloc(8, GFP_KERNEL); ··· 54 52 return; 55 53 } 56 54 57 - if (led->blue) 58 - color &= ~(BLUE); 59 - if (led->red) 60 - color &= ~(RED); 61 - if (led->green) 62 - color &= ~(GREEN); 63 - dev_dbg(&led->udev->dev, 64 - "blue = %d, red = %d, green = %d, color = %.2x\n", 65 - led->blue, led->red, led->green, color); 55 + switch (led->type) { 56 + case DELCOM_VISUAL_SIGNAL_INDICATOR: { 57 + unsigned char color = 0x07; 66 58 67 - retval = usb_control_msg(led->udev, 68 - usb_sndctrlpipe(led->udev, 0), 69 - 0x12, 70 - 0xc8, 71 - (0x02 * 0x100) + 0x0a, 72 - (0x00 * 0x100) + color, 73 - buffer, 74 - 8, 75 - 2000); 59 + if (led->blue) 60 + color &= ~0x04; 61 + if (led->red) 62 + color &= ~0x02; 63 + if (led->green) 64 + color &= ~0x01; 65 + dev_dbg(&led->udev->dev, 66 + "blue = %d, red = %d, green = %d, color = %.2x\n", 67 + led->blue, led->red, led->green, color); 68 + 69 + retval = usb_control_msg(led->udev, 70 + usb_sndctrlpipe(led->udev, 0), 71 + 0x12, 72 + 0xc8, 73 + (0x02 * 0x100) + 0x0a, 74 + (0x00 * 0x100) + color, 75 + buffer, 76 + 8, 77 + 2000); 78 + break; 79 + } 80 + 81 + case DREAM_CHEEKY_WEBMAIL_NOTIFIER: 82 + dev_dbg(&led->udev->dev, 83 + "red = %d, green = %d, blue = %d\n", 84 + led->red, led->green, led->blue); 85 + 86 + buffer[0] = led->red; 87 + buffer[1] = led->green; 88 + buffer[2] = led->blue; 89 + buffer[3] = buffer[4] = buffer[5] = 0; 90 + buffer[6] = 0x1a; 91 + buffer[7] = 0x05; 92 + 93 + retval = usb_control_msg(led->udev, 94 + usb_sndctrlpipe(led->udev, 0), 95 + 0x09, 96 + 0x21, 97 + 0x200, 98 + 0, 99 + buffer, 100 + 8, 101 + 2000); 102 + break; 103 + 104 + default: 105 + dev_err(&led->udev->dev, "unknown device type %d\n", led->type); 106 + } 107 + 76 108 if (retval) 77 109 dev_dbg(&led->udev->dev, "retval = %d\n", retval); 78 110 kfree(buffer); ··· 143 107 144 108 dev = kzalloc(sizeof(struct usb_led), GFP_KERNEL); 145 109 if (dev == NULL) { 146 - dev_err(&interface->dev, "Out of memory\n"); 110 + dev_err(&interface->dev, "out of memory\n"); 147 111 goto error_mem; 148 112 } 149 113 150 114 dev->udev = usb_get_dev(udev); 115 + dev->type = id->driver_info; 151 116 152 117 usb_set_intfdata (interface, dev); 153 118 ··· 161 124 retval = device_create_file(&interface->dev, &dev_attr_green); 162 125 if (retval) 163 126 goto error; 127 + 128 + if (dev->type == DREAM_CHEEKY_WEBMAIL_NOTIFIER) { 129 + unsigned char *enable; 130 + 131 + enable = kmemdup("\x1f\x02\0\x5f\0\0\x1a\x03", 8, GFP_KERNEL); 132 + if (!enable) { 133 + dev_err(&interface->dev, "out of memory\n"); 134 + retval = -ENOMEM; 135 + goto error; 136 + } 137 + 138 + retval = usb_control_msg(udev, 139 + usb_sndctrlpipe(udev, 0), 140 + 0x09, 141 + 0x21, 142 + 0x200, 143 + 0, 144 + enable, 145 + 8, 146 + 2000); 147 + 148 + kfree(enable); 149 + if (retval != 8) 150 + goto error; 151 + } 164 152 165 153 dev_info(&interface->dev, "USB LED device now attached\n"); 166 154 return 0;