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
  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