-/* $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>
*
int sc_ridx;
int sc_widx;
int sc_cs;
+ u_int sc_cs_delay;
};
int imxspi_match(struct device *, void *, 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);
return;
}
sc->sc_cs = cs;
+ sc->sc_cs_delay = conf->sc_cs_delay;
conreg = SPI_CONREG_EN;
conreg |= SPI_CONREG_CHANNEL_MASTER;
}
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;
gpio_controller_set_pin(gpio, 0);
delay(1);
}
+ delay(sc->sc_cs_delay);
/* drain input buffer */
while (HREAD4(sc, SPI_STATREG) & SPI_STATREG_RR)
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;
-/* $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>
*
struct spi_controller sc_tag;
int sc_cs;
+ u_int sc_cs_delay;
};
int mvspi_match(struct device *, void *, void *);
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);
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));
}
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,
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:
-/* $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>
*
#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 {
#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) \