diff options
author | Heiner Kallweit <hkallweit1@gmail.com> | 2016-07-04 15:45:54 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2016-07-07 05:17:12 -0400 |
commit | de9086509e716e9797f401dd260d5b4bdd2244c7 (patch) | |
tree | ce91d0f0b88f92b174c5aeaa10d6c47293adfa95 | |
parent | 34d9810b316b6de11a801a30339c070d1798a7b0 (diff) |
HID: hid-led: add support for Delcom Visual Signal Indicator G2
Add support for the HID-compliant Delcom Visual Signal Indicator
generation 2 devices.
Successfully tested with part no 904000 from the family of these devices.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/Kconfig | 1 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 1 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 3 | ||||
-rw-r--r-- | drivers/hid/hid-led.c | 98 |
4 files changed, 103 insertions, 0 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 8b1eb47930bc..e33ccefe3e54 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -397,6 +397,7 @@ config HID_LED | |||
397 | - Riso Kagaku Webmail Notifier | 397 | - Riso Kagaku Webmail Notifier |
398 | - Dream Cheeky Webmail Notifier and Friends Alert | 398 | - Dream Cheeky Webmail Notifier and Friends Alert |
399 | - ThingM blink(1) | 399 | - ThingM blink(1) |
400 | - Delcom Visual Signal Indicator Generation 2 | ||
400 | 401 | ||
401 | To compile this driver as a module, choose M here: the | 402 | To compile this driver as a module, choose M here: the |
402 | module will be called hid-led. | 403 | module will be called hid-led. |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index eb674ce75fab..f808ae71f9a1 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1877,6 +1877,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1877 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, | 1877 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, |
1878 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_4) }, | 1878 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_4) }, |
1879 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, | 1879 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, |
1880 | { HID_USB_DEVICE(USB_VENDOR_ID_DELCOM, USB_DEVICE_ID_DELCOM_VISUAL_IND) }, | ||
1880 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, | 1881 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, |
1881 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) }, | 1882 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) }, |
1882 | { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_WN) }, | 1883 | { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_WN) }, |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index e104abae0dad..ffefbd09fb4c 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -296,6 +296,9 @@ | |||
296 | #define USB_VENDOR_ID_DEALEXTREAME 0x10c5 | 296 | #define USB_VENDOR_ID_DEALEXTREAME 0x10c5 |
297 | #define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a | 297 | #define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a |
298 | 298 | ||
299 | #define USB_VENDOR_ID_DELCOM 0x0fc5 | ||
300 | #define USB_DEVICE_ID_DELCOM_VISUAL_IND 0xb080 | ||
301 | |||
299 | #define USB_VENDOR_ID_DELORME 0x1163 | 302 | #define USB_VENDOR_ID_DELORME 0x1163 |
300 | #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 | 303 | #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 |
301 | #define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 | 304 | #define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 |
diff --git a/drivers/hid/hid-led.c b/drivers/hid/hid-led.c index fce2a03cb647..d793ecefb8b6 100644 --- a/drivers/hid/hid-led.c +++ b/drivers/hid/hid-led.c | |||
@@ -27,6 +27,7 @@ enum hidled_type { | |||
27 | RISO_KAGAKU, | 27 | RISO_KAGAKU, |
28 | DREAM_CHEEKY, | 28 | DREAM_CHEEKY, |
29 | THINGM, | 29 | THINGM, |
30 | DELCOM, | ||
30 | }; | 31 | }; |
31 | 32 | ||
32 | static unsigned const char riso_kagaku_tbl[] = { | 33 | static unsigned const char riso_kagaku_tbl[] = { |
@@ -43,6 +44,28 @@ static unsigned const char riso_kagaku_tbl[] = { | |||
43 | 44 | ||
44 | #define RISO_KAGAKU_IX(r, g, b) riso_kagaku_tbl[((r)?1:0)+((g)?2:0)+((b)?4:0)] | 45 | #define RISO_KAGAKU_IX(r, g, b) riso_kagaku_tbl[((r)?1:0)+((g)?2:0)+((b)?4:0)] |
45 | 46 | ||
47 | union delcom_packet { | ||
48 | __u8 data[8]; | ||
49 | struct { | ||
50 | __u8 major_cmd; | ||
51 | __u8 minor_cmd; | ||
52 | __u8 data_lsb; | ||
53 | __u8 data_msb; | ||
54 | } tx; | ||
55 | struct { | ||
56 | __u8 cmd; | ||
57 | } rx; | ||
58 | struct { | ||
59 | __le16 family_code; | ||
60 | __le16 security_code; | ||
61 | __u8 fw_version; | ||
62 | } fw; | ||
63 | }; | ||
64 | |||
65 | #define DELCOM_GREEN_LED 0 | ||
66 | #define DELCOM_RED_LED 1 | ||
67 | #define DELCOM_BLUE_LED 2 | ||
68 | |||
46 | struct hidled_device; | 69 | struct hidled_device; |
47 | struct hidled_rgb; | 70 | struct hidled_rgb; |
48 | 71 | ||
@@ -244,6 +267,68 @@ static int thingm_init(struct hidled_device *ldev) | |||
244 | return 0; | 267 | return 0; |
245 | } | 268 | } |
246 | 269 | ||
270 | static inline int delcom_get_lednum(const struct hidled_led *led) | ||
271 | { | ||
272 | if (led == &led->rgb->red) | ||
273 | return DELCOM_RED_LED; | ||
274 | else if (led == &led->rgb->green) | ||
275 | return DELCOM_GREEN_LED; | ||
276 | else | ||
277 | return DELCOM_BLUE_LED; | ||
278 | } | ||
279 | |||
280 | static int delcom_enable_led(struct hidled_led *led) | ||
281 | { | ||
282 | union delcom_packet dp = { .tx.major_cmd = 101, .tx.minor_cmd = 12 }; | ||
283 | |||
284 | dp.tx.data_lsb = 1 << delcom_get_lednum(led); | ||
285 | dp.tx.data_msb = 0; | ||
286 | |||
287 | return hidled_send(led->rgb->ldev, dp.data); | ||
288 | } | ||
289 | |||
290 | static int delcom_set_pwm(struct hidled_led *led) | ||
291 | { | ||
292 | union delcom_packet dp = { .tx.major_cmd = 101, .tx.minor_cmd = 34 }; | ||
293 | |||
294 | dp.tx.data_lsb = delcom_get_lednum(led); | ||
295 | dp.tx.data_msb = led->cdev.brightness; | ||
296 | |||
297 | return hidled_send(led->rgb->ldev, dp.data); | ||
298 | } | ||
299 | |||
300 | static int delcom_write(struct led_classdev *cdev, enum led_brightness br) | ||
301 | { | ||
302 | struct hidled_led *led = to_hidled_led(cdev); | ||
303 | int ret; | ||
304 | |||
305 | /* | ||
306 | * enable LED | ||
307 | * We can't do this in the init function already because the device | ||
308 | * is internally reset later. | ||
309 | */ | ||
310 | ret = delcom_enable_led(led); | ||
311 | if (ret) | ||
312 | return ret; | ||
313 | |||
314 | return delcom_set_pwm(led); | ||
315 | } | ||
316 | |||
317 | static int delcom_init(struct hidled_device *ldev) | ||
318 | { | ||
319 | union delcom_packet dp = { .rx.cmd = 104 }; | ||
320 | int ret; | ||
321 | |||
322 | ret = hidled_recv(ldev, dp.data); | ||
323 | if (ret) | ||
324 | return ret; | ||
325 | /* | ||
326 | * Several Delcom devices share the same USB VID/PID | ||
327 | * Check for family id 2 for Visual Signal Indicator | ||
328 | */ | ||
329 | return dp.fw.family_code == 2 ? 0 : -ENODEV; | ||
330 | } | ||
331 | |||
247 | static const struct hidled_config hidled_configs[] = { | 332 | static const struct hidled_config hidled_configs[] = { |
248 | { | 333 | { |
249 | .type = RISO_KAGAKU, | 334 | .type = RISO_KAGAKU, |
@@ -277,6 +362,17 @@ static const struct hidled_config hidled_configs[] = { | |||
277 | .init = thingm_init, | 362 | .init = thingm_init, |
278 | .write = thingm_write, | 363 | .write = thingm_write, |
279 | }, | 364 | }, |
365 | { | ||
366 | .type = DELCOM, | ||
367 | .name = "Delcom Visual Signal Indicator G2", | ||
368 | .short_name = "delcom", | ||
369 | .max_brightness = 100, | ||
370 | .num_leds = 1, | ||
371 | .report_size = 8, | ||
372 | .report_type = RAW_REQUEST, | ||
373 | .init = delcom_init, | ||
374 | .write = delcom_write, | ||
375 | }, | ||
280 | }; | 376 | }; |
281 | 377 | ||
282 | static int hidled_init_led(struct hidled_led *led, const char *color_name, | 378 | static int hidled_init_led(struct hidled_led *led, const char *color_name, |
@@ -382,6 +478,8 @@ static const struct hid_device_id hidled_table[] = { | |||
382 | USB_DEVICE_ID_DREAM_CHEEKY_FA), .driver_data = DREAM_CHEEKY }, | 478 | USB_DEVICE_ID_DREAM_CHEEKY_FA), .driver_data = DREAM_CHEEKY }, |
383 | { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, | 479 | { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, |
384 | USB_DEVICE_ID_BLINK1), .driver_data = THINGM }, | 480 | USB_DEVICE_ID_BLINK1), .driver_data = THINGM }, |
481 | { HID_USB_DEVICE(USB_VENDOR_ID_DELCOM, | ||
482 | USB_DEVICE_ID_DELCOM_VISUAL_IND), .driver_data = DELCOM }, | ||
385 | { } | 483 | { } |
386 | }; | 484 | }; |
387 | MODULE_DEVICE_TABLE(hid, hidled_table); | 485 | MODULE_DEVICE_TABLE(hid, hidled_table); |