^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) * Touchscreen driver for WM831x PMICs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2011 Wolfson Microelectronics plc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mfd/wm831x/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mfd/wm831x/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/mfd/wm831x/pdata.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * R16424 (0x4028) - Touch Control 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define WM831X_TCH_ENA 0x8000 /* TCH_ENA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define WM831X_TCH_CVT_ENA 0x4000 /* TCH_CVT_ENA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define WM831X_TCH_SLPENA 0x1000 /* TCH_SLPENA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define WM831X_TCH_Z_ENA 0x0400 /* TCH_Z_ENA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define WM831X_TCH_Y_ENA 0x0200 /* TCH_Y_ENA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define WM831X_TCH_X_ENA 0x0100 /* TCH_X_ENA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define WM831X_TCH_DELAY_MASK 0x00E0 /* TCH_DELAY - [7:5] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define WM831X_TCH_DELAY_SHIFT 5 /* TCH_DELAY - [7:5] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define WM831X_TCH_DELAY_WIDTH 3 /* TCH_DELAY - [7:5] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define WM831X_TCH_RATE_MASK 0x001F /* TCH_RATE - [4:0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define WM831X_TCH_RATE_SHIFT 0 /* TCH_RATE - [4:0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define WM831X_TCH_RATE_WIDTH 5 /* TCH_RATE - [4:0] */
^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) * R16425 (0x4029) - Touch Control 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define WM831X_TCH_PD_WK 0x2000 /* TCH_PD_WK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define WM831X_TCH_5WIRE 0x1000 /* TCH_5WIRE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define WM831X_TCH_PDONLY 0x0800 /* TCH_PDONLY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define WM831X_TCH_ISEL 0x0100 /* TCH_ISEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define WM831X_TCH_RPU_MASK 0x000F /* TCH_RPU - [3:0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define WM831X_TCH_RPU_SHIFT 0 /* TCH_RPU - [3:0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define WM831X_TCH_RPU_WIDTH 4 /* TCH_RPU - [3:0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * R16426-8 (0x402A-C) - Touch Data X/Y/X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define WM831X_TCH_PD 0x8000 /* TCH_PD1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define WM831X_TCH_DATA_MASK 0x0FFF /* TCH_DATA - [11:0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define WM831X_TCH_DATA_SHIFT 0 /* TCH_DATA - [11:0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define WM831X_TCH_DATA_WIDTH 12 /* TCH_DATA - [11:0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct wm831x_ts {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct input_dev *input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct wm831x *wm831x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unsigned int data_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) unsigned int pd_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) bool pressure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) bool pen_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct work_struct pd_data_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static void wm831x_pd_data_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct wm831x_ts *wm831x_ts =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) container_of(work, struct wm831x_ts, pd_data_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (wm831x_ts->pen_down) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) enable_irq(wm831x_ts->data_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) dev_dbg(wm831x_ts->wm831x->dev, "IRQ PD->DATA done\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) enable_irq(wm831x_ts->pd_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) dev_dbg(wm831x_ts->wm831x->dev, "IRQ DATA->PD done\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct wm831x_ts *wm831x_ts = irq_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct wm831x *wm831x = wm831x_ts->wm831x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static int data_types[] = { ABS_X, ABS_Y, ABS_PRESSURE };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u16 data[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (wm831x_ts->pressure)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) count = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) WM831X_TCHDATA_EINT, WM831X_TCHDATA_EINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ret = wm831x_bulk_read(wm831x, WM831X_TOUCH_DATA_X, count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) dev_err(wm831x->dev, "Failed to read touch data: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^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) * We get a pen down reading on every reading, report pen up if any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * individual reading does so.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) wm831x_ts->pen_down = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (!(data[i] & WM831X_TCH_PD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) wm831x_ts->pen_down = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) input_report_abs(wm831x_ts->input_dev, data_types[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) data[i] & WM831X_TCH_DATA_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (!wm831x_ts->pen_down) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* Switch from data to pen down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) dev_dbg(wm831x->dev, "IRQ DATA->PD\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) disable_irq_nosync(wm831x_ts->data_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* Don't need data any more */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) WM831X_TCH_Z_ENA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* Flush any final samples that arrived while reading */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) WM831X_TCHDATA_EINT, WM831X_TCHDATA_EINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) wm831x_bulk_read(wm831x, WM831X_TOUCH_DATA_X, count, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (wm831x_ts->pressure)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) input_report_abs(wm831x_ts->input_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ABS_PRESSURE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) schedule_work(&wm831x_ts->pd_data_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) input_sync(wm831x_ts->input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return IRQ_HANDLED;
^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) static irqreturn_t wm831x_ts_pen_down_irq(int irq, void *irq_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct wm831x_ts *wm831x_ts = irq_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct wm831x *wm831x = wm831x_ts->wm831x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) int ena = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (wm831x_ts->pen_down)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) disable_irq_nosync(wm831x_ts->pd_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* Start collecting data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (wm831x_ts->pressure)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ena |= WM831X_TCH_Z_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | ena);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) WM831X_TCHPD_EINT, WM831X_TCHPD_EINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) wm831x_ts->pen_down = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* Switch from pen down to data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) dev_dbg(wm831x->dev, "IRQ PD->DATA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) schedule_work(&wm831x_ts->pd_data_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static int wm831x_ts_input_open(struct input_dev *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct wm831x_ts *wm831x_ts = input_get_drvdata(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct wm831x *wm831x = wm831x_ts->wm831x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) WM831X_TCH_ENA | WM831X_TCH_CVT_ENA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) WM831X_TCH_Z_ENA, WM831X_TCH_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) WM831X_TCH_CVT_ENA, WM831X_TCH_CVT_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static void wm831x_ts_input_close(struct input_dev *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct wm831x_ts *wm831x_ts = input_get_drvdata(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct wm831x *wm831x = wm831x_ts->wm831x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* Shut the controller down, disabling all other functionality too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) WM831X_TCH_ENA | WM831X_TCH_X_ENA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* Make sure any pending IRQs are done, the above will prevent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * new ones firing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) synchronize_irq(wm831x_ts->data_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) synchronize_irq(wm831x_ts->pd_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* Make sure the IRQ completion work is quiesced */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) flush_work(&wm831x_ts->pd_data_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /* If we ended up with the pen down then make sure we revert back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * to pen detection state for the next time we start up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (wm831x_ts->pen_down) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) disable_irq(wm831x_ts->data_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) enable_irq(wm831x_ts->pd_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) wm831x_ts->pen_down = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static int wm831x_ts_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct wm831x_ts *wm831x_ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct wm831x_pdata *core_pdata = dev_get_platdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct wm831x_touch_pdata *pdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct input_dev *input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) int error, irqf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (core_pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) pdata = core_pdata->touch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) wm831x_ts = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) input_dev = devm_input_allocate_device(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (!wm831x_ts || !input_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) goto err_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) wm831x_ts->wm831x = wm831x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) wm831x_ts->input_dev = input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) INIT_WORK(&wm831x_ts->pd_data_work, wm831x_pd_data_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * If we have a direct IRQ use it, otherwise use the interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * from the WM831x IRQ controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) wm831x_ts->data_irq = wm831x_irq(wm831x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) platform_get_irq_byname(pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) "TCHDATA"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (pdata && pdata->data_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) wm831x_ts->data_irq = pdata->data_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) wm831x_ts->pd_irq = wm831x_irq(wm831x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) platform_get_irq_byname(pdev, "TCHPD"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (pdata && pdata->pd_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) wm831x_ts->pd_irq = pdata->pd_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) wm831x_ts->pressure = pdata->pressure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) wm831x_ts->pressure = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* Five wire touchscreens can't report pressure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (pdata && pdata->fivewire) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) WM831X_TCH_5WIRE, WM831X_TCH_5WIRE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /* Pressure measurements are not possible for five wire mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) WARN_ON(pdata->pressure && pdata->fivewire);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) wm831x_ts->pressure = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) WM831X_TCH_5WIRE, 0);
^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) if (pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) switch (pdata->isel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) dev_err(&pdev->dev, "Unsupported ISEL setting: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) pdata->isel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) case 200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) WM831X_TCH_ISEL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) case 400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) WM831X_TCH_ISEL, WM831X_TCH_ISEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^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) wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) WM831X_TCH_PDONLY, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* Default to 96 samples/sec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) WM831X_TCH_RATE_MASK, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (pdata && pdata->data_irqf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) irqf = pdata->data_irqf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) irqf = IRQF_TRIGGER_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) error = request_threaded_irq(wm831x_ts->data_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) NULL, wm831x_ts_data_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) irqf | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) "Touchscreen data", wm831x_ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) dev_err(&pdev->dev, "Failed to request data IRQ %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) wm831x_ts->data_irq, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) goto err_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) disable_irq(wm831x_ts->data_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (pdata && pdata->pd_irqf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) irqf = pdata->pd_irqf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) irqf = IRQF_TRIGGER_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) error = request_threaded_irq(wm831x_ts->pd_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) NULL, wm831x_ts_pen_down_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) irqf | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) "Touchscreen pen down", wm831x_ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) dev_err(&pdev->dev, "Failed to request pen down IRQ %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) wm831x_ts->pd_irq, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) goto err_data_irq;
^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) /* set up touch configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) input_dev->name = "WM831x touchscreen";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) input_dev->phys = "wm831x";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) input_dev->open = wm831x_ts_input_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) input_dev->close = wm831x_ts_input_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) __set_bit(EV_ABS, input_dev->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) __set_bit(EV_KEY, input_dev->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) __set_bit(BTN_TOUCH, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) input_set_abs_params(input_dev, ABS_X, 0, 4095, 5, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) input_set_abs_params(input_dev, ABS_Y, 0, 4095, 5, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (wm831x_ts->pressure)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) input_set_abs_params(input_dev, ABS_PRESSURE, 0, 4095, 5, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) input_set_drvdata(input_dev, wm831x_ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) input_dev->dev.parent = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) error = input_register_device(input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) goto err_pd_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) platform_set_drvdata(pdev, wm831x_ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) err_pd_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) free_irq(wm831x_ts->pd_irq, wm831x_ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) err_data_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) free_irq(wm831x_ts->data_irq, wm831x_ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) err_alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static int wm831x_ts_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct wm831x_ts *wm831x_ts = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) free_irq(wm831x_ts->pd_irq, wm831x_ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) free_irq(wm831x_ts->data_irq, wm831x_ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static struct platform_driver wm831x_ts_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) .name = "wm831x-touch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .probe = wm831x_ts_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .remove = wm831x_ts_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) module_platform_driver(wm831x_ts_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /* Module information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) MODULE_DESCRIPTION("WM831x PMIC touchscreen driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) MODULE_ALIAS("platform:wm831x-touch");