summaryrefslogtreecommitdiffstats
path: root/drivers/auxdisplay/hd44780_common.c
diff options
context:
space:
mode:
authorLars Poeschel <poeschel@lemonage.de>2020-11-03 10:58:20 +0100
committerMiguel Ojeda <ojeda@kernel.org>2020-11-04 11:04:04 +0100
commit339acb082987a6b0aa7c67a5a77b29f6c81962f6 (patch)
tree82479df566aa68da55d9bf42427963cd27b2ed9d /drivers/auxdisplay/hd44780_common.c
parent8a86270ef0ea5ebc37c9a1223589c1d45c7e07de (diff)
downloadlinux-339acb082987a6b0aa7c67a5a77b29f6c81962f6.tar.bz2
auxdisplay: Move char redefine code to hd44780_common
Take the code to redefine characters out of charlcd and move it to hd44780_common, as this is hd44780 specific. There is now a function hd44780_common_redefine_char that drivers use and charlcd calls it through its ops function pointer. 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/hd44780_common.c')
-rw-r--r--drivers/auxdisplay/hd44780_common.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/drivers/auxdisplay/hd44780_common.c b/drivers/auxdisplay/hd44780_common.c
index 9d538fdcd260..c528fb8e8808 100644
--- a/drivers/auxdisplay/hd44780_common.c
+++ b/drivers/auxdisplay/hd44780_common.c
@@ -26,6 +26,8 @@
#define LCD_CMD_TWO_LINES 0x08 /* Set to two display lines */
#define LCD_CMD_FONT_5X10_DOTS 0x04 /* Set char font to 5x10 dots */
+#define LCD_CMD_SET_CGRAM_ADDR 0x40 /* Set char generator RAM address */
+
#define LCD_CMD_SET_DDRAM_ADDR 0x80 /* Set display data RAM address */
/* sleeps that many milliseconds with a reschedule */
@@ -289,6 +291,61 @@ int hd44780_common_lines(struct charlcd *lcd, enum charlcd_lines lines)
}
EXPORT_SYMBOL_GPL(hd44780_common_lines);
+int hd44780_common_redefine_char(struct charlcd *lcd, char *esc)
+{
+ /* Generator : LGcxxxxx...xx; must have <c> between '0'
+ * and '7', representing the numerical ASCII code of the
+ * redefined character, and <xx...xx> a sequence of 16
+ * hex digits representing 8 bytes for each character.
+ * Most LCDs will only use 5 lower bits of the 7 first
+ * bytes.
+ */
+
+ struct hd44780_common *hdc = lcd->drvdata;
+ unsigned char cgbytes[8];
+ unsigned char cgaddr;
+ int cgoffset;
+ int shift;
+ char value;
+ int addr;
+
+ if (!strchr(esc, ';'))
+ return 0;
+
+ esc++;
+
+ cgaddr = *(esc++) - '0';
+ if (cgaddr > 7)
+ return 1;
+
+ cgoffset = 0;
+ shift = 0;
+ value = 0;
+ while (*esc && cgoffset < 8) {
+ int half;
+
+ shift ^= 4;
+ half = hex_to_bin(*esc++);
+ if (half < 0)
+ continue;
+
+ value |= half << shift;
+ if (shift == 0) {
+ cgbytes[cgoffset++] = value;
+ value = 0;
+ }
+ }
+
+ hdc->write_cmd(hdc, LCD_CMD_SET_CGRAM_ADDR | (cgaddr * 8));
+ for (addr = 0; addr < cgoffset; addr++)
+ hdc->write_data(hdc, cgbytes[addr]);
+
+ /* ensures that we stop writing to CGRAM */
+ lcd->ops->gotoxy(lcd);
+ return 1;
+}
+EXPORT_SYMBOL_GPL(hd44780_common_redefine_char);
+
struct hd44780_common *hd44780_common_alloc(void)
{
struct hd44780_common *hd;