diff options
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/lcd-gigabeat-s.c')
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/lcd-gigabeat-s.c | 158 |
1 files changed, 11 insertions, 147 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/lcd-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/lcd-gigabeat-s.c index 6a0c889851..8185479390 100644 --- a/firmware/target/arm/imx31/gigabeat-s/lcd-gigabeat-s.c +++ b/firmware/target/arm/imx31/gigabeat-s/lcd-gigabeat-s.c | |||
@@ -18,32 +18,20 @@ | |||
18 | * KIND, either express or implied. | 18 | * KIND, either express or implied. |
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | #include <sys/types.h> | ||
22 | #include "inttypes.h" | ||
23 | |||
24 | #include "config.h" | 21 | #include "config.h" |
25 | #include "system.h" | 22 | #include "system.h" |
26 | #include "cpu.h" | ||
27 | #include "spi-imx31.h" | ||
28 | #include "mc13783.h" | ||
29 | #include "string.h" | ||
30 | #include "lcd.h" | 23 | #include "lcd.h" |
31 | #include "kernel.h" | ||
32 | #include "lcd-target.h" | 24 | #include "lcd-target.h" |
33 | #include "backlight-target.h" | 25 | #include "backlight-target.h" |
26 | #include "spi-imx31.h" | ||
27 | #include "mc13783.h" | ||
34 | 28 | ||
35 | #define MAIN_LCD_IDMAC_CHANNEL 14 | 29 | extern void lcd_set_active(bool active); |
36 | #define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)]) | ||
37 | 30 | ||
38 | /* Copies a rectangle from one framebuffer to another. Can be used in | 31 | #define MAIN_LCD_IDMAC_CHANNEL 14 |
39 | single transfer mode with width = num pixels, and height = 1 which | ||
40 | allows a full-width rectangle to be copied more efficiently. */ | ||
41 | extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, | ||
42 | int width, int height); | ||
43 | 32 | ||
44 | static bool lcd_on = true; | ||
45 | static bool lcd_powered = true; | 33 | static bool lcd_powered = true; |
46 | static unsigned lcd_yuv_options = 0; | 34 | |
47 | /* Settings shadow regs */ | 35 | /* Settings shadow regs */ |
48 | #ifdef HAVE_LCD_CONTRAST | 36 | #ifdef HAVE_LCD_CONTRAST |
49 | static uint8_t reg0x0b = 0x2f; | 37 | static uint8_t reg0x0b = 0x2f; |
@@ -184,44 +172,6 @@ void INIT_ATTR lcd_init_device(void) | |||
184 | lcd_sync_settings(); | 172 | lcd_sync_settings(); |
185 | } | 173 | } |
186 | 174 | ||
187 | /* Update a fraction of the display. */ | ||
188 | void lcd_update_rect(int x, int y, int width, int height) | ||
189 | { | ||
190 | fb_data *dst, *src; | ||
191 | |||
192 | if (!lcd_on) | ||
193 | return; | ||
194 | |||
195 | if (x + width > LCD_WIDTH) | ||
196 | width = LCD_WIDTH - x; /* Clip right */ | ||
197 | if (x < 0) | ||
198 | width += x, x = 0; /* Clip left */ | ||
199 | if (width <= 0) | ||
200 | return; /* nothing left to do */ | ||
201 | |||
202 | if (y + height > LCD_HEIGHT) | ||
203 | height = LCD_HEIGHT - y; /* Clip bottom */ | ||
204 | if (y < 0) | ||
205 | height += y, y = 0; /* Clip top */ | ||
206 | if (height <= 0) | ||
207 | return; /* nothing left to do */ | ||
208 | |||
209 | dst = (fb_data *)FRAME + LCD_WIDTH*y + x; | ||
210 | src = &lcd_framebuffer[y][x]; | ||
211 | |||
212 | /* Copy part of the Rockbox framebuffer to the second framebuffer */ | ||
213 | if (width < LCD_WIDTH) | ||
214 | { | ||
215 | /* Not full width - do line-by-line */ | ||
216 | lcd_copy_buffer_rect(dst, src, width, height); | ||
217 | } | ||
218 | else | ||
219 | { | ||
220 | /* Full width - copy as one line */ | ||
221 | lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); | ||
222 | } | ||
223 | } | ||
224 | |||
225 | void lcd_sleep(void) | 175 | void lcd_sleep(void) |
226 | { | 176 | { |
227 | if (!lcd_powered) | 177 | if (!lcd_powered) |
@@ -235,7 +185,7 @@ void lcd_sleep(void) | |||
235 | 185 | ||
236 | void lcd_enable(bool state) | 186 | void lcd_enable(bool state) |
237 | { | 187 | { |
238 | if (state == lcd_on) | 188 | if (state == lcd_active()) |
239 | return; | 189 | return; |
240 | 190 | ||
241 | if (state) | 191 | if (state) |
@@ -245,99 +195,13 @@ void lcd_enable(bool state) | |||
245 | IPU_IDMAC_CHA_EN |= 1ul << MAIN_LCD_IDMAC_CHANNEL; | 195 | IPU_IDMAC_CHA_EN |= 1ul << MAIN_LCD_IDMAC_CHANNEL; |
246 | lcd_sync_settings(); | 196 | lcd_sync_settings(); |
247 | sleep(HZ/50); | 197 | sleep(HZ/50); |
248 | lcd_on = true; | 198 | lcd_set_active(true); |
249 | lcd_update(); | 199 | lcd_update(); |
250 | send_event(LCD_EVENT_ACTIVATION, NULL); | 200 | send_event(LCD_EVENT_ACTIVATION, NULL); |
251 | } | 201 | } |
252 | else | 202 | else |
253 | { | 203 | { |
254 | lcd_on = false; | 204 | lcd_set_active(false); |
255 | } | ||
256 | } | ||
257 | |||
258 | bool lcd_active(void) | ||
259 | { | ||
260 | return lcd_on; | ||
261 | } | ||
262 | |||
263 | /* Update the display. | ||
264 | This must be called after all other LCD functions that change the display. */ | ||
265 | void lcd_update(void) | ||
266 | { | ||
267 | if (!lcd_on) | ||
268 | return; | ||
269 | |||
270 | lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0], | ||
271 | LCD_WIDTH*LCD_HEIGHT, 1); | ||
272 | } | ||
273 | |||
274 | void lcd_yuv_set_options(unsigned options) | ||
275 | { | ||
276 | lcd_yuv_options = options; | ||
277 | } | ||
278 | |||
279 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | ||
280 | extern void lcd_write_yuv420_lines(fb_data *dst, | ||
281 | unsigned char const * const src[3], | ||
282 | int width, | ||
283 | int stride); | ||
284 | extern void lcd_write_yuv420_lines_odither(fb_data *dst, | ||
285 | unsigned char const * const src[3], | ||
286 | int width, | ||
287 | int stride, | ||
288 | int x_screen, /* To align dither pattern */ | ||
289 | int y_screen); | ||
290 | /* Performance function to blit a YUV bitmap directly to the LCD */ | ||
291 | /* For the Gigabeat - show it rotated */ | ||
292 | /* So the LCD_WIDTH is now the height */ | ||
293 | void lcd_blit_yuv(unsigned char * const src[3], | ||
294 | int src_x, int src_y, int stride, | ||
295 | int x, int y, int width, int height) | ||
296 | { | ||
297 | /* Caches for chroma data so it only need be recaculated every other | ||
298 | line */ | ||
299 | unsigned char const * yuv_src[3]; | ||
300 | off_t z; | ||
301 | |||
302 | if (!lcd_on) | ||
303 | return; | ||
304 | |||
305 | /* Sorry, but width and height must be >= 2 or else */ | ||
306 | width &= ~1; | ||
307 | height >>= 1; | ||
308 | |||
309 | y = LCD_WIDTH - 1 - y; | ||
310 | fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + y; | ||
311 | |||
312 | z = stride*src_y; | ||
313 | yuv_src[0] = src[0] + z + src_x; | ||
314 | yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); | ||
315 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | ||
316 | |||
317 | if (lcd_yuv_options & LCD_YUV_DITHER) | ||
318 | { | ||
319 | do | ||
320 | { | ||
321 | lcd_write_yuv420_lines_odither(dst, yuv_src, width, stride, y, x); | ||
322 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
323 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
324 | yuv_src[2] += stride >> 1; | ||
325 | dst -= 2; | ||
326 | y -= 2; | ||
327 | } | ||
328 | while (--height > 0); | ||
329 | } | ||
330 | else | ||
331 | { | ||
332 | do | ||
333 | { | ||
334 | lcd_write_yuv420_lines(dst, yuv_src, width, stride); | ||
335 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
336 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
337 | yuv_src[2] += stride >> 1; | ||
338 | dst -= 2; | ||
339 | } | ||
340 | while (--height > 0); | ||
341 | } | 205 | } |
342 | } | 206 | } |
343 | 207 | ||
@@ -346,7 +210,7 @@ void lcd_set_contrast(int val) | |||
346 | { | 210 | { |
347 | reg0x0b = val & 0x3f; | 211 | reg0x0b = val & 0x3f; |
348 | 212 | ||
349 | if (!lcd_on) | 213 | if (!lcd_active()) |
350 | return; | 214 | return; |
351 | 215 | ||
352 | lcd_write_reg(0x0b, reg0x0b); | 216 | lcd_write_reg(0x0b, reg0x0b); |
@@ -363,7 +227,7 @@ void lcd_set_invert_display(bool yesno) | |||
363 | { | 227 | { |
364 | reg0x27 = yesno ? 0x10 : 0x00; | 228 | reg0x27 = yesno ? 0x10 : 0x00; |
365 | 229 | ||
366 | if (!lcd_on) | 230 | if (!lcd_active()) |
367 | return; | 231 | return; |
368 | 232 | ||
369 | lcd_write_reg(0x27, reg0x27); | 233 | lcd_write_reg(0x27, reg0x27); |
@@ -375,7 +239,7 @@ void lcd_set_flip(bool yesno) | |||
375 | { | 239 | { |
376 | reg0x06 = yesno ? 0x02 : 0x04; | 240 | reg0x06 = yesno ? 0x02 : 0x04; |
377 | 241 | ||
378 | if (!lcd_on) | 242 | if (!lcd_active()) |
379 | return; | 243 | return; |
380 | 244 | ||
381 | lcd_write_reg(0x06, reg0x06); | 245 | lcd_write_reg(0x06, reg0x06); |