1/* 2 * DaVinci Key Scan Driver for TI platforms 3 * 4 * Copyright (C) 2009 Texas Instruments, Inc 5 * 6 * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com> 7 * 8 * Intial Code: Sandeep Paulraj <s-paulraj@ti.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 */ 24#include <linux/module.h> 25#include <linux/init.h> 26#include <linux/interrupt.h> 27#include <linux/types.h> 28#include <linux/input.h> 29#include <linux/kernel.h> 30#include <linux/delay.h> 31#include <linux/platform_device.h> 32#include <linux/errno.h> 33#include <linux/slab.h> 34 35#include <asm/irq.h> 36 37#include <mach/hardware.h> 38#include <mach/irqs.h> 39#include <mach/keyscan.h> 40 41/* Key scan registers */ 42#define DAVINCI_KEYSCAN_KEYCTRL 0x0000 43#define DAVINCI_KEYSCAN_INTENA 0x0004 44#define DAVINCI_KEYSCAN_INTFLAG 0x0008 45#define DAVINCI_KEYSCAN_INTCLR 0x000c 46#define DAVINCI_KEYSCAN_STRBWIDTH 0x0010 47#define DAVINCI_KEYSCAN_INTERVAL 0x0014 48#define DAVINCI_KEYSCAN_CONTTIME 0x0018 49#define DAVINCI_KEYSCAN_CURRENTST 0x001c 50#define DAVINCI_KEYSCAN_PREVSTATE 0x0020 51#define DAVINCI_KEYSCAN_EMUCTRL 0x0024 52#define DAVINCI_KEYSCAN_IODFTCTRL 0x002c 53 54/* Key Control Register (KEYCTRL) */ 55#define DAVINCI_KEYSCAN_KEYEN 0x00000001 56#define DAVINCI_KEYSCAN_PREVMODE 0x00000002 57#define DAVINCI_KEYSCAN_CHATOFF 0x00000004 58#define DAVINCI_KEYSCAN_AUTODET 0x00000008 59#define DAVINCI_KEYSCAN_SCANMODE 0x00000010 60#define DAVINCI_KEYSCAN_OUTTYPE 0x00000020 61 62/* Masks for the interrupts */ 63#define DAVINCI_KEYSCAN_INT_CONT 0x00000008 64#define DAVINCI_KEYSCAN_INT_OFF 0x00000004 65#define DAVINCI_KEYSCAN_INT_ON 0x00000002 66#define DAVINCI_KEYSCAN_INT_CHANGE 0x00000001 67#define DAVINCI_KEYSCAN_INT_ALL 0x0000000f 68 69struct davinci_ks { 70 struct input_dev *input; 71 struct davinci_ks_platform_data *pdata; 72 int irq; 73 void __iomem *base; 74 resource_size_t pbase; 75 size_t base_size; 76 unsigned short keymap[]; 77}; 78 79/* Initializing the kp Module */ 80static int __init davinci_ks_initialize(struct davinci_ks *davinci_ks) 81{ 82 struct device *dev = &davinci_ks->input->dev; 83 struct davinci_ks_platform_data *pdata = davinci_ks->pdata; 84 u32 matrix_ctrl; 85 86 /* Enable all interrupts */ 87 __raw_writel(DAVINCI_KEYSCAN_INT_ALL, 88 davinci_ks->base + DAVINCI_KEYSCAN_INTENA); 89 90 /* Clear interrupts if any */ 91 __raw_writel(DAVINCI_KEYSCAN_INT_ALL, 92 davinci_ks->base + DAVINCI_KEYSCAN_INTCLR); 93 94 /* Setup the scan period = strobe + interval */ 95 __raw_writel(pdata->strobe, 96 davinci_ks->base + DAVINCI_KEYSCAN_STRBWIDTH); 97 __raw_writel(pdata->interval, 98 davinci_ks->base + DAVINCI_KEYSCAN_INTERVAL); 99 __raw_writel(0x01, 100 davinci_ks->base + DAVINCI_KEYSCAN_CONTTIME); 101 102 /* Define matrix type */ 103 switch (pdata->matrix_type) { 104 case DAVINCI_KEYSCAN_MATRIX_4X4: 105 matrix_ctrl = 0; 106 break; 107 case DAVINCI_KEYSCAN_MATRIX_5X3: 108 matrix_ctrl = (1 << 6); 109 break; 110 default: 111 dev_err(dev->parent, "wrong matrix type\n"); 112 return -EINVAL; 113 } 114 115 /* Enable key scan module and set matrix type */ 116 __raw_writel(DAVINCI_KEYSCAN_AUTODET | DAVINCI_KEYSCAN_KEYEN | 117 matrix_ctrl, davinci_ks->base + DAVINCI_KEYSCAN_KEYCTRL); 118 119 return 0; 120} 121 122static irqreturn_t davinci_ks_interrupt(int irq, void *dev_id) 123{ 124 struct davinci_ks *davinci_ks = dev_id; 125 struct device *dev = &davinci_ks->input->dev; 126 unsigned short *keymap = davinci_ks->keymap; 127 int keymapsize = davinci_ks->pdata->keymapsize; 128 u32 prev_status, new_status, changed; 129 bool release; 130 int keycode = KEY_UNKNOWN; 131 int i; 132 133 /* Disable interrupt */ 134 __raw_writel(0x0, davinci_ks->base + DAVINCI_KEYSCAN_INTENA); 135 136 /* Reading previous and new status of the key scan */ 137 prev_status = __raw_readl(davinci_ks->base + DAVINCI_KEYSCAN_PREVSTATE); 138 new_status = __raw_readl(davinci_ks->base + DAVINCI_KEYSCAN_CURRENTST); 139 140 changed = prev_status ^ new_status; 141 142 if (changed) { 143 /* 144 * It goes through all bits in 'changed' to ensure 145 * that no key changes are being missed 146 */ 147 for (i = 0 ; i < keymapsize; i++) { 148 if ((changed>>i) & 0x1) { 149 keycode = keymap[i]; 150 release = (new_status >> i) & 0x1; 151 dev_dbg(dev->parent, "key %d %s\n", keycode, 152 release ? "released" : "pressed"); 153 input_report_key(davinci_ks->input, keycode, 154 !release); 155 input_sync(davinci_ks->input); 156 } 157 } 158 /* Clearing interrupt */ 159 __raw_writel(DAVINCI_KEYSCAN_INT_ALL, 160 davinci_ks->base + DAVINCI_KEYSCAN_INTCLR); 161 } 162 163 /* Enable interrupts */ 164 __raw_writel(0x1, davinci_ks->base + DAVINCI_KEYSCAN_INTENA); 165 166 return IRQ_HANDLED; 167} 168 169static int __init davinci_ks_probe(struct platform_device *pdev) 170{ 171 struct davinci_ks *davinci_ks; 172 struct input_dev *key_dev; 173 struct resource *res, *mem; 174 struct device *dev = &pdev->dev; 175 struct davinci_ks_platform_data *pdata = pdev->dev.platform_data; 176 int error, i; 177 178 if (pdata->device_enable) { 179 error = pdata->device_enable(dev); 180 if (error < 0) { 181 dev_dbg(dev, "device enable function failed\n"); 182 return error; 183 } 184 } 185 186 if (!pdata->keymap) { 187 dev_dbg(dev, "no keymap from pdata\n"); 188 return -EINVAL; 189 } 190 191 davinci_ks = kzalloc(sizeof(struct davinci_ks) + 192 sizeof(unsigned short) * pdata->keymapsize, GFP_KERNEL); 193 if (!davinci_ks) { 194 dev_dbg(dev, "could not allocate memory for private data\n"); 195 return -ENOMEM; 196 } 197 198 memcpy(davinci_ks->keymap, pdata->keymap, 199 sizeof(unsigned short) * pdata->keymapsize); 200 201 key_dev = input_allocate_device(); 202 if (!key_dev) { 203 dev_dbg(dev, "could not allocate input device\n"); 204 error = -ENOMEM; 205 goto fail1; 206 } 207 208 davinci_ks->input = key_dev; 209 210 davinci_ks->irq = platform_get_irq(pdev, 0); 211 if (davinci_ks->irq < 0) { 212 dev_err(dev, "no key scan irq\n"); 213 error = davinci_ks->irq; 214 goto fail2; 215 } 216 217 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 218 if (!res) { 219 dev_err(dev, "no mem resource\n"); 220 error = -EINVAL; 221 goto fail2; 222 } 223 224 davinci_ks->pbase = res->start; 225 davinci_ks->base_size = resource_size(res); 226 227 mem = request_mem_region(davinci_ks->pbase, davinci_ks->base_size, 228 pdev->name); 229 if (!mem) { 230 dev_err(dev, "key scan registers at %08x are not free\n", 231 davinci_ks->pbase); 232 error = -EBUSY; 233 goto fail2; 234 } 235 236 davinci_ks->base = ioremap(davinci_ks->pbase, davinci_ks->base_size); 237 if (!davinci_ks->base) { 238 dev_err(dev, "can't ioremap MEM resource.\n"); 239 error = -ENOMEM; 240 goto fail3; 241 } 242 243 /* Enable auto repeat feature of Linux input subsystem */ 244 if (pdata->rep) 245 __set_bit(EV_REP, key_dev->evbit); 246 247 /* Setup input device */ 248 __set_bit(EV_KEY, key_dev->evbit); 249 250 /* Setup the platform data */ 251 davinci_ks->pdata = pdata; 252 253 for (i = 0; i < davinci_ks->pdata->keymapsize; i++) 254 __set_bit(davinci_ks->pdata->keymap[i], key_dev->keybit); 255 256 key_dev->name = "davinci_keyscan"; 257 key_dev->phys = "davinci_keyscan/input0"; 258 key_dev->dev.parent = &pdev->dev; 259 key_dev->id.bustype = BUS_HOST; 260 key_dev->id.vendor = 0x0001; 261 key_dev->id.product = 0x0001; 262 key_dev->id.version = 0x0001; 263 key_dev->keycode = davinci_ks->keymap; 264 key_dev->keycodesize = sizeof(davinci_ks->keymap[0]); 265 key_dev->keycodemax = davinci_ks->pdata->keymapsize; 266 267 error = input_register_device(davinci_ks->input); 268 if (error < 0) { 269 dev_err(dev, "unable to register davinci key scan device\n"); 270 goto fail4; 271 } 272 273 error = request_irq(davinci_ks->irq, davinci_ks_interrupt, 274 IRQF_DISABLED, pdev->name, davinci_ks); 275 if (error < 0) { 276 dev_err(dev, "unable to register davinci key scan interrupt\n"); 277 goto fail5; 278 } 279 280 error = davinci_ks_initialize(davinci_ks); 281 if (error < 0) { 282 dev_err(dev, "unable to initialize davinci key scan device\n"); 283 goto fail6; 284 } 285 286 platform_set_drvdata(pdev, davinci_ks); 287 return 0; 288 289fail6: 290 free_irq(davinci_ks->irq, davinci_ks); 291fail5: 292 input_unregister_device(davinci_ks->input); 293 key_dev = NULL; 294fail4: 295 iounmap(davinci_ks->base); 296fail3: 297 release_mem_region(davinci_ks->pbase, davinci_ks->base_size); 298fail2: 299 input_free_device(key_dev); 300fail1: 301 kfree(davinci_ks); 302 303 return error; 304} 305 306static int __devexit davinci_ks_remove(struct platform_device *pdev) 307{ 308 struct davinci_ks *davinci_ks = platform_get_drvdata(pdev); 309 310 free_irq(davinci_ks->irq, davinci_ks); 311 312 input_unregister_device(davinci_ks->input); 313 314 iounmap(davinci_ks->base); 315 release_mem_region(davinci_ks->pbase, davinci_ks->base_size); 316 317 platform_set_drvdata(pdev, NULL); 318 319 kfree(davinci_ks); 320 321 return 0; 322} 323 324static struct platform_driver davinci_ks_driver = { 325 .driver = { 326 .name = "davinci_keyscan", 327 .owner = THIS_MODULE, 328 }, 329 .remove = __devexit_p(davinci_ks_remove), 330}; 331 332static int __init davinci_ks_init(void) 333{ 334 return platform_driver_probe(&davinci_ks_driver, davinci_ks_probe); 335} 336module_init(davinci_ks_init); 337 338static void __exit davinci_ks_exit(void) 339{ 340 platform_driver_unregister(&davinci_ks_driver); 341} 342module_exit(davinci_ks_exit); 343 344MODULE_AUTHOR("Miguel Aguilar"); 345MODULE_DESCRIPTION("Texas Instruments DaVinci Key Scan Driver"); 346MODULE_LICENSE("GPL"); 347