aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMelchior FRANZ <mfranz@aon.at>2010-12-21 20:04:33 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-12-21 23:48:21 -0500
commit73bc7d315f56e260071bdb5f15e25b53bddc1402 (patch)
tree20e676a2eb44f2b5eba6bee581a74ccca6a60cde /drivers
parentc466cd2bb9cee2e576fc9663b828f51e322d7b4b (diff)
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hid/hid-core.c1
-rw-r--r--drivers/hid/hid-ids.h2
-rw-r--r--drivers/usb/misc/usbled.c118
3 files changed, 93 insertions, 28 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 88cb04e7962b..ed1adc20c8eb 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1604,6 +1604,7 @@ static const struct hid_device_id hid_ignore_list[] = {
1604 { HID_USB_DEVICE(USB_VENDOR_ID_DEALEXTREAME, USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701) }, 1604 { HID_USB_DEVICE(USB_VENDOR_ID_DEALEXTREAME, USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701) },
1605 { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, 1605 { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) },
1606 { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, 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 { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, 1608 { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
1608 { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) }, 1609 { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) },
1609 { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) }, 1610 { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 3341baa86a30..5a559de22282 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -200,6 +200,8 @@
200#define USB_VENDOR_ID_ELECOM 0x056e 200#define USB_VENDOR_ID_ELECOM 0x056e
201#define USB_DEVICE_ID_ELECOM_BM084 0x0061 201#define USB_DEVICE_ID_ELECOM_BM084 0x0061
202 202
203#define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34
204
203#define USB_VENDOR_ID_ELO 0x04E7 205#define USB_VENDOR_ID_ELO 0x04E7
204#define USB_DEVICE_ID_ELO_TS2700 0x0020 206#define USB_DEVICE_ID_ELO_TS2700 0x0020
205 207
diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c
index c96f51de1696..1732d9bc097e 100644
--- a/drivers/usb/misc/usbled.c
+++ b/drivers/usb/misc/usbled.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * USB LED driver - 1.1 2 * USB LED driver
3 * 3 *
4 * Copyright (C) 2004 Greg Kroah-Hartman (greg@kroah.com) 4 * Copyright (C) 2004 Greg Kroah-Hartman (greg@kroah.com)
5 * 5 *
@@ -20,12 +20,17 @@
20#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com" 20#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com"
21#define DRIVER_DESC "USB LED Driver" 21#define DRIVER_DESC "USB LED Driver"
22 22
23#define VENDOR_ID 0x0fc5 23enum led_type {
24#define PRODUCT_ID 0x1223 24 DELCOM_VISUAL_SIGNAL_INDICATOR,
25 DREAM_CHEEKY_WEBMAIL_NOTIFIER,
26};
25 27
26/* table of devices that work with this driver */ 28/* table of devices that work with this driver */
27static const struct usb_device_id id_table[] = { 29static 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};
31MODULE_DEVICE_TABLE (usb, id_table); 36MODULE_DEVICE_TABLE (usb, id_table);
@@ -35,15 +40,12 @@ struct usb_led {
35 unsigned char blue; 40 unsigned char blue;
36 unsigned char red; 41 unsigned char red;
37 unsigned char green; 42 unsigned char green;
43 enum led_type type;
38}; 44};
39 45
40#define BLUE 0x04
41#define RED 0x02
42#define GREEN 0x01
43static void change_color(struct usb_led *led) 46static void change_color(struct usb_led *led)
44{ 47{
45 int retval; 48 int retval;
46 unsigned char color = 0x07;
47 unsigned char *buffer; 49 unsigned char *buffer;
48 50
49 buffer = kmalloc(8, GFP_KERNEL); 51 buffer = kmalloc(8, GFP_KERNEL);
@@ -52,25 +54,59 @@ static void change_color(struct usb_led *led)
52 return; 54 return;
53 } 55 }
54 56
55 if (led->blue) 57 switch (led->type) {
56 color &= ~(BLUE); 58 case DELCOM_VISUAL_SIGNAL_INDICATOR: {
57 if (led->red) 59 unsigned char color = 0x07;
58 color &= ~(RED); 60
59 if (led->green) 61 if (led->blue)
60 color &= ~(GREEN); 62 color &= ~0x04;
61 dev_dbg(&led->udev->dev, 63 if (led->red)
62 "blue = %d, red = %d, green = %d, color = %.2x\n", 64 color &= ~0x02;
63 led->blue, led->red, led->green, color); 65 if (led->green)
64 66 color &= ~0x01;
65 retval = usb_control_msg(led->udev, 67 dev_dbg(&led->udev->dev,
66 usb_sndctrlpipe(led->udev, 0), 68 "blue = %d, red = %d, green = %d, color = %.2x\n",
67 0x12, 69 led->blue, led->red, led->green, color);
68 0xc8, 70
69 (0x02 * 0x100) + 0x0a, 71 retval = usb_control_msg(led->udev,
70 (0x00 * 0x100) + color, 72 usb_sndctrlpipe(led->udev, 0),
71 buffer, 73 0x12,
72 8, 74 0xc8,
73 2000); 75 (0x02 * 0x100) + 0x0a,
76 (0x00 * 0x100) + color,
77 buffer,
78 8,
79 2000);
80 break;
81 }
82
83 case DREAM_CHEEKY_WEBMAIL_NOTIFIER:
84 dev_dbg(&led->udev->dev,
85 "red = %d, green = %d, blue = %d\n",
86 led->red, led->green, led->blue);
87
88 buffer[0] = led->red;
89 buffer[1] = led->green;
90 buffer[2] = led->blue;
91 buffer[3] = buffer[4] = buffer[5] = 0;
92 buffer[6] = 0x1a;
93 buffer[7] = 0x05;
94
95 retval = usb_control_msg(led->udev,
96 usb_sndctrlpipe(led->udev, 0),
97 0x09,
98 0x21,
99 0x200,
100 0,
101 buffer,
102 8,
103 2000);
104 break;
105
106 default:
107 dev_err(&led->udev->dev, "unknown device type %d\n", led->type);
108 }
109
74 if (retval) 110 if (retval)
75 dev_dbg(&led->udev->dev, "retval = %d\n", retval); 111 dev_dbg(&led->udev->dev, "retval = %d\n", retval);
76 kfree(buffer); 112 kfree(buffer);
@@ -107,11 +143,12 @@ static int led_probe(struct usb_interface *interface, const struct usb_device_id
107 143
108 dev = kzalloc(sizeof(struct usb_led), GFP_KERNEL); 144 dev = kzalloc(sizeof(struct usb_led), GFP_KERNEL);
109 if (dev == NULL) { 145 if (dev == NULL) {
110 dev_err(&interface->dev, "Out of memory\n"); 146 dev_err(&interface->dev, "out of memory\n");
111 goto error_mem; 147 goto error_mem;
112 } 148 }
113 149
114 dev->udev = usb_get_dev(udev); 150 dev->udev = usb_get_dev(udev);
151 dev->type = id->driver_info;
115 152
116 usb_set_intfdata (interface, dev); 153 usb_set_intfdata (interface, dev);
117 154
@@ -125,6 +162,31 @@ static int led_probe(struct usb_interface *interface, const struct usb_device_id
125 if (retval) 162 if (retval)
126 goto error; 163 goto error;
127 164
165 if (dev->type == DREAM_CHEEKY_WEBMAIL_NOTIFIER) {
166 unsigned char *enable;
167
168 enable = kmemdup("\x1f\x02\0\x5f\0\0\x1a\x03", 8, GFP_KERNEL);
169 if (!enable) {
170 dev_err(&interface->dev, "out of memory\n");
171 retval = -ENOMEM;
172 goto error;
173 }
174
175 retval = usb_control_msg(udev,
176 usb_sndctrlpipe(udev, 0),
177 0x09,
178 0x21,
179 0x200,
180 0,
181 enable,
182 8,
183 2000);
184
185 kfree(enable);
186 if (retval != 8)
187 goto error;
188 }
189
128 dev_info(&interface->dev, "USB LED device now attached\n"); 190 dev_info(&interface->dev, "USB LED device now attached\n");
129 return 0; 191 return 0;
130 192