diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2019-10-07 19:35:08 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2019-10-07 19:35:08 +0000 |
commit | 74abe2d6dd43b867f0ed5e832223a63ba02501d3 (patch) | |
tree | a2f18e1f5b4da7a34e87fae8039d7ee4ae5d8fb5 /sys/dev | |
parent | 4b4abfd593f9f092e3e6fa282a98704e5a8b39eb (diff) |
Add moxtet(4), a driver for the Turris Mox modules. For now this
driver only enumerates and shows the connected modules. The next
step is to implement GPIO controller functionality to e.g. control
the pins to the SFP on the MOX D.
ok kettenis@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/fdt/files.fdt | 8 | ||||
-rw-r--r-- | sys/dev/fdt/moxtet.c | 176 |
2 files changed, 182 insertions, 2 deletions
diff --git a/sys/dev/fdt/files.fdt b/sys/dev/fdt/files.fdt index 9cc5c6eceab..57bee7428a7 100644 --- a/sys/dev/fdt/files.fdt +++ b/sys/dev/fdt/files.fdt @@ -1,4 +1,4 @@ -# $OpenBSD: files.fdt,v 1.97 2019/10/07 19:30:12 patrick Exp $ +# $OpenBSD: files.fdt,v 1.98 2019/10/07 19:35:07 patrick Exp $ # # Config file and device description for machine-independent FDT code. # Included by ports that need it. @@ -240,6 +240,11 @@ device dwpcie: pcibus attach dwpcie at fdt file dev/fdt/dwpcie.c dwpcie +define spi {} +device moxtet +attach moxtet at spi +file dev/fdt/moxtet.c moxtet + device mvclock attach mvclock at fdt file dev/fdt/mvclock.c mvclock @@ -284,7 +289,6 @@ device mvrtc attach mvrtc at fdt file dev/fdt/mvrtc.c mvrtc -define spi {} device mvspi: spi attach mvspi at fdt file dev/fdt/mvspi.c mvspi diff --git a/sys/dev/fdt/moxtet.c b/sys/dev/fdt/moxtet.c new file mode 100644 index 00000000000..003d0c52d29 --- /dev/null +++ b/sys/dev/fdt/moxtet.c @@ -0,0 +1,176 @@ +/* $OpenBSD: moxtet.c,v 1.1 2019/10/07 19:35:07 patrick Exp $ */ +/* + * Copyright (c) 2019 Patrick Wildt <patrick@blueri.se> + * + * 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. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/device.h> +#include <sys/malloc.h> + +#include <dev/spi/spivar.h> + +#include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_gpio.h> +#include <dev/ofw/ofw_pinctrl.h> + +#define MOX_NMODULE 10 + +#define MOX_CPU_EMMC 0x00 +#define MOX_CPU_SD 0x10 + +#define MOX_MODULE_SFP 0x01 +#define MOX_MODULE_PCI 0x02 +#define MOX_MODULE_TOPAZ 0x03 +#define MOX_MODULE_PERIDOT 0x04 +#define MOX_MODULE_USB3 0x05 +#define MOX_MODULE_PASSPCI 0x06 + +struct moxtet_softc { + struct device sc_dev; + int sc_node; + + spi_tag_t sc_spi_tag; + struct spi_config sc_spi_conf; + + int sc_nmodule; +}; + +int moxtet_match(struct device *, void *, void *); +void moxtet_attach(struct device *, struct device *, void *); +int moxtet_detach(struct device *, int); + +int moxtet_read(struct moxtet_softc *, char *, size_t); +int moxtet_write(struct moxtet_softc *, char *, size_t); + +struct cfattach moxtet_ca = { + sizeof(struct moxtet_softc), moxtet_match, moxtet_attach, moxtet_detach +}; + +struct cfdriver moxtet_cd = { + NULL, "moxtet", DV_DULL +}; + +int +moxtet_match(struct device *parent, void *match, void *aux) +{ + struct spi_attach_args *sa = aux; + + if (strcmp(sa->sa_name, "cznic,moxtet") == 0) + return 1; + + return 0; +} + +void +moxtet_attach(struct device *parent, struct device *self, void *aux) +{ + struct moxtet_softc *sc = (struct moxtet_softc *)self; + struct spi_attach_args *sa = aux; + uint8_t buf[MOX_NMODULE]; + int i; + + sc->sc_spi_tag = sa->sa_tag; + sc->sc_node = *(int *)sa->sa_cookie; + + pinctrl_byname(sc->sc_node, "default"); + + sc->sc_spi_conf.sc_bpw = 8; + sc->sc_spi_conf.sc_freq = OF_getpropint(sc->sc_node, + "spi-max-frequency", 0); + sc->sc_spi_conf.sc_cs = OF_getpropint(sc->sc_node, "reg", 0); + if (OF_getproplen(sc->sc_node, "spi-cpol") == 0) + sc->sc_spi_conf.sc_flags |= SPI_CONFIG_CPOL; + if (OF_getproplen(sc->sc_node, "spi-cpha") == 0) + sc->sc_spi_conf.sc_flags |= SPI_CONFIG_CPHA; + if (OF_getproplen(sc->sc_node, "spi-cs-high") == 0) + sc->sc_spi_conf.sc_flags |= SPI_CONFIG_CS_HIGH; + + if (moxtet_read(sc, buf, sizeof(buf))) { + printf(": can't read moxtet\n"); + return; + } + + if (buf[0] == MOX_CPU_EMMC) + printf(": eMMC"); + else if (buf[0] == MOX_CPU_SD) + printf(": SD"); + else { + printf(": unknown\n"); + return; + } + + for (i = 1; i < MOX_NMODULE; i++) { + if (buf[i] == 0xff) + break; + sc->sc_nmodule++; + switch (buf[i] & 0xf) { + case MOX_MODULE_SFP: + printf(", SFP"); + break; + case MOX_MODULE_PCI: + printf(", mPCIe"); + break; + case MOX_MODULE_TOPAZ: + printf(", 4x GbE"); + break; + case MOX_MODULE_PERIDOT: + printf(", 8x GbE"); + break; + case MOX_MODULE_USB3: + printf(", 4x USB 3.0"); + break; + case MOX_MODULE_PASSPCI: + printf(", mPCIe (passthrough)"); + break; + default: + printf(", unknown (0x%02x)", buf[i] & 0xf); + break; + } + } + + printf("\n"); +} + +int +moxtet_detach(struct device *self, int flags) +{ + return 0; +} + +int +moxtet_read(struct moxtet_softc *sc, char *buf, size_t len) +{ + int error; + + spi_acquire_bus(sc->sc_spi_tag, 0); + spi_config(sc->sc_spi_tag, &sc->sc_spi_conf); + error = spi_read(sc->sc_spi_tag, buf, len); + spi_release_bus(sc->sc_spi_tag, 0); + return error; +} + +int +moxtet_write(struct moxtet_softc *sc, char *buf, size_t len) +{ + int error; + + spi_acquire_bus(sc->sc_spi_tag, 0); + spi_config(sc->sc_spi_tag, &sc->sc_spi_conf); + error = spi_write(sc->sc_spi_tag, buf, len); + spi_release_bus(sc->sc_spi_tag, 0); + return error; +} |