1
2
3
4
5
6
7
8
9
10
11
12
13#include <common.h>
14#include <asm/arch/sys_proto.h>
15#include <asm/arch/cpu.h>
16#include <asm/arch/emc.h>
17#include <asm/gpio.h>
18#include <spi.h>
19#include <i2c.h>
20#include <version.h>
21#include <vsprintf.h>
22
23
24
25
26
27#define GPO_15 111
28
29
30
31
32
33#define MAX6957_CONF 0x04
34
35#define MAX6957_CONF_08_11 0x0A
36#define MAX6957_CONF_12_15 0x0B
37#define MAX6957_CONF_16_19 0x0C
38
39
40
41
42
43#define MAX6957AAX_HD44780_RS 0x29
44#define MAX6957AAX_HD44780_R_W 0x2A
45#define MAX6957AAX_HD44780_EN 0x2B
46#define MAX6957AAX_HD44780_DATA 0x4C
47
48
49
50
51
52
53#define HD44780_FUNCTION_SET 0x38
54
55
56#define HD44780_DISPLAY_ON_OFF_CONTROL 0x0C
57
58
59#define HD44780_ENTRY_MODE_SET 0x06
60
61
62#define HD44780_CLEAR_DISPLAY 0x01
63
64
65#define HD44780_SET_DDRAM_ADDR 0x80
66
67
68#define HD44780_SET_CGRAM_ADDR 0x40
69
70
71
72
73
74#define CONTRAST_DEFAULT 25
75
76
77
78
79
80
81static struct spi_slave *slave;
82
83
84
85
86
87static void max6957aax_write(uint8_t reg, uint8_t value)
88{
89 uint8_t dout[2];
90
91 dout[0] = reg;
92 dout[1] = value;
93 gpio_set_value(GPO_15, 0);
94
95 spi_xfer(slave, 16, dout, dout, SPI_XFER_BEGIN | SPI_XFER_END);
96 gpio_set_value(GPO_15, 1);
97}
98
99
100
101
102
103
104
105
106
107
108
109static uint8_t max6957aax_read(uint8_t reg)
110{
111 uint8_t dout[2], din[2];
112
113
114 dout[0] = reg | 0x80;
115 dout[1] = 0;
116 gpio_set_value(GPO_15, 0);
117
118 spi_xfer(slave, 16, dout, dout, SPI_XFER_BEGIN | SPI_XFER_END);
119
120 gpio_set_value(GPO_15, 1);
121
122 din[0] = 0;
123 din[1] = 0;
124 gpio_set_value(GPO_15, 0);
125
126 spi_xfer(slave, 16, din, din, SPI_XFER_BEGIN | SPI_XFER_END);
127
128 gpio_set_value(GPO_15, 1);
129 return din[1];
130}
131
132static void hd44780_instruction(unsigned long instruction)
133{
134 max6957aax_write(MAX6957AAX_HD44780_RS, 0);
135 max6957aax_write(MAX6957AAX_HD44780_R_W, 0);
136 max6957aax_write(MAX6957AAX_HD44780_EN, 1);
137 max6957aax_write(MAX6957AAX_HD44780_DATA, instruction);
138 max6957aax_write(MAX6957AAX_HD44780_EN, 0);
139
140 if (instruction == HD44780_CLEAR_DISPLAY)
141 udelay(2000);
142 else
143 udelay(100);
144}
145
146static void hd44780_write_char(char c)
147{
148 max6957aax_write(MAX6957AAX_HD44780_RS, 1);
149 max6957aax_write(MAX6957AAX_HD44780_R_W, 0);
150 max6957aax_write(MAX6957AAX_HD44780_EN, 1);
151 max6957aax_write(MAX6957AAX_HD44780_DATA, c);
152 max6957aax_write(MAX6957AAX_HD44780_EN, 0);
153
154 udelay(100);
155}
156
157static void hd44780_write_str(char *s)
158{
159 max6957aax_write(MAX6957AAX_HD44780_RS, 1);
160 max6957aax_write(MAX6957AAX_HD44780_R_W, 0);
161 while (*s) {
162 max6957aax_write(MAX6957AAX_HD44780_EN, 1);
163 max6957aax_write(MAX6957AAX_HD44780_DATA, *s);
164 max6957aax_write(MAX6957AAX_HD44780_EN, 0);
165 s++;
166
167 udelay(100);
168 }
169}
170
171
172
173
174
175
176static u8 char_gen_chars[] = {
177
178 0x1F, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1F,
179
180 0x10, 0x18, 0x1C, 0x1E, 0x1C, 0x18, 0x10, 0x00,
181
182 0x01, 0x03, 0x07, 0x0F, 0x07, 0x03, 0x01, 0x00,
183
184 0x04, 0x0E, 0x1F, 0x00, 0x00, 0x1F, 0x0E, 0x04,
185
186 0x04, 0x04, 0x1F, 0x04, 0x04, 0x00, 0x1F, 0x00,
187
188 0x06, 0x06, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00,
189
190 0x00, 0x1F, 0x11, 0x11, 0x11, 0x1F, 0x00, 0x00,
191
192 0x00, 0x1F, 0x19, 0x15, 0x13, 0x1F, 0x00, 0x00,
193};
194
195static void hd44780_init_char_gen(void)
196{
197 int i;
198
199 hd44780_instruction(HD44780_SET_CGRAM_ADDR);
200
201 for (i = 0; i < sizeof(char_gen_chars); i++)
202 hd44780_write_char(char_gen_chars[i]);
203
204 hd44780_instruction(HD44780_SET_DDRAM_ADDR);
205}
206
207void work_92105_display_init(void)
208{
209 int claim_err;
210 char *display_contrast_str;
211 uint8_t display_contrast = CONTRAST_DEFAULT;
212 uint8_t enable_backlight = 0x96;
213
214 slave = spi_setup_slave(0, 0, 500000, 0);
215
216 if (!slave) {
217 printf("Failed to set up SPI slave\n");
218 return;
219 }
220
221 claim_err = spi_claim_bus(slave);
222
223 if (claim_err)
224 debug("Failed to claim SPI bus: %d\n", claim_err);
225
226
227 i2c_write(0x2c, 0x01, 1, &enable_backlight, 1);
228
229
230 display_contrast_str = env_get("fwopt_dispcontrast");
231 if (display_contrast_str)
232 display_contrast = simple_strtoul(display_contrast_str,
233 NULL, 10);
234 i2c_write(0x2c, 0x00, 1, &display_contrast, 1);
235
236
237 gpio_request(GPO_15, "MAX6957_nCS");
238 gpio_direction_output(GPO_15, 1);
239
240
241 max6957aax_write(MAX6957_CONF, 0x01);
242
243 max6957aax_write(MAX6957_CONF_08_11, 0x56);
244 max6957aax_write(MAX6957_CONF_12_15, 0x55);
245 max6957aax_write(MAX6957_CONF_16_19, 0x55);
246
247
248 max6957aax_write(MAX6957AAX_HD44780_EN, 0);
249 hd44780_instruction(HD44780_FUNCTION_SET);
250 hd44780_instruction(HD44780_DISPLAY_ON_OFF_CONTROL);
251 hd44780_instruction(HD44780_ENTRY_MODE_SET);
252
253
254 hd44780_init_char_gen();
255
256
257 hd44780_instruction(HD44780_CLEAR_DISPLAY);
258 hd44780_instruction(HD44780_SET_DDRAM_ADDR | 0);
259 hd44780_write_str(U_BOOT_VERSION);
260 hd44780_instruction(HD44780_SET_DDRAM_ADDR | 64);
261 hd44780_write_str(U_BOOT_DATE);
262 hd44780_instruction(HD44780_SET_DDRAM_ADDR | 64 | 20);
263 hd44780_write_str(U_BOOT_TIME);
264}
265
266#ifdef CONFIG_CMD_MAX6957
267
268static int do_max6957aax(cmd_tbl_t *cmdtp, int flag, int argc,
269 char *const argv[])
270{
271 int reg, val;
272
273 if (argc != 3)
274 return CMD_RET_USAGE;
275 switch (argv[1][0]) {
276 case 'r':
277 case 'R':
278 reg = simple_strtoul(argv[2], NULL, 0);
279 val = max6957aax_read(reg);
280 printf("MAX6957 reg 0x%02x read 0x%02x\n", reg, val);
281 return 0;
282 default:
283 reg = simple_strtoul(argv[1], NULL, 0);
284 val = simple_strtoul(argv[2], NULL, 0);
285 max6957aax_write(reg, val);
286 printf("MAX6957 reg 0x%02x wrote 0x%02x\n", reg, val);
287 return 0;
288 }
289 return 1;
290}
291
292#ifdef CONFIG_SYS_LONGHELP
293static char max6957aax_help_text[] =
294 "max6957aax - write or read display register:\n"
295 "\tmax6957aax R|r reg - read display register;\n"
296 "\tmax6957aax reg val - write display register.";
297#endif
298
299U_BOOT_CMD(
300 max6957aax, 6, 1, do_max6957aax,
301 "SPI MAX6957 display write/read",
302 max6957aax_help_text
303);
304#endif
305
306#ifdef CONFIG_CMD_HD44760
307
308
309
310
311
312
313#if !defined(CONFIG_HUSH_PARSER)
314#error CONFIG_CMD_HD44760 requires CONFIG_HUSH_PARSER
315#endif
316
317static int do_hd44780(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
318{
319 char *cmd;
320
321 if (argc != 3)
322 return CMD_RET_USAGE;
323
324 cmd = argv[1];
325
326 if (strcasecmp(cmd, "cmd") == 0)
327 hd44780_instruction(simple_strtol(argv[2], NULL, 0));
328 else if (strcasecmp(cmd, "data") == 0)
329 hd44780_write_char(simple_strtol(argv[2], NULL, 0));
330 else if (strcasecmp(cmd, "str") == 0)
331 hd44780_write_str(argv[2]);
332 return 0;
333}
334
335#ifdef CONFIG_SYS_LONGHELP
336static char hd44780_help_text[] =
337 "hd44780 - control LCD driver:\n"
338 "\thd44780 cmd <val> - send command <val> to driver;\n"
339 "\thd44780 data <val> - send data <val> to driver;\n"
340 "\thd44780 str \"<text>\" - send \"<text>\" to driver.";
341#endif
342
343U_BOOT_CMD(
344 hd44780, 6, 1, do_hd44780,
345 "HD44780 LCD driver control",
346 hd44780_help_text
347);
348#endif
349