1 /* 2 * SPEAr Keyboard Driver 3 * Based on omap-keypad driver 4 * 5 * Copyright (C) 2010 ST Microelectronics 6 * Rajeev Kumar<rajeev-dlh.kumar@st.com> 7 * 8 * This file is licensed under the terms of the GNU General Public 9 * License version 2. This program is licensed "as is" without any 10 * warranty of any kind, whether express or implied. 11 */ 12 13 #include <linux/clk.h> 14 #include <linux/errno.h> 15 #include <linux/init.h> 16 #include <linux/interrupt.h> 17 #include <linux/input.h> 18 #include <linux/io.h> 19 #include <linux/irq.h> 20 #include <linux/kernel.h> 21 #include <linux/module.h> 22 #include <linux/of.h> 23 #include <linux/platform_device.h> 24 #include <linux/pm_wakeup.h> 25 #include <linux/slab.h> 26 #include <linux/types.h> 27 #include <plat/keyboard.h> 28 29 /* Keyboard Registers */ 30 #define MODE_REG 0x00 /* 16 bit reg */ 31 #define STATUS_REG 0x0C /* 2 bit reg */ 32 #define DATA_REG 0x10 /* 8 bit reg */ 33 #define INTR_MASK 0x54 34 35 /* Register Values */ 36 /* 37 * pclk freq mask = (APB FEQ -1)= 82 MHZ.Programme bit 15-9 in mode 38 * control register as 1010010(82MHZ) 39 */ 40 #define PCLK_FREQ_MSK 0xA400 /* 82 MHz */ 41 #define START_SCAN 0x0100 42 #define SCAN_RATE_10 0x0000 43 #define SCAN_RATE_20 0x0004 44 #define SCAN_RATE_40 0x0008 45 #define SCAN_RATE_80 0x000C 46 #define MODE_KEYBOARD 0x0002 47 #define DATA_AVAIL 0x2 48 49 #define KEY_MASK 0xFF000000 50 #define KEY_VALUE 0x00FFFFFF 51 #define ROW_MASK 0xF0 52 #define COLUMN_MASK 0x0F 53 #define NUM_ROWS 16 54 #define NUM_COLS 16 55 56 #define KEY_MATRIX_SHIFT 6 57 58 struct spear_kbd { 59 struct input_dev *input; 60 struct resource *res; 61 void __iomem *io_base; 62 struct clk *clk; 63 unsigned int irq; 64 unsigned int mode; 65 unsigned short last_key; 66 unsigned short keycodes[NUM_ROWS * NUM_COLS]; 67 bool rep; 68 }; 69 70 static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) 71 { 72 struct spear_kbd *kbd = dev_id; 73 struct input_dev *input = kbd->input; 74 unsigned int key; 75 u8 sts, val; 76 77 sts = readb(kbd->io_base + STATUS_REG); 78 if (!(sts & DATA_AVAIL)) 79 return IRQ_NONE; 80 81 if (kbd->last_key != KEY_RESERVED) { 82 input_report_key(input, kbd->last_key, 0); 83 kbd->last_key = KEY_RESERVED; 84 } 85 86 /* following reads active (row, col) pair */ 87 val = readb(kbd->io_base + DATA_REG); 88 key = kbd->keycodes[val]; 89 90 input_event(input, EV_MSC, MSC_SCAN, val); 91 input_report_key(input, key, 1); 92 input_sync(input); 93 94 kbd->last_key = key; 95 96 /* clear interrupt */ 97 writeb(0, kbd->io_base + STATUS_REG); 98 99 return IRQ_HANDLED; 100 } 101 102 static int spear_kbd_open(struct input_dev *dev) 103 { 104 struct spear_kbd *kbd = input_get_drvdata(dev); 105 int error; 106 u16 val; 107 108 kbd->last_key = KEY_RESERVED; 109 110 error = clk_enable(kbd->clk); 111 if (error) 112 return error; 113 114 /* program keyboard */ 115 val = SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK | 116 (kbd->mode << KEY_MATRIX_SHIFT); 117 writew(val, kbd->io_base + MODE_REG); 118 writeb(1, kbd->io_base + STATUS_REG); 119 120 /* start key scan */ 121 val = readw(kbd->io_base + MODE_REG); 122 val |= START_SCAN; 123 writew(val, kbd->io_base + MODE_REG); 124 125 return 0; 126 } 127 128 static void spear_kbd_close(struct input_dev *dev) 129 { 130 struct spear_kbd *kbd = input_get_drvdata(dev); 131 u16 val; 132 133 /* stop key scan */ 134 val = readw(kbd->io_base + MODE_REG); 135 val &= ~START_SCAN; 136 writew(val, kbd->io_base + MODE_REG); 137 138 clk_disable(kbd->clk); 139 140 kbd->last_key = KEY_RESERVED; 141 } 142 143 #ifdef CONFIG_OF 144 static int __devinit spear_kbd_parse_dt(struct platform_device *pdev, 145 struct spear_kbd *kbd) 146 { 147 struct device_node *np = pdev->dev.of_node; 148 int error; 149 u32 val; 150 151 if (!np) { 152 dev_err(&pdev->dev, "Missing DT data\n"); 153 return -EINVAL; 154 } 155 156 if (of_property_read_bool(np, "autorepeat")) 157 kbd->rep = true; 158 159 error = of_property_read_u32(np, "st,mode", &val); 160 if (error) { 161 dev_err(&pdev->dev, "DT: Invalid or missing mode\n"); 162 return error; 163 } 164 165 kbd->mode = val; 166 return 0; 167 } 168 #else 169 static inline int spear_kbd_parse_dt(struct platform_device *pdev, 170 struct spear_kbd *kbd) 171 { 172 return -ENOSYS; 173 } 174 #endif 175 176 static int __devinit spear_kbd_probe(struct platform_device *pdev) 177 { 178 struct kbd_platform_data *pdata = dev_get_platdata(&pdev->dev); 179 const struct matrix_keymap_data *keymap = pdata ? pdata->keymap : NULL; 180 struct spear_kbd *kbd; 181 struct input_dev *input_dev; 182 struct resource *res; 183 int irq; 184 int error; 185 186 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 187 if (!res) { 188 dev_err(&pdev->dev, "no keyboard resource defined\n"); 189 return -EBUSY; 190 } 191 192 irq = platform_get_irq(pdev, 0); 193 if (irq < 0) { 194 dev_err(&pdev->dev, "not able to get irq for the device\n"); 195 return irq; 196 } 197 198 kbd = kzalloc(sizeof(*kbd), GFP_KERNEL); 199 input_dev = input_allocate_device(); 200 if (!kbd || !input_dev) { 201 dev_err(&pdev->dev, "out of memory\n"); 202 error = -ENOMEM; 203 goto err_free_mem; 204 } 205 206 kbd->input = input_dev; 207 kbd->irq = irq; 208 209 if (!pdata) { 210 error = spear_kbd_parse_dt(pdev, kbd); 211 if (error) 212 goto err_free_mem; 213 } else { 214 kbd->mode = pdata->mode; 215 kbd->rep = pdata->rep; 216 } 217 218 kbd->res = request_mem_region(res->start, resource_size(res), 219 pdev->name); 220 if (!kbd->res) { 221 dev_err(&pdev->dev, "keyboard region already claimed\n"); 222 error = -EBUSY; 223 goto err_free_mem; 224 } 225 226 kbd->io_base = ioremap(res->start, resource_size(res)); 227 if (!kbd->io_base) { 228 dev_err(&pdev->dev, "ioremap failed for kbd_region\n"); 229 error = -ENOMEM; 230 goto err_release_mem_region; 231 } 232 233 kbd->clk = clk_get(&pdev->dev, NULL); 234 if (IS_ERR(kbd->clk)) { 235 error = PTR_ERR(kbd->clk); 236 goto err_iounmap; 237 } 238 239 input_dev->name = "Spear Keyboard"; 240 input_dev->phys = "keyboard/input0"; 241 input_dev->dev.parent = &pdev->dev; 242 input_dev->id.bustype = BUS_HOST; 243 input_dev->id.vendor = 0x0001; 244 input_dev->id.product = 0x0001; 245 input_dev->id.version = 0x0100; 246 input_dev->open = spear_kbd_open; 247 input_dev->close = spear_kbd_close; 248 249 error = matrix_keypad_build_keymap(keymap, NULL, NUM_ROWS, NUM_COLS, 250 kbd->keycodes, input_dev); 251 if (error) { 252 dev_err(&pdev->dev, "Failed to build keymap\n"); 253 goto err_put_clk; 254 } 255 256 if (kbd->rep) 257 __set_bit(EV_REP, input_dev->evbit); 258 input_set_capability(input_dev, EV_MSC, MSC_SCAN); 259 260 input_set_drvdata(input_dev, kbd); 261 262 error = request_irq(irq, spear_kbd_interrupt, 0, "keyboard", kbd); 263 if (error) { 264 dev_err(&pdev->dev, "request_irq fail\n"); 265 goto err_put_clk; 266 } 267 268 error = input_register_device(input_dev); 269 if (error) { 270 dev_err(&pdev->dev, "Unable to register keyboard device\n"); 271 goto err_free_irq; 272 } 273 274 device_init_wakeup(&pdev->dev, 1); 275 platform_set_drvdata(pdev, kbd); 276 277 return 0; 278 279 err_free_irq: 280 free_irq(kbd->irq, kbd); 281 err_put_clk: 282 clk_put(kbd->clk); 283 err_iounmap: 284 iounmap(kbd->io_base); 285 err_release_mem_region: 286 release_mem_region(res->start, resource_size(res)); 287 err_free_mem: 288 input_free_device(input_dev); 289 kfree(kbd); 290 291 return error; 292 } 293 294 static int __devexit spear_kbd_remove(struct platform_device *pdev) 295 { 296 struct spear_kbd *kbd = platform_get_drvdata(pdev); 297 298 free_irq(kbd->irq, kbd); 299 input_unregister_device(kbd->input); 300 clk_put(kbd->clk); 301 iounmap(kbd->io_base); 302 release_mem_region(kbd->res->start, resource_size(kbd->res)); 303 kfree(kbd); 304 305 device_init_wakeup(&pdev->dev, 1); 306 platform_set_drvdata(pdev, NULL); 307 308 return 0; 309 } 310 311 #ifdef CONFIG_PM 312 static int spear_kbd_suspend(struct device *dev) 313 { 314 struct platform_device *pdev = to_platform_device(dev); 315 struct spear_kbd *kbd = platform_get_drvdata(pdev); 316 struct input_dev *input_dev = kbd->input; 317 318 mutex_lock(&input_dev->mutex); 319 320 if (input_dev->users) 321 clk_enable(kbd->clk); 322 323 if (device_may_wakeup(&pdev->dev)) 324 enable_irq_wake(kbd->irq); 325 326 mutex_unlock(&input_dev->mutex); 327 328 return 0; 329 } 330 331 static int spear_kbd_resume(struct device *dev) 332 { 333 struct platform_device *pdev = to_platform_device(dev); 334 struct spear_kbd *kbd = platform_get_drvdata(pdev); 335 struct input_dev *input_dev = kbd->input; 336 337 mutex_lock(&input_dev->mutex); 338 339 if (device_may_wakeup(&pdev->dev)) 340 disable_irq_wake(kbd->irq); 341 342 if (input_dev->users) 343 clk_enable(kbd->clk); 344 345 mutex_unlock(&input_dev->mutex); 346 347 return 0; 348 } 349 #endif 350 351 static SIMPLE_DEV_PM_OPS(spear_kbd_pm_ops, spear_kbd_suspend, spear_kbd_resume); 352 353 #ifdef CONFIG_OF 354 static const struct of_device_id spear_kbd_id_table[] = { 355 { .compatible = "st,spear300-kbd" }, 356 {} 357 }; 358 MODULE_DEVICE_TABLE(of, spear_kbd_id_table); 359 #endif 360 361 static struct platform_driver spear_kbd_driver = { 362 .probe = spear_kbd_probe, 363 .remove = __devexit_p(spear_kbd_remove), 364 .driver = { 365 .name = "keyboard", 366 .owner = THIS_MODULE, 367 .pm = &spear_kbd_pm_ops, 368 .of_match_table = of_match_ptr(spear_kbd_id_table), 369 }, 370 }; 371 module_platform_driver(spear_kbd_driver); 372 373 MODULE_AUTHOR("Rajeev Kumar"); 374 MODULE_DESCRIPTION("SPEAr Keyboard Driver"); 375 MODULE_LICENSE("GPL"); 376