]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/video/omap2/displays/panel-taal.c
OMAP: DSS2: Taal: Clean up ESD queueing
[mv-sheeva.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/workqueue.h>
32 #include <linux/slab.h>
33 #include <linux/regulator/consumer.h>
34 #include <linux/mutex.h>
35
36 #include <video/omapdss.h>
37 #include <video/omap-panel-nokia-dsi.h>
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
66 static irqreturn_t taal_te_isr(int irq, void *data);
67 static void taal_te_timeout_work_callback(struct work_struct *work);
68 static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
69
70 struct panel_regulator {
71         struct regulator *regulator;
72         const char *name;
73         int min_uV;
74         int max_uV;
75 };
76
77 static void free_regulators(struct panel_regulator *regulators, int n)
78 {
79         int i;
80
81         for (i = 0; i < n; i++) {
82                 /* disable/put in reverse order */
83                 regulator_disable(regulators[n - i - 1].regulator);
84                 regulator_put(regulators[n - i - 1].regulator);
85         }
86 }
87
88 static int init_regulators(struct omap_dss_device *dssdev,
89                         struct panel_regulator *regulators, int n)
90 {
91         int r, i, v;
92
93         for (i = 0; i < n; i++) {
94                 struct regulator *reg;
95
96                 reg = regulator_get(&dssdev->dev, regulators[i].name);
97                 if (IS_ERR(reg)) {
98                         dev_err(&dssdev->dev, "failed to get regulator %s\n",
99                                 regulators[i].name);
100                         r = PTR_ERR(reg);
101                         goto err;
102                 }
103
104                 /* FIXME: better handling of fixed vs. variable regulators */
105                 v = regulator_get_voltage(reg);
106                 if (v < regulators[i].min_uV || v > regulators[i].max_uV) {
107                         r = regulator_set_voltage(reg, regulators[i].min_uV,
108                                                 regulators[i].max_uV);
109                         if (r) {
110                                 dev_err(&dssdev->dev,
111                                         "failed to set regulator %s voltage\n",
112                                         regulators[i].name);
113                                 regulator_put(reg);
114                                 goto err;
115                         }
116                 }
117
118                 r = regulator_enable(reg);
119                 if (r) {
120                         dev_err(&dssdev->dev, "failed to enable regulator %s\n",
121                                 regulators[i].name);
122                         regulator_put(reg);
123                         goto err;
124                 }
125
126                 regulators[i].regulator = reg;
127         }
128
129         return 0;
130
131 err:
132         free_regulators(regulators, i);
133
134         return r;
135 }
136
137 /**
138  * struct panel_config - panel configuration
139  * @name: panel name
140  * @type: panel type
141  * @timings: panel resolution
142  * @sleep: various panel specific delays, passed to msleep() if non-zero
143  * @reset_sequence: reset sequence timings, passed to udelay() if non-zero
144  * @regulators: array of panel regulators
145  * @num_regulators: number of regulators in the array
146  */
147 struct panel_config {
148         const char *name;
149         int type;
150
151         struct omap_video_timings timings;
152
153         struct {
154                 unsigned int sleep_in;
155                 unsigned int sleep_out;
156                 unsigned int hw_reset;
157                 unsigned int enable_te;
158         } sleep;
159
160         struct {
161                 unsigned int high;
162                 unsigned int low;
163         } reset_sequence;
164
165         struct panel_regulator *regulators;
166         int num_regulators;
167 };
168
169 enum {
170         PANEL_TAAL,
171 };
172
173 static struct panel_config panel_configs[] = {
174         {
175                 .name           = "taal",
176                 .type           = PANEL_TAAL,
177                 .timings        = {
178                         .x_res          = 864,
179                         .y_res          = 480,
180                 },
181                 .sleep          = {
182                         .sleep_in       = 5,
183                         .sleep_out      = 5,
184                         .hw_reset       = 5,
185                         .enable_te      = 100, /* possible panel bug */
186                 },
187                 .reset_sequence = {
188                         .high           = 10,
189                         .low            = 10,
190                 },
191         },
192 };
193
194 struct taal_data {
195         struct mutex lock;
196
197         struct backlight_device *bldev;
198
199         unsigned long   hw_guard_end;   /* next value of jiffies when we can
200                                          * issue the next sleep in/out command
201                                          */
202         unsigned long   hw_guard_wait;  /* max guard time in jiffies */
203
204         struct omap_dss_device *dssdev;
205
206         bool enabled;
207         u8 rotate;
208         bool mirror;
209
210         bool te_enabled;
211
212         atomic_t do_update;
213         struct {
214                 u16 x;
215                 u16 y;
216                 u16 w;
217                 u16 h;
218         } update_region;
219         int channel;
220
221         struct delayed_work te_timeout_work;
222
223         bool use_dsi_bl;
224
225         bool cabc_broken;
226         unsigned cabc_mode;
227
228         bool intro_printed;
229
230         struct workqueue_struct *esd_wq;
231         struct delayed_work esd_work;
232         unsigned esd_interval;
233
234         struct panel_config *panel_config;
235 };
236
237 static inline struct nokia_dsi_panel_data
238 *get_panel_data(const struct omap_dss_device *dssdev)
239 {
240         return (struct nokia_dsi_panel_data *) dssdev->data;
241 }
242
243 static void taal_esd_work(struct work_struct *work);
244
245 static void hw_guard_start(struct taal_data *td, int guard_msec)
246 {
247         td->hw_guard_wait = msecs_to_jiffies(guard_msec);
248         td->hw_guard_end = jiffies + td->hw_guard_wait;
249 }
250
251 static void hw_guard_wait(struct taal_data *td)
252 {
253         unsigned long wait = td->hw_guard_end - jiffies;
254
255         if ((long)wait > 0 && wait <= td->hw_guard_wait) {
256                 set_current_state(TASK_UNINTERRUPTIBLE);
257                 schedule_timeout(wait);
258         }
259 }
260
261 static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
262 {
263         int r;
264         u8 buf[1];
265
266         r = dsi_vc_dcs_read(td->channel, dcs_cmd, buf, 1);
267
268         if (r < 0)
269                 return r;
270
271         *data = buf[0];
272
273         return 0;
274 }
275
276 static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd)
277 {
278         return dsi_vc_dcs_write(td->channel, &dcs_cmd, 1);
279 }
280
281 static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
282 {
283         u8 buf[2];
284         buf[0] = dcs_cmd;
285         buf[1] = param;
286         return dsi_vc_dcs_write(td->channel, buf, 2);
287 }
288
289 static int taal_sleep_in(struct taal_data *td)
290
291 {
292         u8 cmd;
293         int r;
294
295         hw_guard_wait(td);
296
297         cmd = DCS_SLEEP_IN;
298         r = dsi_vc_dcs_write_nosync(td->channel, &cmd, 1);
299         if (r)
300                 return r;
301
302         hw_guard_start(td, 120);
303
304         if (td->panel_config->sleep.sleep_in)
305                 msleep(td->panel_config->sleep.sleep_in);
306
307         return 0;
308 }
309
310 static int taal_sleep_out(struct taal_data *td)
311 {
312         int r;
313
314         hw_guard_wait(td);
315
316         r = taal_dcs_write_0(td, DCS_SLEEP_OUT);
317         if (r)
318                 return r;
319
320         hw_guard_start(td, 120);
321
322         if (td->panel_config->sleep.sleep_out)
323                 msleep(td->panel_config->sleep.sleep_out);
324
325         return 0;
326 }
327
328 static int taal_get_id(struct taal_data *td, u8 *id1, u8 *id2, u8 *id3)
329 {
330         int r;
331
332         r = taal_dcs_read_1(td, DCS_GET_ID1, id1);
333         if (r)
334                 return r;
335         r = taal_dcs_read_1(td, DCS_GET_ID2, id2);
336         if (r)
337                 return r;
338         r = taal_dcs_read_1(td, DCS_GET_ID3, id3);
339         if (r)
340                 return r;
341
342         return 0;
343 }
344
345 static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
346 {
347         int r;
348         u8 mode;
349         int b5, b6, b7;
350
351         r = taal_dcs_read_1(td, DCS_READ_MADCTL, &mode);
352         if (r)
353                 return r;
354
355         switch (rotate) {
356         default:
357         case 0:
358                 b7 = 0;
359                 b6 = 0;
360                 b5 = 0;
361                 break;
362         case 1:
363                 b7 = 0;
364                 b6 = 1;
365                 b5 = 1;
366                 break;
367         case 2:
368                 b7 = 1;
369                 b6 = 1;
370                 b5 = 0;
371                 break;
372         case 3:
373                 b7 = 1;
374                 b6 = 0;
375                 b5 = 1;
376                 break;
377         }
378
379         if (mirror)
380                 b6 = !b6;
381
382         mode &= ~((1<<7) | (1<<6) | (1<<5));
383         mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
384
385         return taal_dcs_write_1(td, DCS_MEM_ACC_CTRL, mode);
386 }
387
388 static int taal_set_update_window(struct taal_data *td,
389                 u16 x, u16 y, u16 w, u16 h)
390 {
391         int r;
392         u16 x1 = x;
393         u16 x2 = x + w - 1;
394         u16 y1 = y;
395         u16 y2 = y + h - 1;
396
397         u8 buf[5];
398         buf[0] = DCS_COLUMN_ADDR;
399         buf[1] = (x1 >> 8) & 0xff;
400         buf[2] = (x1 >> 0) & 0xff;
401         buf[3] = (x2 >> 8) & 0xff;
402         buf[4] = (x2 >> 0) & 0xff;
403
404         r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf));
405         if (r)
406                 return r;
407
408         buf[0] = DCS_PAGE_ADDR;
409         buf[1] = (y1 >> 8) & 0xff;
410         buf[2] = (y1 >> 0) & 0xff;
411         buf[3] = (y2 >> 8) & 0xff;
412         buf[4] = (y2 >> 0) & 0xff;
413
414         r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf));
415         if (r)
416                 return r;
417
418         dsi_vc_send_bta_sync(td->channel);
419
420         return r;
421 }
422
423 static void taal_queue_esd_work(struct omap_dss_device *dssdev)
424 {
425         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
426
427         if (td->esd_interval > 0)
428                 queue_delayed_work(td->esd_wq, &td->esd_work,
429                                 msecs_to_jiffies(td->esd_interval));
430 }
431
432 static void taal_cancel_esd_work(struct omap_dss_device *dssdev)
433 {
434         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
435
436         cancel_delayed_work(&td->esd_work);
437 }
438
439 static int taal_bl_update_status(struct backlight_device *dev)
440 {
441         struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
442         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
443         struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
444         int r;
445         int level;
446
447         if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
448                         dev->props.power == FB_BLANK_UNBLANK)
449                 level = dev->props.brightness;
450         else
451                 level = 0;
452
453         dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
454
455         mutex_lock(&td->lock);
456
457         if (td->use_dsi_bl) {
458                 if (td->enabled) {
459                         dsi_bus_lock();
460                         r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
461                         dsi_bus_unlock();
462                 } else {
463                         r = 0;
464                 }
465         } else {
466                 if (!panel_data->set_backlight)
467                         r = -EINVAL;
468                 else
469                         r = panel_data->set_backlight(dssdev, level);
470         }
471
472         mutex_unlock(&td->lock);
473
474         return r;
475 }
476
477 static int taal_bl_get_intensity(struct backlight_device *dev)
478 {
479         if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
480                         dev->props.power == FB_BLANK_UNBLANK)
481                 return dev->props.brightness;
482
483         return 0;
484 }
485
486 static const struct backlight_ops taal_bl_ops = {
487         .get_brightness = taal_bl_get_intensity,
488         .update_status  = taal_bl_update_status,
489 };
490
491 static void taal_get_timings(struct omap_dss_device *dssdev,
492                         struct omap_video_timings *timings)
493 {
494         *timings = dssdev->panel.timings;
495 }
496
497 static void taal_get_resolution(struct omap_dss_device *dssdev,
498                 u16 *xres, u16 *yres)
499 {
500         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
501
502         if (td->rotate == 0 || td->rotate == 2) {
503                 *xres = dssdev->panel.timings.x_res;
504                 *yres = dssdev->panel.timings.y_res;
505         } else {
506                 *yres = dssdev->panel.timings.x_res;
507                 *xres = dssdev->panel.timings.y_res;
508         }
509 }
510
511 static ssize_t taal_num_errors_show(struct device *dev,
512                 struct device_attribute *attr, char *buf)
513 {
514         struct omap_dss_device *dssdev = to_dss_device(dev);
515         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
516         u8 errors;
517         int r;
518
519         mutex_lock(&td->lock);
520
521         if (td->enabled) {
522                 dsi_bus_lock();
523                 r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors);
524                 dsi_bus_unlock();
525         } else {
526                 r = -ENODEV;
527         }
528
529         mutex_unlock(&td->lock);
530
531         if (r)
532                 return r;
533
534         return snprintf(buf, PAGE_SIZE, "%d\n", errors);
535 }
536
537 static ssize_t taal_hw_revision_show(struct device *dev,
538                 struct device_attribute *attr, char *buf)
539 {
540         struct omap_dss_device *dssdev = to_dss_device(dev);
541         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
542         u8 id1, id2, id3;
543         int r;
544
545         mutex_lock(&td->lock);
546
547         if (td->enabled) {
548                 dsi_bus_lock();
549                 r = taal_get_id(td, &id1, &id2, &id3);
550                 dsi_bus_unlock();
551         } else {
552                 r = -ENODEV;
553         }
554
555         mutex_unlock(&td->lock);
556
557         if (r)
558                 return r;
559
560         return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3);
561 }
562
563 static const char *cabc_modes[] = {
564         "off",          /* used also always when CABC is not supported */
565         "ui",
566         "still-image",
567         "moving-image",
568 };
569
570 static ssize_t show_cabc_mode(struct device *dev,
571                 struct device_attribute *attr,
572                 char *buf)
573 {
574         struct omap_dss_device *dssdev = to_dss_device(dev);
575         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
576         const char *mode_str;
577         int mode;
578         int len;
579
580         mode = td->cabc_mode;
581
582         mode_str = "unknown";
583         if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes))
584                 mode_str = cabc_modes[mode];
585         len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str);
586
587         return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1;
588 }
589
590 static ssize_t store_cabc_mode(struct device *dev,
591                 struct device_attribute *attr,
592                 const char *buf, size_t count)
593 {
594         struct omap_dss_device *dssdev = to_dss_device(dev);
595         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
596         int i;
597
598         for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) {
599                 if (sysfs_streq(cabc_modes[i], buf))
600                         break;
601         }
602
603         if (i == ARRAY_SIZE(cabc_modes))
604                 return -EINVAL;
605
606         mutex_lock(&td->lock);
607
608         if (td->enabled) {
609                 dsi_bus_lock();
610                 if (!td->cabc_broken)
611                         taal_dcs_write_1(td, DCS_WRITE_CABC, i);
612                 dsi_bus_unlock();
613         }
614
615         td->cabc_mode = i;
616
617         mutex_unlock(&td->lock);
618
619         return count;
620 }
621
622 static ssize_t show_cabc_available_modes(struct device *dev,
623                 struct device_attribute *attr,
624                 char *buf)
625 {
626         int len;
627         int i;
628
629         for (i = 0, len = 0;
630              len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++)
631                 len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s",
632                         i ? " " : "", cabc_modes[i],
633                         i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : "");
634
635         return len < PAGE_SIZE ? len : PAGE_SIZE - 1;
636 }
637
638 static DEVICE_ATTR(num_dsi_errors, S_IRUGO, taal_num_errors_show, NULL);
639 static DEVICE_ATTR(hw_revision, S_IRUGO, taal_hw_revision_show, NULL);
640 static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR,
641                 show_cabc_mode, store_cabc_mode);
642 static DEVICE_ATTR(cabc_available_modes, S_IRUGO,
643                 show_cabc_available_modes, NULL);
644
645 static struct attribute *taal_attrs[] = {
646         &dev_attr_num_dsi_errors.attr,
647         &dev_attr_hw_revision.attr,
648         &dev_attr_cabc_mode.attr,
649         &dev_attr_cabc_available_modes.attr,
650         NULL,
651 };
652
653 static struct attribute_group taal_attr_group = {
654         .attrs = taal_attrs,
655 };
656
657 static void taal_hw_reset(struct omap_dss_device *dssdev)
658 {
659         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
660         struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
661
662         if (panel_data->reset_gpio == -1)
663                 return;
664
665         gpio_set_value(panel_data->reset_gpio, 1);
666         if (td->panel_config->reset_sequence.high)
667                 udelay(td->panel_config->reset_sequence.high);
668         /* reset the panel */
669         gpio_set_value(panel_data->reset_gpio, 0);
670         /* assert reset */
671         if (td->panel_config->reset_sequence.low)
672                 udelay(td->panel_config->reset_sequence.low);
673         gpio_set_value(panel_data->reset_gpio, 1);
674         /* wait after releasing reset */
675         if (td->panel_config->sleep.hw_reset)
676                 msleep(td->panel_config->sleep.hw_reset);
677 }
678
679 static int taal_probe(struct omap_dss_device *dssdev)
680 {
681         struct backlight_properties props;
682         struct taal_data *td;
683         struct backlight_device *bldev;
684         struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
685         struct panel_config *panel_config = NULL;
686         int r, i;
687
688         dev_dbg(&dssdev->dev, "probe\n");
689
690         if (!panel_data || !panel_data->name) {
691                 r = -EINVAL;
692                 goto err;
693         }
694
695         for (i = 0; i < ARRAY_SIZE(panel_configs); i++) {
696                 if (strcmp(panel_data->name, panel_configs[i].name) == 0) {
697                         panel_config = &panel_configs[i];
698                         break;
699                 }
700         }
701
702         if (!panel_config) {
703                 r = -EINVAL;
704                 goto err;
705         }
706
707         dssdev->panel.config = OMAP_DSS_LCD_TFT;
708         dssdev->panel.timings = panel_config->timings;
709         dssdev->ctrl.pixel_size = 24;
710
711         td = kzalloc(sizeof(*td), GFP_KERNEL);
712         if (!td) {
713                 r = -ENOMEM;
714                 goto err;
715         }
716         td->dssdev = dssdev;
717         td->panel_config = panel_config;
718         td->esd_interval = panel_data->esd_interval;
719
720         mutex_init(&td->lock);
721
722         atomic_set(&td->do_update, 0);
723
724         r = init_regulators(dssdev, panel_config->regulators,
725                         panel_config->num_regulators);
726         if (r)
727                 goto err_reg;
728
729         td->esd_wq = create_singlethread_workqueue("taal_esd");
730         if (td->esd_wq == NULL) {
731                 dev_err(&dssdev->dev, "can't create ESD workqueue\n");
732                 r = -ENOMEM;
733                 goto err_wq;
734         }
735         INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
736
737         dev_set_drvdata(&dssdev->dev, td);
738
739         taal_hw_reset(dssdev);
740
741         /* if no platform set_backlight() defined, presume DSI backlight
742          * control */
743         memset(&props, 0, sizeof(struct backlight_properties));
744         if (!panel_data->set_backlight)
745                 td->use_dsi_bl = true;
746
747         if (td->use_dsi_bl)
748                 props.max_brightness = 255;
749         else
750                 props.max_brightness = 127;
751
752         props.type = BACKLIGHT_RAW;
753         bldev = backlight_device_register("taal", &dssdev->dev, dssdev,
754                                           &taal_bl_ops, &props);
755         if (IS_ERR(bldev)) {
756                 r = PTR_ERR(bldev);
757                 goto err_bl;
758         }
759
760         td->bldev = bldev;
761
762         bldev->props.fb_blank = FB_BLANK_UNBLANK;
763         bldev->props.power = FB_BLANK_UNBLANK;
764         if (td->use_dsi_bl)
765                 bldev->props.brightness = 255;
766         else
767                 bldev->props.brightness = 127;
768
769         taal_bl_update_status(bldev);
770
771         if (panel_data->use_ext_te) {
772                 int gpio = panel_data->ext_te_gpio;
773
774                 r = gpio_request(gpio, "taal irq");
775                 if (r) {
776                         dev_err(&dssdev->dev, "GPIO request failed\n");
777                         goto err_gpio;
778                 }
779
780                 gpio_direction_input(gpio);
781
782                 r = request_irq(gpio_to_irq(gpio), taal_te_isr,
783                                 IRQF_DISABLED | IRQF_TRIGGER_RISING,
784                                 "taal vsync", dssdev);
785
786                 if (r) {
787                         dev_err(&dssdev->dev, "IRQ request failed\n");
788                         gpio_free(gpio);
789                         goto err_irq;
790                 }
791
792                 INIT_DELAYED_WORK_DEFERRABLE(&td->te_timeout_work,
793                                         taal_te_timeout_work_callback);
794
795                 dev_dbg(&dssdev->dev, "Using GPIO TE\n");
796         }
797
798         r = omap_dsi_request_vc(dssdev, &td->channel);
799         if (r) {
800                 dev_err(&dssdev->dev, "failed to get virtual channel\n");
801                 goto err_req_vc;
802         }
803
804         r = omap_dsi_set_vc_id(dssdev, td->channel, TCH);
805         if (r) {
806                 dev_err(&dssdev->dev, "failed to set VC_ID\n");
807                 goto err_vc_id;
808         }
809
810         r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group);
811         if (r) {
812                 dev_err(&dssdev->dev, "failed to create sysfs files\n");
813                 goto err_vc_id;
814         }
815
816         return 0;
817
818 err_vc_id:
819         omap_dsi_release_vc(dssdev, td->channel);
820 err_req_vc:
821         if (panel_data->use_ext_te)
822                 free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
823 err_irq:
824         if (panel_data->use_ext_te)
825                 gpio_free(panel_data->ext_te_gpio);
826 err_gpio:
827         backlight_device_unregister(bldev);
828 err_bl:
829         destroy_workqueue(td->esd_wq);
830 err_wq:
831         free_regulators(panel_config->regulators, panel_config->num_regulators);
832 err_reg:
833         kfree(td);
834 err:
835         return r;
836 }
837
838 static void __exit taal_remove(struct omap_dss_device *dssdev)
839 {
840         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
841         struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
842         struct backlight_device *bldev;
843
844         dev_dbg(&dssdev->dev, "remove\n");
845
846         sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
847         omap_dsi_release_vc(dssdev, td->channel);
848
849         if (panel_data->use_ext_te) {
850                 int gpio = panel_data->ext_te_gpio;
851                 free_irq(gpio_to_irq(gpio), dssdev);
852                 gpio_free(gpio);
853         }
854
855         bldev = td->bldev;
856         bldev->props.power = FB_BLANK_POWERDOWN;
857         taal_bl_update_status(bldev);
858         backlight_device_unregister(bldev);
859
860         taal_cancel_esd_work(dssdev);
861         destroy_workqueue(td->esd_wq);
862
863         /* reset, to be sure that the panel is in a valid state */
864         taal_hw_reset(dssdev);
865
866         free_regulators(td->panel_config->regulators,
867                         td->panel_config->num_regulators);
868
869         kfree(td);
870 }
871
872 static int taal_power_on(struct omap_dss_device *dssdev)
873 {
874         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
875         u8 id1, id2, id3;
876         int r;
877
878         r = omapdss_dsi_display_enable(dssdev);
879         if (r) {
880                 dev_err(&dssdev->dev, "failed to enable DSI\n");
881                 goto err0;
882         }
883
884         taal_hw_reset(dssdev);
885
886         omapdss_dsi_vc_enable_hs(td->channel, false);
887
888         r = taal_sleep_out(td);
889         if (r)
890                 goto err;
891
892         r = taal_get_id(td, &id1, &id2, &id3);
893         if (r)
894                 goto err;
895
896         /* on early Taal revisions CABC is broken */
897         if (td->panel_config->type == PANEL_TAAL &&
898                 (id2 == 0x00 || id2 == 0xff || id2 == 0x81))
899                 td->cabc_broken = true;
900
901         r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff);
902         if (r)
903                 goto err;
904
905         r = taal_dcs_write_1(td, DCS_CTRL_DISPLAY,
906                         (1<<2) | (1<<5));       /* BL | BCTRL */
907         if (r)
908                 goto err;
909
910         r = taal_dcs_write_1(td, DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
911         if (r)
912                 goto err;
913
914         r = taal_set_addr_mode(td, td->rotate, td->mirror);
915         if (r)
916                 goto err;
917
918         if (!td->cabc_broken) {
919                 r = taal_dcs_write_1(td, DCS_WRITE_CABC, td->cabc_mode);
920                 if (r)
921                         goto err;
922         }
923
924         r = taal_dcs_write_0(td, DCS_DISPLAY_ON);
925         if (r)
926                 goto err;
927
928         r = _taal_enable_te(dssdev, td->te_enabled);
929         if (r)
930                 goto err;
931
932         td->enabled = 1;
933
934         if (!td->intro_printed) {
935                 dev_info(&dssdev->dev, "%s panel revision %02x.%02x.%02x\n",
936                         td->panel_config->name, id1, id2, id3);
937                 if (td->cabc_broken)
938                         dev_info(&dssdev->dev,
939                                         "old Taal version, CABC disabled\n");
940                 td->intro_printed = true;
941         }
942
943         omapdss_dsi_vc_enable_hs(td->channel, true);
944
945         return 0;
946 err:
947         dev_err(&dssdev->dev, "error while enabling panel, issuing HW reset\n");
948
949         taal_hw_reset(dssdev);
950
951         omapdss_dsi_display_disable(dssdev, true, false);
952 err0:
953         return r;
954 }
955
956 static void taal_power_off(struct omap_dss_device *dssdev)
957 {
958         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
959         int r;
960
961         r = taal_dcs_write_0(td, DCS_DISPLAY_OFF);
962         if (!r) {
963                 r = taal_sleep_in(td);
964                 /* HACK: wait a bit so that the message goes through */
965                 msleep(10);
966         }
967
968         if (r) {
969                 dev_err(&dssdev->dev,
970                                 "error disabling panel, issuing HW reset\n");
971                 taal_hw_reset(dssdev);
972         }
973
974         omapdss_dsi_display_disable(dssdev, true, false);
975
976         td->enabled = 0;
977 }
978
979 static int taal_enable(struct omap_dss_device *dssdev)
980 {
981         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
982         int r;
983
984         dev_dbg(&dssdev->dev, "enable\n");
985
986         mutex_lock(&td->lock);
987
988         if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
989                 r = -EINVAL;
990                 goto err;
991         }
992
993         dsi_bus_lock();
994
995         r = taal_power_on(dssdev);
996
997         dsi_bus_unlock();
998
999         if (r)
1000                 goto err;
1001
1002         taal_queue_esd_work(dssdev);
1003
1004         dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
1005
1006         mutex_unlock(&td->lock);
1007
1008         return 0;
1009 err:
1010         dev_dbg(&dssdev->dev, "enable failed\n");
1011         mutex_unlock(&td->lock);
1012         return r;
1013 }
1014
1015 static void taal_disable(struct omap_dss_device *dssdev)
1016 {
1017         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1018
1019         dev_dbg(&dssdev->dev, "disable\n");
1020
1021         mutex_lock(&td->lock);
1022
1023         taal_cancel_esd_work(dssdev);
1024
1025         dsi_bus_lock();
1026
1027         if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
1028                 taal_power_off(dssdev);
1029
1030         dsi_bus_unlock();
1031
1032         dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
1033
1034         mutex_unlock(&td->lock);
1035 }
1036
1037 static int taal_suspend(struct omap_dss_device *dssdev)
1038 {
1039         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1040         int r;
1041
1042         dev_dbg(&dssdev->dev, "suspend\n");
1043
1044         mutex_lock(&td->lock);
1045
1046         if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
1047                 r = -EINVAL;
1048                 goto err;
1049         }
1050
1051         taal_cancel_esd_work(dssdev);
1052
1053         dsi_bus_lock();
1054
1055         taal_power_off(dssdev);
1056
1057         dsi_bus_unlock();
1058
1059         dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
1060
1061         mutex_unlock(&td->lock);
1062
1063         return 0;
1064 err:
1065         mutex_unlock(&td->lock);
1066         return r;
1067 }
1068
1069 static int taal_resume(struct omap_dss_device *dssdev)
1070 {
1071         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1072         int r;
1073
1074         dev_dbg(&dssdev->dev, "resume\n");
1075
1076         mutex_lock(&td->lock);
1077
1078         if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
1079                 r = -EINVAL;
1080                 goto err;
1081         }
1082
1083         dsi_bus_lock();
1084
1085         r = taal_power_on(dssdev);
1086
1087         dsi_bus_unlock();
1088
1089         if (r) {
1090                 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
1091         } else {
1092                 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
1093                 taal_queue_esd_work(dssdev);
1094         }
1095
1096         mutex_unlock(&td->lock);
1097
1098         return r;
1099 err:
1100         mutex_unlock(&td->lock);
1101         return r;
1102 }
1103
1104 static void taal_framedone_cb(int err, void *data)
1105 {
1106         struct omap_dss_device *dssdev = data;
1107         dev_dbg(&dssdev->dev, "framedone, err %d\n", err);
1108         dsi_bus_unlock();
1109 }
1110
1111 static irqreturn_t taal_te_isr(int irq, void *data)
1112 {
1113         struct omap_dss_device *dssdev = data;
1114         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1115         int old;
1116         int r;
1117
1118         old = atomic_cmpxchg(&td->do_update, 1, 0);
1119
1120         if (old) {
1121                 cancel_delayed_work(&td->te_timeout_work);
1122
1123                 r = omap_dsi_update(dssdev, td->channel,
1124                                 td->update_region.x,
1125                                 td->update_region.y,
1126                                 td->update_region.w,
1127                                 td->update_region.h,
1128                                 taal_framedone_cb, dssdev);
1129                 if (r)
1130                         goto err;
1131         }
1132
1133         return IRQ_HANDLED;
1134 err:
1135         dev_err(&dssdev->dev, "start update failed\n");
1136         dsi_bus_unlock();
1137         return IRQ_HANDLED;
1138 }
1139
1140 static void taal_te_timeout_work_callback(struct work_struct *work)
1141 {
1142         struct taal_data *td = container_of(work, struct taal_data,
1143                                         te_timeout_work.work);
1144         struct omap_dss_device *dssdev = td->dssdev;
1145
1146         dev_err(&dssdev->dev, "TE not received for 250ms!\n");
1147
1148         atomic_set(&td->do_update, 0);
1149         dsi_bus_unlock();
1150 }
1151
1152 static int taal_update(struct omap_dss_device *dssdev,
1153                                     u16 x, u16 y, u16 w, u16 h)
1154 {
1155         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1156         struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
1157         int r;
1158
1159         dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
1160
1161         mutex_lock(&td->lock);
1162         dsi_bus_lock();
1163
1164         if (!td->enabled) {
1165                 r = 0;
1166                 goto err;
1167         }
1168
1169         r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h, true);
1170         if (r)
1171                 goto err;
1172
1173         r = taal_set_update_window(td, x, y, w, h);
1174         if (r)
1175                 goto err;
1176
1177         if (td->te_enabled && panel_data->use_ext_te) {
1178                 td->update_region.x = x;
1179                 td->update_region.y = y;
1180                 td->update_region.w = w;
1181                 td->update_region.h = h;
1182                 barrier();
1183                 schedule_delayed_work(&td->te_timeout_work,
1184                                 msecs_to_jiffies(250));
1185                 atomic_set(&td->do_update, 1);
1186         } else {
1187                 r = omap_dsi_update(dssdev, td->channel, x, y, w, h,
1188                                 taal_framedone_cb, dssdev);
1189                 if (r)
1190                         goto err;
1191         }
1192
1193         /* note: no bus_unlock here. unlock is in framedone_cb */
1194         mutex_unlock(&td->lock);
1195         return 0;
1196 err:
1197         dsi_bus_unlock();
1198         mutex_unlock(&td->lock);
1199         return r;
1200 }
1201
1202 static int taal_sync(struct omap_dss_device *dssdev)
1203 {
1204         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1205
1206         dev_dbg(&dssdev->dev, "sync\n");
1207
1208         mutex_lock(&td->lock);
1209         dsi_bus_lock();
1210         dsi_bus_unlock();
1211         mutex_unlock(&td->lock);
1212
1213         dev_dbg(&dssdev->dev, "sync done\n");
1214
1215         return 0;
1216 }
1217
1218 static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1219 {
1220         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1221         struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
1222         int r;
1223
1224         if (enable)
1225                 r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
1226         else
1227                 r = taal_dcs_write_0(td, DCS_TEAR_OFF);
1228
1229         if (!panel_data->use_ext_te)
1230                 omapdss_dsi_enable_te(dssdev, enable);
1231
1232         if (td->panel_config->sleep.enable_te)
1233                 msleep(td->panel_config->sleep.enable_te);
1234
1235         return r;
1236 }
1237
1238 static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1239 {
1240         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1241         int r;
1242
1243         mutex_lock(&td->lock);
1244
1245         if (td->te_enabled == enable)
1246                 goto end;
1247
1248         dsi_bus_lock();
1249
1250         if (td->enabled) {
1251                 r = _taal_enable_te(dssdev, enable);
1252                 if (r)
1253                         goto err;
1254         }
1255
1256         td->te_enabled = enable;
1257
1258         dsi_bus_unlock();
1259 end:
1260         mutex_unlock(&td->lock);
1261
1262         return 0;
1263 err:
1264         dsi_bus_unlock();
1265         mutex_unlock(&td->lock);
1266
1267         return r;
1268 }
1269
1270 static int taal_get_te(struct omap_dss_device *dssdev)
1271 {
1272         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1273         int r;
1274
1275         mutex_lock(&td->lock);
1276         r = td->te_enabled;
1277         mutex_unlock(&td->lock);
1278
1279         return r;
1280 }
1281
1282 static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
1283 {
1284         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1285         int r;
1286
1287         dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
1288
1289         mutex_lock(&td->lock);
1290
1291         if (td->rotate == rotate)
1292                 goto end;
1293
1294         dsi_bus_lock();
1295
1296         if (td->enabled) {
1297                 r = taal_set_addr_mode(td, rotate, td->mirror);
1298                 if (r)
1299                         goto err;
1300         }
1301
1302         td->rotate = rotate;
1303
1304         dsi_bus_unlock();
1305 end:
1306         mutex_unlock(&td->lock);
1307         return 0;
1308 err:
1309         dsi_bus_unlock();
1310         mutex_unlock(&td->lock);
1311         return r;
1312 }
1313
1314 static u8 taal_get_rotate(struct omap_dss_device *dssdev)
1315 {
1316         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1317         int r;
1318
1319         mutex_lock(&td->lock);
1320         r = td->rotate;
1321         mutex_unlock(&td->lock);
1322
1323         return r;
1324 }
1325
1326 static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
1327 {
1328         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1329         int r;
1330
1331         dev_dbg(&dssdev->dev, "mirror %d\n", enable);
1332
1333         mutex_lock(&td->lock);
1334
1335         if (td->mirror == enable)
1336                 goto end;
1337
1338         dsi_bus_lock();
1339         if (td->enabled) {
1340                 r = taal_set_addr_mode(td, td->rotate, enable);
1341                 if (r)
1342                         goto err;
1343         }
1344
1345         td->mirror = enable;
1346
1347         dsi_bus_unlock();
1348 end:
1349         mutex_unlock(&td->lock);
1350         return 0;
1351 err:
1352         dsi_bus_unlock();
1353         mutex_unlock(&td->lock);
1354         return r;
1355 }
1356
1357 static bool taal_get_mirror(struct omap_dss_device *dssdev)
1358 {
1359         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1360         int r;
1361
1362         mutex_lock(&td->lock);
1363         r = td->mirror;
1364         mutex_unlock(&td->lock);
1365
1366         return r;
1367 }
1368
1369 static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1370 {
1371         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1372         u8 id1, id2, id3;
1373         int r;
1374
1375         mutex_lock(&td->lock);
1376
1377         if (!td->enabled) {
1378                 r = -ENODEV;
1379                 goto err1;
1380         }
1381
1382         dsi_bus_lock();
1383
1384         r = taal_dcs_read_1(td, DCS_GET_ID1, &id1);
1385         if (r)
1386                 goto err2;
1387         r = taal_dcs_read_1(td, DCS_GET_ID2, &id2);
1388         if (r)
1389                 goto err2;
1390         r = taal_dcs_read_1(td, DCS_GET_ID3, &id3);
1391         if (r)
1392                 goto err2;
1393
1394         dsi_bus_unlock();
1395         mutex_unlock(&td->lock);
1396         return 0;
1397 err2:
1398         dsi_bus_unlock();
1399 err1:
1400         mutex_unlock(&td->lock);
1401         return r;
1402 }
1403
1404 static int taal_memory_read(struct omap_dss_device *dssdev,
1405                 void *buf, size_t size,
1406                 u16 x, u16 y, u16 w, u16 h)
1407 {
1408         int r;
1409         int first = 1;
1410         int plen;
1411         unsigned buf_used = 0;
1412         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1413
1414         if (size < w * h * 3)
1415                 return -ENOMEM;
1416
1417         mutex_lock(&td->lock);
1418
1419         if (!td->enabled) {
1420                 r = -ENODEV;
1421                 goto err1;
1422         }
1423
1424         size = min(w * h * 3,
1425                         dssdev->panel.timings.x_res *
1426                         dssdev->panel.timings.y_res * 3);
1427
1428         dsi_bus_lock();
1429
1430         /* plen 1 or 2 goes into short packet. until checksum error is fixed,
1431          * use short packets. plen 32 works, but bigger packets seem to cause
1432          * an error. */
1433         if (size % 2)
1434                 plen = 1;
1435         else
1436                 plen = 2;
1437
1438         taal_set_update_window(td, x, y, w, h);
1439
1440         r = dsi_vc_set_max_rx_packet_size(td->channel, plen);
1441         if (r)
1442                 goto err2;
1443
1444         while (buf_used < size) {
1445                 u8 dcs_cmd = first ? 0x2e : 0x3e;
1446                 first = 0;
1447
1448                 r = dsi_vc_dcs_read(td->channel, dcs_cmd,
1449                                 buf + buf_used, size - buf_used);
1450
1451                 if (r < 0) {
1452                         dev_err(&dssdev->dev, "read error\n");
1453                         goto err3;
1454                 }
1455
1456                 buf_used += r;
1457
1458                 if (r < plen) {
1459                         dev_err(&dssdev->dev, "short read\n");
1460                         break;
1461                 }
1462
1463                 if (signal_pending(current)) {
1464                         dev_err(&dssdev->dev, "signal pending, "
1465                                         "aborting memory read\n");
1466                         r = -ERESTARTSYS;
1467                         goto err3;
1468                 }
1469         }
1470
1471         r = buf_used;
1472
1473 err3:
1474         dsi_vc_set_max_rx_packet_size(td->channel, 1);
1475 err2:
1476         dsi_bus_unlock();
1477 err1:
1478         mutex_unlock(&td->lock);
1479         return r;
1480 }
1481
1482 static void taal_esd_work(struct work_struct *work)
1483 {
1484         struct taal_data *td = container_of(work, struct taal_data,
1485                         esd_work.work);
1486         struct omap_dss_device *dssdev = td->dssdev;
1487         struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
1488         u8 state1, state2;
1489         int r;
1490
1491         mutex_lock(&td->lock);
1492
1493         if (!td->enabled) {
1494                 mutex_unlock(&td->lock);
1495                 return;
1496         }
1497
1498         dsi_bus_lock();
1499
1500         r = taal_dcs_read_1(td, DCS_RDDSDR, &state1);
1501         if (r) {
1502                 dev_err(&dssdev->dev, "failed to read Taal status\n");
1503                 goto err;
1504         }
1505
1506         /* Run self diagnostics */
1507         r = taal_sleep_out(td);
1508         if (r) {
1509                 dev_err(&dssdev->dev, "failed to run Taal self-diagnostics\n");
1510                 goto err;
1511         }
1512
1513         r = taal_dcs_read_1(td, DCS_RDDSDR, &state2);
1514         if (r) {
1515                 dev_err(&dssdev->dev, "failed to read Taal status\n");
1516                 goto err;
1517         }
1518
1519         /* Each sleep out command will trigger a self diagnostic and flip
1520          * Bit6 if the test passes.
1521          */
1522         if (!((state1 ^ state2) & (1 << 6))) {
1523                 dev_err(&dssdev->dev, "LCD self diagnostics failed\n");
1524                 goto err;
1525         }
1526         /* Self-diagnostics result is also shown on TE GPIO line. We need
1527          * to re-enable TE after self diagnostics */
1528         if (td->te_enabled && panel_data->use_ext_te) {
1529                 r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
1530                 if (r)
1531                         goto err;
1532         }
1533
1534         dsi_bus_unlock();
1535
1536         taal_queue_esd_work(dssdev);
1537
1538         mutex_unlock(&td->lock);
1539         return;
1540 err:
1541         dev_err(&dssdev->dev, "performing LCD reset\n");
1542
1543         taal_power_off(dssdev);
1544         taal_hw_reset(dssdev);
1545         taal_power_on(dssdev);
1546
1547         dsi_bus_unlock();
1548
1549         taal_queue_esd_work(dssdev);
1550
1551         mutex_unlock(&td->lock);
1552 }
1553
1554 static int taal_set_update_mode(struct omap_dss_device *dssdev,
1555                 enum omap_dss_update_mode mode)
1556 {
1557         if (mode != OMAP_DSS_UPDATE_MANUAL)
1558                 return -EINVAL;
1559         return 0;
1560 }
1561
1562 static enum omap_dss_update_mode taal_get_update_mode(
1563                 struct omap_dss_device *dssdev)
1564 {
1565         return OMAP_DSS_UPDATE_MANUAL;
1566 }
1567
1568 static struct omap_dss_driver taal_driver = {
1569         .probe          = taal_probe,
1570         .remove         = __exit_p(taal_remove),
1571
1572         .enable         = taal_enable,
1573         .disable        = taal_disable,
1574         .suspend        = taal_suspend,
1575         .resume         = taal_resume,
1576
1577         .set_update_mode = taal_set_update_mode,
1578         .get_update_mode = taal_get_update_mode,
1579
1580         .update         = taal_update,
1581         .sync           = taal_sync,
1582
1583         .get_resolution = taal_get_resolution,
1584         .get_recommended_bpp = omapdss_default_get_recommended_bpp,
1585
1586         .enable_te      = taal_enable_te,
1587         .get_te         = taal_get_te,
1588
1589         .set_rotate     = taal_rotate,
1590         .get_rotate     = taal_get_rotate,
1591         .set_mirror     = taal_mirror,
1592         .get_mirror     = taal_get_mirror,
1593         .run_test       = taal_run_test,
1594         .memory_read    = taal_memory_read,
1595
1596         .get_timings    = taal_get_timings,
1597
1598         .driver         = {
1599                 .name   = "taal",
1600                 .owner  = THIS_MODULE,
1601         },
1602 };
1603
1604 static int __init taal_init(void)
1605 {
1606         omap_dss_register_driver(&taal_driver);
1607
1608         return 0;
1609 }
1610
1611 static void __exit taal_exit(void)
1612 {
1613         omap_dss_unregister_driver(&taal_driver);
1614 }
1615
1616 module_init(taal_init);
1617 module_exit(taal_exit);
1618
1619 MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
1620 MODULE_DESCRIPTION("Taal Driver");
1621 MODULE_LICENSE("GPL");