summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2014-12-24 18:46:15 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2014-12-24 18:46:15 +0000
commitc697a5647423f8ef9b818e56b048a01605455c60 (patch)
tree073069a0ee5d5606e8be6663ed6d13eb4f20b33c /sys/arch
parentb0ed684d1e9621b3cc11b3988fe075dbe1d14af4 (diff)
tsciic(4): i2c controller onboard Tsunami and Titan chipsets, gives access to
the fan sensors on systems without RMC. From NetBSD, ok deraadt@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/alpha/conf/GENERIC4
-rw-r--r--sys/arch/alpha/conf/files.alpha6
-rw-r--r--sys/arch/alpha/pci/tsc.c9
-rw-r--r--sys/arch/alpha/pci/tsciic.c207
-rw-r--r--sys/arch/alpha/pci/tsreg.h7
5 files changed, 228 insertions, 5 deletions
diff --git a/sys/arch/alpha/conf/GENERIC b/sys/arch/alpha/conf/GENERIC
index 4b059eff2d4..6f4f2752ba5 100644
--- a/sys/arch/alpha/conf/GENERIC
+++ b/sys/arch/alpha/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.250 2014/12/11 19:44:16 tedu Exp $
+# $OpenBSD: GENERIC,v 1.251 2014/12/24 18:46:14 miod Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -281,6 +281,8 @@ ukphy* at mii? # "unknown" PHYs
# sensors
alipm* at pci? disable
iic* at alipm?
+tsciic* at tsc?
+iic* at tsciic?
adc* at iic? # Analog Devices AD7416/AD7417/7418
admtemp* at iic? # Analog Devices ADM1021
diff --git a/sys/arch/alpha/conf/files.alpha b/sys/arch/alpha/conf/files.alpha
index 3f9e838116b..e94dd8b2b30 100644
--- a/sys/arch/alpha/conf/files.alpha
+++ b/sys/arch/alpha/conf/files.alpha
@@ -1,4 +1,4 @@
-# $OpenBSD: files.alpha,v 1.100 2014/12/04 21:03:50 tedu Exp $
+# $OpenBSD: files.alpha,v 1.101 2014/12/24 18:46:14 miod Exp $
# $NetBSD: files.alpha,v 1.32 1996/11/25 04:03:21 cgd Exp $
#
# alpha-specific configuration info
@@ -212,6 +212,10 @@ device tsc {}
attach tsc at mainbus
file arch/alpha/pci/tsc.c tsc
+device tsciic: i2cbus, i2c_bitbang
+attach tsciic at tsc
+file arch/alpha/pci/tsciic.c tsciic
+
device tsp: pcibus, alpha_sgmap, alpha_pci_sgmap_pte64
attach tsp at tsc
file arch/alpha/pci/tsp_dma.c tsp
diff --git a/sys/arch/alpha/pci/tsc.c b/sys/arch/alpha/pci/tsc.c
index 0ea9235b9b7..8549752d96a 100644
--- a/sys/arch/alpha/pci/tsc.c
+++ b/sys/arch/alpha/pci/tsc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tsc.c,v 1.15 2009/10/02 18:01:47 miod Exp $ */
+/* $OpenBSD: tsc.c,v 1.16 2014/12/24 18:46:14 miod Exp $ */
/* $NetBSD: tsc.c,v 1.3 2000/06/25 19:17:40 thorpej Exp $ */
/*-
@@ -156,6 +156,10 @@ tscattach(parent, self, aux)
config_found(self, &tsp, tscprint);
}
}
+
+ tsp.tsp_name = "tsciic";
+ tsp.tsp_slot = -1;
+ config_found(self, &tsp, tscprint);
}
static int
@@ -167,7 +171,8 @@ tscprint(aux, p)
if (p)
printf("%s at %s", tsp->tsp_name, p);
- printf(" hose %d", tsp->tsp_slot);
+ if (tsp->tsp_slot >= 0)
+ printf(" hose %d", tsp->tsp_slot);
return UNCONF;
}
diff --git a/sys/arch/alpha/pci/tsciic.c b/sys/arch/alpha/pci/tsciic.c
new file mode 100644
index 00000000000..d5845c77bf1
--- /dev/null
+++ b/sys/arch/alpha/pci/tsciic.c
@@ -0,0 +1,207 @@
+/* $OpenBSD: tsciic.c,v 1.1 2014/12/24 18:46:14 miod Exp $ */
+/* $NetBSD: tsciic.c,v 1.1 2014/02/21 12:23:30 jdc Exp $ */
+
+/*
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Julian Coleman.
+ *
+ * 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/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/rwlock.h>
+
+#include <alpha/pci/tsreg.h>
+#include <alpha/pci/tsvar.h>
+
+#include <dev/i2c/i2cvar.h>
+#include <dev/i2c/i2c_bitbang.h>
+
+struct tsciic_softc {
+ struct device sc_dev;
+
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+
+ struct i2c_controller sc_i2c_tag;
+ struct rwlock sc_i2c_lock;
+};
+
+int tsciic_match(struct device *, void *, void *);
+void tsciic_attach(struct device *, struct device *, void *);
+
+const struct cfattach tsciic_ca = {
+ .ca_devsize = sizeof(struct tsciic_softc),
+ .ca_match = tsciic_match,
+ .ca_attach = tsciic_attach
+};
+
+struct cfdriver tsciic_cd = {
+ .cd_name = "tsciic",
+ .cd_class = DV_DULL
+};
+
+/* I2C glue */
+int tsciic_acquire_bus(void *, int);
+void tsciic_release_bus(void *, int);
+int tsciic_send_start(void *, int);
+int tsciic_send_stop(void *, int);
+int tsciic_initiate_xfer(void *, i2c_addr_t, int);
+int tsciic_read_byte(void *, uint8_t *, int);
+int tsciic_write_byte(void *, uint8_t, int);
+
+/* I2C bitbang glue */
+void tsciicbb_set_bits(void *, uint32_t);
+void tsciicbb_set_dir(void *, uint32_t);
+uint32_t tsciicbb_read(void *);
+
+#define MPD_BIT_SDA 0x01
+#define MPD_BIT_SCL 0x02
+static const struct i2c_bitbang_ops tsciicbb_ops = {
+ .ibo_set_bits = tsciicbb_set_bits,
+ .ibo_set_dir = tsciicbb_set_dir,
+ .ibo_read_bits = tsciicbb_read,
+ .ibo_bits = {
+ [I2C_BIT_SDA] MPD_BIT_SDA,
+ [I2C_BIT_SCL] MPD_BIT_SCL
+ }
+};
+
+int
+tsciic_match(struct device *parent, void *match, void *aux)
+{
+ struct tsp_attach_args *tsp = (struct tsp_attach_args *)aux;
+
+ return strcmp(tsp->tsp_name, tsciic_cd.cd_name) == 0;
+}
+
+void
+tsciic_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct tsciic_softc *sc = (struct tsciic_softc *)self;
+ struct i2cbus_attach_args iba;
+
+ printf("\n");
+
+ rw_init(&sc->sc_i2c_lock, "tsciiclk");
+ sc->sc_i2c_tag.ic_cookie = sc;
+ sc->sc_i2c_tag.ic_acquire_bus = tsciic_acquire_bus;
+ sc->sc_i2c_tag.ic_release_bus = tsciic_release_bus;
+ sc->sc_i2c_tag.ic_send_start = tsciic_send_start;
+ sc->sc_i2c_tag.ic_send_stop = tsciic_send_stop;
+ sc->sc_i2c_tag.ic_initiate_xfer = tsciic_initiate_xfer;
+ sc->sc_i2c_tag.ic_read_byte = tsciic_read_byte;
+ sc->sc_i2c_tag.ic_write_byte = tsciic_write_byte;
+
+ memset(&iba, 0, sizeof iba);
+ iba.iba_name = "iic";
+ iba.iba_tag = &sc->sc_i2c_tag;
+ config_found(self, &iba, iicbus_print);
+}
+
+int
+tsciic_acquire_bus(void *cookie, int flags)
+{
+ struct tsciic_softc *sc = cookie;
+
+ if (cold || (flags & I2C_F_POLL))
+ return 0;
+
+ return rw_enter(&sc->sc_i2c_lock, RW_WRITE | RW_INTR);
+}
+
+void
+tsciic_release_bus(void *cookie, int flags)
+{
+ struct tsciic_softc *sc = cookie;
+
+ if (cold || (flags & I2C_F_POLL))
+ return;
+
+ rw_exit(&sc->sc_i2c_lock);
+}
+
+int
+tsciic_send_start(void *cookie, int flags)
+{
+ return i2c_bitbang_send_start(cookie, flags, &tsciicbb_ops);
+}
+
+int
+tsciic_send_stop(void *cookie, int flags)
+{
+ return i2c_bitbang_send_stop(cookie, flags, &tsciicbb_ops);
+}
+
+int
+tsciic_initiate_xfer(void *cookie, i2c_addr_t addr, int flags)
+{
+ return i2c_bitbang_initiate_xfer(cookie, addr, flags, &tsciicbb_ops);
+}
+
+int
+tsciic_read_byte(void *cookie, uint8_t *valp, int flags)
+{
+ return i2c_bitbang_read_byte(cookie, valp, flags, &tsciicbb_ops);
+}
+
+int
+tsciic_write_byte(void *cookie, uint8_t val, int flags)
+{
+ return i2c_bitbang_write_byte(cookie, val, flags, &tsciicbb_ops);
+}
+
+/* I2C bitbanging */
+void
+tsciicbb_set_bits(void *cookie, uint32_t bits)
+{
+ uint64_t val;
+
+ val = (bits & MPD_BIT_SDA ? MPD_DS : 0) |
+ (bits & MPD_BIT_SCL ? MPD_CKS : 0);
+ alpha_mb();
+ STQP(TS_C_MPD) = val;
+ alpha_mb();
+}
+
+void
+tsciicbb_set_dir(void *cookie, uint32_t dir)
+{
+ /* Nothing to do */
+}
+
+uint32_t
+tsciicbb_read(void *cookie)
+{
+ uint64_t val;
+ uint32_t bits;
+
+ val = LDQP(TS_C_MPD);
+ bits = (val & MPD_DR ? MPD_BIT_SDA : 0) |
+ (val & MPD_CKR ? MPD_BIT_SCL : 0);
+ return bits;
+}
diff --git a/sys/arch/alpha/pci/tsreg.h b/sys/arch/alpha/pci/tsreg.h
index a6120fef104..51c9549d6b8 100644
--- a/sys/arch/alpha/pci/tsreg.h
+++ b/sys/arch/alpha/pci/tsreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tsreg.h,v 1.5 2009/10/02 18:01:47 miod Exp $ */
+/* $OpenBSD: tsreg.h,v 1.6 2014/12/24 18:46:14 miod Exp $ */
/* $NetBSD: tsreg.h,v 1.1 1999/06/29 06:46:47 ross Exp $ */
/*-
@@ -94,6 +94,11 @@
#define TS_C_MPD 0x101##a000##00c0UL
+# define MPD_DR 0x08 /* RO: Data receive */
+# define MPD_CKR 0x04 /* RO: Clock receive */
+# define MPD_DS 0x02 /* WO: Data send - Must be a 1 to receive */
+# define MPD_CKS 0x01 /* WO: Clock send */
+
#define TS_C_AAR0 0x101##a000##0100UL
#define TS_C_AAR1 0x101##a000##0140UL
#define TS_C_AAR2 0x101##a000##0180UL