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