1 /* 2 * SuperH KEYSC Keypad Driver 3 * 4 * Copyright (C) 2008 Magnus Damm 5 * 6 * Based on gpio_keys.c, Copyright 2005 Phil Blundell 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 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/init.h> 16 #include <linux/interrupt.h> 17 #include <linux/irq.h> 18 #include <linux/delay.h> 19 #include <linux/platform_device.h> 20 #include <linux/input.h> 21 #include <linux/clk.h> 22 #include <linux/io.h> 23 #include <asm/sh_keysc.h> 24 25 #define KYCR1_OFFS 0x00 26 #define KYCR2_OFFS 0x04 27 #define KYINDR_OFFS 0x08 28 #define KYOUTDR_OFFS 0x0c 29 30 #define KYCR2_IRQ_LEVEL 0x10 31 #define KYCR2_IRQ_DISABLED 0x00 32 33 static const struct { 34 unsigned char kymd, keyout, keyin; 35 } sh_keysc_mode[] = { 36 [SH_KEYSC_MODE_1] = { 0, 6, 5 }, 37 [SH_KEYSC_MODE_2] = { 1, 5, 6 }, 38 [SH_KEYSC_MODE_3] = { 2, 4, 7 }, 39 }; 40 41 struct sh_keysc_priv { 42 void __iomem *iomem_base; 43 struct clk *clk; 44 unsigned long last_keys; 45 struct input_dev *input; 46 struct sh_keysc_info pdata; 47 }; 48 49 static irqreturn_t sh_keysc_isr(int irq, void *dev_id) 50 { 51 struct platform_device *pdev = dev_id; 52 struct sh_keysc_priv *priv = platform_get_drvdata(pdev); 53 struct sh_keysc_info *pdata = &priv->pdata; 54 unsigned long keys, keys1, keys0, mask; 55 unsigned char keyin_set, tmp; 56 int i, k; 57 58 dev_dbg(&pdev->dev, "isr!\n"); 59 60 keys1 = ~0; 61 keys0 = 0; 62 63 do { 64 keys = 0; 65 keyin_set = 0; 66 67 iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); 68 69 for (i = 0; i < sh_keysc_mode[pdata->mode].keyout; i++) { 70 iowrite16(0xfff ^ (3 << (i * 2)), 71 priv->iomem_base + KYOUTDR_OFFS); 72 udelay(pdata->delay); 73 tmp = ioread16(priv->iomem_base + KYINDR_OFFS); 74 keys |= tmp << (sh_keysc_mode[pdata->mode].keyin * i); 75 tmp ^= (1 << sh_keysc_mode[pdata->mode].keyin) - 1; 76 keyin_set |= tmp; 77 } 78 79 iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); 80 iowrite16(KYCR2_IRQ_LEVEL | (keyin_set << 8), 81 priv->iomem_base + KYCR2_OFFS); 82 83 keys ^= ~0; 84 keys &= (1 << (sh_keysc_mode[pdata->mode].keyin * 85 sh_keysc_mode[pdata->mode].keyout)) - 1; 86 keys1 &= keys; 87 keys0 |= keys; 88 89 dev_dbg(&pdev->dev, "keys 0x%08lx\n", keys); 90 91 } while (ioread16(priv->iomem_base + KYCR2_OFFS) & 0x01); 92 93 dev_dbg(&pdev->dev, "last_keys 0x%08lx keys0 0x%08lx keys1 0x%08lx\n", 94 priv->last_keys, keys0, keys1); 95 96 for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { 97 k = pdata->keycodes[i]; 98 if (!k) 99 continue; 100 101 mask = 1 << i; 102 103 if (!((priv->last_keys ^ keys0) & mask)) 104 continue; 105 106 if ((keys1 | keys0) & mask) { 107 input_event(priv->input, EV_KEY, k, 1); 108 priv->last_keys |= mask; 109 } 110 111 if (!(keys1 & mask)) { 112 input_event(priv->input, EV_KEY, k, 0); 113 priv->last_keys &= ~mask; 114 } 115 116 } 117 input_sync(priv->input); 118 119 return IRQ_HANDLED; 120 } 121 122 #define res_size(res) ((res)->end - (res)->start + 1) 123 124 static int __devinit sh_keysc_probe(struct platform_device *pdev) 125 { 126 struct sh_keysc_priv *priv; 127 struct sh_keysc_info *pdata; 128 struct resource *res; 129 struct input_dev *input; 130 char clk_name[8]; 131 int i, k; 132 int irq, error; 133 134 if (!pdev->dev.platform_data) { 135 dev_err(&pdev->dev, "no platform data defined\n"); 136 error = -EINVAL; 137 goto err0; 138 } 139 140 error = -ENXIO; 141 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 142 if (res == NULL) { 143 dev_err(&pdev->dev, "failed to get I/O memory\n"); 144 goto err0; 145 } 146 147 irq = platform_get_irq(pdev, 0); 148 if (irq < 0) { 149 dev_err(&pdev->dev, "failed to get irq\n"); 150 goto err0; 151 } 152 153 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 154 if (priv == NULL) { 155 dev_err(&pdev->dev, "failed to allocate driver data\n"); 156 error = -ENOMEM; 157 goto err0; 158 } 159 160 platform_set_drvdata(pdev, priv); 161 memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata)); 162 pdata = &priv->pdata; 163 164 priv->iomem_base = ioremap_nocache(res->start, res_size(res)); 165 if (priv->iomem_base == NULL) { 166 dev_err(&pdev->dev, "failed to remap I/O memory\n"); 167 error = -ENXIO; 168 goto err1; 169 } 170 171 snprintf(clk_name, sizeof(clk_name), "keysc%d", pdev->id); 172 priv->clk = clk_get(&pdev->dev, clk_name); 173 if (IS_ERR(priv->clk)) { 174 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); 175 error = PTR_ERR(priv->clk); 176 goto err2; 177 } 178 179 priv->input = input_allocate_device(); 180 if (!priv->input) { 181 dev_err(&pdev->dev, "failed to allocate input device\n"); 182 error = -ENOMEM; 183 goto err3; 184 } 185 186 input = priv->input; 187 input->evbit[0] = BIT_MASK(EV_KEY); 188 189 input->name = pdev->name; 190 input->phys = "sh-keysc-keys/input0"; 191 input->dev.parent = &pdev->dev; 192 193 input->id.bustype = BUS_HOST; 194 input->id.vendor = 0x0001; 195 input->id.product = 0x0001; 196 input->id.version = 0x0100; 197 198 error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev); 199 if (error) { 200 dev_err(&pdev->dev, "failed to request IRQ\n"); 201 goto err4; 202 } 203 204 for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { 205 k = pdata->keycodes[i]; 206 if (k) 207 input_set_capability(input, EV_KEY, k); 208 } 209 210 error = input_register_device(input); 211 if (error) { 212 dev_err(&pdev->dev, "failed to register input device\n"); 213 goto err5; 214 } 215 216 clk_enable(priv->clk); 217 218 iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) | 219 pdata->scan_timing, priv->iomem_base + KYCR1_OFFS); 220 iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); 221 iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); 222 223 device_init_wakeup(&pdev->dev, 1); 224 return 0; 225 err5: 226 free_irq(irq, pdev); 227 err4: 228 input_free_device(input); 229 err3: 230 clk_put(priv->clk); 231 err2: 232 iounmap(priv->iomem_base); 233 err1: 234 platform_set_drvdata(pdev, NULL); 235 kfree(priv); 236 err0: 237 return error; 238 } 239 240 static int __devexit sh_keysc_remove(struct platform_device *pdev) 241 { 242 struct sh_keysc_priv *priv = platform_get_drvdata(pdev); 243 244 iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); 245 246 input_unregister_device(priv->input); 247 free_irq(platform_get_irq(pdev, 0), pdev); 248 iounmap(priv->iomem_base); 249 250 clk_disable(priv->clk); 251 clk_put(priv->clk); 252 253 platform_set_drvdata(pdev, NULL); 254 kfree(priv); 255 return 0; 256 } 257 258 static int sh_keysc_suspend(struct device *dev) 259 { 260 struct platform_device *pdev = to_platform_device(dev); 261 struct sh_keysc_priv *priv = platform_get_drvdata(pdev); 262 int irq = platform_get_irq(pdev, 0); 263 unsigned short value; 264 265 value = ioread16(priv->iomem_base + KYCR1_OFFS); 266 267 if (device_may_wakeup(dev)) { 268 value |= 0x80; 269 enable_irq_wake(irq); 270 } 271 else 272 value &= ~0x80; 273 274 iowrite16(value, priv->iomem_base + KYCR1_OFFS); 275 return 0; 276 } 277 278 static int sh_keysc_resume(struct device *dev) 279 { 280 struct platform_device *pdev = to_platform_device(dev); 281 int irq = platform_get_irq(pdev, 0); 282 283 if (device_may_wakeup(dev)) 284 disable_irq_wake(irq); 285 286 return 0; 287 } 288 289 static struct dev_pm_ops sh_keysc_dev_pm_ops = { 290 .suspend = sh_keysc_suspend, 291 .resume = sh_keysc_resume, 292 }; 293 294 struct platform_driver sh_keysc_device_driver = { 295 .probe = sh_keysc_probe, 296 .remove = __devexit_p(sh_keysc_remove), 297 .driver = { 298 .name = "sh_keysc", 299 .pm = &sh_keysc_dev_pm_ops, 300 } 301 }; 302 303 static int __init sh_keysc_init(void) 304 { 305 return platform_driver_register(&sh_keysc_device_driver); 306 } 307 308 static void __exit sh_keysc_exit(void) 309 { 310 platform_driver_unregister(&sh_keysc_device_driver); 311 } 312 313 module_init(sh_keysc_init); 314 module_exit(sh_keysc_exit); 315 316 MODULE_AUTHOR("Magnus Damm"); 317 MODULE_DESCRIPTION("SuperH KEYSC Keypad Driver"); 318 MODULE_LICENSE("GPL"); 319