Re: [PATCH v2 4/6] drm/ssd130x: Add support for the SSD132x OLED controller family
From: Geert Uytterhoeven
Date: Thu Oct 12 2023 - 03:57:52 EST
Hi Javier,
On Thu, Oct 12, 2023 at 8:58 AM Javier Martinez Canillas
<javierm@xxxxxxxxxx> 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@xxxxxxxxxx>
> ---
>
> 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@xxxxxxxxxxxxxx
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