Added lirc.
[irreco.git] / lirc-0.8.4a / daemons / hw_hiddev.c
blobd0c939d52a6fd974db93d151157c64938ff894c6
1 /****************************************************************************
2 ** hw_hiddev.c *************************************************************
3 ****************************************************************************
5 * receive keycodes input via /dev/usb/hiddev...
6 *
7 * Copyright (C) 2002 Oliver Endriss <o.endriss@gmx.de>
8 * Copyright (C) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au>
9 * Copyright (C) 2005 William Uther <william.uther@nicta.com.au>
10 * Copyright (C) 2007 Brice DUBOST <ml@braice.net>
11 * Copyright (C) 2007 Benjamin Drung <benjamin.drung@gmail.com>
12 * Copyright (C) 2007 Stephen Williams <stephen.gw@gmail.com>
14 * Distribute under GPL version 2 or later.
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
22 #include <stdio.h>
23 #include <sys/fcntl.h>
24 #include <sys/ioctl.h>
26 #include <linux/types.h>
27 #include <linux/hiddev.h>
29 #include "hardware.h"
30 #include "ir_remote.h"
31 #include "lircd.h"
32 #include "receive.h"
34 #define TIMEOUT 20000
36 static int hiddev_init();
37 static int hiddev_deinit(void);
38 static int hiddev_decode(struct ir_remote *remote,
39 ir_code *prep, ir_code *codep, ir_code *postp,
40 int *repeat_flagp,
41 lirc_t *min_remaining_gapp,
42 lirc_t *max_remaining_gapp);
43 static char *hiddev_rec(struct ir_remote *remotes);
44 static int sb0540_init();
45 static char *sb0540_rec(struct ir_remote *remotes);
46 static char *macmini_rec(struct ir_remote *remotes);
47 static int samsung_init();
48 static char *samsung_rec(struct ir_remote *remotes);
50 struct hardware hw_dvico=
52 "/dev/usb/hiddev0", /* "device" */
53 -1, /* fd (device) */
54 LIRC_CAN_REC_LIRCCODE, /* features */
55 0, /* send_mode */
56 LIRC_MODE_LIRCCODE, /* rec_mode */
57 64, /* code_length */
58 hiddev_init, /* init_func */
59 NULL, /* config_func */
60 hiddev_deinit, /* deinit_func */
61 NULL, /* send_func */
62 hiddev_rec, /* rec_func */
63 hiddev_decode, /* decode_func */
64 NULL, /* ioctl_func */
65 NULL, /* readdata */
66 "dvico"
69 static int dvico_repeat_mask = 0x8000;
71 static int pre_code_length = 32;
72 static int main_code_length = 32;
74 static unsigned int pre_code;
75 static signed int main_code = 0;
77 static int repeat_flag = 0;
79 /* Remotec Mediamaster specific */
80 struct hardware hw_bw6130=
82 "/dev/usb/hid/hiddev0", /* "device" */
83 -1, /* fd (device) */
84 LIRC_CAN_REC_LIRCCODE, /* features */
85 0, /* send_mode */
86 LIRC_MODE_LIRCCODE, /* rec_mode */
87 64, /* code_length */
88 hiddev_init, /* init_func */
89 NULL, /* config_func */
90 hiddev_deinit, /* deinit_func */
91 NULL, /* send_func */
92 hiddev_rec, /* rec_func */
93 hiddev_decode, /* decode_func */
94 NULL, /* ioctl_func */
95 NULL, /* readdata */
96 "bw6130"
99 struct hardware hw_asusdh=
101 "/dev/usb/hiddev0", /* "device" */
102 -1, /* fd (device) */
103 LIRC_CAN_REC_LIRCCODE, /* features */
104 0, /* send_mode */
105 LIRC_MODE_LIRCCODE, /* rec_mode */
106 64, /* code_length */
107 hiddev_init, /* init_func */
108 NULL, /* config_func */
109 hiddev_deinit, /* deinit_func */
110 NULL, /* send_func */
111 hiddev_rec, /* rec_func */
112 hiddev_decode, /* decode_func */
113 NULL, /* ioctl_func */
114 NULL, /* readdata */
115 "asusdh" /* name */
118 #ifdef HAVE_LINUX_HIDDEV_FLAG_UREF
119 /* Creative USB IR Receiver (SB0540) */
120 struct hardware hw_sb0540=
122 "/dev/usb/hiddev0", /* "device" */
123 -1, /* fd (device) */
124 LIRC_CAN_REC_LIRCCODE, /* features */
125 0, /* send_mode */
126 LIRC_MODE_LIRCCODE, /* rec_mode */
127 32, /* code_length */
128 sb0540_init, /* init_func */
129 NULL, /* config_func */
130 hiddev_deinit, /* deinit_func */
131 NULL, /* send_func */
132 sb0540_rec, /* rec_func */
133 hiddev_decode, /* decode_func */
134 NULL, /* ioctl_func */
135 NULL, /* readdata */
136 "sb0540" /* name */
138 #endif
140 /* Apple Mac mini USB IR Receiver */
141 struct hardware hw_macmini=
143 "/dev/usb/hiddev0", /* "device" */
144 -1, /* fd (device) */
145 LIRC_CAN_REC_LIRCCODE, /* features */
146 0, /* send_mode */
147 LIRC_MODE_LIRCCODE, /* rec_mode */
148 32, /* code_length */
149 hiddev_init, /* init_func */
150 NULL, /* config_func */
151 hiddev_deinit, /* deinit_func */
152 NULL, /* send_func */
153 macmini_rec, /* rec_func */
154 hiddev_decode, /* decode_func */
155 NULL, /* ioctl_func */
156 NULL, /* readdata */
157 "macmini" /* name */
160 #ifdef HAVE_LINUX_HIDDEV_FLAG_UREF
161 /* Samsung USB IR Receiver */
162 struct hardware hw_samsung=
164 "/dev/usb/hiddev0", /* "device" */
165 -1, /* fd (device) */
166 LIRC_CAN_REC_LIRCCODE, /* features */
167 0, /* send_mode */
168 LIRC_MODE_LIRCCODE, /* rec_mode */
169 32, /* code_length */
170 samsung_init, /* init_func */
171 NULL, /* config_func */
172 hiddev_deinit, /* deinit_func */
173 NULL, /* send_func */
174 samsung_rec, /* rec_func */
175 hiddev_decode, /* decode_func */
176 NULL, /* ioctl_func */
177 NULL, /* readdata */
178 "samsung" /* name */
180 #endif
182 static int old_main_code = 0;
184 const static int mousegrid[9][9]=
185 {{0x00,0x15,0x15,0x16,0x16,0x16,0x16,0x17,0x17},
186 {0x05,0x0d,0x11,0x12,0x12,0x12,0x16,0x17,0x17},
187 {0x05,0x09,0x0e,0x12,0x12,0x12,0x13,0x13,0x13},
188 {0x06,0x0a,0x0a,0x0e,0x0e,0x12,0x13,0x13,0x13},
189 {0x06,0x0a,0x0a,0x0e,0x0e,0x0f,0x13,0x13,0x13},
190 {0x06,0x0a,0x0a,0x0a,0x0f,0x0f,0x0f,0x0f,0x13},
191 {0x06,0x06,0x0b,0x0b,0x0b,0x0f,0x0f,0x0f,0x0f},
192 {0x07,0x07,0x0b,0x0b,0x0b,0x0f,0x0f,0x0f,0x0f},
193 {0x07,0x07,0x0b,0x0b,0x0b,0x0b,0x0f,0x0f,0x0f}};
196 int hiddev_init()
198 logprintf(LOG_INFO, "initializing '%s'", hw.device);
200 if ((hw.fd = open(hw.device, O_RDONLY)) < 0) {
201 logprintf(LOG_ERR, "unable to open '%s'", hw.device);
202 return 0;
205 return 1;
209 int hiddev_deinit(void)
211 if(hw.fd != -1)
213 logprintf(LOG_INFO, "closing '%s'", hw.device);
214 close(hw.fd);
215 hw.fd=-1;
217 return 1;
221 int hiddev_decode(struct ir_remote *remote,
222 ir_code *prep, ir_code *codep, ir_code *postp,
223 int *repeat_flagp,
224 lirc_t *min_remaining_gapp,
225 lirc_t *max_remaining_gapp)
227 LOGPRINTF(1, "hiddev_decode");
229 if(!map_code(remote,prep,codep,postp,
230 pre_code_length,pre_code,
231 main_code_length,main_code,
232 0,0))
234 return(0);
237 LOGPRINTF(1, "lirc code: 0x%X", *codep);
239 *repeat_flagp = repeat_flag;
240 *min_remaining_gapp = 0;
241 *max_remaining_gapp = 0;
243 return 1;
247 char *hiddev_rec(struct ir_remote *remotes)
249 struct hiddev_event event;
250 struct hiddev_event asus_events[8];
251 int rd;
252 /* Remotec Mediamaster specific */
253 static int wheel_count = 0;
254 static int x_movement = 0;
255 static struct timeval time_of_last_code;
256 int y_movement=0;
257 int x_direction=0;
258 int y_direction=0;
259 int i;
261 LOGPRINTF(1, "hiddev_rec");
263 rd = read(hw.fd, &event, sizeof event);
264 if (rd != sizeof event) {
265 logprintf(LOG_ERR, "error reading '%s'", hw.device);
266 logperror(LOG_ERR, NULL);
267 hiddev_deinit();
268 return 0;
271 LOGPRINTF(1, "hid 0x%X value 0x%X", event.hid, event.value);
273 pre_code = event.hid;
274 main_code = event.value;
277 * This stuff is probably dvico specific.
278 * I don't have any other hid devices to test...
280 * See further for the Asus DH specific code
284 if (event.hid == 0x90001)
286 /* This is the DVICO Remote. It actually sends two hid
287 * events, the first of which has 0 as the hid.value and
288 * is of no use in decoding the remote code. If we
289 * receive this type of event, read the next event
290 * (which should be immediately available) and
291 * use it to obtain the remote code.
294 LOGPRINTF(1, "This is another type Dvico - sends two codes");
295 if(!waitfordata(TIMEOUT))
297 logprintf(LOG_ERR,"timeout reading next event");
298 return(NULL);
300 rd = read(hw.fd, &event, sizeof event);
301 if (rd != sizeof event) {
302 logprintf(LOG_ERR, "error reading '%s'",
303 hw.device);
304 return 0;
306 pre_code = event.hid;
307 main_code = event.value;
310 if (event.hid == 0x10046) {
311 struct timeval now;
312 repeat_flag = (main_code & dvico_repeat_mask);
313 main_code = (main_code & ~dvico_repeat_mask);
315 gettimeofday (&now, NULL);
317 /* The hardware dongle for the dvico remote sends spurious */
318 /* repeats of the last code received it it gets a false */
319 /* trigger from some other IR source, or if it misses */
320 /* receiving the first code of a new button press. To */
321 /* minimise the impact of this hardware bug, ignore any */
322 /* repeats that occur more than half a second after the */
323 /* previous valid code because it is likely that they are */
324 /* spurious. */
326 if(repeat_flag)
328 if(time_elapsed(&time_of_last_code, &now) > 500000)
330 return NULL;
333 time_of_last_code = now;
335 LOGPRINTF(1, "main 0x%X repeat flag 0x%X", main_code, repeat_flag);
336 return decode_all(remotes);
337 #if 0
338 /* the following code could be used to recreate the
339 real codes of the remote control (currently
340 verified for the MCE remote only) */
341 ir_code pre, main;
343 pre_code_length = 16;
344 main_code_length = 16;
346 pre = event.value&0xff;
347 pre_code = reverse(~pre, 8)<<8 | reverse(pre, 8);
349 repeat_flag = (event.value & dvico_repeat_mask);
351 main = (event.value&0x7f00) >> 8;
352 main_code = reverse(main, 8)<<8 | reverse(~main, 8);
353 return decode_all(remotes);
354 #endif
357 /* Asus DH remote specific code */
358 else if (event.hid == 0xFF000000)
360 LOGPRINTF(1, "This is an asus P5 DH remote, "
361 "we read the other events");
362 asus_events[0]=event;
363 for (i=1;i<8;i++)
365 if(!waitfordata(TIMEOUT))
367 logprintf(LOG_ERR,"timeout reading byte %d",i);
368 return(NULL);
370 rd = read(hw.fd, &asus_events[i], sizeof event);
371 if (rd != sizeof event) {
372 logprintf(LOG_ERR, "error reading '%s'",
373 hw.device);
374 return 0;
377 for (i=0;i<8;i++)
379 LOGPRINTF(1, "Event number %d hid 0x%X value 0x%X",
380 i, asus_events[i].hid,
381 asus_events[i].value);
383 pre_code = asus_events[1].hid;
384 main_code = asus_events[1].value;
385 if (main_code)
387 return decode_all(remotes);
391 /* Remotec Mediamaster specific code */
392 /* Y-Coordinate,
393 second event field after button code (wheel_count==2) */
394 if (wheel_count == 2) {
395 y_movement = event.value & 0x0000000F;
396 y_direction = (event.value & 0x000000F0) >> 2;
397 x_direction = (x_movement & 0x000000F0) >> 1;
398 x_movement &= 0x0000000F;
400 if(x_movement > 8 || y_movement > 8)
402 logprintf(LOG_ERR, "unexpected coordinates: %u,%u",
403 x_movement, y_movement);
404 return NULL;
407 main_code=mousegrid[x_movement][y_movement];
408 main_code |= x_direction;
409 main_code |= y_direction;
410 main_code |= 0x00000080; //just to make it unique
412 wheel_count=0;
413 pre_code=0xFFA10003; //so it gets recognized
414 return decode_all(remotes);
416 /* X-Coordinate,
417 first event field after button code (wheel_count==1) */
418 else if (wheel_count==1) {
419 x_movement=event.value;
421 wheel_count=2;
422 return NULL;
425 if ((event.hid == 0xFFA10003) &&
426 (event.value != 0xFFFFFFFF) &&
427 (event.value != 0xFFFFFFAA))
429 if (old_main_code == main_code) repeat_flag = 1;
430 old_main_code = main_code;
431 if (main_code==0x40) { /* the mousedial has been touched */
432 wheel_count=1;
433 return 0;
435 return decode_all(remotes);
437 else if ((event.hid == 0xFFA10003) && (event.value == 0xFFFFFFAA)) {
438 repeat_flag = 0;
439 old_main_code = 0;
442 /* insert decoding logic for other hiddev remotes here */
444 return 0;
448 * Creative USB IR Receiver specific code
450 * based on creative_rm1500_usb-0.1 from http://ecto.teftin.net/rm1500.html
451 * which is written by Stan Sawa teftin(at)gmail.com
455 #ifdef HAVE_LINUX_HIDDEV_FLAG_UREF
456 int sb0540_init()
458 int rv = hiddev_init();
460 if (rv == 1) {
461 /* we want to get info on each report received from device */
462 int flags = HIDDEV_FLAG_UREF | HIDDEV_FLAG_REPORT;
463 if (ioctl(hw.fd, HIDIOCSFLAG, &flags)) {
464 return 0;
468 return rv;
471 char *sb0540_rec(struct ir_remote *remotes)
474 * at this point, each read from opened file/device should return
475 * hiddev_usage_ref structure
479 ir_code code;
480 ssize_t rd;
481 struct hiddev_usage_ref uref;
483 LOGPRINTF(1, "sb0540_rec");
485 pre_code_length = 16;
486 main_code_length = 16;
487 pre_code = 0x8322;
488 repeat_flag = 0;
490 rd = read(hw.fd, &uref, sizeof(uref));
491 if (rd < 0) {
492 logprintf(LOG_ERR, "error reading '%s'", hw.device);
493 logperror(LOG_ERR, NULL);
494 hiddev_deinit();
495 return 0;
498 if (uref.field_index == HID_FIELD_INDEX_NONE) {
500 * we get this when the new report has been send from
501 * device at this point we have the uref structure
502 * prefilled with correct report type and id
506 /* this got guessed by getting the device report
507 descriptor (function devinfo in source) */
508 uref.field_index = 0; /* which field of report */
509 /* this got guessed by taking all values from device
510 and checking which ones are changing ;) */
511 uref.usage_index = 3; /* which usage entry of field */
513 /* fetch the usage code for given indexes */
514 ioctl(hw.fd, HIDIOCGUCODE, &uref, sizeof(uref));
515 /* fetch the value from report */
516 ioctl(hw.fd, HIDIOCGUSAGE, &uref, sizeof(uref));
517 /* now we have the key */
519 code = reverse(uref.value, 8);
520 main_code = (code << 8) + ((~code)&0xff);
522 return decode_all(remotes);
525 * we are not interested in any other events, as they are only
526 * giving info what changed in report and this not always
527 * works, is complicated, doesn't output anything sensible on
528 * repeated key and we already have all the info from real
529 * report
533 return 0;
535 #endif
538 * Apple Mac mini USB IR Receiver specific code.
542 char *macmini_rec(struct ir_remote *remotes)
544 static struct timeval time_of_last_code;
545 struct timeval now;
546 struct hiddev_event ev[4];
547 int rd;
548 int i;
550 LOGPRINTF(1, "macmini_rec");
552 for (i=0;i<4;i++)
554 if(i>0 && !waitfordata(TIMEOUT))
556 logprintf(LOG_ERR,"timeout reading byte %d",i);
557 return(NULL);
559 rd = read(hw.fd, &ev[i], sizeof(ev[i]));
560 if (rd != sizeof(ev[i])) {
561 logprintf(LOG_ERR, "error reading '%s'", hw.device);
562 hiddev_deinit();
563 return 0;
567 gettimeofday (&now, NULL);
568 /* Record the code */
569 pre_code_length = 0;
570 pre_code = 0;
571 main_code = (ev[0].value << 24) + (ev[1].value << 16) +
572 (ev[2].value << 8) + (ev[3].value << 0);
573 if (main_code == 0)
575 /* some variants seem to send 0 to indicate repeats */
576 if(time_elapsed(&time_of_last_code, &now) > 500000)
578 /* but some send 0 if they receive codes from
579 a different remote, so only send repeats if
580 close to the original code */
581 return NULL;
583 main_code = old_main_code;
585 if (old_main_code == main_code)
587 repeat_flag = 1;
589 old_main_code = main_code;
590 time_of_last_code = now;
592 return decode_all(remotes);
596 * Samsung/Cypress USB IR Receiver specific code
597 * (e.g. used in Satelco EasyWatch remotes)
599 * Based on sb0540 code.
600 * Written by r.schedel (at)yahoo.de
604 #ifdef HAVE_LINUX_HIDDEV_FLAG_UREF
605 int samsung_init()
607 int rv = hiddev_init();
609 if (rv == 1) {
610 /* we want to get info on each report received from device */
611 int flags = HIDDEV_FLAG_UREF | HIDDEV_FLAG_REPORT;
612 if (ioctl(hw.fd, HIDIOCSFLAG, &flags)) {
613 return 0;
617 return rv;
620 char *samsung_rec(struct ir_remote *remotes)
623 * at this point, each read from opened file/device should return
624 * hiddev_usage_ref structure
628 ssize_t rd;
629 struct hiddev_usage_ref uref;
631 LOGPRINTF(1, "samsung_rec");
633 pre_code_length = 0;
634 main_code_length = 32;
635 pre_code = 0;
636 repeat_flag = 0;
638 rd = read(hw.fd, &uref, sizeof(uref));
639 if (rd < 0) {
640 logprintf(LOG_ERR, "error reading '%s'", hw.device);
641 logperror(LOG_ERR, NULL);
642 hiddev_deinit();
643 return 0;
646 if (uref.field_index == HID_FIELD_INDEX_NONE) {
648 * we get this when the new report has been send from
649 * device at this point we have the uref structure
650 * prefilled with correct report type and id
654 LOGPRINTF(2, "hiddev event: reptype %d, repid %d, field"
655 " idx %d, usage idx %x, usage code %x, val %d\n",
656 uref.report_type, uref.report_id, uref.field_index,
657 uref.usage_index, uref.usage_code, uref.value);
659 switch (uref.report_id)
661 case 1: /* USB standard keyboard usage page */
663 /* This page reports cursor keys */
664 LOGPRINTF(3, "Keyboard (standard)\n");
666 /* populate required field number */
667 uref.field_index = 1;
668 uref.usage_index = 0;
670 /* fetch the usage code for given indexes */
671 ioctl(hw.fd, HIDIOCGUCODE, &uref, sizeof(uref));
672 /* fetch the value from report */
673 ioctl(hw.fd, HIDIOCGUSAGE, &uref, sizeof(uref));
674 /* now we have the key */
676 main_code = (uref.usage_code & 0xffff0000)
677 | uref.value;
679 LOGPRINTF(3, "Main code: %x\n", main_code);
680 return decode_all(remotes);
682 break;
684 case 3: /* USB generic desktop usage page */
686 /* This page reports power key
687 * (via SystemControl SLEEP)
689 LOGPRINTF(3, "Generic desktop (standard)\n");
691 /* populate required field number */
692 uref.field_index = 0;
693 uref.usage_index = 1; /* or 7 */
695 /* fetch the usage code for given indexes */
696 ioctl(hw.fd, HIDIOCGUCODE, &uref, sizeof(uref));
697 /* fetch the value from report */
698 ioctl(hw.fd, HIDIOCGUSAGE, &uref, sizeof(uref));
699 /* now we have the key */
701 main_code = (uref.usage_code & 0xffff0000)
702 | uref.value;
704 LOGPRINTF(3, "Main code: %x\n", main_code);
705 return decode_all(remotes);
707 break;
709 case 4: /* Samsung proprietary usage page */
711 /* This page reports all other keys.
712 * It is the only page with keys we cannot
713 * receive via HID input layer directly.
714 * This is why we need to implement all of
715 * this hiddev stuff here.
717 int maxbit, i;
718 LOGPRINTF(3, "Samsung usage (proprietary)\n");
720 /* According to tests, at most one of the
721 * 48 key bits can be set.
722 * Due to the required kernel patch, the
723 * 48 bits are received in the report as
724 * 6 usages a 8 bit.
725 * We want to avoid using a 64 bit value
726 * if max. one bit is set anyway.
727 * Therefore, we use the (highest) set bit
728 * as final key value.
730 * Now fetch each usage and
731 * combine to single value.
733 for (i=0, maxbit=1; i<6; i++, maxbit += 8)
735 unsigned int tmpval = 0;
737 uref.field_index = 0;
738 uref.usage_index = i;
740 /* fetch the usage code for given indexes */
741 ioctl(hw.fd, HIDIOCGUCODE, &uref, sizeof(uref));
742 /* fetch the value from report */
743 ioctl(hw.fd, HIDIOCGUSAGE, &uref, sizeof(uref));
744 /* now we have the key byte */
745 tmpval = uref.value & 0xff; /* 8 bit */
747 if (i == 0)
749 /* fetch usage code from first usage
750 * (should be 0xffcc)
752 main_code = (uref.usage_code & 0xffff0000);
755 /* find index of highest bit with binary search */
756 if (tmpval > 0)
758 if ( tmpval & 0xf0 ) { maxbit += 4; tmpval >>= 4; }
759 if ( tmpval & 0x0c ) { maxbit += 2; tmpval >>= 2; }
760 if ( tmpval & 0x02 ) { maxbit += 1; }
761 main_code |= maxbit;
762 /* We found a/the pressed key, so break out */
763 break;
767 LOGPRINTF(3, "Main code: %x\n", main_code);
769 /* decode combined key value */
770 return decode_all(remotes);
772 break;
774 default:
775 /* Unknown/unsupported report id.
776 * Should not happen because remaining reports
777 * from report descriptor seem to be unused by remote.
779 logprintf(LOG_ERR, "Unexpected report id %d", uref.report_id);
780 break;
784 * we are not interested in any other events, as they are only
785 * giving info what changed in report and this not always
786 * works, is complicated, doesn't output anything sensible on
787 * repeated key and we already have all the info from real
788 * report
792 return 0;
794 #endif