linux/arch/xtensa/platforms/xtfpga/lcd.c
<<
>>
Prefs
   1/*
   2 * Driver for the LCD display on the Tensilica XTFPGA board family.
   3 * http://www.mytechcorp.com/cfdata/productFile/File1/MOC-16216B-B-A0A04.pdf
   4 *
   5 * This file is subject to the terms and conditions of the GNU General Public
   6 * License.  See the file "COPYING" in the main directory of this archive
   7 * for more details.
   8 *
   9 * Copyright (C) 2001, 2006 Tensilica Inc.
  10 * Copyright (C) 2015 Cadence Design Systems Inc.
  11 */
  12
  13#include <linux/delay.h>
  14#include <linux/init.h>
  15#include <linux/io.h>
  16
  17#include <platform/hardware.h>
  18#include <platform/lcd.h>
  19
  20/* LCD instruction and data addresses. */
  21#define LCD_INSTR_ADDR          ((char *)IOADDR(CONFIG_XTFPGA_LCD_BASE_ADDR))
  22#define LCD_DATA_ADDR           (LCD_INSTR_ADDR + 4)
  23
  24#define LCD_CLEAR               0x1
  25#define LCD_DISPLAY_ON          0xc
  26
  27/* 8bit and 2 lines display */
  28#define LCD_DISPLAY_MODE8BIT    0x38
  29#define LCD_DISPLAY_MODE4BIT    0x28
  30#define LCD_DISPLAY_POS         0x80
  31#define LCD_SHIFT_LEFT          0x18
  32#define LCD_SHIFT_RIGHT         0x1c
  33
  34static void lcd_put_byte(u8 *addr, u8 data)
  35{
  36#ifdef CONFIG_XTFPGA_LCD_8BIT_ACCESS
  37        WRITE_ONCE(*addr, data);
  38#else
  39        WRITE_ONCE(*addr, data & 0xf0);
  40        WRITE_ONCE(*addr, (data << 4) & 0xf0);
  41#endif
  42}
  43
  44static int __init lcd_init(void)
  45{
  46        WRITE_ONCE(*LCD_INSTR_ADDR, LCD_DISPLAY_MODE8BIT);
  47        mdelay(5);
  48        WRITE_ONCE(*LCD_INSTR_ADDR, LCD_DISPLAY_MODE8BIT);
  49        udelay(200);
  50        WRITE_ONCE(*LCD_INSTR_ADDR, LCD_DISPLAY_MODE8BIT);
  51        udelay(50);
  52#ifndef CONFIG_XTFPGA_LCD_8BIT_ACCESS
  53        WRITE_ONCE(*LCD_INSTR_ADDR, LCD_DISPLAY_MODE4BIT);
  54        udelay(50);
  55        lcd_put_byte(LCD_INSTR_ADDR, LCD_DISPLAY_MODE4BIT);
  56        udelay(50);
  57#endif
  58        lcd_put_byte(LCD_INSTR_ADDR, LCD_DISPLAY_ON);
  59        udelay(50);
  60        lcd_put_byte(LCD_INSTR_ADDR, LCD_CLEAR);
  61        mdelay(10);
  62        lcd_disp_at_pos("XTENSA LINUX", 0);
  63        return 0;
  64}
  65
  66void lcd_disp_at_pos(char *str, unsigned char pos)
  67{
  68        lcd_put_byte(LCD_INSTR_ADDR, LCD_DISPLAY_POS | pos);
  69        udelay(100);
  70        while (*str != 0) {
  71                lcd_put_byte(LCD_DATA_ADDR, *str);
  72                udelay(200);
  73                str++;
  74        }
  75}
  76
  77void lcd_shiftleft(void)
  78{
  79        lcd_put_byte(LCD_INSTR_ADDR, LCD_SHIFT_LEFT);
  80        udelay(50);
  81}
  82
  83void lcd_shiftright(void)
  84{
  85        lcd_put_byte(LCD_INSTR_ADDR, LCD_SHIFT_RIGHT);
  86        udelay(50);
  87}
  88
  89arch_initcall(lcd_init);
  90