1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Driver for Sitronix ST7571, a 4 level gray scale dot matrix LCD controller 4 * 5 * Copyright (C) 2025 Marcus Folkesson <marcus.folkesson@gmail.com> 6 */ 7 8 #include <linux/bitfield.h> 9 #include <linux/delay.h> 10 #include <linux/gpio/consumer.h> 11 #include <linux/i2c.h> 12 #include <linux/module.h> 13 #include <linux/regmap.h> 14 15 #include <drm/clients/drm_client_setup.h> 16 #include <drm/drm_atomic.h> 17 #include <drm/drm_atomic_helper.h> 18 #include <drm/drm_connector.h> 19 #include <drm/drm_crtc_helper.h> 20 #include <drm/drm_damage_helper.h> 21 #include <drm/drm_drv.h> 22 #include <drm/drm_encoder.h> 23 #include <drm/drm_fb_helper.h> 24 #include <drm/drm_fbdev_shmem.h> 25 #include <drm/drm_fourcc.h> 26 #include <drm/drm_framebuffer.h> 27 #include <drm/drm_gem_atomic_helper.h> 28 #include <drm/drm_gem_framebuffer_helper.h> 29 #include <drm/drm_gem_shmem_helper.h> 30 #include <drm/drm_modeset_helper_vtables.h> 31 #include <drm/drm_module.h> 32 #include <drm/drm_plane.h> 33 #include <drm/drm_probe_helper.h> 34 35 #include <video/display_timing.h> 36 #include <video/of_display_timing.h> 37 38 #include "st7571.h" 39 40 #define ST7571_COMMAND_MODE (0x00) 41 #define ST7571_DATA_MODE (0x40) 42 43 /* Normal mode command set */ 44 #define ST7571_DISPLAY_OFF (0xae) 45 #define ST7571_DISPLAY_ON (0xaf) 46 #define ST7571_OSC_ON (0xab) 47 #define ST7571_SET_COLUMN_LSB(c) (0x00 | FIELD_PREP(GENMASK(3, 0), (c))) 48 #define ST7571_SET_COLUMN_MSB(c) (0x10 | FIELD_PREP(GENMASK(2, 0), (c) >> 4)) 49 #define ST7571_SET_COM0_LSB(x) (FIELD_PREP(GENMASK(6, 0), (x))) 50 #define ST7571_SET_COM0_MSB (0x44) 51 #define ST7571_SET_COM_SCAN_DIR(d) (0xc0 | FIELD_PREP(GENMASK(3, 3), (d))) 52 #define ST7571_SET_CONTRAST_LSB(c) (FIELD_PREP(GENMASK(5, 0), (c))) 53 #define ST7571_SET_CONTRAST_MSB (0x81) 54 #define ST7571_SET_DISPLAY_DUTY_LSB(d) (FIELD_PREP(GENMASK(7, 0), (d))) 55 #define ST7571_SET_DISPLAY_DUTY_MSB (0x48) 56 #define ST7571_SET_ENTIRE_DISPLAY_ON(p) (0xa4 | FIELD_PREP(GENMASK(0, 0), (p))) 57 #define ST7571_SET_LCD_BIAS(b) (0x50 | FIELD_PREP(GENMASK(2, 0), (b))) 58 #define ST7571_SET_MODE_LSB(m) (FIELD_PREP(GENMASK(7, 2), (m))) 59 #define ST7571_SET_MODE_MSB (0x38) 60 #define ST7571_SET_PAGE(p) (0xb0 | FIELD_PREP(GENMASK(3, 0), (p))) 61 #define ST7571_SET_POWER(p) (0x28 | FIELD_PREP(GENMASK(2, 0), (p))) 62 #define ST7571_SET_REGULATOR_REG(r) (0x20 | FIELD_PREP(GENMASK(2, 0), (r))) 63 #define ST7571_SET_REVERSE(r) (0xa6 | FIELD_PREP(GENMASK(0, 0), (r))) 64 #define ST7571_SET_SEG_SCAN_DIR(d) (0xa0 | FIELD_PREP(GENMASK(0, 0), (d))) 65 #define ST7571_SET_START_LINE_LSB(l) (FIELD_PREP(GENMASK(6, 0), (l))) 66 #define ST7571_SET_START_LINE_MSB (0x40) 67 68 /* Extension command set 3 */ 69 #define ST7571_COMMAND_SET_3 (0x7b) 70 #define ST7571_SET_COLOR_MODE(c) (0x10 | FIELD_PREP(GENMASK(0, 0), (c))) 71 #define ST7571_COMMAND_SET_NORMAL (0x00) 72 73 /* ST7567 commands */ 74 #define ST7567_SET_LCD_BIAS(m) (0xa2 | FIELD_PREP(GENMASK(0, 0), (m))) 75 76 #define ST7571_PAGE_HEIGHT 8 77 78 #define DRIVER_NAME "st7571" 79 #define DRIVER_DESC "ST7571 DRM driver" 80 #define DRIVER_MAJOR 1 81 #define DRIVER_MINOR 0 82 83 static inline struct st7571_device *drm_to_st7571(struct drm_device *drm) 84 { 85 return container_of(drm, struct st7571_device, drm); 86 } 87 88 static int st7571_send_command_list(struct st7571_device *st7571, 89 const u8 *cmd_list, size_t len) 90 { 91 int ret; 92 93 for (int i = 0; i < len; i++) { 94 ret = regmap_write(st7571->regmap, ST7571_COMMAND_MODE, cmd_list[i]); 95 if (ret < 0) 96 return ret; 97 } 98 99 return ret; 100 } 101 102 static inline u8 st7571_transform_xy(const char *p, int x, int y, u8 bpp) 103 { 104 int xrest = x % 8; 105 u8 result = 0; 106 u8 row_len = 16 * bpp; 107 108 /* 109 * Transforms an (x, y) pixel coordinate into a vertical 8-bit 110 * column from the framebuffer. It calculates the corresponding byte in the 111 * framebuffer, extracts the bit at the given x position across 8 consecutive 112 * rows, and packs those bits into a single byte. 113 * 114 * Return an 8-bit value representing a vertical column of pixels. 115 */ 116 x = x / 8; 117 y = (y / 8) * 8; 118 119 for (int i = 0; i < 8; i++) { 120 int row_idx = y + i; 121 u8 byte = p[row_idx * row_len + x]; 122 u8 bit = (byte >> xrest) & 1; 123 124 result |= (bit << i); 125 } 126 127 return result; 128 } 129 130 static int st7571_set_position(struct st7571_device *st7571, int x, int y) 131 { 132 u8 cmd_list[] = { 133 ST7571_SET_COLUMN_LSB(x), 134 ST7571_SET_COLUMN_MSB(x), 135 ST7571_SET_PAGE(y / ST7571_PAGE_HEIGHT), 136 }; 137 138 return st7571_send_command_list(st7571, cmd_list, ARRAY_SIZE(cmd_list)); 139 } 140 141 static int st7571_fb_clear_screen(struct st7571_device *st7571) 142 { 143 u32 npixels = st7571->ncols * round_up(st7571->nlines, ST7571_PAGE_HEIGHT) * st7571->bpp; 144 char pixelvalue = 0x00; 145 146 st7571_set_position(st7571, 0, 0); 147 for (int i = 0; i < npixels; i++) 148 regmap_bulk_write(st7571->regmap, ST7571_DATA_MODE, &pixelvalue, 1); 149 150 return 0; 151 } 152 153 static void st7571_prepare_buffer_monochrome(struct st7571_device *st7571, 154 const struct iosys_map *vmap, 155 struct drm_framebuffer *fb, 156 struct drm_rect *rect, 157 struct drm_format_conv_state *fmtcnv_state) 158 { 159 unsigned int dst_pitch; 160 struct iosys_map dst; 161 u32 size; 162 163 switch (fb->format->format) { 164 case DRM_FORMAT_XRGB8888: 165 dst_pitch = DIV_ROUND_UP(drm_rect_width(rect), 8); 166 iosys_map_set_vaddr(&dst, st7571->hwbuf); 167 168 drm_fb_xrgb8888_to_mono(&dst, &dst_pitch, vmap, fb, rect, fmtcnv_state); 169 break; 170 171 case DRM_FORMAT_R1: 172 size = (rect->x2 - rect->x1) * (rect->y2 - rect->y1) / 8; 173 memcpy(st7571->hwbuf, vmap->vaddr, size); 174 break; 175 } 176 } 177 178 static void st7571_prepare_buffer_grayscale(struct st7571_device *st7571, 179 const struct iosys_map *vmap, 180 struct drm_framebuffer *fb, 181 struct drm_rect *rect, 182 struct drm_format_conv_state *fmtcnv_state) 183 { 184 u32 size = (rect->x2 - rect->x1) * (rect->y2 - rect->y1) / 8; 185 unsigned int dst_pitch; 186 struct iosys_map dst; 187 188 switch (fb->format->format) { 189 case DRM_FORMAT_XRGB8888: 190 dst_pitch = DIV_ROUND_UP(drm_rect_width(rect), 4); 191 iosys_map_set_vaddr(&dst, st7571->hwbuf); 192 193 drm_fb_xrgb8888_to_gray2(&dst, &dst_pitch, vmap, fb, rect, fmtcnv_state); 194 break; 195 196 case DRM_FORMAT_R1: 197 size = (rect->x2 - rect->x1) * (rect->y2 - rect->y1) / 8; 198 memcpy(st7571->hwbuf, vmap->vaddr, size); 199 break; 200 201 case DRM_FORMAT_R2: 202 size = (rect->x2 - rect->x1) * (rect->y2 - rect->y1) / 4; 203 memcpy(st7571->hwbuf, vmap->vaddr, size); 204 break; 205 } 206 } 207 208 static int st7571_fb_update_rect_monochrome(struct drm_framebuffer *fb, struct drm_rect *rect) 209 { 210 struct st7571_device *st7571 = drm_to_st7571(fb->dev); 211 char *row = st7571->row; 212 213 /* Align y to display page boundaries */ 214 rect->y1 = round_down(rect->y1, ST7571_PAGE_HEIGHT); 215 rect->y2 = min_t(unsigned int, round_up(rect->y2, ST7571_PAGE_HEIGHT), st7571->nlines); 216 217 for (int y = rect->y1; y < rect->y2; y += ST7571_PAGE_HEIGHT) { 218 for (int x = rect->x1; x < rect->x2; x++) 219 row[x] = st7571_transform_xy(st7571->hwbuf, x, y, 1); 220 221 st7571_set_position(st7571, rect->x1, y); 222 223 /* TODO: Investige why we can't write multiple bytes at once */ 224 for (int x = rect->x1; x < rect->x2; x++) 225 regmap_bulk_write(st7571->regmap, ST7571_DATA_MODE, row + x, 1); 226 } 227 228 return 0; 229 } 230 231 static int st7571_fb_update_rect_grayscale(struct drm_framebuffer *fb, struct drm_rect *rect) 232 { 233 struct st7571_device *st7571 = drm_to_st7571(fb->dev); 234 u32 format = fb->format->format; 235 char *row = st7571->row; 236 int x1; 237 int x2; 238 239 /* Align y to display page boundaries */ 240 rect->y1 = round_down(rect->y1, ST7571_PAGE_HEIGHT); 241 rect->y2 = min_t(unsigned int, round_up(rect->y2, ST7571_PAGE_HEIGHT), st7571->nlines); 242 243 switch (format) { 244 case DRM_FORMAT_R1: 245 x1 = rect->x1 * 1; 246 x2 = rect->x2 * 1; 247 break; 248 case DRM_FORMAT_R2: 249 fallthrough; 250 case DRM_FORMAT_XRGB8888: 251 x1 = rect->x1 * 2; 252 x2 = rect->x2 * 2; 253 break; 254 } 255 256 for (int y = rect->y1; y < rect->y2; y += ST7571_PAGE_HEIGHT) { 257 for (int x = x1; x < x2; x++) 258 row[x] = st7571_transform_xy(st7571->hwbuf, x, y, 2); 259 260 st7571_set_position(st7571, rect->x1, y); 261 262 /* TODO: Investige why we can't write multiple bytes at once */ 263 for (int x = x1; x < x2; x++) { 264 regmap_bulk_write(st7571->regmap, ST7571_DATA_MODE, row + x, 1); 265 266 /* 267 * As the display supports grayscale, all pixels must be written as two bits 268 * even if the format is monochrome. 269 * 270 * The bit values maps to the following grayscale: 271 * 0 0 = Black 272 * 0 1 = Dark gray 273 * 1 0 = Light gray 274 * 1 1 = White 275 * 276 * For monochrome formats, write the same value twice to get 277 * either a black or white pixel. 278 */ 279 if (format == DRM_FORMAT_R1) 280 regmap_bulk_write(st7571->regmap, ST7571_DATA_MODE, row + x, 1); 281 } 282 } 283 284 return 0; 285 } 286 287 static int st7571_connector_get_modes(struct drm_connector *conn) 288 { 289 struct st7571_device *st7571 = drm_to_st7571(conn->dev); 290 291 return drm_connector_helper_get_modes_fixed(conn, &st7571->mode); 292 } 293 294 static const struct drm_connector_helper_funcs st7571_connector_helper_funcs = { 295 .get_modes = st7571_connector_get_modes, 296 }; 297 298 static const struct st7571_panel_format st7571_monochrome = { 299 .prepare_buffer = st7571_prepare_buffer_monochrome, 300 .update_rect = st7571_fb_update_rect_monochrome, 301 .mode = ST7571_COLOR_MODE_BLACKWHITE, 302 .formats = { 303 DRM_FORMAT_XRGB8888, 304 DRM_FORMAT_R1, 305 }, 306 .nformats = 2, 307 }; 308 309 static const struct st7571_panel_format st7571_grayscale = { 310 .prepare_buffer = st7571_prepare_buffer_grayscale, 311 .update_rect = st7571_fb_update_rect_grayscale, 312 .mode = ST7571_COLOR_MODE_GRAY, 313 .formats = { 314 DRM_FORMAT_XRGB8888, 315 DRM_FORMAT_R1, 316 DRM_FORMAT_R2, 317 }, 318 .nformats = 3, 319 }; 320 321 static const u64 st7571_primary_plane_fmtmods[] = { 322 DRM_FORMAT_MOD_LINEAR, 323 DRM_FORMAT_MOD_INVALID 324 }; 325 326 static int st7571_primary_plane_helper_atomic_check(struct drm_plane *plane, 327 struct drm_atomic_state *state) 328 { 329 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); 330 struct drm_crtc *new_crtc = new_plane_state->crtc; 331 struct drm_crtc_state *new_crtc_state = NULL; 332 333 if (new_crtc) 334 new_crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc); 335 336 return drm_atomic_helper_check_plane_state(new_plane_state, new_crtc_state, 337 DRM_PLANE_NO_SCALING, 338 DRM_PLANE_NO_SCALING, 339 false, false); 340 } 341 342 static void st7571_primary_plane_helper_atomic_update(struct drm_plane *plane, 343 struct drm_atomic_state *state) 344 { 345 struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); 346 struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); 347 struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); 348 struct drm_framebuffer *fb = plane_state->fb; 349 struct drm_atomic_helper_damage_iter iter; 350 struct drm_device *drm = plane->dev; 351 struct drm_rect damage; 352 struct st7571_device *st7571 = drm_to_st7571(plane->dev); 353 int ret, idx; 354 355 if (!fb) 356 return; /* no framebuffer; plane is disabled */ 357 358 ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE); 359 if (ret) 360 return; 361 362 if (!drm_dev_enter(drm, &idx)) 363 goto out_drm_gem_fb_end_cpu_access; 364 365 drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state); 366 drm_atomic_for_each_plane_damage(&iter, &damage) { 367 st7571->pformat->prepare_buffer(st7571, 368 &shadow_plane_state->data[0], 369 fb, &damage, 370 &shadow_plane_state->fmtcnv_state); 371 372 st7571->pformat->update_rect(fb, &damage); 373 } 374 375 drm_dev_exit(idx); 376 377 out_drm_gem_fb_end_cpu_access: 378 drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); 379 } 380 381 static void st7571_primary_plane_helper_atomic_disable(struct drm_plane *plane, 382 struct drm_atomic_state *state) 383 { 384 struct drm_device *drm = plane->dev; 385 struct st7571_device *st7571 = drm_to_st7571(plane->dev); 386 int idx; 387 388 if (!drm_dev_enter(drm, &idx)) 389 return; 390 391 st7571_fb_clear_screen(st7571); 392 drm_dev_exit(idx); 393 } 394 395 static const struct drm_plane_helper_funcs st7571_primary_plane_helper_funcs = { 396 DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, 397 .atomic_check = st7571_primary_plane_helper_atomic_check, 398 .atomic_update = st7571_primary_plane_helper_atomic_update, 399 .atomic_disable = st7571_primary_plane_helper_atomic_disable, 400 }; 401 402 static const struct drm_plane_funcs st7571_primary_plane_funcs = { 403 .update_plane = drm_atomic_helper_update_plane, 404 .disable_plane = drm_atomic_helper_disable_plane, 405 .destroy = drm_plane_cleanup, 406 DRM_GEM_SHADOW_PLANE_FUNCS, 407 }; 408 409 /* 410 * CRTC 411 */ 412 413 static enum drm_mode_status st7571_crtc_mode_valid(struct drm_crtc *crtc, 414 const struct drm_display_mode *mode) 415 { 416 struct st7571_device *st7571 = drm_to_st7571(crtc->dev); 417 418 return drm_crtc_helper_mode_valid_fixed(crtc, mode, &st7571->mode); 419 } 420 421 static const struct drm_crtc_helper_funcs st7571_crtc_helper_funcs = { 422 .atomic_check = drm_crtc_helper_atomic_check, 423 .mode_valid = st7571_crtc_mode_valid, 424 }; 425 426 static const struct drm_crtc_funcs st7571_crtc_funcs = { 427 .reset = drm_atomic_helper_crtc_reset, 428 .destroy = drm_crtc_cleanup, 429 .set_config = drm_atomic_helper_set_config, 430 .page_flip = drm_atomic_helper_page_flip, 431 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, 432 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 433 }; 434 435 /* 436 * Encoder 437 */ 438 439 static void st7571_encoder_atomic_enable(struct drm_encoder *encoder, 440 struct drm_atomic_state *state) 441 { 442 struct drm_device *drm = encoder->dev; 443 struct st7571_device *st7571 = drm_to_st7571(drm); 444 u8 command = ST7571_DISPLAY_ON; 445 int ret; 446 447 ret = st7571->pdata->init(st7571); 448 if (ret) 449 return; 450 451 st7571_send_command_list(st7571, &command, 1); 452 } 453 454 static void st7571_encoder_atomic_disable(struct drm_encoder *encoder, 455 struct drm_atomic_state *state) 456 { 457 struct drm_device *drm = encoder->dev; 458 struct st7571_device *st7571 = drm_to_st7571(drm); 459 u8 command = ST7571_DISPLAY_OFF; 460 461 st7571_send_command_list(st7571, &command, 1); 462 } 463 464 static const struct drm_encoder_funcs st7571_encoder_funcs = { 465 .destroy = drm_encoder_cleanup, 466 467 }; 468 469 static const struct drm_encoder_helper_funcs st7571_encoder_helper_funcs = { 470 .atomic_enable = st7571_encoder_atomic_enable, 471 .atomic_disable = st7571_encoder_atomic_disable, 472 }; 473 474 /* 475 * Connector 476 */ 477 478 static const struct drm_connector_funcs st7571_connector_funcs = { 479 .reset = drm_atomic_helper_connector_reset, 480 .fill_modes = drm_helper_probe_single_connector_modes, 481 .destroy = drm_connector_cleanup, 482 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 483 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 484 }; 485 486 static const struct drm_mode_config_funcs st7571_mode_config_funcs = { 487 .fb_create = drm_gem_fb_create_with_dirty, 488 .atomic_check = drm_atomic_helper_check, 489 .atomic_commit = drm_atomic_helper_commit, 490 }; 491 492 static struct drm_display_mode st7571_mode(struct st7571_device *st7571) 493 { 494 struct drm_display_mode mode = { 495 DRM_SIMPLE_MODE(st7571->ncols, st7571->nlines, 496 st7571->width_mm, st7571->height_mm), 497 }; 498 499 return mode; 500 } 501 502 static int st7571_mode_config_init(struct st7571_device *st7571) 503 { 504 struct drm_device *drm = &st7571->drm; 505 const struct st7571_panel_constraints *constraints = &st7571->pdata->constraints; 506 int ret; 507 508 ret = drmm_mode_config_init(drm); 509 if (ret) 510 return ret; 511 512 drm->mode_config.min_width = constraints->min_ncols; 513 drm->mode_config.min_height = constraints->min_nlines; 514 drm->mode_config.max_width = constraints->max_ncols; 515 drm->mode_config.max_height = constraints->max_nlines; 516 drm->mode_config.preferred_depth = 24; 517 drm->mode_config.funcs = &st7571_mode_config_funcs; 518 519 return 0; 520 } 521 522 static int st7571_plane_init(struct st7571_device *st7571, 523 const struct st7571_panel_format *pformat) 524 { 525 struct drm_plane *primary_plane = &st7571->primary_plane; 526 struct drm_device *drm = &st7571->drm; 527 int ret; 528 529 ret = drm_universal_plane_init(drm, primary_plane, 0, 530 &st7571_primary_plane_funcs, 531 pformat->formats, 532 pformat->nformats, 533 st7571_primary_plane_fmtmods, 534 DRM_PLANE_TYPE_PRIMARY, NULL); 535 if (ret) 536 return ret; 537 538 drm_plane_helper_add(primary_plane, &st7571_primary_plane_helper_funcs); 539 drm_plane_enable_fb_damage_clips(primary_plane); 540 541 return 0; 542 } 543 544 static int st7571_crtc_init(struct st7571_device *st7571) 545 { 546 struct drm_plane *primary_plane = &st7571->primary_plane; 547 struct drm_crtc *crtc = &st7571->crtc; 548 struct drm_device *drm = &st7571->drm; 549 int ret; 550 551 ret = drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL, 552 &st7571_crtc_funcs, NULL); 553 if (ret) 554 return ret; 555 556 drm_crtc_helper_add(crtc, &st7571_crtc_helper_funcs); 557 558 return 0; 559 } 560 561 static int st7571_encoder_init(struct st7571_device *st7571) 562 { 563 struct drm_encoder *encoder = &st7571->encoder; 564 struct drm_crtc *crtc = &st7571->crtc; 565 struct drm_device *drm = &st7571->drm; 566 int ret; 567 568 ret = drm_encoder_init(drm, encoder, &st7571_encoder_funcs, DRM_MODE_ENCODER_NONE, NULL); 569 if (ret) 570 return ret; 571 572 drm_encoder_helper_add(encoder, &st7571_encoder_helper_funcs); 573 574 encoder->possible_crtcs = drm_crtc_mask(crtc); 575 576 return 0; 577 } 578 579 static int st7571_connector_init(struct st7571_device *st7571) 580 { 581 struct drm_connector *connector = &st7571->connector; 582 struct drm_encoder *encoder = &st7571->encoder; 583 struct drm_device *drm = &st7571->drm; 584 int ret; 585 586 ret = drm_connector_init(drm, connector, &st7571_connector_funcs, 587 DRM_MODE_CONNECTOR_Unknown); 588 if (ret) 589 return ret; 590 591 drm_connector_helper_add(connector, &st7571_connector_helper_funcs); 592 593 return drm_connector_attach_encoder(connector, encoder); 594 } 595 596 DEFINE_DRM_GEM_FOPS(st7571_fops); 597 598 static const struct drm_driver st7571_driver = { 599 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, 600 601 .name = DRIVER_NAME, 602 .desc = DRIVER_DESC, 603 .major = DRIVER_MAJOR, 604 .minor = DRIVER_MINOR, 605 606 .fops = &st7571_fops, 607 DRM_GEM_SHMEM_DRIVER_OPS, 608 DRM_FBDEV_SHMEM_DRIVER_OPS, 609 }; 610 611 static int st7571_validate_parameters(struct st7571_device *st7571) 612 { 613 struct device *dev = st7571->dev; 614 const struct st7571_panel_constraints *constraints = &st7571->pdata->constraints; 615 616 if (st7571->width_mm == 0) { 617 dev_err(dev, "Invalid panel width\n"); 618 return -EINVAL; 619 } 620 621 if (st7571->height_mm == 0) { 622 dev_err(dev, "Invalid panel height\n"); 623 return -EINVAL; 624 } 625 626 if (st7571->nlines < constraints->min_nlines || 627 st7571->nlines > constraints->max_nlines) { 628 dev_err(dev, "Invalid timing configuration.\n"); 629 return -EINVAL; 630 } 631 632 if (st7571->startline + st7571->nlines > constraints->max_nlines) { 633 dev_err(dev, "Invalid timing configuration.\n"); 634 return -EINVAL; 635 } 636 637 if (st7571->ncols < constraints->min_ncols || 638 st7571->ncols > constraints->max_ncols) { 639 dev_err(dev, "Invalid timing configuration.\n"); 640 return -EINVAL; 641 } 642 643 if (st7571->grayscale && !constraints->support_grayscale) { 644 dev_err(dev, "Grayscale not supported\n"); 645 return -EINVAL; 646 } 647 648 return 0; 649 } 650 651 static int st7567_parse_dt(struct st7571_device *st7567) 652 { 653 struct device *dev = st7567->dev; 654 struct device_node *np = dev->of_node; 655 struct display_timing dt; 656 int ret; 657 658 ret = of_get_display_timing(np, "panel-timing", &dt); 659 if (ret) { 660 dev_err(dev, "Failed to get display timing from DT\n"); 661 return ret; 662 } 663 664 of_property_read_u32(np, "width-mm", &st7567->width_mm); 665 of_property_read_u32(np, "height-mm", &st7567->height_mm); 666 st7567->inverted = of_property_read_bool(np, "sitronix,inverted"); 667 668 st7567->pformat = &st7571_monochrome; 669 st7567->bpp = 1; 670 671 st7567->startline = dt.vfront_porch.typ; 672 st7567->nlines = dt.vactive.typ; 673 st7567->ncols = dt.hactive.typ; 674 675 return 0; 676 } 677 678 static int st7571_parse_dt(struct st7571_device *st7571) 679 { 680 struct device *dev = st7571->dev; 681 struct device_node *np = dev->of_node; 682 struct display_timing dt; 683 int ret; 684 685 ret = of_get_display_timing(np, "panel-timing", &dt); 686 if (ret) { 687 dev_err(dev, "Failed to get display timing from DT\n"); 688 return ret; 689 } 690 691 of_property_read_u32(np, "width-mm", &st7571->width_mm); 692 of_property_read_u32(np, "height-mm", &st7571->height_mm); 693 st7571->grayscale = of_property_read_bool(np, "sitronix,grayscale"); 694 st7571->inverted = of_property_read_bool(np, "sitronix,inverted"); 695 696 if (st7571->grayscale) { 697 st7571->pformat = &st7571_grayscale; 698 st7571->bpp = 2; 699 } else { 700 st7571->pformat = &st7571_monochrome; 701 st7571->bpp = 1; 702 } 703 704 st7571->startline = dt.vfront_porch.typ; 705 st7571->nlines = dt.vactive.typ; 706 st7571->ncols = dt.hactive.typ; 707 708 st7571->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); 709 if (IS_ERR(st7571->reset)) 710 return dev_err_probe(dev, PTR_ERR(st7571->reset), 711 "Failed to get reset gpio\n"); 712 713 return 0; 714 } 715 716 static void st7571_reset(struct st7571_device *st7571) 717 { 718 gpiod_set_value_cansleep(st7571->reset, 1); 719 fsleep(20); 720 gpiod_set_value_cansleep(st7571->reset, 0); 721 } 722 723 static int st7567_lcd_init(struct st7571_device *st7567) 724 { 725 /* 726 * Most of the initialization sequence is taken directly from the 727 * referential initial code in the ST7567 datasheet. 728 */ 729 u8 commands[] = { 730 ST7571_DISPLAY_OFF, 731 732 ST7567_SET_LCD_BIAS(1), 733 734 ST7571_SET_SEG_SCAN_DIR(0), 735 ST7571_SET_COM_SCAN_DIR(1), 736 737 ST7571_SET_REGULATOR_REG(4), 738 ST7571_SET_CONTRAST_MSB, 739 ST7571_SET_CONTRAST_LSB(0x20), 740 741 ST7571_SET_START_LINE_MSB, 742 ST7571_SET_START_LINE_LSB(st7567->startline), 743 744 ST7571_SET_POWER(0x4), /* Power Control, VC: ON, VR: OFF, VF: OFF */ 745 ST7571_SET_POWER(0x6), /* Power Control, VC: ON, VR: ON, VF: OFF */ 746 ST7571_SET_POWER(0x7), /* Power Control, VC: ON, VR: ON, VF: ON */ 747 748 ST7571_SET_REVERSE(st7567->inverted ? 1 : 0), 749 ST7571_SET_ENTIRE_DISPLAY_ON(0), 750 }; 751 752 return st7571_send_command_list(st7567, commands, ARRAY_SIZE(commands)); 753 } 754 755 static int st7571_lcd_init(struct st7571_device *st7571) 756 { 757 /* 758 * Most of the initialization sequence is taken directly from the 759 * referential initial code in the ST7571 datasheet. 760 */ 761 u8 commands[] = { 762 ST7571_DISPLAY_OFF, 763 764 ST7571_SET_MODE_MSB, 765 ST7571_SET_MODE_LSB(0x2e), 766 767 ST7571_SET_SEG_SCAN_DIR(0), 768 ST7571_SET_COM_SCAN_DIR(1), 769 770 ST7571_SET_COM0_MSB, 771 ST7571_SET_COM0_LSB(0x00), 772 773 ST7571_SET_START_LINE_MSB, 774 ST7571_SET_START_LINE_LSB(st7571->startline), 775 776 ST7571_OSC_ON, 777 ST7571_SET_REGULATOR_REG(5), 778 ST7571_SET_CONTRAST_MSB, 779 ST7571_SET_CONTRAST_LSB(0x33), 780 ST7571_SET_LCD_BIAS(0x04), 781 ST7571_SET_DISPLAY_DUTY_MSB, 782 ST7571_SET_DISPLAY_DUTY_LSB(st7571->nlines), 783 784 ST7571_SET_POWER(0x4), /* Power Control, VC: ON, VR: OFF, VF: OFF */ 785 ST7571_SET_POWER(0x6), /* Power Control, VC: ON, VR: ON, VF: OFF */ 786 ST7571_SET_POWER(0x7), /* Power Control, VC: ON, VR: ON, VF: ON */ 787 788 ST7571_COMMAND_SET_3, 789 ST7571_SET_COLOR_MODE(st7571->pformat->mode), 790 ST7571_COMMAND_SET_NORMAL, 791 792 ST7571_SET_REVERSE(st7571->inverted ? 1 : 0), 793 ST7571_SET_ENTIRE_DISPLAY_ON(0), 794 }; 795 796 /* Perform a reset before initializing the controller */ 797 st7571_reset(st7571); 798 799 return st7571_send_command_list(st7571, commands, ARRAY_SIZE(commands)); 800 } 801 802 struct st7571_device *st7571_probe(struct device *dev, 803 struct regmap *regmap) 804 { 805 struct st7571_device *st7571; 806 struct drm_device *drm; 807 int ret; 808 809 st7571 = devm_drm_dev_alloc(dev, &st7571_driver, 810 struct st7571_device, drm); 811 if (IS_ERR(st7571)) 812 return st7571; 813 814 drm = &st7571->drm; 815 st7571->dev = dev; 816 st7571->pdata = device_get_match_data(st7571->dev); 817 818 ret = st7571->pdata->parse_dt(st7571); 819 if (ret) 820 return ERR_PTR(ret); 821 822 ret = st7571_validate_parameters(st7571); 823 if (ret) 824 return ERR_PTR(ret); 825 826 st7571->mode = st7571_mode(st7571); 827 st7571->regmap = regmap; 828 829 st7571->hwbuf = devm_kzalloc(st7571->dev, 830 (st7571->nlines * st7571->ncols * st7571->bpp) / 8, 831 GFP_KERNEL); 832 if (!st7571->hwbuf) 833 return ERR_PTR(-ENOMEM); 834 835 st7571->row = devm_kzalloc(st7571->dev, 836 (st7571->ncols * st7571->bpp), 837 GFP_KERNEL); 838 if (!st7571->row) 839 return ERR_PTR(-ENOMEM); 840 841 ret = st7571_mode_config_init(st7571); 842 if (ret) { 843 dev_err(st7571->dev, "Failed to initialize mode config\n"); 844 return ERR_PTR(ret); 845 } 846 847 ret = st7571_plane_init(st7571, st7571->pformat); 848 if (ret) { 849 dev_err(st7571->dev, "Failed to initialize primary plane\n"); 850 return ERR_PTR(ret); 851 } 852 853 ret = st7571_crtc_init(st7571); 854 if (ret < 0) { 855 dev_err(st7571->dev, "Failed to initialize CRTC\n"); 856 return ERR_PTR(ret); 857 } 858 859 ret = st7571_encoder_init(st7571); 860 if (ret < 0) { 861 dev_err(st7571->dev, "Failed to initialize encoder\n"); 862 return ERR_PTR(ret); 863 } 864 865 ret = st7571_connector_init(st7571); 866 if (ret < 0) { 867 dev_err(st7571->dev, "Failed to initialize connector\n"); 868 return ERR_PTR(ret); 869 } 870 871 drm_mode_config_reset(drm); 872 873 ret = drm_dev_register(drm, 0); 874 if (ret) { 875 dev_err(st7571->dev, "Failed to register DRM device\n"); 876 return ERR_PTR(ret); 877 } 878 879 drm_client_setup(drm, NULL); 880 return st7571; 881 } 882 EXPORT_SYMBOL_GPL(st7571_probe); 883 884 void st7571_remove(struct st7571_device *st7571) 885 { 886 drm_dev_unplug(&st7571->drm); 887 } 888 EXPORT_SYMBOL_GPL(st7571_remove); 889 890 const struct st7571_panel_data st7567_config = { 891 .init = st7567_lcd_init, 892 .parse_dt = st7567_parse_dt, 893 .constraints = { 894 .min_nlines = 1, 895 .max_nlines = 64, 896 .min_ncols = 128, 897 .max_ncols = 128, 898 .support_grayscale = false, 899 }, 900 }; 901 EXPORT_SYMBOL_NS_GPL(st7567_config, "DRM_ST7571"); 902 903 const struct st7571_panel_data st7571_config = { 904 .init = st7571_lcd_init, 905 .parse_dt = st7571_parse_dt, 906 .constraints = { 907 .min_nlines = 1, 908 .max_nlines = 128, 909 .min_ncols = 128, 910 .max_ncols = 128, 911 .support_grayscale = true, 912 }, 913 }; 914 EXPORT_SYMBOL_NS_GPL(st7571_config, "DRM_ST7571"); 915 916 MODULE_AUTHOR("Marcus Folkesson <marcus.folkesson@gmail.com>"); 917 MODULE_DESCRIPTION("DRM Driver for Sitronix ST7571 LCD controller"); 918 MODULE_LICENSE("GPL"); 919