linux/arch/mips/lasat/picvue.c
<<
>>
Prefs
   1/*
   2 * Picvue PVC160206 display driver
   3 *
   4 * Brian Murphy <brian@murphy.dk>
   5 *
   6 */
   7#include <linux/kernel.h>
   8#include <linux/delay.h>
   9#include <asm/bootinfo.h>
  10#include <asm/lasat/lasat.h>
  11#include <linux/module.h>
  12#include <linux/errno.h>
  13#include <linux/string.h>
  14
  15#include "picvue.h"
  16
  17#define PVC_BUSY                0x80
  18#define PVC_NLINES              2
  19#define PVC_DISPMEM             80
  20#define PVC_LINELEN             PVC_DISPMEM / PVC_NLINES
  21
  22struct pvc_defs *picvue;
  23
  24static void pvc_reg_write(u32 val)
  25{
  26        *picvue->reg = val;
  27}
  28
  29static u32 pvc_reg_read(void)
  30{
  31        u32 tmp = *picvue->reg;
  32        return tmp;
  33}
  34
  35static void pvc_write_byte(u32 data, u8 byte)
  36{
  37        data |= picvue->e;
  38        pvc_reg_write(data);
  39        data &= ~picvue->data_mask;
  40        data |= byte << picvue->data_shift;
  41        pvc_reg_write(data);
  42        ndelay(220);
  43        pvc_reg_write(data & ~picvue->e);
  44        ndelay(220);
  45}
  46
  47static u8 pvc_read_byte(u32 data)
  48{
  49        u8 byte;
  50
  51        data |= picvue->e;
  52        pvc_reg_write(data);
  53        ndelay(220);
  54        byte = (pvc_reg_read() & picvue->data_mask) >> picvue->data_shift;
  55        data &= ~picvue->e;
  56        pvc_reg_write(data);
  57        ndelay(220);
  58        return byte;
  59}
  60
  61static u8 pvc_read_data(void)
  62{
  63        u32 data = pvc_reg_read();
  64        u8 byte;
  65        data |= picvue->rw;
  66        data &= ~picvue->rs;
  67        pvc_reg_write(data);
  68        ndelay(40);
  69        byte = pvc_read_byte(data);
  70        data |= picvue->rs;
  71        pvc_reg_write(data);
  72        return byte;
  73}
  74
  75#define TIMEOUT 1000
  76static int pvc_wait(void)
  77{
  78        int i = TIMEOUT;
  79        int err = 0;
  80
  81        while ((pvc_read_data() & PVC_BUSY) && i)
  82                i--;
  83        if (i == 0)
  84                err = -ETIME;
  85
  86        return err;
  87}
  88
  89#define MODE_INST 0
  90#define MODE_DATA 1
  91static void pvc_write(u8 byte, int mode)
  92{
  93        u32 data = pvc_reg_read();
  94        data &= ~picvue->rw;
  95        if (mode == MODE_DATA)
  96                data |= picvue->rs;
  97        else
  98                data &= ~picvue->rs;
  99        pvc_reg_write(data);
 100        ndelay(40);
 101        pvc_write_byte(data, byte);
 102        if (mode == MODE_DATA)
 103                data &= ~picvue->rs;
 104        else
 105                data |= picvue->rs;
 106        pvc_reg_write(data);
 107        pvc_wait();
 108}
 109
 110void pvc_write_string(const unsigned char *str, u8 addr, int line)
 111{
 112        int i = 0;
 113
 114        if (line > 0 && (PVC_NLINES > 1))
 115                addr += 0x40 * line;
 116        pvc_write(0x80 | addr, MODE_INST);
 117
 118        while (*str != 0 && i < PVC_LINELEN) {
 119                pvc_write(*str++, MODE_DATA);
 120                i++;
 121        }
 122}
 123
 124void pvc_write_string_centered(const unsigned char *str, int line)
 125{
 126        int len = strlen(str);
 127        u8 addr;
 128
 129        if (len > PVC_VISIBLE_CHARS)
 130                addr = 0;
 131        else
 132                addr = (PVC_VISIBLE_CHARS - strlen(str))/2;
 133
 134        pvc_write_string(str, addr, line);
 135}
 136
 137void pvc_dump_string(const unsigned char *str)
 138{
 139        int len = strlen(str);
 140
 141        pvc_write_string(str, 0, 0);
 142        if (len > PVC_VISIBLE_CHARS)
 143                pvc_write_string(&str[PVC_VISIBLE_CHARS], 0, 1);
 144}
 145
 146#define BM_SIZE                 8
 147#define MAX_PROGRAMMABLE_CHARS  8
 148int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE])
 149{
 150        int i;
 151        int addr;
 152
 153        if (charnum > MAX_PROGRAMMABLE_CHARS)
 154                return -ENOENT;
 155
 156        addr = charnum * 8;
 157        pvc_write(0x40 | addr, MODE_INST);
 158
 159        for (i = 0; i < BM_SIZE; i++)
 160                pvc_write(bitmap[i], MODE_DATA);
 161        return 0;
 162}
 163
 164#define FUNC_SET_CMD    0x20
 165#define  EIGHT_BYTE     (1 << 4)
 166#define  FOUR_BYTE      0
 167#define  TWO_LINES      (1 << 3)
 168#define  ONE_LINE       0
 169#define  LARGE_FONT     (1 << 2)
 170#define  SMALL_FONT     0
 171
 172static void pvc_funcset(u8 cmd)
 173{
 174        pvc_write(FUNC_SET_CMD | (cmd & (EIGHT_BYTE|TWO_LINES|LARGE_FONT)),
 175                  MODE_INST);
 176}
 177
 178#define ENTRYMODE_CMD           0x4
 179#define  AUTO_INC               (1 << 1)
 180#define  AUTO_DEC               0
 181#define  CURSOR_FOLLOWS_DISP    (1 << 0)
 182
 183static void pvc_entrymode(u8 cmd)
 184{
 185        pvc_write(ENTRYMODE_CMD | (cmd & (AUTO_INC|CURSOR_FOLLOWS_DISP)),
 186                  MODE_INST);
 187}
 188
 189#define DISP_CNT_CMD    0x08
 190#define  DISP_OFF       0
 191#define  DISP_ON        (1 << 2)
 192#define  CUR_ON         (1 << 1)
 193#define  CUR_BLINK      (1 << 0)
 194void pvc_dispcnt(u8 cmd)
 195{
 196        pvc_write(DISP_CNT_CMD | (cmd & (DISP_ON|CUR_ON|CUR_BLINK)), MODE_INST);
 197}
 198
 199#define MOVE_CMD        0x10
 200#define  DISPLAY        (1 << 3)
 201#define  CURSOR         0
 202#define  RIGHT          (1 << 2)
 203#define  LEFT           0
 204void pvc_move(u8 cmd)
 205{
 206        pvc_write(MOVE_CMD | (cmd & (DISPLAY|RIGHT)), MODE_INST);
 207}
 208
 209#define CLEAR_CMD       0x1
 210void pvc_clear(void)
 211{
 212        pvc_write(CLEAR_CMD, MODE_INST);
 213}
 214
 215#define HOME_CMD        0x2
 216void pvc_home(void)
 217{
 218        pvc_write(HOME_CMD, MODE_INST);
 219}
 220
 221int pvc_init(void)
 222{
 223        u8 cmd = EIGHT_BYTE;
 224
 225        if (PVC_NLINES == 2)
 226                cmd |= (SMALL_FONT|TWO_LINES);
 227        else
 228                cmd |= (LARGE_FONT|ONE_LINE);
 229        pvc_funcset(cmd);
 230        pvc_dispcnt(DISP_ON);
 231        pvc_entrymode(AUTO_INC);
 232
 233        pvc_clear();
 234        pvc_write_string_centered("Display", 0);
 235        pvc_write_string_centered("Initialized", 1);
 236
 237        return 0;
 238}
 239
 240module_init(pvc_init);
 241MODULE_LICENSE("GPL");
 242