All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] new driver for Ahanix D.Vine 5 IR/VFD
@ 2018-01-15  9:58 Sean Young
  2018-01-15  9:58 ` [PATCH 1/5] auxdisplay: charlcd: no need to call charlcd_gotoxy() if nothing changes Sean Young
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Sean Young @ 2018-01-15  9:58 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, linux-media

This is a newer driver for this device. It originally supported by the
lirc_sasem.c staging driver, which was removed in kernel v4.12.

Here a some more information about the hardware and my attempts to
understand it:

http://www.mess.org/2018/01/17/Ahanix-D-Vine-5-IR-VFD-module/

Sean Young (5):
  auxdisplay: charlcd: no need to call charlcd_gotoxy() if nothing
    changes
  auxdisplay: charlcd: add flush function
  auxdisplay: charlcd: add escape sequence for brightness on NEC
    µPD16314
  media: rc: add keymap for Dign Remote
  media: rc: new driver for Sasem Remote Controller VFD/IR

 MAINTAINERS                        |   6 +
 drivers/auxdisplay/charlcd.c       |  33 ++++-
 drivers/media/rc/Kconfig           |  16 ++
 drivers/media/rc/Makefile          |   1 +
 drivers/media/rc/keymaps/Makefile  |   1 +
 drivers/media/rc/keymaps/rc-dign.c |  70 +++++++++
 drivers/media/rc/sasem_ir.c        | 297 +++++++++++++++++++++++++++++++++++++
 include/media/rc-map.h             |   1 +
 include/misc/charlcd.h             |   1 +
 9 files changed, 421 insertions(+), 5 deletions(-)
 create mode 100644 drivers/media/rc/keymaps/rc-dign.c
 create mode 100644 drivers/media/rc/sasem_ir.c

-- 
2.14.3

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

* [PATCH 1/5] auxdisplay: charlcd: no need to call charlcd_gotoxy() if nothing changes
  2018-01-15  9:58 [PATCH 0/5] new driver for Ahanix D.Vine 5 IR/VFD Sean Young
@ 2018-01-15  9:58 ` Sean Young
  2018-02-12 13:42   ` Miguel Ojeda
  2018-01-15  9:58 ` [PATCH 2/5] auxdisplay: charlcd: add flush function Sean Young
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Sean Young @ 2018-01-15  9:58 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, linux-media

If the line extends beyond the width to the screen, nothing changes. The
existing code will call charlcd_gotoxy every time for this case.

Signed-off-by: Sean Young <sean@mess.org>
---
 drivers/auxdisplay/charlcd.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
index 642afd88870b..45ec5ce697c4 100644
--- a/drivers/auxdisplay/charlcd.c
+++ b/drivers/auxdisplay/charlcd.c
@@ -192,10 +192,11 @@ static void charlcd_print(struct charlcd *lcd, char c)
 			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)
+			charlcd_gotoxy(lcd);
 	}
-	/* prevents the cursor from wrapping onto the next line */
-	if (priv->addr.x == lcd->bwidth)
-		charlcd_gotoxy(lcd);
 }
 
 static void charlcd_clear_fast(struct charlcd *lcd)
-- 
2.14.3

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

* [PATCH 2/5] auxdisplay: charlcd: add flush function
  2018-01-15  9:58 [PATCH 0/5] new driver for Ahanix D.Vine 5 IR/VFD Sean Young
  2018-01-15  9:58 ` [PATCH 1/5] auxdisplay: charlcd: no need to call charlcd_gotoxy() if nothing changes Sean Young
@ 2018-01-15  9:58 ` Sean Young
  2018-02-12 20:44   ` Miguel Ojeda
  2018-01-15  9:58 ` [PATCH 3/5] auxdisplay: charlcd: add escape sequence for brightness on NEC µPD16314 Sean Young
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Sean Young @ 2018-01-15  9:58 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, linux-media

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(+)

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

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

* [PATCH 3/5] auxdisplay: charlcd: add escape sequence for brightness on NEC µPD16314
  2018-01-15  9:58 [PATCH 0/5] new driver for Ahanix D.Vine 5 IR/VFD Sean Young
  2018-01-15  9:58 ` [PATCH 1/5] auxdisplay: charlcd: no need to call charlcd_gotoxy() if nothing changes Sean Young
  2018-01-15  9:58 ` [PATCH 2/5] auxdisplay: charlcd: add flush function Sean Young
@ 2018-01-15  9:58 ` Sean Young
  2018-02-12 11:56   ` Miguel Ojeda
  2018-01-15  9:58 ` [PATCH 4/5] media: rc: add keymap for Dign Remote Sean Young
  2018-01-15  9:58 ` [PATCH 5/5] media: rc: new driver for Sasem Remote Controller VFD/IR Sean Young
  4 siblings, 1 reply; 13+ messages in thread
From: Sean Young @ 2018-01-15  9:58 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, linux-media

The NEC µPD16314 can alter the the brightness of the LCD. Make it possible
to set this via escape sequence Y0 - Y3. B and R were already taken, so
I picked Y for luminance.

Signed-off-by: Sean Young <sean@mess.org>
---
 drivers/auxdisplay/charlcd.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
index a16c72779722..7a671ad959d1 100644
--- a/drivers/auxdisplay/charlcd.c
+++ b/drivers/auxdisplay/charlcd.c
@@ -39,6 +39,8 @@
 #define LCD_FLAG_F		0x0020	/* Large font mode */
 #define LCD_FLAG_N		0x0040	/* 2-rows mode */
 #define LCD_FLAG_L		0x0080	/* Backlight enabled */
+#define LCD_BRIGHTNESS_MASK	0x0300	/* Brightness */
+#define LCD_BRIGHTNESS_SHIFT	8
 
 /* LCD commands */
 #define LCD_CMD_DISPLAY_CLEAR	0x01	/* Clear entire display */
@@ -490,6 +492,17 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 		charlcd_gotoxy(lcd);
 		processed = 1;
 		break;
+	case 'Y':	/* brightness (luma) */
+		switch (esc[1]) {
+		case '0':	/* 25% */
+		case '1':	/* 50% */
+		case '2':	/* 75% */
+		case '3':	/* 100% */
+			priv->flags = (priv->flags & ~(LCD_BRIGHTNESS_MASK)) |
+				(('3' - esc[1]) << LCD_BRIGHTNESS_SHIFT);
+			processed =  1;
+			break;
+		}
 	}
 
 	/* TODO: This indent party here got ugly, clean it! */
@@ -507,12 +520,15 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
 			((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))
+	else if ((oldflags ^ priv->flags) & (LCD_FLAG_F | LCD_FLAG_N |
+					     LCD_BRIGHTNESS_MASK))
 		lcd->ops->write_cmd(lcd,
 			LCD_CMD_FUNCTION_SET |
 			((lcd->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));
+			((priv->flags & LCD_FLAG_N) ? LCD_CMD_TWO_LINES : 0) |
+			((priv->flags & LCD_BRIGHTNESS_MASK) >>
+							LCD_BRIGHTNESS_SHIFT));
 	/* check whether L flag was changed */
 	else if ((oldflags ^ priv->flags) & LCD_FLAG_L)
 		charlcd_backlight(lcd, !!(priv->flags & LCD_FLAG_L));
-- 
2.14.3

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

* [PATCH 4/5] media: rc: add keymap for Dign Remote
  2018-01-15  9:58 [PATCH 0/5] new driver for Ahanix D.Vine 5 IR/VFD Sean Young
                   ` (2 preceding siblings ...)
  2018-01-15  9:58 ` [PATCH 3/5] auxdisplay: charlcd: add escape sequence for brightness on NEC µPD16314 Sean Young
@ 2018-01-15  9:58 ` Sean Young
  2018-01-15  9:58 ` [PATCH 5/5] media: rc: new driver for Sasem Remote Controller VFD/IR Sean Young
  4 siblings, 0 replies; 13+ messages in thread
From: Sean Young @ 2018-01-15  9:58 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, linux-media

This is the remote which comes with the Ahanix D.Vine 5 HTPC case.

Signed-off-by: Sean Young <sean@mess.org>
---
 drivers/media/rc/keymaps/Makefile  |  1 +
 drivers/media/rc/keymaps/rc-dign.c | 70 ++++++++++++++++++++++++++++++++++++++
 include/media/rc-map.h             |  1 +
 3 files changed, 72 insertions(+)
 create mode 100644 drivers/media/rc/keymaps/rc-dign.c

diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 50b319355edf..5a7aebe12285 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
 			rc-dib0700-rc5.o \
 			rc-digitalnow-tinytwin.o \
 			rc-digittrade.o \
+			rc-dign.o \
 			rc-dm1105-nec.o \
 			rc-dntv-live-dvb-t.o \
 			rc-dntv-live-dvbt-pro.o \
diff --git a/drivers/media/rc/keymaps/rc-dign.c b/drivers/media/rc/keymaps/rc-dign.c
new file mode 100644
index 000000000000..a70bb5f89278
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-dign.c
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Keymap for Dign Remote for Ahanix D.Vine 5 Case
+//
+// Copyright (C) 2018 by Sean Young <sean@mess.org>
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+static struct rc_map_table dign[] = {
+	{ 0x8000, KEY_POWER },
+	{ 0x8002, KEY_EJECTCD },
+	{ 0x8008, KEY_1 },
+	{ 0x8009, KEY_2 },
+	{ 0x800a, KEY_3 },
+	{ 0x8010, KEY_4 },
+	{ 0x8011, KEY_5 },
+	{ 0x8012, KEY_6 },
+	{ 0x8018, KEY_7 },
+	{ 0x8019, KEY_8 },
+	{ 0x801a, KEY_9 },
+
+	{ 0x8040, KEY_ENTER }, /* Start/Windows */
+	{ 0x8041, KEY_0 },
+	{ 0x8006, KEY_MENU },
+
+	{ 0x800f, KEY_VOLUMEDOWN },
+	{ 0x800e, KEY_VOLUMEUP },
+
+	{ 0x8005, KEY_ESC },
+	{ 0x8007, KEY_CLOSE },
+	{ 0x800b, KEY_UP },
+	{ 0x8003, KEY_LEFT },
+	{ 0x801b, KEY_RIGHT },
+	{ 0x8043, KEY_DOWN },
+	{ 0x8013, KEY_ENTER },
+
+	{ 0x800c, KEY_PREVIOUSSONG },
+	{ 0x8001, KEY_NEXTSONG },
+
+	{ 0x800d, KEY_MUTE },
+	{ 0x8004, KEY_FRAMEFORWARD }, /* Step */
+	{ 0x8049, KEY_PLAYPAUSE },
+	{ 0x8048, KEY_STOP },
+};
+
+static struct rc_map_list dign_map = {
+	.map = {
+		.scan     = dign,
+		.size     = ARRAY_SIZE(dign),
+		.rc_proto = RC_PROTO_NEC,
+		.name     = RC_MAP_DIGN,
+	}
+};
+
+static int __init init_rc_map_dign(void)
+{
+	return rc_map_register(&dign_map);
+}
+
+static void __exit exit_rc_map_dign(void)
+{
+	rc_map_unregister(&dign_map);
+}
+
+module_init(init_rc_map_dign)
+module_exit(exit_rc_map_dign)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sean Young <sean@mess.org>");
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 7046734b3895..1c0016af45a1 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -185,6 +185,7 @@ struct rc_map *rc_map_get(const char *name);
 #define RC_MAP_DIB0700_RC5_TABLE         "rc-dib0700-rc5"
 #define RC_MAP_DIGITALNOW_TINYTWIN       "rc-digitalnow-tinytwin"
 #define RC_MAP_DIGITTRADE                "rc-digittrade"
+#define RC_MAP_DIGN			 "rc-dign"
 #define RC_MAP_DM1105_NEC                "rc-dm1105-nec"
 #define RC_MAP_DNTV_LIVE_DVBT_PRO        "rc-dntv-live-dvbt-pro"
 #define RC_MAP_DNTV_LIVE_DVB_T           "rc-dntv-live-dvb-t"
-- 
2.14.3

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

* [PATCH 5/5] media: rc: new driver for Sasem Remote Controller VFD/IR
  2018-01-15  9:58 [PATCH 0/5] new driver for Ahanix D.Vine 5 IR/VFD Sean Young
                   ` (3 preceding siblings ...)
  2018-01-15  9:58 ` [PATCH 4/5] media: rc: add keymap for Dign Remote Sean Young
@ 2018-01-15  9:58 ` Sean Young
  4 siblings, 0 replies; 13+ messages in thread
From: Sean Young @ 2018-01-15  9:58 UTC (permalink / raw)
  To: Miguel Ojeda Sandonis, linux-media

This device is built into the Ahanix D.Vine 5 HTPC case. It has an LCD
device, and an IR receiver.

The LCD can be controlled via the charlcd driver. Unfortunately the device
does not seem to provide a method for accessing the character generator
ram.

Signed-off-by: Sean Young <sean@mess.org>
---
 MAINTAINERS                 |   6 +
 drivers/media/rc/Kconfig    |  16 +++
 drivers/media/rc/Makefile   |   1 +
 drivers/media/rc/sasem_ir.c | 297 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 320 insertions(+)
 create mode 100644 drivers/media/rc/sasem_ir.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 58797b83dd8d..a06801032ee3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12066,6 +12066,12 @@ F:	drivers/phy/samsung/phy-s5pv210-usb2.c
 F:	drivers/phy/samsung/phy-samsung-usb2.c
 F:	drivers/phy/samsung/phy-samsung-usb2.h
 
+SASEM REMOTE CONTROLLER
+M:	Sean Young <sean@mess.org>
+L:	linux-media@vger.kernel.org
+S:	Maintained
+F:	drivers/media/rc/sasem_ir.c
+
 SC1200 WDT DRIVER
 M:	Zwane Mwaikambo <zwanem@gmail.com>
 S:	Maintained
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index 7919f4a36ad2..bffa39e06a68 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -457,6 +457,22 @@ config IR_SERIAL
 	   To compile this driver as a module, choose M here: the module will
 	   be called serial-ir.
 
+config IR_SASEM
+	tristate "Sasem Remote Controller"
+	depends on USB_ARCH_HAS_HCD
+	depends on RC_CORE
+	select USB
+	select CHARLCD
+	---help---
+	   Driver for the Sasem OnAir Remocon-V or Dign HV5 HTPC IR/VFD Module
+
+	   The LCD can be controlled via the charlcd driver. Unfortunately the
+	   device does not seem to provide a method for accessing the
+	   character generator ram.
+
+	   To compile this driver as a module, choose M here: the module will
+	   be called sesam_ir.
+
 config IR_SERIAL_TRANSMITTER
 	bool "Serial Port Transmitter"
 	default y
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index e098e127b26a..9b474c8b49dc 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o
 obj-$(CONFIG_RC_ST) += st_rc.o
 obj-$(CONFIG_IR_SUNXI) += sunxi-cir.o
 obj-$(CONFIG_IR_IMG) += img-ir/
+obj-$(CONFIG_IR_SASEM) += sasem_ir.o
 obj-$(CONFIG_IR_SERIAL) += serial_ir.o
 obj-$(CONFIG_IR_SIR) += sir_ir.o
 obj-$(CONFIG_IR_MTK) += mtk-cir.o
diff --git a/drivers/media/rc/sasem_ir.c b/drivers/media/rc/sasem_ir.c
new file mode 100644
index 000000000000..33d3b8bdb56d
--- /dev/null
+++ b/drivers/media/rc/sasem_ir.c
@@ -0,0 +1,297 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (C) 2018 Sean Young <sean@mess.org>
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/input.h>
+#include <misc/charlcd.h>
+
+#include <media/rc-core.h>
+
+struct sasem {
+	struct device *dev;
+	struct urb *ir_urb;
+	struct urb *vfd_urb;
+	struct rc_dev *rcdev;
+	struct completion completion;
+	u8 ir_buf[8];
+	u8 vfd_buf[8];
+	unsigned int offset;
+	char phys[64];
+};
+
+static void sasem_ir_rx(struct urb *urb)
+{
+	struct sasem *sasem = urb->context;
+	enum rc_proto proto;
+	u32 code;
+	int ret;
+
+	switch (urb->status) {
+	case 0:
+		dev_dbg(sasem->dev, "data: %*ph", 8, sasem->ir_buf);
+		/*
+		 * Note that sanyo and jvc protocols are also supported,
+		 * but the scancode seems garbled. More testing needed.
+		 */
+		switch (sasem->ir_buf[0]) {
+		case 0xc:
+			code = ir_nec_bytes_to_scancode(sasem->ir_buf[1],
+				sasem->ir_buf[2], sasem->ir_buf[3],
+				sasem->ir_buf[4], &proto);
+			rc_keydown(sasem->rcdev, proto, code, 0);
+			break;
+		case 0x8:
+			rc_repeat(sasem->rcdev);
+			break;
+		}
+		break;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		usb_unlink_urb(urb);
+		return;
+	case -EPIPE:
+	default:
+		dev_dbg(sasem->dev, "error: urb status = %d", urb->status);
+		break;
+	}
+
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	if (ret && ret != -ENODEV)
+		dev_warn(sasem->dev, "failed to resubmit urb: %d", ret);
+}
+
+static void sasem_vfd_complete(struct urb *urb)
+{
+	struct sasem *sasem = urb->context;
+
+	if (urb->status)
+		dev_info(sasem->dev, "error: vfd urb status = %d", urb->status);
+
+	complete(&sasem->completion);
+}
+
+static int sasem_vfd_send(struct sasem *sasem)
+{
+	int ret;
+
+	reinit_completion(&sasem->completion);
+
+	ret = usb_submit_urb(sasem->vfd_urb, GFP_KERNEL);
+	if (ret)
+		return ret;
+
+	if (wait_for_completion_timeout(&sasem->completion, 1000) == 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static void sasem_lcd_flush(struct charlcd *lcd)
+{
+	struct sasem *sasem = lcd->drvdata;
+
+	if (sasem->offset > 0) {
+		while (sasem->offset < 8)
+			sasem->vfd_buf[sasem->offset++] = 0;
+
+		sasem_vfd_send(sasem);
+
+		sasem->offset = 0;
+	}
+}
+
+static void sasem_lcd_write_cmd(struct charlcd *lcd, int cmd)
+{
+	struct sasem *sasem = lcd->drvdata;
+
+	dev_dbg(sasem->dev, "lcd_write_cmd: %02x", cmd);
+
+	if (sasem->offset >= 6)
+		sasem_lcd_flush(lcd);
+
+	if (cmd & 0x80) {
+		sasem->vfd_buf[sasem->offset++] = 0x09;
+		sasem->vfd_buf[sasem->offset++] = ((cmd & 0x7f) + 1) ^ 0x40;
+	} else {
+		sasem->vfd_buf[sasem->offset++] = 0x07;
+
+		/* The interface between Sasem and NEC µPD16314 is 4-bit */
+		if ((cmd & 0xe0) == 0x20)
+			cmd &= ~0x10;
+		sasem->vfd_buf[sasem->offset++] = cmd;
+	}
+}
+
+static void sasem_lcd_write_data(struct charlcd *lcd, int data)
+{
+	struct sasem *sasem = lcd->drvdata;
+
+	dev_dbg(sasem->dev, "lcd_write_data: %02x", data);
+
+	if (sasem->offset >= 7)
+		sasem_lcd_flush(lcd);
+
+	sasem->vfd_buf[sasem->offset++] = data;
+}
+
+static const struct charlcd_ops sasem_lcd_ops = {
+	.write_cmd = sasem_lcd_write_cmd,
+	.write_data = sasem_lcd_write_data,
+	.flush = sasem_lcd_flush
+};
+
+static int sasem_probe(struct usb_interface *intf,
+		       const struct usb_device_id *id)
+{
+	struct usb_endpoint_descriptor *ir_ep = NULL;
+	struct usb_endpoint_descriptor *vfd_ep = NULL;
+	struct usb_host_interface *idesc;
+	struct usb_device *udev;
+	struct rc_dev *rcdev;
+	struct charlcd *lcd;
+	struct sasem *sasem;
+	int i, ret;
+
+	udev = interface_to_usbdev(intf);
+	idesc = intf->cur_altsetting;
+
+	for (i = 0; i < idesc->desc.bNumEndpoints; i++) {
+		struct usb_endpoint_descriptor *ep = &idesc->endpoint[i].desc;
+
+		if (usb_endpoint_is_int_in(ep) && !ir_ep)
+			ir_ep = ep;
+		else if (usb_endpoint_is_int_out(ep) && !vfd_ep)
+			vfd_ep = ep;
+	}
+
+	if (!ir_ep || !vfd_ep) {
+		dev_err(&intf->dev, "usb endpoint missing");
+		return -ENODEV;
+	}
+
+	lcd = charlcd_alloc(sizeof(*sasem));
+	if (!lcd)
+		return -ENOMEM;
+
+	sasem = lcd->drvdata;
+
+	sasem->ir_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!sasem->ir_urb) {
+		ret = -ENOMEM;
+		goto out_free;
+	}
+
+	sasem->dev = &intf->dev;
+	usb_fill_int_urb(sasem->ir_urb, udev,
+			 usb_rcvintpipe(udev, ir_ep->bEndpointAddress),
+			 sasem->ir_buf, sizeof(sasem->ir_buf),
+			 sasem_ir_rx, sasem, ir_ep->bInterval);
+
+	rcdev = devm_rc_allocate_device(&intf->dev, RC_DRIVER_SCANCODE);
+	if (!rcdev) {
+		ret = -ENOMEM;
+		goto out_free;
+	}
+
+	usb_make_path(udev, sasem->phys, sizeof(sasem->phys));
+
+	rcdev->device_name = "Sasem Remote Controller";
+	rcdev->driver_name = KBUILD_MODNAME;
+	rcdev->input_phys = sasem->phys;
+	usb_to_input_id(udev, &rcdev->input_id);
+	rcdev->dev.parent = &intf->dev;
+	rcdev->allowed_protocols = RC_PROTO_BIT_NEC;
+	rcdev->map_name = RC_MAP_DIGN;
+	rcdev->priv = sasem;
+
+	ret = devm_rc_register_device(&intf->dev, rcdev);
+	if (ret)
+		goto out_free;
+
+	sasem->rcdev = rcdev;
+
+	lcd->height = 2;
+	lcd->width = 16;
+	lcd->bwidth = 16;
+	lcd->ops = &sasem_lcd_ops;
+
+	init_completion(&sasem->completion);
+
+	sasem->vfd_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!sasem->vfd_urb) {
+		ret = -ENOMEM;
+		goto out_free;
+	}
+
+	usb_fill_int_urb(sasem->vfd_urb, udev,
+			 usb_sndintpipe(udev, vfd_ep->bEndpointAddress),
+			 sasem->vfd_buf, sizeof(sasem->vfd_buf),
+			 sasem_vfd_complete, sasem, vfd_ep->bInterval);
+
+	/*
+	 * After usb is plugged in, the device programs the LCD with
+	 * 'Welcome DIGN Home Theatre PC'. Wait for this to complete,
+	 * else our commands will be mixed up with these commands.
+	 */
+	msleep(20);
+
+	ret = charlcd_register(lcd);
+	if (ret)
+		goto out_free;
+
+	ret = usb_submit_urb(sasem->ir_urb, GFP_KERNEL);
+	if (ret)
+		goto out_lcd;
+
+	usb_set_intfdata(intf, lcd);
+
+	return 0;
+
+out_lcd:
+	charlcd_unregister(lcd);
+out_free:
+	usb_free_urb(sasem->ir_urb);
+	usb_free_urb(sasem->vfd_urb);
+	kfree(lcd);
+
+	return ret;
+}
+
+static void sasem_disconnect(struct usb_interface *intf)
+{
+	struct charlcd *lcd = usb_get_intfdata(intf);
+	struct sasem *sasem = lcd->drvdata;
+
+	charlcd_unregister(lcd);
+
+	usb_kill_urb(sasem->ir_urb);
+	usb_free_urb(sasem->ir_urb);
+	usb_kill_urb(sasem->vfd_urb);
+	usb_free_urb(sasem->vfd_urb);
+
+	kfree(lcd);
+}
+
+static const struct usb_device_id sasem_table[] = {
+	/* Sasem USB Control Board */
+	{ USB_DEVICE(0x11ba, 0x0101) },
+
+	{}
+};
+
+static struct usb_driver sasem_driver = {
+	.name = KBUILD_MODNAME,
+	.probe = sasem_probe,
+	.disconnect = sasem_disconnect,
+	.id_table = sasem_table
+};
+
+module_usb_driver(sasem_driver);
+
+MODULE_DESCRIPTION("Sasem Remote Controller");
+MODULE_AUTHOR("Sean Young <sean@mess.org>");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(usb, sasem_table);
-- 
2.14.3

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

* Re: [PATCH 3/5] auxdisplay: charlcd: add escape sequence for brightness on NEC µPD16314
  2018-01-15  9:58 ` [PATCH 3/5] auxdisplay: charlcd: add escape sequence for brightness on NEC µPD16314 Sean Young
@ 2018-02-12 11:56   ` Miguel Ojeda
  2018-02-13 17:34     ` Sean Young
  0 siblings, 1 reply; 13+ messages in thread
From: Miguel Ojeda @ 2018-02-12 11:56 UTC (permalink / raw)
  To: Sean Young; +Cc: linux-media, Willy Tarreau, Geert Uytterhoeven

On Mon, Jan 15, 2018 at 10:58 AM, Sean Young <sean@mess.org> wrote:
> The NEC µPD16314 can alter the the brightness of the LCD. Make it possible
> to set this via escape sequence Y0 - Y3. B and R were already taken, so
> I picked Y for luminance.
>
> Signed-off-by: Sean Young <sean@mess.org>

CC'ing Willy and Geert.

> ---
>  drivers/auxdisplay/charlcd.c | 20 ++++++++++++++++++--
>  1 file changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
> index a16c72779722..7a671ad959d1 100644
> --- a/drivers/auxdisplay/charlcd.c
> +++ b/drivers/auxdisplay/charlcd.c
> @@ -39,6 +39,8 @@
>  #define LCD_FLAG_F             0x0020  /* Large font mode */
>  #define LCD_FLAG_N             0x0040  /* 2-rows mode */
>  #define LCD_FLAG_L             0x0080  /* Backlight enabled */
> +#define LCD_BRIGHTNESS_MASK    0x0300  /* Brightness */
> +#define LCD_BRIGHTNESS_SHIFT   8

Not sure about the name (since the brightness is also used in
priv->flags). By the way, should we start using the bitops.h stuff
(e.g. BIT(9) | BIT(8), GENMASK(9, 8)...) in new code? Not sure how
widespread they are.

>
>  /* LCD commands */
>  #define LCD_CMD_DISPLAY_CLEAR  0x01    /* Clear entire display */
> @@ -490,6 +492,17 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
>                 charlcd_gotoxy(lcd);
>                 processed = 1;
>                 break;
> +       case 'Y':       /* brightness (luma) */
> +               switch (esc[1]) {
> +               case '0':       /* 25% */
> +               case '1':       /* 50% */
> +               case '2':       /* 75% */
> +               case '3':       /* 100% */
> +                       priv->flags = (priv->flags & ~(LCD_BRIGHTNESS_MASK)) |
> +                               (('3' - esc[1]) << LCD_BRIGHTNESS_SHIFT);
> +                       processed =  1;
> +                       break;
> +               }
>         }
>
>         /* TODO: This indent party here got ugly, clean it! */
> @@ -507,12 +520,15 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
>                         ((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 */

Should we add "or brightness" to the comment?

> -       else if ((oldflags ^ priv->flags) & (LCD_FLAG_F | LCD_FLAG_N))
> +       else if ((oldflags ^ priv->flags) & (LCD_FLAG_F | LCD_FLAG_N |
> +                                            LCD_BRIGHTNESS_MASK))
>                 lcd->ops->write_cmd(lcd,
>                         LCD_CMD_FUNCTION_SET |
>                         ((lcd->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));
> +                       ((priv->flags & LCD_FLAG_N) ? LCD_CMD_TWO_LINES : 0) |
> +                       ((priv->flags & LCD_BRIGHTNESS_MASK) >>
> +                                                       LCD_BRIGHTNESS_SHIFT));
>         /* check whether L flag was changed */
>         else if ((oldflags ^ priv->flags) & LCD_FLAG_L)
>                 charlcd_backlight(lcd, !!(priv->flags & LCD_FLAG_L));
> --
> 2.14.3
>

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

* Re: [PATCH 1/5] auxdisplay: charlcd: no need to call charlcd_gotoxy() if nothing changes
  2018-01-15  9:58 ` [PATCH 1/5] auxdisplay: charlcd: no need to call charlcd_gotoxy() if nothing changes Sean Young
@ 2018-02-12 13:42   ` Miguel Ojeda
  2018-02-12 13:59     ` Geert Uytterhoeven
  0 siblings, 1 reply; 13+ messages in thread
From: Miguel Ojeda @ 2018-02-12 13:42 UTC (permalink / raw)
  To: Sean Young, Willy Tarreau, Geert Uytterhoeven; +Cc: linux-media

On Mon, Jan 15, 2018 at 10:58 AM, Sean Young <sean@mess.org> wrote:
> If the line extends beyond the width to the screen, nothing changes. The
> existing code will call charlcd_gotoxy every time for this case.
>
> Signed-off-by: Sean Young <sean@mess.org>
> ---
>  drivers/auxdisplay/charlcd.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
> index 642afd88870b..45ec5ce697c4 100644
> --- a/drivers/auxdisplay/charlcd.c
> +++ b/drivers/auxdisplay/charlcd.c
> @@ -192,10 +192,11 @@ static void charlcd_print(struct charlcd *lcd, char c)
>                         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)
> +                       charlcd_gotoxy(lcd);
>         }
> -       /* prevents the cursor from wrapping onto the next line */
> -       if (priv->addr.x == lcd->bwidth)
> -               charlcd_gotoxy(lcd);
>  }
>

Willy, Geert: is this fine with you? Seems fine: charlcd_write_char()
right now does an unconditional write_cmd() when writing a normal
character; so unless some HW requires the command for some reason even
if there is nothing changed, we can skip it.

>  static void charlcd_clear_fast(struct charlcd *lcd)
> --
> 2.14.3
>

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

* Re: [PATCH 1/5] auxdisplay: charlcd: no need to call charlcd_gotoxy() if nothing changes
  2018-02-12 13:42   ` Miguel Ojeda
@ 2018-02-12 13:59     ` Geert Uytterhoeven
  2018-02-12 17:30       ` Miguel Ojeda
  0 siblings, 1 reply; 13+ messages in thread
From: Geert Uytterhoeven @ 2018-02-12 13:59 UTC (permalink / raw)
  To: Miguel Ojeda; +Cc: Sean Young, Willy Tarreau, Linux Media Mailing List

On Mon, Feb 12, 2018 at 2:42 PM, Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
> On Mon, Jan 15, 2018 at 10:58 AM, Sean Young <sean@mess.org> wrote:
>> If the line extends beyond the width to the screen, nothing changes. The
>> existing code will call charlcd_gotoxy every time for this case.
>>
>> Signed-off-by: Sean Young <sean@mess.org>
>> ---
>>  drivers/auxdisplay/charlcd.c | 7 ++++---
>>  1 file changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
>> index 642afd88870b..45ec5ce697c4 100644
>> --- a/drivers/auxdisplay/charlcd.c
>> +++ b/drivers/auxdisplay/charlcd.c
>> @@ -192,10 +192,11 @@ static void charlcd_print(struct charlcd *lcd, char c)
>>                         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)
>> +                       charlcd_gotoxy(lcd);
>>         }
>> -       /* prevents the cursor from wrapping onto the next line */
>> -       if (priv->addr.x == lcd->bwidth)
>> -               charlcd_gotoxy(lcd);
>>  }
>>
>
> Willy, Geert: is this fine with you? Seems fine: charlcd_write_char()
> right now does an unconditional write_cmd() when writing a normal
> character; so unless some HW requires the command for some reason even
> if there is nothing changed, we can skip it.

Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH 1/5] auxdisplay: charlcd: no need to call charlcd_gotoxy() if nothing changes
  2018-02-12 13:59     ` Geert Uytterhoeven
@ 2018-02-12 17:30       ` Miguel Ojeda
  0 siblings, 0 replies; 13+ messages in thread
From: Miguel Ojeda @ 2018-02-12 17:30 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Sean Young, Willy Tarreau, Linux Media Mailing List

On Mon, Feb 12, 2018 at 2:59 PM, Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
> On Mon, Feb 12, 2018 at 2:42 PM, Miguel Ojeda
> <miguel.ojeda.sandonis@gmail.com> wrote:
>> On Mon, Jan 15, 2018 at 10:58 AM, Sean Young <sean@mess.org> wrote:
>>> If the line extends beyond the width to the screen, nothing changes. The
>>> existing code will call charlcd_gotoxy every time for this case.
>>>
>>> Signed-off-by: Sean Young <sean@mess.org>
>>> ---
>>>  drivers/auxdisplay/charlcd.c | 7 ++++---
>>>  1 file changed, 4 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
>>> index 642afd88870b..45ec5ce697c4 100644
>>> --- a/drivers/auxdisplay/charlcd.c
>>> +++ b/drivers/auxdisplay/charlcd.c
>>> @@ -192,10 +192,11 @@ static void charlcd_print(struct charlcd *lcd, char c)
>>>                         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)
>>> +                       charlcd_gotoxy(lcd);
>>>         }
>>> -       /* prevents the cursor from wrapping onto the next line */
>>> -       if (priv->addr.x == lcd->bwidth)
>>> -               charlcd_gotoxy(lcd);
>>>  }
>>>
>>
>> Willy, Geert: is this fine with you? Seems fine: charlcd_write_char()
>> right now does an unconditional write_cmd() when writing a normal
>> character; so unless some HW requires the command for some reason even
>> if there is nothing changed, we can skip it.
>
> Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
>

Thanks a lot, picking it up then.

Miguel

> Gr{oetje,eeting}s,
>
>                         Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds

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

* Re: [PATCH 2/5] auxdisplay: charlcd: add flush function
  2018-01-15  9:58 ` [PATCH 2/5] auxdisplay: charlcd: add flush function Sean Young
@ 2018-02-12 20:44   ` Miguel Ojeda
  2018-02-13 13:47     ` Andy Shevchenko
  0 siblings, 1 reply; 13+ messages in thread
From: Miguel Ojeda @ 2018-02-12 20:44 UTC (permalink / raw)
  To: Sean Young, Arnd Bergmann, Greg KH; +Cc: Linux Media Mailing List

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
>

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

* Re: [PATCH 2/5] auxdisplay: charlcd: add flush function
  2018-02-12 20:44   ` Miguel Ojeda
@ 2018-02-13 13:47     ` Andy Shevchenko
  0 siblings, 0 replies; 13+ messages in thread
From: Andy Shevchenko @ 2018-02-13 13:47 UTC (permalink / raw)
  To: Miguel Ojeda; +Cc: Sean Young, Arnd Bergmann, Greg KH, Linux Media Mailing List

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/.

-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH 3/5] auxdisplay: charlcd: add escape sequence for brightness on NEC µPD16314
  2018-02-12 11:56   ` Miguel Ojeda
@ 2018-02-13 17:34     ` Sean Young
  0 siblings, 0 replies; 13+ messages in thread
From: Sean Young @ 2018-02-13 17:34 UTC (permalink / raw)
  To: Miguel Ojeda; +Cc: linux-media, Willy Tarreau, Geert Uytterhoeven

On Mon, Feb 12, 2018 at 12:56:58PM +0100, Miguel Ojeda wrote:
> On Mon, Jan 15, 2018 at 10:58 AM, Sean Young <sean@mess.org> wrote:
> > The NEC µPD16314 can alter the the brightness of the LCD. Make it possible
> > to set this via escape sequence Y0 - Y3. B and R were already taken, so
> > I picked Y for luminance.
> >
> > Signed-off-by: Sean Young <sean@mess.org>
> 
> CC'ing Willy and Geert.
> 
> > ---
> >  drivers/auxdisplay/charlcd.c | 20 ++++++++++++++++++--
> >  1 file changed, 18 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c
> > index a16c72779722..7a671ad959d1 100644
> > --- a/drivers/auxdisplay/charlcd.c
> > +++ b/drivers/auxdisplay/charlcd.c
> > @@ -39,6 +39,8 @@
> >  #define LCD_FLAG_F             0x0020  /* Large font mode */
> >  #define LCD_FLAG_N             0x0040  /* 2-rows mode */
> >  #define LCD_FLAG_L             0x0080  /* Backlight enabled */
> > +#define LCD_BRIGHTNESS_MASK    0x0300  /* Brightness */
> > +#define LCD_BRIGHTNESS_SHIFT   8
> 
> Not sure about the name (since the brightness is also used in
> priv->flags). By the way, should we start using the bitops.h stuff
> (e.g. BIT(9) | BIT(8), GENMASK(9, 8)...) in new code? Not sure how
> widespread they are.

The brightness is not really a flag, maybe it belongs in a separate field;
we could use bit fields in order to waste less space.

BIT() would be nicer and is more idiomatic by current standards.

Note that x, y and flags are currently unsigned long, they could be u8.

> 
> >
> >  /* LCD commands */
> >  #define LCD_CMD_DISPLAY_CLEAR  0x01    /* Clear entire display */
> > @@ -490,6 +492,17 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
> >                 charlcd_gotoxy(lcd);
> >                 processed = 1;
> >                 break;
> > +       case 'Y':       /* brightness (luma) */
> > +               switch (esc[1]) {
> > +               case '0':       /* 25% */
> > +               case '1':       /* 50% */
> > +               case '2':       /* 75% */
> > +               case '3':       /* 100% */
> > +                       priv->flags = (priv->flags & ~(LCD_BRIGHTNESS_MASK)) |
> > +                               (('3' - esc[1]) << LCD_BRIGHTNESS_SHIFT);
> > +                       processed =  1;
> > +                       break;
> > +               }
> >         }
> >
> >         /* TODO: This indent party here got ugly, clean it! */
> > @@ -507,12 +520,15 @@ static inline int handle_lcd_special_code(struct charlcd *lcd)
> >                         ((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 */
> 
> Should we add "or brightness" to the comment?

Indeed we should.

> 
> > -       else if ((oldflags ^ priv->flags) & (LCD_FLAG_F | LCD_FLAG_N))
> > +       else if ((oldflags ^ priv->flags) & (LCD_FLAG_F | LCD_FLAG_N |
> > +                                            LCD_BRIGHTNESS_MASK))
> >                 lcd->ops->write_cmd(lcd,
> >                         LCD_CMD_FUNCTION_SET |
> >                         ((lcd->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));
> > +                       ((priv->flags & LCD_FLAG_N) ? LCD_CMD_TWO_LINES : 0) |
> > +                       ((priv->flags & LCD_BRIGHTNESS_MASK) >>
> > +                                                       LCD_BRIGHTNESS_SHIFT));
> >         /* check whether L flag was changed */
> >         else if ((oldflags ^ priv->flags) & LCD_FLAG_L)
> >                 charlcd_backlight(lcd, !!(priv->flags & LCD_FLAG_L));
> > --
> > 2.14.3
> >

I've discovered an issue in my sasem driver, I'll send out a new version
of these patch series once that is resolved.

Thanks,

Sean

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

end of thread, other threads:[~2018-02-13 17:34 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-15  9:58 [PATCH 0/5] new driver for Ahanix D.Vine 5 IR/VFD Sean Young
2018-01-15  9:58 ` [PATCH 1/5] auxdisplay: charlcd: no need to call charlcd_gotoxy() if nothing changes Sean Young
2018-02-12 13:42   ` Miguel Ojeda
2018-02-12 13:59     ` Geert Uytterhoeven
2018-02-12 17:30       ` Miguel Ojeda
2018-01-15  9:58 ` [PATCH 2/5] auxdisplay: charlcd: add flush function Sean Young
2018-02-12 20:44   ` Miguel Ojeda
2018-02-13 13:47     ` Andy Shevchenko
2018-01-15  9:58 ` [PATCH 3/5] auxdisplay: charlcd: add escape sequence for brightness on NEC µPD16314 Sean Young
2018-02-12 11:56   ` Miguel Ojeda
2018-02-13 17:34     ` Sean Young
2018-01-15  9:58 ` [PATCH 4/5] media: rc: add keymap for Dign Remote Sean Young
2018-01-15  9:58 ` [PATCH 5/5] media: rc: new driver for Sasem Remote Controller VFD/IR Sean Young

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.