root/arch/mips/lasat/picvue.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pvc_reg_write
  2. pvc_reg_read
  3. pvc_write_byte
  4. pvc_read_byte
  5. pvc_read_data
  6. pvc_wait
  7. pvc_write
  8. pvc_write_string
  9. pvc_write_string_centered
  10. pvc_dump_string
  11. pvc_program_cg
  12. pvc_funcset
  13. pvc_entrymode
  14. pvc_dispcnt
  15. pvc_move
  16. pvc_clear
  17. pvc_home
  18. pvc_init

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

/* [<][>][^][v][top][bottom][index][help] */