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