FILE
fbtft-core.c
File preview with syntax highlighting.
linux-6.19.14/drivers/staging/fbtft/fbtft-core.c
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2013 Noralf Tronnes 4 * 5 * This driver is inspired by: 6 * st7735fb.c, Copyright (C) 2011, Matt Porter 7 * broadsheetfb.c, Copyright (C) 2008, Jaya Kumar 8 */ 9 10#include <linux/module.h> 11#include <linux/kernel.h> 12#include <linux/errno.h> 13#include <linux/string.h> 14#include <linux/mm.h> 15#include <linux/vmalloc.h> 16#include <linux/slab.h> 17#include <linux/init.h> 18#include <linux/fb.h> 19#include <linux/gpio/consumer.h> 20#include <linux/spi/spi.h> 21#include <linux/delay.h> 22#include <linux/uaccess.h> 23#include <linux/backlight.h> 24#include <linux/platform_device.h> 25#include <linux/property.h> 26#include <linux/spinlock.h> 27 28#include <video/mipi_display.h> 29 30#include "fbtft.h" 31#include "internal.h" 32 33static unsigned long debug; 34module_param(debug, ulong, 0000); 35MODULE_PARM_DESC(debug, "override device debug level"); 36 37int fbtft_write_buf_dc(struct fbtft_par *par, void *buf, size_t len, int dc) 38{ 39 int ret; 40 41 gpiod_set_value(par->gpio.dc, dc); 42 43 ret = par->fbtftops.write(par, buf, len); 44 if (ret < 0) 45 dev_err(par->info->device, 46 "write() failed and returned %d\n", ret); 47 return ret; 48} 49EXPORT_SYMBOL(fbtft_write_buf_dc); 50 51void fbtft_dbg_hex(const struct device *dev, int groupsize, 52 const void *buf, size_t len, const char *fmt, ...) 53{ 54 va_list args; 55 static char textbuf[512]; 56 char *text = textbuf; 57 size_t text_len; 58 59 va_start(args, fmt); 60 text_len = vscnprintf(text, sizeof(textbuf), fmt, args); 61 va_end(args); 62 63 hex_dump_to_buffer(buf, len, 32, groupsize, text + text_len, 64 512 - text_len, false); 65 66 if (len > 32) 67 dev_info(dev, "%s ...\n", text); 68 else 69 dev_info(dev, "%s\n", text); 70} 71EXPORT_SYMBOL(fbtft_dbg_hex); 72 73static int fbtft_request_one_gpio(struct fbtft_par *par, 74 const char *name, int index, 75 struct gpio_desc **gpiop) 76{ 77 struct device *dev = par->info->device; 78 79 *gpiop = devm_gpiod_get_index_optional(dev, name, index, 80 GPIOD_OUT_LOW); 81 if (IS_ERR(*gpiop)) 82 return dev_err_probe(dev, PTR_ERR(*gpiop), "Failed to request %s GPIO\n", name); 83 84 fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' GPIO\n", 85 __func__, name); 86 87 return 0; 88} 89 90static int fbtft_request_gpios(struct fbtft_par *par) 91{ 92 int i; 93 int ret; 94 95 ret = fbtft_request_one_gpio(par, "reset", 0, &par->gpio.reset); 96 if (ret) 97 return ret; 98 ret = fbtft_request_one_gpio(par, "dc", 0, &par->gpio.dc); 99 if (ret) 100 return ret; 101 ret = fbtft_request_one_gpio(par, "rd", 0, &par->gpio.rd); 102 if (ret) 103 return ret; 104 ret = fbtft_request_one_gpio(par, "wr", 0, &par->gpio.wr); 105 if (ret) 106 return ret; 107 ret = fbtft_request_one_gpio(par, "cs", 0, &par->gpio.cs); 108 if (ret) 109 return ret; 110 ret = fbtft_request_one_gpio(par, "latch", 0, &par->gpio.latch); 111 if (ret) 112 return ret; 113 for (i = 0; i < 16; i++) { 114 ret = fbtft_request_one_gpio(par, "db", i, 115 &par->gpio.db[i]); 116 if (ret) 117 return ret; 118 ret = fbtft_request_one_gpio(par, "led", i, 119 &par->gpio.led[i]); 120 if (ret) 121 return ret; 122 ret = fbtft_request_one_gpio(par, "aux", i, 123 &par->gpio.aux[i]); 124 if (ret) 125 return ret; 126 } 127 128 return 0; 129} 130 131static int fbtft_backlight_update_status(struct backlight_device *bd) 132{ 133 struct fbtft_par *par = bl_get_data(bd); 134 bool polarity = par->polarity; 135 136 fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s: polarity=%d, power=%d\n", __func__, 137 polarity, bd->props.power); 138 139 if (!backlight_is_blank(bd)) 140 gpiod_set_value(par->gpio.led[0], polarity); 141 else 142 gpiod_set_value(par->gpio.led[0], !polarity); 143 144 return 0; 145} 146 147static int fbtft_backlight_get_brightness(struct backlight_device *bd) 148{ 149 return bd->props.brightness; 150} 151 152void fbtft_unregister_backlight(struct fbtft_par *par) 153{ 154 if (par->info->bl_dev) { 155 par->info->bl_dev->props.power = BACKLIGHT_POWER_OFF; 156 backlight_update_status(par->info->bl_dev); 157 backlight_device_unregister(par->info->bl_dev); 158 par->info->bl_dev = NULL; 159 } 160} 161EXPORT_SYMBOL(fbtft_unregister_backlight); 162 163static const struct backlight_ops fbtft_bl_ops = { 164 .get_brightness = fbtft_backlight_get_brightness, 165 .update_status = fbtft_backlight_update_status, 166}; 167 168void fbtft_register_backlight(struct fbtft_par *par) 169{ 170 struct backlight_device *bd; 171 struct backlight_properties bl_props = { 0, }; 172 173 if (!par->gpio.led[0]) { 174 fbtft_par_dbg(DEBUG_BACKLIGHT, par, 175 "%s(): led pin not set, exiting.\n", __func__); 176 return; 177 } 178 179 bl_props.type = BACKLIGHT_RAW; 180 /* Assume backlight is off, get polarity from current state of pin */ 181 bl_props.power = BACKLIGHT_POWER_OFF; 182 if (!gpiod_get_value(par->gpio.led[0])) 183 par->polarity = true; 184 185 bd = backlight_device_register(dev_driver_string(par->info->device), 186 par->info->device, par, 187 &fbtft_bl_ops, &bl_props); 188 if (IS_ERR(bd)) { 189 dev_err(par->info->device, 190 "cannot register backlight device (%ld)\n", 191 PTR_ERR(bd)); 192 return; 193 } 194 par->info->bl_dev = bd; 195 196 if (!par->fbtftops.unregister_backlight) 197 par->fbtftops.unregister_backlight = fbtft_unregister_backlight; 198} 199EXPORT_SYMBOL(fbtft_register_backlight); 200 201static void fbtft_set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, 202 int ye) 203{ 204 write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS, 205 (xs >> 8) & 0xFF, xs & 0xFF, (xe >> 8) & 0xFF, xe & 0xFF); 206 207 write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS, 208 (ys >> 8) & 0xFF, ys & 0xFF, (ye >> 8) & 0xFF, ye & 0xFF); 209 210 write_reg(par, MIPI_DCS_WRITE_MEMORY_START); 211} 212 213static void fbtft_reset(struct fbtft_par *par) 214{ 215 if (!par->gpio.reset) 216 return; 217 218 gpiod_set_value_cansleep(par->gpio.reset, 1); 219 usleep_range(20, 40); 220 gpiod_set_value_cansleep(par->gpio.reset, 0); 221 msleep(120); 222 223 gpiod_set_value_cansleep(par->gpio.cs, 1); /* Activate chip */ 224} 225 226static void fbtft_update_display(struct fbtft_par *par, unsigned int start_line, 227 unsigned int end_line) 228{ 229 size_t offset, len; 230 ktime_t ts_start, ts_end; 231 long fps, throughput; 232 bool timeit = false; 233 int ret = 0; 234 235 if (unlikely(par->debug & (DEBUG_TIME_FIRST_UPDATE | 236 DEBUG_TIME_EACH_UPDATE))) { 237 if ((par->debug & DEBUG_TIME_EACH_UPDATE) || 238 ((par->debug & DEBUG_TIME_FIRST_UPDATE) && 239 !par->first_update_done)) { 240 ts_start = ktime_get(); 241 timeit = true; 242 } 243 } 244 245 /* Sanity checks */ 246 if (start_line > end_line) { 247 dev_warn(par->info->device, 248 "%s: start_line=%u is larger than end_line=%u. Shouldn't happen, will do full display update\n", 249 __func__, start_line, end_line); 250 start_line = 0; 251 end_line = par->info->var.yres - 1; 252 } 253 if (start_line > par->info->var.yres - 1 || 254 end_line > par->info->var.yres - 1) { 255 dev_warn(par->info->device, 256 "%s: start_line=%u or end_line=%u is larger than max=%d. Shouldn't happen, will do full display update\n", 257 __func__, start_line, 258 end_line, par->info->var.yres - 1); 259 start_line = 0; 260 end_line = par->info->var.yres - 1; 261 } 262 263 fbtft_par_dbg(DEBUG_UPDATE_DISPLAY, par, "%s(start_line=%u, end_line=%u)\n", 264 __func__, start_line, end_line); 265 266 if (par->fbtftops.set_addr_win) 267 par->fbtftops.set_addr_win(par, 0, start_line, 268 par->info->var.xres - 1, end_line); 269 270 offset = start_line * par->info->fix.line_length; 271 len = (end_line - start_line + 1) * par->info->fix.line_length; 272 ret = par->fbtftops.write_vmem(par, offset, len); 273 if (ret < 0) 274 dev_err(par->info->device, 275 "%s: write_vmem failed to update display buffer\n", 276 __func__); 277 278 if (unlikely(timeit)) { 279 ts_end = ktime_get(); 280 if (!ktime_to_ns(par->update_time)) 281 par->update_time = ts_start; 282 283 fps = ktime_us_delta(ts_start, par->update_time); 284 par->update_time = ts_start; 285 fps = fps ? 1000000 / fps : 0; 286 287 throughput = ktime_us_delta(ts_end, ts_start); 288 throughput = throughput ? (len * 1000) / throughput : 0; 289 throughput = throughput * 1000 / 1024; 290 291 dev_info(par->info->device, 292 "Display update: %ld kB/s, fps=%ld\n", 293 throughput, fps); 294 par->first_update_done = true; 295 } 296} 297 298static void fbtft_mkdirty(struct fb_info *info, int y, int height) 299{ 300 struct fbtft_par *par = info->par; 301 struct fb_deferred_io *fbdefio = info->fbdefio; 302 303 /* special case, needed ? */ 304 if (y == -1) { 305 y = 0; 306 height = info->var.yres; 307 } 308 309 /* Mark display lines/area as dirty */ 310 spin_lock(&par->dirty_lock); 311 if (y < par->dirty_lines_start) 312 par->dirty_lines_start = y; 313 if (y + height - 1 > par->dirty_lines_end) 314 par->dirty_lines_end = y + height - 1; 315 spin_unlock(&par->dirty_lock); 316 317 /* Schedule deferred_io to update display (no-op if already on queue)*/ 318 schedule_delayed_work(&info->deferred_work, fbdefio->delay); 319} 320 321static void fbtft_deferred_io(struct fb_info *info, struct list_head *pagereflist) 322{ 323 struct fbtft_par *par = info->par; 324 unsigned int dirty_lines_start, dirty_lines_end; 325 struct fb_deferred_io_pageref *pageref; 326 unsigned int y_low = 0, y_high = 0; 327 328 spin_lock(&par->dirty_lock); 329 dirty_lines_start = par->dirty_lines_start; 330 dirty_lines_end = par->dirty_lines_end; 331 /* set display line markers as clean */ 332 par->dirty_lines_start = par->info->var.yres - 1; 333 par->dirty_lines_end = 0; 334 spin_unlock(&par->dirty_lock); 335 336 /* Mark display lines as dirty */ 337 list_for_each_entry(pageref, pagereflist, list) { 338 y_low = pageref->offset / info->fix.line_length; 339 y_high = (pageref->offset + PAGE_SIZE - 1) / info->fix.line_length; 340 dev_dbg(info->device, "y_low=%d y_high=%d\n", y_low, y_high); 341 if (y_high > info->var.yres - 1) 342 y_high = info->var.yres - 1; 343 if (y_low < dirty_lines_start) 344 dirty_lines_start = y_low; 345 if (y_high > dirty_lines_end) 346 dirty_lines_end = y_high; 347 } 348 349 par->fbtftops.update_display(info->par, 350 dirty_lines_start, dirty_lines_end); 351} 352 353/* from pxafb.c */ 354static unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf) 355{ 356 chan &= 0xffff; 357 chan >>= 16 - bf->length; 358 return chan << bf->offset; 359} 360 361static int fbtft_fb_setcolreg(unsigned int regno, unsigned int red, 362 unsigned int green, unsigned int blue, 363 unsigned int transp, struct fb_info *info) 364{ 365 unsigned int val; 366 int ret = 1; 367 368 dev_dbg(info->dev, 369 "%s(regno=%u, red=0x%X, green=0x%X, blue=0x%X, trans=0x%X)\n", 370 __func__, regno, red, green, blue, transp); 371 372 switch (info->fix.visual) { 373 case FB_VISUAL_TRUECOLOR: 374 if (regno < 16) { 375 u32 *pal = info->pseudo_palette; 376 377 val = chan_to_field(red, &info->var.red); 378 val |= chan_to_field(green, &info->var.green); 379 val |= chan_to_field(blue, &info->var.blue); 380 381 pal[regno] = val; 382 ret = 0; 383 } 384 break; 385 } 386 return ret; 387} 388 389static int fbtft_fb_blank(int blank, struct fb_info *info) 390{ 391 struct fbtft_par *par = info->par; 392 int ret = -EINVAL; 393 394 dev_dbg(info->dev, "%s(blank=%d)\n", 395 __func__, blank); 396 397 if (!par->fbtftops.blank) 398 return ret; 399 400 switch (blank) { 401 case FB_BLANK_POWERDOWN: 402 case FB_BLANK_VSYNC_SUSPEND: 403 case FB_BLANK_HSYNC_SUSPEND: 404 case FB_BLANK_NORMAL: 405 ret = par->fbtftops.blank(par, true); 406 break; 407 case FB_BLANK_UNBLANK: 408 ret = par->fbtftops.blank(par, false); 409 break; 410 } 411 return ret; 412} 413 414static void fbtft_ops_damage_range(struct fb_info *info, off_t off, size_t len) 415{ 416 struct fbtft_par *par = info->par; 417 418 /* TODO: only mark changed area update all for now */ 419 par->fbtftops.mkdirty(info, -1, 0); 420} 421 422static void fbtft_ops_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, u32 height) 423{ 424 struct fbtft_par *par = info->par; 425 426 par->fbtftops.mkdirty(info, y, height); 427} 428 429FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(fbtft_ops, 430 fbtft_ops_damage_range, 431 fbtft_ops_damage_area) 432 433static const struct fb_ops fbtft_ops = { 434 .owner = THIS_MODULE, 435 FB_DEFAULT_DEFERRED_OPS(fbtft_ops), 436 .fb_setcolreg = fbtft_fb_setcolreg, 437 .fb_blank = fbtft_fb_blank, 438}; 439 440static void fbtft_merge_fbtftops(struct fbtft_ops *dst, struct fbtft_ops *src) 441{ 442 if (src->write) 443 dst->write = src->write; 444 if (src->read) 445 dst->read = src->read; 446 if (src->write_vmem) 447 dst->write_vmem = src->write_vmem; 448 if (src->write_register) 449 dst->write_register = src->write_register; 450 if (src->set_addr_win) 451 dst->set_addr_win = src->set_addr_win; 452 if (src->reset) 453 dst->reset = src->reset; 454 if (src->mkdirty) 455 dst->mkdirty = src->mkdirty; 456 if (src->update_display) 457 dst->update_display = src->update_display; 458 if (src->init_display) 459 dst->init_display = src->init_display; 460 if (src->blank) 461 dst->blank = src->blank; 462 if (src->request_gpios_match) 463 dst->request_gpios_match = src->request_gpios_match; 464 if (src->request_gpios) 465 dst->request_gpios = src->request_gpios; 466 if (src->verify_gpios) 467 dst->verify_gpios = src->verify_gpios; 468 if (src->register_backlight) 469 dst->register_backlight = src->register_backlight; 470 if (src->unregister_backlight) 471 dst->unregister_backlight = src->unregister_backlight; 472 if (src->set_var) 473 dst->set_var = src->set_var; 474 if (src->set_gamma) 475 dst->set_gamma = src->set_gamma; 476} 477 478/** 479 * fbtft_framebuffer_alloc - creates a new frame buffer info structure 480 * 481 * @display: pointer to structure describing the display 482 * @dev: pointer to the device for this fb, this can be NULL 483 * @pdata: platform data for the display in use 484 * 485 * Creates a new frame buffer info structure. 486 * 487 * Also creates and populates the following structures: 488 * info->fbdefio 489 * info->pseudo_palette 490 * par->fbtftops 491 * par->txbuf 492 * 493 * Returns the new structure, or NULL if an error occurred. 494 * 495 */ 496struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, 497 struct device *dev, 498 struct fbtft_platform_data *pdata) 499{ 500 struct fb_info *info; 501 struct fbtft_par *par; 502 struct fb_deferred_io *fbdefio = NULL; 503 u8 *vmem = NULL; 504 void *txbuf = NULL; 505 void *buf = NULL; 506 unsigned int width; 507 unsigned int height; 508 int txbuflen = display->txbuflen; 509 unsigned int bpp = display->bpp; 510 unsigned int fps = display->fps; 511 int vmem_size; 512 const s16 *init_sequence = display->init_sequence; 513 char *gamma = display->gamma; 514 u32 *gamma_curves = NULL; 515 516 /* sanity check */ 517 if (display->gamma_num * display->gamma_len > 518 FBTFT_GAMMA_MAX_VALUES_TOTAL) { 519 dev_err(dev, "FBTFT_GAMMA_MAX_VALUES_TOTAL=%d is exceeded\n", 520 FBTFT_GAMMA_MAX_VALUES_TOTAL); 521 return NULL; 522 } 523 524 /* defaults */ 525 if (!fps) 526 fps = 20; 527 if (!bpp) 528 bpp = 16; 529 530 if (!pdata) { 531 dev_err(dev, "platform data is missing\n"); 532 return NULL; 533 } 534 535 /* override driver values? */ 536 if (pdata->fps) 537 fps = pdata->fps; 538 if (pdata->txbuflen) 539 txbuflen = pdata->txbuflen; 540 if (pdata->display.init_sequence) 541 init_sequence = pdata->display.init_sequence; 542 if (pdata->gamma) 543 gamma = pdata->gamma; 544 if (pdata->display.debug) 545 display->debug = pdata->display.debug; 546 if (pdata->display.backlight) 547 display->backlight = pdata->display.backlight; 548 if (pdata->display.width) 549 display->width = pdata->display.width; 550 if (pdata->display.height) 551 display->height = pdata->display.height; 552 if (pdata->display.buswidth) 553 display->buswidth = pdata->display.buswidth; 554 if (pdata->display.regwidth) 555 display->regwidth = pdata->display.regwidth; 556 557 display->debug |= debug; 558 fbtft_expand_debug_value(&display->debug); 559 560 switch (pdata->rotate) { 561 case 90: 562 case 270: 563 width = display->height; 564 height = display->width; 565 break; 566 default: 567 width = display->width; 568 height = display->height; 569 } 570 571 fbdefio = devm_kzalloc(dev, sizeof(struct fb_deferred_io), GFP_KERNEL); 572 if (!fbdefio) 573 return NULL; 574 575 buf = devm_kzalloc(dev, 128, GFP_KERNEL); 576 if (!buf) 577 return NULL; 578 579 if (display->gamma_num && display->gamma_len) { 580 gamma_curves = devm_kcalloc(dev, 581 display->gamma_num * 582 display->gamma_len, 583 sizeof(gamma_curves[0]), 584 GFP_KERNEL); 585 if (!gamma_curves) 586 return NULL; 587 } 588 589 info = framebuffer_alloc(sizeof(struct fbtft_par), dev); 590 if (!info) 591 return NULL; 592 593 vmem_size = display->width * display->height * bpp / 8; 594 vmem = vzalloc(vmem_size); 595 if (!vmem) 596 goto release_framebuf; 597 598 info->screen_buffer = vmem; 599 info->fbops = &fbtft_ops; 600 info->fbdefio = fbdefio; 601 602 fbdefio->delay = HZ / fps; 603 fbdefio->sort_pagereflist = true; 604 fbdefio->deferred_io = fbtft_deferred_io; 605 606 snprintf(info->fix.id, sizeof(info->fix.id), "%s", dev->driver->name); 607 info->fix.type = FB_TYPE_PACKED_PIXELS; 608 info->fix.visual = FB_VISUAL_TRUECOLOR; 609 info->fix.xpanstep = 0; 610 info->fix.ypanstep = 0; 611 info->fix.ywrapstep = 0; 612 info->fix.line_length = width * bpp / 8; 613 info->fix.accel = FB_ACCEL_NONE; 614 info->fix.smem_len = vmem_size; 615 if (fb_deferred_io_init(info)) 616 goto release_screen_buffer; 617 618 info->var.rotate = pdata->rotate; 619 info->var.xres = width; 620 info->var.yres = height; 621 info->var.xres_virtual = info->var.xres; 622 info->var.yres_virtual = info->var.yres; 623 info->var.bits_per_pixel = bpp; 624 info->var.nonstd = 1; 625 626 /* RGB565 */ 627 info->var.red.offset = 11; 628 info->var.red.length = 5; 629 info->var.green.offset = 5; 630 info->var.green.length = 6; 631 info->var.blue.offset = 0; 632 info->var.blue.length = 5; 633 info->var.transp.offset = 0; 634 info->var.transp.length = 0; 635 636 info->flags = FBINFO_VIRTFB; 637 638 par = info->par; 639 par->info = info; 640 par->pdata = pdata; 641 par->debug = display->debug; 642 par->buf = buf; 643 spin_lock_init(&par->dirty_lock); 644 par->bgr = pdata->bgr; 645 par->startbyte = pdata->startbyte; 646 par->init_sequence = init_sequence; 647 par->gamma.curves = gamma_curves; 648 par->gamma.num_curves = display->gamma_num; 649 par->gamma.num_values = display->gamma_len; 650 mutex_init(&par->gamma.lock); 651 info->pseudo_palette = par->pseudo_palette; 652 653 if (par->gamma.curves && gamma) { 654 if (fbtft_gamma_parse_str(par, par->gamma.curves, gamma, 655 strlen(gamma))) 656 goto cleanup_deferred; 657 } 658 659 /* Transmit buffer */ 660 if (txbuflen == -1) 661 txbuflen = vmem_size + 2; /* add in case startbyte is used */ 662 if (txbuflen >= vmem_size + 2) 663 txbuflen = 0; 664 665#ifdef __LITTLE_ENDIAN 666 if ((!txbuflen) && (bpp > 8)) 667 txbuflen = PAGE_SIZE; /* need buffer for byteswapping */ 668#endif 669 670 if (txbuflen > 0) { 671 txbuf = kzalloc(txbuflen, GFP_KERNEL); 672 if (!txbuf) 673 goto cleanup_deferred; 674 par->txbuf.buf = txbuf; 675 par->txbuf.len = txbuflen; 676 } 677 678 /* default fbtft operations */ 679 par->fbtftops.write = fbtft_write_spi; 680 par->fbtftops.read = fbtft_read_spi; 681 par->fbtftops.write_vmem = fbtft_write_vmem16_bus8; 682 par->fbtftops.write_register = fbtft_write_reg8_bus8; 683 par->fbtftops.set_addr_win = fbtft_set_addr_win; 684 par->fbtftops.reset = fbtft_reset; 685 par->fbtftops.mkdirty = fbtft_mkdirty; 686 par->fbtftops.update_display = fbtft_update_display; 687 if (display->backlight) 688 par->fbtftops.register_backlight = fbtft_register_backlight; 689 690 /* use driver provided functions */ 691 fbtft_merge_fbtftops(&par->fbtftops, &display->fbtftops); 692 693 return info; 694 695cleanup_deferred: 696 fb_deferred_io_cleanup(info); 697release_screen_buffer: 698 vfree(info->screen_buffer); 699release_framebuf: 700 framebuffer_release(info); 701 return NULL; 702} 703EXPORT_SYMBOL(fbtft_framebuffer_alloc); 704 705/** 706 * fbtft_framebuffer_release - frees up all memory used by the framebuffer 707 * 708 * @info: frame buffer info structure 709 * 710 */ 711void fbtft_framebuffer_release(struct fb_info *info) 712{ 713 struct fbtft_par *par = info->par; 714 715 kfree(par->txbuf.buf); 716 fb_deferred_io_cleanup(info); 717 vfree(info->screen_buffer); 718 framebuffer_release(info); 719} 720EXPORT_SYMBOL(fbtft_framebuffer_release); 721 722/** 723 * fbtft_register_framebuffer - registers a tft frame buffer device 724 * @fb_info: frame buffer info structure 725 * 726 * Sets SPI driverdata if needed 727 * Requests needed gpios. 728 * Initializes display 729 * Updates display. 730 * Registers a frame buffer device @fb_info. 731 * 732 * Returns negative errno on error, or zero for success. 733 * 734 */ 735int fbtft_register_framebuffer(struct fb_info *fb_info) 736{ 737 int ret; 738 char text1[50] = ""; 739 char text2[50] = ""; 740 struct fbtft_par *par = fb_info->par; 741 struct spi_device *spi = par->spi; 742 743 /* sanity checks */ 744 if (!par->fbtftops.init_display) { 745 dev_err(fb_info->device, "missing fbtftops.init_display()\n"); 746 return -EINVAL; 747 } 748 749 if (spi) 750 spi_set_drvdata(spi, fb_info); 751 if (par->pdev) 752 platform_set_drvdata(par->pdev, fb_info); 753 754 ret = par->fbtftops.request_gpios(par); 755 if (ret < 0) 756 goto reg_fail; 757 758 if (par->fbtftops.verify_gpios) { 759 ret = par->fbtftops.verify_gpios(par); 760 if (ret < 0) 761 goto reg_fail; 762 } 763 764 ret = par->fbtftops.init_display(par); 765 if (ret < 0) 766 goto reg_fail; 767 if (par->fbtftops.set_var) { 768 ret = par->fbtftops.set_var(par); 769 if (ret < 0) 770 goto reg_fail; 771 } 772 773 /* update the entire display */ 774 par->fbtftops.update_display(par, 0, par->info->var.yres - 1); 775 776 if (par->fbtftops.set_gamma && par->gamma.curves) { 777 ret = par->fbtftops.set_gamma(par, par->gamma.curves); 778 if (ret) 779 goto reg_fail; 780 } 781 782 if (par->fbtftops.register_backlight) 783 par->fbtftops.register_backlight(par); 784 785 ret = register_framebuffer(fb_info); 786 if (ret < 0) 787 goto reg_fail; 788 789 fbtft_sysfs_init(par); 790 791 if (par->txbuf.buf && par->txbuf.len >= 1024) 792 sprintf(text1, ", %zu KiB buffer memory", par->txbuf.len >> 10); 793 if (spi) 794 sprintf(text2, ", spi%d.%d at %d MHz", spi->controller->bus_num, 795 spi_get_chipselect(spi, 0), spi->max_speed_hz / 1000000); 796 dev_info(fb_info->dev, 797 "%s frame buffer, %dx%d, %d KiB video memory%s, fps=%lu%s\n", 798 fb_info->fix.id, fb_info->var.xres, fb_info->var.yres, 799 fb_info->fix.smem_len >> 10, text1, 800 HZ / fb_info->fbdefio->delay, text2); 801 802 /* Turn on backlight if available */ 803 if (fb_info->bl_dev) { 804 fb_info->bl_dev->props.power = BACKLIGHT_POWER_ON; 805 fb_info->bl_dev->ops->update_status(fb_info->bl_dev); 806 } 807 808 return 0; 809 810reg_fail: 811 if (par->fbtftops.unregister_backlight) 812 par->fbtftops.unregister_backlight(par); 813 814 return ret; 815} 816EXPORT_SYMBOL(fbtft_register_framebuffer); 817 818/** 819 * fbtft_unregister_framebuffer - releases a tft frame buffer device 820 * @fb_info: frame buffer info structure 821 * 822 * Frees SPI driverdata if needed 823 * Frees gpios. 824 * Unregisters frame buffer device. 825 * 826 */ 827int fbtft_unregister_framebuffer(struct fb_info *fb_info) 828{ 829 struct fbtft_par *par = fb_info->par; 830 831 if (par->fbtftops.unregister_backlight) 832 par->fbtftops.unregister_backlight(par); 833 fbtft_sysfs_exit(par); 834 unregister_framebuffer(fb_info); 835 836 return 0; 837} 838EXPORT_SYMBOL(fbtft_unregister_framebuffer); 839 840/** 841 * fbtft_init_display_from_property() - Device Tree init_display() function 842 * @par: Driver data 843 * 844 * Return: 0 if successful, negative if error 845 */ 846static int fbtft_init_display_from_property(struct fbtft_par *par) 847{ 848 struct device *dev = par->info->device; 849 int buf[64], count, index, i, j, ret; 850 u32 *values; 851 u32 val; 852 853 count = device_property_count_u32(dev, "init"); 854 if (count < 0) 855 return count; 856 if (count == 0) 857 return -EINVAL; 858 859 values = kmalloc_array(count + 1, sizeof(*values), GFP_KERNEL); 860 if (!values) 861 return -ENOMEM; 862 863 ret = device_property_read_u32_array(dev, "init", values, count); 864 if (ret) 865 goto out_free; 866 867 par->fbtftops.reset(par); 868 869 index = -1; 870 val = values[++index]; 871 872 while (index < count) { 873 if (val & FBTFT_OF_INIT_CMD) { 874 val &= 0xFFFF; 875 i = 0; 876 while ((index < count) && !(val & 0xFFFF0000)) { 877 if (i > 63) { 878 dev_err(dev, 879 "%s: Maximum register values exceeded\n", 880 __func__); 881 ret = -EINVAL; 882 goto out_free; 883 } 884 buf[i++] = val; 885 val = values[++index]; 886 } 887 /* make debug message */ 888 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, 889 "init: write_register:\n"); 890 for (j = 0; j < i; j++) 891 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, 892 "buf[%d] = %02X\n", j, buf[j]); 893 894 par->fbtftops.write_register(par, i, 895 buf[0], buf[1], buf[2], buf[3], 896 buf[4], buf[5], buf[6], buf[7], 897 buf[8], buf[9], buf[10], buf[11], 898 buf[12], buf[13], buf[14], buf[15], 899 buf[16], buf[17], buf[18], buf[19], 900 buf[20], buf[21], buf[22], buf[23], 901 buf[24], buf[25], buf[26], buf[27], 902 buf[28], buf[29], buf[30], buf[31], 903 buf[32], buf[33], buf[34], buf[35], 904 buf[36], buf[37], buf[38], buf[39], 905 buf[40], buf[41], buf[42], buf[43], 906 buf[44], buf[45], buf[46], buf[47], 907 buf[48], buf[49], buf[50], buf[51], 908 buf[52], buf[53], buf[54], buf[55], 909 buf[56], buf[57], buf[58], buf[59], 910 buf[60], buf[61], buf[62], buf[63]); 911 } else if (val & FBTFT_OF_INIT_DELAY) { 912 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, 913 "init: msleep(%u)\n", val & 0xFFFF); 914 msleep(val & 0xFFFF); 915 val = values[++index]; 916 } else { 917 dev_err(dev, "illegal init value 0x%X\n", val); 918 ret = -EINVAL; 919 goto out_free; 920 } 921 } 922 923out_free: 924 kfree(values); 925 return ret; 926} 927 928/** 929 * fbtft_init_display() - Generic init_display() function 930 * @par: Driver data 931 * 932 * Uses par->init_sequence to do the initialization 933 * 934 * Return: 0 if successful, negative if error 935 */ 936int fbtft_init_display(struct fbtft_par *par) 937{ 938 int buf[64]; 939 int i; 940 int j; 941 942 /* sanity check */ 943 if (!par->init_sequence) { 944 dev_err(par->info->device, 945 "error: init_sequence is not set\n"); 946 return -EINVAL; 947 } 948 949 /* make sure stop marker exists */ 950 for (i = 0; i < FBTFT_MAX_INIT_SEQUENCE; i++) { 951 if (par->init_sequence[i] == -3) 952 break; 953 } 954 955 if (i == FBTFT_MAX_INIT_SEQUENCE) { 956 dev_err(par->info->device, 957 "missing stop marker at end of init sequence\n"); 958 return -EINVAL; 959 } 960 961 par->fbtftops.reset(par); 962 963 i = 0; 964 while (i < FBTFT_MAX_INIT_SEQUENCE) { 965 if (par->init_sequence[i] == -3) { 966 /* done */ 967 return 0; 968 } 969 if (par->init_sequence[i] >= 0) { 970 dev_err(par->info->device, 971 "missing delimiter at position %d\n", i); 972 return -EINVAL; 973 } 974 if (par->init_sequence[i + 1] < 0) { 975 dev_err(par->info->device, 976 "missing value after delimiter %d at position %d\n", 977 par->init_sequence[i], i); 978 return -EINVAL; 979 } 980 switch (par->init_sequence[i]) { 981 case -1: 982 i++; 983 984 /* make debug message */ 985 for (j = 0; par->init_sequence[i + 1 + j] >= 0; j++) 986 ; 987 988 fbtft_par_dbg_hex(DEBUG_INIT_DISPLAY, par, par->info->device, 989 s16, &par->init_sequence[i + 1], j, 990 "init: write(0x%02X)", par->init_sequence[i]); 991 992 /* Write */ 993 j = 0; 994 while (par->init_sequence[i] >= 0) { 995 if (j > 63) { 996 dev_err(par->info->device, 997 "%s: Maximum register values exceeded\n", 998 __func__); 999 return -EINVAL; 1000 } 1001 buf[j++] = par->init_sequence[i++]; 1002 } 1003 par->fbtftops.write_register(par, j, 1004 buf[0], buf[1], buf[2], buf[3], 1005 buf[4], buf[5], buf[6], buf[7], 1006 buf[8], buf[9], buf[10], buf[11], 1007 buf[12], buf[13], buf[14], buf[15], 1008 buf[16], buf[17], buf[18], buf[19], 1009 buf[20], buf[21], buf[22], buf[23], 1010 buf[24], buf[25], buf[26], buf[27], 1011 buf[28], buf[29], buf[30], buf[31], 1012 buf[32], buf[33], buf[34], buf[35], 1013 buf[36], buf[37], buf[38], buf[39], 1014 buf[40], buf[41], buf[42], buf[43], 1015 buf[44], buf[45], buf[46], buf[47], 1016 buf[48], buf[49], buf[50], buf[51], 1017 buf[52], buf[53], buf[54], buf[55], 1018 buf[56], buf[57], buf[58], buf[59], 1019 buf[60], buf[61], buf[62], buf[63]); 1020 break; 1021 case -2: 1022 i++; 1023 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, 1024 "init: mdelay(%d)\n", 1025 par->init_sequence[i]); 1026 mdelay(par->init_sequence[i++]); 1027 break; 1028 default: 1029 dev_err(par->info->device, 1030 "unknown delimiter %d at position %d\n", 1031 par->init_sequence[i], i); 1032 return -EINVAL; 1033 } 1034 } 1035 1036 dev_err(par->info->device, 1037 "%s: something is wrong. Shouldn't get here.\n", __func__); 1038 return -EINVAL; 1039} 1040EXPORT_SYMBOL(fbtft_init_display); 1041 1042/** 1043 * fbtft_verify_gpios() - Generic verify_gpios() function 1044 * @par: Driver data 1045 * 1046 * Uses @spi, @pdev and @buswidth to determine which GPIOs is needed 1047 * 1048 * Return: 0 if successful, negative if error 1049 */ 1050static int fbtft_verify_gpios(struct fbtft_par *par) 1051{ 1052 struct fbtft_platform_data *pdata = par->pdata; 1053 int i; 1054 1055 if (pdata->display.buswidth != 9 && par->startbyte == 0 && 1056 !par->gpio.dc) { 1057 dev_err(par->info->device, 1058 "Missing info about 'dc' gpio. Aborting.\n"); 1059 return -EINVAL; 1060 } 1061 1062 if (!par->pdev) 1063 return 0; 1064 1065 if (!par->gpio.wr) { 1066 dev_err(par->info->device, "Missing 'wr' gpio. Aborting.\n"); 1067 return -EINVAL; 1068 } 1069 for (i = 0; i < pdata->display.buswidth; i++) { 1070 if (!par->gpio.db[i]) { 1071 dev_err(par->info->device, 1072 "Missing 'db%02d' gpio. Aborting.\n", i); 1073 return -EINVAL; 1074 } 1075 } 1076 1077 return 0; 1078} 1079 1080/* returns 0 if the property is not present */ 1081static u32 fbtft_property_value(struct device *dev, const char *propname) 1082{ 1083 int ret; 1084 u32 val = 0; 1085 1086 ret = device_property_read_u32(dev, propname, &val); 1087 if (ret == 0) 1088 dev_info(dev, "%s: %s = %u\n", __func__, propname, val); 1089 1090 return val; 1091} 1092 1093static struct fbtft_platform_data *fbtft_properties_read(struct device *dev) 1094{ 1095 struct fbtft_platform_data *pdata; 1096 1097 if (!dev_fwnode(dev)) { 1098 dev_err(dev, "Missing platform data or properties\n"); 1099 return ERR_PTR(-EINVAL); 1100 } 1101 1102 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 1103 if (!pdata) 1104 return ERR_PTR(-ENOMEM); 1105 1106 pdata->display.width = fbtft_property_value(dev, "width"); 1107 pdata->display.height = fbtft_property_value(dev, "height"); 1108 pdata->display.regwidth = fbtft_property_value(dev, "regwidth"); 1109 pdata->display.buswidth = fbtft_property_value(dev, "buswidth"); 1110 pdata->display.backlight = fbtft_property_value(dev, "backlight"); 1111 pdata->display.bpp = fbtft_property_value(dev, "bpp"); 1112 pdata->display.debug = fbtft_property_value(dev, "debug"); 1113 pdata->rotate = fbtft_property_value(dev, "rotate"); 1114 pdata->bgr = device_property_read_bool(dev, "bgr"); 1115 pdata->fps = fbtft_property_value(dev, "fps"); 1116 pdata->txbuflen = fbtft_property_value(dev, "txbuflen"); 1117 pdata->startbyte = fbtft_property_value(dev, "startbyte"); 1118 device_property_read_string(dev, "gamma", (const char **)&pdata->gamma); 1119 1120 if (device_property_present(dev, "led-gpios")) 1121 pdata->display.backlight = 1; 1122 if (device_property_present(dev, "init")) 1123 pdata->display.fbtftops.init_display = 1124 fbtft_init_display_from_property; 1125 1126 pdata->display.fbtftops.request_gpios = fbtft_request_gpios; 1127 1128 return pdata; 1129} 1130 1131/** 1132 * fbtft_probe_common() - Generic device probe() helper function 1133 * @display: Display properties 1134 * @sdev: SPI device 1135 * @pdev: Platform device 1136 * 1137 * Allocates, initializes and registers a framebuffer 1138 * 1139 * Either @sdev or @pdev should be NULL 1140 * 1141 * Return: 0 if successful, negative if error 1142 */ 1143int fbtft_probe_common(struct fbtft_display *display, 1144 struct spi_device *sdev, 1145 struct platform_device *pdev) 1146{ 1147 struct device *dev; 1148 struct fb_info *info; 1149 struct fbtft_par *par; 1150 struct fbtft_platform_data *pdata; 1151 int ret; 1152 1153 if (sdev) 1154 dev = &sdev->dev; 1155 else 1156 dev = &pdev->dev; 1157 1158 pdata = dev->platform_data; 1159 if (!pdata) { 1160 pdata = fbtft_properties_read(dev); 1161 if (IS_ERR(pdata)) 1162 return PTR_ERR(pdata); 1163 } 1164 1165 info = fbtft_framebuffer_alloc(display, dev, pdata); 1166 if (!info) 1167 return -ENOMEM; 1168 1169 par = info->par; 1170 par->spi = sdev; 1171 par->pdev = pdev; 1172 1173 if (display->buswidth == 0) { 1174 ret = dev_err_probe(dev, -EINVAL, "buswidth is not set\n"); 1175 goto out_release; 1176 } 1177 1178 /* write register functions */ 1179 if (display->regwidth == 8 && display->buswidth == 8) 1180 par->fbtftops.write_register = fbtft_write_reg8_bus8; 1181 else if (display->regwidth == 8 && display->buswidth == 9 && par->spi) 1182 par->fbtftops.write_register = fbtft_write_reg8_bus9; 1183 else if (display->regwidth == 16 && display->buswidth == 8) 1184 par->fbtftops.write_register = fbtft_write_reg16_bus8; 1185 else if (display->regwidth == 16 && display->buswidth == 16) 1186 par->fbtftops.write_register = fbtft_write_reg16_bus16; 1187 else 1188 dev_warn(dev, 1189 "no default functions for regwidth=%d and buswidth=%d\n", 1190 display->regwidth, display->buswidth); 1191 1192 /* write_vmem() functions */ 1193 if (display->buswidth == 8) 1194 par->fbtftops.write_vmem = fbtft_write_vmem16_bus8; 1195 else if (display->buswidth == 9) 1196 par->fbtftops.write_vmem = fbtft_write_vmem16_bus9; 1197 else if (display->buswidth == 16) 1198 par->fbtftops.write_vmem = fbtft_write_vmem16_bus16; 1199 1200 /* GPIO write() functions */ 1201 if (par->pdev) { 1202 if (display->buswidth == 8) 1203 par->fbtftops.write = fbtft_write_gpio8_wr; 1204 else if (display->buswidth == 16) 1205 par->fbtftops.write = fbtft_write_gpio16_wr; 1206 } 1207 1208 /* 9-bit SPI setup */ 1209 if (par->spi && display->buswidth == 9) { 1210 if (par->spi->controller->bits_per_word_mask & SPI_BPW_MASK(9)) { 1211 par->spi->bits_per_word = 9; 1212 } else { 1213 dev_warn(&par->spi->dev, 1214 "9-bit SPI not available, emulating using 8-bit.\n"); 1215 /* allocate buffer with room for dc bits */ 1216 par->extra = devm_kzalloc(par->info->device, 1217 par->txbuf.len + 1218 (par->txbuf.len / 8) + 8, 1219 GFP_KERNEL); 1220 if (!par->extra) { 1221 ret = -ENOMEM; 1222 goto out_release; 1223 } 1224 par->fbtftops.write = fbtft_write_spi_emulate_9; 1225 } 1226 } 1227 1228 if (!par->fbtftops.verify_gpios) 1229 par->fbtftops.verify_gpios = fbtft_verify_gpios; 1230 1231 /* make sure we still use the driver provided functions */ 1232 fbtft_merge_fbtftops(&par->fbtftops, &display->fbtftops); 1233 1234 /* use init_sequence if provided */ 1235 if (par->init_sequence) 1236 par->fbtftops.init_display = fbtft_init_display; 1237 1238 /* use platform_data provided functions above all */ 1239 fbtft_merge_fbtftops(&par->fbtftops, &pdata->display.fbtftops); 1240 1241 ret = fbtft_register_framebuffer(info); 1242 if (ret < 0) 1243 goto out_release; 1244 1245 return 0; 1246 1247out_release: 1248 fbtft_framebuffer_release(info); 1249 1250 return ret; 1251} 1252EXPORT_SYMBOL(fbtft_probe_common); 1253 1254/** 1255 * fbtft_remove_common() - Generic device remove() helper function 1256 * @dev: Device 1257 * @info: Framebuffer 1258 * 1259 * Unregisters and releases the framebuffer 1260 */ 1261void fbtft_remove_common(struct device *dev, struct fb_info *info) 1262{ 1263 struct fbtft_par *par; 1264 1265 par = info->par; 1266 if (par) 1267 fbtft_par_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, par, 1268 "%s()\n", __func__); 1269 fbtft_unregister_framebuffer(info); 1270 fbtft_framebuffer_release(info); 1271} 1272EXPORT_SYMBOL(fbtft_remove_common); 1273 1274MODULE_DESCRIPTION("Core FB support for small TFT LCD display modules"); 1275MODULE_LICENSE("GPL");
~/
Read-only file preview.