Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic Add a driver for the Sony SPIC that handles jog d...
details: https://anonhg.NetBSD.org/src/rev/e9960f7509f2
branches: trunk
changeset: 525951:e9960f7509f2
user: augustss <augustss%NetBSD.org@localhost>
date: Mon Apr 22 12:42:11 2002 +0000
description:
Add a driver for the Sony SPIC that handles jog dials etc.
This driver works on my SRX77, but probably little else.
It makes the jog dial appear as a wsmouse.
diffstat:
sys/dev/ic/spic.c | 277 +++++++++++++++++++++++++++++++++++++++++++++++++++
sys/dev/ic/spicvar.h | 17 +++
2 files changed, 294 insertions(+), 0 deletions(-)
diffs (truncated from 302 to 300 lines):
diff -r eeb7a3ec0d6a -r e9960f7509f2 sys/dev/ic/spic.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/ic/spic.c Mon Apr 22 12:42:11 2002 +0000
@@ -0,0 +1,277 @@
+/* $NetBSD: spic.c,v 1.1 2002/04/22 12:42:11 augustss Exp $ */
+
+/*
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lennart%augustsson.net@localhost) at
+ * Carlstedt Research & Technology.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+/*
+ * The SPIC is used on some Sony Vaios to handle the jog dial and other
+ * peripherals.
+ * The protocol used by the SPIC seems to vary wildly among the different
+ * models, and I've found no documentation.
+ * This file handles the jog dial on the SRX77 model, and perhaps nothing
+ * else.
+ *
+ * The general way of talking to the SPIC was gleaned from the Linux and
+ * FreeBSD drivers. The hex numbers were taken from these drivers (they
+ * come from reverese engineering.)
+ *
+ * TODO:
+ * Make it handle more models.
+ * Figure out why the interrupt mode doesn't work.
+ */
+
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: spic.c,v 1.1 2002/04/22 12:42:11 augustss Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/proc.h>
+#include <sys/kernel.h>
+#include <sys/callout.h>
+
+#include <machine/bus.h>
+
+#include <dev/ic/spicvar.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsmousevar.h>
+
+#define POLLRATE (hz/30)
+
+/* Some hardware constants */
+#define SPIC_PORT1 0
+#define SPIC_PORT2 4
+
+#ifdef SPIC_DEBUG
+int spicdebug = 0;
+#endif
+
+static int spic_enable(void *);
+static void spic_disable(void *);
+static int spic_ioctl(void *, u_long, caddr_t, int, struct proc *);
+
+static const struct wsmouse_accessops spic_accessops = {
+ spic_enable,
+ spic_ioctl,
+ spic_disable,
+};
+
+#define SPIC_COMMAND(quiet, command) do { \
+ unsigned int n = 10000; \
+ while (--n && (command)) \
+ delay(1); \
+ if (n == 0 && !(quiet)) \
+ printf("spic: command failed at line %d\n", __LINE__); \
+} while (0)
+
+#if 0
+#define INB(sc, p) (delay(100), printf("inb(%x)=%x\n", (uint)sc->sc_ioh+p, bus_space_read_1(sc->sc_iot, sc->sc_ioh, p)), delay(100), bus_space_read_1(sc->sc_iot, sc->sc_ioh, (p)))
+#define OUTB(sc, v, p) do { delay(100); bus_space_write_1(sc->sc_iot, sc->sc_ioh, (p), (v)); printf("outb(%x, %x)\n", (uint)sc->sc_ioh+p, v); } while(0)
+#else
+#define INB(sc, p) (delay(100), bus_space_read_1(sc->sc_iot, sc->sc_ioh, (p)))
+#define OUTB(sc, v, p) do { delay(100); bus_space_write_1(sc->sc_iot, sc->sc_ioh, (p), (v)); } while(0)
+#endif
+
+static u_int8_t
+spic_call1(struct spic_softc *sc, u_int8_t dev)
+{
+ u_int8_t v1, v2;
+
+ SPIC_COMMAND(0, INB(sc, SPIC_PORT2) & 2);
+ OUTB(sc, dev, SPIC_PORT2);
+ v1 = INB(sc, SPIC_PORT2);
+ v2 = INB(sc, SPIC_PORT1);
+ return v2;
+}
+
+static u_int8_t
+spic_call2(struct spic_softc *sc, u_int8_t dev, u_int8_t fn)
+{
+ u_int8_t v1;
+
+ SPIC_COMMAND(0, INB(sc, SPIC_PORT2) & 2);
+ OUTB(sc, dev, SPIC_PORT2);
+ SPIC_COMMAND(0, INB(sc, SPIC_PORT2) & 2);
+ OUTB(sc, fn, SPIC_PORT1);
+ v1 = INB(sc, SPIC_PORT1);
+ return v1;
+}
+
+/* Interrupt handler: some event is available */
+int
+spic_intr(void *v) {
+ struct spic_softc *sc = v;
+ u_int8_t v1, v2;
+ int dz, buttons;
+
+ v1 = INB(sc, SPIC_PORT1);
+ v2 = INB(sc, SPIC_PORT2);
+
+ buttons = 0;
+ if (v1 & 0x40)
+ buttons |= 1 << 1;
+ if (v1 & 0x20)
+ buttons |= 1 << 5;
+ dz = v1 & 0x1f;
+ switch (dz) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ break;
+ case 0x1f:
+ case 0x1e:
+ case 0x1d:
+ dz -= 0x20;
+ break;
+ default:
+ printf("spic: v1=0x%02x v2=0x%02x\n", v1, v2);
+ goto skip;
+ }
+
+ if (!sc->sc_enabled) {
+ /*printf("spic: not enabled\n");*/
+ goto skip;
+ }
+
+ if (dz != 0 || buttons != sc->sc_buttons) {
+#ifdef SPIC_DEBUG
+ if (spicdebug)
+ printf("spic: but=0x%x dz=%d v1=0x%02x v2=0x%02x\n",
+ buttons, dz, v1, v2);
+#endif
+ sc->sc_buttons = buttons;
+ if (sc->sc_wsmousedev != NULL) {
+ wsmouse_input(sc->sc_wsmousedev, buttons, 0, 0, dz,
+ WSMOUSE_INPUT_DELTA);
+ }
+ }
+
+skip:
+ spic_call2(sc, 0x81, 0xff); /* Clear event */
+ return (1);
+}
+
+static void
+spictimeout(void *v)
+{
+ struct spic_softc *sc = v;
+ int s = spltty();
+ spic_intr(v);
+ splx(s);
+ callout_reset(&sc->sc_poll, POLLRATE, spictimeout, sc);
+}
+
+void
+spic_attach(struct spic_softc *sc)
+{
+ struct wsmousedev_attach_args a;
+
+#ifdef SPIC_DEBUG
+ if (spicdebug)
+ printf("spic_attach %x %x\n", sc->sc_iot, (uint)sc->sc_ioh);
+#endif
+
+ callout_init(&sc->sc_poll);
+
+ spic_call1(sc, 0x82);
+ spic_call2(sc, 0x81, 0xff);
+ spic_call1(sc, 0x92); /* or 0x82 */
+
+ a.accessops = &spic_accessops;
+ a.accesscookie = sc;
+ sc->sc_wsmousedev = config_found(&sc->sc_dev, &a, wsmousedevprint);
+}
+
+
+static int
+spic_enable(void *v)
+{
+ struct spic_softc *sc = v;
+
+ if (sc->sc_enabled)
+ return (EBUSY);
+
+ sc->sc_enabled = 1;
+ sc->sc_buttons = 0;
+
+#ifdef SPIC_DEBUG
+ if (spicdebug)
+ printf("spic_enable\n");
+#endif
+
+ callout_reset(&sc->sc_poll, POLLRATE, spictimeout, sc);
+
+ return (0);
+}
+
+static void
+spic_disable(void *v)
+{
+ struct spic_softc *sc = v;
+
+#ifdef DIAGNOSTIC
+ if (!sc->sc_enabled) {
+ printf("spic_disable: not enabled\n");
+ return;
+ }
+#endif
+
+ callout_stop(&sc->sc_poll);
+
+ sc->sc_enabled = 0;
+
+#ifdef SPIC_DEBUG
+ if (spicdebug)
+ printf("spic_disable\n");
+#endif
+}
+
+static int
+spic_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ switch (cmd) {
+ case WSMOUSEIO_GTYPE:
+ /* XXX this is not really correct */
+ *(u_int *)data = WSMOUSE_TYPE_PS2;
+ return (0);
+ }
+
+ return (-1);
+}
diff -r eeb7a3ec0d6a -r e9960f7509f2 sys/dev/ic/spicvar.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/ic/spicvar.h Mon Apr 22 12:42:11 2002 +0000
@@ -0,0 +1,17 @@
+struct spic_softc {
+ struct device sc_dev;
+
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+
+ struct callout sc_poll;
+
+ int sc_buttons;
+ char sc_enabled;
+
+ struct device *sc_wsmousedev;
+};
+
+void spic_attach(struct spic_softc *);
Home |
Main Index |
Thread Index |
Old Index