blob: 2872301598df266ffe2822f9eb782b0e23b7156c [file] [log] [blame]
Max Filippov0d456ba2012-11-05 07:37:14 +04001/*
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
37static 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
53void 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
64void lcd_shiftleft(void)
65{
66 *LCD_INSTR_ADDR = LCD_SHIFT_LEFT;
67 udelay(50);
68}
69
70void lcd_shiftright(void)
71{
72 *LCD_INSTR_ADDR = LCD_SHIFT_RIGHT;
73 udelay(50);
74}
75
76arch_initcall(lcd_init);