From 84a1ed0407d209beff4d9cb41120d0f69a89d4b8 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 6 Feb 2017 15:38:03 +0100 Subject: misc: panel: Fix LCD_FLAG_F/LCD_FLAG_N exchange LCD_FLAG_F is the font flag, LCD_FLAG_N is the two-lines flag. Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/misc/panel.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/misc/panel.c') diff --git a/drivers/misc/panel.c b/drivers/misc/panel.c index 6030ac5b8c63..cac7ac62ce5b 100644 --- a/drivers/misc/panel.c +++ b/drivers/misc/panel.c @@ -1278,9 +1278,10 @@ static inline int handle_lcd_special_code(void) lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS | ((lcd.flags & LCD_FLAG_F) - ? LCD_CMD_TWO_LINES : 0) - | ((lcd.flags & LCD_FLAG_N) ? LCD_CMD_FONT_5X10_DOTS + : 0) + | ((lcd.flags & LCD_FLAG_N) + ? LCD_CMD_TWO_LINES : 0)); /* check whether L flag was changed */ else if ((oldflags ^ lcd.flags) & (LCD_FLAG_L)) { -- cgit From 30f468b2ea7a75aa7e212b7d89eb136a55462ee8 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 6 Feb 2017 15:38:04 +0100 Subject: misc: panel: Remove PANEL_VERSION Hardcoded driver versions are so pre-git. Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/misc/panel.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'drivers/misc/panel.c') diff --git a/drivers/misc/panel.c b/drivers/misc/panel.c index cac7ac62ce5b..fa4c12768a16 100644 --- a/drivers/misc/panel.c +++ b/drivers/misc/panel.c @@ -64,8 +64,6 @@ #define LCD_MINOR 156 #define KEYPAD_MINOR 185 -#define PANEL_VERSION "0.9.5" - #define LCD_MAXBYTES 256 /* max burst write */ #define KEYPAD_BUFFER 64 @@ -1656,8 +1654,7 @@ static void lcd_init(void) panel_lcd_print("\x1b[Lc\x1b[Lb\x1b[L*" CONFIG_PANEL_BOOT_MESSAGE); #endif #else - panel_lcd_print("\x1b[Lc\x1b[Lb\x1b[L*Linux-" UTS_RELEASE "\nPanel-" - PANEL_VERSION); + panel_lcd_print("\x1b[Lc\x1b[Lb\x1b[L*Linux-" UTS_RELEASE); #endif lcd.addr.x = 0; lcd.addr.y = 0; @@ -2278,8 +2275,7 @@ static void panel_detach(struct parport *port) } if (lcd.enabled) { - panel_lcd_print("\x0cLCD driver " PANEL_VERSION - "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-"); + panel_lcd_print("\x0cLCD driver unloaded.\x1b[Lc\x1b[Lb\x1b[L-"); misc_deregister(&lcd_dev); lcd.initialized = false; } @@ -2401,7 +2397,7 @@ static int __init panel_init_module(void) if (!lcd.enabled && !keypad.enabled) { /* no device enabled, let's exit */ - pr_err("driver version " PANEL_VERSION " disabled.\n"); + pr_err("panel driver disabled.\n"); return -ENODEV; } @@ -2412,12 +2408,10 @@ static int __init panel_init_module(void) } if (pprt) - pr_info("driver version " PANEL_VERSION - " registered on parport%d (io=0x%lx).\n", parport, - pprt->port->base); + pr_info("panel driver registered on parport%d (io=0x%lx).\n", + parport, pprt->port->base); else - pr_info("driver version " PANEL_VERSION - " not yet registered\n"); + pr_info("panel driver not yet registered\n"); return 0; } -- cgit From e28fa714aa8bb682d07136ba3821bc883c78f6df Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 6 Feb 2017 15:38:05 +0100 Subject: misc: panel: Remove unused LCD_FLAG_S and LCD_FLAG_ID These definitions were never used in any publicly available version since (at least) 2004. Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/misc/panel.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/misc/panel.c') diff --git a/drivers/misc/panel.c b/drivers/misc/panel.c index fa4c12768a16..8af500ecaaaf 100644 --- a/drivers/misc/panel.c +++ b/drivers/misc/panel.c @@ -119,8 +119,6 @@ #define PIN_SELECP 17 #define PIN_NOT_SET 127 -#define LCD_FLAG_S 0x0001 -#define LCD_FLAG_ID 0x0002 #define LCD_FLAG_B 0x0004 /* blink on */ #define LCD_FLAG_C 0x0008 /* cursor on */ #define LCD_FLAG_D 0x0010 /* display on */ -- cgit From 3f77b43965054c17fbc3111650c4e90f294a7bbe Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 6 Feb 2017 15:38:08 +0100 Subject: misc: panel: Remove always-true check from panel_detach() panel_detach() already verified that pptr is a valid pointer. Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/misc/panel.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'drivers/misc/panel.c') diff --git a/drivers/misc/panel.c b/drivers/misc/panel.c index 8af500ecaaaf..ed19b3e399b0 100644 --- a/drivers/misc/panel.c +++ b/drivers/misc/panel.c @@ -2266,24 +2266,22 @@ static void panel_detach(struct parport *port) if (scan_timer.function) del_timer_sync(&scan_timer); - if (pprt) { - if (keypad.enabled) { - misc_deregister(&keypad_dev); - keypad_initialized = 0; - } - - if (lcd.enabled) { - panel_lcd_print("\x0cLCD driver unloaded.\x1b[Lc\x1b[Lb\x1b[L-"); - misc_deregister(&lcd_dev); - lcd.initialized = false; - } + if (keypad.enabled) { + misc_deregister(&keypad_dev); + keypad_initialized = 0; + } - /* TODO: free all input signals */ - parport_release(pprt); - parport_unregister_device(pprt); - pprt = NULL; - unregister_reboot_notifier(&panel_notifier); + if (lcd.enabled) { + panel_lcd_print("\x0cLCD driver unloaded.\x1b[Lc\x1b[Lb\x1b[L-"); + misc_deregister(&lcd_dev); + lcd.initialized = false; } + + /* TODO: free all input signals */ + parport_release(pprt); + parport_unregister_device(pprt); + pprt = NULL; + unregister_reboot_notifier(&panel_notifier); } static struct parport_driver panel_driver = { -- cgit From 204a4f6d67a4d7e65571c21bd90039fdccc35b2c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 6 Feb 2017 15:38:09 +0100 Subject: misc: panel: Add lcd_home() helper Add a helper function to move the cursor to the home position, so callers no longer need access to internal state. Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/misc/panel.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) (limited to 'drivers/misc/panel.c') diff --git a/drivers/misc/panel.c b/drivers/misc/panel.c index ed19b3e399b0..9c7b00951c22 100644 --- a/drivers/misc/panel.c +++ b/drivers/misc/panel.c @@ -903,6 +903,13 @@ static void lcd_gotoxy(void) (lcd.hwidth - 1) : lcd.bwidth - 1)); } +static void lcd_home(void) +{ + lcd.addr.x = 0; + lcd.addr.y = 0; + lcd_gotoxy(); +} + static void lcd_print(char c) { if (lcd.addr.x < lcd.bwidth) { @@ -921,9 +928,7 @@ static void lcd_clear_fast_s(void) { int pos; - lcd.addr.x = 0; - lcd.addr.y = 0; - lcd_gotoxy(); + lcd_home(); spin_lock_irq(&pprt_lock); for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) { @@ -935,9 +940,7 @@ static void lcd_clear_fast_s(void) } spin_unlock_irq(&pprt_lock); - lcd.addr.x = 0; - lcd.addr.y = 0; - lcd_gotoxy(); + lcd_home(); } /* fills the display with spaces and resets X/Y */ @@ -945,9 +948,7 @@ static void lcd_clear_fast_p8(void) { int pos; - lcd.addr.x = 0; - lcd.addr.y = 0; - lcd_gotoxy(); + lcd_home(); spin_lock_irq(&pprt_lock); for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) { @@ -973,9 +974,7 @@ static void lcd_clear_fast_p8(void) } spin_unlock_irq(&pprt_lock); - lcd.addr.x = 0; - lcd.addr.y = 0; - lcd_gotoxy(); + lcd_home(); } /* fills the display with spaces and resets X/Y */ @@ -983,9 +982,7 @@ static void lcd_clear_fast_tilcd(void) { int pos; - lcd.addr.x = 0; - lcd.addr.y = 0; - lcd_gotoxy(); + lcd_home(); spin_lock_irq(&pprt_lock); for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) { @@ -996,9 +993,7 @@ static void lcd_clear_fast_tilcd(void) spin_unlock_irq(&pprt_lock); - lcd.addr.x = 0; - lcd.addr.y = 0; - lcd_gotoxy(); + lcd_home(); } /* clears the display and resets X/Y */ @@ -1373,9 +1368,7 @@ static void lcd_write_char(char c) processed = 1; } else if (!strcmp(lcd.esc_seq.buf, "[H")) { /* cursor to home */ - lcd.addr.x = 0; - lcd.addr.y = 0; - lcd_gotoxy(); + lcd_home(); processed = 1; } /* codes starting with ^[[L */ @@ -1654,11 +1647,9 @@ static void lcd_init(void) #else panel_lcd_print("\x1b[Lc\x1b[Lb\x1b[L*Linux-" UTS_RELEASE); #endif - lcd.addr.x = 0; - lcd.addr.y = 0; /* clear the display on the next device opening */ lcd.must_clear = true; - lcd_gotoxy(); + lcd_home(); } /* -- cgit From fda4ae1819ce3603857a6baceda53d2c46d5bbd9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 6 Feb 2017 15:38:10 +0100 Subject: misc: panel: Abstract temporary backlight handling Currently the periodic scan timer is used for three purposes, entangling keypad and display handling, which are both optional: 1. Scanning the keypad, 2. Flashing the backlight when a key is pressed, 3. Disabling temporary backlighting after a fixed period of time. Abstract the second purpose using a new lcd_poke() function. Make the non-periodic temporary backlight handling independent from keypad handling by converting it to a delayed workqueue. Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/misc/panel.c | 101 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 41 deletions(-) (limited to 'drivers/misc/panel.c') diff --git a/drivers/misc/panel.c b/drivers/misc/panel.c index 9c7b00951c22..ef2ece0f26af 100644 --- a/drivers/misc/panel.c +++ b/drivers/misc/panel.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -75,8 +76,8 @@ /* a key repeats this times INPUT_POLL_TIME */ #define KEYPAD_REP_DELAY (2) -/* keep the light on this times INPUT_POLL_TIME for each flash */ -#define FLASH_LIGHT_TEMPO (200) +/* keep the light on this many seconds for each flash */ +#define FLASH_LIGHT_TEMPO (4) /* converts an r_str() input to an active high, bits string : 000BAOSE */ #define PNL_PINPUT(a) ((((unsigned char)(a)) ^ 0x7F) >> 3) @@ -252,7 +253,10 @@ static struct { int hwidth; int charset; int proto; - int light_tempo; + + struct delayed_work bl_work; + struct mutex bl_tempo_lock; /* Protects access to bl_tempo */ + bool bl_tempo; /* TODO: use union here? */ struct { @@ -657,8 +661,6 @@ static void lcd_get_bits(unsigned int port, int *val) } } -static void init_scan_timer(void); - /* sets data port bits according to current signals values */ static int set_data_bits(void) { @@ -790,11 +792,8 @@ static void lcd_send_serial(int byte) } /* turn the backlight on or off */ -static void lcd_backlight(int on) +static void __lcd_backlight(int on) { - if (lcd.pins.bl == PIN_NONE) - return; - /* The backlight is activated by setting the AUTOFEED line to +5V */ spin_lock_irq(&pprt_lock); if (on) @@ -805,6 +804,44 @@ static void lcd_backlight(int on) spin_unlock_irq(&pprt_lock); } +static void lcd_backlight(int on) +{ + if (lcd.pins.bl == PIN_NONE) + return; + + mutex_lock(&lcd.bl_tempo_lock); + if (!lcd.bl_tempo) + __lcd_backlight(on); + mutex_unlock(&lcd.bl_tempo_lock); +} + +static void lcd_bl_off(struct work_struct *work) +{ + mutex_lock(&lcd.bl_tempo_lock); + if (lcd.bl_tempo) { + lcd.bl_tempo = false; + if (!(lcd.flags & LCD_FLAG_L)) + __lcd_backlight(0); + } + mutex_unlock(&lcd.bl_tempo_lock); +} + +/* turn the backlight on for a little while */ +static void lcd_poke(void) +{ + if (lcd.pins.bl == PIN_NONE) + return; + + cancel_delayed_work_sync(&lcd.bl_work); + + mutex_lock(&lcd.bl_tempo_lock); + if (!lcd.bl_tempo && !(lcd.flags & LCD_FLAG_L)) + __lcd_backlight(1); + lcd.bl_tempo = true; + schedule_delayed_work(&lcd.bl_work, FLASH_LIGHT_TEMPO * HZ); + mutex_unlock(&lcd.bl_tempo_lock); +} + /* send a command to the LCD panel in serial mode */ static void lcd_write_cmd_s(int cmd) { @@ -1099,13 +1136,8 @@ static inline int handle_lcd_special_code(void) processed = 1; break; case '*': - /* flash back light using the keypad timer */ - if (scan_timer.function) { - if (lcd.light_tempo == 0 && - ((lcd.flags & LCD_FLAG_L) == 0)) - lcd_backlight(1); - lcd.light_tempo = FLASH_LIGHT_TEMPO; - } + /* flash back light */ + lcd_poke(); processed = 1; break; case 'f': /* Small Font */ @@ -1275,16 +1307,8 @@ static inline int handle_lcd_special_code(void) ? LCD_CMD_TWO_LINES : 0)); /* check whether L flag was changed */ - else if ((oldflags ^ lcd.flags) & (LCD_FLAG_L)) { - if (lcd.flags & (LCD_FLAG_L)) - lcd_backlight(1); - else if (lcd.light_tempo == 0) - /* - * switch off the light only when the tempo - * lighting is gone - */ - lcd_backlight(0); - } + else if ((oldflags ^ lcd.flags) & (LCD_FLAG_L)) + lcd_backlight(!!(lcd.flags & LCD_FLAG_L)); } return processed; @@ -1615,8 +1639,10 @@ static void lcd_init(void) else lcd_char_conv = NULL; - if (lcd.pins.bl != PIN_NONE) - init_scan_timer(); + if (lcd.pins.bl != PIN_NONE) { + mutex_init(&lcd.bl_tempo_lock); + INIT_DELAYED_WORK(&lcd.bl_work, lcd_bl_off); + } pin_to_bits(lcd.pins.e, lcd_bits[LCD_PORT_D][LCD_BIT_E], lcd_bits[LCD_PORT_C][LCD_BIT_E]); @@ -1984,19 +2010,8 @@ static void panel_scan_timer(void) panel_process_inputs(); } - if (lcd.enabled && lcd.initialized) { - if (keypressed) { - if (lcd.light_tempo == 0 && - ((lcd.flags & LCD_FLAG_L) == 0)) - lcd_backlight(1); - lcd.light_tempo = FLASH_LIGHT_TEMPO; - } else if (lcd.light_tempo > 0) { - lcd.light_tempo--; - if (lcd.light_tempo == 0 && - ((lcd.flags & LCD_FLAG_L) == 0)) - lcd_backlight(0); - } - } + if (keypressed && lcd.enabled && lcd.initialized) + lcd_poke(); mod_timer(&scan_timer, jiffies + INPUT_POLL_TIME); } @@ -2265,6 +2280,10 @@ static void panel_detach(struct parport *port) if (lcd.enabled) { panel_lcd_print("\x0cLCD driver unloaded.\x1b[Lc\x1b[Lb\x1b[L-"); misc_deregister(&lcd_dev); + if (lcd.pins.bl != PIN_NONE) { + cancel_delayed_work_sync(&lcd.bl_work); + __lcd_backlight(0); + } lcd.initialized = false; } -- cgit