Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: synaptics-rmi4 - add support for Forcepads (F21)

Forcepad devices do not have physical buttons underneath the surface and
use F21 to report "clicks" based on touch pressure.

Signed-off-by: Marge Yang <Marge.Yang@tw.synaptics.com>
Link: https://lore.kernel.org/r/20250716033648.1785509-1-marge.yang@tw.synaptics.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Marge Yang and committed by
Dmitry Torokhov
a9c95d17 bc25e6bf

+192
+8
drivers/input/rmi4/Kconfig
··· 82 82 touchpads. For sensors that support relative pointing, F12 also 83 83 provides mouse input. 84 84 85 + config RMI4_F21 86 + bool "RMI4 Function 21 (PRESSURE)" 87 + help 88 + Say Y here if you want to add support for RMI4 function 21. 89 + 90 + Function 21 provides buttons/pressure handling for RMI4 devices. 91 + This includes support for buttons/pressure on PressurePad. 92 + 85 93 config RMI4_F30 86 94 bool "RMI4 Function 30 (GPIO LED)" 87 95 help
+1
drivers/input/rmi4/Makefile
··· 8 8 rmi_core-$(CONFIG_RMI4_F03) += rmi_f03.o 9 9 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o 10 10 rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o 11 + rmi_core-$(CONFIG_RMI4_F21) += rmi_f21.o 11 12 rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o 12 13 rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o rmi_f34v7.o 13 14 rmi_core-$(CONFIG_RMI4_F3A) += rmi_f3a.o
+3
drivers/input/rmi4/rmi_bus.c
··· 360 360 #ifdef CONFIG_RMI4_F12 361 361 &rmi_f12_handler, 362 362 #endif 363 + #ifdef CONFIG_RMI4_F21 364 + &rmi_f21_handler, 365 + #endif 363 366 #ifdef CONFIG_RMI4_F30 364 367 &rmi_f30_handler, 365 368 #endif
+1
drivers/input/rmi4/rmi_driver.h
··· 133 133 extern struct rmi_function_handler rmi_f03_handler; 134 134 extern struct rmi_function_handler rmi_f11_handler; 135 135 extern struct rmi_function_handler rmi_f12_handler; 136 + extern struct rmi_function_handler rmi_f21_handler; 136 137 extern struct rmi_function_handler rmi_f30_handler; 137 138 extern struct rmi_function_handler rmi_f34_handler; 138 139 extern struct rmi_function_handler rmi_f3a_handler;
+179
drivers/input/rmi4/rmi_f21.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2012-2025 Synaptics Incorporated 4 + */ 5 + 6 + #include <linux/bits.h> 7 + #include <linux/dev_printk.h> 8 + #include <linux/kernel.h> 9 + #include <linux/rmi.h> 10 + #include <linux/input.h> 11 + #include <linux/slab.h> 12 + #include "rmi_driver.h" 13 + 14 + #define RMI_F21_SENSOR_COUNT_MASK GENMASK(3, 0) 15 + #define RMI_F21_FINGER_COUNT_PRESENT BIT(5) 16 + #define RMI_F21_NEW_REPORT_FORMAT BIT(6) 17 + 18 + #define RMI_F21_FINGER_COUNT_MASK GENMASK(3, 0) 19 + 20 + #define RMI_F21_MAX_SENSORS 16 21 + #define RMI_F21_MAX_FINGERS 16 22 + #define RMI_F21_DATA_REGS_MAX_SIZE (RMI_F21_MAX_SENSORS * 2 + \ 23 + RMI_F21_MAX_FINGERS * 2 + 1) 24 + 25 + #define RMI_F21_FORCE_CLICK_BIT BIT(0) 26 + 27 + #define RMI_F21_FORCEPAD_BUTTON_COUNT 1 28 + 29 + struct f21_data { 30 + struct input_dev *input; 31 + u16 key_code; 32 + 33 + unsigned int attn_data_size; 34 + unsigned int attn_data_button_offset; 35 + 36 + unsigned int data_reg_size; 37 + unsigned int data_reg_button_offset; 38 + u8 data_regs[RMI_F21_DATA_REGS_MAX_SIZE]; 39 + }; 40 + 41 + static irqreturn_t rmi_f21_attention(int irq, void *ctx) 42 + { 43 + struct rmi_function *fn = ctx; 44 + struct f21_data *f21 = dev_get_drvdata(&fn->dev); 45 + struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev); 46 + u8 *pdata; 47 + int error; 48 + bool pressed; 49 + 50 + if (drvdata->attn_data.data) { 51 + if (drvdata->attn_data.size < f21->attn_data_size) { 52 + dev_warn(&fn->dev, "f21 interrupt, but data is missing\n"); 53 + return IRQ_HANDLED; 54 + } 55 + 56 + pdata = drvdata->attn_data.data + f21->attn_data_button_offset; 57 + 58 + drvdata->attn_data.data += f21->attn_data_size; 59 + drvdata->attn_data.size -= f21->attn_data_size; 60 + } else { 61 + error = rmi_read_block(fn->rmi_dev, fn->fd.data_base_addr, 62 + f21->data_regs, f21->data_reg_size); 63 + if (error) { 64 + dev_err(&fn->dev, "failed to read f21 data registers: %d\n", 65 + error); 66 + return IRQ_RETVAL(error); 67 + } 68 + 69 + pdata = f21->data_regs + f21->data_reg_button_offset; 70 + } 71 + 72 + pressed = *pdata & RMI_F21_FORCE_CLICK_BIT; 73 + input_report_key(f21->input, f21->key_code, pressed); 74 + 75 + return IRQ_HANDLED; 76 + } 77 + 78 + static int rmi_f21_config(struct rmi_function *fn) 79 + { 80 + struct rmi_driver *drv = fn->rmi_dev->driver; 81 + 82 + drv->set_irq_bits(fn->rmi_dev, fn->irq_mask); 83 + 84 + return 0; 85 + } 86 + 87 + static int rmi_f21_initialize(struct rmi_function *fn, struct f21_data *f21) 88 + { 89 + struct input_dev *input = f21->input; 90 + 91 + f21->key_code = BTN_LEFT; 92 + 93 + input->keycode = &f21->key_code; 94 + input->keycodesize = sizeof(f21->key_code); 95 + input->keycodemax = RMI_F21_FORCEPAD_BUTTON_COUNT; 96 + 97 + input_set_capability(input, EV_KEY, f21->key_code); 98 + __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); 99 + 100 + return 0; 101 + } 102 + 103 + static int rmi_f21_probe(struct rmi_function *fn) 104 + { 105 + struct rmi_device *rmi_dev = fn->rmi_dev; 106 + struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev); 107 + struct f21_data *f21; 108 + unsigned int sensor_count; 109 + unsigned int max_fingers; 110 + unsigned int query15_offset; 111 + u8 query15_data; 112 + int error; 113 + 114 + if (!drv_data->input) { 115 + dev_info(&fn->dev, "f21: no input device found, ignoring\n"); 116 + return -ENXIO; 117 + } 118 + 119 + f21 = devm_kzalloc(&fn->dev, sizeof(*f21), GFP_KERNEL); 120 + if (!f21) 121 + return -ENOMEM; 122 + 123 + f21->input = drv_data->input; 124 + 125 + error = rmi_f21_initialize(fn, f21); 126 + if (error) 127 + return error; 128 + 129 + dev_set_drvdata(&fn->dev, f21); 130 + 131 + sensor_count = fn->fd.query_base_addr & RMI_F21_SENSOR_COUNT_MASK; 132 + if (fn->fd.query_base_addr & RMI_F21_FINGER_COUNT_PRESENT) { 133 + query15_offset = fn->fd.query_base_addr & RMI_F21_NEW_REPORT_FORMAT ? 2 : 1; 134 + error = rmi_read_block(fn->rmi_dev, 135 + fn->fd.query_base_addr + query15_offset, 136 + &query15_data, sizeof(query15_data)); 137 + if (error) 138 + return dev_err_probe(&fn->dev, error, 139 + "failed to read 'query15' data"); 140 + 141 + max_fingers = query15_data & RMI_F21_FINGER_COUNT_MASK; 142 + } else { 143 + max_fingers = 5; 144 + } 145 + 146 + if (fn->fd.query_base_addr & RMI_F21_NEW_REPORT_FORMAT) { 147 + /* Each finger uses one byte, and the button state uses one byte.*/ 148 + f21->attn_data_size = max_fingers + 1; 149 + f21->attn_data_button_offset = f21->attn_data_size - 1; 150 + /* 151 + * Each sensor uses two bytes, the button state uses one byte, 152 + * and each finger uses two bytes. 153 + */ 154 + f21->data_reg_size = sensor_count * 2 + 1 + max_fingers * 2; 155 + f21->data_reg_button_offset = sensor_count * 2; 156 + } else { 157 + /* 158 + * Regardless of the transport each finger uses two bytes, 159 + * and the button state uses one byte. 160 + */ 161 + f21->attn_data_size = sensor_count * 2 + 1; 162 + f21->attn_data_button_offset = sensor_count * 2; 163 + 164 + f21->data_reg_size = f21->attn_data_size; 165 + f21->data_reg_button_offset = f21->attn_data_button_offset; 166 + } 167 + 168 + return 0; 169 + } 170 + 171 + struct rmi_function_handler rmi_f21_handler = { 172 + .driver = { 173 + .name = "rmi4_f21", 174 + }, 175 + .func = 0x21, 176 + .probe = rmi_f21_probe, 177 + .config = rmi_f21_config, 178 + .attention = rmi_f21_attention, 179 + };