1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37#include <linux/module.h>
38
39#include <linux/types.h>
40#include <linux/errno.h>
41#include <linux/signal.h>
42#include <linux/sched.h>
43#include <linux/spinlock.h>
44#include <linux/smp_lock.h>
45#include <linux/interrupt.h>
46#include <linux/miscdevice.h>
47#include <linux/slab.h>
48#include <linux/ioport.h>
49#include <linux/fcntl.h>
50#include <linux/init.h>
51#include <linux/delay.h>
52#include <linux/ctype.h>
53#include <linux/parport.h>
54#include <linux/version.h>
55#include <linux/list.h>
56#include <linux/notifier.h>
57#include <linux/reboot.h>
58#include <linux/utsrelease.h>
59
60#include <linux/io.h>
61#include <asm/uaccess.h>
62#include <asm/system.h>
63
64#define LCD_MINOR 156
65#define KEYPAD_MINOR 185
66
67#define PANEL_VERSION "0.9.5"
68
69#define LCD_MAXBYTES 256
70
71#define KEYPAD_BUFFER 64
72#define INPUT_POLL_TIME (HZ/50)
73#define KEYPAD_REP_START (10)
74#define KEYPAD_REP_DELAY (2)
75
76#define FLASH_LIGHT_TEMPO (200)
77
78
79#define PNL_PINPUT(a) ((((unsigned char)(a)) ^ 0x7F) >> 3)
80
81#define PNL_PBUSY 0x80
82#define PNL_PACK 0x40
83#define PNL_POUTPA 0x20
84#define PNL_PSELECD 0x10
85#define PNL_PERRORP 0x08
86
87#define PNL_PBIDIR 0x20
88#define PNL_PINTEN 0x10
89#define PNL_PSELECP 0x08
90#define PNL_PINITP 0x04
91#define PNL_PAUTOLF 0x02
92#define PNL_PSTROBE 0x01
93
94#define PNL_PD0 0x01
95#define PNL_PD1 0x02
96#define PNL_PD2 0x04
97#define PNL_PD3 0x08
98#define PNL_PD4 0x10
99#define PNL_PD5 0x20
100#define PNL_PD6 0x40
101#define PNL_PD7 0x80
102
103#define PIN_NONE 0
104#define PIN_STROBE 1
105#define PIN_D0 2
106#define PIN_D1 3
107#define PIN_D2 4
108#define PIN_D3 5
109#define PIN_D4 6
110#define PIN_D5 7
111#define PIN_D6 8
112#define PIN_D7 9
113#define PIN_AUTOLF 14
114#define PIN_INITP 16
115#define PIN_SELECP 17
116#define PIN_NOT_SET 127
117
118#define LCD_FLAG_S 0x0001
119#define LCD_FLAG_ID 0x0002
120#define LCD_FLAG_B 0x0004
121#define LCD_FLAG_C 0x0008
122#define LCD_FLAG_D 0x0010
123#define LCD_FLAG_F 0x0020
124#define LCD_FLAG_N 0x0040
125#define LCD_FLAG_L 0x0080
126
127#define LCD_ESCAPE_LEN 24
128#define LCD_ESCAPE_CHAR 27
129
130
131#define r_ctr(x) (parport_read_control((x)->port))
132#define r_dtr(x) (parport_read_data((x)->port))
133#define r_str(x) (parport_read_status((x)->port))
134#define w_ctr(x, y) do { parport_write_control((x)->port, (y)); } while (0)
135#define w_dtr(x, y) do { parport_write_data((x)->port, (y)); } while (0)
136
137
138static __u8 scan_mask_o;
139static __u8 scan_mask_i;
140
141typedef __u64 pmask_t;
142
143enum input_type {
144 INPUT_TYPE_STD,
145 INPUT_TYPE_KBD,
146};
147
148enum input_state {
149 INPUT_ST_LOW,
150 INPUT_ST_RISING,
151 INPUT_ST_HIGH,
152 INPUT_ST_FALLING,
153};
154
155struct logical_input {
156 struct list_head list;
157 pmask_t mask;
158 pmask_t value;
159 enum input_type type;
160 enum input_state state;
161 __u8 rise_time, fall_time;
162 __u8 rise_timer, fall_timer, high_timer;
163
164 union {
165 struct {
166 void (*press_fct) (int);
167 void (*release_fct) (int);
168 int press_data;
169 int release_data;
170 } std;
171 struct {
172
173 char press_str[sizeof(void *) + sizeof(int)];
174 char repeat_str[sizeof(void *) + sizeof(int)];
175 char release_str[sizeof(void *) + sizeof(int)];
176 } kbd;
177 } u;
178};
179
180LIST_HEAD(logical_inputs);
181
182
183
184
185
186
187
188
189
190
191
192static pmask_t phys_read;
193static pmask_t phys_read_prev;
194static pmask_t phys_curr;
195static pmask_t phys_prev;
196static char inputs_stable;
197
198
199static char keypad_buffer[KEYPAD_BUFFER];
200static int keypad_buflen;
201static int keypad_start;
202static char keypressed;
203static wait_queue_head_t keypad_read_wait;
204
205
206static unsigned long int lcd_flags;
207static unsigned long int lcd_addr_x;
208static unsigned long int lcd_addr_y;
209static char lcd_escape[LCD_ESCAPE_LEN + 1];
210static int lcd_escape_len = -1;
211
212
213
214
215
216
217#define BIT_CLR 0
218#define BIT_SET 1
219#define BIT_MSK 2
220#define BIT_STATES 3
221
222
223
224#define LCD_BIT_E 0
225#define LCD_BIT_RS 1
226#define LCD_BIT_RW 2
227#define LCD_BIT_BL 3
228#define LCD_BIT_CL 4
229#define LCD_BIT_DA 5
230#define LCD_BITS 6
231
232
233
234
235#define LCD_PORT_C 0
236#define LCD_PORT_D 1
237#define LCD_PORTS 2
238
239static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES];
240
241
242
243
244#define LCD_PROTO_PARALLEL 0
245#define LCD_PROTO_SERIAL 1
246#define LCD_PROTO_TI_DA8XX_LCD 2
247
248
249
250
251#define LCD_CHARSET_NORMAL 0
252#define LCD_CHARSET_KS0074 1
253
254
255
256
257#define LCD_TYPE_NONE 0
258#define LCD_TYPE_OLD 1
259#define LCD_TYPE_KS0074 2
260#define LCD_TYPE_HANTRONIX 3
261#define LCD_TYPE_NEXCOM 4
262#define LCD_TYPE_CUSTOM 5
263
264
265
266
267#define KEYPAD_TYPE_NONE 0
268#define KEYPAD_TYPE_OLD 1
269#define KEYPAD_TYPE_NEW 2
270#define KEYPAD_TYPE_NEXCOM 3
271
272
273
274
275#define PANEL_PROFILE_CUSTOM 0
276#define PANEL_PROFILE_OLD 1
277#define PANEL_PROFILE_NEW 2
278#define PANEL_PROFILE_HANTRONIX 3
279#define PANEL_PROFILE_NEXCOM 4
280#define PANEL_PROFILE_LARGE 5
281
282
283
284
285#define DEFAULT_PROFILE PANEL_PROFILE_LARGE
286#define DEFAULT_PARPORT 0
287#define DEFAULT_LCD LCD_TYPE_OLD
288#define DEFAULT_KEYPAD KEYPAD_TYPE_OLD
289#define DEFAULT_LCD_WIDTH 40
290#define DEFAULT_LCD_BWIDTH 40
291#define DEFAULT_LCD_HWIDTH 64
292#define DEFAULT_LCD_HEIGHT 2
293#define DEFAULT_LCD_PROTO LCD_PROTO_PARALLEL
294
295#define DEFAULT_LCD_PIN_E PIN_AUTOLF
296#define DEFAULT_LCD_PIN_RS PIN_SELECP
297#define DEFAULT_LCD_PIN_RW PIN_INITP
298#define DEFAULT_LCD_PIN_SCL PIN_STROBE
299#define DEFAULT_LCD_PIN_SDA PIN_D0
300#define DEFAULT_LCD_PIN_BL PIN_NOT_SET
301#define DEFAULT_LCD_CHARSET LCD_CHARSET_NORMAL
302
303#ifdef CONFIG_PANEL_PROFILE
304#undef DEFAULT_PROFILE
305#define DEFAULT_PROFILE CONFIG_PANEL_PROFILE
306#endif
307
308#ifdef CONFIG_PANEL_PARPORT
309#undef DEFAULT_PARPORT
310#define DEFAULT_PARPORT CONFIG_PANEL_PARPORT
311#endif
312
313#if DEFAULT_PROFILE == 0
314#ifdef CONFIG_PANEL_KEYPAD
315#undef DEFAULT_KEYPAD
316#define DEFAULT_KEYPAD CONFIG_PANEL_KEYPAD
317#endif
318
319#ifdef CONFIG_PANEL_LCD
320#undef DEFAULT_LCD
321#define DEFAULT_LCD CONFIG_PANEL_LCD
322#endif
323
324#ifdef CONFIG_PANEL_LCD_WIDTH
325#undef DEFAULT_LCD_WIDTH
326#define DEFAULT_LCD_WIDTH CONFIG_PANEL_LCD_WIDTH
327#endif
328
329#ifdef CONFIG_PANEL_LCD_BWIDTH
330#undef DEFAULT_LCD_BWIDTH
331#define DEFAULT_LCD_BWIDTH CONFIG_PANEL_LCD_BWIDTH
332#endif
333
334#ifdef CONFIG_PANEL_LCD_HWIDTH
335#undef DEFAULT_LCD_HWIDTH
336#define DEFAULT_LCD_HWIDTH CONFIG_PANEL_LCD_HWIDTH
337#endif
338
339#ifdef CONFIG_PANEL_LCD_HEIGHT
340#undef DEFAULT_LCD_HEIGHT
341#define DEFAULT_LCD_HEIGHT CONFIG_PANEL_LCD_HEIGHT
342#endif
343
344#ifdef CONFIG_PANEL_LCD_PROTO
345#undef DEFAULT_LCD_PROTO
346#define DEFAULT_LCD_PROTO CONFIG_PANEL_LCD_PROTO
347#endif
348
349#ifdef CONFIG_PANEL_LCD_PIN_E
350#undef DEFAULT_LCD_PIN_E
351#define DEFAULT_LCD_PIN_E CONFIG_PANEL_LCD_PIN_E
352#endif
353
354#ifdef CONFIG_PANEL_LCD_PIN_RS
355#undef DEFAULT_LCD_PIN_RS
356#define DEFAULT_LCD_PIN_RS CONFIG_PANEL_LCD_PIN_RS
357#endif
358
359#ifdef CONFIG_PANEL_LCD_PIN_RW
360#undef DEFAULT_LCD_PIN_RW
361#define DEFAULT_LCD_PIN_RW CONFIG_PANEL_LCD_PIN_RW
362#endif
363
364#ifdef CONFIG_PANEL_LCD_PIN_SCL
365#undef DEFAULT_LCD_PIN_SCL
366#define DEFAULT_LCD_PIN_SCL CONFIG_PANEL_LCD_PIN_SCL
367#endif
368
369#ifdef CONFIG_PANEL_LCD_PIN_SDA
370#undef DEFAULT_LCD_PIN_SDA
371#define DEFAULT_LCD_PIN_SDA CONFIG_PANEL_LCD_PIN_SDA
372#endif
373
374#ifdef CONFIG_PANEL_LCD_PIN_BL
375#undef DEFAULT_LCD_PIN_BL
376#define DEFAULT_LCD_PIN_BL CONFIG_PANEL_LCD_PIN_BL
377#endif
378
379#ifdef CONFIG_PANEL_LCD_CHARSET
380#undef DEFAULT_LCD_CHARSET
381#define DEFAULT_LCD_CHARSET
382#endif
383
384#endif
385
386
387static int keypad_open_cnt;
388static int lcd_open_cnt;
389static struct pardevice *pprt;
390
391static int lcd_initialized;
392static int keypad_initialized;
393
394static int light_tempo;
395
396static char lcd_must_clear;
397static char lcd_left_shift;
398static char init_in_progress;
399
400static void (*lcd_write_cmd) (int);
401static void (*lcd_write_data) (int);
402static void (*lcd_clear_fast) (void);
403
404static DEFINE_SPINLOCK(pprt_lock);
405static struct timer_list scan_timer;
406
407MODULE_DESCRIPTION("Generic parallel port LCD/Keypad driver");
408
409static int parport = -1;
410module_param(parport, int, 0000);
411MODULE_PARM_DESC(parport, "Parallel port index (0=lpt1, 1=lpt2, ...)");
412
413static int lcd_height = -1;
414module_param(lcd_height, int, 0000);
415MODULE_PARM_DESC(lcd_height, "Number of lines on the LCD");
416
417static int lcd_width = -1;
418module_param(lcd_width, int, 0000);
419MODULE_PARM_DESC(lcd_width, "Number of columns on the LCD");
420
421static int lcd_bwidth = -1;
422module_param(lcd_bwidth, int, 0000);
423MODULE_PARM_DESC(lcd_bwidth, "Internal LCD line width (40)");
424
425static int lcd_hwidth = -1;
426module_param(lcd_hwidth, int, 0000);
427MODULE_PARM_DESC(lcd_hwidth, "LCD line hardware address (64)");
428
429static int lcd_enabled = -1;
430module_param(lcd_enabled, int, 0000);
431MODULE_PARM_DESC(lcd_enabled, "Deprecated option, use lcd_type instead");
432
433static int keypad_enabled = -1;
434module_param(keypad_enabled, int, 0000);
435MODULE_PARM_DESC(keypad_enabled, "Deprecated option, use keypad_type instead");
436
437static int lcd_type = -1;
438module_param(lcd_type, int, 0000);
439MODULE_PARM_DESC(lcd_type,
440 "LCD type: 0=none, 1=old //, 2=serial ks0074, 3=hantronix //, 4=nexcom //, 5=compiled-in");
441
442static int lcd_proto = -1;
443module_param(lcd_proto, int, 0000);
444MODULE_PARM_DESC(lcd_proto, "LCD communication: 0=parallel (//), 1=serial,"
445 "2=TI LCD Interface");
446
447static int lcd_charset = -1;
448module_param(lcd_charset, int, 0000);
449MODULE_PARM_DESC(lcd_charset, "LCD character set: 0=standard, 1=KS0074");
450
451static int keypad_type = -1;
452module_param(keypad_type, int, 0000);
453MODULE_PARM_DESC(keypad_type,
454 "Keypad type: 0=none, 1=old 6 keys, 2=new 6+1 keys, 3=nexcom 4 keys");
455
456static int profile = DEFAULT_PROFILE;
457module_param(profile, int, 0000);
458MODULE_PARM_DESC(profile,
459 "1=16x2 old kp; 2=serial 16x2, new kp; 3=16x2 hantronix; 4=16x2 nexcom; default=40x2, old kp");
460
461
462
463
464
465
466
467
468
469
470static int lcd_e_pin = PIN_NOT_SET;
471module_param(lcd_e_pin, int, 0000);
472MODULE_PARM_DESC(lcd_e_pin,
473 "# of the // port pin connected to LCD 'E' signal, with polarity (-17..17)");
474
475static int lcd_rs_pin = PIN_NOT_SET;
476module_param(lcd_rs_pin, int, 0000);
477MODULE_PARM_DESC(lcd_rs_pin,
478 "# of the // port pin connected to LCD 'RS' signal, with polarity (-17..17)");
479
480static int lcd_rw_pin = PIN_NOT_SET;
481module_param(lcd_rw_pin, int, 0000);
482MODULE_PARM_DESC(lcd_rw_pin,
483 "# of the // port pin connected to LCD 'RW' signal, with polarity (-17..17)");
484
485static int lcd_bl_pin = PIN_NOT_SET;
486module_param(lcd_bl_pin, int, 0000);
487MODULE_PARM_DESC(lcd_bl_pin,
488 "# of the // port pin connected to LCD backlight, with polarity (-17..17)");
489
490static int lcd_da_pin = PIN_NOT_SET;
491module_param(lcd_da_pin, int, 0000);
492MODULE_PARM_DESC(lcd_da_pin,
493 "# of the // port pin connected to serial LCD 'SDA' signal, with polarity (-17..17)");
494
495static int lcd_cl_pin = PIN_NOT_SET;
496module_param(lcd_cl_pin, int, 0000);
497MODULE_PARM_DESC(lcd_cl_pin,
498 "# of the // port pin connected to serial LCD 'SCL' signal, with polarity (-17..17)");
499
500static unsigned char *lcd_char_conv;
501
502
503static unsigned char lcd_char_conv_ks0074[256] = {
504
505 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
506 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
507 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
508 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
509 0x20, 0x21, 0x22, 0x23, 0xa2, 0x25, 0x26, 0x27,
510 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
511 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
512 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
513 0xa0, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
514 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
515 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
516 0x58, 0x59, 0x5a, 0xfa, 0xfb, 0xfc, 0x1d, 0xc4,
517 0x96, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
518 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
519 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
520 0x78, 0x79, 0x7a, 0xfd, 0xfe, 0xff, 0xce, 0x20,
521 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
522 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
523 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
524 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
525 0x20, 0x40, 0xb1, 0xa1, 0x24, 0xa3, 0xfe, 0x5f,
526 0x22, 0xc8, 0x61, 0x14, 0x97, 0x2d, 0xad, 0x96,
527 0x80, 0x8c, 0x82, 0x83, 0x27, 0x8f, 0x86, 0xdd,
528 0x2c, 0x81, 0x6f, 0x15, 0x8b, 0x8a, 0x84, 0x60,
529 0xe2, 0xe2, 0xe2, 0x5b, 0x5b, 0xae, 0xbc, 0xa9,
530 0xc5, 0xbf, 0xc6, 0xf1, 0xe3, 0xe3, 0xe3, 0xe3,
531 0x44, 0x5d, 0xa8, 0xe4, 0xec, 0xec, 0x5c, 0x78,
532 0xab, 0xa6, 0xe5, 0x5e, 0x5e, 0xe6, 0xaa, 0xbe,
533 0x7f, 0xe7, 0xaf, 0x7b, 0x7b, 0xaf, 0xbd, 0xc8,
534 0xa4, 0xa5, 0xc7, 0xf6, 0xa7, 0xe8, 0x69, 0x69,
535 0xed, 0x7d, 0xa8, 0xe4, 0xec, 0x5c, 0x5c, 0x25,
536 0xac, 0xa6, 0xea, 0xef, 0x7e, 0xeb, 0xb2, 0x79,
537};
538
539char old_keypad_profile[][4][9] = {
540 {"S0", "Left\n", "Left\n", ""},
541 {"S1", "Down\n", "Down\n", ""},
542 {"S2", "Up\n", "Up\n", ""},
543 {"S3", "Right\n", "Right\n", ""},
544 {"S4", "Esc\n", "Esc\n", ""},
545 {"S5", "Ret\n", "Ret\n", ""},
546 {"", "", "", ""}
547};
548
549
550char new_keypad_profile[][4][9] = {
551 {"S0", "Left\n", "Left\n", ""},
552 {"S1", "Down\n", "Down\n", ""},
553 {"S2", "Up\n", "Up\n", ""},
554 {"S3", "Right\n", "Right\n", ""},
555 {"S4s5", "", "Esc\n", "Esc\n"},
556 {"s4S5", "", "Ret\n", "Ret\n"},
557 {"S4S5", "Help\n", "", ""},
558
559 {"", "", "", ""}
560};
561
562
563char nexcom_keypad_profile[][4][9] = {
564 {"a-p-e-", "Down\n", "Down\n", ""},
565 {"a-p-E-", "Ret\n", "Ret\n", ""},
566 {"a-P-E-", "Esc\n", "Esc\n", ""},
567 {"a-P-e-", "Up\n", "Up\n", ""},
568
569 {"", "", "", ""}
570};
571
572static char (*keypad_profile)[4][9] = old_keypad_profile;
573
574
575static struct {
576 unsigned char e;
577 unsigned char rs;
578 unsigned char rw;
579 unsigned char bl;
580 unsigned char cl;
581 unsigned char da;
582} bits;
583
584static void init_scan_timer(void);
585
586
587static int set_data_bits(void)
588{
589 int val, bit;
590
591 val = r_dtr(pprt);
592 for (bit = 0; bit < LCD_BITS; bit++)
593 val &= lcd_bits[LCD_PORT_D][bit][BIT_MSK];
594
595 val |= lcd_bits[LCD_PORT_D][LCD_BIT_E][bits.e]
596 | lcd_bits[LCD_PORT_D][LCD_BIT_RS][bits.rs]
597 | lcd_bits[LCD_PORT_D][LCD_BIT_RW][bits.rw]
598 | lcd_bits[LCD_PORT_D][LCD_BIT_BL][bits.bl]
599 | lcd_bits[LCD_PORT_D][LCD_BIT_CL][bits.cl]
600 | lcd_bits[LCD_PORT_D][LCD_BIT_DA][bits.da];
601
602 w_dtr(pprt, val);
603 return val;
604}
605
606
607static int set_ctrl_bits(void)
608{
609 int val, bit;
610
611 val = r_ctr(pprt);
612 for (bit = 0; bit < LCD_BITS; bit++)
613 val &= lcd_bits[LCD_PORT_C][bit][BIT_MSK];
614
615 val |= lcd_bits[LCD_PORT_C][LCD_BIT_E][bits.e]
616 | lcd_bits[LCD_PORT_C][LCD_BIT_RS][bits.rs]
617 | lcd_bits[LCD_PORT_C][LCD_BIT_RW][bits.rw]
618 | lcd_bits[LCD_PORT_C][LCD_BIT_BL][bits.bl]
619 | lcd_bits[LCD_PORT_C][LCD_BIT_CL][bits.cl]
620 | lcd_bits[LCD_PORT_C][LCD_BIT_DA][bits.da];
621
622 w_ctr(pprt, val);
623 return val;
624}
625
626
627static void panel_set_bits(void)
628{
629 set_data_bits();
630 set_ctrl_bits();
631}
632
633
634
635
636
637
638
639
640
641
642void pin_to_bits(int pin, unsigned char *d_val, unsigned char *c_val)
643{
644 int d_bit, c_bit, inv;
645
646 d_val[0] = c_val[0] = d_val[1] = c_val[1] = 0;
647 d_val[2] = c_val[2] = 0xFF;
648
649 if (pin == 0)
650 return;
651
652 inv = (pin < 0);
653 if (inv)
654 pin = -pin;
655
656 d_bit = c_bit = 0;
657
658 switch (pin) {
659 case PIN_STROBE:
660 c_bit = PNL_PSTROBE;
661 inv = !inv;
662 break;
663 case PIN_D0...PIN_D7:
664 d_bit = 1 << (pin - 2);
665 break;
666 case PIN_AUTOLF:
667 c_bit = PNL_PAUTOLF;
668 inv = !inv;
669 break;
670 case PIN_INITP:
671 c_bit = PNL_PINITP;
672 break;
673 case PIN_SELECP:
674 c_bit = PNL_PSELECP;
675 inv = !inv;
676 break;
677 default:
678 break;
679 }
680
681 if (c_bit) {
682 c_val[2] &= ~c_bit;
683 c_val[!inv] = c_bit;
684 } else if (d_bit) {
685 d_val[2] &= ~d_bit;
686 d_val[!inv] = d_bit;
687 }
688}
689
690
691static void long_sleep(int ms)
692{
693
694 if (in_interrupt())
695 mdelay(ms);
696 else {
697 current->state = TASK_INTERRUPTIBLE;
698 schedule_timeout((ms * HZ + 999) / 1000);
699 }
700}
701
702
703static void lcd_send_serial(int byte)
704{
705 int bit;
706
707
708
709
710 for (bit = 0; bit < 8; bit++) {
711 bits.cl = BIT_CLR;
712 panel_set_bits();
713 bits.da = byte & 1;
714 panel_set_bits();
715 udelay(2);
716 bits.cl = BIT_SET;
717 panel_set_bits();
718 udelay(1);
719 byte >>= 1;
720 }
721}
722
723
724static void lcd_backlight(int on)
725{
726 if (lcd_bl_pin == PIN_NONE)
727 return;
728
729
730 spin_lock(&pprt_lock);
731 bits.bl = on;
732 panel_set_bits();
733 spin_unlock(&pprt_lock);
734}
735
736
737static void lcd_write_cmd_s(int cmd)
738{
739 spin_lock(&pprt_lock);
740 lcd_send_serial(0x1F);
741 lcd_send_serial(cmd & 0x0F);
742 lcd_send_serial((cmd >> 4) & 0x0F);
743 udelay(40);
744 spin_unlock(&pprt_lock);
745}
746
747
748static void lcd_write_data_s(int data)
749{
750 spin_lock(&pprt_lock);
751 lcd_send_serial(0x5F);
752 lcd_send_serial(data & 0x0F);
753 lcd_send_serial((data >> 4) & 0x0F);
754 udelay(40);
755 spin_unlock(&pprt_lock);
756}
757
758
759static void lcd_write_cmd_p8(int cmd)
760{
761 spin_lock(&pprt_lock);
762
763 w_dtr(pprt, cmd);
764 udelay(20);
765
766 bits.e = BIT_SET;
767 bits.rs = BIT_CLR;
768 bits.rw = BIT_CLR;
769 set_ctrl_bits();
770
771 udelay(40);
772
773 bits.e = BIT_CLR;
774 set_ctrl_bits();
775
776 udelay(120);
777 spin_unlock(&pprt_lock);
778}
779
780
781static void lcd_write_data_p8(int data)
782{
783 spin_lock(&pprt_lock);
784
785 w_dtr(pprt, data);
786 udelay(20);
787
788 bits.e = BIT_SET;
789 bits.rs = BIT_SET;
790 bits.rw = BIT_CLR;
791 set_ctrl_bits();
792
793 udelay(40);
794
795 bits.e = BIT_CLR;
796 set_ctrl_bits();
797
798 udelay(45);
799 spin_unlock(&pprt_lock);
800}
801
802
803static void lcd_write_cmd_tilcd(int cmd)
804{
805 spin_lock(&pprt_lock);
806
807 w_ctr(pprt, cmd);
808 udelay(60);
809 spin_unlock(&pprt_lock);
810}
811
812
813static void lcd_write_data_tilcd(int data)
814{
815 spin_lock(&pprt_lock);
816
817 w_dtr(pprt, data);
818 udelay(60);
819 spin_unlock(&pprt_lock);
820}
821
822static void lcd_gotoxy(void)
823{
824 lcd_write_cmd(0x80
825 | (lcd_addr_y ? lcd_hwidth : 0)
826
827 | ((lcd_addr_x < lcd_bwidth) ? lcd_addr_x &
828 (lcd_hwidth - 1) : lcd_bwidth - 1));
829}
830
831static void lcd_print(char c)
832{
833 if (lcd_addr_x < lcd_bwidth) {
834 if (lcd_char_conv != NULL)
835 c = lcd_char_conv[(unsigned char)c];
836 lcd_write_data(c);
837 lcd_addr_x++;
838 }
839
840 if (lcd_addr_x == lcd_bwidth)
841 lcd_gotoxy();
842}
843
844
845static void lcd_clear_fast_s(void)
846{
847 int pos;
848 lcd_addr_x = lcd_addr_y = 0;
849 lcd_gotoxy();
850
851 spin_lock(&pprt_lock);
852 for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) {
853 lcd_send_serial(0x5F);
854 lcd_send_serial(' ' & 0x0F);
855 lcd_send_serial((' ' >> 4) & 0x0F);
856 udelay(40);
857 }
858 spin_unlock(&pprt_lock);
859
860 lcd_addr_x = lcd_addr_y = 0;
861 lcd_gotoxy();
862}
863
864
865static void lcd_clear_fast_p8(void)
866{
867 int pos;
868 lcd_addr_x = lcd_addr_y = 0;
869 lcd_gotoxy();
870
871 spin_lock(&pprt_lock);
872 for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) {
873
874 w_dtr(pprt, ' ');
875 udelay(20);
876
877 bits.e = BIT_SET;
878 bits.rs = BIT_SET;
879 bits.rw = BIT_CLR;
880 set_ctrl_bits();
881
882 udelay(40);
883
884 bits.e = BIT_CLR;
885 set_ctrl_bits();
886
887 udelay(45);
888 }
889 spin_unlock(&pprt_lock);
890
891 lcd_addr_x = lcd_addr_y = 0;
892 lcd_gotoxy();
893}
894
895
896static void lcd_clear_fast_tilcd(void)
897{
898 int pos;
899 lcd_addr_x = lcd_addr_y = 0;
900 lcd_gotoxy();
901
902 spin_lock(&pprt_lock);
903 for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) {
904
905 w_dtr(pprt, ' ');
906 udelay(60);
907 }
908
909 spin_unlock(&pprt_lock);
910
911 lcd_addr_x = lcd_addr_y = 0;
912 lcd_gotoxy();
913}
914
915
916static void lcd_clear_display(void)
917{
918 lcd_write_cmd(0x01);
919 lcd_addr_x = lcd_addr_y = 0;
920
921 long_sleep(15);
922}
923
924static void lcd_init_display(void)
925{
926
927 lcd_flags = ((lcd_height > 1) ? LCD_FLAG_N : 0)
928 | LCD_FLAG_D | LCD_FLAG_C | LCD_FLAG_B;
929
930 long_sleep(20);
931
932 lcd_write_cmd(0x30);
933 long_sleep(10);
934 lcd_write_cmd(0x30);
935 long_sleep(10);
936 lcd_write_cmd(0x30);
937 long_sleep(10);
938
939 lcd_write_cmd(0x30
940 | ((lcd_flags & LCD_FLAG_F) ? 4 : 0)
941 | ((lcd_flags & LCD_FLAG_N) ? 8 : 0)
942 );
943 long_sleep(10);
944
945 lcd_write_cmd(0x08);
946 long_sleep(10);
947
948 lcd_write_cmd(0x08
949 | ((lcd_flags & LCD_FLAG_D) ? 4 : 0)
950 | ((lcd_flags & LCD_FLAG_C) ? 2 : 0)
951 | ((lcd_flags & LCD_FLAG_B) ? 1 : 0)
952 );
953
954 lcd_backlight((lcd_flags & LCD_FLAG_L) ? 1 : 0);
955
956 long_sleep(10);
957
958 lcd_write_cmd(0x06);
959
960 lcd_clear_display();
961}
962
963
964
965
966
967
968
969
970static ssize_t lcd_write(struct file *file,
971 const char *buf, size_t count, loff_t *ppos)
972{
973
974 const char *tmp = buf;
975 char c;
976
977 for (; count-- > 0; (ppos ? (*ppos)++ : 0), ++tmp) {
978 if (!in_interrupt() && (((count + 1) & 0x1f) == 0))
979 schedule();
980
981 if (ppos == NULL && file == NULL)
982 c = *tmp;
983 else if (get_user(c, tmp))
984 return -EFAULT;
985
986
987 if ((c != '\n') && lcd_escape_len >= 0) {
988 lcd_escape[lcd_escape_len++] = c;
989 lcd_escape[lcd_escape_len] = 0;
990 } else {
991 lcd_escape_len = -1;
992
993 switch (c) {
994 case LCD_ESCAPE_CHAR:
995 lcd_escape_len = 0;
996 lcd_escape[lcd_escape_len] = 0;
997 break;
998 case '\b':
999 if (lcd_addr_x > 0) {
1000 if (lcd_addr_x < lcd_bwidth)
1001 lcd_write_cmd(0x10);
1002 lcd_addr_x--;
1003 }
1004 lcd_write_data(' ');
1005 lcd_write_cmd(0x10);
1006 break;
1007 case '\014':
1008 lcd_clear_fast();
1009 break;
1010 case '\n':
1011
1012 for (; lcd_addr_x < lcd_bwidth; lcd_addr_x++)
1013 lcd_write_data(' ');
1014 lcd_addr_x = 0;
1015 lcd_addr_y = (lcd_addr_y + 1) % lcd_height;
1016 lcd_gotoxy();
1017 break;
1018 case '\r':
1019 lcd_addr_x = 0;
1020 lcd_gotoxy();
1021 break;
1022 case '\t':
1023 lcd_print(' ');
1024 break;
1025 default:
1026 lcd_print(c);
1027 break;
1028 }
1029 }
1030
1031
1032
1033
1034 if (lcd_escape_len >= 2) {
1035 int processed = 0;
1036
1037 if (!strcmp(lcd_escape, "[2J")) {
1038 lcd_clear_fast();
1039 processed = 1;
1040 } else if (!strcmp(lcd_escape, "[H")) {
1041 lcd_addr_x = lcd_addr_y = 0;
1042 lcd_gotoxy();
1043 processed = 1;
1044 }
1045
1046 else if ((lcd_escape_len >= 3) &&
1047 (lcd_escape[0] == '[') && (lcd_escape[1] == 'L')) {
1048
1049 char *esc = lcd_escape + 2;
1050 int oldflags = lcd_flags;
1051
1052
1053 switch (*esc) {
1054 case 'D':
1055 lcd_flags |= LCD_FLAG_D;
1056 processed = 1;
1057 break;
1058 case 'd':
1059 lcd_flags &= ~LCD_FLAG_D;
1060 processed = 1;
1061 break;
1062 case 'C':
1063 lcd_flags |= LCD_FLAG_C;
1064 processed = 1;
1065 break;
1066 case 'c':
1067 lcd_flags &= ~LCD_FLAG_C;
1068 processed = 1;
1069 break;
1070 case 'B':
1071 lcd_flags |= LCD_FLAG_B;
1072 processed = 1;
1073 break;
1074 case 'b':
1075 lcd_flags &= ~LCD_FLAG_B;
1076 processed = 1;
1077 break;
1078 case '+':
1079 lcd_flags |= LCD_FLAG_L;
1080 processed = 1;
1081 break;
1082 case '-':
1083 lcd_flags &= ~LCD_FLAG_L;
1084 processed = 1;
1085 break;
1086 case '*':
1087 if (scan_timer.function != NULL) {
1088 if (light_tempo == 0
1089 && ((lcd_flags & LCD_FLAG_L)
1090 == 0))
1091 lcd_backlight(1);
1092 light_tempo = FLASH_LIGHT_TEMPO;
1093 }
1094 processed = 1;
1095 break;
1096 case 'f':
1097 lcd_flags &= ~LCD_FLAG_F;
1098 processed = 1;
1099 break;
1100 case 'F':
1101 lcd_flags |= LCD_FLAG_F;
1102 processed = 1;
1103 break;
1104 case 'n':
1105 lcd_flags &= ~LCD_FLAG_N;
1106 processed = 1;
1107 break;
1108 case 'N':
1109 lcd_flags |= LCD_FLAG_N;
1110 break;
1111
1112 case 'l':
1113 if (lcd_addr_x > 0) {
1114 if (lcd_addr_x < lcd_bwidth)
1115 lcd_write_cmd(0x10);
1116 lcd_addr_x--;
1117 }
1118 processed = 1;
1119 break;
1120
1121 case 'r':
1122 if (lcd_addr_x < lcd_width) {
1123 if (lcd_addr_x < (lcd_bwidth - 1))
1124 lcd_write_cmd(0x14);
1125 lcd_addr_x++;
1126 }
1127 processed = 1;
1128 break;
1129
1130 case 'L':
1131 lcd_left_shift++;
1132 lcd_write_cmd(0x18);
1133 processed = 1;
1134 break;
1135
1136 case 'R':
1137 lcd_left_shift--;
1138 lcd_write_cmd(0x1C);
1139 processed = 1;
1140 break;
1141
1142 case 'k':{
1143 int x;
1144 for (x = lcd_addr_x; x < lcd_bwidth; x++)
1145 lcd_write_data(' ');
1146 lcd_gotoxy();
1147 processed = 1;
1148 break;
1149 }
1150 case 'I':
1151 lcd_init_display();
1152 lcd_left_shift = 0;
1153 processed = 1;
1154 break;
1155
1156 case 'G': {
1157
1158
1159
1160
1161
1162
1163 unsigned char cgbytes[8];
1164 unsigned char cgaddr;
1165 int cgoffset;
1166 int shift;
1167 char value;
1168 int addr;
1169
1170 if (strchr(esc, ';') == NULL)
1171 break;
1172
1173 esc++;
1174
1175 cgaddr = *(esc++) - '0';
1176 if (cgaddr > 7) {
1177 processed = 1;
1178 break;
1179 }
1180
1181 cgoffset = 0;
1182 shift = 0;
1183 value = 0;
1184 while (*esc && cgoffset < 8) {
1185 shift ^= 4;
1186 if (*esc >= '0' && *esc <= '9')
1187 value |= (*esc - '0') << shift;
1188 else if (*esc >= 'A' && *esc <= 'Z')
1189 value |= (*esc - 'A' + 10) << shift;
1190 else if (*esc >= 'a' && *esc <= 'z')
1191 value |= (*esc - 'a' + 10) << shift;
1192 else {
1193 esc++;
1194 continue;
1195 }
1196
1197 if (shift == 0) {
1198 cgbytes[cgoffset++] = value;
1199 value = 0;
1200 }
1201
1202 esc++;
1203 }
1204
1205 lcd_write_cmd(0x40 | (cgaddr * 8));
1206 for (addr = 0; addr < cgoffset; addr++)
1207 lcd_write_data(cgbytes[addr]);
1208
1209 lcd_gotoxy();
1210 processed = 1;
1211 break;
1212 }
1213 case 'x':
1214 case 'y':
1215 if (strchr(esc, ';') == NULL)
1216 break;
1217
1218 while (*esc) {
1219 if (*esc == 'x') {
1220 esc++;
1221 lcd_addr_x = 0;
1222 while (isdigit(*esc)) {
1223 lcd_addr_x =
1224 lcd_addr_x *
1225 10 + (*esc -
1226 '0');
1227 esc++;
1228 }
1229 } else if (*esc == 'y') {
1230 esc++;
1231 lcd_addr_y = 0;
1232 while (isdigit(*esc)) {
1233 lcd_addr_y =
1234 lcd_addr_y *
1235 10 + (*esc -
1236 '0');
1237 esc++;
1238 }
1239 } else
1240 break;
1241 }
1242
1243 lcd_gotoxy();
1244 processed = 1;
1245 break;
1246 }
1247
1248
1249 if (oldflags != lcd_flags) {
1250
1251 if ((oldflags ^ lcd_flags) &
1252 (LCD_FLAG_B | LCD_FLAG_C | LCD_FLAG_D))
1253
1254 lcd_write_cmd(0x08 |
1255 ((lcd_flags & LCD_FLAG_D) ? 4 : 0) |
1256 ((lcd_flags & LCD_FLAG_C) ? 2 : 0) |
1257 ((lcd_flags & LCD_FLAG_B) ? 1 : 0));
1258
1259 else if ((oldflags ^ lcd_flags) &
1260 (LCD_FLAG_F | LCD_FLAG_N))
1261 lcd_write_cmd(0x30 |
1262 ((lcd_flags & LCD_FLAG_F) ? 4 : 0) |
1263 ((lcd_flags & LCD_FLAG_N) ? 8 : 0));
1264
1265 else if ((oldflags ^ lcd_flags) &
1266 (LCD_FLAG_L)) {
1267 if (lcd_flags & (LCD_FLAG_L))
1268 lcd_backlight(1);
1269 else if (light_tempo == 0)
1270 lcd_backlight(0);
1271 }
1272 }
1273 }
1274
1275
1276
1277
1278 if (processed || (lcd_escape_len >= LCD_ESCAPE_LEN))
1279 lcd_escape_len = -1;
1280 }
1281 }
1282
1283 return tmp - buf;
1284}
1285
1286static int lcd_open(struct inode *inode, struct file *file)
1287{
1288 if (lcd_open_cnt)
1289 return -EBUSY;
1290
1291 if (file->f_mode & FMODE_READ)
1292 return -EPERM;
1293
1294 if (lcd_must_clear) {
1295 lcd_clear_display();
1296 lcd_must_clear = 0;
1297 }
1298 lcd_open_cnt++;
1299 return 0;
1300}
1301
1302static int lcd_release(struct inode *inode, struct file *file)
1303{
1304 lcd_open_cnt--;
1305 return 0;
1306}
1307
1308static struct file_operations lcd_fops = {
1309 .write = lcd_write,
1310 .open = lcd_open,
1311 .release = lcd_release,
1312};
1313
1314static struct miscdevice lcd_dev = {
1315 LCD_MINOR,
1316 "lcd",
1317 &lcd_fops
1318};
1319
1320
1321void panel_lcd_print(char *s)
1322{
1323 if (lcd_enabled && lcd_initialized)
1324 lcd_write(NULL, s, strlen(s), NULL);
1325}
1326
1327
1328void lcd_init(void)
1329{
1330 switch (lcd_type) {
1331 case LCD_TYPE_OLD:
1332 if (lcd_proto < 0)
1333 lcd_proto = LCD_PROTO_PARALLEL;
1334 if (lcd_charset < 0)
1335 lcd_charset = LCD_CHARSET_NORMAL;
1336 if (lcd_e_pin == PIN_NOT_SET)
1337 lcd_e_pin = PIN_STROBE;
1338 if (lcd_rs_pin == PIN_NOT_SET)
1339 lcd_rs_pin = PIN_AUTOLF;
1340
1341 if (lcd_width < 0)
1342 lcd_width = 40;
1343 if (lcd_bwidth < 0)
1344 lcd_bwidth = 40;
1345 if (lcd_hwidth < 0)
1346 lcd_hwidth = 64;
1347 if (lcd_height < 0)
1348 lcd_height = 2;
1349 break;
1350 case LCD_TYPE_KS0074:
1351 if (lcd_proto < 0)
1352 lcd_proto = LCD_PROTO_SERIAL;
1353 if (lcd_charset < 0)
1354 lcd_charset = LCD_CHARSET_KS0074;
1355 if (lcd_bl_pin == PIN_NOT_SET)
1356 lcd_bl_pin = PIN_AUTOLF;
1357 if (lcd_cl_pin == PIN_NOT_SET)
1358 lcd_cl_pin = PIN_STROBE;
1359 if (lcd_da_pin == PIN_NOT_SET)
1360 lcd_da_pin = PIN_D0;
1361
1362 if (lcd_width < 0)
1363 lcd_width = 16;
1364 if (lcd_bwidth < 0)
1365 lcd_bwidth = 40;
1366 if (lcd_hwidth < 0)
1367 lcd_hwidth = 16;
1368 if (lcd_height < 0)
1369 lcd_height = 2;
1370 break;
1371 case LCD_TYPE_NEXCOM:
1372 if (lcd_proto < 0)
1373 lcd_proto = LCD_PROTO_PARALLEL;
1374 if (lcd_charset < 0)
1375 lcd_charset = LCD_CHARSET_NORMAL;
1376 if (lcd_e_pin == PIN_NOT_SET)
1377 lcd_e_pin = PIN_AUTOLF;
1378 if (lcd_rs_pin == PIN_NOT_SET)
1379 lcd_rs_pin = PIN_SELECP;
1380 if (lcd_rw_pin == PIN_NOT_SET)
1381 lcd_rw_pin = PIN_INITP;
1382
1383 if (lcd_width < 0)
1384 lcd_width = 16;
1385 if (lcd_bwidth < 0)
1386 lcd_bwidth = 40;
1387 if (lcd_hwidth < 0)
1388 lcd_hwidth = 64;
1389 if (lcd_height < 0)
1390 lcd_height = 2;
1391 break;
1392 case LCD_TYPE_CUSTOM:
1393 if (lcd_proto < 0)
1394 lcd_proto = DEFAULT_LCD_PROTO;
1395 if (lcd_charset < 0)
1396 lcd_charset = DEFAULT_LCD_CHARSET;
1397
1398 break;
1399 case LCD_TYPE_HANTRONIX:
1400 default:
1401 if (lcd_proto < 0)
1402 lcd_proto = LCD_PROTO_PARALLEL;
1403 if (lcd_charset < 0)
1404 lcd_charset = LCD_CHARSET_NORMAL;
1405 if (lcd_e_pin == PIN_NOT_SET)
1406 lcd_e_pin = PIN_STROBE;
1407 if (lcd_rs_pin == PIN_NOT_SET)
1408 lcd_rs_pin = PIN_SELECP;
1409
1410 if (lcd_width < 0)
1411 lcd_width = 16;
1412 if (lcd_bwidth < 0)
1413 lcd_bwidth = 40;
1414 if (lcd_hwidth < 0)
1415 lcd_hwidth = 64;
1416 if (lcd_height < 0)
1417 lcd_height = 2;
1418 break;
1419 }
1420
1421
1422 if (lcd_width <= 0)
1423 lcd_width = DEFAULT_LCD_WIDTH;
1424 if (lcd_bwidth <= 0)
1425 lcd_bwidth = DEFAULT_LCD_BWIDTH;
1426 if (lcd_hwidth <= 0)
1427 lcd_hwidth = DEFAULT_LCD_HWIDTH;
1428 if (lcd_height <= 0)
1429 lcd_height = DEFAULT_LCD_HEIGHT;
1430
1431 if (lcd_proto == LCD_PROTO_SERIAL) {
1432 lcd_write_cmd = lcd_write_cmd_s;
1433 lcd_write_data = lcd_write_data_s;
1434 lcd_clear_fast = lcd_clear_fast_s;
1435
1436 if (lcd_cl_pin == PIN_NOT_SET)
1437 lcd_cl_pin = DEFAULT_LCD_PIN_SCL;
1438 if (lcd_da_pin == PIN_NOT_SET)
1439 lcd_da_pin = DEFAULT_LCD_PIN_SDA;
1440
1441 } else if (lcd_proto == LCD_PROTO_PARALLEL) {
1442 lcd_write_cmd = lcd_write_cmd_p8;
1443 lcd_write_data = lcd_write_data_p8;
1444 lcd_clear_fast = lcd_clear_fast_p8;
1445
1446 if (lcd_e_pin == PIN_NOT_SET)
1447 lcd_e_pin = DEFAULT_LCD_PIN_E;
1448 if (lcd_rs_pin == PIN_NOT_SET)
1449 lcd_rs_pin = DEFAULT_LCD_PIN_RS;
1450 if (lcd_rw_pin == PIN_NOT_SET)
1451 lcd_rw_pin = DEFAULT_LCD_PIN_RW;
1452 } else {
1453 lcd_write_cmd = lcd_write_cmd_tilcd;
1454 lcd_write_data = lcd_write_data_tilcd;
1455 lcd_clear_fast = lcd_clear_fast_tilcd;
1456 }
1457
1458 if (lcd_bl_pin == PIN_NOT_SET)
1459 lcd_bl_pin = DEFAULT_LCD_PIN_BL;
1460
1461 if (lcd_e_pin == PIN_NOT_SET)
1462 lcd_e_pin = PIN_NONE;
1463 if (lcd_rs_pin == PIN_NOT_SET)
1464 lcd_rs_pin = PIN_NONE;
1465 if (lcd_rw_pin == PIN_NOT_SET)
1466 lcd_rw_pin = PIN_NONE;
1467 if (lcd_bl_pin == PIN_NOT_SET)
1468 lcd_bl_pin = PIN_NONE;
1469 if (lcd_cl_pin == PIN_NOT_SET)
1470 lcd_cl_pin = PIN_NONE;
1471 if (lcd_da_pin == PIN_NOT_SET)
1472 lcd_da_pin = PIN_NONE;
1473
1474 if (lcd_charset < 0)
1475 lcd_charset = DEFAULT_LCD_CHARSET;
1476
1477 if (lcd_charset == LCD_CHARSET_KS0074)
1478 lcd_char_conv = lcd_char_conv_ks0074;
1479 else
1480 lcd_char_conv = NULL;
1481
1482 if (lcd_bl_pin != PIN_NONE)
1483 init_scan_timer();
1484
1485 pin_to_bits(lcd_e_pin, lcd_bits[LCD_PORT_D][LCD_BIT_E],
1486 lcd_bits[LCD_PORT_C][LCD_BIT_E]);
1487 pin_to_bits(lcd_rs_pin, lcd_bits[LCD_PORT_D][LCD_BIT_RS],
1488 lcd_bits[LCD_PORT_C][LCD_BIT_RS]);
1489 pin_to_bits(lcd_rw_pin, lcd_bits[LCD_PORT_D][LCD_BIT_RW],
1490 lcd_bits[LCD_PORT_C][LCD_BIT_RW]);
1491 pin_to_bits(lcd_bl_pin, lcd_bits[LCD_PORT_D][LCD_BIT_BL],
1492 lcd_bits[LCD_PORT_C][LCD_BIT_BL]);
1493 pin_to_bits(lcd_cl_pin, lcd_bits[LCD_PORT_D][LCD_BIT_CL],
1494 lcd_bits[LCD_PORT_C][LCD_BIT_CL]);
1495 pin_to_bits(lcd_da_pin, lcd_bits[LCD_PORT_D][LCD_BIT_DA],
1496 lcd_bits[LCD_PORT_C][LCD_BIT_DA]);
1497
1498
1499
1500
1501
1502 lcd_initialized = 1;
1503 lcd_init_display();
1504
1505
1506#ifdef CONFIG_PANEL_CHANGE_MESSAGE
1507#ifdef CONFIG_PANEL_BOOT_MESSAGE
1508 panel_lcd_print("\x1b[Lc\x1b[Lb\x1b[L*" CONFIG_PANEL_BOOT_MESSAGE);
1509#endif
1510#else
1511 panel_lcd_print("\x1b[Lc\x1b[Lb\x1b[L*Linux-" UTS_RELEASE "\nPanel-"
1512 PANEL_VERSION);
1513#endif
1514 lcd_addr_x = lcd_addr_y = 0;
1515 lcd_must_clear = 1;
1516 lcd_gotoxy();
1517}
1518
1519
1520
1521
1522
1523static ssize_t keypad_read(struct file *file,
1524 char *buf, size_t count, loff_t *ppos)
1525{
1526
1527 unsigned i = *ppos;
1528 char *tmp = buf;
1529
1530 if (keypad_buflen == 0) {
1531 if (file->f_flags & O_NONBLOCK)
1532 return -EAGAIN;
1533
1534 interruptible_sleep_on(&keypad_read_wait);
1535 if (signal_pending(current))
1536 return -EINTR;
1537 }
1538
1539 for (; count-- > 0 && (keypad_buflen > 0); ++i, ++tmp, --keypad_buflen) {
1540 put_user(keypad_buffer[keypad_start], tmp);
1541 keypad_start = (keypad_start + 1) % KEYPAD_BUFFER;
1542 }
1543 *ppos = i;
1544
1545 return tmp - buf;
1546}
1547
1548static int keypad_open(struct inode *inode, struct file *file)
1549{
1550
1551 if (keypad_open_cnt)
1552 return -EBUSY;
1553
1554 if (file->f_mode & FMODE_WRITE)
1555 return -EPERM;
1556
1557 keypad_buflen = 0;
1558 keypad_open_cnt++;
1559 return 0;
1560}
1561
1562static int keypad_release(struct inode *inode, struct file *file)
1563{
1564 keypad_open_cnt--;
1565 return 0;
1566}
1567
1568static struct file_operations keypad_fops = {
1569 .read = keypad_read,
1570 .open = keypad_open,
1571 .release = keypad_release,
1572};
1573
1574static struct miscdevice keypad_dev = {
1575 KEYPAD_MINOR,
1576 "keypad",
1577 &keypad_fops
1578};
1579
1580static void keypad_send_key(char *string, int max_len)
1581{
1582 if (init_in_progress)
1583 return;
1584
1585
1586 if (keypad_open_cnt > 0) {
1587 while (max_len-- && keypad_buflen < KEYPAD_BUFFER && *string) {
1588 keypad_buffer[(keypad_start + keypad_buflen++) %
1589 KEYPAD_BUFFER] = *string++;
1590 }
1591 wake_up_interruptible(&keypad_read_wait);
1592 }
1593}
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604static void phys_scan_contacts(void)
1605{
1606 int bit, bitval;
1607 char oldval;
1608 char bitmask;
1609 char gndmask;
1610
1611 phys_prev = phys_curr;
1612 phys_read_prev = phys_read;
1613 phys_read = 0;
1614
1615 oldval = r_dtr(pprt) | scan_mask_o;
1616 w_dtr(pprt, oldval & ~scan_mask_o);
1617 bitmask = PNL_PINPUT(r_str(pprt)) & scan_mask_i;
1618 w_dtr(pprt, oldval);
1619
1620
1621
1622
1623 gndmask = PNL_PINPUT(r_str(pprt)) & scan_mask_i;
1624
1625 phys_read |= (pmask_t) gndmask << 40;
1626
1627 if (bitmask != gndmask) {
1628
1629
1630
1631 for (bit = 0; bit < 8; bit++) {
1632 bitval = 1 << bit;
1633
1634 if (!(scan_mask_o & bitval))
1635 continue;
1636
1637 w_dtr(pprt, oldval & ~bitval);
1638 bitmask = PNL_PINPUT(r_str(pprt)) & ~gndmask;
1639 phys_read |= (pmask_t) bitmask << (5 * bit);
1640 }
1641 w_dtr(pprt, oldval);
1642 }
1643
1644 phys_curr =
1645 (phys_prev & (phys_read ^ phys_read_prev)) | (phys_read &
1646 ~(phys_read ^
1647 phys_read_prev));
1648}
1649
1650static void panel_process_inputs(void)
1651{
1652 struct list_head *item;
1653 struct logical_input *input;
1654
1655#if 0
1656 printk(KERN_DEBUG
1657 "entering panel_process_inputs with pp=%016Lx & pc=%016Lx\n",
1658 phys_prev, phys_curr);
1659#endif
1660
1661 keypressed = 0;
1662 inputs_stable = 1;
1663 list_for_each(item, &logical_inputs) {
1664 input = list_entry(item, struct logical_input, list);
1665
1666 switch (input->state) {
1667 case INPUT_ST_LOW:
1668 if ((phys_curr & input->mask) != input->value)
1669 break;
1670
1671
1672
1673
1674
1675 if ((phys_prev & input->mask) == input->value)
1676 break;
1677 input->rise_timer = 0;
1678 input->state = INPUT_ST_RISING;
1679
1680 case INPUT_ST_RISING:
1681 if ((phys_curr & input->mask) != input->value) {
1682 input->state = INPUT_ST_LOW;
1683 break;
1684 }
1685 if (input->rise_timer < input->rise_time) {
1686 inputs_stable = 0;
1687 input->rise_timer++;
1688 break;
1689 }
1690 input->high_timer = 0;
1691 input->state = INPUT_ST_HIGH;
1692
1693 case INPUT_ST_HIGH:
1694#if 0
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709 if (((phys_prev & input->mask) == input->value)
1710 && ((phys_curr & input->mask) > input->value)) {
1711 input->state = INPUT_ST_LOW;
1712 break;
1713 }
1714#endif
1715
1716 if ((phys_curr & input->mask) == input->value) {
1717 if ((input->type == INPUT_TYPE_STD)
1718 && (input->high_timer == 0)) {
1719 input->high_timer++;
1720 if (input->u.std.press_fct != NULL)
1721 input->u.std.press_fct(input->u.
1722 std.
1723 press_data);
1724 } else if (input->type == INPUT_TYPE_KBD) {
1725 keypressed = 1;
1726
1727 if (input->high_timer == 0) {
1728 if (input->u.kbd.press_str[0])
1729 keypad_send_key(input->
1730 u.kbd.
1731 press_str,
1732 sizeof
1733 (input->
1734 u.kbd.
1735 press_str));
1736 }
1737
1738 if (input->u.kbd.repeat_str[0]) {
1739 if (input->high_timer >=
1740 KEYPAD_REP_START) {
1741 input->high_timer -=
1742 KEYPAD_REP_DELAY;
1743 keypad_send_key(input->
1744 u.kbd.
1745 repeat_str,
1746 sizeof
1747 (input->
1748 u.kbd.
1749 repeat_str));
1750 }
1751 inputs_stable = 0;
1752 }
1753
1754 if (input->high_timer < 255)
1755 input->high_timer++;
1756 }
1757 break;
1758 } else {
1759
1760 input->state = INPUT_ST_FALLING;
1761 input->fall_timer = 0;
1762 }
1763
1764 case INPUT_ST_FALLING:
1765#if 0
1766
1767 if (((phys_prev & input->mask) == input->value)
1768 && ((phys_curr & input->mask) > input->value)) {
1769 input->state = INPUT_ST_LOW;
1770 break;
1771 }
1772#endif
1773
1774 if ((phys_curr & input->mask) == input->value) {
1775 if (input->type == INPUT_TYPE_KBD) {
1776 keypressed = 1;
1777
1778 if (input->u.kbd.repeat_str[0]) {
1779 if (input->high_timer >= KEYPAD_REP_START)
1780 input->high_timer -= KEYPAD_REP_DELAY;
1781 keypad_send_key(input->u.kbd.repeat_str,
1782 sizeof(input->u.kbd.repeat_str));
1783 inputs_stable = 0;
1784 }
1785
1786 if (input->high_timer < 255)
1787 input->high_timer++;
1788 }
1789 input->state = INPUT_ST_HIGH;
1790 break;
1791 } else if (input->fall_timer >= input->fall_time) {
1792
1793 if (input->type == INPUT_TYPE_STD) {
1794 if (input->u.std.release_fct != NULL)
1795 input->u.std.release_fct(input->u.std.release_data);
1796
1797 } else if (input->type == INPUT_TYPE_KBD) {
1798 if (input->u.kbd.release_str[0])
1799 keypad_send_key(input->u.kbd.release_str,
1800 sizeof(input->u.kbd.release_str));
1801 }
1802
1803 input->state = INPUT_ST_LOW;
1804 break;
1805 } else {
1806 input->fall_timer++;
1807 inputs_stable = 0;
1808 break;
1809 }
1810 }
1811 }
1812}
1813
1814static void panel_scan_timer(void)
1815{
1816 if (keypad_enabled && keypad_initialized) {
1817 if (spin_trylock(&pprt_lock)) {
1818 phys_scan_contacts();
1819 spin_unlock(&pprt_lock);
1820 }
1821
1822 if (!inputs_stable || phys_curr != phys_prev)
1823 panel_process_inputs();
1824 }
1825
1826 if (lcd_enabled && lcd_initialized) {
1827 if (keypressed) {
1828 if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0))
1829 lcd_backlight(1);
1830 light_tempo = FLASH_LIGHT_TEMPO;
1831 } else if (light_tempo > 0) {
1832 light_tempo--;
1833 if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0))
1834 lcd_backlight(0);
1835 }
1836 }
1837
1838 mod_timer(&scan_timer, jiffies + INPUT_POLL_TIME);
1839}
1840
1841static void init_scan_timer(void)
1842{
1843 if (scan_timer.function != NULL)
1844 return;
1845
1846 init_timer(&scan_timer);
1847 scan_timer.expires = jiffies + INPUT_POLL_TIME;
1848 scan_timer.data = 0;
1849 scan_timer.function = (void *)&panel_scan_timer;
1850 add_timer(&scan_timer);
1851}
1852
1853
1854
1855
1856
1857
1858static int input_name2mask(char *name, pmask_t *mask, pmask_t *value,
1859 char *imask, char *omask)
1860{
1861 static char sigtab[10] = "EeSsPpAaBb";
1862 char im, om;
1863 pmask_t m, v;
1864
1865 om = im = m = v = 0ULL;
1866 while (*name) {
1867 int in, out, bit, neg;
1868 for (in = 0; (in < sizeof(sigtab)) && (sigtab[in] != *name); in++)
1869 ;
1870 if (in >= sizeof(sigtab))
1871 return 0;
1872 neg = (in & 1);
1873 in >>= 1;
1874 im |= (1 << in);
1875
1876 name++;
1877 if (isdigit(*name)) {
1878 out = *name - '0';
1879 om |= (1 << out);
1880 } else if (*name == '-')
1881 out = 8;
1882 else
1883 return 0;
1884
1885 bit = (out * 5) + in;
1886
1887 m |= 1ULL << bit;
1888 if (!neg)
1889 v |= 1ULL << bit;
1890 name++;
1891 }
1892 *mask = m;
1893 *value = v;
1894 if (imask)
1895 *imask |= im;
1896 if (omask)
1897 *omask |= om;
1898 return 1;
1899}
1900
1901
1902
1903
1904
1905static struct logical_input *panel_bind_key(char *name, char *press,
1906 char *repeat, char *release)
1907{
1908 struct logical_input *key;
1909
1910 key = kmalloc(sizeof(struct logical_input), GFP_KERNEL);
1911 if (!key) {
1912 printk(KERN_ERR "panel: not enough memory\n");
1913 return NULL;
1914 }
1915 memset(key, 0, sizeof(struct logical_input));
1916 if (!input_name2mask(name, &key->mask, &key->value, &scan_mask_i,
1917 &scan_mask_o))
1918 return NULL;
1919
1920 key->type = INPUT_TYPE_KBD;
1921 key->state = INPUT_ST_LOW;
1922 key->rise_time = 1;
1923 key->fall_time = 1;
1924
1925#if 0
1926 printk(KERN_DEBUG "bind: <%s> : m=%016Lx v=%016Lx\n", name, key->mask,
1927 key->value);
1928#endif
1929 strncpy(key->u.kbd.press_str, press, sizeof(key->u.kbd.press_str));
1930 strncpy(key->u.kbd.repeat_str, repeat, sizeof(key->u.kbd.repeat_str));
1931 strncpy(key->u.kbd.release_str, release,
1932 sizeof(key->u.kbd.release_str));
1933 list_add(&key->list, &logical_inputs);
1934 return key;
1935}
1936
1937#if 0
1938
1939
1940
1941
1942
1943static struct logical_input *panel_bind_callback(char *name,
1944 void (*press_fct) (int),
1945 int press_data,
1946 void (*release_fct) (int),
1947 int release_data)
1948{
1949 struct logical_input *callback;
1950
1951 callback = kmalloc(sizeof(struct logical_input), GFP_KERNEL);
1952 if (!callback) {
1953 printk(KERN_ERR "panel: not enough memory\n");
1954 return NULL;
1955 }
1956 memset(callback, 0, sizeof(struct logical_input));
1957 if (!input_name2mask(name, &callback->mask, &callback->value,
1958 &scan_mask_i, &scan_mask_o))
1959 return NULL;
1960
1961 callback->type = INPUT_TYPE_STD;
1962 callback->state = INPUT_ST_LOW;
1963 callback->rise_time = 1;
1964 callback->fall_time = 1;
1965 callback->u.std.press_fct = press_fct;
1966 callback->u.std.press_data = press_data;
1967 callback->u.std.release_fct = release_fct;
1968 callback->u.std.release_data = release_data;
1969 list_add(&callback->list, &logical_inputs);
1970 return callback;
1971}
1972#endif
1973
1974static void keypad_init(void)
1975{
1976 int keynum;
1977 init_waitqueue_head(&keypad_read_wait);
1978 keypad_buflen = 0;
1979
1980
1981
1982 for (keynum = 0; keypad_profile[keynum][0][0]; keynum++) {
1983 panel_bind_key(keypad_profile[keynum][0],
1984 keypad_profile[keynum][1],
1985 keypad_profile[keynum][2],
1986 keypad_profile[keynum][3]);
1987 }
1988
1989 init_scan_timer();
1990 keypad_initialized = 1;
1991}
1992
1993
1994
1995
1996
1997static int panel_notify_sys(struct notifier_block *this, unsigned long code,
1998 void *unused)
1999{
2000 if (lcd_enabled && lcd_initialized) {
2001 switch (code) {
2002 case SYS_DOWN:
2003 panel_lcd_print
2004 ("\x0cReloading\nSystem...\x1b[Lc\x1b[Lb\x1b[L+");
2005 break;
2006 case SYS_HALT:
2007 panel_lcd_print
2008 ("\x0cSystem Halted.\x1b[Lc\x1b[Lb\x1b[L+");
2009 break;
2010 case SYS_POWER_OFF:
2011 panel_lcd_print("\x0cPower off.\x1b[Lc\x1b[Lb\x1b[L+");
2012 break;
2013 default:
2014 break;
2015 }
2016 }
2017 return NOTIFY_DONE;
2018}
2019
2020static struct notifier_block panel_notifier = {
2021 panel_notify_sys,
2022 NULL,
2023 0
2024};
2025
2026static void panel_attach(struct parport *port)
2027{
2028 if (port->number != parport)
2029 return;
2030
2031 if (pprt) {
2032 printk(KERN_ERR
2033 "panel_attach(): port->number=%d parport=%d, already registered !\n",
2034 port->number, parport);
2035 return;
2036 }
2037
2038 pprt = parport_register_device(port, "panel", NULL, NULL,
2039 NULL,
2040
2041 0, (void *)&pprt);
2042
2043 if (parport_claim(pprt)) {
2044 printk(KERN_ERR
2045 "Panel: could not claim access to parport%d. Aborting.\n",
2046 parport);
2047 return;
2048 }
2049
2050
2051 if (lcd_enabled) {
2052 lcd_init();
2053 misc_register(&lcd_dev);
2054 }
2055
2056 if (keypad_enabled) {
2057 keypad_init();
2058 misc_register(&keypad_dev);
2059 }
2060}
2061
2062static void panel_detach(struct parport *port)
2063{
2064 if (port->number != parport)
2065 return;
2066
2067 if (!pprt) {
2068 printk(KERN_ERR
2069 "panel_detach(): port->number=%d parport=%d, nothing to unregister.\n",
2070 port->number, parport);
2071 return;
2072 }
2073
2074 if (keypad_enabled && keypad_initialized) {
2075 misc_deregister(&keypad_dev);
2076 keypad_initialized = 0;
2077 }
2078
2079 if (lcd_enabled && lcd_initialized) {
2080 misc_deregister(&lcd_dev);
2081 lcd_initialized = 0;
2082 }
2083
2084 parport_release(pprt);
2085 parport_unregister_device(pprt);
2086 pprt = NULL;
2087}
2088
2089static struct parport_driver panel_driver = {
2090 .name = "panel",
2091 .attach = panel_attach,
2092 .detach = panel_detach,
2093};
2094
2095
2096int panel_init(void)
2097{
2098
2099 if (keypad_type < 0)
2100 keypad_type = keypad_enabled;
2101
2102 if (lcd_type < 0)
2103 lcd_type = lcd_enabled;
2104
2105 if (parport < 0)
2106 parport = DEFAULT_PARPORT;
2107
2108
2109 switch (profile) {
2110 case PANEL_PROFILE_CUSTOM:
2111 if (keypad_type < 0)
2112 keypad_type = DEFAULT_KEYPAD;
2113 if (lcd_type < 0)
2114 lcd_type = DEFAULT_LCD;
2115 break;
2116 case PANEL_PROFILE_OLD:
2117 if (keypad_type < 0)
2118 keypad_type = KEYPAD_TYPE_OLD;
2119 if (lcd_type < 0)
2120 lcd_type = LCD_TYPE_OLD;
2121 if (lcd_width < 0)
2122 lcd_width = 16;
2123 if (lcd_hwidth < 0)
2124 lcd_hwidth = 16;
2125 break;
2126 case PANEL_PROFILE_NEW:
2127 if (keypad_type < 0)
2128 keypad_type = KEYPAD_TYPE_NEW;
2129 if (lcd_type < 0)
2130 lcd_type = LCD_TYPE_KS0074;
2131 break;
2132 case PANEL_PROFILE_HANTRONIX:
2133 if (keypad_type < 0)
2134 keypad_type = KEYPAD_TYPE_NONE;
2135 if (lcd_type < 0)
2136 lcd_type = LCD_TYPE_HANTRONIX;
2137 break;
2138 case PANEL_PROFILE_NEXCOM:
2139 if (keypad_type < 0)
2140 keypad_type = KEYPAD_TYPE_NEXCOM;
2141 if (lcd_type < 0)
2142 lcd_type = LCD_TYPE_NEXCOM;
2143 break;
2144 case PANEL_PROFILE_LARGE:
2145 if (keypad_type < 0)
2146 keypad_type = KEYPAD_TYPE_OLD;
2147 if (lcd_type < 0)
2148 lcd_type = LCD_TYPE_OLD;
2149 break;
2150 }
2151
2152 lcd_enabled = (lcd_type > 0);
2153 keypad_enabled = (keypad_type > 0);
2154
2155 switch (keypad_type) {
2156 case KEYPAD_TYPE_OLD:
2157 keypad_profile = old_keypad_profile;
2158 break;
2159 case KEYPAD_TYPE_NEW:
2160 keypad_profile = new_keypad_profile;
2161 break;
2162 case KEYPAD_TYPE_NEXCOM:
2163 keypad_profile = nexcom_keypad_profile;
2164 break;
2165 default:
2166 keypad_profile = NULL;
2167 break;
2168 }
2169
2170
2171 init_in_progress = 1;
2172
2173 if (parport_register_driver(&panel_driver)) {
2174 printk(KERN_ERR
2175 "Panel: could not register with parport. Aborting.\n");
2176 return -EIO;
2177 }
2178
2179 if (!lcd_enabled && !keypad_enabled) {
2180
2181 if (pprt) {
2182 parport_release(pprt);
2183 parport_unregister_device(pprt);
2184 }
2185 parport_unregister_driver(&panel_driver);
2186 printk(KERN_ERR "Panel driver version " PANEL_VERSION
2187 " disabled.\n");
2188 return -ENODEV;
2189 }
2190
2191 register_reboot_notifier(&panel_notifier);
2192
2193 if (pprt)
2194 printk(KERN_INFO "Panel driver version " PANEL_VERSION
2195 " registered on parport%d (io=0x%lx).\n", parport,
2196 pprt->port->base);
2197 else
2198 printk(KERN_INFO "Panel driver version " PANEL_VERSION
2199 " not yet registered\n");
2200
2201 init_in_progress = 0;
2202 return 0;
2203}
2204
2205static int __init panel_init_module(void)
2206{
2207 return panel_init();
2208}
2209
2210static void __exit panel_cleanup_module(void)
2211{
2212 unregister_reboot_notifier(&panel_notifier);
2213
2214 if (scan_timer.function != NULL)
2215 del_timer(&scan_timer);
2216
2217 if (pprt != NULL) {
2218 if (keypad_enabled) {
2219 misc_deregister(&keypad_dev);
2220 keypad_initialized = 0;
2221 }
2222
2223 if (lcd_enabled) {
2224 panel_lcd_print("\x0cLCD driver " PANEL_VERSION
2225 "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-");
2226 misc_deregister(&lcd_dev);
2227 lcd_initialized = 0;
2228 }
2229
2230
2231 parport_release(pprt);
2232 parport_unregister_device(pprt);
2233 }
2234 parport_unregister_driver(&panel_driver);
2235}
2236
2237module_init(panel_init_module);
2238module_exit(panel_cleanup_module);
2239MODULE_AUTHOR("Willy Tarreau");
2240MODULE_LICENSE("GPL");
2241
2242
2243
2244
2245
2246
2247
2248