Commit 339acb08 authored by Lars Poeschel's avatar Lars Poeschel Committed by Miguel Ojeda
Browse files

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: default avatarWilly Tarreau <w@1wt.eu>
Signed-off-by: default avatarLars Poeschel <poeschel@lemonage.de>
Signed-off-by: default avatarMiguel Ojeda <ojeda@kernel.org>
parent 8a86270e
Loading
Loading
Loading
Loading
+5 −55
Original line number Diff line number Diff line
@@ -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 */

@@ -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] != ';')
+2 −0
Original line number Diff line number Diff line
@@ -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);
@@ -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);
+2 −0
Original line number Diff line number Diff line
@@ -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 */
@@ -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)
+57 −0
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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);
Loading