Commit 01ec46df authored by Lars Poeschel's avatar Lars Poeschel Committed by Miguel Ojeda
Browse files

auxdisplay: Move init_display to hd44780_common



The init_display function is moved over to hd44780_common. charlcd uses
it via its ops function pointer and drivers initialize the ops with the
common hd44780_common_init_display function.

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 bd26b181
Loading
Loading
Loading
Loading
+6 −89
Original line number Diff line number Diff line
@@ -8,7 +8,6 @@

#include <linux/atomic.h>
#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
@@ -26,17 +25,7 @@
/* Keep the backlight on this many seconds for each flash */
#define LCD_BL_TEMPO_PERIOD	4

#define LCD_FLAG_B		0x0004	/* Blink on */
#define LCD_FLAG_C		0x0008	/* Cursor on */
#define LCD_FLAG_D		0x0010	/* Display on */
#define LCD_FLAG_F		0x0020	/* Large font mode */
#define LCD_FLAG_N		0x0040	/* 2-rows mode */
#define LCD_FLAG_L		0x0080	/* Backlight enabled */

/* LCD commands */
#define LCD_CMD_ENTRY_MODE	0x04	/* Set entry mode */
#define LCD_CMD_CURSOR_INC	0x02	/* Increment cursor */

#define LCD_CMD_DISPLAY_CTRL	0x08	/* Display control */
#define LCD_CMD_DISPLAY_ON	0x04	/* Set display on */
#define LCD_CMD_CURSOR_ON	0x02	/* Set cursor on */
@@ -84,12 +73,6 @@ struct charlcd_priv {
/* Device single-open policy control */
static atomic_t charlcd_available = ATOMIC_INIT(1);

/* sleeps that many milliseconds with a reschedule */
static void long_sleep(int ms)
{
	schedule_timeout_interruptible(msecs_to_jiffies(ms));
}

/* turn the backlight on or off */
void charlcd_backlight(struct charlcd *lcd, enum charlcd_onoff on)
{
@@ -177,76 +160,6 @@ static void charlcd_clear_fast(struct charlcd *lcd)
	charlcd_home(lcd);
}

static int charlcd_init_display(struct charlcd *lcd)
{
	void (*write_cmd_raw)(struct hd44780_common *hdc, int cmd);
	struct charlcd_priv *priv = charlcd_to_priv(lcd);
	struct hd44780_common *hdc = lcd->drvdata;
	u8 init;

	if (hdc->ifwidth != 4 && hdc->ifwidth != 8)
		return -EINVAL;

	priv->flags = ((lcd->height > 1) ? LCD_FLAG_N : 0) | LCD_FLAG_D |
		      LCD_FLAG_C | LCD_FLAG_B;

	long_sleep(20);		/* wait 20 ms after power-up for the paranoid */

	/*
	 * 8-bit mode, 1 line, small fonts; let's do it 3 times, to make sure
	 * the LCD is in 8-bit mode afterwards
	 */
	init = LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS;
	if (hdc->ifwidth == 4) {
		init >>= 4;
		write_cmd_raw = hdc->write_cmd_raw4;
	} else {
		write_cmd_raw = hdc->write_cmd;
	}
	write_cmd_raw(hdc, init);
	long_sleep(10);
	write_cmd_raw(hdc, init);
	long_sleep(10);
	write_cmd_raw(hdc, init);
	long_sleep(10);

	if (hdc->ifwidth == 4) {
		/* Switch to 4-bit mode, 1 line, small fonts */
		hdc->write_cmd_raw4(hdc, LCD_CMD_FUNCTION_SET >> 4);
		long_sleep(10);
	}

	/* set font height and lines number */
	hdc->write_cmd(hdc,
		LCD_CMD_FUNCTION_SET |
		((hdc->ifwidth == 8) ? LCD_CMD_DATA_LEN_8BITS : 0) |
		((priv->flags & LCD_FLAG_F) ? LCD_CMD_FONT_5X10_DOTS : 0) |
		((priv->flags & LCD_FLAG_N) ? LCD_CMD_TWO_LINES : 0));
	long_sleep(10);

	/* display off, cursor off, blink off */
	hdc->write_cmd(hdc, LCD_CMD_DISPLAY_CTRL);
	long_sleep(10);

	hdc->write_cmd(hdc,
		LCD_CMD_DISPLAY_CTRL |	/* set display mode */
		((priv->flags & LCD_FLAG_D) ? LCD_CMD_DISPLAY_ON : 0) |
		((priv->flags & LCD_FLAG_C) ? LCD_CMD_CURSOR_ON : 0) |
		((priv->flags & LCD_FLAG_B) ? LCD_CMD_BLINK_ON : 0));

	charlcd_backlight(lcd, (priv->flags & LCD_FLAG_L) ? 1 : 0);

	long_sleep(10);

	/* entry mode set : increment, cursor shifting */
	hdc->write_cmd(hdc, LCD_CMD_ENTRY_MODE | LCD_CMD_CURSOR_INC);

	lcd->ops->clear_display(lcd);
	lcd->addr.x = 0;
	lcd->addr.y = 0;
	return 0;
}

/*
 * Parses a movement command of the form "(.*);", where the group can be
 * any number of subcommands of the form "(x|y)[0-9]+".
@@ -418,7 +331,9 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
		break;
	}
	case 'I':	/* reinitialize display */
		charlcd_init_display(lcd);
		lcd->ops->init_display(lcd);
		priv->flags = ((lcd->height > 1) ? LCD_FLAG_N : 0) | LCD_FLAG_D |
			LCD_FLAG_C | LCD_FLAG_B;
		processed = 1;
		break;
	case 'G': {
@@ -727,6 +642,8 @@ static int charlcd_init(struct charlcd *lcd)
	struct charlcd_priv *priv = charlcd_to_priv(lcd);
	int ret;

	priv->flags = ((lcd->height > 1) ? LCD_FLAG_N : 0) | LCD_FLAG_D |
		      LCD_FLAG_C | LCD_FLAG_B;
	if (lcd->ops->backlight) {
		mutex_init(&priv->bl_tempo_lock);
		INIT_DELAYED_WORK(&priv->bl_work, charlcd_bl_off);
@@ -737,7 +654,7 @@ static int charlcd_init(struct charlcd *lcd)
	 * Since charlcd_init_display() needs to write data, we have to
	 * enable mark the LCD initialized just before.
	 */
	ret = charlcd_init_display(lcd);
	ret = lcd->ops->init_display(lcd);
	if (ret)
		return ret;

+9 −0
Original line number Diff line number Diff line
@@ -9,6 +9,13 @@
#ifndef _CHARLCD_H
#define _CHARLCD_H

#define LCD_FLAG_B		0x0004	/* Blink on */
#define LCD_FLAG_C		0x0008	/* Cursor on */
#define LCD_FLAG_D		0x0010	/* Display on */
#define LCD_FLAG_F		0x0020	/* Large font mode */
#define LCD_FLAG_N		0x0040	/* 2-rows mode */
#define LCD_FLAG_L		0x0080	/* Backlight enabled */

enum charlcd_onoff {
	CHARLCD_OFF = 0,
	CHARLCD_ON,
@@ -46,6 +53,7 @@ struct charlcd {
 * @clear_display: Again clear the whole display, set the cursor to 0, 0. The
 * values in addr.x and addr.y are set to 0, 0 by charlcd prior to calling this
 * function.
 * @init_display: Initialize the display.
 */
struct charlcd_ops {
	void (*clear_fast)(struct charlcd *lcd);
@@ -54,6 +62,7 @@ struct charlcd_ops {
	int (*gotoxy)(struct charlcd *lcd);
	int (*home)(struct charlcd *lcd);
	int (*clear_display)(struct charlcd *lcd);
	int (*init_display)(struct charlcd *lcd);
};

void charlcd_backlight(struct charlcd *lcd, enum charlcd_onoff on);
+2 −0
Original line number Diff line number Diff line
@@ -130,6 +130,7 @@ static const struct charlcd_ops hd44780_ops_gpio8 = {
	.gotoxy		= hd44780_common_gotoxy,
	.home		= hd44780_common_home,
	.clear_display	= hd44780_common_clear_display,
	.init_display	= hd44780_common_init_display,
};

/* Send a command to the LCD panel in 4 bit GPIO mode */
@@ -177,6 +178,7 @@ static const struct charlcd_ops hd44780_ops_gpio4 = {
	.gotoxy		= hd44780_common_gotoxy,
	.home		= hd44780_common_home,
	.clear_display	= hd44780_common_clear_display,
	.init_display	= hd44780_common_init_display,
};

static int hd44780_probe(struct platform_device *pdev)
+88 −0
Original line number Diff line number Diff line
@@ -9,6 +9,19 @@
/* LCD commands */
#define LCD_CMD_DISPLAY_CLEAR	0x01	/* Clear entire display */

#define LCD_CMD_ENTRY_MODE	0x04	/* Set entry mode */
#define LCD_CMD_CURSOR_INC	0x02	/* Increment cursor */

#define LCD_CMD_DISPLAY_CTRL	0x08	/* Display control */
#define LCD_CMD_DISPLAY_ON	0x04	/* Set display on */
#define LCD_CMD_CURSOR_ON	0x02	/* Set cursor on */
#define LCD_CMD_BLINK_ON	0x01	/* Set blink on */

#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 */
#define LCD_CMD_FONT_5X10_DOTS	0x04	/* Set char font to 5x10 dots */

#define LCD_CMD_SET_DDRAM_ADDR	0x80	/* Set display data RAM address */

/* sleeps that many milliseconds with a reschedule */
@@ -70,6 +83,81 @@ int hd44780_common_clear_display(struct charlcd *lcd)
}
EXPORT_SYMBOL_GPL(hd44780_common_clear_display);

int hd44780_common_init_display(struct charlcd *lcd)
{
	struct hd44780_common *hdc = lcd->drvdata;

	void (*write_cmd_raw)(struct hd44780_common *hdc, int cmd);
	u8 init;

	if (hdc->ifwidth != 4 && hdc->ifwidth != 8)
		return -EINVAL;

	hdc->hd44780_common_flags = ((lcd->height > 1) ? LCD_FLAG_N : 0) |
		LCD_FLAG_D | LCD_FLAG_C | LCD_FLAG_B;

	long_sleep(20);		/* wait 20 ms after power-up for the paranoid */

	/*
	 * 8-bit mode, 1 line, small fonts; let's do it 3 times, to make sure
	 * the LCD is in 8-bit mode afterwards
	 */
	init = LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS;
	if (hdc->ifwidth == 4) {
		init >>= 4;
		write_cmd_raw = hdc->write_cmd_raw4;
	} else {
		write_cmd_raw = hdc->write_cmd;
	}
	write_cmd_raw(hdc, init);
	long_sleep(10);
	write_cmd_raw(hdc, init);
	long_sleep(10);
	write_cmd_raw(hdc, init);
	long_sleep(10);

	if (hdc->ifwidth == 4) {
		/* Switch to 4-bit mode, 1 line, small fonts */
		hdc->write_cmd_raw4(hdc, LCD_CMD_FUNCTION_SET >> 4);
		long_sleep(10);
	}

	/* set font height and lines number */
	hdc->write_cmd(hdc,
		LCD_CMD_FUNCTION_SET |
		((hdc->ifwidth == 8) ? LCD_CMD_DATA_LEN_8BITS : 0) |
		((hdc->hd44780_common_flags & LCD_FLAG_F) ?
			LCD_CMD_FONT_5X10_DOTS : 0) |
		((hdc->hd44780_common_flags & LCD_FLAG_N) ?
			LCD_CMD_TWO_LINES : 0));
	long_sleep(10);

	/* display off, cursor off, blink off */
	hdc->write_cmd(hdc, LCD_CMD_DISPLAY_CTRL);
	long_sleep(10);

	hdc->write_cmd(hdc,
		LCD_CMD_DISPLAY_CTRL |	/* set display mode */
		((hdc->hd44780_common_flags & LCD_FLAG_D) ?
			LCD_CMD_DISPLAY_ON : 0) |
		((hdc->hd44780_common_flags & LCD_FLAG_C) ?
			LCD_CMD_CURSOR_ON : 0) |
		((hdc->hd44780_common_flags & LCD_FLAG_B) ?
			LCD_CMD_BLINK_ON : 0));

	charlcd_backlight(lcd,
			(hdc->hd44780_common_flags & LCD_FLAG_L) ? 1 : 0);

	long_sleep(10);

	/* entry mode set : increment, cursor shifting */
	hdc->write_cmd(hdc, LCD_CMD_ENTRY_MODE | LCD_CMD_CURSOR_INC);

	hd44780_common_clear_display(lcd);
	return 0;
}
EXPORT_SYMBOL_GPL(hd44780_common_init_display);

struct hd44780_common *hd44780_common_alloc(void)
{
	struct hd44780_common *hd;
+2 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ struct hd44780_common {
	int ifwidth;			/* 4-bit or 8-bit (default) */
	int bwidth;			/* Default set by hd44780_alloc() */
	int hwidth;			/* Default set by hd44780_alloc() */
	unsigned long hd44780_common_flags;
	void (*write_data)(struct hd44780_common *hdc, int data);
	void (*write_cmd)(struct hd44780_common *hdc, int cmd);
	/* write_cmd_raw4 is for 4-bit connected displays only */
@@ -18,4 +19,5 @@ int hd44780_common_print(struct charlcd *lcd, int c);
int hd44780_common_gotoxy(struct charlcd *lcd);
int hd44780_common_home(struct charlcd *lcd);
int hd44780_common_clear_display(struct charlcd *lcd);
int hd44780_common_init_display(struct charlcd *lcd);
struct hd44780_common *hd44780_common_alloc(void);
Loading