18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * STMicroelectronics STMPE811 Touchscreen Driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * (C) 2010 Luotao Fu <l.fu@pengutronix.de> 68c2ecf20Sopenharmony_ci * All rights reserved. 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/kernel.h> 108c2ecf20Sopenharmony_ci#include <linux/module.h> 118c2ecf20Sopenharmony_ci#include <linux/sched.h> 128c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 138c2ecf20Sopenharmony_ci#include <linux/device.h> 148c2ecf20Sopenharmony_ci#include <linux/of.h> 158c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 168c2ecf20Sopenharmony_ci#include <linux/input.h> 178c2ecf20Sopenharmony_ci#include <linux/slab.h> 188c2ecf20Sopenharmony_ci#include <linux/delay.h> 198c2ecf20Sopenharmony_ci#include <linux/i2c.h> 208c2ecf20Sopenharmony_ci#include <linux/workqueue.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#include <linux/mfd/stmpe.h> 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci/* Register layouts and functionalities are identical on all stmpexxx variants 258c2ecf20Sopenharmony_ci * with touchscreen controller 268c2ecf20Sopenharmony_ci */ 278c2ecf20Sopenharmony_ci#define STMPE_REG_INT_STA 0x0B 288c2ecf20Sopenharmony_ci#define STMPE_REG_TSC_CTRL 0x40 298c2ecf20Sopenharmony_ci#define STMPE_REG_TSC_CFG 0x41 308c2ecf20Sopenharmony_ci#define STMPE_REG_FIFO_TH 0x4A 318c2ecf20Sopenharmony_ci#define STMPE_REG_FIFO_STA 0x4B 328c2ecf20Sopenharmony_ci#define STMPE_REG_FIFO_SIZE 0x4C 338c2ecf20Sopenharmony_ci#define STMPE_REG_TSC_DATA_XYZ 0x52 348c2ecf20Sopenharmony_ci#define STMPE_REG_TSC_FRACTION_Z 0x56 358c2ecf20Sopenharmony_ci#define STMPE_REG_TSC_I_DRIVE 0x58 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#define OP_MOD_XYZ 0 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#define STMPE_TSC_CTRL_TSC_EN (1<<0) 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci#define STMPE_FIFO_STA_RESET (1<<0) 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#define STMPE_IRQ_TOUCH_DET 0 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci#define STMPE_TS_NAME "stmpe-ts" 468c2ecf20Sopenharmony_ci#define XY_MASK 0xfff 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci/** 498c2ecf20Sopenharmony_ci * struct stmpe_touch - stmpe811 touch screen controller state 508c2ecf20Sopenharmony_ci * @stmpe: pointer back to STMPE MFD container 518c2ecf20Sopenharmony_ci * @idev: registered input device 528c2ecf20Sopenharmony_ci * @work: a work item used to scan the device 538c2ecf20Sopenharmony_ci * @dev: a pointer back to the MFD cell struct device* 548c2ecf20Sopenharmony_ci * @ave_ctrl: Sample average control 558c2ecf20Sopenharmony_ci * (0 -> 1 sample, 1 -> 2 samples, 2 -> 4 samples, 3 -> 8 samples) 568c2ecf20Sopenharmony_ci * @touch_det_delay: Touch detect interrupt delay 578c2ecf20Sopenharmony_ci * (0 -> 10 us, 1 -> 50 us, 2 -> 100 us, 3 -> 500 us, 588c2ecf20Sopenharmony_ci * 4-> 1 ms, 5 -> 5 ms, 6 -> 10 ms, 7 -> 50 ms) 598c2ecf20Sopenharmony_ci * recommended is 3 608c2ecf20Sopenharmony_ci * @settling: Panel driver settling time 618c2ecf20Sopenharmony_ci * (0 -> 10 us, 1 -> 100 us, 2 -> 500 us, 3 -> 1 ms, 628c2ecf20Sopenharmony_ci * 4 -> 5 ms, 5 -> 10 ms, 6 for 50 ms, 7 -> 100 ms) 638c2ecf20Sopenharmony_ci * recommended is 2 648c2ecf20Sopenharmony_ci * @fraction_z: Length of the fractional part in z 658c2ecf20Sopenharmony_ci * (fraction_z ([0..7]) = Count of the fractional part) 668c2ecf20Sopenharmony_ci * recommended is 7 678c2ecf20Sopenharmony_ci * @i_drive: current limit value of the touchscreen drivers 688c2ecf20Sopenharmony_ci * (0 -> 20 mA typical 35 mA max, 1 -> 50 mA typical 80 mA max) 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_cistruct stmpe_touch { 718c2ecf20Sopenharmony_ci struct stmpe *stmpe; 728c2ecf20Sopenharmony_ci struct input_dev *idev; 738c2ecf20Sopenharmony_ci struct delayed_work work; 748c2ecf20Sopenharmony_ci struct device *dev; 758c2ecf20Sopenharmony_ci u8 ave_ctrl; 768c2ecf20Sopenharmony_ci u8 touch_det_delay; 778c2ecf20Sopenharmony_ci u8 settling; 788c2ecf20Sopenharmony_ci u8 fraction_z; 798c2ecf20Sopenharmony_ci u8 i_drive; 808c2ecf20Sopenharmony_ci}; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_cistatic int __stmpe_reset_fifo(struct stmpe *stmpe) 838c2ecf20Sopenharmony_ci{ 848c2ecf20Sopenharmony_ci int ret; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci ret = stmpe_set_bits(stmpe, STMPE_REG_FIFO_STA, 878c2ecf20Sopenharmony_ci STMPE_FIFO_STA_RESET, STMPE_FIFO_STA_RESET); 888c2ecf20Sopenharmony_ci if (ret) 898c2ecf20Sopenharmony_ci return ret; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci return stmpe_set_bits(stmpe, STMPE_REG_FIFO_STA, 928c2ecf20Sopenharmony_ci STMPE_FIFO_STA_RESET, 0); 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_cistatic void stmpe_work(struct work_struct *work) 968c2ecf20Sopenharmony_ci{ 978c2ecf20Sopenharmony_ci int int_sta; 988c2ecf20Sopenharmony_ci u32 timeout = 40; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci struct stmpe_touch *ts = 1018c2ecf20Sopenharmony_ci container_of(work, struct stmpe_touch, work.work); 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci int_sta = stmpe_reg_read(ts->stmpe, STMPE_REG_INT_STA); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci /* 1068c2ecf20Sopenharmony_ci * touch_det sometimes get desasserted or just get stuck. This appears 1078c2ecf20Sopenharmony_ci * to be a silicon bug, We still have to clearify this with the 1088c2ecf20Sopenharmony_ci * manufacture. As a workaround We release the key anyway if the 1098c2ecf20Sopenharmony_ci * touch_det keeps coming in after 4ms, while the FIFO contains no value 1108c2ecf20Sopenharmony_ci * during the whole time. 1118c2ecf20Sopenharmony_ci */ 1128c2ecf20Sopenharmony_ci while ((int_sta & (1 << STMPE_IRQ_TOUCH_DET)) && (timeout > 0)) { 1138c2ecf20Sopenharmony_ci timeout--; 1148c2ecf20Sopenharmony_ci int_sta = stmpe_reg_read(ts->stmpe, STMPE_REG_INT_STA); 1158c2ecf20Sopenharmony_ci udelay(100); 1168c2ecf20Sopenharmony_ci } 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci /* reset the FIFO before we report release event */ 1198c2ecf20Sopenharmony_ci __stmpe_reset_fifo(ts->stmpe); 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci input_report_abs(ts->idev, ABS_PRESSURE, 0); 1228c2ecf20Sopenharmony_ci input_report_key(ts->idev, BTN_TOUCH, 0); 1238c2ecf20Sopenharmony_ci input_sync(ts->idev); 1248c2ecf20Sopenharmony_ci} 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic irqreturn_t stmpe_ts_handler(int irq, void *data) 1278c2ecf20Sopenharmony_ci{ 1288c2ecf20Sopenharmony_ci u8 data_set[4]; 1298c2ecf20Sopenharmony_ci int x, y, z; 1308c2ecf20Sopenharmony_ci struct stmpe_touch *ts = data; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci /* 1338c2ecf20Sopenharmony_ci * Cancel scheduled polling for release if we have new value 1348c2ecf20Sopenharmony_ci * available. Wait if the polling is already running. 1358c2ecf20Sopenharmony_ci */ 1368c2ecf20Sopenharmony_ci cancel_delayed_work_sync(&ts->work); 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci /* 1398c2ecf20Sopenharmony_ci * The FIFO sometimes just crashes and stops generating interrupts. This 1408c2ecf20Sopenharmony_ci * appears to be a silicon bug. We still have to clearify this with 1418c2ecf20Sopenharmony_ci * the manufacture. As a workaround we disable the TSC while we are 1428c2ecf20Sopenharmony_ci * collecting data and flush the FIFO after reading 1438c2ecf20Sopenharmony_ci */ 1448c2ecf20Sopenharmony_ci stmpe_set_bits(ts->stmpe, STMPE_REG_TSC_CTRL, 1458c2ecf20Sopenharmony_ci STMPE_TSC_CTRL_TSC_EN, 0); 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci stmpe_block_read(ts->stmpe, STMPE_REG_TSC_DATA_XYZ, 4, data_set); 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci x = (data_set[0] << 4) | (data_set[1] >> 4); 1508c2ecf20Sopenharmony_ci y = ((data_set[1] & 0xf) << 8) | data_set[2]; 1518c2ecf20Sopenharmony_ci z = data_set[3]; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci input_report_abs(ts->idev, ABS_X, x); 1548c2ecf20Sopenharmony_ci input_report_abs(ts->idev, ABS_Y, y); 1558c2ecf20Sopenharmony_ci input_report_abs(ts->idev, ABS_PRESSURE, z); 1568c2ecf20Sopenharmony_ci input_report_key(ts->idev, BTN_TOUCH, 1); 1578c2ecf20Sopenharmony_ci input_sync(ts->idev); 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci /* flush the FIFO after we have read out our values. */ 1608c2ecf20Sopenharmony_ci __stmpe_reset_fifo(ts->stmpe); 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci /* reenable the tsc */ 1638c2ecf20Sopenharmony_ci stmpe_set_bits(ts->stmpe, STMPE_REG_TSC_CTRL, 1648c2ecf20Sopenharmony_ci STMPE_TSC_CTRL_TSC_EN, STMPE_TSC_CTRL_TSC_EN); 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci /* start polling for touch_det to detect release */ 1678c2ecf20Sopenharmony_ci schedule_delayed_work(&ts->work, msecs_to_jiffies(50)); 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci return IRQ_HANDLED; 1708c2ecf20Sopenharmony_ci} 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_cistatic int stmpe_init_hw(struct stmpe_touch *ts) 1738c2ecf20Sopenharmony_ci{ 1748c2ecf20Sopenharmony_ci int ret; 1758c2ecf20Sopenharmony_ci u8 tsc_cfg, tsc_cfg_mask; 1768c2ecf20Sopenharmony_ci struct stmpe *stmpe = ts->stmpe; 1778c2ecf20Sopenharmony_ci struct device *dev = ts->dev; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci ret = stmpe_enable(stmpe, STMPE_BLOCK_TOUCHSCREEN | STMPE_BLOCK_ADC); 1808c2ecf20Sopenharmony_ci if (ret) { 1818c2ecf20Sopenharmony_ci dev_err(dev, "Could not enable clock for ADC and TS\n"); 1828c2ecf20Sopenharmony_ci return ret; 1838c2ecf20Sopenharmony_ci } 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci ret = stmpe811_adc_common_init(stmpe); 1868c2ecf20Sopenharmony_ci if (ret) { 1878c2ecf20Sopenharmony_ci stmpe_disable(stmpe, STMPE_BLOCK_TOUCHSCREEN | STMPE_BLOCK_ADC); 1888c2ecf20Sopenharmony_ci return ret; 1898c2ecf20Sopenharmony_ci } 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci tsc_cfg = STMPE_AVE_CTRL(ts->ave_ctrl) | 1928c2ecf20Sopenharmony_ci STMPE_DET_DELAY(ts->touch_det_delay) | 1938c2ecf20Sopenharmony_ci STMPE_SETTLING(ts->settling); 1948c2ecf20Sopenharmony_ci tsc_cfg_mask = STMPE_AVE_CTRL(0xff) | STMPE_DET_DELAY(0xff) | 1958c2ecf20Sopenharmony_ci STMPE_SETTLING(0xff); 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci ret = stmpe_set_bits(stmpe, STMPE_REG_TSC_CFG, tsc_cfg_mask, tsc_cfg); 1988c2ecf20Sopenharmony_ci if (ret) { 1998c2ecf20Sopenharmony_ci dev_err(dev, "Could not config touch\n"); 2008c2ecf20Sopenharmony_ci return ret; 2018c2ecf20Sopenharmony_ci } 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci ret = stmpe_set_bits(stmpe, STMPE_REG_TSC_FRACTION_Z, 2048c2ecf20Sopenharmony_ci STMPE_FRACTION_Z(0xff), STMPE_FRACTION_Z(ts->fraction_z)); 2058c2ecf20Sopenharmony_ci if (ret) { 2068c2ecf20Sopenharmony_ci dev_err(dev, "Could not config touch\n"); 2078c2ecf20Sopenharmony_ci return ret; 2088c2ecf20Sopenharmony_ci } 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci ret = stmpe_set_bits(stmpe, STMPE_REG_TSC_I_DRIVE, 2118c2ecf20Sopenharmony_ci STMPE_I_DRIVE(0xff), STMPE_I_DRIVE(ts->i_drive)); 2128c2ecf20Sopenharmony_ci if (ret) { 2138c2ecf20Sopenharmony_ci dev_err(dev, "Could not config touch\n"); 2148c2ecf20Sopenharmony_ci return ret; 2158c2ecf20Sopenharmony_ci } 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci /* set FIFO to 1 for single point reading */ 2188c2ecf20Sopenharmony_ci ret = stmpe_reg_write(stmpe, STMPE_REG_FIFO_TH, 1); 2198c2ecf20Sopenharmony_ci if (ret) { 2208c2ecf20Sopenharmony_ci dev_err(dev, "Could not set FIFO\n"); 2218c2ecf20Sopenharmony_ci return ret; 2228c2ecf20Sopenharmony_ci } 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci ret = stmpe_set_bits(stmpe, STMPE_REG_TSC_CTRL, 2258c2ecf20Sopenharmony_ci STMPE_OP_MODE(0xff), STMPE_OP_MODE(OP_MOD_XYZ)); 2268c2ecf20Sopenharmony_ci if (ret) { 2278c2ecf20Sopenharmony_ci dev_err(dev, "Could not set mode\n"); 2288c2ecf20Sopenharmony_ci return ret; 2298c2ecf20Sopenharmony_ci } 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci return 0; 2328c2ecf20Sopenharmony_ci} 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_cistatic int stmpe_ts_open(struct input_dev *dev) 2358c2ecf20Sopenharmony_ci{ 2368c2ecf20Sopenharmony_ci struct stmpe_touch *ts = input_get_drvdata(dev); 2378c2ecf20Sopenharmony_ci int ret = 0; 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci ret = __stmpe_reset_fifo(ts->stmpe); 2408c2ecf20Sopenharmony_ci if (ret) 2418c2ecf20Sopenharmony_ci return ret; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci return stmpe_set_bits(ts->stmpe, STMPE_REG_TSC_CTRL, 2448c2ecf20Sopenharmony_ci STMPE_TSC_CTRL_TSC_EN, STMPE_TSC_CTRL_TSC_EN); 2458c2ecf20Sopenharmony_ci} 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_cistatic void stmpe_ts_close(struct input_dev *dev) 2488c2ecf20Sopenharmony_ci{ 2498c2ecf20Sopenharmony_ci struct stmpe_touch *ts = input_get_drvdata(dev); 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci cancel_delayed_work_sync(&ts->work); 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci stmpe_set_bits(ts->stmpe, STMPE_REG_TSC_CTRL, 2548c2ecf20Sopenharmony_ci STMPE_TSC_CTRL_TSC_EN, 0); 2558c2ecf20Sopenharmony_ci} 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_cistatic void stmpe_ts_get_platform_info(struct platform_device *pdev, 2588c2ecf20Sopenharmony_ci struct stmpe_touch *ts) 2598c2ecf20Sopenharmony_ci{ 2608c2ecf20Sopenharmony_ci struct device_node *np = pdev->dev.of_node; 2618c2ecf20Sopenharmony_ci u32 val; 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci if (np) { 2648c2ecf20Sopenharmony_ci if (!of_property_read_u32(np, "st,sample-time", &val)) 2658c2ecf20Sopenharmony_ci ts->stmpe->sample_time = val; 2668c2ecf20Sopenharmony_ci if (!of_property_read_u32(np, "st,mod-12b", &val)) 2678c2ecf20Sopenharmony_ci ts->stmpe->mod_12b = val; 2688c2ecf20Sopenharmony_ci if (!of_property_read_u32(np, "st,ref-sel", &val)) 2698c2ecf20Sopenharmony_ci ts->stmpe->ref_sel = val; 2708c2ecf20Sopenharmony_ci if (!of_property_read_u32(np, "st,adc-freq", &val)) 2718c2ecf20Sopenharmony_ci ts->stmpe->adc_freq = val; 2728c2ecf20Sopenharmony_ci if (!of_property_read_u32(np, "st,ave-ctrl", &val)) 2738c2ecf20Sopenharmony_ci ts->ave_ctrl = val; 2748c2ecf20Sopenharmony_ci if (!of_property_read_u32(np, "st,touch-det-delay", &val)) 2758c2ecf20Sopenharmony_ci ts->touch_det_delay = val; 2768c2ecf20Sopenharmony_ci if (!of_property_read_u32(np, "st,settling", &val)) 2778c2ecf20Sopenharmony_ci ts->settling = val; 2788c2ecf20Sopenharmony_ci if (!of_property_read_u32(np, "st,fraction-z", &val)) 2798c2ecf20Sopenharmony_ci ts->fraction_z = val; 2808c2ecf20Sopenharmony_ci if (!of_property_read_u32(np, "st,i-drive", &val)) 2818c2ecf20Sopenharmony_ci ts->i_drive = val; 2828c2ecf20Sopenharmony_ci } 2838c2ecf20Sopenharmony_ci} 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_cistatic int stmpe_input_probe(struct platform_device *pdev) 2868c2ecf20Sopenharmony_ci{ 2878c2ecf20Sopenharmony_ci struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); 2888c2ecf20Sopenharmony_ci struct stmpe_touch *ts; 2898c2ecf20Sopenharmony_ci struct input_dev *idev; 2908c2ecf20Sopenharmony_ci int error; 2918c2ecf20Sopenharmony_ci int ts_irq; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci ts_irq = platform_get_irq_byname(pdev, "FIFO_TH"); 2948c2ecf20Sopenharmony_ci if (ts_irq < 0) 2958c2ecf20Sopenharmony_ci return ts_irq; 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci ts = devm_kzalloc(&pdev->dev, sizeof(*ts), GFP_KERNEL); 2988c2ecf20Sopenharmony_ci if (!ts) 2998c2ecf20Sopenharmony_ci return -ENOMEM; 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci idev = devm_input_allocate_device(&pdev->dev); 3028c2ecf20Sopenharmony_ci if (!idev) 3038c2ecf20Sopenharmony_ci return -ENOMEM; 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci platform_set_drvdata(pdev, ts); 3068c2ecf20Sopenharmony_ci ts->stmpe = stmpe; 3078c2ecf20Sopenharmony_ci ts->idev = idev; 3088c2ecf20Sopenharmony_ci ts->dev = &pdev->dev; 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci stmpe_ts_get_platform_info(pdev, ts); 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci INIT_DELAYED_WORK(&ts->work, stmpe_work); 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci error = devm_request_threaded_irq(&pdev->dev, ts_irq, 3158c2ecf20Sopenharmony_ci NULL, stmpe_ts_handler, 3168c2ecf20Sopenharmony_ci IRQF_ONESHOT, STMPE_TS_NAME, ts); 3178c2ecf20Sopenharmony_ci if (error) { 3188c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "Failed to request IRQ %d\n", ts_irq); 3198c2ecf20Sopenharmony_ci return error; 3208c2ecf20Sopenharmony_ci } 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci error = stmpe_init_hw(ts); 3238c2ecf20Sopenharmony_ci if (error) 3248c2ecf20Sopenharmony_ci return error; 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci idev->name = STMPE_TS_NAME; 3278c2ecf20Sopenharmony_ci idev->phys = STMPE_TS_NAME"/input0"; 3288c2ecf20Sopenharmony_ci idev->id.bustype = BUS_I2C; 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci idev->open = stmpe_ts_open; 3318c2ecf20Sopenharmony_ci idev->close = stmpe_ts_close; 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci input_set_drvdata(idev, ts); 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci input_set_capability(idev, EV_KEY, BTN_TOUCH); 3368c2ecf20Sopenharmony_ci input_set_abs_params(idev, ABS_X, 0, XY_MASK, 0, 0); 3378c2ecf20Sopenharmony_ci input_set_abs_params(idev, ABS_Y, 0, XY_MASK, 0, 0); 3388c2ecf20Sopenharmony_ci input_set_abs_params(idev, ABS_PRESSURE, 0x0, 0xff, 0, 0); 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci error = input_register_device(idev); 3418c2ecf20Sopenharmony_ci if (error) { 3428c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "Could not register input device\n"); 3438c2ecf20Sopenharmony_ci return error; 3448c2ecf20Sopenharmony_ci } 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci return 0; 3478c2ecf20Sopenharmony_ci} 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_cistatic int stmpe_ts_remove(struct platform_device *pdev) 3508c2ecf20Sopenharmony_ci{ 3518c2ecf20Sopenharmony_ci struct stmpe_touch *ts = platform_get_drvdata(pdev); 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ci stmpe_disable(ts->stmpe, STMPE_BLOCK_TOUCHSCREEN); 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci return 0; 3568c2ecf20Sopenharmony_ci} 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_cistatic struct platform_driver stmpe_ts_driver = { 3598c2ecf20Sopenharmony_ci .driver = { 3608c2ecf20Sopenharmony_ci .name = STMPE_TS_NAME, 3618c2ecf20Sopenharmony_ci }, 3628c2ecf20Sopenharmony_ci .probe = stmpe_input_probe, 3638c2ecf20Sopenharmony_ci .remove = stmpe_ts_remove, 3648c2ecf20Sopenharmony_ci}; 3658c2ecf20Sopenharmony_cimodule_platform_driver(stmpe_ts_driver); 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_cistatic const struct of_device_id stmpe_ts_ids[] = { 3688c2ecf20Sopenharmony_ci { .compatible = "st,stmpe-ts", }, 3698c2ecf20Sopenharmony_ci { }, 3708c2ecf20Sopenharmony_ci}; 3718c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, stmpe_ts_ids); 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ciMODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>"); 3748c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("STMPEXXX touchscreen driver"); 3758c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 376