SPONSORED LINKS

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

TP360CE: NetBSD-1.0 and XFree86-3.1 files



Enclosed in this mail is a PS/2 mouse driver(*) for NetBSD-1.0 that
seems to work with the Trackpoint device on a TP360CE.  Enclosed is
also the config file I used to build the kernel, and the XF86Config
file for XFree86-3.1.  Everything seems to run just fine.

(*) Thanks to Keith Moore and Charles Hannum who provided me with
    valuable information.

-- Arne
|    Arne Helme, arne@acm.org, arne@pegasus.esprit.ec.org (finger)     |
|    PHONE: +31-53-893735, FAX: +31-53-333895, HOME: +31-53-326377     |
|    WWW  : http://www.pegasus.esprit.ec.org/people/arne/index.html    |
| Inf/SPA, Univ. of Twente, P.O.Box 217, 7500 AE Enschede, Netherlands |

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	TP360CE
#	XF86Config
#	pms.c
#
echo x - TP360CE
sed 's/^X//' >TP360CE << 'END-of-TP360CE'
X############################ -*- Mode: Makefile -*- ###########################
X## TP360CE -- NetBSD-1.0 configuration file for IBM ThinkPad 360CE
X## 
X## Author          : Arne Helme
X## Created On      : Sun Nov 20 19:31:09 1994
X## Last Modified By: Arne Helme
X## Last Modified On: Thu Jan 26 11:45:58 1995
X## Status          : Unknown, Use with caution!
X## 
X## $Locker$
X## $Log$
X###############################################################################
X
Xmachine		"i386"
Xident		"TP360CE"
Xcpu		"I486_CPU"
Xtimezone	0 dst 0
Xmaxusers	5
Xoptions		SWAPPAGER,VNODEPAGER,DEVPAGER
Xoptions		FIFO
Xoptions		SYSVMSG
Xoptions		SYSVSEM
Xoptions		SYSVSHM
Xoptions		FFS
Xoptions		INET,NFSCLIENT,NFSSERVER
Xoptions		"COMPAT_43"
Xoptions		"TCP_COMPAT_42"
Xoptions		XSERVER,UCONSOLE
Xoptions		MSDOSFS
Xoptions		KERNFS
Xoptions		"COMPAT_NOMID"
Xoptions		"COMPAT_09"
Xoptions		"MACHINE_NONCONTIG"
Xoptions		KTRACE
Xoptions		"IBM_TRACKPOINT"
X
Xconfig		netbsd	root on wd0 swap on wd0
X
Xcontroller	isa0
X
Xdevice		pc0	at isa? port "IO_KBD" irq 1
Xdevice		com0	at isa? port "IO_COM1" irq 4
X
Xdevice		lpt0	at isa? port "IO_LPT1" irq 7
Xdevice		lpt2	at isa? port "IO_LPT3"
X
X#device		pms0	at isa? port "IO_KBD" irq 12
X#device		pms0	at isa? port "IO_KBD" irq 5
X#device          pms0    at isa? port "IO_KBD" tty irq 12 vector pmsintr
Xdevice          pms0    at isa? port "IO_KBD" irq 12
X
Xcontroller	wdc0	at isa? port "IO_WD1" irq 14
Xdisk		wd0	at wdc0 drive ?
X
Xcontroller	fdc0	at isa? port "IO_FD1" irq 6 drq 2
Xdisk		fd0	at fdc0 drive ?
X
Xdevice		npx0	at isa? port "IO_NPX" irq 13
X
Xpseudo-device	log	1
Xpseudo-device	loop	1
Xpseudo-device	pty	16
Xpseudo-device	sl	1
Xpseudo-device	tun	1
Xpseudo-device	bpfilter	1
END-of-TP360CE
echo x - XF86Config
sed 's/^X//' >XF86Config << 'END-of-XF86Config'
XSection "Files"
X    RgbPath	"/usr/X11R6/lib/X11/rgb/"
X    FontPath	"/usr/X11R6/lib/X11/fonts/misc/"
X    FontPath	"/usr/X11R6/lib/X11/fonts/75dpi/"
XEndSection
X
XSection "Keyboard"
X    Protocol	"Standard"
X    AutoRepeat	500 5
X    ServerNumLock
XEndSection
X
XSection "Pointer"
X     Protocol   "BusMouse"
X     Device	"/dev/pms0"
X     Emulate3Buttons
XEndSection
X
XSection "Monitor"
X    Identifier	"LCD Screen"
X    VendorName	"IBM"
X    ModelName	"Unknown"
X
X#    Bandwidth	90
X    HorizSync   35.40 
X    VertRefresh 67.43
X
X    Mode "640x480"
X        DotClock	28.32
X        HTimings	640 664 760 800
X        VTimings	480 491 493 525
X    EndMode
XEndSection
X
X
XSection "Device"
X    Identifier	"WD90C24"
X    VendorName	"Western Digital"
X    BoardName	"RocketChip"
X    Chipset     "wd90c30"
X    VideoRam     1024
X    Clocks      28.32  28.32  28.32  28.32  28.32  28.32  28.32  28.32  
X    Clocks      28.32  28.32  28.32  28.32  28.32  28.32  28.32  28.32
X    Clocks      49.84
XEndSection
X
X
XSection "Screen"
X    Driver	"svga"
X    Device	"WD90C24"
X    Monitor	"LCD Screen"
X    Subsection "Display"
X        Depth	    8
X        Modes	    "640x480"
X        ViewPort    0 0
X        Virtual     640 480
X    EndSubsection
XEndSection
X
END-of-XF86Config
echo x - pms.c
sed 's/^X//' >pms.c << 'END-of-pms.c'
X/*-
X * Copyright (c) 1994 Charles Hannum.
X * Copyright (c) 1992, 1993 Erik Forsberg.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X *
X * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED
X * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
X * NO EVENT SHALL I BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
X * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
X * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
X * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
X * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
X * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
X * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
X *
X *	$Id: pms.c,v 1.9.2.2 1994/07/19 17:01:52 cgd Exp $
X */
X
X/*
X * XXXX
X * This is a hack.  This driver should really be combined with the
X * keyboard driver, since they go through the same buffer and use the
X * same I/O ports.  Frobbing the mouse and keyboard at the same time
X * may result in dropped characters and/or corrupted mouse events.
X */
X
X#include "pms.h"
X#if NPMS > 1
X#error Only one PS/2 style mouse may be configured into your system.
X#endif
X
X#include <sys/param.h>
X#include <sys/kernel.h>
X#include <sys/systm.h>
X#include <sys/buf.h>
X#include <sys/malloc.h>
X#include <sys/ioctl.h>
X#include <sys/tty.h>
X#include <sys/file.h>
X#include <sys/select.h>
X#include <sys/proc.h>
X#include <sys/vnode.h>
X#include <sys/device.h>
X
X#include <machine/cpu.h>
X#include <machine/pio.h>
X#include <machine/mouse.h>
X
X#include <i386/isa/isavar.h>
X
X#define	PMS_DATA	0       /* offset for data port, read-write */
X#define	PMS_CNTRL	4       /* offset for control port, write-only */
X#define	PMS_STATUS	4	/* offset for status port, read-only */
X#define	PMS_NPORTS	8
X
X/* status bits */
X#define	PMS_OBUF_FULL	0x01
X#define	PMS_IBUF_FULL	0x02
X
X/* controller commands */
X#define	PMS_INT_ENABLE	0x47	/* enable controller interrupts */
X#define	PMS_INT_DISABLE	0x65	/* disable controller interrupts */
X#define	PMS_AUX_ENABLE	0xa7	/* enable auxiliary port */
X#define	PMS_AUX_DISABLE	0xa8	/* disable auxiliary port */
X#define	PMS_MAGIC_1	0xa9	/* XXX */
X#define	PMS_MAGIC_2	0xaa	/* XXX */
X
X#define	PMS_8042_CMD	0x65
X
X/* mouse commands */
X#define	PMS_SET_SCALE11	0xe6	/* set scaling 1:1 */
X#define	PMS_SET_SCALE21 0xe7	/* set scaling 2:1 */
X#define	PMS_SET_RES	0xe8	/* set resolution */
X#define	PMS_GET_SCALE	0xe9	/* get scaling factor */
X#define	PMS_SET_STREAM	0xea	/* set streaming mode */
X#define	PMS_SET_SAMPLE	0xf3	/* set sampling rate */
X#define	PMS_DEV_ENABLE	0xf4	/* mouse on */
X#define	PMS_DEV_DISABLE	0xf5	/* mouse off */
X#define	PMS_RESET	0xff	/* reset */
X
X#define	PMS_CHUNK	128	/* chunk size for read */
X#define	PMS_BSIZE	1020	/* buffer size */
X
Xstruct pms_softc {		/* driver status information */
X	struct device sc_dev;
X	struct intrhand sc_ih;
X
X	struct clist sc_q;
X	struct selinfo sc_rsel;
X	u_short sc_iobase;	/* I/O port base */
X	u_char sc_state;	/* mouse driver state */
X#define	PMS_OPEN	0x01	/* device is open */
X#define	PMS_ASLP	0x02	/* waiting for mouse data */
X	u_char sc_status;	/* mouse button status */
X	int sc_x, sc_y;		/* accumulated motion in the X,Y axis */
X};
X
Xint pmsprobe();
Xvoid pmsattach();
Xint pmsintr __P((struct pms_softc *));
X
Xstruct cfdriver pmscd = {\
X	NULL, "pms", pmsprobe, pmsattach, DV_TTY, sizeof(struct pms_softc)
X};
X
X#define	PMSUNIT(dev)	(minor(dev))
X
Xstatic inline void
Xpms_flush(iobase)
X	u_short iobase;
X{
X	u_char c;
X	while (c = inb(iobase+PMS_STATUS) & 0x03)
X		if ((c & PMS_OBUF_FULL) == PMS_OBUF_FULL) {
X			/* XXX - delay is needed to prevent some keyboards from
X			   wedging when the system boots */
X			delay(6);
X			(void) inb(iobase+PMS_DATA);
X		}
X}
X
Xstatic inline void
Xpms_dev_cmd(iobase, value)
X	u_short iobase;
X	u_char value;
X{
X	pms_flush(iobase);
X	outb(iobase+PMS_CNTRL, 0xd4);
X	pms_flush(iobase);
X	outb(iobase+PMS_DATA, value);
X}
X
Xstatic inline void
Xpms_aux_cmd(iobase, value)
X	u_short iobase;
X	u_char value;
X{
X	pms_flush(iobase);
X	outb(iobase+PMS_CNTRL, value);
X}
X
Xstatic inline void
Xpms_pit_cmd(iobase, value)
X	u_short iobase;
X	u_char value;
X{
X	pms_flush(iobase);
X	outb(iobase+PMS_CNTRL, 0x60);
X	pms_flush(iobase);
X	outb(iobase+PMS_DATA, value);
X}
X
Xint
Xpmsprobe(parent, self, aux)
X	struct device *parent, *self;
X	void *aux;
X{
X	struct isa_attach_args *ia = aux;
X	u_short iobase = ia->ia_iobase;
X	u_char x;
X
X	pms_dev_cmd(iobase, PMS_RESET);
X	pms_aux_cmd(iobase, PMS_MAGIC_1);
X#ifndef IBM_TRACKPOINT
X	pms_aux_cmd(iobase, PMS_MAGIC_2);
X#endif /* IBM_TRACKPOINT */
X	x = inb(iobase+PMS_DATA);
X	pms_pit_cmd(iobase, PMS_INT_DISABLE);
X	if (x & 0x04)
X		return 0;
X
X	ia->ia_iosize = PMS_NPORTS;
X	ia->ia_msize = 0;
X
X	return 1;
X}
X
Xvoid
Xpmsattach(parent, self, aux)
X	struct device *parent, *self;
X	void *aux;
X{
X	struct pms_softc *sc = (void *)self;
X	struct isa_attach_args *ia = aux;
X	u_short iobase = ia->ia_iobase;
X
X	printf("\n");
X
X	/* Other initialization was done by pmsprobe. */
X	sc->sc_iobase = iobase;
X	sc->sc_state = 0;
X
X	sc->sc_ih.ih_fun = pmsintr;
X	sc->sc_ih.ih_arg = sc;
X	sc->sc_ih.ih_level = IPL_NONE;
X	intr_establish(ia->ia_irq, &sc->sc_ih);
X}
X
Xint
Xpmsopen(dev, flag)
X	dev_t dev;
X	int flag;
X{
X	int unit = PMSUNIT(dev);
X	struct pms_softc *sc;
X
X	if (unit >= pmscd.cd_ndevs)
X		return ENXIO;
X	sc = pmscd.cd_devs[unit];
X	if (!sc)
X		return ENXIO;
X
X	if (sc->sc_state & PMS_OPEN)
X		return EBUSY;
X
X	if (clalloc(&sc->sc_q, PMS_BSIZE, 0) == -1)
X		return ENOMEM;
X
X	sc->sc_state |= PMS_OPEN;
X	sc->sc_status = 0;
X	sc->sc_x = sc->sc_y = 0;
X
X	/* Enable interrupts. */
X	pms_dev_cmd(sc->sc_iobase, PMS_DEV_ENABLE);
X	pms_aux_cmd(sc->sc_iobase, PMS_AUX_ENABLE);
X#if 0
X	pms_dev_cmd(sc->sc_iobase, PMS_SET_RES);
X	pms_dev_cmd(sc->sc_iobase, 3);		/* 8 counts/mm */
X	pms_dev_cmd(sc->sc_iobase, PMS_SET_SCALE21);
X	pms_dev_cmd(sc->sc_iobase, PMS_SET_SAMPLE);
X	pms_dev_cmd(sc->sc_iobase, 100);	/* 100 samples/sec */
X	pms_dev_cmd(sc->sc_iobase, PMS_SET_STREAM);
X#endif
X	pms_pit_cmd(sc->sc_iobase, PMS_INT_ENABLE);
X
X	return 0;
X}
X
Xint
Xpmsclose(dev, flag)
X	dev_t dev;
X	int flag;
X{
X	struct pms_softc *sc = pmscd.cd_devs[PMSUNIT(dev)];
X
X	/* Disable interrupts. */
X#ifdef IBM_TRACKPOINT
X	/* The following piece of code prevents the keyboard from
X	   locking up on IBM ThinkPads with TrackPoint mouse device.  */
X	pms_pit_cmd(sc->sc_iobase, PMS_INT_DISABLE);
X	while (inb (sc->sc_iobase + PMS_STATUS) & 0x03) {
X		if (inb (sc->sc_iobase + PMS_STATUS) & 0x02 == 0x02)
X			inb (sc->sc_iobase + PMS_DATA);
X	}
X#else /* not IBM_TRACKPOINT */
X	pms_dev_cmd(sc->sc_iobase, PMS_DEV_DISABLE);
X	pms_pit_cmd(sc->sc_iobase, PMS_INT_DISABLE);
X	pms_aux_cmd(sc->sc_iobase, PMS_AUX_DISABLE);
X#endif /* not IBM_TRACKPOINT */
X
X	sc->sc_state &= ~PMS_OPEN;
X
X	clfree(&sc->sc_q);
X
X	return 0;
X}
X
Xint
Xpmsread(dev, uio, flag)
X	dev_t dev;
X	struct uio *uio;
X	int flag;
X{
X	struct pms_softc *sc = pmscd.cd_devs[PMSUNIT(dev)];
X	int s;
X	int error;
X	size_t length;
X	u_char buffer[PMS_CHUNK];
X
X	/* Block until mouse activity occured. */
X
X	s = spltty();
X	while (sc->sc_q.c_cc == 0) {
X		if (flag & IO_NDELAY) {
X			splx(s);
X			return EWOULDBLOCK;
X		}
X		sc->sc_state |= PMS_ASLP;
X		if (error = tsleep((caddr_t)sc, PZERO | PCATCH, "pmsrea", 0)) {
X			sc->sc_state &= ~PMS_ASLP;
X			splx(s);
X			return error;
X		}
X	}
X	splx(s);
X
X	/* Transfer as many chunks as possible. */
X
X	while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0) {
X		length = min(sc->sc_q.c_cc, uio->uio_resid);
X		if (length > sizeof(buffer))
X			length = sizeof(buffer);
X
X		/* Remove a small chunk from the input queue. */
X		(void) q_to_b(&sc->sc_q, buffer, length);
X
X		/* Copy the data to the user process. */
X		if (error = uiomove(buffer, length, uio))
X			break;
X	}
X
X	return error;
X}
X
Xint
Xpmsioctl(dev, cmd, addr, flag)
X	dev_t dev;
X	int cmd;
X	caddr_t addr;
X	int flag;
X{
X	struct pms_softc *sc = pmscd.cd_devs[PMSUNIT(dev)];
X	struct mouseinfo info;
X	int s;
X	int error;
X
X	switch (cmd) {
X	case MOUSEIOCREAD:
X		s = spltty();
X
X		info.status = sc->sc_status;
X		if (sc->sc_x || sc->sc_y)
X			info.status |= MOVEMENT;
X
X		if (sc->sc_x > 127)
X			info.xmotion = 127;
X		else if (sc->sc_x < -127)
X			/* Bounding at -127 avoids a bug in XFree86. */
X			info.xmotion = -127;
X		else
X			info.xmotion = sc->sc_x;
X
X		if (sc->sc_y > 127)
X			info.ymotion = 127;
X		else if (sc->sc_y < -127)
X			info.ymotion = -127;
X		else
X			info.ymotion = sc->sc_y;
X
X		/* Reset historical information. */
X		sc->sc_x = sc->sc_y = 0;
X		sc->sc_status &= ~BUTCHNGMASK;
X		ndflush(&sc->sc_q, sc->sc_q.c_cc);
X
X		splx(s);
X		error = copyout(&info, addr, sizeof(struct mouseinfo));
X		break;
X
X	default:
X		error = EINVAL;
X		break;
X	}
X
X	return error;
X}
X
X/* Masks for the first byte of a packet */
X#define PS2LBUTMASK 0x01
X#define PS2RBUTMASK 0x02
X#define PS2MBUTMASK 0x04
X
Xint
Xpmsintr(sc)
X	struct pms_softc *sc;
X{
X	u_short iobase = sc->sc_iobase;
X	static int state = 0;
X	static u_char buttons;
X	u_char changed;
X	static char dx, dy;
X	u_char buffer[5];
X
X	if ((sc->sc_state & PMS_OPEN) == 0) {
X		/* Interrupts are not expected.  Discard the byte. */
X		(void) inb(iobase + PMS_DATA);
X		return 0;
X	}
X
X	switch (state) {
X
X	case 0:
X		buttons = inb(iobase + PMS_DATA);
X		if ((buttons & 0xc0) == 0)
X			++state;
X		break;
X
X	case 1:
X		dx = inb(iobase + PMS_DATA);
X		/* Bounding at -127 avoids a bug in XFree86. */
X		dx = (dx == -128) ? -127 : dx;
X		++state;
X		break;
X
X	case 2:
X		dy = inb(iobase + PMS_DATA);
X		dy = (dy == -128) ? -127 : dy;
X		state = 0;
X
X		buttons = ((buttons & PS2LBUTMASK) << 2) |
X			  ((buttons & (PS2RBUTMASK | PS2MBUTMASK)) >> 1);
X		changed = ((buttons ^ sc->sc_status) & BUTSTATMASK) << 3;
X		sc->sc_status = buttons | (sc->sc_status & ~BUTSTATMASK) | changed;
X
X		if (dx || dy || changed) {
X			/* Update accumulated movements. */
X			sc->sc_x += dx;
X			sc->sc_y += dy;
X
X			/* Add this event to the queue. */
X			buffer[0] = 0x80 | (buttons ^ BUTSTATMASK);
X			buffer[1] = dx;
X			buffer[2] = dy;
X			buffer[3] = buffer[4] = 0;
X			(void) b_to_q(buffer, sizeof buffer, &sc->sc_q);
X
X			if (sc->sc_state & PMS_ASLP) {
X				sc->sc_state &= ~PMS_ASLP;
X				wakeup((caddr_t)sc);
X			}
X			selwakeup(&sc->sc_rsel);
X		}
X
X		break;
X	}
X
X	return -1;
X}
X
Xint
Xpmsselect(dev, rw, p)
X	dev_t dev;
X	int rw;
X	struct proc *p;
X{
X	struct pms_softc *sc = pmscd.cd_devs[PMSUNIT(dev)];
X	int s;
X	int ret;
X
X	if (rw == FWRITE)
X		return 0;
X
X	s = spltty();
X	if (!sc->sc_q.c_cc) {
X		selrecord(p, &sc->sc_rsel);
X		ret = 0;
X	} else
X		ret = 1;
X	splx(s);
X
X	return ret;
X}
END-of-pms.c
exit