summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm/imx233/creative-zen
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx233/creative-zen')
-rw-r--r--firmware/target/arm/imx233/creative-zen/lcd-zenv.c207
1 files changed, 207 insertions, 0 deletions
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 <sys/types.h> /* off_t */
+#include <string.h>
+#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