root/drivers/input/keyboard/ep93xx_keypad.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ep93xx_keypad_irq_handler
  2. ep93xx_keypad_config
  3. ep93xx_keypad_open
  4. ep93xx_keypad_close
  5. ep93xx_keypad_suspend
  6. ep93xx_keypad_resume
  7. ep93xx_keypad_probe
  8. ep93xx_keypad_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Driver for the Cirrus EP93xx matrix keypad controller.
   4  *
   5  * Copyright (c) 2008 H Hartley Sweeten <hsweeten@visionengravers.com>
   6  *
   7  * Based on the pxa27x matrix keypad controller by Rodolfo Giometti.
   8  *
   9  * NOTE:
  10  *
  11  * The 3-key reset is triggered by pressing the 3 keys in
  12  * Row 0, Columns 2, 4, and 7 at the same time.  This action can
  13  * be disabled by setting the EP93XX_KEYPAD_DISABLE_3_KEY flag.
  14  *
  15  * Normal operation for the matrix does not autorepeat the key press.
  16  * This action can be enabled by setting the EP93XX_KEYPAD_AUTOREPEAT
  17  * flag.
  18  */
  19 
  20 #include <linux/module.h>
  21 #include <linux/platform_device.h>
  22 #include <linux/interrupt.h>
  23 #include <linux/clk.h>
  24 #include <linux/io.h>
  25 #include <linux/input/matrix_keypad.h>
  26 #include <linux/slab.h>
  27 #include <linux/soc/cirrus/ep93xx.h>
  28 #include <linux/platform_data/keypad-ep93xx.h>
  29 
  30 /*
  31  * Keypad Interface Register offsets
  32  */
  33 #define KEY_INIT                0x00    /* Key Scan Initialization register */
  34 #define KEY_DIAG                0x04    /* Key Scan Diagnostic register */
  35 #define KEY_REG                 0x08    /* Key Value Capture register */
  36 
  37 /* Key Scan Initialization Register bit defines */
  38 #define KEY_INIT_DBNC_MASK      (0x00ff0000)
  39 #define KEY_INIT_DBNC_SHIFT     (16)
  40 #define KEY_INIT_DIS3KY         (1<<15)
  41 #define KEY_INIT_DIAG           (1<<14)
  42 #define KEY_INIT_BACK           (1<<13)
  43 #define KEY_INIT_T2             (1<<12)
  44 #define KEY_INIT_PRSCL_MASK     (0x000003ff)
  45 #define KEY_INIT_PRSCL_SHIFT    (0)
  46 
  47 /* Key Scan Diagnostic Register bit defines */
  48 #define KEY_DIAG_MASK           (0x0000003f)
  49 #define KEY_DIAG_SHIFT          (0)
  50 
  51 /* Key Value Capture Register bit defines */
  52 #define KEY_REG_K               (1<<15)
  53 #define KEY_REG_INT             (1<<14)
  54 #define KEY_REG_2KEYS           (1<<13)
  55 #define KEY_REG_1KEY            (1<<12)
  56 #define KEY_REG_KEY2_MASK       (0x00000fc0)
  57 #define KEY_REG_KEY2_SHIFT      (6)
  58 #define KEY_REG_KEY1_MASK       (0x0000003f)
  59 #define KEY_REG_KEY1_SHIFT      (0)
  60 
  61 #define EP93XX_MATRIX_SIZE      (EP93XX_MATRIX_ROWS * EP93XX_MATRIX_COLS)
  62 
  63 struct ep93xx_keypad {
  64         struct ep93xx_keypad_platform_data *pdata;
  65         struct input_dev *input_dev;
  66         struct clk *clk;
  67 
  68         void __iomem *mmio_base;
  69 
  70         unsigned short keycodes[EP93XX_MATRIX_SIZE];
  71 
  72         int key1;
  73         int key2;
  74 
  75         int irq;
  76 
  77         bool enabled;
  78 };
  79 
  80 static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id)
  81 {
  82         struct ep93xx_keypad *keypad = dev_id;
  83         struct input_dev *input_dev = keypad->input_dev;
  84         unsigned int status;
  85         int keycode, key1, key2;
  86 
  87         status = __raw_readl(keypad->mmio_base + KEY_REG);
  88 
  89         keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT;
  90         key1 = keypad->keycodes[keycode];
  91 
  92         keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT;
  93         key2 = keypad->keycodes[keycode];
  94 
  95         if (status & KEY_REG_2KEYS) {
  96                 if (keypad->key1 && key1 != keypad->key1 && key2 != keypad->key1)
  97                         input_report_key(input_dev, keypad->key1, 0);
  98 
  99                 if (keypad->key2 && key1 != keypad->key2 && key2 != keypad->key2)
 100                         input_report_key(input_dev, keypad->key2, 0);
 101 
 102                 input_report_key(input_dev, key1, 1);
 103                 input_report_key(input_dev, key2, 1);
 104 
 105                 keypad->key1 = key1;
 106                 keypad->key2 = key2;
 107 
 108         } else if (status & KEY_REG_1KEY) {
 109                 if (keypad->key1 && key1 != keypad->key1)
 110                         input_report_key(input_dev, keypad->key1, 0);
 111 
 112                 if (keypad->key2 && key1 != keypad->key2)
 113                         input_report_key(input_dev, keypad->key2, 0);
 114 
 115                 input_report_key(input_dev, key1, 1);
 116 
 117                 keypad->key1 = key1;
 118                 keypad->key2 = 0;
 119 
 120         } else {
 121                 input_report_key(input_dev, keypad->key1, 0);
 122                 input_report_key(input_dev, keypad->key2, 0);
 123 
 124                 keypad->key1 = keypad->key2 = 0;
 125         }
 126         input_sync(input_dev);
 127 
 128         return IRQ_HANDLED;
 129 }
 130 
 131 static void ep93xx_keypad_config(struct ep93xx_keypad *keypad)
 132 {
 133         struct ep93xx_keypad_platform_data *pdata = keypad->pdata;
 134         unsigned int val = 0;
 135 
 136         clk_set_rate(keypad->clk, pdata->clk_rate);
 137 
 138         if (pdata->flags & EP93XX_KEYPAD_DISABLE_3_KEY)
 139                 val |= KEY_INIT_DIS3KY;
 140         if (pdata->flags & EP93XX_KEYPAD_DIAG_MODE)
 141                 val |= KEY_INIT_DIAG;
 142         if (pdata->flags & EP93XX_KEYPAD_BACK_DRIVE)
 143                 val |= KEY_INIT_BACK;
 144         if (pdata->flags & EP93XX_KEYPAD_TEST_MODE)
 145                 val |= KEY_INIT_T2;
 146 
 147         val |= ((pdata->debounce << KEY_INIT_DBNC_SHIFT) & KEY_INIT_DBNC_MASK);
 148 
 149         val |= ((pdata->prescale << KEY_INIT_PRSCL_SHIFT) & KEY_INIT_PRSCL_MASK);
 150 
 151         __raw_writel(val, keypad->mmio_base + KEY_INIT);
 152 }
 153 
 154 static int ep93xx_keypad_open(struct input_dev *pdev)
 155 {
 156         struct ep93xx_keypad *keypad = input_get_drvdata(pdev);
 157 
 158         if (!keypad->enabled) {
 159                 ep93xx_keypad_config(keypad);
 160                 clk_enable(keypad->clk);
 161                 keypad->enabled = true;
 162         }
 163 
 164         return 0;
 165 }
 166 
 167 static void ep93xx_keypad_close(struct input_dev *pdev)
 168 {
 169         struct ep93xx_keypad *keypad = input_get_drvdata(pdev);
 170 
 171         if (keypad->enabled) {
 172                 clk_disable(keypad->clk);
 173                 keypad->enabled = false;
 174         }
 175 }
 176 
 177 
 178 #ifdef CONFIG_PM_SLEEP
 179 static int ep93xx_keypad_suspend(struct device *dev)
 180 {
 181         struct platform_device *pdev = to_platform_device(dev);
 182         struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
 183         struct input_dev *input_dev = keypad->input_dev;
 184 
 185         mutex_lock(&input_dev->mutex);
 186 
 187         if (keypad->enabled) {
 188                 clk_disable(keypad->clk);
 189                 keypad->enabled = false;
 190         }
 191 
 192         mutex_unlock(&input_dev->mutex);
 193 
 194         if (device_may_wakeup(&pdev->dev))
 195                 enable_irq_wake(keypad->irq);
 196 
 197         return 0;
 198 }
 199 
 200 static int ep93xx_keypad_resume(struct device *dev)
 201 {
 202         struct platform_device *pdev = to_platform_device(dev);
 203         struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
 204         struct input_dev *input_dev = keypad->input_dev;
 205 
 206         if (device_may_wakeup(&pdev->dev))
 207                 disable_irq_wake(keypad->irq);
 208 
 209         mutex_lock(&input_dev->mutex);
 210 
 211         if (input_dev->users) {
 212                 if (!keypad->enabled) {
 213                         ep93xx_keypad_config(keypad);
 214                         clk_enable(keypad->clk);
 215                         keypad->enabled = true;
 216                 }
 217         }
 218 
 219         mutex_unlock(&input_dev->mutex);
 220 
 221         return 0;
 222 }
 223 #endif
 224 
 225 static SIMPLE_DEV_PM_OPS(ep93xx_keypad_pm_ops,
 226                          ep93xx_keypad_suspend, ep93xx_keypad_resume);
 227 
 228 static int ep93xx_keypad_probe(struct platform_device *pdev)
 229 {
 230         struct ep93xx_keypad *keypad;
 231         const struct matrix_keymap_data *keymap_data;
 232         struct input_dev *input_dev;
 233         struct resource *res;
 234         int err;
 235 
 236         keypad = kzalloc(sizeof(struct ep93xx_keypad), GFP_KERNEL);
 237         if (!keypad)
 238                 return -ENOMEM;
 239 
 240         keypad->pdata = dev_get_platdata(&pdev->dev);
 241         if (!keypad->pdata) {
 242                 err = -EINVAL;
 243                 goto failed_free;
 244         }
 245 
 246         keymap_data = keypad->pdata->keymap_data;
 247         if (!keymap_data) {
 248                 err = -EINVAL;
 249                 goto failed_free;
 250         }
 251 
 252         keypad->irq = platform_get_irq(pdev, 0);
 253         if (!keypad->irq) {
 254                 err = -ENXIO;
 255                 goto failed_free;
 256         }
 257 
 258         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 259         if (!res) {
 260                 err = -ENXIO;
 261                 goto failed_free;
 262         }
 263 
 264         res = request_mem_region(res->start, resource_size(res), pdev->name);
 265         if (!res) {
 266                 err = -EBUSY;
 267                 goto failed_free;
 268         }
 269 
 270         keypad->mmio_base = ioremap(res->start, resource_size(res));
 271         if (keypad->mmio_base == NULL) {
 272                 err = -ENXIO;
 273                 goto failed_free_mem;
 274         }
 275 
 276         err = ep93xx_keypad_acquire_gpio(pdev);
 277         if (err)
 278                 goto failed_free_io;
 279 
 280         keypad->clk = clk_get(&pdev->dev, NULL);
 281         if (IS_ERR(keypad->clk)) {
 282                 err = PTR_ERR(keypad->clk);
 283                 goto failed_free_gpio;
 284         }
 285 
 286         input_dev = input_allocate_device();
 287         if (!input_dev) {
 288                 err = -ENOMEM;
 289                 goto failed_put_clk;
 290         }
 291 
 292         keypad->input_dev = input_dev;
 293 
 294         input_dev->name = pdev->name;
 295         input_dev->id.bustype = BUS_HOST;
 296         input_dev->open = ep93xx_keypad_open;
 297         input_dev->close = ep93xx_keypad_close;
 298         input_dev->dev.parent = &pdev->dev;
 299 
 300         err = matrix_keypad_build_keymap(keymap_data, NULL,
 301                                          EP93XX_MATRIX_ROWS, EP93XX_MATRIX_COLS,
 302                                          keypad->keycodes, input_dev);
 303         if (err)
 304                 goto failed_free_dev;
 305 
 306         if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT)
 307                 __set_bit(EV_REP, input_dev->evbit);
 308         input_set_drvdata(input_dev, keypad);
 309 
 310         err = request_irq(keypad->irq, ep93xx_keypad_irq_handler,
 311                           0, pdev->name, keypad);
 312         if (err)
 313                 goto failed_free_dev;
 314 
 315         err = input_register_device(input_dev);
 316         if (err)
 317                 goto failed_free_irq;
 318 
 319         platform_set_drvdata(pdev, keypad);
 320         device_init_wakeup(&pdev->dev, 1);
 321 
 322         return 0;
 323 
 324 failed_free_irq:
 325         free_irq(keypad->irq, keypad);
 326 failed_free_dev:
 327         input_free_device(input_dev);
 328 failed_put_clk:
 329         clk_put(keypad->clk);
 330 failed_free_gpio:
 331         ep93xx_keypad_release_gpio(pdev);
 332 failed_free_io:
 333         iounmap(keypad->mmio_base);
 334 failed_free_mem:
 335         release_mem_region(res->start, resource_size(res));
 336 failed_free:
 337         kfree(keypad);
 338         return err;
 339 }
 340 
 341 static int ep93xx_keypad_remove(struct platform_device *pdev)
 342 {
 343         struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
 344         struct resource *res;
 345 
 346         free_irq(keypad->irq, keypad);
 347 
 348         if (keypad->enabled)
 349                 clk_disable(keypad->clk);
 350         clk_put(keypad->clk);
 351 
 352         input_unregister_device(keypad->input_dev);
 353 
 354         ep93xx_keypad_release_gpio(pdev);
 355 
 356         iounmap(keypad->mmio_base);
 357 
 358         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 359         release_mem_region(res->start, resource_size(res));
 360 
 361         kfree(keypad);
 362 
 363         return 0;
 364 }
 365 
 366 static struct platform_driver ep93xx_keypad_driver = {
 367         .driver         = {
 368                 .name   = "ep93xx-keypad",
 369                 .pm     = &ep93xx_keypad_pm_ops,
 370         },
 371         .probe          = ep93xx_keypad_probe,
 372         .remove         = ep93xx_keypad_remove,
 373 };
 374 module_platform_driver(ep93xx_keypad_driver);
 375 
 376 MODULE_LICENSE("GPL");
 377 MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
 378 MODULE_DESCRIPTION("EP93xx Matrix Keypad Controller");
 379 MODULE_ALIAS("platform:ep93xx-keypad");

/* [<][>][^][v][top][bottom][index][help] */