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