Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 22 Oct 2016 02:15:40 +0000 (UTC)
From:      Oleksandr Tymoshenko <gonzo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r307764 - in stable/11/sys: dev/usb/input modules/usb/ukbd
Message-ID:  <201610220215.u9M2FeOo087725@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gonzo
Date: Sat Oct 22 02:15:39 2016
New Revision: 307764
URL: https://svnweb.freebsd.org/changeset/base/307764

Log:
  MFC r306132, r306275:
  
  r306132:
  Add evdev support to ukbd driver
  
  event generation is disabled by default in favour of kbdmux. This
  behavoiur is controlled by kern.evdev.rcpt_mask sysctl, bit 3 should
  be set to give priority to hw over mux
  
  Submitted by:	Vladimir Kondratiev <wulf@cicgroup.ru>
  Reviewed by:	hans
  Differential Revision:	https://reviews.freebsd.org/D7957
  
  r306275:
  Do not perform extra check for NULL, evdev_free can handle NULL value
  
  Submitted by:	Vladimir Kondratiev <wulf@cicgroup.ru>

Modified:
  stable/11/sys/dev/usb/input/ukbd.c
  stable/11/sys/modules/usb/ukbd/Makefile
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/usb/input/ukbd.c
==============================================================================
--- stable/11/sys/dev/usb/input/ukbd.c	Sat Oct 22 02:11:53 2016	(r307763)
+++ stable/11/sys/dev/usb/input/ukbd.c	Sat Oct 22 02:15:39 2016	(r307764)
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
 #include "opt_compat.h"
 #include "opt_kbd.h"
 #include "opt_ukbd.h"
+#include "opt_evdev.h"
 
 #include <sys/stdint.h>
 #include <sys/stddef.h>
@@ -73,6 +74,11 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/usb/quirk/usb_quirk.h>
 
+#ifdef EVDEV
+#include <dev/evdev/input.h>
+#include <dev/evdev/evdev.h>
+#endif
+
 #include <sys/ioccom.h>
 #include <sys/filio.h>
 #include <sys/tty.h>
@@ -162,6 +168,9 @@ struct ukbd_softc {
 	struct usb_device *sc_udev;
 	struct usb_interface *sc_iface;
 	struct usb_xfer *sc_xfer[UKBD_N_TRANSFER];
+#ifdef EVDEV
+	struct evdev_dev *sc_evdev;
+#endif
 
 	uint32_t sc_ntime[UKBD_NKEYCODE];
 	uint32_t sc_otime[UKBD_NKEYCODE];
@@ -377,6 +386,12 @@ static device_attach_t ukbd_attach;
 static device_detach_t ukbd_detach;
 static device_resume_t ukbd_resume;
 
+#ifdef EVDEV
+static struct evdev_methods ukbd_evdev_methods = {
+	.ev_event = evdev_ev_kbd_event,
+};
+#endif
+
 static uint8_t
 ukbd_any_key_pressed(struct ukbd_softc *sc)
 {
@@ -405,6 +420,14 @@ ukbd_put_key(struct ukbd_softc *sc, uint
 	DPRINTF("0x%02x (%d) %s\n", key, key,
 	    (key & KEY_RELEASE) ? "released" : "pressed");
 
+#ifdef EVDEV
+	if (evdev_rcpt_mask & EVDEV_RCPT_HW_KBD && sc->sc_evdev != NULL) {
+		evdev_push_event(sc->sc_evdev, EV_KEY,
+		    evdev_hid2key(KEY_INDEX(key)), !(key & KEY_RELEASE));
+		evdev_sync(sc->sc_evdev);
+	}
+#endif
+
 	if (sc->sc_inputs < UKBD_IN_BUF_SIZE) {
 		sc->sc_input[sc->sc_inputtail] = key;
 		++(sc->sc_inputs);
@@ -918,6 +941,11 @@ ukbd_set_leds_callback(struct usb_xfer *
 		if (!any)
 			break;
 
+#ifdef EVDEV
+		if (sc->sc_evdev != NULL)
+			evdev_push_leds(sc->sc_evdev, sc->sc_leds);
+#endif
+
 		/* range check output report length */
 		len = sc->sc_led_size;
 		if (len > (UKBD_BUFFER_SIZE - 1))
@@ -1193,6 +1221,10 @@ ukbd_attach(device_t dev)
 	usb_error_t err;
 	uint16_t n;
 	uint16_t hid_len;
+#ifdef EVDEV
+	struct evdev_dev *evdev;
+	int i;
+#endif
 #ifdef USB_DEBUG
 	int rate;
 #endif
@@ -1307,6 +1339,37 @@ ukbd_attach(device_t dev)
 		goto detach;
 	}
 #endif
+
+#ifdef EVDEV
+	evdev = evdev_alloc();
+	evdev_set_name(evdev, device_get_desc(dev));
+	evdev_set_phys(evdev, device_get_nameunit(dev));
+	evdev_set_id(evdev, BUS_USB, uaa->info.idVendor,
+	   uaa->info.idProduct, 0);
+	evdev_set_serial(evdev, usb_get_serial(uaa->device));
+	evdev_set_methods(evdev, kbd, &ukbd_evdev_methods);
+	evdev_support_event(evdev, EV_SYN);
+	evdev_support_event(evdev, EV_KEY);
+	if (sc->sc_flags & (UKBD_FLAG_NUMLOCK | UKBD_FLAG_CAPSLOCK |
+			    UKBD_FLAG_SCROLLLOCK))
+		evdev_support_event(evdev, EV_LED);
+	evdev_support_event(evdev, EV_REP);
+
+	for (i = 0x00; i <= 0xFF; i++)
+		evdev_support_key(evdev, evdev_hid2key(i));
+	if (sc->sc_flags & UKBD_FLAG_NUMLOCK)
+		evdev_support_led(evdev, LED_NUML);
+	if (sc->sc_flags & UKBD_FLAG_CAPSLOCK)
+		evdev_support_led(evdev, LED_CAPSL);
+	if (sc->sc_flags & UKBD_FLAG_SCROLLLOCK)
+		evdev_support_led(evdev, LED_SCROLLL);
+
+	if (evdev_register(evdev))
+		evdev_free(evdev);
+	else
+		sc->sc_evdev = evdev;
+#endif
+
 	sc->sc_flags |= UKBD_FLAG_ATTACHED;
 
 	if (bootverbose) {
@@ -1377,6 +1440,11 @@ ukbd_detach(device_t dev)
 		}
 	}
 #endif
+
+#ifdef EVDEV
+	evdev_free(sc->sc_evdev);
+#endif
+
 	if (KBD_IS_CONFIGURED(&sc->sc_kbd)) {
 		error = kbd_unregister(&sc->sc_kbd);
 		if (error) {
@@ -1908,6 +1976,10 @@ ukbd_ioctl_locked(keyboard_t *kbd, u_lon
 		else
 			kbd->kb_delay1 = ((int *)arg)[0];
 		kbd->kb_delay2 = ((int *)arg)[1];
+#ifdef EVDEV
+		if (sc->sc_evdev != NULL)
+			evdev_push_repeats(sc->sc_evdev, kbd);
+#endif
 		return (0);
 
 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
@@ -2056,6 +2128,9 @@ ukbd_set_leds(struct ukbd_softc *sc, uin
 static int
 ukbd_set_typematic(keyboard_t *kbd, int code)
 {
+#ifdef EVDEV
+	struct ukbd_softc *sc = kbd->kb_data;
+#endif
 	static const int delays[] = {250, 500, 750, 1000};
 	static const int rates[] = {34, 38, 42, 46, 50, 55, 59, 63,
 		68, 76, 84, 92, 100, 110, 118, 126,
@@ -2067,6 +2142,10 @@ ukbd_set_typematic(keyboard_t *kbd, int 
 	}
 	kbd->kb_delay1 = delays[(code >> 5) & 3];
 	kbd->kb_delay2 = rates[code & 0x1f];
+#ifdef EVDEV
+	if (sc->sc_evdev != NULL)
+		evdev_push_repeats(sc->sc_evdev, kbd);
+#endif
 	return (0);
 }
 

Modified: stable/11/sys/modules/usb/ukbd/Makefile
==============================================================================
--- stable/11/sys/modules/usb/ukbd/Makefile	Sat Oct 22 02:11:53 2016	(r307763)
+++ stable/11/sys/modules/usb/ukbd/Makefile	Sat Oct 22 02:15:39 2016	(r307764)
@@ -30,7 +30,7 @@ S=     ${.CURDIR}/../../..
 .PATH: $S/dev/usb/input
 
 KMOD=	ukbd
-SRCS=	opt_bus.h opt_compat.h opt_kbd.h opt_ukbd.h opt_usb.h \
+SRCS=	opt_bus.h opt_compat.h opt_evdev.h opt_kbd.h opt_ukbd.h opt_usb.h \
 	device_if.h bus_if.h usb_if.h usbdevs.h \
 	ukbd.c
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610220215.u9M2FeOo087725>