1 /*
2  * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT espressif_esp32_touch
8 
9 #include <zephyr/device.h>
10 #include <zephyr/input/input.h>
11 #include <zephyr/kernel.h>
12 #include <zephyr/logging/log.h>
13 #include <zephyr/drivers/interrupt_controller/intc_esp32.h>
14 
15 #include <esp_err.h>
16 #include <soc/soc_pins.h>
17 #include <soc/periph_defs.h>
18 #include <hal/touch_sensor_types.h>
19 #include <hal/touch_sensor_hal.h>
20 #include <driver/rtc_io.h>
21 #include <esp_intr_alloc.h>
22 
23 LOG_MODULE_REGISTER(espressif_esp32_touch, CONFIG_INPUT_LOG_LEVEL);
24 
25 #define ESP32_SCAN_DONE_MAX_COUNT 5
26 
27 #if defined(CONFIG_SOC_SERIES_ESP32)
28 #define ESP32_RTC_INTR_MSK RTC_CNTL_TOUCH_INT_ST_M
29 #elif defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3)
30 
31 #define ESP32_RTC_INTR_MSK (RTC_CNTL_TOUCH_DONE_INT_ST_M |		\
32 			    RTC_CNTL_TOUCH_ACTIVE_INT_ST_M |		\
33 			    RTC_CNTL_TOUCH_INACTIVE_INT_ST_M |		\
34 			    RTC_CNTL_TOUCH_SCAN_DONE_INT_ST_M |		\
35 			    RTC_CNTL_TOUCH_TIMEOUT_INT_ST_M)
36 
37 #define ESP32_TOUCH_PAD_INTR_MASK (TOUCH_PAD_INTR_MASK_ACTIVE |		\
38 				   TOUCH_PAD_INTR_MASK_INACTIVE |	\
39 				   TOUCH_PAD_INTR_MASK_TIMEOUT |	\
40 				   TOUCH_PAD_INTR_MASK_SCAN_DONE)
41 
42 #endif /* defined(CONFIG_SOC_SERIES_ESP32) */
43 
44 struct esp32_touch_sensor_channel_config {
45 	int32_t channel_num;
46 	int32_t channel_sens;
47 	uint32_t zephyr_code;
48 };
49 
50 struct esp32_touch_sensor_config {
51 	uint32_t debounce_interval_ms;
52 	int num_channels;
53 	int href_microvolt_enum_idx;
54 	int lref_microvolt_enum_idx;
55 	int href_atten_microvolt_enum_idx;
56 	int filter_mode;
57 	int filter_debounce_cnt;
58 	int filter_noise_thr;
59 	int filter_jitter_step;
60 	int filter_smooth_level;
61 	const struct esp32_touch_sensor_channel_config *channel_cfg;
62 	struct esp32_touch_sensor_channel_data *channel_data;
63 };
64 
65 struct esp32_touch_sensor_channel_data {
66 	const struct device *dev;
67 	struct k_work_delayable work;
68 	uint32_t status;
69 #if defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3)
70 	uint32_t last_status;
71 #endif /* defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3) */
72 };
73 
74 struct esp32_touch_sensor_data {
75 };
76 
esp32_touch_sensor_interrupt_cb(void * arg)77 static void esp32_touch_sensor_interrupt_cb(void *arg)
78 {
79 	const struct device *dev = arg;
80 	const struct esp32_touch_sensor_config *dev_cfg = dev->config;
81 	const struct esp32_touch_sensor_channel_config *channel_cfg;
82 	const int num_channels = dev_cfg->num_channels;
83 	uint32_t pad_status;
84 
85 #if defined(CONFIG_SOC_SERIES_ESP32)
86 	touch_hal_intr_clear();
87 
88 #elif defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3)
89 	static uint8_t scan_done_counter;
90 
91 	touch_pad_intr_mask_t intr_mask = touch_hal_read_intr_status_mask();
92 
93 	if (intr_mask & TOUCH_PAD_INTR_MASK_SCAN_DONE) {
94 		if (++scan_done_counter == ESP32_SCAN_DONE_MAX_COUNT) {
95 			touch_hal_intr_disable(TOUCH_PAD_INTR_MASK_SCAN_DONE);
96 			for (int i = 0; i < num_channels; i++) {
97 				channel_cfg = &dev_cfg->channel_cfg[i];
98 
99 				/* Set interrupt threshold */
100 				uint32_t benchmark_value;
101 
102 				touch_hal_read_benchmark(channel_cfg->channel_num,
103 					&benchmark_value);
104 				touch_hal_set_threshold(channel_cfg->channel_num,
105 					channel_cfg->channel_sens * benchmark_value / 100);
106 			}
107 		}
108 		return;
109 	}
110 #endif /* defined(CONFIG_SOC_SERIES_ESP32) */
111 
112 	touch_hal_read_trigger_status_mask(&pad_status);
113 #if defined(CONFIG_SOC_SERIES_ESP32)
114 	touch_hal_clear_trigger_status_mask();
115 #endif /* defined(CONFIG_SOC_SERIES_ESP32) */
116 	for (int i = 0; i < num_channels; i++) {
117 		uint32_t channel_status;
118 
119 		channel_cfg = &dev_cfg->channel_cfg[i];
120 		channel_status = (pad_status >> channel_cfg->channel_num) & 0x01;
121 
122 #if defined(CONFIG_SOC_SERIES_ESP32)
123 		if (channel_status != 0) {
124 #elif defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3)
125 		uint32_t channel_num = (uint32_t)touch_hal_get_current_meas_channel();
126 
127 		if (channel_cfg->channel_num == channel_num) {
128 #endif /* CONFIG_SOC_SERIES_ESP32 */
129 			struct esp32_touch_sensor_channel_data
130 				*channel_data = &dev_cfg->channel_data[i];
131 
132 			channel_data->status = channel_status;
133 			(void)k_work_reschedule(&channel_data->work,
134 						K_MSEC(dev_cfg->debounce_interval_ms));
135 		}
136 	}
137 }
138 
139 static void esp32_touch_rtc_isr(void *arg)
140 {
141 	uint32_t status = REG_READ(RTC_CNTL_INT_ST_REG);
142 
143 	if (!(status & ESP32_RTC_INTR_MSK)) {
144 		return;
145 	}
146 
147 	esp32_touch_sensor_interrupt_cb(arg);
148 	REG_WRITE(RTC_CNTL_INT_CLR_REG, status);
149 }
150 
151 
152 /**
153  * Handle debounced touch sensor touch state.
154  */
155 static void esp32_touch_sensor_change_deferred(struct k_work *work)
156 {
157 	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
158 	struct esp32_touch_sensor_channel_data *channel_data =
159 			CONTAINER_OF(dwork, struct esp32_touch_sensor_channel_data, work);
160 	const struct device *dev = channel_data->dev;
161 	const struct esp32_touch_sensor_config *dev_cfg = dev->config;
162 	int key_index = channel_data - &dev_cfg->channel_data[0];
163 	const struct esp32_touch_sensor_channel_config
164 		*channel_cfg = &dev_cfg->channel_cfg[key_index];
165 
166 #if defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3)
167 	if (channel_data->last_status != channel_data->status) {
168 #endif /* defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3) */
169 		input_report_key(dev, channel_cfg->zephyr_code,
170 				channel_data->status, true, K_FOREVER);
171 #if defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3)
172 		channel_data->last_status = channel_data->status;
173 	}
174 #endif /* defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3) */
175 }
176 
177 static int esp32_touch_sensor_init(const struct device *dev)
178 {
179 	esp_err_t err, flags;
180 
181 	const struct esp32_touch_sensor_config *dev_cfg = dev->config;
182 	const int num_channels = dev_cfg->num_channels;
183 
184 	touch_hal_init();
185 
186 #if defined(CONFIG_SOC_SERIES_ESP32)
187 	touch_hal_volt_t volt = {
188 		.refh = dev_cfg->href_microvolt_enum_idx,
189 		.refh = dev_cfg->href_microvolt_enum_idx,
190 		.atten = dev_cfg->href_atten_microvolt_enum_idx
191 	};
192 
193 	touch_hal_set_voltage(&volt);
194 	touch_hal_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
195 #endif /* defined(CONFIG_SOC_SERIES_ESP32) */
196 
197 	for (int i = 0; i < num_channels; i++) {
198 		struct esp32_touch_sensor_channel_data *channel_data = &dev_cfg->channel_data[i];
199 		const struct esp32_touch_sensor_channel_config *channel_cfg =
200 			&dev_cfg->channel_cfg[i];
201 
202 		if (!(channel_cfg->channel_num > 0 &&
203 			channel_cfg->channel_num < SOC_TOUCH_SENSOR_NUM)) {
204 			LOG_ERR("Touch %d configuration failed: "
205 				"Touch channel error", i);
206 			return -EINVAL;
207 		}
208 
209 #if defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3)
210 		if (channel_cfg->channel_num == SOC_TOUCH_DENOISE_CHANNEL) {
211 			LOG_ERR("Touch %d configuration failed: "
212 				"TOUCH0 is internal denoise channel", i);
213 			return -EINVAL;
214 		}
215 #endif  /* defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3) */
216 
217 		gpio_num_t gpio_num = touch_sensor_channel_io_map[channel_cfg->channel_num];
218 
219 		rtc_gpio_init(gpio_num);
220 		rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED);
221 		rtc_gpio_pulldown_dis(gpio_num);
222 		rtc_gpio_pullup_dis(gpio_num);
223 
224 		touch_hal_config(channel_cfg->channel_num);
225 #if defined(CONFIG_SOC_SERIES_ESP32)
226 		touch_hal_set_threshold(channel_cfg->channel_num, 0);
227 		touch_hal_set_group_mask(BIT(channel_cfg->channel_num),
228 					 BIT(channel_cfg->channel_num));
229 #endif /* defined(CONFIG_SOC_SERIES_ESP32) */
230 		touch_hal_set_channel_mask(BIT(channel_cfg->channel_num));
231 
232 		channel_data->status = 0;
233 #if defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3)
234 		channel_data->last_status = 0;
235 #endif /* defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3) */
236 		channel_data->dev = dev;
237 
238 		k_work_init_delayable(&channel_data->work, esp32_touch_sensor_change_deferred);
239 	}
240 
241 #if defined(CONFIG_SOC_SERIES_ESP32)
242 	for (int i = 0; i < num_channels; i++) {
243 		const struct esp32_touch_sensor_channel_config *channel_cfg =
244 			&dev_cfg->channel_cfg[i];
245 		uint32_t ref_time;
246 
247 		ref_time = k_uptime_get_32();
248 		while (!touch_hal_meas_is_done()) {
249 			if (k_uptime_get_32() - ref_time > 500) {
250 				return -ETIMEDOUT;
251 			}
252 			k_busy_wait(1000);
253 		}
254 		uint16_t touch_value = touch_hal_read_raw_data(channel_cfg->channel_num);
255 
256 		touch_hal_set_threshold(channel_cfg->channel_num,
257 					touch_value * (100 - channel_cfg->channel_num) / 100);
258 	}
259 
260 #elif defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3)
261 	touch_filter_config_t filter_info = {
262 		.mode = dev_cfg->filter_mode,
263 		.debounce_cnt = dev_cfg->filter_debounce_cnt,
264 		.noise_thr = dev_cfg->filter_noise_thr,
265 		.jitter_step = dev_cfg->filter_jitter_step,
266 		.smh_lvl = dev_cfg->filter_smooth_level,
267 	};
268 	touch_hal_filter_set_config(&filter_info);
269 	touch_hal_filter_enable();
270 
271 	touch_hal_timeout_enable();
272 	touch_hal_timeout_set_threshold(SOC_TOUCH_PAD_THRESHOLD_MAX);
273 #endif /* defined(CONFIG_SOC_SERIES_ESP32) */
274 
275 	flags = ESP_PRIO_TO_FLAGS(DT_IRQ_BY_IDX(DT_NODELABEL(touch), 0, priority)) |
276 		ESP_INT_FLAGS_CHECK(DT_IRQ_BY_IDX(DT_NODELABEL(touch), 0, flags)) |
277 		ESP_INTR_FLAG_SHARED;
278 	err = esp_intr_alloc(DT_IRQ_BY_IDX(DT_NODELABEL(touch), 0, irq), flags, esp32_touch_rtc_isr,
279 			     (void *)dev, NULL);
280 	if (err) {
281 		LOG_ERR("Failed to register ISR\n");
282 		return -EFAULT;
283 	}
284 
285 #if defined(CONFIG_SOC_SERIES_ESP32)
286 	touch_hal_intr_enable();
287 #elif defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3)
288 	touch_hal_intr_enable(ESP32_TOUCH_PAD_INTR_MASK);
289 	touch_hal_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
290 #endif /* defined(CONFIG_SOC_SERIES_ESP32) */
291 
292 	touch_hal_start_fsm();
293 
294 	return 0;
295 }
296 
297 #define ESP32_TOUCH_SENSOR_CHANNEL_CFG_INIT(node_id)						\
298 	{											\
299 		.channel_num  = DT_PROP(node_id, channel_num),					\
300 		.channel_sens = DT_PROP(node_id, channel_sens),					\
301 		.zephyr_code  = DT_PROP(node_id, zephyr_code),					\
302 	}
303 
304 #define ESP32_TOUCH_SENSOR_INIT(inst)								\
305 	static const struct esp32_touch_sensor_channel_config					\
306 		esp32_touch_sensor_channel_config_##inst[] = {					\
307 			DT_INST_FOREACH_CHILD_STATUS_OKAY_SEP(inst,				\
308 				ESP32_TOUCH_SENSOR_CHANNEL_CFG_INIT, (,))			\
309 		};										\
310 												\
311 	static struct esp32_touch_sensor_channel_data esp32_touch_sensor_channel_data_##inst	\
312 				[ARRAY_SIZE(esp32_touch_sensor_channel_config_##inst)];		\
313 												\
314 	static const struct esp32_touch_sensor_config esp32_touch_sensor_config_##inst = {	\
315 		.debounce_interval_ms = DT_INST_PROP(inst, debounce_interval_ms),		\
316 		.num_channels = ARRAY_SIZE(esp32_touch_sensor_channel_config_##inst),		\
317 		.href_microvolt_enum_idx = DT_INST_ENUM_IDX(inst, href_microvolt),		\
318 		.lref_microvolt_enum_idx = DT_INST_ENUM_IDX(inst, lref_microvolt),		\
319 		.href_atten_microvolt_enum_idx = DT_INST_ENUM_IDX(inst, href_atten_microvolt),	\
320 		.filter_mode = DT_INST_PROP(inst, filter_mode),					\
321 		.filter_debounce_cnt = DT_INST_PROP(inst, filter_debounce_cnt),			\
322 		.filter_noise_thr = DT_INST_PROP(inst, filter_noise_thr),			\
323 		.filter_jitter_step = DT_INST_PROP(inst, filter_jitter_step),			\
324 		.filter_smooth_level = DT_INST_PROP(inst, filter_smooth_level),			\
325 		.channel_cfg = esp32_touch_sensor_channel_config_##inst,			\
326 		.channel_data = esp32_touch_sensor_channel_data_##inst,				\
327 	};											\
328 												\
329 	static struct esp32_touch_sensor_data esp32_touch_sensor_data_##inst;			\
330 												\
331 	DEVICE_DT_INST_DEFINE(inst,								\
332 			      &esp32_touch_sensor_init,						\
333 			      NULL,								\
334 			      &esp32_touch_sensor_data_##inst,					\
335 			      &esp32_touch_sensor_config_##inst,				\
336 			      POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY,				\
337 			      NULL);
338 
339 DT_INST_FOREACH_STATUS_OKAY(ESP32_TOUCH_SENSOR_INIT)
340