[11/13] auxdisplay: charlcd: Add support for displays with more than two lines
diff mbox series

Message ID 1486391895-9554-12-git-send-email-geert@linux-m68k.org
State New, archived
Headers show
Series
  • Add HD44780 Character LCD support
Related show

Commit Message

Geert Uytterhoeven Feb. 6, 2017, 2:38 p.m. UTC
On displays with more than two lines, the additional lines are stored in
the buffers used for the first two lines, but beyond the visible parts.
Adjust the DDRAM address calculation to cater for this.

When clearing the display, avoid writing more spaces than the actual
size of the physical buffer.

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/auxdisplay/charlcd.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

Patch
diff mbox series

diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
index 6d27d9363c9baaf2..6aea90086e3695c5 100644
--- a/drivers/auxdisplay/charlcd.c
+++ b/drivers/auxdisplay/charlcd.c
@@ -159,15 +159,19 @@  void charlcd_poke(struct charlcd *lcd)
 static void charlcd_gotoxy(struct charlcd *lcd)
 {
 	struct charlcd_priv *priv = to_priv(lcd);
+	unsigned int addr;
 
-	lcd->ops->write_cmd(lcd,
-		LCD_CMD_SET_DDRAM_ADDR | (priv->addr.y ? lcd->hwidth : 0) |
-		/*
-		 * we force the cursor to stay at the end of the
-		 * line if it wants to go farther
-		 */
-		((priv->addr.x < lcd->bwidth) ? priv->addr.x & (lcd->hwidth - 1)
-					      : lcd->bwidth - 1));
+	/*
+	 * 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;
+	if (priv->addr.y & 1)
+		addr += lcd->hwidth;
+	if (priv->addr.y & 2)
+		addr += lcd->bwidth;
+	lcd->ops->write_cmd(lcd, LCD_CMD_SET_DDRAM_ADDR | addr);
 }
 
 static void charlcd_home(struct charlcd *lcd)
@@ -203,7 +207,7 @@  static void charlcd_clear_fast(struct charlcd *lcd)
 	if (lcd->ops->clear_fast)
 		lcd->ops->clear_fast(lcd);
 	else
-		for (pos = 0; pos < lcd->height * lcd->hwidth; pos++)
+		for (pos = 0; pos < min(2, lcd->height) * lcd->hwidth; pos++)
 			lcd->ops->write_data(lcd, ' ');
 
 	charlcd_home(lcd);