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