video: irq: Remove IRQF_DISABLED
[linux-2.6-block.git] / drivers / video / omap2 / displays / panel-taal.c
CommitLineData
f133a9d7
TV
1/*
2 * Taal DSI command mode panel
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/*#define DEBUG*/
21
22#include <linux/module.h>
23#include <linux/delay.h>
24#include <linux/err.h>
25#include <linux/jiffies.h>
26#include <linux/sched.h>
27#include <linux/backlight.h>
28#include <linux/fb.h>
29#include <linux/interrupt.h>
30#include <linux/gpio.h>
f133a9d7 31#include <linux/workqueue.h>
5a0e3ad6 32#include <linux/slab.h>
c8cd4547 33#include <linux/regulator/consumer.h>
a3201a0e 34#include <linux/mutex.h>
f133a9d7 35
a0b38cc4 36#include <video/omapdss.h>
4e9f99d7 37#include <video/omap-panel-nokia-dsi.h>
f133a9d7
TV
38
39/* DSI Virtual channel. Hardcoded for now. */
40#define TCH 0
41
42#define DCS_READ_NUM_ERRORS 0x05
43#define DCS_READ_POWER_MODE 0x0a
44#define DCS_READ_MADCTL 0x0b
45#define DCS_READ_PIXEL_FORMAT 0x0c
46#define DCS_RDDSDR 0x0f
47#define DCS_SLEEP_IN 0x10
48#define DCS_SLEEP_OUT 0x11
49#define DCS_DISPLAY_OFF 0x28
50#define DCS_DISPLAY_ON 0x29
51#define DCS_COLUMN_ADDR 0x2a
52#define DCS_PAGE_ADDR 0x2b
53#define DCS_MEMORY_WRITE 0x2c
54#define DCS_TEAR_OFF 0x34
55#define DCS_TEAR_ON 0x35
56#define DCS_MEM_ACC_CTRL 0x36
57#define DCS_PIXEL_FORMAT 0x3a
58#define DCS_BRIGHTNESS 0x51
59#define DCS_CTRL_DISPLAY 0x53
60#define DCS_WRITE_CABC 0x55
61#define DCS_READ_CABC 0x56
62#define DCS_GET_ID1 0xda
63#define DCS_GET_ID2 0xdb
64#define DCS_GET_ID3 0xdc
65
7ae2fb11
JN
66static irqreturn_t taal_te_isr(int irq, void *data);
67static void taal_te_timeout_work_callback(struct work_struct *work);
21df20fc
TV
68static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
69
1abf7814
TV
70static int taal_panel_reset(struct omap_dss_device *dssdev);
71
c8cd4547
TV
72struct panel_regulator {
73 struct regulator *regulator;
74 const char *name;
75 int min_uV;
76 int max_uV;
77};
78
79static void free_regulators(struct panel_regulator *regulators, int n)
80{
81 int i;
82
83 for (i = 0; i < n; i++) {
84 /* disable/put in reverse order */
85 regulator_disable(regulators[n - i - 1].regulator);
86 regulator_put(regulators[n - i - 1].regulator);
87 }
88}
89
90static int init_regulators(struct omap_dss_device *dssdev,
91 struct panel_regulator *regulators, int n)
92{
93 int r, i, v;
94
95 for (i = 0; i < n; i++) {
96 struct regulator *reg;
97
98 reg = regulator_get(&dssdev->dev, regulators[i].name);
99 if (IS_ERR(reg)) {
100 dev_err(&dssdev->dev, "failed to get regulator %s\n",
101 regulators[i].name);
102 r = PTR_ERR(reg);
103 goto err;
104 }
105
106 /* FIXME: better handling of fixed vs. variable regulators */
107 v = regulator_get_voltage(reg);
108 if (v < regulators[i].min_uV || v > regulators[i].max_uV) {
109 r = regulator_set_voltage(reg, regulators[i].min_uV,
110 regulators[i].max_uV);
111 if (r) {
112 dev_err(&dssdev->dev,
113 "failed to set regulator %s voltage\n",
114 regulators[i].name);
115 regulator_put(reg);
116 goto err;
117 }
118 }
119
120 r = regulator_enable(reg);
121 if (r) {
122 dev_err(&dssdev->dev, "failed to enable regulator %s\n",
123 regulators[i].name);
124 regulator_put(reg);
125 goto err;
126 }
127
128 regulators[i].regulator = reg;
129 }
130
131 return 0;
132
133err:
134 free_regulators(regulators, i);
135
136 return r;
137}
138
e7f6c3f2
JN
139/**
140 * struct panel_config - panel configuration
141 * @name: panel name
142 * @type: panel type
143 * @timings: panel resolution
144 * @sleep: various panel specific delays, passed to msleep() if non-zero
145 * @reset_sequence: reset sequence timings, passed to udelay() if non-zero
c8cd4547
TV
146 * @regulators: array of panel regulators
147 * @num_regulators: number of regulators in the array
e7f6c3f2
JN
148 */
149struct panel_config {
150 const char *name;
151 int type;
152
153 struct omap_video_timings timings;
154
155 struct {
156 unsigned int sleep_in;
157 unsigned int sleep_out;
158 unsigned int hw_reset;
159 unsigned int enable_te;
160 } sleep;
161
162 struct {
163 unsigned int high;
164 unsigned int low;
165 } reset_sequence;
c8cd4547
TV
166
167 struct panel_regulator *regulators;
168 int num_regulators;
e7f6c3f2
JN
169};
170
171enum {
172 PANEL_TAAL,
173};
174
175static struct panel_config panel_configs[] = {
176 {
177 .name = "taal",
178 .type = PANEL_TAAL,
179 .timings = {
180 .x_res = 864,
181 .y_res = 480,
182 },
183 .sleep = {
184 .sleep_in = 5,
185 .sleep_out = 5,
186 .hw_reset = 5,
187 .enable_te = 100, /* possible panel bug */
188 },
189 .reset_sequence = {
190 .high = 10,
191 .low = 10,
192 },
193 },
194};
195
f133a9d7 196struct taal_data {
a3201a0e
TV
197 struct mutex lock;
198
f133a9d7
TV
199 struct backlight_device *bldev;
200
201 unsigned long hw_guard_end; /* next value of jiffies when we can
202 * issue the next sleep in/out command
203 */
204 unsigned long hw_guard_wait; /* max guard time in jiffies */
205
206 struct omap_dss_device *dssdev;
207
208 bool enabled;
209 u8 rotate;
210 bool mirror;
211
212 bool te_enabled;
7ae2fb11
JN
213
214 atomic_t do_update;
215 struct {
216 u16 x;
217 u16 y;
218 u16 w;
219 u16 h;
220 } update_region;
bc6d4b1d
AT
221 int channel;
222
7ae2fb11 223 struct delayed_work te_timeout_work;
f133a9d7
TV
224
225 bool use_dsi_bl;
226
227 bool cabc_broken;
228 unsigned cabc_mode;
229
230 bool intro_printed;
231
883b9ac9
TV
232 struct workqueue_struct *workqueue;
233
f133a9d7 234 struct delayed_work esd_work;
33a410be 235 unsigned esd_interval;
e7f6c3f2 236
1abf7814
TV
237 bool ulps_enabled;
238 unsigned ulps_timeout;
239 struct delayed_work ulps_work;
240
e7f6c3f2 241 struct panel_config *panel_config;
f133a9d7
TV
242};
243
8d3573c8
TV
244static inline struct nokia_dsi_panel_data
245*get_panel_data(const struct omap_dss_device *dssdev)
246{
247 return (struct nokia_dsi_panel_data *) dssdev->data;
248}
249
f133a9d7 250static void taal_esd_work(struct work_struct *work);
1abf7814 251static void taal_ulps_work(struct work_struct *work);
f133a9d7
TV
252
253static void hw_guard_start(struct taal_data *td, int guard_msec)
254{
255 td->hw_guard_wait = msecs_to_jiffies(guard_msec);
256 td->hw_guard_end = jiffies + td->hw_guard_wait;
257}
258
259static void hw_guard_wait(struct taal_data *td)
260{
261 unsigned long wait = td->hw_guard_end - jiffies;
262
263 if ((long)wait > 0 && wait <= td->hw_guard_wait) {
264 set_current_state(TASK_UNINTERRUPTIBLE);
265 schedule_timeout(wait);
266 }
267}
268
bc6d4b1d 269static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
f133a9d7
TV
270{
271 int r;
272 u8 buf[1];
273
1ffefe75 274 r = dsi_vc_dcs_read(td->dssdev, td->channel, dcs_cmd, buf, 1);
f133a9d7
TV
275
276 if (r < 0)
277 return r;
278
279 *data = buf[0];
280
281 return 0;
282}
283
bc6d4b1d 284static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd)
f133a9d7 285{
1ffefe75 286 return dsi_vc_dcs_write(td->dssdev, td->channel, &dcs_cmd, 1);
f133a9d7
TV
287}
288
bc6d4b1d 289static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
f133a9d7
TV
290{
291 u8 buf[2];
292 buf[0] = dcs_cmd;
293 buf[1] = param;
1ffefe75 294 return dsi_vc_dcs_write(td->dssdev, td->channel, buf, 2);
f133a9d7
TV
295}
296
297static int taal_sleep_in(struct taal_data *td)
298
299{
300 u8 cmd;
301 int r;
302
303 hw_guard_wait(td);
304
305 cmd = DCS_SLEEP_IN;
1ffefe75 306 r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, &cmd, 1);
f133a9d7
TV
307 if (r)
308 return r;
309
310 hw_guard_start(td, 120);
311
e7f6c3f2
JN
312 if (td->panel_config->sleep.sleep_in)
313 msleep(td->panel_config->sleep.sleep_in);
f133a9d7
TV
314
315 return 0;
316}
317
318static int taal_sleep_out(struct taal_data *td)
319{
320 int r;
321
322 hw_guard_wait(td);
323
bc6d4b1d 324 r = taal_dcs_write_0(td, DCS_SLEEP_OUT);
f133a9d7
TV
325 if (r)
326 return r;
327
328 hw_guard_start(td, 120);
329
e7f6c3f2
JN
330 if (td->panel_config->sleep.sleep_out)
331 msleep(td->panel_config->sleep.sleep_out);
f133a9d7
TV
332
333 return 0;
334}
335
bc6d4b1d 336static int taal_get_id(struct taal_data *td, u8 *id1, u8 *id2, u8 *id3)
f133a9d7
TV
337{
338 int r;
339
bc6d4b1d 340 r = taal_dcs_read_1(td, DCS_GET_ID1, id1);
f133a9d7
TV
341 if (r)
342 return r;
bc6d4b1d 343 r = taal_dcs_read_1(td, DCS_GET_ID2, id2);
f133a9d7
TV
344 if (r)
345 return r;
bc6d4b1d 346 r = taal_dcs_read_1(td, DCS_GET_ID3, id3);
f133a9d7
TV
347 if (r)
348 return r;
349
350 return 0;
351}
352
bc6d4b1d 353static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
f133a9d7
TV
354{
355 int r;
356 u8 mode;
357 int b5, b6, b7;
358
bc6d4b1d 359 r = taal_dcs_read_1(td, DCS_READ_MADCTL, &mode);
f133a9d7
TV
360 if (r)
361 return r;
362
363 switch (rotate) {
364 default:
365 case 0:
366 b7 = 0;
367 b6 = 0;
368 b5 = 0;
369 break;
370 case 1:
371 b7 = 0;
372 b6 = 1;
373 b5 = 1;
374 break;
375 case 2:
376 b7 = 1;
377 b6 = 1;
378 b5 = 0;
379 break;
380 case 3:
381 b7 = 1;
382 b6 = 0;
383 b5 = 1;
384 break;
385 }
386
387 if (mirror)
388 b6 = !b6;
389
390 mode &= ~((1<<7) | (1<<6) | (1<<5));
391 mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
392
bc6d4b1d 393 return taal_dcs_write_1(td, DCS_MEM_ACC_CTRL, mode);
f133a9d7
TV
394}
395
bc6d4b1d
AT
396static int taal_set_update_window(struct taal_data *td,
397 u16 x, u16 y, u16 w, u16 h)
f133a9d7
TV
398{
399 int r;
400 u16 x1 = x;
401 u16 x2 = x + w - 1;
402 u16 y1 = y;
403 u16 y2 = y + h - 1;
404
405 u8 buf[5];
406 buf[0] = DCS_COLUMN_ADDR;
407 buf[1] = (x1 >> 8) & 0xff;
408 buf[2] = (x1 >> 0) & 0xff;
409 buf[3] = (x2 >> 8) & 0xff;
410 buf[4] = (x2 >> 0) & 0xff;
411
1ffefe75 412 r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf));
f133a9d7
TV
413 if (r)
414 return r;
415
416 buf[0] = DCS_PAGE_ADDR;
417 buf[1] = (y1 >> 8) & 0xff;
418 buf[2] = (y1 >> 0) & 0xff;
419 buf[3] = (y2 >> 8) & 0xff;
420 buf[4] = (y2 >> 0) & 0xff;
421
1ffefe75 422 r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf));
f133a9d7
TV
423 if (r)
424 return r;
425
1ffefe75 426 dsi_vc_send_bta_sync(td->dssdev, td->channel);
f133a9d7
TV
427
428 return r;
429}
430
1663d2f7
TV
431static void taal_queue_esd_work(struct omap_dss_device *dssdev)
432{
433 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
434
435 if (td->esd_interval > 0)
883b9ac9 436 queue_delayed_work(td->workqueue, &td->esd_work,
1663d2f7
TV
437 msecs_to_jiffies(td->esd_interval));
438}
439
440static void taal_cancel_esd_work(struct omap_dss_device *dssdev)
441{
442 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
443
444 cancel_delayed_work(&td->esd_work);
445}
446
1abf7814
TV
447static void taal_queue_ulps_work(struct omap_dss_device *dssdev)
448{
449 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
450
451 if (td->ulps_timeout > 0)
452 queue_delayed_work(td->workqueue, &td->ulps_work,
453 msecs_to_jiffies(td->ulps_timeout));
454}
455
456static void taal_cancel_ulps_work(struct omap_dss_device *dssdev)
457{
458 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
459
460 cancel_delayed_work(&td->ulps_work);
461}
462
463static int taal_enter_ulps(struct omap_dss_device *dssdev)
464{
465 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
466 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
467 int r;
468
469 if (td->ulps_enabled)
470 return 0;
471
472 taal_cancel_ulps_work(dssdev);
473
474 r = _taal_enable_te(dssdev, false);
475 if (r)
476 goto err;
477
478 disable_irq(gpio_to_irq(panel_data->ext_te_gpio));
479
480 omapdss_dsi_display_disable(dssdev, false, true);
481
482 td->ulps_enabled = true;
483
484 return 0;
485
486err:
487 dev_err(&dssdev->dev, "enter ULPS failed");
488 taal_panel_reset(dssdev);
489
490 td->ulps_enabled = false;
491
492 taal_queue_ulps_work(dssdev);
493
494 return r;
495}
496
497static int taal_exit_ulps(struct omap_dss_device *dssdev)
498{
499 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
500 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
501 int r;
502
503 if (!td->ulps_enabled)
504 return 0;
505
506 r = omapdss_dsi_display_enable(dssdev);
e8945677
TV
507 if (r) {
508 dev_err(&dssdev->dev, "failed to enable DSI\n");
509 goto err1;
510 }
1abf7814 511
1ffefe75 512 omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
1abf7814
TV
513
514 r = _taal_enable_te(dssdev, true);
e8945677
TV
515 if (r) {
516 dev_err(&dssdev->dev, "failed to re-enable TE");
517 goto err2;
518 }
1abf7814
TV
519
520 enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
521
522 taal_queue_ulps_work(dssdev);
523
524 td->ulps_enabled = false;
525
526 return 0;
527
e8945677
TV
528err2:
529 dev_err(&dssdev->dev, "failed to exit ULPS");
1abf7814 530
e8945677
TV
531 r = taal_panel_reset(dssdev);
532 if (!r) {
533 enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
534 td->ulps_enabled = false;
535 }
536err1:
1abf7814
TV
537 taal_queue_ulps_work(dssdev);
538
539 return r;
540}
541
542static int taal_wake_up(struct omap_dss_device *dssdev)
543{
544 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
545
546 if (td->ulps_enabled)
547 return taal_exit_ulps(dssdev);
548
549 taal_cancel_ulps_work(dssdev);
550 taal_queue_ulps_work(dssdev);
551 return 0;
552}
553
f133a9d7
TV
554static int taal_bl_update_status(struct backlight_device *dev)
555{
556 struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
557 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
8d3573c8 558 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
f133a9d7
TV
559 int r;
560 int level;
561
562 if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
563 dev->props.power == FB_BLANK_UNBLANK)
564 level = dev->props.brightness;
565 else
566 level = 0;
567
568 dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
569
1cbc8703
TV
570 mutex_lock(&td->lock);
571
f133a9d7
TV
572 if (td->use_dsi_bl) {
573 if (td->enabled) {
1ffefe75 574 dsi_bus_lock(dssdev);
1abf7814
TV
575
576 r = taal_wake_up(dssdev);
577 if (!r)
578 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
579
1ffefe75 580 dsi_bus_unlock(dssdev);
1cbc8703
TV
581 } else {
582 r = 0;
f133a9d7
TV
583 }
584 } else {
8d3573c8 585 if (!panel_data->set_backlight)
1cbc8703
TV
586 r = -EINVAL;
587 else
8d3573c8 588 r = panel_data->set_backlight(dssdev, level);
f133a9d7
TV
589 }
590
1cbc8703
TV
591 mutex_unlock(&td->lock);
592
593 return r;
f133a9d7
TV
594}
595
596static int taal_bl_get_intensity(struct backlight_device *dev)
597{
598 if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
599 dev->props.power == FB_BLANK_UNBLANK)
600 return dev->props.brightness;
601
602 return 0;
603}
604
acc2472e 605static const struct backlight_ops taal_bl_ops = {
f133a9d7
TV
606 .get_brightness = taal_bl_get_intensity,
607 .update_status = taal_bl_update_status,
608};
609
610static void taal_get_timings(struct omap_dss_device *dssdev,
611 struct omap_video_timings *timings)
612{
613 *timings = dssdev->panel.timings;
614}
615
616static void taal_get_resolution(struct omap_dss_device *dssdev,
617 u16 *xres, u16 *yres)
618{
619 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
620
621 if (td->rotate == 0 || td->rotate == 2) {
622 *xres = dssdev->panel.timings.x_res;
623 *yres = dssdev->panel.timings.y_res;
624 } else {
625 *yres = dssdev->panel.timings.x_res;
626 *xres = dssdev->panel.timings.y_res;
627 }
628}
629
f133a9d7
TV
630static ssize_t taal_num_errors_show(struct device *dev,
631 struct device_attribute *attr, char *buf)
632{
633 struct omap_dss_device *dssdev = to_dss_device(dev);
634 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
635 u8 errors;
636 int r;
637
6b316715
JN
638 mutex_lock(&td->lock);
639
f133a9d7 640 if (td->enabled) {
1ffefe75 641 dsi_bus_lock(dssdev);
1abf7814
TV
642
643 r = taal_wake_up(dssdev);
644 if (!r)
645 r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors);
646
1ffefe75 647 dsi_bus_unlock(dssdev);
f133a9d7
TV
648 } else {
649 r = -ENODEV;
650 }
651
6b316715
JN
652 mutex_unlock(&td->lock);
653
f133a9d7
TV
654 if (r)
655 return r;
656
657 return snprintf(buf, PAGE_SIZE, "%d\n", errors);
658}
659
660static ssize_t taal_hw_revision_show(struct device *dev,
661 struct device_attribute *attr, char *buf)
662{
663 struct omap_dss_device *dssdev = to_dss_device(dev);
664 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
665 u8 id1, id2, id3;
666 int r;
667
6b316715
JN
668 mutex_lock(&td->lock);
669
f133a9d7 670 if (td->enabled) {
1ffefe75 671 dsi_bus_lock(dssdev);
1abf7814
TV
672
673 r = taal_wake_up(dssdev);
674 if (!r)
675 r = taal_get_id(td, &id1, &id2, &id3);
676
1ffefe75 677 dsi_bus_unlock(dssdev);
f133a9d7
TV
678 } else {
679 r = -ENODEV;
680 }
681
6b316715
JN
682 mutex_unlock(&td->lock);
683
f133a9d7
TV
684 if (r)
685 return r;
686
687 return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3);
688}
689
690static const char *cabc_modes[] = {
691 "off", /* used also always when CABC is not supported */
692 "ui",
693 "still-image",
694 "moving-image",
695};
696
697static ssize_t show_cabc_mode(struct device *dev,
698 struct device_attribute *attr,
699 char *buf)
700{
701 struct omap_dss_device *dssdev = to_dss_device(dev);
702 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
703 const char *mode_str;
704 int mode;
705 int len;
706
707 mode = td->cabc_mode;
708
709 mode_str = "unknown";
710 if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes))
711 mode_str = cabc_modes[mode];
712 len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str);
713
714 return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1;
715}
716
717static ssize_t store_cabc_mode(struct device *dev,
718 struct device_attribute *attr,
719 const char *buf, size_t count)
720{
721 struct omap_dss_device *dssdev = to_dss_device(dev);
722 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
723 int i;
1abf7814 724 int r;
f133a9d7
TV
725
726 for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) {
727 if (sysfs_streq(cabc_modes[i], buf))
728 break;
729 }
730
731 if (i == ARRAY_SIZE(cabc_modes))
732 return -EINVAL;
733
6b316715
JN
734 mutex_lock(&td->lock);
735
f133a9d7 736 if (td->enabled) {
1ffefe75 737 dsi_bus_lock(dssdev);
1abf7814
TV
738
739 if (!td->cabc_broken) {
740 r = taal_wake_up(dssdev);
741 if (r)
742 goto err;
743
744 r = taal_dcs_write_1(td, DCS_WRITE_CABC, i);
745 if (r)
746 goto err;
747 }
748
1ffefe75 749 dsi_bus_unlock(dssdev);
f133a9d7
TV
750 }
751
752 td->cabc_mode = i;
753
6b316715
JN
754 mutex_unlock(&td->lock);
755
f133a9d7 756 return count;
1abf7814 757err:
1ffefe75 758 dsi_bus_unlock(dssdev);
1abf7814
TV
759 mutex_unlock(&td->lock);
760 return r;
f133a9d7
TV
761}
762
763static ssize_t show_cabc_available_modes(struct device *dev,
764 struct device_attribute *attr,
765 char *buf)
766{
767 int len;
768 int i;
769
770 for (i = 0, len = 0;
771 len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++)
772 len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s",
773 i ? " " : "", cabc_modes[i],
774 i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : "");
775
776 return len < PAGE_SIZE ? len : PAGE_SIZE - 1;
777}
778
1f8fa452
TV
779static ssize_t taal_store_esd_interval(struct device *dev,
780 struct device_attribute *attr,
781 const char *buf, size_t count)
782{
783 struct omap_dss_device *dssdev = to_dss_device(dev);
784 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
785
786 unsigned long t;
787 int r;
788
789 r = strict_strtoul(buf, 10, &t);
790 if (r)
791 return r;
792
793 mutex_lock(&td->lock);
794 taal_cancel_esd_work(dssdev);
795 td->esd_interval = t;
796 if (td->enabled)
797 taal_queue_esd_work(dssdev);
798 mutex_unlock(&td->lock);
799
800 return count;
801}
802
803static ssize_t taal_show_esd_interval(struct device *dev,
804 struct device_attribute *attr,
805 char *buf)
806{
807 struct omap_dss_device *dssdev = to_dss_device(dev);
808 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
809 unsigned t;
810
811 mutex_lock(&td->lock);
812 t = td->esd_interval;
813 mutex_unlock(&td->lock);
814
815 return snprintf(buf, PAGE_SIZE, "%u\n", t);
816}
817
1abf7814
TV
818static ssize_t taal_store_ulps(struct device *dev,
819 struct device_attribute *attr,
820 const char *buf, size_t count)
821{
822 struct omap_dss_device *dssdev = to_dss_device(dev);
823 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
824 unsigned long t;
825 int r;
826
827 r = strict_strtoul(buf, 10, &t);
828 if (r)
829 return r;
830
831 mutex_lock(&td->lock);
832
833 if (td->enabled) {
1ffefe75 834 dsi_bus_lock(dssdev);
1abf7814
TV
835
836 if (t)
837 r = taal_enter_ulps(dssdev);
838 else
839 r = taal_wake_up(dssdev);
840
1ffefe75 841 dsi_bus_unlock(dssdev);
1abf7814
TV
842 }
843
844 mutex_unlock(&td->lock);
845
846 if (r)
847 return r;
848
849 return count;
850}
851
852static ssize_t taal_show_ulps(struct device *dev,
853 struct device_attribute *attr,
854 char *buf)
855{
856 struct omap_dss_device *dssdev = to_dss_device(dev);
857 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
858 unsigned t;
859
860 mutex_lock(&td->lock);
861 t = td->ulps_enabled;
862 mutex_unlock(&td->lock);
863
864 return snprintf(buf, PAGE_SIZE, "%u\n", t);
865}
866
867static ssize_t taal_store_ulps_timeout(struct device *dev,
868 struct device_attribute *attr,
869 const char *buf, size_t count)
870{
871 struct omap_dss_device *dssdev = to_dss_device(dev);
872 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
873 unsigned long t;
874 int r;
875
876 r = strict_strtoul(buf, 10, &t);
877 if (r)
878 return r;
879
880 mutex_lock(&td->lock);
881 td->ulps_timeout = t;
882
883 if (td->enabled) {
884 /* taal_wake_up will restart the timer */
1ffefe75 885 dsi_bus_lock(dssdev);
1abf7814 886 r = taal_wake_up(dssdev);
1ffefe75 887 dsi_bus_unlock(dssdev);
1abf7814
TV
888 }
889
890 mutex_unlock(&td->lock);
891
892 if (r)
893 return r;
894
895 return count;
896}
897
898static ssize_t taal_show_ulps_timeout(struct device *dev,
899 struct device_attribute *attr,
900 char *buf)
901{
902 struct omap_dss_device *dssdev = to_dss_device(dev);
903 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
904 unsigned t;
905
906 mutex_lock(&td->lock);
907 t = td->ulps_timeout;
908 mutex_unlock(&td->lock);
909
910 return snprintf(buf, PAGE_SIZE, "%u\n", t);
911}
912
f133a9d7
TV
913static DEVICE_ATTR(num_dsi_errors, S_IRUGO, taal_num_errors_show, NULL);
914static DEVICE_ATTR(hw_revision, S_IRUGO, taal_hw_revision_show, NULL);
915static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR,
916 show_cabc_mode, store_cabc_mode);
917static DEVICE_ATTR(cabc_available_modes, S_IRUGO,
918 show_cabc_available_modes, NULL);
1f8fa452
TV
919static DEVICE_ATTR(esd_interval, S_IRUGO | S_IWUSR,
920 taal_show_esd_interval, taal_store_esd_interval);
1abf7814
TV
921static DEVICE_ATTR(ulps, S_IRUGO | S_IWUSR,
922 taal_show_ulps, taal_store_ulps);
923static DEVICE_ATTR(ulps_timeout, S_IRUGO | S_IWUSR,
924 taal_show_ulps_timeout, taal_store_ulps_timeout);
f133a9d7
TV
925
926static struct attribute *taal_attrs[] = {
927 &dev_attr_num_dsi_errors.attr,
928 &dev_attr_hw_revision.attr,
929 &dev_attr_cabc_mode.attr,
930 &dev_attr_cabc_available_modes.attr,
1f8fa452 931 &dev_attr_esd_interval.attr,
1abf7814
TV
932 &dev_attr_ulps.attr,
933 &dev_attr_ulps_timeout.attr,
f133a9d7
TV
934 NULL,
935};
936
937static struct attribute_group taal_attr_group = {
938 .attrs = taal_attrs,
939};
940
006db7b4
JN
941static void taal_hw_reset(struct omap_dss_device *dssdev)
942{
e7f6c3f2 943 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
8d3573c8
TV
944 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
945
946 if (panel_data->reset_gpio == -1)
006db7b4
JN
947 return;
948
8d3573c8 949 gpio_set_value(panel_data->reset_gpio, 1);
e7f6c3f2
JN
950 if (td->panel_config->reset_sequence.high)
951 udelay(td->panel_config->reset_sequence.high);
006db7b4 952 /* reset the panel */
8d3573c8 953 gpio_set_value(panel_data->reset_gpio, 0);
e7f6c3f2
JN
954 /* assert reset */
955 if (td->panel_config->reset_sequence.low)
956 udelay(td->panel_config->reset_sequence.low);
8d3573c8 957 gpio_set_value(panel_data->reset_gpio, 1);
e7f6c3f2
JN
958 /* wait after releasing reset */
959 if (td->panel_config->sleep.hw_reset)
960 msleep(td->panel_config->sleep.hw_reset);
006db7b4
JN
961}
962
f133a9d7
TV
963static int taal_probe(struct omap_dss_device *dssdev)
964{
a19a6ee6 965 struct backlight_properties props;
f133a9d7
TV
966 struct taal_data *td;
967 struct backlight_device *bldev;
8d3573c8 968 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
e7f6c3f2
JN
969 struct panel_config *panel_config = NULL;
970 int r, i;
f133a9d7
TV
971
972 dev_dbg(&dssdev->dev, "probe\n");
973
8d3573c8
TV
974 if (!panel_data || !panel_data->name) {
975 r = -EINVAL;
976 goto err;
977 }
978
e7f6c3f2
JN
979 for (i = 0; i < ARRAY_SIZE(panel_configs); i++) {
980 if (strcmp(panel_data->name, panel_configs[i].name) == 0) {
981 panel_config = &panel_configs[i];
982 break;
983 }
984 }
985
986 if (!panel_config) {
987 r = -EINVAL;
988 goto err;
989 }
990
f133a9d7 991 dssdev->panel.config = OMAP_DSS_LCD_TFT;
e7f6c3f2 992 dssdev->panel.timings = panel_config->timings;
f133a9d7
TV
993 dssdev->ctrl.pixel_size = 24;
994
995 td = kzalloc(sizeof(*td), GFP_KERNEL);
996 if (!td) {
997 r = -ENOMEM;
d2b65787 998 goto err;
f133a9d7
TV
999 }
1000 td->dssdev = dssdev;
e7f6c3f2 1001 td->panel_config = panel_config;
33a410be 1002 td->esd_interval = panel_data->esd_interval;
1abf7814
TV
1003 td->ulps_enabled = false;
1004 td->ulps_timeout = panel_data->ulps_timeout;
f133a9d7 1005
a3201a0e
TV
1006 mutex_init(&td->lock);
1007
7ae2fb11
JN
1008 atomic_set(&td->do_update, 0);
1009
c8cd4547
TV
1010 r = init_regulators(dssdev, panel_config->regulators,
1011 panel_config->num_regulators);
1012 if (r)
1013 goto err_reg;
1014
883b9ac9
TV
1015 td->workqueue = create_singlethread_workqueue("taal_esd");
1016 if (td->workqueue == NULL) {
f133a9d7
TV
1017 dev_err(&dssdev->dev, "can't create ESD workqueue\n");
1018 r = -ENOMEM;
d2b65787 1019 goto err_wq;
f133a9d7
TV
1020 }
1021 INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
1abf7814 1022 INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
f133a9d7
TV
1023
1024 dev_set_drvdata(&dssdev->dev, td);
1025
006db7b4
JN
1026 taal_hw_reset(dssdev);
1027
f133a9d7
TV
1028 /* if no platform set_backlight() defined, presume DSI backlight
1029 * control */
a19a6ee6 1030 memset(&props, 0, sizeof(struct backlight_properties));
8d3573c8 1031 if (!panel_data->set_backlight)
f133a9d7
TV
1032 td->use_dsi_bl = true;
1033
a19a6ee6
MG
1034 if (td->use_dsi_bl)
1035 props.max_brightness = 255;
1036 else
1037 props.max_brightness = 127;
bb7ca747
MG
1038
1039 props.type = BACKLIGHT_RAW;
634610ac
AT
1040 bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev,
1041 dssdev, &taal_bl_ops, &props);
f133a9d7
TV
1042 if (IS_ERR(bldev)) {
1043 r = PTR_ERR(bldev);
d2b65787 1044 goto err_bl;
f133a9d7
TV
1045 }
1046
1047 td->bldev = bldev;
1048
1049 bldev->props.fb_blank = FB_BLANK_UNBLANK;
1050 bldev->props.power = FB_BLANK_UNBLANK;
a19a6ee6 1051 if (td->use_dsi_bl)
f133a9d7 1052 bldev->props.brightness = 255;
a19a6ee6 1053 else
f133a9d7 1054 bldev->props.brightness = 127;
f133a9d7
TV
1055
1056 taal_bl_update_status(bldev);
1057
8d3573c8
TV
1058 if (panel_data->use_ext_te) {
1059 int gpio = panel_data->ext_te_gpio;
f133a9d7
TV
1060
1061 r = gpio_request(gpio, "taal irq");
1062 if (r) {
1063 dev_err(&dssdev->dev, "GPIO request failed\n");
d2b65787 1064 goto err_gpio;
f133a9d7
TV
1065 }
1066
1067 gpio_direction_input(gpio);
1068
1069 r = request_irq(gpio_to_irq(gpio), taal_te_isr,
f8798ccb 1070 IRQF_TRIGGER_RISING,
f133a9d7
TV
1071 "taal vsync", dssdev);
1072
1073 if (r) {
1074 dev_err(&dssdev->dev, "IRQ request failed\n");
1075 gpio_free(gpio);
d2b65787 1076 goto err_irq;
f133a9d7
TV
1077 }
1078
7ae2fb11
JN
1079 INIT_DELAYED_WORK_DEFERRABLE(&td->te_timeout_work,
1080 taal_te_timeout_work_callback);
f133a9d7 1081
7ae2fb11 1082 dev_dbg(&dssdev->dev, "Using GPIO TE\n");
f133a9d7
TV
1083 }
1084
bc6d4b1d
AT
1085 r = omap_dsi_request_vc(dssdev, &td->channel);
1086 if (r) {
1087 dev_err(&dssdev->dev, "failed to get virtual channel\n");
1088 goto err_req_vc;
1089 }
1090
1091 r = omap_dsi_set_vc_id(dssdev, td->channel, TCH);
1092 if (r) {
1093 dev_err(&dssdev->dev, "failed to set VC_ID\n");
1094 goto err_vc_id;
1095 }
1096
f133a9d7
TV
1097 r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group);
1098 if (r) {
1099 dev_err(&dssdev->dev, "failed to create sysfs files\n");
bc6d4b1d 1100 goto err_vc_id;
f133a9d7
TV
1101 }
1102
1103 return 0;
bc6d4b1d
AT
1104
1105err_vc_id:
1106 omap_dsi_release_vc(dssdev, td->channel);
1107err_req_vc:
8d3573c8
TV
1108 if (panel_data->use_ext_te)
1109 free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
d2b65787 1110err_irq:
8d3573c8
TV
1111 if (panel_data->use_ext_te)
1112 gpio_free(panel_data->ext_te_gpio);
d2b65787 1113err_gpio:
f133a9d7 1114 backlight_device_unregister(bldev);
d2b65787 1115err_bl:
883b9ac9 1116 destroy_workqueue(td->workqueue);
d2b65787 1117err_wq:
c8cd4547
TV
1118 free_regulators(panel_config->regulators, panel_config->num_regulators);
1119err_reg:
f133a9d7 1120 kfree(td);
d2b65787 1121err:
f133a9d7
TV
1122 return r;
1123}
1124
14e4d784 1125static void __exit taal_remove(struct omap_dss_device *dssdev)
f133a9d7
TV
1126{
1127 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
8d3573c8 1128 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
f133a9d7
TV
1129 struct backlight_device *bldev;
1130
1131 dev_dbg(&dssdev->dev, "remove\n");
1132
1133 sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
bc6d4b1d 1134 omap_dsi_release_vc(dssdev, td->channel);
f133a9d7 1135
8d3573c8
TV
1136 if (panel_data->use_ext_te) {
1137 int gpio = panel_data->ext_te_gpio;
f133a9d7
TV
1138 free_irq(gpio_to_irq(gpio), dssdev);
1139 gpio_free(gpio);
1140 }
1141
1142 bldev = td->bldev;
1143 bldev->props.power = FB_BLANK_POWERDOWN;
1144 taal_bl_update_status(bldev);
1145 backlight_device_unregister(bldev);
1146
1abf7814 1147 taal_cancel_ulps_work(dssdev);
1663d2f7 1148 taal_cancel_esd_work(dssdev);
883b9ac9 1149 destroy_workqueue(td->workqueue);
f133a9d7 1150
006db7b4
JN
1151 /* reset, to be sure that the panel is in a valid state */
1152 taal_hw_reset(dssdev);
1153
c8cd4547
TV
1154 free_regulators(td->panel_config->regulators,
1155 td->panel_config->num_regulators);
1156
f133a9d7
TV
1157 kfree(td);
1158}
1159
37ac60e4 1160static int taal_power_on(struct omap_dss_device *dssdev)
f133a9d7
TV
1161{
1162 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1163 u8 id1, id2, id3;
1164 int r;
1165
37ac60e4
TV
1166 r = omapdss_dsi_display_enable(dssdev);
1167 if (r) {
1168 dev_err(&dssdev->dev, "failed to enable DSI\n");
1169 goto err0;
1170 }
1171
006db7b4
JN
1172 taal_hw_reset(dssdev);
1173
1ffefe75 1174 omapdss_dsi_vc_enable_hs(dssdev, td->channel, false);
37ac60e4 1175
f133a9d7
TV
1176 r = taal_sleep_out(td);
1177 if (r)
1178 goto err;
1179
bc6d4b1d 1180 r = taal_get_id(td, &id1, &id2, &id3);
f133a9d7
TV
1181 if (r)
1182 goto err;
1183
1e8943db
JN
1184 /* on early Taal revisions CABC is broken */
1185 if (td->panel_config->type == PANEL_TAAL &&
1186 (id2 == 0x00 || id2 == 0xff || id2 == 0x81))
f133a9d7
TV
1187 td->cabc_broken = true;
1188
bc6d4b1d 1189 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff);
f2a8b75c
JN
1190 if (r)
1191 goto err;
f133a9d7 1192
bc6d4b1d 1193 r = taal_dcs_write_1(td, DCS_CTRL_DISPLAY,
f2a8b75c
JN
1194 (1<<2) | (1<<5)); /* BL | BCTRL */
1195 if (r)
1196 goto err;
f133a9d7 1197
bc6d4b1d 1198 r = taal_dcs_write_1(td, DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
f2a8b75c
JN
1199 if (r)
1200 goto err;
f133a9d7 1201
bc6d4b1d 1202 r = taal_set_addr_mode(td, td->rotate, td->mirror);
f2a8b75c
JN
1203 if (r)
1204 goto err;
1205
1206 if (!td->cabc_broken) {
bc6d4b1d 1207 r = taal_dcs_write_1(td, DCS_WRITE_CABC, td->cabc_mode);
f2a8b75c
JN
1208 if (r)
1209 goto err;
1210 }
1211
bc6d4b1d 1212 r = taal_dcs_write_0(td, DCS_DISPLAY_ON);
f2a8b75c
JN
1213 if (r)
1214 goto err;
f133a9d7 1215
21df20fc
TV
1216 r = _taal_enable_te(dssdev, td->te_enabled);
1217 if (r)
1218 goto err;
1219
f133a9d7
TV
1220 td->enabled = 1;
1221
1222 if (!td->intro_printed) {
0f45bddf
JN
1223 dev_info(&dssdev->dev, "%s panel revision %02x.%02x.%02x\n",
1224 td->panel_config->name, id1, id2, id3);
f133a9d7
TV
1225 if (td->cabc_broken)
1226 dev_info(&dssdev->dev,
1227 "old Taal version, CABC disabled\n");
1228 td->intro_printed = true;
1229 }
1230
1ffefe75 1231 omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
37ac60e4 1232
f133a9d7
TV
1233 return 0;
1234err:
006db7b4
JN
1235 dev_err(&dssdev->dev, "error while enabling panel, issuing HW reset\n");
1236
1237 taal_hw_reset(dssdev);
1238
22d6d676 1239 omapdss_dsi_display_disable(dssdev, true, false);
37ac60e4 1240err0:
f133a9d7
TV
1241 return r;
1242}
1243
37ac60e4 1244static void taal_power_off(struct omap_dss_device *dssdev)
f133a9d7
TV
1245{
1246 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
006db7b4 1247 int r;
f133a9d7 1248
bc6d4b1d 1249 r = taal_dcs_write_0(td, DCS_DISPLAY_OFF);
15ffa1da 1250 if (!r)
006db7b4 1251 r = taal_sleep_in(td);
f133a9d7 1252
006db7b4
JN
1253 if (r) {
1254 dev_err(&dssdev->dev,
1255 "error disabling panel, issuing HW reset\n");
1256 taal_hw_reset(dssdev);
1257 }
f133a9d7 1258
22d6d676 1259 omapdss_dsi_display_disable(dssdev, true, false);
37ac60e4 1260
f133a9d7 1261 td->enabled = 0;
37ac60e4
TV
1262}
1263
bb5476c7
TV
1264static int taal_panel_reset(struct omap_dss_device *dssdev)
1265{
1266 dev_err(&dssdev->dev, "performing LCD reset\n");
1267
1268 taal_power_off(dssdev);
1269 taal_hw_reset(dssdev);
1270 return taal_power_on(dssdev);
1271}
1272
37ac60e4
TV
1273static int taal_enable(struct omap_dss_device *dssdev)
1274{
a3201a0e 1275 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
37ac60e4 1276 int r;
a3201a0e 1277
37ac60e4
TV
1278 dev_dbg(&dssdev->dev, "enable\n");
1279
a3201a0e
TV
1280 mutex_lock(&td->lock);
1281
1282 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
1283 r = -EINVAL;
1284 goto err;
1285 }
37ac60e4 1286
1ffefe75 1287 dsi_bus_lock(dssdev);
2c2fc151 1288
37ac60e4 1289 r = taal_power_on(dssdev);
2c2fc151 1290
1ffefe75 1291 dsi_bus_unlock(dssdev);
2c2fc151 1292
37ac60e4 1293 if (r)
a3201a0e 1294 goto err;
37ac60e4 1295
1663d2f7 1296 taal_queue_esd_work(dssdev);
4571a023 1297
37ac60e4
TV
1298 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
1299
a3201a0e
TV
1300 mutex_unlock(&td->lock);
1301
1302 return 0;
1303err:
1304 dev_dbg(&dssdev->dev, "enable failed\n");
1305 mutex_unlock(&td->lock);
37ac60e4
TV
1306 return r;
1307}
1308
1309static void taal_disable(struct omap_dss_device *dssdev)
1310{
a3201a0e
TV
1311 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1312
37ac60e4
TV
1313 dev_dbg(&dssdev->dev, "disable\n");
1314
a3201a0e
TV
1315 mutex_lock(&td->lock);
1316
1abf7814 1317 taal_cancel_ulps_work(dssdev);
1663d2f7 1318 taal_cancel_esd_work(dssdev);
4571a023 1319
1ffefe75 1320 dsi_bus_lock(dssdev);
2c2fc151 1321
1abf7814 1322 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
e8945677
TV
1323 int r;
1324
1325 r = taal_wake_up(dssdev);
1326 if (!r)
1327 taal_power_off(dssdev);
1abf7814 1328 }
37ac60e4 1329
1ffefe75 1330 dsi_bus_unlock(dssdev);
2c2fc151 1331
37ac60e4 1332 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
a3201a0e
TV
1333
1334 mutex_unlock(&td->lock);
f133a9d7
TV
1335}
1336
1337static int taal_suspend(struct omap_dss_device *dssdev)
1338{
a3201a0e
TV
1339 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1340 int r;
1341
37ac60e4 1342 dev_dbg(&dssdev->dev, "suspend\n");
f133a9d7 1343
a3201a0e
TV
1344 mutex_lock(&td->lock);
1345
1346 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
1347 r = -EINVAL;
1348 goto err;
1349 }
37ac60e4 1350
1abf7814 1351 taal_cancel_ulps_work(dssdev);
1663d2f7 1352 taal_cancel_esd_work(dssdev);
4571a023 1353
1ffefe75 1354 dsi_bus_lock(dssdev);
2c2fc151 1355
1abf7814
TV
1356 r = taal_wake_up(dssdev);
1357 if (!r)
1358 taal_power_off(dssdev);
2c2fc151 1359
1ffefe75 1360 dsi_bus_unlock(dssdev);
2c2fc151 1361
37ac60e4 1362 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
f133a9d7 1363
a3201a0e
TV
1364 mutex_unlock(&td->lock);
1365
f133a9d7 1366 return 0;
a3201a0e
TV
1367err:
1368 mutex_unlock(&td->lock);
1369 return r;
f133a9d7
TV
1370}
1371
1372static int taal_resume(struct omap_dss_device *dssdev)
1373{
a3201a0e 1374 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
37ac60e4 1375 int r;
a3201a0e 1376
37ac60e4 1377 dev_dbg(&dssdev->dev, "resume\n");
f133a9d7 1378
a3201a0e
TV
1379 mutex_lock(&td->lock);
1380
1381 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
1382 r = -EINVAL;
1383 goto err;
1384 }
f133a9d7 1385
1ffefe75 1386 dsi_bus_lock(dssdev);
2c2fc151 1387
37ac60e4 1388 r = taal_power_on(dssdev);
2c2fc151 1389
1ffefe75 1390 dsi_bus_unlock(dssdev);
2c2fc151 1391
4571a023 1392 if (r) {
fed44b7a 1393 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
4571a023 1394 } else {
fed44b7a 1395 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
1663d2f7 1396 taal_queue_esd_work(dssdev);
4571a023 1397 }
a3201a0e
TV
1398
1399 mutex_unlock(&td->lock);
1400
1401 return r;
1402err:
1403 mutex_unlock(&td->lock);
37ac60e4 1404 return r;
f133a9d7
TV
1405}
1406
18946f62
TV
1407static void taal_framedone_cb(int err, void *data)
1408{
1409 struct omap_dss_device *dssdev = data;
1410 dev_dbg(&dssdev->dev, "framedone, err %d\n", err);
1ffefe75 1411 dsi_bus_unlock(dssdev);
18946f62
TV
1412}
1413
7ae2fb11
JN
1414static irqreturn_t taal_te_isr(int irq, void *data)
1415{
1416 struct omap_dss_device *dssdev = data;
1417 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1418 int old;
1419 int r;
1420
1421 old = atomic_cmpxchg(&td->do_update, 1, 0);
1422
1423 if (old) {
1424 cancel_delayed_work(&td->te_timeout_work);
1425
bc6d4b1d 1426 r = omap_dsi_update(dssdev, td->channel,
7ae2fb11
JN
1427 td->update_region.x,
1428 td->update_region.y,
1429 td->update_region.w,
1430 td->update_region.h,
1431 taal_framedone_cb, dssdev);
1432 if (r)
1433 goto err;
1434 }
1435
1436 return IRQ_HANDLED;
1437err:
1438 dev_err(&dssdev->dev, "start update failed\n");
1ffefe75 1439 dsi_bus_unlock(dssdev);
7ae2fb11
JN
1440 return IRQ_HANDLED;
1441}
1442
1443static void taal_te_timeout_work_callback(struct work_struct *work)
1444{
1445 struct taal_data *td = container_of(work, struct taal_data,
1446 te_timeout_work.work);
1447 struct omap_dss_device *dssdev = td->dssdev;
1448
1449 dev_err(&dssdev->dev, "TE not received for 250ms!\n");
1450
1451 atomic_set(&td->do_update, 0);
1ffefe75 1452 dsi_bus_unlock(dssdev);
7ae2fb11
JN
1453}
1454
18946f62 1455static int taal_update(struct omap_dss_device *dssdev,
f133a9d7
TV
1456 u16 x, u16 y, u16 w, u16 h)
1457{
18946f62 1458 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
8d3573c8 1459 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
18946f62
TV
1460 int r;
1461
1462 dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
1463
a3201a0e 1464 mutex_lock(&td->lock);
1ffefe75 1465 dsi_bus_lock(dssdev);
18946f62 1466
1abf7814
TV
1467 r = taal_wake_up(dssdev);
1468 if (r)
1469 goto err;
1470
18946f62
TV
1471 if (!td->enabled) {
1472 r = 0;
1473 goto err;
1474 }
1475
26a8c250 1476 r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h, true);
18946f62
TV
1477 if (r)
1478 goto err;
1479
bc6d4b1d 1480 r = taal_set_update_window(td, x, y, w, h);
18946f62
TV
1481 if (r)
1482 goto err;
1483
8d3573c8 1484 if (td->te_enabled && panel_data->use_ext_te) {
7ae2fb11
JN
1485 td->update_region.x = x;
1486 td->update_region.y = y;
1487 td->update_region.w = w;
1488 td->update_region.h = h;
1489 barrier();
1490 schedule_delayed_work(&td->te_timeout_work,
1491 msecs_to_jiffies(250));
1492 atomic_set(&td->do_update, 1);
1493 } else {
bc6d4b1d 1494 r = omap_dsi_update(dssdev, td->channel, x, y, w, h,
7ae2fb11
JN
1495 taal_framedone_cb, dssdev);
1496 if (r)
1497 goto err;
1498 }
18946f62
TV
1499
1500 /* note: no bus_unlock here. unlock is in framedone_cb */
a3201a0e 1501 mutex_unlock(&td->lock);
18946f62
TV
1502 return 0;
1503err:
1ffefe75 1504 dsi_bus_unlock(dssdev);
a3201a0e 1505 mutex_unlock(&td->lock);
18946f62
TV
1506 return r;
1507}
1508
1509static int taal_sync(struct omap_dss_device *dssdev)
1510{
a3201a0e
TV
1511 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1512
18946f62
TV
1513 dev_dbg(&dssdev->dev, "sync\n");
1514
a3201a0e 1515 mutex_lock(&td->lock);
1ffefe75
AT
1516 dsi_bus_lock(dssdev);
1517 dsi_bus_unlock(dssdev);
a3201a0e 1518 mutex_unlock(&td->lock);
18946f62
TV
1519
1520 dev_dbg(&dssdev->dev, "sync done\n");
1521
1522 return 0;
f133a9d7
TV
1523}
1524
21df20fc 1525static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
f133a9d7 1526{
e7f6c3f2 1527 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
8d3573c8 1528 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
f133a9d7
TV
1529 int r;
1530
f133a9d7 1531 if (enable)
bc6d4b1d 1532 r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
f133a9d7 1533 else
bc6d4b1d 1534 r = taal_dcs_write_0(td, DCS_TEAR_OFF);
f133a9d7 1535
8d3573c8 1536 if (!panel_data->use_ext_te)
7ae2fb11 1537 omapdss_dsi_enable_te(dssdev, enable);
225b650d 1538
e7f6c3f2
JN
1539 if (td->panel_config->sleep.enable_te)
1540 msleep(td->panel_config->sleep.enable_te);
225b650d 1541
21df20fc
TV
1542 return r;
1543}
1544
1545static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1546{
a3201a0e 1547 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
21df20fc
TV
1548 int r;
1549
a3201a0e 1550 mutex_lock(&td->lock);
ffb63c95
TV
1551
1552 if (td->te_enabled == enable)
1553 goto end;
1554
1ffefe75 1555 dsi_bus_lock(dssdev);
21df20fc 1556
ee52c0ae 1557 if (td->enabled) {
1abf7814
TV
1558 r = taal_wake_up(dssdev);
1559 if (r)
1560 goto err;
1561
ee52c0ae
JN
1562 r = _taal_enable_te(dssdev, enable);
1563 if (r)
1564 goto err;
1565 }
1566
1567 td->te_enabled = enable;
21df20fc 1568
1ffefe75 1569 dsi_bus_unlock(dssdev);
ffb63c95 1570end:
a3201a0e 1571 mutex_unlock(&td->lock);
225b650d 1572
ee52c0ae
JN
1573 return 0;
1574err:
1ffefe75 1575 dsi_bus_unlock(dssdev);
ee52c0ae
JN
1576 mutex_unlock(&td->lock);
1577
f133a9d7
TV
1578 return r;
1579}
1580
225b650d
TV
1581static int taal_get_te(struct omap_dss_device *dssdev)
1582{
1583 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
a3201a0e
TV
1584 int r;
1585
1586 mutex_lock(&td->lock);
1587 r = td->te_enabled;
1588 mutex_unlock(&td->lock);
1589
1590 return r;
225b650d
TV
1591}
1592
f133a9d7
TV
1593static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
1594{
1595 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1596 int r;
1597
1598 dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
1599
a3201a0e 1600 mutex_lock(&td->lock);
ffb63c95
TV
1601
1602 if (td->rotate == rotate)
1603 goto end;
1604
1ffefe75 1605 dsi_bus_lock(dssdev);
87424e1b 1606
f133a9d7 1607 if (td->enabled) {
1abf7814
TV
1608 r = taal_wake_up(dssdev);
1609 if (r)
1610 goto err;
1611
bc6d4b1d 1612 r = taal_set_addr_mode(td, rotate, td->mirror);
f133a9d7 1613 if (r)
87424e1b 1614 goto err;
f133a9d7
TV
1615 }
1616
1617 td->rotate = rotate;
1618
1ffefe75 1619 dsi_bus_unlock(dssdev);
ffb63c95 1620end:
a3201a0e 1621 mutex_unlock(&td->lock);
f133a9d7 1622 return 0;
87424e1b 1623err:
1ffefe75 1624 dsi_bus_unlock(dssdev);
a3201a0e 1625 mutex_unlock(&td->lock);
87424e1b 1626 return r;
f133a9d7
TV
1627}
1628
1629static u8 taal_get_rotate(struct omap_dss_device *dssdev)
1630{
1631 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
a3201a0e
TV
1632 int r;
1633
1634 mutex_lock(&td->lock);
1635 r = td->rotate;
1636 mutex_unlock(&td->lock);
1637
1638 return r;
f133a9d7
TV
1639}
1640
1641static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
1642{
1643 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1644 int r;
1645
1646 dev_dbg(&dssdev->dev, "mirror %d\n", enable);
1647
a3201a0e 1648 mutex_lock(&td->lock);
ffb63c95
TV
1649
1650 if (td->mirror == enable)
1651 goto end;
1652
1ffefe75 1653 dsi_bus_lock(dssdev);
f133a9d7 1654 if (td->enabled) {
1abf7814
TV
1655 r = taal_wake_up(dssdev);
1656 if (r)
1657 goto err;
1658
bc6d4b1d 1659 r = taal_set_addr_mode(td, td->rotate, enable);
f133a9d7 1660 if (r)
8d8aa61d 1661 goto err;
f133a9d7
TV
1662 }
1663
1664 td->mirror = enable;
1665
1ffefe75 1666 dsi_bus_unlock(dssdev);
ffb63c95 1667end:
a3201a0e 1668 mutex_unlock(&td->lock);
f133a9d7 1669 return 0;
8d8aa61d 1670err:
1ffefe75 1671 dsi_bus_unlock(dssdev);
a3201a0e 1672 mutex_unlock(&td->lock);
8d8aa61d 1673 return r;
f133a9d7
TV
1674}
1675
1676static bool taal_get_mirror(struct omap_dss_device *dssdev)
1677{
1678 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
a3201a0e
TV
1679 int r;
1680
1681 mutex_lock(&td->lock);
1682 r = td->mirror;
1683 mutex_unlock(&td->lock);
1684
1685 return r;
f133a9d7
TV
1686}
1687
1688static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1689{
a3201a0e 1690 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
f133a9d7
TV
1691 u8 id1, id2, id3;
1692 int r;
1693
a3201a0e 1694 mutex_lock(&td->lock);
ee52c0ae
JN
1695
1696 if (!td->enabled) {
1697 r = -ENODEV;
1698 goto err1;
1699 }
1700
1ffefe75 1701 dsi_bus_lock(dssdev);
1a75ef42 1702
1abf7814
TV
1703 r = taal_wake_up(dssdev);
1704 if (r)
1705 goto err2;
1706
bc6d4b1d 1707 r = taal_dcs_read_1(td, DCS_GET_ID1, &id1);
f133a9d7 1708 if (r)
ee52c0ae 1709 goto err2;
bc6d4b1d 1710 r = taal_dcs_read_1(td, DCS_GET_ID2, &id2);
f133a9d7 1711 if (r)
ee52c0ae 1712 goto err2;
bc6d4b1d 1713 r = taal_dcs_read_1(td, DCS_GET_ID3, &id3);
f133a9d7 1714 if (r)
ee52c0ae 1715 goto err2;
f133a9d7 1716
1ffefe75 1717 dsi_bus_unlock(dssdev);
a3201a0e 1718 mutex_unlock(&td->lock);
f133a9d7 1719 return 0;
ee52c0ae 1720err2:
1ffefe75 1721 dsi_bus_unlock(dssdev);
ee52c0ae 1722err1:
a3201a0e 1723 mutex_unlock(&td->lock);
1a75ef42 1724 return r;
f133a9d7
TV
1725}
1726
1727static int taal_memory_read(struct omap_dss_device *dssdev,
1728 void *buf, size_t size,
1729 u16 x, u16 y, u16 w, u16 h)
1730{
1731 int r;
1732 int first = 1;
1733 int plen;
1734 unsigned buf_used = 0;
c75d9464
TV
1735 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1736
f133a9d7
TV
1737 if (size < w * h * 3)
1738 return -ENOMEM;
1739
a3201a0e
TV
1740 mutex_lock(&td->lock);
1741
1742 if (!td->enabled) {
1743 r = -ENODEV;
1744 goto err1;
1745 }
1746
f133a9d7
TV
1747 size = min(w * h * 3,
1748 dssdev->panel.timings.x_res *
1749 dssdev->panel.timings.y_res * 3);
1750
1ffefe75 1751 dsi_bus_lock(dssdev);
c75d9464 1752
1abf7814
TV
1753 r = taal_wake_up(dssdev);
1754 if (r)
1755 goto err2;
1756
f133a9d7
TV
1757 /* plen 1 or 2 goes into short packet. until checksum error is fixed,
1758 * use short packets. plen 32 works, but bigger packets seem to cause
1759 * an error. */
1760 if (size % 2)
1761 plen = 1;
1762 else
1763 plen = 2;
1764
bc6d4b1d 1765 taal_set_update_window(td, x, y, w, h);
f133a9d7 1766
1ffefe75 1767 r = dsi_vc_set_max_rx_packet_size(dssdev, td->channel, plen);
f133a9d7 1768 if (r)
a3201a0e 1769 goto err2;
f133a9d7
TV
1770
1771 while (buf_used < size) {
1772 u8 dcs_cmd = first ? 0x2e : 0x3e;
1773 first = 0;
1774
1ffefe75 1775 r = dsi_vc_dcs_read(dssdev, td->channel, dcs_cmd,
f133a9d7
TV
1776 buf + buf_used, size - buf_used);
1777
1778 if (r < 0) {
1779 dev_err(&dssdev->dev, "read error\n");
a3201a0e 1780 goto err3;
f133a9d7
TV
1781 }
1782
1783 buf_used += r;
1784
1785 if (r < plen) {
1786 dev_err(&dssdev->dev, "short read\n");
1787 break;
1788 }
1789
1790 if (signal_pending(current)) {
1791 dev_err(&dssdev->dev, "signal pending, "
1792 "aborting memory read\n");
1793 r = -ERESTARTSYS;
a3201a0e 1794 goto err3;
f133a9d7
TV
1795 }
1796 }
1797
1798 r = buf_used;
1799
a3201a0e 1800err3:
1ffefe75 1801 dsi_vc_set_max_rx_packet_size(dssdev, td->channel, 1);
a3201a0e 1802err2:
1ffefe75 1803 dsi_bus_unlock(dssdev);
a3201a0e
TV
1804err1:
1805 mutex_unlock(&td->lock);
f133a9d7
TV
1806 return r;
1807}
1808
1abf7814
TV
1809static void taal_ulps_work(struct work_struct *work)
1810{
1811 struct taal_data *td = container_of(work, struct taal_data,
1812 ulps_work.work);
1813 struct omap_dss_device *dssdev = td->dssdev;
1814
1815 mutex_lock(&td->lock);
1816
1817 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || !td->enabled) {
1818 mutex_unlock(&td->lock);
1819 return;
1820 }
1821
1ffefe75 1822 dsi_bus_lock(dssdev);
1abf7814
TV
1823
1824 taal_enter_ulps(dssdev);
1825
1ffefe75 1826 dsi_bus_unlock(dssdev);
1abf7814
TV
1827 mutex_unlock(&td->lock);
1828}
1829
f133a9d7
TV
1830static void taal_esd_work(struct work_struct *work)
1831{
1832 struct taal_data *td = container_of(work, struct taal_data,
1833 esd_work.work);
1834 struct omap_dss_device *dssdev = td->dssdev;
8d3573c8 1835 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
f133a9d7
TV
1836 u8 state1, state2;
1837 int r;
1838
a3201a0e
TV
1839 mutex_lock(&td->lock);
1840
1841 if (!td->enabled) {
1842 mutex_unlock(&td->lock);
f133a9d7 1843 return;
a3201a0e 1844 }
f133a9d7 1845
1ffefe75 1846 dsi_bus_lock(dssdev);
f133a9d7 1847
1abf7814
TV
1848 r = taal_wake_up(dssdev);
1849 if (r) {
1850 dev_err(&dssdev->dev, "failed to exit ULPS\n");
1851 goto err;
1852 }
1853
bc6d4b1d 1854 r = taal_dcs_read_1(td, DCS_RDDSDR, &state1);
f133a9d7
TV
1855 if (r) {
1856 dev_err(&dssdev->dev, "failed to read Taal status\n");
1857 goto err;
1858 }
1859
1860 /* Run self diagnostics */
1861 r = taal_sleep_out(td);
1862 if (r) {
1863 dev_err(&dssdev->dev, "failed to run Taal self-diagnostics\n");
1864 goto err;
1865 }
1866
bc6d4b1d 1867 r = taal_dcs_read_1(td, DCS_RDDSDR, &state2);
f133a9d7
TV
1868 if (r) {
1869 dev_err(&dssdev->dev, "failed to read Taal status\n");
1870 goto err;
1871 }
1872
1873 /* Each sleep out command will trigger a self diagnostic and flip
1874 * Bit6 if the test passes.
1875 */
1876 if (!((state1 ^ state2) & (1 << 6))) {
1877 dev_err(&dssdev->dev, "LCD self diagnostics failed\n");
1878 goto err;
1879 }
1880 /* Self-diagnostics result is also shown on TE GPIO line. We need
1881 * to re-enable TE after self diagnostics */
8d3573c8 1882 if (td->te_enabled && panel_data->use_ext_te) {
bc6d4b1d 1883 r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
1189b7ff
TV
1884 if (r)
1885 goto err;
1886 }
f133a9d7 1887
1ffefe75 1888 dsi_bus_unlock(dssdev);
f133a9d7 1889
1663d2f7 1890 taal_queue_esd_work(dssdev);
f133a9d7 1891
a3201a0e 1892 mutex_unlock(&td->lock);
f133a9d7
TV
1893 return;
1894err:
1895 dev_err(&dssdev->dev, "performing LCD reset\n");
1896
bb5476c7 1897 taal_panel_reset(dssdev);
f133a9d7 1898
1ffefe75 1899 dsi_bus_unlock(dssdev);
f133a9d7 1900
1663d2f7 1901 taal_queue_esd_work(dssdev);
a3201a0e
TV
1902
1903 mutex_unlock(&td->lock);
f133a9d7
TV
1904}
1905
1906static struct omap_dss_driver taal_driver = {
1907 .probe = taal_probe,
14e4d784 1908 .remove = __exit_p(taal_remove),
f133a9d7
TV
1909
1910 .enable = taal_enable,
1911 .disable = taal_disable,
1912 .suspend = taal_suspend,
1913 .resume = taal_resume,
1914
18946f62
TV
1915 .update = taal_update,
1916 .sync = taal_sync,
1917
96adcece 1918 .get_resolution = taal_get_resolution,
a2699504
TV
1919 .get_recommended_bpp = omapdss_default_get_recommended_bpp,
1920
f133a9d7 1921 .enable_te = taal_enable_te,
225b650d 1922 .get_te = taal_get_te,
225b650d 1923
f133a9d7
TV
1924 .set_rotate = taal_rotate,
1925 .get_rotate = taal_get_rotate,
1926 .set_mirror = taal_mirror,
1927 .get_mirror = taal_get_mirror,
1928 .run_test = taal_run_test,
1929 .memory_read = taal_memory_read,
1930
69b2048f
TV
1931 .get_timings = taal_get_timings,
1932
f133a9d7
TV
1933 .driver = {
1934 .name = "taal",
1935 .owner = THIS_MODULE,
1936 },
1937};
1938
1939static int __init taal_init(void)
1940{
1941 omap_dss_register_driver(&taal_driver);
1942
1943 return 0;
1944}
1945
1946static void __exit taal_exit(void)
1947{
1948 omap_dss_unregister_driver(&taal_driver);
1949}
1950
1951module_init(taal_init);
1952module_exit(taal_exit);
1953
1954MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
1955MODULE_DESCRIPTION("Taal Driver");
1956MODULE_LICENSE("GPL");