[2/5] auxdisplay: charlcd: add flush function

Message ID cdfa0d36f2f2d306e0824205b4fca0b685991ee9.1516008708.git.sean@mess.org (mailing list archive)
State New
Delegated to: Sean Young
Headers

Commit Message

Sean Young Jan. 15, 2018, 9:58 a.m. UTC
  The Sasem Remote Controller has an LCD, which is connnected via usb.
Multiple write reg or write data commands can be combined into one usb
packet.

The latency of usb is such that if we send commands one by one, we get
very obvious tearing on the LCD.

By adding a flush function, we can buffer all commands until either
the usb packet is full or the lcd changes are complete.

Signed-off-by: Sean Young <sean@mess.org>
---
 drivers/auxdisplay/charlcd.c | 6 ++++++
 include/misc/charlcd.h       | 1 +
 2 files changed, 7 insertions(+)
  

Comments

Miguel Ojeda Feb. 12, 2018, 8:44 p.m. UTC | #1
On Mon, Jan 15, 2018 at 10:58 AM, Sean Young <sean@mess.org> wrote:
> The Sasem Remote Controller has an LCD, which is connnected via usb.
> Multiple write reg or write data commands can be combined into one usb
> packet.
>
> The latency of usb is such that if we send commands one by one, we get
> very obvious tearing on the LCD.
>
> By adding a flush function, we can buffer all commands until either
> the usb packet is full or the lcd changes are complete.
>
> Signed-off-by: Sean Young <sean@mess.org>
> ---
>  drivers/auxdisplay/charlcd.c | 6 ++++++

Cc'ing Arnd and Greg since this touches include/misc as well.

Miguel

>  include/misc/charlcd.h       | 1 +
>  2 files changed, 7 insertions(+)
>
> diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
> index 45ec5ce697c4..a16c72779722 100644
> --- a/drivers/auxdisplay/charlcd.c
> +++ b/drivers/auxdisplay/charlcd.c
> @@ -642,6 +642,9 @@ static ssize_t charlcd_write(struct file *file, const char __user *buf,
>                 charlcd_write_char(the_charlcd, c);
>         }
>
> +       if (the_charlcd->ops->flush)
> +               the_charlcd->ops->flush(the_charlcd);
> +
>         return tmp - buf;
>  }
>
> @@ -703,6 +706,9 @@ static void charlcd_puts(struct charlcd *lcd, const char *s)
>
>                 charlcd_write_char(lcd, *tmp);
>         }
> +
> +       if (lcd->ops->flush)
> +               lcd->ops->flush(lcd);
>  }
>
>  /* initialize the LCD driver */
> diff --git a/include/misc/charlcd.h b/include/misc/charlcd.h
> index 23f61850f363..ff8fd456018e 100644
> --- a/include/misc/charlcd.h
> +++ b/include/misc/charlcd.h
> @@ -32,6 +32,7 @@ struct charlcd_ops {
>         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 (*flush)(struct charlcd *lcd);
>  };
>
>  struct charlcd *charlcd_alloc(unsigned int drvdata_size);
> --
> 2.14.3
>
  
Andy Shevchenko Feb. 13, 2018, 1:47 p.m. UTC | #2
On Mon, Feb 12, 2018 at 10:44 PM, Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
> On Mon, Jan 15, 2018 at 10:58 AM, Sean Young <sean@mess.org> wrote:
>> The Sasem Remote Controller has an LCD, which is connnected via usb.
>> Multiple write reg or write data commands can be combined into one usb
>> packet.
>>
>> The latency of usb is such that if we send commands one by one, we get
>> very obvious tearing on the LCD.
>>
>> By adding a flush function, we can buffer all commands until either
>> the usb packet is full or the lcd changes are complete.

> Cc'ing Arnd and Greg since this touches include/misc as well.

>> --- a/include/misc/charlcd.h
>> +++ b/include/misc/charlcd.h

As far as I can see better to create a subfolder under include for
auxdisplay stuff.
Currently we have three candidates here:
linux/cfag12864b.h
linux/ks0108.h
misc/charlcd.h

Another possibility to get rid of them under include/ by (re)moving to
drivers/auxdisplay/.
  

Patch

diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
index 45ec5ce697c4..a16c72779722 100644
--- a/drivers/auxdisplay/charlcd.c
+++ b/drivers/auxdisplay/charlcd.c
@@ -642,6 +642,9 @@  static ssize_t charlcd_write(struct file *file, const char __user *buf,
 		charlcd_write_char(the_charlcd, c);
 	}
 
+	if (the_charlcd->ops->flush)
+		the_charlcd->ops->flush(the_charlcd);
+
 	return tmp - buf;
 }
 
@@ -703,6 +706,9 @@  static void charlcd_puts(struct charlcd *lcd, const char *s)
 
 		charlcd_write_char(lcd, *tmp);
 	}
+
+	if (lcd->ops->flush)
+		lcd->ops->flush(lcd);
 }
 
 /* initialize the LCD driver */
diff --git a/include/misc/charlcd.h b/include/misc/charlcd.h
index 23f61850f363..ff8fd456018e 100644
--- a/include/misc/charlcd.h
+++ b/include/misc/charlcd.h
@@ -32,6 +32,7 @@  struct charlcd_ops {
 	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 (*flush)(struct charlcd *lcd);
 };
 
 struct charlcd *charlcd_alloc(unsigned int drvdata_size);