Re: [PATCH v2] HID: google: add google vivaldi HID driver

2020-09-08 Thread Jiri Kosina
On Wed, 26 Aug 2020, Sean O'Brien wrote:

> > I actually believe we should follow the standard convention here, and have
> > just one hid- driver for all google products. Currently we have
> > hid-google-hammer, and this would add hid-google-vivaldi. Would you (or
> > Wei-Ning, CCing here) object on merging these two together?
> 
> I'm a bit reluctant to merge them.  Partly because I'm not familiar with
> the hid-google-hammer driver, but mostly because this driver is intended
> to handle non-google products which will use a google-defined usage code.
> Perhaps I should drop "google" from the driver name?

If it's known that it will be handling non-google products, then I think 
that's indeed the best option. Thanks in advance for v3 with this change,

-- 
Jiri Kosina
SUSE Labs



Re: [PATCH v2] HID: google: add google vivaldi HID driver

2020-08-26 Thread Sean O'Brien
> I actually believe we should follow the standard convention here, and have
> just one hid- driver for all google products. Currently we have
> hid-google-hammer, and this would add hid-google-vivaldi. Would you (or
> Wei-Ning, CCing here) object on merging these two together?

I'm a bit reluctant to merge them.  Partly because I'm not familiar with
the hid-google-hammer driver, but mostly because this driver is intended
to handle non-google products which will use a google-defined usage code.
Perhaps I should drop "google" from the driver name?

Thanks,
Sean O'Brien


Re: [PATCH v2] HID: google: add google vivaldi HID driver

2020-08-26 Thread Jiri Kosina
On Tue, 25 Aug 2020, Sean O'Brien wrote:

> Add Google vivaldi HID driver. This driver allows us to read and report
> the top row layout of keyboards which provide a vendor-defined HID
> usage.

Thanks for the driver.

I actually believe we should follow the standard convention here, and have 
just one hid- driver for all google products. Currently we have 
hid-google-hammer, and this would add hid-google-vivaldi. Would you (or 
Wei-Ning, CCing here) object on merging these two together?

It's of course possible to still have hid-google-vivaldi.c and 
hid-google-hammer.c, but then have only one CONFIG_HID_GOOGLE option 
that'd link these two (and pontentially any future ones) into one single 
hid-google.ko.

Thanks,

-- 
Jiri Kosina
SUSE Labs



[PATCH v2] HID: google: add google vivaldi HID driver

2020-08-25 Thread Sean O'Brien
Add Google vivaldi HID driver. This driver allows us to read and report
the top row layout of keyboards which provide a vendor-defined HID
usage.

Signed-off-by: Sean O'Brien 
---

 drivers/hid/Kconfig  |   9 ++
 drivers/hid/Makefile |   1 +
 drivers/hid/hid-core.c   |   7 ++
 drivers/hid/hid-google-vivaldi.c | 144 +++
 include/linux/hid.h  |   2 +
 5 files changed, 163 insertions(+)
 create mode 100644 drivers/hid/hid-google-vivaldi.c

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 05315b434276..b608a5b1d753 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -397,6 +397,15 @@ config HID_GOOGLE_HAMMER
help
Say Y here if you have a Google Hammer device.
 
+config HID_GOOGLE_VIVALDI
+   tristate "Google Vivaldi Keyboard"
+   depends on HID
+   help
+ Say Y here if you want to enable support for Google Vivaldi keyboards.
+
+ Vivaldi keyboards use a vendor-specific HID usage to report how the
+ keys in the top row are physically ordered.
+
 config HID_GT683R
tristate "MSI GT68xR LED support"
depends on LEDS_CLASS && USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index d8ea4b8c95af..35ca714c7ee2 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_HID_GEMBIRD) += hid-gembird.o
 obj-$(CONFIG_HID_GFRM) += hid-gfrm.o
 obj-$(CONFIG_HID_GLORIOUS)  += hid-glorious.o
 obj-$(CONFIG_HID_GOOGLE_HAMMER)+= hid-google-hammer.o
+obj-$(CONFIG_HID_GOOGLE_VIVALDI)   += hid-google-vivaldi.o
 obj-$(CONFIG_HID_GT683R)   += hid-gt683r.o
 obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
 obj-$(CONFIG_HID_HOLTEK)   += hid-holtek-kbd.o
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 359616e3efbb..4df05b35b4d0 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -814,6 +814,13 @@ static void hid_scan_collection(struct hid_parser *parser, 
unsigned type)
 
if ((parser->global.usage_page << 16) >= HID_UP_MSVENDOR)
parser->scan_flags |= HID_SCAN_FLAG_VENDOR_SPECIFIC;
+
+   if ((parser->global.usage_page << 16) == HID_UP_GOOGLEVENDOR)
+   for (i = 0; i < parser->local.usage_index; i++)
+   if (parser->local.usage[i] ==
+   (HID_UP_GOOGLEVENDOR | 0x0001))
+   parser->device->group =
+   HID_GROUP_GOOGLE_VIVALDI;
 }
 
 static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
diff --git a/drivers/hid/hid-google-vivaldi.c b/drivers/hid/hid-google-vivaldi.c
new file mode 100644
index ..9165ef5e1542
--- /dev/null
+++ b/drivers/hid/hid-google-vivaldi.c
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * HID support for Google Vivaldi Keyboard
+ *
+ * Copyright 2020 Google LLC.
+ * Author: Sean O'Brien 
+ */
+
+#include 
+#include 
+
+#define MIN_FN_ROW_KEY 1
+#define MAX_FN_ROW_KEY 24
+#define HID_VD_FN_ROW_PHYSMAP 0x0001
+#define HID_USAGE_FN_ROW_PHYSMAP (HID_UP_GOOGLEVENDOR | HID_VD_FN_ROW_PHYSMAP)
+
+static struct hid_driver hid_vivaldi;
+
+struct vivaldi_data {
+   u32 function_row_physmap[MAX_FN_ROW_KEY - MIN_FN_ROW_KEY + 1];
+   int max_function_row_key;
+};
+
+static ssize_t function_row_physmap_show(struct device *dev,
+struct device_attribute *attr,
+char *buf)
+{
+   struct hid_device *hdev = to_hid_device(dev);
+   struct vivaldi_data *drvdata = hid_get_drvdata(hdev);
+   ssize_t size = 0;
+   int i;
+
+   if (!drvdata->max_function_row_key)
+   return 0;
+
+   for (i = 0; i < drvdata->max_function_row_key; i++)
+   size += sprintf(buf + size, "%02X ",
+   drvdata->function_row_physmap[i]);
+   size += sprintf(buf + size, "\n");
+   return size;
+}
+
+DEVICE_ATTR_RO(function_row_physmap);
+static struct attribute *sysfs_attrs[] = {
+   &dev_attr_function_row_physmap.attr,
+   NULL
+};
+
+static const struct attribute_group input_attribute_group = {
+   .attrs = sysfs_attrs
+};
+
+static int vivaldi_probe(struct hid_device *hdev,
+const struct hid_device_id *id)
+{
+   struct vivaldi_data *drvdata;
+   int ret;
+
+   drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
+   hid_set_drvdata(hdev, drvdata);
+
+   ret = hid_parse(hdev);
+   if (ret)
+   return ret;
+
+   return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+}
+
+static void vivaldi_feature_mapping(struct hid_device *hdev,
+   struct hid_field *field,
+   struct hid_usage *usage)
+{
+   struct vivaldi_data *drvdata = hid_get_drvdata(hdev);
+   int fn_key;
+   int re