^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Freescale MXS LRADC touchscreen driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2012 DENX Software Engineering, GmbH.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2017 Ksenija Stanojevic <ksenija.stanojevic@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Marek Vasut <marex@denx.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Ksenija Stanojevic <ksenija.stanojevic@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mfd/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/mfd/mxs-lradc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static const char * const mxs_lradc_ts_irq_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) "mxs-lradc-touchscreen",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) "mxs-lradc-channel6",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) "mxs-lradc-channel7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * Touchscreen handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) enum mxs_lradc_ts_plate {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) LRADC_TOUCH = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) LRADC_SAMPLE_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) LRADC_SAMPLE_Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) LRADC_SAMPLE_PRESSURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) LRADC_SAMPLE_VALID,
^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) struct mxs_lradc_ts {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct mxs_lradc *lradc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * When the touchscreen is enabled, we give it two private virtual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * channels: #6 and #7. This means that only 6 virtual channels (instead
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * of 8) will be available for buffered capture.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define TOUCHSCREEN_VCHANNEL1 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define TOUCHSCREEN_VCHANNEL2 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct input_dev *ts_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) enum mxs_lradc_ts_plate cur_plate; /* state machine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) bool ts_valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) unsigned int ts_x_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned int ts_y_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned int ts_pressure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* handle touchscreen's physical behaviour */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* samples per coordinate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) unsigned int over_sample_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* time clocks between samples */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned int over_sample_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* time in clocks to wait after the plates where switched */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned int settling_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct state_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) u32 bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) u32 x_plate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) u32 y_plate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) u32 pressure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static struct state_info info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {LRADC_CTRL0_MX23_PLATE_MASK, LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) LRADC_CTRL0_MX23_XP | LRADC_CTRL0_MX23_XM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_YM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_XM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {LRADC_CTRL0_MX28_PLATE_MASK, LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) LRADC_CTRL0_MX28_XPPSW | LRADC_CTRL0_MX28_XNNSW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_YNNSW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_XNNSW}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static bool mxs_lradc_check_touch_event(struct mxs_lradc_ts *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return !!(readl(ts->base + LRADC_STATUS) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) LRADC_STATUS_TOUCH_DETECT_RAW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static void mxs_lradc_map_ts_channel(struct mxs_lradc_ts *ts, unsigned int vch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) writel(LRADC_CTRL4_LRADCSELECT_MASK(vch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ts->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) writel(LRADC_CTRL4_LRADCSELECT(vch, ch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ts->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static void mxs_lradc_setup_ts_channel(struct mxs_lradc_ts *ts, unsigned int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * prepare for oversampling conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * from the datasheet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * "The ACCUMULATE bit in the appropriate channel register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * HW_LRADC_CHn must be set to 1 if NUM_SAMPLES is greater then 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * otherwise, the IRQs will not fire."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) writel(LRADC_CH_ACCUMULATE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) LRADC_CH_NUM_SAMPLES(ts->over_sample_cnt - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ts->base + LRADC_CH(ch));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* from the datasheet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * "Software must clear this register in preparation for a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * multi-cycle accumulation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) writel(LRADC_CH_VALUE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ts->base + LRADC_CH(ch) + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * prepare the delay/loop unit according to the oversampling count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * from the datasheet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * "The DELAY fields in HW_LRADC_DELAY0, HW_LRADC_DELAY1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * HW_LRADC_DELAY2, and HW_LRADC_DELAY3 must be non-zero; otherwise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * the LRADC will not trigger the delay group."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) writel(LRADC_DELAY_TRIGGER(1 << ch) | LRADC_DELAY_TRIGGER_DELAYS(0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) LRADC_DELAY_LOOP(ts->over_sample_cnt - 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) LRADC_DELAY_DELAY(ts->over_sample_delay - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) ts->base + LRADC_DELAY(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) writel(LRADC_CTRL1_LRADC_IRQ(ch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ts->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * after changing the touchscreen plates setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * the signals need some initial time to settle. Start the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * SoC's delay unit and start the conversion later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * and automatically.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) writel(LRADC_DELAY_TRIGGER(0) | LRADC_DELAY_TRIGGER_DELAYS(BIT(3)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) LRADC_DELAY_KICK | LRADC_DELAY_DELAY(ts->settling_delay),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ts->base + LRADC_DELAY(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * Pressure detection is special:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * We want to do both required measurements for the pressure detection in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * one turn. Use the hardware features to chain both conversions and let the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * hardware report one interrupt if both conversions are done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static void mxs_lradc_setup_ts_pressure(struct mxs_lradc_ts *ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) unsigned int ch1, unsigned int ch2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * prepare for oversampling conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * from the datasheet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * "The ACCUMULATE bit in the appropriate channel register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * HW_LRADC_CHn must be set to 1 if NUM_SAMPLES is greater then 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * otherwise, the IRQs will not fire."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) reg = LRADC_CH_ACCUMULATE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) LRADC_CH_NUM_SAMPLES(ts->over_sample_cnt - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) writel(reg, ts->base + LRADC_CH(ch1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) writel(reg, ts->base + LRADC_CH(ch2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* from the datasheet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * "Software must clear this register in preparation for a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * multi-cycle accumulation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) writel(LRADC_CH_VALUE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) ts->base + LRADC_CH(ch1) + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) writel(LRADC_CH_VALUE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ts->base + LRADC_CH(ch2) + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* prepare the delay/loop unit according to the oversampling count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) writel(LRADC_DELAY_TRIGGER(1 << ch1) | LRADC_DELAY_TRIGGER(1 << ch2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) LRADC_DELAY_TRIGGER_DELAYS(0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) LRADC_DELAY_LOOP(ts->over_sample_cnt - 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) LRADC_DELAY_DELAY(ts->over_sample_delay - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) ts->base + LRADC_DELAY(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) writel(LRADC_CTRL1_LRADC_IRQ(ch2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) ts->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * after changing the touchscreen plates setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * the signals need some initial time to settle. Start the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * SoC's delay unit and start the conversion later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * and automatically.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) writel(LRADC_DELAY_TRIGGER(0) | LRADC_DELAY_TRIGGER_DELAYS(BIT(3)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) LRADC_DELAY_KICK | LRADC_DELAY_DELAY(ts->settling_delay),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ts->base + LRADC_DELAY(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static unsigned int mxs_lradc_ts_read_raw_channel(struct mxs_lradc_ts *ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) unsigned int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) unsigned int num_samples, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) reg = readl(ts->base + LRADC_CH(channel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (reg & LRADC_CH_ACCUMULATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) num_samples = ts->over_sample_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) num_samples = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) val = (reg & LRADC_CH_VALUE_MASK) >> LRADC_CH_VALUE_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return val / num_samples;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static unsigned int mxs_lradc_read_ts_pressure(struct mxs_lradc_ts *ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) unsigned int ch1, unsigned int ch2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) u32 reg, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) unsigned int pressure, m1, m2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) mask = LRADC_CTRL1_LRADC_IRQ(ch1) | LRADC_CTRL1_LRADC_IRQ(ch2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) reg = readl(ts->base + LRADC_CTRL1) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) while (reg != mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) reg = readl(ts->base + LRADC_CTRL1) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) dev_dbg(ts->dev, "One channel is still busy: %X\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) m1 = mxs_lradc_ts_read_raw_channel(ts, ch1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) m2 = mxs_lradc_ts_read_raw_channel(ts, ch2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (m2 == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) dev_warn(ts->dev, "Cannot calculate pressure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return 1 << (LRADC_RESOLUTION - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* simply scale the value from 0 ... max ADC resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) pressure = m1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) pressure *= (1 << LRADC_RESOLUTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) pressure /= m2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) dev_dbg(ts->dev, "Pressure = %u\n", pressure);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return pressure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) #define TS_CH_XP 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) #define TS_CH_YP 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) #define TS_CH_XM 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #define TS_CH_YM 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * YP(open)--+-------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * | |--+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * | | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * YM(-)--+-------------+ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * +--------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * XP(weak+) XM(open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * "weak+" means 200k Ohm VDDIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * (-) means GND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static void mxs_lradc_setup_touch_detection(struct mxs_lradc_ts *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct mxs_lradc *lradc = ts->lradc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * In order to detect a touch event the 'touch detect enable' bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * enables:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * - a weak pullup to the X+ connector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * - a strong ground at the Y- connector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) writel(info[lradc->soc].mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) ts->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) writel(info[lradc->soc].bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) ts->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * YP(meas)--+-------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * | |--+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * | | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * YM(open)--+-------------+ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * +--------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * XP(+) XM(-)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * (+) means here 1.85 V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * (-) means here GND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static void mxs_lradc_prepare_x_pos(struct mxs_lradc_ts *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct mxs_lradc *lradc = ts->lradc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) writel(info[lradc->soc].mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) ts->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) writel(info[lradc->soc].x_plate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) ts->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ts->cur_plate = LRADC_SAMPLE_X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) mxs_lradc_map_ts_channel(ts, TOUCHSCREEN_VCHANNEL1, TS_CH_YP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) mxs_lradc_setup_ts_channel(ts, TOUCHSCREEN_VCHANNEL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * YP(+)--+-------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * | |--+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * | | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * YM(-)--+-------------+ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * +--------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * XP(open) XM(meas)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * (+) means here 1.85 V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * (-) means here GND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static void mxs_lradc_prepare_y_pos(struct mxs_lradc_ts *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct mxs_lradc *lradc = ts->lradc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) writel(info[lradc->soc].mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ts->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) writel(info[lradc->soc].y_plate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ts->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) ts->cur_plate = LRADC_SAMPLE_Y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) mxs_lradc_map_ts_channel(ts, TOUCHSCREEN_VCHANNEL1, TS_CH_XM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) mxs_lradc_setup_ts_channel(ts, TOUCHSCREEN_VCHANNEL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * YP(+)--+-------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * | |--+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * | | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * YM(meas)--+-------------+ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * +--------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * XP(meas) XM(-)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * (+) means here 1.85 V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * (-) means here GND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static void mxs_lradc_prepare_pressure(struct mxs_lradc_ts *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct mxs_lradc *lradc = ts->lradc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) writel(info[lradc->soc].mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) ts->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) writel(info[lradc->soc].pressure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ts->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ts->cur_plate = LRADC_SAMPLE_PRESSURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) mxs_lradc_map_ts_channel(ts, TOUCHSCREEN_VCHANNEL1, TS_CH_YM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) mxs_lradc_map_ts_channel(ts, TOUCHSCREEN_VCHANNEL2, TS_CH_XP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) mxs_lradc_setup_ts_pressure(ts, TOUCHSCREEN_VCHANNEL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) TOUCHSCREEN_VCHANNEL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static void mxs_lradc_enable_touch_detection(struct mxs_lradc_ts *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) mxs_lradc_setup_touch_detection(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) ts->cur_plate = LRADC_TOUCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) writel(LRADC_CTRL1_TOUCH_DETECT_IRQ | LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) ts->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ts->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static void mxs_lradc_start_touch_event(struct mxs_lradc_ts *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) ts->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) writel(LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) ts->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * start with the Y-pos, because it uses nearly the same plate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * settings like the touch detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) mxs_lradc_prepare_y_pos(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static void mxs_lradc_report_ts_event(struct mxs_lradc_ts *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) input_report_abs(ts->ts_input, ABS_X, ts->ts_x_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) input_report_abs(ts->ts_input, ABS_Y, ts->ts_y_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) input_report_abs(ts->ts_input, ABS_PRESSURE, ts->ts_pressure);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) input_report_key(ts->ts_input, BTN_TOUCH, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) input_sync(ts->ts_input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static void mxs_lradc_complete_touch_event(struct mxs_lradc_ts *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) mxs_lradc_setup_touch_detection(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) ts->cur_plate = LRADC_SAMPLE_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * start a dummy conversion to burn time to settle the signals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * note: we are not interested in the conversion's value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) writel(0, ts->base + LRADC_CH(TOUCHSCREEN_VCHANNEL1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) writel(LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) ts->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) writel(LRADC_DELAY_TRIGGER(1 << TOUCHSCREEN_VCHANNEL1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) LRADC_DELAY_KICK | LRADC_DELAY_DELAY(10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ts->base + LRADC_DELAY(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * in order to avoid false measurements, report only samples where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * the surface is still touched after the position measurement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static void mxs_lradc_finish_touch_event(struct mxs_lradc_ts *ts, bool valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* if it is still touched, report the sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (valid && mxs_lradc_check_touch_event(ts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) ts->ts_valid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) mxs_lradc_report_ts_event(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /* if it is even still touched, continue with the next measurement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (mxs_lradc_check_touch_event(ts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) mxs_lradc_prepare_y_pos(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (ts->ts_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /* signal the release */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ts->ts_valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) input_report_key(ts->ts_input, BTN_TOUCH, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) input_sync(ts->ts_input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) /* if it is released, wait for the next touch via IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ts->cur_plate = LRADC_TOUCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) writel(0, ts->base + LRADC_DELAY(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) writel(0, ts->base + LRADC_DELAY(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) writel(LRADC_CTRL1_TOUCH_DETECT_IRQ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) ts->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) ts->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /* touchscreen's state machine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static void mxs_lradc_handle_touch(struct mxs_lradc_ts *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) switch (ts->cur_plate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) case LRADC_TOUCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (mxs_lradc_check_touch_event(ts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) mxs_lradc_start_touch_event(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) writel(LRADC_CTRL1_TOUCH_DETECT_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ts->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) case LRADC_SAMPLE_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ts->ts_y_pos =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) mxs_lradc_ts_read_raw_channel(ts, TOUCHSCREEN_VCHANNEL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) mxs_lradc_prepare_x_pos(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) case LRADC_SAMPLE_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ts->ts_x_pos =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) mxs_lradc_ts_read_raw_channel(ts, TOUCHSCREEN_VCHANNEL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) mxs_lradc_prepare_pressure(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) case LRADC_SAMPLE_PRESSURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ts->ts_pressure =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) mxs_lradc_read_ts_pressure(ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) TOUCHSCREEN_VCHANNEL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) TOUCHSCREEN_VCHANNEL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) mxs_lradc_complete_touch_event(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) case LRADC_SAMPLE_VALID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) mxs_lradc_finish_touch_event(ts, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* IRQ Handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) static irqreturn_t mxs_lradc_ts_handle_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) struct mxs_lradc_ts *ts = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct mxs_lradc *lradc = ts->lradc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) unsigned long reg = readl(ts->base + LRADC_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) u32 clr_irq = mxs_lradc_irq_mask(lradc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) const u32 ts_irq_mask =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) LRADC_CTRL1_TOUCH_DETECT_IRQ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (!(reg & mxs_lradc_irq_mask(lradc)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (reg & ts_irq_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) spin_lock_irqsave(&ts->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) mxs_lradc_handle_touch(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) spin_unlock_irqrestore(&ts->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /* Make sure we don't clear the next conversion's interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) clr_irq &= ~(LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) writel(reg & clr_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ts->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static int mxs_lradc_ts_open(struct input_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct mxs_lradc_ts *ts = input_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) /* Enable the touch-detect circuitry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) mxs_lradc_enable_touch_detection(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static void mxs_lradc_ts_stop(struct mxs_lradc_ts *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct mxs_lradc *lradc = ts->lradc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* stop all interrupts from firing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) ts->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /* Power-down touchscreen touch-detect circuitry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) writel(info[lradc->soc].mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ts->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) writel(lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) ts->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) for (i = 1; i < LRADC_MAX_DELAY_CHANS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) writel(0, ts->base + LRADC_DELAY(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static void mxs_lradc_ts_close(struct input_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) struct mxs_lradc_ts *ts = input_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) mxs_lradc_ts_stop(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static void mxs_lradc_ts_hw_init(struct mxs_lradc_ts *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct mxs_lradc *lradc = ts->lradc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /* Configure the touchscreen type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (lradc->soc == IMX28_LRADC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) writel(LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) ts->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (lradc->touchscreen_wire == MXS_LRADC_TOUCHSCREEN_5WIRE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) writel(LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) ts->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static int mxs_lradc_ts_register(struct mxs_lradc_ts *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct device *dev = ts->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) input = devm_input_allocate_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (!input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) input->name = "mxs-lradc-ts";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) input->id.bustype = BUS_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) input->open = mxs_lradc_ts_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) input->close = mxs_lradc_ts_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) __set_bit(INPUT_PROP_DIRECT, input->propbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) input_set_capability(input, EV_KEY, BTN_TOUCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) input_set_abs_params(input, ABS_X, 0, LRADC_SINGLE_SAMPLE_MASK, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) input_set_abs_params(input, ABS_Y, 0, LRADC_SINGLE_SAMPLE_MASK, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) input_set_abs_params(input, ABS_PRESSURE, 0, LRADC_SINGLE_SAMPLE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) ts->ts_input = input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) input_set_drvdata(input, ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) return input_register_device(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) static int mxs_lradc_ts_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) struct device_node *node = dev->parent->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) struct mxs_lradc *lradc = dev_get_drvdata(dev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) struct mxs_lradc_ts *ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) int ret, irq, virq, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) u32 ts_wires = 0, adapt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (!ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) platform_set_drvdata(pdev, ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) ts->lradc = lradc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) ts->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) spin_lock_init(&ts->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) ts->base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (IS_ERR(ts->base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return PTR_ERR(ts->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ret = of_property_read_u32(node, "fsl,lradc-touchscreen-wires",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) &ts_wires);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (of_property_read_u32(node, "fsl,ave-ctrl", &adapt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) ts->over_sample_cnt = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (adapt >= 1 && adapt <= 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ts->over_sample_cnt = adapt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) dev_err(ts->dev, "Invalid sample count (%u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) adapt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (of_property_read_u32(node, "fsl,ave-delay", &adapt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) ts->over_sample_delay = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (adapt >= 2 && adapt <= LRADC_DELAY_DELAY_MASK + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) ts->over_sample_delay = adapt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) dev_err(ts->dev, "Invalid sample delay (%u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) adapt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (of_property_read_u32(node, "fsl,settling", &adapt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) ts->settling_delay = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (adapt >= 1 && adapt <= LRADC_DELAY_DELAY_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) ts->settling_delay = adapt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) dev_err(ts->dev, "Invalid settling delay (%u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) adapt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) ret = stmp_reset_block(ts->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) mxs_lradc_ts_hw_init(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) irq = platform_get_irq_byname(pdev, mxs_lradc_ts_irq_names[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) virq = irq_of_parse_and_map(node, irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) mxs_lradc_ts_stop(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) ret = devm_request_irq(dev, virq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) mxs_lradc_ts_handle_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 0, mxs_lradc_ts_irq_names[i], ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return mxs_lradc_ts_register(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static struct platform_driver mxs_lradc_ts_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) .name = "mxs-lradc-ts",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) .probe = mxs_lradc_ts_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) module_platform_driver(mxs_lradc_ts_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) MODULE_DESCRIPTION("Freescale MXS LRADC touchscreen driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) MODULE_ALIAS("platform:mxs-lradc-ts");