Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/adb add driver for Kensington Turbo Mouse ( actually...



details:   https://anonhg.NetBSD.org/src/rev/e62e88e308ae
branches:  trunk
changeset: 459388:e62e88e308ae
user:      macallan <macallan%NetBSD.org@localhost>
date:      Sun Sep 08 05:55:15 2019 +0000

description:
add driver for Kensington Turbo Mouse ( actually a trackball )
the adbms driver contains basic support, this driver lets you program the
buttons, I'll add other features once I figure out how they work

diffstat:

 sys/dev/adb/adb_ktm.c |  486 ++++++++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/adb/files.adb |    7 +-
 2 files changed, 492 insertions(+), 1 deletions(-)

diffs (truncated from 516 to 300 lines):

diff -r 867f7021fdae -r e62e88e308ae sys/dev/adb/adb_ktm.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/adb/adb_ktm.c     Sun Sep 08 05:55:15 2019 +0000
@@ -0,0 +1,486 @@
+/*     $NetBSD: adb_ktm.c,v 1.1 2019/09/08 05:55:15 macallan Exp $     */
+
+/*-
+ * Copyright (c) 2019 Michael Lorenz
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: adb_ktm.c,v 1.1 2019/09/08 05:55:15 macallan Exp $");
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/fcntl.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+
+#include <machine/autoconf.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsmousevar.h>
+
+#include <machine/adbsys.h>
+#include <dev/adb/adbvar.h>
+
+#include "adbdebug.h"
+
+#ifdef KTM_DEBUG
+#define DPRINTF printf
+#else
+#define DPRINTF while (0) printf
+#endif
+
+/*
+ * State info, per mouse instance.
+ */
+struct ktm_softc {
+       device_t        sc_dev;
+       struct adb_device *sc_adbdev;
+       struct adb_bus_accessops *sc_ops;
+
+       uint8_t         sc_us;          /* cmd to watch for */
+       device_t        sc_wsmousedev;
+       /* buffers */
+       uint8_t         sc_config[8];
+       int             sc_left;
+       int             sc_right;
+       int             sc_poll;
+       int             sc_msg_len;
+       int             sc_event;
+       uint8_t         sc_buffer[16];
+};
+
+/*
+ * Function declarations.
+ */
+static int     ktm_match(device_t, cfdata_t, void *);
+static void    ktm_attach(device_t, device_t, void *);
+static void    ktm_init(struct ktm_softc *);
+static void    ktm_write_config(struct ktm_softc *);
+static void    ktm_buttons(struct ktm_softc *);
+static void    ktm_process_event(struct ktm_softc *, int, uint8_t *);
+static int     ktm_send_sync(struct ktm_softc *, uint8_t, int, uint8_t *);
+
+/* Driver definition. */
+CFATTACH_DECL_NEW(ktm, sizeof(struct ktm_softc),
+    ktm_match, ktm_attach, NULL, NULL);
+
+static int ktm_enable(void *);
+static int ktm_ioctl(void *, u_long, void *, int, struct lwp *);
+static void ktm_disable(void *);
+
+static void ktm_handler(void *, int, uint8_t *);
+static int  ktm_wait(struct ktm_softc *, int);
+static int  sysctl_ktm_left(SYSCTLFN_ARGS);
+static int  sysctl_ktm_right(SYSCTLFN_ARGS);
+
+const struct wsmouse_accessops ktm_accessops = {
+       ktm_enable,
+       ktm_ioctl,
+       ktm_disable,
+};
+
+static int
+ktm_match(device_t parent, cfdata_t cf, void *aux)
+{
+       struct adb_attach_args *aaa = aux;
+       if ((aaa->dev->original_addr == ADBADDR_MS) &&
+           (aaa->dev->handler_id == ADBMS_TURBO))
+               return 50;      /* beat out adbms */
+       else
+               return 0;
+}
+
+static void
+ktm_attach(device_t parent, device_t self, void *aux)
+{
+       struct ktm_softc *sc = device_private(self);
+       struct adb_attach_args *aaa = aux;
+       struct wsmousedev_attach_args a;
+
+       sc->sc_dev = self;
+       sc->sc_ops = aaa->ops;
+       sc->sc_adbdev = aaa->dev;
+       sc->sc_adbdev->cookie = sc;
+       sc->sc_adbdev->handler = ktm_handler;
+       sc->sc_us = ADBTALK(sc->sc_adbdev->current_addr, 0);
+       printf(" addr %d: Kensington Turbo Mouse\n",
+           sc->sc_adbdev->current_addr);
+
+       sc->sc_poll = 0;
+       sc->sc_msg_len = 0;
+
+       ktm_init(sc);
+
+       a.accessops = &ktm_accessops;
+       a.accesscookie = sc;
+       sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
+}
+
+static int
+ktm_turbo_csum(uint8_t *d)
+{
+       int i = 0, sum = 0;
+
+       for (i = 0; i < 7; i++)
+               sum ^= d[i];
+       return (sum ^ 0xff);
+}
+
+static void
+ktm_write_config(struct ktm_softc *sc)
+{
+       uint8_t addr = sc->sc_adbdev->current_addr;
+
+       ktm_send_sync(sc, ADBFLUSH(addr), 0, NULL);
+       sc->sc_config[7] = ktm_turbo_csum(sc->sc_config);
+       ktm_send_sync(sc, ADBLISTEN(addr, 2), 8, sc->sc_config);
+}
+
+static uint8_t button_to_reg[] = {0, 1, 4, 6};
+
+static void ktm_buttons(struct ktm_softc *sc)
+{
+       uint8_t reg;
+
+       reg = button_to_reg[sc->sc_right] |
+             (button_to_reg[sc->sc_left] << 3);
+       sc->sc_config[1] = reg;
+}
+
+static void
+ktm_init(struct ktm_softc *sc)
+{
+       const struct sysctlnode *me = NULL, *node = NULL;
+       int ret;
+       uint8_t addr;
+
+       /* Found Kensington Turbo Mouse */
+
+/*
+ * byte 0
+ - 0x80 enables EMP output
+ - 0x08 seems to map both buttons together
+ - 0x04 enables the 2nd button
+ - initialized to 0x20 on power up, no idea what that does
+ 
+ * byte 1 assigns what which button does
+ - 0x08 - button 1 - 1, button 2 - nothing
+ - 0x09 - both buttons - 1
+ - 0x0a - butoon 1 - 1, button 2 - toggle 1
+ - 0x0b - button 1 - 1, button 2 - nothing
+ - 0x0c - button 1 - 1, button 2 - 2
+ - 0x0e - button 1 - 1, button 2 - 3
+ - 0x0f - button 1 - 1, button 2 - toggle 3
+ - 0x10 - button 1 toggle 1, button 2 nothing
+ - 0x11 - button 1 - toggle 1, button 2 - 1
+ - 0x12 - both toggle 1
+ - 0x14 - button 1 toggle 1, button 2 - 2
+ - 0x21 - button 1 - 2, button 2 - 1
+ - 0x31 - button 1 - 3, button 2 - 1
+
+ * byte 2 - 0x40 on powerup, seems to do nothing
+ * byte 3 - 0x01 on powerup, seems to do nothing
+ * byte 4 programs a delay for button presses, apparently in 1/100 seconds
+ * byte 5 and 6 init to 0xff
+ * byte 7 is a simple XOR checksum, writes will only stick if it's valid
+          as in, b[7] = (b[0] ^ b[1] ^ ... ^ b[6]) ^ 0xff
+ */
+ 
+       /* this seems to be the most reasonable default */
+       uint8_t data[8] = { 0xa5, 0x0e, 0, 0, 1, 0xff, 0xff, 0 };
+
+       addr = sc->sc_adbdev->current_addr;
+       memcpy(sc->sc_config, data, sizeof(data));
+
+       sc->sc_left = 1;
+       sc->sc_right = 3;
+
+       ktm_buttons(sc);
+
+#ifdef KTM_DEBUG
+       {
+               int i;
+               ktm_send_sync(sc, ADBTALK(addr, 2), 0, NULL);
+               printf("reg *");
+               for (i = 0; i < sc->sc_msg_len; i++)
+                       printf(" %02x", sc->sc_buffer[i]);
+               printf("\n");
+       }
+#endif
+
+       ktm_write_config(sc);
+
+#ifdef KTM_DEBUG
+       int i, reg;
+       for (reg = 1; reg < 4; reg++) {
+               ktm_send_sync(sc, ADBTALK(addr, reg), 0, NULL);
+               printf("reg %d", reg);
+               for (i = 0; i < sc->sc_msg_len; i++)
+                       printf(" %02x", sc->sc_buffer[i]);
+               printf("\n");
+       }
+#endif
+       ret = sysctl_createv(NULL, 0, NULL, &me,
+           CTLFLAG_READWRITE,
+           CTLTYPE_NODE, device_xname(sc->sc_dev), NULL,
+           NULL, 0, NULL, 0,
+           CTL_MACHDEP, CTL_CREATE, CTL_EOL);
+
+       ret = sysctl_createv(NULL, 0, NULL, &node,
+           CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
+           CTLTYPE_INT, "left", "left button assigmnent",
+           sysctl_ktm_left, 1, (void *)sc, 0,
+           CTL_MACHDEP, me->sysctl_num, CTL_CREATE, CTL_EOL);
+
+       ret = sysctl_createv(NULL, 0, NULL, &node,
+           CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
+           CTLTYPE_INT, "right", "right button assigmnent",
+           sysctl_ktm_right, 1, (void *)sc, 0,
+           CTL_MACHDEP, me->sysctl_num, CTL_CREATE, CTL_EOL);
+       __USE(ret);
+}
+
+static void
+ktm_handler(void *cookie, int len, uint8_t *data)
+{
+       struct ktm_softc *sc = cookie;
+
+#ifdef KTM_DEBUG
+       int i;
+       printf("%s: %02x - ", device_xname(sc->sc_dev), sc->sc_us);
+       for (i = 0; i < len; i++) {
+               printf(" %02x", data[i]);
+       }
+       printf("\n");
+#endif
+       if (len >= 2) {
+               memcpy(sc->sc_buffer, &data[2], len - 2);
+               sc->sc_msg_len = len - 2;
+               if (data[1] == sc->sc_us) {
+                       /* make sense of the mouse message */
+                       ktm_process_event(sc, sc->sc_msg_len, sc->sc_buffer);
+                       return;
+               }
+               wakeup(&sc->sc_event);
+       } else {
+               DPRINTF("bogus message\n");
+       }
+}
+
+static void
+ktm_process_event(struct ktm_softc *sc, int len, uint8_t *buffer)
+{
+       int buttons = 0, mask, dx, dy, i;



Home | Main Index | Thread Index | Old Index