Skip to contentSkip to conversation

Add support for Sitronix ST7571 LCD controller

PATCH Applied Marcus Folkesson 3 participants 11 messages Apr 23, 2025 – Apr 29, 2025

Subsystems (4)
lore
Share & tools
lore

Marcus Folkesson

author maintainer
#0 lore raw

v6 cover Add support for Sitronix ST7571 LCD controller

This series add support for the ST7571 LCD Controller.
It is a 4 gray scale dot matrix LCD controller that supports several interfaces such as SPI, I2C and a 8bit parallell port. The controlelr supports both monochrome and grayscale displays.

This driver only supports the I2C interface, but all common parts could easily be put into a common file to be used with other interfaces. I only have I2C to test with.

The device is a little defiant, it tends to NAK some commands, but all commands takes effect, hence the I2C_M_IGNORE_NAK flag.

---
Changes in v6:
- Rebase on drm-misc/drm-next
- Silent checkpatch --strict warnings
- Link to v5: https://lore.kernel.org/r/[email protected]

Changes in v5:
- Use bitfield macros where appropriate
- Add comments where needed
- Link to v4: https://lore.kernel.org/r/[email protected]

Changes in v4:
- (dt-binding) Add sitronix,grayscale property
- Describe why ignore_nack may be needed
- Make drm_to_st7571 an inline function
- Add support to clear screen
- Change from C2 to R2
- Add support for XRGB8888
- Use dev_err_probe() where appropriate
- Make Kconfig config depend on MMU
- Introduce device data to prepare for support for other chips
- Add support for drm_encoder_helper_funcs.atomic_en(dis)able
- Link to v3: https://lore.kernel.org/r/[email protected]

Changes in v3:
- (dt-binding) Use 'Controller' rather than 'Panel' in texts
- (dt-binding) Constrain the reg property
- (dt-binding) Remove panel-timing description
- (dt-binding) Change description
- Mostly cosmetic changes in the driver code
- Don't call drm_atomic_helper_shutdown() in remove()
- Link to v2: https://lore.kernel.org/r/[email protected]

Changes in v2:
- Reworked pretty much the whole driver to not use obsolete code.
- Use panel and timing bindings to specify resolution and panel size
- Link to v1: https://lore.kernel.org/r/[email protected]

---
Marcus Folkesson (3):
dt-bindings: display: Add Sitronix ST7571 LCD Controller drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
MAINTAINERS: add entry for Sitronix ST7571 LCD Controller

 .../bindings/display/sitronix,st7571.yaml          |   73 ++
 MAINTAINERS                                        |    6 +
 drivers/gpu/drm/tiny/Kconfig                       |   11 +
 drivers/gpu/drm/tiny/Makefile                      |    1 +
 drivers/gpu/drm/tiny/st7571-i2c.c                  | 1002 ++++++++++++++++++++
 5 files changed, 1093 insertions(+)

---
base-commit: e270b3665f8321c45ad3e9ba4e3d0fbaf8c9c720
change-id: 20250401-st7571-9382b9cfc03f

Best regards,

Signature · 1 line
Marcus Folkesson <[email protected]>
author maintainer
#1 lore raw

PATCH v6 1/3 dt-bindings: display: Add Sitronix ST7571 LCD Controller

Sitronix ST7571 is a dot matrix LCD controller supporting both 4bit grayscale and monochrome LCDs.

---
 .../bindings/display/sitronix,st7571.yaml          | 73 ++++++++++++++++++++++
 1 file changed, 73 insertions(+)
Documentation/devicetree/bindings/display/sitronix,st7571.yaml new file +73 -0
new file mode 100644
index 0000000000000000000000000000000000000000..4fea782fccd701f5095a08290c13722a12a58b52
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/sitronix,st7571.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sitronix ST7571 Display Controller
+
+maintainers:
+  - Marcus Folkesson <[email protected]>
+
+description:
+  Sitronix ST7571 is a driver and controller for 4-level gray
+  scale and monochrome dot matrix LCD panels.
+
+allOf:
+  - $ref: panel/panel-common.yaml#
+
+properties:
+  compatible:
+    const: sitronix,st7571
+
+  reg:
+    maxItems: 1
+
+  sitronix,grayscale:
+    type: boolean
+    description:
+      Display supports 4-level grayscale.
+
+  reset-gpios: true
+  width-mm: true
+  height-mm: true
+  panel-timing: true
+
+required:
+  - compatible
+  - reg
+  - reset-gpios
+  - width-mm
+  - height-mm
+  - panel-timing
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      display@3f {
+        compatible = "sitronix,st7571";
+        reg = <0x3f>;
+        reset-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
+        width-mm = <37>;
+        height-mm = <27>;
+
+        panel-timing {
+          hactive = <128>;
+          vactive = <96>;
+          hback-porch = <0>;
+          vback-porch = <0>;
+          clock-frequency = <0>;
+          hfront-porch = <0>;
+          hsync-len = <0>;
+          vfront-porch = <0>;
+          vsync-len = <0>;
+        };
+      };
+    };
Signature · 1 line
2.49.0
author maintainer
#2 lore raw

PATCH v6 2/3 drm/st7571-i2c: add support for Sitronix ST7571 LCD controller

In reply to Marcus Folkesson

Sitronix ST7571 is a 4bit gray scale dot matrix LCD controller. The controller has a SPI, I2C and 8bit parallel interface, this driver is for the I2C interface only.

---
 drivers/gpu/drm/tiny/Kconfig      |   11 +
 drivers/gpu/drm/tiny/Makefile     |    1 +
 drivers/gpu/drm/tiny/st7571-i2c.c | 1002 +++++++++++++++++++++++++++++++++++++
 3 files changed, 1014 insertions(+)
drivers/gpu/drm/tiny/Kconfig +11 -0
index 95c1457d773099b4460e4adb872ed8bc64f1f282..9fa333709828f78f5fe5639f7ce40117455ff046 100644
@@ -212,6 +212,17 @@ config TINYDRM_ST7586
 
 	  If M is selected the module will be called st7586.
 
+config DRM_ST7571_I2C
+	tristate "DRM support for Sitronix ST7571 display panels (I2C)"
+	depends on DRM && I2C && MMU
+	select DRM_GEM_SHMEM_HELPER
+	select DRM_KMS_HELPER
+	select REGMAP_I2C
+	help
+	  DRM driver for Sitronix ST7571 panels controlled over I2C.
+
+	  if M is selected the module will be called st7571-i2c.
+
 config TINYDRM_ST7735R
 	tristate "DRM support for Sitronix ST7715R/ST7735R display panels"
 	depends on DRM && SPI
drivers/gpu/drm/tiny/Makefile +1 -0
index ba4a60bb72bdfb24c910e4992cab5047d4f9136d..0151590db5cbd80aebde0629afd03f47b83c3045 100644
@@ -6,6 +6,7 @@ obj-$(CONFIG_DRM_BOCHS)			+= bochs.o
 obj-$(CONFIG_DRM_CIRRUS_QEMU)		+= cirrus-qemu.o
 obj-$(CONFIG_DRM_GM12U320)		+= gm12u320.o
 obj-$(CONFIG_DRM_PANEL_MIPI_DBI)	+= panel-mipi-dbi.o
+obj-$(CONFIG_DRM_ST7571_I2C)		+= st7571-i2c.o
 obj-$(CONFIG_TINYDRM_HX8357D)		+= hx8357d.o
 obj-$(CONFIG_TINYDRM_ILI9163)		+= ili9163.o
 obj-$(CONFIG_TINYDRM_ILI9225)		+= ili9225.o
drivers/gpu/drm/tiny/st7571-i2c.c new file +1002 -0

1,002 lines not on this page · raw message

Signature · 1 line
2.49.0
#3 lore raw

Re: [PATCH v6 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller

Marcus Folkesson <[email protected]> writes:

Hello Marcus,

Quoted 8 lines

Sitronix ST7571 is a 4bit gray scale dot matrix LCD controller. The controller has a SPI, I2C and 8bit parallel interface, this driver is for the I2C interface only.

---

[...]

Review

Quoted 5 lines
(quoted diff) +5 -0
+
+static void st7571_reset(struct st7571_device *st7571)
+{
+	gpiod_set_value_cansleep(st7571->reset, 1);
+	fdelay(20);

There's no fdelay() and this leads to a build failure now:

make -j16 M=drivers/gpu/drm/tiny/
...
CC [M] st7571-i2c.o
st7571-i2c.c: In function ‘st7571_reset’:
st7571-i2c.c:815:9: error: implicit declaration of function ‘fdelay’; did you mean ‘ndelay’? [-Wimplicit-function-declaration]

  815 |         fdelay(20);
      |         ^~~~~~
      |         ndelay

but I think you meant fsleep() here (which makes sense to me), so I will apply the following fixup to this patch before pushing it:

drivers/gpu/drm/tiny/st7571-i2c.c +1 -1
index ba089a7e2b61..dc410ec41baf 100644
@@ -812,7 +812,7 @@ static int st7571_parse_dt(struct st7571_device *st7571)
 static void st7571_reset(struct st7571_device *st7571)
 {
        gpiod_set_value_cansleep(st7571->reset, 1);
-       fdelay(20);
+       fsleep(20);
        gpiod_set_value_cansleep(st7571->reset, 0);
 }
 
Signature · 5 lines
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat
#4 lore raw

Re: [PATCH v6 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller

In reply to Marcus Folkesson

Hi Marcus,

Quoted 7 lines · Marcus Folkesson

Sitronix ST7571 is a 4bit gray scale dot matrix LCD controller. The controller has a SPI, I2C and 8bit parallel interface, this driver is for the I2C interface only.

Thanks for your patch, which is now commit 4b35f0f41ee29505 ("drm/st7571-i2c: add support for Sitronix ST7571 LCD controller") in drm-misc-next.

Quoted 38 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +35 -0
 
+static int st7571_fb_update_rect_grayscale(struct drm_framebuffer *fb, struct drm_rect *rect)
+{
+       struct st7571_device *st7571 = drm_to_st7571(fb->dev);
+       u32 format = fb->format->format;
+       char *row = st7571->row;
+       int x1;
+       int x2;
+
+       /* Align y to display page boundaries */
+       rect->y1 = round_down(rect->y1, ST7571_PAGE_HEIGHT);
+       rect->y2 = min_t(unsigned int, round_up(rect->y2, ST7571_PAGE_HEIGHT), st7571->nlines);
+
+       switch (format) {
+       case DRM_FORMAT_XRGB8888:
+               /* Threated as monochrome (R1) */
+               fallthrough;
+       case DRM_FORMAT_R1:
+               x1 = rect->x1;
+               x2 = rect->x2;
+               break;
+       case DRM_FORMAT_R2:
+               x1 = rect->x1 * 2;
+               x2 = rect->x2 * 2;
+               break;
+       }
+
+       for (int y = rect->y1; y < rect->y2; y += ST7571_PAGE_HEIGHT) {
+               for (int x = x1; x < x2; x++)
+                       row[x] = st7571_transform_xy(st7571->hwbuf, x, y);
+
+               st7571_set_position(st7571, rect->x1, y);
+
+               /* TODO: Investige why we can't write multiple bytes at once */
+               for (int x = x1; x < x2; x++) {
+                       regmap_bulk_write(st7571->regmap, ST7571_DATA_MODE, row + x, 1);

drivers/gpu/drm/tiny/st7571-i2c.c line 388

Quoted 10 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +10 -0
+
+                       /*
+                        * As the display supports grayscale, all pixels must be written as two bits
+                        * even if the format is monochrome.
+                        *
+                        * The bit values maps to the following grayscale:
+                        * 0 0 = White
+                        * 0 1 = Light gray
+                        * 1 0 = Dark gray
+                        * 1 1 = Black

That is not R2, but D2?
include/uapi/drm/drm_fourcc.h:

    /* 2 bpp Red (direct relationship between channel value and brightness) */
    #define DRM_FORMAT_R2             fourcc_code('R', '2', ' ', ' ')

/* [7:0] R0:R1:R2:R3 2:2:2:2 four pixels/byte */

    /* 2 bpp Darkness (inverse relationship between channel value and
brightness) */
    #define DRM_FORMAT_D2             fourcc_code('D', '2', ' ', ' ')

/* [7:0] D0:D1:D2:D3 2:2:2:2 four pixels/byte */

So the driver actually supports D1 and D2, and XRGB8888 should be inverted while converting to monochrome (and grayscale, which is not yet implemented).

drivers/gpu/drm/tiny/st7571-i2c.c line 399

Quoted 11 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +11 -0
+                        *
+                        * For monochrome formats, write the same value twice to get
+                        * either a black or white pixel.
+                        */
+                       if (format == DRM_FORMAT_R1 || format == DRM_FORMAT_XRGB8888)
+                               regmap_bulk_write(st7571->regmap, ST7571_DATA_MODE, row + x, 1);
+               }
+       }
+
+       return 0;
+}

Gr{oetje,eeting}s,

Geert

Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
author maintainer
#5 lore raw

Re: [PATCH v6 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller

Hi Geert,

Quoted 2 lines · Geert Uytterhoeven

Hi Marcus,

[...]

Quoted 17 lines

drivers/gpu/drm/tiny/st7571-i2c.c line 388

Quoted 9 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +9 -0
+                       /*
+                        * As the display supports grayscale, all pixels must be written as two bits
+                        * even if the format is monochrome.
+                        *
+                        * The bit values maps to the following grayscale:
+                        * 0 0 = White
+                        * 0 1 = Light gray
+                        * 1 0 = Dark gray
+                        * 1 1 = Black

That is not R2, but D2?
include/uapi/drm/drm_fourcc.h:

    /* 2 bpp Red (direct relationship between channel value and brightness) */
    #define DRM_FORMAT_R2             fourcc_code('R', '2', ' ', ' ')

/* [7:0] R0:R1:R2:R3 2:2:2:2 four pixels/byte */

Quoted 8 lines
    /* 2 bpp Darkness (inverse relationship between channel value and
brightness) */
    #define DRM_FORMAT_D2             fourcc_code('D', '2', ' ', ' ')

/* [7:0] D0:D1:D2:D3 2:2:2:2 four pixels/byte */

So the driver actually supports D1 and D2, and XRGB8888 should be inverted while converting to monochrome (and grayscale, which is not yet implemented).

Hrm, that seems right.
I'm up to some rework of the driver, so I will put it into my pipeline.

Thank you for noticing this!

Best regards,
Marcus Folkesson

author maintainer
#6 lore raw

Re: [PATCH v6 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller

In reply to Geert Uytterhoeven

Hello Geert,

On Thu, Apr 24, 2025 at 10:38:33AM +0200, Geert Uytterhoeven wrote:

[...]

Quoted 17 lines

drivers/gpu/drm/tiny/st7571-i2c.c line 388

Quoted 9 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +9 -0
+                       /*
+                        * As the display supports grayscale, all pixels must be written as two bits
+                        * even if the format is monochrome.
+                        *
+                        * The bit values maps to the following grayscale:
+                        * 0 0 = White
+                        * 0 1 = Light gray
+                        * 1 0 = Dark gray
+                        * 1 1 = Black

That is not R2, but D2?
include/uapi/drm/drm_fourcc.h:

    /* 2 bpp Red (direct relationship between channel value and brightness) */
    #define DRM_FORMAT_R2             fourcc_code('R', '2', ' ', ' ')

/* [7:0] R0:R1:R2:R3 2:2:2:2 four pixels/byte */

Quoted 8 lines
    /* 2 bpp Darkness (inverse relationship between channel value and
brightness) */
    #define DRM_FORMAT_D2             fourcc_code('D', '2', ' ', ' ')

/* [7:0] D0:D1:D2:D3 2:2:2:2 four pixels/byte */

So the driver actually supports D1 and D2, and XRGB8888 should be inverted while converting to monochrome (and grayscale, which is not yet implemented).

The display supports "reverse" grayscale, so the mapping becomes 1 1 = White
1 0 = Light gray
0 1 = Dark gray
0 0 = Black
instead.

So I will probably add support for D1 and D2 formats and invert the pixels for the R1, R2 and XRGB8888 formats.

Could that work or are there any side effects that I should be aware of?

Best regards,
Marcus Folkesson

#7 lore raw

Re: [PATCH v6 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller

Hi Marcus,

Quoted 37 lines · Marcus Folkesson

On Thu, Apr 24, 2025 at 10:38:33AM +0200, Geert Uytterhoeven wrote:

[...]

Quoted 17 lines

drivers/gpu/drm/tiny/st7571-i2c.c line 388

Quoted 9 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +9 -0
+                       /*
+                        * As the display supports grayscale, all pixels must be written as two bits
+                        * even if the format is monochrome.
+                        *
+                        * The bit values maps to the following grayscale:
+                        * 0 0 = White
+                        * 0 1 = Light gray
+                        * 1 0 = Dark gray
+                        * 1 1 = Black

That is not R2, but D2?
include/uapi/drm/drm_fourcc.h:

    /* 2 bpp Red (direct relationship between channel value and brightness) */
    #define DRM_FORMAT_R2             fourcc_code('R', '2', ' ', ' ')

/* [7:0] R0:R1:R2:R3 2:2:2:2 four pixels/byte */

Quoted 8 lines
    /* 2 bpp Darkness (inverse relationship between channel value and
brightness) */
    #define DRM_FORMAT_D2             fourcc_code('D', '2', ' ', ' ')

/* [7:0] D0:D1:D2:D3 2:2:2:2 four pixels/byte */

So the driver actually supports D1 and D2, and XRGB8888 should be inverted while converting to monochrome (and grayscale, which is not yet implemented).

The display supports "reverse" grayscale, so the mapping becomes 1 1 = White
1 0 = Light gray
0 1 = Dark gray
0 0 = Black
instead.

Quoted 4 lines

So I will probably add support for D1 and D2 formats and invert the pixels for the R1, R2 and XRGB8888 formats.

Could that work or are there any side effects that I should be aware of?

That should work fine.
Note that you do not have to support R1 and R2, as they are non-native. AFAIK XRGB8888 is the only format all drivers must support.

Gr{oetje,eeting}s,

Geert

Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
#8 lore raw

Re: [PATCH v6 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller

Quoted 41 lines · Geert Uytterhoeven

Hi Marcus,

Quoted 37 lines · Marcus Folkesson

On Thu, Apr 24, 2025 at 10:38:33AM +0200, Geert Uytterhoeven wrote:

[...]

Quoted 17 lines

drivers/gpu/drm/tiny/st7571-i2c.c line 388

Quoted 9 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +9 -0
+                       /*
+                        * As the display supports grayscale, all pixels must be written as two bits
+                        * even if the format is monochrome.
+                        *
+                        * The bit values maps to the following grayscale:
+                        * 0 0 = White
+                        * 0 1 = Light gray
+                        * 1 0 = Dark gray
+                        * 1 1 = Black

That is not R2, but D2?
include/uapi/drm/drm_fourcc.h:

    /* 2 bpp Red (direct relationship between channel value and brightness) */
    #define DRM_FORMAT_R2             fourcc_code('R', '2', ' ', ' ')

/* [7:0] R0:R1:R2:R3 2:2:2:2 four pixels/byte */

Quoted 8 lines
    /* 2 bpp Darkness (inverse relationship between channel value and
brightness) */
    #define DRM_FORMAT_D2             fourcc_code('D', '2', ' ', ' ')

/* [7:0] D0:D1:D2:D3 2:2:2:2 four pixels/byte */

So the driver actually supports D1 and D2, and XRGB8888 should be inverted while converting to monochrome (and grayscale, which is not yet implemented).

The display supports "reverse" grayscale, so the mapping becomes 1 1 = White
1 0 = Light gray
0 1 = Dark gray
0 0 = Black
instead.

Quoted 6 lines
Quoted 4 lines

So I will probably add support for D1 and D2 formats and invert the pixels for the R1, R2 and XRGB8888 formats.

Could that work or are there any side effects that I should be aware of?

That should work fine.

Agree.

Quoted 5 lines

Note that you do not have to support R1 and R2, as they are non-native. AFAIK XRGB8888 is the only format all drivers must support.

Gr{oetje,eeting}s,

That's correct. The driver should only support D1 and D2 as native formats and (emulated) XRGB8888 for compatibility with existing user-space. No need to support R1 and R2 since the controller does not support these formats.

Signature · 5 lines
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat
author maintainer
#9 lore raw

PATCH v6 3/3 MAINTAINERS: add entry for Sitronix ST7571 LCD Controller

In reply to Marcus Folkesson

Add MAINTAINERS entry for the Sitronix ST7571 dot matrix LCD controller.

---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)
MAINTAINERS +6 -0
index 251b1f3d0e9225f79fb500f563f35a21510090c6..81b81cc68ca2482f2965b801693ff8a43bbf2053 100644
@@ -7682,6 +7682,12 @@ T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
 F:	Documentation/devicetree/bindings/display/sitronix,st7586.txt
 F:	drivers/gpu/drm/tiny/st7586.c
 
+DRM DRIVER FOR SITRONIX ST7571 PANELS
+M:	Marcus Folkesson <[email protected]>
+S:	Maintained
+F:	Documentation/devicetree/bindings/display/sitronix,st7571.yaml
+F:	drivers/gpu/drm/tiny/st7571-i2c.c
+
 DRM DRIVER FOR SITRONIX ST7701 PANELS
 M:	Jagan Teki <[email protected]>
 S:	Maintained
Signature · 1 line
2.49.0
#10 lore raw
In reply to Marcus Folkesson
Quoted 9 lines · Marcus Folkesson

This series add support for the ST7571 LCD Controller.
It is a 4 gray scale dot matrix LCD controller that supports several interfaces such as SPI, I2C and a 8bit parallell port. The controlelr supports both monochrome and grayscale displays.

This driver only supports the I2C interface, but all common parts could easily be put into a common file to be used with other interfaces. I only have I2C to test with.

Quoted 5 lines

The device is a little defiant, it tends to NAK some commands, but all commands takes effect, hence the I2C_M_IGNORE_NAK flag.

---

Pushed to drm-misc (drm-misc-next). Thanks!

Signature · 5 lines
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat