root/drivers/staging/fbtft/fbtft-core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fbtft_write_buf_dc
  2. fbtft_dbg_hex
  3. fbtft_request_one_gpio
  4. fbtft_request_gpios_dt
  5. fbtft_backlight_update_status
  6. fbtft_backlight_get_brightness
  7. fbtft_unregister_backlight
  8. fbtft_register_backlight
  9. fbtft_register_backlight
  10. fbtft_unregister_backlight
  11. fbtft_set_addr_win
  12. fbtft_reset
  13. fbtft_update_display
  14. fbtft_mkdirty
  15. fbtft_deferred_io
  16. fbtft_fb_fillrect
  17. fbtft_fb_copyarea
  18. fbtft_fb_imageblit
  19. fbtft_fb_write
  20. chan_to_field
  21. fbtft_fb_setcolreg
  22. fbtft_fb_blank
  23. fbtft_merge_fbtftops
  24. fbtft_framebuffer_alloc
  25. fbtft_framebuffer_release
  26. fbtft_register_framebuffer
  27. fbtft_unregister_framebuffer
  28. fbtft_init_display_dt
  29. fbtft_init_display
  30. fbtft_verify_gpios
  31. fbtft_of_value
  32. fbtft_probe_dt
  33. fbtft_probe_dt
  34. fbtft_probe_common
  35. fbtft_remove_common

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

/* [<][>][^][v][top][bottom][index][help] */