1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright 2025 Bootlin 4 * 5 * Author: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com> 6 */ 7 8 #include <linux/bitfield.h> 9 #include <linux/bitops.h> 10 #include <linux/dev_printk.h> 11 #include <linux/device/devres.h> 12 #include <linux/err.h> 13 #include <linux/init.h> 14 #include <linux/input.h> 15 #include <linux/input/matrix_keypad.h> 16 #include <linux/interrupt.h> 17 #include <linux/mfd/max7360.h> 18 #include <linux/minmax.h> 19 #include <linux/module.h> 20 #include <linux/property.h> 21 #include <linux/platform_device.h> 22 #include <linux/pm_wakeirq.h> 23 #include <linux/regmap.h> 24 25 struct max7360_keypad { 26 struct input_dev *input; 27 unsigned int rows; 28 unsigned int cols; 29 unsigned int debounce_ms; 30 int irq; 31 struct regmap *regmap; 32 unsigned short keycodes[MAX7360_MAX_KEY_ROWS * MAX7360_MAX_KEY_COLS]; 33 }; 34 35 static irqreturn_t max7360_keypad_irq(int irq, void *data) 36 { 37 struct max7360_keypad *max7360_keypad = data; 38 struct device *dev = max7360_keypad->input->dev.parent; 39 unsigned int val; 40 unsigned int row, col; 41 unsigned int release; 42 unsigned int code; 43 int error; 44 45 error = regmap_read(max7360_keypad->regmap, MAX7360_REG_KEYFIFO, &val); 46 if (error) { 47 dev_err(dev, "Failed to read MAX7360 FIFO"); 48 return IRQ_NONE; 49 } 50 51 /* FIFO overflow: ignore it and get next event. */ 52 if (val == MAX7360_FIFO_OVERFLOW) { 53 dev_warn(dev, "max7360 FIFO overflow"); 54 error = regmap_read_poll_timeout(max7360_keypad->regmap, MAX7360_REG_KEYFIFO, 55 val, val != MAX7360_FIFO_OVERFLOW, 0, 1000); 56 if (error) { 57 dev_err(dev, "Failed to empty MAX7360 FIFO"); 58 return IRQ_NONE; 59 } 60 } 61 62 if (val == MAX7360_FIFO_EMPTY) { 63 dev_dbg(dev, "Got a spurious interrupt"); 64 65 return IRQ_NONE; 66 } 67 68 row = FIELD_GET(MAX7360_FIFO_ROW, val); 69 col = FIELD_GET(MAX7360_FIFO_COL, val); 70 release = val & MAX7360_FIFO_RELEASE; 71 72 code = MATRIX_SCAN_CODE(row, col, get_count_order(max7360_keypad->cols)); 73 74 dev_dbg(dev, "key[%d:%d] %s\n", row, col, release ? "release" : "press"); 75 76 input_event(max7360_keypad->input, EV_MSC, MSC_SCAN, code); 77 input_report_key(max7360_keypad->input, max7360_keypad->keycodes[code], !release); 78 input_sync(max7360_keypad->input); 79 80 return IRQ_HANDLED; 81 } 82 83 static int max7360_keypad_open(struct input_dev *pdev) 84 { 85 struct max7360_keypad *max7360_keypad = input_get_drvdata(pdev); 86 struct device *dev = max7360_keypad->input->dev.parent; 87 int error; 88 89 /* Somebody is using the device: get out of sleep. */ 90 error = regmap_write_bits(max7360_keypad->regmap, MAX7360_REG_CONFIG, 91 MAX7360_CFG_SLEEP, MAX7360_CFG_SLEEP); 92 if (error) 93 dev_err(dev, "Failed to write max7360 configuration: %d\n", error); 94 95 return error; 96 } 97 98 static void max7360_keypad_close(struct input_dev *pdev) 99 { 100 struct max7360_keypad *max7360_keypad = input_get_drvdata(pdev); 101 struct device *dev = max7360_keypad->input->dev.parent; 102 int error; 103 104 /* Nobody is using the device anymore: go to sleep. */ 105 error = regmap_write_bits(max7360_keypad->regmap, MAX7360_REG_CONFIG, MAX7360_CFG_SLEEP, 0); 106 if (error) 107 dev_err(dev, "Failed to write max7360 configuration: %d\n", error); 108 } 109 110 static int max7360_keypad_hw_init(struct max7360_keypad *max7360_keypad) 111 { 112 struct device *dev = max7360_keypad->input->dev.parent; 113 unsigned int val; 114 int error; 115 116 val = max7360_keypad->debounce_ms - MAX7360_DEBOUNCE_MIN; 117 error = regmap_write_bits(max7360_keypad->regmap, MAX7360_REG_DEBOUNCE, 118 MAX7360_DEBOUNCE, 119 FIELD_PREP(MAX7360_DEBOUNCE, val)); 120 if (error) 121 return dev_err_probe(dev, error, 122 "Failed to write max7360 debounce configuration\n"); 123 124 error = regmap_write_bits(max7360_keypad->regmap, MAX7360_REG_INTERRUPT, 125 MAX7360_INTERRUPT_TIME_MASK, 126 FIELD_PREP(MAX7360_INTERRUPT_TIME_MASK, 1)); 127 if (error) 128 return dev_err_probe(dev, error, 129 "Failed to write max7360 keypad interrupt configuration\n"); 130 131 return 0; 132 } 133 134 static int max7360_keypad_build_keymap(struct max7360_keypad *max7360_keypad) 135 { 136 struct input_dev *input_dev = max7360_keypad->input; 137 struct device *dev = input_dev->dev.parent->parent; 138 struct matrix_keymap_data keymap_data; 139 const char *propname = "linux,keymap"; 140 unsigned int max_keys; 141 int error; 142 int size; 143 144 size = device_property_count_u32(dev, propname); 145 if (size <= 0) { 146 dev_err(dev, "missing or malformed property %s: %d\n", propname, size); 147 return size < 0 ? size : -EINVAL; 148 } 149 150 max_keys = max7360_keypad->cols * max7360_keypad->rows; 151 if (size > max_keys) { 152 dev_err(dev, "%s size overflow (%d vs max %u)\n", propname, size, max_keys); 153 return -EINVAL; 154 } 155 156 u32 *keys __free(kfree) = kmalloc_array(size, sizeof(*keys), GFP_KERNEL); 157 if (!keys) 158 return -ENOMEM; 159 160 error = device_property_read_u32_array(dev, propname, keys, size); 161 if (error) { 162 dev_err(dev, "failed to read %s property: %d\n", propname, error); 163 return error; 164 } 165 166 keymap_data.keymap = keys; 167 keymap_data.keymap_size = size; 168 error = matrix_keypad_build_keymap(&keymap_data, NULL, 169 max7360_keypad->rows, max7360_keypad->cols, 170 max7360_keypad->keycodes, max7360_keypad->input); 171 if (error) 172 return error; 173 174 return 0; 175 } 176 177 static int max7360_keypad_parse_fw(struct device *dev, 178 struct max7360_keypad *max7360_keypad, 179 bool *autorepeat) 180 { 181 int error; 182 183 error = matrix_keypad_parse_properties(dev->parent, &max7360_keypad->rows, 184 &max7360_keypad->cols); 185 if (error) 186 return error; 187 188 if (!max7360_keypad->rows || !max7360_keypad->cols || 189 max7360_keypad->rows > MAX7360_MAX_KEY_ROWS || 190 max7360_keypad->cols > MAX7360_MAX_KEY_COLS) { 191 dev_err(dev, "Invalid number of columns or rows (%ux%u)\n", 192 max7360_keypad->cols, max7360_keypad->rows); 193 return -EINVAL; 194 } 195 196 *autorepeat = device_property_read_bool(dev->parent, "autorepeat"); 197 198 max7360_keypad->debounce_ms = MAX7360_DEBOUNCE_MIN; 199 error = device_property_read_u32(dev->parent, "keypad-debounce-delay-ms", 200 &max7360_keypad->debounce_ms); 201 if (error == -EINVAL) { 202 dev_info(dev, "Using default keypad-debounce-delay-ms: %u\n", 203 max7360_keypad->debounce_ms); 204 } else if (error < 0) { 205 dev_err(dev, "Failed to read keypad-debounce-delay-ms property\n"); 206 return error; 207 } 208 209 if (!in_range(max7360_keypad->debounce_ms, MAX7360_DEBOUNCE_MIN, 210 MAX7360_DEBOUNCE_MAX - MAX7360_DEBOUNCE_MIN + 1)) { 211 dev_err(dev, "Invalid keypad-debounce-delay-ms: %u, should be between %u and %u.\n", 212 max7360_keypad->debounce_ms, MAX7360_DEBOUNCE_MIN, MAX7360_DEBOUNCE_MAX); 213 return -EINVAL; 214 } 215 216 return 0; 217 } 218 219 static int max7360_keypad_probe(struct platform_device *pdev) 220 { 221 struct max7360_keypad *max7360_keypad; 222 struct device *dev = &pdev->dev; 223 struct input_dev *input; 224 struct regmap *regmap; 225 bool autorepeat; 226 int error; 227 int irq; 228 229 regmap = dev_get_regmap(dev->parent, NULL); 230 if (!regmap) 231 return dev_err_probe(dev, -ENODEV, "Could not get parent regmap\n"); 232 233 irq = fwnode_irq_get_byname(dev_fwnode(dev->parent), "intk"); 234 if (irq < 0) 235 return dev_err_probe(dev, irq, "Failed to get IRQ\n"); 236 237 max7360_keypad = devm_kzalloc(dev, sizeof(*max7360_keypad), GFP_KERNEL); 238 if (!max7360_keypad) 239 return -ENOMEM; 240 241 max7360_keypad->regmap = regmap; 242 243 error = max7360_keypad_parse_fw(dev, max7360_keypad, &autorepeat); 244 if (error) 245 return error; 246 247 input = devm_input_allocate_device(dev); 248 if (!input) 249 return -ENOMEM; 250 251 max7360_keypad->input = input; 252 253 input->id.bustype = BUS_I2C; 254 input->name = pdev->name; 255 input->open = max7360_keypad_open; 256 input->close = max7360_keypad_close; 257 258 error = max7360_keypad_build_keymap(max7360_keypad); 259 if (error) 260 return dev_err_probe(dev, error, "Failed to build keymap\n"); 261 262 input_set_capability(input, EV_MSC, MSC_SCAN); 263 if (autorepeat) 264 __set_bit(EV_REP, input->evbit); 265 266 input_set_drvdata(input, max7360_keypad); 267 268 error = devm_request_threaded_irq(dev, irq, NULL, max7360_keypad_irq, 269 IRQF_ONESHOT, 270 "max7360-keypad", max7360_keypad); 271 if (error) 272 return dev_err_probe(dev, error, "Failed to register interrupt\n"); 273 274 error = input_register_device(input); 275 if (error) 276 return dev_err_probe(dev, error, "Could not register input device\n"); 277 278 error = max7360_keypad_hw_init(max7360_keypad); 279 if (error) 280 return dev_err_probe(dev, error, "Failed to initialize max7360 keypad\n"); 281 282 device_init_wakeup(dev, true); 283 error = dev_pm_set_wake_irq(dev, irq); 284 if (error) 285 dev_warn(dev, "Failed to set up wakeup irq: %d\n", error); 286 287 return 0; 288 } 289 290 static void max7360_keypad_remove(struct platform_device *pdev) 291 { 292 dev_pm_clear_wake_irq(&pdev->dev); 293 device_init_wakeup(&pdev->dev, false); 294 } 295 296 static struct platform_driver max7360_keypad_driver = { 297 .driver = { 298 .name = "max7360-keypad", 299 }, 300 .probe = max7360_keypad_probe, 301 .remove = max7360_keypad_remove, 302 }; 303 module_platform_driver(max7360_keypad_driver); 304 305 MODULE_DESCRIPTION("MAX7360 Keypad driver"); 306 MODULE_AUTHOR("Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>"); 307 MODULE_LICENSE("GPL"); 308