Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");