1*c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 26ac24381SMichael Welling /* 36ac24381SMichael Welling * TSC2004/TSC2005 touchscreen driver core 46ac24381SMichael Welling * 56ac24381SMichael Welling * Copyright (C) 2006-2010 Nokia Corporation 66ac24381SMichael Welling * Copyright (C) 2015 QWERTY Embedded Design 76ac24381SMichael Welling * Copyright (C) 2015 EMAC Inc. 86ac24381SMichael Welling * 96ac24381SMichael Welling * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com> 106ac24381SMichael Welling * based on TSC2301 driver by Klaus K. Pedersen <klaus.k.pedersen@nokia.com> 116ac24381SMichael Welling */ 126ac24381SMichael Welling 136ac24381SMichael Welling #include <linux/kernel.h> 146ac24381SMichael Welling #include <linux/module.h> 156ac24381SMichael Welling #include <linux/input.h> 166ac24381SMichael Welling #include <linux/input/touchscreen.h> 176ac24381SMichael Welling #include <linux/interrupt.h> 186ac24381SMichael Welling #include <linux/delay.h> 196ac24381SMichael Welling #include <linux/pm.h> 206ac24381SMichael Welling #include <linux/of.h> 216ac24381SMichael Welling #include <linux/regulator/consumer.h> 226ac24381SMichael Welling #include <linux/regmap.h> 236ac24381SMichael Welling #include <linux/gpio/consumer.h> 246ac24381SMichael Welling #include "tsc200x-core.h" 256ac24381SMichael Welling 266ac24381SMichael Welling /* 276ac24381SMichael Welling * The touchscreen interface operates as follows: 286ac24381SMichael Welling * 296ac24381SMichael Welling * 1) Pen is pressed against the touchscreen. 30ef3b98c2SMichael Welling * 2) TSC200X performs AD conversion. 31ef3b98c2SMichael Welling * 3) After the conversion is done TSC200X drives DAV line down. 32ef3b98c2SMichael Welling * 4) GPIO IRQ is received and tsc200x_irq_thread() is scheduled. 33ef3b98c2SMichael Welling * 5) tsc200x_irq_thread() queues up a transfer to fetch the x, y, z1, z2 346ac24381SMichael Welling * values. 35ef3b98c2SMichael Welling * 6) tsc200x_irq_thread() reports coordinates to input layer and sets up 36ef3b98c2SMichael Welling * tsc200x_penup_timer() to be called after TSC200X_PENUP_TIME_MS (40ms). 376ac24381SMichael Welling * 7) When the penup timer expires, there have not been touch or DAV interrupts 386ac24381SMichael Welling * during the last 40ms which means the pen has been lifted. 396ac24381SMichael Welling * 40ef3b98c2SMichael Welling * ESD recovery via a hardware reset is done if the TSC200X doesn't respond 416ac24381SMichael Welling * after a configurable period (in ms) of activity. If esd_timeout is 0, the 426ac24381SMichael Welling * watchdog is disabled. 436ac24381SMichael Welling */ 446ac24381SMichael Welling 45ef3b98c2SMichael Welling static const struct regmap_range tsc200x_writable_ranges[] = { 46ef3b98c2SMichael Welling regmap_reg_range(TSC200X_REG_AUX_HIGH, TSC200X_REG_CFR2), 476ac24381SMichael Welling }; 486ac24381SMichael Welling 49ef3b98c2SMichael Welling static const struct regmap_access_table tsc200x_writable_table = { 50ef3b98c2SMichael Welling .yes_ranges = tsc200x_writable_ranges, 51ef3b98c2SMichael Welling .n_yes_ranges = ARRAY_SIZE(tsc200x_writable_ranges), 526ac24381SMichael Welling }; 536ac24381SMichael Welling 546ac24381SMichael Welling const struct regmap_config tsc200x_regmap_config = { 556ac24381SMichael Welling .reg_bits = 8, 566ac24381SMichael Welling .val_bits = 16, 576ac24381SMichael Welling .reg_stride = 0x08, 586ac24381SMichael Welling .max_register = 0x78, 59ef3b98c2SMichael Welling .read_flag_mask = TSC200X_REG_READ, 60ef3b98c2SMichael Welling .write_flag_mask = TSC200X_REG_PND0, 61ef3b98c2SMichael Welling .wr_table = &tsc200x_writable_table, 621c96a2f6SDavid Frey .use_single_read = true, 631c96a2f6SDavid Frey .use_single_write = true, 646ac24381SMichael Welling }; 656ac24381SMichael Welling EXPORT_SYMBOL_GPL(tsc200x_regmap_config); 666ac24381SMichael Welling 67ef3b98c2SMichael Welling struct tsc200x_data { 686ac24381SMichael Welling u16 x; 696ac24381SMichael Welling u16 y; 706ac24381SMichael Welling u16 z1; 716ac24381SMichael Welling u16 z2; 726ac24381SMichael Welling } __packed; 73ef3b98c2SMichael Welling #define TSC200X_DATA_REGS 4 746ac24381SMichael Welling 75ef3b98c2SMichael Welling struct tsc200x { 766ac24381SMichael Welling struct device *dev; 776ac24381SMichael Welling struct regmap *regmap; 786ac24381SMichael Welling __u16 bustype; 796ac24381SMichael Welling 806ac24381SMichael Welling struct input_dev *idev; 816ac24381SMichael Welling char phys[32]; 826ac24381SMichael Welling 836ac24381SMichael Welling struct mutex mutex; 846ac24381SMichael Welling 856ac24381SMichael Welling /* raw copy of previous x,y,z */ 866ac24381SMichael Welling int in_x; 876ac24381SMichael Welling int in_y; 886ac24381SMichael Welling int in_z1; 896ac24381SMichael Welling int in_z2; 906ac24381SMichael Welling 916ac24381SMichael Welling spinlock_t lock; 926ac24381SMichael Welling struct timer_list penup_timer; 936ac24381SMichael Welling 946ac24381SMichael Welling unsigned int esd_timeout; 956ac24381SMichael Welling struct delayed_work esd_work; 966ac24381SMichael Welling unsigned long last_valid_interrupt; 976ac24381SMichael Welling 986ac24381SMichael Welling unsigned int x_plate_ohm; 996ac24381SMichael Welling 1006ac24381SMichael Welling bool opened; 1016ac24381SMichael Welling bool suspended; 1026ac24381SMichael Welling 1036ac24381SMichael Welling bool pen_down; 1046ac24381SMichael Welling 1056ac24381SMichael Welling struct regulator *vio; 1066ac24381SMichael Welling 1076ac24381SMichael Welling struct gpio_desc *reset_gpio; 1086ac24381SMichael Welling int (*tsc200x_cmd)(struct device *dev, u8 cmd); 1096ac24381SMichael Welling int irq; 1106ac24381SMichael Welling }; 1116ac24381SMichael Welling 112ef3b98c2SMichael Welling static void tsc200x_update_pen_state(struct tsc200x *ts, 1136ac24381SMichael Welling int x, int y, int pressure) 1146ac24381SMichael Welling { 1156ac24381SMichael Welling if (pressure) { 1166ac24381SMichael Welling input_report_abs(ts->idev, ABS_X, x); 1176ac24381SMichael Welling input_report_abs(ts->idev, ABS_Y, y); 1186ac24381SMichael Welling input_report_abs(ts->idev, ABS_PRESSURE, pressure); 1196ac24381SMichael Welling if (!ts->pen_down) { 1206ac24381SMichael Welling input_report_key(ts->idev, BTN_TOUCH, !!pressure); 1216ac24381SMichael Welling ts->pen_down = true; 1226ac24381SMichael Welling } 1236ac24381SMichael Welling } else { 1246ac24381SMichael Welling input_report_abs(ts->idev, ABS_PRESSURE, 0); 1256ac24381SMichael Welling if (ts->pen_down) { 1266ac24381SMichael Welling input_report_key(ts->idev, BTN_TOUCH, 0); 1276ac24381SMichael Welling ts->pen_down = false; 1286ac24381SMichael Welling } 1296ac24381SMichael Welling } 1306ac24381SMichael Welling input_sync(ts->idev); 1316ac24381SMichael Welling dev_dbg(ts->dev, "point(%4d,%4d), pressure (%4d)\n", x, y, 1326ac24381SMichael Welling pressure); 1336ac24381SMichael Welling } 1346ac24381SMichael Welling 135ef3b98c2SMichael Welling static irqreturn_t tsc200x_irq_thread(int irq, void *_ts) 1366ac24381SMichael Welling { 137ef3b98c2SMichael Welling struct tsc200x *ts = _ts; 1386ac24381SMichael Welling unsigned long flags; 1396ac24381SMichael Welling unsigned int pressure; 140ef3b98c2SMichael Welling struct tsc200x_data tsdata; 1416ac24381SMichael Welling int error; 1426ac24381SMichael Welling 1436ac24381SMichael Welling /* read the coordinates */ 144ef3b98c2SMichael Welling error = regmap_bulk_read(ts->regmap, TSC200X_REG_X, &tsdata, 145ef3b98c2SMichael Welling TSC200X_DATA_REGS); 1466ac24381SMichael Welling if (unlikely(error)) 1476ac24381SMichael Welling goto out; 1486ac24381SMichael Welling 1496ac24381SMichael Welling /* validate position */ 1506ac24381SMichael Welling if (unlikely(tsdata.x > MAX_12BIT || tsdata.y > MAX_12BIT)) 1516ac24381SMichael Welling goto out; 1526ac24381SMichael Welling 1536ac24381SMichael Welling /* Skip reading if the pressure components are out of range */ 1546ac24381SMichael Welling if (unlikely(tsdata.z1 == 0 || tsdata.z2 > MAX_12BIT)) 1556ac24381SMichael Welling goto out; 1566ac24381SMichael Welling if (unlikely(tsdata.z1 >= tsdata.z2)) 1576ac24381SMichael Welling goto out; 1586ac24381SMichael Welling 1596ac24381SMichael Welling /* 1606ac24381SMichael Welling * Skip point if this is a pen down with the exact same values as 1616ac24381SMichael Welling * the value before pen-up - that implies SPI fed us stale data 1626ac24381SMichael Welling */ 1636ac24381SMichael Welling if (!ts->pen_down && 1646ac24381SMichael Welling ts->in_x == tsdata.x && ts->in_y == tsdata.y && 1656ac24381SMichael Welling ts->in_z1 == tsdata.z1 && ts->in_z2 == tsdata.z2) { 1666ac24381SMichael Welling goto out; 1676ac24381SMichael Welling } 1686ac24381SMichael Welling 1696ac24381SMichael Welling /* 1706ac24381SMichael Welling * At this point we are happy we have a valid and useful reading. 1716ac24381SMichael Welling * Remember it for later comparisons. We may now begin downsampling. 1726ac24381SMichael Welling */ 1736ac24381SMichael Welling ts->in_x = tsdata.x; 1746ac24381SMichael Welling ts->in_y = tsdata.y; 1756ac24381SMichael Welling ts->in_z1 = tsdata.z1; 1766ac24381SMichael Welling ts->in_z2 = tsdata.z2; 1776ac24381SMichael Welling 1786ac24381SMichael Welling /* Compute touch pressure resistance using equation #1 */ 1796ac24381SMichael Welling pressure = tsdata.x * (tsdata.z2 - tsdata.z1) / tsdata.z1; 1806ac24381SMichael Welling pressure = pressure * ts->x_plate_ohm / 4096; 1816ac24381SMichael Welling if (unlikely(pressure > MAX_12BIT)) 1826ac24381SMichael Welling goto out; 1836ac24381SMichael Welling 1846ac24381SMichael Welling spin_lock_irqsave(&ts->lock, flags); 1856ac24381SMichael Welling 186ef3b98c2SMichael Welling tsc200x_update_pen_state(ts, tsdata.x, tsdata.y, pressure); 1876ac24381SMichael Welling mod_timer(&ts->penup_timer, 188ef3b98c2SMichael Welling jiffies + msecs_to_jiffies(TSC200X_PENUP_TIME_MS)); 1896ac24381SMichael Welling 1906ac24381SMichael Welling spin_unlock_irqrestore(&ts->lock, flags); 1916ac24381SMichael Welling 1926ac24381SMichael Welling ts->last_valid_interrupt = jiffies; 1936ac24381SMichael Welling out: 1946ac24381SMichael Welling return IRQ_HANDLED; 1956ac24381SMichael Welling } 1966ac24381SMichael Welling 197ee03e3f0SKees Cook static void tsc200x_penup_timer(struct timer_list *t) 1986ac24381SMichael Welling { 199ee03e3f0SKees Cook struct tsc200x *ts = from_timer(ts, t, penup_timer); 2006ac24381SMichael Welling unsigned long flags; 2016ac24381SMichael Welling 2026ac24381SMichael Welling spin_lock_irqsave(&ts->lock, flags); 203ef3b98c2SMichael Welling tsc200x_update_pen_state(ts, 0, 0, 0); 2046ac24381SMichael Welling spin_unlock_irqrestore(&ts->lock, flags); 2056ac24381SMichael Welling } 2066ac24381SMichael Welling 207ef3b98c2SMichael Welling static void tsc200x_start_scan(struct tsc200x *ts) 2086ac24381SMichael Welling { 209ef3b98c2SMichael Welling regmap_write(ts->regmap, TSC200X_REG_CFR0, TSC200X_CFR0_INITVALUE); 210ef3b98c2SMichael Welling regmap_write(ts->regmap, TSC200X_REG_CFR1, TSC200X_CFR1_INITVALUE); 211ef3b98c2SMichael Welling regmap_write(ts->regmap, TSC200X_REG_CFR2, TSC200X_CFR2_INITVALUE); 212ef3b98c2SMichael Welling ts->tsc200x_cmd(ts->dev, TSC200X_CMD_NORMAL); 2136ac24381SMichael Welling } 2146ac24381SMichael Welling 215ef3b98c2SMichael Welling static void tsc200x_stop_scan(struct tsc200x *ts) 2166ac24381SMichael Welling { 217ef3b98c2SMichael Welling ts->tsc200x_cmd(ts->dev, TSC200X_CMD_STOP); 2186ac24381SMichael Welling } 2196ac24381SMichael Welling 220d0d89493SDmitry Torokhov static void tsc200x_reset(struct tsc200x *ts) 2216ac24381SMichael Welling { 222d0d89493SDmitry Torokhov if (ts->reset_gpio) { 223d0d89493SDmitry Torokhov gpiod_set_value_cansleep(ts->reset_gpio, 1); 224d0d89493SDmitry Torokhov usleep_range(100, 500); /* only 10us required */ 225d0d89493SDmitry Torokhov gpiod_set_value_cansleep(ts->reset_gpio, 0); 226d0d89493SDmitry Torokhov } 2276ac24381SMichael Welling } 2286ac24381SMichael Welling 2296ac24381SMichael Welling /* must be called with ts->mutex held */ 230ef3b98c2SMichael Welling static void __tsc200x_disable(struct tsc200x *ts) 2316ac24381SMichael Welling { 232ef3b98c2SMichael Welling tsc200x_stop_scan(ts); 2336ac24381SMichael Welling 2346ac24381SMichael Welling disable_irq(ts->irq); 2356ac24381SMichael Welling del_timer_sync(&ts->penup_timer); 2366ac24381SMichael Welling 2376ac24381SMichael Welling cancel_delayed_work_sync(&ts->esd_work); 2386ac24381SMichael Welling 2396ac24381SMichael Welling enable_irq(ts->irq); 2406ac24381SMichael Welling } 2416ac24381SMichael Welling 2426ac24381SMichael Welling /* must be called with ts->mutex held */ 243ef3b98c2SMichael Welling static void __tsc200x_enable(struct tsc200x *ts) 2446ac24381SMichael Welling { 245ef3b98c2SMichael Welling tsc200x_start_scan(ts); 2466ac24381SMichael Welling 247d0d89493SDmitry Torokhov if (ts->esd_timeout && ts->reset_gpio) { 2486ac24381SMichael Welling ts->last_valid_interrupt = jiffies; 2496ac24381SMichael Welling schedule_delayed_work(&ts->esd_work, 2506ac24381SMichael Welling round_jiffies_relative( 2516ac24381SMichael Welling msecs_to_jiffies(ts->esd_timeout))); 2526ac24381SMichael Welling } 2536ac24381SMichael Welling } 2546ac24381SMichael Welling 255ef3b98c2SMichael Welling static ssize_t tsc200x_selftest_show(struct device *dev, 2566ac24381SMichael Welling struct device_attribute *attr, 2576ac24381SMichael Welling char *buf) 2586ac24381SMichael Welling { 259ef3b98c2SMichael Welling struct tsc200x *ts = dev_get_drvdata(dev); 2606ac24381SMichael Welling unsigned int temp_high; 2616ac24381SMichael Welling unsigned int temp_high_orig; 2626ac24381SMichael Welling unsigned int temp_high_test; 2636ac24381SMichael Welling bool success = true; 2646ac24381SMichael Welling int error; 2656ac24381SMichael Welling 2666ac24381SMichael Welling mutex_lock(&ts->mutex); 2676ac24381SMichael Welling 2686ac24381SMichael Welling /* 269ef3b98c2SMichael Welling * Test TSC200X communications via temp high register. 2706ac24381SMichael Welling */ 271ef3b98c2SMichael Welling __tsc200x_disable(ts); 2726ac24381SMichael Welling 273ef3b98c2SMichael Welling error = regmap_read(ts->regmap, TSC200X_REG_TEMP_HIGH, &temp_high_orig); 2746ac24381SMichael Welling if (error) { 2756ac24381SMichael Welling dev_warn(dev, "selftest failed: read error %d\n", error); 2766ac24381SMichael Welling success = false; 2776ac24381SMichael Welling goto out; 2786ac24381SMichael Welling } 2796ac24381SMichael Welling 2806ac24381SMichael Welling temp_high_test = (temp_high_orig - 1) & MAX_12BIT; 2816ac24381SMichael Welling 282ef3b98c2SMichael Welling error = regmap_write(ts->regmap, TSC200X_REG_TEMP_HIGH, temp_high_test); 2836ac24381SMichael Welling if (error) { 2846ac24381SMichael Welling dev_warn(dev, "selftest failed: write error %d\n", error); 2856ac24381SMichael Welling success = false; 2866ac24381SMichael Welling goto out; 2876ac24381SMichael Welling } 2886ac24381SMichael Welling 289ef3b98c2SMichael Welling error = regmap_read(ts->regmap, TSC200X_REG_TEMP_HIGH, &temp_high); 2906ac24381SMichael Welling if (error) { 2916ac24381SMichael Welling dev_warn(dev, "selftest failed: read error %d after write\n", 2926ac24381SMichael Welling error); 2936ac24381SMichael Welling success = false; 2946ac24381SMichael Welling goto out; 2956ac24381SMichael Welling } 2966ac24381SMichael Welling 2976ac24381SMichael Welling if (temp_high != temp_high_test) { 2986ac24381SMichael Welling dev_warn(dev, "selftest failed: %d != %d\n", 2996ac24381SMichael Welling temp_high, temp_high_test); 3006ac24381SMichael Welling success = false; 3016ac24381SMichael Welling } 3026ac24381SMichael Welling 3036ac24381SMichael Welling /* hardware reset */ 304d0d89493SDmitry Torokhov tsc200x_reset(ts); 3056ac24381SMichael Welling 3066ac24381SMichael Welling if (!success) 3076ac24381SMichael Welling goto out; 3086ac24381SMichael Welling 3096ac24381SMichael Welling /* test that the reset really happened */ 310ef3b98c2SMichael Welling error = regmap_read(ts->regmap, TSC200X_REG_TEMP_HIGH, &temp_high); 3116ac24381SMichael Welling if (error) { 3126ac24381SMichael Welling dev_warn(dev, "selftest failed: read error %d after reset\n", 3136ac24381SMichael Welling error); 3146ac24381SMichael Welling success = false; 3156ac24381SMichael Welling goto out; 3166ac24381SMichael Welling } 3176ac24381SMichael Welling 3186ac24381SMichael Welling if (temp_high != temp_high_orig) { 3196ac24381SMichael Welling dev_warn(dev, "selftest failed after reset: %d != %d\n", 3206ac24381SMichael Welling temp_high, temp_high_orig); 3216ac24381SMichael Welling success = false; 3226ac24381SMichael Welling } 3236ac24381SMichael Welling 3246ac24381SMichael Welling out: 325ef3b98c2SMichael Welling __tsc200x_enable(ts); 3266ac24381SMichael Welling mutex_unlock(&ts->mutex); 3276ac24381SMichael Welling 3286ac24381SMichael Welling return sprintf(buf, "%d\n", success); 3296ac24381SMichael Welling } 3306ac24381SMichael Welling 331ef3b98c2SMichael Welling static DEVICE_ATTR(selftest, S_IRUGO, tsc200x_selftest_show, NULL); 3326ac24381SMichael Welling 333ef3b98c2SMichael Welling static struct attribute *tsc200x_attrs[] = { 3346ac24381SMichael Welling &dev_attr_selftest.attr, 3356ac24381SMichael Welling NULL 3366ac24381SMichael Welling }; 3376ac24381SMichael Welling 338ef3b98c2SMichael Welling static umode_t tsc200x_attr_is_visible(struct kobject *kobj, 3396ac24381SMichael Welling struct attribute *attr, int n) 3406ac24381SMichael Welling { 3416ac24381SMichael Welling struct device *dev = container_of(kobj, struct device, kobj); 342ef3b98c2SMichael Welling struct tsc200x *ts = dev_get_drvdata(dev); 3436ac24381SMichael Welling umode_t mode = attr->mode; 3446ac24381SMichael Welling 3456ac24381SMichael Welling if (attr == &dev_attr_selftest.attr) { 346d0d89493SDmitry Torokhov if (!ts->reset_gpio) 3476ac24381SMichael Welling mode = 0; 3486ac24381SMichael Welling } 3496ac24381SMichael Welling 3506ac24381SMichael Welling return mode; 3516ac24381SMichael Welling } 3526ac24381SMichael Welling 353ef3b98c2SMichael Welling static const struct attribute_group tsc200x_attr_group = { 354ef3b98c2SMichael Welling .is_visible = tsc200x_attr_is_visible, 355ef3b98c2SMichael Welling .attrs = tsc200x_attrs, 3566ac24381SMichael Welling }; 3576ac24381SMichael Welling 358ef3b98c2SMichael Welling static void tsc200x_esd_work(struct work_struct *work) 3596ac24381SMichael Welling { 360ef3b98c2SMichael Welling struct tsc200x *ts = container_of(work, struct tsc200x, esd_work.work); 3616ac24381SMichael Welling int error; 3626ac24381SMichael Welling unsigned int r; 3636ac24381SMichael Welling 3646ac24381SMichael Welling if (!mutex_trylock(&ts->mutex)) { 3656ac24381SMichael Welling /* 3666ac24381SMichael Welling * If the mutex is taken, it means that disable or enable is in 3676ac24381SMichael Welling * progress. In that case just reschedule the work. If the work 3686ac24381SMichael Welling * is not needed, it will be canceled by disable. 3696ac24381SMichael Welling */ 3706ac24381SMichael Welling goto reschedule; 3716ac24381SMichael Welling } 3726ac24381SMichael Welling 3736ac24381SMichael Welling if (time_is_after_jiffies(ts->last_valid_interrupt + 3746ac24381SMichael Welling msecs_to_jiffies(ts->esd_timeout))) 3756ac24381SMichael Welling goto out; 3766ac24381SMichael Welling 3776ac24381SMichael Welling /* We should be able to read register without disabling interrupts. */ 378ef3b98c2SMichael Welling error = regmap_read(ts->regmap, TSC200X_REG_CFR0, &r); 3796ac24381SMichael Welling if (!error && 380ef3b98c2SMichael Welling !((r ^ TSC200X_CFR0_INITVALUE) & TSC200X_CFR0_RW_MASK)) { 3816ac24381SMichael Welling goto out; 3826ac24381SMichael Welling } 3836ac24381SMichael Welling 3846ac24381SMichael Welling /* 3856ac24381SMichael Welling * If we could not read our known value from configuration register 0 3866ac24381SMichael Welling * then we should reset the controller as if from power-up and start 3876ac24381SMichael Welling * scanning again. 3886ac24381SMichael Welling */ 389ef3b98c2SMichael Welling dev_info(ts->dev, "TSC200X not responding - resetting\n"); 3906ac24381SMichael Welling 3916ac24381SMichael Welling disable_irq(ts->irq); 3926ac24381SMichael Welling del_timer_sync(&ts->penup_timer); 3936ac24381SMichael Welling 394ef3b98c2SMichael Welling tsc200x_update_pen_state(ts, 0, 0, 0); 3956ac24381SMichael Welling 396d0d89493SDmitry Torokhov tsc200x_reset(ts); 3976ac24381SMichael Welling 3986ac24381SMichael Welling enable_irq(ts->irq); 399ef3b98c2SMichael Welling tsc200x_start_scan(ts); 4006ac24381SMichael Welling 4016ac24381SMichael Welling out: 4026ac24381SMichael Welling mutex_unlock(&ts->mutex); 4036ac24381SMichael Welling reschedule: 4046ac24381SMichael Welling /* re-arm the watchdog */ 4056ac24381SMichael Welling schedule_delayed_work(&ts->esd_work, 4066ac24381SMichael Welling round_jiffies_relative( 4076ac24381SMichael Welling msecs_to_jiffies(ts->esd_timeout))); 4086ac24381SMichael Welling } 4096ac24381SMichael Welling 410ef3b98c2SMichael Welling static int tsc200x_open(struct input_dev *input) 4116ac24381SMichael Welling { 412ef3b98c2SMichael Welling struct tsc200x *ts = input_get_drvdata(input); 4136ac24381SMichael Welling 4146ac24381SMichael Welling mutex_lock(&ts->mutex); 4156ac24381SMichael Welling 4166ac24381SMichael Welling if (!ts->suspended) 417ef3b98c2SMichael Welling __tsc200x_enable(ts); 4186ac24381SMichael Welling 4196ac24381SMichael Welling ts->opened = true; 4206ac24381SMichael Welling 4216ac24381SMichael Welling mutex_unlock(&ts->mutex); 4226ac24381SMichael Welling 4236ac24381SMichael Welling return 0; 4246ac24381SMichael Welling } 4256ac24381SMichael Welling 426ef3b98c2SMichael Welling static void tsc200x_close(struct input_dev *input) 4276ac24381SMichael Welling { 428ef3b98c2SMichael Welling struct tsc200x *ts = input_get_drvdata(input); 4296ac24381SMichael Welling 4306ac24381SMichael Welling mutex_lock(&ts->mutex); 4316ac24381SMichael Welling 4326ac24381SMichael Welling if (!ts->suspended) 433ef3b98c2SMichael Welling __tsc200x_disable(ts); 4346ac24381SMichael Welling 4356ac24381SMichael Welling ts->opened = false; 4366ac24381SMichael Welling 4376ac24381SMichael Welling mutex_unlock(&ts->mutex); 4386ac24381SMichael Welling } 4396ac24381SMichael Welling 440e9003c9cSMichael Welling int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id, 4416ac24381SMichael Welling struct regmap *regmap, 4426ac24381SMichael Welling int (*tsc200x_cmd)(struct device *dev, u8 cmd)) 4436ac24381SMichael Welling { 444ef3b98c2SMichael Welling struct tsc200x *ts; 4456ac24381SMichael Welling struct input_dev *input_dev; 446d0d89493SDmitry Torokhov u32 x_plate_ohm; 447d0d89493SDmitry Torokhov u32 esd_timeout; 4486ac24381SMichael Welling int error; 4496ac24381SMichael Welling 4506ac24381SMichael Welling if (irq <= 0) { 4516ac24381SMichael Welling dev_err(dev, "no irq\n"); 4526ac24381SMichael Welling return -ENODEV; 4536ac24381SMichael Welling } 4546ac24381SMichael Welling 4556ac24381SMichael Welling if (IS_ERR(regmap)) 4566ac24381SMichael Welling return PTR_ERR(regmap); 4576ac24381SMichael Welling 4586ac24381SMichael Welling if (!tsc200x_cmd) { 4596ac24381SMichael Welling dev_err(dev, "no cmd function\n"); 4606ac24381SMichael Welling return -ENODEV; 4616ac24381SMichael Welling } 4626ac24381SMichael Welling 4636ac24381SMichael Welling ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL); 4646ac24381SMichael Welling if (!ts) 4656ac24381SMichael Welling return -ENOMEM; 4666ac24381SMichael Welling 4676ac24381SMichael Welling input_dev = devm_input_allocate_device(dev); 4686ac24381SMichael Welling if (!input_dev) 4696ac24381SMichael Welling return -ENOMEM; 4706ac24381SMichael Welling 4716ac24381SMichael Welling ts->irq = irq; 4726ac24381SMichael Welling ts->dev = dev; 4736ac24381SMichael Welling ts->idev = input_dev; 4746ac24381SMichael Welling ts->regmap = regmap; 4756ac24381SMichael Welling ts->tsc200x_cmd = tsc200x_cmd; 476d0d89493SDmitry Torokhov 477d0d89493SDmitry Torokhov error = device_property_read_u32(dev, "ti,x-plate-ohms", &x_plate_ohm); 478d0d89493SDmitry Torokhov ts->x_plate_ohm = error ? TSC200X_DEF_RESISTOR : x_plate_ohm; 479d0d89493SDmitry Torokhov 480d0d89493SDmitry Torokhov error = device_property_read_u32(dev, "ti,esd-recovery-timeout-ms", 481d0d89493SDmitry Torokhov &esd_timeout); 482d0d89493SDmitry Torokhov ts->esd_timeout = error ? 0 : esd_timeout; 4836ac24381SMichael Welling 4846ac24381SMichael Welling ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); 4856ac24381SMichael Welling if (IS_ERR(ts->reset_gpio)) { 4866ac24381SMichael Welling error = PTR_ERR(ts->reset_gpio); 4876ac24381SMichael Welling dev_err(dev, "error acquiring reset gpio: %d\n", error); 4886ac24381SMichael Welling return error; 4896ac24381SMichael Welling } 4906ac24381SMichael Welling 491f7bf6f58SDmitry Torokhov ts->vio = devm_regulator_get(dev, "vio"); 4926ac24381SMichael Welling if (IS_ERR(ts->vio)) { 4936ac24381SMichael Welling error = PTR_ERR(ts->vio); 494f7bf6f58SDmitry Torokhov dev_err(dev, "error acquiring vio regulator: %d", error); 4956ac24381SMichael Welling return error; 4966ac24381SMichael Welling } 4976ac24381SMichael Welling 4986ac24381SMichael Welling mutex_init(&ts->mutex); 4996ac24381SMichael Welling 5006ac24381SMichael Welling spin_lock_init(&ts->lock); 501ee03e3f0SKees Cook timer_setup(&ts->penup_timer, tsc200x_penup_timer, 0); 5026ac24381SMichael Welling 503ef3b98c2SMichael Welling INIT_DELAYED_WORK(&ts->esd_work, tsc200x_esd_work); 5046ac24381SMichael Welling 5056ac24381SMichael Welling snprintf(ts->phys, sizeof(ts->phys), 5066ac24381SMichael Welling "%s/input-ts", dev_name(dev)); 5076ac24381SMichael Welling 508e9003c9cSMichael Welling if (tsc_id->product == 2004) { 509ef3b98c2SMichael Welling input_dev->name = "TSC200X touchscreen"; 510e9003c9cSMichael Welling } else { 511e9003c9cSMichael Welling input_dev->name = devm_kasprintf(dev, GFP_KERNEL, 512e9003c9cSMichael Welling "TSC%04d touchscreen", 513e9003c9cSMichael Welling tsc_id->product); 514e9003c9cSMichael Welling if (!input_dev->name) 515e9003c9cSMichael Welling return -ENOMEM; 516e9003c9cSMichael Welling } 517e9003c9cSMichael Welling 5186ac24381SMichael Welling input_dev->phys = ts->phys; 519e9003c9cSMichael Welling input_dev->id = *tsc_id; 5206ac24381SMichael Welling 521ef3b98c2SMichael Welling input_dev->open = tsc200x_open; 522ef3b98c2SMichael Welling input_dev->close = tsc200x_close; 5236ac24381SMichael Welling 5246ac24381SMichael Welling input_set_drvdata(input_dev, ts); 5256ac24381SMichael Welling 526eca25391SMartin Kepplinger __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); 527d0d89493SDmitry Torokhov input_set_capability(input_dev, EV_KEY, BTN_TOUCH); 528d0d89493SDmitry Torokhov 529d0d89493SDmitry Torokhov input_set_abs_params(input_dev, ABS_X, 530d0d89493SDmitry Torokhov 0, MAX_12BIT, TSC200X_DEF_X_FUZZ, 0); 531d0d89493SDmitry Torokhov input_set_abs_params(input_dev, ABS_Y, 532d0d89493SDmitry Torokhov 0, MAX_12BIT, TSC200X_DEF_Y_FUZZ, 0); 533d0d89493SDmitry Torokhov input_set_abs_params(input_dev, ABS_PRESSURE, 534d0d89493SDmitry Torokhov 0, MAX_12BIT, TSC200X_DEF_P_FUZZ, 0); 535d0d89493SDmitry Torokhov 536d0d89493SDmitry Torokhov touchscreen_parse_properties(input_dev, false, NULL); 537d0d89493SDmitry Torokhov 5386ac24381SMichael Welling /* Ensure the touchscreen is off */ 539ef3b98c2SMichael Welling tsc200x_stop_scan(ts); 5406ac24381SMichael Welling 5416ac24381SMichael Welling error = devm_request_threaded_irq(dev, irq, NULL, 542ef3b98c2SMichael Welling tsc200x_irq_thread, 5436ac24381SMichael Welling IRQF_TRIGGER_RISING | IRQF_ONESHOT, 544ef3b98c2SMichael Welling "tsc200x", ts); 5456ac24381SMichael Welling if (error) { 5466ac24381SMichael Welling dev_err(dev, "Failed to request irq, err: %d\n", error); 5476ac24381SMichael Welling return error; 5486ac24381SMichael Welling } 5496ac24381SMichael Welling 5506ac24381SMichael Welling error = regulator_enable(ts->vio); 5516ac24381SMichael Welling if (error) 5526ac24381SMichael Welling return error; 5536ac24381SMichael Welling 5546ac24381SMichael Welling dev_set_drvdata(dev, ts); 555ef3b98c2SMichael Welling error = sysfs_create_group(&dev->kobj, &tsc200x_attr_group); 5566ac24381SMichael Welling if (error) { 5576ac24381SMichael Welling dev_err(dev, 5586ac24381SMichael Welling "Failed to create sysfs attributes, err: %d\n", error); 5596ac24381SMichael Welling goto disable_regulator; 5606ac24381SMichael Welling } 5616ac24381SMichael Welling 5626ac24381SMichael Welling error = input_register_device(ts->idev); 5636ac24381SMichael Welling if (error) { 5646ac24381SMichael Welling dev_err(dev, 5656ac24381SMichael Welling "Failed to register input device, err: %d\n", error); 5666ac24381SMichael Welling goto err_remove_sysfs; 5676ac24381SMichael Welling } 5686ac24381SMichael Welling 5696ac24381SMichael Welling irq_set_irq_wake(irq, 1); 5706ac24381SMichael Welling return 0; 5716ac24381SMichael Welling 5726ac24381SMichael Welling err_remove_sysfs: 573ef3b98c2SMichael Welling sysfs_remove_group(&dev->kobj, &tsc200x_attr_group); 5746ac24381SMichael Welling disable_regulator: 5756ac24381SMichael Welling regulator_disable(ts->vio); 5766ac24381SMichael Welling return error; 5776ac24381SMichael Welling } 5786ac24381SMichael Welling EXPORT_SYMBOL_GPL(tsc200x_probe); 5796ac24381SMichael Welling 5806ac24381SMichael Welling int tsc200x_remove(struct device *dev) 5816ac24381SMichael Welling { 582ef3b98c2SMichael Welling struct tsc200x *ts = dev_get_drvdata(dev); 5836ac24381SMichael Welling 584ef3b98c2SMichael Welling sysfs_remove_group(&dev->kobj, &tsc200x_attr_group); 5856ac24381SMichael Welling 5866ac24381SMichael Welling regulator_disable(ts->vio); 5876ac24381SMichael Welling 5886ac24381SMichael Welling return 0; 5896ac24381SMichael Welling } 5906ac24381SMichael Welling EXPORT_SYMBOL_GPL(tsc200x_remove); 5916ac24381SMichael Welling 592ef3b98c2SMichael Welling static int __maybe_unused tsc200x_suspend(struct device *dev) 5936ac24381SMichael Welling { 594ef3b98c2SMichael Welling struct tsc200x *ts = dev_get_drvdata(dev); 5956ac24381SMichael Welling 5966ac24381SMichael Welling mutex_lock(&ts->mutex); 5976ac24381SMichael Welling 5986ac24381SMichael Welling if (!ts->suspended && ts->opened) 599ef3b98c2SMichael Welling __tsc200x_disable(ts); 6006ac24381SMichael Welling 6016ac24381SMichael Welling ts->suspended = true; 6026ac24381SMichael Welling 6036ac24381SMichael Welling mutex_unlock(&ts->mutex); 6046ac24381SMichael Welling 6056ac24381SMichael Welling return 0; 6066ac24381SMichael Welling } 6076ac24381SMichael Welling 608ef3b98c2SMichael Welling static int __maybe_unused tsc200x_resume(struct device *dev) 6096ac24381SMichael Welling { 610ef3b98c2SMichael Welling struct tsc200x *ts = dev_get_drvdata(dev); 6116ac24381SMichael Welling 6126ac24381SMichael Welling mutex_lock(&ts->mutex); 6136ac24381SMichael Welling 6146ac24381SMichael Welling if (ts->suspended && ts->opened) 615ef3b98c2SMichael Welling __tsc200x_enable(ts); 6166ac24381SMichael Welling 6176ac24381SMichael Welling ts->suspended = false; 6186ac24381SMichael Welling 6196ac24381SMichael Welling mutex_unlock(&ts->mutex); 6206ac24381SMichael Welling 6216ac24381SMichael Welling return 0; 6226ac24381SMichael Welling } 6236ac24381SMichael Welling 624ef3b98c2SMichael Welling SIMPLE_DEV_PM_OPS(tsc200x_pm_ops, tsc200x_suspend, tsc200x_resume); 6256ac24381SMichael Welling EXPORT_SYMBOL_GPL(tsc200x_pm_ops); 6266ac24381SMichael Welling 6276ac24381SMichael Welling MODULE_AUTHOR("Lauri Leukkunen <lauri.leukkunen@nokia.com>"); 628ef3b98c2SMichael Welling MODULE_DESCRIPTION("TSC200x Touchscreen Driver Core"); 6296ac24381SMichael Welling MODULE_LICENSE("GPL"); 630