Lines Matching +full:touchscreen +full:- +full:min +full:- +full:pressure
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Toradex Colibri VF50 Touchscreen driver
25 #define DRIVER_NAME "colibri-vf50-ts"
27 #define VF_ADC_MAX ((1 << 12) - 1)
88 gpiod_set_value(vf50_ts->gpio_ym, 1); in vf50_ts_enable_touch_detection()
92 * Pull-Up on GPIO in vf50_ts_enable_touch_detection()
94 pinctrl_pm_select_idle_state(&vf50_ts->pdev->dev); in vf50_ts_enable_touch_detection()
96 /* Wait for the pull-up to be stable on high */ in vf50_ts_enable_touch_detection()
106 struct device *dev = &vf50_ts->pdev->dev; in vf50_ts_irq_bh()
111 gpiod_set_value(vf50_ts->gpio_ym, 0); in vf50_ts_irq_bh()
116 while (!vf50_ts->stop_touchscreen) { in vf50_ts_irq_bh()
117 /* X-Direction */ in vf50_ts_irq_bh()
118 val_x = adc_ts_measure(&vf50_ts->channels[0], in vf50_ts_irq_bh()
119 vf50_ts->gpio_xp, vf50_ts->gpio_xm); in vf50_ts_irq_bh()
123 /* Y-Direction */ in vf50_ts_irq_bh()
124 val_y = adc_ts_measure(&vf50_ts->channels[1], in vf50_ts_irq_bh()
125 vf50_ts->gpio_yp, vf50_ts->gpio_ym); in vf50_ts_irq_bh()
130 * Touch pressure in vf50_ts_irq_bh()
133 val_z1 = adc_ts_measure(&vf50_ts->channels[2], in vf50_ts_irq_bh()
134 vf50_ts->gpio_yp, vf50_ts->gpio_xm); in vf50_ts_irq_bh()
137 val_z2 = adc_ts_measure(&vf50_ts->channels[3], in vf50_ts_irq_bh()
138 vf50_ts->gpio_yp, vf50_ts->gpio_xm); in vf50_ts_irq_bh()
146 * lower resistance means higher pressure in vf50_ts_irq_bh()
150 val_p = (r_x * val_z2) / val_z1 - r_x; in vf50_ts_irq_bh()
156 val_p = 2000 - val_p; in vf50_ts_irq_bh()
162 * If touch pressure is too low, stop measuring and reenable in vf50_ts_irq_bh()
165 if (val_p < vf50_ts->min_pressure || val_p > 2000) in vf50_ts_irq_bh()
169 * The pressure may not be enough for the first x and the in vf50_ts_irq_bh()
170 * second y measurement, but, the pressure is ok when the in vf50_ts_irq_bh()
181 input_report_abs(vf50_ts->ts_input, in vf50_ts_irq_bh()
182 ABS_X, VF_ADC_MAX - val_x); in vf50_ts_irq_bh()
183 input_report_abs(vf50_ts->ts_input, in vf50_ts_irq_bh()
184 ABS_Y, VF_ADC_MAX - val_y); in vf50_ts_irq_bh()
185 input_report_abs(vf50_ts->ts_input, in vf50_ts_irq_bh()
187 input_report_key(vf50_ts->ts_input, BTN_TOUCH, 1); in vf50_ts_irq_bh()
188 input_sync(vf50_ts->ts_input); in vf50_ts_irq_bh()
195 /* Report no more touch, re-enable touch detection */ in vf50_ts_irq_bh()
196 input_report_abs(vf50_ts->ts_input, ABS_PRESSURE, 0); in vf50_ts_irq_bh()
197 input_report_key(vf50_ts->ts_input, BTN_TOUCH, 0); in vf50_ts_irq_bh()
198 input_sync(vf50_ts->ts_input); in vf50_ts_irq_bh()
208 struct device *dev = &touchdev->pdev->dev; in vf50_ts_open()
211 dev_input->name); in vf50_ts_open()
213 touchdev->stop_touchscreen = false; in vf50_ts_open()
215 /* Mux detection before request IRQ, wait for pull-up to settle */ in vf50_ts_open()
224 struct device *dev = &touchdev->pdev->dev; in vf50_ts_close()
226 touchdev->stop_touchscreen = true; in vf50_ts_close()
230 synchronize_irq(touchdev->pen_irq); in vf50_ts_close()
232 gpiod_set_value(touchdev->gpio_ym, 0); in vf50_ts_close()
236 dev_input->name); in vf50_ts_close()
265 struct device *dev = &pdev->dev; in vf50_ts_probe()
287 return -EINVAL; in vf50_ts_probe()
292 return -ENOMEM; in vf50_ts_probe()
294 touchdev->pdev = pdev; in vf50_ts_probe()
295 touchdev->channels = channels; in vf50_ts_probe()
297 error = of_property_read_u32(dev->of_node, "vf50-ts-min-pressure", in vf50_ts_probe()
298 &touchdev->min_pressure); in vf50_ts_probe()
305 return -ENOMEM; in vf50_ts_probe()
308 input->name = DRIVER_NAME; in vf50_ts_probe()
309 input->id.bustype = BUS_HOST; in vf50_ts_probe()
310 input->dev.parent = dev; in vf50_ts_probe()
311 input->open = vf50_ts_open; in vf50_ts_probe()
312 input->close = vf50_ts_close; in vf50_ts_probe()
319 touchdev->ts_input = input; in vf50_ts_probe()
328 error = vf50_ts_get_gpiod(dev, &touchdev->gpio_xp, "xp", GPIOD_OUT_LOW); in vf50_ts_probe()
332 error = vf50_ts_get_gpiod(dev, &touchdev->gpio_xm, in vf50_ts_probe()
337 error = vf50_ts_get_gpiod(dev, &touchdev->gpio_yp, "yp", GPIOD_OUT_LOW); in vf50_ts_probe()
341 error = vf50_ts_get_gpiod(dev, &touchdev->gpio_ym, "ym", GPIOD_OUT_LOW); in vf50_ts_probe()
345 touchdev->pen_irq = platform_get_irq(pdev, 0); in vf50_ts_probe()
346 if (touchdev->pen_irq < 0) in vf50_ts_probe()
347 return touchdev->pen_irq; in vf50_ts_probe()
349 error = devm_request_threaded_irq(dev, touchdev->pen_irq, in vf50_ts_probe()
354 touchdev->pen_irq, error); in vf50_ts_probe()
362 { .compatible = "toradex,vf50-touchscreen", },
377 MODULE_DESCRIPTION("Colibri VF50 Touchscreen driver");