]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/video/omap/lcd_p2.c
Merge with /home/tmlind/src/kernel/linux-2.6
[linux-2.6-omap-h63xx.git] / drivers / video / omap / lcd_p2.c
1 /*
2  * File: drivers/video/omap/lcd-p2.c
3  *
4  * LCD panel support for the TI OMAP P2 board
5  *
6  * Authors:
7  *   jekyll <jekyll@mail.jekyll.idv.tw>
8  *   B Jp <lastjp_fr@yahoo.fr>
9  *   Brian Swetland <swetland@android.com>
10  *
11  * This program is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU General Public License as published by the
13  * Free Software Foundation; either version 2 of the License, or (at your
14  * option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #include <linux/module.h>
27 #include <linux/delay.h>
28 #include <linux/platform_device.h>
29
30 #include <asm/arch/mux.h>
31 #include <asm/arch/gpio.h>
32 #include <asm/arch/omapfb.h>
33
34 /*
35  * File: epson-md-tft.h
36  *
37  * This file contains definitions for Epsons MD-TF LCD Module
38  *
39  * Copyright (C) 2004 MPC-Data Limited  (http://www.mpc-data.co.uk)
40  * Author: Dave Peverley <dpeverley at mpc-data.co.uk>
41  *
42  *  This program is free software; you can redistribute  it and/or modify it
43  *  under  the terms of  the GNU General  Public License as published by the
44  *  Free Software Foundation;  either version 2 of the  License, or (at your
45  *  option) any later version.
46  *
47  *  THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED
48  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
49  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
50  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
51  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
52  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
53  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
54  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
55  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
56  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57  *
58  *  You should have received a copy of the  GNU General Public License along
59  *  with this program; if not, write  to the Free Software Foundation, Inc.,
60  *  675 Mass Ave, Cambridge, MA 02139, USA.
61  *
62  * Please report all bugs and problems to the author.
63  *
64  */
65
66 /* LCD uWire commands & params
67  * All values from Epson
68  */
69 #define LCD_DISON 0xAF
70 #define LCD_DISOFF 0xAE
71 #define LCD_DISNOR 0xA6
72 #define LCD_DISINV 0xA7
73 #define LCD_DISCTL 0xCA
74 #define LCD_GCP64 0xCB
75 #define LCD_GCP16 0xCC
76 #define LCD_GSSET 0xCD
77 #define LCD_SLPIN 0x95
78 #define LCD_SLPOUT 0x94
79 #define LCD_SD_PSET 0x75
80 #define LCD_MD_PSET 0x76
81 #define LCD_SD_CSET 0x15
82 #define LCD_MD_CSET 0x16
83 #define LCD_DATCTL 0xBC
84 #define LCD_RAMWR 0x5C
85 #define LCD_RAMRD 0x5D
86 #define LCD_PTLIN 0xA8
87 #define LCD_PTLOUT 0xA9
88 #define LCD_ASCSET 0xAA
89 #define LCD_SCSTART 0xAB
90 #define LCD_VOLCTL 0xC6
91 #define LCD_NOP 0x25
92 #define LCD_OSCISEL 0x7
93 #define LCD_3500KSET 0xD1
94 #define LCD_3500KEND 0xD2
95 #define LCD_14MSET 0xD3
96 #define LCD_14MEND 0xD4
97
98 #define INIT_3500KSET 0x45
99 #define INIT_14MSET 0x4B
100 #define INIT_DATCTL 0x08 /* 6.6.6 bits for D-Sample */
101
102 #define INIT_OSCISEL 0x05
103
104 #define INIT_VOLCTL 0x77 /* Nominel "volume" */
105
106 #define INIT_VOLCTL_Ton 0x98 /* Activate power-IC timer */
107 #define INIT_GSSET 0x00
108
109 const unsigned short INIT_DISCTL[11] =
110 {
111         0xDE, 0x01, 0x64, 0x00, 0x1B, 0xF4, 0x00, 0xDC, 0x00, 0x02, 0x00
112 };
113
114 const unsigned short INIT_GCP64[126] =
115 {
116         0x3B,0x00,0x42,0x00,0x4A,0x00,0x51,0x00,
117         0x58,0x00,0x5F,0x00,0x66,0x00,0x6E,0x00,
118         0x75,0x00,0x7C,0x00,0x83,0x00,0x8A,0x00,
119         0x92,0x00,0x99,0x00,0xA0,0x00,0xA7,0x00,
120         0xAE,0x00,0xB6,0x00,0xBD,0x00,0xC4,0x00,
121         0xCB,0x00,0xD2,0x00,0xDA,0x00,0xE1,0x00,
122         0xE8,0x00,0xEF,0x00,0xF6,0x00,0xFE,0x00,
123         0x05,0x01,0x0C,0x01,0x13,0x01,0x1A,0x01,
124         0x22,0x01,0x29,0x01,0x30,0x01,0x37,0x01,
125         0x3E,0x01,0x46,0x01,0x4D,0x01,0x54,0x01,
126         0x5B,0x01,0x62,0x01,0x6A,0x01,0x71,0x01,
127         0x78,0x01,0x7F,0x01,0x86,0x01,0x8E,0x01,
128         0x95,0x01,0x9C,0x01,0xA3,0x01,0xAA,0x01,
129         0xB2,0x01,0xB9,0x01,0xC0,0x01,0xC7,0x01,
130         0xCE,0x01,0xD6,0x01,0xDD,0x01,0xE4,0x01,
131         0xEB,0x01,0xF2,0x01,0xFA,0x01
132 };
133
134 const unsigned short INIT_GCP16[15] =
135 {
136         0x1A,0x31,0x48,0x54,0x5F,0x67,0x70,0x76,0x7C,0x80,0x83,0x84,0x85,0x87,0x96
137 };
138
139 const unsigned short INIT_MD_PSET[4] = { 0, 0, 219, 0 };
140 const unsigned short INIT_MD_CSET[4] = { 2, 0, 177, 0 };
141
142 const unsigned short INIT_SD_PSET[4] = { 0x00, 0x01, 0x00, 0x01 };
143 const unsigned short INIT_SD_CSET[4] = { 0x00, 0x02, 0x00, 0x02 };
144
145 const unsigned short INIT_ASCSET[7] = { 0x00, 0x00, 0xDB, 0x00, 0xDC, 0x00, 0x01 };
146 const unsigned short INIT_SCSTART[2] = { 0x00, 0x00 };
147
148 /* ----- end of epson_md_tft.h ----- */
149
150
151 #include "debug.h"
152 #include "../drivers/ssi/omap-uwire.h"
153
154 #define LCD_UWIRE_CS 0
155
156 static int p2_panel_init(struct omapfb_device *fbdev)
157 {
158         DBGENTER(1);
159         DBGLEAVE(1);
160         return 0;
161 }
162
163 static void p2_panel_cleanup(void)
164 {
165         DBGENTER(1);
166         DBGLEAVE(1);
167 }
168
169 static int p2_panel_enable(void)
170 {
171         int i;
172         unsigned long value;
173         DBGENTER(1);
174
175                 /* thwack the reset line */
176         omap_set_gpio_direction(19, 0);
177         omap_set_gpio_dataout(19, 0);
178         mdelay(2);
179         omap_set_gpio_dataout(19, 1);
180
181                 /* bits 31:28 -> 0  LCD_PXL_15 .. 12 */
182         value = omap_readl(OMAP730_IO_CONF_3) & 0x0FFFFFFF;
183         omap_writel(value, OMAP730_IO_CONF_3);
184
185                 /* bits 19:0 -> 0  LCD_VSYNC, AC, PXL_0, PCLK, HSYNC,
186                 **                 PXL_9..1, PXL_10, PXL_11
187                 */
188         value = omap_readl(OMAP730_IO_CONF_4) & 0xFFF00000;
189         omap_writel(value, OMAP730_IO_CONF_4);
190
191         omap_uwire_configure_mode(0,16);
192
193         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_DISOFF, 9, 0,NULL,1);
194         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_SLPIN, 9, 0,NULL,1);
195         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_DISNOR, 9, 0,NULL,1);
196         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_GSSET, 9, 0,NULL,1);
197         omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_GSSET | 0x100), 9, 0,NULL,1);
198
199         /* DISCTL */
200         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_DISCTL, 9, 0,NULL,1);
201         for (i = 0; i < (sizeof(INIT_DISCTL)/sizeof(unsigned short)); i++)
202                 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_DISCTL[i] | 0x100), 9, 0,NULL,1);
203
204         /* GCP64 */
205         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_GCP64, 9, 0,NULL,1);
206         for (i = 0; i < (sizeof(INIT_GCP64)/sizeof(unsigned short)); i++)
207                 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_GCP64[i] | 0x100), 9, 0,NULL,1);
208
209         /* GCP16 */
210         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_GCP16, 9, 0,NULL,1);
211         for (i = 0; i < (sizeof(INIT_GCP16)/sizeof(unsigned short)); i++)
212                 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_GCP16[i] | 0x100), 9, 0,NULL,1);
213
214         /* MD_CSET */
215         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_MD_CSET, 9, 0,NULL,1);
216         for (i = 0; i < (sizeof(INIT_MD_CSET)/sizeof(unsigned short)); i++)
217                 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_MD_CSET[i] | 0x100), 9, 0,NULL,1);
218
219         /* MD_PSET */
220         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_MD_PSET, 9, 0,NULL,1);
221         for (i = 0; i < (sizeof(INIT_MD_PSET)/sizeof(unsigned short)); i++)
222                 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_MD_PSET[i] | 0x100), 9, 0,NULL,1);
223
224         /* SD_CSET */
225         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_SD_CSET, 9, 0,NULL,1);
226         for (i = 0; i < (sizeof(INIT_SD_CSET)/sizeof(unsigned short)); i++)
227                 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_SD_CSET[i] | 0x100), 9, 0,NULL,1);
228
229         /* SD_PSET */
230         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_SD_PSET, 9, 0,NULL,1);
231         for (i = 0; i < (sizeof(INIT_SD_PSET)/sizeof(unsigned short)); i++)
232                 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_SD_PSET[i] | 0x100), 9, 0,NULL,1);
233
234         /* DATCTL */
235         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_DATCTL, 9, 0,NULL,1);
236         omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_DATCTL | 0x100), 9, 0,NULL,1);
237
238         /* OSSISEL = d'5 */
239         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_OSCISEL, 9, 0,NULL,1);
240         omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_OSCISEL | 0x100), 9, 0,NULL,1);
241
242         /* 14MSET = d'74 */
243         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_14MSET, 9, 0,NULL,1);
244         omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_14MSET | 0x100), 9, 0,NULL,1);
245
246         /* 14MEND */
247         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_14MEND, 9, 0,NULL,1);
248
249         /* 3500KSET = d'69 */
250         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_3500KSET, 9, 0,NULL,1);
251         omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_3500KSET | 0x100), 9, 0,NULL,1);
252
253         /* 3500KEND */
254         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_3500KEND, 9, 0,NULL,1);
255
256         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_SLPOUT, 9, 0,NULL,1);
257
258         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_VOLCTL, 9, 0,NULL,1);
259         omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_VOLCTL_Ton | 0x100), 9, 0,NULL,1);
260
261         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_VOLCTL, 9, 0,NULL,1);
262
263         omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_VOLCTL | 0x100), 9, 0,NULL,1);
264
265         omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_DISON, 9, 0,NULL,1);
266
267         /* enable backlight */
268         omap_set_gpio_direction(134, 0);
269         omap_set_gpio_dataout(134, 1);
270
271         DBGLEAVE(1);
272         return 0;
273 }
274
275 static void p2_panel_disable(void)
276 {
277         DBGENTER(1);
278         DBGLEAVE(1);
279 }
280
281 static unsigned long p2_panel_get_caps(void)
282 {
283         return 0;
284 }
285
286 struct lcd_panel p2_panel = {
287         .name           = "p2",
288         .config         = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_PIX_CLOCK,
289
290         .bpp            = 16,
291         .data_lines     = 16,
292         .x_res          = 176,
293         .y_res          = 220,
294         .pixel_clock    = 12500,
295         .hsw            = 5,
296         .hfp            = 1,
297         .hbp            = 1,
298         .vsw            = 2,
299         .vfp            = 12,
300         .vbp            = 1,
301
302         .init           = p2_panel_init,
303         .cleanup        = p2_panel_cleanup,
304         .enable         = p2_panel_enable,
305         .disable        = p2_panel_disable,
306         .get_caps       = p2_panel_get_caps,
307 };
308
309 static int p2_panel_probe(struct platform_device *pdev)
310 {
311         DBGENTER(1);
312         omapfb_register_panel(&p2_panel);
313         return 0;
314 }
315
316 static int p2_panel_remove(struct platform_device *pdev)
317 {
318         DBGENTER(1);
319         return 0;
320 }
321
322 static int p2_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
323 {
324         DBGENTER(1);
325         return 0;
326 }
327
328 static int p2_panel_resume(struct platform_device *pdev)
329 {
330         DBGENTER(1);
331         return 0;
332 }
333
334 struct platform_driver p2_panel_driver = {
335         .probe          = p2_panel_probe,
336         .remove         = p2_panel_remove,
337         .suspend        = p2_panel_suspend,
338         .resume         = p2_panel_resume,
339         .driver         = {
340                 .name   = "lcd_p2",
341                 .owner  = THIS_MODULE,
342         },
343 };
344
345 static int p2_panel_drv_init(void)
346 {
347         return platform_driver_register(&p2_panel_driver);
348 }
349
350 static void p2_panel_drv_cleanup(void)
351 {
352         platform_driver_unregister(&p2_panel_driver);
353 }
354
355 module_init(p2_panel_drv_init);
356 module_exit(p2_panel_drv_cleanup);
357