^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) // Based on driver from 2011:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Juergen Beisert, Pengutronix <kernel@pengutronix.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) // This is the driver for the imx25 TCQ (Touchscreen Conversion Queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) // connected to the imx25 ADC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mfd/imx25-tsadc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static const char mx25_tcq_name[] = "mx25-tcq";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) enum mx25_tcq_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) MX25_TS_4WIRE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct mx25_tcq_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct regmap *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct regmap *core_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct input_dev *idev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) enum mx25_tcq_mode mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) unsigned int pen_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) unsigned int sample_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) unsigned int expected_samples;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) unsigned int pen_debounce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) unsigned int settling_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static struct regmap_config mx25_tcq_regconfig = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .fast_io = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .max_register = 0x5c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static const struct of_device_id mx25_tcq_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) { .compatible = "fsl,imx25-tcq", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) { /* Sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) MODULE_DEVICE_TABLE(of, mx25_tcq_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define TSC_4WIRE_PRE_INDEX 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define TSC_4WIRE_X_INDEX 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define TSC_4WIRE_Y_INDEX 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define TSC_4WIRE_POST_INDEX 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define TSC_4WIRE_LEAVE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define MX25_TSC_DEF_THRESHOLD 80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define TSC_MAX_SAMPLES 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define MX25_TSC_REPEAT_WAIT 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) enum mx25_adc_configurations {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) MX25_CFG_PRECHARGE = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) MX25_CFG_TOUCH_DETECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) MX25_CFG_X_MEASUREMENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) MX25_CFG_Y_MEASUREMENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define MX25_PRECHARGE_VALUE (\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) MX25_ADCQ_CFG_YPLL_OFF | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) MX25_ADCQ_CFG_XNUR_OFF | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) MX25_ADCQ_CFG_XPUL_HIGH | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) MX25_ADCQ_CFG_REFP_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) MX25_ADCQ_CFG_IN_XP | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) MX25_ADCQ_CFG_REFN_NGND2 | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) MX25_ADCQ_CFG_IGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define MX25_TOUCH_DETECT_VALUE (\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) MX25_ADCQ_CFG_YNLR | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) MX25_ADCQ_CFG_YPLL_OFF | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) MX25_ADCQ_CFG_XNUR_OFF | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) MX25_ADCQ_CFG_XPUL_OFF | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) MX25_ADCQ_CFG_REFP_INT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) MX25_ADCQ_CFG_IN_XP | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) MX25_ADCQ_CFG_REFN_NGND2 | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) MX25_ADCQ_CFG_PENIACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static void imx25_setup_queue_cfgs(struct mx25_tcq_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) unsigned int settling_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u32 precharge_cfg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) MX25_PRECHARGE_VALUE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) u32 touch_detect_cfg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) MX25_TOUCH_DETECT_VALUE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) MX25_ADCQ_CFG_NOS(1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) regmap_write(priv->core_regs, MX25_TSC_TICR, precharge_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* PRECHARGE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_PRECHARGE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) precharge_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* TOUCH_DETECT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_TOUCH_DETECT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) touch_detect_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* X Measurement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_X_MEASUREMENT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) MX25_ADCQ_CFG_YPLL_OFF |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) MX25_ADCQ_CFG_XNUR_LOW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) MX25_ADCQ_CFG_XPUL_HIGH |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) MX25_ADCQ_CFG_REFP_XP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) MX25_ADCQ_CFG_IN_YP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) MX25_ADCQ_CFG_REFN_XN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) MX25_ADCQ_CFG_NOS(priv->sample_count) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* Y Measurement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) regmap_write(priv->regs, MX25_ADCQ_CFG(MX25_CFG_Y_MEASUREMENT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) MX25_ADCQ_CFG_YNLR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) MX25_ADCQ_CFG_YPLL_HIGH |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) MX25_ADCQ_CFG_XNUR_OFF |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) MX25_ADCQ_CFG_XPUL_OFF |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) MX25_ADCQ_CFG_REFP_YP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) MX25_ADCQ_CFG_IN_XP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) MX25_ADCQ_CFG_REFN_YN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) MX25_ADCQ_CFG_NOS(priv->sample_count) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) MX25_ADCQ_CFG_SETTLING_TIME(settling_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* Enable the touch detection right now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) regmap_write(priv->core_regs, MX25_TSC_TICR, touch_detect_cfg |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) MX25_ADCQ_CFG_IGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int imx25_setup_queue_4wire(struct mx25_tcq_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unsigned settling_cnt, int *items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) imx25_setup_queue_cfgs(priv, settling_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* Setup the conversion queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) regmap_write(priv->regs, MX25_ADCQ_ITEM_7_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) MX25_ADCQ_ITEM(0, MX25_CFG_PRECHARGE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) MX25_ADCQ_ITEM(1, MX25_CFG_TOUCH_DETECT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) MX25_ADCQ_ITEM(2, MX25_CFG_X_MEASUREMENT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) MX25_ADCQ_ITEM(3, MX25_CFG_Y_MEASUREMENT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) MX25_ADCQ_ITEM(4, MX25_CFG_PRECHARGE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) MX25_ADCQ_ITEM(5, MX25_CFG_TOUCH_DETECT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * We measure X/Y with 'sample_count' number of samples and execute a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * touch detection twice, with 1 sample each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) priv->expected_samples = priv->sample_count * 2 + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) *items = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static void mx25_tcq_disable_touch_irq(struct mx25_tcq_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_PDMSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) MX25_ADCQ_CR_PDMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static void mx25_tcq_enable_touch_irq(struct mx25_tcq_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_PDMSK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static void mx25_tcq_disable_fifo_irq(struct mx25_tcq_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_FDRY_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) MX25_ADCQ_MR_FDRY_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static void mx25_tcq_enable_fifo_irq(struct mx25_tcq_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_FDRY_IRQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static void mx25_tcq_force_queue_start(struct mx25_tcq_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) regmap_update_bits(priv->regs, MX25_ADCQ_CR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) MX25_ADCQ_CR_FQS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) MX25_ADCQ_CR_FQS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static void mx25_tcq_force_queue_stop(struct mx25_tcq_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) regmap_update_bits(priv->regs, MX25_ADCQ_CR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) MX25_ADCQ_CR_FQS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static void mx25_tcq_fifo_reset(struct mx25_tcq_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u32 tcqcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) regmap_read(priv->regs, MX25_ADCQ_CR, &tcqcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FRST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) MX25_ADCQ_CR_FRST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_FRST, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) regmap_write(priv->regs, MX25_ADCQ_CR, tcqcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static void mx25_tcq_re_enable_touch_detection(struct mx25_tcq_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /* stop the queue from looping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) mx25_tcq_force_queue_stop(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* for a clean touch detection, preload the X plane */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) regmap_write(priv->core_regs, MX25_TSC_TICR, MX25_PRECHARGE_VALUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* waste some time now to pre-load the X plate to high voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) mx25_tcq_fifo_reset(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* re-enable the detection right now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) regmap_write(priv->core_regs, MX25_TSC_TICR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) MX25_TOUCH_DETECT_VALUE | MX25_ADCQ_CFG_IGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) regmap_update_bits(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_PD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) MX25_ADCQ_SR_PD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /* enable the pen down event to be a source for the interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) regmap_update_bits(priv->regs, MX25_ADCQ_MR, MX25_ADCQ_MR_PD_IRQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /* lets fire the next IRQ if someone touches the touchscreen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) mx25_tcq_enable_touch_irq(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static void mx25_tcq_create_event_for_4wire(struct mx25_tcq_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u32 *sample_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) unsigned int samples)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) unsigned int x_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) unsigned int y_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) unsigned int touch_pre = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) unsigned int touch_post = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) for (i = 0; i < samples; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) unsigned int index = MX25_ADCQ_FIFO_ID(sample_buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) unsigned int val = MX25_ADCQ_FIFO_DATA(sample_buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) switch (index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) touch_pre = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) x_pos = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) y_pos = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) touch_post = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) dev_dbg(priv->dev, "Dropped samples because of invalid index %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (samples != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * only if both touch measures are below a threshold,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * the position is valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (touch_pre < priv->pen_threshold &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) touch_post < priv->pen_threshold) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* valid samples, generate a report */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) x_pos /= priv->sample_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) y_pos /= priv->sample_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) input_report_abs(priv->idev, ABS_X, x_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) input_report_abs(priv->idev, ABS_Y, y_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) input_report_key(priv->idev, BTN_TOUCH, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) input_sync(priv->idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* get next sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) mx25_tcq_enable_fifo_irq(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) } else if (touch_pre >= priv->pen_threshold &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) touch_post >= priv->pen_threshold) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * if both samples are invalid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * generate a release report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) input_report_key(priv->idev, BTN_TOUCH, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) input_sync(priv->idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) mx25_tcq_re_enable_touch_detection(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * if only one of both touch measurements are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * below the threshold, still some bouncing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * happens. Take additional samples in this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * case to be sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) mx25_tcq_enable_fifo_irq(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static irqreturn_t mx25_tcq_irq_thread(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct mx25_tcq_priv *priv = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) u32 sample_buf[TSC_MAX_SAMPLES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) unsigned int samples;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) u32 stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * Check how many samples are available. We always have to read exactly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * sample_count samples from the fifo, or a multiple of sample_count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * Otherwise we mixup samples into different touch events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) regmap_read(priv->regs, MX25_ADCQ_SR, &stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) samples = MX25_ADCQ_SR_FDN(stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) samples -= samples % priv->sample_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (!samples)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) for (i = 0; i != samples; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) regmap_read(priv->regs, MX25_ADCQ_FIFO, &sample_buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) mx25_tcq_create_event_for_4wire(priv, sample_buf, samples);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static irqreturn_t mx25_tcq_irq(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct mx25_tcq_priv *priv = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) u32 stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) int ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) regmap_read(priv->regs, MX25_ADCQ_SR, &stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (stat & (MX25_ADCQ_SR_FRR | MX25_ADCQ_SR_FUR | MX25_ADCQ_SR_FOR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) mx25_tcq_re_enable_touch_detection(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (stat & MX25_ADCQ_SR_PD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) mx25_tcq_disable_touch_irq(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) mx25_tcq_force_queue_start(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) mx25_tcq_enable_fifo_irq(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (stat & MX25_ADCQ_SR_FDRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) mx25_tcq_disable_fifo_irq(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ret = IRQ_WAKE_THREAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) regmap_update_bits(priv->regs, MX25_ADCQ_SR, MX25_ADCQ_SR_FRR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) MX25_ADCQ_SR_FUR | MX25_ADCQ_SR_FOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) MX25_ADCQ_SR_PD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) MX25_ADCQ_SR_FRR | MX25_ADCQ_SR_FUR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) MX25_ADCQ_SR_FOR | MX25_ADCQ_SR_PD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* configure the state machine for a 4-wire touchscreen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static int mx25_tcq_init(struct mx25_tcq_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) u32 tgcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) unsigned int ipg_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) unsigned int adc_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) unsigned int debounce_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) unsigned int settling_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) int itemct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) regmap_read(priv->core_regs, MX25_TSC_TGCR, &tgcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) ipg_div = max_t(unsigned int, 4, MX25_TGCR_GET_ADCCLK(tgcr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) adc_period = USEC_PER_SEC * ipg_div * 2 + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) adc_period /= clk_get_rate(priv->clk) / 1000 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) debounce_cnt = DIV_ROUND_UP(priv->pen_debounce, adc_period * 8) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) settling_cnt = DIV_ROUND_UP(priv->settling_time, adc_period * 8) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /* Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) regmap_write(priv->regs, MX25_ADCQ_CR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) MX25_ADCQ_CR_QRST | MX25_ADCQ_CR_FRST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) regmap_update_bits(priv->regs, MX25_ADCQ_CR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) MX25_ADCQ_CR_QRST | MX25_ADCQ_CR_FRST, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /* up to 128 * 8 ADC clocks are possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (debounce_cnt > 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) debounce_cnt = 127;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /* up to 255 * 8 ADC clocks are possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (settling_cnt > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) settling_cnt = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) error = imx25_setup_queue_4wire(priv, settling_cnt, &itemct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) regmap_update_bits(priv->regs, MX25_ADCQ_CR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) MX25_ADCQ_CR_LITEMID_MASK | MX25_ADCQ_CR_WMRK_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) MX25_ADCQ_CR_LITEMID(itemct - 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) MX25_ADCQ_CR_WMRK(priv->expected_samples - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /* setup debounce count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) regmap_update_bits(priv->core_regs, MX25_TSC_TGCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) MX25_TGCR_PDBTIME_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) MX25_TGCR_PDBTIME(debounce_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /* enable debounce */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) regmap_update_bits(priv->core_regs, MX25_TSC_TGCR, MX25_TGCR_PDBEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) MX25_TGCR_PDBEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) regmap_update_bits(priv->core_regs, MX25_TSC_TGCR, MX25_TGCR_PDEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) MX25_TGCR_PDEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* enable the engine on demand */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) regmap_update_bits(priv->regs, MX25_ADCQ_CR, MX25_ADCQ_CR_QSM_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) MX25_ADCQ_CR_QSM_FQS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /* Enable repeat and repeat wait */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) regmap_update_bits(priv->regs, MX25_ADCQ_CR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) MX25_ADCQ_CR_RPT | MX25_ADCQ_CR_RWAIT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) MX25_ADCQ_CR_RPT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) MX25_ADCQ_CR_RWAIT(MX25_TSC_REPEAT_WAIT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static int mx25_tcq_parse_dt(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct mx25_tcq_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) u32 wires;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /* Setup defaults */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) priv->pen_threshold = 500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) priv->sample_count = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) priv->pen_debounce = 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) priv->settling_time = 250000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) error = of_property_read_u32(np, "fsl,wires", &wires);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) dev_err(&pdev->dev, "Failed to find fsl,wires properties\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (wires == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) priv->mode = MX25_TS_4WIRE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) dev_err(&pdev->dev, "%u-wire mode not supported\n", wires);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) /* These are optional, we don't care about the return values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) of_property_read_u32(np, "fsl,pen-threshold", &priv->pen_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) of_property_read_u32(np, "fsl,settling-time-ns", &priv->settling_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) of_property_read_u32(np, "fsl,pen-debounce-ns", &priv->pen_debounce);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) static int mx25_tcq_open(struct input_dev *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct device *dev = &idev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct mx25_tcq_priv *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) error = clk_prepare_enable(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) dev_err(dev, "Failed to enable ipg clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) error = mx25_tcq_init(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) dev_err(dev, "Failed to init tcq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) clk_disable_unprepare(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) mx25_tcq_re_enable_touch_detection(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static void mx25_tcq_close(struct input_dev *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct mx25_tcq_priv *priv = input_get_drvdata(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) mx25_tcq_force_queue_stop(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) mx25_tcq_disable_touch_irq(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) mx25_tcq_disable_fifo_irq(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) clk_disable_unprepare(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static int mx25_tcq_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct input_dev *idev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct mx25_tcq_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct mx25_tsadc *tsadc = dev_get_drvdata(dev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) void __iomem *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) priv->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) mem = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (IS_ERR(mem))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return PTR_ERR(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) error = mx25_tcq_parse_dt(pdev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) priv->regs = devm_regmap_init_mmio(dev, mem, &mx25_tcq_regconfig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (IS_ERR(priv->regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) dev_err(dev, "Failed to initialize regmap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return PTR_ERR(priv->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) priv->irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (priv->irq <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return priv->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) idev = devm_input_allocate_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (!idev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) dev_err(dev, "Failed to allocate input device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) idev->name = mx25_tcq_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) input_set_capability(idev, EV_KEY, BTN_TOUCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) input_set_abs_params(idev, ABS_X, 0, 0xfff, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) input_set_abs_params(idev, ABS_Y, 0, 0xfff, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) idev->id.bustype = BUS_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) idev->open = mx25_tcq_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) idev->close = mx25_tcq_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) priv->idev = idev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) input_set_drvdata(idev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) priv->core_regs = tsadc->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (!priv->core_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) priv->clk = tsadc->clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (!priv->clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) platform_set_drvdata(pdev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) error = devm_request_threaded_irq(dev, priv->irq, mx25_tcq_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) mx25_tcq_irq_thread, 0, pdev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) dev_err(dev, "Failed requesting IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) error = input_register_device(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) dev_err(dev, "Failed to register input device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static struct platform_driver mx25_tcq_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) .name = "mx25-tcq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .of_match_table = mx25_tcq_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) .probe = mx25_tcq_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) module_platform_driver(mx25_tcq_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) MODULE_DESCRIPTION("TS input driver for Freescale mx25");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) MODULE_LICENSE("GPL v2");