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 63struct 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 80static 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 131static 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 154static 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 167static 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 179static 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 200static 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 225static SIMPLE_DEV_PM_OPS(ep93xx_keypad_pm_ops, 226 ep93xx_keypad_suspend, ep93xx_keypad_resume); 227 228static 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 324failed_free_irq: 325 free_irq(keypad->irq, keypad); 326failed_free_dev: 327 input_free_device(input_dev); 328failed_put_clk: 329 clk_put(keypad->clk); 330failed_free_gpio: 331 ep93xx_keypad_release_gpio(pdev); 332failed_free_io: 333 iounmap(keypad->mmio_base); 334failed_free_mem: 335 release_mem_region(res->start, resource_size(res)); 336failed_free: 337 kfree(keypad); 338 return err; 339} 340 341static 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 366static 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}; 374module_platform_driver(ep93xx_keypad_driver); 375 376MODULE_LICENSE("GPL"); 377MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>"); 378MODULE_DESCRIPTION("EP93xx Matrix Keypad Controller"); 379MODULE_ALIAS("platform:ep93xx-keypad"); 380