summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2021-10-31 15:12:01 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2021-10-31 15:12:01 +0000
commit70f0819f64f08065a2e40c3c3770ab39c2fc5dc6 (patch)
tree2eafa7ba6176ab0daf49c1895fd9787b3a523665 /sys
parentd5ce11133e11730a28b63056a3a2ad048a3856b7 (diff)
Extend the SPI bus API a bit. The config structure gets an sc_cs_delay
member to allow us to specify a delay between assert the CS# signal and starting the clock. And the transfer function gains a flags argument, which can be used to specify a new SPI_KEEP_CS flag to keep CS# asserted after the transfer. This allows us to do another transfer immediately afterwards without de-asserting CS# which is necessary for sending commands to the upcoming Apple M1 keyboard/touchpad driver. ok patrick@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/fdt/imxspi.c19
-rw-r--r--sys/dev/fdt/mvspi.c12
-rw-r--r--sys/dev/spi/spivar.h23
3 files changed, 33 insertions, 21 deletions
diff --git a/sys/dev/fdt/imxspi.c b/sys/dev/fdt/imxspi.c
index 425c3cba968..3c07fe68b17 100644
--- a/sys/dev/fdt/imxspi.c
+++ b/sys/dev/fdt/imxspi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imxspi.c,v 1.2 2021/10/24 17:52:26 mpi Exp $ */
+/* $OpenBSD: imxspi.c,v 1.3 2021/10/31 15:12:00 kettenis Exp $ */
/*
* Copyright (c) 2018 Patrick Wildt <patrick@blueri.se>
*
@@ -99,6 +99,7 @@ struct imxspi_softc {
int sc_ridx;
int sc_widx;
int sc_cs;
+ u_int sc_cs_delay;
};
int imxspi_match(struct device *, void *, void *);
@@ -109,7 +110,7 @@ int imxspi_intr(void *);
void imxspi_config(void *, struct spi_config *);
uint32_t imxspi_clkdiv(struct imxspi_softc *, uint32_t);
-int imxspi_transfer(void *, char *, char *, int);
+int imxspi_transfer(void *, char *, char *, int, int);
int imxspi_acquire_bus(void *, int);
void imxspi_release_bus(void *, int);
@@ -235,6 +236,7 @@ imxspi_config(void *cookie, struct spi_config *conf)
return;
}
sc->sc_cs = cs;
+ sc->sc_cs_delay = conf->sc_cs_delay;
conreg = SPI_CONREG_EN;
conreg |= SPI_CONREG_CHANNEL_MASTER;
@@ -322,7 +324,7 @@ imxspi_find_cs_gpio(struct imxspi_softc *sc, int cs)
}
int
-imxspi_transfer(void *cookie, char *out, char *in, int len)
+imxspi_transfer(void *cookie, char *out, char *in, int len, int flags)
{
struct imxspi_softc *sc = cookie;
uint32_t *gpio;
@@ -335,6 +337,7 @@ imxspi_transfer(void *cookie, char *out, char *in, int len)
gpio_controller_set_pin(gpio, 0);
delay(1);
}
+ delay(sc->sc_cs_delay);
/* drain input buffer */
while (HREAD4(sc, SPI_STATREG) & SPI_STATREG_RR)
@@ -370,10 +373,12 @@ imxspi_transfer(void *cookie, char *out, char *in, int len)
HWRITE4(sc, SPI_STATREG, SPI_STATREG_TC);
}
- gpio = imxspi_find_cs_gpio(sc, sc->sc_cs);
- if (gpio) {
- gpio_controller_set_pin(gpio, 1);
- delay(1);
+ if (!ISSET(flags, SPI_KEEP_CS)) {
+ gpio = imxspi_find_cs_gpio(sc, sc->sc_cs);
+ if (gpio) {
+ gpio_controller_set_pin(gpio, 1);
+ delay(1);
+ }
}
return 0;
diff --git a/sys/dev/fdt/mvspi.c b/sys/dev/fdt/mvspi.c
index 4731e349f3e..30b8831dbb5 100644
--- a/sys/dev/fdt/mvspi.c
+++ b/sys/dev/fdt/mvspi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mvspi.c,v 1.2 2021/10/24 17:52:26 mpi Exp $ */
+/* $OpenBSD: mvspi.c,v 1.3 2021/10/31 15:12:00 kettenis Exp $ */
/*
* Copyright (c) 2019 Patrick Wildt <patrick@blueri.se>
*
@@ -60,6 +60,7 @@ struct mvspi_softc {
struct spi_controller sc_tag;
int sc_cs;
+ u_int sc_cs_delay;
};
int mvspi_match(struct device *, void *, void *);
@@ -68,7 +69,7 @@ int mvspi_detach(struct device *, int);
void mvspi_config(void *, struct spi_config *);
uint32_t mvspi_clkdiv(struct mvspi_softc *, uint32_t);
-int mvspi_transfer(void *, char *, char *, int);
+int mvspi_transfer(void *, char *, char *, int, int);
int mvspi_acquire_bus(void *, int);
void mvspi_release_bus(void *, int);
@@ -177,6 +178,7 @@ mvspi_config(void *cookie, struct spi_config *conf)
return;
}
sc->sc_cs = cs;
+ sc->sc_cs_delay = conf->sc_cs_delay;
HCLR4(sc, SPI_CFG, SPI_CFG_PRESCALE_MASK);
HSET4(sc, SPI_CFG, mvspi_clkdiv(sc, conf->sc_freq));
@@ -229,12 +231,13 @@ mvspi_set_cs(struct mvspi_softc *sc, int cs, int on)
}
int
-mvspi_transfer(void *cookie, char *out, char *in, int len)
+mvspi_transfer(void *cookie, char *out, char *in, int len, int flags)
{
struct mvspi_softc *sc = cookie;
int i = 0;
mvspi_set_cs(sc, sc->sc_cs, 1);
+ delay(sc->sc_cs_delay);
while (i < len) {
if (mvspi_wait_state(sc, SPI_CTRL_XFER_READY,
@@ -255,7 +258,8 @@ mvspi_transfer(void *cookie, char *out, char *in, int len)
i++;
}
- mvspi_set_cs(sc, sc->sc_cs, 0);
+ if (!ISSET(flags, SPI_KEEP_CS))
+ mvspi_set_cs(sc, sc->sc_cs, 0);
return 0;
err:
diff --git a/sys/dev/spi/spivar.h b/sys/dev/spi/spivar.h
index 986bc7f602d..c56b840a3b6 100644
--- a/sys/dev/spi/spivar.h
+++ b/sys/dev/spi/spivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: spivar.h,v 1.1 2018/07/26 10:59:07 patrick Exp $ */
+/* $OpenBSD: spivar.h,v 1.2 2021/10/31 15:12:00 kettenis Exp $ */
/*
* Copyright (c) 2018 Patrick Wildt <patrick@blueri.se>
*
@@ -23,14 +23,17 @@ struct spi_config {
#define SPI_CONFIG_CS_HIGH (1 << 2)
int sc_bpw;
uint32_t sc_freq;
+ u_int sc_cs_delay;
};
+#define SPI_KEEP_CS (1 << 0)
+
typedef struct spi_controller {
- void *sc_cookie;
- void (*sc_config)(void *, struct spi_config *);
- int (*sc_transfer)(void *, char *, char *, int);
- int (*sc_acquire_bus)(void *, int);
- void (*sc_release_bus)(void *, int);
+ void *sc_cookie;
+ void (*sc_config)(void *, struct spi_config *);
+ int (*sc_transfer)(void *, char *, char *, int, int);
+ int (*sc_acquire_bus)(void *, int);
+ void (*sc_release_bus)(void *, int);
} *spi_tag_t;
struct spi_attach_args {
@@ -42,11 +45,11 @@ struct spi_attach_args {
#define spi_config(sc, config) \
(*(sc)->sc_config)((sc)->sc_cookie, (config))
#define spi_read(sc, data, len) \
- (*(sc)->sc_transfer)((sc)->sc_cookie, NULL, (data), (len))
+ (*(sc)->sc_transfer)((sc)->sc_cookie, NULL, (data), (len), 0)
#define spi_write(sc, data, len) \
- (*(sc)->sc_transfer)((sc)->sc_cookie, (data), NULL, (len))
-#define spi_transfer(sc, out, in, len) \
- (*(sc)->sc_transfer)((sc)->sc_cookie, (out), (in), (len))
+ (*(sc)->sc_transfer)((sc)->sc_cookie, (data), NULL, (len), 0)
+#define spi_transfer(sc, out, in, len, flags) \
+ (*(sc)->sc_transfer)((sc)->sc_cookie, (out), (in), (len), (flags))
#define spi_acquire_bus(sc, flags) \
(*(sc)->sc_acquire_bus)((sc)->sc_cookie, (flags))
#define spi_release_bus(sc, flags) \