cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

matrix_keypad.c (14690B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  GPIO driven matrix keyboard driver
      4 *
      5 *  Copyright (c) 2008 Marek Vasut <marek.vasut@gmail.com>
      6 *
      7 *  Based on corgikbd.c
      8 */
      9
     10#include <linux/types.h>
     11#include <linux/delay.h>
     12#include <linux/platform_device.h>
     13#include <linux/input.h>
     14#include <linux/irq.h>
     15#include <linux/interrupt.h>
     16#include <linux/jiffies.h>
     17#include <linux/module.h>
     18#include <linux/gpio.h>
     19#include <linux/input/matrix_keypad.h>
     20#include <linux/slab.h>
     21#include <linux/of.h>
     22#include <linux/of_gpio.h>
     23#include <linux/of_platform.h>
     24
     25struct matrix_keypad {
     26	const struct matrix_keypad_platform_data *pdata;
     27	struct input_dev *input_dev;
     28	unsigned int row_shift;
     29
     30	DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS);
     31
     32	uint32_t last_key_state[MATRIX_MAX_COLS];
     33	struct delayed_work work;
     34	spinlock_t lock;
     35	bool scan_pending;
     36	bool stopped;
     37	bool gpio_all_disabled;
     38};
     39
     40/*
     41 * NOTE: If drive_inactive_cols is false, then the GPIO has to be put into
     42 * HiZ when de-activated to cause minmal side effect when scanning other
     43 * columns. In that case it is configured here to be input, otherwise it is
     44 * driven with the inactive value.
     45 */
     46static void __activate_col(const struct matrix_keypad_platform_data *pdata,
     47			   int col, bool on)
     48{
     49	bool level_on = !pdata->active_low;
     50
     51	if (on) {
     52		gpio_direction_output(pdata->col_gpios[col], level_on);
     53	} else {
     54		gpio_set_value_cansleep(pdata->col_gpios[col], !level_on);
     55		if (!pdata->drive_inactive_cols)
     56			gpio_direction_input(pdata->col_gpios[col]);
     57	}
     58}
     59
     60static void activate_col(const struct matrix_keypad_platform_data *pdata,
     61			 int col, bool on)
     62{
     63	__activate_col(pdata, col, on);
     64
     65	if (on && pdata->col_scan_delay_us)
     66		udelay(pdata->col_scan_delay_us);
     67}
     68
     69static void activate_all_cols(const struct matrix_keypad_platform_data *pdata,
     70			      bool on)
     71{
     72	int col;
     73
     74	for (col = 0; col < pdata->num_col_gpios; col++)
     75		__activate_col(pdata, col, on);
     76}
     77
     78static bool row_asserted(const struct matrix_keypad_platform_data *pdata,
     79			 int row)
     80{
     81	return gpio_get_value_cansleep(pdata->row_gpios[row]) ?
     82			!pdata->active_low : pdata->active_low;
     83}
     84
     85static void enable_row_irqs(struct matrix_keypad *keypad)
     86{
     87	const struct matrix_keypad_platform_data *pdata = keypad->pdata;
     88	int i;
     89
     90	if (pdata->clustered_irq > 0)
     91		enable_irq(pdata->clustered_irq);
     92	else {
     93		for (i = 0; i < pdata->num_row_gpios; i++)
     94			enable_irq(gpio_to_irq(pdata->row_gpios[i]));
     95	}
     96}
     97
     98static void disable_row_irqs(struct matrix_keypad *keypad)
     99{
    100	const struct matrix_keypad_platform_data *pdata = keypad->pdata;
    101	int i;
    102
    103	if (pdata->clustered_irq > 0)
    104		disable_irq_nosync(pdata->clustered_irq);
    105	else {
    106		for (i = 0; i < pdata->num_row_gpios; i++)
    107			disable_irq_nosync(gpio_to_irq(pdata->row_gpios[i]));
    108	}
    109}
    110
    111/*
    112 * This gets the keys from keyboard and reports it to input subsystem
    113 */
    114static void matrix_keypad_scan(struct work_struct *work)
    115{
    116	struct matrix_keypad *keypad =
    117		container_of(work, struct matrix_keypad, work.work);
    118	struct input_dev *input_dev = keypad->input_dev;
    119	const unsigned short *keycodes = input_dev->keycode;
    120	const struct matrix_keypad_platform_data *pdata = keypad->pdata;
    121	uint32_t new_state[MATRIX_MAX_COLS];
    122	int row, col, code;
    123
    124	/* de-activate all columns for scanning */
    125	activate_all_cols(pdata, false);
    126
    127	memset(new_state, 0, sizeof(new_state));
    128
    129	/* assert each column and read the row status out */
    130	for (col = 0; col < pdata->num_col_gpios; col++) {
    131
    132		activate_col(pdata, col, true);
    133
    134		for (row = 0; row < pdata->num_row_gpios; row++)
    135			new_state[col] |=
    136				row_asserted(pdata, row) ? (1 << row) : 0;
    137
    138		activate_col(pdata, col, false);
    139	}
    140
    141	for (col = 0; col < pdata->num_col_gpios; col++) {
    142		uint32_t bits_changed;
    143
    144		bits_changed = keypad->last_key_state[col] ^ new_state[col];
    145		if (bits_changed == 0)
    146			continue;
    147
    148		for (row = 0; row < pdata->num_row_gpios; row++) {
    149			if ((bits_changed & (1 << row)) == 0)
    150				continue;
    151
    152			code = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
    153			input_event(input_dev, EV_MSC, MSC_SCAN, code);
    154			input_report_key(input_dev,
    155					 keycodes[code],
    156					 new_state[col] & (1 << row));
    157		}
    158	}
    159	input_sync(input_dev);
    160
    161	memcpy(keypad->last_key_state, new_state, sizeof(new_state));
    162
    163	activate_all_cols(pdata, true);
    164
    165	/* Enable IRQs again */
    166	spin_lock_irq(&keypad->lock);
    167	keypad->scan_pending = false;
    168	enable_row_irqs(keypad);
    169	spin_unlock_irq(&keypad->lock);
    170}
    171
    172static irqreturn_t matrix_keypad_interrupt(int irq, void *id)
    173{
    174	struct matrix_keypad *keypad = id;
    175	unsigned long flags;
    176
    177	spin_lock_irqsave(&keypad->lock, flags);
    178
    179	/*
    180	 * See if another IRQ beaten us to it and scheduled the
    181	 * scan already. In that case we should not try to
    182	 * disable IRQs again.
    183	 */
    184	if (unlikely(keypad->scan_pending || keypad->stopped))
    185		goto out;
    186
    187	disable_row_irqs(keypad);
    188	keypad->scan_pending = true;
    189	schedule_delayed_work(&keypad->work,
    190		msecs_to_jiffies(keypad->pdata->debounce_ms));
    191
    192out:
    193	spin_unlock_irqrestore(&keypad->lock, flags);
    194	return IRQ_HANDLED;
    195}
    196
    197static int matrix_keypad_start(struct input_dev *dev)
    198{
    199	struct matrix_keypad *keypad = input_get_drvdata(dev);
    200
    201	keypad->stopped = false;
    202	mb();
    203
    204	/*
    205	 * Schedule an immediate key scan to capture current key state;
    206	 * columns will be activated and IRQs be enabled after the scan.
    207	 */
    208	schedule_delayed_work(&keypad->work, 0);
    209
    210	return 0;
    211}
    212
    213static void matrix_keypad_stop(struct input_dev *dev)
    214{
    215	struct matrix_keypad *keypad = input_get_drvdata(dev);
    216
    217	spin_lock_irq(&keypad->lock);
    218	keypad->stopped = true;
    219	spin_unlock_irq(&keypad->lock);
    220
    221	flush_delayed_work(&keypad->work);
    222	/*
    223	 * matrix_keypad_scan() will leave IRQs enabled;
    224	 * we should disable them now.
    225	 */
    226	disable_row_irqs(keypad);
    227}
    228
    229#ifdef CONFIG_PM_SLEEP
    230static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad)
    231{
    232	const struct matrix_keypad_platform_data *pdata = keypad->pdata;
    233	unsigned int gpio;
    234	int i;
    235
    236	if (pdata->clustered_irq > 0) {
    237		if (enable_irq_wake(pdata->clustered_irq) == 0)
    238			keypad->gpio_all_disabled = true;
    239	} else {
    240
    241		for (i = 0; i < pdata->num_row_gpios; i++) {
    242			if (!test_bit(i, keypad->disabled_gpios)) {
    243				gpio = pdata->row_gpios[i];
    244
    245				if (enable_irq_wake(gpio_to_irq(gpio)) == 0)
    246					__set_bit(i, keypad->disabled_gpios);
    247			}
    248		}
    249	}
    250}
    251
    252static void matrix_keypad_disable_wakeup(struct matrix_keypad *keypad)
    253{
    254	const struct matrix_keypad_platform_data *pdata = keypad->pdata;
    255	unsigned int gpio;
    256	int i;
    257
    258	if (pdata->clustered_irq > 0) {
    259		if (keypad->gpio_all_disabled) {
    260			disable_irq_wake(pdata->clustered_irq);
    261			keypad->gpio_all_disabled = false;
    262		}
    263	} else {
    264		for (i = 0; i < pdata->num_row_gpios; i++) {
    265			if (test_and_clear_bit(i, keypad->disabled_gpios)) {
    266				gpio = pdata->row_gpios[i];
    267				disable_irq_wake(gpio_to_irq(gpio));
    268			}
    269		}
    270	}
    271}
    272
    273static int matrix_keypad_suspend(struct device *dev)
    274{
    275	struct platform_device *pdev = to_platform_device(dev);
    276	struct matrix_keypad *keypad = platform_get_drvdata(pdev);
    277
    278	matrix_keypad_stop(keypad->input_dev);
    279
    280	if (device_may_wakeup(&pdev->dev))
    281		matrix_keypad_enable_wakeup(keypad);
    282
    283	return 0;
    284}
    285
    286static int matrix_keypad_resume(struct device *dev)
    287{
    288	struct platform_device *pdev = to_platform_device(dev);
    289	struct matrix_keypad *keypad = platform_get_drvdata(pdev);
    290
    291	if (device_may_wakeup(&pdev->dev))
    292		matrix_keypad_disable_wakeup(keypad);
    293
    294	matrix_keypad_start(keypad->input_dev);
    295
    296	return 0;
    297}
    298#endif
    299
    300static SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops,
    301			 matrix_keypad_suspend, matrix_keypad_resume);
    302
    303static int matrix_keypad_init_gpio(struct platform_device *pdev,
    304				   struct matrix_keypad *keypad)
    305{
    306	const struct matrix_keypad_platform_data *pdata = keypad->pdata;
    307	int i, err;
    308
    309	/* initialized strobe lines as outputs, activated */
    310	for (i = 0; i < pdata->num_col_gpios; i++) {
    311		err = gpio_request(pdata->col_gpios[i], "matrix_kbd_col");
    312		if (err) {
    313			dev_err(&pdev->dev,
    314				"failed to request GPIO%d for COL%d\n",
    315				pdata->col_gpios[i], i);
    316			goto err_free_cols;
    317		}
    318
    319		gpio_direction_output(pdata->col_gpios[i], !pdata->active_low);
    320	}
    321
    322	for (i = 0; i < pdata->num_row_gpios; i++) {
    323		err = gpio_request(pdata->row_gpios[i], "matrix_kbd_row");
    324		if (err) {
    325			dev_err(&pdev->dev,
    326				"failed to request GPIO%d for ROW%d\n",
    327				pdata->row_gpios[i], i);
    328			goto err_free_rows;
    329		}
    330
    331		gpio_direction_input(pdata->row_gpios[i]);
    332	}
    333
    334	if (pdata->clustered_irq > 0) {
    335		err = request_any_context_irq(pdata->clustered_irq,
    336				matrix_keypad_interrupt,
    337				pdata->clustered_irq_flags,
    338				"matrix-keypad", keypad);
    339		if (err < 0) {
    340			dev_err(&pdev->dev,
    341				"Unable to acquire clustered interrupt\n");
    342			goto err_free_rows;
    343		}
    344	} else {
    345		for (i = 0; i < pdata->num_row_gpios; i++) {
    346			err = request_any_context_irq(
    347					gpio_to_irq(pdata->row_gpios[i]),
    348					matrix_keypad_interrupt,
    349					IRQF_TRIGGER_RISING |
    350					IRQF_TRIGGER_FALLING,
    351					"matrix-keypad", keypad);
    352			if (err < 0) {
    353				dev_err(&pdev->dev,
    354					"Unable to acquire interrupt for GPIO line %i\n",
    355					pdata->row_gpios[i]);
    356				goto err_free_irqs;
    357			}
    358		}
    359	}
    360
    361	/* initialized as disabled - enabled by input->open */
    362	disable_row_irqs(keypad);
    363	return 0;
    364
    365err_free_irqs:
    366	while (--i >= 0)
    367		free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad);
    368	i = pdata->num_row_gpios;
    369err_free_rows:
    370	while (--i >= 0)
    371		gpio_free(pdata->row_gpios[i]);
    372	i = pdata->num_col_gpios;
    373err_free_cols:
    374	while (--i >= 0)
    375		gpio_free(pdata->col_gpios[i]);
    376
    377	return err;
    378}
    379
    380static void matrix_keypad_free_gpio(struct matrix_keypad *keypad)
    381{
    382	const struct matrix_keypad_platform_data *pdata = keypad->pdata;
    383	int i;
    384
    385	if (pdata->clustered_irq > 0) {
    386		free_irq(pdata->clustered_irq, keypad);
    387	} else {
    388		for (i = 0; i < pdata->num_row_gpios; i++)
    389			free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad);
    390	}
    391
    392	for (i = 0; i < pdata->num_row_gpios; i++)
    393		gpio_free(pdata->row_gpios[i]);
    394
    395	for (i = 0; i < pdata->num_col_gpios; i++)
    396		gpio_free(pdata->col_gpios[i]);
    397}
    398
    399#ifdef CONFIG_OF
    400static struct matrix_keypad_platform_data *
    401matrix_keypad_parse_dt(struct device *dev)
    402{
    403	struct matrix_keypad_platform_data *pdata;
    404	struct device_node *np = dev->of_node;
    405	unsigned int *gpios;
    406	int ret, i, nrow, ncol;
    407
    408	if (!np) {
    409		dev_err(dev, "device lacks DT data\n");
    410		return ERR_PTR(-ENODEV);
    411	}
    412
    413	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
    414	if (!pdata) {
    415		dev_err(dev, "could not allocate memory for platform data\n");
    416		return ERR_PTR(-ENOMEM);
    417	}
    418
    419	pdata->num_row_gpios = nrow = of_gpio_named_count(np, "row-gpios");
    420	pdata->num_col_gpios = ncol = of_gpio_named_count(np, "col-gpios");
    421	if (nrow <= 0 || ncol <= 0) {
    422		dev_err(dev, "number of keypad rows/columns not specified\n");
    423		return ERR_PTR(-EINVAL);
    424	}
    425
    426	if (of_get_property(np, "linux,no-autorepeat", NULL))
    427		pdata->no_autorepeat = true;
    428
    429	pdata->wakeup = of_property_read_bool(np, "wakeup-source") ||
    430			of_property_read_bool(np, "linux,wakeup"); /* legacy */
    431
    432	if (of_get_property(np, "gpio-activelow", NULL))
    433		pdata->active_low = true;
    434
    435	pdata->drive_inactive_cols =
    436		of_property_read_bool(np, "drive-inactive-cols");
    437
    438	of_property_read_u32(np, "debounce-delay-ms", &pdata->debounce_ms);
    439	of_property_read_u32(np, "col-scan-delay-us",
    440						&pdata->col_scan_delay_us);
    441
    442	gpios = devm_kcalloc(dev,
    443			     pdata->num_row_gpios + pdata->num_col_gpios,
    444			     sizeof(unsigned int),
    445			     GFP_KERNEL);
    446	if (!gpios) {
    447		dev_err(dev, "could not allocate memory for gpios\n");
    448		return ERR_PTR(-ENOMEM);
    449	}
    450
    451	for (i = 0; i < nrow; i++) {
    452		ret = of_get_named_gpio(np, "row-gpios", i);
    453		if (ret < 0)
    454			return ERR_PTR(ret);
    455		gpios[i] = ret;
    456	}
    457
    458	for (i = 0; i < ncol; i++) {
    459		ret = of_get_named_gpio(np, "col-gpios", i);
    460		if (ret < 0)
    461			return ERR_PTR(ret);
    462		gpios[nrow + i] = ret;
    463	}
    464
    465	pdata->row_gpios = gpios;
    466	pdata->col_gpios = &gpios[pdata->num_row_gpios];
    467
    468	return pdata;
    469}
    470#else
    471static inline struct matrix_keypad_platform_data *
    472matrix_keypad_parse_dt(struct device *dev)
    473{
    474	dev_err(dev, "no platform data defined\n");
    475
    476	return ERR_PTR(-EINVAL);
    477}
    478#endif
    479
    480static int matrix_keypad_probe(struct platform_device *pdev)
    481{
    482	const struct matrix_keypad_platform_data *pdata;
    483	struct matrix_keypad *keypad;
    484	struct input_dev *input_dev;
    485	int err;
    486
    487	pdata = dev_get_platdata(&pdev->dev);
    488	if (!pdata) {
    489		pdata = matrix_keypad_parse_dt(&pdev->dev);
    490		if (IS_ERR(pdata))
    491			return PTR_ERR(pdata);
    492	} else if (!pdata->keymap_data) {
    493		dev_err(&pdev->dev, "no keymap data defined\n");
    494		return -EINVAL;
    495	}
    496
    497	keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL);
    498	input_dev = input_allocate_device();
    499	if (!keypad || !input_dev) {
    500		err = -ENOMEM;
    501		goto err_free_mem;
    502	}
    503
    504	keypad->input_dev = input_dev;
    505	keypad->pdata = pdata;
    506	keypad->row_shift = get_count_order(pdata->num_col_gpios);
    507	keypad->stopped = true;
    508	INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan);
    509	spin_lock_init(&keypad->lock);
    510
    511	input_dev->name		= pdev->name;
    512	input_dev->id.bustype	= BUS_HOST;
    513	input_dev->dev.parent	= &pdev->dev;
    514	input_dev->open		= matrix_keypad_start;
    515	input_dev->close	= matrix_keypad_stop;
    516
    517	err = matrix_keypad_build_keymap(pdata->keymap_data, NULL,
    518					 pdata->num_row_gpios,
    519					 pdata->num_col_gpios,
    520					 NULL, input_dev);
    521	if (err) {
    522		dev_err(&pdev->dev, "failed to build keymap\n");
    523		goto err_free_mem;
    524	}
    525
    526	if (!pdata->no_autorepeat)
    527		__set_bit(EV_REP, input_dev->evbit);
    528	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
    529	input_set_drvdata(input_dev, keypad);
    530
    531	err = matrix_keypad_init_gpio(pdev, keypad);
    532	if (err)
    533		goto err_free_mem;
    534
    535	err = input_register_device(keypad->input_dev);
    536	if (err)
    537		goto err_free_gpio;
    538
    539	device_init_wakeup(&pdev->dev, pdata->wakeup);
    540	platform_set_drvdata(pdev, keypad);
    541
    542	return 0;
    543
    544err_free_gpio:
    545	matrix_keypad_free_gpio(keypad);
    546err_free_mem:
    547	input_free_device(input_dev);
    548	kfree(keypad);
    549	return err;
    550}
    551
    552static int matrix_keypad_remove(struct platform_device *pdev)
    553{
    554	struct matrix_keypad *keypad = platform_get_drvdata(pdev);
    555
    556	matrix_keypad_free_gpio(keypad);
    557	input_unregister_device(keypad->input_dev);
    558	kfree(keypad);
    559
    560	return 0;
    561}
    562
    563#ifdef CONFIG_OF
    564static const struct of_device_id matrix_keypad_dt_match[] = {
    565	{ .compatible = "gpio-matrix-keypad" },
    566	{ }
    567};
    568MODULE_DEVICE_TABLE(of, matrix_keypad_dt_match);
    569#endif
    570
    571static struct platform_driver matrix_keypad_driver = {
    572	.probe		= matrix_keypad_probe,
    573	.remove		= matrix_keypad_remove,
    574	.driver		= {
    575		.name	= "matrix-keypad",
    576		.pm	= &matrix_keypad_pm_ops,
    577		.of_match_table = of_match_ptr(matrix_keypad_dt_match),
    578	},
    579};
    580module_platform_driver(matrix_keypad_driver);
    581
    582MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
    583MODULE_DESCRIPTION("GPIO Driven Matrix Keypad Driver");
    584MODULE_LICENSE("GPL v2");
    585MODULE_ALIAS("platform:matrix-keypad");