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