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