blob: 6cdd97c64330a987aba30f7588b24fa16d2c3ac3 [file] [log] [blame]
Bryan Wua9a62b62010-11-17 13:34:33 +00001/*
2 * Generic DPI Panels support
3 *
4 * Copyright (C) 2010 Canonical Ltd.
5 * Author: Bryan Wu <bryan.wu@canonical.com>
6 *
Bryan Wuac1427e2010-11-18 09:45:59 +08007 * LCD panel driver for Sharp LQ043T1DG01
8 *
9 * Copyright (C) 2009 Texas Instruments Inc
10 * Author: Vaibhav Hiremath <hvaibhav@ti.com>
11 *
12 * LCD panel driver for Toppoly TDO35S
13 *
14 * Copyright (C) 2009 CompuLab, Ltd.
15 * Author: Mike Rapoport <mike@compulab.co.il>
16 *
Bryan Wua9a62b62010-11-17 13:34:33 +000017 * Copyright (C) 2008 Nokia Corporation
18 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
19 *
20 * This program is free software; you can redistribute it and/or modify it
21 * under the terms of the GNU General Public License version 2 as published by
22 * the Free Software Foundation.
23 *
24 * This program is distributed in the hope that it will be useful, but WITHOUT
25 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
27 * more details.
28 *
29 * You should have received a copy of the GNU General Public License along with
30 * this program. If not, see <http://www.gnu.org/licenses/>.
31 */
32
33#include <linux/module.h>
34#include <linux/delay.h>
35#include <linux/slab.h>
Tomi Valkeinena0b38cc2011-05-11 14:05:07 +030036#include <video/omapdss.h>
Bryan Wua9a62b62010-11-17 13:34:33 +000037
Tomi Valkeinenf8ae2f02011-05-10 19:48:10 +030038#include <video/omap-panel-generic-dpi.h>
Bryan Wua9a62b62010-11-17 13:34:33 +000039
40struct panel_config {
41 struct omap_video_timings timings;
42
Bryan Wua9a62b62010-11-17 13:34:33 +000043 enum omap_panel_config config;
44
45 int power_on_delay;
46 int power_off_delay;
47
48 /*
49 * Used to match device to panel configuration
50 * when use generic panel driver
51 */
52 const char *name;
53};
54
55/* Panel configurations */
56static struct panel_config generic_dpi_panels[] = {
Bryan Wua9a62b62010-11-17 13:34:33 +000057 /* Sharp LQ043T1DG01 */
58 {
59 {
60 .x_res = 480,
61 .y_res = 272,
62
63 .pixel_clock = 9000,
64
65 .hsw = 42,
66 .hfp = 3,
67 .hbp = 2,
68
69 .vsw = 11,
70 .vfp = 3,
71 .vbp = 2,
Archit Tanejaa8d5e412012-06-25 12:26:38 +053072
73 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
74 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
75 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
76 .de_level = OMAPDSS_SIG_ACTIVE_LOW,
77 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Bryan Wua9a62b62010-11-17 13:34:33 +000078 },
Archit Taneja5ae9eaa2012-06-21 09:41:10 +053079 .config = OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS |
80 OMAP_DSS_LCD_IEO,
Bryan Wua9a62b62010-11-17 13:34:33 +000081 .power_on_delay = 50,
82 .power_off_delay = 100,
83 .name = "sharp_lq",
84 },
85
86 /* Sharp LS037V7DW01 */
87 {
88 {
89 .x_res = 480,
90 .y_res = 640,
91
92 .pixel_clock = 19200,
93
94 .hsw = 2,
95 .hfp = 1,
96 .hbp = 28,
97
98 .vsw = 1,
99 .vfp = 1,
100 .vbp = 1,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530101
102 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
103 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
104 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
105 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
106 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Bryan Wua9a62b62010-11-17 13:34:33 +0000107 },
Archit Taneja5ae9eaa2012-06-21 09:41:10 +0530108 .config = OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS,
Bryan Wua9a62b62010-11-17 13:34:33 +0000109 .power_on_delay = 50,
110 .power_off_delay = 100,
111 .name = "sharp_ls",
112 },
113
114 /* Toppoly TDO35S */
115 {
116 {
117 .x_res = 480,
118 .y_res = 640,
119
120 .pixel_clock = 26000,
121
122 .hfp = 104,
123 .hsw = 8,
124 .hbp = 8,
125
126 .vfp = 4,
127 .vsw = 2,
128 .vbp = 2,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530129
130 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
131 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
132 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
133 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
134 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
Bryan Wua9a62b62010-11-17 13:34:33 +0000135 },
Archit Taneja5ae9eaa2012-06-21 09:41:10 +0530136 .config = OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS |
137 OMAP_DSS_LCD_IPC |
138 OMAP_DSS_LCD_ONOFF,
Bryan Wua9a62b62010-11-17 13:34:33 +0000139 .power_on_delay = 0,
140 .power_off_delay = 0,
141 .name = "toppoly_tdo35s",
142 },
Tomi Valkeinen09dc89c2011-02-22 16:39:47 +0200143
144 /* Samsung LTE430WQ-F0C */
145 {
146 {
147 .x_res = 480,
148 .y_res = 272,
149
150 .pixel_clock = 9200,
151
152 .hfp = 8,
153 .hsw = 41,
154 .hbp = 45 - 41,
155
156 .vfp = 4,
157 .vsw = 10,
158 .vbp = 12 - 10,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530159
160 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
161 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
162 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
163 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
164 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Tomi Valkeinen09dc89c2011-02-22 16:39:47 +0200165 },
Archit Taneja5ae9eaa2012-06-21 09:41:10 +0530166 .config = OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS,
Tomi Valkeinen09dc89c2011-02-22 16:39:47 +0200167 .power_on_delay = 0,
168 .power_off_delay = 0,
169 .name = "samsung_lte430wq_f0c",
170 },
Enric Balletbo i Serra50ca19d2011-05-03 09:07:36 +0200171
172 /* Seiko 70WVW1TZ3Z3 */
173 {
174 {
175 .x_res = 800,
176 .y_res = 480,
177
178 .pixel_clock = 33000,
179
180 .hsw = 128,
181 .hfp = 10,
182 .hbp = 10,
183
184 .vsw = 2,
185 .vfp = 4,
186 .vbp = 11,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530187
188 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
189 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
190 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
191 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
192 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Enric Balletbo i Serra50ca19d2011-05-03 09:07:36 +0200193 },
Archit Taneja5ae9eaa2012-06-21 09:41:10 +0530194 .config = OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS,
Enric Balletbo i Serra50ca19d2011-05-03 09:07:36 +0200195 .power_on_delay = 0,
196 .power_off_delay = 0,
197 .name = "seiko_70wvw1tz3",
198 },
Enric Balletbo i Serraa0ce4cc2011-05-03 09:07:37 +0200199
200 /* Powertip PH480272T */
201 {
202 {
203 .x_res = 480,
204 .y_res = 272,
205
206 .pixel_clock = 9000,
207
208 .hsw = 40,
209 .hfp = 2,
210 .hbp = 2,
211
212 .vsw = 10,
213 .vfp = 2,
214 .vbp = 2,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530215
216 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
217 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
218 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
219 .de_level = OMAPDSS_SIG_ACTIVE_LOW,
220 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Enric Balletbo i Serraa0ce4cc2011-05-03 09:07:37 +0200221 },
Archit Taneja5ae9eaa2012-06-21 09:41:10 +0530222 .config = OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS |
223 OMAP_DSS_LCD_IEO,
Enric Balletbo i Serraa0ce4cc2011-05-03 09:07:37 +0200224 .power_on_delay = 0,
225 .power_off_delay = 0,
226 .name = "powertip_ph480272t",
227 },
Thomas Weber1e497c42011-09-01 15:05:07 +0200228
229 /* Innolux AT070TN83 */
230 {
231 {
232 .x_res = 800,
233 .y_res = 480,
234
235 .pixel_clock = 40000,
236
237 .hsw = 48,
238 .hfp = 1,
239 .hbp = 1,
240
241 .vsw = 3,
242 .vfp = 12,
243 .vbp = 25,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530244
245 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
246 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
247 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
248 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
249 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Thomas Weber1e497c42011-09-01 15:05:07 +0200250 },
Archit Taneja5ae9eaa2012-06-21 09:41:10 +0530251 .config = OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS,
Thomas Weber1e497c42011-09-01 15:05:07 +0200252 .power_on_delay = 0,
253 .power_off_delay = 0,
254 .name = "innolux_at070tn83",
255 },
Tomi Valkeinen3fddbf52011-04-19 19:23:05 +0300256
257 /* NEC NL2432DR22-11B */
258 {
259 {
260 .x_res = 240,
261 .y_res = 320,
262
263 .pixel_clock = 5400,
264
265 .hsw = 3,
266 .hfp = 3,
267 .hbp = 39,
268
269 .vsw = 1,
270 .vfp = 2,
271 .vbp = 7,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530272
273 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
274 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
275 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
276 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
277 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Tomi Valkeinen3fddbf52011-04-19 19:23:05 +0300278 },
Archit Taneja5ae9eaa2012-06-21 09:41:10 +0530279 .config = OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS,
Tomi Valkeinen3fddbf52011-04-19 19:23:05 +0300280 .name = "nec_nl2432dr22-11b",
281 },
Tomi Valkeinen8a41ba92011-04-19 19:59:58 +0300282
283 /* Unknown panel used in OMAP H4 */
284 {
285 {
286 .x_res = 240,
287 .y_res = 320,
288
289 .pixel_clock = 6250,
290
291 .hsw = 15,
292 .hfp = 15,
293 .hbp = 60,
294
295 .vsw = 1,
296 .vfp = 1,
297 .vbp = 1,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530298
299 .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
300 .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
301 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
302 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
303 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Tomi Valkeinen8a41ba92011-04-19 19:59:58 +0300304 },
Tomi Valkeinen8a41ba92011-04-19 19:59:58 +0300305 .name = "h4",
306 },
Tomi Valkeinen8d49fe72011-04-20 10:47:28 +0300307
308 /* Unknown panel used in Samsung OMAP2 Apollon */
309 {
310 {
311 .x_res = 480,
312 .y_res = 272,
313
314 .pixel_clock = 6250,
315
316 .hsw = 41,
317 .hfp = 2,
318 .hbp = 2,
319
320 .vsw = 10,
321 .vfp = 2,
322 .vbp = 2,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530323
324 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
325 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
326 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
327 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
328 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Tomi Valkeinen8d49fe72011-04-20 10:47:28 +0300329 },
Archit Taneja5ae9eaa2012-06-21 09:41:10 +0530330 .config = OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS,
Tomi Valkeinen8d49fe72011-04-20 10:47:28 +0300331
332 .name = "apollon",
333 },
Ilya Yanoka47161a2011-11-20 19:15:39 +0100334 /* FocalTech ETM070003DH6 */
335 {
336 {
337 .x_res = 800,
338 .y_res = 480,
339
340 .pixel_clock = 28000,
341
342 .hsw = 48,
343 .hfp = 40,
344 .hbp = 40,
345
346 .vsw = 3,
347 .vfp = 13,
348 .vbp = 29,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530349
350 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
351 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
352 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
353 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
354 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Ilya Yanoka47161a2011-11-20 19:15:39 +0100355 },
Archit Taneja5ae9eaa2012-06-21 09:41:10 +0530356 .config = OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS,
Ilya Yanoka47161a2011-11-20 19:15:39 +0100357 .name = "focaltech_etm070003dh6",
358 },
Daniel Mack62941ec2011-12-20 10:54:32 +0100359
360 /* Microtips Technologies - UMSH-8173MD */
361 {
362 {
363 .x_res = 800,
364 .y_res = 480,
365
366 .pixel_clock = 34560,
367
368 .hsw = 13,
369 .hfp = 101,
370 .hbp = 101,
371
372 .vsw = 23,
373 .vfp = 1,
374 .vbp = 1,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530375
376 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
377 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
378 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
379 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
380 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Daniel Mack62941ec2011-12-20 10:54:32 +0100381 },
Archit Taneja5ae9eaa2012-06-21 09:41:10 +0530382 .config = OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS |
383 OMAP_DSS_LCD_IPC,
Daniel Mack62941ec2011-12-20 10:54:32 +0100384 .power_on_delay = 0,
385 .power_off_delay = 0,
386 .name = "microtips_umsh_8173md",
387 },
Ilya Yanok6acea9c2011-12-26 23:56:41 +0100388
389 /* OrtusTech COM43H4M10XTC */
390 {
391 {
392 .x_res = 480,
393 .y_res = 272,
394
395 .pixel_clock = 8000,
396
397 .hsw = 41,
398 .hfp = 8,
399 .hbp = 4,
400
401 .vsw = 10,
402 .vfp = 4,
403 .vbp = 2,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530404
405 .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
406 .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
407 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
408 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
409 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Ilya Yanok6acea9c2011-12-26 23:56:41 +0100410 },
Ilya Yanok6acea9c2011-12-26 23:56:41 +0100411 .name = "ortustech_com43h4m10xtc",
412 },
Yegor Yefremov992ee642012-02-08 11:11:08 +0100413
414 /* Innolux AT080TN52 */
415 {
416 {
417 .x_res = 800,
418 .y_res = 600,
419
420 .pixel_clock = 41142,
421
422 .hsw = 20,
423 .hfp = 210,
424 .hbp = 46,
425
426 .vsw = 10,
427 .vfp = 12,
428 .vbp = 23,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530429
430 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
431 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
432 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
433 .de_level = OMAPDSS_SIG_ACTIVE_LOW,
434 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Yegor Yefremov992ee642012-02-08 11:11:08 +0100435 },
Archit Taneja5ae9eaa2012-06-21 09:41:10 +0530436 .config = OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS |
437 OMAP_DSS_LCD_IEO,
Yegor Yefremov992ee642012-02-08 11:11:08 +0100438
439 .name = "innolux_at080tn52",
440 },
Thomas Weber697bacb2012-02-17 13:41:58 +0100441
442 /* Mitsubishi AA084SB01 */
443 {
444 {
445 .x_res = 800,
446 .y_res = 600,
447 .pixel_clock = 40000,
448
449 .hsw = 1,
450 .hfp = 254,
451 .hbp = 1,
452
453 .vsw = 1,
454 .vfp = 26,
455 .vbp = 1,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530456
457 .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
458 .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
459 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
460 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
461 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Thomas Weber697bacb2012-02-17 13:41:58 +0100462 },
Thomas Weber697bacb2012-02-17 13:41:58 +0100463 .name = "mitsubishi_aa084sb01",
464 },
Thomas Webere97374c2012-02-17 13:41:59 +0100465 /* EDT ET0500G0DH6 */
466 {
467 {
468 .x_res = 800,
469 .y_res = 480,
470 .pixel_clock = 33260,
471
472 .hsw = 128,
473 .hfp = 216,
474 .hbp = 40,
475
476 .vsw = 2,
477 .vfp = 35,
478 .vbp = 10,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530479
480 .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
481 .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
482 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
483 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
484 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Thomas Webere97374c2012-02-17 13:41:59 +0100485 },
Thomas Webere97374c2012-02-17 13:41:59 +0100486 .name = "edt_et0500g0dh6",
487 },
Jan Weitzel3dd606e2012-04-20 11:41:22 +0200488
489 /* Prime-View PD050VL1 */
490 {
491 {
492 .x_res = 640,
493 .y_res = 480,
494
495 .pixel_clock = 25000,
496
497 .hsw = 96,
498 .hfp = 18,
499 .hbp = 46,
500
501 .vsw = 2,
502 .vfp = 10,
503 .vbp = 33,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530504
505 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
506 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
507 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
508 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
509 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Jan Weitzel3dd606e2012-04-20 11:41:22 +0200510 },
Archit Taneja5ae9eaa2012-06-21 09:41:10 +0530511 .config = OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS |
512 OMAP_DSS_LCD_IPC,
Jan Weitzel3dd606e2012-04-20 11:41:22 +0200513 .name = "primeview_pd050vl1",
514 },
515
516 /* Prime-View PM070WL4 */
517 {
518 {
519 .x_res = 800,
520 .y_res = 480,
521
522 .pixel_clock = 32000,
523
524 .hsw = 128,
525 .hfp = 42,
526 .hbp = 86,
527
528 .vsw = 2,
529 .vfp = 10,
530 .vbp = 33,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530531
532 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
533 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
534 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
535 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
536 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Jan Weitzel3dd606e2012-04-20 11:41:22 +0200537 },
Archit Taneja5ae9eaa2012-06-21 09:41:10 +0530538 .config = OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS |
539 OMAP_DSS_LCD_IPC,
Jan Weitzel3dd606e2012-04-20 11:41:22 +0200540 .name = "primeview_pm070wl4",
541 },
542
543 /* Prime-View PD104SLF */
544 {
545 {
546 .x_res = 800,
547 .y_res = 600,
548
549 .pixel_clock = 40000,
550
551 .hsw = 128,
552 .hfp = 42,
553 .hbp = 86,
554
555 .vsw = 4,
556 .vfp = 1,
557 .vbp = 23,
Archit Tanejaa8d5e412012-06-25 12:26:38 +0530558
559 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
560 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
561 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
562 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
563 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
Jan Weitzel3dd606e2012-04-20 11:41:22 +0200564 },
Archit Taneja5ae9eaa2012-06-21 09:41:10 +0530565 .config = OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS |
566 OMAP_DSS_LCD_IPC,
Jan Weitzel3dd606e2012-04-20 11:41:22 +0200567 .name = "primeview_pd104slf",
568 },
Bryan Wua9a62b62010-11-17 13:34:33 +0000569};
570
571struct panel_drv_data {
572
573 struct omap_dss_device *dssdev;
574
575 struct panel_config *panel_config;
576};
577
578static inline struct panel_generic_dpi_data
579*get_panel_data(const struct omap_dss_device *dssdev)
580{
581 return (struct panel_generic_dpi_data *) dssdev->data;
582}
583
584static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
585{
586 int r;
587 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
588 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
589 struct panel_config *panel_config = drv_data->panel_config;
590
591 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
592 return 0;
593
594 r = omapdss_dpi_display_enable(dssdev);
595 if (r)
596 goto err0;
597
598 /* wait couple of vsyncs until enabling the LCD */
599 if (panel_config->power_on_delay)
600 msleep(panel_config->power_on_delay);
601
602 if (panel_data->platform_enable) {
603 r = panel_data->platform_enable(dssdev);
604 if (r)
605 goto err1;
606 }
607
608 return 0;
609err1:
610 omapdss_dpi_display_disable(dssdev);
611err0:
612 return r;
613}
614
615static void generic_dpi_panel_power_off(struct omap_dss_device *dssdev)
616{
617 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
618 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
619 struct panel_config *panel_config = drv_data->panel_config;
620
621 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
622 return;
623
624 if (panel_data->platform_disable)
625 panel_data->platform_disable(dssdev);
626
627 /* wait couple of vsyncs after disabling the LCD */
628 if (panel_config->power_off_delay)
629 msleep(panel_config->power_off_delay);
630
631 omapdss_dpi_display_disable(dssdev);
632}
633
634static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
635{
636 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
637 struct panel_config *panel_config = NULL;
638 struct panel_drv_data *drv_data = NULL;
639 int i;
640
641 dev_dbg(&dssdev->dev, "probe\n");
642
643 if (!panel_data || !panel_data->name)
644 return -EINVAL;
645
646 for (i = 0; i < ARRAY_SIZE(generic_dpi_panels); i++) {
647 if (strcmp(panel_data->name, generic_dpi_panels[i].name) == 0) {
648 panel_config = &generic_dpi_panels[i];
649 break;
650 }
651 }
652
653 if (!panel_config)
654 return -EINVAL;
655
656 dssdev->panel.config = panel_config->config;
657 dssdev->panel.timings = panel_config->timings;
Bryan Wua9a62b62010-11-17 13:34:33 +0000658
659 drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL);
660 if (!drv_data)
661 return -ENOMEM;
662
663 drv_data->dssdev = dssdev;
664 drv_data->panel_config = panel_config;
665
666 dev_set_drvdata(&dssdev->dev, drv_data);
667
668 return 0;
669}
670
Tomi Valkeinen14e4d782011-03-31 12:03:51 +0300671static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev)
Bryan Wua9a62b62010-11-17 13:34:33 +0000672{
673 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
674
675 dev_dbg(&dssdev->dev, "remove\n");
676
677 kfree(drv_data);
678
679 dev_set_drvdata(&dssdev->dev, NULL);
680}
681
682static int generic_dpi_panel_enable(struct omap_dss_device *dssdev)
683{
684 int r = 0;
685
686 r = generic_dpi_panel_power_on(dssdev);
687 if (r)
688 return r;
689
690 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
691
692 return 0;
693}
694
695static void generic_dpi_panel_disable(struct omap_dss_device *dssdev)
696{
697 generic_dpi_panel_power_off(dssdev);
698
699 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
700}
701
702static int generic_dpi_panel_suspend(struct omap_dss_device *dssdev)
703{
704 generic_dpi_panel_power_off(dssdev);
705
706 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
707
708 return 0;
709}
710
711static int generic_dpi_panel_resume(struct omap_dss_device *dssdev)
712{
713 int r = 0;
714
715 r = generic_dpi_panel_power_on(dssdev);
716 if (r)
717 return r;
718
719 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
720
721 return 0;
722}
723
724static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
725 struct omap_video_timings *timings)
726{
727 dpi_set_timings(dssdev, timings);
728}
729
Bryan Wua9a62b62010-11-17 13:34:33 +0000730static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
731 struct omap_video_timings *timings)
732{
733 return dpi_check_timings(dssdev, timings);
734}
735
736static struct omap_dss_driver dpi_driver = {
737 .probe = generic_dpi_panel_probe,
Tomi Valkeinen14e4d782011-03-31 12:03:51 +0300738 .remove = __exit_p(generic_dpi_panel_remove),
Bryan Wua9a62b62010-11-17 13:34:33 +0000739
740 .enable = generic_dpi_panel_enable,
741 .disable = generic_dpi_panel_disable,
742 .suspend = generic_dpi_panel_suspend,
743 .resume = generic_dpi_panel_resume,
744
745 .set_timings = generic_dpi_panel_set_timings,
Bryan Wua9a62b62010-11-17 13:34:33 +0000746 .check_timings = generic_dpi_panel_check_timings,
747
748 .driver = {
749 .name = "generic_dpi_panel",
750 .owner = THIS_MODULE,
751 },
752};
753
754static int __init generic_dpi_panel_drv_init(void)
755{
756 return omap_dss_register_driver(&dpi_driver);
757}
758
759static void __exit generic_dpi_panel_drv_exit(void)
760{
761 omap_dss_unregister_driver(&dpi_driver);
762}
763
764module_init(generic_dpi_panel_drv_init);
765module_exit(generic_dpi_panel_drv_exit);
766MODULE_LICENSE("GPL");