Merge branch 'fixes' into cleanups
[platform/kernel/u-boot.git] / board / cogent / lcd.c
1 /* most of this is taken from the file */
2 /* hal/powerpc/cogent/current/src/hal_diag.c in the */
3 /* Cygnus eCos source. Here is the copyright notice: */
4 /* */
5 /*============================================================================= */
6 /* */
7 /*      hal_diag.c */
8 /* */
9 /*      HAL diagnostic output code */
10 /* */
11 /*============================================================================= */
12 /*####COPYRIGHTBEGIN#### */
13 /* */
14 /* ------------------------------------------- */
15 /* The contents of this file are subject to the Cygnus eCos Public License */
16 /* Version 1.0 (the "License"); you may not use this file except in */
17 /* compliance with the License.  You may obtain a copy of the License at */
18 /* http://sourceware.cygnus.com/ecos */
19 /* */
20 /* Software distributed under the License is distributed on an "AS IS" */
21 /* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the */
22 /* License for the specific language governing rights and limitations under */
23 /* the License. */
24 /* */
25 /* The Original Code is eCos - Embedded Cygnus Operating System, released */
26 /* September 30, 1998. */
27 /* */
28 /* The Initial Developer of the Original Code is Cygnus.  Portions created */
29 /* by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions.  All Rights Reserved. */
30 /* ------------------------------------------- */
31 /* */
32 /*####COPYRIGHTEND#### */
33 /*============================================================================= */
34 /*#####DESCRIPTIONBEGIN#### */
35 /* */
36 /* Author(s):    nickg, jskov */
37 /* Contributors: nickg, jskov */
38 /* Date:         1999-03-23 */
39 /* Purpose:      HAL diagnostic output */
40 /* Description:  Implementations of HAL diagnostic output support. */
41 /* */
42 /*####DESCRIPTIONEND#### */
43 /* */
44 /*============================================================================= */
45
46 /*----------------------------------------------------------------------------- */
47 /* Cogent board specific LCD code */
48
49 #include <common.h>
50 #include <stdarg.h>
51 #include <board/cogent/lcd.h>
52
53 static char lines[2][LCD_LINE_LENGTH+1];
54 static int curline;
55 static int linepos;
56 static int heartbeat_active;
57 /* make the next two strings exactly LCD_LINE_LENGTH (16) chars long */
58 /* pad to the right with spaces if necessary */
59 static char init_line0[LCD_LINE_LENGTH+1] = "U-Boot Cogent  ";
60 static char init_line1[LCD_LINE_LENGTH+1] = "mjj, 11 Aug 2000";
61
62 static inline unsigned char
63 lcd_read_status(cma_mb_lcd *clp)
64 {
65     /* read the Busy Status Register */
66     return (cma_mb_reg_read(&clp->lcd_bsr));
67 }
68
69 static inline void
70 lcd_wait_not_busy(cma_mb_lcd *clp)
71 {
72     /*
73      * wait for not busy
74      * Note: It seems that the LCD isn't quite ready to process commands
75      * when it clears the BUSY flag. Reading the status address an extra
76      * time seems to give it enough breathing room.
77      */
78
79     while (lcd_read_status(clp) & LCD_STAT_BUSY)
80         ;
81
82     (void)lcd_read_status(clp);
83 }
84
85 static inline void
86 lcd_write_command(cma_mb_lcd *clp, unsigned char cmd)
87 {
88     lcd_wait_not_busy(clp);
89
90     /* write the Command Register */
91     cma_mb_reg_write(&clp->lcd_cmd, cmd);
92 }
93
94 static inline void
95 lcd_write_data(cma_mb_lcd *clp, unsigned char data)
96 {
97     lcd_wait_not_busy(clp);
98
99     /* write the Current Character Register */
100     cma_mb_reg_write(&clp->lcd_ccr, data);
101 }
102
103 static inline void
104 lcd_dis(int addr, char *string)
105 {
106     cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE;
107     int pos, linelen;
108
109     linelen = LCD_LINE_LENGTH;
110     if (heartbeat_active && addr == LCD_LINE0)
111         linelen--;
112
113     lcd_write_command(clp, LCD_CMD_ADD + addr);
114     for (pos = 0; *string != '\0' && pos < linelen; pos++)
115         lcd_write_data(clp, *string++);
116 }
117
118 void
119 lcd_init(void)
120 {
121     cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE;
122     int i;
123
124     /* configure the lcd for 8 bits/char, 2 lines and 5x7 dot matrix */
125     lcd_write_command(clp, LCD_CMD_MODE);
126
127     /* turn the LCD display on */
128     lcd_write_command(clp, LCD_CMD_DON);
129
130     curline = 0;
131     linepos = 0;
132
133     for (i = 0; i < LCD_LINE_LENGTH; i++) {
134         lines[0][i] = init_line0[i];
135         lines[1][i] = init_line1[i];
136     }
137
138     lines[0][LCD_LINE_LENGTH] = lines[1][LCD_LINE_LENGTH] = 0;
139
140     lcd_dis(LCD_LINE0, lines[0]);
141     lcd_dis(LCD_LINE1, lines[1]);
142
143     printf("HD44780 2 line x %d char display\n", LCD_LINE_LENGTH);
144 }
145
146 void
147 lcd_write_char(const char c)
148 {
149     int i, linelen;
150
151     /* ignore CR */
152     if (c == '\r')
153         return;
154
155     linelen = LCD_LINE_LENGTH;
156     if (heartbeat_active && curline == 0)
157         linelen--;
158
159     if (c == '\n') {
160         lcd_dis(LCD_LINE0, &lines[curline^1][0]);
161         lcd_dis(LCD_LINE1, &lines[curline][0]);
162
163         /* Do a line feed */
164         curline ^= 1;
165         linelen = LCD_LINE_LENGTH;
166         if (heartbeat_active && curline == 0)
167             linelen--;
168         linepos = 0;
169
170         for (i = 0; i < linelen; i++)
171             lines[curline][i] = ' ';
172
173         return;
174     }
175
176     /* Only allow to be output if there is room on the LCD line */
177     if (linepos < linelen)
178         lines[curline][linepos++] = c;
179 }
180
181 void
182 lcd_flush(void)
183 {
184     lcd_dis(LCD_LINE1, &lines[curline][0]);
185 }
186
187 void
188 lcd_write_string(const char *s)
189 {
190     char *p;
191
192     for (p = (char *)s; *p != '\0'; p++)
193         lcd_write_char(*p);
194 }
195
196 void
197 lcd_printf(const char *fmt, ...)
198 {
199     va_list args;
200     char buf[CONFIG_SYS_PBSIZE];
201
202     va_start(args, fmt);
203     (void)vsprintf(buf, fmt, args);
204     va_end(args);
205
206     lcd_write_string(buf);
207 }
208
209 void
210 lcd_heartbeat(void)
211 {
212     cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE;
213 #if 0
214     static char rotchars[] = { '|', '/', '-', '\\' };
215 #else
216     /* HD44780 Rom Code A00 has no backslash */
217     static char rotchars[] = { '|', '/', '-', '\315' };
218 #endif
219     static int rotator_index = 0;
220
221     heartbeat_active = 1;
222
223     /* write the address */
224     lcd_write_command(clp, LCD_CMD_ADD + LCD_LINE0 + (LCD_LINE_LENGTH - 1));
225
226     /* write the next char in the sequence */
227     lcd_write_data(clp, rotchars[rotator_index]);
228
229     if (++rotator_index >= (sizeof rotchars / sizeof rotchars[0]))
230         rotator_index = 0;
231 }
232
233 #ifdef CONFIG_SHOW_ACTIVITY
234 void board_show_activity (ulong timestamp)
235 {
236 #ifdef CONFIG_STATUS_LED
237         if ((timestamp % (CONFIG_SYS_HZ / 2) == 0)
238                 lcd_heartbeat ();
239 #endif
240 }
241
242 void show_activity(int arg)
243 {
244 }
245 #endif