xref: /openbmc/linux/arch/xtensa/platforms/xtfpga/lcd.c (revision c819e2cf)
1 /*
2  * Driver for the LCD display on the Tensilica LX60 Board.
3  *
4  * This file is subject to the terms and conditions of the GNU General Public
5  * License.  See the file "COPYING" in the main directory of this archive
6  * for more details.
7  *
8  * Copyright (C) 2001, 2006 Tensilica Inc.
9  */
10 
11 /*
12  *
13  * FIXME: this code is from the examples from the LX60 user guide.
14  *
15  * The lcd_pause function does busy waiting, which is probably not
16  * great. Maybe the code could be changed to use kernel timers, or
17  * change the hardware to not need to wait.
18  */
19 
20 #include <linux/init.h>
21 #include <linux/io.h>
22 
23 #include <platform/hardware.h>
24 #include <platform/lcd.h>
25 #include <linux/delay.h>
26 
27 #define LCD_PAUSE_ITERATIONS	4000
28 #define LCD_CLEAR		0x1
29 #define LCD_DISPLAY_ON		0xc
30 
31 /* 8bit and 2 lines display */
32 #define LCD_DISPLAY_MODE8BIT	0x38
33 #define LCD_DISPLAY_POS		0x80
34 #define LCD_SHIFT_LEFT		0x18
35 #define LCD_SHIFT_RIGHT		0x1c
36 
37 static int __init lcd_init(void)
38 {
39 	*LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT;
40 	mdelay(5);
41 	*LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT;
42 	udelay(200);
43 	*LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT;
44 	udelay(50);
45 	*LCD_INSTR_ADDR = LCD_DISPLAY_ON;
46 	udelay(50);
47 	*LCD_INSTR_ADDR = LCD_CLEAR;
48 	mdelay(10);
49 	lcd_disp_at_pos("XTENSA LINUX", 0);
50 	return 0;
51 }
52 
53 void lcd_disp_at_pos(char *str, unsigned char pos)
54 {
55 	*LCD_INSTR_ADDR = LCD_DISPLAY_POS | pos;
56 	udelay(100);
57 	while (*str != 0) {
58 		*LCD_DATA_ADDR = *str;
59 		udelay(200);
60 		str++;
61 	}
62 }
63 
64 void lcd_shiftleft(void)
65 {
66 	*LCD_INSTR_ADDR = LCD_SHIFT_LEFT;
67 	udelay(50);
68 }
69 
70 void lcd_shiftright(void)
71 {
72 	*LCD_INSTR_ADDR = LCD_SHIFT_RIGHT;
73 	udelay(50);
74 }
75 
76 arch_initcall(lcd_init);
77