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 udelay(40);
829 spin_unlock_irq(&pprt_lock);
830}
831
832
833static void lcd_write_data_s(int data)
834{
835 spin_lock_irq(&pprt_lock);
836 lcd_send_serial(0x5F);
837 lcd_send_serial(data & 0x0F);
838 lcd_send_serial((data >> 4) & 0x0F);
839 udelay(40);
840 spin_unlock_irq(&pprt_lock);
841}
842
843
844static void lcd_write_cmd_p8(int cmd)
845{
846 spin_lock_irq(&pprt_lock);
847
848 w_dtr(pprt, cmd);
849 udelay(20);
850
851 bits.e = BIT_SET;
852 bits.rs = BIT_CLR;
853 bits.rw = BIT_CLR;
854 set_ctrl_bits();
855
856 udelay(40);
857
858 bits.e = BIT_CLR;
859 set_ctrl_bits();
860
861 udelay(120);
862 spin_unlock_irq(&pprt_lock);
863}
864
865
866static void lcd_write_data_p8(int data)
867{
868 spin_lock_irq(&pprt_lock);
869
870 w_dtr(pprt, data);
871 udelay(20);
872
873 bits.e = BIT_SET;
874 bits.rs = BIT_SET;
875 bits.rw = BIT_CLR;
876 set_ctrl_bits();
877
878 udelay(40);
879
880 bits.e = BIT_CLR;
881 set_ctrl_bits();
882
883 udelay(45);
884 spin_unlock_irq(&pprt_lock);
885}
886
887
888static void lcd_write_cmd_tilcd(int cmd)
889{
890 spin_lock_irq(&pprt_lock);
891
892 w_ctr(pprt, cmd);
893 udelay(60);
894 spin_unlock_irq(&pprt_lock);
895}
896
897
898static void lcd_write_data_tilcd(int data)
899{
900 spin_lock_irq(&pprt_lock);
901
902 w_dtr(pprt, data);
903 udelay(60);
904 spin_unlock_irq(&pprt_lock);
905}
906
907static void lcd_gotoxy(void)
908{
909 lcd_write_cmd(LCD_CMD_SET_DDRAM_ADDR
910 | (lcd.addr.y ? lcd.hwidth : 0)
911
912
913
914
915 | ((lcd.addr.x < lcd.bwidth) ? lcd.addr.x &
916 (lcd.hwidth - 1) : lcd.bwidth - 1));
917}
918
919static void lcd_print(char c)
920{
921 if (lcd.addr.x < lcd.bwidth) {
922 if (lcd_char_conv)
923 c = lcd_char_conv[(unsigned char)c];
924 lcd_write_data(c);
925 lcd.addr.x++;
926 }
927
928 if (lcd.addr.x == lcd.bwidth)
929 lcd_gotoxy();
930}
931
932
933static void lcd_clear_fast_s(void)
934{
935 int pos;
936
937 lcd.addr.x = 0;
938 lcd.addr.y = 0;
939 lcd_gotoxy();
940
941 spin_lock_irq(&pprt_lock);
942 for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) {
943 lcd_send_serial(0x5F);
944 lcd_send_serial(' ' & 0x0F);
945 lcd_send_serial((' ' >> 4) & 0x0F);
946 udelay(40);
947 }
948 spin_unlock_irq(&pprt_lock);
949
950 lcd.addr.x = 0;
951 lcd.addr.y = 0;
952 lcd_gotoxy();
953}
954
955
956static void lcd_clear_fast_p8(void)
957{
958 int pos;
959
960 lcd.addr.x = 0;
961 lcd.addr.y = 0;
962 lcd_gotoxy();
963
964 spin_lock_irq(&pprt_lock);
965 for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) {
966
967 w_dtr(pprt, ' ');
968
969
970 udelay(20);
971
972 bits.e = BIT_SET;
973 bits.rs = BIT_SET;
974 bits.rw = BIT_CLR;
975 set_ctrl_bits();
976
977
978 udelay(40);
979
980 bits.e = BIT_CLR;
981 set_ctrl_bits();
982
983
984 udelay(45);
985 }
986 spin_unlock_irq(&pprt_lock);
987
988 lcd.addr.x = 0;
989 lcd.addr.y = 0;
990 lcd_gotoxy();
991}
992
993
994static void lcd_clear_fast_tilcd(void)
995{
996 int pos;
997
998 lcd.addr.x = 0;
999 lcd.addr.y = 0;
1000 lcd_gotoxy();
1001
1002 spin_lock_irq(&pprt_lock);
1003 for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) {
1004
1005 w_dtr(pprt, ' ');
1006 udelay(60);
1007 }
1008
1009 spin_unlock_irq(&pprt_lock);
1010
1011 lcd.addr.x = 0;
1012 lcd.addr.y = 0;
1013 lcd_gotoxy();
1014}
1015
1016
1017static void lcd_clear_display(void)
1018{
1019 lcd_write_cmd(LCD_CMD_DISPLAY_CLEAR);
1020 lcd.addr.x = 0;
1021 lcd.addr.y = 0;
1022
1023 long_sleep(15);
1024}
1025
1026static void lcd_init_display(void)
1027{
1028 lcd.flags = ((lcd.height > 1) ? LCD_FLAG_N : 0)
1029 | LCD_FLAG_D | LCD_FLAG_C | LCD_FLAG_B;
1030
1031 long_sleep(20);
1032
1033
1034 lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS);
1035 long_sleep(10);
1036 lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS);
1037 long_sleep(10);
1038 lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS);
1039 long_sleep(10);
1040
1041
1042 lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS
1043 | ((lcd.flags & LCD_FLAG_F) ? LCD_CMD_FONT_5X10_DOTS : 0)
1044 | ((lcd.flags & LCD_FLAG_N) ? LCD_CMD_TWO_LINES : 0)
1045 );
1046 long_sleep(10);
1047
1048
1049 lcd_write_cmd(LCD_CMD_DISPLAY_CTRL);
1050 long_sleep(10);
1051
1052 lcd_write_cmd(LCD_CMD_DISPLAY_CTRL
1053 | ((lcd.flags & LCD_FLAG_D) ? LCD_CMD_DISPLAY_ON : 0)
1054 | ((lcd.flags & LCD_FLAG_C) ? LCD_CMD_CURSOR_ON : 0)
1055 | ((lcd.flags & LCD_FLAG_B) ? LCD_CMD_BLINK_ON : 0)
1056 );
1057
1058 lcd_backlight((lcd.flags & LCD_FLAG_L) ? 1 : 0);
1059
1060 long_sleep(10);
1061
1062
1063 lcd_write_cmd(LCD_CMD_ENTRY_MODE | LCD_CMD_CURSOR_INC);
1064
1065 lcd_clear_display();
1066}
1067
1068
1069
1070
1071
1072
1073
1074
1075static inline int handle_lcd_special_code(void)
1076{
1077
1078
1079 int processed = 0;
1080
1081 char *esc = lcd.esc_seq.buf + 2;
1082 int oldflags = lcd.flags;
1083
1084
1085 switch (*esc) {
1086 case 'D':
1087 lcd.flags |= LCD_FLAG_D;
1088 processed = 1;
1089 break;
1090 case 'd':
1091 lcd.flags &= ~LCD_FLAG_D;
1092 processed = 1;
1093 break;
1094 case 'C':
1095 lcd.flags |= LCD_FLAG_C;
1096 processed = 1;
1097 break;
1098 case 'c':
1099 lcd.flags &= ~LCD_FLAG_C;
1100 processed = 1;
1101 break;
1102 case 'B':
1103 lcd.flags |= LCD_FLAG_B;
1104 processed = 1;
1105 break;
1106 case 'b':
1107 lcd.flags &= ~LCD_FLAG_B;
1108 processed = 1;
1109 break;
1110 case '+':
1111 lcd.flags |= LCD_FLAG_L;
1112 processed = 1;
1113 break;
1114 case '-':
1115 lcd.flags &= ~LCD_FLAG_L;
1116 processed = 1;
1117 break;
1118 case '*':
1119
1120 if (scan_timer.function) {
1121 if (lcd.light_tempo == 0 &&
1122 ((lcd.flags & LCD_FLAG_L) == 0))
1123 lcd_backlight(1);
1124 lcd.light_tempo = FLASH_LIGHT_TEMPO;
1125 }
1126 processed = 1;
1127 break;
1128 case 'f':
1129 lcd.flags &= ~LCD_FLAG_F;
1130 processed = 1;
1131 break;
1132 case 'F':
1133 lcd.flags |= LCD_FLAG_F;
1134 processed = 1;
1135 break;
1136 case 'n':
1137 lcd.flags &= ~LCD_FLAG_N;
1138 processed = 1;
1139 break;
1140 case 'N':
1141 lcd.flags |= LCD_FLAG_N;
1142 break;
1143 case 'l':
1144 if (lcd.addr.x > 0) {
1145
1146 if (lcd.addr.x < lcd.bwidth)
1147 lcd_write_cmd(LCD_CMD_SHIFT);
1148 lcd.addr.x--;
1149 }
1150 processed = 1;
1151 break;
1152 case 'r':
1153 if (lcd.addr.x < lcd.width) {
1154
1155 if (lcd.addr.x < (lcd.bwidth - 1))
1156 lcd_write_cmd(LCD_CMD_SHIFT |
1157 LCD_CMD_SHIFT_RIGHT);
1158 lcd.addr.x++;
1159 }
1160 processed = 1;
1161 break;
1162 case 'L':
1163 lcd_write_cmd(LCD_CMD_SHIFT | LCD_CMD_DISPLAY_SHIFT);
1164 processed = 1;
1165 break;
1166 case 'R':
1167 lcd_write_cmd(LCD_CMD_SHIFT | LCD_CMD_DISPLAY_SHIFT |
1168 LCD_CMD_SHIFT_RIGHT);
1169 processed = 1;
1170 break;
1171 case 'k': {
1172 int x;
1173
1174 for (x = lcd.addr.x; x < lcd.bwidth; x++)
1175 lcd_write_data(' ');
1176
1177
1178 lcd_gotoxy();
1179 processed = 1;
1180 break;
1181 }
1182 case 'I':
1183 lcd_init_display();
1184 processed = 1;
1185 break;
1186 case 'G': {
1187
1188
1189
1190
1191
1192
1193
1194
1195 unsigned char cgbytes[8];
1196 unsigned char cgaddr;
1197 int cgoffset;
1198 int shift;
1199 char value;
1200 int addr;
1201
1202 if (!strchr(esc, ';'))
1203 break;
1204
1205 esc++;
1206
1207 cgaddr = *(esc++) - '0';
1208 if (cgaddr > 7) {
1209 processed = 1;
1210 break;
1211 }
1212
1213 cgoffset = 0;
1214 shift = 0;
1215 value = 0;
1216 while (*esc && cgoffset < 8) {
1217 shift ^= 4;
1218 if (*esc >= '0' && *esc <= '9') {
1219 value |= (*esc - '0') << shift;
1220 } else if (*esc >= 'A' && *esc <= 'Z') {
1221 value |= (*esc - 'A' + 10) << shift;
1222 } else if (*esc >= 'a' && *esc <= 'z') {
1223 value |= (*esc - 'a' + 10) << shift;
1224 } else {
1225 esc++;
1226 continue;
1227 }
1228
1229 if (shift == 0) {
1230 cgbytes[cgoffset++] = value;
1231 value = 0;
1232 }
1233
1234 esc++;
1235 }
1236
1237 lcd_write_cmd(LCD_CMD_SET_CGRAM_ADDR | (cgaddr * 8));
1238 for (addr = 0; addr < cgoffset; addr++)
1239 lcd_write_data(cgbytes[addr]);
1240
1241
1242 lcd_gotoxy();
1243 processed = 1;
1244 break;
1245 }
1246 case 'x':
1247 case 'y':
1248 if (!strchr(esc, ';'))
1249 break;
1250
1251 while (*esc) {
1252 if (*esc == 'x') {
1253 esc++;
1254 if (kstrtoul(esc, 10, &lcd.addr.x) < 0)
1255 break;
1256 } else if (*esc == 'y') {
1257 esc++;
1258 if (kstrtoul(esc, 10, &lcd.addr.y) < 0)
1259 break;
1260 } else {
1261 break;
1262 }
1263 }
1264
1265 lcd_gotoxy();
1266 processed = 1;
1267 break;
1268 }
1269
1270
1271
1272 if (oldflags != lcd.flags) {
1273
1274 if ((oldflags ^ lcd.flags) &
1275 (LCD_FLAG_B | LCD_FLAG_C | LCD_FLAG_D))
1276
1277 lcd_write_cmd(LCD_CMD_DISPLAY_CTRL
1278 | ((lcd.flags & LCD_FLAG_D)
1279 ? LCD_CMD_DISPLAY_ON : 0)
1280 | ((lcd.flags & LCD_FLAG_C)
1281 ? LCD_CMD_CURSOR_ON : 0)
1282 | ((lcd.flags & LCD_FLAG_B)
1283 ? LCD_CMD_BLINK_ON : 0));
1284
1285 else if ((oldflags ^ lcd.flags) & (LCD_FLAG_F | LCD_FLAG_N))
1286 lcd_write_cmd(LCD_CMD_FUNCTION_SET
1287 | LCD_CMD_DATA_LEN_8BITS
1288 | ((lcd.flags & LCD_FLAG_F)
1289 ? LCD_CMD_TWO_LINES : 0)
1290 | ((lcd.flags & LCD_FLAG_N)
1291 ? LCD_CMD_FONT_5X10_DOTS
1292 : 0));
1293
1294 else if ((oldflags ^ lcd.flags) & (LCD_FLAG_L)) {
1295 if (lcd.flags & (LCD_FLAG_L))
1296 lcd_backlight(1);
1297 else if (lcd.light_tempo == 0)
1298
1299
1300
1301
1302 lcd_backlight(0);
1303 }
1304 }
1305
1306 return processed;
1307}
1308
1309static void lcd_write_char(char c)
1310{
1311
1312 if ((c != '\n') && lcd.esc_seq.len >= 0) {
1313
1314 lcd.esc_seq.buf[lcd.esc_seq.len++] = c;
1315 lcd.esc_seq.buf[lcd.esc_seq.len] = 0;
1316 } else {
1317
1318 lcd.esc_seq.len = -1;
1319
1320 switch (c) {
1321 case LCD_ESCAPE_CHAR:
1322
1323 lcd.esc_seq.len = 0;
1324 lcd.esc_seq.buf[lcd.esc_seq.len] = 0;
1325 break;
1326 case '\b':
1327
1328 if (lcd.addr.x > 0) {
1329
1330
1331
1332
1333 if (lcd.addr.x < lcd.bwidth)
1334
1335 lcd_write_cmd(LCD_CMD_SHIFT);
1336 lcd.addr.x--;
1337 }
1338
1339 lcd_write_data(' ');
1340
1341 lcd_write_cmd(LCD_CMD_SHIFT);
1342 break;
1343 case '\014':
1344
1345 lcd_clear_fast();
1346 break;
1347 case '\n':
1348
1349
1350
1351
1352 for (; lcd.addr.x < lcd.bwidth; lcd.addr.x++)
1353 lcd_write_data(' ');
1354 lcd.addr.x = 0;
1355 lcd.addr.y = (lcd.addr.y + 1) % lcd.height;
1356 lcd_gotoxy();
1357 break;
1358 case '\r':
1359
1360 lcd.addr.x = 0;
1361 lcd_gotoxy();
1362 break;
1363 case '\t':
1364
1365 lcd_print(' ');
1366 break;
1367 default:
1368
1369 lcd_print(c);
1370 break;
1371 }
1372 }
1373
1374
1375
1376
1377
1378 if (lcd.esc_seq.len >= 2) {
1379 int processed = 0;
1380
1381 if (!strcmp(lcd.esc_seq.buf, "[2J")) {
1382
1383 lcd_clear_fast();
1384 processed = 1;
1385 } else if (!strcmp(lcd.esc_seq.buf, "[H")) {
1386
1387 lcd.addr.x = 0;
1388 lcd.addr.y = 0;
1389 lcd_gotoxy();
1390 processed = 1;
1391 }
1392
1393 else if ((lcd.esc_seq.len >= 3) &&
1394 (lcd.esc_seq.buf[0] == '[') &&
1395 (lcd.esc_seq.buf[1] == 'L')) {
1396 processed = handle_lcd_special_code();
1397 }
1398
1399
1400
1401
1402
1403
1404 if (processed || (lcd.esc_seq.len >= LCD_ESCAPE_LEN))
1405 lcd.esc_seq.len = -1;
1406 }
1407}
1408
1409static ssize_t lcd_write(struct file *file,
1410 const char __user *buf, size_t count, loff_t *ppos)
1411{
1412 const char __user *tmp = buf;
1413 char c;
1414
1415 for (; count-- > 0; (*ppos)++, tmp++) {
1416 if (!in_interrupt() && (((count + 1) & 0x1f) == 0))
1417
1418
1419
1420
1421 schedule();
1422
1423 if (get_user(c, tmp))
1424 return -EFAULT;
1425
1426 lcd_write_char(c);
1427 }
1428
1429 return tmp - buf;
1430}
1431
1432static int lcd_open(struct inode *inode, struct file *file)
1433{
1434 if (!atomic_dec_and_test(&lcd_available))
1435 return -EBUSY;
1436
1437 if (file->f_mode & FMODE_READ)
1438 return -EPERM;
1439
1440 if (lcd.must_clear) {
1441 lcd_clear_display();
1442 lcd.must_clear = false;
1443 }
1444 return nonseekable_open(inode, file);
1445}
1446
1447static int lcd_release(struct inode *inode, struct file *file)
1448{
1449 atomic_inc(&lcd_available);
1450 return 0;
1451}
1452
1453static const struct file_operations lcd_fops = {
1454 .write = lcd_write,
1455 .open = lcd_open,
1456 .release = lcd_release,
1457 .llseek = no_llseek,
1458};
1459
1460static struct miscdevice lcd_dev = {
1461 .minor = LCD_MINOR,
1462 .name = "lcd",
1463 .fops = &lcd_fops,
1464};
1465
1466
1467static void panel_lcd_print(const char *s)
1468{
1469 const char *tmp = s;
1470 int count = strlen(s);
1471
1472 if (lcd.enabled && lcd.initialized) {
1473 for (; count-- > 0; tmp++) {
1474 if (!in_interrupt() && (((count + 1) & 0x1f) == 0))
1475
1476
1477
1478
1479 schedule();
1480
1481 lcd_write_char(*tmp);
1482 }
1483 }
1484}
1485
1486
1487static void lcd_init(void)
1488{
1489 switch (selected_lcd_type) {
1490 case LCD_TYPE_OLD:
1491
1492 lcd.proto = LCD_PROTO_PARALLEL;
1493 lcd.charset = LCD_CHARSET_NORMAL;
1494 lcd.pins.e = PIN_STROBE;
1495 lcd.pins.rs = PIN_AUTOLF;
1496
1497 lcd.width = 40;
1498 lcd.bwidth = 40;
1499 lcd.hwidth = 64;
1500 lcd.height = 2;
1501 break;
1502 case LCD_TYPE_KS0074:
1503
1504 lcd.proto = LCD_PROTO_SERIAL;
1505 lcd.charset = LCD_CHARSET_KS0074;
1506 lcd.pins.bl = PIN_AUTOLF;
1507 lcd.pins.cl = PIN_STROBE;
1508 lcd.pins.da = PIN_D0;
1509
1510 lcd.width = 16;
1511 lcd.bwidth = 40;
1512 lcd.hwidth = 16;
1513 lcd.height = 2;
1514 break;
1515 case LCD_TYPE_NEXCOM:
1516
1517 lcd.proto = LCD_PROTO_PARALLEL;
1518 lcd.charset = LCD_CHARSET_NORMAL;
1519 lcd.pins.e = PIN_AUTOLF;
1520 lcd.pins.rs = PIN_SELECP;
1521 lcd.pins.rw = PIN_INITP;
1522
1523 lcd.width = 16;
1524 lcd.bwidth = 40;
1525 lcd.hwidth = 64;
1526 lcd.height = 2;
1527 break;
1528 case LCD_TYPE_CUSTOM:
1529
1530 lcd.proto = DEFAULT_LCD_PROTO;
1531 lcd.charset = DEFAULT_LCD_CHARSET;
1532
1533 break;
1534 case LCD_TYPE_HANTRONIX:
1535
1536 default:
1537 lcd.proto = LCD_PROTO_PARALLEL;
1538 lcd.charset = LCD_CHARSET_NORMAL;
1539 lcd.pins.e = PIN_STROBE;
1540 lcd.pins.rs = PIN_SELECP;
1541
1542 lcd.width = 16;
1543 lcd.bwidth = 40;
1544 lcd.hwidth = 64;
1545 lcd.height = 2;
1546 break;
1547 }
1548
1549
1550 if (lcd_height != NOT_SET)
1551 lcd.height = lcd_height;
1552 if (lcd_width != NOT_SET)
1553 lcd.width = lcd_width;
1554 if (lcd_bwidth != NOT_SET)
1555 lcd.bwidth = lcd_bwidth;
1556 if (lcd_hwidth != NOT_SET)
1557 lcd.hwidth = lcd_hwidth;
1558 if (lcd_charset != NOT_SET)
1559 lcd.charset = lcd_charset;
1560 if (lcd_proto != NOT_SET)
1561 lcd.proto = lcd_proto;
1562 if (lcd_e_pin != PIN_NOT_SET)
1563 lcd.pins.e = lcd_e_pin;
1564 if (lcd_rs_pin != PIN_NOT_SET)
1565 lcd.pins.rs = lcd_rs_pin;
1566 if (lcd_rw_pin != PIN_NOT_SET)
1567 lcd.pins.rw = lcd_rw_pin;
1568 if (lcd_cl_pin != PIN_NOT_SET)
1569 lcd.pins.cl = lcd_cl_pin;
1570 if (lcd_da_pin != PIN_NOT_SET)
1571 lcd.pins.da = lcd_da_pin;
1572 if (lcd_bl_pin != PIN_NOT_SET)
1573 lcd.pins.bl = lcd_bl_pin;
1574
1575
1576 if (lcd.width <= 0)
1577 lcd.width = DEFAULT_LCD_WIDTH;
1578 if (lcd.bwidth <= 0)
1579 lcd.bwidth = DEFAULT_LCD_BWIDTH;
1580 if (lcd.hwidth <= 0)
1581 lcd.hwidth = DEFAULT_LCD_HWIDTH;
1582 if (lcd.height <= 0)
1583 lcd.height = DEFAULT_LCD_HEIGHT;
1584
1585 if (lcd.proto == LCD_PROTO_SERIAL) {
1586 lcd_write_cmd = lcd_write_cmd_s;
1587 lcd_write_data = lcd_write_data_s;
1588 lcd_clear_fast = lcd_clear_fast_s;
1589
1590 if (lcd.pins.cl == PIN_NOT_SET)
1591 lcd.pins.cl = DEFAULT_LCD_PIN_SCL;
1592 if (lcd.pins.da == PIN_NOT_SET)
1593 lcd.pins.da = DEFAULT_LCD_PIN_SDA;
1594
1595 } else if (lcd.proto == LCD_PROTO_PARALLEL) {
1596 lcd_write_cmd = lcd_write_cmd_p8;
1597 lcd_write_data = lcd_write_data_p8;
1598 lcd_clear_fast = lcd_clear_fast_p8;
1599
1600 if (lcd.pins.e == PIN_NOT_SET)
1601 lcd.pins.e = DEFAULT_LCD_PIN_E;
1602 if (lcd.pins.rs == PIN_NOT_SET)
1603 lcd.pins.rs = DEFAULT_LCD_PIN_RS;
1604 if (lcd.pins.rw == PIN_NOT_SET)
1605 lcd.pins.rw = DEFAULT_LCD_PIN_RW;
1606 } else {
1607 lcd_write_cmd = lcd_write_cmd_tilcd;
1608 lcd_write_data = lcd_write_data_tilcd;
1609 lcd_clear_fast = lcd_clear_fast_tilcd;
1610 }
1611
1612 if (lcd.pins.bl == PIN_NOT_SET)
1613 lcd.pins.bl = DEFAULT_LCD_PIN_BL;
1614
1615 if (lcd.pins.e == PIN_NOT_SET)
1616 lcd.pins.e = PIN_NONE;
1617 if (lcd.pins.rs == PIN_NOT_SET)
1618 lcd.pins.rs = PIN_NONE;
1619 if (lcd.pins.rw == PIN_NOT_SET)
1620 lcd.pins.rw = PIN_NONE;
1621 if (lcd.pins.bl == PIN_NOT_SET)
1622 lcd.pins.bl = PIN_NONE;
1623 if (lcd.pins.cl == PIN_NOT_SET)
1624 lcd.pins.cl = PIN_NONE;
1625 if (lcd.pins.da == PIN_NOT_SET)
1626 lcd.pins.da = PIN_NONE;
1627
1628 if (lcd.charset == NOT_SET)
1629 lcd.charset = DEFAULT_LCD_CHARSET;
1630
1631 if (lcd.charset == LCD_CHARSET_KS0074)
1632 lcd_char_conv = lcd_char_conv_ks0074;
1633 else
1634 lcd_char_conv = NULL;
1635
1636 if (lcd.pins.bl != PIN_NONE)
1637 init_scan_timer();
1638
1639 pin_to_bits(lcd.pins.e, lcd_bits[LCD_PORT_D][LCD_BIT_E],
1640 lcd_bits[LCD_PORT_C][LCD_BIT_E]);
1641 pin_to_bits(lcd.pins.rs, lcd_bits[LCD_PORT_D][LCD_BIT_RS],
1642 lcd_bits[LCD_PORT_C][LCD_BIT_RS]);
1643 pin_to_bits(lcd.pins.rw, lcd_bits[LCD_PORT_D][LCD_BIT_RW],
1644 lcd_bits[LCD_PORT_C][LCD_BIT_RW]);
1645 pin_to_bits(lcd.pins.bl, lcd_bits[LCD_PORT_D][LCD_BIT_BL],
1646 lcd_bits[LCD_PORT_C][LCD_BIT_BL]);
1647 pin_to_bits(lcd.pins.cl, lcd_bits[LCD_PORT_D][LCD_BIT_CL],
1648 lcd_bits[LCD_PORT_C][LCD_BIT_CL]);
1649 pin_to_bits(lcd.pins.da, lcd_bits[LCD_PORT_D][LCD_BIT_DA],
1650 lcd_bits[LCD_PORT_C][LCD_BIT_DA]);
1651
1652
1653
1654
1655
1656
1657 lcd.initialized = true;
1658 lcd_init_display();
1659
1660
1661#ifdef CONFIG_PANEL_CHANGE_MESSAGE
1662#ifdef CONFIG_PANEL_BOOT_MESSAGE
1663 panel_lcd_print("\x1b[Lc\x1b[Lb\x1b[L*" CONFIG_PANEL_BOOT_MESSAGE);
1664#endif
1665#else
1666 panel_lcd_print("\x1b[Lc\x1b[Lb\x1b[L*Linux-" UTS_RELEASE "\nPanel-"
1667 PANEL_VERSION);
1668#endif
1669 lcd.addr.x = 0;
1670 lcd.addr.y = 0;
1671
1672 lcd.must_clear = true;
1673 lcd_gotoxy();
1674}
1675
1676
1677
1678
1679
1680static ssize_t keypad_read(struct file *file,
1681 char __user *buf, size_t count, loff_t *ppos)
1682{
1683 unsigned i = *ppos;
1684 char __user *tmp = buf;
1685
1686 if (keypad_buflen == 0) {
1687 if (file->f_flags & O_NONBLOCK)
1688 return -EAGAIN;
1689
1690 if (wait_event_interruptible(keypad_read_wait,
1691 keypad_buflen != 0))
1692 return -EINTR;
1693 }
1694
1695 for (; count-- > 0 && (keypad_buflen > 0);
1696 ++i, ++tmp, --keypad_buflen) {
1697 put_user(keypad_buffer[keypad_start], tmp);
1698 keypad_start = (keypad_start + 1) % KEYPAD_BUFFER;
1699 }
1700 *ppos = i;
1701
1702 return tmp - buf;
1703}
1704
1705static int keypad_open(struct inode *inode, struct file *file)
1706{
1707 if (!atomic_dec_and_test(&keypad_available))
1708 return -EBUSY;
1709
1710 if (file->f_mode & FMODE_WRITE)
1711 return -EPERM;
1712
1713 keypad_buflen = 0;
1714 return 0;
1715}
1716
1717static int keypad_release(struct inode *inode, struct file *file)
1718{
1719 atomic_inc(&keypad_available);
1720 return 0;
1721}
1722
1723static const struct file_operations keypad_fops = {
1724 .read = keypad_read,
1725 .open = keypad_open,
1726 .release = keypad_release,
1727 .llseek = default_llseek,
1728};
1729
1730static struct miscdevice keypad_dev = {
1731 .minor = KEYPAD_MINOR,
1732 .name = "keypad",
1733 .fops = &keypad_fops,
1734};
1735
1736static void keypad_send_key(const char *string, int max_len)
1737{
1738
1739 if (!atomic_read(&keypad_available)) {
1740 while (max_len-- && keypad_buflen < KEYPAD_BUFFER && *string) {
1741 keypad_buffer[(keypad_start + keypad_buflen++) %
1742 KEYPAD_BUFFER] = *string++;
1743 }
1744 wake_up_interruptible(&keypad_read_wait);
1745 }
1746}
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758static void phys_scan_contacts(void)
1759{
1760 int bit, bitval;
1761 char oldval;
1762 char bitmask;
1763 char gndmask;
1764
1765 phys_prev = phys_curr;
1766 phys_read_prev = phys_read;
1767 phys_read = 0;
1768
1769
1770 oldval = r_dtr(pprt) | scan_mask_o;
1771
1772 w_dtr(pprt, oldval & ~scan_mask_o);
1773
1774
1775 bitmask = PNL_PINPUT(r_str(pprt)) & scan_mask_i;
1776
1777 w_dtr(pprt, oldval);
1778
1779
1780
1781
1782
1783
1784 gndmask = PNL_PINPUT(r_str(pprt)) & scan_mask_i;
1785
1786
1787 phys_read |= (pmask_t) gndmask << 40;
1788
1789 if (bitmask != gndmask) {
1790
1791
1792
1793
1794
1795 for (bit = 0; bit < 8; bit++) {
1796 bitval = BIT(bit);
1797
1798 if (!(scan_mask_o & bitval))
1799 continue;
1800
1801 w_dtr(pprt, oldval & ~bitval);
1802 bitmask = PNL_PINPUT(r_str(pprt)) & ~gndmask;
1803 phys_read |= (pmask_t) bitmask << (5 * bit);
1804 }
1805 w_dtr(pprt, oldval);
1806 }
1807
1808
1809
1810
1811 phys_curr = (phys_prev & (phys_read ^ phys_read_prev)) |
1812 (phys_read & ~(phys_read ^ phys_read_prev));
1813}
1814
1815static inline int input_state_high(struct logical_input *input)
1816{
1817#if 0
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835 if (((phys_prev & input->mask) == input->value) &&
1836 ((phys_curr & input->mask) > input->value)) {
1837 input->state = INPUT_ST_LOW;
1838 return 1;
1839 }
1840#endif
1841
1842 if ((phys_curr & input->mask) == input->value) {
1843 if ((input->type == INPUT_TYPE_STD) &&
1844 (input->high_timer == 0)) {
1845 input->high_timer++;
1846 if (input->u.std.press_fct)
1847 input->u.std.press_fct(input->u.std.press_data);
1848 } else if (input->type == INPUT_TYPE_KBD) {
1849
1850 keypressed = 1;
1851
1852 if (input->high_timer == 0) {
1853 char *press_str = input->u.kbd.press_str;
1854
1855 if (press_str[0]) {
1856 int s = sizeof(input->u.kbd.press_str);
1857
1858 keypad_send_key(press_str, s);
1859 }
1860 }
1861
1862 if (input->u.kbd.repeat_str[0]) {
1863 char *repeat_str = input->u.kbd.repeat_str;
1864
1865 if (input->high_timer >= KEYPAD_REP_START) {
1866 int s = sizeof(input->u.kbd.repeat_str);
1867
1868 input->high_timer -= KEYPAD_REP_DELAY;
1869 keypad_send_key(repeat_str, s);
1870 }
1871
1872 inputs_stable = 0;
1873 }
1874
1875 if (input->high_timer < 255)
1876 input->high_timer++;
1877 }
1878 return 1;
1879 }
1880
1881
1882 input->state = INPUT_ST_FALLING;
1883 input->fall_timer = 0;
1884
1885 return 0;
1886}
1887
1888static inline void input_state_falling(struct logical_input *input)
1889{
1890#if 0
1891
1892 if (((phys_prev & input->mask) == input->value) &&
1893 ((phys_curr & input->mask) > input->value)) {
1894 input->state = INPUT_ST_LOW;
1895 return;
1896 }
1897#endif
1898
1899 if ((phys_curr & input->mask) == input->value) {
1900 if (input->type == INPUT_TYPE_KBD) {
1901
1902 keypressed = 1;
1903
1904 if (input->u.kbd.repeat_str[0]) {
1905 char *repeat_str = input->u.kbd.repeat_str;
1906
1907 if (input->high_timer >= KEYPAD_REP_START) {
1908 int s = sizeof(input->u.kbd.repeat_str);
1909
1910 input->high_timer -= KEYPAD_REP_DELAY;
1911 keypad_send_key(repeat_str, s);
1912 }
1913
1914 inputs_stable = 0;
1915 }
1916
1917 if (input->high_timer < 255)
1918 input->high_timer++;
1919 }
1920 input->state = INPUT_ST_HIGH;
1921 } else if (input->fall_timer >= input->fall_time) {
1922
1923 if (input->type == INPUT_TYPE_STD) {
1924 void (*release_fct)(int) = input->u.std.release_fct;
1925
1926 if (release_fct)
1927 release_fct(input->u.std.release_data);
1928 } else if (input->type == INPUT_TYPE_KBD) {
1929 char *release_str = input->u.kbd.release_str;
1930
1931 if (release_str[0]) {
1932 int s = sizeof(input->u.kbd.release_str);
1933
1934 keypad_send_key(release_str, s);
1935 }
1936 }
1937
1938 input->state = INPUT_ST_LOW;
1939 } else {
1940 input->fall_timer++;
1941 inputs_stable = 0;
1942 }
1943}
1944
1945static void panel_process_inputs(void)
1946{
1947 struct list_head *item;
1948 struct logical_input *input;
1949
1950 keypressed = 0;
1951 inputs_stable = 1;
1952 list_for_each(item, &logical_inputs) {
1953 input = list_entry(item, struct logical_input, list);
1954
1955 switch (input->state) {
1956 case INPUT_ST_LOW:
1957 if ((phys_curr & input->mask) != input->value)
1958 break;
1959
1960
1961
1962
1963
1964
1965
1966 if ((phys_prev & input->mask) == input->value)
1967 break;
1968 input->rise_timer = 0;
1969 input->state = INPUT_ST_RISING;
1970
1971 case INPUT_ST_RISING:
1972 if ((phys_curr & input->mask) != input->value) {
1973 input->state = INPUT_ST_LOW;
1974 break;
1975 }
1976 if (input->rise_timer < input->rise_time) {
1977 inputs_stable = 0;
1978 input->rise_timer++;
1979 break;
1980 }
1981 input->high_timer = 0;
1982 input->state = INPUT_ST_HIGH;
1983
1984 case INPUT_ST_HIGH:
1985 if (input_state_high(input))
1986 break;
1987
1988 case INPUT_ST_FALLING:
1989 input_state_falling(input);
1990 }
1991 }
1992}
1993
1994static void panel_scan_timer(void)
1995{
1996 if (keypad.enabled && keypad_initialized) {
1997 if (spin_trylock_irq(&pprt_lock)) {
1998 phys_scan_contacts();
1999
2000
2001 spin_unlock_irq(&pprt_lock);
2002 }
2003
2004 if (!inputs_stable || phys_curr != phys_prev)
2005 panel_process_inputs();
2006 }
2007
2008 if (lcd.enabled && lcd.initialized) {
2009 if (keypressed) {
2010 if (lcd.light_tempo == 0 &&
2011 ((lcd.flags & LCD_FLAG_L) == 0))
2012 lcd_backlight(1);
2013 lcd.light_tempo = FLASH_LIGHT_TEMPO;
2014 } else if (lcd.light_tempo > 0) {
2015 lcd.light_tempo--;
2016 if (lcd.light_tempo == 0 &&
2017 ((lcd.flags & LCD_FLAG_L) == 0))
2018 lcd_backlight(0);
2019 }
2020 }
2021
2022 mod_timer(&scan_timer, jiffies + INPUT_POLL_TIME);
2023}
2024
2025static void init_scan_timer(void)
2026{
2027 if (scan_timer.function)
2028 return;
2029
2030 setup_timer(&scan_timer, (void *)&panel_scan_timer, 0);
2031 scan_timer.expires = jiffies + INPUT_POLL_TIME;
2032 add_timer(&scan_timer);
2033}
2034
2035
2036
2037
2038
2039
2040static int input_name2mask(const char *name, pmask_t *mask, pmask_t *value,
2041 char *imask, char *omask)
2042{
2043 static char sigtab[10] = "EeSsPpAaBb";
2044 char im, om;
2045 pmask_t m, v;
2046
2047 om = 0ULL;
2048 im = 0ULL;
2049 m = 0ULL;
2050 v = 0ULL;
2051 while (*name) {
2052 int in, out, bit, neg;
2053
2054 for (in = 0; (in < sizeof(sigtab)) && (sigtab[in] != *name);
2055 in++)
2056 ;
2057
2058 if (in >= sizeof(sigtab))
2059 return 0;
2060 neg = (in & 1);
2061 in >>= 1;
2062 im |= BIT(in);
2063
2064 name++;
2065 if (isdigit(*name)) {
2066 out = *name - '0';
2067 om |= BIT(out);
2068 } else if (*name == '-') {
2069 out = 8;
2070 } else {
2071 return 0;
2072 }
2073
2074 bit = (out * 5) + in;
2075
2076 m |= 1ULL << bit;
2077 if (!neg)
2078 v |= 1ULL << bit;
2079 name++;
2080 }
2081 *mask = m;
2082 *value = v;
2083 if (imask)
2084 *imask |= im;
2085 if (omask)
2086 *omask |= om;
2087 return 1;
2088}
2089
2090
2091
2092
2093
2094static struct logical_input *panel_bind_key(const char *name, const char *press,
2095 const char *repeat,
2096 const char *release)
2097{
2098 struct logical_input *key;
2099
2100 key = kzalloc(sizeof(*key), GFP_KERNEL);
2101 if (!key)
2102 return NULL;
2103
2104 if (!input_name2mask(name, &key->mask, &key->value, &scan_mask_i,
2105 &scan_mask_o)) {
2106 kfree(key);
2107 return NULL;
2108 }
2109
2110 key->type = INPUT_TYPE_KBD;
2111 key->state = INPUT_ST_LOW;
2112 key->rise_time = 1;
2113 key->fall_time = 1;
2114
2115 strncpy(key->u.kbd.press_str, press, sizeof(key->u.kbd.press_str));
2116 strncpy(key->u.kbd.repeat_str, repeat, sizeof(key->u.kbd.repeat_str));
2117 strncpy(key->u.kbd.release_str, release,
2118 sizeof(key->u.kbd.release_str));
2119 list_add(&key->list, &logical_inputs);
2120 return key;
2121}
2122
2123#if 0
2124
2125
2126
2127
2128
2129
2130static struct logical_input *panel_bind_callback(char *name,
2131 void (*press_fct)(int),
2132 int press_data,
2133 void (*release_fct)(int),
2134 int release_data)
2135{
2136 struct logical_input *callback;
2137
2138 callback = kmalloc(sizeof(*callback), GFP_KERNEL);
2139 if (!callback)
2140 return NULL;
2141
2142 memset(callback, 0, sizeof(struct logical_input));
2143 if (!input_name2mask(name, &callback->mask, &callback->value,
2144 &scan_mask_i, &scan_mask_o))
2145 return NULL;
2146
2147 callback->type = INPUT_TYPE_STD;
2148 callback->state = INPUT_ST_LOW;
2149 callback->rise_time = 1;
2150 callback->fall_time = 1;
2151 callback->u.std.press_fct = press_fct;
2152 callback->u.std.press_data = press_data;
2153 callback->u.std.release_fct = release_fct;
2154 callback->u.std.release_data = release_data;
2155 list_add(&callback->list, &logical_inputs);
2156 return callback;
2157}
2158#endif
2159
2160static void keypad_init(void)
2161{
2162 int keynum;
2163
2164 init_waitqueue_head(&keypad_read_wait);
2165 keypad_buflen = 0;
2166
2167
2168
2169 for (keynum = 0; keypad_profile[keynum][0][0]; keynum++) {
2170 panel_bind_key(keypad_profile[keynum][0],
2171 keypad_profile[keynum][1],
2172 keypad_profile[keynum][2],
2173 keypad_profile[keynum][3]);
2174 }
2175
2176 init_scan_timer();
2177 keypad_initialized = 1;
2178}
2179
2180
2181
2182
2183
2184static int panel_notify_sys(struct notifier_block *this, unsigned long code,
2185 void *unused)
2186{
2187 if (lcd.enabled && lcd.initialized) {
2188 switch (code) {
2189 case SYS_DOWN:
2190 panel_lcd_print
2191 ("\x0cReloading\nSystem...\x1b[Lc\x1b[Lb\x1b[L+");
2192 break;
2193 case SYS_HALT:
2194 panel_lcd_print
2195 ("\x0cSystem Halted.\x1b[Lc\x1b[Lb\x1b[L+");
2196 break;
2197 case SYS_POWER_OFF:
2198 panel_lcd_print("\x0cPower off.\x1b[Lc\x1b[Lb\x1b[L+");
2199 break;
2200 default:
2201 break;
2202 }
2203 }
2204 return NOTIFY_DONE;
2205}
2206
2207static struct notifier_block panel_notifier = {
2208 panel_notify_sys,
2209 NULL,
2210 0
2211};
2212
2213static void panel_attach(struct parport *port)
2214{
2215 struct pardev_cb panel_cb;
2216
2217 if (port->number != parport)
2218 return;
2219
2220 if (pprt) {
2221 pr_err("%s: port->number=%d parport=%d, already registered!\n",
2222 __func__, port->number, parport);
2223 return;
2224 }
2225
2226 memset(&panel_cb, 0, sizeof(panel_cb));
2227 panel_cb.private = &pprt;
2228
2229
2230 pprt = parport_register_dev_model(port, "panel", &panel_cb, 0);
2231 if (!pprt) {
2232 pr_err("%s: port->number=%d parport=%d, parport_register_device() failed\n",
2233 __func__, port->number, parport);
2234 return;
2235 }
2236
2237 if (parport_claim(pprt)) {
2238 pr_err("could not claim access to parport%d. Aborting.\n",
2239 parport);
2240 goto err_unreg_device;
2241 }
2242
2243
2244
2245
2246 if (lcd.enabled) {
2247 lcd_init();
2248 if (misc_register(&lcd_dev))
2249 goto err_unreg_device;
2250 }
2251
2252 if (keypad.enabled) {
2253 keypad_init();
2254 if (misc_register(&keypad_dev))
2255 goto err_lcd_unreg;
2256 }
2257 register_reboot_notifier(&panel_notifier);
2258 return;
2259
2260err_lcd_unreg:
2261 if (lcd.enabled)
2262 misc_deregister(&lcd_dev);
2263err_unreg_device:
2264 parport_unregister_device(pprt);
2265 pprt = NULL;
2266}
2267
2268static void panel_detach(struct parport *port)
2269{
2270 if (port->number != parport)
2271 return;
2272
2273 if (!pprt) {
2274 pr_err("%s: port->number=%d parport=%d, nothing to unregister.\n",
2275 __func__, port->number, parport);
2276 return;
2277 }
2278 if (scan_timer.function)
2279 del_timer_sync(&scan_timer);
2280
2281 if (pprt) {
2282 if (keypad.enabled) {
2283 misc_deregister(&keypad_dev);
2284 keypad_initialized = 0;
2285 }
2286
2287 if (lcd.enabled) {
2288 panel_lcd_print("\x0cLCD driver " PANEL_VERSION
2289 "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-");
2290 misc_deregister(&lcd_dev);
2291 lcd.initialized = false;
2292 }
2293
2294
2295 parport_release(pprt);
2296 parport_unregister_device(pprt);
2297 pprt = NULL;
2298 unregister_reboot_notifier(&panel_notifier);
2299 }
2300}
2301
2302static struct parport_driver panel_driver = {
2303 .name = "panel",
2304 .match_port = panel_attach,
2305 .detach = panel_detach,
2306 .devmodel = true,
2307};
2308
2309
2310static int __init panel_init_module(void)
2311{
2312 int selected_keypad_type = NOT_SET, err;
2313
2314
2315 switch (profile) {
2316 case PANEL_PROFILE_CUSTOM:
2317
2318 selected_keypad_type = DEFAULT_KEYPAD_TYPE;
2319 selected_lcd_type = DEFAULT_LCD_TYPE;
2320 break;
2321 case PANEL_PROFILE_OLD:
2322
2323 selected_keypad_type = KEYPAD_TYPE_OLD;
2324 selected_lcd_type = LCD_TYPE_OLD;
2325
2326
2327 if (lcd_width == NOT_SET)
2328 lcd_width = 16;
2329 if (lcd_hwidth == NOT_SET)
2330 lcd_hwidth = 16;
2331 break;
2332 case PANEL_PROFILE_NEW:
2333
2334 selected_keypad_type = KEYPAD_TYPE_NEW;
2335 selected_lcd_type = LCD_TYPE_KS0074;
2336 break;
2337 case PANEL_PROFILE_HANTRONIX:
2338
2339 selected_keypad_type = KEYPAD_TYPE_NONE;
2340 selected_lcd_type = LCD_TYPE_HANTRONIX;
2341 break;
2342 case PANEL_PROFILE_NEXCOM:
2343
2344 selected_keypad_type = KEYPAD_TYPE_NEXCOM;
2345 selected_lcd_type = LCD_TYPE_NEXCOM;
2346 break;
2347 case PANEL_PROFILE_LARGE:
2348
2349 selected_keypad_type = KEYPAD_TYPE_OLD;
2350 selected_lcd_type = LCD_TYPE_OLD;
2351 break;
2352 }
2353
2354
2355
2356
2357
2358 if (keypad_enabled != NOT_SET)
2359 selected_keypad_type = keypad_enabled;
2360 if (keypad_type != NOT_SET)
2361 selected_keypad_type = keypad_type;
2362
2363 keypad.enabled = (selected_keypad_type > 0);
2364
2365 if (lcd_enabled != NOT_SET)
2366 selected_lcd_type = lcd_enabled;
2367 if (lcd_type != NOT_SET)
2368 selected_lcd_type = lcd_type;
2369
2370 lcd.enabled = (selected_lcd_type > 0);
2371
2372 if (lcd.enabled) {
2373
2374
2375
2376
2377 lcd.height = lcd_height;
2378 lcd.width = lcd_width;
2379 lcd.bwidth = lcd_bwidth;
2380 lcd.hwidth = lcd_hwidth;
2381 lcd.charset = lcd_charset;
2382 lcd.proto = lcd_proto;
2383 lcd.pins.e = lcd_e_pin;
2384 lcd.pins.rs = lcd_rs_pin;
2385 lcd.pins.rw = lcd_rw_pin;
2386 lcd.pins.cl = lcd_cl_pin;
2387 lcd.pins.da = lcd_da_pin;
2388 lcd.pins.bl = lcd_bl_pin;
2389
2390
2391 lcd.esc_seq.len = -1;
2392 }
2393
2394 switch (selected_keypad_type) {
2395 case KEYPAD_TYPE_OLD:
2396 keypad_profile = old_keypad_profile;
2397 break;
2398 case KEYPAD_TYPE_NEW:
2399 keypad_profile = new_keypad_profile;
2400 break;
2401 case KEYPAD_TYPE_NEXCOM:
2402 keypad_profile = nexcom_keypad_profile;
2403 break;
2404 default:
2405 keypad_profile = NULL;
2406 break;
2407 }
2408
2409 if (!lcd.enabled && !keypad.enabled) {
2410
2411 pr_err("driver version " PANEL_VERSION " disabled.\n");
2412 return -ENODEV;
2413 }
2414
2415 err = parport_register_driver(&panel_driver);
2416 if (err) {
2417 pr_err("could not register with parport. Aborting.\n");
2418 return err;
2419 }
2420
2421 if (pprt)
2422 pr_info("driver version " PANEL_VERSION
2423 " registered on parport%d (io=0x%lx).\n", parport,
2424 pprt->port->base);
2425 else
2426 pr_info("driver version " PANEL_VERSION
2427 " not yet registered\n");
2428 return 0;
2429}
2430
2431static void __exit panel_cleanup_module(void)
2432{
2433 parport_unregister_driver(&panel_driver);
2434}
2435
2436module_init(panel_init_module);
2437module_exit(panel_cleanup_module);
2438MODULE_AUTHOR("Willy Tarreau");
2439MODULE_LICENSE("GPL");
2440
2441
2442
2443
2444
2445
2446
2447