Skip to content

Commit

Permalink
auxdisplay: Move char redefine code to hd44780_common
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
poeschel authored and ojeda committed Nov 4, 2020
1 parent 8a86270 commit 339acb0
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 55 deletions.
60 changes: 5 additions & 55 deletions drivers/auxdisplay/charlcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
/* Keep the backlight on this many seconds for each flash */
#define LCD_BL_TEMPO_PERIOD 4

#define LCD_CMD_SET_CGRAM_ADDR 0x40 /* Set char generator RAM address */

#define LCD_ESCAPE_LEN 24 /* Max chars for LCD escape command */
#define LCD_ESCAPE_CHAR 27 /* Use char 27 for escape command */

Expand Down Expand Up @@ -344,61 +342,13 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
LCD_FLAG_C | LCD_FLAG_B;
processed = 1;
break;
case 'G': {
/* 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.
*/

unsigned char cgbytes[8];
unsigned char cgaddr;
int cgoffset;
int shift;
char value;
int addr;

if (!strchr(esc, ';'))
break;

esc++;

cgaddr = *(esc++) - '0';
if (cgaddr > 7) {
case 'G':
if (lcd->ops->redefine_char)
processed = lcd->ops->redefine_char(lcd, esc);
else
processed = 1;
break;
}

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);
processed = 1;
break;
}

case 'x': /* gotoxy : LxXXX[yYYY]; */
case 'y': /* gotoxy : LyYYY[xXXX]; */
if (priv->esc_seq.buf[priv->esc_seq.len - 1] != ';')
Expand Down
2 changes: 2 additions & 0 deletions drivers/auxdisplay/charlcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct charlcd {
* @cursor: Turn cursor on or off.
* @blink: Turn cursor blink on or off.
* @lines: One or two lines.
* @redefine_char: Redefine the actual pixel matrix of character.
*/
struct charlcd_ops {
void (*clear_fast)(struct charlcd *lcd);
Expand All @@ -91,6 +92,7 @@ struct charlcd_ops {
int (*blink)(struct charlcd *lcd, enum charlcd_onoff on);
int (*fontsize)(struct charlcd *lcd, enum charlcd_fontsize size);
int (*lines)(struct charlcd *lcd, enum charlcd_lines lines);
int (*redefine_char)(struct charlcd *lcd, char *esc);
};

void charlcd_backlight(struct charlcd *lcd, enum charlcd_onoff on);
Expand Down
2 changes: 2 additions & 0 deletions drivers/auxdisplay/hd44780.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ static const struct charlcd_ops hd44780_ops_gpio8 = {
.blink = hd44780_common_blink,
.fontsize = hd44780_common_fontsize,
.lines = hd44780_common_lines,
.redefine_char = hd44780_common_redefine_char,
};

/* Send a command to the LCD panel in 4 bit GPIO mode */
Expand Down Expand Up @@ -193,6 +194,7 @@ static const struct charlcd_ops hd44780_ops_gpio4 = {
.blink = hd44780_common_blink,
.fontsize = hd44780_common_fontsize,
.lines = hd44780_common_lines,
.redefine_char = hd44780_common_redefine_char,
};

static int hd44780_probe(struct platform_device *pdev)
Expand Down
57 changes: 57 additions & 0 deletions drivers/auxdisplay/hd44780_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions drivers/auxdisplay/hd44780_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ int hd44780_common_cursor(struct charlcd *lcd, enum charlcd_onoff on);
int hd44780_common_blink(struct charlcd *lcd, enum charlcd_onoff on);
int hd44780_common_fontsize(struct charlcd *lcd, enum charlcd_fontsize size);
int hd44780_common_lines(struct charlcd *lcd, enum charlcd_lines lines);
int hd44780_common_redefine_char(struct charlcd *lcd, char *esc);
struct hd44780_common *hd44780_common_alloc(void);
3 changes: 3 additions & 0 deletions drivers/auxdisplay/panel.c
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,7 @@ static const struct charlcd_ops charlcd_serial_ops = {
.blink = hd44780_common_blink,
.fontsize = hd44780_common_fontsize,
.lines = hd44780_common_lines,
.redefine_char = hd44780_common_redefine_char,
};

static const struct charlcd_ops charlcd_parallel_ops = {
Expand All @@ -902,6 +903,7 @@ static const struct charlcd_ops charlcd_parallel_ops = {
.blink = hd44780_common_blink,
.fontsize = hd44780_common_fontsize,
.lines = hd44780_common_lines,
.redefine_char = hd44780_common_redefine_char,
};

static const struct charlcd_ops charlcd_tilcd_ops = {
Expand All @@ -918,6 +920,7 @@ static const struct charlcd_ops charlcd_tilcd_ops = {
.blink = hd44780_common_blink,
.fontsize = hd44780_common_fontsize,
.lines = hd44780_common_lines,
.redefine_char = hd44780_common_redefine_char,
};

/* initialize the LCD driver */
Expand Down

0 comments on commit 339acb0

Please sign in to comment.