diff options
author | Lars Poeschel <poeschel@lemonage.de> | 2020-11-03 12:58:18 +0300 |
---|---|---|
committer | Miguel Ojeda <ojeda@kernel.org> | 2020-11-04 13:04:04 +0300 |
commit | d2f2187e8f27cd884150acdce7ec96135260413b (patch) | |
tree | 1d9f26fc7efc246b9a83643f5be97a60bc6aa56c /drivers/auxdisplay/charlcd.c | |
parent | 01ec46dfa633a52ccfe38d4a194460d6adb2ba00 (diff) | |
download | linux-d2f2187e8f27cd884150acdce7ec96135260413b.tar.xz |
auxdisplay: implement various hd44780_common_ functions
This implements various hd44780_common_ functions for hd44780 compatible
display drivers to use. charlcd then calls these functions through its
ops function pointer.
The functions namely are:
- hd44780_common_shift_cursor
- hd44780_common_display_shift
- hd44780_common_display
- hd44780_common_cursor
- hd44780_common_blink
- hd44780_common_fontsize
- hd44780_common_lines
Reviewed-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Lars Poeschel <poeschel@lemonage.de>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'drivers/auxdisplay/charlcd.c')
-rw-r--r-- | drivers/auxdisplay/charlcd.c | 73 |
1 files changed, 46 insertions, 27 deletions
diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c index 94f6b0afab13..281a3259c144 100644 --- a/drivers/auxdisplay/charlcd.c +++ b/drivers/auxdisplay/charlcd.c @@ -31,10 +31,6 @@ #define LCD_CMD_CURSOR_ON 0x02 /* Set cursor on */ #define LCD_CMD_BLINK_ON 0x01 /* Set blink on */ -#define LCD_CMD_SHIFT 0x10 /* Shift cursor/display */ -#define LCD_CMD_DISPLAY_SHIFT 0x08 /* Shift display instead of cursor */ -#define LCD_CMD_SHIFT_RIGHT 0x04 /* Shift display/cursor to the right */ - #define LCD_CMD_FUNCTION_SET 0x20 /* Set function */ #define LCD_CMD_DATA_LEN_8BITS 0x10 /* Set data length to 8 bits */ #define LCD_CMD_TWO_LINES 0x08 /* Set to two display lines */ @@ -236,26 +232,44 @@ static inline int handle_lcd_special_code(struct charlcd *lcd) switch (*esc) { case 'D': /* Display ON */ priv->flags |= LCD_FLAG_D; + if (priv->flags != oldflags) + lcd->ops->display(lcd, CHARLCD_ON); + processed = 1; break; case 'd': /* Display OFF */ priv->flags &= ~LCD_FLAG_D; + if (priv->flags != oldflags) + lcd->ops->display(lcd, CHARLCD_OFF); + processed = 1; break; case 'C': /* Cursor ON */ priv->flags |= LCD_FLAG_C; + if (priv->flags != oldflags) + lcd->ops->cursor(lcd, CHARLCD_ON); + processed = 1; break; case 'c': /* Cursor OFF */ priv->flags &= ~LCD_FLAG_C; + if (priv->flags != oldflags) + lcd->ops->cursor(lcd, CHARLCD_OFF); + processed = 1; break; case 'B': /* Blink ON */ priv->flags |= LCD_FLAG_B; + if (priv->flags != oldflags) + lcd->ops->blink(lcd, CHARLCD_ON); + processed = 1; break; case 'b': /* Blink OFF */ priv->flags &= ~LCD_FLAG_B; + if (priv->flags != oldflags) + lcd->ops->blink(lcd, CHARLCD_OFF); + processed = 1; break; case '+': /* Back light ON */ @@ -272,47 +286,54 @@ static inline int handle_lcd_special_code(struct charlcd *lcd) break; case 'f': /* Small Font */ priv->flags &= ~LCD_FLAG_F; + if (priv->flags != oldflags) + lcd->ops->fontsize(lcd, CHARLCD_FONTSIZE_SMALL); + processed = 1; break; case 'F': /* Large Font */ priv->flags |= LCD_FLAG_F; + if (priv->flags != oldflags) + lcd->ops->fontsize(lcd, CHARLCD_FONTSIZE_LARGE); + processed = 1; break; case 'n': /* One Line */ priv->flags &= ~LCD_FLAG_N; + if (priv->flags != oldflags) + lcd->ops->lines(lcd, CHARLCD_LINES_1); + processed = 1; break; case 'N': /* Two Lines */ priv->flags |= LCD_FLAG_N; + if (priv->flags != oldflags) + lcd->ops->lines(lcd, CHARLCD_LINES_2); + processed = 1; break; case 'l': /* Shift Cursor Left */ if (lcd->addr.x > 0) { - /* back one char if not at end of line */ - if (lcd->addr.x < hdc->bwidth) - hdc->write_cmd(hdc, LCD_CMD_SHIFT); - lcd->addr.x--; + if (!lcd->ops->shift_cursor(lcd, CHARLCD_SHIFT_LEFT)) + lcd->addr.x--; } + processed = 1; break; case 'r': /* shift cursor right */ if (lcd->addr.x < lcd->width) { - /* allow the cursor to pass the end of the line */ - if (lcd->addr.x < (hdc->bwidth - 1)) - hdc->write_cmd(hdc, - LCD_CMD_SHIFT | LCD_CMD_SHIFT_RIGHT); - lcd->addr.x++; + if (!lcd->ops->shift_cursor(lcd, CHARLCD_SHIFT_RIGHT)) + lcd->addr.x++; } + processed = 1; break; case 'L': /* shift display left */ - hdc->write_cmd(hdc, LCD_CMD_SHIFT | LCD_CMD_DISPLAY_SHIFT); + lcd->ops->shift_display(lcd, CHARLCD_SHIFT_LEFT); processed = 1; break; case 'R': /* shift display right */ - hdc->write_cmd(hdc, - LCD_CMD_SHIFT | LCD_CMD_DISPLAY_SHIFT | - LCD_CMD_SHIFT_RIGHT); + lcd->ops->shift_display(lcd, CHARLCD_SHIFT_RIGHT); processed = 1; break; case 'k': { /* kill end of line */ @@ -456,19 +477,17 @@ static void charlcd_write_char(struct charlcd *lcd, char c) case '\b': /* go back one char and clear it */ if (lcd->addr.x > 0) { - /* - * check if we're not at the - * end of the line - */ - if (lcd->addr.x < hdc->bwidth) - /* back one char */ - hdc->write_cmd(hdc, LCD_CMD_SHIFT); - lcd->addr.x--; + /* back one char */ + if (!lcd->ops->shift_cursor(lcd, + CHARLCD_SHIFT_LEFT)) + lcd->addr.x--; } /* replace with a space */ - hdc->write_data(hdc, ' '); + charlcd_print(lcd, ' '); /* back one char again */ - hdc->write_cmd(hdc, LCD_CMD_SHIFT); + if (!lcd->ops->shift_cursor(lcd, CHARLCD_SHIFT_LEFT)) + lcd->addr.x--; + break; case '\f': /* quickly clear the display */ |