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_prepare_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_unprepare(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_device_enabled(input_dev)) { 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 < 0) { 254 err = keypad->irq; 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"); 380