Re: Enable addition function keys

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, May 24, 2011 at 1:30 PM, David Christen <davidchristen@xxxxxxxxx> wrote:
> On Tue, May 24, 2011 at 8:22 AM, Dmitry Torokhov
> <dmitry.torokhov@xxxxxxxxx> wrote:
>> Hi David,
>>
>> On Mon, May 16, 2011 at 09:54:49PM +0200, David Christen wrote:
>>> I have a custom made keyboard with 48 Function keys attached to an embedded
>>> PC running on a RISC CPU. With hid module in the kernel the regular part of
>>> the keyboard (i.e. all letters, num pad and Fxx keys up to F12) are working
>>> perfectly fine. However with the additional keys I don't get any events in
>>> /dev/input/event0. This is the same behavior as found on a regular Linux PC
>>> and also under Windows. Although the manufacturer of the keyboard confirmed
>>> that those keys do send proper HID codes (0x68 to 0x8b for F13 to F48).
>>> I don't have any experience in programming on the Kernel level. Could you
>>> maybe direct me in how to get the input events of those keys running?
>>>
>>
>> Even though the usage codes are not mapped you should be able to map
>> them yourself using EVIOCSKEYCODE ioctl. See udev sources for how to
>> adjust keymaps on input devices.
>>
>> We have F1 through F24 keycode defines, but no F25-F48 (nor do I want to
>> add these since userspace would not really know what to do with these,
>> they are device-specific); you'll have to pick some standard ones that
>> match the functions you want to assign to your extended keys.
>>
>
> Dear Dmitry,
>
> Thank you for looking into this.
>
> I'm trying to figure out how to use udev for this. Just to make sure
> that my problem was described correctly. My issue is not the mapping
> from the scancode to the keycode, but that I don't get any scancode at
> all. If I look at the output of usbmon, in particular the rdesc file,
> I get
>
> ====
> Keyboard.0063 ---> Key.KPDot
> Keyboard.0064 ---> Key.102nd
> Keyboard.0065 ---> Key.Compose
> LED.NumLock ---> LED.NumLock
> LED.CapsLock ---> LED.CapsLock
> LED.ScrollLock ---> LED.ScrollLock
> (eof)
> ====
>
> Looking at the output of my standard Logitech keyboard, this would be
> exactly what I would need:
>
> ====
> Keyboard.0080 ---> Key.VolumeUp
> Keyboard.0081 ---> Key.VolumeDown
> Keyboard.0082 ---> Key.Unknown
> Keyboard.0083 ---> Key.Unknown
> Keyboard.0084 ---> Key.Unknown
> Keyboard.0085 ---> Key.KPComma
> Keyboard.0086 ---> Key.Unknown
> Keyboard.0087 ---> Key.RO
> Keyboard.0088 ---> Key.Katakana/Hiragana
> Keyboard.0089 ---> Key.Yen
> Keyboard.008a ---> Key.Henkan
> Keyboard.008b ---> Key.Muhenkan
> Keyboard.008c ---> Key.KPJpComma
> Keyboard.008d ---> Key.Unknown
> Keyboard.008e ---> Key.Unknown
> Keyboard.008f ---> Key.Unknown
> Keyboard.0090 ---> Key.Hangeul
> Keyboard.0091 ---> Key.Hanja
> (eof)
> ====
>
> Even better would be to use a keymap without any Key.Unknown in the
> range 0x6b - 0x8b. The exact keycode is not relevant to me as long as
> they are unique. I translate them immediately to some other codes and
> send them to the serial port.
>
> So is there an easy way to select which keymap should be loaded? Below
> is the output when the keyboard is being attached:
>
> ====
> usb 2-1: new full speed USB device using uhci_hcd and address 9
> usb 2-1: New USB device found, idVendor=03eb, idProduct=2003
> usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
> usb 2-1: Product: USB Foil Keyboard Controller 32 12 885
> usb 2-1: Manufacturer: GESYS
> input: GESYS USB Foil Keyboard Controller 32 12 885 as /class/input/input11
> generic-usb 0003:03EB:2003.000C: input,hidraw0: USB HID v1.11 Keyboard
> [GESYS USB Foil Keyboard Controller 32 12 885] on
> usb-0000:00:06.0-1/input0
> ====
>
> as opposed to the logitech keyboard:
>
> ====
> usb 2-1: new low speed USB device using uhci_hcd and address 10
> usb 2-1: New USB device found, idVendor=046d, idProduct=c30e
> usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
> usb 2-1: Product: HID compliant keyboard
> usb 2-1: Manufacturer: Logitech
> input: Logitech HID compliant keyboard as /class/input/input12
> generic-usb 0003:046D:C30E.000D: input,hidraw0: USB HID v1.10 Keyboard
> [Logitech HID compliant keyboard] on usb-0000:00:06.0-1/input0
> input: Logitech HID compliant keyboard as /class/input/input13
> generic-usb 0003:046D:C30E.000E: input,hidraw1: USB HID v1.10 Device
> [Logitech HID compliant keyboard] on usb-0000:00:06.0-1/input1
> ====
>
> Thank you,
> David
>

Dear Dmitry,

I'm starting to feel stupid. I tried a simple code doing some ioctl
calls using EVIOCSKEYCODE  and EVIOCGKEYCODE. But it does not appear
to work. If I run it using ./ioctl-test /dev/input/event0 I get lots
of complains about wrong arguments:

====
evdev ioctl: Invalid argument
[0]= 125, [1] = 0
evdev ioctl: Invalid argument
[0]= 126, [1] = 0
evdev ioctl: Invalid argument
[0]= 127, [1] = 0
evdev ioctl: Invalid argument
[0]= 128, [1] = 0
evdev ioctl: Invalid argument
[0]= 129, [1] = 0
evdev ioctl: Invalid argument
Testing changes
evdev ioctl: Invalid argument
[0]= 49, [1] = 49
evdev ioctl: Invalid argument
[0]= 50, [1] = 49
====

Sorry for bothering you with this but I haven't found a lot of
information on this on the web.

Best regards,
David
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>

#include <linux/input.h>
#include <linux/serial.h>
#include <errno.h>
#include <unistd.h>
#include <termios.h>

#include <string.h>
#include <linux/input.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>

int main (int argc, char *argv[]) {
    int i, fd, ret;
    struct input_event ev[64];

    if ((fd = open(argv[1], O_RDWR)) < 0) {
        perror("Couldn't open input device");
        return 1;
    }

	int version;

	if (ioctl(fd, EVIOCGVERSION, &version)) {
		perror("evdev ioctl");
	}

	/* the EVIOCGVERSION ioctl() returns an int */
	/* so we unpack it and display it */
	printf("evdev driver version is %d.%d.%d\n",
		   version >> 16, (version >> 8) & 0xff,
		   version & 0xff);

	int codes[2];
	for (i=0; i<130; i++) {
		codes[0] = i;
		if(ioctl(fd, EVIOCSKEYCODE, codes)) {
			perror("evdev ioctl");
		}
		printf("[0]= %d, [1] = %d\n",
			   codes[0], codes[1]);
	}

	codes[0] = 58; /* M keycap */
	codes[1] = 49; /* assign to N */

	if(ioctl(fd, EVIOCSKEYCODE, codes)) {
		perror("evdev ioctl");
	}
	
	printf("Testing changes\n");
	
	for (i=49; i<60; i++) {
		codes[0] = i;
		if(ioctl(fd, EVIOCSKEYCODE, codes)) {
			perror("evdev ioctl");
		}
		printf("[0]= %d, [1] = %d\n",
			   codes[0], codes[1]);
	}

	return 0;
}


[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux