Jonathan Gray
2016-01-26 00:28:39 UTC
acpi described hid devices can have interrupts signalled by gpio.
As there is currently no support for that here is an alternative to poll
the devices at a fixed interval. This makes the keyboard/trackpad on
the ideapad 100s mostly useable, clicking and dragging windows in X
seems a bit off. I'm mostly interested in not having to use a usb
hub and keyboard for now.
Index: acpi/dwiic.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/dwiic.c,v
retrieving revision 1.9
diff -u -p -r1.9 dwiic.c
--- acpi/dwiic.c 22 Jan 2016 22:57:23 -0000 1.9
+++ acpi/dwiic.c 22 Jan 2016 23:01:49 -0000
@@ -563,12 +563,6 @@ dwiic_acpi_foundhid(struct aml_node *nod
aml_parse_resource(&res, dwiic_acpi_parse_crs, &crs);
aml_freevalue(&res);
- if (crs.irq_int <= 0) {
- printf("%s: couldn't find irq for %s\n", sc->sc_dev.dv_xname,
- aml_nodename(node->parent));
- return 0;
- }
-
ia.ia_int = crs.irq_int;
ia.ia_int_flags = crs.irq_flags;
ia.ia_addr = crs.i2c_addr;
Index: i2c/ihidev.c
===================================================================
RCS file: /cvs/src/sys/dev/i2c/ihidev.c,v
retrieving revision 1.8
diff -u -p -r1.8 ihidev.c
--- i2c/ihidev.c 20 Jan 2016 01:19:28 -0000 1.8
+++ i2c/ihidev.c 23 Jan 2016 00:00:44 -0000
@@ -24,6 +24,7 @@
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/stdint.h>
+#include <sys/timeout.h>
#include <dev/i2c/i2cvar.h>
#include <dev/i2c/ihidev.h>
@@ -60,12 +61,15 @@ enum {
static int I2C_HID_POWER_ON = 0x0;
static int I2C_HID_POWER_OFF = 0x1;
+#define IHIDEV_POLL_MS 20
+
int ihidev_match(struct device *, void *, void *);
void ihidev_attach(struct device *, struct device *, void *);
int ihidev_detach(struct device *, int);
int ihidev_hid_command(struct ihidev_softc *, int, void *);
int ihidev_intr(void *);
+void ihidev_poll(void *);
int ihidev_reset(struct ihidev_softc *);
int ihidev_hid_desc_parse(struct ihidev_softc *);
@@ -164,6 +168,9 @@ ihidev_attach(struct device *parent, str
printf(", failed establishing intr\n");
return;
}
+ } else {
+ timeout_set(&sc->sc_poll, ihidev_poll, sc);
+ timeout_add_msec(&sc->sc_poll, IHIDEV_POLL_MS);
}
iha.iaa = ia;
@@ -209,6 +216,8 @@ ihidev_detach(struct device *self, int f
if (sc->sc_ih != NULL) {
intr_disestablish(sc->sc_ih);
sc->sc_ih = NULL;
+ } else {
+ timeout_del(&sc->sc_poll);
}
if (sc->sc_ibuf != NULL) {
@@ -629,6 +638,16 @@ ihidev_intr(void *arg)
scd->sc_intr(scd, p, psize);
return (1);
+}
+
+void
+ihidev_poll(void *arg)
+{
+ struct ihidev_softc *sc = arg;
+ int s = spltty();
+ ihidev_intr(sc);
+ timeout_add_msec(&sc->sc_poll, IHIDEV_POLL_MS);
+ splx(s);
}
int
Index: i2c/ihidev.h
===================================================================
RCS file: /cvs/src/sys/dev/i2c/ihidev.h,v
retrieving revision 1.3
diff -u -p -r1.3 ihidev.h
--- i2c/ihidev.h 20 Jan 2016 01:19:28 -0000 1.3
+++ i2c/ihidev.h 22 Jan 2016 14:01:08 -0000
@@ -87,6 +87,8 @@ struct ihidev_softc {
u_char *sc_ibuf;
int sc_refcnt;
+
+ struct timeout sc_poll;
};
struct ihidev {
Index: i2c/ims.c
===================================================================
RCS file: /cvs/src/sys/dev/i2c/ims.c,v
retrieving revision 1.1
diff -u -p -r1.1 ims.c
--- i2c/ims.c 12 Jan 2016 01:11:15 -0000 1.1
+++ i2c/ims.c 22 Jan 2016 14:09:05 -0000
@@ -22,6 +22,7 @@
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/ioctl.h>
+#include <sys/timeout.h>
#include <dev/i2c/i2cvar.h>
#include <dev/i2c/ihidev.h>
Index: i2c/imt.c
===================================================================
RCS file: /cvs/src/sys/dev/i2c/imt.c,v
retrieving revision 1.1
diff -u -p -r1.1 imt.c
--- i2c/imt.c 20 Jan 2016 01:26:00 -0000 1.1
+++ i2c/imt.c 22 Jan 2016 14:08:50 -0000
@@ -25,6 +25,7 @@
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/ioctl.h>
+#include <sys/timeout.h>
#include <dev/i2c/i2cvar.h>
#include <dev/i2c/ihidev.h>
As there is currently no support for that here is an alternative to poll
the devices at a fixed interval. This makes the keyboard/trackpad on
the ideapad 100s mostly useable, clicking and dragging windows in X
seems a bit off. I'm mostly interested in not having to use a usb
hub and keyboard for now.
Index: acpi/dwiic.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/dwiic.c,v
retrieving revision 1.9
diff -u -p -r1.9 dwiic.c
--- acpi/dwiic.c 22 Jan 2016 22:57:23 -0000 1.9
+++ acpi/dwiic.c 22 Jan 2016 23:01:49 -0000
@@ -563,12 +563,6 @@ dwiic_acpi_foundhid(struct aml_node *nod
aml_parse_resource(&res, dwiic_acpi_parse_crs, &crs);
aml_freevalue(&res);
- if (crs.irq_int <= 0) {
- printf("%s: couldn't find irq for %s\n", sc->sc_dev.dv_xname,
- aml_nodename(node->parent));
- return 0;
- }
-
ia.ia_int = crs.irq_int;
ia.ia_int_flags = crs.irq_flags;
ia.ia_addr = crs.i2c_addr;
Index: i2c/ihidev.c
===================================================================
RCS file: /cvs/src/sys/dev/i2c/ihidev.c,v
retrieving revision 1.8
diff -u -p -r1.8 ihidev.c
--- i2c/ihidev.c 20 Jan 2016 01:19:28 -0000 1.8
+++ i2c/ihidev.c 23 Jan 2016 00:00:44 -0000
@@ -24,6 +24,7 @@
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/stdint.h>
+#include <sys/timeout.h>
#include <dev/i2c/i2cvar.h>
#include <dev/i2c/ihidev.h>
@@ -60,12 +61,15 @@ enum {
static int I2C_HID_POWER_ON = 0x0;
static int I2C_HID_POWER_OFF = 0x1;
+#define IHIDEV_POLL_MS 20
+
int ihidev_match(struct device *, void *, void *);
void ihidev_attach(struct device *, struct device *, void *);
int ihidev_detach(struct device *, int);
int ihidev_hid_command(struct ihidev_softc *, int, void *);
int ihidev_intr(void *);
+void ihidev_poll(void *);
int ihidev_reset(struct ihidev_softc *);
int ihidev_hid_desc_parse(struct ihidev_softc *);
@@ -164,6 +168,9 @@ ihidev_attach(struct device *parent, str
printf(", failed establishing intr\n");
return;
}
+ } else {
+ timeout_set(&sc->sc_poll, ihidev_poll, sc);
+ timeout_add_msec(&sc->sc_poll, IHIDEV_POLL_MS);
}
iha.iaa = ia;
@@ -209,6 +216,8 @@ ihidev_detach(struct device *self, int f
if (sc->sc_ih != NULL) {
intr_disestablish(sc->sc_ih);
sc->sc_ih = NULL;
+ } else {
+ timeout_del(&sc->sc_poll);
}
if (sc->sc_ibuf != NULL) {
@@ -629,6 +638,16 @@ ihidev_intr(void *arg)
scd->sc_intr(scd, p, psize);
return (1);
+}
+
+void
+ihidev_poll(void *arg)
+{
+ struct ihidev_softc *sc = arg;
+ int s = spltty();
+ ihidev_intr(sc);
+ timeout_add_msec(&sc->sc_poll, IHIDEV_POLL_MS);
+ splx(s);
}
int
Index: i2c/ihidev.h
===================================================================
RCS file: /cvs/src/sys/dev/i2c/ihidev.h,v
retrieving revision 1.3
diff -u -p -r1.3 ihidev.h
--- i2c/ihidev.h 20 Jan 2016 01:19:28 -0000 1.3
+++ i2c/ihidev.h 22 Jan 2016 14:01:08 -0000
@@ -87,6 +87,8 @@ struct ihidev_softc {
u_char *sc_ibuf;
int sc_refcnt;
+
+ struct timeout sc_poll;
};
struct ihidev {
Index: i2c/ims.c
===================================================================
RCS file: /cvs/src/sys/dev/i2c/ims.c,v
retrieving revision 1.1
diff -u -p -r1.1 ims.c
--- i2c/ims.c 12 Jan 2016 01:11:15 -0000 1.1
+++ i2c/ims.c 22 Jan 2016 14:09:05 -0000
@@ -22,6 +22,7 @@
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/ioctl.h>
+#include <sys/timeout.h>
#include <dev/i2c/i2cvar.h>
#include <dev/i2c/ihidev.h>
Index: i2c/imt.c
===================================================================
RCS file: /cvs/src/sys/dev/i2c/imt.c,v
retrieving revision 1.1
diff -u -p -r1.1 imt.c
--- i2c/imt.c 20 Jan 2016 01:26:00 -0000 1.1
+++ i2c/imt.c 22 Jan 2016 14:08:50 -0000
@@ -25,6 +25,7 @@
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/ioctl.h>
+#include <sys/timeout.h>
#include <dev/i2c/i2cvar.h>
#include <dev/i2c/ihidev.h>