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