summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-ipod.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-ipod.c')
-rw-r--r--firmware/drivers/lcd-ipod.c201
1 files changed, 188 insertions, 13 deletions
diff --git a/firmware/drivers/lcd-ipod.c b/firmware/drivers/lcd-ipod.c
index 0ff22ab9b5..2d165551e6 100644
--- a/firmware/drivers/lcd-ipod.c
+++ b/firmware/drivers/lcd-ipod.c
@@ -29,7 +29,192 @@
29#include "kernel.h" 29#include "kernel.h"
30#include "system.h" 30#include "system.h"
31 31
32/*** definitions ***/ 32
33/* check if number of useconds has past */
34static int timer_check(int clock_start, int usecs)
35{
36 if ( ((int)(USEC_TIMER - clock_start)) >= usecs ) {
37 return 1;
38 } else {
39 return 0;
40 }
41}
42
43
44#if (CONFIG_LCD == LCD_IPOD2BPP)
45
46/*** hardware configuration ***/
47
48#define IPOD_LCD_BASE 0xc0001000
49#define IPOD_LCD_BUSY_MASK 0x80000000
50
51/* LCD command codes for HD66789R */
52
53
54#define LCD_CMD 0x08
55#define LCD_DATA 0x10
56
57static unsigned int lcd_contrast = 0x6a;
58
59
60/* wait for LCD with timeout */
61static void lcd_wait_write(void)
62{
63 int start = USEC_TIMER;
64
65 do {
66 if ((inl(IPOD_LCD_BASE) & 0x8000) == 0) break;
67 } while (timer_check(start, 1000) == 0);
68}
69
70
71/* send LCD data */
72static void lcd_send_data(int data_lo, int data_hi)
73{
74 lcd_wait_write();
75 outl(data_lo, IPOD_LCD_BASE + LCD_DATA);
76 lcd_wait_write();
77 outl(data_hi, IPOD_LCD_BASE + LCD_DATA);
78}
79
80/* send LCD command */
81static void lcd_prepare_cmd(int cmd)
82{
83 lcd_wait_write();
84
85 outl(0x0, IPOD_LCD_BASE + LCD_CMD);
86 lcd_wait_write();
87 outl(cmd, IPOD_LCD_BASE + LCD_CMD);
88
89}
90
91/* send LCD command and data */
92static void lcd_cmd_and_data(int cmd, int data_lo, int data_hi)
93{
94 lcd_prepare_cmd(cmd);
95
96 lcd_send_data(data_lo, data_hi);
97}
98
99int lcd_default_contrast(void)
100{
101 return 28;
102}
103
104/**
105 *
106 * LCD init
107 **/
108void lcd_init_device(void){
109 /* driver output control - 160x128 */
110 lcd_cmd_and_data(0x1, 0x1, 0xf);
111 lcd_cmd_and_data(0x5, 0x0, 0x10);
112}
113
114/*** update functions ***/
115/* srccopy bitblt, opcode is currently ignored*/
116
117/* Performance function that works with an external buffer
118 note that x and bwidtht are in 8-pixel units! */
119void lcd_blit(const unsigned char* data, int x, int by, int width,
120 int bheight, int stride)
121{
122 /* TODO implement this on iPod */
123 (void)data;
124 (void)x;
125 (void)by;
126 (void)width;
127 (void)bheight;
128 (void)stride;
129}
130
131/* Rolls up the lcd display by the specified amount of lines.
132 * Lines that are rolled out over the top of the screen are
133 * rolled in from the bottom again. This is a hardware
134 * remapping only and all operations on the lcd are affected.
135 * ->
136 * @param int lines - The number of lines that are rolled.
137 * The value must be 0 <= pixels < LCD_HEIGHT. */
138void lcd_roll(int lines)
139{
140 /* TODO Implement lcd_roll() */
141 lines &= LCD_HEIGHT-1;
142}
143
144/*** hardware configuration ***/
145
146/* Update the display.
147 This must be called after all other LCD functions that change the display. */
148void lcd_update(void)
149{
150 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
151}
152
153void lcd_set_contrast(int val)
154{
155 lcd_cmd_and_data(0x4, 0x4, val);
156 lcd_contrast = val;
157}
158
159void lcd_update_rect(int x, int y, int width, int height)
160{
161 int cursor_pos, xx;
162 int ny;
163 int sx = x, sy = y, mx = width, my = height;
164
165 /* only update the ipod if we are writing to the screen */
166
167 sx >>= 3;
168 //mx = (mx+7)>>3;
169 mx >>= 3;
170
171 cursor_pos = sx + (sy << 5);
172
173 for ( ny = sy; ny <= my; ny++ ) {
174 unsigned char * img_data;
175
176
177 // move the cursor
178 lcd_cmd_and_data(0x11, cursor_pos >> 8, cursor_pos & 0xff);
179
180 // setup for printing
181 lcd_prepare_cmd(0x12);
182
183 img_data = &lcd_framebuffer[ny][sx<<1];
184
185 // 160/8 -> 20 == loops 20 times
186 // make sure we loop at least once
187 for ( xx = sx; xx <= mx; xx++ ) {
188 // display a character
189 lcd_send_data(*(img_data+1), *img_data);
190
191 img_data += 2;
192 }
193
194 // update cursor pos counter
195 cursor_pos += 0x20;
196 }
197}
198
199/** Switch on or off the backlight **/
200void lcd_enable (bool on){
201 int lcd_state;
202
203 lcd_state = inl(IPOD_LCD_BASE);
204 if (on){
205 lcd_state = lcd_state | 0x2;
206 outl(lcd_state, IPOD_LCD_BASE);
207 lcd_cmd_and_data(0x7, 0x0, 0x11);
208 }
209 else {
210 lcd_state = lcd_state & ~0x2;
211 outl(lcd_state, IPOD_LCD_BASE);
212 lcd_cmd_and_data(0x7, 0x0, 0x9);
213 }
214}
215
216#else
217
33#define IPOD_LCD_BASE 0x70008a0c 218#define IPOD_LCD_BASE 0x70008a0c
34#define IPOD_LCD_BUSY_MASK 0x80000000 219#define IPOD_LCD_BUSY_MASK 0x80000000
35 220
@@ -42,17 +227,6 @@
42/*** globals ***/ 227/*** globals ***/
43static int lcd_type = 1; /* 0 = "old" Color/Photo, 1 = "new" Color & Nano */ 228static int lcd_type = 1; /* 0 = "old" Color/Photo, 1 = "new" Color & Nano */
44 229
45
46/* check if number of useconds has past */
47static inline int timer_check(unsigned long clock_start, unsigned long usecs)
48{
49 if ( (USEC_TIMER - clock_start) >= usecs ) {
50 return 1;
51 } else {
52 return 0;
53 }
54}
55
56static void lcd_wait_write(void) 230static void lcd_wait_write(void)
57{ 231{
58 if ((inl(IPOD_LCD_BASE) & IPOD_LCD_BUSY_MASK) != 0) { 232 if ((inl(IPOD_LCD_BASE) & IPOD_LCD_BUSY_MASK) != 0) {
@@ -229,7 +403,7 @@ void lcd_update_rect(int x, int y, int width, int height)
229 403
230 /* start vert = max vert */ 404 /* start vert = max vert */
231#if CONFIG_LCD == LCD_IPODCOLOR 405#if CONFIG_LCD == LCD_IPODCOLOR
232 x0 = x1; 406 x0 = x1;
233#endif 407#endif
234 408
235 /* position cursor (set AD0-AD15) */ 409 /* position cursor (set AD0-AD15) */
@@ -288,3 +462,4 @@ void lcd_update(void)
288 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); 462 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
289} 463}
290 464
465#endif