aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/panel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/panel.c')
-rw-r--r--drivers/misc/panel.c827
1 files changed, 92 insertions, 735 deletions
diff --git a/drivers/misc/panel.c b/drivers/misc/panel.c
index ef2ece0f26af..e0c014c2356f 100644
--- a/drivers/misc/panel.c
+++ b/drivers/misc/panel.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Front panel driver for Linux 2 * Front panel driver for Linux
3 * Copyright (C) 2000-2008, Willy Tarreau <w@1wt.eu> 3 * Copyright (C) 2000-2008, Willy Tarreau <w@1wt.eu>
4 * Copyright (C) 2016-2017 Glider bvba
4 * 5 *
5 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
@@ -54,15 +55,12 @@
54#include <linux/ctype.h> 55#include <linux/ctype.h>
55#include <linux/parport.h> 56#include <linux/parport.h>
56#include <linux/list.h> 57#include <linux/list.h>
57#include <linux/notifier.h>
58#include <linux/reboot.h>
59#include <linux/workqueue.h>
60#include <generated/utsrelease.h>
61 58
62#include <linux/io.h> 59#include <linux/io.h>
63#include <linux/uaccess.h> 60#include <linux/uaccess.h>
64 61
65#define LCD_MINOR 156 62#include <misc/charlcd.h>
63
66#define KEYPAD_MINOR 185 64#define KEYPAD_MINOR 185
67 65
68#define LCD_MAXBYTES 256 /* max burst write */ 66#define LCD_MAXBYTES 256 /* max burst write */
@@ -76,9 +74,6 @@
76/* a key repeats this times INPUT_POLL_TIME */ 74/* a key repeats this times INPUT_POLL_TIME */
77#define KEYPAD_REP_DELAY (2) 75#define KEYPAD_REP_DELAY (2)
78 76
79/* keep the light on this many seconds for each flash */
80#define FLASH_LIGHT_TEMPO (4)
81
82/* converts an r_str() input to an active high, bits string : 000BAOSE */ 77/* converts an r_str() input to an active high, bits string : 000BAOSE */
83#define PNL_PINPUT(a) ((((unsigned char)(a)) ^ 0x7F) >> 3) 78#define PNL_PINPUT(a) ((((unsigned char)(a)) ^ 0x7F) >> 3)
84 79
@@ -120,40 +115,6 @@
120#define PIN_SELECP 17 115#define PIN_SELECP 17
121#define PIN_NOT_SET 127 116#define PIN_NOT_SET 127
122 117
123#define LCD_FLAG_B 0x0004 /* blink on */
124#define LCD_FLAG_C 0x0008 /* cursor on */
125#define LCD_FLAG_D 0x0010 /* display on */
126#define LCD_FLAG_F 0x0020 /* large font mode */
127#define LCD_FLAG_N 0x0040 /* 2-rows mode */
128#define LCD_FLAG_L 0x0080 /* backlight enabled */
129
130/* LCD commands */
131#define LCD_CMD_DISPLAY_CLEAR 0x01 /* Clear entire display */
132
133#define LCD_CMD_ENTRY_MODE 0x04 /* Set entry mode */
134#define LCD_CMD_CURSOR_INC 0x02 /* Increment cursor */
135
136#define LCD_CMD_DISPLAY_CTRL 0x08 /* Display control */
137#define LCD_CMD_DISPLAY_ON 0x04 /* Set display on */
138#define LCD_CMD_CURSOR_ON 0x02 /* Set cursor on */
139#define LCD_CMD_BLINK_ON 0x01 /* Set blink on */
140
141#define LCD_CMD_SHIFT 0x10 /* Shift cursor/display */
142#define LCD_CMD_DISPLAY_SHIFT 0x08 /* Shift display instead of cursor */
143#define LCD_CMD_SHIFT_RIGHT 0x04 /* Shift display/cursor to the right */
144
145#define LCD_CMD_FUNCTION_SET 0x20 /* Set function */
146#define LCD_CMD_DATA_LEN_8BITS 0x10 /* Set data length to 8 bits */
147#define LCD_CMD_TWO_LINES 0x08 /* Set to two display lines */
148#define LCD_CMD_FONT_5X10_DOTS 0x04 /* Set char font to 5x10 dots */
149
150#define LCD_CMD_SET_CGRAM_ADDR 0x40 /* Set char generator RAM address */
151
152#define LCD_CMD_SET_DDRAM_ADDR 0x80 /* Set display data RAM address */
153
154#define LCD_ESCAPE_LEN 24 /* max chars for LCD escape command */
155#define LCD_ESCAPE_CHAR 27 /* use char 27 for escape command */
156
157#define NOT_SET -1 118#define NOT_SET -1
158 119
159/* macros to simplify use of the parallel port */ 120/* macros to simplify use of the parallel port */
@@ -245,19 +206,10 @@ static wait_queue_head_t keypad_read_wait;
245static struct { 206static struct {
246 bool enabled; 207 bool enabled;
247 bool initialized; 208 bool initialized;
248 bool must_clear;
249 209
250 int height;
251 int width;
252 int bwidth;
253 int hwidth;
254 int charset; 210 int charset;
255 int proto; 211 int proto;
256 212
257 struct delayed_work bl_work;
258 struct mutex bl_tempo_lock; /* Protects access to bl_tempo */
259 bool bl_tempo;
260
261 /* TODO: use union here? */ 213 /* TODO: use union here? */
262 struct { 214 struct {
263 int e; 215 int e;
@@ -268,20 +220,7 @@ static struct {
268 int bl; 220 int bl;
269 } pins; 221 } pins;
270 222
271 /* contains the LCD config state */ 223 struct charlcd *charlcd;
272 unsigned long int flags;
273
274 /* Contains the LCD X and Y offset */
275 struct {
276 unsigned long int x;
277 unsigned long int y;
278 } addr;
279
280 /* Current escape sequence and it's length or -1 if outside */
281 struct {
282 char buf[LCD_ESCAPE_LEN + 1];
283 int len;
284 } esc_seq;
285} lcd; 224} lcd;
286 225
287/* Needed only for init */ 226/* Needed only for init */
@@ -464,17 +403,12 @@ static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES];
464/* global variables */ 403/* global variables */
465 404
466/* Device single-open policy control */ 405/* Device single-open policy control */
467static atomic_t lcd_available = ATOMIC_INIT(1);
468static atomic_t keypad_available = ATOMIC_INIT(1); 406static atomic_t keypad_available = ATOMIC_INIT(1);
469 407
470static struct pardevice *pprt; 408static struct pardevice *pprt;
471 409
472static int keypad_initialized; 410static int keypad_initialized;
473 411
474static void (*lcd_write_cmd)(int);
475static void (*lcd_write_data)(int);
476static void (*lcd_clear_fast)(void);
477
478static DEFINE_SPINLOCK(pprt_lock); 412static DEFINE_SPINLOCK(pprt_lock);
479static struct timer_list scan_timer; 413static struct timer_list scan_timer;
480 414
@@ -574,8 +508,6 @@ static int keypad_enabled = NOT_SET;
574module_param(keypad_enabled, int, 0000); 508module_param(keypad_enabled, int, 0000);
575MODULE_PARM_DESC(keypad_enabled, "Deprecated option, use keypad_type instead"); 509MODULE_PARM_DESC(keypad_enabled, "Deprecated option, use keypad_type instead");
576 510
577static const unsigned char *lcd_char_conv;
578
579/* for some LCD drivers (ks0074) we need a charset conversion table. */ 511/* for some LCD drivers (ks0074) we need a charset conversion table. */
580static const unsigned char lcd_char_conv_ks0074[256] = { 512static const unsigned char lcd_char_conv_ks0074[256] = {
581 /* 0|8 1|9 2|A 3|B 4|C 5|D 6|E 7|F */ 513 /* 0|8 1|9 2|A 3|B 4|C 5|D 6|E 7|F */
@@ -752,15 +684,6 @@ static void pin_to_bits(int pin, unsigned char *d_val, unsigned char *c_val)
752 } 684 }
753} 685}
754 686
755/* sleeps that many milliseconds with a reschedule */
756static void long_sleep(int ms)
757{
758 if (in_interrupt())
759 mdelay(ms);
760 else
761 schedule_timeout_interruptible(msecs_to_jiffies(ms));
762}
763
764/* 687/*
765 * send a serial byte to the LCD panel. The caller is responsible for locking 688 * send a serial byte to the LCD panel. The caller is responsible for locking
766 * if needed. 689 * if needed.
@@ -792,8 +715,11 @@ static void lcd_send_serial(int byte)
792} 715}
793 716
794/* turn the backlight on or off */ 717/* turn the backlight on or off */
795static void __lcd_backlight(int on) 718static void lcd_backlight(struct charlcd *charlcd, int on)
796{ 719{
720 if (lcd.pins.bl == PIN_NONE)
721 return;
722
797 /* The backlight is activated by setting the AUTOFEED line to +5V */ 723 /* The backlight is activated by setting the AUTOFEED line to +5V */
798 spin_lock_irq(&pprt_lock); 724 spin_lock_irq(&pprt_lock);
799 if (on) 725 if (on)
@@ -804,46 +730,8 @@ static void __lcd_backlight(int on)
804 spin_unlock_irq(&pprt_lock); 730 spin_unlock_irq(&pprt_lock);
805} 731}
806 732
807static void lcd_backlight(int on)
808{
809 if (lcd.pins.bl == PIN_NONE)
810 return;
811
812 mutex_lock(&lcd.bl_tempo_lock);
813 if (!lcd.bl_tempo)
814 __lcd_backlight(on);
815 mutex_unlock(&lcd.bl_tempo_lock);
816}
817
818static void lcd_bl_off(struct work_struct *work)
819{
820 mutex_lock(&lcd.bl_tempo_lock);
821 if (lcd.bl_tempo) {
822 lcd.bl_tempo = false;
823 if (!(lcd.flags & LCD_FLAG_L))
824 __lcd_backlight(0);
825 }
826 mutex_unlock(&lcd.bl_tempo_lock);
827}
828
829/* turn the backlight on for a little while */
830static void lcd_poke(void)
831{
832 if (lcd.pins.bl == PIN_NONE)
833 return;
834
835 cancel_delayed_work_sync(&lcd.bl_work);
836
837 mutex_lock(&lcd.bl_tempo_lock);
838 if (!lcd.bl_tempo && !(lcd.flags & LCD_FLAG_L))
839 __lcd_backlight(1);
840 lcd.bl_tempo = true;
841 schedule_delayed_work(&lcd.bl_work, FLASH_LIGHT_TEMPO * HZ);
842 mutex_unlock(&lcd.bl_tempo_lock);
843}
844
845/* send a command to the LCD panel in serial mode */ 733/* send a command to the LCD panel in serial mode */
846static void lcd_write_cmd_s(int cmd) 734static void lcd_write_cmd_s(struct charlcd *charlcd, int cmd)
847{ 735{
848 spin_lock_irq(&pprt_lock); 736 spin_lock_irq(&pprt_lock);
849 lcd_send_serial(0x1F); /* R/W=W, RS=0 */ 737 lcd_send_serial(0x1F); /* R/W=W, RS=0 */
@@ -854,7 +742,7 @@ static void lcd_write_cmd_s(int cmd)
854} 742}
855 743
856/* send data to the LCD panel in serial mode */ 744/* send data to the LCD panel in serial mode */
857static void lcd_write_data_s(int data) 745static void lcd_write_data_s(struct charlcd *charlcd, int data)
858{ 746{
859 spin_lock_irq(&pprt_lock); 747 spin_lock_irq(&pprt_lock);
860 lcd_send_serial(0x5F); /* R/W=W, RS=1 */ 748 lcd_send_serial(0x5F); /* R/W=W, RS=1 */
@@ -865,7 +753,7 @@ static void lcd_write_data_s(int data)
865} 753}
866 754
867/* send a command to the LCD panel in 8 bits parallel mode */ 755/* send a command to the LCD panel in 8 bits parallel mode */
868static void lcd_write_cmd_p8(int cmd) 756static void lcd_write_cmd_p8(struct charlcd *charlcd, int cmd)
869{ 757{
870 spin_lock_irq(&pprt_lock); 758 spin_lock_irq(&pprt_lock);
871 /* present the data to the data port */ 759 /* present the data to the data port */
@@ -887,7 +775,7 @@ static void lcd_write_cmd_p8(int cmd)
887} 775}
888 776
889/* send data to the LCD panel in 8 bits parallel mode */ 777/* send data to the LCD panel in 8 bits parallel mode */
890static void lcd_write_data_p8(int data) 778static void lcd_write_data_p8(struct charlcd *charlcd, int data)
891{ 779{
892 spin_lock_irq(&pprt_lock); 780 spin_lock_irq(&pprt_lock);
893 /* present the data to the data port */ 781 /* present the data to the data port */
@@ -909,7 +797,7 @@ static void lcd_write_data_p8(int data)
909} 797}
910 798
911/* send a command to the TI LCD panel */ 799/* send a command to the TI LCD panel */
912static void lcd_write_cmd_tilcd(int cmd) 800static void lcd_write_cmd_tilcd(struct charlcd *charlcd, int cmd)
913{ 801{
914 spin_lock_irq(&pprt_lock); 802 spin_lock_irq(&pprt_lock);
915 /* present the data to the control port */ 803 /* present the data to the control port */
@@ -919,7 +807,7 @@ static void lcd_write_cmd_tilcd(int cmd)
919} 807}
920 808
921/* send data to the TI LCD panel */ 809/* send data to the TI LCD panel */
922static void lcd_write_data_tilcd(int data) 810static void lcd_write_data_tilcd(struct charlcd *charlcd, int data)
923{ 811{
924 spin_lock_irq(&pprt_lock); 812 spin_lock_irq(&pprt_lock);
925 /* present the data to the data port */ 813 /* present the data to the data port */
@@ -928,47 +816,13 @@ static void lcd_write_data_tilcd(int data)
928 spin_unlock_irq(&pprt_lock); 816 spin_unlock_irq(&pprt_lock);
929} 817}
930 818
931static void lcd_gotoxy(void)
932{
933 lcd_write_cmd(LCD_CMD_SET_DDRAM_ADDR
934 | (lcd.addr.y ? lcd.hwidth : 0)
935 /*
936 * we force the cursor to stay at the end of the
937 * line if it wants to go farther
938 */
939 | ((lcd.addr.x < lcd.bwidth) ? lcd.addr.x &
940 (lcd.hwidth - 1) : lcd.bwidth - 1));
941}
942
943static void lcd_home(void)
944{
945 lcd.addr.x = 0;
946 lcd.addr.y = 0;
947 lcd_gotoxy();
948}
949
950static void lcd_print(char c)
951{
952 if (lcd.addr.x < lcd.bwidth) {
953 if (lcd_char_conv)
954 c = lcd_char_conv[(unsigned char)c];
955 lcd_write_data(c);
956 lcd.addr.x++;
957 }
958 /* prevents the cursor from wrapping onto the next line */
959 if (lcd.addr.x == lcd.bwidth)
960 lcd_gotoxy();
961}
962
963/* fills the display with spaces and resets X/Y */ 819/* fills the display with spaces and resets X/Y */
964static void lcd_clear_fast_s(void) 820static void lcd_clear_fast_s(struct charlcd *charlcd)
965{ 821{
966 int pos; 822 int pos;
967 823
968 lcd_home();
969
970 spin_lock_irq(&pprt_lock); 824 spin_lock_irq(&pprt_lock);
971 for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) { 825 for (pos = 0; pos < charlcd->height * charlcd->hwidth; pos++) {
972 lcd_send_serial(0x5F); /* R/W=W, RS=1 */ 826 lcd_send_serial(0x5F); /* R/W=W, RS=1 */
973 lcd_send_serial(' ' & 0x0F); 827 lcd_send_serial(' ' & 0x0F);
974 lcd_send_serial((' ' >> 4) & 0x0F); 828 lcd_send_serial((' ' >> 4) & 0x0F);
@@ -976,19 +830,15 @@ static void lcd_clear_fast_s(void)
976 udelay(40); 830 udelay(40);
977 } 831 }
978 spin_unlock_irq(&pprt_lock); 832 spin_unlock_irq(&pprt_lock);
979
980 lcd_home();
981} 833}
982 834
983/* fills the display with spaces and resets X/Y */ 835/* fills the display with spaces and resets X/Y */
984static void lcd_clear_fast_p8(void) 836static void lcd_clear_fast_p8(struct charlcd *charlcd)
985{ 837{
986 int pos; 838 int pos;
987 839
988 lcd_home();
989
990 spin_lock_irq(&pprt_lock); 840 spin_lock_irq(&pprt_lock);
991 for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) { 841 for (pos = 0; pos < charlcd->height * charlcd->hwidth; pos++) {
992 /* present the data to the data port */ 842 /* present the data to the data port */
993 w_dtr(pprt, ' '); 843 w_dtr(pprt, ' ');
994 844
@@ -1010,488 +860,62 @@ static void lcd_clear_fast_p8(void)
1010 udelay(45); 860 udelay(45);
1011 } 861 }
1012 spin_unlock_irq(&pprt_lock); 862 spin_unlock_irq(&pprt_lock);
1013
1014 lcd_home();
1015} 863}
1016 864
1017/* fills the display with spaces and resets X/Y */ 865/* fills the display with spaces and resets X/Y */
1018static void lcd_clear_fast_tilcd(void) 866static void lcd_clear_fast_tilcd(struct charlcd *charlcd)
1019{ 867{
1020 int pos; 868 int pos;
1021 869
1022 lcd_home();
1023
1024 spin_lock_irq(&pprt_lock); 870 spin_lock_irq(&pprt_lock);
1025 for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) { 871 for (pos = 0; pos < charlcd->height * charlcd->hwidth; pos++) {
1026 /* present the data to the data port */ 872 /* present the data to the data port */
1027 w_dtr(pprt, ' '); 873 w_dtr(pprt, ' ');
1028 udelay(60); 874 udelay(60);
1029 } 875 }
1030 876
1031 spin_unlock_irq(&pprt_lock); 877 spin_unlock_irq(&pprt_lock);
1032
1033 lcd_home();
1034}
1035
1036/* clears the display and resets X/Y */
1037static void lcd_clear_display(void)
1038{
1039 lcd_write_cmd(LCD_CMD_DISPLAY_CLEAR);
1040 lcd.addr.x = 0;
1041 lcd.addr.y = 0;
1042 /* we must wait a few milliseconds (15) */
1043 long_sleep(15);
1044} 878}
1045 879
1046static void lcd_init_display(void) 880static struct charlcd_ops charlcd_serial_ops = {
1047{ 881 .write_cmd = lcd_write_cmd_s,
1048 lcd.flags = ((lcd.height > 1) ? LCD_FLAG_N : 0) 882 .write_data = lcd_write_data_s,
1049 | LCD_FLAG_D | LCD_FLAG_C | LCD_FLAG_B; 883 .clear_fast = lcd_clear_fast_s,
1050 884 .backlight = lcd_backlight,
1051 long_sleep(20); /* wait 20 ms after power-up for the paranoid */ 885};
1052
1053 /* 8bits, 1 line, small fonts; let's do it 3 times */
1054 lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS);
1055 long_sleep(10);
1056 lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS);
1057 long_sleep(10);
1058 lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS);
1059 long_sleep(10);
1060
1061 /* set font height and lines number */
1062 lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS
1063 | ((lcd.flags & LCD_FLAG_F) ? LCD_CMD_FONT_5X10_DOTS : 0)
1064 | ((lcd.flags & LCD_FLAG_N) ? LCD_CMD_TWO_LINES : 0)
1065 );
1066 long_sleep(10);
1067
1068 /* display off, cursor off, blink off */
1069 lcd_write_cmd(LCD_CMD_DISPLAY_CTRL);
1070 long_sleep(10);
1071
1072 lcd_write_cmd(LCD_CMD_DISPLAY_CTRL /* set display mode */
1073 | ((lcd.flags & LCD_FLAG_D) ? LCD_CMD_DISPLAY_ON : 0)
1074 | ((lcd.flags & LCD_FLAG_C) ? LCD_CMD_CURSOR_ON : 0)
1075 | ((lcd.flags & LCD_FLAG_B) ? LCD_CMD_BLINK_ON : 0)
1076 );
1077
1078 lcd_backlight((lcd.flags & LCD_FLAG_L) ? 1 : 0);
1079
1080 long_sleep(10);
1081
1082 /* entry mode set : increment, cursor shifting */
1083 lcd_write_cmd(LCD_CMD_ENTRY_MODE | LCD_CMD_CURSOR_INC);
1084 886
1085 lcd_clear_display(); 887static struct charlcd_ops charlcd_parallel_ops = {
1086} 888 .write_cmd = lcd_write_cmd_p8,
889 .write_data = lcd_write_data_p8,
890 .clear_fast = lcd_clear_fast_p8,
891 .backlight = lcd_backlight,
892};
1087 893
1088/* 894static struct charlcd_ops charlcd_tilcd_ops = {
1089 * These are the file operation function for user access to /dev/lcd 895 .write_cmd = lcd_write_cmd_tilcd,
1090 * This function can also be called from inside the kernel, by 896 .write_data = lcd_write_data_tilcd,
1091 * setting file and ppos to NULL. 897 .clear_fast = lcd_clear_fast_tilcd,
1092 * 898 .backlight = lcd_backlight,
1093 */ 899};
1094 900
1095static inline int handle_lcd_special_code(void) 901/* initialize the LCD driver */
902static void lcd_init(void)
1096{ 903{
1097 /* LCD special codes */ 904 struct charlcd *charlcd;
1098
1099 int processed = 0;
1100 905
1101 char *esc = lcd.esc_seq.buf + 2; 906 charlcd = charlcd_alloc(0);
1102 int oldflags = lcd.flags; 907 if (!charlcd)
1103 908 return;
1104 /* check for display mode flags */
1105 switch (*esc) {
1106 case 'D': /* Display ON */
1107 lcd.flags |= LCD_FLAG_D;
1108 processed = 1;
1109 break;
1110 case 'd': /* Display OFF */
1111 lcd.flags &= ~LCD_FLAG_D;
1112 processed = 1;
1113 break;
1114 case 'C': /* Cursor ON */
1115 lcd.flags |= LCD_FLAG_C;
1116 processed = 1;
1117 break;
1118 case 'c': /* Cursor OFF */
1119 lcd.flags &= ~LCD_FLAG_C;
1120 processed = 1;
1121 break;
1122 case 'B': /* Blink ON */
1123 lcd.flags |= LCD_FLAG_B;
1124 processed = 1;
1125 break;
1126 case 'b': /* Blink OFF */
1127 lcd.flags &= ~LCD_FLAG_B;
1128 processed = 1;
1129 break;
1130 case '+': /* Back light ON */
1131 lcd.flags |= LCD_FLAG_L;
1132 processed = 1;
1133 break;
1134 case '-': /* Back light OFF */
1135 lcd.flags &= ~LCD_FLAG_L;
1136 processed = 1;
1137 break;
1138 case '*':
1139 /* flash back light */
1140 lcd_poke();
1141 processed = 1;
1142 break;
1143 case 'f': /* Small Font */
1144 lcd.flags &= ~LCD_FLAG_F;
1145 processed = 1;
1146 break;
1147 case 'F': /* Large Font */
1148 lcd.flags |= LCD_FLAG_F;
1149 processed = 1;
1150 break;
1151 case 'n': /* One Line */
1152 lcd.flags &= ~LCD_FLAG_N;
1153 processed = 1;
1154 break;
1155 case 'N': /* Two Lines */
1156 lcd.flags |= LCD_FLAG_N;
1157 break;
1158 case 'l': /* Shift Cursor Left */
1159 if (lcd.addr.x > 0) {
1160 /* back one char if not at end of line */
1161 if (lcd.addr.x < lcd.bwidth)
1162 lcd_write_cmd(LCD_CMD_SHIFT);
1163 lcd.addr.x--;
1164 }
1165 processed = 1;
1166 break;
1167 case 'r': /* shift cursor right */
1168 if (lcd.addr.x < lcd.width) {
1169 /* allow the cursor to pass the end of the line */
1170 if (lcd.addr.x < (lcd.bwidth - 1))
1171 lcd_write_cmd(LCD_CMD_SHIFT |
1172 LCD_CMD_SHIFT_RIGHT);
1173 lcd.addr.x++;
1174 }
1175 processed = 1;
1176 break;
1177 case 'L': /* shift display left */
1178 lcd_write_cmd(LCD_CMD_SHIFT | LCD_CMD_DISPLAY_SHIFT);
1179 processed = 1;
1180 break;
1181 case 'R': /* shift display right */
1182 lcd_write_cmd(LCD_CMD_SHIFT | LCD_CMD_DISPLAY_SHIFT |
1183 LCD_CMD_SHIFT_RIGHT);
1184 processed = 1;
1185 break;
1186 case 'k': { /* kill end of line */
1187 int x;
1188
1189 for (x = lcd.addr.x; x < lcd.bwidth; x++)
1190 lcd_write_data(' ');
1191
1192 /* restore cursor position */
1193 lcd_gotoxy();
1194 processed = 1;
1195 break;
1196 }
1197 case 'I': /* reinitialize display */
1198 lcd_init_display();
1199 processed = 1;
1200 break;
1201 case 'G': {
1202 /* Generator : LGcxxxxx...xx; must have <c> between '0'
1203 * and '7', representing the numerical ASCII code of the
1204 * redefined character, and <xx...xx> a sequence of 16
1205 * hex digits representing 8 bytes for each character.
1206 * Most LCDs will only use 5 lower bits of the 7 first
1207 * bytes.
1208 */
1209
1210 unsigned char cgbytes[8];
1211 unsigned char cgaddr;
1212 int cgoffset;
1213 int shift;
1214 char value;
1215 int addr;
1216
1217 if (!strchr(esc, ';'))
1218 break;
1219
1220 esc++;
1221
1222 cgaddr = *(esc++) - '0';
1223 if (cgaddr > 7) {
1224 processed = 1;
1225 break;
1226 }
1227
1228 cgoffset = 0;
1229 shift = 0;
1230 value = 0;
1231 while (*esc && cgoffset < 8) {
1232 shift ^= 4;
1233 if (*esc >= '0' && *esc <= '9') {
1234 value |= (*esc - '0') << shift;
1235 } else if (*esc >= 'A' && *esc <= 'Z') {
1236 value |= (*esc - 'A' + 10) << shift;
1237 } else if (*esc >= 'a' && *esc <= 'z') {
1238 value |= (*esc - 'a' + 10) << shift;
1239 } else {
1240 esc++;
1241 continue;
1242 }
1243
1244 if (shift == 0) {
1245 cgbytes[cgoffset++] = value;
1246 value = 0;
1247 }
1248
1249 esc++;
1250 }
1251
1252 lcd_write_cmd(LCD_CMD_SET_CGRAM_ADDR | (cgaddr * 8));
1253 for (addr = 0; addr < cgoffset; addr++)
1254 lcd_write_data(cgbytes[addr]);
1255
1256 /* ensures that we stop writing to CGRAM */
1257 lcd_gotoxy();
1258 processed = 1;
1259 break;
1260 }
1261 case 'x': /* gotoxy : LxXXX[yYYY]; */
1262 case 'y': /* gotoxy : LyYYY[xXXX]; */
1263 if (!strchr(esc, ';'))
1264 break;
1265
1266 while (*esc) {
1267 if (*esc == 'x') {
1268 esc++;
1269 if (kstrtoul(esc, 10, &lcd.addr.x) < 0)
1270 break;
1271 } else if (*esc == 'y') {
1272 esc++;
1273 if (kstrtoul(esc, 10, &lcd.addr.y) < 0)
1274 break;
1275 } else {
1276 break;
1277 }
1278 }
1279
1280 lcd_gotoxy();
1281 processed = 1;
1282 break;
1283 }
1284
1285 /* TODO: This indent party here got ugly, clean it! */
1286 /* Check whether one flag was changed */
1287 if (oldflags != lcd.flags) {
1288 /* check whether one of B,C,D flags were changed */
1289 if ((oldflags ^ lcd.flags) &
1290 (LCD_FLAG_B | LCD_FLAG_C | LCD_FLAG_D))
1291 /* set display mode */
1292 lcd_write_cmd(LCD_CMD_DISPLAY_CTRL
1293 | ((lcd.flags & LCD_FLAG_D)
1294 ? LCD_CMD_DISPLAY_ON : 0)
1295 | ((lcd.flags & LCD_FLAG_C)
1296 ? LCD_CMD_CURSOR_ON : 0)
1297 | ((lcd.flags & LCD_FLAG_B)
1298 ? LCD_CMD_BLINK_ON : 0));
1299 /* check whether one of F,N flags was changed */
1300 else if ((oldflags ^ lcd.flags) & (LCD_FLAG_F | LCD_FLAG_N))
1301 lcd_write_cmd(LCD_CMD_FUNCTION_SET
1302 | LCD_CMD_DATA_LEN_8BITS
1303 | ((lcd.flags & LCD_FLAG_F)
1304 ? LCD_CMD_FONT_5X10_DOTS
1305 : 0)
1306 | ((lcd.flags & LCD_FLAG_N)
1307 ? LCD_CMD_TWO_LINES
1308 : 0));
1309 /* check whether L flag was changed */
1310 else if ((oldflags ^ lcd.flags) & (LCD_FLAG_L))
1311 lcd_backlight(!!(lcd.flags & LCD_FLAG_L));
1312 }
1313
1314 return processed;
1315}
1316
1317static void lcd_write_char(char c)
1318{
1319 /* first, we'll test if we're in escape mode */
1320 if ((c != '\n') && lcd.esc_seq.len >= 0) {
1321 /* yes, let's add this char to the buffer */
1322 lcd.esc_seq.buf[lcd.esc_seq.len++] = c;
1323 lcd.esc_seq.buf[lcd.esc_seq.len] = 0;
1324 } else {
1325 /* aborts any previous escape sequence */
1326 lcd.esc_seq.len = -1;
1327
1328 switch (c) {
1329 case LCD_ESCAPE_CHAR:
1330 /* start of an escape sequence */
1331 lcd.esc_seq.len = 0;
1332 lcd.esc_seq.buf[lcd.esc_seq.len] = 0;
1333 break;
1334 case '\b':
1335 /* go back one char and clear it */
1336 if (lcd.addr.x > 0) {
1337 /*
1338 * check if we're not at the
1339 * end of the line
1340 */
1341 if (lcd.addr.x < lcd.bwidth)
1342 /* back one char */
1343 lcd_write_cmd(LCD_CMD_SHIFT);
1344 lcd.addr.x--;
1345 }
1346 /* replace with a space */
1347 lcd_write_data(' ');
1348 /* back one char again */
1349 lcd_write_cmd(LCD_CMD_SHIFT);
1350 break;
1351 case '\014':
1352 /* quickly clear the display */
1353 lcd_clear_fast();
1354 break;
1355 case '\n':
1356 /*
1357 * flush the remainder of the current line and
1358 * go to the beginning of the next line
1359 */
1360 for (; lcd.addr.x < lcd.bwidth; lcd.addr.x++)
1361 lcd_write_data(' ');
1362 lcd.addr.x = 0;
1363 lcd.addr.y = (lcd.addr.y + 1) % lcd.height;
1364 lcd_gotoxy();
1365 break;
1366 case '\r':
1367 /* go to the beginning of the same line */
1368 lcd.addr.x = 0;
1369 lcd_gotoxy();
1370 break;
1371 case '\t':
1372 /* print a space instead of the tab */
1373 lcd_print(' ');
1374 break;
1375 default:
1376 /* simply print this char */
1377 lcd_print(c);
1378 break;
1379 }
1380 }
1381 909
1382 /* 910 /*
1383 * now we'll see if we're in an escape mode and if the current 911 * Init lcd struct with load-time values to preserve exact
1384 * escape sequence can be understood. 912 * current functionality (at least for now).
1385 */ 913 */
1386 if (lcd.esc_seq.len >= 2) { 914 charlcd->height = lcd_height;
1387 int processed = 0; 915 charlcd->width = lcd_width;
1388 916 charlcd->bwidth = lcd_bwidth;
1389 if (!strcmp(lcd.esc_seq.buf, "[2J")) { 917 charlcd->hwidth = lcd_hwidth;
1390 /* clear the display */
1391 lcd_clear_fast();
1392 processed = 1;
1393 } else if (!strcmp(lcd.esc_seq.buf, "[H")) {
1394 /* cursor to home */
1395 lcd_home();
1396 processed = 1;
1397 }
1398 /* codes starting with ^[[L */
1399 else if ((lcd.esc_seq.len >= 3) &&
1400 (lcd.esc_seq.buf[0] == '[') &&
1401 (lcd.esc_seq.buf[1] == 'L')) {
1402 processed = handle_lcd_special_code();
1403 }
1404
1405 /* LCD special escape codes */
1406 /*
1407 * flush the escape sequence if it's been processed
1408 * or if it is getting too long.
1409 */
1410 if (processed || (lcd.esc_seq.len >= LCD_ESCAPE_LEN))
1411 lcd.esc_seq.len = -1;
1412 } /* escape codes */
1413}
1414 918
1415static ssize_t lcd_write(struct file *file,
1416 const char __user *buf, size_t count, loff_t *ppos)
1417{
1418 const char __user *tmp = buf;
1419 char c;
1420
1421 for (; count-- > 0; (*ppos)++, tmp++) {
1422 if (!in_interrupt() && (((count + 1) & 0x1f) == 0))
1423 /*
1424 * let's be a little nice with other processes
1425 * that need some CPU
1426 */
1427 schedule();
1428
1429 if (get_user(c, tmp))
1430 return -EFAULT;
1431
1432 lcd_write_char(c);
1433 }
1434
1435 return tmp - buf;
1436}
1437
1438static int lcd_open(struct inode *inode, struct file *file)
1439{
1440 if (!atomic_dec_and_test(&lcd_available))
1441 return -EBUSY; /* open only once at a time */
1442
1443 if (file->f_mode & FMODE_READ) /* device is write-only */
1444 return -EPERM;
1445
1446 if (lcd.must_clear) {
1447 lcd_clear_display();
1448 lcd.must_clear = false;
1449 }
1450 return nonseekable_open(inode, file);
1451}
1452
1453static int lcd_release(struct inode *inode, struct file *file)
1454{
1455 atomic_inc(&lcd_available);
1456 return 0;
1457}
1458
1459static const struct file_operations lcd_fops = {
1460 .write = lcd_write,
1461 .open = lcd_open,
1462 .release = lcd_release,
1463 .llseek = no_llseek,
1464};
1465
1466static struct miscdevice lcd_dev = {
1467 .minor = LCD_MINOR,
1468 .name = "lcd",
1469 .fops = &lcd_fops,
1470};
1471
1472/* public function usable from the kernel for any purpose */
1473static void panel_lcd_print(const char *s)
1474{
1475 const char *tmp = s;
1476 int count = strlen(s);
1477
1478 if (lcd.enabled && lcd.initialized) {
1479 for (; count-- > 0; tmp++) {
1480 if (!in_interrupt() && (((count + 1) & 0x1f) == 0))
1481 /*
1482 * let's be a little nice with other processes
1483 * that need some CPU
1484 */
1485 schedule();
1486
1487 lcd_write_char(*tmp);
1488 }
1489 }
1490}
1491
1492/* initialize the LCD driver */
1493static void lcd_init(void)
1494{
1495 switch (selected_lcd_type) { 919 switch (selected_lcd_type) {
1496 case LCD_TYPE_OLD: 920 case LCD_TYPE_OLD:
1497 /* parallel mode, 8 bits */ 921 /* parallel mode, 8 bits */
@@ -1500,10 +924,10 @@ static void lcd_init(void)
1500 lcd.pins.e = PIN_STROBE; 924 lcd.pins.e = PIN_STROBE;
1501 lcd.pins.rs = PIN_AUTOLF; 925 lcd.pins.rs = PIN_AUTOLF;
1502 926
1503 lcd.width = 40; 927 charlcd->width = 40;
1504 lcd.bwidth = 40; 928 charlcd->bwidth = 40;
1505 lcd.hwidth = 64; 929 charlcd->hwidth = 64;
1506 lcd.height = 2; 930 charlcd->height = 2;
1507 break; 931 break;
1508 case LCD_TYPE_KS0074: 932 case LCD_TYPE_KS0074:
1509 /* serial mode, ks0074 */ 933 /* serial mode, ks0074 */
@@ -1513,10 +937,10 @@ static void lcd_init(void)
1513 lcd.pins.cl = PIN_STROBE; 937 lcd.pins.cl = PIN_STROBE;
1514 lcd.pins.da = PIN_D0; 938 lcd.pins.da = PIN_D0;
1515 939
1516 lcd.width = 16; 940 charlcd->width = 16;
1517 lcd.bwidth = 40; 941 charlcd->bwidth = 40;
1518 lcd.hwidth = 16; 942 charlcd->hwidth = 16;
1519 lcd.height = 2; 943 charlcd->height = 2;
1520 break; 944 break;
1521 case LCD_TYPE_NEXCOM: 945 case LCD_TYPE_NEXCOM:
1522 /* parallel mode, 8 bits, generic */ 946 /* parallel mode, 8 bits, generic */
@@ -1526,10 +950,10 @@ static void lcd_init(void)
1526 lcd.pins.rs = PIN_SELECP; 950 lcd.pins.rs = PIN_SELECP;
1527 lcd.pins.rw = PIN_INITP; 951 lcd.pins.rw = PIN_INITP;
1528 952
1529 lcd.width = 16; 953 charlcd->width = 16;
1530 lcd.bwidth = 40; 954 charlcd->bwidth = 40;
1531 lcd.hwidth = 64; 955 charlcd->hwidth = 64;
1532 lcd.height = 2; 956 charlcd->height = 2;
1533 break; 957 break;
1534 case LCD_TYPE_CUSTOM: 958 case LCD_TYPE_CUSTOM:
1535 /* customer-defined */ 959 /* customer-defined */
@@ -1545,22 +969,22 @@ static void lcd_init(void)
1545 lcd.pins.e = PIN_STROBE; 969 lcd.pins.e = PIN_STROBE;
1546 lcd.pins.rs = PIN_SELECP; 970 lcd.pins.rs = PIN_SELECP;
1547 971
1548 lcd.width = 16; 972 charlcd->width = 16;
1549 lcd.bwidth = 40; 973 charlcd->bwidth = 40;
1550 lcd.hwidth = 64; 974 charlcd->hwidth = 64;
1551 lcd.height = 2; 975 charlcd->height = 2;
1552 break; 976 break;
1553 } 977 }
1554 978
1555 /* Overwrite with module params set on loading */ 979 /* Overwrite with module params set on loading */
1556 if (lcd_height != NOT_SET) 980 if (lcd_height != NOT_SET)
1557 lcd.height = lcd_height; 981 charlcd->height = lcd_height;
1558 if (lcd_width != NOT_SET) 982 if (lcd_width != NOT_SET)
1559 lcd.width = lcd_width; 983 charlcd->width = lcd_width;
1560 if (lcd_bwidth != NOT_SET) 984 if (lcd_bwidth != NOT_SET)
1561 lcd.bwidth = lcd_bwidth; 985 charlcd->bwidth = lcd_bwidth;
1562 if (lcd_hwidth != NOT_SET) 986 if (lcd_hwidth != NOT_SET)
1563 lcd.hwidth = lcd_hwidth; 987 charlcd->hwidth = lcd_hwidth;
1564 if (lcd_charset != NOT_SET) 988 if (lcd_charset != NOT_SET)
1565 lcd.charset = lcd_charset; 989 lcd.charset = lcd_charset;
1566 if (lcd_proto != NOT_SET) 990 if (lcd_proto != NOT_SET)
@@ -1579,19 +1003,17 @@ static void lcd_init(void)
1579 lcd.pins.bl = lcd_bl_pin; 1003 lcd.pins.bl = lcd_bl_pin;
1580 1004
1581 /* this is used to catch wrong and default values */ 1005 /* this is used to catch wrong and default values */
1582 if (lcd.width <= 0) 1006 if (charlcd->width <= 0)
1583 lcd.width = DEFAULT_LCD_WIDTH; 1007 charlcd->width = DEFAULT_LCD_WIDTH;
1584 if (lcd.bwidth <= 0) 1008 if (charlcd->bwidth <= 0)
1585 lcd.bwidth = DEFAULT_LCD_BWIDTH; 1009 charlcd->bwidth = DEFAULT_LCD_BWIDTH;
1586 if (lcd.hwidth <= 0) 1010 if (charlcd->hwidth <= 0)
1587 lcd.hwidth = DEFAULT_LCD_HWIDTH; 1011 charlcd->hwidth = DEFAULT_LCD_HWIDTH;
1588 if (lcd.height <= 0) 1012 if (charlcd->height <= 0)
1589 lcd.height = DEFAULT_LCD_HEIGHT; 1013 charlcd->height = DEFAULT_LCD_HEIGHT;
1590 1014
1591 if (lcd.proto == LCD_PROTO_SERIAL) { /* SERIAL */ 1015 if (lcd.proto == LCD_PROTO_SERIAL) { /* SERIAL */
1592 lcd_write_cmd = lcd_write_cmd_s; 1016 charlcd->ops = &charlcd_serial_ops;
1593 lcd_write_data = lcd_write_data_s;
1594 lcd_clear_fast = lcd_clear_fast_s;
1595 1017
1596 if (lcd.pins.cl == PIN_NOT_SET) 1018 if (lcd.pins.cl == PIN_NOT_SET)
1597 lcd.pins.cl = DEFAULT_LCD_PIN_SCL; 1019 lcd.pins.cl = DEFAULT_LCD_PIN_SCL;
@@ -1599,9 +1021,7 @@ static void lcd_init(void)
1599 lcd.pins.da = DEFAULT_LCD_PIN_SDA; 1021 lcd.pins.da = DEFAULT_LCD_PIN_SDA;
1600 1022
1601 } else if (lcd.proto == LCD_PROTO_PARALLEL) { /* PARALLEL */ 1023 } else if (lcd.proto == LCD_PROTO_PARALLEL) { /* PARALLEL */
1602 lcd_write_cmd = lcd_write_cmd_p8; 1024 charlcd->ops = &charlcd_parallel_ops;
1603 lcd_write_data = lcd_write_data_p8;
1604 lcd_clear_fast = lcd_clear_fast_p8;
1605 1025
1606 if (lcd.pins.e == PIN_NOT_SET) 1026 if (lcd.pins.e == PIN_NOT_SET)
1607 lcd.pins.e = DEFAULT_LCD_PIN_E; 1027 lcd.pins.e = DEFAULT_LCD_PIN_E;
@@ -1610,9 +1030,7 @@ static void lcd_init(void)
1610 if (lcd.pins.rw == PIN_NOT_SET) 1030 if (lcd.pins.rw == PIN_NOT_SET)
1611 lcd.pins.rw = DEFAULT_LCD_PIN_RW; 1031 lcd.pins.rw = DEFAULT_LCD_PIN_RW;
1612 } else { 1032 } else {
1613 lcd_write_cmd = lcd_write_cmd_tilcd; 1033 charlcd->ops = &charlcd_tilcd_ops;
1614 lcd_write_data = lcd_write_data_tilcd;
1615 lcd_clear_fast = lcd_clear_fast_tilcd;
1616 } 1034 }
1617 1035
1618 if (lcd.pins.bl == PIN_NOT_SET) 1036 if (lcd.pins.bl == PIN_NOT_SET)
@@ -1635,14 +1053,9 @@ static void lcd_init(void)
1635 lcd.charset = DEFAULT_LCD_CHARSET; 1053 lcd.charset = DEFAULT_LCD_CHARSET;
1636 1054
1637 if (lcd.charset == LCD_CHARSET_KS0074) 1055 if (lcd.charset == LCD_CHARSET_KS0074)
1638 lcd_char_conv = lcd_char_conv_ks0074; 1056 charlcd->char_conv = lcd_char_conv_ks0074;
1639 else 1057 else
1640 lcd_char_conv = NULL; 1058 charlcd->char_conv = NULL;
1641
1642 if (lcd.pins.bl != PIN_NONE) {
1643 mutex_init(&lcd.bl_tempo_lock);
1644 INIT_DELAYED_WORK(&lcd.bl_work, lcd_bl_off);
1645 }
1646 1059
1647 pin_to_bits(lcd.pins.e, lcd_bits[LCD_PORT_D][LCD_BIT_E], 1060 pin_to_bits(lcd.pins.e, lcd_bits[LCD_PORT_D][LCD_BIT_E],
1648 lcd_bits[LCD_PORT_C][LCD_BIT_E]); 1061 lcd_bits[LCD_PORT_C][LCD_BIT_E]);
@@ -1657,25 +1070,8 @@ static void lcd_init(void)
1657 pin_to_bits(lcd.pins.da, lcd_bits[LCD_PORT_D][LCD_BIT_DA], 1070 pin_to_bits(lcd.pins.da, lcd_bits[LCD_PORT_D][LCD_BIT_DA],
1658 lcd_bits[LCD_PORT_C][LCD_BIT_DA]); 1071 lcd_bits[LCD_PORT_C][LCD_BIT_DA]);
1659 1072
1660 /* 1073 lcd.charlcd = charlcd;
1661 * before this line, we must NOT send anything to the display.
1662 * Since lcd_init_display() needs to write data, we have to
1663 * enable mark the LCD initialized just before.
1664 */
1665 lcd.initialized = true; 1074 lcd.initialized = true;
1666 lcd_init_display();
1667
1668 /* display a short message */
1669#ifdef CONFIG_PANEL_CHANGE_MESSAGE
1670#ifdef CONFIG_PANEL_BOOT_MESSAGE
1671 panel_lcd_print("\x1b[Lc\x1b[Lb\x1b[L*" CONFIG_PANEL_BOOT_MESSAGE);
1672#endif
1673#else
1674 panel_lcd_print("\x1b[Lc\x1b[Lb\x1b[L*Linux-" UTS_RELEASE);
1675#endif
1676 /* clear the display on the next device opening */
1677 lcd.must_clear = true;
1678 lcd_home();
1679} 1075}
1680 1076
1681/* 1077/*
@@ -2011,7 +1407,7 @@ static void panel_scan_timer(void)
2011 } 1407 }
2012 1408
2013 if (keypressed && lcd.enabled && lcd.initialized) 1409 if (keypressed && lcd.enabled && lcd.initialized)
2014 lcd_poke(); 1410 charlcd_poke(lcd.charlcd);
2015 1411
2016 mod_timer(&scan_timer, jiffies + INPUT_POLL_TIME); 1412 mod_timer(&scan_timer, jiffies + INPUT_POLL_TIME);
2017} 1413}
@@ -2175,35 +1571,6 @@ static void keypad_init(void)
2175/* device initialization */ 1571/* device initialization */
2176/**************************************************/ 1572/**************************************************/
2177 1573
2178static int panel_notify_sys(struct notifier_block *this, unsigned long code,
2179 void *unused)
2180{
2181 if (lcd.enabled && lcd.initialized) {
2182 switch (code) {
2183 case SYS_DOWN:
2184 panel_lcd_print
2185 ("\x0cReloading\nSystem...\x1b[Lc\x1b[Lb\x1b[L+");
2186 break;
2187 case SYS_HALT:
2188 panel_lcd_print
2189 ("\x0cSystem Halted.\x1b[Lc\x1b[Lb\x1b[L+");
2190 break;
2191 case SYS_POWER_OFF:
2192 panel_lcd_print("\x0cPower off.\x1b[Lc\x1b[Lb\x1b[L+");
2193 break;
2194 default:
2195 break;
2196 }
2197 }
2198 return NOTIFY_DONE;
2199}
2200
2201static struct notifier_block panel_notifier = {
2202 panel_notify_sys,
2203 NULL,
2204 0
2205};
2206
2207static void panel_attach(struct parport *port) 1574static void panel_attach(struct parport *port)
2208{ 1575{
2209 struct pardev_cb panel_cb; 1576 struct pardev_cb panel_cb;
@@ -2239,7 +1606,7 @@ static void panel_attach(struct parport *port)
2239 */ 1606 */
2240 if (lcd.enabled) { 1607 if (lcd.enabled) {
2241 lcd_init(); 1608 lcd_init();
2242 if (misc_register(&lcd_dev)) 1609 if (!lcd.charlcd || charlcd_register(lcd.charlcd))
2243 goto err_unreg_device; 1610 goto err_unreg_device;
2244 } 1611 }
2245 1612
@@ -2248,13 +1615,14 @@ static void panel_attach(struct parport *port)
2248 if (misc_register(&keypad_dev)) 1615 if (misc_register(&keypad_dev))
2249 goto err_lcd_unreg; 1616 goto err_lcd_unreg;
2250 } 1617 }
2251 register_reboot_notifier(&panel_notifier);
2252 return; 1618 return;
2253 1619
2254err_lcd_unreg: 1620err_lcd_unreg:
2255 if (lcd.enabled) 1621 if (lcd.enabled)
2256 misc_deregister(&lcd_dev); 1622 charlcd_unregister(lcd.charlcd);
2257err_unreg_device: 1623err_unreg_device:
1624 kfree(lcd.charlcd);
1625 lcd.charlcd = NULL;
2258 parport_unregister_device(pprt); 1626 parport_unregister_device(pprt);
2259 pprt = NULL; 1627 pprt = NULL;
2260} 1628}
@@ -2278,20 +1646,16 @@ static void panel_detach(struct parport *port)
2278 } 1646 }
2279 1647
2280 if (lcd.enabled) { 1648 if (lcd.enabled) {
2281 panel_lcd_print("\x0cLCD driver unloaded.\x1b[Lc\x1b[Lb\x1b[L-"); 1649 charlcd_unregister(lcd.charlcd);
2282 misc_deregister(&lcd_dev);
2283 if (lcd.pins.bl != PIN_NONE) {
2284 cancel_delayed_work_sync(&lcd.bl_work);
2285 __lcd_backlight(0);
2286 }
2287 lcd.initialized = false; 1650 lcd.initialized = false;
1651 kfree(lcd.charlcd);
1652 lcd.charlcd = NULL;
2288 } 1653 }
2289 1654
2290 /* TODO: free all input signals */ 1655 /* TODO: free all input signals */
2291 parport_release(pprt); 1656 parport_release(pprt);
2292 parport_unregister_device(pprt); 1657 parport_unregister_device(pprt);
2293 pprt = NULL; 1658 pprt = NULL;
2294 unregister_reboot_notifier(&panel_notifier);
2295} 1659}
2296 1660
2297static struct parport_driver panel_driver = { 1661static struct parport_driver panel_driver = {
@@ -2369,10 +1733,6 @@ static int __init panel_init_module(void)
2369 * Init lcd struct with load-time values to preserve exact 1733 * Init lcd struct with load-time values to preserve exact
2370 * current functionality (at least for now). 1734 * current functionality (at least for now).
2371 */ 1735 */
2372 lcd.height = lcd_height;
2373 lcd.width = lcd_width;
2374 lcd.bwidth = lcd_bwidth;
2375 lcd.hwidth = lcd_hwidth;
2376 lcd.charset = lcd_charset; 1736 lcd.charset = lcd_charset;
2377 lcd.proto = lcd_proto; 1737 lcd.proto = lcd_proto;
2378 lcd.pins.e = lcd_e_pin; 1738 lcd.pins.e = lcd_e_pin;
@@ -2381,9 +1741,6 @@ static int __init panel_init_module(void)
2381 lcd.pins.cl = lcd_cl_pin; 1741 lcd.pins.cl = lcd_cl_pin;
2382 lcd.pins.da = lcd_da_pin; 1742 lcd.pins.da = lcd_da_pin;
2383 lcd.pins.bl = lcd_bl_pin; 1743 lcd.pins.bl = lcd_bl_pin;
2384
2385 /* Leave it for now, just in case */
2386 lcd.esc_seq.len = -1;
2387 } 1744 }
2388 1745
2389 switch (selected_keypad_type) { 1746 switch (selected_keypad_type) {