uboot/board/amcc/taihu/lcd.c
<<
>>
Prefs
   1/*
   2 * See file CREDITS for list of people who contributed to this
   3 * project.
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License as
   7 * published by the Free Software Foundation; either version 2 of
   8 * the License, or (at your option) any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  18 * MA 02111-1307 USA
  19 */
  20
  21#include <config.h>
  22#include <common.h>
  23#include <command.h>
  24#include <asm/io.h>
  25#include <asm/gpio.h>
  26
  27#define LCD_CMD_ADDR    0x50100002
  28#define LCD_DATA_ADDR   0x50100003
  29#define LCD_BLK_CTRL    CPLD_REG1_ADDR
  30
  31static char *amcc_logo = "AMCC 405EP TAIHU EVALUATION KIT";
  32static int addr_flag = 0x80;
  33
  34static void lcd_bl_ctrl(char val)
  35{
  36        out_8((u8 *) LCD_BLK_CTRL, in_8((u8 *) LCD_BLK_CTRL) | val);
  37}
  38
  39static void lcd_putc(int val)
  40{
  41        int i = 100;
  42        char addr;
  43
  44        while (i--) {
  45                if ((in_8((u8 *) LCD_CMD_ADDR) & 0x80) != 0x80) { /*BF = 1 ?*/
  46                        udelay(50);
  47                        break;
  48                }
  49                udelay(50);
  50        }
  51
  52        if (in_8((u8 *) LCD_CMD_ADDR) & 0x80) {
  53                printf("LCD is busy\n");
  54                return;
  55        }
  56
  57        addr = in_8((u8 *) LCD_CMD_ADDR);
  58        udelay(50);
  59        if ((addr != 0) && (addr % 0x10 == 0)) {
  60                addr_flag ^= 0x40;
  61                out_8((u8 *) LCD_CMD_ADDR, addr_flag);
  62        }
  63
  64        udelay(50);
  65        out_8((u8 *) LCD_DATA_ADDR, val);
  66        udelay(50);
  67}
  68
  69static void lcd_puts(char *s)
  70{
  71        char *p = s;
  72        int i = 100;
  73
  74        while (i--) {
  75                if ((in_8((u8 *) LCD_CMD_ADDR) & 0x80) != 0x80) { /*BF = 1 ?*/
  76                        udelay(50);
  77                        break;
  78                }
  79                udelay(50);
  80        }
  81
  82        if (in_8((u8 *) LCD_CMD_ADDR) & 0x80) {
  83                printf("LCD is busy\n");
  84                return;
  85        }
  86
  87        while (*p)
  88                lcd_putc(*p++);
  89}
  90
  91static void lcd_put_logo(void)
  92{
  93        int i = 100;
  94        char *p = amcc_logo;
  95
  96        while (i--) {
  97                if ((in_8((u8 *) LCD_CMD_ADDR) & 0x80) != 0x80) { /*BF = 1 ?*/
  98                        udelay(50);
  99                        break;
 100                }
 101                udelay(50);
 102        }
 103
 104        if (in_8((u8 *) LCD_CMD_ADDR) & 0x80) {
 105                printf("LCD is busy\n");
 106                return;
 107        }
 108
 109        out_8((u8 *) LCD_CMD_ADDR, 0x80);
 110        while (*p)
 111                lcd_putc(*p++);
 112}
 113
 114int lcd_init(void)
 115{
 116        puts("LCD: ");
 117        out_8((u8 *) LCD_CMD_ADDR, 0x38); /* set function:8-bit,2-line,5x7 font type */
 118        udelay(50);
 119        out_8((u8 *) LCD_CMD_ADDR, 0x0f); /* set display on,cursor on,blink on */
 120        udelay(50);
 121        out_8((u8 *) LCD_CMD_ADDR, 0x01); /* display clear */
 122        udelay(2000);
 123        out_8((u8 *) LCD_CMD_ADDR, 0x06); /* set entry */
 124        udelay(50);
 125        lcd_bl_ctrl(0x02);              /* set backlight on */
 126        lcd_put_logo();
 127        puts("ready\n");
 128
 129        return 0;
 130}
 131
 132static int do_lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 133{
 134        out_8((u8 *) LCD_CMD_ADDR, 0x01);
 135        udelay(2000);
 136
 137        return 0;
 138}
 139
 140static int do_lcd_puts (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 141{
 142        if (argc < 2) {
 143                printf("%s", cmdtp->usage);
 144                return 1;
 145        }
 146        lcd_puts(argv[1]);
 147
 148        return 0;
 149}
 150
 151static int do_lcd_putc (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 152{
 153        if (argc < 2) {
 154                printf("%s", cmdtp->usage);
 155                return 1;
 156        }
 157        lcd_putc((char)argv[1][0]);
 158
 159        return 0;
 160}
 161
 162static int do_lcd_cur (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 163{
 164        ulong count;
 165        ulong dir;
 166        char cur_addr;
 167
 168        if (argc < 3) {
 169                printf("%s", cmdtp->usage);
 170                return 1;
 171        }
 172
 173        count = simple_strtoul(argv[1], NULL, 16);
 174        if (count > 31) {
 175                printf("unable to shift > 0x20\n");
 176                count = 0;
 177        }
 178
 179        dir = simple_strtoul(argv[2], NULL, 16);
 180        cur_addr = in_8((u8 *) LCD_CMD_ADDR);
 181        udelay(50);
 182
 183        if (dir == 0x0) {
 184                if (addr_flag == 0x80) {
 185                        if (count >= (cur_addr & 0xf)) {
 186                                out_8((u8 *) LCD_CMD_ADDR, 0x80);
 187                                udelay(50);
 188                                count = 0;
 189                        }
 190                } else {
 191                        if (count >= ((cur_addr & 0x0f) + 0x0f)) {
 192                                out_8((u8 *) LCD_CMD_ADDR, 0x80);
 193                                addr_flag = 0x80;
 194                                udelay(50);
 195                                count = 0x0;
 196                        } else if (count >= ( cur_addr & 0xf)) {
 197                                count -= cur_addr & 0xf ;
 198                                out_8((u8 *) LCD_CMD_ADDR, 0x80 | 0xf);
 199                                addr_flag = 0x80;
 200                                udelay(50);
 201                        }
 202                }
 203        } else {
 204                if (addr_flag == 0x80) {
 205                        if (count >= (0x1f - (cur_addr & 0xf))) {
 206                                count = 0x0;
 207                                addr_flag = 0xc0;
 208                                out_8((u8 *) LCD_CMD_ADDR, 0xc0 | 0xf);
 209                                udelay(50);
 210                        } else if ((count + (cur_addr & 0xf ))>=  0x0f) {
 211                                count = count + (cur_addr & 0xf) - 0x0f;
 212                                addr_flag = 0xc0;
 213                                out_8((u8 *) LCD_CMD_ADDR, 0xc0);
 214                                udelay(50);
 215                        }
 216                } else if ((count + (cur_addr & 0xf )) >= 0x0f) {
 217                        count = 0x0;
 218                        out_8((u8 *) LCD_CMD_ADDR, 0xC0 | 0x0F);
 219                        udelay(50);
 220                }
 221        }
 222        while (count--) {
 223                if (dir == 0)
 224                        out_8((u8 *) LCD_CMD_ADDR, 0x10);
 225                else
 226                        out_8((u8 *) LCD_CMD_ADDR, 0x14);
 227                udelay(50);
 228        }
 229
 230        return 0;
 231}
 232
 233U_BOOT_CMD(
 234        lcd_cls, 1, 1, do_lcd_clear,
 235        "lcd_cls - lcd clear display\n",
 236        NULL
 237        );
 238
 239U_BOOT_CMD(
 240        lcd_puts, 2, 1, do_lcd_puts,
 241        "lcd_puts - display string on lcd\n",
 242        "<string> - <string> to be displayed\n"
 243        );
 244
 245U_BOOT_CMD(
 246        lcd_putc, 2, 1, do_lcd_putc,
 247        "lcd_putc - display char on lcd\n",
 248        "<char> - <char> to be displayed\n"
 249        );
 250
 251U_BOOT_CMD(
 252        lcd_cur, 3, 1, do_lcd_cur,
 253        "lcd_cur - shift cursor on lcd\n",
 254        "<count> <dir> - shift cursor on lcd <count> times, direction is <dir> \n"
 255        " <count> - 0..31\n"
 256        " <dir>   - 0=backward 1=forward\n"
 257        );
 258