bcm_iproc_tsc.c (13877B)
1/* 2* Copyright (C) 2015 Broadcom Corporation 3* 4* This program is free software; you can redistribute it and/or 5* modify it under the terms of the GNU General Public License as 6* published by the Free Software Foundation version 2. 7* 8* This program is distributed "as is" WITHOUT ANY WARRANTY of any 9* kind, whether express or implied; without even the implied warranty 10* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11* GNU General Public License for more details. 12*/ 13#include <linux/module.h> 14#include <linux/init.h> 15#include <linux/input.h> 16#include <linux/delay.h> 17#include <linux/interrupt.h> 18#include <linux/keyboard.h> 19#include <linux/platform_device.h> 20#include <linux/slab.h> 21#include <linux/of.h> 22#include <asm/irq.h> 23#include <linux/io.h> 24#include <linux/clk.h> 25#include <linux/serio.h> 26#include <linux/mfd/syscon.h> 27#include <linux/regmap.h> 28 29#define IPROC_TS_NAME "iproc-ts" 30 31#define PEN_DOWN_STATUS 1 32#define PEN_UP_STATUS 0 33 34#define X_MIN 0 35#define Y_MIN 0 36#define X_MAX 0xFFF 37#define Y_MAX 0xFFF 38 39/* Value given by controller for invalid coordinate. */ 40#define INVALID_COORD 0xFFFFFFFF 41 42/* Register offsets */ 43#define REGCTL1 0x00 44#define REGCTL2 0x04 45#define INTERRUPT_THRES 0x08 46#define INTERRUPT_MASK 0x0c 47 48#define INTERRUPT_STATUS 0x10 49#define CONTROLLER_STATUS 0x14 50#define FIFO_DATA 0x18 51#define FIFO_DATA_X_Y_MASK 0xFFFF 52#define ANALOG_CONTROL 0x1c 53 54#define AUX_DATA 0x20 55#define DEBOUNCE_CNTR_STAT 0x24 56#define SCAN_CNTR_STAT 0x28 57#define REM_CNTR_STAT 0x2c 58 59#define SETTLING_TIMER_STAT 0x30 60#define SPARE_REG 0x34 61#define SOFT_BYPASS_CONTROL 0x38 62#define SOFT_BYPASS_DATA 0x3c 63 64 65/* Bit values for INTERRUPT_MASK and INTERRUPT_STATUS regs */ 66#define TS_PEN_INTR_MASK BIT(0) 67#define TS_FIFO_INTR_MASK BIT(2) 68 69/* Bit values for CONTROLLER_STATUS reg1 */ 70#define TS_PEN_DOWN BIT(0) 71 72/* Shift values for control reg1 */ 73#define SCANNING_PERIOD_SHIFT 24 74#define DEBOUNCE_TIMEOUT_SHIFT 16 75#define SETTLING_TIMEOUT_SHIFT 8 76#define TOUCH_TIMEOUT_SHIFT 0 77 78/* Shift values for coordinates from fifo */ 79#define X_COORD_SHIFT 0 80#define Y_COORD_SHIFT 16 81 82/* Bit values for REGCTL2 */ 83#define TS_CONTROLLER_EN_BIT BIT(16) 84#define TS_CONTROLLER_AVGDATA_SHIFT 8 85#define TS_CONTROLLER_AVGDATA_MASK (0x7 << TS_CONTROLLER_AVGDATA_SHIFT) 86#define TS_CONTROLLER_PWR_LDO BIT(5) 87#define TS_CONTROLLER_PWR_ADC BIT(4) 88#define TS_CONTROLLER_PWR_BGP BIT(3) 89#define TS_CONTROLLER_PWR_TS BIT(2) 90#define TS_WIRE_MODE_BIT BIT(1) 91 92#define dbg_reg(dev, priv, reg) \ 93do { \ 94 u32 val; \ 95 regmap_read(priv->regmap, reg, &val); \ 96 dev_dbg(dev, "%20s= 0x%08x\n", #reg, val); \ 97} while (0) 98 99struct tsc_param { 100 /* Each step is 1024 us. Valid 1-256 */ 101 u32 scanning_period; 102 103 /* Each step is 512 us. Valid 0-255 */ 104 u32 debounce_timeout; 105 106 /* 107 * The settling duration (in ms) is the amount of time the tsc 108 * waits to allow the voltage to settle after turning on the 109 * drivers in detection mode. Valid values: 0-11 110 * 0 = 0.008 ms 111 * 1 = 0.01 ms 112 * 2 = 0.02 ms 113 * 3 = 0.04 ms 114 * 4 = 0.08 ms 115 * 5 = 0.16 ms 116 * 6 = 0.32 ms 117 * 7 = 0.64 ms 118 * 8 = 1.28 ms 119 * 9 = 2.56 ms 120 * 10 = 5.12 ms 121 * 11 = 10.24 ms 122 */ 123 u32 settling_timeout; 124 125 /* touch timeout in sample counts */ 126 u32 touch_timeout; 127 128 /* 129 * Number of data samples which are averaged before a final data point 130 * is placed into the FIFO 131 */ 132 u32 average_data; 133 134 /* FIFO threshold */ 135 u32 fifo_threshold; 136 137 /* Optional standard touchscreen properties. */ 138 u32 max_x; 139 u32 max_y; 140 u32 fuzz_x; 141 u32 fuzz_y; 142 bool invert_x; 143 bool invert_y; 144}; 145 146struct iproc_ts_priv { 147 struct platform_device *pdev; 148 struct input_dev *idev; 149 150 struct regmap *regmap; 151 struct clk *tsc_clk; 152 153 int pen_status; 154 struct tsc_param cfg_params; 155}; 156 157/* 158 * Set default values the same as hardware reset values 159 * except for fifo_threshold with is set to 1. 160 */ 161static const struct tsc_param iproc_default_config = { 162 .scanning_period = 0x5, /* 1 to 256 */ 163 .debounce_timeout = 0x28, /* 0 to 255 */ 164 .settling_timeout = 0x7, /* 0 to 11 */ 165 .touch_timeout = 0xa, /* 0 to 255 */ 166 .average_data = 5, /* entry 5 = 32 pts */ 167 .fifo_threshold = 1, /* 0 to 31 */ 168 .max_x = X_MAX, 169 .max_y = Y_MAX, 170}; 171 172static void ts_reg_dump(struct iproc_ts_priv *priv) 173{ 174 struct device *dev = &priv->pdev->dev; 175 176 dbg_reg(dev, priv, REGCTL1); 177 dbg_reg(dev, priv, REGCTL2); 178 dbg_reg(dev, priv, INTERRUPT_THRES); 179 dbg_reg(dev, priv, INTERRUPT_MASK); 180 dbg_reg(dev, priv, INTERRUPT_STATUS); 181 dbg_reg(dev, priv, CONTROLLER_STATUS); 182 dbg_reg(dev, priv, FIFO_DATA); 183 dbg_reg(dev, priv, ANALOG_CONTROL); 184 dbg_reg(dev, priv, AUX_DATA); 185 dbg_reg(dev, priv, DEBOUNCE_CNTR_STAT); 186 dbg_reg(dev, priv, SCAN_CNTR_STAT); 187 dbg_reg(dev, priv, REM_CNTR_STAT); 188 dbg_reg(dev, priv, SETTLING_TIMER_STAT); 189 dbg_reg(dev, priv, SPARE_REG); 190 dbg_reg(dev, priv, SOFT_BYPASS_CONTROL); 191 dbg_reg(dev, priv, SOFT_BYPASS_DATA); 192} 193 194static irqreturn_t iproc_touchscreen_interrupt(int irq, void *data) 195{ 196 struct platform_device *pdev = data; 197 struct iproc_ts_priv *priv = platform_get_drvdata(pdev); 198 u32 intr_status; 199 u32 raw_coordinate; 200 u16 x; 201 u16 y; 202 int i; 203 bool needs_sync = false; 204 205 regmap_read(priv->regmap, INTERRUPT_STATUS, &intr_status); 206 intr_status &= TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK; 207 if (intr_status == 0) 208 return IRQ_NONE; 209 210 /* Clear all interrupt status bits, write-1-clear */ 211 regmap_write(priv->regmap, INTERRUPT_STATUS, intr_status); 212 /* Pen up/down */ 213 if (intr_status & TS_PEN_INTR_MASK) { 214 regmap_read(priv->regmap, CONTROLLER_STATUS, &priv->pen_status); 215 if (priv->pen_status & TS_PEN_DOWN) 216 priv->pen_status = PEN_DOWN_STATUS; 217 else 218 priv->pen_status = PEN_UP_STATUS; 219 220 input_report_key(priv->idev, BTN_TOUCH, priv->pen_status); 221 needs_sync = true; 222 223 dev_dbg(&priv->pdev->dev, 224 "pen up-down (%d)\n", priv->pen_status); 225 } 226 227 /* coordinates in FIFO exceed the theshold */ 228 if (intr_status & TS_FIFO_INTR_MASK) { 229 for (i = 0; i < priv->cfg_params.fifo_threshold; i++) { 230 regmap_read(priv->regmap, FIFO_DATA, &raw_coordinate); 231 if (raw_coordinate == INVALID_COORD) 232 continue; 233 234 /* 235 * The x and y coordinate are 16 bits each 236 * with the x in the lower 16 bits and y in the 237 * upper 16 bits. 238 */ 239 x = (raw_coordinate >> X_COORD_SHIFT) & 240 FIFO_DATA_X_Y_MASK; 241 y = (raw_coordinate >> Y_COORD_SHIFT) & 242 FIFO_DATA_X_Y_MASK; 243 244 /* We only want to retain the 12 msb of the 16 */ 245 x = (x >> 4) & 0x0FFF; 246 y = (y >> 4) & 0x0FFF; 247 248 /* Adjust x y according to LCD tsc mount angle. */ 249 if (priv->cfg_params.invert_x) 250 x = priv->cfg_params.max_x - x; 251 252 if (priv->cfg_params.invert_y) 253 y = priv->cfg_params.max_y - y; 254 255 input_report_abs(priv->idev, ABS_X, x); 256 input_report_abs(priv->idev, ABS_Y, y); 257 needs_sync = true; 258 259 dev_dbg(&priv->pdev->dev, "xy (0x%x 0x%x)\n", x, y); 260 } 261 } 262 263 if (needs_sync) 264 input_sync(priv->idev); 265 266 return IRQ_HANDLED; 267} 268 269static int iproc_ts_start(struct input_dev *idev) 270{ 271 u32 val; 272 u32 mask; 273 int error; 274 struct iproc_ts_priv *priv = input_get_drvdata(idev); 275 276 /* Enable clock */ 277 error = clk_prepare_enable(priv->tsc_clk); 278 if (error) { 279 dev_err(&priv->pdev->dev, "%s clk_prepare_enable failed %d\n", 280 __func__, error); 281 return error; 282 } 283 284 /* 285 * Interrupt is generated when: 286 * FIFO reaches the int_th value, and pen event(up/down) 287 */ 288 val = TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK; 289 regmap_update_bits(priv->regmap, INTERRUPT_MASK, val, val); 290 291 val = priv->cfg_params.fifo_threshold; 292 regmap_write(priv->regmap, INTERRUPT_THRES, val); 293 294 /* Initialize control reg1 */ 295 val = 0; 296 val |= priv->cfg_params.scanning_period << SCANNING_PERIOD_SHIFT; 297 val |= priv->cfg_params.debounce_timeout << DEBOUNCE_TIMEOUT_SHIFT; 298 val |= priv->cfg_params.settling_timeout << SETTLING_TIMEOUT_SHIFT; 299 val |= priv->cfg_params.touch_timeout << TOUCH_TIMEOUT_SHIFT; 300 regmap_write(priv->regmap, REGCTL1, val); 301 302 /* Try to clear all interrupt status */ 303 val = TS_FIFO_INTR_MASK | TS_PEN_INTR_MASK; 304 regmap_update_bits(priv->regmap, INTERRUPT_STATUS, val, val); 305 306 /* Initialize control reg2 */ 307 val = TS_CONTROLLER_EN_BIT | TS_WIRE_MODE_BIT; 308 val |= priv->cfg_params.average_data << TS_CONTROLLER_AVGDATA_SHIFT; 309 310 mask = (TS_CONTROLLER_AVGDATA_MASK); 311 mask |= (TS_CONTROLLER_PWR_LDO | /* PWR up LDO */ 312 TS_CONTROLLER_PWR_ADC | /* PWR up ADC */ 313 TS_CONTROLLER_PWR_BGP | /* PWR up BGP */ 314 TS_CONTROLLER_PWR_TS); /* PWR up TS */ 315 mask |= val; 316 regmap_update_bits(priv->regmap, REGCTL2, mask, val); 317 318 ts_reg_dump(priv); 319 320 return 0; 321} 322 323static void iproc_ts_stop(struct input_dev *dev) 324{ 325 u32 val; 326 struct iproc_ts_priv *priv = input_get_drvdata(dev); 327 328 /* 329 * Disable FIFO int_th and pen event(up/down)Interrupts only 330 * as the interrupt mask register is shared between ADC, TS and 331 * flextimer. 332 */ 333 val = TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK; 334 regmap_update_bits(priv->regmap, INTERRUPT_MASK, val, 0); 335 336 /* Only power down touch screen controller */ 337 val = TS_CONTROLLER_PWR_TS; 338 regmap_update_bits(priv->regmap, REGCTL2, val, val); 339 340 clk_disable(priv->tsc_clk); 341} 342 343static int iproc_get_tsc_config(struct device *dev, struct iproc_ts_priv *priv) 344{ 345 struct device_node *np = dev->of_node; 346 u32 val; 347 348 priv->cfg_params = iproc_default_config; 349 350 if (!np) 351 return 0; 352 353 if (of_property_read_u32(np, "scanning_period", &val) >= 0) { 354 if (val < 1 || val > 256) { 355 dev_err(dev, "scanning_period (%u) must be [1-256]\n", 356 val); 357 return -EINVAL; 358 } 359 priv->cfg_params.scanning_period = val; 360 } 361 362 if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) { 363 if (val > 255) { 364 dev_err(dev, "debounce_timeout (%u) must be [0-255]\n", 365 val); 366 return -EINVAL; 367 } 368 priv->cfg_params.debounce_timeout = val; 369 } 370 371 if (of_property_read_u32(np, "settling_timeout", &val) >= 0) { 372 if (val > 11) { 373 dev_err(dev, "settling_timeout (%u) must be [0-11]\n", 374 val); 375 return -EINVAL; 376 } 377 priv->cfg_params.settling_timeout = val; 378 } 379 380 if (of_property_read_u32(np, "touch_timeout", &val) >= 0) { 381 if (val > 255) { 382 dev_err(dev, "touch_timeout (%u) must be [0-255]\n", 383 val); 384 return -EINVAL; 385 } 386 priv->cfg_params.touch_timeout = val; 387 } 388 389 if (of_property_read_u32(np, "average_data", &val) >= 0) { 390 if (val > 8) { 391 dev_err(dev, "average_data (%u) must be [0-8]\n", val); 392 return -EINVAL; 393 } 394 priv->cfg_params.average_data = val; 395 } 396 397 if (of_property_read_u32(np, "fifo_threshold", &val) >= 0) { 398 if (val > 31) { 399 dev_err(dev, "fifo_threshold (%u)) must be [0-31]\n", 400 val); 401 return -EINVAL; 402 } 403 priv->cfg_params.fifo_threshold = val; 404 } 405 406 /* Parse optional properties. */ 407 of_property_read_u32(np, "touchscreen-size-x", &priv->cfg_params.max_x); 408 of_property_read_u32(np, "touchscreen-size-y", &priv->cfg_params.max_y); 409 410 of_property_read_u32(np, "touchscreen-fuzz-x", 411 &priv->cfg_params.fuzz_x); 412 of_property_read_u32(np, "touchscreen-fuzz-y", 413 &priv->cfg_params.fuzz_y); 414 415 priv->cfg_params.invert_x = 416 of_property_read_bool(np, "touchscreen-inverted-x"); 417 priv->cfg_params.invert_y = 418 of_property_read_bool(np, "touchscreen-inverted-y"); 419 420 return 0; 421} 422 423static int iproc_ts_probe(struct platform_device *pdev) 424{ 425 struct iproc_ts_priv *priv; 426 struct input_dev *idev; 427 int irq; 428 int error; 429 430 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 431 if (!priv) 432 return -ENOMEM; 433 434 /* touchscreen controller memory mapped regs via syscon*/ 435 priv->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, 436 "ts_syscon"); 437 if (IS_ERR(priv->regmap)) { 438 error = PTR_ERR(priv->regmap); 439 dev_err(&pdev->dev, "unable to map I/O memory:%d\n", error); 440 return error; 441 } 442 443 priv->tsc_clk = devm_clk_get(&pdev->dev, "tsc_clk"); 444 if (IS_ERR(priv->tsc_clk)) { 445 error = PTR_ERR(priv->tsc_clk); 446 dev_err(&pdev->dev, 447 "failed getting clock tsc_clk: %d\n", error); 448 return error; 449 } 450 451 priv->pdev = pdev; 452 error = iproc_get_tsc_config(&pdev->dev, priv); 453 if (error) { 454 dev_err(&pdev->dev, "get_tsc_config failed: %d\n", error); 455 return error; 456 } 457 458 idev = devm_input_allocate_device(&pdev->dev); 459 if (!idev) { 460 dev_err(&pdev->dev, "failed to allocate input device\n"); 461 return -ENOMEM; 462 } 463 464 priv->idev = idev; 465 priv->pen_status = PEN_UP_STATUS; 466 467 /* Set input device info */ 468 idev->name = IPROC_TS_NAME; 469 idev->dev.parent = &pdev->dev; 470 471 idev->id.bustype = BUS_HOST; 472 idev->id.vendor = SERIO_UNKNOWN; 473 idev->id.product = 0; 474 idev->id.version = 0; 475 476 idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 477 __set_bit(BTN_TOUCH, idev->keybit); 478 479 input_set_abs_params(idev, ABS_X, X_MIN, priv->cfg_params.max_x, 480 priv->cfg_params.fuzz_x, 0); 481 input_set_abs_params(idev, ABS_Y, Y_MIN, priv->cfg_params.max_y, 482 priv->cfg_params.fuzz_y, 0); 483 484 idev->open = iproc_ts_start; 485 idev->close = iproc_ts_stop; 486 487 input_set_drvdata(idev, priv); 488 platform_set_drvdata(pdev, priv); 489 490 /* get interrupt */ 491 irq = platform_get_irq(pdev, 0); 492 if (irq < 0) 493 return irq; 494 495 error = devm_request_irq(&pdev->dev, irq, 496 iproc_touchscreen_interrupt, 497 IRQF_SHARED, IPROC_TS_NAME, pdev); 498 if (error) 499 return error; 500 501 error = input_register_device(priv->idev); 502 if (error) { 503 dev_err(&pdev->dev, 504 "failed to register input device: %d\n", error); 505 return error; 506 } 507 508 return 0; 509} 510 511static const struct of_device_id iproc_ts_of_match[] = { 512 {.compatible = "brcm,iproc-touchscreen", }, 513 { }, 514}; 515MODULE_DEVICE_TABLE(of, iproc_ts_of_match); 516 517static struct platform_driver iproc_ts_driver = { 518 .probe = iproc_ts_probe, 519 .driver = { 520 .name = IPROC_TS_NAME, 521 .of_match_table = of_match_ptr(iproc_ts_of_match), 522 }, 523}; 524 525module_platform_driver(iproc_ts_driver); 526 527MODULE_DESCRIPTION("IPROC Touchscreen driver"); 528MODULE_AUTHOR("Broadcom"); 529MODULE_LICENSE("GPL v2");