- patches.suse/slab-handle-memoryless-nodes-v2a.patch: Refresh.
[linux-flexiantxendom0-3.2.10.git] / drivers / video / omap2 / displays / panel-taal.c
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>
31 #include <linux/completion.h>
32 #include <linux/workqueue.h>
33
34 #include <plat/display.h>
35
36 /* DSI Virtual channel. Hardcoded for now. */
37 #define TCH 0
38
39 #define DCS_READ_NUM_ERRORS     0x05
40 #define DCS_READ_POWER_MODE     0x0a
41 #define DCS_READ_MADCTL         0x0b
42 #define DCS_READ_PIXEL_FORMAT   0x0c
43 #define DCS_RDDSDR              0x0f
44 #define DCS_SLEEP_IN            0x10
45 #define DCS_SLEEP_OUT           0x11
46 #define DCS_DISPLAY_OFF         0x28
47 #define DCS_DISPLAY_ON          0x29
48 #define DCS_COLUMN_ADDR         0x2a
49 #define DCS_PAGE_ADDR           0x2b
50 #define DCS_MEMORY_WRITE        0x2c
51 #define DCS_TEAR_OFF            0x34
52 #define DCS_TEAR_ON             0x35
53 #define DCS_MEM_ACC_CTRL        0x36
54 #define DCS_PIXEL_FORMAT        0x3a
55 #define DCS_BRIGHTNESS          0x51
56 #define DCS_CTRL_DISPLAY        0x53
57 #define DCS_WRITE_CABC          0x55
58 #define DCS_READ_CABC           0x56
59 #define DCS_GET_ID1             0xda
60 #define DCS_GET_ID2             0xdb
61 #define DCS_GET_ID3             0xdc
62
63 /* #define TAAL_USE_ESD_CHECK */
64 #define TAAL_ESD_CHECK_PERIOD   msecs_to_jiffies(5000)
65
66 struct taal_data {
67         struct backlight_device *bldev;
68
69         unsigned long   hw_guard_end;   /* next value of jiffies when we can
70                                          * issue the next sleep in/out command
71                                          */
72         unsigned long   hw_guard_wait;  /* max guard time in jiffies */
73
74         struct omap_dss_device *dssdev;
75
76         bool enabled;
77         u8 rotate;
78         bool mirror;
79
80         bool te_enabled;
81         bool use_ext_te;
82         struct completion te_completion;
83
84         bool use_dsi_bl;
85
86         bool cabc_broken;
87         unsigned cabc_mode;
88
89         bool intro_printed;
90
91         struct workqueue_struct *esd_wq;
92         struct delayed_work esd_work;
93 };
94
95 static void taal_esd_work(struct work_struct *work);
96
97 static void hw_guard_start(struct taal_data *td, int guard_msec)
98 {
99         td->hw_guard_wait = msecs_to_jiffies(guard_msec);
100         td->hw_guard_end = jiffies + td->hw_guard_wait;
101 }
102
103 static void hw_guard_wait(struct taal_data *td)
104 {
105         unsigned long wait = td->hw_guard_end - jiffies;
106
107         if ((long)wait > 0 && wait <= td->hw_guard_wait) {
108                 set_current_state(TASK_UNINTERRUPTIBLE);
109                 schedule_timeout(wait);
110         }
111 }
112
113 static int taal_dcs_read_1(u8 dcs_cmd, u8 *data)
114 {
115         int r;
116         u8 buf[1];
117
118         r = dsi_vc_dcs_read(TCH, dcs_cmd, buf, 1);
119
120         if (r < 0)
121                 return r;
122
123         *data = buf[0];
124
125         return 0;
126 }
127
128 static int taal_dcs_write_0(u8 dcs_cmd)
129 {
130         return dsi_vc_dcs_write(TCH, &dcs_cmd, 1);
131 }
132
133 static int taal_dcs_write_1(u8 dcs_cmd, u8 param)
134 {
135         u8 buf[2];
136         buf[0] = dcs_cmd;
137         buf[1] = param;
138         return dsi_vc_dcs_write(TCH, buf, 2);
139 }
140
141 static int taal_sleep_in(struct taal_data *td)
142
143 {
144         u8 cmd;
145         int r;
146
147         hw_guard_wait(td);
148
149         cmd = DCS_SLEEP_IN;
150         r = dsi_vc_dcs_write_nosync(TCH, &cmd, 1);
151         if (r)
152                 return r;
153
154         hw_guard_start(td, 120);
155
156         msleep(5);
157
158         return 0;
159 }
160
161 static int taal_sleep_out(struct taal_data *td)
162 {
163         int r;
164
165         hw_guard_wait(td);
166
167         r = taal_dcs_write_0(DCS_SLEEP_OUT);
168         if (r)
169                 return r;
170
171         hw_guard_start(td, 120);
172
173         msleep(5);
174
175         return 0;
176 }
177
178 static int taal_get_id(u8 *id1, u8 *id2, u8 *id3)
179 {
180         int r;
181
182         r = taal_dcs_read_1(DCS_GET_ID1, id1);
183         if (r)
184                 return r;
185         r = taal_dcs_read_1(DCS_GET_ID2, id2);
186         if (r)
187                 return r;
188         r = taal_dcs_read_1(DCS_GET_ID3, id3);
189         if (r)
190                 return r;
191
192         return 0;
193 }
194
195 static int taal_set_addr_mode(u8 rotate, bool mirror)
196 {
197         int r;
198         u8 mode;
199         int b5, b6, b7;
200
201         r = taal_dcs_read_1(DCS_READ_MADCTL, &mode);
202         if (r)
203                 return r;
204
205         switch (rotate) {
206         default:
207         case 0:
208                 b7 = 0;
209                 b6 = 0;
210                 b5 = 0;
211                 break;
212         case 1:
213                 b7 = 0;
214                 b6 = 1;
215                 b5 = 1;
216                 break;
217         case 2:
218                 b7 = 1;
219                 b6 = 1;
220                 b5 = 0;
221                 break;
222         case 3:
223                 b7 = 1;
224                 b6 = 0;
225                 b5 = 1;
226                 break;
227         }
228
229         if (mirror)
230                 b6 = !b6;
231
232         mode &= ~((1<<7) | (1<<6) | (1<<5));
233         mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
234
235         return taal_dcs_write_1(DCS_MEM_ACC_CTRL, mode);
236 }
237
238 static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h)
239 {
240         int r;
241         u16 x1 = x;
242         u16 x2 = x + w - 1;
243         u16 y1 = y;
244         u16 y2 = y + h - 1;
245
246         u8 buf[5];
247         buf[0] = DCS_COLUMN_ADDR;
248         buf[1] = (x1 >> 8) & 0xff;
249         buf[2] = (x1 >> 0) & 0xff;
250         buf[3] = (x2 >> 8) & 0xff;
251         buf[4] = (x2 >> 0) & 0xff;
252
253         r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf));
254         if (r)
255                 return r;
256
257         buf[0] = DCS_PAGE_ADDR;
258         buf[1] = (y1 >> 8) & 0xff;
259         buf[2] = (y1 >> 0) & 0xff;
260         buf[3] = (y2 >> 8) & 0xff;
261         buf[4] = (y2 >> 0) & 0xff;
262
263         r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf));
264         if (r)
265                 return r;
266
267         dsi_vc_send_bta_sync(TCH);
268
269         return r;
270 }
271
272 static int taal_bl_update_status(struct backlight_device *dev)
273 {
274         struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
275         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
276         int r;
277         int level;
278
279         if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
280                         dev->props.power == FB_BLANK_UNBLANK)
281                 level = dev->props.brightness;
282         else
283                 level = 0;
284
285         dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
286
287         if (td->use_dsi_bl) {
288                 if (td->enabled) {
289                         dsi_bus_lock();
290                         r = taal_dcs_write_1(DCS_BRIGHTNESS, level);
291                         dsi_bus_unlock();
292                         if (r)
293                                 return r;
294                 }
295         } else {
296                 if (!dssdev->set_backlight)
297                         return -EINVAL;
298
299                 r = dssdev->set_backlight(dssdev, level);
300                 if (r)
301                         return r;
302         }
303
304         return 0;
305 }
306
307 static int taal_bl_get_intensity(struct backlight_device *dev)
308 {
309         if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
310                         dev->props.power == FB_BLANK_UNBLANK)
311                 return dev->props.brightness;
312
313         return 0;
314 }
315
316 static struct backlight_ops taal_bl_ops = {
317         .get_brightness = taal_bl_get_intensity,
318         .update_status  = taal_bl_update_status,
319 };
320
321 static void taal_get_timings(struct omap_dss_device *dssdev,
322                         struct omap_video_timings *timings)
323 {
324         *timings = dssdev->panel.timings;
325 }
326
327 static void taal_get_resolution(struct omap_dss_device *dssdev,
328                 u16 *xres, u16 *yres)
329 {
330         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
331
332         if (td->rotate == 0 || td->rotate == 2) {
333                 *xres = dssdev->panel.timings.x_res;
334                 *yres = dssdev->panel.timings.y_res;
335         } else {
336                 *yres = dssdev->panel.timings.x_res;
337                 *xres = dssdev->panel.timings.y_res;
338         }
339 }
340
341 static irqreturn_t taal_te_isr(int irq, void *data)
342 {
343         struct omap_dss_device *dssdev = data;
344         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
345
346         complete_all(&td->te_completion);
347
348         return IRQ_HANDLED;
349 }
350
351 static ssize_t taal_num_errors_show(struct device *dev,
352                 struct device_attribute *attr, char *buf)
353 {
354         struct omap_dss_device *dssdev = to_dss_device(dev);
355         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
356         u8 errors;
357         int r;
358
359         if (td->enabled) {
360                 dsi_bus_lock();
361                 r = taal_dcs_read_1(DCS_READ_NUM_ERRORS, &errors);
362                 dsi_bus_unlock();
363         } else {
364                 r = -ENODEV;
365         }
366
367         if (r)
368                 return r;
369
370         return snprintf(buf, PAGE_SIZE, "%d\n", errors);
371 }
372
373 static ssize_t taal_hw_revision_show(struct device *dev,
374                 struct device_attribute *attr, char *buf)
375 {
376         struct omap_dss_device *dssdev = to_dss_device(dev);
377         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
378         u8 id1, id2, id3;
379         int r;
380
381         if (td->enabled) {
382                 dsi_bus_lock();
383                 r = taal_get_id(&id1, &id2, &id3);
384                 dsi_bus_unlock();
385         } else {
386                 r = -ENODEV;
387         }
388
389         if (r)
390                 return r;
391
392         return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3);
393 }
394
395 static const char *cabc_modes[] = {
396         "off",          /* used also always when CABC is not supported */
397         "ui",
398         "still-image",
399         "moving-image",
400 };
401
402 static ssize_t show_cabc_mode(struct device *dev,
403                 struct device_attribute *attr,
404                 char *buf)
405 {
406         struct omap_dss_device *dssdev = to_dss_device(dev);
407         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
408         const char *mode_str;
409         int mode;
410         int len;
411
412         mode = td->cabc_mode;
413
414         mode_str = "unknown";
415         if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes))
416                 mode_str = cabc_modes[mode];
417         len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str);
418
419         return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1;
420 }
421
422 static ssize_t store_cabc_mode(struct device *dev,
423                 struct device_attribute *attr,
424                 const char *buf, size_t count)
425 {
426         struct omap_dss_device *dssdev = to_dss_device(dev);
427         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
428         int i;
429
430         for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) {
431                 if (sysfs_streq(cabc_modes[i], buf))
432                         break;
433         }
434
435         if (i == ARRAY_SIZE(cabc_modes))
436                 return -EINVAL;
437
438         if (td->enabled) {
439                 dsi_bus_lock();
440                 if (!td->cabc_broken)
441                         taal_dcs_write_1(DCS_WRITE_CABC, i);
442                 dsi_bus_unlock();
443         }
444
445         td->cabc_mode = i;
446
447         return count;
448 }
449
450 static ssize_t show_cabc_available_modes(struct device *dev,
451                 struct device_attribute *attr,
452                 char *buf)
453 {
454         int len;
455         int i;
456
457         for (i = 0, len = 0;
458              len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++)
459                 len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s",
460                         i ? " " : "", cabc_modes[i],
461                         i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : "");
462
463         return len < PAGE_SIZE ? len : PAGE_SIZE - 1;
464 }
465
466 static DEVICE_ATTR(num_dsi_errors, S_IRUGO, taal_num_errors_show, NULL);
467 static DEVICE_ATTR(hw_revision, S_IRUGO, taal_hw_revision_show, NULL);
468 static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR,
469                 show_cabc_mode, store_cabc_mode);
470 static DEVICE_ATTR(cabc_available_modes, S_IRUGO,
471                 show_cabc_available_modes, NULL);
472
473 static struct attribute *taal_attrs[] = {
474         &dev_attr_num_dsi_errors.attr,
475         &dev_attr_hw_revision.attr,
476         &dev_attr_cabc_mode.attr,
477         &dev_attr_cabc_available_modes.attr,
478         NULL,
479 };
480
481 static struct attribute_group taal_attr_group = {
482         .attrs = taal_attrs,
483 };
484
485 static int taal_probe(struct omap_dss_device *dssdev)
486 {
487         struct taal_data *td;
488         struct backlight_device *bldev;
489         int r;
490
491         const struct omap_video_timings taal_panel_timings = {
492                 .x_res          = 864,
493                 .y_res          = 480,
494         };
495
496         dev_dbg(&dssdev->dev, "probe\n");
497
498         dssdev->panel.config = OMAP_DSS_LCD_TFT;
499         dssdev->panel.timings = taal_panel_timings;
500         dssdev->ctrl.pixel_size = 24;
501
502         td = kzalloc(sizeof(*td), GFP_KERNEL);
503         if (!td) {
504                 r = -ENOMEM;
505                 goto err0;
506         }
507         td->dssdev = dssdev;
508
509         td->esd_wq = create_singlethread_workqueue("taal_esd");
510         if (td->esd_wq == NULL) {
511                 dev_err(&dssdev->dev, "can't create ESD workqueue\n");
512                 r = -ENOMEM;
513                 goto err2;
514         }
515         INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
516
517         dev_set_drvdata(&dssdev->dev, td);
518
519         dssdev->get_timings = taal_get_timings;
520         dssdev->get_resolution = taal_get_resolution;
521
522         /* if no platform set_backlight() defined, presume DSI backlight
523          * control */
524         if (!dssdev->set_backlight)
525                 td->use_dsi_bl = true;
526
527         bldev = backlight_device_register("taal", &dssdev->dev, dssdev,
528                         &taal_bl_ops);
529         if (IS_ERR(bldev)) {
530                 r = PTR_ERR(bldev);
531                 goto err1;
532         }
533
534         td->bldev = bldev;
535
536         bldev->props.fb_blank = FB_BLANK_UNBLANK;
537         bldev->props.power = FB_BLANK_UNBLANK;
538         if (td->use_dsi_bl) {
539                 bldev->props.max_brightness = 255;
540                 bldev->props.brightness = 255;
541         } else {
542                 bldev->props.max_brightness = 127;
543                 bldev->props.brightness = 127;
544         }
545
546         taal_bl_update_status(bldev);
547
548         if (dssdev->phy.dsi.ext_te) {
549                 int gpio = dssdev->phy.dsi.ext_te_gpio;
550
551                 r = gpio_request(gpio, "taal irq");
552                 if (r) {
553                         dev_err(&dssdev->dev, "GPIO request failed\n");
554                         goto err3;
555                 }
556
557                 gpio_direction_input(gpio);
558
559                 r = request_irq(gpio_to_irq(gpio), taal_te_isr,
560                                 IRQF_DISABLED | IRQF_TRIGGER_RISING,
561                                 "taal vsync", dssdev);
562
563                 if (r) {
564                         dev_err(&dssdev->dev, "IRQ request failed\n");
565                         gpio_free(gpio);
566                         goto err3;
567                 }
568
569                 init_completion(&td->te_completion);
570
571                 td->use_ext_te = true;
572         }
573
574         r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group);
575         if (r) {
576                 dev_err(&dssdev->dev, "failed to create sysfs files\n");
577                 goto err4;
578         }
579
580         return 0;
581 err4:
582         if (td->use_ext_te) {
583                 int gpio = dssdev->phy.dsi.ext_te_gpio;
584                 free_irq(gpio_to_irq(gpio), dssdev);
585                 gpio_free(gpio);
586         }
587 err3:
588         backlight_device_unregister(bldev);
589 err2:
590         cancel_delayed_work_sync(&td->esd_work);
591         destroy_workqueue(td->esd_wq);
592 err1:
593         kfree(td);
594 err0:
595         return r;
596 }
597
598 static void taal_remove(struct omap_dss_device *dssdev)
599 {
600         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
601         struct backlight_device *bldev;
602
603         dev_dbg(&dssdev->dev, "remove\n");
604
605         sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
606
607         if (td->use_ext_te) {
608                 int gpio = dssdev->phy.dsi.ext_te_gpio;
609                 free_irq(gpio_to_irq(gpio), dssdev);
610                 gpio_free(gpio);
611         }
612
613         bldev = td->bldev;
614         bldev->props.power = FB_BLANK_POWERDOWN;
615         taal_bl_update_status(bldev);
616         backlight_device_unregister(bldev);
617
618         cancel_delayed_work_sync(&td->esd_work);
619         destroy_workqueue(td->esd_wq);
620
621         kfree(td);
622 }
623
624 static int taal_enable(struct omap_dss_device *dssdev)
625 {
626         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
627         u8 id1, id2, id3;
628         int r;
629
630         dev_dbg(&dssdev->dev, "enable\n");
631
632         if (dssdev->platform_enable) {
633                 r = dssdev->platform_enable(dssdev);
634                 if (r)
635                         return r;
636         }
637
638         /* it seems we have to wait a bit until taal is ready */
639         msleep(5);
640
641         r = taal_sleep_out(td);
642         if (r)
643                 goto err;
644
645         r = taal_get_id(&id1, &id2, &id3);
646         if (r)
647                 goto err;
648
649         /* on early revisions CABC is broken */
650         if (id2 == 0x00 || id2 == 0xff || id2 == 0x81)
651                 td->cabc_broken = true;
652
653         taal_dcs_write_1(DCS_BRIGHTNESS, 0xff);
654         taal_dcs_write_1(DCS_CTRL_DISPLAY, (1<<2) | (1<<5)); /* BL | BCTRL */
655
656         taal_dcs_write_1(DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
657
658         taal_set_addr_mode(td->rotate, td->mirror);
659         if (!td->cabc_broken)
660                 taal_dcs_write_1(DCS_WRITE_CABC, td->cabc_mode);
661
662         taal_dcs_write_0(DCS_DISPLAY_ON);
663
664 #ifdef TAAL_USE_ESD_CHECK
665         queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
666 #endif
667
668         td->enabled = 1;
669
670         if (!td->intro_printed) {
671                 dev_info(&dssdev->dev, "revision %02x.%02x.%02x\n",
672                                 id1, id2, id3);
673                 if (td->cabc_broken)
674                         dev_info(&dssdev->dev,
675                                         "old Taal version, CABC disabled\n");
676                 td->intro_printed = true;
677         }
678
679         return 0;
680 err:
681         if (dssdev->platform_disable)
682                 dssdev->platform_disable(dssdev);
683
684         return r;
685 }
686
687 static void taal_disable(struct omap_dss_device *dssdev)
688 {
689         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
690
691         dev_dbg(&dssdev->dev, "disable\n");
692
693         cancel_delayed_work(&td->esd_work);
694
695         taal_dcs_write_0(DCS_DISPLAY_OFF);
696         taal_sleep_in(td);
697
698         /* wait a bit so that the message goes through */
699         msleep(10);
700
701         if (dssdev->platform_disable)
702                 dssdev->platform_disable(dssdev);
703
704         td->enabled = 0;
705 }
706
707 static int taal_suspend(struct omap_dss_device *dssdev)
708 {
709         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
710         struct backlight_device *bldev = td->bldev;
711
712         bldev->props.power = FB_BLANK_POWERDOWN;
713         taal_bl_update_status(bldev);
714
715         return 0;
716 }
717
718 static int taal_resume(struct omap_dss_device *dssdev)
719 {
720         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
721         struct backlight_device *bldev = td->bldev;
722
723         bldev->props.power = FB_BLANK_UNBLANK;
724         taal_bl_update_status(bldev);
725
726         return 0;
727 }
728
729 static void taal_setup_update(struct omap_dss_device *dssdev,
730                                     u16 x, u16 y, u16 w, u16 h)
731 {
732         taal_set_update_window(x, y, w, h);
733 }
734
735 static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
736 {
737         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
738         int r;
739
740         td->te_enabled = enable;
741
742         if (enable)
743                 r = taal_dcs_write_1(DCS_TEAR_ON, 0);
744         else
745                 r = taal_dcs_write_0(DCS_TEAR_OFF);
746
747         return r;
748 }
749
750 static int taal_wait_te(struct omap_dss_device *dssdev)
751 {
752         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
753         long wait = msecs_to_jiffies(500);
754
755         if (!td->use_ext_te || !td->te_enabled)
756                 return 0;
757
758         INIT_COMPLETION(td->te_completion);
759         wait = wait_for_completion_timeout(&td->te_completion, wait);
760         if (wait == 0) {
761                 dev_err(&dssdev->dev, "timeout waiting TE\n");
762                 return -ETIME;
763         }
764
765         return 0;
766 }
767
768 static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
769 {
770         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
771         int r;
772
773         dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
774
775         if (td->enabled) {
776                 r = taal_set_addr_mode(rotate, td->mirror);
777
778                 if (r)
779                         return r;
780         }
781
782         td->rotate = rotate;
783
784         return 0;
785 }
786
787 static u8 taal_get_rotate(struct omap_dss_device *dssdev)
788 {
789         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
790         return td->rotate;
791 }
792
793 static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
794 {
795         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
796         int r;
797
798         dev_dbg(&dssdev->dev, "mirror %d\n", enable);
799
800         if (td->enabled) {
801                 r = taal_set_addr_mode(td->rotate, enable);
802
803                 if (r)
804                         return r;
805         }
806
807         td->mirror = enable;
808
809         return 0;
810 }
811
812 static bool taal_get_mirror(struct omap_dss_device *dssdev)
813 {
814         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
815         return td->mirror;
816 }
817
818 static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
819 {
820         u8 id1, id2, id3;
821         int r;
822
823         r = taal_dcs_read_1(DCS_GET_ID1, &id1);
824         if (r)
825                 return r;
826         r = taal_dcs_read_1(DCS_GET_ID2, &id2);
827         if (r)
828                 return r;
829         r = taal_dcs_read_1(DCS_GET_ID3, &id3);
830         if (r)
831                 return r;
832
833         return 0;
834 }
835
836 static int taal_memory_read(struct omap_dss_device *dssdev,
837                 void *buf, size_t size,
838                 u16 x, u16 y, u16 w, u16 h)
839 {
840         int r;
841         int first = 1;
842         int plen;
843         unsigned buf_used = 0;
844
845         if (size < w * h * 3)
846                 return -ENOMEM;
847
848         size = min(w * h * 3,
849                         dssdev->panel.timings.x_res *
850                         dssdev->panel.timings.y_res * 3);
851
852         /* plen 1 or 2 goes into short packet. until checksum error is fixed,
853          * use short packets. plen 32 works, but bigger packets seem to cause
854          * an error. */
855         if (size % 2)
856                 plen = 1;
857         else
858                 plen = 2;
859
860         taal_setup_update(dssdev, x, y, w, h);
861
862         r = dsi_vc_set_max_rx_packet_size(TCH, plen);
863         if (r)
864                 return r;
865
866         while (buf_used < size) {
867                 u8 dcs_cmd = first ? 0x2e : 0x3e;
868                 first = 0;
869
870                 r = dsi_vc_dcs_read(TCH, dcs_cmd,
871                                 buf + buf_used, size - buf_used);
872
873                 if (r < 0) {
874                         dev_err(&dssdev->dev, "read error\n");
875                         goto err;
876                 }
877
878                 buf_used += r;
879
880                 if (r < plen) {
881                         dev_err(&dssdev->dev, "short read\n");
882                         break;
883                 }
884
885                 if (signal_pending(current)) {
886                         dev_err(&dssdev->dev, "signal pending, "
887                                         "aborting memory read\n");
888                         r = -ERESTARTSYS;
889                         goto err;
890                 }
891         }
892
893         r = buf_used;
894
895 err:
896         dsi_vc_set_max_rx_packet_size(TCH, 1);
897
898         return r;
899 }
900
901 static void taal_esd_work(struct work_struct *work)
902 {
903         struct taal_data *td = container_of(work, struct taal_data,
904                         esd_work.work);
905         struct omap_dss_device *dssdev = td->dssdev;
906         u8 state1, state2;
907         int r;
908
909         if (!td->enabled)
910                 return;
911
912         dsi_bus_lock();
913
914         r = taal_dcs_read_1(DCS_RDDSDR, &state1);
915         if (r) {
916                 dev_err(&dssdev->dev, "failed to read Taal status\n");
917                 goto err;
918         }
919
920         /* Run self diagnostics */
921         r = taal_sleep_out(td);
922         if (r) {
923                 dev_err(&dssdev->dev, "failed to run Taal self-diagnostics\n");
924                 goto err;
925         }
926
927         r = taal_dcs_read_1(DCS_RDDSDR, &state2);
928         if (r) {
929                 dev_err(&dssdev->dev, "failed to read Taal status\n");
930                 goto err;
931         }
932
933         /* Each sleep out command will trigger a self diagnostic and flip
934          * Bit6 if the test passes.
935          */
936         if (!((state1 ^ state2) & (1 << 6))) {
937                 dev_err(&dssdev->dev, "LCD self diagnostics failed\n");
938                 goto err;
939         }
940         /* Self-diagnostics result is also shown on TE GPIO line. We need
941          * to re-enable TE after self diagnostics */
942         if (td->use_ext_te && td->te_enabled)
943                 taal_enable_te(dssdev, true);
944
945         dsi_bus_unlock();
946
947         queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
948
949         return;
950 err:
951         dev_err(&dssdev->dev, "performing LCD reset\n");
952
953         taal_disable(dssdev);
954         taal_enable(dssdev);
955
956         dsi_bus_unlock();
957
958         queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
959 }
960
961 static struct omap_dss_driver taal_driver = {
962         .probe          = taal_probe,
963         .remove         = taal_remove,
964
965         .enable         = taal_enable,
966         .disable        = taal_disable,
967         .suspend        = taal_suspend,
968         .resume         = taal_resume,
969
970         .setup_update   = taal_setup_update,
971         .enable_te      = taal_enable_te,
972         .wait_for_te    = taal_wait_te,
973         .set_rotate     = taal_rotate,
974         .get_rotate     = taal_get_rotate,
975         .set_mirror     = taal_mirror,
976         .get_mirror     = taal_get_mirror,
977         .run_test       = taal_run_test,
978         .memory_read    = taal_memory_read,
979
980         .driver         = {
981                 .name   = "taal",
982                 .owner  = THIS_MODULE,
983         },
984 };
985
986 static int __init taal_init(void)
987 {
988         omap_dss_register_driver(&taal_driver);
989
990         return 0;
991 }
992
993 static void __exit taal_exit(void)
994 {
995         omap_dss_unregister_driver(&taal_driver);
996 }
997
998 module_init(taal_init);
999 module_exit(taal_exit);
1000
1001 MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
1002 MODULE_DESCRIPTION("Taal Driver");
1003 MODULE_LICENSE("GPL");