tnetv107x-keypad.c revision d2d8442d0094a7d4b585e2bbde31e3775dba7eb1
1/* 2 * Texas Instruments TNETV107X Keypad Driver 3 * 4 * Copyright (C) 2010 Texas Instruments 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation version 2. 9 * 10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 11 * kind, whether express or implied; without even the implied warranty 12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 */ 15 16#include <linux/kernel.h> 17#include <linux/err.h> 18#include <linux/errno.h> 19#include <linux/input.h> 20#include <linux/platform_device.h> 21#include <linux/interrupt.h> 22#include <linux/slab.h> 23#include <linux/delay.h> 24#include <linux/io.h> 25#include <linux/clk.h> 26#include <linux/input/matrix_keypad.h> 27#include <linux/module.h> 28 29#define BITS(x) (BIT(x) - 1) 30 31#define KEYPAD_ROWS 9 32#define KEYPAD_COLS 9 33 34#define DEBOUNCE_MIN 0x400ul 35#define DEBOUNCE_MAX 0x3ffffffful 36 37struct keypad_regs { 38 u32 rev; 39 u32 mode; 40 u32 mask; 41 u32 pol; 42 u32 dclock; 43 u32 rclock; 44 u32 stable_cnt; 45 u32 in_en; 46 u32 out; 47 u32 out_en; 48 u32 in; 49 u32 lock; 50 u32 pres[3]; 51}; 52 53#define keypad_read(kp, reg) __raw_readl(&(kp)->regs->reg) 54#define keypad_write(kp, reg, val) __raw_writel(val, &(kp)->regs->reg) 55 56struct keypad_data { 57 struct input_dev *input_dev; 58 struct resource *res; 59 struct keypad_regs __iomem *regs; 60 struct clk *clk; 61 struct device *dev; 62 spinlock_t lock; 63 u32 irq_press; 64 u32 irq_release; 65 int rows, cols, row_shift; 66 int debounce_ms, active_low; 67 u32 prev_keys[3]; 68 unsigned short keycodes[]; 69}; 70 71static irqreturn_t keypad_irq(int irq, void *data) 72{ 73 struct keypad_data *kp = data; 74 int i, bit, val, row, col, code; 75 unsigned long flags; 76 u32 curr_keys[3]; 77 u32 change; 78 79 spin_lock_irqsave(&kp->lock, flags); 80 81 memset(curr_keys, 0, sizeof(curr_keys)); 82 if (irq == kp->irq_press) 83 for (i = 0; i < 3; i++) 84 curr_keys[i] = keypad_read(kp, pres[i]); 85 86 for (i = 0; i < 3; i++) { 87 change = curr_keys[i] ^ kp->prev_keys[i]; 88 89 while (change) { 90 bit = fls(change) - 1; 91 change ^= BIT(bit); 92 val = curr_keys[i] & BIT(bit); 93 bit += i * 32; 94 row = bit / KEYPAD_COLS; 95 col = bit % KEYPAD_COLS; 96 97 code = MATRIX_SCAN_CODE(row, col, kp->row_shift); 98 input_event(kp->input_dev, EV_MSC, MSC_SCAN, code); 99 input_report_key(kp->input_dev, kp->keycodes[code], 100 val); 101 } 102 } 103 input_sync(kp->input_dev); 104 memcpy(kp->prev_keys, curr_keys, sizeof(curr_keys)); 105 106 if (irq == kp->irq_press) 107 keypad_write(kp, lock, 0); /* Allow hardware updates */ 108 109 spin_unlock_irqrestore(&kp->lock, flags); 110 111 return IRQ_HANDLED; 112} 113 114static int keypad_start(struct input_dev *dev) 115{ 116 struct keypad_data *kp = input_get_drvdata(dev); 117 unsigned long mask, debounce, clk_rate_khz; 118 unsigned long flags; 119 120 clk_enable(kp->clk); 121 clk_rate_khz = clk_get_rate(kp->clk) / 1000; 122 123 spin_lock_irqsave(&kp->lock, flags); 124 125 /* Initialize device registers */ 126 keypad_write(kp, mode, 0); 127 128 mask = BITS(kp->rows) << KEYPAD_COLS; 129 mask |= BITS(kp->cols); 130 keypad_write(kp, mask, ~mask); 131 132 keypad_write(kp, pol, kp->active_low ? 0 : 0x3ffff); 133 keypad_write(kp, stable_cnt, 3); 134 135 debounce = kp->debounce_ms * clk_rate_khz; 136 debounce = clamp(debounce, DEBOUNCE_MIN, DEBOUNCE_MAX); 137 keypad_write(kp, dclock, debounce); 138 keypad_write(kp, rclock, 4 * debounce); 139 140 keypad_write(kp, in_en, 1); 141 142 spin_unlock_irqrestore(&kp->lock, flags); 143 144 return 0; 145} 146 147static void keypad_stop(struct input_dev *dev) 148{ 149 struct keypad_data *kp = input_get_drvdata(dev); 150 151 synchronize_irq(kp->irq_press); 152 synchronize_irq(kp->irq_release); 153 clk_disable(kp->clk); 154} 155 156static int __devinit keypad_probe(struct platform_device *pdev) 157{ 158 const struct matrix_keypad_platform_data *pdata; 159 const struct matrix_keymap_data *keymap_data; 160 struct device *dev = &pdev->dev; 161 struct keypad_data *kp; 162 int error = 0, sz, row_shift; 163 u32 rev = 0; 164 165 pdata = pdev->dev.platform_data; 166 if (!pdata) { 167 dev_err(dev, "cannot find device data\n"); 168 return -EINVAL; 169 } 170 171 keymap_data = pdata->keymap_data; 172 if (!keymap_data) { 173 dev_err(dev, "cannot find keymap data\n"); 174 return -EINVAL; 175 } 176 177 row_shift = get_count_order(pdata->num_col_gpios); 178 sz = offsetof(struct keypad_data, keycodes); 179 sz += (pdata->num_row_gpios << row_shift) * sizeof(kp->keycodes[0]); 180 kp = kzalloc(sz, GFP_KERNEL); 181 if (!kp) { 182 dev_err(dev, "cannot allocate device info\n"); 183 return -ENOMEM; 184 } 185 186 kp->dev = dev; 187 kp->rows = pdata->num_row_gpios; 188 kp->cols = pdata->num_col_gpios; 189 kp->row_shift = row_shift; 190 platform_set_drvdata(pdev, kp); 191 spin_lock_init(&kp->lock); 192 193 kp->irq_press = platform_get_irq_byname(pdev, "press"); 194 kp->irq_release = platform_get_irq_byname(pdev, "release"); 195 if (kp->irq_press < 0 || kp->irq_release < 0) { 196 dev_err(dev, "cannot determine device interrupts\n"); 197 error = -ENODEV; 198 goto error_res; 199 } 200 201 kp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 202 if (!kp->res) { 203 dev_err(dev, "cannot determine register area\n"); 204 error = -ENODEV; 205 goto error_res; 206 } 207 208 if (!request_mem_region(kp->res->start, resource_size(kp->res), 209 pdev->name)) { 210 dev_err(dev, "cannot claim register memory\n"); 211 kp->res = NULL; 212 error = -EINVAL; 213 goto error_res; 214 } 215 216 kp->regs = ioremap(kp->res->start, resource_size(kp->res)); 217 if (!kp->regs) { 218 dev_err(dev, "cannot map register memory\n"); 219 error = -ENOMEM; 220 goto error_map; 221 } 222 223 kp->clk = clk_get(dev, NULL); 224 if (IS_ERR(kp->clk)) { 225 dev_err(dev, "cannot claim device clock\n"); 226 error = PTR_ERR(kp->clk); 227 goto error_clk; 228 } 229 230 error = request_threaded_irq(kp->irq_press, NULL, keypad_irq, 0, 231 dev_name(dev), kp); 232 if (error < 0) { 233 dev_err(kp->dev, "Could not allocate keypad press key irq\n"); 234 goto error_irq_press; 235 } 236 237 error = request_threaded_irq(kp->irq_release, NULL, keypad_irq, 0, 238 dev_name(dev), kp); 239 if (error < 0) { 240 dev_err(kp->dev, "Could not allocate keypad release key irq\n"); 241 goto error_irq_release; 242 } 243 244 kp->input_dev = input_allocate_device(); 245 if (!kp->input_dev) { 246 dev_err(dev, "cannot allocate input device\n"); 247 error = -ENOMEM; 248 goto error_input; 249 } 250 input_set_drvdata(kp->input_dev, kp); 251 252 kp->input_dev->name = pdev->name; 253 kp->input_dev->dev.parent = &pdev->dev; 254 kp->input_dev->open = keypad_start; 255 kp->input_dev->close = keypad_stop; 256 kp->input_dev->evbit[0] = BIT_MASK(EV_KEY); 257 if (!pdata->no_autorepeat) 258 kp->input_dev->evbit[0] |= BIT_MASK(EV_REP); 259 260 clk_enable(kp->clk); 261 rev = keypad_read(kp, rev); 262 kp->input_dev->id.bustype = BUS_HOST; 263 kp->input_dev->id.product = ((rev >> 8) & 0x07); 264 kp->input_dev->id.version = ((rev >> 16) & 0xfff); 265 clk_disable(kp->clk); 266 267 kp->input_dev->keycode = kp->keycodes; 268 kp->input_dev->keycodesize = sizeof(kp->keycodes[0]); 269 kp->input_dev->keycodemax = kp->rows << kp->row_shift; 270 271 matrix_keypad_build_keymap(keymap_data, kp->row_shift, kp->keycodes, 272 kp->input_dev->keybit); 273 274 input_set_capability(kp->input_dev, EV_MSC, MSC_SCAN); 275 276 error = input_register_device(kp->input_dev); 277 if (error < 0) { 278 dev_err(dev, "Could not register input device\n"); 279 goto error_reg; 280 } 281 282 return 0; 283 284 285error_reg: 286 input_free_device(kp->input_dev); 287error_input: 288 free_irq(kp->irq_release, kp); 289error_irq_release: 290 free_irq(kp->irq_press, kp); 291error_irq_press: 292 clk_put(kp->clk); 293error_clk: 294 iounmap(kp->regs); 295error_map: 296 release_mem_region(kp->res->start, resource_size(kp->res)); 297error_res: 298 platform_set_drvdata(pdev, NULL); 299 kfree(kp); 300 return error; 301} 302 303static int __devexit keypad_remove(struct platform_device *pdev) 304{ 305 struct keypad_data *kp = platform_get_drvdata(pdev); 306 307 free_irq(kp->irq_press, kp); 308 free_irq(kp->irq_release, kp); 309 input_unregister_device(kp->input_dev); 310 clk_put(kp->clk); 311 iounmap(kp->regs); 312 release_mem_region(kp->res->start, resource_size(kp->res)); 313 platform_set_drvdata(pdev, NULL); 314 kfree(kp); 315 316 return 0; 317} 318 319static struct platform_driver keypad_driver = { 320 .probe = keypad_probe, 321 .remove = __devexit_p(keypad_remove), 322 .driver.name = "tnetv107x-keypad", 323 .driver.owner = THIS_MODULE, 324}; 325 326static int __init keypad_init(void) 327{ 328 return platform_driver_register(&keypad_driver); 329} 330 331static void __exit keypad_exit(void) 332{ 333 platform_driver_unregister(&keypad_driver); 334} 335 336module_init(keypad_init); 337module_exit(keypad_exit); 338 339MODULE_AUTHOR("Cyril Chemparathy"); 340MODULE_DESCRIPTION("TNETV107X Keypad Driver"); 341MODULE_ALIAS("platform:tnetv107x-keypad"); 342MODULE_LICENSE("GPL"); 343