linux/drivers/video/auo_k190x.c
<<
>>
Prefs
   1/*
   2 * Common code for AUO-K190X framebuffer drivers
   3 *
   4 * Copyright (C) 2012 Heiko Stuebner <heiko@sntech.de>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 */
  10
  11#include <linux/module.h>
  12#include <linux/kernel.h>
  13#include <linux/gpio.h>
  14#include <linux/platform_device.h>
  15#include <linux/pm_runtime.h>
  16#include <linux/fb.h>
  17#include <linux/delay.h>
  18#include <linux/uaccess.h>
  19#include <linux/vmalloc.h>
  20#include <linux/regulator/consumer.h>
  21
  22#include <video/auo_k190xfb.h>
  23
  24#include "auo_k190x.h"
  25
  26struct panel_info {
  27        int w;
  28        int h;
  29};
  30
  31/* table of panel specific parameters to be indexed into by the board drivers */
  32static struct panel_info panel_table[] = {
  33        /* standard 6" */
  34        [AUOK190X_RESOLUTION_800_600] = {
  35                .w = 800,
  36                .h = 600,
  37        },
  38        /* standard 9" */
  39        [AUOK190X_RESOLUTION_1024_768] = {
  40                .w = 1024,
  41                .h = 768,
  42        },
  43};
  44
  45/*
  46 * private I80 interface to the board driver
  47 */
  48
  49static void auok190x_issue_data(struct auok190xfb_par *par, u16 data)
  50{
  51        par->board->set_ctl(par, AUOK190X_I80_WR, 0);
  52        par->board->set_hdb(par, data);
  53        par->board->set_ctl(par, AUOK190X_I80_WR, 1);
  54}
  55
  56static void auok190x_issue_cmd(struct auok190xfb_par *par, u16 data)
  57{
  58        par->board->set_ctl(par, AUOK190X_I80_DC, 0);
  59        auok190x_issue_data(par, data);
  60        par->board->set_ctl(par, AUOK190X_I80_DC, 1);
  61}
  62
  63static int auok190x_issue_pixels(struct auok190xfb_par *par, int size,
  64                                 u16 *data)
  65{
  66        struct device *dev = par->info->device;
  67        int i;
  68        u16 tmp;
  69
  70        if (size & 3) {
  71                dev_err(dev, "issue_pixels: size %d must be a multiple of 4\n",
  72                        size);
  73                return -EINVAL;
  74        }
  75
  76        for (i = 0; i < (size >> 1); i++) {
  77                par->board->set_ctl(par, AUOK190X_I80_WR, 0);
  78
  79                /* simple reduction of 8bit staticgray to 4bit gray
  80                 * combines 4 * 4bit pixel values into a 16bit value
  81                 */
  82                tmp  = (data[2*i] & 0xF0) >> 4;
  83                tmp |= (data[2*i] & 0xF000) >> 8;
  84                tmp |= (data[2*i+1] & 0xF0) << 4;
  85                tmp |= (data[2*i+1] & 0xF000);
  86
  87                par->board->set_hdb(par, tmp);
  88                par->board->set_ctl(par, AUOK190X_I80_WR, 1);
  89        }
  90
  91        return 0;
  92}
  93
  94static u16 auok190x_read_data(struct auok190xfb_par *par)
  95{
  96        u16 data;
  97
  98        par->board->set_ctl(par, AUOK190X_I80_OE, 0);
  99        data = par->board->get_hdb(par);
 100        par->board->set_ctl(par, AUOK190X_I80_OE, 1);
 101
 102        return data;
 103}
 104
 105/*
 106 * Command interface for the controller drivers
 107 */
 108
 109void auok190x_send_command_nowait(struct auok190xfb_par *par, u16 data)
 110{
 111        par->board->set_ctl(par, AUOK190X_I80_CS, 0);
 112        auok190x_issue_cmd(par, data);
 113        par->board->set_ctl(par, AUOK190X_I80_CS, 1);
 114}
 115EXPORT_SYMBOL_GPL(auok190x_send_command_nowait);
 116
 117void auok190x_send_cmdargs_nowait(struct auok190xfb_par *par, u16 cmd,
 118                                  int argc, u16 *argv)
 119{
 120        int i;
 121
 122        par->board->set_ctl(par, AUOK190X_I80_CS, 0);
 123        auok190x_issue_cmd(par, cmd);
 124
 125        for (i = 0; i < argc; i++)
 126                auok190x_issue_data(par, argv[i]);
 127        par->board->set_ctl(par, AUOK190X_I80_CS, 1);
 128}
 129EXPORT_SYMBOL_GPL(auok190x_send_cmdargs_nowait);
 130
 131int auok190x_send_command(struct auok190xfb_par *par, u16 data)
 132{
 133        int ret;
 134
 135        ret = par->board->wait_for_rdy(par);
 136        if (ret)
 137                return ret;
 138
 139        auok190x_send_command_nowait(par, data);
 140        return 0;
 141}
 142EXPORT_SYMBOL_GPL(auok190x_send_command);
 143
 144int auok190x_send_cmdargs(struct auok190xfb_par *par, u16 cmd,
 145                           int argc, u16 *argv)
 146{
 147        int ret;
 148
 149        ret = par->board->wait_for_rdy(par);
 150        if (ret)
 151                return ret;
 152
 153        auok190x_send_cmdargs_nowait(par, cmd, argc, argv);
 154        return 0;
 155}
 156EXPORT_SYMBOL_GPL(auok190x_send_cmdargs);
 157
 158int auok190x_read_cmdargs(struct auok190xfb_par *par, u16 cmd,
 159                           int argc, u16 *argv)
 160{
 161        int i, ret;
 162
 163        ret = par->board->wait_for_rdy(par);
 164        if (ret)
 165                return ret;
 166
 167        par->board->set_ctl(par, AUOK190X_I80_CS, 0);
 168        auok190x_issue_cmd(par, cmd);
 169
 170        for (i = 0; i < argc; i++)
 171                argv[i] = auok190x_read_data(par);
 172        par->board->set_ctl(par, AUOK190X_I80_CS, 1);
 173
 174        return 0;
 175}
 176EXPORT_SYMBOL_GPL(auok190x_read_cmdargs);
 177
 178void auok190x_send_cmdargs_pixels_nowait(struct auok190xfb_par *par, u16 cmd,
 179                                  int argc, u16 *argv, int size, u16 *data)
 180{
 181        int i;
 182
 183        par->board->set_ctl(par, AUOK190X_I80_CS, 0);
 184
 185        auok190x_issue_cmd(par, cmd);
 186
 187        for (i = 0; i < argc; i++)
 188                auok190x_issue_data(par, argv[i]);
 189
 190        auok190x_issue_pixels(par, size, data);
 191
 192        par->board->set_ctl(par, AUOK190X_I80_CS, 1);
 193}
 194EXPORT_SYMBOL_GPL(auok190x_send_cmdargs_pixels_nowait);
 195
 196int auok190x_send_cmdargs_pixels(struct auok190xfb_par *par, u16 cmd,
 197                                  int argc, u16 *argv, int size, u16 *data)
 198{
 199        int ret;
 200
 201        ret = par->board->wait_for_rdy(par);
 202        if (ret)
 203                return ret;
 204
 205        auok190x_send_cmdargs_pixels_nowait(par, cmd, argc, argv, size, data);
 206
 207        return 0;
 208}
 209EXPORT_SYMBOL_GPL(auok190x_send_cmdargs_pixels);
 210
 211/*
 212 * fbdefio callbacks - common on both controllers.
 213 */
 214
 215static void auok190xfb_dpy_first_io(struct fb_info *info)
 216{
 217        /* tell runtime-pm that we wish to use the device in a short time */
 218        pm_runtime_get(info->device);
 219}
 220
 221/* this is called back from the deferred io workqueue */
 222static void auok190xfb_dpy_deferred_io(struct fb_info *info,
 223                                struct list_head *pagelist)
 224{
 225        struct fb_deferred_io *fbdefio = info->fbdefio;
 226        struct auok190xfb_par *par = info->par;
 227        u16 yres = info->var.yres;
 228        u16 xres = info->var.xres;
 229        u16 y1 = 0, h = 0;
 230        int prev_index = -1;
 231        struct page *cur;
 232        int h_inc;
 233        int threshold;
 234
 235        if (!list_empty(pagelist))
 236                /* the device resume should've been requested through first_io,
 237                 * if the resume did not finish until now, wait for it.
 238                 */
 239                pm_runtime_barrier(info->device);
 240        else
 241                /* We reached this via the fsync or some other way.
 242                 * In either case the first_io function did not run,
 243                 * so we runtime_resume the device here synchronously.
 244                 */
 245                pm_runtime_get_sync(info->device);
 246
 247        /* Do a full screen update every n updates to prevent
 248         * excessive darkening of the Sipix display.
 249         * If we do this, there is no need to walk the pages.
 250         */
 251        if (par->need_refresh(par)) {
 252                par->update_all(par);
 253                goto out;
 254        }
 255
 256        /* height increment is fixed per page */
 257        h_inc = DIV_ROUND_UP(PAGE_SIZE , xres);
 258
 259        /* calculate number of pages from pixel height */
 260        threshold = par->consecutive_threshold / h_inc;
 261        if (threshold < 1)
 262                threshold = 1;
 263
 264        /* walk the written page list and swizzle the data */
 265        list_for_each_entry(cur, &fbdefio->pagelist, lru) {
 266                if (prev_index < 0) {
 267                        /* just starting so assign first page */
 268                        y1 = (cur->index << PAGE_SHIFT) / xres;
 269                        h = h_inc;
 270                } else if ((cur->index - prev_index) <= threshold) {
 271                        /* page is within our threshold for single updates */
 272                        h += h_inc * (cur->index - prev_index);
 273                } else {
 274                        /* page not consecutive, issue previous update first */
 275                        par->update_partial(par, y1, y1 + h);
 276
 277                        /* start over with our non consecutive page */
 278                        y1 = (cur->index << PAGE_SHIFT) / xres;
 279                        h = h_inc;
 280                }
 281                prev_index = cur->index;
 282        }
 283
 284        /* if we still have any pages to update we do so now */
 285        if (h >= yres)
 286                /* its a full screen update, just do it */
 287                par->update_all(par);
 288        else
 289                par->update_partial(par, y1, min((u16) (y1 + h), yres));
 290
 291out:
 292        pm_runtime_mark_last_busy(info->device);
 293        pm_runtime_put_autosuspend(info->device);
 294}
 295
 296/*
 297 * framebuffer operations
 298 */
 299
 300/*
 301 * this is the slow path from userspace. they can seek and write to
 302 * the fb. it's inefficient to do anything less than a full screen draw
 303 */
 304static ssize_t auok190xfb_write(struct fb_info *info, const char __user *buf,
 305                                size_t count, loff_t *ppos)
 306{
 307        struct auok190xfb_par *par = info->par;
 308        unsigned long p = *ppos;
 309        void *dst;
 310        int err = 0;
 311        unsigned long total_size;
 312
 313        if (info->state != FBINFO_STATE_RUNNING)
 314                return -EPERM;
 315
 316        total_size = info->fix.smem_len;
 317
 318        if (p > total_size)
 319                return -EFBIG;
 320
 321        if (count > total_size) {
 322                err = -EFBIG;
 323                count = total_size;
 324        }
 325
 326        if (count + p > total_size) {
 327                if (!err)
 328                        err = -ENOSPC;
 329
 330                count = total_size - p;
 331        }
 332
 333        dst = (void *)(info->screen_base + p);
 334
 335        if (copy_from_user(dst, buf, count))
 336                err = -EFAULT;
 337
 338        if  (!err)
 339                *ppos += count;
 340
 341        par->update_all(par);
 342
 343        return (err) ? err : count;
 344}
 345
 346static void auok190xfb_fillrect(struct fb_info *info,
 347                                   const struct fb_fillrect *rect)
 348{
 349        struct auok190xfb_par *par = info->par;
 350
 351        sys_fillrect(info, rect);
 352
 353        par->update_all(par);
 354}
 355
 356static void auok190xfb_copyarea(struct fb_info *info,
 357                                   const struct fb_copyarea *area)
 358{
 359        struct auok190xfb_par *par = info->par;
 360
 361        sys_copyarea(info, area);
 362
 363        par->update_all(par);
 364}
 365
 366static void auok190xfb_imageblit(struct fb_info *info,
 367                                const struct fb_image *image)
 368{
 369        struct auok190xfb_par *par = info->par;
 370
 371        sys_imageblit(info, image);
 372
 373        par->update_all(par);
 374}
 375
 376static int auok190xfb_check_var(struct fb_var_screeninfo *var,
 377                                   struct fb_info *info)
 378{
 379        if (info->var.xres != var->xres || info->var.yres != var->yres ||
 380            info->var.xres_virtual != var->xres_virtual ||
 381            info->var.yres_virtual != var->yres_virtual) {
 382                pr_info("%s: Resolution not supported: X%u x Y%u\n",
 383                         __func__, var->xres, var->yres);
 384                return -EINVAL;
 385        }
 386
 387        /*
 388         *  Memory limit
 389         */
 390
 391        if ((info->fix.line_length * var->yres_virtual) > info->fix.smem_len) {
 392                pr_info("%s: Memory Limit requested yres_virtual = %u\n",
 393                         __func__, var->yres_virtual);
 394                return -ENOMEM;
 395        }
 396
 397        return 0;
 398}
 399
 400static struct fb_ops auok190xfb_ops = {
 401        .owner          = THIS_MODULE,
 402        .fb_read        = fb_sys_read,
 403        .fb_write       = auok190xfb_write,
 404        .fb_fillrect    = auok190xfb_fillrect,
 405        .fb_copyarea    = auok190xfb_copyarea,
 406        .fb_imageblit   = auok190xfb_imageblit,
 407        .fb_check_var   = auok190xfb_check_var,
 408};
 409
 410/*
 411 * Controller-functions common to both K1900 and K1901
 412 */
 413
 414static int auok190x_read_temperature(struct auok190xfb_par *par)
 415{
 416        struct device *dev = par->info->device;
 417        u16 data[4];
 418        int temp;
 419
 420        pm_runtime_get_sync(dev);
 421
 422        mutex_lock(&(par->io_lock));
 423
 424        auok190x_read_cmdargs(par, AUOK190X_CMD_READ_VERSION, 4, data);
 425
 426        mutex_unlock(&(par->io_lock));
 427
 428        pm_runtime_mark_last_busy(dev);
 429        pm_runtime_put_autosuspend(dev);
 430
 431        /* sanitize and split of half-degrees for now */
 432        temp = ((data[0] & AUOK190X_VERSION_TEMP_MASK) >> 1);
 433
 434        /* handle positive and negative temperatures */
 435        if (temp >= 201)
 436                return (255 - temp + 1) * (-1);
 437        else
 438                return temp;
 439}
 440
 441static void auok190x_identify(struct auok190xfb_par *par)
 442{
 443        struct device *dev = par->info->device;
 444        u16 data[4];
 445
 446        pm_runtime_get_sync(dev);
 447
 448        mutex_lock(&(par->io_lock));
 449
 450        auok190x_read_cmdargs(par, AUOK190X_CMD_READ_VERSION, 4, data);
 451
 452        mutex_unlock(&(par->io_lock));
 453
 454        par->epd_type = data[1] & AUOK190X_VERSION_TEMP_MASK;
 455
 456        par->panel_size_int = AUOK190X_VERSION_SIZE_INT(data[2]);
 457        par->panel_size_float = AUOK190X_VERSION_SIZE_FLOAT(data[2]);
 458        par->panel_model = AUOK190X_VERSION_MODEL(data[2]);
 459
 460        par->tcon_version = AUOK190X_VERSION_TCON(data[3]);
 461        par->lut_version = AUOK190X_VERSION_LUT(data[3]);
 462
 463        dev_dbg(dev, "panel %d.%din, model 0x%x, EPD 0x%x TCON-rev 0x%x, LUT-rev 0x%x",
 464                par->panel_size_int, par->panel_size_float, par->panel_model,
 465                par->epd_type, par->tcon_version, par->lut_version);
 466
 467        pm_runtime_mark_last_busy(dev);
 468        pm_runtime_put_autosuspend(dev);
 469}
 470
 471/*
 472 * Sysfs functions
 473 */
 474
 475static ssize_t update_mode_show(struct device *dev,
 476                                struct device_attribute *attr, char *buf)
 477{
 478        struct fb_info *info = dev_get_drvdata(dev);
 479        struct auok190xfb_par *par = info->par;
 480
 481        return sprintf(buf, "%d\n", par->update_mode);
 482}
 483
 484static ssize_t update_mode_store(struct device *dev,
 485                                 struct device_attribute *attr,
 486                                 const char *buf, size_t count)
 487{
 488        struct fb_info *info = dev_get_drvdata(dev);
 489        struct auok190xfb_par *par = info->par;
 490        int mode, ret;
 491
 492        ret = kstrtoint(buf, 10, &mode);
 493        if (ret)
 494                return ret;
 495
 496        par->update_mode = mode;
 497
 498        /* if we enter a better mode, do a full update */
 499        if (par->last_mode > 1 && mode < par->last_mode)
 500                par->update_all(par);
 501
 502        return count;
 503}
 504
 505static ssize_t flash_show(struct device *dev, struct device_attribute *attr,
 506                          char *buf)
 507{
 508        struct fb_info *info = dev_get_drvdata(dev);
 509        struct auok190xfb_par *par = info->par;
 510
 511        return sprintf(buf, "%d\n", par->flash);
 512}
 513
 514static ssize_t flash_store(struct device *dev, struct device_attribute *attr,
 515                           const char *buf, size_t count)
 516{
 517        struct fb_info *info = dev_get_drvdata(dev);
 518        struct auok190xfb_par *par = info->par;
 519        int flash, ret;
 520
 521        ret = kstrtoint(buf, 10, &flash);
 522        if (ret)
 523                return ret;
 524
 525        if (flash > 0)
 526                par->flash = 1;
 527        else
 528                par->flash = 0;
 529
 530        return count;
 531}
 532
 533static ssize_t temp_show(struct device *dev, struct device_attribute *attr,
 534                         char *buf)
 535{
 536        struct fb_info *info = dev_get_drvdata(dev);
 537        struct auok190xfb_par *par = info->par;
 538        int temp;
 539
 540        temp = auok190x_read_temperature(par);
 541        return sprintf(buf, "%d\n", temp);
 542}
 543
 544static DEVICE_ATTR(update_mode, 0644, update_mode_show, update_mode_store);
 545static DEVICE_ATTR(flash, 0644, flash_show, flash_store);
 546static DEVICE_ATTR(temp, 0644, temp_show, NULL);
 547
 548static struct attribute *auok190x_attributes[] = {
 549        &dev_attr_update_mode.attr,
 550        &dev_attr_flash.attr,
 551        &dev_attr_temp.attr,
 552        NULL
 553};
 554
 555static const struct attribute_group auok190x_attr_group = {
 556        .attrs          = auok190x_attributes,
 557};
 558
 559static int auok190x_power(struct auok190xfb_par *par, bool on)
 560{
 561        struct auok190x_board *board = par->board;
 562        int ret;
 563
 564        if (on) {
 565                /* We should maintain POWER up for at least 80ms before set
 566                 * RST_N and SLP_N to high (TCON spec 20100803_v35 p59)
 567                 */
 568                ret = regulator_enable(par->regulator);
 569                if (ret)
 570                        return ret;
 571
 572                msleep(200);
 573                gpio_set_value(board->gpio_nrst, 1);
 574                gpio_set_value(board->gpio_nsleep, 1);
 575                msleep(200);
 576        } else {
 577                regulator_disable(par->regulator);
 578                gpio_set_value(board->gpio_nrst, 0);
 579                gpio_set_value(board->gpio_nsleep, 0);
 580        }
 581
 582        return 0;
 583}
 584
 585/*
 586 * Recovery - powercycle the controller
 587 */
 588
 589static void auok190x_recover(struct auok190xfb_par *par)
 590{
 591        auok190x_power(par, 0);
 592        msleep(100);
 593        auok190x_power(par, 1);
 594
 595        par->init(par);
 596
 597        /* wait for init to complete */
 598        par->board->wait_for_rdy(par);
 599}
 600
 601/*
 602 * Power-management
 603 */
 604
 605#ifdef CONFIG_PM
 606static int auok190x_runtime_suspend(struct device *dev)
 607{
 608        struct platform_device *pdev = to_platform_device(dev);
 609        struct fb_info *info = platform_get_drvdata(pdev);
 610        struct auok190xfb_par *par = info->par;
 611        struct auok190x_board *board = par->board;
 612        u16 standby_param;
 613
 614        /* take and keep the lock until we are resumed, as the controller
 615         * will never reach the non-busy state when in standby mode
 616         */
 617        mutex_lock(&(par->io_lock));
 618
 619        if (par->standby) {
 620                dev_warn(dev, "already in standby, runtime-pm pairing mismatch\n");
 621                mutex_unlock(&(par->io_lock));
 622                return 0;
 623        }
 624
 625        /* according to runtime_pm.txt runtime_suspend only means, that the
 626         * device will not process data and will not communicate with the CPU
 627         * As we hold the lock, this stays true even without standby
 628         */
 629        if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) {
 630                dev_dbg(dev, "runtime suspend without standby\n");
 631                goto finish;
 632        } else if (board->quirks & AUOK190X_QUIRK_STANDBYPARAM) {
 633                /* for some TCON versions STANDBY expects a parameter (0) but
 634                 * it seems the real tcon version has to be determined yet.
 635                 */
 636                dev_dbg(dev, "runtime suspend with additional empty param\n");
 637                standby_param = 0;
 638                auok190x_send_cmdargs(par, AUOK190X_CMD_STANDBY, 1,
 639                                      &standby_param);
 640        } else {
 641                dev_dbg(dev, "runtime suspend without param\n");
 642                auok190x_send_command(par, AUOK190X_CMD_STANDBY);
 643        }
 644
 645        msleep(64);
 646
 647finish:
 648        par->standby = 1;
 649
 650        return 0;
 651}
 652
 653static int auok190x_runtime_resume(struct device *dev)
 654{
 655        struct platform_device *pdev = to_platform_device(dev);
 656        struct fb_info *info = platform_get_drvdata(pdev);
 657        struct auok190xfb_par *par = info->par;
 658        struct auok190x_board *board = par->board;
 659
 660        if (!par->standby) {
 661                dev_warn(dev, "not in standby, runtime-pm pairing mismatch\n");
 662                return 0;
 663        }
 664
 665        if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) {
 666                dev_dbg(dev, "runtime resume without standby\n");
 667        } else {
 668                /* when in standby, controller is always busy
 669                 * and only accepts the wakeup command
 670                 */
 671                dev_dbg(dev, "runtime resume from standby\n");
 672                auok190x_send_command_nowait(par, AUOK190X_CMD_WAKEUP);
 673
 674                msleep(160);
 675
 676                /* wait for the controller to be ready and release the lock */
 677                board->wait_for_rdy(par);
 678        }
 679
 680        par->standby = 0;
 681
 682        mutex_unlock(&(par->io_lock));
 683
 684        return 0;
 685}
 686
 687static int auok190x_suspend(struct device *dev)
 688{
 689        struct platform_device *pdev = to_platform_device(dev);
 690        struct fb_info *info = platform_get_drvdata(pdev);
 691        struct auok190xfb_par *par = info->par;
 692        struct auok190x_board *board = par->board;
 693        int ret;
 694
 695        dev_dbg(dev, "suspend\n");
 696        if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) {
 697                /* suspend via powering off the ic */
 698                dev_dbg(dev, "suspend with broken standby\n");
 699
 700                auok190x_power(par, 0);
 701        } else {
 702                dev_dbg(dev, "suspend using sleep\n");
 703
 704                /* the sleep state can only be entered from the standby state.
 705                 * pm_runtime_get_noresume gets called before the suspend call.
 706                 * So the devices usage count is >0 but it is not necessarily
 707                 * active.
 708                 */
 709                if (!pm_runtime_status_suspended(dev)) {
 710                        ret = auok190x_runtime_suspend(dev);
 711                        if (ret < 0) {
 712                                dev_err(dev, "auok190x_runtime_suspend failed with %d\n",
 713                                        ret);
 714                                return ret;
 715                        }
 716                        par->manual_standby = 1;
 717                }
 718
 719                gpio_direction_output(board->gpio_nsleep, 0);
 720        }
 721
 722        msleep(100);
 723
 724        return 0;
 725}
 726
 727static int auok190x_resume(struct device *dev)
 728{
 729        struct platform_device *pdev = to_platform_device(dev);
 730        struct fb_info *info = platform_get_drvdata(pdev);
 731        struct auok190xfb_par *par = info->par;
 732        struct auok190x_board *board = par->board;
 733
 734        dev_dbg(dev, "resume\n");
 735        if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) {
 736                dev_dbg(dev, "resume with broken standby\n");
 737
 738                auok190x_power(par, 1);
 739
 740                par->init(par);
 741        } else {
 742                dev_dbg(dev, "resume from sleep\n");
 743
 744                /* device should be in runtime suspend when we were suspended
 745                 * and pm_runtime_put_sync gets called after this function.
 746                 * So there is no need to touch the standby mode here at all.
 747                 */
 748                gpio_direction_output(board->gpio_nsleep, 1);
 749                msleep(100);
 750
 751                /* an additional init call seems to be necessary after sleep */
 752                auok190x_runtime_resume(dev);
 753                par->init(par);
 754
 755                /* if we were runtime-suspended before, suspend again*/
 756                if (!par->manual_standby)
 757                        auok190x_runtime_suspend(dev);
 758                else
 759                        par->manual_standby = 0;
 760        }
 761
 762        return 0;
 763}
 764#endif
 765
 766const struct dev_pm_ops auok190x_pm = {
 767        SET_RUNTIME_PM_OPS(auok190x_runtime_suspend, auok190x_runtime_resume,
 768                           NULL)
 769        SET_SYSTEM_SLEEP_PM_OPS(auok190x_suspend, auok190x_resume)
 770};
 771EXPORT_SYMBOL_GPL(auok190x_pm);
 772
 773/*
 774 * Common probe and remove code
 775 */
 776
 777int auok190x_common_probe(struct platform_device *pdev,
 778                          struct auok190x_init_data *init)
 779{
 780        struct auok190x_board *board = init->board;
 781        struct auok190xfb_par *par;
 782        struct fb_info *info;
 783        struct panel_info *panel;
 784        int videomemorysize, ret;
 785        unsigned char *videomemory;
 786
 787        /* check board contents */
 788        if (!board->init || !board->cleanup || !board->wait_for_rdy
 789            || !board->set_ctl || !board->set_hdb || !board->get_hdb
 790            || !board->setup_irq)
 791                return -EINVAL;
 792
 793        info = framebuffer_alloc(sizeof(struct auok190xfb_par), &pdev->dev);
 794        if (!info)
 795                return -ENOMEM;
 796
 797        par = info->par;
 798        par->info = info;
 799        par->board = board;
 800        par->recover = auok190x_recover;
 801        par->update_partial = init->update_partial;
 802        par->update_all = init->update_all;
 803        par->need_refresh = init->need_refresh;
 804        par->init = init->init;
 805
 806        /* init update modes */
 807        par->update_cnt = 0;
 808        par->update_mode = -1;
 809        par->last_mode = -1;
 810        par->flash = 0;
 811
 812        par->regulator = regulator_get(info->device, "vdd");
 813        if (IS_ERR(par->regulator)) {
 814                ret = PTR_ERR(par->regulator);
 815                dev_err(info->device, "Failed to get regulator: %d\n", ret);
 816                goto err_reg;
 817        }
 818
 819        ret = board->init(par);
 820        if (ret) {
 821                dev_err(info->device, "board init failed, %d\n", ret);
 822                goto err_board;
 823        }
 824
 825        ret = gpio_request(board->gpio_nsleep, "AUOK190x sleep");
 826        if (ret) {
 827                dev_err(info->device, "could not request sleep gpio, %d\n",
 828                        ret);
 829                goto err_gpio1;
 830        }
 831
 832        ret = gpio_direction_output(board->gpio_nsleep, 0);
 833        if (ret) {
 834                dev_err(info->device, "could not set sleep gpio, %d\n", ret);
 835                goto err_gpio2;
 836        }
 837
 838        ret = gpio_request(board->gpio_nrst, "AUOK190x reset");
 839        if (ret) {
 840                dev_err(info->device, "could not request reset gpio, %d\n",
 841                        ret);
 842                goto err_gpio2;
 843        }
 844
 845        ret = gpio_direction_output(board->gpio_nrst, 0);
 846        if (ret) {
 847                dev_err(info->device, "could not set reset gpio, %d\n", ret);
 848                goto err_gpio3;
 849        }
 850
 851        ret = auok190x_power(par, 1);
 852        if (ret) {
 853                dev_err(info->device, "could not power on the device, %d\n",
 854                        ret);
 855                goto err_gpio3;
 856        }
 857
 858        mutex_init(&par->io_lock);
 859
 860        init_waitqueue_head(&par->waitq);
 861
 862        ret = par->board->setup_irq(par->info);
 863        if (ret) {
 864                dev_err(info->device, "could not setup ready-irq, %d\n", ret);
 865                goto err_irq;
 866        }
 867
 868        /* wait for init to complete */
 869        par->board->wait_for_rdy(par);
 870
 871        /*
 872         * From here on the controller can talk to us
 873         */
 874
 875        /* initialise fix, var, resolution and rotation */
 876
 877        strlcpy(info->fix.id, init->id, 16);
 878        info->fix.type = FB_TYPE_PACKED_PIXELS;
 879        info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
 880        info->fix.xpanstep = 0;
 881        info->fix.ypanstep = 0;
 882        info->fix.ywrapstep = 0;
 883        info->fix.accel = FB_ACCEL_NONE;
 884
 885        info->var.bits_per_pixel = 8;
 886        info->var.grayscale = 1;
 887        info->var.red.length = 8;
 888        info->var.green.length = 8;
 889        info->var.blue.length = 8;
 890
 891        panel = &panel_table[board->resolution];
 892
 893        /* if 90 degree rotation, switch width and height */
 894        if (board->rotation & 1) {
 895                info->var.xres = panel->h;
 896                info->var.yres = panel->w;
 897                info->var.xres_virtual = panel->h;
 898                info->var.yres_virtual = panel->w;
 899                info->fix.line_length = panel->h;
 900        } else {
 901                info->var.xres = panel->w;
 902                info->var.yres = panel->h;
 903                info->var.xres_virtual = panel->w;
 904                info->var.yres_virtual = panel->h;
 905                info->fix.line_length = panel->w;
 906        }
 907
 908        par->resolution = board->resolution;
 909        par->rotation = board->rotation;
 910
 911        /* videomemory handling */
 912
 913        videomemorysize = roundup((panel->w * panel->h), PAGE_SIZE);
 914        videomemory = vmalloc(videomemorysize);
 915        if (!videomemory) {
 916                ret = -ENOMEM;
 917                goto err_irq;
 918        }
 919
 920        memset(videomemory, 0, videomemorysize);
 921        info->screen_base = (char *)videomemory;
 922        info->fix.smem_len = videomemorysize;
 923
 924        info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;
 925        info->fbops = &auok190xfb_ops;
 926
 927        /* deferred io init */
 928
 929        info->fbdefio = devm_kzalloc(info->device,
 930                                     sizeof(struct fb_deferred_io),
 931                                     GFP_KERNEL);
 932        if (!info->fbdefio) {
 933                dev_err(info->device, "Failed to allocate memory\n");
 934                ret = -ENOMEM;
 935                goto err_defio;
 936        }
 937
 938        dev_dbg(info->device, "targetting %d frames per second\n", board->fps);
 939        info->fbdefio->delay = HZ / board->fps;
 940        info->fbdefio->first_io = auok190xfb_dpy_first_io,
 941        info->fbdefio->deferred_io = auok190xfb_dpy_deferred_io,
 942        fb_deferred_io_init(info);
 943
 944        /* color map */
 945
 946        ret = fb_alloc_cmap(&info->cmap, 256, 0);
 947        if (ret < 0) {
 948                dev_err(info->device, "Failed to allocate colormap\n");
 949                goto err_cmap;
 950        }
 951
 952        /* controller init */
 953
 954        par->consecutive_threshold = 100;
 955        par->init(par);
 956        auok190x_identify(par);
 957
 958        platform_set_drvdata(pdev, info);
 959
 960        ret = register_framebuffer(info);
 961        if (ret < 0)
 962                goto err_regfb;
 963
 964        ret = sysfs_create_group(&info->device->kobj, &auok190x_attr_group);
 965        if (ret)
 966                goto err_sysfs;
 967
 968        dev_info(info->device, "fb%d: %dx%d using %dK of video memory\n",
 969                 info->node, info->var.xres, info->var.yres,
 970                 videomemorysize >> 10);
 971
 972        /* increase autosuspend_delay when we use alternative methods
 973         * for runtime_pm
 974         */
 975        par->autosuspend_delay = (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN)
 976                                        ? 1000 : 200;
 977
 978        pm_runtime_set_active(info->device);
 979        pm_runtime_enable(info->device);
 980        pm_runtime_set_autosuspend_delay(info->device, par->autosuspend_delay);
 981        pm_runtime_use_autosuspend(info->device);
 982
 983        return 0;
 984
 985err_sysfs:
 986        unregister_framebuffer(info);
 987err_regfb:
 988        fb_dealloc_cmap(&info->cmap);
 989err_cmap:
 990        fb_deferred_io_cleanup(info);
 991err_defio:
 992        vfree((void *)info->screen_base);
 993err_irq:
 994        auok190x_power(par, 0);
 995err_gpio3:
 996        gpio_free(board->gpio_nrst);
 997err_gpio2:
 998        gpio_free(board->gpio_nsleep);
 999err_gpio1:
1000        board->cleanup(par);
1001err_board:
1002        regulator_put(par->regulator);
1003err_reg:
1004        framebuffer_release(info);
1005
1006        return ret;
1007}
1008EXPORT_SYMBOL_GPL(auok190x_common_probe);
1009
1010int  auok190x_common_remove(struct platform_device *pdev)
1011{
1012        struct fb_info *info = platform_get_drvdata(pdev);
1013        struct auok190xfb_par *par = info->par;
1014        struct auok190x_board *board = par->board;
1015
1016        pm_runtime_disable(info->device);
1017
1018        sysfs_remove_group(&info->device->kobj, &auok190x_attr_group);
1019
1020        unregister_framebuffer(info);
1021
1022        fb_dealloc_cmap(&info->cmap);
1023
1024        fb_deferred_io_cleanup(info);
1025
1026        vfree((void *)info->screen_base);
1027
1028        auok190x_power(par, 0);
1029
1030        gpio_free(board->gpio_nrst);
1031        gpio_free(board->gpio_nsleep);
1032
1033        board->cleanup(par);
1034
1035        regulator_put(par->regulator);
1036
1037        framebuffer_release(info);
1038
1039        return 0;
1040}
1041EXPORT_SYMBOL_GPL(auok190x_common_remove);
1042
1043MODULE_DESCRIPTION("Common code for AUO-K190X controllers");
1044MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
1045MODULE_LICENSE("GPL");
1046
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.