Lines Matching +full:num +full:- +full:rows

1 // SPDX-License-Identifier: GPL-2.0-or-later
23 #include <linux/input/samsung-keypad.h>
73 unsigned int rows; member
85 for (col = 0; col < keypad->cols; col++) { in samsung_keypad_scan()
86 if (keypad->type == KEYPAD_TYPE_S5PV210) { in samsung_keypad_scan()
94 writel(val, keypad->base + SAMSUNG_KEYIFCOL); in samsung_keypad_scan()
97 val = readl(keypad->base + SAMSUNG_KEYIFROW); in samsung_keypad_scan()
98 row_state[col] = ~val & ((1 << keypad->rows) - 1); in samsung_keypad_scan()
102 writel(0, keypad->base + SAMSUNG_KEYIFCOL); in samsung_keypad_scan()
108 struct input_dev *input_dev = keypad->input_dev; in samsung_keypad_report()
115 for (col = 0; col < keypad->cols; col++) { in samsung_keypad_report()
116 changed = row_state[col] ^ keypad->row_state[col]; in samsung_keypad_report()
121 for (row = 0; row < keypad->rows; row++) { in samsung_keypad_report()
127 dev_dbg(&keypad->input_dev->dev, in samsung_keypad_report()
131 val = MATRIX_SCAN_CODE(row, col, keypad->row_shift); in samsung_keypad_report()
135 keypad->keycodes[val], pressed); in samsung_keypad_report()
137 input_sync(keypad->input_dev); in samsung_keypad_report()
140 memcpy(keypad->row_state, row_state, sizeof(keypad->row_state)); in samsung_keypad_report()
152 pm_runtime_get_sync(&keypad->pdev->dev); in samsung_keypad_irq()
155 val = readl(keypad->base + SAMSUNG_KEYIFSTSCLR); in samsung_keypad_irq()
157 writel(~0x0, keypad->base + SAMSUNG_KEYIFSTSCLR); in samsung_keypad_irq()
163 wait_event_timeout(keypad->wait, keypad->stopped, in samsung_keypad_irq()
166 } while (key_down && !keypad->stopped); in samsung_keypad_irq()
168 pm_runtime_put(&keypad->pdev->dev); in samsung_keypad_irq()
177 pm_runtime_get_sync(&keypad->pdev->dev); in samsung_keypad_start()
180 keypad->stopped = false; in samsung_keypad_start()
182 clk_enable(keypad->clk); in samsung_keypad_start()
185 val = readl(keypad->base + SAMSUNG_KEYIFCON); in samsung_keypad_start()
187 writel(val, keypad->base + SAMSUNG_KEYIFCON); in samsung_keypad_start()
190 writel(0, keypad->base + SAMSUNG_KEYIFCOL); in samsung_keypad_start()
192 pm_runtime_put(&keypad->pdev->dev); in samsung_keypad_start()
199 pm_runtime_get_sync(&keypad->pdev->dev); in samsung_keypad_stop()
202 keypad->stopped = true; in samsung_keypad_stop()
203 wake_up(&keypad->wait); in samsung_keypad_stop()
204 disable_irq(keypad->irq); in samsung_keypad_stop()
207 writel(~0x0, keypad->base + SAMSUNG_KEYIFSTSCLR); in samsung_keypad_stop()
210 val = readl(keypad->base + SAMSUNG_KEYIFCON); in samsung_keypad_stop()
212 writel(val, keypad->base + SAMSUNG_KEYIFCON); in samsung_keypad_stop()
214 clk_disable(keypad->clk); in samsung_keypad_stop()
218 * re-enable the handler. in samsung_keypad_stop()
220 enable_irq(keypad->irq); in samsung_keypad_stop()
222 pm_runtime_put(&keypad->pdev->dev); in samsung_keypad_stop()
248 struct device_node *np = dev->of_node, *key_np; in samsung_keypad_parse_dt()
253 return ERR_PTR(-EINVAL); in samsung_keypad_parse_dt()
259 return ERR_PTR(-ENOMEM); in samsung_keypad_parse_dt()
262 of_property_read_u32(np, "samsung,keypad-num-rows", &num_rows); in samsung_keypad_parse_dt()
263 of_property_read_u32(np, "samsung,keypad-num-columns", &num_cols); in samsung_keypad_parse_dt()
265 dev_err(dev, "number of keypad rows/columns not specified\n"); in samsung_keypad_parse_dt()
266 return ERR_PTR(-EINVAL); in samsung_keypad_parse_dt()
268 pdata->rows = num_rows; in samsung_keypad_parse_dt()
269 pdata->cols = num_cols; in samsung_keypad_parse_dt()
274 return ERR_PTR(-ENOMEM); in samsung_keypad_parse_dt()
276 pdata->keymap_data = keymap_data; in samsung_keypad_parse_dt()
279 keymap_data->keymap_size = key_count; in samsung_keypad_parse_dt()
283 return ERR_PTR(-ENOMEM); in samsung_keypad_parse_dt()
285 keymap_data->keymap = keymap; in samsung_keypad_parse_dt()
295 if (of_get_property(np, "linux,input-no-autorepeat", NULL)) in samsung_keypad_parse_dt()
296 pdata->no_autorepeat = true; in samsung_keypad_parse_dt()
298 pdata->wakeup = of_property_read_bool(np, "wakeup-source") || in samsung_keypad_parse_dt()
300 of_property_read_bool(np, "linux,input-wakeup"); in samsung_keypad_parse_dt()
311 return ERR_PTR(-EINVAL); in samsung_keypad_parse_dt()
326 pdata = dev_get_platdata(&pdev->dev); in samsung_keypad_probe()
328 pdata = samsung_keypad_parse_dt(&pdev->dev); in samsung_keypad_probe()
333 keymap_data = pdata->keymap_data; in samsung_keypad_probe()
335 dev_err(&pdev->dev, "no keymap data defined\n"); in samsung_keypad_probe()
336 return -EINVAL; in samsung_keypad_probe()
339 if (!pdata->rows || pdata->rows > SAMSUNG_MAX_ROWS) in samsung_keypad_probe()
340 return -EINVAL; in samsung_keypad_probe()
342 if (!pdata->cols || pdata->cols > SAMSUNG_MAX_COLS) in samsung_keypad_probe()
343 return -EINVAL; in samsung_keypad_probe()
346 if (pdata->cfg_gpio) in samsung_keypad_probe()
347 pdata->cfg_gpio(pdata->rows, pdata->cols); in samsung_keypad_probe()
349 row_shift = get_count_order(pdata->cols); in samsung_keypad_probe()
350 keymap_size = (pdata->rows << row_shift) * sizeof(keypad->keycodes[0]); in samsung_keypad_probe()
352 keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad) + keymap_size, in samsung_keypad_probe()
354 input_dev = devm_input_allocate_device(&pdev->dev); in samsung_keypad_probe()
356 return -ENOMEM; in samsung_keypad_probe()
360 return -ENODEV; in samsung_keypad_probe()
362 keypad->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); in samsung_keypad_probe()
363 if (!keypad->base) in samsung_keypad_probe()
364 return -EBUSY; in samsung_keypad_probe()
366 keypad->clk = devm_clk_get(&pdev->dev, "keypad"); in samsung_keypad_probe()
367 if (IS_ERR(keypad->clk)) { in samsung_keypad_probe()
368 dev_err(&pdev->dev, "failed to get keypad clk\n"); in samsung_keypad_probe()
369 return PTR_ERR(keypad->clk); in samsung_keypad_probe()
372 error = clk_prepare(keypad->clk); in samsung_keypad_probe()
374 dev_err(&pdev->dev, "keypad clock prepare failed\n"); in samsung_keypad_probe()
378 keypad->input_dev = input_dev; in samsung_keypad_probe()
379 keypad->pdev = pdev; in samsung_keypad_probe()
380 keypad->row_shift = row_shift; in samsung_keypad_probe()
381 keypad->rows = pdata->rows; in samsung_keypad_probe()
382 keypad->cols = pdata->cols; in samsung_keypad_probe()
383 keypad->stopped = true; in samsung_keypad_probe()
384 init_waitqueue_head(&keypad->wait); in samsung_keypad_probe()
386 if (pdev->dev.of_node) in samsung_keypad_probe()
387 keypad->type = of_device_is_compatible(pdev->dev.of_node, in samsung_keypad_probe()
388 "samsung,s5pv210-keypad"); in samsung_keypad_probe()
390 keypad->type = platform_get_device_id(pdev)->driver_data; in samsung_keypad_probe()
392 input_dev->name = pdev->name; in samsung_keypad_probe()
393 input_dev->id.bustype = BUS_HOST; in samsung_keypad_probe()
394 input_dev->dev.parent = &pdev->dev; in samsung_keypad_probe()
396 input_dev->open = samsung_keypad_open; in samsung_keypad_probe()
397 input_dev->close = samsung_keypad_close; in samsung_keypad_probe()
400 pdata->rows, pdata->cols, in samsung_keypad_probe()
401 keypad->keycodes, input_dev); in samsung_keypad_probe()
403 dev_err(&pdev->dev, "failed to build keymap\n"); in samsung_keypad_probe()
408 if (!pdata->no_autorepeat) in samsung_keypad_probe()
409 __set_bit(EV_REP, input_dev->evbit); in samsung_keypad_probe()
413 keypad->irq = platform_get_irq(pdev, 0); in samsung_keypad_probe()
414 if (keypad->irq < 0) { in samsung_keypad_probe()
415 error = keypad->irq; in samsung_keypad_probe()
419 error = devm_request_threaded_irq(&pdev->dev, keypad->irq, NULL, in samsung_keypad_probe()
421 dev_name(&pdev->dev), keypad); in samsung_keypad_probe()
423 dev_err(&pdev->dev, "failed to register keypad interrupt\n"); in samsung_keypad_probe()
427 device_init_wakeup(&pdev->dev, pdata->wakeup); in samsung_keypad_probe()
429 pm_runtime_enable(&pdev->dev); in samsung_keypad_probe()
431 error = input_register_device(keypad->input_dev); in samsung_keypad_probe()
435 if (pdev->dev.of_node) { in samsung_keypad_probe()
436 devm_kfree(&pdev->dev, (void *)pdata->keymap_data->keymap); in samsung_keypad_probe()
437 devm_kfree(&pdev->dev, (void *)pdata->keymap_data); in samsung_keypad_probe()
438 devm_kfree(&pdev->dev, (void *)pdata); in samsung_keypad_probe()
443 pm_runtime_disable(&pdev->dev); in samsung_keypad_probe()
445 clk_unprepare(keypad->clk); in samsung_keypad_probe()
453 pm_runtime_disable(&pdev->dev); in samsung_keypad_remove()
455 input_unregister_device(keypad->input_dev); in samsung_keypad_remove()
457 clk_unprepare(keypad->clk); in samsung_keypad_remove()
470 if (keypad->stopped) in samsung_keypad_runtime_suspend()
474 error = enable_irq_wake(keypad->irq); in samsung_keypad_runtime_suspend()
476 keypad->wake_enabled = true; in samsung_keypad_runtime_suspend()
478 val = readl(keypad->base + SAMSUNG_KEYIFCON); in samsung_keypad_runtime_suspend()
480 writel(val, keypad->base + SAMSUNG_KEYIFCON); in samsung_keypad_runtime_suspend()
482 clk_disable(keypad->clk); in samsung_keypad_runtime_suspend()
493 if (keypad->stopped) in samsung_keypad_runtime_resume()
496 clk_enable(keypad->clk); in samsung_keypad_runtime_resume()
498 val = readl(keypad->base + SAMSUNG_KEYIFCON); in samsung_keypad_runtime_resume()
500 writel(val, keypad->base + SAMSUNG_KEYIFCON); in samsung_keypad_runtime_resume()
502 if (keypad->wake_enabled) in samsung_keypad_runtime_resume()
503 disable_irq_wake(keypad->irq); in samsung_keypad_runtime_resume()
515 clk_enable(keypad->clk); in samsung_keypad_toggle_wakeup()
517 val = readl(keypad->base + SAMSUNG_KEYIFCON); in samsung_keypad_toggle_wakeup()
520 if (device_may_wakeup(&keypad->pdev->dev)) in samsung_keypad_toggle_wakeup()
521 enable_irq_wake(keypad->irq); in samsung_keypad_toggle_wakeup()
524 if (device_may_wakeup(&keypad->pdev->dev)) in samsung_keypad_toggle_wakeup()
525 disable_irq_wake(keypad->irq); in samsung_keypad_toggle_wakeup()
527 writel(val, keypad->base + SAMSUNG_KEYIFCON); in samsung_keypad_toggle_wakeup()
529 clk_disable(keypad->clk); in samsung_keypad_toggle_wakeup()
536 struct input_dev *input_dev = keypad->input_dev; in samsung_keypad_suspend()
538 mutex_lock(&input_dev->mutex); in samsung_keypad_suspend()
540 if (input_dev->users) in samsung_keypad_suspend()
545 mutex_unlock(&input_dev->mutex); in samsung_keypad_suspend()
554 struct input_dev *input_dev = keypad->input_dev; in samsung_keypad_resume()
556 mutex_lock(&input_dev->mutex); in samsung_keypad_resume()
560 if (input_dev->users) in samsung_keypad_resume()
563 mutex_unlock(&input_dev->mutex); in samsung_keypad_resume()
577 { .compatible = "samsung,s3c6410-keypad" },
578 { .compatible = "samsung,s5pv210-keypad" },
586 .name = "samsung-keypad",
589 .name = "s5pv210-keypad",
600 .name = "samsung-keypad",