linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 00/32] Make charlcd device independent
@ 2020-10-05 12:27 poeschel
  2020-10-05 12:27 ` [PATCH v4 01/32] auxdisplay: Use an enum for charlcd backlight on/off ops poeschel
                   ` (12 more replies)
  0 siblings, 13 replies; 21+ messages in thread
From: poeschel @ 2020-10-05 12:27 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, Willy Tarreau, Ksenija Stanojevic, linux-kernel
  Cc: Lars Poeschel

From: Lars Poeschel <poeschel@lemonage.de>

This tries to make charlcd device independent. At the moment hd44780
device specific code is contained deep in charlcd. This moves this out
into a hd44780_common module, where the two hd44780 drivers we have at
the moment (hd44780 and panel) can use this from. The goal is that at
the end other drivers can use the charlcd interface.
I add one such driver at the end with the last patch.
I submitted this already some time ago, where the wish was so split
this into smaller chunks what I try to do with this new patchset.
Most of the patches pick one specific function in charlcd and move the
device specific code into hd44780_common.

As a note to patch 30:
This might slightly change behaviour.
On hd44780 displays with one or two lines the previous implementation
did still write characters to the buffer of the display even if they are
currently not visible. The shift_display command could be used so set
the "viewing window" to a new position in the buffer and then you could
see the characters previously written.
This described behaviour does not work for hd44780 displays with more
than two display lines. There simply is not enough buffer.
So the behaviour was a bit inconsistens across different displays.
The new behaviour is to stop writing character at the end of a visible
line, even if there would be room in the buffer. This allows us to have
an easy implementation, that should behave equal on all supported
displays. This is not hd44780 hardware dependents anymore.

Link: https://lore.kernel.org/lkml/20191016082430.5955-1-poeschel@lemonage.de/
Link: https://lore.kernel.org/lkml/CANiq72kS-u_Xd_m+2CQVh-JCncPf1XNXrXAZ=4z+mze8fwv2kw@mail.gmail.com/

Lars Poeschel (32):
  auxdisplay: Use an enum for charlcd  backlight on/off ops
  auxdisplay: Introduce hd44780_common.[ch]
  auxdisplay: Move hwidth and bwidth to struct hd44780_common
  auxdisplay: Move ifwidth to struct hd44780_common
  auxdisplay: Move write_data pointer to hd44780_common
  auxdisplay: Move write_cmd pointers to hd44780 drivers
  auxdisplay: Move addr out of charlcd_priv
  auxdisplay: hd44780_common_print
  auxdisplay: provide hd44780_common_gotoxy
  auxdisplay: add home to charlcd_ops
  auxdisplay: Move clear_display to hd44780_common
  auxdisplay: make charlcd_backlight visible to hd44780_common
  auxdisplay: Make use of enum for backlight on / off
  auxdisplay: Move init_display to hd44780_common
  auxdisplay: implement hd44780_common_shift_cursor
  auxdisplay: Implement hd44780_common_display_shift
  auxdisplay: Implement a hd44780_common_display
  auxdisplay: Implement hd44780_common_cursor
  auxdisplay: Implement hd44780_common_blink
  auxdisplay: cleanup unnecessary hd44780 code in charlcd
  auxdisplay: Implement hd44780_common_fontsize
  auxdisplay: Implement hd44780_common_lines
  auxdisplay: Remove unnecessary hd44780 from charlcd
  auxdisplay: Move char redefine code to hd44780_common
  auxdisplay: Call charlcd_backlight in place
  auxdisplay: hd44780_common: Reduce clear_display timeout
  auxdisplay: hd44780: Remove clear_fast
  auxdisplay: charlcd: replace last device specific stuff
  auxdisplay: Change gotoxy calling interface
  auxdisplay: charlcd: Do not print chars at end of line
  auxdisplay: lcd2s DT binding doc
  auxdisplay: add a driver for lcd2s character display

 .../bindings/auxdisplay/modtronix,lcd2s.yaml  |  58 +++
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 drivers/auxdisplay/Kconfig                    |  30 ++
 drivers/auxdisplay/Makefile                   |   2 +
 drivers/auxdisplay/charlcd.c                  | 412 +++++-------------
 drivers/auxdisplay/charlcd.h                  |  86 +++-
 drivers/auxdisplay/hd44780.c                  | 120 +++--
 drivers/auxdisplay/hd44780_common.c           | 368 ++++++++++++++++
 drivers/auxdisplay/hd44780_common.h           |  34 ++
 drivers/auxdisplay/lcd2s.c                    | 409 +++++++++++++++++
 drivers/auxdisplay/panel.c                    | 180 ++++----
 11 files changed, 1251 insertions(+), 450 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/auxdisplay/modtronix,lcd2s.yaml
 create mode 100644 drivers/auxdisplay/hd44780_common.c
 create mode 100644 drivers/auxdisplay/hd44780_common.h
 create mode 100644 drivers/auxdisplay/lcd2s.c

-- 
2.28.0


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v4 01/32] auxdisplay: Use an enum for charlcd  backlight on/off ops
  2020-10-05 12:27 [PATCH v4 00/32] Make charlcd device independent poeschel
@ 2020-10-05 12:27 ` poeschel
  2020-10-16  2:34   ` Miguel Ojeda
  2020-10-05 12:27 ` [PATCH v4 02/32] auxdisplay: Introduce hd44780_common.[ch] poeschel
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 21+ messages in thread
From: poeschel @ 2020-10-05 12:27 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, Willy Tarreau, Ksenija Stanojevic, open list
  Cc: Lars Poeschel, Willy Tarreau

From: Lars Poeschel <poeschel@lemonage.de>

We use an enum for calling the functions in charlcd, that turn the
backlight on or off. This enum is generic and can be used for other
charlcd turn of / turn off operations as well.

Reviewed-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Lars Poeschel <poeschel@lemonage.de>
---
 drivers/auxdisplay/charlcd.c | 2 +-
 drivers/auxdisplay/charlcd.h | 7 ++++++-
 drivers/auxdisplay/hd44780.c | 2 +-
 drivers/auxdisplay/panel.c   | 2 +-
 4 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
index 5aee0f546351..8aaee0fea9ab 100644
--- a/drivers/auxdisplay/charlcd.c
+++ b/drivers/auxdisplay/charlcd.c
@@ -101,7 +101,7 @@ static void long_sleep(int ms)
 }
 
 /* turn the backlight on or off */
-static void charlcd_backlight(struct charlcd *lcd, int on)
+static void charlcd_backlight(struct charlcd *lcd, enum charlcd_onoff on)
 {
 	struct charlcd_priv *priv = charlcd_to_priv(lcd);
 
diff --git a/drivers/auxdisplay/charlcd.h b/drivers/auxdisplay/charlcd.h
index 00911ad0f3de..c66f038e5d2b 100644
--- a/drivers/auxdisplay/charlcd.h
+++ b/drivers/auxdisplay/charlcd.h
@@ -9,6 +9,11 @@
 #ifndef _CHARLCD_H
 #define _CHARLCD_H
 
+enum charlcd_onoff {
+	CHARLCD_OFF = 0,
+	CHARLCD_ON,
+};
+
 struct charlcd {
 	const struct charlcd_ops *ops;
 	const unsigned char *char_conv;	/* Optional */
@@ -30,7 +35,7 @@ struct charlcd_ops {
 	/* Optional */
 	void (*write_cmd_raw4)(struct charlcd *lcd, int cmd);	/* 4-bit only */
 	void (*clear_fast)(struct charlcd *lcd);
-	void (*backlight)(struct charlcd *lcd, int on);
+	void (*backlight)(struct charlcd *lcd, enum charlcd_onoff on);
 };
 
 struct charlcd *charlcd_alloc(unsigned int drvdata_size);
diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c
index bcbe13092327..5982158557bb 100644
--- a/drivers/auxdisplay/hd44780.c
+++ b/drivers/auxdisplay/hd44780.c
@@ -37,7 +37,7 @@ struct hd44780 {
 	struct gpio_desc *pins[PIN_NUM];
 };
 
-static void hd44780_backlight(struct charlcd *lcd, int on)
+static void hd44780_backlight(struct charlcd *lcd, enum charlcd_onoff on)
 {
 	struct hd44780 *hd = lcd->drvdata;
 
diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c
index 1c82d824ae00..de623ae219f1 100644
--- a/drivers/auxdisplay/panel.c
+++ b/drivers/auxdisplay/panel.c
@@ -708,7 +708,7 @@ static void lcd_send_serial(int byte)
 }
 
 /* turn the backlight on or off */
-static void lcd_backlight(struct charlcd *charlcd, int on)
+static void lcd_backlight(struct charlcd *charlcd, enum charlcd_onoff on)
 {
 	if (lcd.pins.bl == PIN_NONE)
 		return;
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 02/32] auxdisplay: Introduce hd44780_common.[ch]
  2020-10-05 12:27 [PATCH v4 00/32] Make charlcd device independent poeschel
  2020-10-05 12:27 ` [PATCH v4 01/32] auxdisplay: Use an enum for charlcd backlight on/off ops poeschel
@ 2020-10-05 12:27 ` poeschel
  2020-10-16  2:48   ` Miguel Ojeda
  2020-10-05 12:27 ` [PATCH v4 03/32] auxdisplay: Move hwidth and bwidth to struct hd44780_common poeschel
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 21+ messages in thread
From: poeschel @ 2020-10-05 12:27 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, Willy Tarreau, Ksenija Stanojevic, open list
  Cc: Lars Poeschel, Willy Tarreau

From: Lars Poeschel <poeschel@lemonage.de>

There is some hd44780 specific code in charlcd and this code is used by
multiple drivers. To make charlcd independent from this device specific
code this has to be moved to a place where the multiple drivers can
share their common code. This common place is now introduced as
hd44780_common.

Reviewed-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Lars Poeschel <poeschel@lemonage.de>
---
Changes in v3:
- Fix some typos
---
 drivers/auxdisplay/Kconfig          | 20 ++++++++++++++
 drivers/auxdisplay/Makefile         |  1 +
 drivers/auxdisplay/hd44780.c        | 43 +++++++++++++++++++----------
 drivers/auxdisplay/hd44780_common.c | 21 ++++++++++++++
 drivers/auxdisplay/hd44780_common.h |  8 ++++++
 drivers/auxdisplay/panel.c          | 18 ++++++++++--
 6 files changed, 94 insertions(+), 17 deletions(-)
 create mode 100644 drivers/auxdisplay/hd44780_common.c
 create mode 100644 drivers/auxdisplay/hd44780_common.h

diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig
index 81757eeded68..a56171d1a1ba 100644
--- a/drivers/auxdisplay/Kconfig
+++ b/drivers/auxdisplay/Kconfig
@@ -14,12 +14,31 @@ menuconfig AUXDISPLAY
 
 	  If you say N, all options in this submenu will be skipped and disabled.
 
+config CHARLCD
+	tristate "Character LCD core support" if COMPILE_TEST
+	help
+	  This is the base system for character-based LCD displays.
+	  It makes no sense to have this alone, you select your display driver
+	  and if it needs the charlcd core, it will select it automatically.
+	  This is some character LCD core interface that multiple drivers can
+	  use.
+
+config HD44780_COMMON
+	tristate "Common functions for HD44780 (and compatibles) LCD displays" if COMPILE_TEST
+	help
+	  This is a module with the common symbols for HD44780 (and compatibles)
+	  displays. This is the code that multiple other modules use. It is not
+	  useful alone. If you have some sort of HD44780 compatible display,
+	  you very likely use this. It is selected automatically by selecting
+	  your concrete display.
+
 if AUXDISPLAY
 
 config HD44780
 	tristate "HD44780 Character LCD support"
 	depends on GPIOLIB || COMPILE_TEST
 	select CHARLCD
+	select HD44780_COMMON
 	help
 	  Enable support for Character LCDs using a HD44780 controller.
 	  The LCD is accessible through the /dev/lcd char device (10, 156).
@@ -168,6 +187,7 @@ menuconfig PARPORT_PANEL
 	tristate "Parallel port LCD/Keypad Panel support"
 	depends on PARPORT
 	select CHARLCD
+	select HD44780_COMMON
 	help
 	  Say Y here if you have an HD44780 or KS-0074 LCD connected to your
 	  parallel port. This driver also features 4 and 6-key keypads. The LCD
diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile
index cf54b5efb07e..7e8a8c3eb3c3 100644
--- a/drivers/auxdisplay/Makefile
+++ b/drivers/auxdisplay/Makefile
@@ -4,6 +4,7 @@
 #
 
 obj-$(CONFIG_CHARLCD)		+= charlcd.o
+obj-$(CONFIG_HD44780_COMMON)	+= hd44780_common.o
 obj-$(CONFIG_ARM_CHARLCD)	+= arm-charlcd.o
 obj-$(CONFIG_KS0108)		+= ks0108.o
 obj-$(CONFIG_CFAG12864B)	+= cfag12864b.o cfag12864bfb.o
diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c
index 5982158557bb..271dba9cd108 100644
--- a/drivers/auxdisplay/hd44780.c
+++ b/drivers/auxdisplay/hd44780.c
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 
 #include "charlcd.h"
+#include "hd44780_common.h"
 
 enum hd44780_pin {
 	/* Order does matter due to writing to GPIO array subsets! */
@@ -179,8 +180,9 @@ static int hd44780_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	unsigned int i, base;
 	struct charlcd *lcd;
+	struct hd44780_common *hdc;
 	struct hd44780 *hd;
-	int ifwidth, ret;
+	int ifwidth, ret = -ENOMEM;
 
 	/* Required pins */
 	ifwidth = gpiod_count(dev, "data");
@@ -198,31 +200,39 @@ static int hd44780_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
+	hdc = hd44780_common_alloc();
+	if (!hdc)
+		return -ENOMEM;
+
 	lcd = charlcd_alloc(sizeof(struct hd44780));
 	if (!lcd)
-		return -ENOMEM;
+		goto fail1;
 
-	hd = lcd->drvdata;
+	hd = kzalloc(sizeof(struct hd44780), GFP_KERNEL);
+	if (!hd)
+		goto fail2;
 
+	hdc->hd44780 = hd;
+	lcd->drvdata = hdc;
 	for (i = 0; i < ifwidth; i++) {
 		hd->pins[base + i] = devm_gpiod_get_index(dev, "data", i,
 							  GPIOD_OUT_LOW);
 		if (IS_ERR(hd->pins[base + i])) {
 			ret = PTR_ERR(hd->pins[base + i]);
-			goto fail;
+			goto fail3;
 		}
 	}
 
 	hd->pins[PIN_CTRL_E] = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
 	if (IS_ERR(hd->pins[PIN_CTRL_E])) {
 		ret = PTR_ERR(hd->pins[PIN_CTRL_E]);
-		goto fail;
+		goto fail3;
 	}
 
 	hd->pins[PIN_CTRL_RS] = devm_gpiod_get(dev, "rs", GPIOD_OUT_HIGH);
 	if (IS_ERR(hd->pins[PIN_CTRL_RS])) {
 		ret = PTR_ERR(hd->pins[PIN_CTRL_RS]);
-		goto fail;
+		goto fail3;
 	}
 
 	/* Optional pins */
@@ -230,24 +240,24 @@ static int hd44780_probe(struct platform_device *pdev)
 							GPIOD_OUT_LOW);
 	if (IS_ERR(hd->pins[PIN_CTRL_RW])) {
 		ret = PTR_ERR(hd->pins[PIN_CTRL_RW]);
-		goto fail;
+		goto fail3;
 	}
 
 	hd->pins[PIN_CTRL_BL] = devm_gpiod_get_optional(dev, "backlight",
 							GPIOD_OUT_LOW);
 	if (IS_ERR(hd->pins[PIN_CTRL_BL])) {
 		ret = PTR_ERR(hd->pins[PIN_CTRL_BL]);
-		goto fail;
+		goto fail3;
 	}
 
 	/* Required properties */
 	ret = device_property_read_u32(dev, "display-height-chars",
 				       &lcd->height);
 	if (ret)
-		goto fail;
+		goto fail3;
 	ret = device_property_read_u32(dev, "display-width-chars", &lcd->width);
 	if (ret)
-		goto fail;
+		goto fail3;
 
 	/*
 	 * On displays with more than two rows, the internal buffer width is
@@ -264,13 +274,17 @@ static int hd44780_probe(struct platform_device *pdev)
 
 	ret = charlcd_register(lcd);
 	if (ret)
-		goto fail;
+		goto fail3;
 
 	platform_set_drvdata(pdev, lcd);
 	return 0;
 
-fail:
-	charlcd_free(lcd);
+fail3:
+	kfree(hd);
+fail2:
+	kfree(lcd);
+fail1:
+	kfree(hdc);
 	return ret;
 }
 
@@ -278,9 +292,10 @@ static int hd44780_remove(struct platform_device *pdev)
 {
 	struct charlcd *lcd = platform_get_drvdata(pdev);
 
+	kfree(lcd->drvdata);
 	charlcd_unregister(lcd);
 
-	charlcd_free(lcd);
+	kfree(lcd);
 	return 0;
 }
 
diff --git a/drivers/auxdisplay/hd44780_common.c b/drivers/auxdisplay/hd44780_common.c
new file mode 100644
index 000000000000..073f47397f7d
--- /dev/null
+++ b/drivers/auxdisplay/hd44780_common.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "hd44780_common.h"
+
+struct hd44780_common *hd44780_common_alloc(void)
+{
+	struct hd44780_common *hd;
+
+	hd = kzalloc(sizeof(*hd), GFP_KERNEL);
+	if (!hd)
+		return NULL;
+
+	return hd;
+
+}
+EXPORT_SYMBOL_GPL(hd44780_common_alloc);
+
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/auxdisplay/hd44780_common.h b/drivers/auxdisplay/hd44780_common.h
new file mode 100644
index 000000000000..767bbda91744
--- /dev/null
+++ b/drivers/auxdisplay/hd44780_common.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+struct hd44780_common {
+	void *hd44780;
+};
+
+struct hd44780_common *hd44780_common_alloc(void);
+
diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c
index de623ae219f1..c3a60e190a7a 100644
--- a/drivers/auxdisplay/panel.c
+++ b/drivers/auxdisplay/panel.c
@@ -56,6 +56,7 @@
 #include <linux/uaccess.h>
 
 #include "charlcd.h"
+#include "hd44780_common.h"
 
 #define LCD_MAXBYTES		256	/* max burst write */
 
@@ -895,10 +896,20 @@ static const struct charlcd_ops charlcd_tilcd_ops = {
 static void lcd_init(void)
 {
 	struct charlcd *charlcd;
+	struct hd44780_common *hdc;
+
+	hdc = hd44780_common_alloc();
+	if (!hdc)
+		return;
 
 	charlcd = charlcd_alloc(0);
-	if (!charlcd)
+	if (!charlcd) {
+		kfree(hdc);
 		return;
+	}
+
+	hdc->hd44780 = &lcd;
+	charlcd->drvdata = hdc;
 
 	/*
 	 * Init lcd struct with load-time values to preserve exact
@@ -1620,7 +1631,7 @@ static void panel_attach(struct parport *port)
 	if (lcd.enabled)
 		charlcd_unregister(lcd.charlcd);
 err_unreg_device:
-	charlcd_free(lcd.charlcd);
+	kfree(lcd.charlcd);
 	lcd.charlcd = NULL;
 	parport_unregister_device(pprt);
 	pprt = NULL;
@@ -1647,7 +1658,8 @@ static void panel_detach(struct parport *port)
 	if (lcd.enabled) {
 		charlcd_unregister(lcd.charlcd);
 		lcd.initialized = false;
-		charlcd_free(lcd.charlcd);
+		kfree(lcd.charlcd->drvdata);
+		kfree(lcd.charlcd);
 		lcd.charlcd = NULL;
 	}
 
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 03/32] auxdisplay: Move hwidth and bwidth to struct hd44780_common
  2020-10-05 12:27 [PATCH v4 00/32] Make charlcd device independent poeschel
  2020-10-05 12:27 ` [PATCH v4 01/32] auxdisplay: Use an enum for charlcd backlight on/off ops poeschel
  2020-10-05 12:27 ` [PATCH v4 02/32] auxdisplay: Introduce hd44780_common.[ch] poeschel
@ 2020-10-05 12:27 ` poeschel
  2020-10-05 12:27 ` [PATCH v4 04/32] auxdisplay: Move ifwidth " poeschel
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: poeschel @ 2020-10-05 12:27 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, Willy Tarreau, Ksenija Stanojevic, open list
  Cc: Lars Poeschel, Willy Tarreau

From: Lars Poeschel <poeschel@lemonage.de>

hwidth is for the hardware buffer size and bwidth is for the buffer
width of one single line. This is specific to the hd44780 displays and
so it is moved out from charlcd to struct hd44780_common.

Reviewed-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Lars Poeschel <poeschel@lemonage.de>
---
 drivers/auxdisplay/charlcd.c        | 40 ++++++++++++-------------
 drivers/auxdisplay/charlcd.h        |  6 ++--
 drivers/auxdisplay/hd44780.c        | 24 +++++++++------
 drivers/auxdisplay/hd44780_common.c |  3 +-
 drivers/auxdisplay/hd44780_common.h |  5 ++++
 drivers/auxdisplay/panel.c          | 45 +++++++++++++++--------------
 6 files changed, 67 insertions(+), 56 deletions(-)

diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
index 8aaee0fea9ab..02392336d7d3 100644
--- a/drivers/auxdisplay/charlcd.c
+++ b/drivers/auxdisplay/charlcd.c
@@ -21,9 +21,7 @@
 #include <generated/utsrelease.h>
 
 #include "charlcd.h"
-
-#define DEFAULT_LCD_BWIDTH      40
-#define DEFAULT_LCD_HWIDTH      64
+#include "hd44780_common.h"
 
 /* Keep the backlight on this many seconds for each flash */
 #define LCD_BL_TEMPO_PERIOD	4
@@ -151,18 +149,19 @@ EXPORT_SYMBOL_GPL(charlcd_poke);
 static void charlcd_gotoxy(struct charlcd *lcd)
 {
 	struct charlcd_priv *priv = charlcd_to_priv(lcd);
+	struct hd44780_common *hdc = lcd->drvdata;
 	unsigned int addr;
 
 	/*
 	 * we force the cursor to stay at the end of the
 	 * line if it wants to go farther
 	 */
-	addr = priv->addr.x < lcd->bwidth ? priv->addr.x & (lcd->hwidth - 1)
-					  : lcd->bwidth - 1;
+	addr = priv->addr.x < hdc->bwidth ? priv->addr.x & (hdc->hwidth - 1)
+					  : hdc->bwidth - 1;
 	if (priv->addr.y & 1)
-		addr += lcd->hwidth;
+		addr += hdc->hwidth;
 	if (priv->addr.y & 2)
-		addr += lcd->bwidth;
+		addr += hdc->bwidth;
 	lcd->ops->write_cmd(lcd, LCD_CMD_SET_DDRAM_ADDR | addr);
 }
 
@@ -178,21 +177,23 @@ static void charlcd_home(struct charlcd *lcd)
 static void charlcd_print(struct charlcd *lcd, char c)
 {
 	struct charlcd_priv *priv = charlcd_to_priv(lcd);
+	struct hd44780_common *hdc = lcd->drvdata;
 
-	if (priv->addr.x < lcd->bwidth) {
+	if (priv->addr.x < hdc->bwidth) {
 		if (lcd->char_conv)
 			c = lcd->char_conv[(unsigned char)c];
 		lcd->ops->write_data(lcd, c);
 		priv->addr.x++;
 
 		/* prevents the cursor from wrapping onto the next line */
-		if (priv->addr.x == lcd->bwidth)
+		if (priv->addr.x == hdc->bwidth)
 			charlcd_gotoxy(lcd);
 	}
 }
 
 static void charlcd_clear_fast(struct charlcd *lcd)
 {
+	struct hd44780_common *hdc = lcd->drvdata;
 	int pos;
 
 	charlcd_home(lcd);
@@ -200,7 +201,7 @@ static void charlcd_clear_fast(struct charlcd *lcd)
 	if (lcd->ops->clear_fast)
 		lcd->ops->clear_fast(lcd);
 	else
-		for (pos = 0; pos < min(2, lcd->height) * lcd->hwidth; pos++)
+		for (pos = 0; pos < min(2, lcd->height) * hdc->hwidth; pos++)
 			lcd->ops->write_data(lcd, ' ');
 
 	charlcd_home(lcd);
@@ -348,6 +349,7 @@ static bool parse_xy(const char *s, unsigned long *x, unsigned long *y)
 static inline int handle_lcd_special_code(struct charlcd *lcd)
 {
 	struct charlcd_priv *priv = charlcd_to_priv(lcd);
+	struct hd44780_common *hdc = lcd->drvdata;
 
 	/* LCD special codes */
 
@@ -413,7 +415,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 	case 'l':	/* Shift Cursor Left */
 		if (priv->addr.x > 0) {
 			/* back one char if not at end of line */
-			if (priv->addr.x < lcd->bwidth)
+			if (priv->addr.x < hdc->bwidth)
 				lcd->ops->write_cmd(lcd, LCD_CMD_SHIFT);
 			priv->addr.x--;
 		}
@@ -422,7 +424,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 	case 'r':	/* shift cursor right */
 		if (priv->addr.x < lcd->width) {
 			/* allow the cursor to pass the end of the line */
-			if (priv->addr.x < (lcd->bwidth - 1))
+			if (priv->addr.x < (hdc->bwidth - 1))
 				lcd->ops->write_cmd(lcd,
 					LCD_CMD_SHIFT | LCD_CMD_SHIFT_RIGHT);
 			priv->addr.x++;
@@ -442,7 +444,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 	case 'k': {	/* kill end of line */
 		int x;
 
-		for (x = priv->addr.x; x < lcd->bwidth; x++)
+		for (x = priv->addr.x; x < hdc->bwidth; x++)
 			lcd->ops->write_data(lcd, ' ');
 
 		/* restore cursor position */
@@ -554,6 +556,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 static void charlcd_write_char(struct charlcd *lcd, char c)
 {
 	struct charlcd_priv *priv = charlcd_to_priv(lcd);
+	struct hd44780_common *hdc = lcd->drvdata;
 
 	/* first, we'll test if we're in escape mode */
 	if ((c != '\n') && priv->esc_seq.len >= 0) {
@@ -577,7 +580,7 @@ static void charlcd_write_char(struct charlcd *lcd, char c)
 				 * check if we're not at the
 				 * end of the line
 				 */
-				if (priv->addr.x < lcd->bwidth)
+				if (priv->addr.x < hdc->bwidth)
 					/* back one char */
 					lcd->ops->write_cmd(lcd, LCD_CMD_SHIFT);
 				priv->addr.x--;
@@ -596,7 +599,7 @@ static void charlcd_write_char(struct charlcd *lcd, char c)
 			 * flush the remainder of the current line and
 			 * go to the beginning of the next line
 			 */
-			for (; priv->addr.x < lcd->bwidth; priv->addr.x++)
+			for (; priv->addr.x < hdc->bwidth; priv->addr.x++)
 				lcd->ops->write_data(lcd, ' ');
 			priv->addr.x = 0;
 			priv->addr.y = (priv->addr.y + 1) % lcd->height;
@@ -779,12 +782,12 @@ static int charlcd_init(struct charlcd *lcd)
 	return 0;
 }
 
-struct charlcd *charlcd_alloc(unsigned int drvdata_size)
+struct charlcd *charlcd_alloc(void)
 {
 	struct charlcd_priv *priv;
 	struct charlcd *lcd;
 
-	priv = kzalloc(sizeof(*priv) + drvdata_size, GFP_KERNEL);
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return NULL;
 
@@ -792,9 +795,6 @@ struct charlcd *charlcd_alloc(unsigned int drvdata_size)
 
 	lcd = &priv->lcd;
 	lcd->ifwidth = 8;
-	lcd->bwidth = DEFAULT_LCD_BWIDTH;
-	lcd->hwidth = DEFAULT_LCD_HWIDTH;
-	lcd->drvdata = priv->drvdata;
 
 	return lcd;
 }
diff --git a/drivers/auxdisplay/charlcd.h b/drivers/auxdisplay/charlcd.h
index c66f038e5d2b..2a12d07705a3 100644
--- a/drivers/auxdisplay/charlcd.h
+++ b/drivers/auxdisplay/charlcd.h
@@ -21,10 +21,8 @@ struct charlcd {
 	int ifwidth;			/* 4-bit or 8-bit (default) */
 	int height;
 	int width;
-	int bwidth;			/* Default set by charlcd_alloc() */
-	int hwidth;			/* Default set by charlcd_alloc() */
 
-	void *drvdata;			/* Set by charlcd_alloc() */
+	void *drvdata;
 };
 
 struct charlcd_ops {
@@ -38,7 +36,7 @@ struct charlcd_ops {
 	void (*backlight)(struct charlcd *lcd, enum charlcd_onoff on);
 };
 
-struct charlcd *charlcd_alloc(unsigned int drvdata_size);
+struct charlcd *charlcd_alloc(void);
 void charlcd_free(struct charlcd *lcd);
 
 int charlcd_register(struct charlcd *lcd);
diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c
index 271dba9cd108..0603af8f2336 100644
--- a/drivers/auxdisplay/hd44780.c
+++ b/drivers/auxdisplay/hd44780.c
@@ -40,7 +40,8 @@ struct hd44780 {
 
 static void hd44780_backlight(struct charlcd *lcd, enum charlcd_onoff on)
 {
-	struct hd44780 *hd = lcd->drvdata;
+	struct hd44780_common *hdc = lcd->drvdata;
+	struct hd44780 *hd = hdc->hd44780;
 
 	if (hd->pins[PIN_CTRL_BL])
 		gpiod_set_value_cansleep(hd->pins[PIN_CTRL_BL], on);
@@ -104,7 +105,8 @@ static void hd44780_write_gpio4(struct hd44780 *hd, u8 val, unsigned int rs)
 /* Send a command to the LCD panel in 8 bit GPIO mode */
 static void hd44780_write_cmd_gpio8(struct charlcd *lcd, int cmd)
 {
-	struct hd44780 *hd = lcd->drvdata;
+	struct hd44780_common *hdc = lcd->drvdata;
+	struct hd44780 *hd = hdc->hd44780;
 
 	hd44780_write_gpio8(hd, cmd, 0);
 
@@ -115,7 +117,8 @@ static void hd44780_write_cmd_gpio8(struct charlcd *lcd, int cmd)
 /* Send data to the LCD panel in 8 bit GPIO mode */
 static void hd44780_write_data_gpio8(struct charlcd *lcd, int data)
 {
-	struct hd44780 *hd = lcd->drvdata;
+	struct hd44780_common *hdc = lcd->drvdata;
+	struct hd44780 *hd = hdc->hd44780;
 
 	hd44780_write_gpio8(hd, data, 1);
 
@@ -132,7 +135,8 @@ static const struct charlcd_ops hd44780_ops_gpio8 = {
 /* Send a command to the LCD panel in 4 bit GPIO mode */
 static void hd44780_write_cmd_gpio4(struct charlcd *lcd, int cmd)
 {
-	struct hd44780 *hd = lcd->drvdata;
+	struct hd44780_common *hdc = lcd->drvdata;
+	struct hd44780 *hd = hdc->hd44780;
 
 	hd44780_write_gpio4(hd, cmd, 0);
 
@@ -144,7 +148,8 @@ static void hd44780_write_cmd_gpio4(struct charlcd *lcd, int cmd)
 static void hd44780_write_cmd_raw_gpio4(struct charlcd *lcd, int cmd)
 {
 	DECLARE_BITMAP(values, 6); /* for DATA[4-7], RS, RW */
-	struct hd44780 *hd = lcd->drvdata;
+	struct hd44780_common *hdc = lcd->drvdata;
+	struct hd44780 *hd = hdc->hd44780;
 	unsigned int n;
 
 	/* Command nibble + RS, RW */
@@ -160,7 +165,8 @@ static void hd44780_write_cmd_raw_gpio4(struct charlcd *lcd, int cmd)
 /* Send data to the LCD panel in 4 bit GPIO mode */
 static void hd44780_write_data_gpio4(struct charlcd *lcd, int data)
 {
-	struct hd44780 *hd = lcd->drvdata;
+	struct hd44780_common *hdc = lcd->drvdata;
+	struct hd44780 *hd = hdc->hd44780;
 
 	hd44780_write_gpio4(hd, data, 1);
 
@@ -204,7 +210,7 @@ static int hd44780_probe(struct platform_device *pdev)
 	if (!hdc)
 		return -ENOMEM;
 
-	lcd = charlcd_alloc(sizeof(struct hd44780));
+	lcd = charlcd_alloc();
 	if (!lcd)
 		goto fail1;
 
@@ -264,10 +270,10 @@ static int hd44780_probe(struct platform_device *pdev)
 	 * usually equal to the display width
 	 */
 	if (lcd->height > 2)
-		lcd->bwidth = lcd->width;
+		hdc->bwidth = lcd->width;
 
 	/* Optional properties */
-	device_property_read_u32(dev, "internal-buffer-width", &lcd->bwidth);
+	device_property_read_u32(dev, "internal-buffer-width", &hdc->bwidth);
 
 	lcd->ifwidth = ifwidth;
 	lcd->ops = ifwidth == 8 ? &hd44780_ops_gpio8 : &hd44780_ops_gpio4;
diff --git a/drivers/auxdisplay/hd44780_common.c b/drivers/auxdisplay/hd44780_common.c
index 073f47397f7d..34e6d292fde8 100644
--- a/drivers/auxdisplay/hd44780_common.c
+++ b/drivers/auxdisplay/hd44780_common.c
@@ -12,10 +12,11 @@ struct hd44780_common *hd44780_common_alloc(void)
 	if (!hd)
 		return NULL;
 
+	hd->bwidth = DEFAULT_LCD_BWIDTH;
+	hd->hwidth = DEFAULT_LCD_HWIDTH;
 	return hd;
 
 }
 EXPORT_SYMBOL_GPL(hd44780_common_alloc);
 
 MODULE_LICENSE("GPL");
-
diff --git a/drivers/auxdisplay/hd44780_common.h b/drivers/auxdisplay/hd44780_common.h
index 767bbda91744..3ff47d2c5691 100644
--- a/drivers/auxdisplay/hd44780_common.h
+++ b/drivers/auxdisplay/hd44780_common.h
@@ -1,6 +1,11 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 
+#define DEFAULT_LCD_BWIDTH      40
+#define DEFAULT_LCD_HWIDTH      64
+
 struct hd44780_common {
+	int bwidth;			/* Default set by hd44780_alloc() */
+	int hwidth;			/* Default set by hd44780_alloc() */
 	void *hd44780;
 };
 
diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c
index c3a60e190a7a..cec6b729d668 100644
--- a/drivers/auxdisplay/panel.c
+++ b/drivers/auxdisplay/panel.c
@@ -299,8 +299,6 @@ static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES];
 #define DEFAULT_LCD_TYPE        LCD_TYPE_OLD
 #define DEFAULT_LCD_HEIGHT      2
 #define DEFAULT_LCD_WIDTH       40
-#define DEFAULT_LCD_BWIDTH      40
-#define DEFAULT_LCD_HWIDTH      64
 #define DEFAULT_LCD_CHARSET     LCD_CHARSET_NORMAL
 #define DEFAULT_LCD_PROTO       LCD_PROTO_PARALLEL
 
@@ -813,10 +811,11 @@ static void lcd_write_data_tilcd(struct charlcd *charlcd, int data)
 /* fills the display with spaces and resets X/Y */
 static void lcd_clear_fast_s(struct charlcd *charlcd)
 {
+	struct hd44780_common *hdc = charlcd->drvdata;
 	int pos;
 
 	spin_lock_irq(&pprt_lock);
-	for (pos = 0; pos < charlcd->height * charlcd->hwidth; pos++) {
+	for (pos = 0; pos < charlcd->height * hdc->hwidth; pos++) {
 		lcd_send_serial(0x5F);	/* R/W=W, RS=1 */
 		lcd_send_serial(' ' & 0x0F);
 		lcd_send_serial((' ' >> 4) & 0x0F);
@@ -829,10 +828,11 @@ static void lcd_clear_fast_s(struct charlcd *charlcd)
 /* fills the display with spaces and resets X/Y */
 static void lcd_clear_fast_p8(struct charlcd *charlcd)
 {
+	struct hd44780_common *hdc = charlcd->drvdata;
 	int pos;
 
 	spin_lock_irq(&pprt_lock);
-	for (pos = 0; pos < charlcd->height * charlcd->hwidth; pos++) {
+	for (pos = 0; pos < charlcd->height * hdc->hwidth; pos++) {
 		/* present the data to the data port */
 		w_dtr(pprt, ' ');
 
@@ -859,10 +859,11 @@ static void lcd_clear_fast_p8(struct charlcd *charlcd)
 /* fills the display with spaces and resets X/Y */
 static void lcd_clear_fast_tilcd(struct charlcd *charlcd)
 {
+	struct hd44780_common *hdc = charlcd->drvdata;
 	int pos;
 
 	spin_lock_irq(&pprt_lock);
-	for (pos = 0; pos < charlcd->height * charlcd->hwidth; pos++) {
+	for (pos = 0; pos < charlcd->height * hdc->hwidth; pos++) {
 		/* present the data to the data port */
 		w_dtr(pprt, ' ');
 		udelay(60);
@@ -902,7 +903,7 @@ static void lcd_init(void)
 	if (!hdc)
 		return;
 
-	charlcd = charlcd_alloc(0);
+	charlcd = charlcd_alloc();
 	if (!charlcd) {
 		kfree(hdc);
 		return;
@@ -917,8 +918,8 @@ static void lcd_init(void)
 	 */
 	charlcd->height = lcd_height;
 	charlcd->width = lcd_width;
-	charlcd->bwidth = lcd_bwidth;
-	charlcd->hwidth = lcd_hwidth;
+	hdc->bwidth = lcd_bwidth;
+	hdc->hwidth = lcd_hwidth;
 
 	switch (selected_lcd_type) {
 	case LCD_TYPE_OLD:
@@ -929,8 +930,8 @@ static void lcd_init(void)
 		lcd.pins.rs = PIN_AUTOLF;
 
 		charlcd->width = 40;
-		charlcd->bwidth = 40;
-		charlcd->hwidth = 64;
+		hdc->bwidth = 40;
+		hdc->hwidth = 64;
 		charlcd->height = 2;
 		break;
 	case LCD_TYPE_KS0074:
@@ -942,8 +943,8 @@ static void lcd_init(void)
 		lcd.pins.da = PIN_D0;
 
 		charlcd->width = 16;
-		charlcd->bwidth = 40;
-		charlcd->hwidth = 16;
+		hdc->bwidth = 40;
+		hdc->hwidth = 16;
 		charlcd->height = 2;
 		break;
 	case LCD_TYPE_NEXCOM:
@@ -955,8 +956,8 @@ static void lcd_init(void)
 		lcd.pins.rw = PIN_INITP;
 
 		charlcd->width = 16;
-		charlcd->bwidth = 40;
-		charlcd->hwidth = 64;
+		hdc->bwidth = 40;
+		hdc->hwidth = 64;
 		charlcd->height = 2;
 		break;
 	case LCD_TYPE_CUSTOM:
@@ -974,8 +975,8 @@ static void lcd_init(void)
 		lcd.pins.rs = PIN_SELECP;
 
 		charlcd->width = 16;
-		charlcd->bwidth = 40;
-		charlcd->hwidth = 64;
+		hdc->bwidth = 40;
+		hdc->hwidth = 64;
 		charlcd->height = 2;
 		break;
 	}
@@ -986,9 +987,9 @@ static void lcd_init(void)
 	if (lcd_width != NOT_SET)
 		charlcd->width = lcd_width;
 	if (lcd_bwidth != NOT_SET)
-		charlcd->bwidth = lcd_bwidth;
+		hdc->bwidth = lcd_bwidth;
 	if (lcd_hwidth != NOT_SET)
-		charlcd->hwidth = lcd_hwidth;
+		hdc->hwidth = lcd_hwidth;
 	if (lcd_charset != NOT_SET)
 		lcd.charset = lcd_charset;
 	if (lcd_proto != NOT_SET)
@@ -1009,10 +1010,10 @@ static void lcd_init(void)
 	/* this is used to catch wrong and default values */
 	if (charlcd->width <= 0)
 		charlcd->width = DEFAULT_LCD_WIDTH;
-	if (charlcd->bwidth <= 0)
-		charlcd->bwidth = DEFAULT_LCD_BWIDTH;
-	if (charlcd->hwidth <= 0)
-		charlcd->hwidth = DEFAULT_LCD_HWIDTH;
+	if (hdc->bwidth <= 0)
+		hdc->bwidth = DEFAULT_LCD_BWIDTH;
+	if (hdc->hwidth <= 0)
+		hdc->hwidth = DEFAULT_LCD_HWIDTH;
 	if (charlcd->height <= 0)
 		charlcd->height = DEFAULT_LCD_HEIGHT;
 
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 04/32] auxdisplay: Move ifwidth to struct hd44780_common
  2020-10-05 12:27 [PATCH v4 00/32] Make charlcd device independent poeschel
                   ` (2 preceding siblings ...)
  2020-10-05 12:27 ` [PATCH v4 03/32] auxdisplay: Move hwidth and bwidth to struct hd44780_common poeschel
@ 2020-10-05 12:27 ` poeschel
  2020-10-05 12:27 ` [PATCH v4 05/32] auxdisplay: Move write_data pointer to hd44780_common poeschel
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: poeschel @ 2020-10-05 12:27 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, open list; +Cc: Lars Poeschel, Willy Tarreau

From: Lars Poeschel <poeschel@lemonage.de>

Move struct charlcd member ifwidth to our new struct hd44780_common.
ifwidth is hd44780 device specific and is used by two drivers at the
moment, so we move it to a common place, where both can use this.

Reviewed-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Lars Poeschel <poeschel@lemonage.de>
---
 drivers/auxdisplay/charlcd.c        | 12 ++++++------
 drivers/auxdisplay/charlcd.h        |  1 -
 drivers/auxdisplay/hd44780.c        |  2 +-
 drivers/auxdisplay/hd44780_common.c |  1 +
 drivers/auxdisplay/hd44780_common.h |  1 +
 5 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
index 02392336d7d3..59e0a815bf3d 100644
--- a/drivers/auxdisplay/charlcd.c
+++ b/drivers/auxdisplay/charlcd.c
@@ -223,9 +223,10 @@ static int charlcd_init_display(struct charlcd *lcd)
 {
 	void (*write_cmd_raw)(struct charlcd *lcd, int cmd);
 	struct charlcd_priv *priv = charlcd_to_priv(lcd);
+	struct hd44780_common *hdc = lcd->drvdata;
 	u8 init;
 
-	if (lcd->ifwidth != 4 && lcd->ifwidth != 8)
+	if (hdc->ifwidth != 4 && hdc->ifwidth != 8)
 		return -EINVAL;
 
 	priv->flags = ((lcd->height > 1) ? LCD_FLAG_N : 0) | LCD_FLAG_D |
@@ -238,7 +239,7 @@ static int charlcd_init_display(struct charlcd *lcd)
 	 * the LCD is in 8-bit mode afterwards
 	 */
 	init = LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS;
-	if (lcd->ifwidth == 4) {
+	if (hdc->ifwidth == 4) {
 		init >>= 4;
 		write_cmd_raw = lcd->ops->write_cmd_raw4;
 	} else {
@@ -251,7 +252,7 @@ static int charlcd_init_display(struct charlcd *lcd)
 	write_cmd_raw(lcd, init);
 	long_sleep(10);
 
-	if (lcd->ifwidth == 4) {
+	if (hdc->ifwidth == 4) {
 		/* Switch to 4-bit mode, 1 line, small fonts */
 		lcd->ops->write_cmd_raw4(lcd, LCD_CMD_FUNCTION_SET >> 4);
 		long_sleep(10);
@@ -260,7 +261,7 @@ static int charlcd_init_display(struct charlcd *lcd)
 	/* set font height and lines number */
 	lcd->ops->write_cmd(lcd,
 		LCD_CMD_FUNCTION_SET |
-		((lcd->ifwidth == 8) ? LCD_CMD_DATA_LEN_8BITS : 0) |
+		((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);
@@ -543,7 +544,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 	else if ((oldflags ^ priv->flags) & (LCD_FLAG_F | LCD_FLAG_N))
 		lcd->ops->write_cmd(lcd,
 			LCD_CMD_FUNCTION_SET |
-			((lcd->ifwidth == 8) ? LCD_CMD_DATA_LEN_8BITS : 0) |
+			((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));
 	/* check whether L flag was changed */
@@ -794,7 +795,6 @@ struct charlcd *charlcd_alloc(void)
 	priv->esc_seq.len = -1;
 
 	lcd = &priv->lcd;
-	lcd->ifwidth = 8;
 
 	return lcd;
 }
diff --git a/drivers/auxdisplay/charlcd.h b/drivers/auxdisplay/charlcd.h
index 2a12d07705a3..5dce9dd36562 100644
--- a/drivers/auxdisplay/charlcd.h
+++ b/drivers/auxdisplay/charlcd.h
@@ -18,7 +18,6 @@ struct charlcd {
 	const struct charlcd_ops *ops;
 	const unsigned char *char_conv;	/* Optional */
 
-	int ifwidth;			/* 4-bit or 8-bit (default) */
 	int height;
 	int width;
 
diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c
index 0603af8f2336..f6786239c36f 100644
--- a/drivers/auxdisplay/hd44780.c
+++ b/drivers/auxdisplay/hd44780.c
@@ -275,7 +275,7 @@ static int hd44780_probe(struct platform_device *pdev)
 	/* Optional properties */
 	device_property_read_u32(dev, "internal-buffer-width", &hdc->bwidth);
 
-	lcd->ifwidth = ifwidth;
+	hdc->ifwidth = ifwidth;
 	lcd->ops = ifwidth == 8 ? &hd44780_ops_gpio8 : &hd44780_ops_gpio4;
 
 	ret = charlcd_register(lcd);
diff --git a/drivers/auxdisplay/hd44780_common.c b/drivers/auxdisplay/hd44780_common.c
index 34e6d292fde8..285073a00302 100644
--- a/drivers/auxdisplay/hd44780_common.c
+++ b/drivers/auxdisplay/hd44780_common.c
@@ -12,6 +12,7 @@ struct hd44780_common *hd44780_common_alloc(void)
 	if (!hd)
 		return NULL;
 
+	hd->ifwidth = 8;
 	hd->bwidth = DEFAULT_LCD_BWIDTH;
 	hd->hwidth = DEFAULT_LCD_HWIDTH;
 	return hd;
diff --git a/drivers/auxdisplay/hd44780_common.h b/drivers/auxdisplay/hd44780_common.h
index 3ff47d2c5691..1100e0a32394 100644
--- a/drivers/auxdisplay/hd44780_common.h
+++ b/drivers/auxdisplay/hd44780_common.h
@@ -4,6 +4,7 @@
 #define DEFAULT_LCD_HWIDTH      64
 
 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() */
 	void *hd44780;
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 05/32] auxdisplay: Move write_data pointer to hd44780_common
  2020-10-05 12:27 [PATCH v4 00/32] Make charlcd device independent poeschel
                   ` (3 preceding siblings ...)
  2020-10-05 12:27 ` [PATCH v4 04/32] auxdisplay: Move ifwidth " poeschel
@ 2020-10-05 12:27 ` poeschel
  2020-10-05 12:27 ` [PATCH v4 06/32] auxdisplay: Move write_cmd pointers to hd44780 drivers poeschel
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: poeschel @ 2020-10-05 12:27 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, Willy Tarreau, Ksenija Stanojevic, open list
  Cc: Lars Poeschel, Willy Tarreau

From: Lars Poeschel <poeschel@lemonage.de>

This moves the write_data function pointer from struct charlcd_ops to
struct hd44780_common. This is the function that actually writes the
character to the display. This hd44780 hardware specific function is
used by two drivers at the moment.

Reviewed-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Lars Poeschel <poeschel@lemonage.de>
---
 drivers/auxdisplay/charlcd.c        | 12 ++++++------
 drivers/auxdisplay/charlcd.h        |  1 -
 drivers/auxdisplay/hd44780.c        | 16 +++++++++-------
 drivers/auxdisplay/hd44780_common.h |  1 +
 drivers/auxdisplay/panel.c          | 12 ++++++------
 5 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
index 59e0a815bf3d..df54078656c1 100644
--- a/drivers/auxdisplay/charlcd.c
+++ b/drivers/auxdisplay/charlcd.c
@@ -182,7 +182,7 @@ static void charlcd_print(struct charlcd *lcd, char c)
 	if (priv->addr.x < hdc->bwidth) {
 		if (lcd->char_conv)
 			c = lcd->char_conv[(unsigned char)c];
-		lcd->ops->write_data(lcd, c);
+		hdc->write_data(hdc, c);
 		priv->addr.x++;
 
 		/* prevents the cursor from wrapping onto the next line */
@@ -202,7 +202,7 @@ static void charlcd_clear_fast(struct charlcd *lcd)
 		lcd->ops->clear_fast(lcd);
 	else
 		for (pos = 0; pos < min(2, lcd->height) * hdc->hwidth; pos++)
-			lcd->ops->write_data(lcd, ' ');
+			hdc->write_data(hdc, ' ');
 
 	charlcd_home(lcd);
 }
@@ -446,7 +446,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 		int x;
 
 		for (x = priv->addr.x; x < hdc->bwidth; x++)
-			lcd->ops->write_data(lcd, ' ');
+			hdc->write_data(hdc, ' ');
 
 		/* restore cursor position */
 		charlcd_gotoxy(lcd);
@@ -505,7 +505,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 
 		lcd->ops->write_cmd(lcd, LCD_CMD_SET_CGRAM_ADDR | (cgaddr * 8));
 		for (addr = 0; addr < cgoffset; addr++)
-			lcd->ops->write_data(lcd, cgbytes[addr]);
+			hdc->write_data(hdc, cgbytes[addr]);
 
 		/* ensures that we stop writing to CGRAM */
 		charlcd_gotoxy(lcd);
@@ -587,7 +587,7 @@ static void charlcd_write_char(struct charlcd *lcd, char c)
 				priv->addr.x--;
 			}
 			/* replace with a space */
-			lcd->ops->write_data(lcd, ' ');
+			hdc->write_data(hdc, ' ');
 			/* back one char again */
 			lcd->ops->write_cmd(lcd, LCD_CMD_SHIFT);
 			break;
@@ -601,7 +601,7 @@ static void charlcd_write_char(struct charlcd *lcd, char c)
 			 * go to the beginning of the next line
 			 */
 			for (; priv->addr.x < hdc->bwidth; priv->addr.x++)
-				lcd->ops->write_data(lcd, ' ');
+				hdc->write_data(hdc, ' ');
 			priv->addr.x = 0;
 			priv->addr.y = (priv->addr.y + 1) % lcd->height;
 			charlcd_gotoxy(lcd);
diff --git a/drivers/auxdisplay/charlcd.h b/drivers/auxdisplay/charlcd.h
index 5dce9dd36562..fba4f2cd42c4 100644
--- a/drivers/auxdisplay/charlcd.h
+++ b/drivers/auxdisplay/charlcd.h
@@ -27,7 +27,6 @@ struct charlcd {
 struct charlcd_ops {
 	/* Required */
 	void (*write_cmd)(struct charlcd *lcd, int cmd);
-	void (*write_data)(struct charlcd *lcd, int data);
 
 	/* Optional */
 	void (*write_cmd_raw4)(struct charlcd *lcd, int cmd);	/* 4-bit only */
diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c
index f6786239c36f..922f0e0d2e6d 100644
--- a/drivers/auxdisplay/hd44780.c
+++ b/drivers/auxdisplay/hd44780.c
@@ -115,9 +115,8 @@ static void hd44780_write_cmd_gpio8(struct charlcd *lcd, int cmd)
 }
 
 /* Send data to the LCD panel in 8 bit GPIO mode */
-static void hd44780_write_data_gpio8(struct charlcd *lcd, int data)
+static void hd44780_write_data_gpio8(struct hd44780_common *hdc, int data)
 {
-	struct hd44780_common *hdc = lcd->drvdata;
 	struct hd44780 *hd = hdc->hd44780;
 
 	hd44780_write_gpio8(hd, data, 1);
@@ -128,7 +127,6 @@ static void hd44780_write_data_gpio8(struct charlcd *lcd, int data)
 
 static const struct charlcd_ops hd44780_ops_gpio8 = {
 	.write_cmd	= hd44780_write_cmd_gpio8,
-	.write_data	= hd44780_write_data_gpio8,
 	.backlight	= hd44780_backlight,
 };
 
@@ -163,9 +161,8 @@ static void hd44780_write_cmd_raw_gpio4(struct charlcd *lcd, int cmd)
 }
 
 /* Send data to the LCD panel in 4 bit GPIO mode */
-static void hd44780_write_data_gpio4(struct charlcd *lcd, int data)
+static void hd44780_write_data_gpio4(struct hd44780_common *hdc, int data)
 {
-	struct hd44780_common *hdc = lcd->drvdata;
 	struct hd44780 *hd = hdc->hd44780;
 
 	hd44780_write_gpio4(hd, data, 1);
@@ -177,7 +174,6 @@ static void hd44780_write_data_gpio4(struct charlcd *lcd, int data)
 static const struct charlcd_ops hd44780_ops_gpio4 = {
 	.write_cmd	= hd44780_write_cmd_gpio4,
 	.write_cmd_raw4	= hd44780_write_cmd_raw_gpio4,
-	.write_data	= hd44780_write_data_gpio4,
 	.backlight	= hd44780_backlight,
 };
 
@@ -276,7 +272,13 @@ static int hd44780_probe(struct platform_device *pdev)
 	device_property_read_u32(dev, "internal-buffer-width", &hdc->bwidth);
 
 	hdc->ifwidth = ifwidth;
-	lcd->ops = ifwidth == 8 ? &hd44780_ops_gpio8 : &hd44780_ops_gpio4;
+	if (ifwidth == 8) {
+		lcd->ops = &hd44780_ops_gpio8;
+		hdc->write_data = hd44780_write_data_gpio8;
+	} else {
+		lcd->ops = &hd44780_ops_gpio4;
+		hdc->write_data = hd44780_write_data_gpio4;
+	}
 
 	ret = charlcd_register(lcd);
 	if (ret)
diff --git a/drivers/auxdisplay/hd44780_common.h b/drivers/auxdisplay/hd44780_common.h
index 1100e0a32394..1d686c99b2c1 100644
--- a/drivers/auxdisplay/hd44780_common.h
+++ b/drivers/auxdisplay/hd44780_common.h
@@ -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() */
+	void (*write_data)(struct hd44780_common *hdc, int data);
 	void *hd44780;
 };
 
diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c
index cec6b729d668..15100d21a6e9 100644
--- a/drivers/auxdisplay/panel.c
+++ b/drivers/auxdisplay/panel.c
@@ -734,7 +734,7 @@ static void lcd_write_cmd_s(struct charlcd *charlcd, int cmd)
 }
 
 /* send data to the LCD panel in serial mode */
-static void lcd_write_data_s(struct charlcd *charlcd, int data)
+static void lcd_write_data_s(struct hd44780_common *hdc, int data)
 {
 	spin_lock_irq(&pprt_lock);
 	lcd_send_serial(0x5F);	/* R/W=W, RS=1 */
@@ -767,7 +767,7 @@ static void lcd_write_cmd_p8(struct charlcd *charlcd, int cmd)
 }
 
 /* send data to the LCD panel in 8 bits parallel mode */
-static void lcd_write_data_p8(struct charlcd *charlcd, int data)
+static void lcd_write_data_p8(struct hd44780_common *hdc, int data)
 {
 	spin_lock_irq(&pprt_lock);
 	/* present the data to the data port */
@@ -799,7 +799,7 @@ static void lcd_write_cmd_tilcd(struct charlcd *charlcd, int cmd)
 }
 
 /* send data to the TI LCD panel */
-static void lcd_write_data_tilcd(struct charlcd *charlcd, int data)
+static void lcd_write_data_tilcd(struct hd44780_common *hdc, int data)
 {
 	spin_lock_irq(&pprt_lock);
 	/* present the data to the data port */
@@ -874,21 +874,18 @@ static void lcd_clear_fast_tilcd(struct charlcd *charlcd)
 
 static const struct charlcd_ops charlcd_serial_ops = {
 	.write_cmd	= lcd_write_cmd_s,
-	.write_data	= lcd_write_data_s,
 	.clear_fast	= lcd_clear_fast_s,
 	.backlight	= lcd_backlight,
 };
 
 static const struct charlcd_ops charlcd_parallel_ops = {
 	.write_cmd	= lcd_write_cmd_p8,
-	.write_data	= lcd_write_data_p8,
 	.clear_fast	= lcd_clear_fast_p8,
 	.backlight	= lcd_backlight,
 };
 
 static const struct charlcd_ops charlcd_tilcd_ops = {
 	.write_cmd	= lcd_write_cmd_tilcd,
-	.write_data	= lcd_write_data_tilcd,
 	.clear_fast	= lcd_clear_fast_tilcd,
 	.backlight	= lcd_backlight,
 };
@@ -1019,6 +1016,7 @@ static void lcd_init(void)
 
 	if (lcd.proto == LCD_PROTO_SERIAL) {	/* SERIAL */
 		charlcd->ops = &charlcd_serial_ops;
+		hdc->write_data = lcd_write_data_s;
 
 		if (lcd.pins.cl == PIN_NOT_SET)
 			lcd.pins.cl = DEFAULT_LCD_PIN_SCL;
@@ -1027,6 +1025,7 @@ static void lcd_init(void)
 
 	} else if (lcd.proto == LCD_PROTO_PARALLEL) {	/* PARALLEL */
 		charlcd->ops = &charlcd_parallel_ops;
+		hdc->write_data = lcd_write_data_p8;
 
 		if (lcd.pins.e == PIN_NOT_SET)
 			lcd.pins.e = DEFAULT_LCD_PIN_E;
@@ -1036,6 +1035,7 @@ static void lcd_init(void)
 			lcd.pins.rw = DEFAULT_LCD_PIN_RW;
 	} else {
 		charlcd->ops = &charlcd_tilcd_ops;
+		hdc->write_data = lcd_write_data_tilcd;
 	}
 
 	if (lcd.pins.bl == PIN_NOT_SET)
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 06/32] auxdisplay: Move write_cmd pointers to hd44780 drivers
  2020-10-05 12:27 [PATCH v4 00/32] Make charlcd device independent poeschel
                   ` (4 preceding siblings ...)
  2020-10-05 12:27 ` [PATCH v4 05/32] auxdisplay: Move write_data pointer to hd44780_common poeschel
@ 2020-10-05 12:27 ` poeschel
  2020-10-05 12:27 ` [PATCH v4 07/32] auxdisplay: Move addr out of charlcd_priv poeschel
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: poeschel @ 2020-10-05 12:27 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, Willy Tarreau, Ksenija Stanojevic, open list
  Cc: Lars Poeschel, Willy Tarreau

From: Lars Poeschel <poeschel@lemonage.de>

The write_cmd function is used to send commands to hd44780 displays.
The individual hd44780 drivers then implement their appropriate way of
doing this with their supported displays. So we move this pointer so
hd44780_common.

Reviewed-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Lars Poeschel <poeschel@lemonage.de>
---
 drivers/auxdisplay/charlcd.c        | 45 +++++++++++++++--------------
 drivers/auxdisplay/charlcd.h        |  5 ----
 drivers/auxdisplay/hd44780.c        | 15 ++++------
 drivers/auxdisplay/hd44780_common.h |  3 ++
 drivers/auxdisplay/panel.c          | 12 ++++----
 5 files changed, 38 insertions(+), 42 deletions(-)

diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
index df54078656c1..ce6622f71c34 100644
--- a/drivers/auxdisplay/charlcd.c
+++ b/drivers/auxdisplay/charlcd.c
@@ -162,7 +162,7 @@ static void charlcd_gotoxy(struct charlcd *lcd)
 		addr += hdc->hwidth;
 	if (priv->addr.y & 2)
 		addr += hdc->bwidth;
-	lcd->ops->write_cmd(lcd, LCD_CMD_SET_DDRAM_ADDR | addr);
+	hdc->write_cmd(hdc, LCD_CMD_SET_DDRAM_ADDR | addr);
 }
 
 static void charlcd_home(struct charlcd *lcd)
@@ -211,8 +211,9 @@ static void charlcd_clear_fast(struct charlcd *lcd)
 static void charlcd_clear_display(struct charlcd *lcd)
 {
 	struct charlcd_priv *priv = charlcd_to_priv(lcd);
+	struct hd44780_common *hdc = lcd->drvdata;
 
-	lcd->ops->write_cmd(lcd, LCD_CMD_DISPLAY_CLEAR);
+	hdc->write_cmd(hdc, LCD_CMD_DISPLAY_CLEAR);
 	priv->addr.x = 0;
 	priv->addr.y = 0;
 	/* we must wait a few milliseconds (15) */
@@ -221,7 +222,7 @@ static void charlcd_clear_display(struct charlcd *lcd)
 
 static int charlcd_init_display(struct charlcd *lcd)
 {
-	void (*write_cmd_raw)(struct charlcd *lcd, int cmd);
+	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;
@@ -241,25 +242,25 @@ static int charlcd_init_display(struct charlcd *lcd)
 	init = LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS;
 	if (hdc->ifwidth == 4) {
 		init >>= 4;
-		write_cmd_raw = lcd->ops->write_cmd_raw4;
+		write_cmd_raw = hdc->write_cmd_raw4;
 	} else {
-		write_cmd_raw = lcd->ops->write_cmd;
+		write_cmd_raw = hdc->write_cmd;
 	}
-	write_cmd_raw(lcd, init);
+	write_cmd_raw(hdc, init);
 	long_sleep(10);
-	write_cmd_raw(lcd, init);
+	write_cmd_raw(hdc, init);
 	long_sleep(10);
-	write_cmd_raw(lcd, init);
+	write_cmd_raw(hdc, init);
 	long_sleep(10);
 
 	if (hdc->ifwidth == 4) {
 		/* Switch to 4-bit mode, 1 line, small fonts */
-		lcd->ops->write_cmd_raw4(lcd, LCD_CMD_FUNCTION_SET >> 4);
+		hdc->write_cmd_raw4(hdc, LCD_CMD_FUNCTION_SET >> 4);
 		long_sleep(10);
 	}
 
 	/* set font height and lines number */
-	lcd->ops->write_cmd(lcd,
+	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) |
@@ -267,10 +268,10 @@ static int charlcd_init_display(struct charlcd *lcd)
 	long_sleep(10);
 
 	/* display off, cursor off, blink off */
-	lcd->ops->write_cmd(lcd, LCD_CMD_DISPLAY_CTRL);
+	hdc->write_cmd(hdc, LCD_CMD_DISPLAY_CTRL);
 	long_sleep(10);
 
-	lcd->ops->write_cmd(lcd,
+	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) |
@@ -281,7 +282,7 @@ static int charlcd_init_display(struct charlcd *lcd)
 	long_sleep(10);
 
 	/* entry mode set : increment, cursor shifting */
-	lcd->ops->write_cmd(lcd, LCD_CMD_ENTRY_MODE | LCD_CMD_CURSOR_INC);
+	hdc->write_cmd(hdc, LCD_CMD_ENTRY_MODE | LCD_CMD_CURSOR_INC);
 
 	charlcd_clear_display(lcd);
 	return 0;
@@ -417,7 +418,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 		if (priv->addr.x > 0) {
 			/* back one char if not at end of line */
 			if (priv->addr.x < hdc->bwidth)
-				lcd->ops->write_cmd(lcd, LCD_CMD_SHIFT);
+				hdc->write_cmd(hdc, LCD_CMD_SHIFT);
 			priv->addr.x--;
 		}
 		processed = 1;
@@ -426,18 +427,18 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 		if (priv->addr.x < lcd->width) {
 			/* allow the cursor to pass the end of the line */
 			if (priv->addr.x < (hdc->bwidth - 1))
-				lcd->ops->write_cmd(lcd,
+				hdc->write_cmd(hdc,
 					LCD_CMD_SHIFT | LCD_CMD_SHIFT_RIGHT);
 			priv->addr.x++;
 		}
 		processed = 1;
 		break;
 	case 'L':	/* shift display left */
-		lcd->ops->write_cmd(lcd, LCD_CMD_SHIFT | LCD_CMD_DISPLAY_SHIFT);
+		hdc->write_cmd(hdc, LCD_CMD_SHIFT | LCD_CMD_DISPLAY_SHIFT);
 		processed = 1;
 		break;
 	case 'R':	/* shift display right */
-		lcd->ops->write_cmd(lcd,
+		hdc->write_cmd(hdc,
 				    LCD_CMD_SHIFT | LCD_CMD_DISPLAY_SHIFT |
 				    LCD_CMD_SHIFT_RIGHT);
 		processed = 1;
@@ -503,7 +504,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 			}
 		}
 
-		lcd->ops->write_cmd(lcd, LCD_CMD_SET_CGRAM_ADDR | (cgaddr * 8));
+		hdc->write_cmd(hdc, LCD_CMD_SET_CGRAM_ADDR | (cgaddr * 8));
 		for (addr = 0; addr < cgoffset; addr++)
 			hdc->write_data(hdc, cgbytes[addr]);
 
@@ -535,14 +536,14 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 	if ((oldflags ^ priv->flags) &
 	    (LCD_FLAG_B | LCD_FLAG_C | LCD_FLAG_D))
 		/* set display mode */
-		lcd->ops->write_cmd(lcd,
+		hdc->write_cmd(hdc,
 			LCD_CMD_DISPLAY_CTRL |
 			((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));
 	/* check whether one of F,N flags was changed */
 	else if ((oldflags ^ priv->flags) & (LCD_FLAG_F | LCD_FLAG_N))
-		lcd->ops->write_cmd(lcd,
+		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) |
@@ -583,13 +584,13 @@ static void charlcd_write_char(struct charlcd *lcd, char c)
 				 */
 				if (priv->addr.x < hdc->bwidth)
 					/* back one char */
-					lcd->ops->write_cmd(lcd, LCD_CMD_SHIFT);
+					hdc->write_cmd(hdc, LCD_CMD_SHIFT);
 				priv->addr.x--;
 			}
 			/* replace with a space */
 			hdc->write_data(hdc, ' ');
 			/* back one char again */
-			lcd->ops->write_cmd(lcd, LCD_CMD_SHIFT);
+			hdc->write_cmd(hdc, LCD_CMD_SHIFT);
 			break;
 		case '\f':
 			/* quickly clear the display */
diff --git a/drivers/auxdisplay/charlcd.h b/drivers/auxdisplay/charlcd.h
index fba4f2cd42c4..ad6fd2733523 100644
--- a/drivers/auxdisplay/charlcd.h
+++ b/drivers/auxdisplay/charlcd.h
@@ -25,11 +25,6 @@ struct charlcd {
 };
 
 struct charlcd_ops {
-	/* Required */
-	void (*write_cmd)(struct charlcd *lcd, int cmd);
-
-	/* Optional */
-	void (*write_cmd_raw4)(struct charlcd *lcd, int cmd);	/* 4-bit only */
 	void (*clear_fast)(struct charlcd *lcd);
 	void (*backlight)(struct charlcd *lcd, enum charlcd_onoff on);
 };
diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c
index 922f0e0d2e6d..dc4738563298 100644
--- a/drivers/auxdisplay/hd44780.c
+++ b/drivers/auxdisplay/hd44780.c
@@ -103,9 +103,8 @@ static void hd44780_write_gpio4(struct hd44780 *hd, u8 val, unsigned int rs)
 }
 
 /* Send a command to the LCD panel in 8 bit GPIO mode */
-static void hd44780_write_cmd_gpio8(struct charlcd *lcd, int cmd)
+static void hd44780_write_cmd_gpio8(struct hd44780_common *hdc, int cmd)
 {
-	struct hd44780_common *hdc = lcd->drvdata;
 	struct hd44780 *hd = hdc->hd44780;
 
 	hd44780_write_gpio8(hd, cmd, 0);
@@ -126,14 +125,12 @@ static void hd44780_write_data_gpio8(struct hd44780_common *hdc, int data)
 }
 
 static const struct charlcd_ops hd44780_ops_gpio8 = {
-	.write_cmd	= hd44780_write_cmd_gpio8,
 	.backlight	= hd44780_backlight,
 };
 
 /* Send a command to the LCD panel in 4 bit GPIO mode */
-static void hd44780_write_cmd_gpio4(struct charlcd *lcd, int cmd)
+static void hd44780_write_cmd_gpio4(struct hd44780_common *hdc, int cmd)
 {
-	struct hd44780_common *hdc = lcd->drvdata;
 	struct hd44780 *hd = hdc->hd44780;
 
 	hd44780_write_gpio4(hd, cmd, 0);
@@ -143,10 +140,9 @@ static void hd44780_write_cmd_gpio4(struct charlcd *lcd, int cmd)
 }
 
 /* Send 4-bits of a command to the LCD panel in raw 4 bit GPIO mode */
-static void hd44780_write_cmd_raw_gpio4(struct charlcd *lcd, int cmd)
+static void hd44780_write_cmd_raw_gpio4(struct hd44780_common *hdc, int cmd)
 {
 	DECLARE_BITMAP(values, 6); /* for DATA[4-7], RS, RW */
-	struct hd44780_common *hdc = lcd->drvdata;
 	struct hd44780 *hd = hdc->hd44780;
 	unsigned int n;
 
@@ -172,8 +168,6 @@ static void hd44780_write_data_gpio4(struct hd44780_common *hdc, int data)
 }
 
 static const struct charlcd_ops hd44780_ops_gpio4 = {
-	.write_cmd	= hd44780_write_cmd_gpio4,
-	.write_cmd_raw4	= hd44780_write_cmd_raw_gpio4,
 	.backlight	= hd44780_backlight,
 };
 
@@ -275,9 +269,12 @@ static int hd44780_probe(struct platform_device *pdev)
 	if (ifwidth == 8) {
 		lcd->ops = &hd44780_ops_gpio8;
 		hdc->write_data = hd44780_write_data_gpio8;
+		hdc->write_cmd = hd44780_write_cmd_gpio8;
 	} else {
 		lcd->ops = &hd44780_ops_gpio4;
 		hdc->write_data = hd44780_write_data_gpio4;
+		hdc->write_cmd = hd44780_write_cmd_gpio4;
+		hdc->write_cmd_raw4 = hd44780_write_cmd_raw_gpio4;
 	}
 
 	ret = charlcd_register(lcd);
diff --git a/drivers/auxdisplay/hd44780_common.h b/drivers/auxdisplay/hd44780_common.h
index 1d686c99b2c1..6c38ddf8f2ce 100644
--- a/drivers/auxdisplay/hd44780_common.h
+++ b/drivers/auxdisplay/hd44780_common.h
@@ -8,6 +8,9 @@ struct hd44780_common {
 	int bwidth;			/* Default set by hd44780_alloc() */
 	int hwidth;			/* Default set by hd44780_alloc() */
 	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 */
+	void (*write_cmd_raw4)(struct hd44780_common *hdc, int cmd);
 	void *hd44780;
 };
 
diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c
index 15100d21a6e9..7ef9bc7188ca 100644
--- a/drivers/auxdisplay/panel.c
+++ b/drivers/auxdisplay/panel.c
@@ -723,7 +723,7 @@ static void lcd_backlight(struct charlcd *charlcd, enum charlcd_onoff on)
 }
 
 /* send a command to the LCD panel in serial mode */
-static void lcd_write_cmd_s(struct charlcd *charlcd, int cmd)
+static void lcd_write_cmd_s(struct hd44780_common *hdc, int cmd)
 {
 	spin_lock_irq(&pprt_lock);
 	lcd_send_serial(0x1F);	/* R/W=W, RS=0 */
@@ -745,7 +745,7 @@ static void lcd_write_data_s(struct hd44780_common *hdc, int data)
 }
 
 /* send a command to the LCD panel in 8 bits parallel mode */
-static void lcd_write_cmd_p8(struct charlcd *charlcd, int cmd)
+static void lcd_write_cmd_p8(struct hd44780_common *hdc, int cmd)
 {
 	spin_lock_irq(&pprt_lock);
 	/* present the data to the data port */
@@ -789,7 +789,7 @@ static void lcd_write_data_p8(struct hd44780_common *hdc, int data)
 }
 
 /* send a command to the TI LCD panel */
-static void lcd_write_cmd_tilcd(struct charlcd *charlcd, int cmd)
+static void lcd_write_cmd_tilcd(struct hd44780_common *hdc, int cmd)
 {
 	spin_lock_irq(&pprt_lock);
 	/* present the data to the control port */
@@ -873,19 +873,16 @@ static void lcd_clear_fast_tilcd(struct charlcd *charlcd)
 }
 
 static const struct charlcd_ops charlcd_serial_ops = {
-	.write_cmd	= lcd_write_cmd_s,
 	.clear_fast	= lcd_clear_fast_s,
 	.backlight	= lcd_backlight,
 };
 
 static const struct charlcd_ops charlcd_parallel_ops = {
-	.write_cmd	= lcd_write_cmd_p8,
 	.clear_fast	= lcd_clear_fast_p8,
 	.backlight	= lcd_backlight,
 };
 
 static const struct charlcd_ops charlcd_tilcd_ops = {
-	.write_cmd	= lcd_write_cmd_tilcd,
 	.clear_fast	= lcd_clear_fast_tilcd,
 	.backlight	= lcd_backlight,
 };
@@ -1017,6 +1014,7 @@ static void lcd_init(void)
 	if (lcd.proto == LCD_PROTO_SERIAL) {	/* SERIAL */
 		charlcd->ops = &charlcd_serial_ops;
 		hdc->write_data = lcd_write_data_s;
+		hdc->write_cmd = lcd_write_cmd_s;
 
 		if (lcd.pins.cl == PIN_NOT_SET)
 			lcd.pins.cl = DEFAULT_LCD_PIN_SCL;
@@ -1026,6 +1024,7 @@ static void lcd_init(void)
 	} else if (lcd.proto == LCD_PROTO_PARALLEL) {	/* PARALLEL */
 		charlcd->ops = &charlcd_parallel_ops;
 		hdc->write_data = lcd_write_data_p8;
+		hdc->write_cmd = lcd_write_cmd_p8;
 
 		if (lcd.pins.e == PIN_NOT_SET)
 			lcd.pins.e = DEFAULT_LCD_PIN_E;
@@ -1036,6 +1035,7 @@ static void lcd_init(void)
 	} else {
 		charlcd->ops = &charlcd_tilcd_ops;
 		hdc->write_data = lcd_write_data_tilcd;
+		hdc->write_cmd = lcd_write_cmd_tilcd;
 	}
 
 	if (lcd.pins.bl == PIN_NOT_SET)
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 07/32] auxdisplay: Move addr out of charlcd_priv
  2020-10-05 12:27 [PATCH v4 00/32] Make charlcd device independent poeschel
                   ` (5 preceding siblings ...)
  2020-10-05 12:27 ` [PATCH v4 06/32] auxdisplay: Move write_cmd pointers to hd44780 drivers poeschel
@ 2020-10-05 12:27 ` poeschel
  2020-10-05 12:27 ` [PATCH v4 08/32] auxdisplay: hd44780_common_print poeschel
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: poeschel @ 2020-10-05 12:27 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, open list; +Cc: Lars Poeschel, Willy Tarreau

From: Lars Poeschel <poeschel@lemonage.de>

Move out the struct addr from struct charlcd_priv into the less private
struct charlcd. This member is used to pass position information. The
individual drivers need to be able to read this information, so we move
this out of charlcd_priv to charlcd structure.

Reviewed-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Lars Poeschel <poeschel@lemonage.de>
---
 drivers/auxdisplay/charlcd.c | 61 +++++++++++++++---------------------
 drivers/auxdisplay/charlcd.h |  6 ++++
 2 files changed, 31 insertions(+), 36 deletions(-)

diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
index ce6622f71c34..1b37d4bc38f9 100644
--- a/drivers/auxdisplay/charlcd.c
+++ b/drivers/auxdisplay/charlcd.c
@@ -72,12 +72,6 @@ struct charlcd_priv {
 	/* contains the LCD config state */
 	unsigned long int flags;
 
-	/* Contains the LCD X and Y offset */
-	struct {
-		unsigned long int x;
-		unsigned long int y;
-	} addr;
-
 	/* Current escape sequence and it's length or -1 if outside */
 	struct {
 		char buf[LCD_ESCAPE_LEN + 1];
@@ -148,7 +142,6 @@ EXPORT_SYMBOL_GPL(charlcd_poke);
 
 static void charlcd_gotoxy(struct charlcd *lcd)
 {
-	struct charlcd_priv *priv = charlcd_to_priv(lcd);
 	struct hd44780_common *hdc = lcd->drvdata;
 	unsigned int addr;
 
@@ -156,37 +149,34 @@ static void charlcd_gotoxy(struct charlcd *lcd)
 	 * we force the cursor to stay at the end of the
 	 * line if it wants to go farther
 	 */
-	addr = priv->addr.x < hdc->bwidth ? priv->addr.x & (hdc->hwidth - 1)
+	addr = lcd->addr.x < hdc->bwidth ? lcd->addr.x & (hdc->hwidth - 1)
 					  : hdc->bwidth - 1;
-	if (priv->addr.y & 1)
+	if (lcd->addr.y & 1)
 		addr += hdc->hwidth;
-	if (priv->addr.y & 2)
+	if (lcd->addr.y & 2)
 		addr += hdc->bwidth;
 	hdc->write_cmd(hdc, LCD_CMD_SET_DDRAM_ADDR | addr);
 }
 
 static void charlcd_home(struct charlcd *lcd)
 {
-	struct charlcd_priv *priv = charlcd_to_priv(lcd);
-
-	priv->addr.x = 0;
-	priv->addr.y = 0;
+	lcd->addr.x = 0;
+	lcd->addr.y = 0;
 	charlcd_gotoxy(lcd);
 }
 
 static void charlcd_print(struct charlcd *lcd, char c)
 {
-	struct charlcd_priv *priv = charlcd_to_priv(lcd);
 	struct hd44780_common *hdc = lcd->drvdata;
 
-	if (priv->addr.x < hdc->bwidth) {
+	if (lcd->addr.x < hdc->bwidth) {
 		if (lcd->char_conv)
 			c = lcd->char_conv[(unsigned char)c];
 		hdc->write_data(hdc, c);
-		priv->addr.x++;
+		lcd->addr.x++;
 
 		/* prevents the cursor from wrapping onto the next line */
-		if (priv->addr.x == hdc->bwidth)
+		if (lcd->addr.x == hdc->bwidth)
 			charlcd_gotoxy(lcd);
 	}
 }
@@ -210,12 +200,11 @@ static void charlcd_clear_fast(struct charlcd *lcd)
 /* clears the display and resets X/Y */
 static void charlcd_clear_display(struct charlcd *lcd)
 {
-	struct charlcd_priv *priv = charlcd_to_priv(lcd);
 	struct hd44780_common *hdc = lcd->drvdata;
 
 	hdc->write_cmd(hdc, LCD_CMD_DISPLAY_CLEAR);
-	priv->addr.x = 0;
-	priv->addr.y = 0;
+	lcd->addr.x = 0;
+	lcd->addr.y = 0;
 	/* we must wait a few milliseconds (15) */
 	long_sleep(15);
 }
@@ -415,21 +404,21 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 		processed = 1;
 		break;
 	case 'l':	/* Shift Cursor Left */
-		if (priv->addr.x > 0) {
+		if (lcd->addr.x > 0) {
 			/* back one char if not at end of line */
-			if (priv->addr.x < hdc->bwidth)
+			if (lcd->addr.x < hdc->bwidth)
 				hdc->write_cmd(hdc, LCD_CMD_SHIFT);
-			priv->addr.x--;
+			lcd->addr.x--;
 		}
 		processed = 1;
 		break;
 	case 'r':	/* shift cursor right */
-		if (priv->addr.x < lcd->width) {
+		if (lcd->addr.x < lcd->width) {
 			/* allow the cursor to pass the end of the line */
-			if (priv->addr.x < (hdc->bwidth - 1))
+			if (lcd->addr.x < (hdc->bwidth - 1))
 				hdc->write_cmd(hdc,
 					LCD_CMD_SHIFT | LCD_CMD_SHIFT_RIGHT);
-			priv->addr.x++;
+			lcd->addr.x++;
 		}
 		processed = 1;
 		break;
@@ -446,7 +435,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 	case 'k': {	/* kill end of line */
 		int x;
 
-		for (x = priv->addr.x; x < hdc->bwidth; x++)
+		for (x = lcd->addr.x; x < hdc->bwidth; x++)
 			hdc->write_data(hdc, ' ');
 
 		/* restore cursor position */
@@ -519,7 +508,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 			break;
 
 		/* If the command is valid, move to the new address */
-		if (parse_xy(esc, &priv->addr.x, &priv->addr.y))
+		if (parse_xy(esc, &lcd->addr.x, &lcd->addr.y))
 			charlcd_gotoxy(lcd);
 
 		/* Regardless of its validity, mark as processed */
@@ -577,15 +566,15 @@ static void charlcd_write_char(struct charlcd *lcd, char c)
 			break;
 		case '\b':
 			/* go back one char and clear it */
-			if (priv->addr.x > 0) {
+			if (lcd->addr.x > 0) {
 				/*
 				 * check if we're not at the
 				 * end of the line
 				 */
-				if (priv->addr.x < hdc->bwidth)
+				if (lcd->addr.x < hdc->bwidth)
 					/* back one char */
 					hdc->write_cmd(hdc, LCD_CMD_SHIFT);
-				priv->addr.x--;
+				lcd->addr.x--;
 			}
 			/* replace with a space */
 			hdc->write_data(hdc, ' ');
@@ -601,15 +590,15 @@ static void charlcd_write_char(struct charlcd *lcd, char c)
 			 * flush the remainder of the current line and
 			 * go to the beginning of the next line
 			 */
-			for (; priv->addr.x < hdc->bwidth; priv->addr.x++)
+			for (; lcd->addr.x < hdc->bwidth; lcd->addr.x++)
 				hdc->write_data(hdc, ' ');
-			priv->addr.x = 0;
-			priv->addr.y = (priv->addr.y + 1) % lcd->height;
+			lcd->addr.x = 0;
+			lcd->addr.y = (lcd->addr.y + 1) % lcd->height;
 			charlcd_gotoxy(lcd);
 			break;
 		case '\r':
 			/* go to the beginning of the same line */
-			priv->addr.x = 0;
+			lcd->addr.x = 0;
 			charlcd_gotoxy(lcd);
 			break;
 		case '\t':
diff --git a/drivers/auxdisplay/charlcd.h b/drivers/auxdisplay/charlcd.h
index ad6fd2733523..ff4896af2189 100644
--- a/drivers/auxdisplay/charlcd.h
+++ b/drivers/auxdisplay/charlcd.h
@@ -21,6 +21,12 @@ struct charlcd {
 	int height;
 	int width;
 
+	/* Contains the LCD X and Y offset */
+	struct {
+		unsigned long x;
+		unsigned long y;
+	} addr;
+
 	void *drvdata;
 };
 
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 08/32] auxdisplay: hd44780_common_print
  2020-10-05 12:27 [PATCH v4 00/32] Make charlcd device independent poeschel
                   ` (6 preceding siblings ...)
  2020-10-05 12:27 ` [PATCH v4 07/32] auxdisplay: Move addr out of charlcd_priv poeschel
@ 2020-10-05 12:27 ` poeschel
  2020-10-16  3:54   ` Miguel Ojeda
  2020-10-05 12:27 ` [PATCH v4 09/32] auxdisplay: provide hd44780_common_gotoxy poeschel
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 21+ messages in thread
From: poeschel @ 2020-10-05 12:27 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, open list
  Cc: Lars Poeschel, kernel test robot, Willy Tarreau

From: Lars Poeschel <poeschel@lemonage.de>

We create a hd44780_common_print function. It is derived from the
original charlcd_print. charlcd_print becomes a device independent print
function, that then only calles via it's ops function pointers, into the
print function offered by drivers.

Reported-by: kernel test robot <lkp@intel.com>
Reviewed-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Lars Poeschel <poeschel@lemonage.de>
---
Changes in v3:
- Fix kernel test robot reported error: Missed EXPORT_SYMBOL_GPL
---
 drivers/auxdisplay/charlcd.c        | 28 +++++++++++++++-------------
 drivers/auxdisplay/charlcd.h        | 11 +++++++++++
 drivers/auxdisplay/hd44780.c        |  2 ++
 drivers/auxdisplay/hd44780_common.c | 14 ++++++++++++++
 drivers/auxdisplay/hd44780_common.h |  1 +
 5 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
index 1b37d4bc38f9..72ed004a8980 100644
--- a/drivers/auxdisplay/charlcd.c
+++ b/drivers/auxdisplay/charlcd.c
@@ -167,18 +167,15 @@ static void charlcd_home(struct charlcd *lcd)
 
 static void charlcd_print(struct charlcd *lcd, char c)
 {
-	struct hd44780_common *hdc = lcd->drvdata;
+	if (lcd->char_conv)
+		c = lcd->char_conv[(unsigned char)c];
 
-	if (lcd->addr.x < hdc->bwidth) {
-		if (lcd->char_conv)
-			c = lcd->char_conv[(unsigned char)c];
-		hdc->write_data(hdc, c);
+	if (!lcd->ops->print(lcd, c))
 		lcd->addr.x++;
 
-		/* prevents the cursor from wrapping onto the next line */
-		if (lcd->addr.x == hdc->bwidth)
-			charlcd_gotoxy(lcd);
-	}
+	/* prevents the cursor from wrapping onto the next line */
+	if (lcd->addr.x == lcd->width)
+		charlcd_gotoxy(lcd);
 }
 
 static void charlcd_clear_fast(struct charlcd *lcd)
@@ -192,7 +189,7 @@ static void charlcd_clear_fast(struct charlcd *lcd)
 		lcd->ops->clear_fast(lcd);
 	else
 		for (pos = 0; pos < min(2, lcd->height) * hdc->hwidth; pos++)
-			hdc->write_data(hdc, ' ');
+			lcd->ops->print(lcd, ' ');
 
 	charlcd_home(lcd);
 }
@@ -433,12 +430,16 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 		processed = 1;
 		break;
 	case 'k': {	/* kill end of line */
-		int x;
+		int x, xs, ys;
 
+		xs = lcd->addr.x;
+		ys = lcd->addr.y;
 		for (x = lcd->addr.x; x < hdc->bwidth; x++)
-			hdc->write_data(hdc, ' ');
+			lcd->ops->print(lcd, ' ');
 
 		/* restore cursor position */
+		lcd->addr.x = xs;
+		lcd->addr.y = ys;
 		charlcd_gotoxy(lcd);
 		processed = 1;
 		break;
@@ -591,7 +592,8 @@ static void charlcd_write_char(struct charlcd *lcd, char c)
 			 * go to the beginning of the next line
 			 */
 			for (; lcd->addr.x < hdc->bwidth; lcd->addr.x++)
-				hdc->write_data(hdc, ' ');
+				lcd->ops->print(lcd, ' ');
+
 			lcd->addr.x = 0;
 			lcd->addr.y = (lcd->addr.y + 1) % lcd->height;
 			charlcd_gotoxy(lcd);
diff --git a/drivers/auxdisplay/charlcd.h b/drivers/auxdisplay/charlcd.h
index ff4896af2189..874519f079b4 100644
--- a/drivers/auxdisplay/charlcd.h
+++ b/drivers/auxdisplay/charlcd.h
@@ -30,9 +30,20 @@ struct charlcd {
 	void *drvdata;
 };
 
+/**
+ * struct charlcd_ops - Functions used by charlcd. Drivers have to implement
+ * these.
+ * @clear_fast: Clear the whole display and set cursor to position 0, 0.
+ * @backlight: Turn backlight on or off. Optional.
+ * @print: just Print one character to the display at current cursor position.
+ * The cursor is advanced by charlcd.
+ * The buffered cursor position is advanced by charlcd. The cursor should not
+ * wrap to the next line at the end of a line.
+ */
 struct charlcd_ops {
 	void (*clear_fast)(struct charlcd *lcd);
 	void (*backlight)(struct charlcd *lcd, enum charlcd_onoff on);
+	int (*print)(struct charlcd *lcd, int c);
 };
 
 struct charlcd *charlcd_alloc(void);
diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c
index dc4738563298..9680bb611639 100644
--- a/drivers/auxdisplay/hd44780.c
+++ b/drivers/auxdisplay/hd44780.c
@@ -126,6 +126,7 @@ static void hd44780_write_data_gpio8(struct hd44780_common *hdc, int data)
 
 static const struct charlcd_ops hd44780_ops_gpio8 = {
 	.backlight	= hd44780_backlight,
+	.print		= hd44780_common_print,
 };
 
 /* Send a command to the LCD panel in 4 bit GPIO mode */
@@ -169,6 +170,7 @@ static void hd44780_write_data_gpio4(struct hd44780_common *hdc, int data)
 
 static const struct charlcd_ops hd44780_ops_gpio4 = {
 	.backlight	= hd44780_backlight,
+	.print		= hd44780_common_print,
 };
 
 static int hd44780_probe(struct platform_device *pdev)
diff --git a/drivers/auxdisplay/hd44780_common.c b/drivers/auxdisplay/hd44780_common.c
index 285073a00302..c03dd7cd56c0 100644
--- a/drivers/auxdisplay/hd44780_common.c
+++ b/drivers/auxdisplay/hd44780_common.c
@@ -2,8 +2,22 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 
+#include "charlcd.h"
 #include "hd44780_common.h"
 
+int hd44780_common_print(struct charlcd *lcd, int c)
+{
+	struct hd44780_common *hdc = lcd->drvdata;
+
+	if (lcd->addr.x < hdc->bwidth) {
+		hdc->write_data(hdc, c);
+		return 0;
+	}
+
+	return 1;
+}
+EXPORT_SYMBOL_GPL(hd44780_common_print);
+
 struct hd44780_common *hd44780_common_alloc(void)
 {
 	struct hd44780_common *hd;
diff --git a/drivers/auxdisplay/hd44780_common.h b/drivers/auxdisplay/hd44780_common.h
index 6c38ddf8f2ce..02d650903e35 100644
--- a/drivers/auxdisplay/hd44780_common.h
+++ b/drivers/auxdisplay/hd44780_common.h
@@ -14,5 +14,6 @@ struct hd44780_common {
 	void *hd44780;
 };
 
+int hd44780_common_print(struct charlcd *lcd, int c);
 struct hd44780_common *hd44780_common_alloc(void);
 
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 09/32] auxdisplay: provide hd44780_common_gotoxy
  2020-10-05 12:27 [PATCH v4 00/32] Make charlcd device independent poeschel
                   ` (7 preceding siblings ...)
  2020-10-05 12:27 ` [PATCH v4 08/32] auxdisplay: hd44780_common_print poeschel
@ 2020-10-05 12:27 ` poeschel
  2020-10-05 12:27 ` [PATCH v4 10/32] auxdisplay: add home to charlcd_ops poeschel
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: poeschel @ 2020-10-05 12:27 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, Willy Tarreau, Ksenija Stanojevic, open list
  Cc: Lars Poeschel, Willy Tarreau

From: Lars Poeschel <poeschel@lemonage.de>

Provide a hd44780_common_gotoxy function and a pointer in the ops for
charlcd to use to move the cursor.

Reviewed-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Lars Poeschel <poeschel@lemonage.de>
---
 drivers/auxdisplay/charlcd.c        | 38 +++++++++--------------------
 drivers/auxdisplay/charlcd.h        |  4 ++-
 drivers/auxdisplay/hd44780.c        |  2 ++
 drivers/auxdisplay/hd44780_common.c | 23 +++++++++++++++++
 drivers/auxdisplay/hd44780_common.h |  1 +
 drivers/auxdisplay/panel.c          |  3 +++
 6 files changed, 43 insertions(+), 28 deletions(-)

diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
index 72ed004a8980..d6f971eea6ae 100644
--- a/drivers/auxdisplay/charlcd.c
+++ b/drivers/auxdisplay/charlcd.c
@@ -55,7 +55,7 @@
 
 #define LCD_CMD_SET_CGRAM_ADDR	0x40	/* Set char generator RAM address */
 
-#define LCD_CMD_SET_DDRAM_ADDR	0x80	/* Set display data RAM address */
+#define LCD_CMD_SET_DDRAM_ADDR 0x80    /* Set display data RAM address */
 
 #define LCD_ESCAPE_LEN		24	/* Max chars for LCD escape command */
 #define LCD_ESCAPE_CHAR		27	/* Use char 27 for escape command */
@@ -140,33 +140,17 @@ void charlcd_poke(struct charlcd *lcd)
 }
 EXPORT_SYMBOL_GPL(charlcd_poke);
 
-static void charlcd_gotoxy(struct charlcd *lcd)
-{
-	struct hd44780_common *hdc = lcd->drvdata;
-	unsigned int addr;
-
-	/*
-	 * we force the cursor to stay at the end of the
-	 * line if it wants to go farther
-	 */
-	addr = lcd->addr.x < hdc->bwidth ? lcd->addr.x & (hdc->hwidth - 1)
-					  : hdc->bwidth - 1;
-	if (lcd->addr.y & 1)
-		addr += hdc->hwidth;
-	if (lcd->addr.y & 2)
-		addr += hdc->bwidth;
-	hdc->write_cmd(hdc, LCD_CMD_SET_DDRAM_ADDR | addr);
-}
-
 static void charlcd_home(struct charlcd *lcd)
 {
 	lcd->addr.x = 0;
 	lcd->addr.y = 0;
-	charlcd_gotoxy(lcd);
+	lcd->ops->gotoxy(lcd);
 }
 
 static void charlcd_print(struct charlcd *lcd, char c)
 {
+	struct hd44780_common *hdc = lcd->drvdata;
+
 	if (lcd->char_conv)
 		c = lcd->char_conv[(unsigned char)c];
 
@@ -174,8 +158,8 @@ static void charlcd_print(struct charlcd *lcd, char c)
 		lcd->addr.x++;
 
 	/* prevents the cursor from wrapping onto the next line */
-	if (lcd->addr.x == lcd->width)
-		charlcd_gotoxy(lcd);
+	if (lcd->addr.x == hdc->bwidth)
+		lcd->ops->gotoxy(lcd);
 }
 
 static void charlcd_clear_fast(struct charlcd *lcd)
@@ -440,7 +424,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 		/* restore cursor position */
 		lcd->addr.x = xs;
 		lcd->addr.y = ys;
-		charlcd_gotoxy(lcd);
+		lcd->ops->gotoxy(lcd);
 		processed = 1;
 		break;
 	}
@@ -499,7 +483,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 			hdc->write_data(hdc, cgbytes[addr]);
 
 		/* ensures that we stop writing to CGRAM */
-		charlcd_gotoxy(lcd);
+		lcd->ops->gotoxy(lcd);
 		processed = 1;
 		break;
 	}
@@ -510,7 +494,7 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 
 		/* If the command is valid, move to the new address */
 		if (parse_xy(esc, &lcd->addr.x, &lcd->addr.y))
-			charlcd_gotoxy(lcd);
+			lcd->ops->gotoxy(lcd);
 
 		/* Regardless of its validity, mark as processed */
 		processed = 1;
@@ -596,12 +580,12 @@ static void charlcd_write_char(struct charlcd *lcd, char c)
 
 			lcd->addr.x = 0;
 			lcd->addr.y = (lcd->addr.y + 1) % lcd->height;
-			charlcd_gotoxy(lcd);
+			lcd->ops->gotoxy(lcd);
 			break;
 		case '\r':
 			/* go to the beginning of the same line */
 			lcd->addr.x = 0;
-			charlcd_gotoxy(lcd);
+			lcd->ops->gotoxy(lcd);
 			break;
 		case '\t':
 			/* print a space instead of the tab */
diff --git a/drivers/auxdisplay/charlcd.h b/drivers/auxdisplay/charlcd.h
index 874519f079b4..04fd241fe6d6 100644
--- a/drivers/auxdisplay/charlcd.h
+++ b/drivers/auxdisplay/charlcd.h
@@ -36,14 +36,16 @@ struct charlcd {
  * @clear_fast: Clear the whole display and set cursor to position 0, 0.
  * @backlight: Turn backlight on or off. Optional.
  * @print: just Print one character to the display at current cursor position.
- * The cursor is advanced by charlcd.
  * The buffered cursor position is advanced by charlcd. The cursor should not
  * wrap to the next line at the end of a line.
+ * @gotoxy: Set cursor to x, y. The x and y values to set the cursor to are
+ * previously set in addr.x and addr.y by charlcd.
  */
 struct charlcd_ops {
 	void (*clear_fast)(struct charlcd *lcd);
 	void (*backlight)(struct charlcd *lcd, enum charlcd_onoff on);
 	int (*print)(struct charlcd *lcd, int c);
+	int (*gotoxy)(struct charlcd *lcd);
 };
 
 struct charlcd *charlcd_alloc(void);
diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c
index 9680bb611639..4d9478f6e5ff 100644
--- a/drivers/auxdisplay/hd44780.c
+++ b/drivers/auxdisplay/hd44780.c
@@ -127,6 +127,7 @@ static void hd44780_write_data_gpio8(struct hd44780_common *hdc, int data)
 static const struct charlcd_ops hd44780_ops_gpio8 = {
 	.backlight	= hd44780_backlight,
 	.print		= hd44780_common_print,
+	.gotoxy		= hd44780_common_gotoxy,
 };
 
 /* Send a command to the LCD panel in 4 bit GPIO mode */
@@ -171,6 +172,7 @@ static void hd44780_write_data_gpio4(struct hd44780_common *hdc, int data)
 static const struct charlcd_ops hd44780_ops_gpio4 = {
 	.backlight	= hd44780_backlight,
 	.print		= hd44780_common_print,
+	.gotoxy		= hd44780_common_gotoxy,
 };
 
 static int hd44780_probe(struct platform_device *pdev)
diff --git a/drivers/auxdisplay/hd44780_common.c b/drivers/auxdisplay/hd44780_common.c
index c03dd7cd56c0..9e463b2fa03f 100644
--- a/drivers/auxdisplay/hd44780_common.c
+++ b/drivers/auxdisplay/hd44780_common.c
@@ -5,6 +5,9 @@
 #include "charlcd.h"
 #include "hd44780_common.h"
 
+/* LCD commands */
+#define LCD_CMD_SET_DDRAM_ADDR	0x80	/* Set display data RAM address */
+
 int hd44780_common_print(struct charlcd *lcd, int c)
 {
 	struct hd44780_common *hdc = lcd->drvdata;
@@ -18,6 +21,26 @@ int hd44780_common_print(struct charlcd *lcd, int c)
 }
 EXPORT_SYMBOL_GPL(hd44780_common_print);
 
+int hd44780_common_gotoxy(struct charlcd *lcd)
+{
+	struct hd44780_common *hdc = lcd->drvdata;
+	unsigned int addr;
+
+	/*
+	 * we force the cursor to stay at the end of the
+	 * line if it wants to go farther
+	 */
+	addr = lcd->addr.x < hdc->bwidth ? lcd->addr.x & (hdc->hwidth - 1)
+					  : hdc->bwidth - 1;
+	if (lcd->addr.y & 1)
+		addr += hdc->hwidth;
+	if (lcd->addr.y & 2)
+		addr += hdc->bwidth;
+	hdc->write_cmd(hdc, LCD_CMD_SET_DDRAM_ADDR | addr);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(hd44780_common_gotoxy);
+
 struct hd44780_common *hd44780_common_alloc(void)
 {
 	struct hd44780_common *hd;
diff --git a/drivers/auxdisplay/hd44780_common.h b/drivers/auxdisplay/hd44780_common.h
index 02d650903e35..0bee6c22761e 100644
--- a/drivers/auxdisplay/hd44780_common.h
+++ b/drivers/auxdisplay/hd44780_common.h
@@ -15,5 +15,6 @@ struct hd44780_common {
 };
 
 int hd44780_common_print(struct charlcd *lcd, int c);
+int hd44780_common_gotoxy(struct charlcd *lcd);
 struct hd44780_common *hd44780_common_alloc(void);
 
diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c
index 7ef9bc7188ca..75894eacd12f 100644
--- a/drivers/auxdisplay/panel.c
+++ b/drivers/auxdisplay/panel.c
@@ -875,16 +875,19 @@ static void lcd_clear_fast_tilcd(struct charlcd *charlcd)
 static const struct charlcd_ops charlcd_serial_ops = {
 	.clear_fast	= lcd_clear_fast_s,
 	.backlight	= lcd_backlight,
+	.gotoxy		= hd44780_common_gotoxy,
 };
 
 static const struct charlcd_ops charlcd_parallel_ops = {
 	.clear_fast	= lcd_clear_fast_p8,
 	.backlight	= lcd_backlight,
+	.gotoxy		= hd44780_common_gotoxy,
 };
 
 static const struct charlcd_ops charlcd_tilcd_ops = {
 	.clear_fast	= lcd_clear_fast_tilcd,
 	.backlight	= lcd_backlight,
+	.gotoxy		= hd44780_common_gotoxy,
 };
 
 /* initialize the LCD driver */
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 10/32] auxdisplay: add home to charlcd_ops
  2020-10-05 12:27 [PATCH v4 00/32] Make charlcd device independent poeschel
                   ` (8 preceding siblings ...)
  2020-10-05 12:27 ` [PATCH v4 09/32] auxdisplay: provide hd44780_common_gotoxy poeschel
@ 2020-10-05 12:27 ` poeschel
  2020-10-05 12:27 ` [PATCH v4 11/32] auxdisplay: Move clear_display to hd44780_common poeschel
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: poeschel @ 2020-10-05 12:27 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, Willy Tarreau, Ksenija Stanojevic, open list
  Cc: Lars Poeschel, Willy Tarreau

From: Lars Poeschel <poeschel@lemonage.de>

This adds a home function to the charlcd_ops struct and offer an
implementation for hd44780_common. This implementation is used by our
two hd44780 drivers. This is to make charlcd device independent.

Reviewed-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Lars Poeschel <poeschel@lemonage.de>
---
 drivers/auxdisplay/charlcd.c        | 2 +-
 drivers/auxdisplay/charlcd.h        | 3 +++
 drivers/auxdisplay/hd44780.c        | 2 ++
 drivers/auxdisplay/hd44780_common.c | 8 ++++++++
 drivers/auxdisplay/hd44780_common.h | 1 +
 drivers/auxdisplay/panel.c          | 3 +++
 6 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
index d6f971eea6ae..44dd6e02eaf9 100644
--- a/drivers/auxdisplay/charlcd.c
+++ b/drivers/auxdisplay/charlcd.c
@@ -144,7 +144,7 @@ static void charlcd_home(struct charlcd *lcd)
 {
 	lcd->addr.x = 0;
 	lcd->addr.y = 0;
-	lcd->ops->gotoxy(lcd);
+	lcd->ops->home(lcd);
 }
 
 static void charlcd_print(struct charlcd *lcd, char c)
diff --git a/drivers/auxdisplay/charlcd.h b/drivers/auxdisplay/charlcd.h
index 04fd241fe6d6..12c348c1a0ae 100644
--- a/drivers/auxdisplay/charlcd.h
+++ b/drivers/auxdisplay/charlcd.h
@@ -40,12 +40,15 @@ struct charlcd {
  * wrap to the next line at the end of a line.
  * @gotoxy: Set cursor to x, y. The x and y values to set the cursor to are
  * previously set in addr.x and addr.y by charlcd.
+ * @home: Set cursor to 0, 0. The values in addr.x and addr.y are set to 0, 0 by
+ * charlcd prior to calling this function.
  */
 struct charlcd_ops {
 	void (*clear_fast)(struct charlcd *lcd);
 	void (*backlight)(struct charlcd *lcd, enum charlcd_onoff on);
 	int (*print)(struct charlcd *lcd, int c);
 	int (*gotoxy)(struct charlcd *lcd);
+	int (*home)(struct charlcd *lcd);
 };
 
 struct charlcd *charlcd_alloc(void);
diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c
index 4d9478f6e5ff..b0893ea49165 100644
--- a/drivers/auxdisplay/hd44780.c
+++ b/drivers/auxdisplay/hd44780.c
@@ -128,6 +128,7 @@ static const struct charlcd_ops hd44780_ops_gpio8 = {
 	.backlight	= hd44780_backlight,
 	.print		= hd44780_common_print,
 	.gotoxy		= hd44780_common_gotoxy,
+	.home		= hd44780_common_home,
 };
 
 /* Send a command to the LCD panel in 4 bit GPIO mode */
@@ -173,6 +174,7 @@ static const struct charlcd_ops hd44780_ops_gpio4 = {
 	.backlight	= hd44780_backlight,
 	.print		= hd44780_common_print,
 	.gotoxy		= hd44780_common_gotoxy,
+	.home		= hd44780_common_home,
 };
 
 static int hd44780_probe(struct platform_device *pdev)
diff --git a/drivers/auxdisplay/hd44780_common.c b/drivers/auxdisplay/hd44780_common.c
index 9e463b2fa03f..a0ce390c6b2e 100644
--- a/drivers/auxdisplay/hd44780_common.c
+++ b/drivers/auxdisplay/hd44780_common.c
@@ -41,6 +41,14 @@ int hd44780_common_gotoxy(struct charlcd *lcd)
 }
 EXPORT_SYMBOL_GPL(hd44780_common_gotoxy);
 
+int hd44780_common_home(struct charlcd *lcd)
+{
+	lcd->addr.x = 0;
+	lcd->addr.y = 0;
+	return hd44780_common_gotoxy(lcd);
+}
+EXPORT_SYMBOL_GPL(hd44780_common_home);
+
 struct hd44780_common *hd44780_common_alloc(void)
 {
 	struct hd44780_common *hd;
diff --git a/drivers/auxdisplay/hd44780_common.h b/drivers/auxdisplay/hd44780_common.h
index 0bee6c22761e..1365484963d8 100644
--- a/drivers/auxdisplay/hd44780_common.h
+++ b/drivers/auxdisplay/hd44780_common.h
@@ -16,5 +16,6 @@ struct hd44780_common {
 
 int hd44780_common_print(struct charlcd *lcd, int c);
 int hd44780_common_gotoxy(struct charlcd *lcd);
+int hd44780_common_home(struct charlcd *lcd);
 struct hd44780_common *hd44780_common_alloc(void);
 
diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c
index 75894eacd12f..b1e874f07456 100644
--- a/drivers/auxdisplay/panel.c
+++ b/drivers/auxdisplay/panel.c
@@ -876,18 +876,21 @@ static const struct charlcd_ops charlcd_serial_ops = {
 	.clear_fast	= lcd_clear_fast_s,
 	.backlight	= lcd_backlight,
 	.gotoxy		= hd44780_common_gotoxy,
+	.home		= hd44780_common_home,
 };
 
 static const struct charlcd_ops charlcd_parallel_ops = {
 	.clear_fast	= lcd_clear_fast_p8,
 	.backlight	= lcd_backlight,
 	.gotoxy		= hd44780_common_gotoxy,
+	.home		= hd44780_common_home,
 };
 
 static const struct charlcd_ops charlcd_tilcd_ops = {
 	.clear_fast	= lcd_clear_fast_tilcd,
 	.backlight	= lcd_backlight,
 	.gotoxy		= hd44780_common_gotoxy,
+	.home		= hd44780_common_home,
 };
 
 /* initialize the LCD driver */
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 11/32] auxdisplay: Move clear_display to hd44780_common
  2020-10-05 12:27 [PATCH v4 00/32] Make charlcd device independent poeschel
                   ` (9 preceding siblings ...)
  2020-10-05 12:27 ` [PATCH v4 10/32] auxdisplay: add home to charlcd_ops poeschel
@ 2020-10-05 12:27 ` poeschel
  2020-10-05 12:27 ` [PATCH v4 12/32] auxdisplay: make charlcd_backlight visible " poeschel
  2020-10-05 15:30 ` [PATCH v4 00/32] Make charlcd device independent Miguel Ojeda
  12 siblings, 0 replies; 21+ messages in thread
From: poeschel @ 2020-10-05 12:27 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, Willy Tarreau, Ksenija Stanojevic, open list
  Cc: Lars Poeschel, Willy Tarreau

From: Lars Poeschel <poeschel@lemonage.de>

This moves the clear_display function from charlcd to hd44780_common.
This is one more step to make charlcd independent from device specific
code. The two hd44780 drivers use the new function from hd44780_common
and charlcd calls this function through its function pointer in its ops
structure.

Reviewed-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Lars Poeschel <poeschel@lemonage.de>
---
 drivers/auxdisplay/charlcd.c        | 22 ++++++----------------
 drivers/auxdisplay/charlcd.h        |  4 ++++
 drivers/auxdisplay/hd44780.c        |  2 ++
 drivers/auxdisplay/hd44780_common.c | 21 +++++++++++++++++++++
 drivers/auxdisplay/hd44780_common.h |  1 +
 drivers/auxdisplay/panel.c          |  3 +++
 6 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
index 44dd6e02eaf9..fc0daf4987d5 100644
--- a/drivers/auxdisplay/charlcd.c
+++ b/drivers/auxdisplay/charlcd.c
@@ -34,8 +34,6 @@
 #define LCD_FLAG_L		0x0080	/* Backlight enabled */
 
 /* 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 */
 
@@ -178,18 +176,6 @@ static void charlcd_clear_fast(struct charlcd *lcd)
 	charlcd_home(lcd);
 }
 
-/* clears the display and resets X/Y */
-static void charlcd_clear_display(struct charlcd *lcd)
-{
-	struct hd44780_common *hdc = lcd->drvdata;
-
-	hdc->write_cmd(hdc, LCD_CMD_DISPLAY_CLEAR);
-	lcd->addr.x = 0;
-	lcd->addr.y = 0;
-	/* we must wait a few milliseconds (15) */
-	long_sleep(15);
-}
-
 static int charlcd_init_display(struct charlcd *lcd)
 {
 	void (*write_cmd_raw)(struct hd44780_common *hdc, int cmd);
@@ -254,7 +240,9 @@ static int charlcd_init_display(struct charlcd *lcd)
 	/* entry mode set : increment, cursor shifting */
 	hdc->write_cmd(hdc, LCD_CMD_ENTRY_MODE | LCD_CMD_CURSOR_INC);
 
-	charlcd_clear_display(lcd);
+	lcd->ops->clear_display(lcd);
+	lcd->addr.x = 0;
+	lcd->addr.y = 0;
 	return 0;
 }
 
@@ -670,8 +658,10 @@ static int charlcd_open(struct inode *inode, struct file *file)
 		goto fail;
 
 	if (priv->must_clear) {
-		charlcd_clear_display(&priv->lcd);
+		priv->lcd.ops->clear_display(&priv->lcd);
 		priv->must_clear = false;
+		priv->lcd.addr.x = 0;
+		priv->lcd.addr.y = 0;
 	}
 	return nonseekable_open(inode, file);
 
diff --git a/drivers/auxdisplay/charlcd.h b/drivers/auxdisplay/charlcd.h
index 12c348c1a0ae..0b3dafbbae72 100644
--- a/drivers/auxdisplay/charlcd.h
+++ b/drivers/auxdisplay/charlcd.h
@@ -42,6 +42,9 @@ struct charlcd {
  * previously set in addr.x and addr.y by charlcd.
  * @home: Set cursor to 0, 0. The values in addr.x and addr.y are set to 0, 0 by
  * charlcd prior to calling this function.
+ * @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.
  */
 struct charlcd_ops {
 	void (*clear_fast)(struct charlcd *lcd);
@@ -49,6 +52,7 @@ struct charlcd_ops {
 	int (*print)(struct charlcd *lcd, int c);
 	int (*gotoxy)(struct charlcd *lcd);
 	int (*home)(struct charlcd *lcd);
+	int (*clear_display)(struct charlcd *lcd);
 };
 
 struct charlcd *charlcd_alloc(void);
diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c
index b0893ea49165..40ea6d25dbe1 100644
--- a/drivers/auxdisplay/hd44780.c
+++ b/drivers/auxdisplay/hd44780.c
@@ -129,6 +129,7 @@ static const struct charlcd_ops hd44780_ops_gpio8 = {
 	.print		= hd44780_common_print,
 	.gotoxy		= hd44780_common_gotoxy,
 	.home		= hd44780_common_home,
+	.clear_display	= hd44780_common_clear_display,
 };
 
 /* Send a command to the LCD panel in 4 bit GPIO mode */
@@ -175,6 +176,7 @@ static const struct charlcd_ops hd44780_ops_gpio4 = {
 	.print		= hd44780_common_print,
 	.gotoxy		= hd44780_common_gotoxy,
 	.home		= hd44780_common_home,
+	.clear_display	= hd44780_common_clear_display,
 };
 
 static int hd44780_probe(struct platform_device *pdev)
diff --git a/drivers/auxdisplay/hd44780_common.c b/drivers/auxdisplay/hd44780_common.c
index a0ce390c6b2e..6bc2b3bf6139 100644
--- a/drivers/auxdisplay/hd44780_common.c
+++ b/drivers/auxdisplay/hd44780_common.c
@@ -1,13 +1,22 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 #include <linux/module.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 
 #include "charlcd.h"
 #include "hd44780_common.h"
 
 /* LCD commands */
+#define LCD_CMD_DISPLAY_CLEAR	0x01	/* Clear entire display */
+
 #define LCD_CMD_SET_DDRAM_ADDR	0x80	/* Set display data RAM address */
 
+/* sleeps that many milliseconds with a reschedule */
+static void long_sleep(int ms)
+{
+	schedule_timeout_interruptible(msecs_to_jiffies(ms));
+}
+
 int hd44780_common_print(struct charlcd *lcd, int c)
 {
 	struct hd44780_common *hdc = lcd->drvdata;
@@ -49,6 +58,18 @@ int hd44780_common_home(struct charlcd *lcd)
 }
 EXPORT_SYMBOL_GPL(hd44780_common_home);
 
+/* clears the display and resets X/Y */
+int hd44780_common_clear_display(struct charlcd *lcd)
+{
+	struct hd44780_common *hdc = lcd->drvdata;
+
+	hdc->write_cmd(hdc, LCD_CMD_DISPLAY_CLEAR);
+	/* we must wait a few milliseconds (15) */
+	long_sleep(15);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(hd44780_common_clear_display);
+
 struct hd44780_common *hd44780_common_alloc(void)
 {
 	struct hd44780_common *hd;
diff --git a/drivers/auxdisplay/hd44780_common.h b/drivers/auxdisplay/hd44780_common.h
index 1365484963d8..11ec4baf6997 100644
--- a/drivers/auxdisplay/hd44780_common.h
+++ b/drivers/auxdisplay/hd44780_common.h
@@ -17,5 +17,6 @@ struct hd44780_common {
 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);
 struct hd44780_common *hd44780_common_alloc(void);
 
diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c
index b1e874f07456..8adf627529f1 100644
--- a/drivers/auxdisplay/panel.c
+++ b/drivers/auxdisplay/panel.c
@@ -877,6 +877,7 @@ static const struct charlcd_ops charlcd_serial_ops = {
 	.backlight	= lcd_backlight,
 	.gotoxy		= hd44780_common_gotoxy,
 	.home		= hd44780_common_home,
+	.clear_display	= hd44780_common_clear_display,
 };
 
 static const struct charlcd_ops charlcd_parallel_ops = {
@@ -884,6 +885,7 @@ static const struct charlcd_ops charlcd_parallel_ops = {
 	.backlight	= lcd_backlight,
 	.gotoxy		= hd44780_common_gotoxy,
 	.home		= hd44780_common_home,
+	.clear_display	= hd44780_common_clear_display,
 };
 
 static const struct charlcd_ops charlcd_tilcd_ops = {
@@ -891,6 +893,7 @@ static const struct charlcd_ops charlcd_tilcd_ops = {
 	.backlight	= lcd_backlight,
 	.gotoxy		= hd44780_common_gotoxy,
 	.home		= hd44780_common_home,
+	.clear_display	= hd44780_common_clear_display,
 };
 
 /* initialize the LCD driver */
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 12/32] auxdisplay: make charlcd_backlight visible to hd44780_common
  2020-10-05 12:27 [PATCH v4 00/32] Make charlcd device independent poeschel
                   ` (10 preceding siblings ...)
  2020-10-05 12:27 ` [PATCH v4 11/32] auxdisplay: Move clear_display to hd44780_common poeschel
@ 2020-10-05 12:27 ` poeschel
  2020-10-05 15:30 ` [PATCH v4 00/32] Make charlcd device independent Miguel Ojeda
  12 siblings, 0 replies; 21+ messages in thread
From: poeschel @ 2020-10-05 12:27 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, open list; +Cc: Lars Poeschel, Willy Tarreau

From: Lars Poeschel <poeschel@lemonage.de>

hd44780_common wants to use the charlcd_backlight function, so make it
visible.

Reviewed-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Lars Poeschel <poeschel@lemonage.de>
---
 drivers/auxdisplay/charlcd.c | 3 ++-
 drivers/auxdisplay/charlcd.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
index fc0daf4987d5..154419513186 100644
--- a/drivers/auxdisplay/charlcd.c
+++ b/drivers/auxdisplay/charlcd.c
@@ -91,7 +91,7 @@ static void long_sleep(int ms)
 }
 
 /* turn the backlight on or off */
-static void charlcd_backlight(struct charlcd *lcd, enum charlcd_onoff on)
+void charlcd_backlight(struct charlcd *lcd, enum charlcd_onoff on)
 {
 	struct charlcd_priv *priv = charlcd_to_priv(lcd);
 
@@ -103,6 +103,7 @@ static void charlcd_backlight(struct charlcd *lcd, enum charlcd_onoff on)
 		lcd->ops->backlight(lcd, on);
 	mutex_unlock(&priv->bl_tempo_lock);
 }
+EXPORT_SYMBOL_GPL(charlcd_backlight);
 
 static void charlcd_bl_off(struct work_struct *work)
 {
diff --git a/drivers/auxdisplay/charlcd.h b/drivers/auxdisplay/charlcd.h
index 0b3dafbbae72..e5b22e72fdc8 100644
--- a/drivers/auxdisplay/charlcd.h
+++ b/drivers/auxdisplay/charlcd.h
@@ -55,6 +55,7 @@ struct charlcd_ops {
 	int (*clear_display)(struct charlcd *lcd);
 };
 
+void charlcd_backlight(struct charlcd *lcd, enum charlcd_onoff on);
 struct charlcd *charlcd_alloc(void);
 void charlcd_free(struct charlcd *lcd);
 
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 00/32] Make charlcd device independent
  2020-10-05 12:27 [PATCH v4 00/32] Make charlcd device independent poeschel
                   ` (11 preceding siblings ...)
  2020-10-05 12:27 ` [PATCH v4 12/32] auxdisplay: make charlcd_backlight visible " poeschel
@ 2020-10-05 15:30 ` Miguel Ojeda
  2020-10-06  8:38   ` Lars Poeschel
  12 siblings, 1 reply; 21+ messages in thread
From: Miguel Ojeda @ 2020-10-05 15:30 UTC (permalink / raw)
  To: Lars Poeschel; +Cc: Willy Tarreau, Ksenija Stanojevic, linux-kernel

Hi Lars,

On Mon, Oct 5, 2020 at 2:27 PM <poeschel@lemonage.de> wrote:
>
> This tries to make charlcd device independent.

Thanks a lot for the work!

I see you have written the differences between versions in each patch,
but given there are 32 patches, it'd be nice to comment which ones have
changed so that folks that already did a review can take a look at
those.

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 00/32] Make charlcd device independent
  2020-10-05 15:30 ` [PATCH v4 00/32] Make charlcd device independent Miguel Ojeda
@ 2020-10-06  8:38   ` Lars Poeschel
  2020-10-16  2:33     ` Miguel Ojeda
  0 siblings, 1 reply; 21+ messages in thread
From: Lars Poeschel @ 2020-10-06  8:38 UTC (permalink / raw)
  To: Miguel Ojeda; +Cc: Willy Tarreau, Ksenija Stanojevic, linux-kernel

On Mon, Oct 05, 2020 at 05:30:59PM +0200, Miguel Ojeda wrote:
> Hi Lars,
> 
> On Mon, Oct 5, 2020 at 2:27 PM <poeschel@lemonage.de> wrote:
> >
> > This tries to make charlcd device independent.
> 
> Thanks a lot for the work!
> 
> I see you have written the differences between versions in each patch,
> but given there are 32 patches, it'd be nice to comment which ones have
> changed so that folks that already did a review can take a look at
> those.

Changes in v4:
- modtronix -> Modtronix in new lcd2s driver
- Kconfig: remove "default n" in new lcd2s driver

Changes in v3:
- Fix some typos in Kconfig stuff
- Fix kernel test robot reported error: Missed EXPORT_SYMBOL_GPL
- new patch to reduce display timeout
- better patch description to why not move cursor beyond end of a line
- Fixed make dt_binding_doc errors

Changes in v2:
- split whole patch into many smaller chunks
- device tree doc in yaml

Regards,
Lars

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 00/32] Make charlcd device independent
  2020-10-06  8:38   ` Lars Poeschel
@ 2020-10-16  2:33     ` Miguel Ojeda
  2020-10-16  3:59       ` Miguel Ojeda
  0 siblings, 1 reply; 21+ messages in thread
From: Miguel Ojeda @ 2020-10-16  2:33 UTC (permalink / raw)
  To: Lars Poeschel; +Cc: Willy Tarreau, Ksenija Stanojevic, linux-kernel

Hi Lars,

On Tue, Oct 6, 2020 at 10:38 AM Lars Poeschel <poeschel@lemonage.de> wrote:
>
> Changes in v4:
> - modtronix -> Modtronix in new lcd2s driver
> - Kconfig: remove "default n" in new lcd2s driver
>
> Changes in v3:
> - Fix some typos in Kconfig stuff
> - Fix kernel test robot reported error: Missed EXPORT_SYMBOL_GPL
> - new patch to reduce display timeout
> - better patch description to why not move cursor beyond end of a line
> - Fixed make dt_binding_doc errors

Picking these for linux-next (including Rob's Reviewed-by). I have
spotted a few typos that I corrected -- I will note them by email.

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 01/32] auxdisplay: Use an enum for charlcd backlight on/off ops
  2020-10-05 12:27 ` [PATCH v4 01/32] auxdisplay: Use an enum for charlcd backlight on/off ops poeschel
@ 2020-10-16  2:34   ` Miguel Ojeda
  0 siblings, 0 replies; 21+ messages in thread
From: Miguel Ojeda @ 2020-10-16  2:34 UTC (permalink / raw)
  To: Lars Poeschel; +Cc: Willy Tarreau, Ksenija Stanojevic, open list, Willy Tarreau

On Mon, Oct 5, 2020 at 2:27 PM <poeschel@lemonage.de> wrote:
>
> We use an enum for calling the functions in charlcd, that turn the
> backlight on or off. This enum is generic and can be used for other
> charlcd turn of / turn off operations as well.

Typo: of -> on

(Already corrected in my queue)

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 02/32] auxdisplay: Introduce hd44780_common.[ch]
  2020-10-05 12:27 ` [PATCH v4 02/32] auxdisplay: Introduce hd44780_common.[ch] poeschel
@ 2020-10-16  2:48   ` Miguel Ojeda
  0 siblings, 0 replies; 21+ messages in thread
From: Miguel Ojeda @ 2020-10-16  2:48 UTC (permalink / raw)
  To: Lars Poeschel; +Cc: Willy Tarreau, Ksenija Stanojevic, open list, Willy Tarreau

On Mon, Oct 5, 2020 at 2:27 PM <poeschel@lemonage.de> wrote:
>
> diff --git a/drivers/auxdisplay/hd44780_common.c b/drivers/auxdisplay/hd44780_common.c
> new file mode 100644
> index 000000000000..073f47397f7d
> --- /dev/null
> +++ b/drivers/auxdisplay/hd44780_common.c
> @@ -0,0 +1,21 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +
> +#include "hd44780_common.h"
> +
> +struct hd44780_common *hd44780_common_alloc(void)
> +{
> +       struct hd44780_common *hd;
> +
> +       hd = kzalloc(sizeof(*hd), GFP_KERNEL);
> +       if (!hd)
> +               return NULL;
> +
> +       return hd;
> +

Typo: spurious newline.

> +}
> +EXPORT_SYMBOL_GPL(hd44780_common_alloc);
> +
> +MODULE_LICENSE("GPL");
> +

Spurious EOF newline.

> diff --git a/drivers/auxdisplay/hd44780_common.h b/drivers/auxdisplay/hd44780_common.h
> new file mode 100644
> index 000000000000..767bbda91744
> --- /dev/null
> +++ b/drivers/auxdisplay/hd44780_common.h
> @@ -0,0 +1,8 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +struct hd44780_common {
> +       void *hd44780;
> +};
> +
> +struct hd44780_common *hd44780_common_alloc(void);
> +

Spurious EOF newline.

(All already corrected in my queue).

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 08/32] auxdisplay: hd44780_common_print
  2020-10-05 12:27 ` [PATCH v4 08/32] auxdisplay: hd44780_common_print poeschel
@ 2020-10-16  3:54   ` Miguel Ojeda
  0 siblings, 0 replies; 21+ messages in thread
From: Miguel Ojeda @ 2020-10-16  3:54 UTC (permalink / raw)
  To: Lars Poeschel; +Cc: open list, kernel test robot, Willy Tarreau

On Mon, Oct 5, 2020 at 2:27 PM <poeschel@lemonage.de> wrote:
>
> We create a hd44780_common_print function. It is derived from the
> original charlcd_print. charlcd_print becomes a device independent print
> function, that then only calles via it's ops function pointers, into the

Typos: calles -> calls, it's -> its

> + * @clear_fast: Clear the whole display and set cursor to position 0, 0.

This one is optional, but the comment seems to say it isn't (it is
later removed, so in the end it doesn't matter, but probably we should
write "Optional." here too).

> + * @backlight: Turn backlight on or off. Optional.
> + * @print: just Print one character to the display at current cursor position.

Typo: remove "just"

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 00/32] Make charlcd device independent
  2020-10-16  2:33     ` Miguel Ojeda
@ 2020-10-16  3:59       ` Miguel Ojeda
  2020-10-22  7:40         ` Lars Poeschel
  0 siblings, 1 reply; 21+ messages in thread
From: Miguel Ojeda @ 2020-10-16  3:59 UTC (permalink / raw)
  To: Lars Poeschel; +Cc: Willy Tarreau, Ksenija Stanojevic, linux-kernel

On Fri, Oct 16, 2020 at 4:33 AM Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
> Picking these for linux-next (including Rob's Reviewed-by). I have
> spotted a few typos that I corrected -- I will note them by email.

Hmm, I think we should do another round instead, since I found what
looks to be an unintended revert of a previous commit in patch 24.
Lars, can you please take a look?

Also, please take the chance to apply my comments given we have a new
round (and Rob's Reviewed-by too).

By the way, I think you could simplify by squashing the "implement
hd44780_*" commits together (i.e. from 15 to 22 except 20), and the
two cleanups together too (i.e. 20 and 23). I know we asked you to
split things up before, but those two sets are quite similar
(including in their commit message) and easy to understand all
together.

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 00/32] Make charlcd device independent
  2020-10-16  3:59       ` Miguel Ojeda
@ 2020-10-22  7:40         ` Lars Poeschel
  0 siblings, 0 replies; 21+ messages in thread
From: Lars Poeschel @ 2020-10-22  7:40 UTC (permalink / raw)
  To: Miguel Ojeda; +Cc: Willy Tarreau, Ksenija Stanojevic, linux-kernel

On Fri, Oct 16, 2020 at 05:59:04AM +0200, Miguel Ojeda wrote:
> On Fri, Oct 16, 2020 at 4:33 AM Miguel Ojeda
> <miguel.ojeda.sandonis@gmail.com> wrote:
> >
> > Picking these for linux-next (including Rob's Reviewed-by). I have
> > spotted a few typos that I corrected -- I will note them by email.
> 
> Hmm, I think we should do another round instead, since I found what
> looks to be an unintended revert of a previous commit in patch 24.
> Lars, can you please take a look?

I will work on this soon.

> Also, please take the chance to apply my comments given we have a new
> round (and Rob's Reviewed-by too).

Yes, of course.

> By the way, I think you could simplify by squashing the "implement
> hd44780_*" commits together (i.e. from 15 to 22 except 20), and the
> two cleanups together too (i.e. 20 and 23). I know we asked you to
> split things up before, but those two sets are quite similar
> (including in their commit message) and easy to understand all
> together.

No problem. I will do this as well.

Regards,
Lars

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2020-10-22  7:40 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-05 12:27 [PATCH v4 00/32] Make charlcd device independent poeschel
2020-10-05 12:27 ` [PATCH v4 01/32] auxdisplay: Use an enum for charlcd backlight on/off ops poeschel
2020-10-16  2:34   ` Miguel Ojeda
2020-10-05 12:27 ` [PATCH v4 02/32] auxdisplay: Introduce hd44780_common.[ch] poeschel
2020-10-16  2:48   ` Miguel Ojeda
2020-10-05 12:27 ` [PATCH v4 03/32] auxdisplay: Move hwidth and bwidth to struct hd44780_common poeschel
2020-10-05 12:27 ` [PATCH v4 04/32] auxdisplay: Move ifwidth " poeschel
2020-10-05 12:27 ` [PATCH v4 05/32] auxdisplay: Move write_data pointer to hd44780_common poeschel
2020-10-05 12:27 ` [PATCH v4 06/32] auxdisplay: Move write_cmd pointers to hd44780 drivers poeschel
2020-10-05 12:27 ` [PATCH v4 07/32] auxdisplay: Move addr out of charlcd_priv poeschel
2020-10-05 12:27 ` [PATCH v4 08/32] auxdisplay: hd44780_common_print poeschel
2020-10-16  3:54   ` Miguel Ojeda
2020-10-05 12:27 ` [PATCH v4 09/32] auxdisplay: provide hd44780_common_gotoxy poeschel
2020-10-05 12:27 ` [PATCH v4 10/32] auxdisplay: add home to charlcd_ops poeschel
2020-10-05 12:27 ` [PATCH v4 11/32] auxdisplay: Move clear_display to hd44780_common poeschel
2020-10-05 12:27 ` [PATCH v4 12/32] auxdisplay: make charlcd_backlight visible " poeschel
2020-10-05 15:30 ` [PATCH v4 00/32] Make charlcd device independent Miguel Ojeda
2020-10-06  8:38   ` Lars Poeschel
2020-10-16  2:33     ` Miguel Ojeda
2020-10-16  3:59       ` Miguel Ojeda
2020-10-22  7:40         ` Lars Poeschel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).