diff options
-rw-r--r-- | drivers/staging/panel/panel.c | 1045 |
1 files changed, 572 insertions, 473 deletions
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index 9ca0e9e2a96..3154ffe5927 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c | |||
@@ -68,11 +68,16 @@ | |||
68 | #define LCD_MAXBYTES 256 /* max burst write */ | 68 | #define LCD_MAXBYTES 256 /* max burst write */ |
69 | 69 | ||
70 | #define KEYPAD_BUFFER 64 | 70 | #define KEYPAD_BUFFER 64 |
71 | #define INPUT_POLL_TIME (HZ/50) /* poll the keyboard this every second */ | ||
72 | #define KEYPAD_REP_START (10) /* a key starts to repeat after this times INPUT_POLL_TIME */ | ||
73 | #define KEYPAD_REP_DELAY (2) /* a key repeats this times INPUT_POLL_TIME */ | ||
74 | 71 | ||
75 | #define FLASH_LIGHT_TEMPO (200) /* keep the light on this times INPUT_POLL_TIME for each flash */ | 72 | /* poll the keyboard this every second */ |
73 | #define INPUT_POLL_TIME (HZ/50) | ||
74 | /* a key starts to repeat after this times INPUT_POLL_TIME */ | ||
75 | #define KEYPAD_REP_START (10) | ||
76 | /* a key repeats this times INPUT_POLL_TIME */ | ||
77 | #define KEYPAD_REP_DELAY (2) | ||
78 | |||
79 | /* keep the light on this times INPUT_POLL_TIME for each flash */ | ||
80 | #define FLASH_LIGHT_TEMPO (200) | ||
76 | 81 | ||
77 | /* converts an r_str() input to an active high, bits string : 000BAOSE */ | 82 | /* converts an r_str() input to an active high, bits string : 000BAOSE */ |
78 | #define PNL_PINPUT(a) ((((unsigned char)(a)) ^ 0x7F) >> 3) | 83 | #define PNL_PINPUT(a) ((((unsigned char)(a)) ^ 0x7F) >> 3) |
@@ -84,7 +89,8 @@ | |||
84 | #define PNL_PERRORP 0x08 /* direct input, active low */ | 89 | #define PNL_PERRORP 0x08 /* direct input, active low */ |
85 | 90 | ||
86 | #define PNL_PBIDIR 0x20 /* bi-directional ports */ | 91 | #define PNL_PBIDIR 0x20 /* bi-directional ports */ |
87 | #define PNL_PINTEN 0x10 /* high to read data in or-ed with data out */ | 92 | /* high to read data in or-ed with data out */ |
93 | #define PNL_PINTEN 0x10 | ||
88 | #define PNL_PSELECP 0x08 /* inverted output, active low */ | 94 | #define PNL_PSELECP 0x08 /* inverted output, active low */ |
89 | #define PNL_PINITP 0x04 /* direct output, active low */ | 95 | #define PNL_PINITP 0x04 /* direct output, active low */ |
90 | #define PNL_PAUTOLF 0x02 /* inverted output, active low */ | 96 | #define PNL_PAUTOLF 0x02 /* inverted output, active low */ |
@@ -123,7 +129,7 @@ | |||
123 | #define LCD_FLAG_N 0x0040 /* 2-rows mode */ | 129 | #define LCD_FLAG_N 0x0040 /* 2-rows mode */ |
124 | #define LCD_FLAG_L 0x0080 /* backlight enabled */ | 130 | #define LCD_FLAG_L 0x0080 /* backlight enabled */ |
125 | 131 | ||
126 | #define LCD_ESCAPE_LEN 24 /* 24 chars max for an LCD escape command */ | 132 | #define LCD_ESCAPE_LEN 24 /* max chars for LCD escape command */ |
127 | #define LCD_ESCAPE_CHAR 27 /* use char 27 for escape command */ | 133 | #define LCD_ESCAPE_CHAR 27 /* use char 27 for escape command */ |
128 | 134 | ||
129 | /* macros to simplify use of the parallel port */ | 135 | /* macros to simplify use of the parallel port */ |
@@ -134,8 +140,10 @@ | |||
134 | #define w_dtr(x, y) do { parport_write_data((x)->port, (y)); } while (0) | 140 | #define w_dtr(x, y) do { parport_write_data((x)->port, (y)); } while (0) |
135 | 141 | ||
136 | /* this defines which bits are to be used and which ones to be ignored */ | 142 | /* this defines which bits are to be used and which ones to be ignored */ |
137 | static __u8 scan_mask_o; /* logical or of the output bits involved in the scan matrix */ | 143 | /* logical or of the output bits involved in the scan matrix */ |
138 | static __u8 scan_mask_i; /* logical or of the input bits involved in the scan matrix */ | 144 | static __u8 scan_mask_o; |
145 | /* logical or of the input bits involved in the scan matrix */ | ||
146 | static __u8 scan_mask_i; | ||
139 | 147 | ||
140 | typedef __u64 pmask_t; | 148 | typedef __u64 pmask_t; |
141 | 149 | ||
@@ -161,14 +169,14 @@ struct logical_input { | |||
161 | __u8 rise_timer, fall_timer, high_timer; | 169 | __u8 rise_timer, fall_timer, high_timer; |
162 | 170 | ||
163 | union { | 171 | union { |
164 | struct { /* this structure is valid when type == INPUT_TYPE_STD */ | 172 | struct { /* valid when type == INPUT_TYPE_STD */ |
165 | void (*press_fct) (int); | 173 | void (*press_fct) (int); |
166 | void (*release_fct) (int); | 174 | void (*release_fct) (int); |
167 | int press_data; | 175 | int press_data; |
168 | int release_data; | 176 | int release_data; |
169 | } std; | 177 | } std; |
170 | struct { /* this structure is valid when type == INPUT_TYPE_KBD */ | 178 | struct { /* valid when type == INPUT_TYPE_KBD */ |
171 | /* strings can be full-length (ie. non null-terminated) */ | 179 | /* strings can be non null-terminated */ |
172 | char press_str[sizeof(void *) + sizeof(int)]; | 180 | char press_str[sizeof(void *) + sizeof(int)]; |
173 | char repeat_str[sizeof(void *) + sizeof(int)]; | 181 | char repeat_str[sizeof(void *) + sizeof(int)]; |
174 | char release_str[sizeof(void *) + sizeof(int)]; | 182 | char release_str[sizeof(void *) + sizeof(int)]; |
@@ -188,11 +196,17 @@ LIST_HEAD(logical_inputs); /* list of all defined logical inputs */ | |||
188 | * 0000000000000000000BAPSEBAPSEBAPSEBAPSEBAPSEBAPSEBAPSEBAPSEBAPSE | 196 | * 0000000000000000000BAPSEBAPSEBAPSEBAPSEBAPSEBAPSEBAPSEBAPSEBAPSE |
189 | * <-----unused------><gnd><d07><d06><d05><d04><d03><d02><d01><d00> | 197 | * <-----unused------><gnd><d07><d06><d05><d04><d03><d02><d01><d00> |
190 | */ | 198 | */ |
191 | static pmask_t phys_read; /* what has just been read from the I/O ports */ | 199 | |
192 | static pmask_t phys_read_prev; /* previous phys_read */ | 200 | /* what has just been read from the I/O ports */ |
193 | static pmask_t phys_curr; /* stabilized phys_read (phys_read|phys_read_prev) */ | 201 | static pmask_t phys_read; |
194 | static pmask_t phys_prev; /* previous phys_curr */ | 202 | /* previous phys_read */ |
195 | static char inputs_stable; /* 0 means that at least one logical signal needs be computed */ | 203 | static pmask_t phys_read_prev; |
204 | /* stabilized phys_read (phys_read|phys_read_prev) */ | ||
205 | static pmask_t phys_curr; | ||
206 | /* previous phys_curr */ | ||
207 | static pmask_t phys_prev; | ||
208 | /* 0 means that at least one logical signal needs be computed */ | ||
209 | static char inputs_stable; | ||
196 | 210 | ||
197 | /* these variables are specific to the keypad */ | 211 | /* these variables are specific to the keypad */ |
198 | static char keypad_buffer[KEYPAD_BUFFER]; | 212 | static char keypad_buffer[KEYPAD_BUFFER]; |
@@ -202,11 +216,17 @@ static char keypressed; | |||
202 | static wait_queue_head_t keypad_read_wait; | 216 | static wait_queue_head_t keypad_read_wait; |
203 | 217 | ||
204 | /* lcd-specific variables */ | 218 | /* lcd-specific variables */ |
205 | static unsigned long int lcd_flags; /* contains the LCD config state */ | 219 | |
206 | static unsigned long int lcd_addr_x; /* contains the LCD X offset */ | 220 | /* contains the LCD config state */ |
207 | static unsigned long int lcd_addr_y; /* contains the LCD Y offset */ | 221 | static unsigned long int lcd_flags; |
208 | static char lcd_escape[LCD_ESCAPE_LEN + 1]; /* current escape sequence, 0 terminated */ | 222 | /* contains the LCD X offset */ |
209 | static int lcd_escape_len = -1; /* not in escape state. >=0 = escape cmd len */ | 223 | static unsigned long int lcd_addr_x; |
224 | /* contains the LCD Y offset */ | ||
225 | static unsigned long int lcd_addr_y; | ||
226 | /* current escape sequence, 0 terminated */ | ||
227 | static char lcd_escape[LCD_ESCAPE_LEN + 1]; | ||
228 | /* not in escape state. >=0 = escape cmd len */ | ||
229 | static int lcd_escape_len = -1; | ||
210 | 230 | ||
211 | /* | 231 | /* |
212 | * Bit masks to convert LCD signals to parallel port outputs. | 232 | * Bit masks to convert LCD signals to parallel port outputs. |
@@ -436,11 +456,13 @@ MODULE_PARM_DESC(keypad_enabled, "Deprecated option, use keypad_type instead"); | |||
436 | static int lcd_type = -1; | 456 | static int lcd_type = -1; |
437 | module_param(lcd_type, int, 0000); | 457 | module_param(lcd_type, int, 0000); |
438 | MODULE_PARM_DESC(lcd_type, | 458 | MODULE_PARM_DESC(lcd_type, |
439 | "LCD type: 0=none, 1=old //, 2=serial ks0074, 3=hantronix //, 4=nexcom //, 5=compiled-in"); | 459 | "LCD type: 0=none, 1=old //, 2=serial ks0074, " |
460 | "3=hantronix //, 4=nexcom //, 5=compiled-in"); | ||
440 | 461 | ||
441 | static int lcd_proto = -1; | 462 | static int lcd_proto = -1; |
442 | module_param(lcd_proto, int, 0000); | 463 | module_param(lcd_proto, int, 0000); |
443 | MODULE_PARM_DESC(lcd_proto, "LCD communication: 0=parallel (//), 1=serial," | 464 | MODULE_PARM_DESC(lcd_proto, |
465 | "LCD communication: 0=parallel (//), 1=serial," | ||
444 | "2=TI LCD Interface"); | 466 | "2=TI LCD Interface"); |
445 | 467 | ||
446 | static int lcd_charset = -1; | 468 | static int lcd_charset = -1; |
@@ -450,12 +472,14 @@ MODULE_PARM_DESC(lcd_charset, "LCD character set: 0=standard, 1=KS0074"); | |||
450 | static int keypad_type = -1; | 472 | static int keypad_type = -1; |
451 | module_param(keypad_type, int, 0000); | 473 | module_param(keypad_type, int, 0000); |
452 | MODULE_PARM_DESC(keypad_type, | 474 | MODULE_PARM_DESC(keypad_type, |
453 | "Keypad type: 0=none, 1=old 6 keys, 2=new 6+1 keys, 3=nexcom 4 keys"); | 475 | "Keypad type: 0=none, 1=old 6 keys, 2=new 6+1 keys, " |
476 | "3=nexcom 4 keys"); | ||
454 | 477 | ||
455 | static int profile = DEFAULT_PROFILE; | 478 | static int profile = DEFAULT_PROFILE; |
456 | module_param(profile, int, 0000); | 479 | module_param(profile, int, 0000); |
457 | MODULE_PARM_DESC(profile, | 480 | MODULE_PARM_DESC(profile, |
458 | "1=16x2 old kp; 2=serial 16x2, new kp; 3=16x2 hantronix; 4=16x2 nexcom; default=40x2, old kp"); | 481 | "1=16x2 old kp; 2=serial 16x2, new kp; 3=16x2 hantronix; " |
482 | "4=16x2 nexcom; default=40x2, old kp"); | ||
459 | 483 | ||
460 | /* | 484 | /* |
461 | * These are the parallel port pins the LCD control signals are connected to. | 485 | * These are the parallel port pins the LCD control signals are connected to. |
@@ -469,32 +493,38 @@ MODULE_PARM_DESC(profile, | |||
469 | static int lcd_e_pin = PIN_NOT_SET; | 493 | static int lcd_e_pin = PIN_NOT_SET; |
470 | module_param(lcd_e_pin, int, 0000); | 494 | module_param(lcd_e_pin, int, 0000); |
471 | MODULE_PARM_DESC(lcd_e_pin, | 495 | MODULE_PARM_DESC(lcd_e_pin, |
472 | "# of the // port pin connected to LCD 'E' signal, with polarity (-17..17)"); | 496 | "# of the // port pin connected to LCD 'E' signal, " |
497 | "with polarity (-17..17)"); | ||
473 | 498 | ||
474 | static int lcd_rs_pin = PIN_NOT_SET; | 499 | static int lcd_rs_pin = PIN_NOT_SET; |
475 | module_param(lcd_rs_pin, int, 0000); | 500 | module_param(lcd_rs_pin, int, 0000); |
476 | MODULE_PARM_DESC(lcd_rs_pin, | 501 | MODULE_PARM_DESC(lcd_rs_pin, |
477 | "# of the // port pin connected to LCD 'RS' signal, with polarity (-17..17)"); | 502 | "# of the // port pin connected to LCD 'RS' signal, " |
503 | "with polarity (-17..17)"); | ||
478 | 504 | ||
479 | static int lcd_rw_pin = PIN_NOT_SET; | 505 | static int lcd_rw_pin = PIN_NOT_SET; |
480 | module_param(lcd_rw_pin, int, 0000); | 506 | module_param(lcd_rw_pin, int, 0000); |
481 | MODULE_PARM_DESC(lcd_rw_pin, | 507 | MODULE_PARM_DESC(lcd_rw_pin, |
482 | "# of the // port pin connected to LCD 'RW' signal, with polarity (-17..17)"); | 508 | "# of the // port pin connected to LCD 'RW' signal, " |
509 | "with polarity (-17..17)"); | ||
483 | 510 | ||
484 | static int lcd_bl_pin = PIN_NOT_SET; | 511 | static int lcd_bl_pin = PIN_NOT_SET; |
485 | module_param(lcd_bl_pin, int, 0000); | 512 | module_param(lcd_bl_pin, int, 0000); |
486 | MODULE_PARM_DESC(lcd_bl_pin, | 513 | MODULE_PARM_DESC(lcd_bl_pin, |
487 | "# of the // port pin connected to LCD backlight, with polarity (-17..17)"); | 514 | "# of the // port pin connected to LCD backlight, " |
515 | "with polarity (-17..17)"); | ||
488 | 516 | ||
489 | static int lcd_da_pin = PIN_NOT_SET; | 517 | static int lcd_da_pin = PIN_NOT_SET; |
490 | module_param(lcd_da_pin, int, 0000); | 518 | module_param(lcd_da_pin, int, 0000); |
491 | MODULE_PARM_DESC(lcd_da_pin, | 519 | MODULE_PARM_DESC(lcd_da_pin, |
492 | "# of the // port pin connected to serial LCD 'SDA' signal, with polarity (-17..17)"); | 520 | "# of the // port pin connected to serial LCD 'SDA' " |
521 | "signal, with polarity (-17..17)"); | ||
493 | 522 | ||
494 | static int lcd_cl_pin = PIN_NOT_SET; | 523 | static int lcd_cl_pin = PIN_NOT_SET; |
495 | module_param(lcd_cl_pin, int, 0000); | 524 | module_param(lcd_cl_pin, int, 0000); |
496 | MODULE_PARM_DESC(lcd_cl_pin, | 525 | MODULE_PARM_DESC(lcd_cl_pin, |
497 | "# of the // port pin connected to serial LCD 'SCL' signal, with polarity (-17..17)"); | 526 | "# of the // port pin connected to serial LCD 'SCL' " |
527 | "signal, with polarity (-17..17)"); | ||
498 | 528 | ||
499 | static unsigned char *lcd_char_conv; | 529 | static unsigned char *lcd_char_conv; |
500 | 530 | ||
@@ -572,12 +602,12 @@ static char (*keypad_profile)[4][9] = old_keypad_profile; | |||
572 | 602 | ||
573 | /* FIXME: this should be converted to a bit array containing signals states */ | 603 | /* FIXME: this should be converted to a bit array containing signals states */ |
574 | static struct { | 604 | static struct { |
575 | unsigned char e; /* parallel LCD E (data latch on falling edge) */ | 605 | unsigned char e; /* parallel LCD E (data latch on falling edge) */ |
576 | unsigned char rs; /* parallel LCD RS (0 = cmd, 1 = data) */ | 606 | unsigned char rs; /* parallel LCD RS (0 = cmd, 1 = data) */ |
577 | unsigned char rw; /* parallel LCD R/W (0 = W, 1 = R) */ | 607 | unsigned char rw; /* parallel LCD R/W (0 = W, 1 = R) */ |
578 | unsigned char bl; /* parallel LCD backlight (0 = off, 1 = on) */ | 608 | unsigned char bl; /* parallel LCD backlight (0 = off, 1 = on) */ |
579 | unsigned char cl; /* serial LCD clock (latch on rising edge) */ | 609 | unsigned char cl; /* serial LCD clock (latch on rising edge) */ |
580 | unsigned char da; /* serial LCD data */ | 610 | unsigned char da; /* serial LCD data */ |
581 | } bits; | 611 | } bits; |
582 | 612 | ||
583 | static void init_scan_timer(void); | 613 | static void init_scan_timer(void); |
@@ -666,7 +696,7 @@ void pin_to_bits(int pin, unsigned char *d_val, unsigned char *c_val) | |||
666 | c_bit = PNL_PAUTOLF; | 696 | c_bit = PNL_PAUTOLF; |
667 | inv = !inv; | 697 | inv = !inv; |
668 | break; | 698 | break; |
669 | case PIN_INITP: /* init, direct */ | 699 | case PIN_INITP: /* init, direct */ |
670 | c_bit = PNL_PINITP; | 700 | c_bit = PNL_PINITP; |
671 | break; | 701 | break; |
672 | case PIN_SELECP: /* select_in, inverted */ | 702 | case PIN_SELECP: /* select_in, inverted */ |
@@ -698,23 +728,23 @@ static void long_sleep(int ms) | |||
698 | } | 728 | } |
699 | } | 729 | } |
700 | 730 | ||
701 | /* send a serial byte to the LCD panel. The caller is responsible for locking if needed. */ | 731 | /* send a serial byte to the LCD panel. The caller is responsible for locking |
732 | if needed. */ | ||
702 | static void lcd_send_serial(int byte) | 733 | static void lcd_send_serial(int byte) |
703 | { | 734 | { |
704 | int bit; | 735 | int bit; |
705 | 736 | ||
706 | /* the data bit is set on D0, and the clock on STROBE. | 737 | /* the data bit is set on D0, and the clock on STROBE. |
707 | * LCD reads D0 on STROBE's rising edge. | 738 | * LCD reads D0 on STROBE's rising edge. */ |
708 | */ | ||
709 | for (bit = 0; bit < 8; bit++) { | 739 | for (bit = 0; bit < 8; bit++) { |
710 | bits.cl = BIT_CLR; /* CLK low */ | 740 | bits.cl = BIT_CLR; /* CLK low */ |
711 | panel_set_bits(); | 741 | panel_set_bits(); |
712 | bits.da = byte & 1; | 742 | bits.da = byte & 1; |
713 | panel_set_bits(); | 743 | panel_set_bits(); |
714 | udelay(2); /* maintain the data during 2 us before CLK up */ | 744 | udelay(2); /* maintain the data during 2 us before CLK up */ |
715 | bits.cl = BIT_SET; /* CLK high */ | 745 | bits.cl = BIT_SET; /* CLK high */ |
716 | panel_set_bits(); | 746 | panel_set_bits(); |
717 | udelay(1); /* maintain the strobe during 1 us */ | 747 | udelay(1); /* maintain the strobe during 1 us */ |
718 | byte >>= 1; | 748 | byte >>= 1; |
719 | } | 749 | } |
720 | } | 750 | } |
@@ -760,19 +790,19 @@ static void lcd_write_cmd_p8(int cmd) | |||
760 | spin_lock(&pprt_lock); | 790 | spin_lock(&pprt_lock); |
761 | /* present the data to the data port */ | 791 | /* present the data to the data port */ |
762 | w_dtr(pprt, cmd); | 792 | w_dtr(pprt, cmd); |
763 | udelay(20); /* maintain the data during 20 us before the strobe */ | 793 | udelay(20); /* maintain the data during 20 us before the strobe */ |
764 | 794 | ||
765 | bits.e = BIT_SET; | 795 | bits.e = BIT_SET; |
766 | bits.rs = BIT_CLR; | 796 | bits.rs = BIT_CLR; |
767 | bits.rw = BIT_CLR; | 797 | bits.rw = BIT_CLR; |
768 | set_ctrl_bits(); | 798 | set_ctrl_bits(); |
769 | 799 | ||
770 | udelay(40); /* maintain the strobe during 40 us */ | 800 | udelay(40); /* maintain the strobe during 40 us */ |
771 | 801 | ||
772 | bits.e = BIT_CLR; | 802 | bits.e = BIT_CLR; |
773 | set_ctrl_bits(); | 803 | set_ctrl_bits(); |
774 | 804 | ||
775 | udelay(120); /* the shortest command takes at least 120 us */ | 805 | udelay(120); /* the shortest command takes at least 120 us */ |
776 | spin_unlock(&pprt_lock); | 806 | spin_unlock(&pprt_lock); |
777 | } | 807 | } |
778 | 808 | ||
@@ -782,19 +812,19 @@ static void lcd_write_data_p8(int data) | |||
782 | spin_lock(&pprt_lock); | 812 | spin_lock(&pprt_lock); |
783 | /* present the data to the data port */ | 813 | /* present the data to the data port */ |
784 | w_dtr(pprt, data); | 814 | w_dtr(pprt, data); |
785 | udelay(20); /* maintain the data during 20 us before the strobe */ | 815 | udelay(20); /* maintain the data during 20 us before the strobe */ |
786 | 816 | ||
787 | bits.e = BIT_SET; | 817 | bits.e = BIT_SET; |
788 | bits.rs = BIT_SET; | 818 | bits.rs = BIT_SET; |
789 | bits.rw = BIT_CLR; | 819 | bits.rw = BIT_CLR; |
790 | set_ctrl_bits(); | 820 | set_ctrl_bits(); |
791 | 821 | ||
792 | udelay(40); /* maintain the strobe during 40 us */ | 822 | udelay(40); /* maintain the strobe during 40 us */ |
793 | 823 | ||
794 | bits.e = BIT_CLR; | 824 | bits.e = BIT_CLR; |
795 | set_ctrl_bits(); | 825 | set_ctrl_bits(); |
796 | 826 | ||
797 | udelay(45); /* the shortest data takes at least 45 us */ | 827 | udelay(45); /* the shortest data takes at least 45 us */ |
798 | spin_unlock(&pprt_lock); | 828 | spin_unlock(&pprt_lock); |
799 | } | 829 | } |
800 | 830 | ||
@@ -822,7 +852,8 @@ static void lcd_gotoxy(void) | |||
822 | { | 852 | { |
823 | lcd_write_cmd(0x80 /* set DDRAM address */ | 853 | lcd_write_cmd(0x80 /* set DDRAM address */ |
824 | | (lcd_addr_y ? lcd_hwidth : 0) | 854 | | (lcd_addr_y ? lcd_hwidth : 0) |
825 | /* we force the cursor to stay at the end of the line if it wants to go farther */ | 855 | /* we force the cursor to stay at the end of the |
856 | line if it wants to go farther */ | ||
826 | | ((lcd_addr_x < lcd_bwidth) ? lcd_addr_x & | 857 | | ((lcd_addr_x < lcd_bwidth) ? lcd_addr_x & |
827 | (lcd_hwidth - 1) : lcd_bwidth - 1)); | 858 | (lcd_hwidth - 1) : lcd_bwidth - 1)); |
828 | } | 859 | } |
@@ -871,19 +902,23 @@ static void lcd_clear_fast_p8(void) | |||
871 | for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) { | 902 | for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) { |
872 | /* present the data to the data port */ | 903 | /* present the data to the data port */ |
873 | w_dtr(pprt, ' '); | 904 | w_dtr(pprt, ' '); |
874 | udelay(20); /* maintain the data during 20 us before the strobe */ | 905 | |
906 | /* maintain the data during 20 us before the strobe */ | ||
907 | udelay(20); | ||
875 | 908 | ||
876 | bits.e = BIT_SET; | 909 | bits.e = BIT_SET; |
877 | bits.rs = BIT_SET; | 910 | bits.rs = BIT_SET; |
878 | bits.rw = BIT_CLR; | 911 | bits.rw = BIT_CLR; |
879 | set_ctrl_bits(); | 912 | set_ctrl_bits(); |
880 | 913 | ||
881 | udelay(40); /* maintain the strobe during 40 us */ | 914 | /* maintain the strobe during 40 us */ |
915 | udelay(40); | ||
882 | 916 | ||
883 | bits.e = BIT_CLR; | 917 | bits.e = BIT_CLR; |
884 | set_ctrl_bits(); | 918 | set_ctrl_bits(); |
885 | 919 | ||
886 | udelay(45); /* the shortest data takes at least 45 us */ | 920 | /* the shortest data takes at least 45 us */ |
921 | udelay(45); | ||
887 | } | 922 | } |
888 | spin_unlock(&pprt_lock); | 923 | spin_unlock(&pprt_lock); |
889 | 924 | ||
@@ -954,7 +989,8 @@ static void lcd_init_display(void) | |||
954 | 989 | ||
955 | long_sleep(10); | 990 | long_sleep(10); |
956 | 991 | ||
957 | lcd_write_cmd(0x06); /* entry mode set : increment, cursor shifting */ | 992 | /* entry mode set : increment, cursor shifting */ |
993 | lcd_write_cmd(0x06); | ||
958 | 994 | ||
959 | lcd_clear_display(); | 995 | lcd_clear_display(); |
960 | } | 996 | } |
@@ -966,317 +1002,342 @@ static void lcd_init_display(void) | |||
966 | * | 1002 | * |
967 | */ | 1003 | */ |
968 | 1004 | ||
1005 | static inline int handle_lcd_special_code(void) | ||
1006 | { | ||
1007 | /* LCD special codes */ | ||
1008 | |||
1009 | int processed = 0; | ||
1010 | |||
1011 | char *esc = lcd_escape + 2; | ||
1012 | int oldflags = lcd_flags; | ||
1013 | |||
1014 | /* check for display mode flags */ | ||
1015 | switch (*esc) { | ||
1016 | case 'D': /* Display ON */ | ||
1017 | lcd_flags |= LCD_FLAG_D; | ||
1018 | processed = 1; | ||
1019 | break; | ||
1020 | case 'd': /* Display OFF */ | ||
1021 | lcd_flags &= ~LCD_FLAG_D; | ||
1022 | processed = 1; | ||
1023 | break; | ||
1024 | case 'C': /* Cursor ON */ | ||
1025 | lcd_flags |= LCD_FLAG_C; | ||
1026 | processed = 1; | ||
1027 | break; | ||
1028 | case 'c': /* Cursor OFF */ | ||
1029 | lcd_flags &= ~LCD_FLAG_C; | ||
1030 | processed = 1; | ||
1031 | break; | ||
1032 | case 'B': /* Blink ON */ | ||
1033 | lcd_flags |= LCD_FLAG_B; | ||
1034 | processed = 1; | ||
1035 | break; | ||
1036 | case 'b': /* Blink OFF */ | ||
1037 | lcd_flags &= ~LCD_FLAG_B; | ||
1038 | processed = 1; | ||
1039 | break; | ||
1040 | case '+': /* Back light ON */ | ||
1041 | lcd_flags |= LCD_FLAG_L; | ||
1042 | processed = 1; | ||
1043 | break; | ||
1044 | case '-': /* Back light OFF */ | ||
1045 | lcd_flags &= ~LCD_FLAG_L; | ||
1046 | processed = 1; | ||
1047 | break; | ||
1048 | case '*': | ||
1049 | /* flash back light using the keypad timer */ | ||
1050 | if (scan_timer.function != NULL) { | ||
1051 | if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0)) | ||
1052 | lcd_backlight(1); | ||
1053 | light_tempo = FLASH_LIGHT_TEMPO; | ||
1054 | } | ||
1055 | processed = 1; | ||
1056 | break; | ||
1057 | case 'f': /* Small Font */ | ||
1058 | lcd_flags &= ~LCD_FLAG_F; | ||
1059 | processed = 1; | ||
1060 | break; | ||
1061 | case 'F': /* Large Font */ | ||
1062 | lcd_flags |= LCD_FLAG_F; | ||
1063 | processed = 1; | ||
1064 | break; | ||
1065 | case 'n': /* One Line */ | ||
1066 | lcd_flags &= ~LCD_FLAG_N; | ||
1067 | processed = 1; | ||
1068 | break; | ||
1069 | case 'N': /* Two Lines */ | ||
1070 | lcd_flags |= LCD_FLAG_N; | ||
1071 | break; | ||
1072 | case 'l': /* Shift Cursor Left */ | ||
1073 | if (lcd_addr_x > 0) { | ||
1074 | /* back one char if not at end of line */ | ||
1075 | if (lcd_addr_x < lcd_bwidth) | ||
1076 | lcd_write_cmd(0x10); | ||
1077 | lcd_addr_x--; | ||
1078 | } | ||
1079 | processed = 1; | ||
1080 | break; | ||
1081 | case 'r': /* shift cursor right */ | ||
1082 | if (lcd_addr_x < lcd_width) { | ||
1083 | /* allow the cursor to pass the end of the line */ | ||
1084 | if (lcd_addr_x < | ||
1085 | (lcd_bwidth - 1)) | ||
1086 | lcd_write_cmd(0x14); | ||
1087 | lcd_addr_x++; | ||
1088 | } | ||
1089 | processed = 1; | ||
1090 | break; | ||
1091 | case 'L': /* shift display left */ | ||
1092 | lcd_left_shift++; | ||
1093 | lcd_write_cmd(0x18); | ||
1094 | processed = 1; | ||
1095 | break; | ||
1096 | case 'R': /* shift display right */ | ||
1097 | lcd_left_shift--; | ||
1098 | lcd_write_cmd(0x1C); | ||
1099 | processed = 1; | ||
1100 | break; | ||
1101 | case 'k': { /* kill end of line */ | ||
1102 | int x; | ||
1103 | for (x = lcd_addr_x; x < lcd_bwidth; x++) | ||
1104 | lcd_write_data(' '); | ||
1105 | |||
1106 | /* restore cursor position */ | ||
1107 | lcd_gotoxy(); | ||
1108 | processed = 1; | ||
1109 | break; | ||
1110 | } | ||
1111 | case 'I': /* reinitialize display */ | ||
1112 | lcd_init_display(); | ||
1113 | lcd_left_shift = 0; | ||
1114 | processed = 1; | ||
1115 | break; | ||
1116 | case 'G': { | ||
1117 | /* Generator : LGcxxxxx...xx; must have <c> between '0' | ||
1118 | * and '7', representing the numerical ASCII code of the | ||
1119 | * redefined character, and <xx...xx> a sequence of 16 | ||
1120 | * hex digits representing 8 bytes for each character. | ||
1121 | * Most LCDs will only use 5 lower bits of the 7 first | ||
1122 | * bytes. | ||
1123 | */ | ||
1124 | |||
1125 | unsigned char cgbytes[8]; | ||
1126 | unsigned char cgaddr; | ||
1127 | int cgoffset; | ||
1128 | int shift; | ||
1129 | char value; | ||
1130 | int addr; | ||
1131 | |||
1132 | if (strchr(esc, ';') == NULL) | ||
1133 | break; | ||
1134 | |||
1135 | esc++; | ||
1136 | |||
1137 | cgaddr = *(esc++) - '0'; | ||
1138 | if (cgaddr > 7) { | ||
1139 | processed = 1; | ||
1140 | break; | ||
1141 | } | ||
1142 | |||
1143 | cgoffset = 0; | ||
1144 | shift = 0; | ||
1145 | value = 0; | ||
1146 | while (*esc && cgoffset < 8) { | ||
1147 | shift ^= 4; | ||
1148 | if (*esc >= '0' && *esc <= '9') | ||
1149 | value |= (*esc - '0') << shift; | ||
1150 | else if (*esc >= 'A' && *esc <= 'Z') | ||
1151 | value |= (*esc - 'A' + 10) << shift; | ||
1152 | else if (*esc >= 'a' && *esc <= 'z') | ||
1153 | value |= (*esc - 'a' + 10) << shift; | ||
1154 | else { | ||
1155 | esc++; | ||
1156 | continue; | ||
1157 | } | ||
1158 | |||
1159 | if (shift == 0) { | ||
1160 | cgbytes[cgoffset++] = value; | ||
1161 | value = 0; | ||
1162 | } | ||
1163 | |||
1164 | esc++; | ||
1165 | } | ||
1166 | |||
1167 | lcd_write_cmd(0x40 | (cgaddr * 8)); | ||
1168 | for (addr = 0; addr < cgoffset; addr++) | ||
1169 | lcd_write_data(cgbytes[addr]); | ||
1170 | |||
1171 | /* ensures that we stop writing to CGRAM */ | ||
1172 | lcd_gotoxy(); | ||
1173 | processed = 1; | ||
1174 | break; | ||
1175 | } | ||
1176 | case 'x': /* gotoxy : LxXXX[yYYY]; */ | ||
1177 | case 'y': /* gotoxy : LyYYY[xXXX]; */ | ||
1178 | if (strchr(esc, ';') == NULL) | ||
1179 | break; | ||
1180 | |||
1181 | while (*esc) { | ||
1182 | if (*esc == 'x') { | ||
1183 | esc++; | ||
1184 | lcd_addr_x = 0; | ||
1185 | while (isdigit(*esc)) { | ||
1186 | lcd_addr_x = lcd_addr_x * 10 + | ||
1187 | (*esc - '0'); | ||
1188 | esc++; | ||
1189 | } | ||
1190 | } else if (*esc == 'y') { | ||
1191 | esc++; | ||
1192 | lcd_addr_y = 0; | ||
1193 | while (isdigit(*esc)) { | ||
1194 | lcd_addr_y = lcd_addr_y * 10 + | ||
1195 | (*esc - '0'); | ||
1196 | esc++; | ||
1197 | } | ||
1198 | } else | ||
1199 | break; | ||
1200 | } | ||
1201 | |||
1202 | lcd_gotoxy(); | ||
1203 | processed = 1; | ||
1204 | break; | ||
1205 | } | ||
1206 | |||
1207 | /* Check wether one flag was changed */ | ||
1208 | if (oldflags != lcd_flags) { | ||
1209 | /* check whether one of B,C,D flags were changed */ | ||
1210 | if ((oldflags ^ lcd_flags) & | ||
1211 | (LCD_FLAG_B | LCD_FLAG_C | LCD_FLAG_D)) | ||
1212 | /* set display mode */ | ||
1213 | lcd_write_cmd(0x08 | ||
1214 | | ((lcd_flags & LCD_FLAG_D) ? 4 : 0) | ||
1215 | | ((lcd_flags & LCD_FLAG_C) ? 2 : 0) | ||
1216 | | ((lcd_flags & LCD_FLAG_B) ? 1 : 0)); | ||
1217 | /* check whether one of F,N flags was changed */ | ||
1218 | else if ((oldflags ^ lcd_flags) & (LCD_FLAG_F | LCD_FLAG_N)) | ||
1219 | lcd_write_cmd(0x30 | ||
1220 | | ((lcd_flags & LCD_FLAG_F) ? 4 : 0) | ||
1221 | | ((lcd_flags & LCD_FLAG_N) ? 8 : 0)); | ||
1222 | /* check wether L flag was changed */ | ||
1223 | else if ((oldflags ^ lcd_flags) & (LCD_FLAG_L)) { | ||
1224 | if (lcd_flags & (LCD_FLAG_L)) | ||
1225 | lcd_backlight(1); | ||
1226 | else if (light_tempo == 0) | ||
1227 | /* switch off the light only when the tempo | ||
1228 | lighting is gone */ | ||
1229 | lcd_backlight(0); | ||
1230 | } | ||
1231 | } | ||
1232 | |||
1233 | return processed; | ||
1234 | } | ||
1235 | |||
969 | static ssize_t lcd_write(struct file *file, | 1236 | static ssize_t lcd_write(struct file *file, |
970 | const char *buf, size_t count, loff_t *ppos) | 1237 | const char *buf, size_t count, loff_t *ppos) |
971 | { | 1238 | { |
972 | |||
973 | const char *tmp = buf; | 1239 | const char *tmp = buf; |
974 | char c; | 1240 | char c; |
975 | 1241 | ||
976 | for (; count-- > 0; (ppos ? (*ppos)++ : 0), ++tmp) { | 1242 | for (; count-- > 0; (ppos ? (*ppos)++ : 0), ++tmp) { |
977 | if (!in_interrupt() && (((count + 1) & 0x1f) == 0)) | 1243 | if (!in_interrupt() && (((count + 1) & 0x1f) == 0)) |
978 | schedule(); /* let's be a little nice with other processes that need some CPU */ | 1244 | /* let's be a little nice with other processes |
1245 | that need some CPU */ | ||
1246 | schedule(); | ||
979 | 1247 | ||
980 | if (ppos == NULL && file == NULL) | 1248 | if (ppos == NULL && file == NULL) |
981 | c = *tmp; /* let's not use get_user() from the kernel ! */ | 1249 | /* let's not use get_user() from the kernel ! */ |
1250 | c = *tmp; | ||
982 | else if (get_user(c, tmp)) | 1251 | else if (get_user(c, tmp)) |
983 | return -EFAULT; | 1252 | return -EFAULT; |
984 | 1253 | ||
985 | /* first, we'll test if we're in escape mode */ | 1254 | /* first, we'll test if we're in escape mode */ |
986 | if ((c != '\n') && lcd_escape_len >= 0) { /* yes, let's add this char to the buffer */ | 1255 | if ((c != '\n') && lcd_escape_len >= 0) { |
1256 | /* yes, let's add this char to the buffer */ | ||
987 | lcd_escape[lcd_escape_len++] = c; | 1257 | lcd_escape[lcd_escape_len++] = c; |
988 | lcd_escape[lcd_escape_len] = 0; | 1258 | lcd_escape[lcd_escape_len] = 0; |
989 | } else { | 1259 | } else { |
990 | lcd_escape_len = -1; /* aborts any previous escape sequence */ | 1260 | /* aborts any previous escape sequence */ |
1261 | lcd_escape_len = -1; | ||
991 | 1262 | ||
992 | switch (c) { | 1263 | switch (c) { |
993 | case LCD_ESCAPE_CHAR: /* start of an escape sequence */ | 1264 | case LCD_ESCAPE_CHAR: |
1265 | /* start of an escape sequence */ | ||
994 | lcd_escape_len = 0; | 1266 | lcd_escape_len = 0; |
995 | lcd_escape[lcd_escape_len] = 0; | 1267 | lcd_escape[lcd_escape_len] = 0; |
996 | break; | 1268 | break; |
997 | case '\b': /* go back one char and clear it */ | 1269 | case '\b': |
1270 | /* go back one char and clear it */ | ||
998 | if (lcd_addr_x > 0) { | 1271 | if (lcd_addr_x > 0) { |
999 | if (lcd_addr_x < lcd_bwidth) /* check if we're not at the end of the line */ | 1272 | /* check if we're not at the |
1000 | lcd_write_cmd(0x10); /* back one char */ | 1273 | end of the line */ |
1274 | if (lcd_addr_x < lcd_bwidth) | ||
1275 | /* back one char */ | ||
1276 | lcd_write_cmd(0x10); | ||
1001 | lcd_addr_x--; | 1277 | lcd_addr_x--; |
1002 | } | 1278 | } |
1003 | lcd_write_data(' '); /* replace with a space */ | 1279 | /* replace with a space */ |
1004 | lcd_write_cmd(0x10); /* back one char again */ | 1280 | lcd_write_data(' '); |
1281 | /* back one char again */ | ||
1282 | lcd_write_cmd(0x10); | ||
1005 | break; | 1283 | break; |
1006 | case '\014': /* quickly clear the display */ | 1284 | case '\014': |
1285 | /* quickly clear the display */ | ||
1007 | lcd_clear_fast(); | 1286 | lcd_clear_fast(); |
1008 | break; | 1287 | break; |
1009 | case '\n': /* flush the remainder of the current line and go to the | 1288 | case '\n': |
1010 | beginning of the next line */ | 1289 | /* flush the remainder of the current line and |
1290 | go to the beginning of the next line */ | ||
1011 | for (; lcd_addr_x < lcd_bwidth; lcd_addr_x++) | 1291 | for (; lcd_addr_x < lcd_bwidth; lcd_addr_x++) |
1012 | lcd_write_data(' '); | 1292 | lcd_write_data(' '); |
1013 | lcd_addr_x = 0; | 1293 | lcd_addr_x = 0; |
1014 | lcd_addr_y = (lcd_addr_y + 1) % lcd_height; | 1294 | lcd_addr_y = (lcd_addr_y + 1) % lcd_height; |
1015 | lcd_gotoxy(); | 1295 | lcd_gotoxy(); |
1016 | break; | 1296 | break; |
1017 | case '\r': /* go to the beginning of the same line */ | 1297 | case '\r': |
1298 | /* go to the beginning of the same line */ | ||
1018 | lcd_addr_x = 0; | 1299 | lcd_addr_x = 0; |
1019 | lcd_gotoxy(); | 1300 | lcd_gotoxy(); |
1020 | break; | 1301 | break; |
1021 | case '\t': /* print a space instead of the tab */ | 1302 | case '\t': |
1303 | /* print a space instead of the tab */ | ||
1022 | lcd_print(' '); | 1304 | lcd_print(' '); |
1023 | break; | 1305 | break; |
1024 | default: /* simply print this char */ | 1306 | default: |
1307 | /* simply print this char */ | ||
1025 | lcd_print(c); | 1308 | lcd_print(c); |
1026 | break; | 1309 | break; |
1027 | } | 1310 | } |
1028 | } | 1311 | } |
1029 | 1312 | ||
1030 | /* now we'll see if we're in an escape mode and if the current | 1313 | /* now we'll see if we're in an escape mode and if the current |
1031 | escape sequence can be understood. | 1314 | escape sequence can be understood. */ |
1032 | */ | 1315 | if (lcd_escape_len >= 2) { |
1033 | if (lcd_escape_len >= 2) { /* minimal length for an escape command */ | 1316 | int processed = 0; |
1034 | int processed = 0; /* 1 means the command has been processed */ | ||
1035 | 1317 | ||
1036 | if (!strcmp(lcd_escape, "[2J")) { /* Clear the display */ | 1318 | if (!strcmp(lcd_escape, "[2J")) { |
1037 | lcd_clear_fast(); /* clear display */ | 1319 | /* clear the display */ |
1320 | lcd_clear_fast(); | ||
1038 | processed = 1; | 1321 | processed = 1; |
1039 | } else if (!strcmp(lcd_escape, "[H")) { /* Cursor to home */ | 1322 | } else if (!strcmp(lcd_escape, "[H")) { |
1323 | /* cursor to home */ | ||
1040 | lcd_addr_x = lcd_addr_y = 0; | 1324 | lcd_addr_x = lcd_addr_y = 0; |
1041 | lcd_gotoxy(); | 1325 | lcd_gotoxy(); |
1042 | processed = 1; | 1326 | processed = 1; |
1043 | } | 1327 | } |
1044 | /* codes starting with ^[[L */ | 1328 | /* codes starting with ^[[L */ |
1045 | else if ((lcd_escape_len >= 3) && | 1329 | else if ((lcd_escape_len >= 3) && |
1046 | (lcd_escape[0] == '[') && (lcd_escape[1] == 'L')) { /* LCD special codes */ | 1330 | (lcd_escape[0] == '[') && |
1047 | 1331 | (lcd_escape[1] == 'L')) { | |
1048 | char *esc = lcd_escape + 2; | 1332 | processed = handle_lcd_special_code(); |
1049 | int oldflags = lcd_flags; | ||
1050 | |||
1051 | /* check for display mode flags */ | ||
1052 | switch (*esc) { | ||
1053 | case 'D': /* Display ON */ | ||
1054 | lcd_flags |= LCD_FLAG_D; | ||
1055 | processed = 1; | ||
1056 | break; | ||
1057 | case 'd': /* Display OFF */ | ||
1058 | lcd_flags &= ~LCD_FLAG_D; | ||
1059 | processed = 1; | ||
1060 | break; | ||
1061 | case 'C': /* Cursor ON */ | ||
1062 | lcd_flags |= LCD_FLAG_C; | ||
1063 | processed = 1; | ||
1064 | break; | ||
1065 | case 'c': /* Cursor OFF */ | ||
1066 | lcd_flags &= ~LCD_FLAG_C; | ||
1067 | processed = 1; | ||
1068 | break; | ||
1069 | case 'B': /* Blink ON */ | ||
1070 | lcd_flags |= LCD_FLAG_B; | ||
1071 | processed = 1; | ||
1072 | break; | ||
1073 | case 'b': /* Blink OFF */ | ||
1074 | lcd_flags &= ~LCD_FLAG_B; | ||
1075 | processed = 1; | ||
1076 | break; | ||
1077 | case '+': /* Back light ON */ | ||
1078 | lcd_flags |= LCD_FLAG_L; | ||
1079 | processed = 1; | ||
1080 | break; | ||
1081 | case '-': /* Back light OFF */ | ||
1082 | lcd_flags &= ~LCD_FLAG_L; | ||
1083 | processed = 1; | ||
1084 | break; | ||
1085 | case '*': /* flash back light using the keypad timer */ | ||
1086 | if (scan_timer.function != NULL) { | ||
1087 | if (light_tempo == 0 | ||
1088 | && ((lcd_flags & LCD_FLAG_L) | ||
1089 | == 0)) | ||
1090 | lcd_backlight(1); | ||
1091 | light_tempo = FLASH_LIGHT_TEMPO; | ||
1092 | } | ||
1093 | processed = 1; | ||
1094 | break; | ||
1095 | case 'f': /* Small Font */ | ||
1096 | lcd_flags &= ~LCD_FLAG_F; | ||
1097 | processed = 1; | ||
1098 | break; | ||
1099 | case 'F': /* Large Font */ | ||
1100 | lcd_flags |= LCD_FLAG_F; | ||
1101 | processed = 1; | ||
1102 | break; | ||
1103 | case 'n': /* One Line */ | ||
1104 | lcd_flags &= ~LCD_FLAG_N; | ||
1105 | processed = 1; | ||
1106 | break; | ||
1107 | case 'N': /* Two Lines */ | ||
1108 | lcd_flags |= LCD_FLAG_N; | ||
1109 | break; | ||
1110 | |||
1111 | case 'l': /* Shift Cursor Left */ | ||
1112 | if (lcd_addr_x > 0) { | ||
1113 | if (lcd_addr_x < lcd_bwidth) | ||
1114 | lcd_write_cmd(0x10); /* back one char if not at end of line */ | ||
1115 | lcd_addr_x--; | ||
1116 | } | ||
1117 | processed = 1; | ||
1118 | break; | ||
1119 | |||
1120 | case 'r': /* shift cursor right */ | ||
1121 | if (lcd_addr_x < lcd_width) { | ||
1122 | if (lcd_addr_x < (lcd_bwidth - 1)) | ||
1123 | lcd_write_cmd(0x14); /* allow the cursor to pass the end of the line */ | ||
1124 | lcd_addr_x++; | ||
1125 | } | ||
1126 | processed = 1; | ||
1127 | break; | ||
1128 | |||
1129 | case 'L': /* shift display left */ | ||
1130 | lcd_left_shift++; | ||
1131 | lcd_write_cmd(0x18); | ||
1132 | processed = 1; | ||
1133 | break; | ||
1134 | |||
1135 | case 'R': /* shift display right */ | ||
1136 | lcd_left_shift--; | ||
1137 | lcd_write_cmd(0x1C); | ||
1138 | processed = 1; | ||
1139 | break; | ||
1140 | |||
1141 | case 'k':{ /* kill end of line */ | ||
1142 | int x; | ||
1143 | for (x = lcd_addr_x; x < lcd_bwidth; x++) | ||
1144 | lcd_write_data(' '); | ||
1145 | lcd_gotoxy(); /* restore cursor position */ | ||
1146 | processed = 1; | ||
1147 | break; | ||
1148 | } | ||
1149 | case 'I': /* reinitialize display */ | ||
1150 | lcd_init_display(); | ||
1151 | lcd_left_shift = 0; | ||
1152 | processed = 1; | ||
1153 | break; | ||
1154 | |||
1155 | case 'G': /* Generator : LGcxxxxx...xx; */ { | ||
1156 | /* must have <c> between '0' and '7', representing the numerical | ||
1157 | * ASCII code of the redefined character, and <xx...xx> a sequence | ||
1158 | * of 16 hex digits representing 8 bytes for each character. Most | ||
1159 | * LCDs will only use 5 lower bits of the 7 first bytes. | ||
1160 | */ | ||
1161 | |||
1162 | unsigned char cgbytes[8]; | ||
1163 | unsigned char cgaddr; | ||
1164 | int cgoffset; | ||
1165 | int shift; | ||
1166 | char value; | ||
1167 | int addr; | ||
1168 | |||
1169 | if (strchr(esc, ';') == NULL) | ||
1170 | break; | ||
1171 | |||
1172 | esc++; | ||
1173 | |||
1174 | cgaddr = *(esc++) - '0'; | ||
1175 | if (cgaddr > 7) { | ||
1176 | processed = 1; | ||
1177 | break; | ||
1178 | } | ||
1179 | |||
1180 | cgoffset = 0; | ||
1181 | shift = 0; | ||
1182 | value = 0; | ||
1183 | while (*esc && cgoffset < 8) { | ||
1184 | shift ^= 4; | ||
1185 | if (*esc >= '0' && *esc <= '9') | ||
1186 | value |= (*esc - '0') << shift; | ||
1187 | else if (*esc >= 'A' && *esc <= 'Z') | ||
1188 | value |= (*esc - 'A' + 10) << shift; | ||
1189 | else if (*esc >= 'a' && *esc <= 'z') | ||
1190 | value |= (*esc - 'a' + 10) << shift; | ||
1191 | else { | ||
1192 | esc++; | ||
1193 | continue; | ||
1194 | } | ||
1195 | |||
1196 | if (shift == 0) { | ||
1197 | cgbytes[cgoffset++] = value; | ||
1198 | value = 0; | ||
1199 | } | ||
1200 | |||
1201 | esc++; | ||
1202 | } | ||
1203 | |||
1204 | lcd_write_cmd(0x40 | (cgaddr * 8)); | ||
1205 | for (addr = 0; addr < cgoffset; addr++) | ||
1206 | lcd_write_data(cgbytes[addr]); | ||
1207 | |||
1208 | lcd_gotoxy(); /* ensures that we stop writing to CGRAM */ | ||
1209 | processed = 1; | ||
1210 | break; | ||
1211 | } | ||
1212 | case 'x': /* gotoxy : LxXXX[yYYY]; */ | ||
1213 | case 'y': /* gotoxy : LyYYY[xXXX]; */ | ||
1214 | if (strchr(esc, ';') == NULL) | ||
1215 | break; | ||
1216 | |||
1217 | while (*esc) { | ||
1218 | if (*esc == 'x') { | ||
1219 | esc++; | ||
1220 | lcd_addr_x = 0; | ||
1221 | while (isdigit(*esc)) { | ||
1222 | lcd_addr_x = | ||
1223 | lcd_addr_x * | ||
1224 | 10 + (*esc - | ||
1225 | '0'); | ||
1226 | esc++; | ||
1227 | } | ||
1228 | } else if (*esc == 'y') { | ||
1229 | esc++; | ||
1230 | lcd_addr_y = 0; | ||
1231 | while (isdigit(*esc)) { | ||
1232 | lcd_addr_y = | ||
1233 | lcd_addr_y * | ||
1234 | 10 + (*esc - | ||
1235 | '0'); | ||
1236 | esc++; | ||
1237 | } | ||
1238 | } else | ||
1239 | break; | ||
1240 | } | ||
1241 | |||
1242 | lcd_gotoxy(); | ||
1243 | processed = 1; | ||
1244 | break; | ||
1245 | } /* end of switch */ | ||
1246 | |||
1247 | /* Check wether one flag was changed */ | ||
1248 | if (oldflags != lcd_flags) { | ||
1249 | /* check wether one of B,C,D flags was changed */ | ||
1250 | if ((oldflags ^ lcd_flags) & | ||
1251 | (LCD_FLAG_B | LCD_FLAG_C | LCD_FLAG_D)) | ||
1252 | /* set display mode */ | ||
1253 | lcd_write_cmd(0x08 | | ||
1254 | ((lcd_flags & LCD_FLAG_D) ? 4 : 0) | | ||
1255 | ((lcd_flags & LCD_FLAG_C) ? 2 : 0) | | ||
1256 | ((lcd_flags & LCD_FLAG_B) ? 1 : 0)); | ||
1257 | /* check wether one of F,N flags was changed */ | ||
1258 | else if ((oldflags ^ lcd_flags) & | ||
1259 | (LCD_FLAG_F | LCD_FLAG_N)) | ||
1260 | lcd_write_cmd(0x30 | | ||
1261 | ((lcd_flags & LCD_FLAG_F) ? 4 : 0) | | ||
1262 | ((lcd_flags & LCD_FLAG_N) ? 8 : 0)); | ||
1263 | /* check wether L flag was changed */ | ||
1264 | else if ((oldflags ^ lcd_flags) & | ||
1265 | (LCD_FLAG_L)) { | ||
1266 | if (lcd_flags & (LCD_FLAG_L)) | ||
1267 | lcd_backlight(1); | ||
1268 | else if (light_tempo == 0) /* switch off the light only when the tempo lighting is gone */ | ||
1269 | lcd_backlight(0); | ||
1270 | } | ||
1271 | } | ||
1272 | } | 1333 | } |
1273 | 1334 | ||
1274 | /* LCD special escape codes */ | 1335 | /* LCD special escape codes */ |
1275 | /* flush the escape sequence if it's been processed or if it is | 1336 | /* flush the escape sequence if it's been processed |
1276 | getting too long. */ | 1337 | or if it is getting too long. */ |
1277 | if (processed || (lcd_escape_len >= LCD_ESCAPE_LEN)) | 1338 | if (processed || (lcd_escape_len >= LCD_ESCAPE_LEN)) |
1278 | lcd_escape_len = -1; | 1339 | lcd_escape_len = -1; |
1279 | } /* escape codes */ | 1340 | } /* escape codes */ |
1280 | } | 1341 | } |
1281 | 1342 | ||
1282 | return tmp - buf; | 1343 | return tmp - buf; |
@@ -1304,7 +1365,7 @@ static int lcd_release(struct inode *inode, struct file *file) | |||
1304 | return 0; | 1365 | return 0; |
1305 | } | 1366 | } |
1306 | 1367 | ||
1307 | static struct file_operations lcd_fops = { | 1368 | static const struct file_operations lcd_fops = { |
1308 | .write = lcd_write, | 1369 | .write = lcd_write, |
1309 | .open = lcd_open, | 1370 | .open = lcd_open, |
1310 | .release = lcd_release, | 1371 | .release = lcd_release, |
@@ -1327,7 +1388,8 @@ void panel_lcd_print(char *s) | |||
1327 | void lcd_init(void) | 1388 | void lcd_init(void) |
1328 | { | 1389 | { |
1329 | switch (lcd_type) { | 1390 | switch (lcd_type) { |
1330 | case LCD_TYPE_OLD: /* parallel mode, 8 bits */ | 1391 | case LCD_TYPE_OLD: |
1392 | /* parallel mode, 8 bits */ | ||
1331 | if (lcd_proto < 0) | 1393 | if (lcd_proto < 0) |
1332 | lcd_proto = LCD_PROTO_PARALLEL; | 1394 | lcd_proto = LCD_PROTO_PARALLEL; |
1333 | if (lcd_charset < 0) | 1395 | if (lcd_charset < 0) |
@@ -1346,7 +1408,8 @@ void lcd_init(void) | |||
1346 | if (lcd_height < 0) | 1408 | if (lcd_height < 0) |
1347 | lcd_height = 2; | 1409 | lcd_height = 2; |
1348 | break; | 1410 | break; |
1349 | case LCD_TYPE_KS0074: /* serial mode, ks0074 */ | 1411 | case LCD_TYPE_KS0074: |
1412 | /* serial mode, ks0074 */ | ||
1350 | if (lcd_proto < 0) | 1413 | if (lcd_proto < 0) |
1351 | lcd_proto = LCD_PROTO_SERIAL; | 1414 | lcd_proto = LCD_PROTO_SERIAL; |
1352 | if (lcd_charset < 0) | 1415 | if (lcd_charset < 0) |
@@ -1367,7 +1430,8 @@ void lcd_init(void) | |||
1367 | if (lcd_height < 0) | 1430 | if (lcd_height < 0) |
1368 | lcd_height = 2; | 1431 | lcd_height = 2; |
1369 | break; | 1432 | break; |
1370 | case LCD_TYPE_NEXCOM: /* parallel mode, 8 bits, generic */ | 1433 | case LCD_TYPE_NEXCOM: |
1434 | /* parallel mode, 8 bits, generic */ | ||
1371 | if (lcd_proto < 0) | 1435 | if (lcd_proto < 0) |
1372 | lcd_proto = LCD_PROTO_PARALLEL; | 1436 | lcd_proto = LCD_PROTO_PARALLEL; |
1373 | if (lcd_charset < 0) | 1437 | if (lcd_charset < 0) |
@@ -1388,14 +1452,16 @@ void lcd_init(void) | |||
1388 | if (lcd_height < 0) | 1452 | if (lcd_height < 0) |
1389 | lcd_height = 2; | 1453 | lcd_height = 2; |
1390 | break; | 1454 | break; |
1391 | case LCD_TYPE_CUSTOM: /* customer-defined */ | 1455 | case LCD_TYPE_CUSTOM: |
1456 | /* customer-defined */ | ||
1392 | if (lcd_proto < 0) | 1457 | if (lcd_proto < 0) |
1393 | lcd_proto = DEFAULT_LCD_PROTO; | 1458 | lcd_proto = DEFAULT_LCD_PROTO; |
1394 | if (lcd_charset < 0) | 1459 | if (lcd_charset < 0) |
1395 | lcd_charset = DEFAULT_LCD_CHARSET; | 1460 | lcd_charset = DEFAULT_LCD_CHARSET; |
1396 | /* default geometry will be set later */ | 1461 | /* default geometry will be set later */ |
1397 | break; | 1462 | break; |
1398 | case LCD_TYPE_HANTRONIX: /* parallel mode, 8 bits, hantronix-like */ | 1463 | case LCD_TYPE_HANTRONIX: |
1464 | /* parallel mode, 8 bits, hantronix-like */ | ||
1399 | default: | 1465 | default: |
1400 | if (lcd_proto < 0) | 1466 | if (lcd_proto < 0) |
1401 | lcd_proto = LCD_PROTO_PARALLEL; | 1467 | lcd_proto = LCD_PROTO_PARALLEL; |
@@ -1496,8 +1562,7 @@ void lcd_init(void) | |||
1496 | 1562 | ||
1497 | /* before this line, we must NOT send anything to the display. | 1563 | /* before this line, we must NOT send anything to the display. |
1498 | * Since lcd_init_display() needs to write data, we have to | 1564 | * Since lcd_init_display() needs to write data, we have to |
1499 | * enable mark the LCD initialized just before. | 1565 | * enable mark the LCD initialized just before. */ |
1500 | */ | ||
1501 | lcd_initialized = 1; | 1566 | lcd_initialized = 1; |
1502 | lcd_init_display(); | 1567 | lcd_init_display(); |
1503 | 1568 | ||
@@ -1511,7 +1576,8 @@ void lcd_init(void) | |||
1511 | PANEL_VERSION); | 1576 | PANEL_VERSION); |
1512 | #endif | 1577 | #endif |
1513 | lcd_addr_x = lcd_addr_y = 0; | 1578 | lcd_addr_x = lcd_addr_y = 0; |
1514 | lcd_must_clear = 1; /* clear the display on the next device opening */ | 1579 | /* clear the display on the next device opening */ |
1580 | lcd_must_clear = 1; | ||
1515 | lcd_gotoxy(); | 1581 | lcd_gotoxy(); |
1516 | } | 1582 | } |
1517 | 1583 | ||
@@ -1535,7 +1601,8 @@ static ssize_t keypad_read(struct file *file, | |||
1535 | return -EINTR; | 1601 | return -EINTR; |
1536 | } | 1602 | } |
1537 | 1603 | ||
1538 | for (; count-- > 0 && (keypad_buflen > 0); ++i, ++tmp, --keypad_buflen) { | 1604 | for (; count-- > 0 && (keypad_buflen > 0); |
1605 | ++i, ++tmp, --keypad_buflen) { | ||
1539 | put_user(keypad_buffer[keypad_start], tmp); | 1606 | put_user(keypad_buffer[keypad_start], tmp); |
1540 | keypad_start = (keypad_start + 1) % KEYPAD_BUFFER; | 1607 | keypad_start = (keypad_start + 1) % KEYPAD_BUFFER; |
1541 | } | 1608 | } |
@@ -1564,7 +1631,7 @@ static int keypad_release(struct inode *inode, struct file *file) | |||
1564 | return 0; | 1631 | return 0; |
1565 | } | 1632 | } |
1566 | 1633 | ||
1567 | static struct file_operations keypad_fops = { | 1634 | static const struct file_operations keypad_fops = { |
1568 | .read = keypad_read, /* read */ | 1635 | .read = keypad_read, /* read */ |
1569 | .open = keypad_open, /* open */ | 1636 | .open = keypad_open, /* open */ |
1570 | .release = keypad_release, /* close */ | 1637 | .release = keypad_release, /* close */ |
@@ -1591,14 +1658,15 @@ static void keypad_send_key(char *string, int max_len) | |||
1591 | } | 1658 | } |
1592 | } | 1659 | } |
1593 | 1660 | ||
1594 | /* this function scans all the bits involving at least one logical signal, and puts the | 1661 | /* this function scans all the bits involving at least one logical signal, |
1595 | * results in the bitfield "phys_read" (one bit per established contact), and sets | 1662 | * and puts the results in the bitfield "phys_read" (one bit per established |
1596 | * "phys_read_prev" to "phys_read". | 1663 | * contact), and sets "phys_read_prev" to "phys_read". |
1597 | * | 1664 | * |
1598 | * Note: to debounce input signals, we will only consider as switched a signal which is | 1665 | * Note: to debounce input signals, we will only consider as switched a signal |
1599 | * stable across 2 measures. Signals which are different between two reads will be kept | 1666 | * which is stable across 2 measures. Signals which are different between two |
1600 | * as they previously were in their logical form (phys_prev). A signal which has just | 1667 | * reads will be kept as they previously were in their logical form (phys_prev). |
1601 | * switched will have a 1 in (phys_read ^ phys_read_prev). | 1668 | * A signal which has just switched will have a 1 in |
1669 | * (phys_read ^ phys_read_prev). | ||
1602 | */ | 1670 | */ |
1603 | static void phys_scan_contacts(void) | 1671 | static void phys_scan_contacts(void) |
1604 | { | 1672 | { |
@@ -1611,21 +1679,30 @@ static void phys_scan_contacts(void) | |||
1611 | phys_read_prev = phys_read; | 1679 | phys_read_prev = phys_read; |
1612 | phys_read = 0; /* flush all signals */ | 1680 | phys_read = 0; /* flush all signals */ |
1613 | 1681 | ||
1614 | oldval = r_dtr(pprt) | scan_mask_o; /* keep track of old value, with all outputs disabled */ | 1682 | /* keep track of old value, with all outputs disabled */ |
1615 | w_dtr(pprt, oldval & ~scan_mask_o); /* activate all keyboard outputs (active low) */ | 1683 | oldval = r_dtr(pprt) | scan_mask_o; |
1616 | bitmask = PNL_PINPUT(r_str(pprt)) & scan_mask_i; /* will have a 1 for each bit set to gnd */ | 1684 | /* activate all keyboard outputs (active low) */ |
1617 | w_dtr(pprt, oldval); /* disable all matrix signals */ | 1685 | w_dtr(pprt, oldval & ~scan_mask_o); |
1686 | |||
1687 | /* will have a 1 for each bit set to gnd */ | ||
1688 | bitmask = PNL_PINPUT(r_str(pprt)) & scan_mask_i; | ||
1689 | /* disable all matrix signals */ | ||
1690 | w_dtr(pprt, oldval); | ||
1618 | 1691 | ||
1619 | /* now that all outputs are cleared, the only active input bits are | 1692 | /* now that all outputs are cleared, the only active input bits are |
1620 | * directly connected to the ground | 1693 | * directly connected to the ground |
1621 | */ | 1694 | */ |
1622 | gndmask = PNL_PINPUT(r_str(pprt)) & scan_mask_i; /* 1 for each grounded input */ | ||
1623 | 1695 | ||
1624 | phys_read |= (pmask_t) gndmask << 40; /* grounded inputs are signals 40-44 */ | 1696 | /* 1 for each grounded input */ |
1697 | gndmask = PNL_PINPUT(r_str(pprt)) & scan_mask_i; | ||
1698 | |||
1699 | /* grounded inputs are signals 40-44 */ | ||
1700 | phys_read |= (pmask_t) gndmask << 40; | ||
1625 | 1701 | ||
1626 | if (bitmask != gndmask) { | 1702 | if (bitmask != gndmask) { |
1627 | /* since clearing the outputs changed some inputs, we know that some | 1703 | /* since clearing the outputs changed some inputs, we know |
1628 | * input signals are currently tied to some outputs. So we'll scan them. | 1704 | * that some input signals are currently tied to some outputs. |
1705 | * So we'll scan them. | ||
1629 | */ | 1706 | */ |
1630 | for (bit = 0; bit < 8; bit++) { | 1707 | for (bit = 0; bit < 8; bit++) { |
1631 | bitval = 1 << bit; | 1708 | bitval = 1 << bit; |
@@ -1639,11 +1716,127 @@ static void phys_scan_contacts(void) | |||
1639 | } | 1716 | } |
1640 | w_dtr(pprt, oldval); /* disable all outputs */ | 1717 | w_dtr(pprt, oldval); /* disable all outputs */ |
1641 | } | 1718 | } |
1642 | /* this is easy: use old bits when they are flapping, use new ones when stable */ | 1719 | /* this is easy: use old bits when they are flapping, |
1643 | phys_curr = | 1720 | * use new ones when stable */ |
1644 | (phys_prev & (phys_read ^ phys_read_prev)) | (phys_read & | 1721 | phys_curr = (phys_prev & (phys_read ^ phys_read_prev)) | |
1645 | ~(phys_read ^ | 1722 | (phys_read & ~(phys_read ^ phys_read_prev)); |
1646 | phys_read_prev)); | 1723 | } |
1724 | |||
1725 | static inline int input_state_high(struct logical_input *input) | ||
1726 | { | ||
1727 | #if 0 | ||
1728 | /* FIXME: | ||
1729 | * this is an invalid test. It tries to catch | ||
1730 | * transitions from single-key to multiple-key, but | ||
1731 | * doesn't take into account the contacts polarity. | ||
1732 | * The only solution to the problem is to parse keys | ||
1733 | * from the most complex to the simplest combinations, | ||
1734 | * and mark them as 'caught' once a combination | ||
1735 | * matches, then unmatch it for all other ones. | ||
1736 | */ | ||
1737 | |||
1738 | /* try to catch dangerous transitions cases : | ||
1739 | * someone adds a bit, so this signal was a false | ||
1740 | * positive resulting from a transition. We should | ||
1741 | * invalidate the signal immediately and not call the | ||
1742 | * release function. | ||
1743 | * eg: 0 -(press A)-> A -(press B)-> AB : don't match A's release. | ||
1744 | */ | ||
1745 | if (((phys_prev & input->mask) == input->value) | ||
1746 | && ((phys_curr & input->mask) > input->value)) { | ||
1747 | input->state = INPUT_ST_LOW; /* invalidate */ | ||
1748 | return 1; | ||
1749 | } | ||
1750 | #endif | ||
1751 | |||
1752 | if ((phys_curr & input->mask) == input->value) { | ||
1753 | if ((input->type == INPUT_TYPE_STD) && | ||
1754 | (input->high_timer == 0)) { | ||
1755 | input->high_timer++; | ||
1756 | if (input->u.std.press_fct != NULL) | ||
1757 | input->u.std.press_fct(input->u.std.press_data); | ||
1758 | } else if (input->type == INPUT_TYPE_KBD) { | ||
1759 | /* will turn on the light */ | ||
1760 | keypressed = 1; | ||
1761 | |||
1762 | if (input->high_timer == 0) { | ||
1763 | char *press_str = input->u.kbd.press_str; | ||
1764 | if (press_str[0]) | ||
1765 | keypad_send_key(press_str, | ||
1766 | sizeof(press_str)); | ||
1767 | } | ||
1768 | |||
1769 | if (input->u.kbd.repeat_str[0]) { | ||
1770 | char *repeat_str = input->u.kbd.repeat_str; | ||
1771 | if (input->high_timer >= KEYPAD_REP_START) { | ||
1772 | input->high_timer -= KEYPAD_REP_DELAY; | ||
1773 | keypad_send_key(repeat_str, | ||
1774 | sizeof(repeat_str)); | ||
1775 | } | ||
1776 | /* we will need to come back here soon */ | ||
1777 | inputs_stable = 0; | ||
1778 | } | ||
1779 | |||
1780 | if (input->high_timer < 255) | ||
1781 | input->high_timer++; | ||
1782 | } | ||
1783 | return 1; | ||
1784 | } else { | ||
1785 | /* else signal falling down. Let's fall through. */ | ||
1786 | input->state = INPUT_ST_FALLING; | ||
1787 | input->fall_timer = 0; | ||
1788 | } | ||
1789 | return 0; | ||
1790 | } | ||
1791 | |||
1792 | static inline void input_state_falling(struct logical_input *input) | ||
1793 | { | ||
1794 | #if 0 | ||
1795 | /* FIXME !!! same comment as in input_state_high */ | ||
1796 | if (((phys_prev & input->mask) == input->value) | ||
1797 | && ((phys_curr & input->mask) > input->value)) { | ||
1798 | input->state = INPUT_ST_LOW; /* invalidate */ | ||
1799 | return; | ||
1800 | } | ||
1801 | #endif | ||
1802 | |||
1803 | if ((phys_curr & input->mask) == input->value) { | ||
1804 | if (input->type == INPUT_TYPE_KBD) { | ||
1805 | /* will turn on the light */ | ||
1806 | keypressed = 1; | ||
1807 | |||
1808 | if (input->u.kbd.repeat_str[0]) { | ||
1809 | char *repeat_str = input->u.kbd.repeat_str; | ||
1810 | if (input->high_timer >= KEYPAD_REP_START) | ||
1811 | input->high_timer -= KEYPAD_REP_DELAY; | ||
1812 | keypad_send_key(repeat_str, | ||
1813 | sizeof(repeat_str)); | ||
1814 | /* we will need to come back here soon */ | ||
1815 | inputs_stable = 0; | ||
1816 | } | ||
1817 | |||
1818 | if (input->high_timer < 255) | ||
1819 | input->high_timer++; | ||
1820 | } | ||
1821 | input->state = INPUT_ST_HIGH; | ||
1822 | } else if (input->fall_timer >= input->fall_time) { | ||
1823 | /* call release event */ | ||
1824 | if (input->type == INPUT_TYPE_STD) { | ||
1825 | void (*release_fct)(int) = input->u.std.release_fct; | ||
1826 | if (release_fct != NULL) | ||
1827 | release_fct(input->u.std.release_data); | ||
1828 | } else if (input->type == INPUT_TYPE_KBD) { | ||
1829 | char *release_str = input->u.kbd.release_str; | ||
1830 | if (release_str[0]) | ||
1831 | keypad_send_key(release_str, | ||
1832 | sizeof(release_str)); | ||
1833 | } | ||
1834 | |||
1835 | input->state = INPUT_ST_LOW; | ||
1836 | } else { | ||
1837 | input->fall_timer++; | ||
1838 | inputs_stable = 0; | ||
1839 | } | ||
1647 | } | 1840 | } |
1648 | 1841 | ||
1649 | static void panel_process_inputs(void) | 1842 | static void panel_process_inputs(void) |
@@ -1666,10 +1859,12 @@ static void panel_process_inputs(void) | |||
1666 | case INPUT_ST_LOW: | 1859 | case INPUT_ST_LOW: |
1667 | if ((phys_curr & input->mask) != input->value) | 1860 | if ((phys_curr & input->mask) != input->value) |
1668 | break; | 1861 | break; |
1669 | /* if all needed ones were already set previously, this means that | 1862 | /* if all needed ones were already set previously, |
1670 | * this logical signal has been activated by the releasing of | 1863 | * this means that this logical signal has been |
1671 | * another combined signal, so we don't want to match. | 1864 | * activated by the releasing of another combined |
1672 | * eg: AB -(release B)-> A -(release A)-> 0 : don't match A. | 1865 | * signal, so we don't want to match. |
1866 | * eg: AB -(release B)-> A -(release A)-> 0 : | ||
1867 | * don't match A. | ||
1673 | */ | 1868 | */ |
1674 | if ((phys_prev & input->mask) == input->value) | 1869 | if ((phys_prev & input->mask) == input->value) |
1675 | break; | 1870 | break; |
@@ -1690,122 +1885,11 @@ static void panel_process_inputs(void) | |||
1690 | input->state = INPUT_ST_HIGH; | 1885 | input->state = INPUT_ST_HIGH; |
1691 | /* no break here, fall through */ | 1886 | /* no break here, fall through */ |
1692 | case INPUT_ST_HIGH: | 1887 | case INPUT_ST_HIGH: |
1693 | #if 0 | 1888 | if (input_state_high(input)) |
1694 | /* FIXME: | ||
1695 | * this is an invalid test. It tries to catch transitions from single-key | ||
1696 | * to multiple-key, but doesn't take into account the contacts polarity. | ||
1697 | * The only solution to the problem is to parse keys from the most complex | ||
1698 | * to the simplest combinations, and mark them as 'caught' once a combination | ||
1699 | * matches, then unmatch it for all other ones. | ||
1700 | */ | ||
1701 | |||
1702 | /* try to catch dangerous transitions cases : | ||
1703 | * someone adds a bit, so this signal was a false | ||
1704 | * positive resulting from a transition. We should invalidate | ||
1705 | * the signal immediately and not call the release function. | ||
1706 | * eg: 0 -(press A)-> A -(press B)-> AB : don't match A's release. | ||
1707 | */ | ||
1708 | if (((phys_prev & input->mask) == input->value) | ||
1709 | && ((phys_curr & input->mask) > input->value)) { | ||
1710 | input->state = INPUT_ST_LOW; /* invalidate */ | ||
1711 | break; | 1889 | break; |
1712 | } | ||
1713 | #endif | ||
1714 | |||
1715 | if ((phys_curr & input->mask) == input->value) { | ||
1716 | if ((input->type == INPUT_TYPE_STD) | ||
1717 | && (input->high_timer == 0)) { | ||
1718 | input->high_timer++; | ||
1719 | if (input->u.std.press_fct != NULL) | ||
1720 | input->u.std.press_fct(input->u. | ||
1721 | std. | ||
1722 | press_data); | ||
1723 | } else if (input->type == INPUT_TYPE_KBD) { | ||
1724 | keypressed = 1; /* will turn on the light */ | ||
1725 | |||
1726 | if (input->high_timer == 0) { | ||
1727 | if (input->u.kbd.press_str[0]) | ||
1728 | keypad_send_key(input-> | ||
1729 | u.kbd. | ||
1730 | press_str, | ||
1731 | sizeof | ||
1732 | (input-> | ||
1733 | u.kbd. | ||
1734 | press_str)); | ||
1735 | } | ||
1736 | |||
1737 | if (input->u.kbd.repeat_str[0]) { | ||
1738 | if (input->high_timer >= | ||
1739 | KEYPAD_REP_START) { | ||
1740 | input->high_timer -= | ||
1741 | KEYPAD_REP_DELAY; | ||
1742 | keypad_send_key(input-> | ||
1743 | u.kbd. | ||
1744 | repeat_str, | ||
1745 | sizeof | ||
1746 | (input-> | ||
1747 | u.kbd. | ||
1748 | repeat_str)); | ||
1749 | } | ||
1750 | inputs_stable = 0; /* we will need to come back here soon */ | ||
1751 | } | ||
1752 | |||
1753 | if (input->high_timer < 255) | ||
1754 | input->high_timer++; | ||
1755 | } | ||
1756 | break; | ||
1757 | } else { | ||
1758 | /* else signal falling down. Let's fall through. */ | ||
1759 | input->state = INPUT_ST_FALLING; | ||
1760 | input->fall_timer = 0; | ||
1761 | } | ||
1762 | /* no break here, fall through */ | 1890 | /* no break here, fall through */ |
1763 | case INPUT_ST_FALLING: | 1891 | case INPUT_ST_FALLING: |
1764 | #if 0 | 1892 | input_state_falling(input); |
1765 | /* FIXME !!! same comment as above */ | ||
1766 | if (((phys_prev & input->mask) == input->value) | ||
1767 | && ((phys_curr & input->mask) > input->value)) { | ||
1768 | input->state = INPUT_ST_LOW; /* invalidate */ | ||
1769 | break; | ||
1770 | } | ||
1771 | #endif | ||
1772 | |||
1773 | if ((phys_curr & input->mask) == input->value) { | ||
1774 | if (input->type == INPUT_TYPE_KBD) { | ||
1775 | keypressed = 1; /* will turn on the light */ | ||
1776 | |||
1777 | if (input->u.kbd.repeat_str[0]) { | ||
1778 | if (input->high_timer >= KEYPAD_REP_START) | ||
1779 | input->high_timer -= KEYPAD_REP_DELAY; | ||
1780 | keypad_send_key(input->u.kbd.repeat_str, | ||
1781 | sizeof(input->u.kbd.repeat_str)); | ||
1782 | inputs_stable = 0; /* we will need to come back here soon */ | ||
1783 | } | ||
1784 | |||
1785 | if (input->high_timer < 255) | ||
1786 | input->high_timer++; | ||
1787 | } | ||
1788 | input->state = INPUT_ST_HIGH; | ||
1789 | break; | ||
1790 | } else if (input->fall_timer >= input->fall_time) { | ||
1791 | /* call release event */ | ||
1792 | if (input->type == INPUT_TYPE_STD) { | ||
1793 | if (input->u.std.release_fct != NULL) | ||
1794 | input->u.std.release_fct(input->u.std.release_data); | ||
1795 | |||
1796 | } else if (input->type == INPUT_TYPE_KBD) { | ||
1797 | if (input->u.kbd.release_str[0]) | ||
1798 | keypad_send_key(input->u.kbd.release_str, | ||
1799 | sizeof(input->u.kbd.release_str)); | ||
1800 | } | ||
1801 | |||
1802 | input->state = INPUT_ST_LOW; | ||
1803 | break; | ||
1804 | } else { | ||
1805 | input->fall_timer++; | ||
1806 | inputs_stable = 0; | ||
1807 | break; | ||
1808 | } | ||
1809 | } | 1893 | } |
1810 | } | 1894 | } |
1811 | } | 1895 | } |
@@ -1815,7 +1899,9 @@ static void panel_scan_timer(void) | |||
1815 | if (keypad_enabled && keypad_initialized) { | 1899 | if (keypad_enabled && keypad_initialized) { |
1816 | if (spin_trylock(&pprt_lock)) { | 1900 | if (spin_trylock(&pprt_lock)) { |
1817 | phys_scan_contacts(); | 1901 | phys_scan_contacts(); |
1818 | spin_unlock(&pprt_lock); /* no need for the parport anymore */ | 1902 | |
1903 | /* no need for the parport anymore */ | ||
1904 | spin_unlock(&pprt_lock); | ||
1819 | } | 1905 | } |
1820 | 1906 | ||
1821 | if (!inputs_stable || phys_curr != phys_prev) | 1907 | if (!inputs_stable || phys_curr != phys_prev) |
@@ -1850,8 +1936,8 @@ static void init_scan_timer(void) | |||
1850 | } | 1936 | } |
1851 | 1937 | ||
1852 | /* converts a name of the form "({BbAaPpSsEe}{01234567-})*" to a series of bits. | 1938 | /* converts a name of the form "({BbAaPpSsEe}{01234567-})*" to a series of bits. |
1853 | * if <omask> or <imask> are non-null, they will be or'ed with the bits corresponding | 1939 | * if <omask> or <imask> are non-null, they will be or'ed with the bits |
1854 | * to out and in bits respectively. | 1940 | * corresponding to out and in bits respectively. |
1855 | * returns 1 if ok, 0 if error (in which case, nothing is written). | 1941 | * returns 1 if ok, 0 if error (in which case, nothing is written). |
1856 | */ | 1942 | */ |
1857 | static int input_name2mask(char *name, pmask_t *mask, pmask_t *value, | 1943 | static int input_name2mask(char *name, pmask_t *mask, pmask_t *value, |
@@ -1864,7 +1950,8 @@ static int input_name2mask(char *name, pmask_t *mask, pmask_t *value, | |||
1864 | om = im = m = v = 0ULL; | 1950 | om = im = m = v = 0ULL; |
1865 | while (*name) { | 1951 | while (*name) { |
1866 | int in, out, bit, neg; | 1952 | int in, out, bit, neg; |
1867 | for (in = 0; (in < sizeof(sigtab)) && (sigtab[in] != *name); in++) | 1953 | for (in = 0; (in < sizeof(sigtab)) && |
1954 | (sigtab[in] != *name); in++) | ||
1868 | ; | 1955 | ; |
1869 | if (in >= sizeof(sigtab)) | 1956 | if (in >= sizeof(sigtab)) |
1870 | return 0; /* input name not found */ | 1957 | return 0; /* input name not found */ |
@@ -1936,7 +2023,8 @@ static struct logical_input *panel_bind_key(char *name, char *press, | |||
1936 | /* tries to bind a callback function to the signal name <name>. The function | 2023 | /* tries to bind a callback function to the signal name <name>. The function |
1937 | * <press_fct> will be called with the <press_data> arg when the signal is | 2024 | * <press_fct> will be called with the <press_data> arg when the signal is |
1938 | * activated, and so on for <release_fct>/<release_data> | 2025 | * activated, and so on for <release_fct>/<release_data> |
1939 | * Returns the pointer to the new signal if ok, NULL if the signal could not be bound. | 2026 | * Returns the pointer to the new signal if ok, NULL if the signal could not |
2027 | * be bound. | ||
1940 | */ | 2028 | */ |
1941 | static struct logical_input *panel_bind_callback(char *name, | 2029 | static struct logical_input *panel_bind_callback(char *name, |
1942 | void (*press_fct) (int), | 2030 | void (*press_fct) (int), |
@@ -2028,24 +2116,27 @@ static void panel_attach(struct parport *port) | |||
2028 | 2116 | ||
2029 | if (pprt) { | 2117 | if (pprt) { |
2030 | printk(KERN_ERR | 2118 | printk(KERN_ERR |
2031 | "panel_attach(): port->number=%d parport=%d, already registered !\n", | 2119 | "panel_attach(): port->number=%d parport=%d, " |
2120 | "already registered !\n", | ||
2032 | port->number, parport); | 2121 | port->number, parport); |
2033 | return; | 2122 | return; |
2034 | } | 2123 | } |
2035 | 2124 | ||
2036 | pprt = parport_register_device(port, "panel", NULL, NULL, /* pf, kf */ | 2125 | pprt = parport_register_device(port, "panel", NULL, NULL, /* pf, kf */ |
2037 | NULL, | 2126 | NULL, |
2038 | /*PARPORT_DEV_EXCL */ | 2127 | /*PARPORT_DEV_EXCL */ |
2039 | 0, (void *)&pprt); | 2128 | 0, (void *)&pprt); |
2040 | 2129 | ||
2041 | if (parport_claim(pprt)) { | 2130 | if (parport_claim(pprt)) { |
2042 | printk(KERN_ERR | 2131 | printk(KERN_ERR |
2043 | "Panel: could not claim access to parport%d. Aborting.\n", | 2132 | "Panel: could not claim access to parport%d. " |
2044 | parport); | 2133 | "Aborting.\n", parport); |
2045 | return; | 2134 | return; |
2046 | } | 2135 | } |
2047 | 2136 | ||
2048 | /* must init LCD first, just in case an IRQ from the keypad is generated at keypad init */ | 2137 | /* must init LCD first, just in case an IRQ from the keypad is |
2138 | * generated at keypad init | ||
2139 | */ | ||
2049 | if (lcd_enabled) { | 2140 | if (lcd_enabled) { |
2050 | lcd_init(); | 2141 | lcd_init(); |
2051 | misc_register(&lcd_dev); | 2142 | misc_register(&lcd_dev); |
@@ -2064,7 +2155,8 @@ static void panel_detach(struct parport *port) | |||
2064 | 2155 | ||
2065 | if (!pprt) { | 2156 | if (!pprt) { |
2066 | printk(KERN_ERR | 2157 | printk(KERN_ERR |
2067 | "panel_detach(): port->number=%d parport=%d, nothing to unregister.\n", | 2158 | "panel_detach(): port->number=%d parport=%d, " |
2159 | "nothing to unregister.\n", | ||
2068 | port->number, parport); | 2160 | port->number, parport); |
2069 | return; | 2161 | return; |
2070 | } | 2162 | } |
@@ -2105,13 +2197,15 @@ int panel_init(void) | |||
2105 | 2197 | ||
2106 | /* take care of an eventual profile */ | 2198 | /* take care of an eventual profile */ |
2107 | switch (profile) { | 2199 | switch (profile) { |
2108 | case PANEL_PROFILE_CUSTOM: /* custom profile */ | 2200 | case PANEL_PROFILE_CUSTOM: |
2201 | /* custom profile */ | ||
2109 | if (keypad_type < 0) | 2202 | if (keypad_type < 0) |
2110 | keypad_type = DEFAULT_KEYPAD; | 2203 | keypad_type = DEFAULT_KEYPAD; |
2111 | if (lcd_type < 0) | 2204 | if (lcd_type < 0) |
2112 | lcd_type = DEFAULT_LCD; | 2205 | lcd_type = DEFAULT_LCD; |
2113 | break; | 2206 | break; |
2114 | case PANEL_PROFILE_OLD: /* 8 bits, 2*16, old keypad */ | 2207 | case PANEL_PROFILE_OLD: |
2208 | /* 8 bits, 2*16, old keypad */ | ||
2115 | if (keypad_type < 0) | 2209 | if (keypad_type < 0) |
2116 | keypad_type = KEYPAD_TYPE_OLD; | 2210 | keypad_type = KEYPAD_TYPE_OLD; |
2117 | if (lcd_type < 0) | 2211 | if (lcd_type < 0) |
@@ -2121,25 +2215,29 @@ int panel_init(void) | |||
2121 | if (lcd_hwidth < 0) | 2215 | if (lcd_hwidth < 0) |
2122 | lcd_hwidth = 16; | 2216 | lcd_hwidth = 16; |
2123 | break; | 2217 | break; |
2124 | case PANEL_PROFILE_NEW: /* serial, 2*16, new keypad */ | 2218 | case PANEL_PROFILE_NEW: |
2219 | /* serial, 2*16, new keypad */ | ||
2125 | if (keypad_type < 0) | 2220 | if (keypad_type < 0) |
2126 | keypad_type = KEYPAD_TYPE_NEW; | 2221 | keypad_type = KEYPAD_TYPE_NEW; |
2127 | if (lcd_type < 0) | 2222 | if (lcd_type < 0) |
2128 | lcd_type = LCD_TYPE_KS0074; | 2223 | lcd_type = LCD_TYPE_KS0074; |
2129 | break; | 2224 | break; |
2130 | case PANEL_PROFILE_HANTRONIX: /* 8 bits, 2*16 hantronix-like, no keypad */ | 2225 | case PANEL_PROFILE_HANTRONIX: |
2226 | /* 8 bits, 2*16 hantronix-like, no keypad */ | ||
2131 | if (keypad_type < 0) | 2227 | if (keypad_type < 0) |
2132 | keypad_type = KEYPAD_TYPE_NONE; | 2228 | keypad_type = KEYPAD_TYPE_NONE; |
2133 | if (lcd_type < 0) | 2229 | if (lcd_type < 0) |
2134 | lcd_type = LCD_TYPE_HANTRONIX; | 2230 | lcd_type = LCD_TYPE_HANTRONIX; |
2135 | break; | 2231 | break; |
2136 | case PANEL_PROFILE_NEXCOM: /* generic 8 bits, 2*16, nexcom keypad, eg. Nexcom. */ | 2232 | case PANEL_PROFILE_NEXCOM: |
2233 | /* generic 8 bits, 2*16, nexcom keypad, eg. Nexcom. */ | ||
2137 | if (keypad_type < 0) | 2234 | if (keypad_type < 0) |
2138 | keypad_type = KEYPAD_TYPE_NEXCOM; | 2235 | keypad_type = KEYPAD_TYPE_NEXCOM; |
2139 | if (lcd_type < 0) | 2236 | if (lcd_type < 0) |
2140 | lcd_type = LCD_TYPE_NEXCOM; | 2237 | lcd_type = LCD_TYPE_NEXCOM; |
2141 | break; | 2238 | break; |
2142 | case PANEL_PROFILE_LARGE: /* 8 bits, 2*40, old keypad */ | 2239 | case PANEL_PROFILE_LARGE: |
2240 | /* 8 bits, 2*40, old keypad */ | ||
2143 | if (keypad_type < 0) | 2241 | if (keypad_type < 0) |
2144 | keypad_type = KEYPAD_TYPE_OLD; | 2242 | keypad_type = KEYPAD_TYPE_OLD; |
2145 | if (lcd_type < 0) | 2243 | if (lcd_type < 0) |
@@ -2195,7 +2293,8 @@ int panel_init(void) | |||
2195 | else | 2293 | else |
2196 | printk(KERN_INFO "Panel driver version " PANEL_VERSION | 2294 | printk(KERN_INFO "Panel driver version " PANEL_VERSION |
2197 | " not yet registered\n"); | 2295 | " not yet registered\n"); |
2198 | /* tells various subsystems about the fact that initialization is finished */ | 2296 | /* tells various subsystems about the fact that initialization |
2297 | is finished */ | ||
2199 | init_in_progress = 0; | 2298 | init_in_progress = 0; |
2200 | return 0; | 2299 | return 0; |
2201 | } | 2300 | } |