summaryrefslogtreecommitdiff
path: root/sys/arch/sgi/dev
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-11-18 19:03:28 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-11-18 19:03:28 +0000
commit539fb2c086bcc8d287cf8f8e6f223e660d5d7a25 (patch)
treefc001406d13a56881785d4a41a64c441543167d7 /sys/arch/sgi/dev
parent49f6574b58bcf203ba3d6accf6e0f8286f620cc6 (diff)
Add glue to attach iockbc(4) to iof(4) as well. Tested by deraadt@
Diffstat (limited to 'sys/arch/sgi/dev')
-rw-r--r--sys/arch/sgi/dev/iockbc.c156
-rw-r--r--sys/arch/sgi/dev/iockbcreg.h51
2 files changed, 155 insertions, 52 deletions
diff --git a/sys/arch/sgi/dev/iockbc.c b/sys/arch/sgi/dev/iockbc.c
index 366c861b6c6..ff7a3872158 100644
--- a/sys/arch/sgi/dev/iockbc.c
+++ b/sys/arch/sgi/dev/iockbc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: iockbc.c,v 1.3 2009/11/11 15:56:41 miod Exp $ */
+/* $OpenBSD: iockbc.c,v 1.4 2009/11/18 19:03:27 miod Exp $ */
/*
* Copyright (c) 2006, 2007, 2009 Joel Sing <jsing@openbsd.org>
*
@@ -45,7 +45,7 @@
*/
/*
- * Driver for IOC3 PS/2 Controllers (iockbc)
+ * Driver for IOC3 and IOC4 PS/2 Controllers (iockbc)
*/
#include <sys/param.h>
@@ -65,14 +65,18 @@
#include <mips64/archtype.h>
-#include <sgi/localbus/crimebus.h>
-#include <sgi/localbus/macebus.h>
+#include <sgi/dev/iockbcreg.h>
+
#include <sgi/pci/iocreg.h>
#include <sgi/pci/iocvar.h>
+#include <sgi/pci/iofreg.h>
+#include <sgi/pci/iofvar.h>
#include <dev/ic/pckbcvar.h>
#include <dev/pckbc/pckbdvar.h>
+#include "iockbc.h"
+
const char *iockbc_slot_names[] = { "kbd", "mouse" };
#define KBC_DEVCMD_ACK 0xfa
@@ -91,14 +95,23 @@ struct iockbc_softc {
bus_space_handle_t ioh;
bus_addr_t rx[PCKBC_NSLOTS];
bus_addr_t tx[PCKBC_NSLOTS];
+ bus_addr_t cs;
};
int iockbc_match(struct device *, void *, void *);
-void iockbc_attach(struct device *, struct device *, void *);
+void iockbc_ioc_attach(struct device *, struct device *, void *);
+void iockbc_iof_attach(struct device *, struct device *, void *);
-struct cfattach iockbc_ca = {
- sizeof(struct iockbc_softc), iockbc_match, iockbc_attach
+#if NIOCKBC_IOC > 0
+struct cfattach iockbc_ioc_ca = {
+ sizeof(struct iockbc_softc), iockbc_match, iockbc_ioc_attach
+};
+#endif
+#if NIOCKBC_IOF > 0
+struct cfattach iockbc_iof_ca = {
+ sizeof(struct iockbc_softc), iockbc_match, iockbc_iof_attach
};
+#endif
struct cfdriver iockbc_cd = {
NULL, "iockbc", DV_DULL
@@ -131,6 +144,7 @@ struct pckbc_slotdata {
static int iockbc_console;
+void iockbc_attach_common(struct iockbc_softc *, bus_addr_t);
void iockbc_start(struct pckbc_internal *, pckbc_slot_t);
int iockbc_attach_slot(struct iockbc_softc *, pckbc_slot_t);
void iockbc_init_slotdata(struct pckbc_slotdata *);
@@ -151,11 +165,79 @@ int
iockbc_match(struct device *parent, void *cf, void *aux)
{
/*
- * We expect ioc NOT to attach us on if there are no PS/2 ports.
+ * We expect ioc and iof NOT to attach us on if there are no PS/2 ports.
*/
return 1;
}
+#if NIOCKBC_IOC > 0
+void
+iockbc_ioc_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct iockbc_softc *isc = (void*)self;
+ struct ioc_attach_args *iaa = aux;
+
+ /*
+ * For some reason keyboard and mouse ports are inverted on Fuel.
+ */
+
+ if (ISSET(iaa->iaa_flags, IOC_FLAGS_OBIO) &&
+ sys_config.system_type == SGI_IP35) {
+ isc->rx[PCKBC_KBD_SLOT] = IOC3_KBC_AUX_RX;
+ isc->rx[PCKBC_AUX_SLOT] = IOC3_KBC_KBD_RX;
+ isc->tx[PCKBC_KBD_SLOT] = IOC3_KBC_AUX_TX;
+ isc->tx[PCKBC_AUX_SLOT] = IOC3_KBC_KBD_TX;
+ } else {
+ isc->rx[PCKBC_KBD_SLOT] = IOC3_KBC_KBD_RX;
+ isc->rx[PCKBC_AUX_SLOT] = IOC3_KBC_AUX_RX;
+ isc->tx[PCKBC_KBD_SLOT] = IOC3_KBC_KBD_TX;
+ isc->tx[PCKBC_AUX_SLOT] = IOC3_KBC_AUX_TX;
+ }
+ isc->cs = IOC3_KBC_CTRL_STATUS;
+
+ /* Setup bus space mapping. */
+ isc->iot = iaa->iaa_memt;
+ isc->ioh = iaa->iaa_memh;
+
+ /* Establish interrupt handler. */
+ if (ioc_intr_establish(parent, iaa->iaa_dev, IPL_TTY, iockbcintr,
+ (void *)isc, self->dv_xname))
+ printf("\n");
+ else
+ printf(": unable to establish interrupt\n");
+
+ iockbc_attach_common(isc, iaa->iaa_base);
+}
+#endif
+
+#if NIOCKBC_IOF > 0
+void
+iockbc_iof_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct iockbc_softc *isc = (void*)self;
+ struct iof_attach_args *iaa = aux;
+
+ isc->rx[PCKBC_KBD_SLOT] = IOC4_KBC_KBD_RX;
+ isc->rx[PCKBC_AUX_SLOT] = IOC4_KBC_AUX_RX;
+ isc->tx[PCKBC_KBD_SLOT] = IOC4_KBC_KBD_TX;
+ isc->tx[PCKBC_AUX_SLOT] = IOC4_KBC_AUX_TX;
+ isc->cs = IOC4_KBC_CTRL_STATUS;
+
+ /* Setup bus space mapping. */
+ isc->iot = iaa->iaa_memt;
+ isc->ioh = iaa->iaa_memh;
+
+ /* Establish interrupt handler. */
+ if (iof_intr_establish(parent, iaa->iaa_dev, IPL_TTY, iockbcintr,
+ (void *)isc, self->dv_xname))
+ printf("\n");
+ else
+ printf(": unable to establish interrupt\n");
+
+ iockbc_attach_common(isc, iaa->iaa_base);
+}
+#endif
+
void
iockbc_init_slotdata(struct pckbc_slotdata *q)
{
@@ -222,34 +304,24 @@ iockbc_attach_slot(struct iockbc_softc *sc, pckbc_slot_t slot)
}
void
-iockbc_attach(struct device *parent, struct device *self, void *aux)
+iockbc_attach_common(struct iockbc_softc *isc, bus_addr_t addr)
{
- struct iockbc_softc *isc = (void*)self;
- struct ioc_attach_args *iaa = aux;
struct pckbc_softc *sc = &isc->sc_pckbc;
struct pckbc_internal *t;
uint32_t csr;
/*
- * For some reason keyboard and mouse ports are inverted on Fuel.
+ * Setup up controller: do not force pull clock and data lines low,
+ * clamp clocks after three bytes received.
*/
-
- if (ISSET(iaa->iaa_flags, IOC_FLAGS_OBIO) &&
- sys_config.system_type == SGI_IP35) {
- isc->rx[PCKBC_KBD_SLOT] = IOC3_KBC_AUX_RX;
- isc->rx[PCKBC_AUX_SLOT] = IOC3_KBC_KBD_RX;
- isc->tx[PCKBC_KBD_SLOT] = IOC3_KBC_AUX_TX;
- isc->tx[PCKBC_AUX_SLOT] = IOC3_KBC_KBD_TX;
- } else {
- isc->rx[PCKBC_KBD_SLOT] = IOC3_KBC_KBD_RX;
- isc->rx[PCKBC_AUX_SLOT] = IOC3_KBC_AUX_RX;
- isc->tx[PCKBC_KBD_SLOT] = IOC3_KBC_KBD_TX;
- isc->tx[PCKBC_AUX_SLOT] = IOC3_KBC_AUX_TX;
- }
-
- /* Setup bus space mapping. */
- isc->iot = iaa->iaa_memt;
- isc->ioh = iaa->iaa_memh;
+ csr = bus_space_read_4(isc->iot, isc->ioh, isc->cs);
+ csr &= ~(IOC3_KBC_CTRL_KBD_PULL_DATA_LOW |
+ IOC3_KBC_CTRL_KBD_PULL_CLOCK_LOW |
+ IOC3_KBC_CTRL_AUX_PULL_DATA_LOW |
+ IOC3_KBC_CTRL_AUX_PULL_CLOCK_LOW |
+ IOC3_KBC_CTRL_KBD_CLAMP_1 | IOC3_KBC_CTRL_AUX_CLAMP_1);
+ csr |= IOC3_KBC_CTRL_KBD_CLAMP_3 | IOC3_KBC_CTRL_AUX_CLAMP_3;
+ bus_space_write_4(isc->iot, isc->ioh, isc->cs, csr);
/* Setup pckbc_internal structure. */
t = malloc(sizeof(struct pckbc_internal), M_DEVBUF,
@@ -257,33 +329,13 @@ iockbc_attach(struct device *parent, struct device *self, void *aux)
t->t_iot = isc->iot;
t->t_ioh_d = isc->ioh;
t->t_ioh_c = isc->ioh;
- t->t_addr = iaa->iaa_base;
- t->t_sc = (struct pckbc_softc *)sc;
+ t->t_addr = addr;
+ t->t_sc = sc;
sc->id = t;
timeout_set(&t->t_cleanup, iockbc_cleanup, t);
timeout_set(&t->t_poll, iockbc_poll, t);
- /* Establish interrupt handler. */
- if (ioc_intr_establish(parent, iaa->iaa_dev, IPL_TTY, iockbcintr,
- (void *)isc, sc->sc_dv.dv_xname))
- printf("\n");
- else
- printf(": unable to establish interrupt\n");
-
- /*
- * Setup up controller: do not force pull clock and data lines low,
- * clamp clocks after three bytes received.
- */
- csr = bus_space_read_4(isc->iot, isc->ioh, IOC3_KBC_CTRL_STATUS);
- csr &= ~(IOC3_KBC_CTRL_KBD_PULL_DATA_LOW |
- IOC3_KBC_CTRL_KBD_PULL_CLOCK_LOW |
- IOC3_KBC_CTRL_AUX_PULL_DATA_LOW |
- IOC3_KBC_CTRL_AUX_PULL_CLOCK_LOW |
- IOC3_KBC_CTRL_KBD_CLAMP_1 | IOC3_KBC_CTRL_AUX_CLAMP_1);
- csr |= IOC3_KBC_CTRL_KBD_CLAMP_3 | IOC3_KBC_CTRL_AUX_CLAMP_3;
- bus_space_write_4(isc->iot, isc->ioh, IOC3_KBC_CTRL_STATUS, csr);
-
/*
* Attach "slots".
*/
@@ -407,7 +459,7 @@ iockbc_poll_write(struct pckbc_internal *t, pckbc_slot_t slot, int val)
/* Attempt to write a value to the controller. */
while (timeout--) {
- stat = bus_space_read_4(iot, ioh, IOC3_KBC_CTRL_STATUS);
+ stat = bus_space_read_4(iot, ioh, isc->cs);
if ((stat & busy) == 0) {
bus_space_write_4(iot, ioh, offset, val & 0xff);
return 0;
diff --git a/sys/arch/sgi/dev/iockbcreg.h b/sys/arch/sgi/dev/iockbcreg.h
new file mode 100644
index 00000000000..ecd31c81bcb
--- /dev/null
+++ b/sys/arch/sgi/dev/iockbcreg.h
@@ -0,0 +1,51 @@
+/* $OpenBSD: iockbcreg.h,v 1.1 2009/11/18 19:03:27 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Joel Sing.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Register definitions for the PS/2 controller part of SGI IOC3 and IOC4 ASICS.
+ */
+
+/* bits in KBC_CTRL_STATUS */
+#define IOC3_KBC_STATUS_KBD_WRITE_PENDING 0x00000001
+#define IOC3_KBC_STATUS_AUX_WRITE_PENDING 0x00000002
+#define IOC3_KBC_STATUS_KBD_DATA 0x00000010
+#define IOC3_KBC_STATUS_KBD_CLOCK 0x00000020
+#define IOC3_KBC_CTRL_KBD_PULL_DATA_LOW 0x00000040
+#define IOC3_KBC_CTRL_KBD_PULL_CLOCK_LOW 0x00000080
+#define IOC3_KBC_STATUS_AUX_DATA 0x00000100
+#define IOC3_KBC_STATUS_AUX_CLOCK 0x00000200
+#define IOC3_KBC_CTRL_AUX_PULL_DATA_LOW 0x00000400
+#define IOC3_KBC_CTRL_AUX_PULL_CLOCK_LOW 0x00000800
+#define IOC3_KBC_CTRL_KBD_CLAMP_1 0x00100000
+#define IOC3_KBC_CTRL_AUX_CLAMP_1 0x00200000
+#define IOC3_KBC_CTRL_KBD_CLAMP_3 0x00400000
+#define IOC3_KBC_CTRL_AUX_CLAMP_3 0x00800000
+
+/* bits in KBC_*_RX */
+#define IOC3_KBC_DATA_0_VALID 0x80000000
+#define IOC3_KBC_DATA_1_VALID 0x40000000
+#define IOC3_KBC_DATA_2_VALID 0x20000000
+#define IOC3_KBC_DATA_VALID (IOC3_KBC_DATA_0_VALID | \
+ IOC3_KBC_DATA_1_VALID | \
+ IOC3_KBC_DATA_2_VALID)
+#define IOC3_KBC_DATA_0_MASK 0x00ff0000
+#define IOC3_KBC_DATA_0_SHIFT 16
+#define IOC3_KBC_DATA_1_MASK 0x0000ff00
+#define IOC3_KBC_DATA_1_SHIFT 8
+#define IOC3_KBC_DATA_2_MASK 0x000000ff
+#define IOC3_KBC_DATA_2_SHIFT 0