1 /****************************************************************************
2 ** hw_hiddev.c *************************************************************
3 ****************************************************************************
5 * receive keycodes input via /dev/usb/hiddev...
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.
23 #include <sys/fcntl.h>
24 #include <sys/ioctl.h>
26 #include <linux/types.h>
27 #include <linux/hiddev.h>
30 #include "ir_remote.h"
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
,
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" */
54 LIRC_CAN_REC_LIRCCODE
, /* features */
56 LIRC_MODE_LIRCCODE
, /* rec_mode */
58 hiddev_init
, /* init_func */
59 NULL
, /* config_func */
60 hiddev_deinit
, /* deinit_func */
62 hiddev_rec
, /* rec_func */
63 hiddev_decode
, /* decode_func */
64 NULL
, /* ioctl_func */
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" */
84 LIRC_CAN_REC_LIRCCODE
, /* features */
86 LIRC_MODE_LIRCCODE
, /* rec_mode */
88 hiddev_init
, /* init_func */
89 NULL
, /* config_func */
90 hiddev_deinit
, /* deinit_func */
92 hiddev_rec
, /* rec_func */
93 hiddev_decode
, /* decode_func */
94 NULL
, /* ioctl_func */
99 struct hardware hw_asusdh
=
101 "/dev/usb/hiddev0", /* "device" */
102 -1, /* fd (device) */
103 LIRC_CAN_REC_LIRCCODE
, /* features */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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}};
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
);
209 int hiddev_deinit(void)
213 logprintf(LOG_INFO
, "closing '%s'", hw
.device
);
221 int hiddev_decode(struct ir_remote
*remote
,
222 ir_code
*prep
, ir_code
*codep
, ir_code
*postp
,
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
,
237 LOGPRINTF(1, "lirc code: 0x%X", *codep
);
239 *repeat_flagp
= repeat_flag
;
240 *min_remaining_gapp
= 0;
241 *max_remaining_gapp
= 0;
247 char *hiddev_rec(struct ir_remote
*remotes
)
249 struct hiddev_event event
;
250 struct hiddev_event asus_events
[8];
252 /* Remotec Mediamaster specific */
253 static int wheel_count
= 0;
254 static int x_movement
= 0;
255 static struct timeval time_of_last_code
;
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
);
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");
300 rd
= read(hw
.fd
, &event
, sizeof event
);
301 if (rd
!= sizeof event
) {
302 logprintf(LOG_ERR
, "error reading '%s'",
306 pre_code
= event
.hid
;
307 main_code
= event
.value
;
310 if (event
.hid
== 0x10046) {
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 */
328 if(time_elapsed(&time_of_last_code
, &now
) > 500000)
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
);
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) */
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
);
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
;
365 if(!waitfordata(TIMEOUT
))
367 logprintf(LOG_ERR
,"timeout reading byte %d",i
);
370 rd
= read(hw
.fd
, &asus_events
[i
], sizeof event
);
371 if (rd
!= sizeof event
) {
372 logprintf(LOG_ERR
, "error reading '%s'",
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
;
387 return decode_all(remotes
);
391 /* Remotec Mediamaster specific code */
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
);
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
413 pre_code
=0xFFA10003; //so it gets recognized
414 return decode_all(remotes
);
417 first event field after button code (wheel_count==1) */
418 else if (wheel_count
==1) {
419 x_movement
=event
.value
;
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 */
435 return decode_all(remotes
);
437 else if ((event
.hid
== 0xFFA10003) && (event
.value
== 0xFFFFFFAA)) {
442 /* insert decoding logic for other hiddev remotes here */
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
458 int rv
= hiddev_init();
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
)) {
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
481 struct hiddev_usage_ref uref
;
483 LOGPRINTF(1, "sb0540_rec");
485 pre_code_length
= 16;
486 main_code_length
= 16;
490 rd
= read(hw
.fd
, &uref
, sizeof(uref
));
492 logprintf(LOG_ERR
, "error reading '%s'", hw
.device
);
493 logperror(LOG_ERR
, NULL
);
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
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
;
546 struct hiddev_event ev
[4];
550 LOGPRINTF(1, "macmini_rec");
554 if(i
>0 && !waitfordata(TIMEOUT
))
556 logprintf(LOG_ERR
,"timeout reading byte %d",i
);
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
);
567 gettimeofday (&now
, NULL
);
568 /* Record the code */
571 main_code
= (ev
[0].value
<< 24) + (ev
[1].value
<< 16) +
572 (ev
[2].value
<< 8) + (ev
[3].value
<< 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 */
583 main_code
= old_main_code
;
585 if (old_main_code
== main_code
)
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
607 int rv
= hiddev_init();
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
)) {
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
629 struct hiddev_usage_ref uref
;
631 LOGPRINTF(1, "samsung_rec");
634 main_code_length
= 32;
638 rd
= read(hw
.fd
, &uref
, sizeof(uref
));
640 logprintf(LOG_ERR
, "error reading '%s'", hw
.device
);
641 logperror(LOG_ERR
, NULL
);
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)
679 LOGPRINTF(3, "Main code: %x\n", main_code
);
680 return decode_all(remotes
);
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)
704 LOGPRINTF(3, "Main code: %x\n", main_code
);
705 return decode_all(remotes
);
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.
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
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 */
749 /* fetch usage code from first usage
752 main_code
= (uref
.usage_code
& 0xffff0000);
755 /* find index of highest bit with binary search */
758 if ( tmpval
& 0xf0 ) { maxbit
+= 4; tmpval
>>= 4; }
759 if ( tmpval
& 0x0c ) { maxbit
+= 2; tmpval
>>= 2; }
760 if ( tmpval
& 0x02 ) { maxbit
+= 1; }
762 /* We found a/the pressed key, so break out */
767 LOGPRINTF(3, "Main code: %x\n", main_code
);
769 /* decode combined key value */
770 return decode_all(remotes
);
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
);
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