aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/panel
diff options
context:
space:
mode:
authorWilly Tarreau <w@1wt.eu>2008-11-13 20:18:59 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-01-06 16:52:29 -0500
commit7005b58458e4beecaf5efacb872c456bc7d3541a (patch)
treef9e42e1afd86d077508759180d0e4ea5832998ff /drivers/staging/panel
parent18223a99e60787ce41159ed321c8f0a21c328ac1 (diff)
Staging: add lcd-panel driver
This adds the lcd-panel parallel port driver to the staging tree. See the file, drivers/staging/panel/TODO for what needs to be fixed up in order for this to be properly merged into the rest of the kernel tree. Cc: Willy Tarreau <w@1wt.eu> Cc: Frank Menne <frank.menne@hsm.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/panel')
-rw-r--r--drivers/staging/panel/Kconfig290
-rw-r--r--drivers/staging/panel/Makefile1
-rw-r--r--drivers/staging/panel/TODO9
-rw-r--r--drivers/staging/panel/lcd-panel-cgram.txt24
-rw-r--r--drivers/staging/panel/panel.c2343
5 files changed, 2667 insertions, 0 deletions
diff --git a/drivers/staging/panel/Kconfig b/drivers/staging/panel/Kconfig
new file mode 100644
index 00000000000..7cf65575774
--- /dev/null
+++ b/drivers/staging/panel/Kconfig
@@ -0,0 +1,290 @@
1config PANEL
2 tristate "Parallel port LCD/Keypad Panel support"
3 depends on PARPORT
4 ---help---
5 Say Y here if you have an HD44780 or KS-0074 LCD connected to your
6 parallel port. This driver also features 4 and 6-key keypads, and a
7 'smartcard' reader. The LCD is accessible through the /dev/lcd char
8 device (10, 156), the keypad through /dev/keypad (10, 185), and the
9 smartcard through /dev/smartcard (10, 186). Both require misc device
10 to be enabled. This code can either be compiled as a module, or linked
11 into the kernel and started at boot. If you don't understand what all
12 this is about, say N.
13
14config PANEL_PARPORT
15 int "Default parallel port number (0=LPT1)"
16 depends on PANEL
17 range 0 255
18 default "0"
19 ---help---
20 This is the index of the parallel port the panel is connected to. One
21 driver instance only supports one parallel port, so if your keypad
22 and LCD are connected to two separate ports, you have to start two
23 modules with different arguments. Numbering starts with '0' for LPT1,
24 and so on.
25
26config PANEL_PROFILE
27 int "Default panel profile (0-5, 0=custom)"
28 depends on PANEL
29 range 0 5
30 default "5"
31 ---help---
32 To ease configuration, the driver supports different configuration
33 profiles for past and recent wirings. These profiles can also be
34 used to define an approximative configuration, completed by a few
35 other options. Here are the profiles :
36
37 0 = custom (see further)
38 1 = 2x16 parallel LCD, old keypad
39 2 = 2x16 serial LCD (KS-0074), new keypad
40 3 = 2x16 parallel LCD (Hantronix), no keypad
41 4 = 2x16 parallel LCD (Nexcom NSA1045) with Nexcom's keypad
42 5 = 2x40 parallel LCD (old one), with old keypad
43
44 Custom configurations allow you to define how your display is
45 wired to the parallel port, and how it works. This is only intended
46 for experts.
47
48config PANEL_SMARTCARD
49 depends on PANEL && PANEL_PROFILE="0"
50 bool "Enable smartcard reader (read help!)"
51 default "n"
52 ---help---
53 This enables the 'smartcard' reader as installed on the server at
54 'www.ant-computing.com'. It was not really a smartcard reader, just
55 a telephone-card reader. It is left here for demonstration and
56 experimentation. If you enable this driver, it will be accessible
57 through character device 10,186.
58
59config PANEL_KEYPAD
60 depends on PANEL && PANEL_PROFILE="0"
61 int "Keypad type (0=none, 1=old 6 keys, 2=new 6 keys, 3=Nexcom 4 keys)"
62 range 0 4
63 default 0
64 ---help---
65 This enables and configures a keypad connected to the parallel port.
66 The keys will be read from character device 10,185. Valid values are :
67
68 0 : do not enable this driver
69 1 : old 6 keys keypad
70 2 : new 6 keys keypad, as used on the server at www.ant-computing.com
71 3 : Nexcom NSA1045's 4 keys keypad
72
73 New profiles can be described in the driver source. The driver also
74 supports simultaneous keys pressed when the keypad supports them.
75
76config PANEL_LCD
77 depends on PANEL && PANEL_PROFILE="0"
78 int "LCD type (0=none, 1=custom, 2=old //, 3=ks0074, 4=hantronix, 5=Nexcom)"
79 range 0 5
80 default 0
81 ---help---
82 This enables and configures an LCD connected to the parallel port.
83 The driver includes an interpreter for escape codes starting with
84 '\e[L' which are specific to the LCD, and a few ANSI codes. The
85 driver will be registered as character device 10,156, usually
86 under the name '/dev/lcd'. There are a total of 6 supported types :
87
88 0 : do not enable the driver
89 1 : custom configuration and wiring (see further)
90 2 : 2x16 & 2x40 parallel LCD (old wiring)
91 3 : 2x16 serial LCD (KS-0074 based)
92 4 : 2x16 parallel LCD (Hantronix wiring)
93 5 : 2x16 parallel LCD (Nexcom wiring)
94
95 When type '1' is specified, other options will appear to configure
96 more precise aspects (wiring, dimensions, protocol, ...). Please note
97 that those values changed from the 2.4 driver for better consistency.
98
99config PANEL_LCD_HEIGHT
100 depends on PANEL && PANEL_PROFILE="0" && PANEL_LCD="1"
101 int "Number of lines on the LCD (1-2)"
102 range 1 2
103 default 2
104 ---help---
105 This is the number of visible character lines on the LCD in custom profile.
106 It can either be 1 or 2.
107
108config PANEL_LCD_WIDTH
109 depends on PANEL && PANEL_PROFILE="0" && PANEL_LCD="1"
110 int "Number of characters per line on the LCD (1-40)"
111 range 1 40
112 default 40
113 ---help---
114 This is the number of characters per line on the LCD in custom profile.
115 Common values are 16,20,24,40.
116
117config PANEL_LCD_BWIDTH
118 depends on PANEL && PANEL_PROFILE="0" && PANEL_LCD="1"
119 int "Internal LCD line width (1-40, 40 by default)"
120 range 1 40
121 default 40
122 ---help---
123 Most LCDs use a standard controller which supports hardware lines of 40
124 characters, although sometimes only 16, 20 or 24 of them are really wired
125 to the terminal. This results in some non-visible but adressable characters,
126 and is the case for most parallel LCDs. Other LCDs, and some serial ones,
127 however, use the same line width internally as what is visible. The KS0074
128 for example, uses 16 characters per line for 16 visible characters per line.
129
130 This option lets you configure the value used by your LCD in 'custom' profile.
131 If you don't know, put '40' here.
132
133config PANEL_LCD_HWIDTH
134 depends on PANEL && PANEL_PROFILE="0" && PANEL_LCD="1"
135 int "Hardware LCD line width (1-64, 64 by default)"
136 range 1 64
137 default 64
138 ---help---
139 Most LCDs use a single address bit to differentiate line 0 and line 1. Since
140 some of them need to be able to address 40 chars with the lower bits, they
141 often use the immediately superior power of 2, which is 64, to address the
142 next line.
143
144 If you don't know what your LCD uses, in doubt let 16 here for a 2x16, and
145 64 here for a 2x40.
146
147config PANEL_LCD_CHARSET
148 depends on PANEL && PANEL_PROFILE="0" && PANEL_LCD="1"
149 int "LCD character set (0=normal, 1=KS0074)"
150 range 0 1
151 default 0
152 ---help---
153 Some controllers such as the KS0074 use a somewhat strange character set
154 where many symbols are at unusual places. The driver knows how to map
155 'standard' ASCII characters to the character sets used by these controllers.
156 Valid values are :
157
158 0 : normal (untranslated) character set
159 1 : KS0074 character set
160
161 If you don't know, use the normal one (0).
162
163config PANEL_LCD_PROTO
164 depends on PANEL && PANEL_PROFILE="0" && PANEL_LCD="1"
165 int "LCD communication mode (0=parallel 8 bits, 1=serial)"
166 range 0 1
167 default 0
168 ---help---
169 This driver now supports any serial or parallel LCD wired to a parallel
170 port. But before assigning signals, the driver needs to know if it will
171 be driving a serial LCD or a parallel one. Serial LCDs only use 2 wires
172 (SDA/SCL), while parallel ones use 2 or 3 wires for the control signals
173 (E, RS, sometimes RW), and 4 or 8 for the data. Use 0 here for a 8 bits
174 parallel LCD, and 1 for a serial LCD.
175
176config PANEL_LCD_PIN_E
177 depends on PANEL && PANEL_PROFILE="0" && PANEL_LCD="1" && PANEL_LCD_PROTO="0"
178 int "Parallel port pin number & polarity connected to the LCD E signal (-17...17) "
179 range -17 17
180 default 14
181 ---help---
182 This describes the number of the parallel port pin to which the LCD 'E'
183 signal has been connected. It can be :
184
185 0 : no connection (eg: connected to ground)
186 1..17 : directly connected to any of these pins on the DB25 plug
187 -1..-17 : connected to the same pin through an inverter (eg: transistor).
188
189 Default for the 'E' pin in custom profile is '14' (AUTOFEED).
190
191config PANEL_LCD_PIN_RS
192 depends on PANEL && PANEL_PROFILE="0" && PANEL_LCD="1" && PANEL_LCD_PROTO="0"
193 int "Parallel port pin number & polarity connected to the LCD RS signal (-17...17) "
194 range -17 17
195 default 17
196 ---help---
197 This describes the number of the parallel port pin to which the LCD 'RS'
198 signal has been connected. It can be :
199
200 0 : no connection (eg: connected to ground)
201 1..17 : directly connected to any of these pins on the DB25 plug
202 -1..-17 : connected to the same pin through an inverter (eg: transistor).
203
204 Default for the 'RS' pin in custom profile is '17' (SELECT IN).
205
206config PANEL_LCD_PIN_RW
207 depends on PANEL && PANEL_PROFILE="0" && PANEL_LCD="1" && PANEL_LCD_PROTO="0"
208 int "Parallel port pin number & polarity connected to the LCD RW signal (-17...17) "
209 range -17 17
210 default 16
211 ---help---
212 This describes the number of the parallel port pin to which the LCD 'RW'
213 signal has been connected. It can be :
214
215 0 : no connection (eg: connected to ground)
216 1..17 : directly connected to any of these pins on the DB25 plug
217 -1..-17 : connected to the same pin through an inverter (eg: transistor).
218
219 Default for the 'RW' pin in custom profile is '16' (INIT).
220
221config PANEL_LCD_PIN_SCL
222 depends on PANEL && PANEL_PROFILE="0" && PANEL_LCD="1" && PANEL_LCD_PROTO!="0"
223 int "Parallel port pin number & polarity connected to the LCD SCL signal (-17...17) "
224 range -17 17
225 default 1
226 ---help---
227 This describes the number of the parallel port pin to which the serial
228 LCD 'SCL' signal has been connected. It can be :
229
230 0 : no connection (eg: connected to ground)
231 1..17 : directly connected to any of these pins on the DB25 plug
232 -1..-17 : connected to the same pin through an inverter (eg: transistor).
233
234 Default for the 'SCL' pin in custom profile is '1' (STROBE).
235
236config PANEL_LCD_PIN_SDA
237 depends on PANEL && PANEL_PROFILE="0" && PANEL_LCD="1" && PANEL_LCD_PROTO!="0"
238 int "Parallel port pin number & polarity connected to the LCD SDA signal (-17...17) "
239 range -17 17
240 default 2
241 ---help---
242 This describes the number of the parallel port pin to which the serial
243 LCD 'SDA' signal has been connected. It can be :
244
245 0 : no connection (eg: connected to ground)
246 1..17 : directly connected to any of these pins on the DB25 plug
247 -1..-17 : connected to the same pin through an inverter (eg: transistor).
248
249 Default for the 'SDA' pin in custom profile is '2' (D0).
250
251config PANEL_LCD_PIN_BL
252 depends on PANEL && PANEL_PROFILE="0" && PANEL_LCD="1"
253 int "Parallel port pin number & polarity connected to the LCD backlight signal (-17...17) "
254 range -17 17
255 default 0
256 ---help---
257 This describes the number of the parallel port pin to which the LCD 'BL' signal
258 has been connected. It can be :
259
260 0 : no connection (eg: connected to ground)
261 1..17 : directly connected to any of these pins on the DB25 plug
262 -1..-17 : connected to the same pin through an inverter (eg: transistor).
263
264 Default for the 'BL' pin in custom profile is '0' (uncontrolled).
265
266config PANEL_CHANGE_MESSAGE
267 depends on PANEL
268 bool "Change LCD initialization message ?"
269 default "n"
270 ---help---
271 This allows you to replace the boot message indicating the kernel version
272 and the driver version with a custom message. This is useful on appliances
273 where a simple 'Starting system' message can be enough to stop a customer
274 from worrying.
275
276 If you say 'Y' here, you'll be able to choose a message yourself. Otherwise,
277 say 'N' and keep the default message with the version.
278
279config PANEL_BOOT_MESSAGE
280 depends on PANEL && PANEL_CHANGE_MESSAGE="y"
281 string "New initialization message"
282 default ""
283 ---help---
284 This allows you to replace the boot message indicating the kernel version
285 and the driver version with a custom message. This is useful on appliances
286 where a simple 'Starting system' message can be enough to stop a customer
287 from worrying.
288
289 An empty message will only clear the display at driver init time. Any other
290 printf()-formatted message is valid with newline and escape codes.
diff --git a/drivers/staging/panel/Makefile b/drivers/staging/panel/Makefile
new file mode 100644
index 00000000000..747c238b82f
--- /dev/null
+++ b/drivers/staging/panel/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_PANEL) += panel.o
diff --git a/drivers/staging/panel/TODO b/drivers/staging/panel/TODO
new file mode 100644
index 00000000000..a4be749bcdf
--- /dev/null
+++ b/drivers/staging/panel/TODO
@@ -0,0 +1,9 @@
1TODO:
2 - checkpatch.pl cleanups
3 - Lindent
4 - review major/minor usages
5 - review userspace api
6 - see if all of this could be easier done in userspace instead.
7
8Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
9Willy Tarreau <willy@meta-x.org>
diff --git a/drivers/staging/panel/lcd-panel-cgram.txt b/drivers/staging/panel/lcd-panel-cgram.txt
new file mode 100644
index 00000000000..f9ceef4322a
--- /dev/null
+++ b/drivers/staging/panel/lcd-panel-cgram.txt
@@ -0,0 +1,24 @@
1Some LCDs allow you to define up to 8 characters, mapped to ASCII
2characters 0 to 7. The escape code to define a new character is
3'\e[LG' followed by one digit from 0 to 7, representing the character
4number, and up to 8 couples of hex digits terminated by a semi-colon
5(';'). Each couple of digits represents a line, with 1-bits for each
6illuminated pixel with LSB on the right. Lines are numberred from the
7top of the character to the bottom. On a 5x7 matrix, only the 5 lower
8bits of the 7 first bytes are used for each character. If the string
9is incomplete, only complete lines will be redefined. Here are some
10examples :
11
12 printf "\e[LG0010101050D1F0C04;" => 0 = [enter]
13 printf "\e[LG1040E1F0000000000;" => 1 = [up]
14 printf "\e[LG2000000001F0E0400;" => 2 = [down]
15 printf "\e[LG3040E1F001F0E0400;" => 3 = [up-down]
16 printf "\e[LG40002060E1E0E0602;" => 4 = [left]
17 printf "\e[LG500080C0E0F0E0C08;" => 5 = [right]
18 printf "\e[LG60016051516141400;" => 6 = "IP"
19
20 printf "\e[LG00103071F1F070301;" => big speaker
21 printf "\e[LG00002061E1E060200;" => small speaker
22
23Willy
24
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c
new file mode 100644
index 00000000000..e021f5c4e07
--- /dev/null
+++ b/drivers/staging/panel/panel.c
@@ -0,0 +1,2343 @@
1/*
2 * Front panel driver for Linux - 20000810 - Willy Tarreau - willy@meta-x.org.
3 * It includes and LCD display (/dev/lcd), a 4-key keypad (/dev/keypad), and a
4 * smart card reader (/dev/smartcard).
5 *
6 * Updates for this driver may be found here :
7 *
8 * http://w.ods.org/linux/kernel/lcdpanel/
9 *
10 * the driver skeleton has been stolen from nvram.c which was clearly written.
11 *
12 * Changes:
13 * 2000/08/10
14 * - keypad now scrolls LCD when not opened
15 * - released 0.5.1
16 * 2000/08/10
17 * - bug fixes
18 * - released 0.5.2
19 * 2000/08/10
20 * - Reposition LCD when opening /dev/keypad (WIP)
21 * - Released 0.5.3
22 * 2001/02/04
23 * - Start of port to kernel 2.4.1
24 * 2001/03/11
25 * - implementation of a 24-key keyboard scanner with less electronics
26 * around, thus allowing to release the IRQ line.
27 * 2001/03/25
28 * - the driver now compiles and works with both 2.4.2 and 2.2.18 kernels
29 * 2001/04/22
30 * - implementation of KS0074-based serial LCD (load with lcd_enabled=2 and lcd_hwidth=16)
31 * 2001/04/29
32 * - added back-light support, released 0.7.1
33 * 2001/05/01
34 * - added charset conversion table for ks0074, released 0.7.2
35 * 2001/05/08
36 * - start of rewriting towards v0.8
37 * 2001/10/21
38 * - replaced linux/malloc.h with linux/slab.h to be 2.4 compliant
39 * - definition of the multi-layer input system with its naming scheme
40 * - profile support for simplified configuration
41 * 2001/10/28
42 * - smartcard now works for telecards. /dev/smartcard returns the card serial number
43 * 2001/11/10
44 * - fix too short sleep for lcd_clear
45 * 2004/05/09
46 * - add support for hantronix LCD modules (RS on SELECTIN instead of AUTOLF)
47 * (load with lcd_enabled=3 or profile=3)
48 * 2004/06/04
49 * - changed all parallel LCD functions to be more generic. Now any
50 * connection of control signal is allowed with lcd_*_pin.
51 * 2004/07/23
52 * - cleaned up some code
53 * - added support for keypads with inverted inputs
54 * - added support for Nexcom's LCD/Keypad on profile 4
55 * - added character generator for chars 0-7 : "\e[LG{0-7}{8*2 hexdigits};"
56 * 2004/07/29 : 0.9.0
57 * - deprecated lcd_enabled and keypad_enabled in profit of *_type
58 * - changed configuration so that the user can choose everything at
59 * kernel compilation time
60 * 2004/07/31 : 0.9.2
61 * - fixed a stupid copy-paste bug affecting only the serial LCD
62 * - moved display geometries to lcd_init() to avoid problems with custom profiles.
63 * 2004/08/06 : 0.9.3
64 * - added a system notifier callback to print the system state on the LCD
65 * during reboots or halts.
66 *
67 * 2005/05/20 : 0.9.4
68 * - first working port on kernel 2.6
69 *
70 * 2006/12/18 : 0.9.5
71 * - fixed a long standing bug in 2.6 causing panics during reboot/kexec
72 * if the LCD was enabled but not initialized due to lack of parport.
73 *
74 * FIXME:
75 * - the initialization/deinitialization process is very dirty and should
76 * be rewritten. It may even be buggy.
77 *
78 * TODO:
79 * - document 24 keys keyboard (3 rows of 8 cols, 32 diodes + 2 inputs)
80 * - make the LCD a part of a virtual screen of Vx*Vy
81 * - make the inputs list smp-safe
82 * - change the keyboard to a double mapping : signals -> key_id -> values
83 * so that applications can change values without knowing signals
84 *
85 */
86
87#include <linux/module.h>
88
89#include <linux/types.h>
90#include <linux/errno.h>
91#include <linux/signal.h>
92#include <linux/sched.h>
93#include <linux/spinlock.h>
94#include <linux/smp_lock.h>
95#include <linux/interrupt.h>
96#include <linux/miscdevice.h>
97#include <linux/slab.h> // previously <linux/malloc.h>
98#include <linux/ioport.h>
99#include <linux/fcntl.h>
100#include <linux/init.h>
101#include <linux/delay.h>
102#include <linux/ctype.h>
103#include <linux/parport.h>
104#include <linux/version.h>
105#include <linux/list.h>
106#include <linux/notifier.h>
107#include <linux/reboot.h>
108#include <linux/utsrelease.h>
109
110#include <asm/io.h>
111#include <asm/uaccess.h>
112#include <asm/system.h>
113
114/* smartcard length */
115#define SMARTCARD_BYTES 64
116#define LCD_MINOR 156
117#define KEYPAD_MINOR 185
118#define SMARTCARD_MINOR 186
119
120#define PANEL_VERSION "0.9.5"
121
122#define LCD_MAXBYTES 256 /* max burst write */
123
124#define SMARTCARD_LOGICAL_DETECTOR "S6" /* D6 wired to SELECT = card inserted */
125
126#define KEYPAD_BUFFER 64
127#define INPUT_POLL_TIME (HZ/50) /* poll the keyboard this every second */
128#define KEYPAD_REP_START (10) /* a key starts to repeat after this times INPUT_POLL_TIME */
129#define KEYPAD_REP_DELAY (2) /* a key repeats this times INPUT_POLL_TIME */
130
131#define FLASH_LIGHT_TEMPO (200) /* keep the light on this times INPUT_POLL_TIME for each flash */
132
133/* converts an r_str() input to an active high, bits string : 000BAOSE */
134#define PNL_PINPUT(a) ((((unsigned char)(a)) ^ 0x7F) >> 3)
135
136#define PNL_PBUSY 0x80 /* inverted input, active low */
137#define PNL_PACK 0x40 /* direct input, active low */
138#define PNL_POUTPA 0x20 /* direct input, active high */
139#define PNL_PSELECD 0x10 /* direct input, active high */
140#define PNL_PERRORP 0x08 /* direct input, active low */
141
142#define PNL_PBIDIR 0x20 /* bi-directional ports */
143#define PNL_PINTEN 0x10 /* high to read data in or-ed with data out */
144#define PNL_PSELECP 0x08 /* inverted output, active low */
145#define PNL_PINITP 0x04 /* direct output, active low */
146#define PNL_PAUTOLF 0x02 /* inverted output, active low */
147#define PNL_PSTROBE 0x01 /* inverted output */
148
149#define PNL_PD0 0x01
150#define PNL_PD1 0x02
151#define PNL_PD2 0x04
152#define PNL_PD3 0x08
153#define PNL_PD4 0x10
154#define PNL_PD5 0x20
155#define PNL_PD6 0x40
156#define PNL_PD7 0x80
157
158#define PIN_NONE 0
159#define PIN_STROBE 1
160#define PIN_D0 2
161#define PIN_D1 3
162#define PIN_D2 4
163#define PIN_D3 5
164#define PIN_D4 6
165#define PIN_D5 7
166#define PIN_D6 8
167#define PIN_D7 9
168#define PIN_AUTOLF 14
169#define PIN_INITP 16
170#define PIN_SELECP 17
171#define PIN_NOT_SET 127
172
173/* some smartcard-specific signals */
174#define PNL_SC_IO PNL_PD1 /* Warning! inverted output, 0=highZ */
175#define PNL_SC_RST PNL_PD2
176#define PNL_SC_CLK PNL_PD3
177#define PNL_SC_RW PNL_PD4
178#define PNL_SC_ENA PNL_PINITP
179#define PNL_SC_IOR PNL_PACK
180#define PNL_SC_BITS (PNL_SC_IO | PNL_SC_RST | PNL_SC_CLK | PNL_SC_RW)
181
182#define LCD_FLAG_S 0x0001
183#define LCD_FLAG_ID 0x0002
184#define LCD_FLAG_B 0x0004 /* blink on */
185#define LCD_FLAG_C 0x0008 /* cursor on */
186#define LCD_FLAG_D 0x0010 /* display on */
187#define LCD_FLAG_F 0x0020 /* large font mode */
188#define LCD_FLAG_N 0x0040 /* 2-rows mode */
189#define LCD_FLAG_L 0x0080 /* backlight enabled */
190
191#define LCD_ESCAPE_LEN 24 /* 24 chars max for an LCD escape command */
192#define LCD_ESCAPE_CHAR 27 /* use char 27 for escape command */
193
194/* macros to simplify use of the parallel port */
195#define r_ctr(x) (parport_read_control((x)->port))
196#define r_dtr(x) (parport_read_data((x)->port))
197#define r_str(x) (parport_read_status((x)->port))
198#define w_ctr(x,y) do { parport_write_control((x)->port, (y)); } while (0)
199#define w_dtr(x,y) do { parport_write_data((x)->port, (y)); } while (0)
200
201/* this defines which bits are to be used and which ones to be ignored */
202static __u8 scan_mask_o = 0; /* logical or of the output bits involved in the scan matrix */
203static __u8 scan_mask_i = 0; /* logical or of the input bits involved in the scan matrix */
204
205typedef __u64 pmask_t;
206
207enum input_type {
208 INPUT_TYPE_STD,
209 INPUT_TYPE_KBD,
210};
211
212enum input_state {
213 INPUT_ST_LOW,
214 INPUT_ST_RISING,
215 INPUT_ST_HIGH,
216 INPUT_ST_FALLING,
217};
218
219struct logical_input {
220 struct list_head list;
221 pmask_t mask;
222 pmask_t value;
223 enum input_type type;
224 enum input_state state;
225 __u8 rise_time, fall_time;
226 __u8 rise_timer, fall_timer, high_timer;
227
228 union {
229 struct { /* this structure is valid when type == INPUT_TYPE_STD */
230 void(*press_fct)(int);
231 void(*release_fct)(int);
232 int press_data;
233 int release_data;
234 } std;
235 struct { /* this structure is valid when type == INPUT_TYPE_KBD */
236 /* strings can be full-length (ie. non null-terminated) */
237 char press_str[sizeof(void *) + sizeof (int)];
238 char repeat_str[sizeof(void *) + sizeof (int)];
239 char release_str[sizeof(void *) + sizeof (int)];
240 } kbd;
241 } u;
242};
243
244LIST_HEAD(logical_inputs); /* list of all defined logical inputs */
245
246/* physical contacts history
247 * Physical contacts are a 45 bits string of 9 groups of 5 bits each.
248 * The 8 lower groups correspond to output bits 0 to 7, and the 9th group
249 * corresponds to the ground.
250 * Within each group, bits are stored in the same order as read on the port :
251 * BAPSE (busy=4, ack=3, paper empty=2, select=1, error=0).
252 * So, each __u64 (or pmask_t) is represented like this :
253 * 0000000000000000000BAPSEBAPSEBAPSEBAPSEBAPSEBAPSEBAPSEBAPSEBAPSE
254 * <-----unused------><gnd><d07><d06><d05><d04><d03><d02><d01><d00>
255 */
256static pmask_t phys_read; /* what has just been read from the I/O ports */
257static pmask_t phys_read_prev; /* previous phys_read */
258static pmask_t phys_curr; /* stabilized phys_read (phys_read|phys_read_prev) */
259static pmask_t phys_prev; /* previous phys_curr */
260static char inputs_stable = 0; /* 0 means that at least one logical signal needs be computed */
261
262/* these variables are specific to the smartcard */
263static __u8 smartcard_data[SMARTCARD_BYTES];
264static int smartcard_ptr = 0; /* pointer to half bytes in smartcard_data */
265
266/* these variables are specific to the keypad */
267static char keypad_buffer[KEYPAD_BUFFER];
268static int keypad_buflen = 0;
269static int keypad_start = 0;
270static char keypressed = 0;
271static wait_queue_head_t keypad_read_wait;
272static wait_queue_head_t smartcard_read_wait;
273
274/* lcd-specific variables */
275static unsigned long int lcd_flags = 0; /* contains the LCD config state */
276static unsigned long int lcd_addr_x = 0; /* contains the LCD X offset */
277static unsigned long int lcd_addr_y = 0; /* contains the LCD Y offset */
278static char lcd_escape[LCD_ESCAPE_LEN+1]; /* current escape sequence, 0 terminated */
279static int lcd_escape_len = -1; /* not in escape state. >=0 = escape cmd len */
280
281static int lcd_height = -1;
282static int lcd_width = -1;
283static int lcd_hwidth = -1; /* hardware buffer width (usually 64) */
284static int lcd_bwidth = -1; /* internal buffer width (usually 40) */
285
286/*
287 * These are the parallel port pins the LCD control signals are connected to.
288 * Set this to 0 if the signal is not used. Set it to its opposite value
289 * (negative) if the signal is negated. -MAXINT is used to indicate that the
290 * pin has not been explicitly specified.
291 *
292 * WARNING! no check will be performed about collisions with keypad/smartcard !
293 */
294static int lcd_e_pin = PIN_NOT_SET;
295static int lcd_rs_pin = PIN_NOT_SET;
296static int lcd_rw_pin = PIN_NOT_SET;
297static int lcd_bl_pin = PIN_NOT_SET;
298static int lcd_cl_pin = PIN_NOT_SET;
299static int lcd_da_pin = PIN_NOT_SET;
300
301/*
302 * Bit masks to convert LCD signals to parallel port outputs.
303 * _d_ are values for data port, _c_ are for control port.
304 * [0] = signal OFF, [1] = signal ON, [2] = mask
305 */
306#define BIT_CLR 0
307#define BIT_SET 1
308#define BIT_MSK 2
309#define BIT_STATES 3
310/*
311 * one entry for each bit on the LCD
312 */
313#define LCD_BIT_E 0
314#define LCD_BIT_RS 1
315#define LCD_BIT_RW 2
316#define LCD_BIT_BL 3
317#define LCD_BIT_CL 4
318#define LCD_BIT_DA 5
319#define LCD_BITS 6
320
321/*
322 * each bit can be either connected to a DATA or CTRL port
323 */
324#define LCD_PORT_C 0
325#define LCD_PORT_D 1
326#define LCD_PORTS 2
327
328static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES];
329
330/*
331 * LCD protocols
332 */
333#define LCD_PROTO_PARALLEL 0
334#define LCD_PROTO_SERIAL 1
335
336/*
337 * LCD character sets
338 */
339#define LCD_CHARSET_NORMAL 0
340#define LCD_CHARSET_KS0074 1
341
342/*
343 * LCD types
344 */
345#define LCD_TYPE_NONE 0
346#define LCD_TYPE_OLD 1
347#define LCD_TYPE_KS0074 2
348#define LCD_TYPE_HANTRONIX 3
349#define LCD_TYPE_NEXCOM 4
350#define LCD_TYPE_CUSTOM 5
351
352/*
353 * keypad types
354 */
355#define KEYPAD_TYPE_NONE 0
356#define KEYPAD_TYPE_OLD 1
357#define KEYPAD_TYPE_NEW 2
358#define KEYPAD_TYPE_NEXCOM 3
359
360/*
361 * panel profiles
362 */
363#define PANEL_PROFILE_CUSTOM 0
364#define PANEL_PROFILE_OLD 1
365#define PANEL_PROFILE_NEW 2
366#define PANEL_PROFILE_HANTRONIX 3
367#define PANEL_PROFILE_NEXCOM 4
368#define PANEL_PROFILE_LARGE 5
369
370/*
371 * Construct custom config from the kernel's configuration
372 */
373#define DEFAULT_PROFILE PANEL_PROFILE_LARGE
374#define DEFAULT_PARPORT 0
375#define DEFAULT_LCD LCD_TYPE_OLD
376#define DEFAULT_KEYPAD KEYPAD_TYPE_OLD
377#define DEFAULT_SMARTCARD 0
378#define DEFAULT_LCD_WIDTH 40
379#define DEFAULT_LCD_BWIDTH 40
380#define DEFAULT_LCD_HWIDTH 64
381#define DEFAULT_LCD_HEIGHT 2
382#define DEFAULT_LCD_PROTO LCD_PROTO_PARALLEL
383
384#define DEFAULT_LCD_PIN_E PIN_AUTOLF
385#define DEFAULT_LCD_PIN_RS PIN_SELECP
386#define DEFAULT_LCD_PIN_RW PIN_INITP
387#define DEFAULT_LCD_PIN_SCL PIN_STROBE
388#define DEFAULT_LCD_PIN_SDA PIN_D0
389#define DEFAULT_LCD_PIN_BL PIN_NOT_SET
390#define DEFAULT_LCD_CHARSET LCD_CHARSET_NORMAL
391
392#ifdef CONFIG_PANEL_PROFILE
393#undef DEFAULT_PROFILE
394#define DEFAULT_PROFILE CONFIG_PANEL_PROFILE
395#endif
396
397#ifdef CONFIG_PANEL_PARPORT
398#undef DEFAULT_PARPORT
399#define DEFAULT_PARPORT CONFIG_PANEL_PARPORT
400#endif
401
402#if DEFAULT_PROFILE==0 /* custom */
403#ifdef CONFIG_PANEL_KEYPAD
404#undef DEFAULT_KEYPAD
405#define DEFAULT_KEYPAD CONFIG_PANEL_KEYPAD
406#endif
407
408#ifdef CONFIG_PANEL_SMARTCARD
409#undef DEFAULT_SMARTCARD
410#define DEFAULT_SMARTCARD 1
411#endif
412
413#ifdef CONFIG_PANEL_LCD
414#undef DEFAULT_LCD
415#define DEFAULT_LCD CONFIG_PANEL_LCD
416#endif
417
418#ifdef CONFIG_PANEL_LCD_WIDTH
419#undef DEFAULT_LCD_WIDTH
420#define DEFAULT_LCD_WIDTH CONFIG_PANEL_LCD_WIDTH
421#endif
422
423#ifdef CONFIG_PANEL_LCD_BWIDTH
424#undef DEFAULT_LCD_BWIDTH
425#define DEFAULT_LCD_BWIDTH CONFIG_PANEL_LCD_BWIDTH
426#endif
427
428#ifdef CONFIG_PANEL_LCD_HWIDTH
429#undef DEFAULT_LCD_HWIDTH
430#define DEFAULT_LCD_HWIDTH CONFIG_PANEL_LCD_HWIDTH
431#endif
432
433#ifdef CONFIG_PANEL_LCD_HEIGHT
434#undef DEFAULT_LCD_HEIGHT
435#define DEFAULT_LCD_HEIGHT CONFIG_PANEL_LCD_HEIGHT
436#endif
437
438#ifdef CONFIG_PANEL_LCD_PROTO
439#undef DEFAULT_LCD_PROTO
440#define DEFAULT_LCD_PROTO CONFIG_PANEL_LCD_PROTO
441#endif
442
443#ifdef CONFIG_PANEL_LCD_PIN_E
444#undef DEFAULT_LCD_PIN_E
445#define DEFAULT_LCD_PIN_E CONFIG_PANEL_LCD_PIN_E
446#endif
447
448#ifdef CONFIG_PANEL_LCD_PIN_RS
449#undef DEFAULT_LCD_PIN_RS
450#define DEFAULT_LCD_PIN_RS CONFIG_PANEL_LCD_PIN_RS
451#endif
452
453#ifdef CONFIG_PANEL_LCD_PIN_RW
454#undef DEFAULT_LCD_PIN_RW
455#define DEFAULT_LCD_PIN_RW CONFIG_PANEL_LCD_PIN_RW
456#endif
457
458#ifdef CONFIG_PANEL_LCD_PIN_SCL
459#undef DEFAULT_LCD_PIN_SCL
460#define DEFAULT_LCD_PIN_SCL CONFIG_PANEL_LCD_PIN_SCL
461#endif
462
463#ifdef CONFIG_PANEL_LCD_PIN_SDA
464#undef DEFAULT_LCD_PIN_SDA
465#define DEFAULT_LCD_PIN_SDA CONFIG_PANEL_LCD_PIN_SDA
466#endif
467
468#ifdef CONFIG_PANEL_LCD_PIN_BL
469#undef DEFAULT_LCD_PIN_BL
470#define DEFAULT_LCD_PIN_BL CONFIG_PANEL_LCD_PIN_BL
471#endif
472
473#ifdef CONFIG_PANEL_LCD_CHARSET
474#undef DEFAULT_LCD_CHARSET
475#define DEFAULT_LCD_CHARSET
476#endif
477
478#endif /* DEFAULT_PROFILE == 0 */
479
480/* global variables */
481static int smartcard_open_cnt = 0; /* #times opened */
482static int keypad_open_cnt = 0; /* #times opened */
483static int lcd_open_cnt = 0; /* #times opened */
484
485static int profile = DEFAULT_PROFILE;
486static struct pardevice *pprt = NULL;
487static int parport = -1;
488static int lcd_enabled = -1;
489static int lcd_type = -1;
490static int lcd_proto = -1;
491static int lcd_charset = -1;
492static int keypad_enabled = -1;
493static int keypad_type = -1;
494static int smartcard_enabled = -1;
495
496static int lcd_initialized, keypad_initialized, smartcard_initialized;
497
498static int light_tempo = 0;
499
500static char lcd_must_clear = 0;
501static char lcd_left_shift = 0;
502static char init_in_progress = 0;
503
504static void(*lcd_write_cmd)(int) = NULL;
505static void(*lcd_write_data)(int) = NULL;
506static void(*lcd_clear_fast)(void) = NULL;
507
508static spinlock_t pprt_lock = SPIN_LOCK_UNLOCKED;
509static struct timer_list scan_timer;
510
511#ifdef MODULE
512
513MODULE_DESCRIPTION("Generic parallel port LCD/Keypad/Smartcard driver");
514module_param(parport, int, 0000);MODULE_PARM_DESC(parport, "Parallel port index (0=lpt1, 1=lpt2, ...)");
515module_param(lcd_height, int, 0000);MODULE_PARM_DESC(lcd_height, "Number of lines on the LCD");
516module_param(lcd_width, int, 0000);MODULE_PARM_DESC(lcd_width, "Number of columns on the LCD");
517module_param(lcd_bwidth, int, 0000);MODULE_PARM_DESC(lcd_bwidth, "Internal LCD line width (40)");
518module_param(lcd_hwidth, int, 0000);MODULE_PARM_DESC(lcd_hwidth, "LCD line hardware address (64)");
519module_param(lcd_enabled, int, 0000);MODULE_PARM_DESC(lcd_enabled, "Deprecated option, use lcd_type instead");
520module_param(keypad_enabled, int, 0000);MODULE_PARM_DESC(keypad_enabled, "Deprecated option, use keypad_type instead");
521module_param(lcd_type, int, 0000);MODULE_PARM_DESC(lcd_type, "LCD type: 0=none, 1=old //, 2=serial ks0074, 3=hantronix //, 4=nexcom //, 5=compiled-in");
522module_param(lcd_proto, int, 0000);MODULE_PARM_DESC(lcd_proto, "LCD communication: 0=parallel (//), 1=serial");
523module_param(lcd_charset, int, 0000);MODULE_PARM_DESC(lcd_charset, "LCD character set: 0=standard, 1=KS0074");
524module_param(keypad_type, int, 0000);MODULE_PARM_DESC(keypad_type, "Keypad type: 0=none, 1=old 6 keys, 2=new 6+1 keys, 3=nexcom 4 keys");
525module_param(smartcard_enabled, int, 0000);MODULE_PARM_DESC(smartcard_enabled, "Smartcard reader: 0=disabled (default), 1=enabled");
526module_param(profile, int, 0000); MODULE_PARM_DESC(profile, "1=16x2 old kp; 2=serial 16x2, new kp; 3=16x2 hantronix; 4=16x2 nexcom; default=40x2, old kp");
527
528module_param(lcd_e_pin, int, 0000); MODULE_PARM_DESC(lcd_e_pin, "# of the // port pin connected to LCD 'E' signal, with polarity (-17..17)");
529module_param(lcd_rs_pin, int, 0000);MODULE_PARM_DESC(lcd_rs_pin, "# of the // port pin connected to LCD 'RS' signal, with polarity (-17..17)");
530module_param(lcd_rw_pin, int, 0000);MODULE_PARM_DESC(lcd_rw_pin, "# of the // port pin connected to LCD 'RW' signal, with polarity (-17..17)");
531module_param(lcd_bl_pin, int, 0000);MODULE_PARM_DESC(lcd_bl_pin, "# of the // port pin connected to LCD backlight, with polarity (-17..17)");
532module_param(lcd_da_pin, int, 0000);MODULE_PARM_DESC(lcd_da_pin, "# of the // port pin connected to serial LCD 'SDA' signal, with polarity (-17..17)");
533module_param(lcd_cl_pin, int, 0000);MODULE_PARM_DESC(lcd_cl_pin, "# of the // port pin connected to serial LCD 'SCL' signal, with polarity (-17..17)");
534
535#endif
536
537static unsigned char *lcd_char_conv = NULL;
538
539/* for some LCD drivers (ks0074) we need a charset conversion table. */
540static unsigned char lcd_char_conv_ks0074[256] = {
541 /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
542 /* 0x00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
543 /* 0x10 */ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
544 /* 0x20 */ 0x20, 0x21, 0x22, 0x23, 0xa2, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
545 /* 0x30 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
546 /* 0x40 */ 0xa0, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
547 /* 0x50 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0xfa, 0xfb, 0xfc, 0x1d, 0xc4,
548 /* 0x60 */ 0x96, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
549 /* 0x70 */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0xfd, 0xfe, 0xff, 0xce, 0x20,
550 /* 0x80 */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
551 /* 0x90 */ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
552 /* 0xA0 */ 0x20, 0x40, 0xb1, 0xa1, 0x24, 0xa3, 0xfe, 0x5f, 0x22, 0xc8, 0x61, 0x14, 0x97, 0x2d, 0xad, 0x96,
553 /* 0xB0 */ 0x80, 0x8c, 0x82, 0x83, 0x27, 0x8f, 0x86, 0xdd, 0x2c, 0x81, 0x6f, 0x15, 0x8b, 0x8a, 0x84, 0x60,
554 /* 0xC0 */ 0xe2, 0xe2, 0xe2, 0x5b, 0x5b, 0xae, 0xbc, 0xa9, 0xc5, 0xbf, 0xc6, 0xf1, 0xe3, 0xe3, 0xe3, 0xe3,
555 /* 0xD0 */ 0x44, 0x5d, 0xa8, 0xe4, 0xec, 0xec, 0x5c, 0x78, 0xab, 0xa6, 0xe5, 0x5e, 0x5e, 0xe6, 0xaa, 0xbe,
556 /* 0xE0 */ 0x7f, 0xe7, 0xaf, 0x7b, 0x7b, 0xaf, 0xbd, 0xc8, 0xa4, 0xa5, 0xc7, 0xf6, 0xa7, 0xe8, 0x69, 0x69,
557 /* 0xF0 */ 0xed, 0x7d, 0xa8, 0xe4, 0xec, 0x5c, 0x5c, 0x25, 0xac, 0xa6, 0xea, 0xef, 0x7e, 0xeb, 0xb2, 0x79,
558};
559
560char old_keypad_profile[][4][9] = {
561 {"S0", "Left\n", "Left\n", ""},
562 {"S1", "Down\n", "Down\n", ""},
563 {"S2", "Up\n", "Up\n", ""},
564 {"S3", "Right\n", "Right\n", ""},
565 {"S4", "Esc\n", "Esc\n", ""},
566 {"S5", "Ret\n", "Ret\n", ""},
567 {"","","",""}
568};
569
570/* signals, press, repeat, release */
571char new_keypad_profile[][4][9] = {
572 {"S0", "Left\n", "Left\n", ""},
573 {"S1", "Down\n", "Down\n", ""},
574 {"S2", "Up\n", "Up\n", ""},
575 {"S3", "Right\n", "Right\n", ""},
576 {"S4s5", "", "Esc\n", "Esc\n"},
577 {"s4S5", "", "Ret\n", "Ret\n"},
578 {"S4S5", "Help\n", "", ""},
579 /* add new signals above this line */
580 {"","","",""}
581};
582
583/* signals, press, repeat, release */
584char nexcom_keypad_profile[][4][9] = {
585 {"a-p-e-", "Down\n", "Down\n", ""}, // Down
586 {"a-p-E-", "Ret\n", "Ret\n", ""}, // Enter
587 {"a-P-E-", "Esc\n", "Esc\n", ""}, // Esc
588 {"a-P-e-", "Up\n", "Up\n", ""}, // Up
589 /* add new signals above this line */
590 {"","","",""}
591};
592
593static char (*keypad_profile)[4][9] = old_keypad_profile;
594
595/* FIXME: this should be converted to a bit array containing signals states */
596static struct {
597 unsigned char e; /* parallel LCD E (data latch on falling edge) */
598 unsigned char rs; /* parallel LCD RS (0 = cmd, 1 = data) */
599 unsigned char rw; /* parallel LCD R/W (0 = W, 1 = R) */
600 unsigned char bl; /* parallel LCD backlight (0 = off, 1 = on) */
601 unsigned char cl; /* serial LCD clock (latch on rising edge) */
602 unsigned char da; /* serial LCD data */
603} bits;
604
605static void init_scan_timer(void);
606
607/* sets data port bits according to current signals values */
608static int set_data_bits(void) {
609 int val, bit;
610
611 val = r_dtr(pprt);
612 for (bit = 0; bit < LCD_BITS; bit++)
613 val &= lcd_bits[LCD_PORT_D][bit][BIT_MSK];
614
615 val |= lcd_bits[LCD_PORT_D][LCD_BIT_E][bits.e]
616 | lcd_bits[LCD_PORT_D][LCD_BIT_RS][bits.rs]
617 | lcd_bits[LCD_PORT_D][LCD_BIT_RW][bits.rw]
618 | lcd_bits[LCD_PORT_D][LCD_BIT_BL][bits.bl]
619 | lcd_bits[LCD_PORT_D][LCD_BIT_CL][bits.cl]
620 | lcd_bits[LCD_PORT_D][LCD_BIT_DA][bits.da];
621
622 w_dtr(pprt, val);
623 return val;
624}
625
626/* sets ctrl port bits according to current signals values */
627static int set_ctrl_bits(void) {
628 int val, bit;
629
630 val = r_ctr(pprt);
631 for (bit = 0; bit < LCD_BITS; bit++)
632 val &= lcd_bits[LCD_PORT_C][bit][BIT_MSK];
633
634 val |= lcd_bits[LCD_PORT_C][LCD_BIT_E][bits.e]
635 | lcd_bits[LCD_PORT_C][LCD_BIT_RS][bits.rs]
636 | lcd_bits[LCD_PORT_C][LCD_BIT_RW][bits.rw]
637 | lcd_bits[LCD_PORT_C][LCD_BIT_BL][bits.bl]
638 | lcd_bits[LCD_PORT_C][LCD_BIT_CL][bits.cl]
639 | lcd_bits[LCD_PORT_C][LCD_BIT_DA][bits.da];
640
641 w_ctr(pprt, val);
642 return val;
643}
644
645/* sets ctrl & data port bits according to current signals values */
646static void set_bits(void) {
647 set_data_bits();
648 set_ctrl_bits();
649}
650
651/*
652 * Converts a parallel port pin (from -25 to 25) to data and control ports
653 * masks, and data and control port bits. The signal will be considered
654 * unconnected if it's on pin 0 or an invalid pin (<-25 or >25).
655 *
656 * Result will be used this way :
657 * out(dport, in(dport) & d_val[2] | d_val[signal_state])
658 * out(cport, in(cport) & c_val[2] | c_val[signal_state])
659 */
660void pin_to_bits(int pin, unsigned char *d_val, unsigned char *c_val) {
661 int d_bit, c_bit, inv;
662
663 d_val[0] = c_val[0] = d_val[1] = c_val[1] = 0;
664 d_val[2] = c_val[2] = 0xFF;
665
666 if (pin == 0)
667 return;
668
669 inv = (pin < 0);
670 if (inv)
671 pin = -pin;
672
673 d_bit = c_bit = 0;
674
675 switch (pin) {
676 case PIN_STROBE: /* strobe, inverted */
677 c_bit = PNL_PSTROBE;
678 inv = !inv;
679 break;
680 case PIN_D0 ... PIN_D7: /* D0 - D7 = 2 - 9 */
681 d_bit = 1 << (pin - 2);
682 break;
683 case PIN_AUTOLF: /* autofeed, inverted */
684 c_bit = PNL_PAUTOLF;
685 inv = !inv;
686 break;
687 case PIN_INITP: /* init, direct */
688 c_bit = PNL_PINITP;
689 break;
690 case PIN_SELECP: /* select_in, inverted */
691 c_bit = PNL_PSELECP;
692 inv = !inv;
693 break;
694 default: /* unknown pin, ignore */
695 break;
696 }
697
698 if (c_bit) {
699 c_val[2] &= ~c_bit;
700 c_val[!inv] = c_bit;
701 } else if (d_bit) {
702 d_val[2] &= ~d_bit;
703 d_val[!inv] = d_bit;
704 }
705}
706
707/* sleeps that many milliseconds with a reschedule */
708static void long_sleep(int ms) {
709
710 if (in_interrupt())
711 mdelay(ms);
712 else {
713 current->state = TASK_INTERRUPTIBLE;
714 schedule_timeout((ms*HZ+999)/1000);
715 }
716}
717
718
719/* send a serial byte to the LCD panel. The caller is responsible for locking if needed. */
720static void lcd_send_serial(int byte) {
721 int bit;
722
723 /* the data bit is set on D0, and the clock on STROBE.
724 * LCD reads D0 on STROBE's rising edge.
725 */
726 for (bit = 0; bit < 8; bit++) {
727 bits.cl = BIT_CLR; /* CLK low */
728 set_bits();
729 bits.da = byte & 1;
730 set_bits();
731 udelay(2); /* maintain the data during 2 us before CLK up */
732 bits.cl = BIT_SET; /* CLK high */
733 set_bits();
734 udelay(1); /* maintain the strobe during 1 us */
735 byte >>= 1;
736 }
737}
738
739/* turn the backlight on or off */
740static void lcd_backlight(int on) {
741 if (lcd_bl_pin == PIN_NONE)
742 return;
743
744 /* The backlight is activated by seting the AUTOFEED line to +5V */
745 spin_lock(&pprt_lock);
746 bits.bl = on;
747 set_bits();
748 spin_unlock(&pprt_lock);
749}
750
751/* send a command to the LCD panel in serial mode */
752static void lcd_write_cmd_s(int cmd) {
753 spin_lock(&pprt_lock);
754 lcd_send_serial(0x1F); /* R/W=W, RS=0 */
755 lcd_send_serial(cmd & 0x0F);
756 lcd_send_serial((cmd >> 4) & 0x0F);
757 udelay(40); /* the shortest command takes at least 40 us */
758 spin_unlock(&pprt_lock);
759}
760
761/* send data to the LCD panel in serial mode */
762static void lcd_write_data_s(int data) {
763 spin_lock(&pprt_lock);
764 lcd_send_serial(0x5F); /* R/W=W, RS=1 */
765 lcd_send_serial(data & 0x0F);
766 lcd_send_serial((data >> 4) & 0x0F);
767 udelay(40); /* the shortest data takes at least 40 us */
768 spin_unlock(&pprt_lock);
769}
770
771/* send a command to the LCD panel in 8 bits parallel mode */
772static void lcd_write_cmd_p8(int cmd) {
773 spin_lock(&pprt_lock);
774 /* present the data to the data port */
775 w_dtr(pprt, cmd);
776 udelay(20); /* maintain the data during 20 us before the strobe */
777
778 bits.e = BIT_SET ; bits.rs = BIT_CLR ; bits.rw = BIT_CLR;
779 set_ctrl_bits();
780
781 udelay(40); /* maintain the strobe during 40 us */
782
783 bits.e = BIT_CLR;
784 set_ctrl_bits();
785
786 udelay(120); /* the shortest command takes at least 120 us */
787 spin_unlock(&pprt_lock);
788}
789
790/* send data to the LCD panel in 8 bits parallel mode */
791static void lcd_write_data_p8(int data) {
792 spin_lock(&pprt_lock);
793 /* present the data to the data port */
794 w_dtr(pprt, data);
795 udelay(20); /* maintain the data during 20 us before the strobe */
796
797 bits.e = BIT_SET ; bits.rs = BIT_SET ; bits.rw = BIT_CLR;
798 set_ctrl_bits();
799
800 udelay(40); /* maintain the strobe during 40 us */
801
802 bits.e = BIT_CLR;
803 set_ctrl_bits();
804
805 udelay(45); /* the shortest data takes at least 45 us */
806 spin_unlock(&pprt_lock);
807}
808
809static void lcd_gotoxy(void) {
810 lcd_write_cmd(0x80 /* set DDRAM address */
811 | (lcd_addr_y ? lcd_hwidth : 0)
812 /* we force the cursor to stay at the end of the line if it wants to go farther */
813 | ((lcd_addr_x < lcd_bwidth) ? lcd_addr_x & (lcd_hwidth-1) : lcd_bwidth - 1));
814}
815
816static void lcd_print(char c) {
817 if (lcd_addr_x < lcd_bwidth) {
818 if (lcd_char_conv != NULL)
819 c = lcd_char_conv[(unsigned char)c];
820 lcd_write_data(c);
821 lcd_addr_x++;
822 }
823 /* prevents the cursor from wrapping onto the next line */
824 if (lcd_addr_x == lcd_bwidth) {
825 lcd_gotoxy();
826 }
827}
828
829/* fills the display with spaces and resets X/Y */
830static void lcd_clear_fast_s(void) {
831 int pos;
832 lcd_addr_x = lcd_addr_y = 0;
833 lcd_gotoxy();
834
835 spin_lock(&pprt_lock);
836 for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) {
837 lcd_send_serial(0x5F); /* R/W=W, RS=1 */
838 lcd_send_serial(' ' & 0x0F);
839 lcd_send_serial((' ' >> 4) & 0x0F);
840 udelay(40); /* the shortest data takes at least 40 us */
841 }
842 spin_unlock(&pprt_lock);
843
844 lcd_addr_x = lcd_addr_y = 0;
845 lcd_gotoxy();
846}
847
848/* fills the display with spaces and resets X/Y */
849static void lcd_clear_fast_p8(void) {
850 int pos;
851 lcd_addr_x = lcd_addr_y = 0;
852 lcd_gotoxy();
853
854 spin_lock(&pprt_lock);
855 for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) {
856 /* present the data to the data port */
857 w_dtr(pprt, ' ');
858 udelay(20); /* maintain the data during 20 us before the strobe */
859
860 bits.e = BIT_SET ; bits.rs = BIT_SET ; bits.rw = BIT_CLR;
861 set_ctrl_bits();
862
863 udelay(40); /* maintain the strobe during 40 us */
864
865 bits.e = BIT_CLR;
866 set_ctrl_bits();
867
868 udelay(45); /* the shortest data takes at least 45 us */
869 }
870 spin_unlock(&pprt_lock);
871
872 lcd_addr_x = lcd_addr_y = 0;
873 lcd_gotoxy();
874}
875
876/* clears the display and resets X/Y */
877static void lcd_clear_display(void) {
878 lcd_write_cmd(0x01); /* clear display */
879 lcd_addr_x = lcd_addr_y = 0;
880 /* we must wait a few milliseconds (15) */
881 long_sleep(15);
882}
883
884static void lcd_init_display(void) {
885
886 lcd_flags = ((lcd_height > 1) ? LCD_FLAG_N : 0)
887 | LCD_FLAG_D | LCD_FLAG_C | LCD_FLAG_B;
888
889 long_sleep(20); /* wait 20 ms after power-up for the paranoid */
890
891 lcd_write_cmd(0x30); /* 8bits, 1 line, small fonts */
892 long_sleep(10);
893 lcd_write_cmd(0x30); /* 8bits, 1 line, small fonts */
894 long_sleep(10);
895 lcd_write_cmd(0x30); /* 8bits, 1 line, small fonts */
896 long_sleep(10);
897
898 lcd_write_cmd(0x30 /* set font height and lines number */
899 | ((lcd_flags & LCD_FLAG_F)?4:0)
900 | ((lcd_flags & LCD_FLAG_N)?8:0)
901 );
902 long_sleep(10);
903
904 lcd_write_cmd(0x08); /* display off, cursor off, blink off */
905 long_sleep(10);
906
907 lcd_write_cmd(0x08 /* set display mode */
908 | ((lcd_flags & LCD_FLAG_D)?4:0)
909 | ((lcd_flags & LCD_FLAG_C)?2:0)
910 | ((lcd_flags & LCD_FLAG_B)?1:0)
911 );
912
913 lcd_backlight((lcd_flags & LCD_FLAG_L) ? 1 : 0);
914
915 long_sleep(10);
916
917 lcd_write_cmd(0x06); /* entry mode set : increment, cursor shifting */
918
919 lcd_clear_display();
920}
921
922/*
923 * These are the file operation function for user access to /dev/lcd
924 * This function can also be called from inside the kernel, by
925 * setting file and ppos to NULL.
926 *
927 */
928
929static ssize_t lcd_write(struct file * file,
930 const char * buf, size_t count, loff_t *ppos ) {
931
932 const char *tmp = buf;
933 char c;
934
935 for( ; count-- > 0; (ppos ? (*ppos)++ : 0), ++tmp ) {
936 if (!in_interrupt() && (((count + 1) & 0x1f) == 0)) {
937 schedule(); /* let's be a little nice with other processes that need some CPU */
938 }
939 if (ppos == NULL && file == NULL)
940 c = *tmp; /* let's not use get_user() from the kernel ! */
941 else if (get_user( c, tmp ))
942 return -EFAULT;
943
944 /* first, we'll test if we're in escape mode */
945 if ((c != '\n') && lcd_escape_len >= 0) { /* yes, let's add this char to the buffer */
946 lcd_escape[lcd_escape_len++] = c;
947 lcd_escape[lcd_escape_len] = 0;
948 }
949 else {
950 lcd_escape_len = -1; /* aborts any previous escape sequence */
951
952 switch (c) {
953 case LCD_ESCAPE_CHAR: /* start of an escape sequence */
954 lcd_escape_len = 0;
955 lcd_escape[lcd_escape_len] = 0;
956 break;
957 case '\b': /* go back one char and clear it */
958 if (lcd_addr_x > 0) {
959 if (lcd_addr_x < lcd_bwidth) /* check if we're not at the end of the line */
960 lcd_write_cmd(0x10); /* back one char */
961 lcd_addr_x--;
962 }
963 lcd_write_data(' '); /* replace with a space */
964 lcd_write_cmd(0x10); /* back one char again */
965 break;
966 case '\014': /* quickly clear the display */
967 lcd_clear_fast();
968 break;
969 case '\n': /* flush the remainder of the current line and go to the
970 beginning of the next line */
971 for (; lcd_addr_x<lcd_bwidth; lcd_addr_x++)
972 lcd_write_data(' ');
973 lcd_addr_x = 0;
974 lcd_addr_y = (lcd_addr_y + 1) % lcd_height;
975 lcd_gotoxy();
976 break;
977 case '\r': /* go to the beginning of the same line */
978 lcd_addr_x = 0;
979 lcd_gotoxy();
980 break;
981 case '\t': /* print a space instead of the tab */
982 lcd_print(' ');
983 break;
984 default : /* simply print this char */
985 lcd_print(c);
986 break;
987 }
988 }
989
990 /* now we'll see if we're in an escape mode and if the current
991 escape sequence can be understood.
992 */
993 if (lcd_escape_len >= 2) { /* minimal length for an escape command */
994 int processed = 0; /* 1 means the command has been processed */
995
996 if (!strcmp(lcd_escape,"[2J")) { /* Clear the display */
997 lcd_clear_fast(); /* clear display */
998 processed = 1;
999 }
1000 else if (!strcmp(lcd_escape,"[H")) { /* Cursor to home */
1001 lcd_addr_x = lcd_addr_y = 0;
1002 lcd_gotoxy();
1003 processed = 1;
1004 }
1005 /* codes starting with ^[[L */
1006 else if ((lcd_escape_len >= 3) &&
1007 (lcd_escape[0]=='[') && (lcd_escape[1]=='L')) { /* LCD special codes */
1008
1009 char *esc = lcd_escape + 2;
1010 int oldflags = lcd_flags;
1011
1012 /* check for display mode flags */
1013 switch (*esc) {
1014 case 'D' : /* Display ON */
1015 lcd_flags |= LCD_FLAG_D;
1016 processed = 1;
1017 break;
1018 case 'd' : /* Display OFF */
1019 lcd_flags &= ~LCD_FLAG_D;
1020 processed = 1;
1021 break;
1022 case 'C' : /* Cursor ON */
1023 lcd_flags |= LCD_FLAG_C;
1024 processed = 1;
1025 break;
1026 case 'c' : /* Cursor OFF */
1027 lcd_flags &= ~LCD_FLAG_C;
1028 processed = 1;
1029 break;
1030 case 'B' : /* Blink ON */
1031 lcd_flags |= LCD_FLAG_B;
1032 processed = 1;
1033 break;
1034 case 'b' : /* Blink OFF */
1035 lcd_flags &= ~LCD_FLAG_B;
1036 processed = 1;
1037 break;
1038 case '+' : /* Back light ON */
1039 lcd_flags |= LCD_FLAG_L;
1040 processed = 1;
1041 break;
1042 case '-' : /* Back light OFF */
1043 lcd_flags &= ~LCD_FLAG_L;
1044 processed = 1;
1045 break;
1046 case '*' : /* flash back light using the keypad timer */
1047 if (scan_timer.function != NULL) {
1048 if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0))
1049 lcd_backlight(1);
1050 light_tempo = FLASH_LIGHT_TEMPO;
1051 }
1052 processed = 1;
1053 break;
1054 case 'f' : /* Small Font */
1055 lcd_flags &= ~LCD_FLAG_F;
1056 processed = 1;
1057 break;
1058 case 'F' : /* Large Font */
1059 lcd_flags |= LCD_FLAG_F;
1060 processed = 1;
1061 break;
1062 case 'n' : /* One Line */
1063 lcd_flags &= ~LCD_FLAG_N;
1064 processed = 1;
1065 break;
1066 case 'N' : /* Two Lines */
1067 lcd_flags |= LCD_FLAG_N;
1068 break;
1069
1070 case 'l' : /* Shift Cursor Left */
1071 if (lcd_addr_x > 0) {
1072 if (lcd_addr_x < lcd_bwidth)
1073 lcd_write_cmd(0x10); /* back one char if not at end of line */
1074 lcd_addr_x--;
1075 }
1076 processed = 1;
1077 break;
1078
1079 case 'r' : /* shift cursor right */
1080 if (lcd_addr_x < lcd_width) {
1081 if (lcd_addr_x < (lcd_bwidth - 1))
1082 lcd_write_cmd(0x14); /* allow the cursor to pass the end of the line */
1083 lcd_addr_x++;
1084 }
1085 processed = 1;
1086 break;
1087
1088 case 'L' : /* shift display left */
1089 lcd_left_shift++;
1090 lcd_write_cmd(0x18);
1091 processed = 1;
1092 break;
1093
1094 case 'R' : /* shift display right */
1095 lcd_left_shift--;
1096 lcd_write_cmd(0x1C);
1097 processed = 1;
1098 break;
1099
1100 case 'k' : { /* kill end of line */
1101 int x;
1102 for (x=lcd_addr_x; x<lcd_bwidth; x++)
1103 lcd_write_data(' ');
1104 lcd_gotoxy(); /* restore cursor position */
1105 processed = 1;
1106 break;
1107 }
1108 case 'I' : /* reinitialize display */
1109 lcd_init_display();
1110 lcd_left_shift = 0;
1111 processed = 1;
1112 break;
1113
1114 case 'G' : /* Generator : LGcxxxxx...xx; */ {
1115 /* must have <c> between '0' and '7', representing the numerical
1116 * ASCII code of the redefined character, and <xx...xx> a sequence
1117 * of 16 hex digits representing 8 bytes for each character. Most
1118 * LCDs will only use 5 lower bits of the 7 first bytes.
1119 */
1120
1121 unsigned char cgbytes[8];
1122 unsigned char cgaddr;
1123 int cgoffset;
1124 int shift;
1125 char value;
1126 int addr;
1127
1128 if (strchr(esc, ';') == NULL)
1129 break;
1130
1131 esc++;
1132
1133 cgaddr = *(esc++) - '0';
1134 if (cgaddr > 7) {
1135 processed = 1;
1136 break;
1137 }
1138
1139 cgoffset = 0;
1140 shift = 0;
1141 value = 0;
1142 while (*esc && cgoffset < 8) {
1143 shift ^= 4;
1144 if (*esc >= '0' && *esc <='9')
1145 value |= (*esc - '0') << shift;
1146 else if (*esc >= 'A' && *esc <='Z')
1147 value |= (*esc - 'A' + 10) << shift;
1148 else if (*esc >= 'a' && *esc <='z')
1149 value |= (*esc - 'a' + 10) << shift;
1150 else {
1151 esc++;
1152 continue;
1153 }
1154
1155 if (shift == 0) {
1156 cgbytes[cgoffset++] = value;
1157 value = 0;
1158 }
1159
1160 esc++;
1161 }
1162
1163 lcd_write_cmd(0x40 | (cgaddr * 8));
1164 for (addr = 0; addr < cgoffset; addr++) {
1165 lcd_write_data(cgbytes[addr]);
1166 }
1167
1168 lcd_gotoxy(); /* ensures that we stop writing to CGRAM */
1169 processed = 1;
1170 break;
1171 }
1172 case 'x' : /* gotoxy : LxXXX[yYYY]; */
1173 case 'y' : /* gotoxy : LyYYY[xXXX]; */
1174 if (strchr(esc, ';') == NULL)
1175 break;
1176
1177 while (*esc) {
1178 if (*esc == 'x') {
1179 esc++;
1180 lcd_addr_x = 0;
1181 while (isdigit(*esc)) {
1182 lcd_addr_x = lcd_addr_x*10 + (*esc - '0');
1183 esc++;
1184 }
1185 }
1186 else if (*esc == 'y') {
1187 esc++;
1188 lcd_addr_y = 0;
1189 while (isdigit(*esc)) {
1190 lcd_addr_y = lcd_addr_y*10 + (*esc - '0');
1191 esc++;
1192 }
1193 }
1194 else break;
1195 }
1196
1197 lcd_gotoxy();
1198 processed = 1;
1199 break;
1200 } /* end of switch */
1201
1202 /* Check wether one flag was changed */
1203 if (oldflags != lcd_flags) {
1204 /* check wether one of B,C,D flags was changed */
1205 if ((oldflags ^ lcd_flags) & (LCD_FLAG_B | LCD_FLAG_C | LCD_FLAG_D))
1206 lcd_write_cmd(0x08 /* set display mode */
1207 | ((lcd_flags & LCD_FLAG_D)?4:0)
1208 | ((lcd_flags & LCD_FLAG_C)?2:0)
1209 | ((lcd_flags & LCD_FLAG_B)?1:0)
1210 );
1211 /* check wether one of F,N flags was changed */
1212 else if ((oldflags ^ lcd_flags) & (LCD_FLAG_F | LCD_FLAG_N))
1213 lcd_write_cmd(0x30
1214 | ((lcd_flags & LCD_FLAG_F)?4:0)
1215 | ((lcd_flags & LCD_FLAG_N)?8:0)
1216 );
1217 /* check wether L flag was changed */
1218 else if ((oldflags ^ lcd_flags) & (LCD_FLAG_L)) {
1219 if (lcd_flags & (LCD_FLAG_L))
1220 lcd_backlight(1);
1221 else if (light_tempo == 0) /* switch off the light only when the tempo lighting is gone */
1222 lcd_backlight(0);
1223 }
1224 }
1225 } /* LCD special escape codes */
1226
1227 /* flush the escape sequence if it's been processed or if it is
1228 getting too long. */
1229 if (processed || (lcd_escape_len >= LCD_ESCAPE_LEN))
1230 lcd_escape_len = -1;
1231 } /* escape codes */
1232 }
1233
1234 return( tmp - buf );
1235}
1236
1237static int lcd_open( struct inode *inode, struct file *file ) {
1238 if (lcd_open_cnt)
1239 return( -EBUSY ); /* open only once at a time */
1240
1241 if (file->f_mode & FMODE_READ) /* device is write-only */
1242 return ( -EPERM );
1243
1244 if (lcd_must_clear) {
1245 lcd_clear_display();
1246 lcd_must_clear = 0;
1247 }
1248 lcd_open_cnt++;
1249 return( 0 );
1250}
1251
1252static int lcd_release( struct inode *inode, struct file *file ) {
1253 lcd_open_cnt--;
1254 return( 0 );
1255}
1256
1257
1258static struct file_operations lcd_fops = {
1259 write: lcd_write,
1260 open: lcd_open,
1261 release: lcd_release,
1262};
1263
1264static struct miscdevice lcd_dev = {
1265 LCD_MINOR,
1266 "lcd",
1267 &lcd_fops
1268};
1269
1270
1271
1272/* public function usable from the kernel for any purpose */
1273void panel_lcd_print(char *s) {
1274 if (lcd_enabled && lcd_initialized)
1275 lcd_write(NULL, s, strlen(s), NULL);
1276}
1277
1278
1279/* initialize the LCD driver */
1280void lcd_init(void) {
1281 switch (lcd_type) {
1282 case LCD_TYPE_OLD : /* parallel mode, 8 bits */
1283 if (lcd_proto < 0) lcd_proto = LCD_PROTO_PARALLEL;
1284 if (lcd_charset < 0) lcd_charset = LCD_CHARSET_NORMAL;
1285 if (lcd_e_pin == PIN_NOT_SET) lcd_e_pin = PIN_STROBE;
1286 if (lcd_rs_pin == PIN_NOT_SET) lcd_rs_pin = PIN_AUTOLF;
1287
1288 if (lcd_width < 0) lcd_width = 40;
1289 if (lcd_bwidth < 0) lcd_bwidth = 40;
1290 if (lcd_hwidth < 0) lcd_hwidth = 64;
1291 if (lcd_height < 0) lcd_height = 2;
1292 break;
1293 case LCD_TYPE_KS0074 : /* serial mode, ks0074 */
1294 if (lcd_proto < 0) lcd_proto = LCD_PROTO_SERIAL;
1295 if (lcd_charset < 0) lcd_charset = LCD_CHARSET_KS0074;
1296 if (lcd_bl_pin == PIN_NOT_SET) lcd_bl_pin = PIN_AUTOLF;
1297 if (lcd_cl_pin == PIN_NOT_SET) lcd_cl_pin = PIN_STROBE;
1298 if (lcd_da_pin == PIN_NOT_SET) lcd_da_pin = PIN_D0;
1299
1300 if (lcd_width < 0) lcd_width = 16;
1301 if (lcd_bwidth < 0) lcd_bwidth = 40;
1302 if (lcd_hwidth < 0) lcd_hwidth = 16;
1303 if (lcd_height < 0) lcd_height = 2;
1304 break;
1305 case LCD_TYPE_NEXCOM : /* parallel mode, 8 bits, generic */
1306 if (lcd_proto < 0) lcd_proto = LCD_PROTO_PARALLEL;
1307 if (lcd_charset < 0) lcd_charset = LCD_CHARSET_NORMAL;
1308 if (lcd_e_pin == PIN_NOT_SET) lcd_e_pin = PIN_AUTOLF;
1309 if (lcd_rs_pin == PIN_NOT_SET) lcd_rs_pin = PIN_SELECP;
1310 if (lcd_rw_pin == PIN_NOT_SET) lcd_rw_pin = PIN_INITP;
1311
1312 if (lcd_width < 0) lcd_width = 16;
1313 if (lcd_bwidth < 0) lcd_bwidth = 40;
1314 if (lcd_hwidth < 0) lcd_hwidth = 64;
1315 if (lcd_height < 0) lcd_height = 2;
1316 break;
1317 case LCD_TYPE_CUSTOM : /* customer-defined */
1318 if (lcd_proto < 0) lcd_proto = DEFAULT_LCD_PROTO;
1319 if (lcd_charset < 0) lcd_charset = DEFAULT_LCD_CHARSET;
1320 /* default geometry will be set later */
1321 break;
1322 case LCD_TYPE_HANTRONIX : /* parallel mode, 8 bits, hantronix-like */
1323 default :
1324 if (lcd_proto < 0) lcd_proto = LCD_PROTO_PARALLEL;
1325 if (lcd_charset < 0) lcd_charset = LCD_CHARSET_NORMAL;
1326 if (lcd_e_pin == PIN_NOT_SET) lcd_e_pin = PIN_STROBE;
1327 if (lcd_rs_pin == PIN_NOT_SET) lcd_rs_pin = PIN_SELECP;
1328
1329 if (lcd_width < 0) lcd_width = 16;
1330 if (lcd_bwidth < 0) lcd_bwidth = 40;
1331 if (lcd_hwidth < 0) lcd_hwidth = 64;
1332 if (lcd_height < 0) lcd_height = 2;
1333 break;
1334 }
1335
1336 /* this is used to catch wrong and default values */
1337 if (lcd_width <= 0) lcd_width = DEFAULT_LCD_WIDTH;
1338 if (lcd_bwidth <= 0) lcd_bwidth = DEFAULT_LCD_BWIDTH;
1339 if (lcd_hwidth <= 0) lcd_hwidth = DEFAULT_LCD_HWIDTH;
1340 if (lcd_height <= 0) lcd_height = DEFAULT_LCD_HEIGHT;
1341
1342 if (lcd_proto == LCD_PROTO_SERIAL) { /* SERIAL */
1343 lcd_write_cmd = lcd_write_cmd_s;
1344 lcd_write_data = lcd_write_data_s;
1345 lcd_clear_fast = lcd_clear_fast_s;
1346
1347 if (lcd_cl_pin == PIN_NOT_SET)
1348 lcd_cl_pin = DEFAULT_LCD_PIN_SCL;
1349 if (lcd_da_pin == PIN_NOT_SET)
1350 lcd_da_pin = DEFAULT_LCD_PIN_SDA;
1351
1352 } else { /* PARALLEL */
1353 lcd_write_cmd = lcd_write_cmd_p8;
1354 lcd_write_data = lcd_write_data_p8;
1355 lcd_clear_fast = lcd_clear_fast_p8;
1356
1357 if (lcd_e_pin == PIN_NOT_SET)
1358 lcd_e_pin = DEFAULT_LCD_PIN_E;
1359 if (lcd_rs_pin == PIN_NOT_SET)
1360 lcd_rs_pin = DEFAULT_LCD_PIN_RS;
1361 if (lcd_rw_pin == PIN_NOT_SET)
1362 lcd_rw_pin = DEFAULT_LCD_PIN_RW;
1363 }
1364
1365 if (lcd_bl_pin == PIN_NOT_SET)
1366 lcd_bl_pin = DEFAULT_LCD_PIN_BL;
1367
1368 if (lcd_e_pin == PIN_NOT_SET) lcd_e_pin = PIN_NONE;
1369 if (lcd_rs_pin == PIN_NOT_SET) lcd_rs_pin = PIN_NONE;
1370 if (lcd_rw_pin == PIN_NOT_SET) lcd_rw_pin = PIN_NONE;
1371 if (lcd_bl_pin == PIN_NOT_SET) lcd_bl_pin = PIN_NONE;
1372 if (lcd_cl_pin == PIN_NOT_SET) lcd_cl_pin = PIN_NONE;
1373 if (lcd_da_pin == PIN_NOT_SET) lcd_da_pin = PIN_NONE;
1374
1375 if (lcd_charset < 0)
1376 lcd_charset = DEFAULT_LCD_CHARSET;
1377
1378 if (lcd_charset == LCD_CHARSET_KS0074)
1379 lcd_char_conv = lcd_char_conv_ks0074;
1380 else
1381 lcd_char_conv = NULL;
1382
1383 if (lcd_bl_pin != PIN_NONE)
1384 init_scan_timer();
1385
1386 pin_to_bits(lcd_e_pin, lcd_bits[LCD_PORT_D][LCD_BIT_E], lcd_bits[LCD_PORT_C][LCD_BIT_E]);
1387 pin_to_bits(lcd_rs_pin, lcd_bits[LCD_PORT_D][LCD_BIT_RS], lcd_bits[LCD_PORT_C][LCD_BIT_RS]);
1388 pin_to_bits(lcd_rw_pin, lcd_bits[LCD_PORT_D][LCD_BIT_RW], lcd_bits[LCD_PORT_C][LCD_BIT_RW]);
1389 pin_to_bits(lcd_bl_pin, lcd_bits[LCD_PORT_D][LCD_BIT_BL], lcd_bits[LCD_PORT_C][LCD_BIT_BL]);
1390 pin_to_bits(lcd_cl_pin, lcd_bits[LCD_PORT_D][LCD_BIT_CL], lcd_bits[LCD_PORT_C][LCD_BIT_CL]);
1391 pin_to_bits(lcd_da_pin, lcd_bits[LCD_PORT_D][LCD_BIT_DA], lcd_bits[LCD_PORT_C][LCD_BIT_DA]);
1392
1393 /* before this line, we must NOT send anything to the display.
1394 * Since lcd_init_display() needs to write data, we have to
1395 * enable mark the LCD initialized just before.
1396 */
1397 lcd_initialized = 1;
1398 lcd_init_display();
1399
1400 /* display a short message */
1401#ifdef CONFIG_PANEL_CHANGE_MESSAGE
1402#ifdef CONFIG_PANEL_BOOT_MESSAGE
1403 panel_lcd_print("\x1b[Lc\x1b[Lb\x1b[L*" CONFIG_PANEL_BOOT_MESSAGE);
1404#endif
1405#else
1406 panel_lcd_print("\x1b[Lc\x1b[Lb\x1b[L*Linux-" UTS_RELEASE "\nPanel-" PANEL_VERSION);
1407#endif
1408 lcd_addr_x = lcd_addr_y = 0;
1409 lcd_must_clear = 1; /* clear the display on the next device opening */
1410 lcd_gotoxy();
1411}
1412
1413
1414/*
1415 * These are the file operation function for user access to /dev/keypad
1416 */
1417
1418static ssize_t keypad_read(struct file * file,
1419 char * buf, size_t count, loff_t *ppos ) {
1420
1421 unsigned i = *ppos;
1422 char *tmp = buf;
1423
1424 if (keypad_buflen == 0) {
1425 if (file->f_flags & O_NONBLOCK)
1426 return -EAGAIN;
1427
1428 //printk(KERN_ERR "keypad_read():1 len=%d", keypad_buflen);
1429 interruptible_sleep_on(&keypad_read_wait);
1430 //printk(KERN_ERR "keypad_read():2 len=%d", keypad_buflen);
1431 if (signal_pending(current))
1432 return -EINTR;
1433 }
1434
1435 //printk(KERN_ERR "keypad_read():3 len=%d", keypad_buflen);
1436 for( ; count-- > 0 && (keypad_buflen > 0); ++i, ++tmp, --keypad_buflen ) {
1437 put_user( keypad_buffer[keypad_start], tmp );
1438 keypad_start = (keypad_start + 1) % KEYPAD_BUFFER;
1439 }
1440 *ppos = i;
1441 //printk(KERN_ERR "keypad_read():4 len=%d", keypad_buflen);
1442
1443 return( tmp - buf );
1444}
1445
1446
1447static int keypad_open( struct inode *inode, struct file *file ) {
1448
1449 if (keypad_open_cnt)
1450 return( -EBUSY ); /* open only once at a time */
1451
1452 if (file->f_mode & FMODE_WRITE) /* device is read-only */
1453 return ( -EPERM );
1454
1455 keypad_buflen = 0; /* flush the buffer on opening */
1456 keypad_open_cnt++;
1457 return( 0 );
1458}
1459
1460static int keypad_release( struct inode *inode, struct file *file ) {
1461 keypad_open_cnt--;
1462 return( 0 );
1463}
1464
1465static struct file_operations keypad_fops = {
1466 read: keypad_read, /* read */
1467 open: keypad_open, /* open */
1468 release: keypad_release, /* close */
1469};
1470
1471static struct miscdevice keypad_dev = {
1472 KEYPAD_MINOR,
1473 "keypad",
1474 &keypad_fops
1475};
1476
1477static void keypad_send_key(char *string, int max_len) {
1478 //printk(KERN_ERR "keypad_send_key(%c,%d):1\n", *string,max_len);
1479 if (init_in_progress)
1480 return;
1481 //printk(KERN_ERR "keypad_send_key(%c,%d):2\n", *string,max_len);
1482
1483 /* send the key to the device only if a process is attached to it. */
1484 if (keypad_open_cnt > 0) {
1485 //printk(KERN_ERR "keypad_send_key(%c,%d):3\n", *string,max_len);
1486 while (max_len-- && keypad_buflen < KEYPAD_BUFFER && *string) {
1487 keypad_buffer[(keypad_start + keypad_buflen++) % KEYPAD_BUFFER] = *string++;
1488 }
1489 //printk(KERN_ERR "keypad_send_key(%d):4\n", *string,max_len);
1490 wake_up_interruptible(&keypad_read_wait);
1491 }
1492 //printk(KERN_ERR "keypad_send_key(%d):5\n", *string,max_len);
1493}
1494
1495
1496/* this function scans all the bits involving at least one logical signal, and puts the
1497 * results in the bitfield "phys_read" (one bit per established contact), and sets
1498 * "phys_read_prev" to "phys_read".
1499 *
1500 * Note: to debounce input signals, we will only consider as switched a signal which is
1501 * stable across 2 measures. Signals which are different between two reads will be kept
1502 * as they previously were in their logical form (phys_prev). A signal which has just
1503 * switched will have a 1 in (phys_read ^ phys_read_prev).
1504 */
1505static void phys_scan_contacts(void) {
1506 int bit, bitval;
1507 char oldval;
1508 char bitmask;
1509 char gndmask;
1510
1511 phys_prev = phys_curr;
1512 phys_read_prev = phys_read;
1513 phys_read = 0; /* flush all signals */
1514
1515 oldval = r_dtr(pprt) | scan_mask_o; /* keep track of old value, with all outputs disabled */
1516 w_dtr(pprt, oldval & ~scan_mask_o); /* activate all keyboard outputs (active low) */
1517 bitmask = PNL_PINPUT(r_str(pprt)) & scan_mask_i; /* will have a 1 for each bit set to gnd */
1518 w_dtr(pprt, oldval); /* disable all matrix signals */
1519
1520 /* now that all outputs are cleared, the only active input bits are
1521 * directly connected to the ground
1522 */
1523 gndmask = PNL_PINPUT(r_str(pprt)) & scan_mask_i; /* 1 for each grounded input */
1524
1525 phys_read |= (pmask_t)gndmask << 40; /* grounded inputs are signals 40-44 */
1526
1527 if (bitmask != gndmask) {
1528 /* since clearing the outputs changed some inputs, we know that some
1529 * input signals are currently tied to some outputs. So we'll scan them.
1530 */
1531 for (bit = 0; bit < 8; bit ++) {
1532 bitval = 1 << bit;
1533
1534 if (!(scan_mask_o & bitval)) /* skip unused bits */
1535 continue;
1536
1537 w_dtr(pprt, oldval & ~bitval); /* enable this output */
1538 bitmask = PNL_PINPUT(r_str(pprt)) & ~gndmask;
1539 phys_read |= (pmask_t) bitmask << (5*bit);
1540 }
1541 w_dtr(pprt, oldval); /* disable all outputs */
1542 }
1543 /* this is easy: use old bits when they are flapping, use new ones when stable */
1544 phys_curr = (phys_prev & (phys_read ^ phys_read_prev)) | (phys_read & ~(phys_read ^ phys_read_prev));
1545}
1546
1547static void panel_process_inputs(void) {
1548 struct list_head *item;
1549 struct logical_input *input;
1550
1551#if 0
1552 printk(KERN_DEBUG "entering panel_process_inputs with pp=%016Lx & pc=%016Lx\n",
1553 phys_prev, phys_curr);
1554#endif
1555
1556 keypressed = 0;
1557 inputs_stable = 1;
1558 list_for_each(item, &logical_inputs) {
1559 input = list_entry(item, struct logical_input, list);
1560
1561 switch (input->state) {
1562 case INPUT_ST_LOW:
1563 if ((phys_curr & input->mask) != input->value)
1564 break;
1565 /* if all needed ones were already set previously, this means that
1566 * this logical signal has been activated by the releasing of
1567 * another combined signal, so we don't want to match.
1568 * eg: AB -(release B)-> A -(release A)-> 0 : don't match A.
1569 */
1570 if ((phys_prev & input->mask) == input->value)
1571 break;
1572 input->rise_timer = 0;
1573 input->state = INPUT_ST_RISING;
1574 /* no break here, fall through */
1575 case INPUT_ST_RISING:
1576 if ((phys_curr & input->mask) != input->value) {
1577 input->state = INPUT_ST_LOW;
1578 break;
1579 }
1580 if (input->rise_timer < input->rise_time) {
1581 inputs_stable = 0;
1582 input->rise_timer++;
1583 break;
1584 }
1585 input->high_timer = 0;
1586 input->state = INPUT_ST_HIGH;
1587 /* no break here, fall through */
1588 case INPUT_ST_HIGH:
1589#if 0
1590 /* FIXME:
1591 * this is an invalid test. It tries to catch transitions from single-key
1592 * to multiple-key, but doesn't take into account the contacts polarity.
1593 * The only solution to the problem is to parse keys from the most complex
1594 * to the simplest combinations, and mark them as 'caught' once a combination
1595 * matches, then unmatch it for all other ones.
1596 */
1597
1598 /* try to catch dangerous transitions cases :
1599 * someone adds a bit, so this signal was a false
1600 * positive resulting from a transition. We should invalidate
1601 * the signal immediately and not call the release function.
1602 * eg: 0 -(press A)-> A -(press B)-> AB : don't match A's release.
1603 */
1604 if (((phys_prev & input->mask) == input->value)
1605 && ((phys_curr & input->mask) > input->value)) {
1606 input->state = INPUT_ST_LOW; /* invalidate */
1607 break;
1608 }
1609 //else
1610#endif
1611
1612 if ((phys_curr & input->mask) == input->value) {
1613 if ((input->type == INPUT_TYPE_STD) && (input->high_timer == 0)) {
1614 input->high_timer++;
1615 if (input->u.std.press_fct != NULL)
1616 input->u.std.press_fct(input->u.std.press_data);
1617 }
1618 else if (input->type == INPUT_TYPE_KBD) {
1619 keypressed = 1; /* will turn on the light */
1620
1621 if (input->high_timer == 0) {
1622 if (input->u.kbd.press_str[0])
1623 keypad_send_key(input->u.kbd.press_str, sizeof(input->u.kbd.press_str));
1624 }
1625
1626 if (input->u.kbd.repeat_str[0]) {
1627 if (input->high_timer >= KEYPAD_REP_START) {
1628 input->high_timer -= KEYPAD_REP_DELAY;
1629 keypad_send_key(input->u.kbd.repeat_str, sizeof(input->u.kbd.repeat_str));
1630 }
1631 inputs_stable = 0; /* we will need to come back here soon */
1632 }
1633
1634 if (input->high_timer < 255) {
1635 input->high_timer++;
1636 }
1637 }
1638 break;
1639 }
1640 else {
1641 /* else signal falling down. Let's fall through. */
1642 input->state = INPUT_ST_FALLING;
1643 input->fall_timer = 0;
1644 }
1645 /* no break here, fall through */
1646 case INPUT_ST_FALLING:
1647#if 0
1648 /* FIXME !!! same comment as above */
1649 if (((phys_prev & input->mask) == input->value)
1650 && ((phys_curr & input->mask) > input->value)) {
1651 input->state = INPUT_ST_LOW; /* invalidate */
1652 break;
1653 }
1654 //else
1655#endif
1656
1657 if ((phys_curr & input->mask) == input->value) {
1658 if (input->type == INPUT_TYPE_KBD) {
1659 keypressed = 1; /* will turn on the light */
1660
1661 if (input->u.kbd.repeat_str[0]) {
1662 if (input->high_timer >= KEYPAD_REP_START)
1663 input->high_timer -= KEYPAD_REP_DELAY;
1664 keypad_send_key(input->u.kbd.repeat_str, sizeof(input->u.kbd.repeat_str));
1665 inputs_stable = 0; /* we will need to come back here soon */
1666 }
1667
1668 if (input->high_timer < 255) {
1669 input->high_timer++;
1670 }
1671 }
1672 input->state = INPUT_ST_HIGH;
1673 break;
1674 }
1675 else if (input->fall_timer >= input->fall_time) {
1676 /* call release event */
1677 if (input->type == INPUT_TYPE_STD) {
1678 if (input->u.std.release_fct != NULL)
1679 input->u.std.release_fct(input->u.std.release_data);
1680 }
1681 else if (input->type == INPUT_TYPE_KBD) {
1682 if (input->u.kbd.release_str[0])
1683 keypad_send_key(input->u.kbd.release_str, sizeof(input->u.kbd.release_str));
1684 }
1685
1686 input->state = INPUT_ST_LOW;
1687 break;
1688 }
1689 else {
1690 input->fall_timer++;
1691 inputs_stable = 0;
1692 break;
1693 }
1694 }
1695 }
1696}
1697
1698static void panel_scan_timer(void) {
1699 if ((keypad_enabled && keypad_initialized)
1700 || (smartcard_enabled && smartcard_enabled)) {
1701
1702 if (spin_trylock(&pprt_lock)) {
1703 phys_scan_contacts();
1704 spin_unlock(&pprt_lock); /* no need for the parport anymore */
1705 }
1706
1707 if (!inputs_stable || phys_curr != phys_prev) {
1708 panel_process_inputs();
1709 }
1710 }
1711
1712 if (lcd_enabled && lcd_initialized) {
1713 if (keypressed) {
1714 if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0))
1715 lcd_backlight(1);
1716 light_tempo = FLASH_LIGHT_TEMPO;
1717 }
1718 else if (light_tempo > 0) {
1719 light_tempo--;
1720 if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0))
1721 lcd_backlight(0);
1722 }
1723 }
1724
1725 mod_timer(&scan_timer, jiffies + INPUT_POLL_TIME);
1726}
1727
1728/* send a high / low clock impulse of <duration> microseconds high and low */
1729static void smartcard_send_clock(int duration) {
1730 int old;
1731
1732 w_dtr(pprt, (old = r_dtr(pprt)) | PNL_SC_CLK);
1733 udelay(duration);
1734 w_dtr(pprt, (old & ~PNL_SC_CLK));
1735 udelay(duration);
1736}
1737
1738static void smartcard_insert(int dummy) {
1739 int ofs;
1740
1741 spin_lock(&pprt_lock);
1742 w_dtr(pprt, (r_dtr(pprt) & ~PNL_SC_BITS));
1743 w_ctr(pprt, (r_ctr(pprt) | PNL_SC_ENA));
1744
1745 udelay(30); /* ensure the rst is low at least 30 us */
1746
1747 smartcard_send_clock(100); /* reset address counter */
1748
1749 w_dtr(pprt, r_dtr(pprt) | PNL_SC_RST);
1750 udelay(30); /* ensure the rst is high at least 30 us */
1751
1752 for (ofs = 0; ofs < SMARTCARD_BYTES; ofs++) {
1753 int bit, byte;
1754 byte = 0;
1755 for (bit = 128; bit > 0; bit >>= 1) {
1756 if (!(r_str(pprt) & PNL_SC_IOR))
1757 byte |= bit;
1758 smartcard_send_clock(15); /* 15 us are enough for data */
1759 }
1760 smartcard_data[ofs] = byte;
1761 }
1762
1763 w_dtr(pprt, (r_dtr(pprt) & ~PNL_SC_BITS));
1764 w_ctr(pprt, (r_ctr(pprt) & ~PNL_SC_ENA));
1765
1766 spin_unlock(&pprt_lock);
1767
1768 printk(KERN_INFO "Panel: smart card inserted : %02x%02x%02x%02x%1x\n",
1769 smartcard_data[2], smartcard_data[3], smartcard_data[4],
1770 smartcard_data[5], smartcard_data[6] >> 4);
1771 keypad_send_key("CardIn\n", 7);
1772}
1773
1774static void smartcard_remove(int dummy) {
1775 printk(KERN_INFO "Panel: smart card removed : %02x%02x%02x%02x%1x\n",
1776 smartcard_data[2], smartcard_data[3], smartcard_data[4],
1777 smartcard_data[5], smartcard_data[6] >> 4);
1778 memset(smartcard_data, 0, sizeof(smartcard_data));
1779 keypad_send_key("CardOut\n", 8);
1780}
1781
1782/*
1783 * These are the file operation function for user access to /dev/smartcard
1784 */
1785
1786static ssize_t smartcard_read(struct file * file,
1787 char * buf, size_t count, loff_t *ppos ) {
1788
1789 unsigned i = *ppos;
1790 char *tmp = buf;
1791
1792 for( ; count-- > 0 && (smartcard_ptr < 9); ++i, ++tmp, ++smartcard_ptr ) {
1793 if (smartcard_ptr & 1)
1794 put_user( '0' + (smartcard_data[2 + (smartcard_ptr >> 1)] & 0xF), tmp );
1795 else
1796 put_user( '0' + (smartcard_data[2 + (smartcard_ptr >> 1)] >> 4), tmp );
1797 }
1798 *ppos = i;
1799
1800 return( tmp - buf );
1801}
1802
1803
1804static int smartcard_open( struct inode *inode, struct file *file ) {
1805
1806 if (smartcard_open_cnt)
1807 return( -EBUSY ); /* open only once at a time */
1808
1809 if (file->f_mode & FMODE_WRITE) /* device is read-only */
1810 return ( -EPERM );
1811
1812 smartcard_ptr = 0; /* flush the buffer on opening */
1813 smartcard_open_cnt++;
1814 return( 0 );
1815}
1816
1817static int smartcard_release( struct inode *inode, struct file *file ) {
1818 smartcard_open_cnt--;
1819 return( 0 );
1820}
1821
1822static struct file_operations smartcard_fops = {
1823 read: smartcard_read, /* read */
1824 open: smartcard_open, /* open */
1825 release: smartcard_release, /* close */
1826};
1827
1828static struct miscdevice smartcard_dev = {
1829 SMARTCARD_MINOR,
1830 "smartcard",
1831 &smartcard_fops
1832};
1833
1834static void init_scan_timer(void) {
1835 if (scan_timer.function != NULL)
1836 return; /* already started */
1837
1838 init_timer(&scan_timer);
1839 scan_timer.expires = jiffies + INPUT_POLL_TIME;
1840 scan_timer.data = 0;
1841 scan_timer.function = (void *)&panel_scan_timer;
1842 add_timer(&scan_timer);
1843}
1844
1845/* converts a name of the form "({BbAaPpSsEe}{01234567-})*" to a series of bits.
1846 * if <omask> or <imask> are non-null, they will be or'ed with the bits corresponding
1847 * to out and in bits respectively.
1848 * returns 1 if ok, 0 if error (in which case, nothing is written).
1849 */
1850static int input_name2mask(char *name, pmask_t *mask, pmask_t *value, char *imask, char *omask) {
1851 static char sigtab[10]="EeSsPpAaBb";
1852 char im, om;
1853 pmask_t m, v;
1854
1855 om = im = m = v = 0ULL;
1856 while (*name) {
1857 int in, out, bit, neg;
1858 for (in = 0; (in < sizeof(sigtab)) && (sigtab[in] != *name); in++);
1859 if (in >= sizeof(sigtab))
1860 return 0; /* input name not found */
1861 neg = (in & 1); /* odd (lower) names are negated */
1862 in >>= 1;
1863 im |= (1 << in);
1864
1865 name++;
1866 if (isdigit(*name)) {
1867 out = *name - '0';
1868 om |= (1 << out);
1869 }
1870 else if (*name == '-')
1871 out = 8;
1872 else
1873 return 0; /* unknown bit name */
1874
1875 bit = (out * 5) + in;
1876
1877 m |= 1ULL << bit;
1878 if (!neg)
1879 v |= 1ULL << bit;
1880 name++;
1881 }
1882 *mask = m;
1883 *value = v;
1884 if (imask)
1885 *imask |= im;
1886 if (omask)
1887 *omask |= om;
1888 return 1;
1889}
1890
1891/* tries to bind a key to the signal name <name>. The key will send the
1892 * strings <press>, <repeat>, <release> for these respective events.
1893 * Returns the pointer to the new key if ok, NULL if the key could not be bound.
1894 */
1895static struct logical_input *panel_bind_key(char *name, char *press, char *repeat, char *release) {
1896 struct logical_input *key;
1897
1898 key = (struct logical_input*)kmalloc(sizeof(struct logical_input), GFP_KERNEL);
1899 if (!key) {
1900 printk(KERN_ERR "panel: not enough memory\n");
1901 return NULL;
1902 }
1903 memset(key, 0, sizeof(struct logical_input));
1904 if (!input_name2mask(name, &key->mask, &key->value, &scan_mask_i, &scan_mask_o))
1905 return NULL;
1906 key->type = INPUT_TYPE_KBD;
1907 key->state = INPUT_ST_LOW;
1908 key->rise_time = 1;
1909 key->fall_time = 1;
1910
1911#if 0
1912 printk(KERN_DEBUG "bind: <%s> : m=%016Lx v=%016Lx\n", name, key->mask, key->value);
1913#endif
1914 strncpy(key->u.kbd.press_str, press, sizeof(key->u.kbd.press_str));
1915 strncpy(key->u.kbd.repeat_str, repeat, sizeof(key->u.kbd.repeat_str));
1916 strncpy(key->u.kbd.release_str, release, sizeof(key->u.kbd.release_str));
1917 list_add(&key->list, &logical_inputs);
1918 return key;
1919}
1920
1921/* tries to bind a callback function to the signal name <name>. The function
1922 * <press_fct> will be called with the <press_data> arg when the signal is
1923 * activated, and so on for <release_fct>/<release_data>
1924 * Returns the pointer to the new signal if ok, NULL if the signal could not be bound.
1925 */
1926static struct logical_input *panel_bind_callback(char *name,
1927 void (*press_fct)(int), int press_data,
1928 void (*release_fct)(int), int release_data) {
1929 struct logical_input *callback;
1930
1931 callback = (struct logical_input*)kmalloc(sizeof(struct logical_input), GFP_KERNEL);
1932 if (!callback) {
1933 printk(KERN_ERR "panel: not enough memory\n");
1934 return NULL;
1935 }
1936 memset(callback, 0, sizeof(struct logical_input));
1937 if (!input_name2mask(name, &callback->mask, &callback->value, &scan_mask_i, &scan_mask_o))
1938 return NULL;
1939 callback->type = INPUT_TYPE_STD;
1940 callback->state = INPUT_ST_LOW;
1941 callback->rise_time = 1;
1942 callback->fall_time = 1;
1943 callback->u.std.press_fct = press_fct;
1944 callback->u.std.press_data = press_data;
1945 callback->u.std.release_fct = release_fct;
1946 callback->u.std.release_data = release_data;
1947 list_add(&callback->list, &logical_inputs);
1948 return callback;
1949}
1950
1951static void keypad_init(void) {
1952 int keynum;
1953 init_waitqueue_head(&keypad_read_wait);
1954 keypad_buflen = 0; /* flushes any eventual noisy keystroke */
1955
1956 /* Let's create all known keys */
1957
1958 for (keynum = 0; keypad_profile[keynum][0][0]; keynum++) {
1959 panel_bind_key(keypad_profile[keynum][0],
1960 keypad_profile[keynum][1],
1961 keypad_profile[keynum][2],
1962 keypad_profile[keynum][3]);
1963 }
1964
1965 init_scan_timer();
1966 keypad_initialized = 1;
1967}
1968
1969
1970static void smartcard_init(void) {
1971 init_waitqueue_head(&smartcard_read_wait);
1972
1973 panel_bind_callback(SMARTCARD_LOGICAL_DETECTOR, &smartcard_insert, 0, &smartcard_remove, 0);
1974 init_scan_timer();
1975 smartcard_enabled = 1;
1976}
1977
1978
1979/**************************************************/
1980/* device initialization */
1981/**************************************************/
1982
1983#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
1984#define INIT_FUNC static int __init panel_init_module
1985#define CLEANUP_FUNC static void __exit panel_cleanup_module
1986#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1987#define INIT_FUNC static int __init panel_init_module
1988#define CLEANUP_FUNC static void panel_cleanup_module
1989#else
1990#define INIT_FUNC int init_module
1991#define CLEANUP_FUNC int cleanup_module
1992#endif
1993
1994#ifndef MODULE
1995/* called when compiled into the kernel */
1996#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1997static int __init panel_setup(char *str)
1998#else
1999__initfunc(void panel_setup(char *str, int *ints))
2000#endif
2001{
2002 int dummy;
2003 int *where;
2004 int helpdisplayed = 0;
2005
2006 if (!str)
2007 return 0;
2008
2009 while (*str) {
2010 where = NULL;
2011
2012 /* let's parse each of the command line parameters of the following form :
2013 panel=[parport:x],[lcd_height:x],[lcd_width:x],[lcd_bwidth:x],[lcd_hwidth:x]
2014 */
2015 if (!strncmp(str, "parport:", 8)) {
2016 str += 8;
2017 where = &parport;
2018 }
2019 else if (!strncmp(str, "disabled", 8)) {
2020 return 0;
2021 }
2022 else if (!strncmp(str, "lcd_height:", 11)) {
2023 str += 11;
2024 where = &lcd_height;
2025 }
2026 else if (!strncmp(str, "lcd_width:", 10)) {
2027 str += 10;
2028 where = &lcd_width;
2029 }
2030 else if (!strncmp(str, "lcd_bwidth:", 11)) {
2031 str += 11;
2032 where = &lcd_bwidth;
2033 }
2034 else if (!strncmp(str, "lcd_hwidth:", 11)) {
2035 str += 11;
2036 where = &lcd_hwidth;
2037 }
2038 else if (!strncmp(str, "lcd_enabled:", 12)) {
2039 str += 12;
2040 where = &lcd_enabled;
2041 }
2042 else if (!strncmp(str, "keypad_enabled:", 15)) {
2043 str += 15;
2044 where = &keypad_enabled;
2045 }
2046 else if (!strncmp(str, "smartcard_enabled:", 18)) {
2047 str += 18;
2048 where = &smartcard_enabled;
2049 }
2050 else if (!strncmp(str, "profile:", 8)) {
2051 str += 8;
2052 where = &profile;
2053 }
2054 else if (!helpdisplayed) {
2055 helpdisplayed = 1;
2056 printk(KERN_ERR "Panel version " PANEL_VERSION ": invalid argument. Known arguments are :\n"
2057 " parport:, lcd_{height,width,bwidth,enabled}:, keypad_enabled:\n");
2058 }
2059
2060 /* see if we need to read a number */
2061 if (where != NULL) {
2062 dummy = 0;
2063 while (isdigit(*str)) {
2064 dummy = (dummy*10) + (*str - '0');
2065 str++;
2066 }
2067 *where = dummy;
2068 }
2069
2070 /* look for next arg */
2071 while (*str && (*str != ','))
2072 str++;
2073 while (*str == ',')
2074 str++;
2075 }
2076 return 1;
2077}
2078
2079#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2080__setup("panel=", panel_setup );
2081#else
2082__setup("panel", panel_setup );
2083#endif
2084
2085#endif /* !MODULE */
2086
2087static int panel_notify_sys(struct notifier_block *this, unsigned long code, void *unused) {
2088 if (lcd_enabled && lcd_initialized) {
2089 switch(code) {
2090 case SYS_DOWN:
2091 panel_lcd_print("\x0cReloading\nSystem...\x1b[Lc\x1b[Lb\x1b[L+");
2092 break;
2093 case SYS_HALT:
2094 panel_lcd_print("\x0cSystem Halted.\x1b[Lc\x1b[Lb\x1b[L+");
2095 break;
2096 case SYS_POWER_OFF:
2097 panel_lcd_print("\x0cPower off.\x1b[Lc\x1b[Lb\x1b[L+");
2098 break;
2099 default:
2100 break;
2101 }
2102 }
2103 return NOTIFY_DONE;
2104}
2105
2106static struct notifier_block panel_notifier = {
2107 panel_notify_sys,
2108 NULL,
2109 0
2110};
2111
2112
2113static void panel_attach (struct parport *port)
2114{
2115 if (port->number != parport)
2116 return;
2117
2118 if (pprt) {
2119 printk(KERN_ERR "panel_attach(): port->number=%d parport=%d, already registered !\n", port->number, parport);
2120 return;
2121 }
2122
2123 pprt = parport_register_device(port, "panel",
2124 NULL, NULL, /* pf, kf */
2125 NULL,
2126 /*PARPORT_DEV_EXCL*/
2127 0,
2128 (void *)&pprt);
2129
2130 if (parport_claim(pprt)) {
2131 printk(KERN_ERR "Panel: could not claim access to parport%d. Aborting.\n", parport);
2132 //parport_unregister_device(pprt);
2133 //parport_unregister_driver(&panel_driver);
2134 //return -EIO;
2135 return;
2136 }
2137
2138 /* turns IRQ off */
2139 // port->ops->disable_irq(port);
2140
2141 /* must init LCD first, just in case an IRQ from the keypad is generated at keypad init */
2142 if (lcd_enabled) {
2143 lcd_init();
2144 misc_register( &lcd_dev );
2145 }
2146
2147 if (keypad_enabled) {
2148 keypad_init();
2149 misc_register( &keypad_dev );
2150 }
2151
2152 if (smartcard_enabled) {
2153 smartcard_init();
2154 misc_register( &smartcard_dev );
2155 }
2156}
2157
2158static void panel_detach (struct parport *port)
2159{
2160 if (port->number != parport)
2161 return;
2162
2163 if (!pprt) {
2164 printk(KERN_ERR "panel_detach(): port->number=%d parport=%d, nothing to unregister.\n",
2165 port->number, parport);
2166 return;
2167 }
2168
2169 if (smartcard_enabled && smartcard_initialized) {
2170 misc_deregister( &smartcard_dev );
2171 }
2172
2173 if (keypad_enabled && keypad_initialized) {
2174 misc_deregister( &keypad_dev );
2175 }
2176
2177 if (lcd_enabled && lcd_initialized) {
2178 misc_deregister( &lcd_dev );
2179 }
2180
2181 parport_release(pprt);
2182 parport_unregister_device(pprt);
2183 pprt = NULL;
2184}
2185
2186static struct parport_driver panel_driver = {
2187 .name = "panel",
2188 .attach = panel_attach,
2189 .detach = panel_detach,
2190};
2191
2192/* init function */
2193int panel_init (void) {
2194 /* for backwards compatibility */
2195 if (keypad_type < 0)
2196 keypad_type = keypad_enabled;
2197
2198 if (lcd_type < 0)
2199 lcd_type = lcd_enabled;
2200
2201 if (parport < 0)
2202 parport = DEFAULT_PARPORT;
2203
2204 /* take care of an eventual profile */
2205 switch (profile) {
2206 case PANEL_PROFILE_CUSTOM: /* custom profile */
2207 if (keypad_type < 0) keypad_type = DEFAULT_KEYPAD;
2208 if (smartcard_enabled < 0) smartcard_enabled = DEFAULT_SMARTCARD;
2209 if (lcd_type < 0) lcd_type = DEFAULT_LCD;
2210 break;
2211 case PANEL_PROFILE_OLD: /* 8 bits, 2*16, old keypad */
2212 if (keypad_type < 0) keypad_type = KEYPAD_TYPE_OLD;
2213 if (smartcard_enabled < 0) smartcard_enabled = 0;
2214 if (lcd_type < 0) lcd_type = LCD_TYPE_OLD;
2215 if (lcd_width < 0) lcd_width = 16;
2216 if (lcd_hwidth < 0) lcd_hwidth = 16;
2217 break;
2218 case PANEL_PROFILE_NEW: /* serial, 2*16, new keypad */
2219 if (keypad_type < 0) keypad_type = KEYPAD_TYPE_NEW;
2220 if (smartcard_enabled < 0) smartcard_enabled = 1;
2221 if (lcd_type < 0) lcd_type = LCD_TYPE_KS0074;
2222 break;
2223 case PANEL_PROFILE_HANTRONIX: /* 8 bits, 2*16 hantronix-like, no keypad */
2224 if (keypad_type < 0) keypad_type = KEYPAD_TYPE_NONE;
2225 if (smartcard_enabled < 0) smartcard_enabled = 0;
2226 if (lcd_type < 0) lcd_type = LCD_TYPE_HANTRONIX;
2227 break;
2228 case PANEL_PROFILE_NEXCOM: /* generic 8 bits, 2*16, nexcom keypad, eg. Nexcom. */
2229 if (keypad_type < 0) keypad_type = KEYPAD_TYPE_NEXCOM;
2230 if (smartcard_enabled < 0) smartcard_enabled = 0;
2231 if (lcd_type < 0) lcd_type = LCD_TYPE_NEXCOM;
2232 break;
2233 case PANEL_PROFILE_LARGE: /* 8 bits, 2*40, old keypad */
2234 if (keypad_type < 0) keypad_type = KEYPAD_TYPE_OLD;
2235 if (smartcard_enabled < 0) smartcard_enabled = 0;
2236 if (lcd_type < 0) lcd_type = LCD_TYPE_OLD;
2237 break;
2238 }
2239
2240 lcd_enabled = (lcd_type > 0);
2241 keypad_enabled = (keypad_type > 0);
2242
2243 switch (keypad_type) {
2244 case KEYPAD_TYPE_OLD:
2245 keypad_profile = old_keypad_profile;
2246 break;
2247 case KEYPAD_TYPE_NEW:
2248 keypad_profile = new_keypad_profile;
2249 break;
2250 case KEYPAD_TYPE_NEXCOM:
2251 keypad_profile = nexcom_keypad_profile;
2252 break;
2253 default:
2254 keypad_profile = NULL;
2255 break;
2256 }
2257
2258 /* tells various subsystems about the fact that we are initializing */
2259 init_in_progress = 1;
2260
2261 if (parport_register_driver(&panel_driver)) {
2262 printk(KERN_ERR "Panel: could not register with parport. Aborting.\n");
2263 return -EIO;
2264 }
2265
2266 // The parport can be asynchronously registered later.
2267 //if (pprt == NULL) {
2268 // printk(KERN_ERR "Panel: could not register parport%d. Aborting.\n", parport);
2269 // parport_unregister_driver(&panel_driver);
2270 // return -ENODEV; /* port not found */
2271 //}
2272
2273
2274 if (!lcd_enabled && !keypad_enabled && !smartcard_enabled) { /* no device enabled, let's release the parport */
2275 if (pprt) {
2276 parport_release(pprt);
2277 parport_unregister_device(pprt);
2278 }
2279 parport_unregister_driver(&panel_driver);
2280 printk(KERN_ERR "Panel driver version " PANEL_VERSION " disabled.\n");
2281 return -ENODEV;
2282 }
2283
2284 register_reboot_notifier(&panel_notifier);
2285
2286 if (pprt)
2287 printk(KERN_INFO "Panel driver version " PANEL_VERSION " registered on parport%d (io=0x%lx).\n",
2288 parport, pprt->port->base);
2289 else
2290 printk(KERN_INFO "Panel driver version " PANEL_VERSION " not yet registered\n");
2291 /* tells various subsystems about the fact that initialization is finished */
2292 init_in_progress = 0;
2293 return 0;
2294}
2295
2296
2297#if defined(MODULE) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))
2298INIT_FUNC (void) {
2299 return panel_init();
2300}
2301
2302CLEANUP_FUNC (void) {
2303 unregister_reboot_notifier(&panel_notifier);
2304
2305 if (scan_timer.function != NULL) {
2306 del_timer(&scan_timer);
2307 }
2308
2309 if (keypad_enabled) {
2310 misc_deregister( &keypad_dev );
2311 }
2312
2313 if (smartcard_enabled) {
2314 misc_deregister( &smartcard_dev );
2315 }
2316
2317 if (lcd_enabled) {
2318 panel_lcd_print("\x0cLCD driver " PANEL_VERSION "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-");
2319 misc_deregister( &lcd_dev );
2320 }
2321
2322 /* TODO: free all input signals */
2323
2324 parport_release(pprt);
2325 parport_unregister_device(pprt);
2326 parport_unregister_driver(&panel_driver);
2327}
2328#endif
2329
2330#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2331module_init(panel_init_module);
2332module_exit(panel_cleanup_module);
2333MODULE_AUTHOR("Willy Tarreau");
2334MODULE_LICENSE("GPL");
2335#endif
2336
2337/*
2338 * Local variables:
2339 * c-indent-level: 4
2340 * tab-width: 8
2341 * End:
2342 */
2343