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

Configure Feed

Select the types of activity you want to include in your feed.

Input: matrix_keypad - switch to gpiod API and generic device properties

gpiod API and generic device properties work with software nodes and
static properties, which will allow removing platform data support
from the driver, simplifying and streamlining the code.

Acked-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20240805014710.1961677-3-dmitry.torokhov@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

+189 -160
+189 -160
drivers/input/keyboard/matrix_keypad.c
··· 17 17 #include <linux/jiffies.h> 18 18 #include <linux/module.h> 19 19 #include <linux/gpio.h> 20 + #include <linux/gpio/consumer.h> 20 21 #include <linux/input/matrix_keypad.h> 21 22 #include <linux/slab.h> 22 23 #include <linux/of.h> 23 - #include <linux/of_gpio.h> 24 - #include <linux/of_platform.h> 25 24 26 25 struct matrix_keypad { 27 - const struct matrix_keypad_platform_data *pdata; 28 26 struct input_dev *input_dev; 29 27 unsigned int row_shift; 28 + 29 + unsigned int col_scan_delay_us; 30 + /* key debounce interval in milli-second */ 31 + unsigned int debounce_ms; 32 + bool drive_inactive_cols; 33 + 34 + struct gpio_desc *row_gpios[MATRIX_MAX_ROWS]; 35 + unsigned int num_row_gpios; 36 + 37 + struct gpio_desc *col_gpios[MATRIX_MAX_ROWS]; 38 + unsigned int num_col_gpios; 30 39 31 40 unsigned int row_irqs[MATRIX_MAX_ROWS]; 32 41 DECLARE_BITMAP(wakeup_enabled_irqs, MATRIX_MAX_ROWS); ··· 53 44 * columns. In that case it is configured here to be input, otherwise it is 54 45 * driven with the inactive value. 55 46 */ 56 - static void __activate_col(const struct matrix_keypad_platform_data *pdata, 57 - int col, bool on) 47 + static void __activate_col(struct matrix_keypad *keypad, int col, bool on) 58 48 { 59 - bool level_on = !pdata->active_low; 60 - 61 49 if (on) { 62 - gpio_direction_output(pdata->col_gpios[col], level_on); 50 + gpiod_direction_output(keypad->col_gpios[col], 1); 63 51 } else { 64 - gpio_set_value_cansleep(pdata->col_gpios[col], !level_on); 65 - if (!pdata->drive_inactive_cols) 66 - gpio_direction_input(pdata->col_gpios[col]); 52 + gpiod_set_value_cansleep(keypad->col_gpios[col], 0); 53 + if (!keypad->drive_inactive_cols) 54 + gpiod_direction_input(keypad->col_gpios[col]); 67 55 } 68 56 } 69 57 70 - static void activate_col(const struct matrix_keypad_platform_data *pdata, 71 - int col, bool on) 58 + static void activate_col(struct matrix_keypad *keypad, int col, bool on) 72 59 { 73 - __activate_col(pdata, col, on); 60 + __activate_col(keypad, col, on); 74 61 75 - if (on && pdata->col_scan_delay_us) 76 - udelay(pdata->col_scan_delay_us); 62 + if (on && keypad->col_scan_delay_us) 63 + udelay(keypad->col_scan_delay_us); 77 64 } 78 65 79 - static void activate_all_cols(const struct matrix_keypad_platform_data *pdata, 80 - bool on) 66 + static void activate_all_cols(struct matrix_keypad *keypad, bool on) 81 67 { 82 68 int col; 83 69 84 - for (col = 0; col < pdata->num_col_gpios; col++) 85 - __activate_col(pdata, col, on); 70 + for (col = 0; col < keypad->num_col_gpios; col++) 71 + __activate_col(keypad, col, on); 86 72 } 87 73 88 - static bool row_asserted(const struct matrix_keypad_platform_data *pdata, 89 - int row) 74 + static bool row_asserted(struct matrix_keypad *keypad, int row) 90 75 { 91 - return gpio_get_value_cansleep(pdata->row_gpios[row]) ? 92 - !pdata->active_low : pdata->active_low; 76 + return gpiod_get_value_cansleep(keypad->row_gpios[row]); 93 77 } 94 78 95 79 static void enable_row_irqs(struct matrix_keypad *keypad) 96 80 { 97 81 int i; 98 82 99 - for (i = 0; i < keypad->pdata->num_row_gpios; i++) 83 + for (i = 0; i < keypad->num_row_gpios; i++) 100 84 enable_irq(keypad->row_irqs[i]); 101 85 } 102 86 ··· 97 95 { 98 96 int i; 99 97 100 - for (i = 0; i < keypad->pdata->num_row_gpios; i++) 98 + for (i = 0; i < keypad->num_row_gpios; i++) 101 99 disable_irq_nosync(keypad->row_irqs[i]); 102 100 } 103 101 ··· 110 108 container_of(work, struct matrix_keypad, work.work); 111 109 struct input_dev *input_dev = keypad->input_dev; 112 110 const unsigned short *keycodes = input_dev->keycode; 113 - const struct matrix_keypad_platform_data *pdata = keypad->pdata; 114 111 uint32_t new_state[MATRIX_MAX_COLS]; 115 112 int row, col, code; 116 113 117 114 /* de-activate all columns for scanning */ 118 - activate_all_cols(pdata, false); 115 + activate_all_cols(keypad, false); 119 116 120 117 memset(new_state, 0, sizeof(new_state)); 121 118 122 - for (row = 0; row < pdata->num_row_gpios; row++) 123 - gpio_direction_input(pdata->row_gpios[row]); 119 + for (row = 0; row < keypad->num_row_gpios; row++) 120 + gpiod_direction_input(keypad->row_gpios[row]); 124 121 125 122 /* assert each column and read the row status out */ 126 - for (col = 0; col < pdata->num_col_gpios; col++) { 123 + for (col = 0; col < keypad->num_col_gpios; col++) { 127 124 128 - activate_col(pdata, col, true); 125 + activate_col(keypad, col, true); 129 126 130 - for (row = 0; row < pdata->num_row_gpios; row++) 127 + for (row = 0; row < keypad->num_row_gpios; row++) 131 128 new_state[col] |= 132 - row_asserted(pdata, row) ? (1 << row) : 0; 129 + row_asserted(keypad, row) ? BIT(row) : 0; 133 130 134 - activate_col(pdata, col, false); 131 + activate_col(keypad, col, false); 135 132 } 136 133 137 - for (col = 0; col < pdata->num_col_gpios; col++) { 134 + for (col = 0; col < keypad->num_col_gpios; col++) { 138 135 uint32_t bits_changed; 139 136 140 137 bits_changed = keypad->last_key_state[col] ^ new_state[col]; 141 138 if (bits_changed == 0) 142 139 continue; 143 140 144 - for (row = 0; row < pdata->num_row_gpios; row++) { 145 - if ((bits_changed & (1 << row)) == 0) 141 + for (row = 0; row < keypad->num_row_gpios; row++) { 142 + if (!(bits_changed & BIT(row))) 146 143 continue; 147 144 148 145 code = MATRIX_SCAN_CODE(row, col, keypad->row_shift); ··· 155 154 156 155 memcpy(keypad->last_key_state, new_state, sizeof(new_state)); 157 156 158 - activate_all_cols(pdata, true); 157 + activate_all_cols(keypad, true); 159 158 160 159 /* Enable IRQs again */ 161 160 spin_lock_irq(&keypad->lock); ··· 182 181 disable_row_irqs(keypad); 183 182 keypad->scan_pending = true; 184 183 schedule_delayed_work(&keypad->work, 185 - msecs_to_jiffies(keypad->pdata->debounce_ms)); 184 + msecs_to_jiffies(keypad->debounce_ms)); 186 185 187 186 out: 188 187 spin_unlock_irqrestore(&keypad->lock, flags); ··· 226 225 int i; 227 226 228 227 for_each_clear_bit(i, keypad->wakeup_enabled_irqs, 229 - keypad->pdata->num_row_gpios) 228 + keypad->num_row_gpios) 230 229 if (enable_irq_wake(keypad->row_irqs[i]) == 0) 231 230 __set_bit(i, keypad->wakeup_enabled_irqs); 232 231 } ··· 236 235 int i; 237 236 238 237 for_each_set_bit(i, keypad->wakeup_enabled_irqs, 239 - keypad->pdata->num_row_gpios) { 238 + keypad->num_row_gpios) { 240 239 disable_irq_wake(keypad->row_irqs[i]); 241 240 __clear_bit(i, keypad->wakeup_enabled_irqs); 242 241 } ··· 271 270 static DEFINE_SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops, 272 271 matrix_keypad_suspend, matrix_keypad_resume); 273 272 274 - static int matrix_keypad_init_gpio(struct platform_device *pdev, 275 - struct matrix_keypad *keypad) 273 + static int matrix_keypad_init_pdata_gpio(struct platform_device *pdev, 274 + const struct matrix_keypad_platform_data *pdata, 275 + struct matrix_keypad *keypad) 276 276 { 277 - const struct matrix_keypad_platform_data *pdata = keypad->pdata; 278 - int i, irq, err; 277 + int i, err; 278 + 279 + keypad->num_col_gpios = pdata->num_col_gpios; 280 + keypad->num_row_gpios = pdata->num_row_gpios; 279 281 280 282 /* initialized strobe lines as outputs, activated */ 281 283 for (i = 0; i < pdata->num_col_gpios; i++) { ··· 291 287 return err; 292 288 } 293 289 294 - gpio_direction_output(pdata->col_gpios[i], !pdata->active_low); 290 + keypad->col_gpios[i] = gpio_to_desc(pdata->col_gpios[i]); 291 + 292 + if (pdata->active_low ^ gpiod_is_active_low(keypad->col_gpios[i])) 293 + gpiod_toggle_active_low(keypad->col_gpios[i]); 294 + 295 + gpiod_direction_output(keypad->col_gpios[i], 1); 295 296 } 296 297 297 298 for (i = 0; i < pdata->num_row_gpios; i++) { ··· 309 300 return err; 310 301 } 311 302 312 - gpio_direction_input(pdata->row_gpios[i]); 303 + keypad->row_gpios[i] = gpio_to_desc(pdata->row_gpios[i]); 304 + 305 + if (pdata->active_low ^ gpiod_is_active_low(keypad->row_gpios[i])) 306 + gpiod_toggle_active_low(keypad->row_gpios[i]); 307 + 308 + gpiod_direction_input(keypad->row_gpios[i]); 313 309 } 314 310 315 - for (i = 0; i < pdata->num_row_gpios; i++) { 316 - irq = gpio_to_irq(pdata->row_gpios[i]); 311 + return 0; 312 + } 313 + 314 + static int matrix_keypad_init_gpio(struct platform_device *pdev, 315 + struct matrix_keypad *keypad) 316 + { 317 + bool active_low; 318 + int nrow, ncol; 319 + int err; 320 + int i; 321 + 322 + nrow = gpiod_count(&pdev->dev, "row"); 323 + ncol = gpiod_count(&pdev->dev, "col"); 324 + if (nrow < 0 || ncol < 0) { 325 + dev_err(&pdev->dev, "missing row or column GPIOs\n"); 326 + return -EINVAL; 327 + } 328 + 329 + keypad->num_row_gpios = nrow; 330 + keypad->num_col_gpios = ncol; 331 + 332 + active_low = device_property_read_bool(&pdev->dev, "gpio-activelow"); 333 + 334 + /* initialize strobe lines as outputs, activated */ 335 + for (i = 0; i < keypad->num_col_gpios; i++) { 336 + keypad->col_gpios[i] = devm_gpiod_get_index(&pdev->dev, "col", 337 + i, GPIOD_ASIS); 338 + err = PTR_ERR_OR_ZERO(keypad->col_gpios[i]); 339 + if (err) { 340 + dev_err(&pdev->dev, 341 + "failed to request GPIO for COL%d: %d\n", 342 + i, err); 343 + return err; 344 + } 345 + 346 + gpiod_set_consumer_name(keypad->col_gpios[i], "matrix_kbd_col"); 347 + 348 + if (active_low ^ gpiod_is_active_low(keypad->col_gpios[i])) 349 + gpiod_toggle_active_low(keypad->col_gpios[i]); 350 + 351 + gpiod_direction_output(keypad->col_gpios[i], 1); 352 + } 353 + 354 + for (i = 0; i < keypad->num_row_gpios; i++) { 355 + keypad->row_gpios[i] = devm_gpiod_get_index(&pdev->dev, "row", 356 + i, GPIOD_IN); 357 + err = PTR_ERR_OR_ZERO(keypad->row_gpios[i]); 358 + if (err) { 359 + dev_err(&pdev->dev, 360 + "failed to request GPIO for ROW%d: %d\n", 361 + i, err); 362 + return err; 363 + } 364 + 365 + gpiod_set_consumer_name(keypad->row_gpios[i], "matrix_kbd_row"); 366 + 367 + if (active_low ^ gpiod_is_active_low(keypad->row_gpios[i])) 368 + gpiod_toggle_active_low(keypad->row_gpios[i]); 369 + } 370 + 371 + return 0; 372 + } 373 + 374 + static int matrix_keypad_setup_interrupts(struct platform_device *pdev, 375 + struct matrix_keypad *keypad) 376 + { 377 + int err; 378 + int irq; 379 + int i; 380 + 381 + for (i = 0; i < keypad->num_row_gpios; i++) { 382 + irq = gpiod_to_irq(keypad->row_gpios[i]); 317 383 if (irq < 0) { 318 384 err = irq; 319 385 dev_err(&pdev->dev, 320 386 "Unable to convert GPIO line %i to irq: %d\n", 321 - pdata->row_gpios[i], err); 387 + i, err); 322 388 return err; 323 389 } 324 390 325 - err = devm_request_any_context_irq(&pdev->dev, 326 - irq, 327 - matrix_keypad_interrupt, 328 - IRQF_TRIGGER_RISING | 329 - IRQF_TRIGGER_FALLING, 330 - "matrix-keypad", keypad); 391 + err = devm_request_any_context_irq(&pdev->dev, irq, 392 + matrix_keypad_interrupt, 393 + IRQF_TRIGGER_RISING | 394 + IRQF_TRIGGER_FALLING, 395 + "matrix-keypad", keypad); 331 396 if (err < 0) { 332 397 dev_err(&pdev->dev, 333 - "Unable to acquire interrupt for GPIO line %i\n", 334 - pdata->row_gpios[i]); 398 + "Unable to acquire interrupt for row %i: %d\n", 399 + i, err); 335 400 return err; 336 401 } 337 402 ··· 418 335 return 0; 419 336 } 420 337 421 - #ifdef CONFIG_OF 422 - static struct matrix_keypad_platform_data * 423 - matrix_keypad_parse_dt(struct device *dev) 424 - { 425 - struct matrix_keypad_platform_data *pdata; 426 - struct device_node *np = dev->of_node; 427 - unsigned int *gpios; 428 - int ret, i, nrow, ncol; 429 - 430 - if (!np) { 431 - dev_err(dev, "device lacks DT data\n"); 432 - return ERR_PTR(-ENODEV); 433 - } 434 - 435 - pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 436 - if (!pdata) { 437 - dev_err(dev, "could not allocate memory for platform data\n"); 438 - return ERR_PTR(-ENOMEM); 439 - } 440 - 441 - pdata->num_row_gpios = nrow = gpiod_count(dev, "row"); 442 - pdata->num_col_gpios = ncol = gpiod_count(dev, "col"); 443 - if (nrow < 0 || ncol < 0) { 444 - dev_err(dev, "number of keypad rows/columns not specified\n"); 445 - return ERR_PTR(-EINVAL); 446 - } 447 - 448 - pdata->no_autorepeat = of_property_read_bool(np, "linux,no-autorepeat"); 449 - 450 - pdata->wakeup = of_property_read_bool(np, "wakeup-source") || 451 - of_property_read_bool(np, "linux,wakeup"); /* legacy */ 452 - 453 - pdata->active_low = of_property_read_bool(np, "gpio-activelow"); 454 - 455 - pdata->drive_inactive_cols = 456 - of_property_read_bool(np, "drive-inactive-cols"); 457 - 458 - of_property_read_u32(np, "debounce-delay-ms", &pdata->debounce_ms); 459 - of_property_read_u32(np, "col-scan-delay-us", 460 - &pdata->col_scan_delay_us); 461 - 462 - gpios = devm_kcalloc(dev, 463 - pdata->num_row_gpios + pdata->num_col_gpios, 464 - sizeof(unsigned int), 465 - GFP_KERNEL); 466 - if (!gpios) { 467 - dev_err(dev, "could not allocate memory for gpios\n"); 468 - return ERR_PTR(-ENOMEM); 469 - } 470 - 471 - for (i = 0; i < nrow; i++) { 472 - ret = of_get_named_gpio(np, "row-gpios", i); 473 - if (ret < 0) 474 - return ERR_PTR(ret); 475 - gpios[i] = ret; 476 - } 477 - 478 - for (i = 0; i < ncol; i++) { 479 - ret = of_get_named_gpio(np, "col-gpios", i); 480 - if (ret < 0) 481 - return ERR_PTR(ret); 482 - gpios[nrow + i] = ret; 483 - } 484 - 485 - pdata->row_gpios = gpios; 486 - pdata->col_gpios = &gpios[pdata->num_row_gpios]; 487 - 488 - return pdata; 489 - } 490 - #else 491 - static inline struct matrix_keypad_platform_data * 492 - matrix_keypad_parse_dt(struct device *dev) 493 - { 494 - dev_err(dev, "no platform data defined\n"); 495 - 496 - return ERR_PTR(-EINVAL); 497 - } 498 - #endif 499 - 500 338 static int matrix_keypad_probe(struct platform_device *pdev) 501 339 { 502 - const struct matrix_keypad_platform_data *pdata; 340 + const struct matrix_keypad_platform_data *pdata = 341 + dev_get_platdata(&pdev->dev); 503 342 struct matrix_keypad *keypad; 504 343 struct input_dev *input_dev; 344 + bool autorepeat; 345 + bool wakeup; 505 346 int err; 506 - 507 - pdata = dev_get_platdata(&pdev->dev); 508 - if (!pdata) { 509 - pdata = matrix_keypad_parse_dt(&pdev->dev); 510 - if (IS_ERR(pdata)) 511 - return PTR_ERR(pdata); 512 - } else if (!pdata->keymap_data) { 513 - dev_err(&pdev->dev, "no keymap data defined\n"); 514 - return -EINVAL; 515 - } 516 347 517 348 keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL); 518 349 if (!keypad) ··· 437 440 return -ENOMEM; 438 441 439 442 keypad->input_dev = input_dev; 440 - keypad->pdata = pdata; 441 - keypad->row_shift = get_count_order(pdata->num_col_gpios); 442 443 keypad->stopped = true; 443 444 INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan); 444 445 spin_lock_init(&keypad->lock); 446 + 447 + keypad->drive_inactive_cols = 448 + device_property_read_bool(&pdev->dev, "drive-inactive-cols"); 449 + device_property_read_u32(&pdev->dev, "debounce-delay-ms", 450 + &keypad->debounce_ms); 451 + device_property_read_u32(&pdev->dev, "col-scan-delay-us", 452 + &keypad->col_scan_delay_us); 453 + 454 + if (pdata) { 455 + keypad->col_scan_delay_us = pdata->col_scan_delay_us; 456 + keypad->debounce_ms = pdata->debounce_ms; 457 + keypad->drive_inactive_cols = pdata->drive_inactive_cols; 458 + } 459 + 460 + if (pdata) 461 + err = matrix_keypad_init_pdata_gpio(pdev, pdata, keypad); 462 + else 463 + err = matrix_keypad_init_gpio(pdev, keypad); 464 + if (err) 465 + return err; 466 + 467 + keypad->row_shift = get_count_order(keypad->num_col_gpios); 468 + 469 + err = matrix_keypad_setup_interrupts(pdev, keypad); 470 + if (err) 471 + return err; 445 472 446 473 input_dev->name = pdev->name; 447 474 input_dev->id.bustype = BUS_HOST; 448 475 input_dev->open = matrix_keypad_start; 449 476 input_dev->close = matrix_keypad_stop; 450 477 451 - err = matrix_keypad_build_keymap(pdata->keymap_data, NULL, 452 - pdata->num_row_gpios, 453 - pdata->num_col_gpios, 478 + err = matrix_keypad_build_keymap(pdata ? pdata->keymap_data : NULL, 479 + NULL, 480 + keypad->num_row_gpios, 481 + keypad->num_col_gpios, 454 482 NULL, input_dev); 455 483 if (err) { 456 484 dev_err(&pdev->dev, "failed to build keymap\n"); 457 485 return -ENOMEM; 458 486 } 459 487 460 - if (!pdata->no_autorepeat) 488 + autorepeat = !device_property_read_bool(&pdev->dev, 489 + "linux,no-autorepeat"); 490 + if (autorepeat && pdata->no_autorepeat) 491 + autorepeat = false; 492 + if (autorepeat) 461 493 __set_bit(EV_REP, input_dev->evbit); 494 + 462 495 input_set_capability(input_dev, EV_MSC, MSC_SCAN); 463 496 input_set_drvdata(input_dev, keypad); 464 - 465 - err = matrix_keypad_init_gpio(pdev, keypad); 466 - if (err) 467 - return err; 468 497 469 498 err = input_register_device(keypad->input_dev); 470 499 if (err) 471 500 return err; 472 501 473 - device_init_wakeup(&pdev->dev, pdata->wakeup); 502 + wakeup = device_property_read_bool(&pdev->dev, "wakeup-source") || 503 + /* legacy */ 504 + device_property_read_bool(&pdev->dev, "linux,wakeup"); 505 + if (!wakeup && pdata) 506 + wakeup = pdata->wakeup; 507 + device_init_wakeup(&pdev->dev, wakeup); 508 + 474 509 platform_set_drvdata(pdev, keypad); 475 510 476 511 return 0;