Lines Matching +full:adc +full:- +full:ts +full:- +full:wires
1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
8 // connected to the imx25 ADC.
14 #include <linux/mfd/imx25-tsadc.h>
20 static const char mx25_tcq_name[] = "mx25-tcq";
50 { .compatible = "fsl,imx25-tcq", },
103 regmap_write(priv->core_regs, MX25_TSC_TICR, precharge_cfg); in imx25_setup_queue_cfgs()
106 regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_PRECHARGE), in imx25_setup_queue_cfgs()
110 regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_TOUCH_DETECT), in imx25_setup_queue_cfgs()
114 regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_X_MEASUREMENT), in imx25_setup_queue_cfgs()
121 MX25_ADCQ_CFG_NOS(priv->sample_count) | in imx25_setup_queue_cfgs()
125 regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_Y_MEASUREMENT), in imx25_setup_queue_cfgs()
133 MX25_ADCQ_CFG_NOS(priv->sample_count) | in imx25_setup_queue_cfgs()
137 regmap_write(priv->core_regs, MX25_TSC_TICR, touch_detect_cfg | in imx25_setup_queue_cfgs()
147 regmap_write(priv->regs, MX25_ADCQ_ITEM_7_0, in imx25_setup_queue_4wire()
159 priv->expected_samples = priv->sample_count * 2 + 2; in imx25_setup_queue_4wire()
167 regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_PDMSK, in mx25_tcq_disable_touch_irq()
173 regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_PDMSK, 0); in mx25_tcq_enable_touch_irq()
178 regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_FDRY_IRQ, in mx25_tcq_disable_fifo_irq()
184 regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_FDRY_IRQ, 0); in mx25_tcq_enable_fifo_irq()
189 regmap_update_bits(priv->regs, MX25_ADCQ_CR, in mx25_tcq_force_queue_start()
196 regmap_update_bits(priv->regs, MX25_ADCQ_CR, in mx25_tcq_force_queue_stop()
204 regmap_read(priv->regs, MX25_ADCQ_CR, &tcqcr); in mx25_tcq_fifo_reset()
205 regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FRST, in mx25_tcq_fifo_reset()
207 regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FRST, 0); in mx25_tcq_fifo_reset()
208 regmap_write(priv->regs, MX25_ADCQ_CR, tcqcr); in mx25_tcq_fifo_reset()
217 regmap_write(priv->core_regs, MX25_TSC_TICR, MX25_PRECHARGE_VALUE); in mx25_tcq_re_enable_touch_detection()
219 /* waste some time now to pre-load the X plate to high voltage */ in mx25_tcq_re_enable_touch_detection()
222 /* re-enable the detection right now */ in mx25_tcq_re_enable_touch_detection()
223 regmap_write(priv->core_regs, MX25_TSC_TICR, in mx25_tcq_re_enable_touch_detection()
226 regmap_update_bits(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_PD, in mx25_tcq_re_enable_touch_detection()
230 regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_PD_IRQ, 0); in mx25_tcq_re_enable_touch_detection()
264 dev_dbg(priv->dev, "Dropped samples because of invalid index %d\n", in mx25_tcq_create_event_for_4wire()
275 if (touch_pre < priv->pen_threshold && in mx25_tcq_create_event_for_4wire()
276 touch_post < priv->pen_threshold) { in mx25_tcq_create_event_for_4wire()
278 x_pos /= priv->sample_count; in mx25_tcq_create_event_for_4wire()
279 y_pos /= priv->sample_count; in mx25_tcq_create_event_for_4wire()
280 input_report_abs(priv->idev, ABS_X, x_pos); in mx25_tcq_create_event_for_4wire()
281 input_report_abs(priv->idev, ABS_Y, y_pos); in mx25_tcq_create_event_for_4wire()
282 input_report_key(priv->idev, BTN_TOUCH, 1); in mx25_tcq_create_event_for_4wire()
283 input_sync(priv->idev); in mx25_tcq_create_event_for_4wire()
287 } else if (touch_pre >= priv->pen_threshold && in mx25_tcq_create_event_for_4wire()
288 touch_post >= priv->pen_threshold) { in mx25_tcq_create_event_for_4wire()
293 input_report_key(priv->idev, BTN_TOUCH, 0); in mx25_tcq_create_event_for_4wire()
294 input_sync(priv->idev); in mx25_tcq_create_event_for_4wire()
321 regmap_read(priv->regs, MX25_ADCQ_SR, &stats); in mx25_tcq_irq_thread()
323 samples -= samples % priv->sample_count; in mx25_tcq_irq_thread()
329 regmap_read(priv->regs, MX25_ADCQ_FIFO, &sample_buf[i]); in mx25_tcq_irq_thread()
342 regmap_read(priv->regs, MX25_ADCQ_SR, &stat); in mx25_tcq_irq()
358 regmap_update_bits(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_FRR | in mx25_tcq_irq()
367 /* configure the state machine for a 4-wire touchscreen */
378 regmap_read(priv->core_regs, MX25_TSC_TGCR, &tgcr); in mx25_tcq_init()
381 adc_period /= clk_get_rate(priv->clk) / 1000 + 1; in mx25_tcq_init()
382 debounce_cnt = DIV_ROUND_UP(priv->pen_debounce, adc_period * 8) - 1; in mx25_tcq_init()
383 settling_cnt = DIV_ROUND_UP(priv->settling_time, adc_period * 8) - 1; in mx25_tcq_init()
386 regmap_write(priv->regs, MX25_ADCQ_CR, in mx25_tcq_init()
388 regmap_update_bits(priv->regs, MX25_ADCQ_CR, in mx25_tcq_init()
391 /* up to 128 * 8 ADC clocks are possible */ in mx25_tcq_init()
395 /* up to 255 * 8 ADC clocks are possible */ in mx25_tcq_init()
403 regmap_update_bits(priv->regs, MX25_ADCQ_CR, in mx25_tcq_init()
405 MX25_ADCQ_CR_LITEMID(itemct - 1) | in mx25_tcq_init()
406 MX25_ADCQ_CR_WMRK(priv->expected_samples - 1)); in mx25_tcq_init()
409 regmap_update_bits(priv->core_regs, MX25_TSC_TGCR, in mx25_tcq_init()
414 regmap_update_bits(priv->core_regs, MX25_TSC_TGCR, MX25_TGCR_PDBEN, in mx25_tcq_init()
416 regmap_update_bits(priv->core_regs, MX25_TSC_TGCR, MX25_TGCR_PDEN, in mx25_tcq_init()
420 regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_QSM_MASK, in mx25_tcq_init()
424 regmap_update_bits(priv->regs, MX25_ADCQ_CR, in mx25_tcq_init()
435 struct device_node *np = pdev->dev.of_node; in mx25_tcq_parse_dt()
436 u32 wires; in mx25_tcq_parse_dt() local
440 priv->pen_threshold = 500; in mx25_tcq_parse_dt()
441 priv->sample_count = 3; in mx25_tcq_parse_dt()
442 priv->pen_debounce = 1000000; in mx25_tcq_parse_dt()
443 priv->settling_time = 250000; in mx25_tcq_parse_dt()
445 error = of_property_read_u32(np, "fsl,wires", &wires); in mx25_tcq_parse_dt()
447 dev_err(&pdev->dev, "Failed to find fsl,wires properties\n"); in mx25_tcq_parse_dt()
451 if (wires == 4) { in mx25_tcq_parse_dt()
452 priv->mode = MX25_TS_4WIRE; in mx25_tcq_parse_dt()
454 dev_err(&pdev->dev, "%u-wire mode not supported\n", wires); in mx25_tcq_parse_dt()
455 return -EINVAL; in mx25_tcq_parse_dt()
459 of_property_read_u32(np, "fsl,pen-threshold", &priv->pen_threshold); in mx25_tcq_parse_dt()
460 of_property_read_u32(np, "fsl,settling-time-ns", &priv->settling_time); in mx25_tcq_parse_dt()
461 of_property_read_u32(np, "fsl,pen-debounce-ns", &priv->pen_debounce); in mx25_tcq_parse_dt()
468 struct device *dev = &idev->dev; in mx25_tcq_open()
472 error = clk_prepare_enable(priv->clk); in mx25_tcq_open()
481 clk_disable_unprepare(priv->clk); in mx25_tcq_open()
497 clk_disable_unprepare(priv->clk); in mx25_tcq_close()
502 struct device *dev = &pdev->dev; in mx25_tcq_probe()
505 struct mx25_tsadc *tsadc = dev_get_drvdata(dev->parent); in mx25_tcq_probe()
511 return -ENOMEM; in mx25_tcq_probe()
512 priv->dev = dev; in mx25_tcq_probe()
522 priv->regs = devm_regmap_init_mmio(dev, mem, &mx25_tcq_regconfig); in mx25_tcq_probe()
523 if (IS_ERR(priv->regs)) { in mx25_tcq_probe()
525 return PTR_ERR(priv->regs); in mx25_tcq_probe()
528 priv->irq = platform_get_irq(pdev, 0); in mx25_tcq_probe()
529 if (priv->irq <= 0) in mx25_tcq_probe()
530 return priv->irq; in mx25_tcq_probe()
535 return -ENOMEM; in mx25_tcq_probe()
538 idev->name = mx25_tcq_name; in mx25_tcq_probe()
543 idev->id.bustype = BUS_HOST; in mx25_tcq_probe()
544 idev->open = mx25_tcq_open; in mx25_tcq_probe()
545 idev->close = mx25_tcq_close; in mx25_tcq_probe()
547 priv->idev = idev; in mx25_tcq_probe()
550 priv->core_regs = tsadc->regs; in mx25_tcq_probe()
551 if (!priv->core_regs) in mx25_tcq_probe()
552 return -EINVAL; in mx25_tcq_probe()
554 priv->clk = tsadc->clk; in mx25_tcq_probe()
555 if (!priv->clk) in mx25_tcq_probe()
556 return -EINVAL; in mx25_tcq_probe()
560 error = devm_request_threaded_irq(dev, priv->irq, mx25_tcq_irq, in mx25_tcq_probe()
561 mx25_tcq_irq_thread, 0, pdev->name, in mx25_tcq_probe()
579 .name = "mx25-tcq",
586 MODULE_DESCRIPTION("TS input driver for Freescale mx25");