Skip to content

Commit 45ceaf1

Browse files
bebarinodtor
authored andcommitted
Input: extract ChromeOS vivaldi physmap show function
Let's introduce a common library file for the physmap show function duplicated between three different keyboard drivers. This largely copies the code from cros_ec_keyb.c which has the most recent version of the show function, while using the vivaldi_data struct from the hid-vivaldi driver. This saves a small amount of space in an allyesconfig build. $ ./scripts/bloat-o-meter vmlinux.before vmlinux.after add/remove: 3/0 grow/shrink: 2/3 up/down: 412/-720 (-308) Function old new delta vivaldi_function_row_physmap_show - 292 +292 _sub_I_65535_1 1057564 1057616 +52 _sub_D_65535_0 1057564 1057616 +52 e843419@49f2_00062737_9b04 - 8 +8 e843419@20f6_0002a34d_35bc - 8 +8 atkbd_parse_fwnode_data 480 472 -8 atkbd_do_show_function_row_physmap 316 76 -240 function_row_physmap_show 620 148 -472 Total: Before=285581925, After=285581617, chg -0.00% Signed-off-by: Stephen Boyd <swboyd@chromium.org> Tested-by: Stephen Boyd <swboyd@chromium.org> # coachz, wormdingler Link: https://lore.kernel.org/r/20220228075446.466016-3-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
1 parent d950db3 commit 45ceaf1

9 files changed

Lines changed: 108 additions & 66 deletions

File tree

drivers/hid/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ config HID_GOOGLE_HAMMER
411411

412412
config HID_VIVALDI
413413
tristate "Vivaldi Keyboard"
414+
select INPUT_VIVALDIFMAP
414415
depends on HID
415416
help
416417
Say Y here if you want to enable support for Vivaldi keyboards.

drivers/hid/hid-vivaldi.c

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,24 @@
88

99
#include <linux/device.h>
1010
#include <linux/hid.h>
11+
#include <linux/input/vivaldi-fmap.h>
1112
#include <linux/kernel.h>
1213
#include <linux/module.h>
1314
#include <linux/sysfs.h>
1415

15-
#define MIN_FN_ROW_KEY 1
16-
#define MAX_FN_ROW_KEY 24
16+
#define MIN_FN_ROW_KEY 1
17+
#define MAX_FN_ROW_KEY VIVALDI_MAX_FUNCTION_ROW_KEYS
1718
#define HID_VD_FN_ROW_PHYSMAP 0x00000001
1819
#define HID_USAGE_FN_ROW_PHYSMAP (HID_UP_GOOGLEVENDOR | HID_VD_FN_ROW_PHYSMAP)
1920

20-
struct vivaldi_data {
21-
u32 function_row_physmap[MAX_FN_ROW_KEY - MIN_FN_ROW_KEY + 1];
22-
int max_function_row_key;
23-
};
24-
2521
static ssize_t function_row_physmap_show(struct device *dev,
2622
struct device_attribute *attr,
2723
char *buf)
2824
{
2925
struct hid_device *hdev = to_hid_device(dev);
3026
struct vivaldi_data *drvdata = hid_get_drvdata(hdev);
31-
ssize_t size = 0;
32-
int i;
33-
34-
if (!drvdata->max_function_row_key)
35-
return 0;
3627

37-
for (i = 0; i < drvdata->max_function_row_key; i++)
38-
size += sprintf(buf + size, "%02X ",
39-
drvdata->function_row_physmap[i]);
40-
size += sprintf(buf + size, "\n");
41-
return size;
28+
return vivaldi_function_row_physmap_show(drvdata, buf);
4229
}
4330

4431
static DEVICE_ATTR_RO(function_row_physmap);
@@ -85,11 +72,11 @@ static void vivaldi_feature_mapping(struct hid_device *hdev,
8572
(usage->hid & HID_USAGE_PAGE) != HID_UP_ORDINAL)
8673
return;
8774

88-
fn_key = (usage->hid & HID_USAGE);
75+
fn_key = usage->hid & HID_USAGE;
8976
if (fn_key < MIN_FN_ROW_KEY || fn_key > MAX_FN_ROW_KEY)
9077
return;
91-
if (fn_key > drvdata->max_function_row_key)
92-
drvdata->max_function_row_key = fn_key;
78+
if (fn_key > drvdata->num_function_row_keys)
79+
drvdata->num_function_row_keys = fn_key;
9380

9481
report_data = buf = hid_alloc_report_buf(report, GFP_KERNEL);
9582
if (!report_data)

drivers/input/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ config INPUT_MATRIXKMAP
7777
To compile this driver as a module, choose M here: the
7878
module will be called matrix-keymap.
7979

80+
config INPUT_VIVALDIFMAP
81+
tristate
82+
help
83+
ChromeOS Vivaldi keymap support library. This is a hidden
84+
option so that drivers can use common code to parse and
85+
expose the vivaldi function row keymap.
86+
8087
comment "Userland interfaces"
8188

8289
config INPUT_MOUSEDEV

drivers/input/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ input-core-y += touchscreen.o
1212
obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o
1313
obj-$(CONFIG_INPUT_SPARSEKMAP) += sparse-keymap.o
1414
obj-$(CONFIG_INPUT_MATRIXKMAP) += matrix-keymap.o
15+
obj-$(CONFIG_INPUT_VIVALDIFMAP) += vivaldi-fmap.o
1516

1617
obj-$(CONFIG_INPUT_LEDS) += input-leds.o
1718
obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o

drivers/input/keyboard/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ config KEYBOARD_ATKBD
103103
select SERIO_LIBPS2
104104
select SERIO_I8042 if ARCH_MIGHT_HAVE_PC_SERIO
105105
select SERIO_GSCPS2 if GSC
106+
select INPUT_VIVALDIFMAP
106107
help
107108
Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
108109
you'll need this, unless you have a different type keyboard (USB, ADB
@@ -749,6 +750,7 @@ config KEYBOARD_XTKBD
749750
config KEYBOARD_CROS_EC
750751
tristate "ChromeOS EC keyboard"
751752
select INPUT_MATRIXKMAP
753+
select INPUT_VIVALDIFMAP
752754
depends on CROS_EC
753755
help
754756
Say Y here to enable the matrix keyboard used by ChromeOS devices

drivers/input/keyboard/atkbd.c

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/interrupt.h>
2020
#include <linux/init.h>
2121
#include <linux/input.h>
22+
#include <linux/input/vivaldi-fmap.h>
2223
#include <linux/serio.h>
2324
#include <linux/workqueue.h>
2425
#include <linux/libps2.h>
@@ -64,8 +65,6 @@ static bool atkbd_terminal;
6465
module_param_named(terminal, atkbd_terminal, bool, 0);
6566
MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard connected via AT/PS2");
6667

67-
#define MAX_FUNCTION_ROW_KEYS 24
68-
6968
#define SCANCODE(keymap) ((keymap >> 16) & 0xFFFF)
7069
#define KEYCODE(keymap) (keymap & 0xFFFF)
7170

@@ -237,8 +236,7 @@ struct atkbd {
237236
/* Serializes reconnect(), attr->set() and event work */
238237
struct mutex mutex;
239238

240-
u32 function_row_physmap[MAX_FUNCTION_ROW_KEYS];
241-
int num_function_row_keys;
239+
struct vivaldi_data vdata;
242240
};
243241

244242
/*
@@ -308,17 +306,7 @@ static struct attribute *atkbd_attributes[] = {
308306

309307
static ssize_t atkbd_show_function_row_physmap(struct atkbd *atkbd, char *buf)
310308
{
311-
ssize_t size = 0;
312-
int i;
313-
314-
if (!atkbd->num_function_row_keys)
315-
return 0;
316-
317-
for (i = 0; i < atkbd->num_function_row_keys; i++)
318-
size += scnprintf(buf + size, PAGE_SIZE - size, "%02X ",
319-
atkbd->function_row_physmap[i]);
320-
size += scnprintf(buf + size, PAGE_SIZE - size, "\n");
321-
return size;
309+
return vivaldi_function_row_physmap_show(&atkbd->vdata, buf);
322310
}
323311

324312
static umode_t atkbd_attr_is_visible(struct kobject *kobj,
@@ -329,7 +317,7 @@ static umode_t atkbd_attr_is_visible(struct kobject *kobj,
329317
struct atkbd *atkbd = serio_get_drvdata(serio);
330318

331319
if (attr == &atkbd_attr_function_row_physmap.attr &&
332-
!atkbd->num_function_row_keys)
320+
!atkbd->vdata.num_function_row_keys)
333321
return 0;
334322

335323
return attr->mode;
@@ -1206,10 +1194,11 @@ static void atkbd_parse_fwnode_data(struct serio *serio)
12061194

12071195
/* Parse "function-row-physmap" property */
12081196
n = device_property_count_u32(dev, "function-row-physmap");
1209-
if (n > 0 && n <= MAX_FUNCTION_ROW_KEYS &&
1197+
if (n > 0 && n <= VIVALDI_MAX_FUNCTION_ROW_KEYS &&
12101198
!device_property_read_u32_array(dev, "function-row-physmap",
1211-
atkbd->function_row_physmap, n)) {
1212-
atkbd->num_function_row_keys = n;
1199+
atkbd->vdata.function_row_physmap,
1200+
n)) {
1201+
atkbd->vdata.num_function_row_keys = n;
12131202
dev_dbg(dev, "FW reported %d function-row key locations\n", n);
12141203
}
12151204
}

drivers/input/keyboard/cros_ec_keyb.c

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/bitops.h>
1616
#include <linux/i2c.h>
1717
#include <linux/input.h>
18+
#include <linux/input/vivaldi-fmap.h>
1819
#include <linux/interrupt.h>
1920
#include <linux/kernel.h>
2021
#include <linux/notifier.h>
@@ -27,8 +28,6 @@
2728

2829
#include <asm/unaligned.h>
2930

30-
#define MAX_NUM_TOP_ROW_KEYS 15
31-
3231
/**
3332
* struct cros_ec_keyb - Structure representing EC keyboard device
3433
*
@@ -44,9 +43,7 @@
4443
* @idev: The input device for the matrix keys.
4544
* @bs_idev: The input device for non-matrix buttons and switches (or NULL).
4645
* @notifier: interrupt event notifier for transport devices
47-
* @function_row_physmap: An array of the encoded rows/columns for the top
48-
* row function keys, in an order from left to right
49-
* @num_function_row_keys: The number of top row keys in a custom keyboard
46+
* @vdata: vivaldi function row data
5047
*/
5148
struct cros_ec_keyb {
5249
unsigned int rows;
@@ -64,8 +61,7 @@ struct cros_ec_keyb {
6461
struct input_dev *bs_idev;
6562
struct notifier_block notifier;
6663

67-
u16 function_row_physmap[MAX_NUM_TOP_ROW_KEYS];
68-
size_t num_function_row_keys;
64+
struct vivaldi_data vdata;
6965
};
7066

7167
/**
@@ -537,9 +533,9 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
537533
int err;
538534
struct property *prop;
539535
const __be32 *p;
540-
u16 *physmap;
536+
u32 *physmap;
541537
u32 key_pos;
542-
int row, col;
538+
unsigned int row, col, scancode, n_physmap;
543539

544540
err = matrix_keypad_parse_properties(dev, &ckdev->rows, &ckdev->cols);
545541
if (err)
@@ -591,20 +587,21 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
591587
ckdev->idev = idev;
592588
cros_ec_keyb_compute_valid_keys(ckdev);
593589

594-
physmap = ckdev->function_row_physmap;
590+
physmap = ckdev->vdata.function_row_physmap;
591+
n_physmap = 0;
595592
of_property_for_each_u32(dev->of_node, "function-row-physmap",
596593
prop, p, key_pos) {
597-
if (ckdev->num_function_row_keys == MAX_NUM_TOP_ROW_KEYS) {
594+
if (n_physmap == VIVALDI_MAX_FUNCTION_ROW_KEYS) {
598595
dev_warn(dev, "Only support up to %d top row keys\n",
599-
MAX_NUM_TOP_ROW_KEYS);
596+
VIVALDI_MAX_FUNCTION_ROW_KEYS);
600597
break;
601598
}
602599
row = KEY_ROW(key_pos);
603600
col = KEY_COL(key_pos);
604-
*physmap = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
605-
physmap++;
606-
ckdev->num_function_row_keys++;
601+
scancode = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
602+
physmap[n_physmap++] = scancode;
607603
}
604+
ckdev->vdata.num_function_row_keys = n_physmap;
608605

609606
err = input_register_device(ckdev->idev);
610607
if (err) {
@@ -619,18 +616,10 @@ static ssize_t function_row_physmap_show(struct device *dev,
619616
struct device_attribute *attr,
620617
char *buf)
621618
{
622-
ssize_t size = 0;
623-
int i;
624-
struct cros_ec_keyb *ckdev = dev_get_drvdata(dev);
625-
u16 *physmap = ckdev->function_row_physmap;
626-
627-
for (i = 0; i < ckdev->num_function_row_keys; i++)
628-
size += scnprintf(buf + size, PAGE_SIZE - size,
629-
"%s%02X", size ? " " : "", physmap[i]);
630-
if (size)
631-
size += scnprintf(buf + size, PAGE_SIZE - size, "\n");
619+
const struct cros_ec_keyb *ckdev = dev_get_drvdata(dev);
620+
const struct vivaldi_data *data = &ckdev->vdata;
632621

633-
return size;
622+
return vivaldi_function_row_physmap_show(data, buf);
634623
}
635624

636625
static DEVICE_ATTR_RO(function_row_physmap);
@@ -648,7 +637,7 @@ static umode_t cros_ec_keyb_attr_is_visible(struct kobject *kobj,
648637
struct cros_ec_keyb *ckdev = dev_get_drvdata(dev);
649638

650639
if (attr == &dev_attr_function_row_physmap.attr &&
651-
!ckdev->num_function_row_keys)
640+
!ckdev->vdata.num_function_row_keys)
652641
return 0;
653642

654643
return attr->mode;

drivers/input/vivaldi-fmap.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Helpers for ChromeOS Vivaldi keyboard function row mapping
4+
*
5+
* Copyright (C) 2022 Google, Inc
6+
*/
7+
8+
#include <linux/export.h>
9+
#include <linux/input/vivaldi-fmap.h>
10+
#include <linux/kernel.h>
11+
#include <linux/module.h>
12+
#include <linux/types.h>
13+
14+
/**
15+
* vivaldi_function_row_physmap_show - Print vivaldi function row physmap attribute
16+
* @data: The vivaldi function row map
17+
* @buf: Buffer to print the function row phsymap to
18+
*/
19+
ssize_t vivaldi_function_row_physmap_show(const struct vivaldi_data *data,
20+
char *buf)
21+
{
22+
ssize_t size = 0;
23+
int i;
24+
const u32 *physmap = data->function_row_physmap;
25+
26+
if (!data->num_function_row_keys)
27+
return 0;
28+
29+
for (i = 0; i < data->num_function_row_keys; i++)
30+
size += scnprintf(buf + size, PAGE_SIZE - size,
31+
"%s%02X", size ? " " : "", physmap[i]);
32+
if (size)
33+
size += scnprintf(buf + size, PAGE_SIZE - size, "\n");
34+
35+
return size;
36+
}
37+
EXPORT_SYMBOL_GPL(vivaldi_function_row_physmap_show);
38+
39+
MODULE_LICENSE("GPL");

include/linux/input/vivaldi-fmap.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef _VIVALDI_FMAP_H
3+
#define _VIVALDI_FMAP_H
4+
5+
#include <linux/types.h>
6+
7+
#define VIVALDI_MAX_FUNCTION_ROW_KEYS 24
8+
9+
/**
10+
* struct vivaldi_data - Function row map data for ChromeOS Vivaldi keyboards
11+
* @function_row_physmap: An array of scancodes or their equivalent (HID usage
12+
* codes, encoded rows/columns, etc) for the top
13+
* row function keys, in an order from left to right
14+
* @num_function_row_keys: The number of top row keys in a custom keyboard
15+
*
16+
* This structure is supposed to be used by ChromeOS keyboards using
17+
* the Vivaldi keyboard function row design.
18+
*/
19+
struct vivaldi_data {
20+
u32 function_row_physmap[VIVALDI_MAX_FUNCTION_ROW_KEYS];
21+
unsigned int num_function_row_keys;
22+
};
23+
24+
ssize_t vivaldi_function_row_physmap_show(const struct vivaldi_data *data,
25+
char *buf);
26+
27+
#endif /* _VIVALDI_FMAP_H */

0 commit comments

Comments
 (0)