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 66 struct 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 82 static 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 104 static 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 119 static 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 133 static 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 141 static 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_properties(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 169 static 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) { 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 280 static 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 298 static 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 319 static SIMPLE_DEV_PM_OPS(lpc32xx_kscan_pm_ops, lpc32xx_kscan_suspend, 320 lpc32xx_kscan_resume); 321 322 static const struct of_device_id lpc32xx_kscan_match[] = { 323 { .compatible = "nxp,lpc3220-key" }, 324 {}, 325 }; 326 MODULE_DEVICE_TABLE(of, lpc32xx_kscan_match); 327 328 static 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 337 module_platform_driver(lpc32xx_kscan_driver); 338 339 MODULE_LICENSE("GPL"); 340 MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>"); 341 MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>"); 342 MODULE_DESCRIPTION("Key scanner driver for LPC32XX devices"); 343