pandora: reserve CMA area for c64_tools
[pandora-kernel.git] / drivers / video / backlight / ld9040.c
1 /*
2  * ld9040 AMOLED LCD panel driver.
3  *
4  * Copyright (c) 2011 Samsung Electronics
5  * Author: Donghwa Lee  <dh09.lee@samsung.com>
6  * Derived from drivers/video/backlight/s6e63m0.c
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2 of the License, or (at your
11  * option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  */
22
23 #include <linux/wait.h>
24 #include <linux/fb.h>
25 #include <linux/delay.h>
26 #include <linux/gpio.h>
27 #include <linux/spi/spi.h>
28 #include <linux/irq.h>
29 #include <linux/interrupt.h>
30 #include <linux/kernel.h>
31 #include <linux/lcd.h>
32 #include <linux/backlight.h>
33 #include <linux/module.h>
34
35 #include "ld9040_gamma.h"
36
37 #define SLEEPMSEC               0x1000
38 #define ENDDEF                  0x2000
39 #define DEFMASK                 0xFF00
40 #define COMMAND_ONLY            0xFE
41 #define DATA_ONLY               0xFF
42
43 #define MIN_BRIGHTNESS          0
44 #define MAX_BRIGHTNESS          24
45 #define power_is_on(pwr)        ((pwr) <= FB_BLANK_NORMAL)
46
47 struct ld9040 {
48         struct device                   *dev;
49         struct spi_device               *spi;
50         unsigned int                    power;
51         unsigned int                    current_brightness;
52
53         struct lcd_device               *ld;
54         struct backlight_device         *bd;
55         struct lcd_platform_data        *lcd_pd;
56 };
57
58 static const unsigned short seq_swreset[] = {
59         0x01, COMMAND_ONLY,
60         ENDDEF, 0x00
61 };
62
63 static const unsigned short seq_user_setting[] = {
64         0xF0, 0x5A,
65
66         DATA_ONLY, 0x5A,
67         ENDDEF, 0x00
68 };
69
70 static const unsigned short seq_elvss_on[] = {
71         0xB1, 0x0D,
72
73         DATA_ONLY, 0x00,
74         DATA_ONLY, 0x16,
75         ENDDEF, 0x00
76 };
77
78 static const unsigned short seq_gtcon[] = {
79         0xF7, 0x09,
80
81         DATA_ONLY, 0x00,
82         DATA_ONLY, 0x00,
83         ENDDEF, 0x00
84 };
85
86 static const unsigned short seq_panel_condition[] = {
87         0xF8, 0x05,
88
89         DATA_ONLY, 0x65,
90         DATA_ONLY, 0x96,
91         DATA_ONLY, 0x71,
92         DATA_ONLY, 0x7D,
93         DATA_ONLY, 0x19,
94         DATA_ONLY, 0x3B,
95         DATA_ONLY, 0x0D,
96         DATA_ONLY, 0x19,
97         DATA_ONLY, 0x7E,
98         DATA_ONLY, 0x0D,
99         DATA_ONLY, 0xE2,
100         DATA_ONLY, 0x00,
101         DATA_ONLY, 0x00,
102         DATA_ONLY, 0x7E,
103         DATA_ONLY, 0x7D,
104         DATA_ONLY, 0x07,
105         DATA_ONLY, 0x07,
106         DATA_ONLY, 0x20,
107         DATA_ONLY, 0x20,
108         DATA_ONLY, 0x20,
109         DATA_ONLY, 0x02,
110         DATA_ONLY, 0x02,
111         ENDDEF, 0x00
112 };
113
114 static const unsigned short seq_gamma_set1[] = {
115         0xF9, 0x00,
116
117         DATA_ONLY, 0xA7,
118         DATA_ONLY, 0xB4,
119         DATA_ONLY, 0xAE,
120         DATA_ONLY, 0xBF,
121         DATA_ONLY, 0x00,
122         DATA_ONLY, 0x91,
123         DATA_ONLY, 0x00,
124         DATA_ONLY, 0xB2,
125         DATA_ONLY, 0xB4,
126         DATA_ONLY, 0xAA,
127         DATA_ONLY, 0xBB,
128         DATA_ONLY, 0x00,
129         DATA_ONLY, 0xAC,
130         DATA_ONLY, 0x00,
131         DATA_ONLY, 0xB3,
132         DATA_ONLY, 0xB1,
133         DATA_ONLY, 0xAA,
134         DATA_ONLY, 0xBC,
135         DATA_ONLY, 0x00,
136         DATA_ONLY, 0xB3,
137         ENDDEF, 0x00
138 };
139
140 static const unsigned short seq_gamma_ctrl[] = {
141         0xFB, 0x02,
142
143         DATA_ONLY, 0x5A,
144         ENDDEF, 0x00
145 };
146
147 static const unsigned short seq_gamma_start[] = {
148         0xF9, COMMAND_ONLY,
149
150         ENDDEF, 0x00
151 };
152
153 static const unsigned short seq_apon[] = {
154         0xF3, 0x00,
155
156         DATA_ONLY, 0x00,
157         DATA_ONLY, 0x00,
158         DATA_ONLY, 0x0A,
159         DATA_ONLY, 0x02,
160         ENDDEF, 0x00
161 };
162
163 static const unsigned short seq_display_ctrl[] = {
164         0xF2, 0x02,
165
166         DATA_ONLY, 0x08,
167         DATA_ONLY, 0x08,
168         DATA_ONLY, 0x10,
169         DATA_ONLY, 0x10,
170         ENDDEF, 0x00
171 };
172
173 static const unsigned short seq_manual_pwr[] = {
174         0xB0, 0x04,
175         ENDDEF, 0x00
176 };
177
178 static const unsigned short seq_pwr_ctrl[] = {
179         0xF4, 0x0A,
180
181         DATA_ONLY, 0x87,
182         DATA_ONLY, 0x25,
183         DATA_ONLY, 0x6A,
184         DATA_ONLY, 0x44,
185         DATA_ONLY, 0x02,
186         DATA_ONLY, 0x88,
187         ENDDEF, 0x00
188 };
189
190 static const unsigned short seq_sleep_out[] = {
191         0x11, COMMAND_ONLY,
192         ENDDEF, 0x00
193 };
194
195 static const unsigned short seq_sleep_in[] = {
196         0x10, COMMAND_ONLY,
197         ENDDEF, 0x00
198 };
199
200 static const unsigned short seq_display_on[] = {
201         0x29, COMMAND_ONLY,
202         ENDDEF, 0x00
203 };
204
205 static const unsigned short seq_display_off[] = {
206         0x28, COMMAND_ONLY,
207         ENDDEF, 0x00
208 };
209
210 static const unsigned short seq_vci1_1st_en[] = {
211         0xF3, 0x10,
212
213         DATA_ONLY, 0x00,
214         DATA_ONLY, 0x00,
215         DATA_ONLY, 0x00,
216         DATA_ONLY, 0x02,
217         ENDDEF, 0x00
218 };
219
220 static const unsigned short seq_vl1_en[] = {
221         0xF3, 0x11,
222
223         DATA_ONLY, 0x00,
224         DATA_ONLY, 0x00,
225         DATA_ONLY, 0x00,
226         DATA_ONLY, 0x02,
227         ENDDEF, 0x00
228 };
229
230 static const unsigned short seq_vl2_en[] = {
231         0xF3, 0x13,
232
233         DATA_ONLY, 0x00,
234         DATA_ONLY, 0x00,
235         DATA_ONLY, 0x00,
236         DATA_ONLY, 0x02,
237         ENDDEF, 0x00
238 };
239
240 static const unsigned short seq_vci1_2nd_en[] = {
241         0xF3, 0x33,
242
243         DATA_ONLY, 0x00,
244         DATA_ONLY, 0x00,
245         DATA_ONLY, 0x00,
246         DATA_ONLY, 0x02,
247         ENDDEF, 0x00
248 };
249
250 static const unsigned short seq_vl3_en[] = {
251         0xF3, 0x37,
252
253         DATA_ONLY, 0x00,
254         DATA_ONLY, 0x00,
255         DATA_ONLY, 0x00,
256         DATA_ONLY, 0x02,
257         ENDDEF, 0x00
258 };
259
260 static const unsigned short seq_vreg1_amp_en[] = {
261         0xF3, 0x37,
262
263         DATA_ONLY, 0x01,
264         DATA_ONLY, 0x00,
265         DATA_ONLY, 0x00,
266         DATA_ONLY, 0x02,
267         ENDDEF, 0x00
268 };
269
270 static const unsigned short seq_vgh_amp_en[] = {
271         0xF3, 0x37,
272
273         DATA_ONLY, 0x11,
274         DATA_ONLY, 0x00,
275         DATA_ONLY, 0x00,
276         DATA_ONLY, 0x02,
277         ENDDEF, 0x00
278 };
279
280 static const unsigned short seq_vgl_amp_en[] = {
281         0xF3, 0x37,
282
283         DATA_ONLY, 0x31,
284         DATA_ONLY, 0x00,
285         DATA_ONLY, 0x00,
286         DATA_ONLY, 0x02,
287         ENDDEF, 0x00
288 };
289
290 static const unsigned short seq_vmos_amp_en[] = {
291         0xF3, 0x37,
292
293         DATA_ONLY, 0xB1,
294         DATA_ONLY, 0x00,
295         DATA_ONLY, 0x00,
296         DATA_ONLY, 0x03,
297         ENDDEF, 0x00
298 };
299
300 static const unsigned short seq_vint_amp_en[] = {
301         0xF3, 0x37,
302
303         DATA_ONLY, 0xF1,
304         /* DATA_ONLY, 0x71,     VMOS/VBL/VBH not used */
305         DATA_ONLY, 0x00,
306         DATA_ONLY, 0x00,
307         DATA_ONLY, 0x03,
308         /* DATA_ONLY, 0x02,     VMOS/VBL/VBH not used */
309         ENDDEF, 0x00
310 };
311
312 static const unsigned short seq_vbh_amp_en[] = {
313         0xF3, 0x37,
314
315         DATA_ONLY, 0xF9,
316         DATA_ONLY, 0x00,
317         DATA_ONLY, 0x00,
318         DATA_ONLY, 0x03,
319         ENDDEF, 0x00
320 };
321
322 static const unsigned short seq_vbl_amp_en[] = {
323         0xF3, 0x37,
324
325         DATA_ONLY, 0xFD,
326         DATA_ONLY, 0x00,
327         DATA_ONLY, 0x00,
328         DATA_ONLY, 0x03,
329         ENDDEF, 0x00
330 };
331
332 static const unsigned short seq_gam_amp_en[] = {
333         0xF3, 0x37,
334
335         DATA_ONLY, 0xFF,
336         /* DATA_ONLY, 0x73,     VMOS/VBL/VBH not used */
337         DATA_ONLY, 0x00,
338         DATA_ONLY, 0x00,
339         DATA_ONLY, 0x03,
340         /* DATA_ONLY, 0x02,     VMOS/VBL/VBH not used */
341         ENDDEF, 0x00
342 };
343
344 static const unsigned short seq_sd_amp_en[] = {
345         0xF3, 0x37,
346
347         DATA_ONLY, 0xFF,
348         /* DATA_ONLY, 0x73,     VMOS/VBL/VBH not used */
349         DATA_ONLY, 0x80,
350         DATA_ONLY, 0x00,
351         DATA_ONLY, 0x03,
352         /* DATA_ONLY, 0x02,     VMOS/VBL/VBH not used */
353         ENDDEF, 0x00
354 };
355
356 static const unsigned short seq_gls_en[] = {
357         0xF3, 0x37,
358
359         DATA_ONLY, 0xFF,
360         /* DATA_ONLY, 0x73,     VMOS/VBL/VBH not used */
361         DATA_ONLY, 0x81,
362         DATA_ONLY, 0x00,
363         DATA_ONLY, 0x03,
364         /* DATA_ONLY, 0x02,     VMOS/VBL/VBH not used */
365         ENDDEF, 0x00
366 };
367
368 static const unsigned short seq_els_en[] = {
369         0xF3, 0x37,
370
371         DATA_ONLY, 0xFF,
372         /* DATA_ONLY, 0x73,     VMOS/VBL/VBH not used */
373         DATA_ONLY, 0x83,
374         DATA_ONLY, 0x00,
375         DATA_ONLY, 0x03,
376         /* DATA_ONLY, 0x02,     VMOS/VBL/VBH not used */
377         ENDDEF, 0x00
378 };
379
380 static const unsigned short seq_el_on[] = {
381         0xF3, 0x37,
382
383         DATA_ONLY, 0xFF,
384         /* DATA_ONLY, 0x73,     VMOS/VBL/VBH not used */
385         DATA_ONLY, 0x87,
386         DATA_ONLY, 0x00,
387         DATA_ONLY, 0x03,
388         /* DATA_ONLY, 0x02,     VMOS/VBL/VBH not used */
389         ENDDEF, 0x00
390 };
391
392 static int ld9040_spi_write_byte(struct ld9040 *lcd, int addr, int data)
393 {
394         u16 buf[1];
395         struct spi_message msg;
396
397         struct spi_transfer xfer = {
398                 .len            = 2,
399                 .tx_buf         = buf,
400         };
401
402         buf[0] = (addr << 8) | data;
403
404         spi_message_init(&msg);
405         spi_message_add_tail(&xfer, &msg);
406
407         return spi_sync(lcd->spi, &msg);
408 }
409
410 static int ld9040_spi_write(struct ld9040 *lcd, unsigned char address,
411         unsigned char command)
412 {
413         int ret = 0;
414
415         if (address != DATA_ONLY)
416                 ret = ld9040_spi_write_byte(lcd, 0x0, address);
417         if (command != COMMAND_ONLY)
418                 ret = ld9040_spi_write_byte(lcd, 0x1, command);
419
420         return ret;
421 }
422
423 static int ld9040_panel_send_sequence(struct ld9040 *lcd,
424         const unsigned short *wbuf)
425 {
426         int ret = 0, i = 0;
427
428         while ((wbuf[i] & DEFMASK) != ENDDEF) {
429                 if ((wbuf[i] & DEFMASK) != SLEEPMSEC) {
430                         ret = ld9040_spi_write(lcd, wbuf[i], wbuf[i+1]);
431                         if (ret)
432                                 break;
433                 } else
434                         udelay(wbuf[i+1]*1000);
435                 i += 2;
436         }
437
438         return ret;
439 }
440
441 static int _ld9040_gamma_ctl(struct ld9040 *lcd, const unsigned int *gamma)
442 {
443         unsigned int i = 0;
444         int ret = 0;
445
446         /* start gamma table updating. */
447         ret = ld9040_panel_send_sequence(lcd, seq_gamma_start);
448         if (ret) {
449                 dev_err(lcd->dev, "failed to disable gamma table updating.\n");
450                 goto gamma_err;
451         }
452
453         for (i = 0 ; i < GAMMA_TABLE_COUNT; i++) {
454                 ret = ld9040_spi_write(lcd, DATA_ONLY, gamma[i]);
455                 if (ret) {
456                         dev_err(lcd->dev, "failed to set gamma table.\n");
457                         goto gamma_err;
458                 }
459         }
460
461         /* update gamma table. */
462         ret = ld9040_panel_send_sequence(lcd, seq_gamma_ctrl);
463         if (ret)
464                 dev_err(lcd->dev, "failed to update gamma table.\n");
465
466 gamma_err:
467         return ret;
468 }
469
470 static int ld9040_gamma_ctl(struct ld9040 *lcd, int gamma)
471 {
472         int ret = 0;
473
474         ret = _ld9040_gamma_ctl(lcd, gamma_table.gamma_22_table[gamma]);
475
476         return ret;
477 }
478
479
480 static int ld9040_ldi_init(struct ld9040 *lcd)
481 {
482         int ret, i;
483         static const unsigned short *init_seq[] = {
484                 seq_user_setting,
485                 seq_panel_condition,
486                 seq_display_ctrl,
487                 seq_manual_pwr,
488                 seq_elvss_on,
489                 seq_gtcon,
490                 seq_gamma_set1,
491                 seq_gamma_ctrl,
492                 seq_sleep_out,
493         };
494
495         for (i = 0; i < ARRAY_SIZE(init_seq); i++) {
496                 ret = ld9040_panel_send_sequence(lcd, init_seq[i]);
497                 /* workaround: minimum delay time for transferring CMD */
498                 udelay(300);
499                 if (ret)
500                         break;
501         }
502
503         return ret;
504 }
505
506 static int ld9040_ldi_enable(struct ld9040 *lcd)
507 {
508         int ret = 0;
509
510         ret = ld9040_panel_send_sequence(lcd, seq_display_on);
511
512         return ret;
513 }
514
515 static int ld9040_ldi_disable(struct ld9040 *lcd)
516 {
517         int ret;
518
519         ret = ld9040_panel_send_sequence(lcd, seq_display_off);
520         ret = ld9040_panel_send_sequence(lcd, seq_sleep_in);
521
522         return ret;
523 }
524
525 static int ld9040_power_on(struct ld9040 *lcd)
526 {
527         int ret = 0;
528         struct lcd_platform_data *pd = NULL;
529         pd = lcd->lcd_pd;
530         if (!pd) {
531                 dev_err(lcd->dev, "platform data is NULL.\n");
532                 return -EFAULT;
533         }
534
535         if (!pd->power_on) {
536                 dev_err(lcd->dev, "power_on is NULL.\n");
537                 return -EFAULT;
538         } else {
539                 pd->power_on(lcd->ld, 1);
540                 mdelay(pd->power_on_delay);
541         }
542
543         if (!pd->reset) {
544                 dev_err(lcd->dev, "reset is NULL.\n");
545                 return -EFAULT;
546         } else {
547                 pd->reset(lcd->ld);
548                 mdelay(pd->reset_delay);
549         }
550
551         ret = ld9040_ldi_init(lcd);
552         if (ret) {
553                 dev_err(lcd->dev, "failed to initialize ldi.\n");
554                 return ret;
555         }
556
557         ret = ld9040_ldi_enable(lcd);
558         if (ret) {
559                 dev_err(lcd->dev, "failed to enable ldi.\n");
560                 return ret;
561         }
562
563         return 0;
564 }
565
566 static int ld9040_power_off(struct ld9040 *lcd)
567 {
568         int ret = 0;
569         struct lcd_platform_data *pd = NULL;
570
571         pd = lcd->lcd_pd;
572         if (!pd) {
573                 dev_err(lcd->dev, "platform data is NULL.\n");
574                 return -EFAULT;
575         }
576
577         ret = ld9040_ldi_disable(lcd);
578         if (ret) {
579                 dev_err(lcd->dev, "lcd setting failed.\n");
580                 return -EIO;
581         }
582
583         mdelay(pd->power_off_delay);
584
585         if (!pd->power_on) {
586                 dev_err(lcd->dev, "power_on is NULL.\n");
587                 return -EFAULT;
588         } else
589                 pd->power_on(lcd->ld, 0);
590
591         return 0;
592 }
593
594 static int ld9040_power(struct ld9040 *lcd, int power)
595 {
596         int ret = 0;
597
598         if (power_is_on(power) && !power_is_on(lcd->power))
599                 ret = ld9040_power_on(lcd);
600         else if (!power_is_on(power) && power_is_on(lcd->power))
601                 ret = ld9040_power_off(lcd);
602
603         if (!ret)
604                 lcd->power = power;
605
606         return ret;
607 }
608
609 static int ld9040_set_power(struct lcd_device *ld, int power)
610 {
611         struct ld9040 *lcd = lcd_get_data(ld);
612
613         if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
614                 power != FB_BLANK_NORMAL) {
615                 dev_err(lcd->dev, "power value should be 0, 1 or 4.\n");
616                 return -EINVAL;
617         }
618
619         return ld9040_power(lcd, power);
620 }
621
622 static int ld9040_get_power(struct lcd_device *ld)
623 {
624         struct ld9040 *lcd = lcd_get_data(ld);
625
626         return lcd->power;
627 }
628
629 static int ld9040_get_brightness(struct backlight_device *bd)
630 {
631         return bd->props.brightness;
632 }
633
634 static int ld9040_set_brightness(struct backlight_device *bd)
635 {
636         int ret = 0, brightness = bd->props.brightness;
637         struct ld9040 *lcd = bl_get_data(bd);
638
639         if (brightness < MIN_BRIGHTNESS ||
640                 brightness > bd->props.max_brightness) {
641                 dev_err(&bd->dev, "lcd brightness should be %d to %d.\n",
642                         MIN_BRIGHTNESS, MAX_BRIGHTNESS);
643                 return -EINVAL;
644         }
645
646         ret = ld9040_gamma_ctl(lcd, bd->props.brightness);
647         if (ret) {
648                 dev_err(&bd->dev, "lcd brightness setting failed.\n");
649                 return -EIO;
650         }
651
652         return ret;
653 }
654
655 static struct lcd_ops ld9040_lcd_ops = {
656         .set_power = ld9040_set_power,
657         .get_power = ld9040_get_power,
658 };
659
660 static const struct backlight_ops ld9040_backlight_ops  = {
661         .get_brightness = ld9040_get_brightness,
662         .update_status = ld9040_set_brightness,
663 };
664
665
666 static int ld9040_probe(struct spi_device *spi)
667 {
668         int ret = 0;
669         struct ld9040 *lcd = NULL;
670         struct lcd_device *ld = NULL;
671         struct backlight_device *bd = NULL;
672         struct backlight_properties props;
673
674         lcd = kzalloc(sizeof(struct ld9040), GFP_KERNEL);
675         if (!lcd)
676                 return -ENOMEM;
677
678         /* ld9040 lcd panel uses 3-wire 9bits SPI Mode. */
679         spi->bits_per_word = 9;
680
681         ret = spi_setup(spi);
682         if (ret < 0) {
683                 dev_err(&spi->dev, "spi setup failed.\n");
684                 goto out_free_lcd;
685         }
686
687         lcd->spi = spi;
688         lcd->dev = &spi->dev;
689
690         lcd->lcd_pd = spi->dev.platform_data;
691         if (!lcd->lcd_pd) {
692                 dev_err(&spi->dev, "platform data is NULL.\n");
693                 goto out_free_lcd;
694         }
695
696         ld = lcd_device_register("ld9040", &spi->dev, lcd, &ld9040_lcd_ops);
697         if (IS_ERR(ld)) {
698                 ret = PTR_ERR(ld);
699                 goto out_free_lcd;
700         }
701
702         lcd->ld = ld;
703
704         memset(&props, 0, sizeof(struct backlight_properties));
705         props.type = BACKLIGHT_RAW;
706         props.max_brightness = MAX_BRIGHTNESS;
707
708         bd = backlight_device_register("ld9040-bl", &spi->dev,
709                 lcd, &ld9040_backlight_ops, &props);
710         if (IS_ERR(bd)) {
711                 ret = PTR_ERR(bd);
712                 goto out_unregister_lcd;
713         }
714
715         bd->props.brightness = MAX_BRIGHTNESS;
716         lcd->bd = bd;
717
718         /*
719          * if lcd panel was on from bootloader like u-boot then
720          * do not lcd on.
721          */
722         if (!lcd->lcd_pd->lcd_enabled) {
723                 /*
724                  * if lcd panel was off from bootloader then
725                  * current lcd status is powerdown and then
726                  * it enables lcd panel.
727                  */
728                 lcd->power = FB_BLANK_POWERDOWN;
729
730                 ld9040_power(lcd, FB_BLANK_UNBLANK);
731         } else
732                 lcd->power = FB_BLANK_UNBLANK;
733
734         dev_set_drvdata(&spi->dev, lcd);
735
736         dev_info(&spi->dev, "ld9040 panel driver has been probed.\n");
737         return 0;
738
739 out_unregister_lcd:
740         lcd_device_unregister(lcd->ld);
741 out_free_lcd:
742         kfree(lcd);
743         return ret;
744 }
745
746 static int __devexit ld9040_remove(struct spi_device *spi)
747 {
748         struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
749
750         ld9040_power(lcd, FB_BLANK_POWERDOWN);
751         backlight_device_unregister(lcd->bd);
752         lcd_device_unregister(lcd->ld);
753         kfree(lcd);
754
755         return 0;
756 }
757
758 #if defined(CONFIG_PM)
759 static int ld9040_suspend(struct spi_device *spi, pm_message_t mesg)
760 {
761         int ret = 0;
762         struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
763
764         dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power);
765
766         /*
767          * when lcd panel is suspend, lcd panel becomes off
768          * regardless of status.
769          */
770         ret = ld9040_power(lcd, FB_BLANK_POWERDOWN);
771
772         return ret;
773 }
774
775 static int ld9040_resume(struct spi_device *spi)
776 {
777         int ret = 0;
778         struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
779
780         lcd->power = FB_BLANK_POWERDOWN;
781
782         ret = ld9040_power(lcd, FB_BLANK_UNBLANK);
783
784         return ret;
785 }
786 #else
787 #define ld9040_suspend          NULL
788 #define ld9040_resume           NULL
789 #endif
790
791 /* Power down all displays on reboot, poweroff or halt. */
792 static void ld9040_shutdown(struct spi_device *spi)
793 {
794         struct ld9040 *lcd = dev_get_drvdata(&spi->dev);
795
796         ld9040_power(lcd, FB_BLANK_POWERDOWN);
797 }
798
799 static struct spi_driver ld9040_driver = {
800         .driver = {
801                 .name   = "ld9040",
802                 .bus    = &spi_bus_type,
803                 .owner  = THIS_MODULE,
804         },
805         .probe          = ld9040_probe,
806         .remove         = __devexit_p(ld9040_remove),
807         .shutdown       = ld9040_shutdown,
808         .suspend        = ld9040_suspend,
809         .resume         = ld9040_resume,
810 };
811
812 static int __init ld9040_init(void)
813 {
814         return spi_register_driver(&ld9040_driver);
815 }
816
817 static void __exit ld9040_exit(void)
818 {
819         spi_unregister_driver(&ld9040_driver);
820 }
821
822 module_init(ld9040_init);
823 module_exit(ld9040_exit);
824
825 MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
826 MODULE_DESCRIPTION("ld9040 LCD Driver");
827 MODULE_LICENSE("GPL");