linux/drivers/input/touchscreen/bcm_iproc_tsc.c
<<
>>
Prefs
   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                dev_err(&pdev->dev, "platform_get_irq failed: %d\n", irq);
 494                return irq;
 495        }
 496
 497        error = devm_request_irq(&pdev->dev, irq,
 498                                 iproc_touchscreen_interrupt,
 499                                 IRQF_SHARED, IPROC_TS_NAME, pdev);
 500        if (error)
 501                return error;
 502
 503        error = input_register_device(priv->idev);
 504        if (error) {
 505                dev_err(&pdev->dev,
 506                        "failed to register input device: %d\n", error);
 507                return error;
 508        }
 509
 510        return 0;
 511}
 512
 513static const struct of_device_id iproc_ts_of_match[] = {
 514        {.compatible = "brcm,iproc-touchscreen", },
 515        { },
 516};
 517MODULE_DEVICE_TABLE(of, iproc_ts_of_match);
 518
 519static struct platform_driver iproc_ts_driver = {
 520        .probe = iproc_ts_probe,
 521        .driver = {
 522                .name   = IPROC_TS_NAME,
 523                .of_match_table = of_match_ptr(iproc_ts_of_match),
 524        },
 525};
 526
 527module_platform_driver(iproc_ts_driver);
 528
 529MODULE_DESCRIPTION("IPROC Touchscreen driver");
 530MODULE_AUTHOR("Broadcom");
 531MODULE_LICENSE("GPL v2");
 532