From 0c394770aa5f82331e9173922d3cef9162f6958d Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Tue, 19 Nov 2013 21:05:47 +0000 Subject: Forgot lcd driver of the ZEN V ! Change-Id: I0e0e04d4de3b28058e3822043d46d64291265c75 --- firmware/target/arm/imx233/creative-zen/lcd-zenv.c | 207 +++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 firmware/target/arm/imx233/creative-zen/lcd-zenv.c diff --git a/firmware/target/arm/imx233/creative-zen/lcd-zenv.c b/firmware/target/arm/imx233/creative-zen/lcd-zenv.c new file mode 100644 index 0000000000..3bc8e67e5d --- /dev/null +++ b/firmware/target/arm/imx233/creative-zen/lcd-zenv.c @@ -0,0 +1,207 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (c) 2013 by Amaury Pouly + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include /* off_t */ +#include +#include "cpu.h" +#include "system.h" +#include "backlight-target.h" +#include "lcd.h" +#include "lcdif-imx233.h" +#include "clkctrl-imx233.h" +#include "pinctrl-imx233.h" +#include "dcp-imx233.h" +#include "logf.h" +#ifndef BOOTLOADER +#include "button.h" +#include "font.h" +#include "action.h" +#endif + +#ifdef HAVE_LCD_ENABLE +static bool lcd_on; +#endif + +static bool lcd_has_power; +static bool lcd_kind; + +static void lcd_send(bool data, uint8_t val) +{ + imx233_lcdif_pio_send(data, 1, &val); +} + +void lcd_init_device(void) +{ + // determine power type + imx233_pinctrl_acquire(3, 16, "lcd power kind"); + imx233_pinctrl_set_function(3, 16, PINCTRL_FUNCTION_GPIO); + imx233_pinctrl_enable_gpio(3, 16, false); + udelay(10); + lcd_has_power = !imx233_pinctrl_get_gpio(3, 16); + if(lcd_has_power) + { + imx233_pinctrl_acquire(0, 27, "lcd power"); + imx233_pinctrl_set_function(0, 27, PINCTRL_FUNCTION_GPIO); + imx233_pinctrl_enable_gpio(0, 27, true); + imx233_pinctrl_set_gpio(0, 27, true); + } + // determine kind (don't acquire pin because it's a lcdif pin !) + imx233_pinctrl_set_function(1, 0, PINCTRL_FUNCTION_GPIO); + imx233_pinctrl_enable_gpio(1, 0, false); + udelay(10); + lcd_kind = imx233_pinctrl_get_gpio(1, 0); + + imx233_lcdif_init(); + imx233_lcdif_reset_lcd(false); + imx233_lcdif_reset_lcd(true); + imx233_lcdif_setup_system_pins(16); + imx233_lcdif_set_timings(2, 2, 2, 2); + imx233_lcdif_set_word_length(8); + // set mux ratio + lcd_send(false, 0xca); lcd_send(true, 131); + // set remap, color and depth + lcd_send(false, 0xa0); lcd_send(true, 0x74); + // set master contrast + lcd_send(false, 0xc7); lcd_send(true, 0x8); + // set V_COMH + lcd_send(false, 0xbe); lcd_send(true, lcd_kind ? 0x1c : 0x18); + // set color contrasts + lcd_send(false, 0xc1); lcd_send(true, 0x7b); lcd_send(true, 0x69); lcd_send(true, lcd_kind ? 0xcf : 0x9f); + // set timings + lcd_send(false, 0xb1); lcd_send(true, 0x1f); + lcd_send(false, 0xb3); lcd_send(true, 0x80); + // set precharge voltages + lcd_send(false, 0xbb); lcd_send(true, 0x00); lcd_send(true, 0x00); lcd_send(true, 0x00); + // set master config + lcd_send(false, 0xad); lcd_send(true, 0x8a); + // set power saving mode + lcd_send(false, 0xb0); lcd_send(true, 0x00); + // set normal display (seem to be a SSD1338 only command, not present in SS1339 datasheet) + lcd_send(false, 0xd1); lcd_send(true, 0x02); + // set LUT + lcd_send(false, 0xb8); + static uint8_t lut[32] = + { + 0x01, 0x15, 0x19, 0x1D, 0x21, 0x25, 0x29, 0x2D, 0x31, 0x35, 0x39, 0x3D, + 0x41, 0x45, 0x49, 0x4D, 0x51, 0x55, 0x59, 0x5D, 0x61, 0x65, 0x69, 0x6D, + 0x71, 0x75, 0x79, 0x7D, 0x81, 0x85, 0x89, 0x8D + }; + for(int i = 0; i < 32; i++) + lcd_send(true, lut[i]); + // set display offset (this lcd is really wired strangely) + lcd_send(false, 0xa2); lcd_send(true, 128); + // normal display + lcd_send(false, 0xa6); + // sleep mode off + lcd_send(false, 0xaf); + + // write ram + lcd_send(false, 0x5c); + imx233_lcdif_set_word_length(16); + for(int y = 0; y < LCD_HEIGHT; y++) + for(int x = 0; x < LCD_WIDTH; x++) + { + uint16_t v = 0; + imx233_lcdif_pio_send(true, 1, &v); + } +#ifdef HAVE_LCD_ENABLE + lcd_on = true; +#endif +} + +#ifdef HAVE_LCD_ENABLE +bool lcd_active(void) +{ + return lcd_on; +} + +void lcd_enable(bool enable) +{ + if(lcd_on == enable) + return; + + lcd_on = enable; +} +#endif + +void lcd_set_contrast(int val) +{ + // NOTE: this should not interfere with lcd_update_rect + imx233_lcdif_wait_ready(); + imx233_lcdif_set_word_length(8); + // set contrast + lcd_send(false, 0xc7); lcd_send(true, val); +} + +void lcd_update(void) +{ + lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); +} + +void lcd_update_rect(int x, int y, int w, int h) +{ + #ifdef HAVE_LCD_ENABLE + if(!lcd_on) + return; + #endif + + imx233_lcdif_wait_ready(); + imx233_lcdif_set_word_length(8); + // set column address + lcd_send(false, 0x15); lcd_send(true, x); lcd_send(true, x + w - 1); + // set row address + lcd_send(false, 0x75); lcd_send(true, y); lcd_send(true, y + h - 1); + lcd_send(false, 0x5c); + imx233_lcdif_set_word_length(16); + for(int yy = y; yy < y + h; yy++) + imx233_lcdif_pio_send(true, w, FBADDR(x, yy)); +} + +#ifndef BOOTLOADER +bool lcd_debug_screen(void) +{ + lcd_setfont(FONT_SYSFIXED); + + while(1) + { + int button = get_action(CONTEXT_STD, HZ / 10); + switch(button) + { + case ACTION_STD_NEXT: + case ACTION_STD_PREV: + case ACTION_STD_OK: + case ACTION_STD_MENU: + lcd_setfont(FONT_UI); + return true; + case ACTION_STD_CANCEL: + lcd_setfont(FONT_UI); + return false; + } + + lcd_clear_display(); + lcd_putsf(0, 0, "has power: %d", lcd_has_power); + lcd_putsf(0, 1, "lcd kind: %d", lcd_kind); + lcd_update(); + yield(); + } + + return true; +} +#endif -- cgit v1.2.3