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