1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Driver for Motorola PCAP2 touchscreen as found in the EZX phone platform. 4 * 5 * Copyright (C) 2006 Harald Welte <laforge@openezx.org> 6 * Copyright (C) 2009 Daniel Ribeiro <drwyrm@gmail.com> 7 */ 8 9 #include <linux/module.h> 10 #include <linux/fs.h> 11 #include <linux/string.h> 12 #include <linux/slab.h> 13 #include <linux/pm.h> 14 #include <linux/timer.h> 15 #include <linux/interrupt.h> 16 #include <linux/platform_device.h> 17 #include <linux/input.h> 18 #include <linux/mfd/ezx-pcap.h> 19 20 struct pcap_ts { 21 struct pcap_chip *pcap; 22 struct input_dev *input; 23 struct delayed_work work; 24 u16 x, y; 25 u16 pressure; 26 u8 read_state; 27 }; 28 29 #define SAMPLE_DELAY 20 /* msecs */ 30 31 #define X_AXIS_MIN 0 32 #define X_AXIS_MAX 1023 33 #define Y_AXIS_MAX X_AXIS_MAX 34 #define Y_AXIS_MIN X_AXIS_MIN 35 #define PRESSURE_MAX X_AXIS_MAX 36 #define PRESSURE_MIN X_AXIS_MIN 37 38 static void pcap_ts_read_xy(void *data, u16 res[2]) 39 { 40 struct pcap_ts *pcap_ts = data; 41 42 switch (pcap_ts->read_state) { 43 case PCAP_ADC_TS_M_PRESSURE: 44 /* pressure reading is unreliable */ 45 if (res[0] > PRESSURE_MIN && res[0] < PRESSURE_MAX) 46 pcap_ts->pressure = res[0]; 47 pcap_ts->read_state = PCAP_ADC_TS_M_XY; 48 schedule_delayed_work(&pcap_ts->work, 0); 49 break; 50 case PCAP_ADC_TS_M_XY: 51 pcap_ts->y = res[0]; 52 pcap_ts->x = res[1]; 53 if (pcap_ts->x <= X_AXIS_MIN || pcap_ts->x >= X_AXIS_MAX || 54 pcap_ts->y <= Y_AXIS_MIN || pcap_ts->y >= Y_AXIS_MAX) { 55 /* pen has been released */ 56 input_report_abs(pcap_ts->input, ABS_PRESSURE, 0); 57 input_report_key(pcap_ts->input, BTN_TOUCH, 0); 58 59 pcap_ts->read_state = PCAP_ADC_TS_M_STANDBY; 60 schedule_delayed_work(&pcap_ts->work, 0); 61 } else { 62 /* pen is touching the screen */ 63 input_report_abs(pcap_ts->input, ABS_X, pcap_ts->x); 64 input_report_abs(pcap_ts->input, ABS_Y, pcap_ts->y); 65 input_report_key(pcap_ts->input, BTN_TOUCH, 1); 66 input_report_abs(pcap_ts->input, ABS_PRESSURE, 67 pcap_ts->pressure); 68 69 /* switch back to pressure read mode */ 70 pcap_ts->read_state = PCAP_ADC_TS_M_PRESSURE; 71 schedule_delayed_work(&pcap_ts->work, 72 msecs_to_jiffies(SAMPLE_DELAY)); 73 } 74 input_sync(pcap_ts->input); 75 break; 76 default: 77 dev_warn(&pcap_ts->input->dev, 78 "pcap_ts: Warning, unhandled read_state %d\n", 79 pcap_ts->read_state); 80 break; 81 } 82 } 83 84 static void pcap_ts_work(struct work_struct *work) 85 { 86 struct delayed_work *dw = to_delayed_work(work); 87 struct pcap_ts *pcap_ts = container_of(dw, struct pcap_ts, work); 88 u8 ch[2]; 89 90 pcap_set_ts_bits(pcap_ts->pcap, 91 pcap_ts->read_state << PCAP_ADC_TS_M_SHIFT); 92 93 if (pcap_ts->read_state == PCAP_ADC_TS_M_STANDBY) 94 return; 95 96 /* start adc conversion */ 97 ch[0] = PCAP_ADC_CH_TS_X1; 98 ch[1] = PCAP_ADC_CH_TS_Y1; 99 pcap_adc_async(pcap_ts->pcap, PCAP_ADC_BANK_1, 0, ch, 100 pcap_ts_read_xy, pcap_ts); 101 } 102 103 static irqreturn_t pcap_ts_event_touch(int pirq, void *data) 104 { 105 struct pcap_ts *pcap_ts = data; 106 107 if (pcap_ts->read_state == PCAP_ADC_TS_M_STANDBY) { 108 pcap_ts->read_state = PCAP_ADC_TS_M_PRESSURE; 109 schedule_delayed_work(&pcap_ts->work, 0); 110 } 111 return IRQ_HANDLED; 112 } 113 114 static int pcap_ts_open(struct input_dev *dev) 115 { 116 struct pcap_ts *pcap_ts = input_get_drvdata(dev); 117 118 pcap_ts->read_state = PCAP_ADC_TS_M_STANDBY; 119 schedule_delayed_work(&pcap_ts->work, 0); 120 121 return 0; 122 } 123 124 static void pcap_ts_close(struct input_dev *dev) 125 { 126 struct pcap_ts *pcap_ts = input_get_drvdata(dev); 127 128 cancel_delayed_work_sync(&pcap_ts->work); 129 130 pcap_ts->read_state = PCAP_ADC_TS_M_NONTS; 131 pcap_set_ts_bits(pcap_ts->pcap, 132 pcap_ts->read_state << PCAP_ADC_TS_M_SHIFT); 133 } 134 135 static int pcap_ts_probe(struct platform_device *pdev) 136 { 137 struct input_dev *input_dev; 138 struct pcap_ts *pcap_ts; 139 int err = -ENOMEM; 140 141 pcap_ts = kzalloc(sizeof(*pcap_ts), GFP_KERNEL); 142 if (!pcap_ts) 143 return err; 144 145 pcap_ts->pcap = dev_get_drvdata(pdev->dev.parent); 146 platform_set_drvdata(pdev, pcap_ts); 147 148 input_dev = input_allocate_device(); 149 if (!input_dev) 150 goto fail; 151 152 INIT_DELAYED_WORK(&pcap_ts->work, pcap_ts_work); 153 154 pcap_ts->read_state = PCAP_ADC_TS_M_NONTS; 155 pcap_set_ts_bits(pcap_ts->pcap, 156 pcap_ts->read_state << PCAP_ADC_TS_M_SHIFT); 157 158 pcap_ts->input = input_dev; 159 input_set_drvdata(input_dev, pcap_ts); 160 161 input_dev->name = "pcap-touchscreen"; 162 input_dev->phys = "pcap_ts/input0"; 163 input_dev->id.bustype = BUS_HOST; 164 input_dev->id.vendor = 0x0001; 165 input_dev->id.product = 0x0002; 166 input_dev->id.version = 0x0100; 167 input_dev->dev.parent = &pdev->dev; 168 input_dev->open = pcap_ts_open; 169 input_dev->close = pcap_ts_close; 170 171 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 172 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); 173 input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0); 174 input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0); 175 input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN, 176 PRESSURE_MAX, 0, 0); 177 178 err = input_register_device(pcap_ts->input); 179 if (err) 180 goto fail_allocate; 181 182 err = request_irq(pcap_to_irq(pcap_ts->pcap, PCAP_IRQ_TS), 183 pcap_ts_event_touch, 0, "Touch Screen", pcap_ts); 184 if (err) 185 goto fail_register; 186 187 return 0; 188 189 fail_register: 190 input_unregister_device(input_dev); 191 goto fail; 192 fail_allocate: 193 input_free_device(input_dev); 194 fail: 195 kfree(pcap_ts); 196 197 return err; 198 } 199 200 static void pcap_ts_remove(struct platform_device *pdev) 201 { 202 struct pcap_ts *pcap_ts = platform_get_drvdata(pdev); 203 204 free_irq(pcap_to_irq(pcap_ts->pcap, PCAP_IRQ_TS), pcap_ts); 205 cancel_delayed_work_sync(&pcap_ts->work); 206 207 input_unregister_device(pcap_ts->input); 208 209 kfree(pcap_ts); 210 } 211 212 #ifdef CONFIG_PM 213 static int pcap_ts_suspend(struct device *dev) 214 { 215 struct pcap_ts *pcap_ts = dev_get_drvdata(dev); 216 217 pcap_set_ts_bits(pcap_ts->pcap, PCAP_ADC_TS_REF_LOWPWR); 218 return 0; 219 } 220 221 static int pcap_ts_resume(struct device *dev) 222 { 223 struct pcap_ts *pcap_ts = dev_get_drvdata(dev); 224 225 pcap_set_ts_bits(pcap_ts->pcap, 226 pcap_ts->read_state << PCAP_ADC_TS_M_SHIFT); 227 return 0; 228 } 229 230 static const struct dev_pm_ops pcap_ts_pm_ops = { 231 .suspend = pcap_ts_suspend, 232 .resume = pcap_ts_resume, 233 }; 234 #define PCAP_TS_PM_OPS (&pcap_ts_pm_ops) 235 #else 236 #define PCAP_TS_PM_OPS NULL 237 #endif 238 239 static struct platform_driver pcap_ts_driver = { 240 .probe = pcap_ts_probe, 241 .remove_new = pcap_ts_remove, 242 .driver = { 243 .name = "pcap-ts", 244 .pm = PCAP_TS_PM_OPS, 245 }, 246 }; 247 module_platform_driver(pcap_ts_driver); 248 249 MODULE_DESCRIPTION("Motorola PCAP2 touchscreen driver"); 250 MODULE_AUTHOR("Daniel Ribeiro / Harald Welte"); 251 MODULE_LICENSE("GPL"); 252 MODULE_ALIAS("platform:pcap_ts"); 253