MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / drivers / char / lcm1.c
blob4845bffa5b9825fe4ee66f4965d61d323e0c2344
1 /*
2 * Copyright (C) MOXA Inc. All rights reserved.
4 * This software is distributed under the terms of the
5 * MOXA License. See the file COPYING-MOXA for details.
7 * This is Moxa CPU for IVTC ODM LCM moudle WG240128B device driver.
8 * It is from misc interface. So the device node major number is 10.
9 * The device node minor number is following:
10 * lcm : 102
12 * There devices are mapping system memory is following:
13 * lcm : 0x04000000 read only, data -> LCM & control signal
14 * : 0x04002000 write only, LCM -> data & control signal
16 * History:
17 * Date Aurhor Comment
18 * 12-05-2005 Victor Yu. Create it.
19 * 01-19-2005 Jimmy Chen. Fix to work.
20 * 09-03-2008 Victor Yu. Modify to support IVTC write byte feature.
22 * There devices are mapping system memory is following:
23 * lcm : 0x84004000 read only, data -> LCM & control signal
24 * : 0x84000000 write only, LCM -> data & control signal
27 #include <linux/config.h>
28 #include <asm/arch/moxa.h>
29 #include <linux/module.h>
30 #include <linux/kernel.h>
31 #include <linux/types.h>
32 #include <linux/miscdevice.h>
33 #include <linux/fcntl.h>
34 #include <linux/init.h>
35 #include <linux/poll.h>
36 #include <linux/proc_fs.h>
37 #include <linux/spinlock.h>
38 #include <linux/delay.h>
39 #include <linux/rtc.h>
40 #include <linux/timer.h>
41 #include <linux/ioport.h>
43 #include <asm/io.h>
44 #include <asm/uaccess.h>
45 #include <asm/system.h>
46 #include "moxalcm.h"
48 #define LCM_WRITE_ADDR 0x84000000
49 #define LCM_READ_ADDR 0x84004000
51 #define MOXA_LCM_MINOR 102
53 static spinlock_t lcm_lock= SPIN_LOCK_UNLOCKED;
56 // LCM file operation function call
58 static unsigned char fnt8x8[]={
59 0x70,0x88,0x98,0xA8,0xC8,0x88,0x70,0x00,0x20,0x60,0x20,0x20,0x20,0x20,0xF8,0x00,
60 0x70,0x88,0x08,0x10,0x20,0x48,0xF8,0x00,0x70,0x88,0x08,0x70,0x08,0x88,0x70,0x00,
61 0x10,0x30,0x50,0x90,0xF8,0x10,0x38,0x00,0xF8,0x80,0xF0,0x08,0x08,0x88,0x70,0x00,
62 0x30,0x48,0x80,0xF0,0x88,0x88,0x70,0x00,0xF8,0x88,0x10,0x20,0x20,0x20,0x20,0x00,
63 0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00,0x70,0x88,0x88,0x78,0x08,0x88,0x70,0x00,
64 0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,0xF0,0x48,0x48,0x70,0x48,0x48,0xF0,0x00,
65 0x30,0x48,0x80,0x80,0x80,0x48,0x30,0x00,0xE0,0x90,0x88,0x88,0x88,0x90,0xE0,0x00,
66 0xF8,0x48,0x40,0x70,0x40,0x48,0xF8,0x00,0xF8,0x48,0x40,0x70,0x40,0x40,0xE0,0x00,
67 0x80,0xE0,0xF8,0xFE,0xF8,0xE0,0x80,0x00,0x02,0x0E,0x3E,0xFE,0x3E,0x0E,0x02,0x00,
68 0x18,0x3C,0x7E,0x18,0x18,0x7E,0x3C,0x18,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x00,
69 0x7F,0xDB,0xDB,0x7B,0x1B,0x1B,0x1B,0x00,0x3E,0x63,0x38,0x6C,0x6C,0x38,0xCC,0x78,
70 0x00,0x00,0x00,0x00,0x7E,0x7E,0x7E,0x00,0x18,0x3C,0x7E,0x18,0x7E,0x3C,0x18,0xFF,
71 0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,
72 0x00,0x18,0x0C,0xFE,0x0C,0x18,0x00,0x00,0x00,0x30,0x60,0xFE,0x60,0x30,0x00,0x00,
73 0x00,0x00,0xC0,0xC0,0xC0,0xFE,0x00,0x00,0x00,0x24,0x66,0xFF,0x66,0x24,0x00,0x00,
74 0x00,0x18,0x3C,0x7E,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0x7E,0x3C,0x18,0x00,0x00,
75 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x00,0x10,0x00,
76 0x44,0x44,0x44,0x00,0x00,0x00,0x00,0x00,0x44,0x44,0xFE,0x44,0xFE,0x44,0x44,0x00,
77 0x20,0x70,0x80,0x70,0x08,0xF0,0x20,0x00,0xC2,0xC4,0x08,0x10,0x20,0x46,0x86,0x00,
78 0x70,0x88,0x50,0x74,0x88,0x84,0x7A,0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,
79 0x08,0x10,0x20,0x20,0x20,0x10,0x08,0x00,0x20,0x10,0x08,0x08,0x08,0x10,0x20,0x00,
80 0x00,0x42,0x24,0xFF,0x24,0x42,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,
81 0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x20,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,
82 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x00,
83 0x7C,0x86,0x8A,0x92,0xA2,0xC2,0x7C,0x00,0x20,0x60,0x20,0x20,0x20,0x20,0xF8,0x00,
84 0x78,0x84,0x04,0x18,0x60,0x80,0xFC,0x00,0x78,0x84,0x04,0x18,0x04,0x84,0x78,0x00,
85 0x1C,0x24,0x44,0x84,0xFE,0x04,0x0E,0x00,0xFC,0x80,0xF8,0x04,0x04,0x84,0x78,0x00,
86 0x30,0x40,0x80,0xF8,0x84,0x84,0x78,0x00,0xFC,0x84,0x04,0x08,0x10,0x10,0x10,0x00,
87 0x78,0x84,0x84,0x78,0x84,0x84,0x78,0x00,0x78,0x84,0x84,0x7C,0x04,0x08,0x70,0x00,
88 0x00,0x20,0x20,0x00,0x00,0x20,0x20,0x00,0x00,0x20,0x20,0x00,0x00,0x20,0x20,0x40,
89 0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x00,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,
90 0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x00,0x78,0x84,0x04,0x08,0x10,0x00,0x10,0x00,
91 0x7C,0x82,0x82,0x82,0x9C,0x80,0x78,0x00,0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00,
92 0xF8,0x44,0x44,0x78,0x44,0x44,0xF8,0x00,0x38,0x44,0x80,0x80,0x80,0x44,0x38,0x00,
93 0xF8,0x44,0x42,0x42,0x42,0x44,0xF8,0x00,0xFE,0x80,0x80,0xF0,0x80,0x80,0xFE,0x00,
94 0xFE,0x80,0x80,0xF0,0x80,0x80,0x80,0x00,0x3C,0x42,0x80,0x80,0x86,0x42,0x3C,0x00,
95 0x84,0x84,0x84,0xFC,0x84,0x84,0x84,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,
96 0x0E,0x04,0x04,0x04,0x84,0x84,0x78,0x00,0x42,0x42,0x44,0x78,0x44,0x42,0x42,0x00,
97 0x40,0x40,0x40,0x40,0x40,0x40,0x7E,0x00,0x82,0xC6,0xAA,0x92,0x82,0x82,0x82,0x00,
98 0x82,0xC2,0xA2,0x92,0x8A,0x86,0x82,0x00,0x38,0x44,0x82,0x82,0x82,0x44,0x38,0x00,
99 0x7C,0x42,0x42,0x7C,0x40,0x40,0x40,0x00,0x78,0x84,0x84,0x84,0x84,0x78,0x0C,0x00,
100 0xF8,0x84,0x84,0xF8,0x88,0x84,0x84,0x00,0x78,0x84,0x80,0x78,0x04,0x84,0x78,0x00,
101 0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x84,0x84,0x84,0x84,0x84,0x84,0x78,0x00,
102 0x84,0x84,0x84,0x84,0x84,0x48,0x30,0x00,0x82,0x82,0x82,0x92,0xAA,0xC6,0x82,0x00,
103 0x82,0x44,0x28,0x10,0x28,0x44,0x82,0x00,0x88,0x88,0x88,0x70,0x20,0x20,0x20,0x00,
104 0xFE,0x04,0x08,0x10,0x20,0x40,0xFE,0x00,0x78,0x40,0x40,0x40,0x40,0x40,0x78,0x00,
105 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x78,0x00,
106 0x10,0x28,0x44,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
107 0x10,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x04,0x7C,0x84,0x76,0x00,
108 0x40,0x40,0x40,0x7C,0x42,0x42,0x7C,0x00,0x00,0x00,0x78,0x84,0x80,0x84,0x78,0x00,
109 0x04,0x04,0x04,0x7C,0x84,0x84,0x78,0x00,0x00,0x00,0x78,0x84,0xF8,0x80,0x78,0x00,
110 0x38,0x44,0x40,0xF0,0x40,0x40,0x40,0x00,0x00,0x00,0x78,0x84,0x84,0x7C,0x04,0xF8,
111 0x40,0x40,0x40,0x7C,0x42,0x42,0x42,0x00,0x10,0x00,0x10,0x10,0x10,0x10,0x10,0x00,
112 0x04,0x00,0x04,0x04,0x04,0x84,0x84,0x78,0x80,0x80,0x84,0x88,0xF0,0x88,0x84,0x00,
113 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x44,0xAA,0x92,0x82,0x82,0x00,
114 0x00,0x00,0xF8,0x84,0x84,0x84,0x84,0x00,0x00,0x00,0x78,0x84,0x84,0x84,0x78,0x00,
115 0x00,0x00,0xF8,0x84,0x84,0xF8,0x80,0x80,0x00,0x00,0x7C,0x84,0x84,0x7C,0x04,0x04,
116 0x00,0x00,0xB8,0xC4,0x80,0x80,0x80,0x00,0x00,0x00,0x7C,0x80,0x78,0x04,0xF8,0x00,
117 0x10,0x10,0x38,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x84,0x84,0x84,0x84,0x78,0x00,
118 0x00,0x00,0x84,0x84,0x84,0x48,0x30,0x00,0x00,0x00,0x82,0x82,0x92,0xAA,0x44,0x00,
119 0x00,0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00,0x00,0x84,0x84,0x84,0x7C,0x04,0xF8,
120 0x00,0x00,0xFC,0x08,0x10,0x20,0xFC,0x00,0x0C,0x10,0x10,0x60,0x10,0x10,0x0C,0x00,
121 0x10,0x10,0x10,0x00,0x10,0x10,0x10,0x00,0xC0,0x20,0x20,0x18,0x20,0x20,0xC0,0x00,
122 0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x28,0x44,0x82,0x82,0xFE,0x00,
123 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
124 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
125 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
126 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
127 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
128 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
129 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
130 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
131 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
132 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
133 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
134 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
135 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
136 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
137 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
138 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
139 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
140 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
141 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
142 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
143 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
144 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
145 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
146 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
147 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
148 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
149 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
150 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
151 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
152 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
153 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
154 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
155 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
156 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
157 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
158 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
159 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
160 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
161 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
162 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
163 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
164 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
165 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
166 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
167 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
168 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
169 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
170 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
171 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
172 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
173 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
174 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
175 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
176 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
177 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
178 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
179 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
180 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
181 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
182 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
183 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
184 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
185 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
186 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
188 static int lcmx, lcmy; // dots position
190 // following on LCM command
191 #define LCM_CMD_SET_CUR_POINT 0x21 // set cursor pointer
192 #define LCM_CMD_SET_OFF_REG 0x22 // set offset register
193 #define LCM_CMD_SET_ADDR_POINT 0x24 // set address pointer
194 #define LCM_CMD_SET_T_H_ADDR 0x40 // set text home address
195 #define LCM_CMD_SET_T_AREA 0x41 // set text area
196 #define LCM_CMD_SET_G_H_ADDR 0x42 // set graphic home address
197 #define LCM_CMD_SET_G_AREA 0x43 // set graphic area
198 #define LCM_CMD_OR_MODE 0x80 // OR mode
199 #define LCM_CMD_EXOR_MODE 0x81 // EXOR mode
200 #define LCM_CMD_AND_MODE 0x83 // AND mode
201 #define LCM_CMD_T_ATTR 0x84 // text attribute mode
202 #define LCM_CMD_INT_CG_ROM 0x85 // internal CG ROM mode
203 #define LCM_CMD_EXT_CG_RAM 0x88 // external CG RAM mode
204 #define LCM_CMD_DISPLAY_OFF 0x90 // display off
205 #define LCM_CMD_CO_BF 0x92 // cursor on, blink off
206 #define LCM_CMD_CO_BO 0x93 // cursor on, blink on
207 #define LCM_CMD_TO_GF 0x94 // text on, graphic off
208 #define LCM_CMD_TF_GO 0x98 // text off, graphic on
209 #define LCM_CMD_TO_GO 0x9c // text on, graphic on
210 #define LCM_CMD_CUR_1 0xa0 // 1-line cursor
211 #define LCM_CMD_CUR_2 0xa1 // 2-line cursor
212 #define LCM_CMD_CUR_3 0xa2 // 3-line cursor
213 #define LCM_CMD_CUR_4 0xa3 // 4-line cursor
214 #define LCM_CMD_CUR_5 0xa4 // 5-line cursor
215 #define LCM_CMD_CUR_6 0xa5 // 6-line cursor
216 #define LCM_CMD_CUR_7 0xa6 // 7-line cursor
217 #define LCM_CMD_CUR_8 0xa7 // 8-line cursor
218 #define LCM_CMD_DATA_AW 0xb0 // set data auto write
219 #define LCM_CMD_DATA_AR 0xb1 // set data auto read
220 #define LCM_CMD_AUTO_RESET 0xb2 // auto reset
221 #define LCM_CMD_DW_INC 0xc0 // data write and increment ADP
222 #define LCM_CMD_DR_INC 0xc1 // data read and increment ADP
223 #define LCM_CMD_DW_DEC 0xc2 // data write and decrement ADP
224 #define LCM_CMD_DR_DEC 0xc3 // data read and decrement ADP
225 #define LCM_CMD_DW_NON 0xc4 // data write and nonvariable ADP
226 #define LCM_CMD_DR_NON 0xc5 // data read and nonvariable ADP
227 #define LCM_CMD_SCR_PEEk 0xe0 // screen peek
228 #define LCM_CMD_SCR_COPY 0xe8 // screen copy
229 #define LCM_CMD_BIT_RESET 0xf0 // bit reset
230 #define LCM_CMD_BIT_SET 0xf9 // bit set
231 #define LCM_CMD_BIT_0 0xf8 // bit 0
232 #define LCM_CMD_BIT_1 0xf9 // bit 1
233 #define LCM_CMD_BIT_2 0xfa // bit 2
234 #define LCM_CMD_BIT_3 0xfb // bit 3
235 #define LCM_CMD_BIT_4 0xfc // bit 4
236 #define LCM_CMD_BIT_5 0xfd // bit 5
237 #define LCM_CMD_BIT_6 0xfe // bit 6
238 #define LCM_CMD_BIT_7 0xff // bit 7
240 // following status
241 #define LCM_CMD_EXEC_CAP (1<<0) // check command execution cap.
242 #define LCM_DATA_RW_CAP (1<<1) // check data read/write cap.
243 #define LCM_AUTO_RD_CAP (1<<2) // check auto mode data read cap.
244 #define LCM_AUTO_WD_CAP (1<<3) // check auto mode data write cap.
245 #define LCM_CTRL_OP_CAP (1<<5) // check controller operation cap.
246 #define LCM_ERR_FLAG (1<<6) // error flag
247 #define LCM_BLINK_CON (1<<7) // check the blink condition
249 // following LCM control for CPU
250 #define CD_0 0
251 #define CD_1 (1<<8) // when write
252 #define CE_1 (1<<10)
253 #define CE_0 0
254 #define RD_1 (1<<9) // data write
255 #define RD_0 0
256 #define WR_1 (1<<12) // data read
257 #define WR_0 0
258 #define LCM_STATUS_READ (1<<8) // when read
259 #define LCM_READ_ENABLE (1<<14)
260 #define LCM_WRITE_ENABLE 0
261 #define LCM_DATA_MASK 0xff
263 //DATA AUTO READ/WRITE
264 #define LCM_DATA_ATOW 0xB0 //Set Data Auto Write
265 #define LCM_DATA_ATOR 0xB1 //Set Data Auto Read
266 #define LCM_AUTO_RESET 0xB2 //Auto Reset
268 #define LCM_MAX_X_DOTS 240
269 #define LCM_MAX_Y_DOTS 128
270 #define LCM_HALF_X_DOTS (LCM_MAX_X_DOTS/2)
271 #define LCM_X_DOTS 8
272 #define LCM_Y_DOTS 8
273 #define LCM_MAX_X (LCM_MAX_X_DOTS/LCM_X_DOTS)
274 #define LCM_MAX_Y (LCM_MAX_Y_DOTS/LCM_Y_DOTS)
275 #define LCM_ADDRESS_X_Y(x,y) ((y)*LCM_MAX_X + x)
277 static unsigned char lcm_pix_buffer[LCM_MAX_X_DOTS][LCM_MAX_Y_DOTS];
278 static int lcm_auto_scroll_flag=1;
279 static int lcm_reverse_flag=0;
280 typedef struct lcm_xy {
281 int x; // 0 - 15
282 int y; // 0 - 7
283 } lcm_xy_t;
285 #define LCM_NOT_LOCK_INT
286 static inline int LCM_check_status(u16 check_status)
288 #define LCM_RETRY_COUNT 10
289 int i, ret = 0;
290 u16 status ;
292 for ( i=0; i<LCM_RETRY_COUNT; i++ ) {
293 outw(CD_0|CE_0|RD_1|WR_1|LCM_READ_ENABLE,LCM_WRITE_ADDR) ;
294 outw(CD_1|CE_0|RD_0|WR_1|LCM_READ_ENABLE, LCM_WRITE_ADDR);
295 udelay(1) ;
296 status = inw(LCM_READ_ADDR) ;
297 if ( status & check_status ) {
298 ret = 1;
299 break;
302 /* back to initial */
303 outw(CD_0|CE_1|RD_1|WR_1|LCM_READ_ENABLE,LCM_WRITE_ADDR) ;
304 return ret;
307 static inline void LCM_write_cmd(u16 cmd)
309 outw(CD_0|CE_1|RD_1|WR_1|LCM_READ_ENABLE,LCM_WRITE_ADDR) ;
310 udelay(1) ;
311 outw(CD_1|CE_1|RD_1|WR_1|LCM_WRITE_ENABLE,LCM_WRITE_ADDR) ;
312 udelay(1) ;
313 outw(CD_1|CE_0|RD_1|WR_0|LCM_WRITE_ENABLE,LCM_WRITE_ADDR) ;
314 udelay(1) ;
315 outw(CD_1|CE_0|RD_1|WR_0|LCM_WRITE_ENABLE|cmd,LCM_WRITE_ADDR) ;
316 udelay(1) ;
317 outw(CD_1|CE_0|RD_1|WR_1|LCM_WRITE_ENABLE|cmd,LCM_WRITE_ADDR) ;
318 udelay(1) ;
319 /*back to initial*/
320 outw(CD_0|CE_1|RD_1|WR_1|LCM_READ_ENABLE|cmd,LCM_WRITE_ADDR) ;
323 static inline void LCM_write_data(u16 data)
325 outw(CD_1|CE_1|RD_1|WR_1|LCM_READ_ENABLE,LCM_WRITE_ADDR) ;
326 udelay(1) ;
327 outw(CD_0|CE_1|RD_1|WR_1|LCM_WRITE_ENABLE,LCM_WRITE_ADDR) ;
328 udelay(1) ;
329 outw(CD_0|CE_0|RD_1|WR_0|LCM_WRITE_ENABLE,LCM_WRITE_ADDR) ;
330 udelay(1) ;
331 outw(CD_0|CE_0|RD_1|WR_0|LCM_WRITE_ENABLE|data,LCM_WRITE_ADDR) ;
332 udelay(1) ;
333 outw(CD_0|CE_0|RD_1|WR_1|LCM_WRITE_ENABLE|data,LCM_WRITE_ADDR) ;
334 udelay(1) ;
335 /*back to initial*/
336 outw(CD_1|CE_1|RD_1|WR_1|LCM_READ_ENABLE|data,LCM_WRITE_ADDR) ;
339 static void LCM_no_argument_cmd(u16 cmd)
341 spin_lock(&lcm_lock);
342 if ( LCM_check_status(LCM_CMD_EXEC_CAP) )
343 LCM_write_cmd(cmd);
344 spin_unlock(&lcm_lock);
347 static void LCM_one_argument_cmd(u16 cmd, u16 data)
349 spin_lock(&lcm_lock);
350 if ( !LCM_check_status(LCM_CMD_EXEC_CAP) )
351 goto one_cmd_end;
352 LCM_write_data(data);
353 if ( !LCM_check_status(LCM_CMD_EXEC_CAP) )
354 goto one_cmd_end;
355 LCM_write_cmd(cmd);
356 one_cmd_end:
357 spin_unlock(&lcm_lock);
360 static void LCM_two_arguments_cmd(u16 cmd, u16 data1, u16 data2)
362 spin_lock(&lcm_lock);
363 if ( !LCM_check_status(LCM_CMD_EXEC_CAP) )
364 goto two_cmd_end;
365 LCM_write_data(data1);
366 if ( !LCM_check_status(LCM_CMD_EXEC_CAP) )
367 goto two_cmd_end;
368 LCM_write_data(data2);
369 if ( !LCM_check_status(LCM_CMD_EXEC_CAP) )
370 goto two_cmd_end;
371 LCM_write_cmd(cmd);
372 two_cmd_end:
373 spin_unlock(&lcm_lock);
376 static void lcm_up_one_line(void)
378 int x, y, index, i, addr;
380 // first up one line for lcm buffer
381 spin_lock(&lcm_lock);
382 for ( y=1; y<LCM_MAX_Y; y++ ) {
383 for ( x=0; x<LCM_MAX_X; x++ ) {
384 memcpy(&lcm_pix_buffer[y-1][x*LCM_X_DOTS], &lcm_pix_buffer[y][x*LCM_X_DOTS], LCM_X_DOTS);
387 for ( x=0; x<LCM_MAX_X; x++ ) {
388 memset(&lcm_pix_buffer[LCM_MAX_Y-1][x*LCM_X_DOTS], 0, LCM_X_DOTS);
390 spin_unlock(&lcm_lock);
392 // second redisplay up one line on LCM
393 LCM_no_argument_cmd(LCM_CMD_DISPLAY_OFF);
394 for ( y=0; y<LCM_MAX_Y; y++ ) {
395 for ( x=0; x<LCM_MAX_X; x++ ) {
396 addr = LCM_ADDRESS_X_Y(x, y);
397 LCM_two_arguments_cmd(LCM_CMD_SET_ADDR_POINT, addr&0xff, (addr>>8)&0xff);
398 index = x * LCM_X_DOTS;
399 for ( i=0; i<LCM_X_DOTS; i++, index++ ) {
400 LCM_one_argument_cmd(LCM_CMD_DW_INC, (u16)lcm_pix_buffer[y][index]);
404 LCM_no_argument_cmd(LCM_CMD_TF_GO);
405 spin_lock(&lcm_lock);
406 lcmx = 0;
407 lcmy = LCM_MAX_Y - 1;
408 spin_unlock(&lcm_lock);
411 static void LCM_printf_char(unsigned char ch)
413 int index, i ;
414 u16 addr;
416 if ( ch == '\n' ) {
417 spin_lock(&lcm_lock);
418 for ( i=(lcmx/LCM_X_DOTS); i<LCM_MAX_X; i++ ) {
419 if ( lcm_reverse_flag )
420 memset(&lcm_pix_buffer[lcmy][i*LCM_X_DOTS], 1, LCM_X_DOTS);
421 else
422 memset(&lcm_pix_buffer[lcmy][i*LCM_X_DOTS], 0, LCM_X_DOTS);
424 lcmx = 0;
425 lcmy++;
426 if ( lcmy >= LCM_MAX_Y ) {
427 if ( lcm_auto_scroll_flag ) {
428 lcmy = LCM_MAX_Y - 1;
429 spin_unlock(&lcm_lock);
430 lcm_up_one_line();
431 return;
432 } else {
433 lcmy = 0;
436 spin_unlock(&lcm_lock);
437 return;
439 addr = ((lcmy*8)*0x1e) + (lcmx/LCM_X_DOTS) ;
440 //addr = LCM_ADDRESS_X_Y(lcmx, lcmy);
441 LCM_two_arguments_cmd(LCM_CMD_SET_ADDR_POINT,(u16)addr&0xFF,(u16)(addr>>8));
443 index = ch * LCM_X_DOTS;
444 for ( i=0; i<LCM_Y_DOTS; i++, index++, lcmx++ ) {
445 spin_lock(&lcm_lock);
446 if ( lcm_reverse_flag )
447 lcm_pix_buffer[lcmy][lcmx] = ~fnt8x8[index];
448 else
449 lcm_pix_buffer[lcmy][lcmx] = fnt8x8[index];
450 spin_unlock(&lcm_lock);
451 //LCM_one_argument_cmd(LCM_CMD_DW_INC, (u16)fnt8x8[index]);
453 LCM_two_arguments_cmd(LCM_CMD_SET_ADDR_POINT,\
454 (u16)(addr+(0x1e*i))&0xFF,(u16)(addr+(0x1e*i))>>8) ;
455 LCM_one_argument_cmd(LCM_CMD_DW_INC,(u16)fnt8x8[index]);
457 spin_lock(&lcm_lock);
458 if ( lcmx >= LCM_MAX_X_DOTS ) {
459 lcmx = 0;
460 lcmy++;
461 if ( lcmy >= LCM_MAX_Y ) {
462 if ( lcm_auto_scroll_flag ) {
463 lcmy = LCM_MAX_Y - 1;
464 spin_unlock(&lcm_lock);
465 lcm_up_one_line();
466 return;
467 } else {
468 lcmy = 0;
472 spin_unlock(&lcm_lock);
475 static void LCM_clear_line(void)
477 int x, index, i, addr;
479 for ( x=0; x<LCM_MAX_X; x++ ) {
480 spin_lock(&lcm_lock);
481 if ( lcm_reverse_flag )
482 memset(&lcm_pix_buffer[lcmy][x*LCM_X_DOTS], 1, LCM_X_DOTS);
483 else
484 memset(&lcm_pix_buffer[lcmy][x*LCM_X_DOTS], 0, LCM_X_DOTS);
485 spin_unlock(&lcm_lock);
486 addr = LCM_ADDRESS_X_Y(x, lcmy);
487 LCM_two_arguments_cmd(LCM_CMD_SET_ADDR_POINT, addr&0xff, (addr>>8)&0xff);
488 index = x * LCM_X_DOTS;
489 for ( i=0; i<LCM_X_DOTS; i++, index++ ) {
490 LCM_one_argument_cmd(LCM_CMD_DW_INC, (u16)lcm_pix_buffer[lcmy][index]);
493 spin_lock(&lcm_lock);
494 lcmx = 0;
495 spin_unlock(&lcm_lock);
497 static void LCM_clear(void)
499 int i , x , y ;
500 i = x = y = 0 ;
501 LCM_two_arguments_cmd(LCM_CMD_SET_ADDR_POINT,0,0) ;
502 //LCM_no_argument_cmd(LCM_DATA_ATOW) ;
503 for(;i<(LCM_MAX_X*LCM_MAX_Y_DOTS);i++)
504 LCM_one_argument_cmd(LCM_CMD_DW_INC,0x00);
505 //LCM_no_argument_cmd(LCM_AUTO_RESET) ;
507 memset(&lcm_pix_buffer,0,(LCM_MAX_X_DOTS*LCM_MAX_Y_DOTS)) ;
508 lcmx = lcmy = 0 ;
511 #if 0 // mask by Victor Yu. 09-03-2008, not used
512 static void LCM_write_string(u16 column,char *string,int size)
514 LCM_two_arguments_cmd(LCM_CMD_SET_ADDR_POINT,column&0xFF,column>>8) ;
515 //LCM_no_argument_cmd(LCM_DATA_ATOW) ;
516 while(size--)
517 LCM_one_argument_cmd(LCM_CMD_DW_INC,(*string++)-' ');
518 //LCM_no_argument_cmd(LCM_AUTO_RESET) ;
520 static void LCM_write_graph(u16 column,u16 data)
522 LCM_two_arguments_cmd(LCM_CMD_SET_ADDR_POINT,column&0xFF,column>>8) ;
523 //LCM_no_argument_cmd(LCM_DATA_ATOW) ;
524 LCM_one_argument_cmd(LCM_CMD_DW_INC,data);
525 //LCM_no_argument_cmd(LCM_AUTO_RESET) ;
527 #endif
529 #define T_AREA_SIZE 0x1e
530 #define G_AREA_SIZE 0x1e
531 #define TEST_STRING0 "Hello world !! Phone: 02-89191"
532 #define TEST_STRING1 "230 # 235"
535 * I don't know why cannot malloc memory from kernel.
536 * 03-10-2004 Victor Yu.
538 #define USE_WRITE_BUFFER
539 static ssize_t lcm_write(struct file * filp, const char * buf, size_t count, loff_t *ppos)
541 #ifdef USE_WRITE_BUFFER
542 char write_buffer[LCM_MAX_X * LCM_MAX_Y];
543 #else
544 char *ptr;
545 #endif
546 int i;
548 if ( count == 0 )
549 return 0;
550 #ifdef USE_WRITE_BUFFER
551 if ( count > (LCM_MAX_X * LCM_MAX_Y) )
552 count = LCM_MAX_X * LCM_MAX_Y;
553 if ( copy_from_user(write_buffer, buf, count) ) {
554 return -EFAULT;
556 for ( i=0; i<count; i++ )
557 LCM_printf_char(write_buffer[i]);
558 #else
559 ptr = kmalloc(count, GFP_KERNEL);
560 if ( ptr == NULL )
561 return -ENOMEM;
562 if ( copy_from_user(ptr, buf, count) ) {
563 kfree(ptr);
564 return -EFAULT;
566 for ( i=0; i<count; i++ )
567 LCM_printf_char(*ptr++);
568 kfree(ptr);
569 #endif
570 return count;
573 static int lcm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
575 lcm_xy_t pos;
576 static unsigned char user_data;
578 switch ( cmd ) {
579 case IOCTL_LCM_PIX_ON :
580 case IOCTL_LCM_PIX_OFF :
582 unsigned char v, mask;
583 u16 addr;
585 if ( copy_from_user(&pos, (void *)arg, sizeof(pos)) )
586 return -EFAULT;
587 if ( pos.x < 0 || pos.x >= LCM_MAX_X_DOTS || pos.y < 0 || pos.y >= LCM_MAX_Y_DOTS )
588 return -EINVAL;
589 spin_lock(&lcm_lock);
590 v = lcm_pix_buffer[pos.y][pos.x/LCM_X_DOTS];
591 mask = 0x80 >> (pos.x % 8);
592 if ( cmd == IOCTL_LCM_PIX_ON )
593 v |= mask;
594 else
595 v &= ~mask;
596 lcm_pix_buffer[pos.y][pos.x/LCM_X_DOTS] = v;
597 spin_unlock(&lcm_lock);
598 addr = ((pos.y)*0x1e) + (pos.x/LCM_X_DOTS) ;
599 LCM_two_arguments_cmd(LCM_CMD_SET_ADDR_POINT,(u16)(addr&0xFF),(u16)(addr>>8));
600 LCM_one_argument_cmd(LCM_CMD_DW_INC,(u16)v);
601 break;
603 case IOCTL_LCM_GOTO_XY :
604 if ( copy_from_user(&pos, (void *)arg, sizeof(pos)) )
605 return -EFAULT;
606 if ( pos.x < 0 || pos.x >= LCM_MAX_X || pos.y < 0 || pos.y >= LCM_MAX_Y )
607 return -EINVAL;
608 spin_lock(&lcm_lock);
609 lcmx = pos.x * LCM_X_DOTS;
610 lcmy = pos.y;
611 spin_unlock(&lcm_lock);
612 break;
613 case IOCTL_LCM_CLS :
614 LCM_clear();
615 break;
616 case IOCTL_LCM_CLEAN_LINE :
617 LCM_clear_line();
618 break;
619 case IOCTL_LCM_GET_XY :
620 spin_lock(&lcm_lock);
621 pos.x = lcmx / LCM_X_DOTS;
622 pos.y = lcmy;
623 spin_unlock(&lcm_lock);
624 if ( copy_to_user((void *)arg, &pos,sizeof(pos)) )
625 return -EFAULT;
626 break;
627 case IOCTL_LCM_BACK_LIGHT_ON :
628 case IOCTL_LCM_BACK_LIGHT_OFF :
629 break;
630 case IOCTL_LCM_AUTO_SCROLL_ON :
631 spin_lock(&lcm_lock);
632 lcm_auto_scroll_flag = 1;
633 spin_unlock(&lcm_lock);
634 break;
635 case IOCTL_LCM_AUTO_SCROLL_OFF :
636 spin_lock(&lcm_lock);
637 lcm_auto_scroll_flag = 0;
638 spin_unlock(&lcm_lock);
639 break;
640 case IOCTL_LCM_REVERSE_ON :
641 spin_lock(&lcm_lock);
642 lcm_reverse_flag = 1;
643 spin_unlock(&lcm_lock);
644 break;
645 case IOCTL_LCM_REVERSE_OFF :
646 spin_lock(&lcm_lock);
647 lcm_reverse_flag = 0;
648 spin_unlock(&lcm_lock);
649 break;
650 case IOCTL_LCM_SAVE_BYTE :
651 if ( copy_from_user(&user_data, (void *)arg, sizeof(user_data)) )
652 return -EFAULT;
653 break;
654 case IOCTL_LCM_WRITE_BYTE :
656 u16 addr;
658 if ( copy_from_user(&pos, (void *)arg, sizeof(pos)) )
659 return -EFAULT;
660 if ( pos.x < 0 || pos.x >= LCM_MAX_X_DOTS || pos.y < 0 || pos.y >= LCM_MAX_Y_DOTS )
661 return -EINVAL;
662 spin_lock(&lcm_lock);
663 lcm_pix_buffer[pos.y][pos.x/LCM_X_DOTS] = user_data;
664 spin_unlock(&lcm_lock);
665 addr = ((pos.y)*0x1e) + (pos.x/LCM_X_DOTS) ;
666 LCM_two_arguments_cmd(LCM_CMD_SET_ADDR_POINT,(u16)(addr&0xFF),(u16)(addr>>8));
667 LCM_one_argument_cmd(LCM_CMD_DW_INC,(u16)user_data);
668 break;
670 case IOCTL_LCM_DISPLAY_OFF :
671 LCM_no_argument_cmd(LCM_CMD_DISPLAY_OFF);
672 break;
673 case IOCTL_LCM_DISPLAY_ON :
674 LCM_no_argument_cmd(LCM_CMD_TF_GO);
675 break;
676 default:
677 return -EINVAL;
680 return 0;
683 static int lcm_open(struct inode *inode, struct file *file)
685 if ( MINOR(inode->i_rdev) == MOXA_LCM_MINOR )
686 return 0;
687 return -ENODEV;
690 static int lcm_release(struct inode *inode, struct file *file)
692 return 0;
695 static struct file_operations lcm_fops = {
696 owner:THIS_MODULE,
697 llseek:NULL,
698 write:lcm_write,
699 ioctl:lcm_ioctl,
700 open:lcm_open,
701 release:lcm_release,
703 static struct miscdevice lcm_dev = {
704 MOXA_LCM_MINOR,
705 "lcm",
706 &lcm_fops
709 #if 1 // add by Victor Yu. 04-03-2007
710 extern int lcm_module_flag;
711 #endif
712 static void __exit ivtc_lcm1_exit(void)
714 misc_deregister(&lcm_dev);
715 lcm_module_flag = 0;
718 static int __init ivtc_lcm1_init(void)
721 printk("Moxa CPU misc: Register LCM module WG240128B misc ver1.0 ");
722 if ( lcm_module_flag ) {
723 printk("fail !\nThe other type LCM module device driver has loaded.\n");
724 return -ENOMEM;
726 if ( misc_register(&lcm_dev) ) {
727 printk("fail !\n");
728 return -ENOMEM;
730 lcm_module_flag = 1;
731 printk("OK.\n");
733 /* text address & area
734 jimmy_chen@moxa.com.tw:turn down text area, we use own font
735 LCM_two_arguments_cmd(LCM_CMD_SET_T_H_ADDR,0,0) ;
736 LCM_two_arguments_cmd(LCM_CMD_SET_T_AREA,T_AREA_SIZE,0) ;
738 /* graphic address & area */
739 LCM_two_arguments_cmd(LCM_CMD_SET_G_H_ADDR,0,0) ;
740 LCM_two_arguments_cmd(LCM_CMD_SET_G_AREA,G_AREA_SIZE,0) ;
741 /* set or mode */
742 LCM_no_argument_cmd(LCM_CMD_OR_MODE) ;
743 /* reset register off set is use by text area */
744 LCM_two_arguments_cmd(LCM_CMD_SET_OFF_REG,0,0) ;
745 /* set text off graphic on mode */
746 LCM_no_argument_cmd(LCM_CMD_TF_GO) ;
747 /* clear screen */
748 LCM_clear() ;
751 LCM_write_graph(0x00,fnt8x8[16]) ;
752 LCM_write_graph(0x1e*1,fnt8x8[17]) ;
753 LCM_write_graph(0x1e*2,fnt8x8[18]) ;
754 LCM_write_graph(0x1e*3,fnt8x8[19]) ;
755 LCM_write_graph(0x1e*4,fnt8x8[20]) ;
756 LCM_write_graph(0x1e*5,fnt8x8[21]) ;
757 LCM_write_graph(0x1e*6,fnt8x8[22]) ;
758 LCM_write_graph(0x1e*7,fnt8x8[23]) ;
761 return 0;
764 module_init(ivtc_lcm1_init);
765 module_exit(ivtc_lcm1_exit);
767 MODULE_AUTHOR("Victor Yu");
768 MODULE_LICENSE("GPL");