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