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