2 * Copyright (C) 2012 Spreadtrum Communications Inc.
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
16 #include <asm/arch/sc8810_lcd.h>
17 #define mdelay(a) udelay(a * 1000)
18 #define LCD_DelayMS mdelay
22 #define LCD_PRINT printf
24 #define LCD_PRINT(...)
27 static int32_t s6d04h0_init(struct lcd_spec *self)
29 Send_data send_cmd = self->info.mcu->ops->send_cmd;
30 Send_data send_data = self->info.mcu->ops->send_data;
32 LCD_PRINT("s6d04h0_init\n");
100 send_cmd(0xFA); // (PDISPCTRL_WRCTL)
118 send_cmd(0xFB); // (PDISPCTRL_WRCTL)
139 send_cmd(0xFA); // (PDISPCTRL_WRCTL)
157 send_cmd(0xFB); // (PDISPCTRL_WRCTL)
178 send_cmd(0xFA); // (PDISPCTRL_WRCTL)
196 send_cmd(0xFB); // (PDISPCTRL_WRCTL)
218 send_cmd(0x11); // (SLPOUT)
220 LCD_DelayMS(130); // 120ms
222 send_cmd(0x29); // (DISPON)
224 LCD_DelayMS(40); // 40ms
229 static int32_t s6d04h0_off(struct lcd_spec *self)
231 Send_data send_cmd = self->info.mcu->ops->send_cmd;
232 Send_data send_data = self->info.mcu->ops->send_data;
234 send_cmd(0x10); // (SLPIN)
240 static int32_t s6d04h0_set_window(struct lcd_spec *self,
241 uint16_t left, uint16_t top, uint16_t right,
244 Send_data send_cmd = self->info.mcu->ops->send_cmd;
245 Send_data send_data = self->info.mcu->ops->send_data;
247 LCD_PRINT("s6d04h0_set_window:%d, %d, %d, %d\n", left, top, right,
250 send_cmd(0x2A); // col
251 send_data((left >> 8));
252 send_data((left & 0xFF));
253 send_data((right >> 8));
254 send_data((right & 0xFF));
256 send_cmd(0x2B); // row
257 send_data((top >> 8));
258 send_data((top & 0xFF));
259 send_data((bottom >> 8));
260 send_data((bottom & 0xFF));
267 static int32_t s6d04h0_invalidate(struct lcd_spec *self)
270 return self->ops->lcd_set_window(self, 0, 0,
271 self->width - 1, self->height - 1);
275 static int32_t s6d04h0_invalidate_rect(struct lcd_spec *self,
276 uint16_t left, uint16_t top,
277 uint16_t right, uint16_t bottom)
280 LCD_PRINT("s6d04h0_invalidate_rect\n");
282 return self->ops->lcd_set_window(self, left, top, right, bottom);
285 static int32_t s6d04h0_set_direction(struct lcd_spec *self,
289 LCD_PRINT("s6d04h0_set_direction\n");
293 static int32_t s6d04h0_enter_sleep(struct lcd_spec *self, uint8_t is_sleep)
296 LCD_PRINT("[LCD] s6d04h0_enter_sleep\n");
297 self->ops->lcd_close(self);
299 LCD_PRINT("[LCD] s6d04h0_enter_wakeup\n");
300 self->ops->lcd_init(self);
305 static uint32_t s6d04h0_read_id(struct lcd_spec *self)
307 uint32_t read_value = 0;
308 Send_data send_cmd = self->info.mcu->ops->send_cmd;
309 Read_data read_data = self->info.mcu->ops->read_data;
314 read_value += read_data() << 16;
315 read_value += read_data() << 8;
316 read_value += read_data();
318 LCD_PRINT("s6d04h0_read_id=%#x=====\n", read_value);
323 static struct lcd_operations lcd_s6d04h0_operations = {
324 .lcd_init = s6d04h0_init,
325 .lcd_close = s6d04h0_off,
326 .lcd_set_window = s6d04h0_set_window,
327 .lcd_invalidate = s6d04h0_invalidate,
328 .lcd_invalidate_rect = s6d04h0_invalidate_rect,
329 .lcd_set_direction = s6d04h0_set_direction,
330 .lcd_enter_sleep = s6d04h0_enter_sleep,
331 .lcd_readid = s6d04h0_read_id,
334 static struct timing_mcu lcd_s6d04h0_timing[] = {
335 [LCD_REGISTER_TIMING] = {
343 [LCD_GRAM_TIMING] = {
353 static struct info_mcu lcd_s6d04h0_info = {
354 .bus_mode = LCD_BUS_8080,
356 .timing = lcd_s6d04h0_timing,
360 struct lcd_spec lcd_s6d04h0_spec = {
363 .mode = LCD_MODE_MCU,
364 .direction = LCD_DIRECT_NORMAL,
366 .mcu = &lcd_s6d04h0_info},
367 .ops = &lcd_s6d04h0_operations,
371 struct lcd_cfg lcd_s6d04h0 = {
373 .lcd_id = 0xC0, /* RDID3:LCD module ID */
374 .lcd_name = "lcd_s6d04h0",
375 .panel = &lcd_s6d04h0_spec,
378 static int lcd_regulator(void)
381 struct regulator *lcd_regulator = NULL;
382 struct regulator *lcdio_regulator = NULL;
383 lcd_regulator = regulator_get(NULL, REGU_NAME_LCD);
384 if (IS_ERR(lcd_regulator)) {
385 pr_err("LCD s6d04h0:could not get lcd regulator\n");
388 err = regulator_enable(lcd_regulator);
390 pr_err("LCD s6d04h0:could not enable lcd regulator\n");
393 err = regulator_set_voltage(lcd_regulator, 3000000, 3000000);
395 pr_err("LCD s6d04h0:could not set lcd to 3000mv.\n");
396 lcdio_regulator = regulator_get(NULL, REGU_NAME_LCDIO);
397 if (IS_ERR(lcdio_regulator)) {
398 pr_err("LCD s6d04h0:could not get lcdio regulator\n");
401 err = regulator_enable(lcdio_regulator);
403 pr_err("LCD s6d04h0:could not enable lcdio regulator\n");
406 err = regulator_set_voltage(lcdio_regulator, 2800000, 2800000);
408 pr_err("LCD s6d04h0:could not set lcdio to 1800mv.\n");
412 static int __init lcd_s6d04h0_init(void)
415 return sprd_register_panel(&lcd_s6d04h0);
419 subsys_initcall(lcd_s6d04h0_init);