ssdfb_spi: fix issues with command xfers needed for SSD1306 & SH1106
These controllers require D/C# to be deasserted for the entire duration of the command, contrary to docs and how newer controllers like SSD1353 behave. Probably this is needed for all controllers that do not have the WRITE_RAM (0x5c) command. Also support using alternate padding commands for 3-wire mode when WRITE_RAM is not available.
This commit is contained in:
parent
21a95dabdc
commit
d15f52d220
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ssdfb_spi.c,v 1.9 2021/08/05 19:17:22 tnn Exp $ */
|
||||
/* $NetBSD: ssdfb_spi.c,v 1.10 2021/08/19 11:04:21 tnn Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 The NetBSD Foundation, Inc.
|
||||
|
@ -30,7 +30,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ssdfb_spi.c,v 1.9 2021/08/05 19:17:22 tnn Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ssdfb_spi.c,v 1.10 2021/08/19 11:04:21 tnn Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
|
@ -58,6 +58,8 @@ struct ssdfb_spi_softc {
|
|||
struct fdtbus_gpio_pin *sc_gpio_res;
|
||||
#endif
|
||||
bool sc_3wiremode;
|
||||
bool sc_late_dc_deassert;
|
||||
uint8_t sc_padding_cmd;
|
||||
};
|
||||
|
||||
static int ssdfb_spi_match(device_t, cfdata_t, void *);
|
||||
|
@ -78,7 +80,7 @@ static void ssdfb_bitstream_append(struct bs_state *, uint8_t, uint8_t);
|
|||
static void ssdfb_bitstream_append_cmd(struct bs_state *, uint8_t);
|
||||
static void ssdfb_bitstream_append_data(struct bs_state *, uint8_t *,
|
||||
size_t);
|
||||
static void ssdfb_bitstream_final(struct bs_state *);
|
||||
static void ssdfb_bitstream_final(struct bs_state *, uint8_t);
|
||||
|
||||
CFATTACH_DECL_NEW(ssdfb_spi, sizeof(struct ssdfb_spi_softc),
|
||||
ssdfb_spi_match, ssdfb_spi_attach, NULL, NULL);
|
||||
|
@ -167,6 +169,7 @@ ssdfb_spi_attach(device_t parent, device_t self, void *aux)
|
|||
sc->sc.sc_transfer_rect = sc->sc_3wiremode
|
||||
? ssdfb_spi_xfer_rect_3wire_ssd1322
|
||||
: ssdfb_spi_xfer_rect_4wire_ssd1322;
|
||||
sc->sc_padding_cmd = SSD1322_CMD_WRITE_RAM;
|
||||
break;
|
||||
case SSDFB_PRODUCT_SSD1353_GENERIC:
|
||||
case SSDFB_PRODUCT_DEP_160128A_RGB:
|
||||
|
@ -200,7 +203,7 @@ ssdfb_spi_cmd_3wire(void *cookie, uint8_t *cmd, size_t len, bool usepoll)
|
|||
cmd++;
|
||||
len--;
|
||||
ssdfb_bitstream_append_data(&s, cmd, len);
|
||||
ssdfb_bitstream_final(&s);
|
||||
ssdfb_bitstream_final(&s, sc->sc_padding_cmd);
|
||||
|
||||
return spi_send(sc->sc_sh, s.cur - s.base, bitstream);
|
||||
}
|
||||
|
@ -230,7 +233,7 @@ ssdfb_spi_xfer_rect_3wire_ssd1322(void *cookie, uint8_t fromcol, uint8_t tocol,
|
|||
ssdfb_bitstream_append_data(&s, &fromcol, 1);
|
||||
ssdfb_bitstream_append_data(&s, &tocol, 1);
|
||||
ssdfb_bitstream_append_cmd(&s, SSD1322_CMD_WRITE_RAM);
|
||||
ssdfb_bitstream_final(&s);
|
||||
ssdfb_bitstream_final(&s, sc->sc_padding_cmd);
|
||||
error = spi_send(sc->sc_sh, s.cur - s.base, bitstream);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -239,7 +242,7 @@ ssdfb_spi_xfer_rect_3wire_ssd1322(void *cookie, uint8_t fromcol, uint8_t tocol,
|
|||
for (row = fromrow; row <= torow; row++) {
|
||||
ssdfb_bitstream_init(&s, bitstream);
|
||||
ssdfb_bitstream_append_data(&s, p, rlen);
|
||||
ssdfb_bitstream_final(&s);
|
||||
ssdfb_bitstream_final(&s, sc->sc_padding_cmd);
|
||||
error = spi_send(sc->sc_sh, s.cur - s.base, bitstream);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -290,11 +293,8 @@ ssdfb_bitstream_append_data(struct bs_state *s, uint8_t *data, size_t len)
|
|||
}
|
||||
|
||||
static void
|
||||
ssdfb_bitstream_final(struct bs_state *s)
|
||||
ssdfb_bitstream_final(struct bs_state *s, uint8_t padding_cmd)
|
||||
{
|
||||
uint8_t padding_cmd = SSD1322_CMD_WRITE_RAM;
|
||||
/* padding_cmd = SSDFB_NOP_CMD; */
|
||||
|
||||
while (s->mask != 0x80) {
|
||||
ssdfb_bitstream_append_cmd(s, padding_cmd);
|
||||
}
|
||||
|
@ -321,7 +321,8 @@ ssdfb_spi_cmd_4wire(void *cookie, uint8_t *cmd, size_t len, bool usepoll)
|
|||
if (error)
|
||||
return error;
|
||||
if (len > 1) {
|
||||
ssdfb_spi_4wire_set_dc(sc, 1);
|
||||
if (!sc->sc_late_dc_deassert)
|
||||
ssdfb_spi_4wire_set_dc(sc, 1);
|
||||
len--;
|
||||
cmd++;
|
||||
error = spi_send(sc->sc_sh, len, cmd);
|
||||
|
|
Loading…
Reference in New Issue