Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Driver for the Cirrus EP93xx matrix keypad controller.
0004  *
0005  * Copyright (c) 2008 H Hartley Sweeten <hsweeten@visionengravers.com>
0006  *
0007  * Based on the pxa27x matrix keypad controller by Rodolfo Giometti.
0008  *
0009  * NOTE:
0010  *
0011  * The 3-key reset is triggered by pressing the 3 keys in
0012  * Row 0, Columns 2, 4, and 7 at the same time.  This action can
0013  * be disabled by setting the EP93XX_KEYPAD_DISABLE_3_KEY flag.
0014  *
0015  * Normal operation for the matrix does not autorepeat the key press.
0016  * This action can be enabled by setting the EP93XX_KEYPAD_AUTOREPEAT
0017  * flag.
0018  */
0019 
0020 #include <linux/bits.h>
0021 #include <linux/module.h>
0022 #include <linux/platform_device.h>
0023 #include <linux/interrupt.h>
0024 #include <linux/clk.h>
0025 #include <linux/io.h>
0026 #include <linux/input/matrix_keypad.h>
0027 #include <linux/slab.h>
0028 #include <linux/soc/cirrus/ep93xx.h>
0029 #include <linux/platform_data/keypad-ep93xx.h>
0030 #include <linux/pm_wakeirq.h>
0031 
0032 /*
0033  * Keypad Interface Register offsets
0034  */
0035 #define KEY_INIT        0x00    /* Key Scan Initialization register */
0036 #define KEY_DIAG        0x04    /* Key Scan Diagnostic register */
0037 #define KEY_REG         0x08    /* Key Value Capture register */
0038 
0039 /* Key Scan Initialization Register bit defines */
0040 #define KEY_INIT_DBNC_MASK  GENMASK(23, 16)
0041 #define KEY_INIT_DBNC_SHIFT 16
0042 #define KEY_INIT_DIS3KY     BIT(15)
0043 #define KEY_INIT_DIAG       BIT(14)
0044 #define KEY_INIT_BACK       BIT(13)
0045 #define KEY_INIT_T2     BIT(12)
0046 #define KEY_INIT_PRSCL_MASK GENMASK(9, 0)
0047 #define KEY_INIT_PRSCL_SHIFT    0
0048 
0049 /* Key Scan Diagnostic Register bit defines */
0050 #define KEY_DIAG_MASK       GENMASK(5, 0)
0051 #define KEY_DIAG_SHIFT      0
0052 
0053 /* Key Value Capture Register bit defines */
0054 #define KEY_REG_K       BIT(15)
0055 #define KEY_REG_INT     BIT(14)
0056 #define KEY_REG_2KEYS       BIT(13)
0057 #define KEY_REG_1KEY        BIT(12)
0058 #define KEY_REG_KEY2_MASK   GENMASK(11, 6)
0059 #define KEY_REG_KEY2_SHIFT  6
0060 #define KEY_REG_KEY1_MASK   GENMASK(5, 0)
0061 #define KEY_REG_KEY1_SHIFT  0
0062 
0063 #define EP93XX_MATRIX_SIZE  (EP93XX_MATRIX_ROWS * EP93XX_MATRIX_COLS)
0064 
0065 struct ep93xx_keypad {
0066     struct ep93xx_keypad_platform_data *pdata;
0067     struct input_dev *input_dev;
0068     struct clk *clk;
0069 
0070     void __iomem *mmio_base;
0071 
0072     unsigned short keycodes[EP93XX_MATRIX_SIZE];
0073 
0074     int key1;
0075     int key2;
0076 
0077     int irq;
0078 
0079     bool enabled;
0080 };
0081 
0082 static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id)
0083 {
0084     struct ep93xx_keypad *keypad = dev_id;
0085     struct input_dev *input_dev = keypad->input_dev;
0086     unsigned int status;
0087     int keycode, key1, key2;
0088 
0089     status = __raw_readl(keypad->mmio_base + KEY_REG);
0090 
0091     keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT;
0092     key1 = keypad->keycodes[keycode];
0093 
0094     keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT;
0095     key2 = keypad->keycodes[keycode];
0096 
0097     if (status & KEY_REG_2KEYS) {
0098         if (keypad->key1 && key1 != keypad->key1 && key2 != keypad->key1)
0099             input_report_key(input_dev, keypad->key1, 0);
0100 
0101         if (keypad->key2 && key1 != keypad->key2 && key2 != keypad->key2)
0102             input_report_key(input_dev, keypad->key2, 0);
0103 
0104         input_report_key(input_dev, key1, 1);
0105         input_report_key(input_dev, key2, 1);
0106 
0107         keypad->key1 = key1;
0108         keypad->key2 = key2;
0109 
0110     } else if (status & KEY_REG_1KEY) {
0111         if (keypad->key1 && key1 != keypad->key1)
0112             input_report_key(input_dev, keypad->key1, 0);
0113 
0114         if (keypad->key2 && key1 != keypad->key2)
0115             input_report_key(input_dev, keypad->key2, 0);
0116 
0117         input_report_key(input_dev, key1, 1);
0118 
0119         keypad->key1 = key1;
0120         keypad->key2 = 0;
0121 
0122     } else {
0123         input_report_key(input_dev, keypad->key1, 0);
0124         input_report_key(input_dev, keypad->key2, 0);
0125 
0126         keypad->key1 = keypad->key2 = 0;
0127     }
0128     input_sync(input_dev);
0129 
0130     return IRQ_HANDLED;
0131 }
0132 
0133 static void ep93xx_keypad_config(struct ep93xx_keypad *keypad)
0134 {
0135     struct ep93xx_keypad_platform_data *pdata = keypad->pdata;
0136     unsigned int val = 0;
0137 
0138     clk_set_rate(keypad->clk, pdata->clk_rate);
0139 
0140     if (pdata->flags & EP93XX_KEYPAD_DISABLE_3_KEY)
0141         val |= KEY_INIT_DIS3KY;
0142     if (pdata->flags & EP93XX_KEYPAD_DIAG_MODE)
0143         val |= KEY_INIT_DIAG;
0144     if (pdata->flags & EP93XX_KEYPAD_BACK_DRIVE)
0145         val |= KEY_INIT_BACK;
0146     if (pdata->flags & EP93XX_KEYPAD_TEST_MODE)
0147         val |= KEY_INIT_T2;
0148 
0149     val |= ((pdata->debounce << KEY_INIT_DBNC_SHIFT) & KEY_INIT_DBNC_MASK);
0150 
0151     val |= ((pdata->prescale << KEY_INIT_PRSCL_SHIFT) & KEY_INIT_PRSCL_MASK);
0152 
0153     __raw_writel(val, keypad->mmio_base + KEY_INIT);
0154 }
0155 
0156 static int ep93xx_keypad_open(struct input_dev *pdev)
0157 {
0158     struct ep93xx_keypad *keypad = input_get_drvdata(pdev);
0159 
0160     if (!keypad->enabled) {
0161         ep93xx_keypad_config(keypad);
0162         clk_prepare_enable(keypad->clk);
0163         keypad->enabled = true;
0164     }
0165 
0166     return 0;
0167 }
0168 
0169 static void ep93xx_keypad_close(struct input_dev *pdev)
0170 {
0171     struct ep93xx_keypad *keypad = input_get_drvdata(pdev);
0172 
0173     if (keypad->enabled) {
0174         clk_disable_unprepare(keypad->clk);
0175         keypad->enabled = false;
0176     }
0177 }
0178 
0179 
0180 static int __maybe_unused ep93xx_keypad_suspend(struct device *dev)
0181 {
0182     struct platform_device *pdev = to_platform_device(dev);
0183     struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
0184     struct input_dev *input_dev = keypad->input_dev;
0185 
0186     mutex_lock(&input_dev->mutex);
0187 
0188     if (keypad->enabled) {
0189         clk_disable(keypad->clk);
0190         keypad->enabled = false;
0191     }
0192 
0193     mutex_unlock(&input_dev->mutex);
0194 
0195     return 0;
0196 }
0197 
0198 static int __maybe_unused ep93xx_keypad_resume(struct device *dev)
0199 {
0200     struct platform_device *pdev = to_platform_device(dev);
0201     struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
0202     struct input_dev *input_dev = keypad->input_dev;
0203 
0204     mutex_lock(&input_dev->mutex);
0205 
0206     if (input_device_enabled(input_dev)) {
0207         if (!keypad->enabled) {
0208             ep93xx_keypad_config(keypad);
0209             clk_enable(keypad->clk);
0210             keypad->enabled = true;
0211         }
0212     }
0213 
0214     mutex_unlock(&input_dev->mutex);
0215 
0216     return 0;
0217 }
0218 
0219 static SIMPLE_DEV_PM_OPS(ep93xx_keypad_pm_ops,
0220              ep93xx_keypad_suspend, ep93xx_keypad_resume);
0221 
0222 static void ep93xx_keypad_release_gpio_action(void *_pdev)
0223 {
0224     struct platform_device *pdev = _pdev;
0225 
0226     ep93xx_keypad_release_gpio(pdev);
0227 }
0228 
0229 static int ep93xx_keypad_probe(struct platform_device *pdev)
0230 {
0231     struct ep93xx_keypad *keypad;
0232     const struct matrix_keymap_data *keymap_data;
0233     struct input_dev *input_dev;
0234     int err;
0235 
0236     keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
0237     if (!keypad)
0238         return -ENOMEM;
0239 
0240     keypad->pdata = dev_get_platdata(&pdev->dev);
0241     if (!keypad->pdata)
0242         return -EINVAL;
0243 
0244     keymap_data = keypad->pdata->keymap_data;
0245     if (!keymap_data)
0246         return -EINVAL;
0247 
0248     keypad->irq = platform_get_irq(pdev, 0);
0249     if (keypad->irq < 0)
0250         return keypad->irq;
0251 
0252     keypad->mmio_base = devm_platform_ioremap_resource(pdev, 0);
0253     if (IS_ERR(keypad->mmio_base))
0254         return PTR_ERR(keypad->mmio_base);
0255 
0256     err = ep93xx_keypad_acquire_gpio(pdev);
0257     if (err)
0258         return err;
0259 
0260     err = devm_add_action_or_reset(&pdev->dev,
0261                        ep93xx_keypad_release_gpio_action, pdev);
0262     if (err)
0263         return err;
0264 
0265     keypad->clk = devm_clk_get(&pdev->dev, NULL);
0266     if (IS_ERR(keypad->clk))
0267         return PTR_ERR(keypad->clk);
0268 
0269     input_dev = devm_input_allocate_device(&pdev->dev);
0270     if (!input_dev)
0271         return -ENOMEM;
0272 
0273     keypad->input_dev = input_dev;
0274 
0275     input_dev->name = pdev->name;
0276     input_dev->id.bustype = BUS_HOST;
0277     input_dev->open = ep93xx_keypad_open;
0278     input_dev->close = ep93xx_keypad_close;
0279 
0280     err = matrix_keypad_build_keymap(keymap_data, NULL,
0281                      EP93XX_MATRIX_ROWS, EP93XX_MATRIX_COLS,
0282                      keypad->keycodes, input_dev);
0283     if (err)
0284         return err;
0285 
0286     if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT)
0287         __set_bit(EV_REP, input_dev->evbit);
0288     input_set_drvdata(input_dev, keypad);
0289 
0290     err = devm_request_irq(&pdev->dev, keypad->irq,
0291                    ep93xx_keypad_irq_handler,
0292                    0, pdev->name, keypad);
0293     if (err)
0294         return err;
0295 
0296     err = input_register_device(input_dev);
0297     if (err)
0298         return err;
0299 
0300     platform_set_drvdata(pdev, keypad);
0301 
0302     device_init_wakeup(&pdev->dev, 1);
0303     err = dev_pm_set_wake_irq(&pdev->dev, keypad->irq);
0304     if (err)
0305         dev_warn(&pdev->dev, "failed to set up wakeup irq: %d\n", err);
0306 
0307     return 0;
0308 }
0309 
0310 static int ep93xx_keypad_remove(struct platform_device *pdev)
0311 {
0312     dev_pm_clear_wake_irq(&pdev->dev);
0313 
0314     return 0;
0315 }
0316 
0317 static struct platform_driver ep93xx_keypad_driver = {
0318     .driver     = {
0319         .name   = "ep93xx-keypad",
0320         .pm = &ep93xx_keypad_pm_ops,
0321     },
0322     .probe      = ep93xx_keypad_probe,
0323     .remove     = ep93xx_keypad_remove,
0324 };
0325 module_platform_driver(ep93xx_keypad_driver);
0326 
0327 MODULE_LICENSE("GPL");
0328 MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
0329 MODULE_DESCRIPTION("EP93xx Matrix Keypad Controller");
0330 MODULE_ALIAS("platform:ep93xx-keypad");