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