aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHeiko Stübner <heiko@sntech.de>2012-04-28 06:20:00 -0400
committerFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2012-04-29 15:35:35 -0400
commit2c8304d3125b9c75797a35037945df63869bfdf6 (patch)
tree7785826daa53e6ae5f27d66e404eb2627e53b830 /drivers
parent1f45f9dbb392f9ca0919e9cd2370ab66ae752ec8 (diff)
video: auo_k190x: add code shared by controller drivers
The AUO-K190X controllers share a very similar set of commands and can therefore also share most of the driver code. Signed-off-by: Heiko Stübner <heiko@sntech.de> Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/Kconfig17
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/auo_k190x.c1046
-rw-r--r--drivers/video/auo_k190x.h129
4 files changed, 1193 insertions, 0 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index edc2a22d289e..caf9eaa0fb93 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2382,6 +2382,23 @@ config FB_BROADSHEET
2382 and could also have been called by other names when coupled with 2382 and could also have been called by other names when coupled with
2383 a bridge adapter. 2383 a bridge adapter.
2384 2384
2385config FB_AUO_K190X
2386 tristate "AUO-K190X EPD controller support"
2387 depends on FB
2388 select FB_SYS_FILLRECT
2389 select FB_SYS_COPYAREA
2390 select FB_SYS_IMAGEBLIT
2391 select FB_SYS_FOPS
2392 select FB_DEFERRED_IO
2393 help
2394 Provides support for epaper controllers from the K190X series
2395 of AUO. These controllers can be used to drive epaper displays
2396 from Sipix.
2397
2398 This option enables the common support, shared by the individual
2399 controller drivers. You will also have to enable the driver
2400 for the controller type used in your device.
2401
2385config FB_JZ4740 2402config FB_JZ4740
2386 tristate "JZ4740 LCD framebuffer support" 2403 tristate "JZ4740 LCD framebuffer support"
2387 depends on FB && MACH_JZ4740 2404 depends on FB && MACH_JZ4740
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 9356add945b3..d5406f2f2e5f 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -118,6 +118,7 @@ obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o
118obj-$(CONFIG_FB_MAXINE) += maxinefb.o 118obj-$(CONFIG_FB_MAXINE) += maxinefb.o
119obj-$(CONFIG_FB_METRONOME) += metronomefb.o 119obj-$(CONFIG_FB_METRONOME) += metronomefb.o
120obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o 120obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o
121obj-$(CONFIG_FB_AUO_K190X) += auo_k190x.o
121obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o 122obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
122obj-$(CONFIG_FB_SH7760) += sh7760fb.o 123obj-$(CONFIG_FB_SH7760) += sh7760fb.o
123obj-$(CONFIG_FB_IMX) += imxfb.o 124obj-$(CONFIG_FB_IMX) += imxfb.o
diff --git a/drivers/video/auo_k190x.c b/drivers/video/auo_k190x.c
new file mode 100644
index 000000000000..77da6a2f43dc
--- /dev/null
+++ b/drivers/video/auo_k190x.c
@@ -0,0 +1,1046 @@
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);
990 kfree(info->fbdefio);
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 __devexit 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 kfree(info->fbdefio);
1026
1027 vfree((void *)info->screen_base);
1028
1029 auok190x_power(par, 0);
1030
1031 gpio_free(board->gpio_nrst);
1032 gpio_free(board->gpio_nsleep);
1033
1034 board->cleanup(par);
1035
1036 regulator_put(par->regulator);
1037
1038 framebuffer_release(info);
1039
1040 return 0;
1041}
1042EXPORT_SYMBOL_GPL(auok190x_common_remove);
1043
1044MODULE_DESCRIPTION("Common code for AUO-K190X controllers");
1045MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
1046MODULE_LICENSE("GPL");
diff --git a/drivers/video/auo_k190x.h b/drivers/video/auo_k190x.h
new file mode 100644
index 000000000000..e35af1f51b28
--- /dev/null
+++ b/drivers/video/auo_k190x.h
@@ -0,0 +1,129 @@
1/*
2 * Private common definitions 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/*
12 * I80 interface specific defines
13 */
14
15#define AUOK190X_I80_CS 0x01
16#define AUOK190X_I80_DC 0x02
17#define AUOK190X_I80_WR 0x03
18#define AUOK190X_I80_OE 0x04
19
20/*
21 * AUOK190x commands, common to both controllers
22 */
23
24#define AUOK190X_CMD_INIT 0x0000
25#define AUOK190X_CMD_STANDBY 0x0001
26#define AUOK190X_CMD_WAKEUP 0x0002
27#define AUOK190X_CMD_TCON_RESET 0x0003
28#define AUOK190X_CMD_DATA_STOP 0x1002
29#define AUOK190X_CMD_LUT_START 0x1003
30#define AUOK190X_CMD_DISP_REFRESH 0x1004
31#define AUOK190X_CMD_DISP_RESET 0x1005
32#define AUOK190X_CMD_PRE_DISPLAY_START 0x100D
33#define AUOK190X_CMD_PRE_DISPLAY_STOP 0x100F
34#define AUOK190X_CMD_FLASH_W 0x2000
35#define AUOK190X_CMD_FLASH_E 0x2001
36#define AUOK190X_CMD_FLASH_STS 0x2002
37#define AUOK190X_CMD_FRAMERATE 0x3000
38#define AUOK190X_CMD_READ_VERSION 0x4000
39#define AUOK190X_CMD_READ_STATUS 0x4001
40#define AUOK190X_CMD_READ_LUT 0x4003
41#define AUOK190X_CMD_DRIVERTIMING 0x5000
42#define AUOK190X_CMD_LBALANCE 0x5001
43#define AUOK190X_CMD_AGINGMODE 0x6000
44#define AUOK190X_CMD_AGINGEXIT 0x6001
45
46/*
47 * Common settings for AUOK190X_CMD_INIT
48 */
49
50#define AUOK190X_INIT_DATA_FILTER (0 << 12)
51#define AUOK190X_INIT_DATA_BYPASS (1 << 12)
52#define AUOK190X_INIT_INVERSE_WHITE (0 << 9)
53#define AUOK190X_INIT_INVERSE_BLACK (1 << 9)
54#define AUOK190X_INIT_SCAN_DOWN (0 << 1)
55#define AUOK190X_INIT_SCAN_UP (1 << 1)
56#define AUOK190X_INIT_SHIFT_LEFT (0 << 0)
57#define AUOK190X_INIT_SHIFT_RIGHT (1 << 0)
58
59/* Common bits to pixels
60 * Mode 15-12 11-8 7-4 3-0
61 * format0 4 3 2 1
62 * format1 3 4 1 2
63 */
64
65#define AUOK190X_INIT_FORMAT0 0
66#define AUOK190X_INIT_FORMAT1 (1 << 6)
67
68/*
69 * settings for AUOK190X_CMD_RESET
70 */
71
72#define AUOK190X_RESET_TCON (0 << 0)
73#define AUOK190X_RESET_NORMAL (1 << 0)
74#define AUOK190X_RESET_PON (1 << 1)
75
76/*
77 * AUOK190X_CMD_VERSION
78 */
79
80#define AUOK190X_VERSION_TEMP_MASK (0x1ff)
81#define AUOK190X_VERSION_EPD_MASK (0xff)
82#define AUOK190X_VERSION_SIZE_INT(_val) ((_val & 0xfc00) >> 10)
83#define AUOK190X_VERSION_SIZE_FLOAT(_val) ((_val & 0x3c0) >> 6)
84#define AUOK190X_VERSION_MODEL(_val) (_val & 0x3f)
85#define AUOK190X_VERSION_LUT(_val) (_val & 0xff)
86#define AUOK190X_VERSION_TCON(_val) ((_val & 0xff00) >> 8)
87
88/*
89 * update modes for CMD_PARTIALDISP on K1900 and CMD_DDMA on K1901
90 */
91
92#define AUOK190X_UPDATE_MODE(_res) ((_res & 0x7) << 12)
93#define AUOK190X_UPDATE_NONFLASH (1 << 15)
94
95/*
96 * track panel specific parameters for common init
97 */
98
99struct auok190x_init_data {
100 char *id;
101 struct auok190x_board *board;
102
103 void (*update_partial)(struct auok190xfb_par *par, u16 y1, u16 y2);
104 void (*update_all)(struct auok190xfb_par *par);
105 bool (*need_refresh)(struct auok190xfb_par *par);
106 void (*init)(struct auok190xfb_par *par);
107};
108
109
110extern void auok190x_send_command_nowait(struct auok190xfb_par *par, u16 data);
111extern int auok190x_send_command(struct auok190xfb_par *par, u16 data);
112extern void auok190x_send_cmdargs_nowait(struct auok190xfb_par *par, u16 cmd,
113 int argc, u16 *argv);
114extern int auok190x_send_cmdargs(struct auok190xfb_par *par, u16 cmd,
115 int argc, u16 *argv);
116extern void auok190x_send_cmdargs_pixels_nowait(struct auok190xfb_par *par,
117 u16 cmd, int argc, u16 *argv,
118 int size, u16 *data);
119extern int auok190x_send_cmdargs_pixels(struct auok190xfb_par *par, u16 cmd,
120 int argc, u16 *argv, int size,
121 u16 *data);
122extern int auok190x_read_cmdargs(struct auok190xfb_par *par, u16 cmd,
123 int argc, u16 *argv);
124
125extern int auok190x_common_probe(struct platform_device *pdev,
126 struct auok190x_init_data *init);
127extern int auok190x_common_remove(struct platform_device *pdev);
128
129extern const struct dev_pm_ops auok190x_pm;