diff options
Diffstat (limited to 'firmware/target/arm/tcc77x/iaudio7/lcd-iaudio7.c')
-rw-r--r-- | firmware/target/arm/tcc77x/iaudio7/lcd-iaudio7.c | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/firmware/target/arm/tcc77x/iaudio7/lcd-iaudio7.c b/firmware/target/arm/tcc77x/iaudio7/lcd-iaudio7.c new file mode 100644 index 0000000000..bbc20b6860 --- /dev/null +++ b/firmware/target/arm/tcc77x/iaudio7/lcd-iaudio7.c | |||
@@ -0,0 +1,252 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2004 by Linus Nielsen Feltzing | ||
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 | |||
22 | /* | ||
23 | Thanks Hein-Pieter van Braam for initial work. | ||
24 | |||
25 | Mostly based on lcd-h300.c, adapted for the iaudio 7 by Vitja Makarov | ||
26 | */ | ||
27 | |||
28 | #include <config.h> | ||
29 | |||
30 | #include <kernel.h> | ||
31 | #include <cpu.h> | ||
32 | #include <lcd.h> | ||
33 | #include <system-target.h> | ||
34 | |||
35 | #include "hd66789r.h" | ||
36 | |||
37 | static bool display_on = false; /* is the display turned on? */ | ||
38 | |||
39 | static inline void lcd_write_reg(int reg, int data) | ||
40 | { | ||
41 | GPIOA &= ~0x400; | ||
42 | outw(0, 0x50010000); | ||
43 | outw(reg << 1, 0x50010000); | ||
44 | GPIOA |= 0x400; | ||
45 | |||
46 | outw((data & 0xff00) >> 7, 0x50010008); | ||
47 | outw((data << 24) >> 23, 0x50010008); | ||
48 | } | ||
49 | |||
50 | static void lcd_write_cmd(int reg) | ||
51 | { | ||
52 | GPIOA &= ~0x400; | ||
53 | outw(0, 0x50010000); | ||
54 | outw(reg << 1, 0x50010000); | ||
55 | GPIOA |= 0x400; | ||
56 | } | ||
57 | |||
58 | /* Do what OF do */ | ||
59 | static void lcd_delay(int x) | ||
60 | { | ||
61 | int i; | ||
62 | |||
63 | x *= 0xc35; | ||
64 | for (i = 0; i < x * 8; i++) { | ||
65 | } | ||
66 | } | ||
67 | |||
68 | |||
69 | static void _display_on(void) | ||
70 | { | ||
71 | GPIOA_DIR |= 0x8000 | 0x400; | ||
72 | GPIOA |= 0x8000; | ||
73 | |||
74 | /* power setup */ | ||
75 | lcd_write_reg(R_START_OSC, 0x0001); | ||
76 | lcd_delay(0xf); | ||
77 | lcd_write_reg(R_DISP_CONTROL1, 0x000); | ||
78 | lcd_delay(0xa); | ||
79 | lcd_write_reg(R_POWER_CONTROL2, 0x0002); | ||
80 | lcd_write_reg(R_POWER_CONTROL3, 0x000a); | ||
81 | lcd_write_reg(R_POWER_CONTROL4, 0xc5a); | ||
82 | lcd_write_reg(R_POWER_CONTROL1, 0x0004); | ||
83 | lcd_write_reg(R_POWER_CONTROL1, 0x0134); | ||
84 | lcd_write_reg(R_POWER_CONTROL2, 0x0111); | ||
85 | lcd_write_reg(R_POWER_CONTROL3, 0x001c); | ||
86 | lcd_delay(0x28); | ||
87 | lcd_write_reg(R_POWER_CONTROL4, 0x2c40); | ||
88 | lcd_write_reg(R_POWER_CONTROL1, 0x0510); | ||
89 | lcd_delay(0x3c); | ||
90 | |||
91 | /* lcd init 2 */ | ||
92 | lcd_write_reg(R_DRV_OUTPUT_CONTROL, 0x0113); | ||
93 | lcd_write_reg(R_DRV_WAVEFORM_CONTROL, 0x0700); | ||
94 | lcd_write_reg(R_ENTRY_MODE, 0x1038); | ||
95 | lcd_write_reg(R_DISP_CONTROL2, 0x0508); // 0x3c8, TMM | ||
96 | lcd_write_reg(R_DISP_CONTROL3, 0x0000); | ||
97 | lcd_write_reg(R_FRAME_CYCLE_CONTROL, 0x0003); | ||
98 | lcd_write_reg(R_RAM_ADDR_SET, 0x0000); | ||
99 | lcd_write_reg(R_GAMMA_FINE_ADJ_POS1, 0x0406); | ||
100 | lcd_write_reg(R_GAMMA_FINE_ADJ_POS2, 0x0303); | ||
101 | lcd_write_reg(R_GAMMA_FINE_ADJ_POS3, 0x0000); | ||
102 | lcd_write_reg(R_GAMMA_GRAD_ADJ_POS, 0x0305); | ||
103 | lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1, 0x0404); | ||
104 | lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2, 0x0000); | ||
105 | lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3, 0x0000); | ||
106 | lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG, 0x0503); | ||
107 | lcd_write_reg(R_GAMMA_AMP_ADJ_RES_POS, 0x1d05); | ||
108 | lcd_write_reg(R_GAMMA_AMP_AVG_ADJ_RES_NEG, 0x1d05); | ||
109 | lcd_write_reg(R_VERT_SCROLL_CONTROL, 0x0000); | ||
110 | lcd_write_reg(R_1ST_SCR_DRV_POS, 0x9f00); | ||
111 | lcd_write_reg(R_2ND_SCR_DRV_POS, 0x9f00); | ||
112 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, 0x7f00); | ||
113 | lcd_write_reg(R_VERT_RAM_ADDR_POS, 0x9f00); | ||
114 | |||
115 | /* lcd init 3 */ | ||
116 | lcd_write_reg(R_POWER_CONTROL1, 0x4510); | ||
117 | lcd_write_reg(R_DISP_CONTROL1, 0x0005); | ||
118 | lcd_delay(0x28); | ||
119 | lcd_write_reg(R_DISP_CONTROL1, 0x0025); | ||
120 | lcd_write_reg(R_DISP_CONTROL1, 0x0027); | ||
121 | lcd_delay(0x28); | ||
122 | lcd_write_reg(R_DISP_CONTROL1, 0x0037); | ||
123 | |||
124 | display_on = true; | ||
125 | } | ||
126 | |||
127 | void lcd_init_device(void) | ||
128 | { | ||
129 | /* Configure external memory banks */ | ||
130 | CSCFG1 = 0x3d500023; | ||
131 | |||
132 | /* may be reset */ | ||
133 | GPIOA |= 0x8000; | ||
134 | |||
135 | _display_on(); | ||
136 | } | ||
137 | |||
138 | void lcd_enable(bool on) | ||
139 | { | ||
140 | if (display_on == on) | ||
141 | return; | ||
142 | |||
143 | if (on) { | ||
144 | _display_on(); | ||
145 | // lcd_call_enable_hook(); | ||
146 | } else { | ||
147 | /** Off sequence according to datasheet, p. 130 **/ | ||
148 | lcd_write_reg(R_FRAME_CYCLE_CONTROL, 0x0002); /* EQ=0, 18 clks/line */ | ||
149 | lcd_write_reg(R_DISP_CONTROL1, 0x0036); /* GON=1, DTE=1, REV=1, D1-0=10 */ | ||
150 | sleep(2); | ||
151 | |||
152 | lcd_write_reg(R_DISP_CONTROL1, 0x0026); /* GON=1, DTE=0, REV=1, D1-0=10 */ | ||
153 | sleep(2); | ||
154 | |||
155 | lcd_write_reg(R_DISP_CONTROL1, 0x0000); /* GON=0, DTE=0, D1-0=00 */ | ||
156 | |||
157 | lcd_write_reg(R_POWER_CONTROL1, 0x0000); /* SAP2-0=000, AP2-0=000 */ | ||
158 | lcd_write_reg(R_POWER_CONTROL3, 0x0000); /* PON=0 */ | ||
159 | lcd_write_reg(R_POWER_CONTROL4, 0x0000); /* VCOMG=0 */ | ||
160 | |||
161 | /* datasheet p. 131 */ | ||
162 | lcd_write_reg(R_POWER_CONTROL1, 0x0001); /* STB=1: standby mode */ | ||
163 | |||
164 | display_on = false; | ||
165 | } | ||
166 | } | ||
167 | |||
168 | bool lcd_enabled(void) | ||
169 | { | ||
170 | return display_on; | ||
171 | } | ||
172 | |||
173 | |||
174 | #define RGB(r,g,b) ((((r)&0x3f) << 12)|(((g)&0x3f) << 6)|(((b)&0x3f))) | ||
175 | |||
176 | |||
177 | void lcd_update(void) | ||
178 | { | ||
179 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); | ||
180 | } | ||
181 | |||
182 | /* todo: need tests */ | ||
183 | void lcd_update_rect(int sx, int sy, int width, int height) | ||
184 | { | ||
185 | int x, y; | ||
186 | |||
187 | if (!display_on) | ||
188 | return; | ||
189 | |||
190 | if (width <= 0 || height <= 0) /* nothing to do */ | ||
191 | return; | ||
192 | |||
193 | width += sx; | ||
194 | height += sy; | ||
195 | |||
196 | if (width > LCD_WIDTH) | ||
197 | width = LCD_WIDTH; | ||
198 | if (height > LCD_HEIGHT) | ||
199 | height = LCD_HEIGHT; | ||
200 | |||
201 | lcd_write_reg(R_ENTRY_MODE, 0x1028); | ||
202 | /* set update window */ | ||
203 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (LCD_HEIGHT - 1) << 8); | ||
204 | lcd_write_reg(R_VERT_RAM_ADDR_POS, ((width - 1) << 8) | sx); | ||
205 | lcd_write_reg(R_RAM_ADDR_SET, (sx << 8) | (LCD_HEIGHT - sy - 1)); | ||
206 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); | ||
207 | |||
208 | for (y = sy; y < height; y++) { | ||
209 | for (x = sx; x < width; x++) { | ||
210 | fb_data c; | ||
211 | unsigned long color; | ||
212 | |||
213 | c = lcd_framebuffer[y][x]; | ||
214 | color = | ||
215 | ((c & 0x1f) << 1) | ((c & 0x7e0) << 1) | ((c & 0xf800) << | ||
216 | 2); | ||
217 | |||
218 | /* TODO: our color is 18-bit */ | ||
219 | outw((color >> 9) & 0x1ff, 0x50010008); | ||
220 | outw((color) & 0x1ff, 0x50010008); | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | |||
225 | void lcd_set_contrast(int val) | ||
226 | { | ||
227 | (void) val; | ||
228 | } | ||
229 | |||
230 | void lcd_set_invert_display(bool yesno) | ||
231 | { | ||
232 | (void) yesno; | ||
233 | } | ||
234 | |||
235 | void lcd_set_flip(bool yesno) | ||
236 | { | ||
237 | (void) yesno; | ||
238 | } | ||
239 | |||
240 | /* TODO: implement me */ | ||
241 | void lcd_blit_yuv(unsigned char *const src[3], | ||
242 | int src_x, int src_y, int stride, | ||
243 | int x, int y, int width, int height) | ||
244 | { | ||
245 | if (!display_on) | ||
246 | return; | ||
247 | |||
248 | width &= ~1; /* stay on the safe side */ | ||
249 | height &= ~1; | ||
250 | |||
251 | panicf("%s", __func__); | ||
252 | } | ||