[PATCH v2 4/6] drm/ssd130x: Add support for the SSD132x OLED controller family

Geert Uytterhoeven geert at linux-m68k.org
Thu Oct 12 07:57:33 UTC 2023


Hi Javier,

On Thu, Oct 12, 2023 at 8:58 AM Javier Martinez Canillas
<javierm at redhat.com> wrote:
> The Solomon SSD132x controllers (such as the SSD1322, SSD1325 and SSD1327)
> are used by 16 grayscale dot matrix OLED panels, extend the driver to also
> support this chip family.
>
> Signed-off-by: Javier Martinez Canillas <javierm at redhat.com>
> ---
>
> Changes in v2:
> - Align the rectangle to the segment width (Geert Uytterhoeven).

Thanks for the update!

> --- a/drivers/gpu/drm/solomon/ssd130x.c
> +++ b/drivers/gpu/drm/solomon/ssd130x.c

> +static int ssd132x_update_rect(struct ssd130x_device *ssd130x,
> +                              struct drm_rect *rect, u8 *buf,
> +                              u8 *data_array)
> +{
> +       unsigned int x = rect->x1;
> +       unsigned int y = rect->y1;
> +       unsigned int segment_width = SSD132X_SEGMENT_WIDTH;
> +       unsigned int width = drm_rect_width(rect);
> +       unsigned int height = drm_rect_height(rect);
> +       unsigned int columns = DIV_ROUND_UP(width, segment_width);
> +       unsigned int rows = height;
> +       struct drm_device *drm = &ssd130x->drm;
> +       u32 array_idx = 0;
> +       int ret, i, j;

unsigned int i, j;

> +
> +       drm_WARN_ONCE(drm, x % segment_width != 0, "x must be aligned to screen segment\n");
> +
> +       /*
> +        * The screen is divided in Segment and Common outputs, where
> +        * COM0 to COM[N - 1] are the rows and SEG0 to SEG[M - 1] are
> +        * the columns.
> +        *
> +        * Each Segment has a 4-bit pixel and each Common output has a
> +        * row of pixels. When using the (default) horizontal address
> +        * increment mode, each byte of data sent to the controller has
> +        * two Segments (e.g: SEG0 and SEG1) that are stored in the lower
> +        * and higher nibbles of a single byte representing one column.
> +        * That is, the first byte are SEG0 (D0[3:0]) and SEG1 (D0[7:4]),
> +        * the second byte are SEG2 (D1[3:0]) and SEG3 (D1[7:4]) and so on.
> +        */
> +
> +       /* Set column start and end */
> +       ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE, x / segment_width, columns - 1);
> +       if (ret < 0)
> +               return ret;
> +
> +       /* Set row start and end */
> +       ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE, y, rows - 1);
> +       if (ret < 0)
> +               return ret;
> +
> +       for (i = 0; i < height; i++) {
> +               /* Process pair of pixels and combine them into a single byte */
> +               for (j = 0; j < width; j += segment_width) {
> +                       u8 n1 = buf[i * width + j];
> +                       u8 n2 = buf[i * width + j + 1];
> +
> +                       data_array[array_idx++] = (n2 << 4) | n1;
> +               }
> +       }
> +
> +       /* Write out update in one go since horizontal addressing mode is used */
> +       ret = ssd130x_write_data(ssd130x, data_array, columns * rows);
> +
> +       return ret;
> +}

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

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


More information about the dri-devel mailing list