2 * LCD panel support for the TI OMAP P2 board
5 * jekyll <jekyll@mail.jekyll.idv.tw>
6 * B Jp <lastjp_fr@yahoo.fr>
7 * Brian Swetland <swetland@android.com>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include <linux/module.h>
25 #include <linux/delay.h>
26 #include <linux/platform_device.h>
29 #include <mach/gpio.h>
30 #include <mach/omapfb.h>
33 * File: epson-md-tft.h
35 * This file contains definitions for Epsons MD-TF LCD Module
37 * Copyright (C) 2004 MPC-Data Limited (http://www.mpc-data.co.uk)
38 * Author: Dave Peverley <dpeverley at mpc-data.co.uk>
40 * This program is free software; you can redistribute it and/or modify it
41 * under the terms of the GNU General Public License as published by the
42 * Free Software Foundation; either version 2 of the License, or (at your
43 * option) any later version.
45 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
46 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
47 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
48 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
49 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
51 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
52 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
53 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
54 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 * You should have received a copy of the GNU General Public License along
57 * with this program; if not, write to the Free Software Foundation, Inc.,
58 * 675 Mass Ave, Cambridge, MA 02139, USA.
60 * Please report all bugs and problems to the author.
64 /* LCD uWire commands & params
65 * All values from Epson
67 #define LCD_DISON 0xAF
68 #define LCD_DISOFF 0xAE
69 #define LCD_DISNOR 0xA6
70 #define LCD_DISINV 0xA7
71 #define LCD_DISCTL 0xCA
72 #define LCD_GCP64 0xCB
73 #define LCD_GCP16 0xCC
74 #define LCD_GSSET 0xCD
75 #define LCD_SLPIN 0x95
76 #define LCD_SLPOUT 0x94
77 #define LCD_SD_PSET 0x75
78 #define LCD_MD_PSET 0x76
79 #define LCD_SD_CSET 0x15
80 #define LCD_MD_CSET 0x16
81 #define LCD_DATCTL 0xBC
82 #define LCD_RAMWR 0x5C
83 #define LCD_RAMRD 0x5D
84 #define LCD_PTLIN 0xA8
85 #define LCD_PTLOUT 0xA9
86 #define LCD_ASCSET 0xAA
87 #define LCD_SCSTART 0xAB
88 #define LCD_VOLCTL 0xC6
90 #define LCD_OSCISEL 0x7
91 #define LCD_3500KSET 0xD1
92 #define LCD_3500KEND 0xD2
93 #define LCD_14MSET 0xD3
94 #define LCD_14MEND 0xD4
96 #define INIT_3500KSET 0x45
97 #define INIT_14MSET 0x4B
98 #define INIT_DATCTL 0x08 /* 6.6.6 bits for D-Sample */
100 #define INIT_OSCISEL 0x05
102 #define INIT_VOLCTL 0x77 /* Nominel "volume" */
104 #define INIT_VOLCTL_Ton 0x98 /* Activate power-IC timer */
105 #define INIT_GSSET 0x00
107 const unsigned short INIT_DISCTL[11] =
109 0xDE, 0x01, 0x64, 0x00, 0x1B, 0xF4, 0x00, 0xDC, 0x00, 0x02, 0x00
112 const unsigned short INIT_GCP64[126] =
114 0x3B,0x00,0x42,0x00,0x4A,0x00,0x51,0x00,
115 0x58,0x00,0x5F,0x00,0x66,0x00,0x6E,0x00,
116 0x75,0x00,0x7C,0x00,0x83,0x00,0x8A,0x00,
117 0x92,0x00,0x99,0x00,0xA0,0x00,0xA7,0x00,
118 0xAE,0x00,0xB6,0x00,0xBD,0x00,0xC4,0x00,
119 0xCB,0x00,0xD2,0x00,0xDA,0x00,0xE1,0x00,
120 0xE8,0x00,0xEF,0x00,0xF6,0x00,0xFE,0x00,
121 0x05,0x01,0x0C,0x01,0x13,0x01,0x1A,0x01,
122 0x22,0x01,0x29,0x01,0x30,0x01,0x37,0x01,
123 0x3E,0x01,0x46,0x01,0x4D,0x01,0x54,0x01,
124 0x5B,0x01,0x62,0x01,0x6A,0x01,0x71,0x01,
125 0x78,0x01,0x7F,0x01,0x86,0x01,0x8E,0x01,
126 0x95,0x01,0x9C,0x01,0xA3,0x01,0xAA,0x01,
127 0xB2,0x01,0xB9,0x01,0xC0,0x01,0xC7,0x01,
128 0xCE,0x01,0xD6,0x01,0xDD,0x01,0xE4,0x01,
129 0xEB,0x01,0xF2,0x01,0xFA,0x01
132 const unsigned short INIT_GCP16[15] =
134 0x1A,0x31,0x48,0x54,0x5F,0x67,0x70,0x76,0x7C,0x80,0x83,0x84,0x85,0x87,0x96
137 const unsigned short INIT_MD_PSET[4] = { 0, 0, 219, 0 };
138 const unsigned short INIT_MD_CSET[4] = { 2, 0, 177, 0 };
140 const unsigned short INIT_SD_PSET[4] = { 0x00, 0x01, 0x00, 0x01 };
141 const unsigned short INIT_SD_CSET[4] = { 0x00, 0x02, 0x00, 0x02 };
143 const unsigned short INIT_ASCSET[7] = { 0x00, 0x00, 0xDB, 0x00, 0xDC, 0x00, 0x01 };
144 const unsigned short INIT_SCSTART[2] = { 0x00, 0x00 };
146 /* ----- end of epson_md_tft.h ----- */
149 #include "../drivers/ssi/omap-uwire.h"
151 #define LCD_UWIRE_CS 0
153 static int p2_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
158 static void p2_panel_cleanup(struct lcd_panel *panel)
162 static int p2_panel_enable(struct lcd_panel *panel)
167 /* thwack the reset line */
168 omap_set_gpio_direction(19, 0);
169 omap_set_gpio_dataout(19, 0);
171 omap_set_gpio_dataout(19, 1);
173 /* bits 31:28 -> 0 LCD_PXL_15 .. 12 */
174 value = omap_readl(OMAP730_IO_CONF_3) & 0x0FFFFFFF;
175 omap_writel(value, OMAP730_IO_CONF_3);
177 /* bits 19:0 -> 0 LCD_VSYNC, AC, PXL_0, PCLK, HSYNC,
178 ** PXL_9..1, PXL_10, PXL_11
180 value = omap_readl(OMAP730_IO_CONF_4) & 0xFFF00000;
181 omap_writel(value, OMAP730_IO_CONF_4);
183 omap_uwire_configure_mode(0,16);
185 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_DISOFF, 9, 0,NULL,1);
186 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_SLPIN, 9, 0,NULL,1);
187 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_DISNOR, 9, 0,NULL,1);
188 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_GSSET, 9, 0,NULL,1);
189 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_GSSET | 0x100), 9, 0,NULL,1);
192 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_DISCTL, 9, 0,NULL,1);
193 for (i = 0; i < (sizeof(INIT_DISCTL)/sizeof(unsigned short)); i++)
194 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_DISCTL[i] | 0x100), 9, 0,NULL,1);
197 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_GCP64, 9, 0,NULL,1);
198 for (i = 0; i < (sizeof(INIT_GCP64)/sizeof(unsigned short)); i++)
199 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_GCP64[i] | 0x100), 9, 0,NULL,1);
202 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_GCP16, 9, 0,NULL,1);
203 for (i = 0; i < (sizeof(INIT_GCP16)/sizeof(unsigned short)); i++)
204 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_GCP16[i] | 0x100), 9, 0,NULL,1);
207 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_MD_CSET, 9, 0,NULL,1);
208 for (i = 0; i < (sizeof(INIT_MD_CSET)/sizeof(unsigned short)); i++)
209 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_MD_CSET[i] | 0x100), 9, 0,NULL,1);
212 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_MD_PSET, 9, 0,NULL,1);
213 for (i = 0; i < (sizeof(INIT_MD_PSET)/sizeof(unsigned short)); i++)
214 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_MD_PSET[i] | 0x100), 9, 0,NULL,1);
217 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_SD_CSET, 9, 0,NULL,1);
218 for (i = 0; i < (sizeof(INIT_SD_CSET)/sizeof(unsigned short)); i++)
219 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_SD_CSET[i] | 0x100), 9, 0,NULL,1);
222 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_SD_PSET, 9, 0,NULL,1);
223 for (i = 0; i < (sizeof(INIT_SD_PSET)/sizeof(unsigned short)); i++)
224 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_SD_PSET[i] | 0x100), 9, 0,NULL,1);
227 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_DATCTL, 9, 0,NULL,1);
228 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_DATCTL | 0x100), 9, 0,NULL,1);
231 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_OSCISEL, 9, 0,NULL,1);
232 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_OSCISEL | 0x100), 9, 0,NULL,1);
235 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_14MSET, 9, 0,NULL,1);
236 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_14MSET | 0x100), 9, 0,NULL,1);
239 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_14MEND, 9, 0,NULL,1);
241 /* 3500KSET = d'69 */
242 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_3500KSET, 9, 0,NULL,1);
243 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_3500KSET | 0x100), 9, 0,NULL,1);
246 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_3500KEND, 9, 0,NULL,1);
248 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_SLPOUT, 9, 0,NULL,1);
250 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_VOLCTL, 9, 0,NULL,1);
251 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_VOLCTL_Ton | 0x100), 9, 0,NULL,1);
253 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_VOLCTL, 9, 0,NULL,1);
255 omap_uwire_data_transfer(LCD_UWIRE_CS, (INIT_VOLCTL | 0x100), 9, 0,NULL,1);
257 omap_uwire_data_transfer(LCD_UWIRE_CS, LCD_DISON, 9, 0,NULL,1);
259 /* enable backlight */
260 omap_set_gpio_direction(134, 0);
261 omap_set_gpio_dataout(134, 1);
266 static void p2_panel_disable(struct lcd_panel *panel)
270 static unsigned long p2_panel_get_caps(struct lcd_panel *panel)
275 struct lcd_panel p2_panel = {
277 .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_PIX_CLOCK,
283 .pixel_clock = 12500,
291 .init = p2_panel_init,
292 .cleanup = p2_panel_cleanup,
293 .enable = p2_panel_enable,
294 .disable = p2_panel_disable,
295 .get_caps = p2_panel_get_caps,
298 static int p2_panel_probe(struct platform_device *pdev)
300 omapfb_register_panel(&p2_panel);
304 static int p2_panel_remove(struct platform_device *pdev)
309 static int p2_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
314 static int p2_panel_resume(struct platform_device *pdev)
319 struct platform_driver p2_panel_driver = {
320 .probe = p2_panel_probe,
321 .remove = p2_panel_remove,
322 .suspend = p2_panel_suspend,
323 .resume = p2_panel_resume,
326 .owner = THIS_MODULE,
330 static int p2_panel_drv_init(void)
332 return platform_driver_register(&p2_panel_driver);
335 static void p2_panel_drv_cleanup(void)
337 platform_driver_unregister(&p2_panel_driver);
340 module_init(p2_panel_drv_init);
341 module_exit(p2_panel_drv_cleanup);