1/* 2 * NXP LPC32xx SoC Key Scan Interface 3 * 4 * Authors: 5 * Kevin Wells <kevin.wells@nxp.com> 6 * Roland Stigge <stigge@antcom.de> 7 * 8 * Copyright (C) 2010 NXP Semiconductors 9 * Copyright (C) 2012 Roland Stigge 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * 22 * This controller supports square key matrices from 1x1 up to 8x8 23 */ 24 25#include <linux/module.h> 26#include <linux/interrupt.h> 27#include <linux/slab.h> 28#include <linux/irq.h> 29#include <linux/pm.h> 30#include <linux/platform_device.h> 31#include <linux/input.h> 32#include <linux/clk.h> 33#include <linux/io.h> 34#include <linux/of.h> 35#include <linux/input/matrix_keypad.h> 36 37#define DRV_NAME "lpc32xx_keys" 38 39/* 40 * Key scanner register offsets 41 */ 42#define LPC32XX_KS_DEB(x) ((x) + 0x00) 43#define LPC32XX_KS_STATE_COND(x) ((x) + 0x04) 44#define LPC32XX_KS_IRQ(x) ((x) + 0x08) 45#define LPC32XX_KS_SCAN_CTL(x) ((x) + 0x0C) 46#define LPC32XX_KS_FAST_TST(x) ((x) + 0x10) 47#define LPC32XX_KS_MATRIX_DIM(x) ((x) + 0x14) /* 1..8 */ 48#define LPC32XX_KS_DATA(x, y) ((x) + 0x40 + ((y) << 2)) 49 50#define LPC32XX_KSCAN_DEB_NUM_DEB_PASS(n) ((n) & 0xFF) 51 52#define LPC32XX_KSCAN_SCOND_IN_IDLE 0x0 53#define LPC32XX_KSCAN_SCOND_IN_SCANONCE 0x1 54#define LPC32XX_KSCAN_SCOND_IN_IRQGEN 0x2 55#define LPC32XX_KSCAN_SCOND_IN_SCAN_MATRIX 0x3 56 57#define LPC32XX_KSCAN_IRQ_PENDING_CLR 0x1 58 59#define LPC32XX_KSCAN_SCTRL_SCAN_DELAY(n) ((n) & 0xFF) 60 61#define LPC32XX_KSCAN_FTST_FORCESCANONCE 0x1 62#define LPC32XX_KSCAN_FTST_USE32K_CLK 0x2 63 64#define LPC32XX_KSCAN_MSEL_SELECT(n) ((n) & 0xF) 65 66struct lpc32xx_kscan_drv { 67 struct input_dev *input; 68 struct clk *clk; 69 void __iomem *kscan_base; 70 unsigned int irq; 71 72 u32 matrix_sz; /* Size of matrix in XxY, ie. 3 = 3x3 */ 73 u32 deb_clks; /* Debounce clocks (based on 32KHz clock) */ 74 u32 scan_delay; /* Scan delay (based on 32KHz clock) */ 75 76 unsigned short *keymap; /* Pointer to key map for the scan matrix */ 77 unsigned int row_shift; 78 79 u8 lastkeystates[8]; 80}; 81 82static void lpc32xx_mod_states(struct lpc32xx_kscan_drv *kscandat, int col) 83{ 84 struct input_dev *input = kscandat->input; 85 unsigned row, changed, scancode, keycode; 86 u8 key; 87 88 key = readl(LPC32XX_KS_DATA(kscandat->kscan_base, col)); 89 changed = key ^ kscandat->lastkeystates[col]; 90 kscandat->lastkeystates[col] = key; 91 92 for (row = 0; changed; row++, changed >>= 1) { 93 if (changed & 1) { 94 /* Key state changed, signal an event */ 95 scancode = MATRIX_SCAN_CODE(row, col, 96 kscandat->row_shift); 97 keycode = kscandat->keymap[scancode]; 98 input_event(input, EV_MSC, MSC_SCAN, scancode); 99 input_report_key(input, keycode, key & (1 << row)); 100 } 101 } 102} 103 104static irqreturn_t lpc32xx_kscan_irq(int irq, void *dev_id) 105{ 106 struct lpc32xx_kscan_drv *kscandat = dev_id; 107 int i; 108 109 for (i = 0; i < kscandat->matrix_sz; i++) 110 lpc32xx_mod_states(kscandat, i); 111 112 writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); 113 114 input_sync(kscandat->input); 115 116 return IRQ_HANDLED; 117} 118 119static int lpc32xx_kscan_open(struct input_dev *dev) 120{ 121 struct lpc32xx_kscan_drv *kscandat = input_get_drvdata(dev); 122 int error; 123 124 error = clk_prepare_enable(kscandat->clk); 125 if (error) 126 return error; 127 128 writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); 129 130 return 0; 131} 132 133static void lpc32xx_kscan_close(struct input_dev *dev) 134{ 135 struct lpc32xx_kscan_drv *kscandat = input_get_drvdata(dev); 136 137 writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); 138 clk_disable_unprepare(kscandat->clk); 139} 140 141static int lpc32xx_parse_dt(struct device *dev, 142 struct lpc32xx_kscan_drv *kscandat) 143{ 144 struct device_node *np = dev->of_node; 145 u32 rows = 0, columns = 0; 146 int err; 147 148 err = matrix_keypad_parse_of_params(dev, &rows, &columns); 149 if (err) 150 return err; 151 if (rows != columns) { 152 dev_err(dev, "rows and columns must be equal!\n"); 153 return -EINVAL; 154 } 155 156 kscandat->matrix_sz = rows; 157 kscandat->row_shift = get_count_order(columns); 158 159 of_property_read_u32(np, "nxp,debounce-delay-ms", &kscandat->deb_clks); 160 of_property_read_u32(np, "nxp,scan-delay-ms", &kscandat->scan_delay); 161 if (!kscandat->deb_clks || !kscandat->scan_delay) { 162 dev_err(dev, "debounce or scan delay not specified\n"); 163 return -EINVAL; 164 } 165 166 return 0; 167} 168 169static int lpc32xx_kscan_probe(struct platform_device *pdev) 170{ 171 struct lpc32xx_kscan_drv *kscandat; 172 struct input_dev *input; 173 struct resource *res; 174 size_t keymap_size; 175 int error; 176 int irq; 177 178 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 179 if (!res) { 180 dev_err(&pdev->dev, "failed to get platform I/O memory\n"); 181 return -EINVAL; 182 } 183 184 irq = platform_get_irq(pdev, 0); 185 if (irq < 0 || irq >= NR_IRQS) { 186 dev_err(&pdev->dev, "failed to get platform irq\n"); 187 return -EINVAL; 188 } 189 190 kscandat = devm_kzalloc(&pdev->dev, sizeof(*kscandat), 191 GFP_KERNEL); 192 if (!kscandat) 193 return -ENOMEM; 194 195 error = lpc32xx_parse_dt(&pdev->dev, kscandat); 196 if (error) { 197 dev_err(&pdev->dev, "failed to parse device tree\n"); 198 return error; 199 } 200 201 keymap_size = sizeof(kscandat->keymap[0]) * 202 (kscandat->matrix_sz << kscandat->row_shift); 203 kscandat->keymap = devm_kzalloc(&pdev->dev, keymap_size, GFP_KERNEL); 204 if (!kscandat->keymap) 205 return -ENOMEM; 206 207 kscandat->input = input = devm_input_allocate_device(&pdev->dev); 208 if (!input) { 209 dev_err(&pdev->dev, "failed to allocate input device\n"); 210 return -ENOMEM; 211 } 212 213 /* Setup key input */ 214 input->name = pdev->name; 215 input->phys = "lpc32xx/input0"; 216 input->id.vendor = 0x0001; 217 input->id.product = 0x0001; 218 input->id.version = 0x0100; 219 input->open = lpc32xx_kscan_open; 220 input->close = lpc32xx_kscan_close; 221 input->dev.parent = &pdev->dev; 222 223 input_set_capability(input, EV_MSC, MSC_SCAN); 224 225 error = matrix_keypad_build_keymap(NULL, NULL, 226 kscandat->matrix_sz, 227 kscandat->matrix_sz, 228 kscandat->keymap, kscandat->input); 229 if (error) { 230 dev_err(&pdev->dev, "failed to build keymap\n"); 231 return error; 232 } 233 234 input_set_drvdata(kscandat->input, kscandat); 235 236 kscandat->kscan_base = devm_ioremap_resource(&pdev->dev, res); 237 if (IS_ERR(kscandat->kscan_base)) 238 return PTR_ERR(kscandat->kscan_base); 239 240 /* Get the key scanner clock */ 241 kscandat->clk = devm_clk_get(&pdev->dev, NULL); 242 if (IS_ERR(kscandat->clk)) { 243 dev_err(&pdev->dev, "failed to get clock\n"); 244 return PTR_ERR(kscandat->clk); 245 } 246 247 /* Configure the key scanner */ 248 error = clk_prepare_enable(kscandat->clk); 249 if (error) 250 return error; 251 252 writel(kscandat->deb_clks, LPC32XX_KS_DEB(kscandat->kscan_base)); 253 writel(kscandat->scan_delay, LPC32XX_KS_SCAN_CTL(kscandat->kscan_base)); 254 writel(LPC32XX_KSCAN_FTST_USE32K_CLK, 255 LPC32XX_KS_FAST_TST(kscandat->kscan_base)); 256 writel(kscandat->matrix_sz, 257 LPC32XX_KS_MATRIX_DIM(kscandat->kscan_base)); 258 writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); 259 clk_disable_unprepare(kscandat->clk); 260 261 error = devm_request_irq(&pdev->dev, irq, lpc32xx_kscan_irq, 0, 262 pdev->name, kscandat); 263 if (error) { 264 dev_err(&pdev->dev, "failed to request irq\n"); 265 return error; 266 } 267 268 error = input_register_device(kscandat->input); 269 if (error) { 270 dev_err(&pdev->dev, "failed to register input device\n"); 271 return error; 272 } 273 274 platform_set_drvdata(pdev, kscandat); 275 276 return 0; 277} 278 279#ifdef CONFIG_PM_SLEEP 280static int lpc32xx_kscan_suspend(struct device *dev) 281{ 282 struct platform_device *pdev = to_platform_device(dev); 283 struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); 284 struct input_dev *input = kscandat->input; 285 286 mutex_lock(&input->mutex); 287 288 if (input->users) { 289 /* Clear IRQ and disable clock */ 290 writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); 291 clk_disable_unprepare(kscandat->clk); 292 } 293 294 mutex_unlock(&input->mutex); 295 return 0; 296} 297 298static int lpc32xx_kscan_resume(struct device *dev) 299{ 300 struct platform_device *pdev = to_platform_device(dev); 301 struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); 302 struct input_dev *input = kscandat->input; 303 int retval = 0; 304 305 mutex_lock(&input->mutex); 306 307 if (input->users) { 308 /* Enable clock and clear IRQ */ 309 retval = clk_prepare_enable(kscandat->clk); 310 if (retval == 0) 311 writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); 312 } 313 314 mutex_unlock(&input->mutex); 315 return retval; 316} 317#endif 318 319static SIMPLE_DEV_PM_OPS(lpc32xx_kscan_pm_ops, lpc32xx_kscan_suspend, 320 lpc32xx_kscan_resume); 321 322static const struct of_device_id lpc32xx_kscan_match[] = { 323 { .compatible = "nxp,lpc3220-key" }, 324 {}, 325}; 326MODULE_DEVICE_TABLE(of, lpc32xx_kscan_match); 327 328static struct platform_driver lpc32xx_kscan_driver = { 329 .probe = lpc32xx_kscan_probe, 330 .driver = { 331 .name = DRV_NAME, 332 .pm = &lpc32xx_kscan_pm_ops, 333 .of_match_table = lpc32xx_kscan_match, 334 } 335}; 336 337module_platform_driver(lpc32xx_kscan_driver); 338 339MODULE_LICENSE("GPL"); 340MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>"); 341MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>"); 342MODULE_DESCRIPTION("Key scanner driver for LPC32XX devices"); 343