blob: 367cdc4129356ff509b665f2eb9c38494d9af8fc [file] [log] [blame]
Wentao Xu97df7fd2011-01-19 15:01:17 -05001/*
Duy Truongf3ac7b32013-02-13 01:07:28 -08002 * Copyright (c) 2011, The Linux Foundation. All rights reserved.
Wentao Xu97df7fd2011-01-19 15:01:17 -05003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in
11 * the documentation and/or other materials provided with the
12 * distribution.
Duy Truongf3ac7b32013-02-13 01:07:28 -080013 * * Neither the name of The Linux Foundation nor
Wentao Xu97df7fd2011-01-19 15:01:17 -050014 * the names of its contributors may be used to endorse or promote
15 * products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <debug.h>
33#include <dev/gpio.h>
34#include <kernel/thread.h>
35#include "gpio_hw.h"
36#include "panel.h"
37#include <dev/lcdc.h>
38
Wentao Xu97df7fd2011-01-19 15:01:17 -050039#define VEE_RESET 20
40#define LCD_RESET 180
41
Ajay Dudanib01e5062011-12-03 23:23:42 -080042#define GPIO26_GPIO_CNTRL 0x169 /* backlight */
Wentao Xu97df7fd2011-01-19 15:01:17 -050043
44struct sharp_spi_data {
45 unsigned addr;
46 unsigned data;
47};
48
49static struct sharp_spi_data init_sequence[] = {
Ajay Dudanib01e5062011-12-03 23:23:42 -080050 {15, 0x01},
51 {5, 0x01},
52 {7, 0x10},
53 {9, 0x1E},
54 {10, 0x04},
55 {17, 0xFF},
56 {21, 0x8A},
57 {22, 0x00},
58 {23, 0x82},
59 {24, 0x24},
60 {25, 0x22},
61 {26, 0x6D},
62 {27, 0xEB},
63 {28, 0xB9},
64 {29, 0x3A},
65 {49, 0x1A},
66 {50, 0x16},
67 {51, 0x05},
68 {55, 0x7F},
69 {56, 0x15},
70 {57, 0x7B},
71 {60, 0x05},
72 {61, 0x0C},
73 {62, 0x80},
74 {63, 0x00},
75 {92, 0x90},
76 {97, 0x01},
77 {98, 0xFF},
78 {113, 0x11},
79 {114, 0x02},
80 {115, 0x08},
81 {123, 0xAB},
82 {124, 0x04},
83 {6, 0x02},
84 {133, 0x00},
85 {134, 0xFE},
86 {135, 0x22},
87 {136, 0x0B},
88 {137, 0xFF},
89 {138, 0x0F},
90 {139, 0x00},
91 {140, 0xFE},
92 {141, 0x22},
93 {142, 0x0B},
94 {143, 0xFF},
95 {144, 0x0F},
96 {145, 0x00},
97 {146, 0xFE},
98 {147, 0x22},
99 {148, 0x0B},
100 {149, 0xFF},
101 {150, 0x0F},
102 {202, 0x30},
103 {30, 0x01},
104 {4, 0x01},
105 {31, 0x41}
Wentao Xu97df7fd2011-01-19 15:01:17 -0500106};
107
Ajay Dudanib01e5062011-12-03 23:23:42 -0800108static unsigned char bit_shift[8] = { (1 << 7), /* MSB */
Wentao Xu97df7fd2011-01-19 15:01:17 -0500109 (1 << 6),
110 (1 << 5),
111 (1 << 4),
112 (1 << 3),
113 (1 << 2),
114 (1 << 1),
Ajay Dudanib01e5062011-12-03 23:23:42 -0800115 (1 << 0) /* LSB */
Wentao Xu97df7fd2011-01-19 15:01:17 -0500116};
117
118static unsigned vee_reset_gpio =
119GPIO_CFG(VEE_RESET, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA);
120
121static unsigned lcd_reset_gpio =
122GPIO_CFG(LCD_RESET, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA);
123
Wentao Xu97df7fd2011-01-19 15:01:17 -0500124static int sharp_display_common_power(int on)
125{
126 int rc = 0, flag_on = !!on;
127 static int display_common_power_save_on;
128 unsigned int vreg_ldo12, vreg_ldo15, vreg_ldo20, vreg_ldo16, vreg_ldo8;
129 if (display_common_power_save_on == flag_on)
130 return 0;
131
132 display_common_power_save_on = flag_on;
133
134 if (on) {
135 /* set LCD reset */
136 rc = gpio_tlmm_config(lcd_reset_gpio, GPIO_ENABLE);
137 if (rc) {
138 return rc;
139 }
140
Ajay Dudanib01e5062011-12-03 23:23:42 -0800141 gpio_set(LCD_RESET, 0); /* bring reset line low to hold reset */
Wentao Xu97df7fd2011-01-19 15:01:17 -0500142
143 /* set VEE reset */
144 rc = gpio_tlmm_config(vee_reset_gpio, GPIO_ENABLE);
145
146 if (rc) {
147 return rc;
148 }
149
150 gpio_set(VEE_RESET, 1);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800151 gpio_set(VEE_RESET, 0); /* bring reset line low to hold reset */
Wentao Xu97df7fd2011-01-19 15:01:17 -0500152 mdelay(10);
153 }
154
155 /* Set LD008 to 1.8V - VEE (VCC, VDDIO, pullups) */
156 pmic_write(LDO08_CNTRL, 0x06 | LDO_LOCAL_EN_BMSK);
157
158 /* Set LD012 to 1.8V - display (VDDIO) */
159 pmic_write(LDO12_CNTRL, 0x06 | LDO_LOCAL_EN_BMSK);
160
161 /* Set LD015 to 3.0V - display (VCC), VEE (VLP) */
162 pmic_write(LDO15_CNTRL, 0x1E | LDO_LOCAL_EN_BMSK);
163
164 /* wait for power to stabilize */
165 mdelay(10);
166
Ajay Dudanib01e5062011-12-03 23:23:42 -0800167 gpio_config(VEE_RESET, 0); /*disable VEE_RESET, rely on pullups to bring it high */
Wentao Xu97df7fd2011-01-19 15:01:17 -0500168 mdelay(5);
169
Ajay Dudanib01e5062011-12-03 23:23:42 -0800170 gpio_set(LCD_RESET, 1); /* bring reset line high */
171 mdelay(10); /* 10 msec before IO can be accessed */
Wentao Xu97df7fd2011-01-19 15:01:17 -0500172
173 return rc;
174}
175
176static struct msm_gpio sharp_lcd_panel_gpios[] = {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800177 {GPIO_CFG(45, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "spi_clk"},
178 {GPIO_CFG(46, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "spi_cs0"},
179 {GPIO_CFG(47, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "spi_mosi"},
180 {GPIO_CFG(48, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA), "spi_miso"},
181 {GPIO_CFG(22, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_blu2"},
182 {GPIO_CFG(25, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_red2"},
183 {GPIO_CFG(90, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_pclk"},
184 {GPIO_CFG(91, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en"},
185 {GPIO_CFG(92, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_vsync"},
186 {GPIO_CFG(93, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_hsync"},
187 {GPIO_CFG(94, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_grn2"},
188 {GPIO_CFG(95, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_grn3"},
189 {GPIO_CFG(96, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_grn4"},
190 {GPIO_CFG(97, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_grn5"},
191 {GPIO_CFG(98, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_grn6"},
192 {GPIO_CFG(99, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_grn7"},
193 {GPIO_CFG(100, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_blu3"},
194 {GPIO_CFG(101, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_blu4"},
195 {GPIO_CFG(102, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_blu5"},
196 {GPIO_CFG(103, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_blu6"},
197 {GPIO_CFG(104, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_blu7"},
198 {GPIO_CFG(105, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_red3"},
199 {GPIO_CFG(106, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_red4"},
200 {GPIO_CFG(107, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_red5"},
201 {GPIO_CFG(108, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_red6"},
Wentao Xu97df7fd2011-01-19 15:01:17 -0500202};
203
204int sharp_lcdc_panel_power(int on)
205{
206 int rc, i;
207 struct msm_gpio *gp;
208
209 rc = sharp_display_common_power(on);
210 if (rc < 0) {
211 return rc;
212 }
213
214 if (on) {
215 rc = platform_gpios_enable(sharp_lcd_panel_gpios,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800216 ARRAY_SIZE(sharp_lcd_panel_gpios));
217 if (rc) {
Wentao Xu97df7fd2011-01-19 15:01:17 -0500218 return rc;
219 }
Ajay Dudanib01e5062011-12-03 23:23:42 -0800220 } else { /* off */
Wentao Xu97df7fd2011-01-19 15:01:17 -0500221 gp = sharp_lcd_panel_gpios;
222 for (i = 0; i < ARRAY_SIZE(sharp_lcd_panel_gpios); i++) {
223 /* ouput low */
224 gpio_set(GPIO_PIN(gp->gpio_cfg), 0);
225 gp++;
226 }
227 }
228 return rc;
229}
230
Wentao Xu97df7fd2011-01-19 15:01:17 -0500231static void sharp_spi_write_byte(unsigned val)
232{
233 int i;
234
235 /* Clock should be Low before entering */
236 for (i = 0; i < 8; i++) {
237 /* #1: Drive the Data (High or Low) */
238 if (val & bit_shift[i])
239 gpio_set(SPI_MOSI, 1);
240 else
241 gpio_set(SPI_MOSI, 0);
242
243 /* #2: Drive the Clk High and then Low */
244 gpio_set(SPI_SCLK, 1);
245 gpio_set(SPI_SCLK, 0);
246 }
247}
248
249static int serigo(unsigned reg, unsigned data)
250{
251 /* Enable the Chip Select - low */
252 gpio_set(SPI_CS, 0);
253 udelay(1);
254
255 /* Transmit register address first, then data */
256 sharp_spi_write_byte(reg);
257
258 /* Idle state of MOSI is Low */
259 gpio_set(SPI_MOSI, 0);
260 udelay(1);
261 sharp_spi_write_byte(data);
262
263 gpio_set(SPI_MOSI, 0);
264 gpio_set(SPI_CS, 1);
265 return 0;
266}
267
Ajay Dudanib01e5062011-12-03 23:23:42 -0800268void sharp_lcdc_disp_on(void)
Wentao Xu97df7fd2011-01-19 15:01:17 -0500269{
270 unsigned i;
271 gpio_set(SPI_CS, 1);
272 gpio_set(SPI_SCLK, 1);
273 gpio_set(SPI_MOSI, 0);
274 gpio_set(SPI_MISO, 0);
275
276 for (i = 0; i < ARRAY_SIZE(init_sequence); i++) {
277 serigo(init_sequence[i].addr, init_sequence[i].data);
278 }
279 mdelay(10);
280 serigo(31, 0xC1);
281 mdelay(10);
282 serigo(31, 0xD9);
283 serigo(31, 0xDF);
284}
285
286void sharp_lcdc_on(void)
287{
288 lcdc_clock_init(27648000);
289 sharp_lcdc_panel_power(1);
290
291 /*enable backlight, open up gpio, use default for LPG */
Ajay Dudanib01e5062011-12-03 23:23:42 -0800292 pmic_write(GPIO26_GPIO_CNTRL, 0x81); /* Write, Bank0, VIN0=VPH, Mode selection enabled */
293 pmic_write(GPIO26_GPIO_CNTRL, 0x99); /* Write, Bank1, OutOn/InOff, CMOS, Invert Output (GPIO High) */
294 pmic_write(GPIO26_GPIO_CNTRL, 0xAA); /* Write, Bank2, GPIO no pull */
295 pmic_write(GPIO26_GPIO_CNTRL, 0xB4); /* Write, Bank3, high drv strength */
296 pmic_write(GPIO26_GPIO_CNTRL, 0xC6); /* Write, Bank4, Src: Special Function 2 */
Wentao Xu97df7fd2011-01-19 15:01:17 -0500297
298 sharp_lcdc_disp_on();
299}
300
301static struct lcdc_timing_parameters param = {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800302 .lcdc_fb_width = 480,
303 .lcdc_fb_height = 800,
304 .lcdc_hsync_pulse_width_dclk = 10,
305 .lcdc_hsync_back_porch_dclk = 20,
306 .lcdc_hsync_front_porch_dclk = 10,
307 .lcdc_hsync_skew_dclk = 0,
Wentao Xu97df7fd2011-01-19 15:01:17 -0500308
Ajay Dudanib01e5062011-12-03 23:23:42 -0800309 .lcdc_vsync_pulse_width_lines = 2,
310 .lcdc_vsync_back_porch_lines = 2,
311 .lcdc_vsync_front_porch_lines = 2,
Wentao Xu97df7fd2011-01-19 15:01:17 -0500312};
313
314struct lcdc_timing_parameters *sharp_timing_param()
315{
316 return &param;
317}