linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4l-utils 1/4] keytable: support 64 bit scancodes
@ 2020-01-29 11:54 Sean Young
  2020-01-29 11:54 ` [PATCH v2] media: rc: make scancodes 64 bit Sean Young
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Sean Young @ 2020-01-29 11:54 UTC (permalink / raw)
  To: linux-media; +Cc: Frank Wunderlich

Signed-off-by: Sean Young <sean@mess.org>
---
 utils/common/keymap.c     |  4 +-
 utils/common/keymap.h     |  4 +-
 utils/keytable/keytable.c | 80 +++++++++++++++++++++++++++------------
 3 files changed, 59 insertions(+), 29 deletions(-)

diff --git a/utils/common/keymap.c b/utils/common/keymap.c
index d06deb59..15c31c76 100644
--- a/utils/common/keymap.c
+++ b/utils/common/keymap.c
@@ -162,7 +162,7 @@ static error_t parse_plain_keymap(char *fname, struct keymap **keymap, bool verb
 			return ENOMEM;
 		}
 
-		se->scancode = strtoul(scancode, NULL, 0);
+		se->scancode = strtoull(scancode, NULL, 0);
 		se->keycode = strdup(keycode);
 		se->next = map->scancode;
 		map->scancode = se;
@@ -442,7 +442,7 @@ static error_t parse_toml_protocol(const char *fname, struct toml_table_t *proot
 			return ENOMEM;
 		}
 
-		se->scancode = strtoul(scancode, NULL, 0);
+		se->scancode = strtoull(scancode, NULL, 0);
 		se->keycode = keycode;
 		*next = se;
 		next = &se->next;
diff --git a/utils/common/keymap.h b/utils/common/keymap.h
index f2b29632..99833827 100644
--- a/utils/common/keymap.h
+++ b/utils/common/keymap.h
@@ -20,13 +20,13 @@ struct protocol_param {
 
 struct scancode_entry {
 	struct scancode_entry *next;
-	u_int32_t scancode;
+	u_int64_t scancode;
 	char *keycode;
 };
 
 struct raw_entry {
 	struct raw_entry *next;
-	u_int32_t scancode;
+	u_int64_t scancode;
 	u_int32_t raw_length;
 	char *keycode;
 	u_int32_t raw[1];
diff --git a/utils/keytable/keytable.c b/utils/keytable/keytable.c
index e2a1bfe1..cc1b5217 100644
--- a/utils/keytable/keytable.c
+++ b/utils/keytable/keytable.c
@@ -76,7 +76,8 @@ struct input_keymap_entry_v2 {
 #endif
 
 struct keytable_entry {
-	u_int32_t scancode;
+	// 64 bit int which can printed with %llx
+	unsigned long long scancode;
 	u_int32_t keycode;
 	struct keytable_entry *next;
 };
@@ -400,7 +401,7 @@ static int add_keymap(struct keymap *map, const char *fname)
 			if (value == -1) {
 				value = strtol(se->keycode, &p, 0);
 				if (errno || *p) {
-					fprintf(stderr, _("%s: keycode `%s' not recognised, no mapping for scancode %d\n"), fname, se->keycode, se->scancode);
+					fprintf(stderr, _("%s: keycode `%s' not recognised, no mapping for scancode %llx\n"), fname, se->keycode, (unsigned long long)se->scancode);
 					continue;
 				}
 			}
@@ -589,7 +590,7 @@ static error_t parse_opt(int k, char *arg, struct argp_state *state)
 				return ENOMEM;
 			}
 
-			ke->scancode = strtoul(p, NULL, 0);
+			ke->scancode = strtoull(p, NULL, 0);
 			if (errno) {
 				free(ke);
 				argp_error(state, _("Invalid scancode: %s"), p);
@@ -616,7 +617,7 @@ static error_t parse_opt(int k, char *arg, struct argp_state *state)
 			ke->keycode = key;
 
 			if (debug)
-				fprintf(stderr, _("scancode 0x%04x=%u\n"),
+				fprintf(stderr, _("scancode 0x%04llx=%u\n"),
 					ke->scancode, ke->keycode);
 
 			ke->next = keytable;
@@ -722,21 +723,21 @@ static struct argp argp = {
 	.doc = doc,
 };
 
-static void prtcode(int *codes)
+static void prtcode(unsigned long long scancode, int keycode)
 {
 	struct parse_event *p;
 
 	for (p = key_events; p->name != NULL; p++) {
-		if (p->value == (unsigned)codes[1]) {
-			printf(_("scancode 0x%04x = %s (0x%02x)\n"), codes[0], p->name, codes[1]);
+		if (p->value == keycode) {
+			printf(_("scancode 0x%04llx = %s (0x%02x)\n"), scancode, p->name, keycode);
 			return;
 		}
 	}
 
-	if (isprint (codes[1]))
-		printf(_("scancode 0x%04x = '%c' (0x%02x)\n"), codes[0], codes[1], codes[1]);
+	if (isprint (keycode))
+		printf(_("scancode 0x%04llx = '%c' (0x%02x)\n"), scancode, keycode, keycode);
 	else
-		printf(_("scancode 0x%04x = 0x%02x\n"), codes[0], codes[1]);
+		printf(_("scancode 0x%04llx = 0x%02x\n"), scancode, keycode);
 }
 
 static void free_names(struct sysfs_names *names)
@@ -1399,17 +1400,34 @@ static int add_keys(int fd)
 	for (ke = keytable; ke; ke = ke->next) {
 		write_cnt++;
 		if (debug)
-			fprintf(stderr, "\t%04x=%04x\n",
+			fprintf(stderr, "\t%04llx=%04x\n",
 				ke->scancode, ke->keycode);
 
 		codes[0] = ke->scancode;
 		codes[1] = ke->keycode;
 
-		if (ioctl(fd, EVIOCSKEYCODE, codes)) {
-			fprintf(stderr,
-				_("Setting scancode 0x%04x with 0x%04x via "),
-				ke->scancode, ke->keycode);
-			perror("EVIOCSKEYCODE");
+		if (codes[0] != ke->scancode) {
+			// 64 bit scancode
+			struct input_keymap_entry_v2 entry = {
+				.keycode = ke->keycode,
+				.len = sizeof(ke->scancode)
+			};
+
+			memcpy(entry.scancode, &ke->scancode, sizeof(ke->scancode));
+
+			if (ioctl(fd, EVIOCSKEYCODE_V2, &entry)) {
+				fprintf(stderr,
+					_("Setting scancode 0x%04llx with 0x%04x via "),
+					ke->scancode, ke->keycode);
+				perror("EVIOCSKEYCODE");
+			}
+		} else {
+			if (ioctl(fd, EVIOCSKEYCODE, codes)) {
+				fprintf(stderr,
+					_("Setting scancode 0x%04llx with 0x%04x via "),
+					ke->scancode, ke->keycode);
+				perror("EVIOCSKEYCODE");
+			}
 		}
 	}
 
@@ -1596,7 +1614,7 @@ static void display_table_v1(struct rc_device *rc_dev, int fd)
 			if (ioctl(fd, EVIOCGKEYCODE, codes) == -1)
 				perror("EVIOCGKEYCODE");
 			else if (codes[1] != KEY_RESERVED)
-				prtcode(codes);
+				prtcode(codes[0], codes[1]);
 		}
 	}
 	display_proto(rc_dev);
@@ -1604,25 +1622,37 @@ static void display_table_v1(struct rc_device *rc_dev, int fd)
 
 static void display_table_v2(struct rc_device *rc_dev, int fd)
 {
+	struct input_keymap_entry_v2 entry = {};
+	unsigned long long scancode;
 	int i;
-	struct input_keymap_entry_v2 entry;
-	int codes[2];
 
-	memset(&entry, '\0', sizeof(entry));
 	i = 0;
 	do {
 		entry.flags = KEYMAP_BY_INDEX;
 		entry.index = i;
-		entry.len = sizeof(u_int32_t);
+		entry.len = sizeof(scancode);
 
 		if (ioctl(fd, EVIOCGKEYCODE_V2, &entry) == -1)
 			break;
 
-		/* FIXME: Extend it to support scancodes > 32 bits */
-		memcpy(&codes[0], entry.scancode, sizeof(codes[0]));
-		codes[1] = entry.keycode;
+		if (entry.len == sizeof(u_int32_t)) {
+			u_int32_t temp;
+
+			memcpy(&temp, entry.scancode, sizeof(temp));
+
+			scancode = temp;
+		} else if (entry.len == sizeof(u_int64_t)) {
+			u_int64_t temp;
+
+			memcpy(&temp, entry.scancode, sizeof(temp));
+
+			scancode = temp;
+		} else {
+			printf("error: unknown scancode length %d\n", entry.len);
+			continue;
+		}
 
-		prtcode(codes);
+		prtcode(scancode, entry.keycode);
 		i++;
 	} while (1);
 	display_proto(rc_dev);
-- 
2.24.1


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

* [PATCH v2] media: rc: make scancodes 64 bit
  2020-01-29 11:54 [PATCH v4l-utils 1/4] keytable: support 64 bit scancodes Sean Young
@ 2020-01-29 11:54 ` Sean Young
  2020-03-02  9:31   ` Mauro Carvalho Chehab
  2020-01-29 11:54 ` [PATCH v4l-utils 2/4] keytable: new samsung36 bpf decoder Sean Young
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Sean Young @ 2020-01-29 11:54 UTC (permalink / raw)
  To: linux-media; +Cc: Frank Wunderlich

There are many protocols that encode more than 32 bit. We want 64 bit
support so that BPF IR decoders can decode more than 32 bit. None of
the existing kernel IR decoders/encoders support 64 bit, for now.

The MSC_SCAN event can only contain 32 bit scancodes, so we no longer
generate these input events. The full 64 bit scancode can be read from
the lirc chardev.

Signed-off-by: Sean Young <sean@mess.org>
---
 drivers/media/rc/bpf-lirc.c |  5 ---
 drivers/media/rc/lirc_dev.c |  7 +---
 drivers/media/rc/rc-main.c  | 77 ++++++++++++++++++++++++-------------
 include/media/rc-core.h     |  8 ++--
 include/media/rc-map.h      |  4 +-
 5 files changed, 58 insertions(+), 43 deletions(-)

diff --git a/drivers/media/rc/bpf-lirc.c b/drivers/media/rc/bpf-lirc.c
index 0a0ce620e4a2..0f3417d161b8 100644
--- a/drivers/media/rc/bpf-lirc.c
+++ b/drivers/media/rc/bpf-lirc.c
@@ -35,11 +35,6 @@ static const struct bpf_func_proto rc_repeat_proto = {
 	.arg1_type = ARG_PTR_TO_CTX,
 };
 
-/*
- * Currently rc-core does not support 64-bit scancodes, but there are many
- * known protocols with more than 32 bits. So, define the interface as u64
- * as a future-proof.
- */
 BPF_CALL_4(bpf_rc_keydown, u32*, sample, u32, protocol, u64, scancode,
 	   u32, toggle)
 {
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 9a8c1cf54ac4..583e4f32a0da 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -269,12 +269,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
 			goto out_unlock;
 		}
 
-		/*
-		 * The scancode field in lirc_scancode is 64-bit simply
-		 * to future-proof it, since there are IR protocols encode
-		 * use more than 32 bits. For now only 32-bit protocols
-		 * are supported.
-		 */
+		/* We only have encoders for 32-bit protocols. */
 		if (scan.scancode > U32_MAX ||
 		    !rc_validate_scancode(scan.rc_proto, scan.scancode)) {
 			ret = -EINVAL;
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 6f80c251f641..047b079c37eb 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -163,6 +163,41 @@ static struct rc_map_list empty_map = {
 	}
 };
 
+/**
+ * scancode_to_u64() - converts scancode in &struct input_keymap_entry
+ * @ke: keymap entry containing scancode to be converted.
+ * @scancode: pointer to the location where converted scancode should
+ *	be stored.
+ *
+ * This function is a version of input_scancode_to_scalar specialized for
+ * rc-core.
+ */
+static int scancode_to_u64(const struct input_keymap_entry *ke, u64 *scancode)
+{
+	switch (ke->len) {
+	case 1:
+		*scancode = *((u8 *)ke->scancode);
+		break;
+
+	case 2:
+		*scancode = *((u16 *)ke->scancode);
+		break;
+
+	case 4:
+		*scancode = *((u32 *)ke->scancode);
+		break;
+
+	case 8:
+		*scancode = *((u64 *)ke->scancode);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 /**
  * ir_create_table() - initializes a scancode table
  * @dev:	the rc_dev device
@@ -285,13 +320,13 @@ static unsigned int ir_update_mapping(struct rc_dev *dev,
 
 	/* Did the user wish to remove the mapping? */
 	if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) {
-		dev_dbg(&dev->dev, "#%d: Deleting scan 0x%04x\n",
+		dev_dbg(&dev->dev, "#%d: Deleting scan 0x%04llx\n",
 			index, rc_map->scan[index].scancode);
 		rc_map->len--;
 		memmove(&rc_map->scan[index], &rc_map->scan[index+ 1],
 			(rc_map->len - index) * sizeof(struct rc_map_table));
 	} else {
-		dev_dbg(&dev->dev, "#%d: %s scan 0x%04x with key 0x%04x\n",
+		dev_dbg(&dev->dev, "#%d: %s scan 0x%04llx with key 0x%04x\n",
 			index,
 			old_keycode == KEY_RESERVED ? "New" : "Replacing",
 			rc_map->scan[index].scancode, new_keycode);
@@ -334,8 +369,7 @@ static unsigned int ir_update_mapping(struct rc_dev *dev,
  */
 static unsigned int ir_establish_scancode(struct rc_dev *dev,
 					  struct rc_map *rc_map,
-					  unsigned int scancode,
-					  bool resize)
+					  u64 scancode, bool resize)
 {
 	unsigned int i;
 
@@ -394,7 +428,7 @@ static int ir_setkeycode(struct input_dev *idev,
 	struct rc_dev *rdev = input_get_drvdata(idev);
 	struct rc_map *rc_map = &rdev->rc_map;
 	unsigned int index;
-	unsigned int scancode;
+	u64 scancode;
 	int retval = 0;
 	unsigned long flags;
 
@@ -407,7 +441,7 @@ static int ir_setkeycode(struct input_dev *idev,
 			goto out;
 		}
 	} else {
-		retval = input_scancode_to_scalar(ke, &scancode);
+		retval = scancode_to_u64(ke, &scancode);
 		if (retval)
 			goto out;
 
@@ -434,8 +468,7 @@ static int ir_setkeycode(struct input_dev *idev,
  *
  * return:	-ENOMEM if all keycodes could not be inserted, otherwise zero.
  */
-static int ir_setkeytable(struct rc_dev *dev,
-			  const struct rc_map *from)
+static int ir_setkeytable(struct rc_dev *dev, const struct rc_map *from)
 {
 	struct rc_map *rc_map = &dev->rc_map;
 	unsigned int i, index;
@@ -466,7 +499,7 @@ static int ir_setkeytable(struct rc_dev *dev,
 
 static int rc_map_cmp(const void *key, const void *elt)
 {
-	const unsigned int *scancode = key;
+	const u64 *scancode = key;
 	const struct rc_map_table *e = elt;
 
 	if (*scancode < e->scancode)
@@ -487,7 +520,7 @@ static int rc_map_cmp(const void *key, const void *elt)
  * return:	index in the table, -1U if not found
  */
 static unsigned int ir_lookup_by_scancode(const struct rc_map *rc_map,
-					  unsigned int scancode)
+					  u64 scancode)
 {
 	struct rc_map_table *res;
 
@@ -516,7 +549,7 @@ static int ir_getkeycode(struct input_dev *idev,
 	struct rc_map_table *entry;
 	unsigned long flags;
 	unsigned int index;
-	unsigned int scancode;
+	u64 scancode;
 	int retval;
 
 	spin_lock_irqsave(&rc_map->lock, flags);
@@ -524,7 +557,7 @@ static int ir_getkeycode(struct input_dev *idev,
 	if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
 		index = ke->index;
 	} else {
-		retval = input_scancode_to_scalar(ke, &scancode);
+		retval = scancode_to_u64(ke, &scancode);
 		if (retval)
 			goto out;
 
@@ -538,7 +571,6 @@ static int ir_getkeycode(struct input_dev *idev,
 		ke->keycode = entry->keycode;
 		ke->len = sizeof(entry->scancode);
 		memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));
-
 	} else if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) {
 		/*
 		 * We do not really know the valid range of scancodes
@@ -570,7 +602,7 @@ static int ir_getkeycode(struct input_dev *idev,
  *
  * return:	the corresponding keycode, or KEY_RESERVED
  */
-u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode)
+u32 rc_g_keycode_from_table(struct rc_dev *dev, u64 scancode)
 {
 	struct rc_map *rc_map = &dev->rc_map;
 	unsigned int keycode;
@@ -586,7 +618,7 @@ u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode)
 	spin_unlock_irqrestore(&rc_map->lock, flags);
 
 	if (keycode != KEY_RESERVED)
-		dev_dbg(&dev->dev, "%s: scancode 0x%04x keycode 0x%02x\n",
+		dev_dbg(&dev->dev, "%s: scancode 0x%04llx keycode 0x%02x\n",
 			dev->device_name, scancode, keycode);
 
 	return keycode;
@@ -719,9 +751,6 @@ void rc_repeat(struct rc_dev *dev)
 
 	spin_lock_irqsave(&dev->keylock, flags);
 
-	input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode);
-	input_sync(dev->input_dev);
-
 	if (dev->keypressed) {
 		dev->keyup_jiffies = jiffies + timeout;
 		mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
@@ -743,7 +772,7 @@ EXPORT_SYMBOL_GPL(rc_repeat);
  * called with keylock held.
  */
 static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
-			  u32 scancode, u32 keycode, u8 toggle)
+			  u64 scancode, u32 keycode, u8 toggle)
 {
 	bool new_event = (!dev->keypressed		 ||
 			  dev->last_protocol != protocol ||
@@ -761,8 +790,6 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
 	if (new_event && dev->keypressed)
 		ir_do_keyup(dev, false);
 
-	input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
-
 	dev->last_protocol = protocol;
 	dev->last_scancode = scancode;
 	dev->last_toggle = toggle;
@@ -772,7 +799,7 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
 		/* Register a keypress */
 		dev->keypressed = true;
 
-		dev_dbg(&dev->dev, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08x\n",
+		dev_dbg(&dev->dev, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08llx\n",
 			dev->device_name, keycode, protocol, scancode);
 		input_report_key(dev->input_dev, keycode, 1);
 
@@ -809,7 +836,7 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
  * This routine is used to signal that a key has been pressed on the
  * remote control.
  */
-void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode,
+void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u64 scancode,
 		u8 toggle)
 {
 	unsigned long flags;
@@ -840,7 +867,7 @@ EXPORT_SYMBOL_GPL(rc_keydown);
  * remote control. The driver must manually call rc_keyup() at a later stage.
  */
 void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol,
-			  u32 scancode, u8 toggle)
+			  u64 scancode, u8 toggle)
 {
 	unsigned long flags;
 	u32 keycode = rc_g_keycode_from_table(dev, scancode);
@@ -1769,8 +1796,6 @@ static int rc_prepare_rx_device(struct rc_dev *dev)
 	/* Keyboard events */
 	set_bit(EV_KEY, dev->input_dev->evbit);
 	set_bit(EV_REP, dev->input_dev->evbit);
-	set_bit(EV_MSC, dev->input_dev->evbit);
-	set_bit(MSC_SCAN, dev->input_dev->mscbit);
 
 	/* Pointer/mouse events */
 	set_bit(INPUT_PROP_POINTING_STICK, dev->input_dev->propbit);
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index 1f695d9c200a..d3f85df64bb2 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -192,7 +192,7 @@ struct rc_dev {
 	struct timer_list		timer_repeat;
 	u32				last_keycode;
 	enum rc_proto			last_protocol;
-	u32				last_scancode;
+	u64				last_scancode;
 	u8				last_toggle;
 	u32				timeout;
 	u32				min_timeout;
@@ -284,12 +284,12 @@ int devm_rc_register_device(struct device *parent, struct rc_dev *dev);
 void rc_unregister_device(struct rc_dev *dev);
 
 void rc_repeat(struct rc_dev *dev);
-void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode,
+void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u64 scancode,
 		u8 toggle);
 void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol,
-			  u32 scancode, u8 toggle);
+			  u64 scancode, u8 toggle);
 void rc_keyup(struct rc_dev *dev);
-u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode);
+u32 rc_g_keycode_from_table(struct rc_dev *dev, u64 scancode);
 
 /*
  * From rc-raw.c
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index d22810dcd85c..0ce896f10202 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -85,11 +85,11 @@
 /**
  * struct rc_map_table - represents a scancode/keycode pair
  *
- * @scancode: scan code (u32)
+ * @scancode: scan code (u64)
  * @keycode: Linux input keycode
  */
 struct rc_map_table {
-	u32	scancode;
+	u64	scancode;
 	u32	keycode;
 };
 
-- 
2.24.1


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

* [PATCH v4l-utils 2/4] keytable: new samsung36 bpf decoder
  2020-01-29 11:54 [PATCH v4l-utils 1/4] keytable: support 64 bit scancodes Sean Young
  2020-01-29 11:54 ` [PATCH v2] media: rc: make scancodes 64 bit Sean Young
@ 2020-01-29 11:54 ` Sean Young
  2020-01-29 11:54 ` [PATCH v4l-utils 3/4] Add keymap for Samsung AK59-00125A remote Sean Young
  2020-01-29 11:54 ` [PATCH v4l-utils 4/4] keytable: a bpf protocol can have parameters and no scancodes Sean Young
  3 siblings, 0 replies; 8+ messages in thread
From: Sean Young @ 2020-01-29 11:54 UTC (permalink / raw)
  To: linux-media; +Cc: Frank Wunderlich

Signed-off-by: Sean Young <sean@mess.org>
---
 utils/keytable/bpf_protocols/Makefile.am |   2 +-
 utils/keytable/bpf_protocols/samsung36.c | 136 +++++++++++++++++++++++
 2 files changed, 137 insertions(+), 1 deletion(-)
 create mode 100644 utils/keytable/bpf_protocols/samsung36.c

diff --git a/utils/keytable/bpf_protocols/Makefile.am b/utils/keytable/bpf_protocols/Makefile.am
index 3423aba1..13be2794 100644
--- a/utils/keytable/bpf_protocols/Makefile.am
+++ b/utils/keytable/bpf_protocols/Makefile.am
@@ -10,7 +10,7 @@ CLANG_SYS_INCLUDES := $(shell $(CLANG) -v -E - </dev/null 2>&1 \
 %.o: %.c bpf_helpers.h
 	$(CLANG) $(CLANG_SYS_INCLUDES) -D__linux__ -I$(top_srcdir)/include -target bpf -O2 -c $<
 
-PROTOCOLS = grundig.o pulse_distance.o pulse_length.o rc_mm.o manchester.o xbox-dvd.o imon_rsc.o raw.o
+PROTOCOLS = grundig.o pulse_distance.o pulse_length.o rc_mm.o manchester.o xbox-dvd.o imon_rsc.o raw.o samsung36.o
 
 all: $(PROTOCOLS)
 
diff --git a/utils/keytable/bpf_protocols/samsung36.c b/utils/keytable/bpf_protocols/samsung36.c
new file mode 100644
index 00000000..1b09365f
--- /dev/null
+++ b/utils/keytable/bpf_protocols/samsung36.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Remote protocol used by some Samsung remotes. It has 36 bits and the
+// 16th bit is not really a bit, but a marker to distinguish it from
+// shorter samsung protocols.
+//
+// http://www.hifi-remote.com/wiki/index.php/DecodeIR#Samsung36
+// Copyright (C) 2020 Sean Young <sean@mess.org>
+
+#include <linux/lirc.h>
+#include <linux/bpf.h>
+
+#include "bpf_helpers.h"
+
+enum state {
+	STATE_INACTIVE,
+	STATE_HEADER_SPACE,
+	STATE_BITS_SPACE,
+	STATE_BITS_PULSE,
+	STATE_TRAILER,
+};
+
+struct decoder_state {
+	unsigned long bits;
+	enum state state;
+	unsigned int count;
+};
+
+struct bpf_map_def SEC("maps") decoder_state_map = {
+	.type = BPF_MAP_TYPE_ARRAY,
+	.key_size = sizeof(unsigned int),
+	.value_size = sizeof(struct decoder_state),
+	.max_entries = 1,
+};
+
+// These values can be overridden in the rc_keymap toml
+//
+// We abuse elf relocations. We cast the address of these variables to
+// an int, so that the compiler emits a mov immediate for the address
+// but uses it as an int. The bpf loader replaces the relocation with the
+// actual value (either overridden or taken from the data segment).
+int margin = 300;
+int rc_protocol = 69;
+
+#define BPF_PARAM(x) (int)(&(x))
+
+static inline int eq_margin(unsigned d1, unsigned d2)
+{
+	return ((d1 > (d2 - BPF_PARAM(margin))) && (d1 < (d2 + BPF_PARAM(margin))));
+}
+
+SEC("samsung36")
+int bpf_decoder(unsigned int *sample)
+{
+	unsigned int key = 0;
+	struct decoder_state *s = bpf_map_lookup_elem(&decoder_state_map, &key);
+
+	if (!s)
+		return 0;
+
+	switch (*sample & LIRC_MODE2_MASK) {
+	case LIRC_MODE2_SPACE:
+	case LIRC_MODE2_PULSE:
+	case LIRC_MODE2_TIMEOUT:
+		break;
+	default:
+		// not a timing events
+		return 0;
+	}
+
+	int duration = LIRC_VALUE(*sample);
+	int pulse = LIRC_IS_PULSE(*sample);
+
+	switch (s->state) {
+	case STATE_INACTIVE:
+		if (pulse && eq_margin(duration, 4500)) {
+			s->bits = 0;
+			s->state = STATE_HEADER_SPACE;
+			s->count = 0;
+		}
+		break;
+	case STATE_HEADER_SPACE:
+		if (!pulse && eq_margin(duration, 4500))
+			s->state = STATE_BITS_PULSE;
+		else
+			s->state = STATE_INACTIVE;
+		break;
+	case STATE_BITS_PULSE:
+		if (pulse && eq_margin(duration, 500))
+			s->state = STATE_BITS_SPACE;
+		else
+			s->state = STATE_INACTIVE;
+		break;
+	case STATE_BITS_SPACE:
+		if (pulse) {
+			s->state = STATE_INACTIVE;
+			break;
+		}
+
+		s->count++;
+
+		if (s->count == 17) {
+			if (eq_margin(duration, 4450)) {
+				s->state = STATE_BITS_PULSE;
+			} else {
+				s->state = STATE_INACTIVE;
+			}
+			break;
+		}
+
+		s->bits <<= 1;
+
+		if (eq_margin(duration, 1600)) {
+			s->bits |= 1;
+		} else if (!eq_margin(duration, 500)) {
+			s->state = STATE_INACTIVE;
+			break;
+		}
+
+		if (s->count == 37)
+			s->state = STATE_TRAILER;
+		else
+			s->state = STATE_BITS_PULSE;
+		break;
+	case STATE_TRAILER:
+		if (pulse && eq_margin(duration, 500)) {
+			bpf_rc_keydown(sample, BPF_PARAM(rc_protocol), s->bits, 0);
+		}
+
+		s->state = STATE_INACTIVE;
+	}
+
+	return 0;
+}
+
+char _license[] SEC("license") = "GPL";
-- 
2.24.1


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

* [PATCH v4l-utils 3/4] Add keymap for Samsung AK59-00125A remote
  2020-01-29 11:54 [PATCH v4l-utils 1/4] keytable: support 64 bit scancodes Sean Young
  2020-01-29 11:54 ` [PATCH v2] media: rc: make scancodes 64 bit Sean Young
  2020-01-29 11:54 ` [PATCH v4l-utils 2/4] keytable: new samsung36 bpf decoder Sean Young
@ 2020-01-29 11:54 ` Sean Young
  2020-01-29 11:54 ` [PATCH v4l-utils 4/4] keytable: a bpf protocol can have parameters and no scancodes Sean Young
  3 siblings, 0 replies; 8+ messages in thread
From: Sean Young @ 2020-01-29 11:54 UTC (permalink / raw)
  To: linux-media; +Cc: Frank Wunderlich

Signed-off-by: Sean Young <sean@mess.org>
---
 .../samsung_ak59_00125a.toml                  | 69 +++++++++++++++++++
 1 file changed, 69 insertions(+)
 create mode 100644 utils/keytable/rc_keymaps_userspace/samsung_ak59_00125a.toml

diff --git a/utils/keytable/rc_keymaps_userspace/samsung_ak59_00125a.toml b/utils/keytable/rc_keymaps_userspace/samsung_ak59_00125a.toml
new file mode 100644
index 00000000..5d068f7c
--- /dev/null
+++ b/utils/keytable/rc_keymaps_userspace/samsung_ak59_00125a.toml
@@ -0,0 +1,69 @@
+[[protocols]]
+name = 'Samsung AK59-00125A'
+protocol = 'pulse_distance'
+header_pulse = 4500
+header_space = 4500
+bit_pulse = 600
+bit_0_space = 500
+bit_1_space = 1600
+bits = 32
+margin = 300
+trailer_pulse = 600
+[protocols.scancodes]
+0xe0e040bf = "KEY_POWER2"
+# input
+0xe0e0807f = "KEY_VIDEO"
+0xe0e0e01f = "KEY_VOLUMEUP"
+0xe0e0d02f = "KEY_VOLUMEDOWN"
+0xe0e0f00f = "KEY_MUTE"
+0xe0e048b7 = "KEY_CHANNELUP"
+0xe0e008f7 = "KEY_CHANNELDOWN"
+[[protocols]]
+protocol = 'samsung36'
+[protocols.scancodes]
+0x400e00ff = "KEY_POWER"
+# bonus view
+0x400ecc33 = "KEY_VENDOR"
+0x400e807f = "KEY_EJECTCD"
+0x400e40bf = "KEY_NUMERIC_1"
+0x400ec03f = "KEY_NUMERIC_2"
+0x400e20df = "KEY_NUMERIC_3"
+0x400ea05f = "KEY_NUMERIC_4"
+0x400e609f = "KEY_NUMERIC_5"
+0x400ee01f = "KEY_NUMERIC_6"
+0x400e10ef = "KEY_NUMERIC_7"
+0x400e906f = "KEY_NUMERIC_8"
+0x400e50af = "KEY_NUMERIC_9"
+0x400ed02f = "KEY_NUMERIC_0"
+0x400ea45b = "KEY_AUDIO"
+0x400e649b = "KEY_SUBTITLE"
+0x400eb04f = "KEY_PREVIOUS"
+0x400e8877 = "KEY_NEXT"
+0x400e48b7 = "KEY_FASTREVERSE"
+0x400ea857 = "KEY_FASTFORWARD"
+0x400ec837 = "KEY_STOP"
+0x400e28d7 = "KEY_PLAY"
+0x400e4cb3 = "KEY_PAUSE"
+# disc menu
+0x400eb847 = "KEY_ROOT_MENU" 
+0x400e6897 = "KEY_MENU"
+# title menu/popup
+0x400e04fb = "KEY_TITLE"
+# tools
+0x400e5ca3 = "KEY_CONFIG"
+0x400e7887 = "KEY_INFO"
+0x400e18e7 = "KEY_UP"
+0x400ed827 = "KEY_LEFT"
+0x400e58a7 = "KEY_RIGHT"
+0x400e9867 = "KEY_DOWN"
+0x400e38c7 = "KEY_ENTER"
+0x400ee817 = "KEY_ESC"
+0x400ed42b = "KEY_EXIT"
+0x400e847b = "KEY_RED"
+0x400e44bb = "KEY_GREEN"
+0x400ec43b = "KEY_YELLOW"
+0x400e24db = "KEY_BLUE"
+# smart/hub
+0x400e1ce3 = "KEY_VENDOR"
+0x400ebc43 = "KEY_SEARCH"
+0x400ee41b = "KEY_MEDIA_REPEAT"
-- 
2.24.1


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

* [PATCH v4l-utils 4/4] keytable: a bpf protocol can have parameters and no scancodes
  2020-01-29 11:54 [PATCH v4l-utils 1/4] keytable: support 64 bit scancodes Sean Young
                   ` (2 preceding siblings ...)
  2020-01-29 11:54 ` [PATCH v4l-utils 3/4] Add keymap for Samsung AK59-00125A remote Sean Young
@ 2020-01-29 11:54 ` Sean Young
  3 siblings, 0 replies; 8+ messages in thread
From: Sean Young @ 2020-01-29 11:54 UTC (permalink / raw)
  To: linux-media; +Cc: Frank Wunderlich

Currently a protocol without scancodes does not get its parameters
parsed.

Signed-off-by: Sean Young <sean@mess.org>
---
 utils/common/keymap.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/utils/common/keymap.c b/utils/common/keymap.c
index 15c31c76..a3c1349e 100644
--- a/utils/common/keymap.c
+++ b/utils/common/keymap.c
@@ -384,13 +384,6 @@ static error_t parse_toml_protocol(const char *fname, struct toml_table_t *proot
 		return EINVAL;
 	}
 
-	scancodes = toml_table_in(proot, "scancodes");
-	if (!scancodes) {
-		if (verbose)
-			fprintf(stderr, _("%s: no [protocols.scancodes] section\n"), fname);
-		return 0;
-	}
-
 	for (i = 0; (key = toml_key_in(proot, i)) != NULL; i++) {
 		int64_t value;
 
@@ -408,6 +401,13 @@ static error_t parse_toml_protocol(const char *fname, struct toml_table_t *proot
 		}
 	}
 
+	scancodes = toml_table_in(proot, "scancodes");
+	if (!scancodes) {
+		if (verbose)
+			fprintf(stderr, _("%s: no [protocols.scancodes] section\n"), fname);
+		return 0;
+	}
+
 	struct scancode_entry **next = &map->scancode;
 	i = 0;
 
-- 
2.24.1


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

* Re: [PATCH v2] media: rc: make scancodes 64 bit
  2020-01-29 11:54 ` [PATCH v2] media: rc: make scancodes 64 bit Sean Young
@ 2020-03-02  9:31   ` Mauro Carvalho Chehab
  2020-03-05  1:01     ` Sean Young
  2020-03-09 11:46     ` Sean Young
  0 siblings, 2 replies; 8+ messages in thread
From: Mauro Carvalho Chehab @ 2020-03-02  9:31 UTC (permalink / raw)
  To: Sean Young; +Cc: linux-media, Frank Wunderlich

Hi Sean,

Em Wed, 29 Jan 2020 11:54:16 +0000
Sean Young <sean@mess.org> escreveu:

> There are many protocols that encode more than 32 bit. We want 64 bit
> support so that BPF IR decoders can decode more than 32 bit. None of
> the existing kernel IR decoders/encoders support 64 bit, for now.

Since the beginning, the goal were to support longer scancodes. When we
designed the RC subsystem, we were even expecting longer codes[1].

[1] RC6 mode 6A scancode may have, according to the specs, up to 128 bits.
At the time we added the RC subsystem, RC6 were brand new, so we opted
to be more conservative. That's said, I never found myself any 
implementation with more than 64 bits for scancodes.

That's why we added the EVIOCGKEYCODE_V2, with uses:

struct input_keymap_entry {
#define INPUT_KEYMAP_BY_INDEX	(1 << 0)
	__u8  flags;
	__u8  len;
	__u16 index;
	__u32 keycode;
	__u8  scancode[32];
};

capable of storing scancodes up to 256 bits. The way the code is
written at the Kernel, is even possible to extend it further if ever
needed.

The reason why we don't properly support 64 bits yet [2] is that it requires 
some changes in order to provide a backward-compatible set of functions.

[2] Actually, I guess we have one driver with has 64 bits scancodes.

A proper patchset should likely modify also the code under drivers/input,
and needs to be submitted against input/evdev tree.

> 
> The MSC_SCAN event can only contain 32 bit scancodes, so we no longer
> generate these input events. The full 64 bit scancode can be read from
> the lirc chardev.

For example, if all possible scancodes are <= 32 bit, it should still
generate MSC_SCAN, as otherwise existing tools that rely on it will 
break.

> 
> Signed-off-by: Sean Young <sean@mess.org>
> ---
>  drivers/media/rc/bpf-lirc.c |  5 ---
>  drivers/media/rc/lirc_dev.c |  7 +---
>  drivers/media/rc/rc-main.c  | 77 ++++++++++++++++++++++++-------------
>  include/media/rc-core.h     |  8 ++--
>  include/media/rc-map.h      |  4 +-
>  5 files changed, 58 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/media/rc/bpf-lirc.c b/drivers/media/rc/bpf-lirc.c
> index 0a0ce620e4a2..0f3417d161b8 100644
> --- a/drivers/media/rc/bpf-lirc.c
> +++ b/drivers/media/rc/bpf-lirc.c
> @@ -35,11 +35,6 @@ static const struct bpf_func_proto rc_repeat_proto = {
>  	.arg1_type = ARG_PTR_TO_CTX,
>  };
>  
> -/*
> - * Currently rc-core does not support 64-bit scancodes, but there are many
> - * known protocols with more than 32 bits. So, define the interface as u64
> - * as a future-proof.
> - */
>  BPF_CALL_4(bpf_rc_keydown, u32*, sample, u32, protocol, u64, scancode,
>  	   u32, toggle)
>  {
> diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
> index 9a8c1cf54ac4..583e4f32a0da 100644
> --- a/drivers/media/rc/lirc_dev.c
> +++ b/drivers/media/rc/lirc_dev.c
> @@ -269,12 +269,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
>  			goto out_unlock;
>  		}
>  
> -		/*
> -		 * The scancode field in lirc_scancode is 64-bit simply
> -		 * to future-proof it, since there are IR protocols encode
> -		 * use more than 32 bits. For now only 32-bit protocols
> -		 * are supported.
> -		 */
> +		/* We only have encoders for 32-bit protocols. */
>  		if (scan.scancode > U32_MAX ||
>  		    !rc_validate_scancode(scan.rc_proto, scan.scancode)) {
>  			ret = -EINVAL;
> diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
> index 6f80c251f641..047b079c37eb 100644
> --- a/drivers/media/rc/rc-main.c
> +++ b/drivers/media/rc/rc-main.c
> @@ -163,6 +163,41 @@ static struct rc_map_list empty_map = {
>  	}
>  };
>  
> +/**
> + * scancode_to_u64() - converts scancode in &struct input_keymap_entry
> + * @ke: keymap entry containing scancode to be converted.
> + * @scancode: pointer to the location where converted scancode should
> + *	be stored.
> + *
> + * This function is a version of input_scancode_to_scalar specialized for
> + * rc-core.
> + */
> +static int scancode_to_u64(const struct input_keymap_entry *ke, u64 *scancode)
> +{
> +	switch (ke->len) {
> +	case 1:
> +		*scancode = *((u8 *)ke->scancode);
> +		break;
> +
> +	case 2:
> +		*scancode = *((u16 *)ke->scancode);
> +		break;
> +
> +	case 4:
> +		*scancode = *((u32 *)ke->scancode);
> +		break;
> +
> +	case 8:
> +		*scancode = *((u64 *)ke->scancode);
> +		break;
> +
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
>  /**
>   * ir_create_table() - initializes a scancode table
>   * @dev:	the rc_dev device
> @@ -285,13 +320,13 @@ static unsigned int ir_update_mapping(struct rc_dev *dev,
>  
>  	/* Did the user wish to remove the mapping? */
>  	if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) {
> -		dev_dbg(&dev->dev, "#%d: Deleting scan 0x%04x\n",
> +		dev_dbg(&dev->dev, "#%d: Deleting scan 0x%04llx\n",
>  			index, rc_map->scan[index].scancode);
>  		rc_map->len--;
>  		memmove(&rc_map->scan[index], &rc_map->scan[index+ 1],
>  			(rc_map->len - index) * sizeof(struct rc_map_table));
>  	} else {
> -		dev_dbg(&dev->dev, "#%d: %s scan 0x%04x with key 0x%04x\n",
> +		dev_dbg(&dev->dev, "#%d: %s scan 0x%04llx with key 0x%04x\n",
>  			index,
>  			old_keycode == KEY_RESERVED ? "New" : "Replacing",
>  			rc_map->scan[index].scancode, new_keycode);
> @@ -334,8 +369,7 @@ static unsigned int ir_update_mapping(struct rc_dev *dev,
>   */
>  static unsigned int ir_establish_scancode(struct rc_dev *dev,
>  					  struct rc_map *rc_map,
> -					  unsigned int scancode,
> -					  bool resize)
> +					  u64 scancode, bool resize)
>  {
>  	unsigned int i;
>  
> @@ -394,7 +428,7 @@ static int ir_setkeycode(struct input_dev *idev,
>  	struct rc_dev *rdev = input_get_drvdata(idev);
>  	struct rc_map *rc_map = &rdev->rc_map;
>  	unsigned int index;
> -	unsigned int scancode;
> +	u64 scancode;
>  	int retval = 0;
>  	unsigned long flags;
>  
> @@ -407,7 +441,7 @@ static int ir_setkeycode(struct input_dev *idev,
>  			goto out;
>  		}
>  	} else {
> -		retval = input_scancode_to_scalar(ke, &scancode);
> +		retval = scancode_to_u64(ke, &scancode);
>  		if (retval)
>  			goto out;
>  
> @@ -434,8 +468,7 @@ static int ir_setkeycode(struct input_dev *idev,
>   *
>   * return:	-ENOMEM if all keycodes could not be inserted, otherwise zero.
>   */
> -static int ir_setkeytable(struct rc_dev *dev,
> -			  const struct rc_map *from)
> +static int ir_setkeytable(struct rc_dev *dev, const struct rc_map *from)
>  {
>  	struct rc_map *rc_map = &dev->rc_map;
>  	unsigned int i, index;
> @@ -466,7 +499,7 @@ static int ir_setkeytable(struct rc_dev *dev,
>  
>  static int rc_map_cmp(const void *key, const void *elt)
>  {
> -	const unsigned int *scancode = key;
> +	const u64 *scancode = key;
>  	const struct rc_map_table *e = elt;
>  
>  	if (*scancode < e->scancode)
> @@ -487,7 +520,7 @@ static int rc_map_cmp(const void *key, const void *elt)
>   * return:	index in the table, -1U if not found
>   */
>  static unsigned int ir_lookup_by_scancode(const struct rc_map *rc_map,
> -					  unsigned int scancode)
> +					  u64 scancode)
>  {
>  	struct rc_map_table *res;
>  
> @@ -516,7 +549,7 @@ static int ir_getkeycode(struct input_dev *idev,
>  	struct rc_map_table *entry;
>  	unsigned long flags;
>  	unsigned int index;
> -	unsigned int scancode;
> +	u64 scancode;
>  	int retval;
>  
>  	spin_lock_irqsave(&rc_map->lock, flags);
> @@ -524,7 +557,7 @@ static int ir_getkeycode(struct input_dev *idev,
>  	if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
>  		index = ke->index;
>  	} else {
> -		retval = input_scancode_to_scalar(ke, &scancode);
> +		retval = scancode_to_u64(ke, &scancode);
>  		if (retval)
>  			goto out;
>  
> @@ -538,7 +571,6 @@ static int ir_getkeycode(struct input_dev *idev,
>  		ke->keycode = entry->keycode;
>  		ke->len = sizeof(entry->scancode);
>  		memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));
> -
>  	} else if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) {
>  		/*
>  		 * We do not really know the valid range of scancodes
> @@ -570,7 +602,7 @@ static int ir_getkeycode(struct input_dev *idev,
>   *
>   * return:	the corresponding keycode, or KEY_RESERVED
>   */
> -u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode)
> +u32 rc_g_keycode_from_table(struct rc_dev *dev, u64 scancode)
>  {
>  	struct rc_map *rc_map = &dev->rc_map;
>  	unsigned int keycode;
> @@ -586,7 +618,7 @@ u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode)
>  	spin_unlock_irqrestore(&rc_map->lock, flags);
>  
>  	if (keycode != KEY_RESERVED)
> -		dev_dbg(&dev->dev, "%s: scancode 0x%04x keycode 0x%02x\n",
> +		dev_dbg(&dev->dev, "%s: scancode 0x%04llx keycode 0x%02x\n",
>  			dev->device_name, scancode, keycode);
>  
>  	return keycode;
> @@ -719,9 +751,6 @@ void rc_repeat(struct rc_dev *dev)
>  
>  	spin_lock_irqsave(&dev->keylock, flags);
>  
> -	input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode);
> -	input_sync(dev->input_dev);
> -
>  	if (dev->keypressed) {
>  		dev->keyup_jiffies = jiffies + timeout;
>  		mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
> @@ -743,7 +772,7 @@ EXPORT_SYMBOL_GPL(rc_repeat);
>   * called with keylock held.
>   */
>  static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
> -			  u32 scancode, u32 keycode, u8 toggle)
> +			  u64 scancode, u32 keycode, u8 toggle)
>  {
>  	bool new_event = (!dev->keypressed		 ||
>  			  dev->last_protocol != protocol ||
> @@ -761,8 +790,6 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
>  	if (new_event && dev->keypressed)
>  		ir_do_keyup(dev, false);
>  
> -	input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
> -
>  	dev->last_protocol = protocol;
>  	dev->last_scancode = scancode;
>  	dev->last_toggle = toggle;
> @@ -772,7 +799,7 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
>  		/* Register a keypress */
>  		dev->keypressed = true;
>  
> -		dev_dbg(&dev->dev, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08x\n",
> +		dev_dbg(&dev->dev, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08llx\n",
>  			dev->device_name, keycode, protocol, scancode);
>  		input_report_key(dev->input_dev, keycode, 1);
>  
> @@ -809,7 +836,7 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
>   * This routine is used to signal that a key has been pressed on the
>   * remote control.
>   */
> -void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode,
> +void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u64 scancode,
>  		u8 toggle)
>  {
>  	unsigned long flags;
> @@ -840,7 +867,7 @@ EXPORT_SYMBOL_GPL(rc_keydown);
>   * remote control. The driver must manually call rc_keyup() at a later stage.
>   */
>  void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol,
> -			  u32 scancode, u8 toggle)
> +			  u64 scancode, u8 toggle)
>  {
>  	unsigned long flags;
>  	u32 keycode = rc_g_keycode_from_table(dev, scancode);
> @@ -1769,8 +1796,6 @@ static int rc_prepare_rx_device(struct rc_dev *dev)
>  	/* Keyboard events */
>  	set_bit(EV_KEY, dev->input_dev->evbit);
>  	set_bit(EV_REP, dev->input_dev->evbit);
> -	set_bit(EV_MSC, dev->input_dev->evbit);
> -	set_bit(MSC_SCAN, dev->input_dev->mscbit);
>  
>  	/* Pointer/mouse events */
>  	set_bit(INPUT_PROP_POINTING_STICK, dev->input_dev->propbit);
> diff --git a/include/media/rc-core.h b/include/media/rc-core.h
> index 1f695d9c200a..d3f85df64bb2 100644
> --- a/include/media/rc-core.h
> +++ b/include/media/rc-core.h
> @@ -192,7 +192,7 @@ struct rc_dev {
>  	struct timer_list		timer_repeat;
>  	u32				last_keycode;
>  	enum rc_proto			last_protocol;
> -	u32				last_scancode;
> +	u64				last_scancode;
>  	u8				last_toggle;
>  	u32				timeout;
>  	u32				min_timeout;
> @@ -284,12 +284,12 @@ int devm_rc_register_device(struct device *parent, struct rc_dev *dev);
>  void rc_unregister_device(struct rc_dev *dev);
>  
>  void rc_repeat(struct rc_dev *dev);
> -void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode,
> +void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u64 scancode,
>  		u8 toggle);
>  void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol,
> -			  u32 scancode, u8 toggle);
> +			  u64 scancode, u8 toggle);
>  void rc_keyup(struct rc_dev *dev);
> -u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode);
> +u32 rc_g_keycode_from_table(struct rc_dev *dev, u64 scancode);
>  
>  /*
>   * From rc-raw.c
> diff --git a/include/media/rc-map.h b/include/media/rc-map.h
> index d22810dcd85c..0ce896f10202 100644
> --- a/include/media/rc-map.h
> +++ b/include/media/rc-map.h
> @@ -85,11 +85,11 @@
>  /**
>   * struct rc_map_table - represents a scancode/keycode pair
>   *
> - * @scancode: scan code (u32)
> + * @scancode: scan code (u64)
>   * @keycode: Linux input keycode
>   */
>  struct rc_map_table {
> -	u32	scancode;
> +	u64	scancode;
>  	u32	keycode;
>  };
>  


Thanks,
Mauro

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

* Re: [PATCH v2] media: rc: make scancodes 64 bit
  2020-03-02  9:31   ` Mauro Carvalho Chehab
@ 2020-03-05  1:01     ` Sean Young
  2020-03-09 11:46     ` Sean Young
  1 sibling, 0 replies; 8+ messages in thread
From: Sean Young @ 2020-03-05  1:01 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-media, Frank Wunderlich

Hi Mauro,

On Mon, Mar 02, 2020 at 10:31:27AM +0100, Mauro Carvalho Chehab wrote:
> Hi Sean,
> Sean Young <sean@mess.org> escreveu:
> 
> > There are many protocols that encode more than 32 bit. We want 64 bit
> > support so that BPF IR decoders can decode more than 32 bit. None of
> > the existing kernel IR decoders/encoders support 64 bit, for now.
> 
> Since the beginning, the goal were to support longer scancodes. When we
> designed the RC subsystem, we were even expecting longer codes[1].
> 
> [1] RC6 mode 6A scancode may have, according to the specs, up to 128 bits.
> At the time we added the RC subsystem, RC6 were brand new, so we opted
> to be more conservative. That's said, I never found myself any 
> implementation with more than 64 bits for scancodes.
> 
> That's why we added the EVIOCGKEYCODE_V2, with uses:
> 
> struct input_keymap_entry {
> #define INPUT_KEYMAP_BY_INDEX	(1 << 0)
> 	__u8  flags;
> 	__u8  len;
> 	__u16 index;
> 	__u32 keycode;
> 	__u8  scancode[32];
> };
> 
> capable of storing scancodes up to 256 bits. The way the code is
> written at the Kernel, is even possible to extend it further if ever
> needed.
> 
> The reason why we don't properly support 64 bits yet [2] is that it requires 
> some changes in order to provide a backward-compatible set of functions.

I'm not sure what you mean. ir_setkeycode() requires the len to be set
accurately; previously it would not work if the len is 8, now it does.

ir_getcodekey() is more problematic, and I may have cheated a bit. The
existing user-space applications do not look a the len, so changing the
len does not affect them. On little endian, if you write a u64 to memory
the lower u32 will be written first, so this works magically. The
set of bigendian systems with old userspace using IR and someone reading
back scancodes must be a small set (so running ir-keytable -r).

What I should have done is write a u32 if the scancode fits into a u32
and a u64 if not. That way, nothing changes on either endian systems
until a 64 bit keymap is loaded, which would need new userspace anyway.

> [2] Actually, I guess we have one driver with has 64 bits scancodes.
> 
> A proper patchset should likely modify also the code under drivers/input,
> and needs to be submitted against input/evdev tree.

I'm not sure why.

> > The MSC_SCAN event can only contain 32 bit scancodes, so we no longer
> > generate these input events. The full 64 bit scancode can be read from
> > the lirc chardev.
> 
> For example, if all possible scancodes are <= 32 bit, it should still
> generate MSC_SCAN, as otherwise existing tools that rely on it will 
> break.

v1.16 ir-keytable -t gets the scancodes from the lirc deivce. Just generating
MSC_SCAN for 32 bit scancodes is a bit confusing when a 64 bit scancode comes
along.

Thanks for the review,

Sean

> 
> > 
> > Signed-off-by: Sean Young <sean@mess.org>
> > ---
> >  drivers/media/rc/bpf-lirc.c |  5 ---
> >  drivers/media/rc/lirc_dev.c |  7 +---
> >  drivers/media/rc/rc-main.c  | 77 ++++++++++++++++++++++++-------------
> >  include/media/rc-core.h     |  8 ++--
> >  include/media/rc-map.h      |  4 +-
> >  5 files changed, 58 insertions(+), 43 deletions(-)
> > 
> > diff --git a/drivers/media/rc/bpf-lirc.c b/drivers/media/rc/bpf-lirc.c
> > index 0a0ce620e4a2..0f3417d161b8 100644
> > --- a/drivers/media/rc/bpf-lirc.c
> > +++ b/drivers/media/rc/bpf-lirc.c
> > @@ -35,11 +35,6 @@ static const struct bpf_func_proto rc_repeat_proto = {
> >  	.arg1_type = ARG_PTR_TO_CTX,
> >  };
> >  
> > -/*
> > - * Currently rc-core does not support 64-bit scancodes, but there are many
> > - * known protocols with more than 32 bits. So, define the interface as u64
> > - * as a future-proof.
> > - */
> >  BPF_CALL_4(bpf_rc_keydown, u32*, sample, u32, protocol, u64, scancode,
> >  	   u32, toggle)
> >  {
> > diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
> > index 9a8c1cf54ac4..583e4f32a0da 100644
> > --- a/drivers/media/rc/lirc_dev.c
> > +++ b/drivers/media/rc/lirc_dev.c
> > @@ -269,12 +269,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
> >  			goto out_unlock;
> >  		}
> >  
> > -		/*
> > -		 * The scancode field in lirc_scancode is 64-bit simply
> > -		 * to future-proof it, since there are IR protocols encode
> > -		 * use more than 32 bits. For now only 32-bit protocols
> > -		 * are supported.
> > -		 */
> > +		/* We only have encoders for 32-bit protocols. */
> >  		if (scan.scancode > U32_MAX ||
> >  		    !rc_validate_scancode(scan.rc_proto, scan.scancode)) {
> >  			ret = -EINVAL;
> > diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
> > index 6f80c251f641..047b079c37eb 100644
> > --- a/drivers/media/rc/rc-main.c
> > +++ b/drivers/media/rc/rc-main.c
> > @@ -163,6 +163,41 @@ static struct rc_map_list empty_map = {
> >  	}
> >  };
> >  
> > +/**
> > + * scancode_to_u64() - converts scancode in &struct input_keymap_entry
> > + * @ke: keymap entry containing scancode to be converted.
> > + * @scancode: pointer to the location where converted scancode should
> > + *	be stored.
> > + *
> > + * This function is a version of input_scancode_to_scalar specialized for
> > + * rc-core.
> > + */
> > +static int scancode_to_u64(const struct input_keymap_entry *ke, u64 *scancode)
> > +{
> > +	switch (ke->len) {
> > +	case 1:
> > +		*scancode = *((u8 *)ke->scancode);
> > +		break;
> > +
> > +	case 2:
> > +		*scancode = *((u16 *)ke->scancode);
> > +		break;
> > +
> > +	case 4:
> > +		*scancode = *((u32 *)ke->scancode);
> > +		break;
> > +
> > +	case 8:
> > +		*scancode = *((u64 *)ke->scancode);
> > +		break;
> > +
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  /**
> >   * ir_create_table() - initializes a scancode table
> >   * @dev:	the rc_dev device
> > @@ -285,13 +320,13 @@ static unsigned int ir_update_mapping(struct rc_dev *dev,
> >  
> >  	/* Did the user wish to remove the mapping? */
> >  	if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) {
> > -		dev_dbg(&dev->dev, "#%d: Deleting scan 0x%04x\n",
> > +		dev_dbg(&dev->dev, "#%d: Deleting scan 0x%04llx\n",
> >  			index, rc_map->scan[index].scancode);
> >  		rc_map->len--;
> >  		memmove(&rc_map->scan[index], &rc_map->scan[index+ 1],
> >  			(rc_map->len - index) * sizeof(struct rc_map_table));
> >  	} else {
> > -		dev_dbg(&dev->dev, "#%d: %s scan 0x%04x with key 0x%04x\n",
> > +		dev_dbg(&dev->dev, "#%d: %s scan 0x%04llx with key 0x%04x\n",
> >  			index,
> >  			old_keycode == KEY_RESERVED ? "New" : "Replacing",
> >  			rc_map->scan[index].scancode, new_keycode);
> > @@ -334,8 +369,7 @@ static unsigned int ir_update_mapping(struct rc_dev *dev,
> >   */
> >  static unsigned int ir_establish_scancode(struct rc_dev *dev,
> >  					  struct rc_map *rc_map,
> > -					  unsigned int scancode,
> > -					  bool resize)
> > +					  u64 scancode, bool resize)
> >  {
> >  	unsigned int i;
> >  
> > @@ -394,7 +428,7 @@ static int ir_setkeycode(struct input_dev *idev,
> >  	struct rc_dev *rdev = input_get_drvdata(idev);
> >  	struct rc_map *rc_map = &rdev->rc_map;
> >  	unsigned int index;
> > -	unsigned int scancode;
> > +	u64 scancode;
> >  	int retval = 0;
> >  	unsigned long flags;
> >  
> > @@ -407,7 +441,7 @@ static int ir_setkeycode(struct input_dev *idev,
> >  			goto out;
> >  		}
> >  	} else {
> > -		retval = input_scancode_to_scalar(ke, &scancode);
> > +		retval = scancode_to_u64(ke, &scancode);
> >  		if (retval)
> >  			goto out;
> >  
> > @@ -434,8 +468,7 @@ static int ir_setkeycode(struct input_dev *idev,
> >   *
> >   * return:	-ENOMEM if all keycodes could not be inserted, otherwise zero.
> >   */
> > -static int ir_setkeytable(struct rc_dev *dev,
> > -			  const struct rc_map *from)
> > +static int ir_setkeytable(struct rc_dev *dev, const struct rc_map *from)
> >  {
> >  	struct rc_map *rc_map = &dev->rc_map;
> >  	unsigned int i, index;
> > @@ -466,7 +499,7 @@ static int ir_setkeytable(struct rc_dev *dev,
> >  
> >  static int rc_map_cmp(const void *key, const void *elt)
> >  {
> > -	const unsigned int *scancode = key;
> > +	const u64 *scancode = key;
> >  	const struct rc_map_table *e = elt;
> >  
> >  	if (*scancode < e->scancode)
> > @@ -487,7 +520,7 @@ static int rc_map_cmp(const void *key, const void *elt)
> >   * return:	index in the table, -1U if not found
> >   */
> >  static unsigned int ir_lookup_by_scancode(const struct rc_map *rc_map,
> > -					  unsigned int scancode)
> > +					  u64 scancode)
> >  {
> >  	struct rc_map_table *res;
> >  
> > @@ -516,7 +549,7 @@ static int ir_getkeycode(struct input_dev *idev,
> >  	struct rc_map_table *entry;
> >  	unsigned long flags;
> >  	unsigned int index;
> > -	unsigned int scancode;
> > +	u64 scancode;
> >  	int retval;
> >  
> >  	spin_lock_irqsave(&rc_map->lock, flags);
> > @@ -524,7 +557,7 @@ static int ir_getkeycode(struct input_dev *idev,
> >  	if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
> >  		index = ke->index;
> >  	} else {
> > -		retval = input_scancode_to_scalar(ke, &scancode);
> > +		retval = scancode_to_u64(ke, &scancode);
> >  		if (retval)
> >  			goto out;
> >  
> > @@ -538,7 +571,6 @@ static int ir_getkeycode(struct input_dev *idev,
> >  		ke->keycode = entry->keycode;
> >  		ke->len = sizeof(entry->scancode);
> >  		memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));
> > -
> >  	} else if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) {
> >  		/*
> >  		 * We do not really know the valid range of scancodes
> > @@ -570,7 +602,7 @@ static int ir_getkeycode(struct input_dev *idev,
> >   *
> >   * return:	the corresponding keycode, or KEY_RESERVED
> >   */
> > -u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode)
> > +u32 rc_g_keycode_from_table(struct rc_dev *dev, u64 scancode)
> >  {
> >  	struct rc_map *rc_map = &dev->rc_map;
> >  	unsigned int keycode;
> > @@ -586,7 +618,7 @@ u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode)
> >  	spin_unlock_irqrestore(&rc_map->lock, flags);
> >  
> >  	if (keycode != KEY_RESERVED)
> > -		dev_dbg(&dev->dev, "%s: scancode 0x%04x keycode 0x%02x\n",
> > +		dev_dbg(&dev->dev, "%s: scancode 0x%04llx keycode 0x%02x\n",
> >  			dev->device_name, scancode, keycode);
> >  
> >  	return keycode;
> > @@ -719,9 +751,6 @@ void rc_repeat(struct rc_dev *dev)
> >  
> >  	spin_lock_irqsave(&dev->keylock, flags);
> >  
> > -	input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode);
> > -	input_sync(dev->input_dev);
> > -
> >  	if (dev->keypressed) {
> >  		dev->keyup_jiffies = jiffies + timeout;
> >  		mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
> > @@ -743,7 +772,7 @@ EXPORT_SYMBOL_GPL(rc_repeat);
> >   * called with keylock held.
> >   */
> >  static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
> > -			  u32 scancode, u32 keycode, u8 toggle)
> > +			  u64 scancode, u32 keycode, u8 toggle)
> >  {
> >  	bool new_event = (!dev->keypressed		 ||
> >  			  dev->last_protocol != protocol ||
> > @@ -761,8 +790,6 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
> >  	if (new_event && dev->keypressed)
> >  		ir_do_keyup(dev, false);
> >  
> > -	input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
> > -
> >  	dev->last_protocol = protocol;
> >  	dev->last_scancode = scancode;
> >  	dev->last_toggle = toggle;
> > @@ -772,7 +799,7 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
> >  		/* Register a keypress */
> >  		dev->keypressed = true;
> >  
> > -		dev_dbg(&dev->dev, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08x\n",
> > +		dev_dbg(&dev->dev, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08llx\n",
> >  			dev->device_name, keycode, protocol, scancode);
> >  		input_report_key(dev->input_dev, keycode, 1);
> >  
> > @@ -809,7 +836,7 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
> >   * This routine is used to signal that a key has been pressed on the
> >   * remote control.
> >   */
> > -void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode,
> > +void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u64 scancode,
> >  		u8 toggle)
> >  {
> >  	unsigned long flags;
> > @@ -840,7 +867,7 @@ EXPORT_SYMBOL_GPL(rc_keydown);
> >   * remote control. The driver must manually call rc_keyup() at a later stage.
> >   */
> >  void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol,
> > -			  u32 scancode, u8 toggle)
> > +			  u64 scancode, u8 toggle)
> >  {
> >  	unsigned long flags;
> >  	u32 keycode = rc_g_keycode_from_table(dev, scancode);
> > @@ -1769,8 +1796,6 @@ static int rc_prepare_rx_device(struct rc_dev *dev)
> >  	/* Keyboard events */
> >  	set_bit(EV_KEY, dev->input_dev->evbit);
> >  	set_bit(EV_REP, dev->input_dev->evbit);
> > -	set_bit(EV_MSC, dev->input_dev->evbit);
> > -	set_bit(MSC_SCAN, dev->input_dev->mscbit);
> >  
> >  	/* Pointer/mouse events */
> >  	set_bit(INPUT_PROP_POINTING_STICK, dev->input_dev->propbit);
> > diff --git a/include/media/rc-core.h b/include/media/rc-core.h
> > index 1f695d9c200a..d3f85df64bb2 100644
> > --- a/include/media/rc-core.h
> > +++ b/include/media/rc-core.h
> > @@ -192,7 +192,7 @@ struct rc_dev {
> >  	struct timer_list		timer_repeat;
> >  	u32				last_keycode;
> >  	enum rc_proto			last_protocol;
> > -	u32				last_scancode;
> > +	u64				last_scancode;
> >  	u8				last_toggle;
> >  	u32				timeout;
> >  	u32				min_timeout;
> > @@ -284,12 +284,12 @@ int devm_rc_register_device(struct device *parent, struct rc_dev *dev);
> >  void rc_unregister_device(struct rc_dev *dev);
> >  
> >  void rc_repeat(struct rc_dev *dev);
> > -void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode,
> > +void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u64 scancode,
> >  		u8 toggle);
> >  void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol,
> > -			  u32 scancode, u8 toggle);
> > +			  u64 scancode, u8 toggle);
> >  void rc_keyup(struct rc_dev *dev);
> > -u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode);
> > +u32 rc_g_keycode_from_table(struct rc_dev *dev, u64 scancode);
> >  
> >  /*
> >   * From rc-raw.c
> > diff --git a/include/media/rc-map.h b/include/media/rc-map.h
> > index d22810dcd85c..0ce896f10202 100644
> > --- a/include/media/rc-map.h
> > +++ b/include/media/rc-map.h
> > @@ -85,11 +85,11 @@
> >  /**
> >   * struct rc_map_table - represents a scancode/keycode pair
> >   *
> > - * @scancode: scan code (u32)
> > + * @scancode: scan code (u64)
> >   * @keycode: Linux input keycode
> >   */
> >  struct rc_map_table {
> > -	u32	scancode;
> > +	u64	scancode;
> >  	u32	keycode;
> >  };
> >  
> 
> 
> Thanks,
> Mauro

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

* Re: [PATCH v2] media: rc: make scancodes 64 bit
  2020-03-02  9:31   ` Mauro Carvalho Chehab
  2020-03-05  1:01     ` Sean Young
@ 2020-03-09 11:46     ` Sean Young
  1 sibling, 0 replies; 8+ messages in thread
From: Sean Young @ 2020-03-09 11:46 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-media, Frank Wunderlich

Hi Mauro,

On Mon, Mar 02, 2020 at 10:31:27AM +0100, Mauro Carvalho Chehab wrote:
> Em Wed, 29 Jan 2020 11:54:16 +0000
> Sean Young <sean@mess.org> escreveu:
> 
> > There are many protocols that encode more than 32 bit. We want 64 bit
> > support so that BPF IR decoders can decode more than 32 bit. None of
> > the existing kernel IR decoders/encoders support 64 bit, for now.
> 
> The reason why we don't properly support 64 bits yet [2] is that it requires 
> some changes in order to provide a backward-compatible set of functions.

This should be supported.

> [2] Actually, I guess we have one driver with has 64 bits scancodes.

Which one is that?

> > The MSC_SCAN event can only contain 32 bit scancodes, so we no longer
> > generate these input events. The full 64 bit scancode can be read from
> > the lirc chardev.
> 
> For example, if all possible scancodes are <= 32 bit, it should still
> generate MSC_SCAN, as otherwise existing tools that rely on it will 
> break.

The scancodes are generated from the driver, and even if there is no
keymap loaded, scancodes are still generated. Therefore I don't think it
makes sense to switch on whether there are any 64 bit scancodes in the
current keymap.

We don't know if a driver will produce 64 bit scancodes right now. Although
BPF is the only route (currently) which can produce 64 bit scancodes,
there is no way to see if a BPF program will generate 64 bit scancodes
in advance.

So, I've changed the code to generate MSC_SCANCODE if the scancode fits
into 32 bits, reluctantly. However, I think this is the best we can do
for compatibility. I will post a v2 shortly.

Thanks
Sean

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

end of thread, other threads:[~2020-03-09 11:46 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-29 11:54 [PATCH v4l-utils 1/4] keytable: support 64 bit scancodes Sean Young
2020-01-29 11:54 ` [PATCH v2] media: rc: make scancodes 64 bit Sean Young
2020-03-02  9:31   ` Mauro Carvalho Chehab
2020-03-05  1:01     ` Sean Young
2020-03-09 11:46     ` Sean Young
2020-01-29 11:54 ` [PATCH v4l-utils 2/4] keytable: new samsung36 bpf decoder Sean Young
2020-01-29 11:54 ` [PATCH v4l-utils 3/4] Add keymap for Samsung AK59-00125A remote Sean Young
2020-01-29 11:54 ` [PATCH v4l-utils 4/4] keytable: a bpf protocol can have parameters and no scancodes Sean Young

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