summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (c) 2013 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <sys/types.h> /* off_t */
22#include <string.h>
23#include "cpu.h"
24#include "system.h"
25#include "backlight-target.h"
26#include "lcd.h"
27#include "lcdif-imx233.h"
28#include "clkctrl-imx233.h"
29#include "pinctrl-imx233.h"
30#include "dcp-imx233.h"
31#include "logf.h"
32#ifndef BOOTLOADER
33#include "button.h"
34#include "font.h"
35#include "action.h"
36#endif
37
38#ifdef HAVE_LCD_ENABLE
39static bool lcd_on;
40#endif
41
42static bool lcd_has_power;
43static bool lcd_kind;
44
45static void lcd_send(bool data, uint8_t val)
46{
47 imx233_lcdif_pio_send(data, 1, &val);
48}
49
50void lcd_init_device(void)
51{
52 // determine power type
53 imx233_pinctrl_acquire(3, 16, "lcd power kind");
54 imx233_pinctrl_set_function(3, 16, PINCTRL_FUNCTION_GPIO);
55 imx233_pinctrl_enable_gpio(3, 16, false);
56 udelay(10);
57 lcd_has_power = !imx233_pinctrl_get_gpio(3, 16);
58 if(lcd_has_power)
59 {
60 imx233_pinctrl_acquire(0, 27, "lcd power");
61 imx233_pinctrl_set_function(0, 27, PINCTRL_FUNCTION_GPIO);
62 imx233_pinctrl_enable_gpio(0, 27, true);
63 imx233_pinctrl_set_gpio(0, 27, true);
64 }
65 // determine kind (don't acquire pin because it's a lcdif pin !)
66 imx233_pinctrl_set_function(1, 0, PINCTRL_FUNCTION_GPIO);
67 imx233_pinctrl_enable_gpio(1, 0, false);
68 udelay(10);
69 lcd_kind = imx233_pinctrl_get_gpio(1, 0);
70
71 imx233_lcdif_init();
72 imx233_lcdif_reset_lcd(false);
73 imx233_lcdif_reset_lcd(true);
74 imx233_lcdif_setup_system_pins(16);
75 imx233_lcdif_set_timings(2, 2, 2, 2);
76 imx233_lcdif_set_word_length(8);
77 // set mux ratio
78 lcd_send(false, 0xca); lcd_send(true, 131);
79 // set remap, color and depth
80 lcd_send(false, 0xa0); lcd_send(true, 0x74);
81 // set master contrast
82 lcd_send(false, 0xc7); lcd_send(true, 0x8);
83 // set V_COMH
84 lcd_send(false, 0xbe); lcd_send(true, lcd_kind ? 0x1c : 0x18);
85 // set color contrasts
86 lcd_send(false, 0xc1); lcd_send(true, 0x7b); lcd_send(true, 0x69); lcd_send(true, lcd_kind ? 0xcf : 0x9f);
87 // set timings
88 lcd_send(false, 0xb1); lcd_send(true, 0x1f);
89 lcd_send(false, 0xb3); lcd_send(true, 0x80);
90 // set precharge voltages
91 lcd_send(false, 0xbb); lcd_send(true, 0x00); lcd_send(true, 0x00); lcd_send(true, 0x00);
92 // set master config
93 lcd_send(false, 0xad); lcd_send(true, 0x8a);
94 // set power saving mode
95 lcd_send(false, 0xb0); lcd_send(true, 0x00);
96 // set normal display (seem to be a SSD1338 only command, not present in SS1339 datasheet)
97 lcd_send(false, 0xd1); lcd_send(true, 0x02);
98 // set LUT
99 lcd_send(false, 0xb8);
100 static uint8_t lut[32] =
101 {
102 0x01, 0x15, 0x19, 0x1D, 0x21, 0x25, 0x29, 0x2D, 0x31, 0x35, 0x39, 0x3D,
103 0x41, 0x45, 0x49, 0x4D, 0x51, 0x55, 0x59, 0x5D, 0x61, 0x65, 0x69, 0x6D,
104 0x71, 0x75, 0x79, 0x7D, 0x81, 0x85, 0x89, 0x8D
105 };
106 for(int i = 0; i < 32; i++)
107 lcd_send(true, lut[i]);
108 // set display offset (this lcd is really wired strangely)
109 lcd_send(false, 0xa2); lcd_send(true, 128);
110 // normal display
111 lcd_send(false, 0xa6);
112 // sleep mode off
113 lcd_send(false, 0xaf);
114
115 // write ram
116 lcd_send(false, 0x5c);
117 imx233_lcdif_set_word_length(16);
118 for(int y = 0; y < LCD_HEIGHT; y++)
119 for(int x = 0; x < LCD_WIDTH; x++)
120 {
121 uint16_t v = 0;
122 imx233_lcdif_pio_send(true, 1, &v);
123 }
124#ifdef HAVE_LCD_ENABLE
125 lcd_on = true;
126#endif
127}
128
129#ifdef HAVE_LCD_ENABLE
130bool lcd_active(void)
131{
132 return lcd_on;
133}
134
135void lcd_enable(bool enable)
136{
137 if(lcd_on == enable)
138 return;
139
140 lcd_on = enable;
141}
142#endif
143
144void lcd_set_contrast(int val)
145{
146 // NOTE: this should not interfere with lcd_update_rect
147 imx233_lcdif_wait_ready();
148 imx233_lcdif_set_word_length(8);
149 // set contrast
150 lcd_send(false, 0xc7); lcd_send(true, val);
151}
152
153void lcd_update(void)
154{
155 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
156}
157
158void lcd_update_rect(int x, int y, int w, int h)
159{
160 #ifdef HAVE_LCD_ENABLE
161 if(!lcd_on)
162 return;
163 #endif
164
165 imx233_lcdif_wait_ready();
166 imx233_lcdif_set_word_length(8);
167 // set column address
168 lcd_send(false, 0x15); lcd_send(true, x); lcd_send(true, x + w - 1);
169 // set row address
170 lcd_send(false, 0x75); lcd_send(true, y); lcd_send(true, y + h - 1);
171 lcd_send(false, 0x5c);
172 imx233_lcdif_set_word_length(16);
173 for(int yy = y; yy < y + h; yy++)
174 imx233_lcdif_pio_send(true, w, FBADDR(x, yy));
175}
176
177#ifndef BOOTLOADER
178bool lcd_debug_screen(void)
179{
180 lcd_setfont(FONT_SYSFIXED);
181
182 while(1)
183 {
184 int button = get_action(CONTEXT_STD, HZ / 10);
185 switch(button)
186 {
187 case ACTION_STD_NEXT:
188 case ACTION_STD_PREV:
189 case ACTION_STD_OK:
190 case ACTION_STD_MENU:
191 lcd_setfont(FONT_UI);
192 return true;
193 case ACTION_STD_CANCEL:
194 lcd_setfont(FONT_UI);
195 return false;
196 }
197
198 lcd_clear_display();
199 lcd_putsf(0, 0, "has power: %d", lcd_has_power);
200 lcd_putsf(0, 1, "lcd kind: %d", lcd_kind);
201 lcd_update();
202 yield();
203 }
204
205 return true;
206}
207#endif