1 /*
2  * Copyright (c) 2021 Linumiz
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/init.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/drivers/gpio.h>
10 #include <zephyr/drivers/sensor.h>
11 #include <zephyr/drivers/uart.h>
12 #include <zephyr/sys/byteorder.h>
13 #include <zephyr/drivers/led.h>
14 #include <zephyr/sys/util.h>
15 
16 #include <zephyr/drivers/sensor/grow_r502a.h>
17 #include "grow_r502a.h"
18 
19 #include <zephyr/logging/log.h>
20 LOG_MODULE_REGISTER(GROW_R502A, CONFIG_SENSOR_LOG_LEVEL);
21 
transceive_packet(const struct device * dev,union r502a_packet * tx_packet,union r502a_packet * rx_packet,uint16_t data_len)22 static int transceive_packet(const struct device *dev, union r502a_packet *tx_packet,
23 				union r502a_packet *rx_packet, uint16_t data_len)
24 {
25 	const struct grow_r502a_config *cfg = dev->config;
26 	struct grow_r502a_data *drv_data = dev->data;
27 
28 	if (tx_packet) {
29 		uint16_t check_sum, pkg_len;
30 
31 		pkg_len = data_len + R502A_CHECKSUM_LEN;
32 		check_sum = (pkg_len >> 8) + (pkg_len & 0xFF) + tx_packet->pid;
33 
34 		tx_packet->start = sys_cpu_to_be16(R502A_STARTCODE);
35 		tx_packet->addr = sys_cpu_to_be32(cfg->comm_addr);
36 		tx_packet->len = sys_cpu_to_be16(pkg_len);
37 
38 		for (int i = 0; i < data_len; i++) {
39 			check_sum += tx_packet->data[i];
40 		}
41 		sys_put_be16(check_sum, &tx_packet->buf[data_len + R502A_HEADER_LEN]);
42 
43 		drv_data->tx_buf.len = pkg_len + R502A_HEADER_LEN;
44 		drv_data->tx_buf.data = tx_packet->buf;
45 
46 		LOG_HEXDUMP_DBG(drv_data->tx_buf.data, drv_data->tx_buf.len, "TX");
47 
48 		uart_irq_tx_enable(cfg->dev);
49 
50 		if (k_sem_take(&drv_data->uart_tx_sem, K_MSEC(1500)) != 0) {
51 			LOG_ERR("Tx data timeout");
52 			return -ETIMEDOUT;
53 		}
54 	}
55 
56 	if (rx_packet) {
57 		drv_data->rx_buf.data = rx_packet->buf;
58 		drv_data->rx_buf.len = 0;
59 		drv_data->pkt_len = R502A_HEADER_LEN;
60 		uart_irq_rx_enable(cfg->dev);
61 		if (k_sem_take(&drv_data->uart_rx_sem, K_MSEC(1500)) != 0) {
62 			LOG_ERR("Rx data timeout");
63 			return -ETIMEDOUT;
64 		}
65 	}
66 
67 	return 0;
68 }
69 
r502a_validate_rx_packet(union r502a_packet * rx_packet)70 static int r502a_validate_rx_packet(union r502a_packet *rx_packet)
71 {
72 	uint16_t recv_cks = 0, calc_cks = 0;
73 	uint8_t cks_start_idx;
74 
75 	if (sys_be16_to_cpu(rx_packet->start) == R502A_STARTCODE) {
76 		LOG_DBG("startcode matched 0x%X", sys_be16_to_cpu(rx_packet->start));
77 	} else {
78 		LOG_ERR("startcode didn't match 0x%X", sys_be16_to_cpu(rx_packet->start));
79 		return -EINVAL;
80 	}
81 
82 	if (sys_be32_to_cpu(rx_packet->addr) == R502A_DEFAULT_ADDRESS) {
83 		LOG_DBG("Address matched 0x%X", sys_be32_to_cpu(rx_packet->addr));
84 	} else {
85 		LOG_ERR("Address didn't match 0x%X", sys_be32_to_cpu(rx_packet->addr));
86 		return -EINVAL;
87 	}
88 
89 	switch (rx_packet->pid) {
90 	case R502A_DATA_PACKET:
91 		LOG_DBG("Data Packet Received 0x%X", rx_packet->pid);
92 		break;
93 	case R502A_END_DATA_PACKET:
94 		LOG_DBG("End of Data Packet Received 0x%X", rx_packet->pid);
95 		break;
96 	case R502A_ACK_PACKET:
97 		LOG_DBG("Acknowledgment Packet Received 0x%X", rx_packet->pid);
98 		break;
99 	default:
100 		LOG_ERR("Error Package ID 0x%X", rx_packet->pid);
101 		return -EINVAL;
102 	}
103 
104 	cks_start_idx = sys_be16_to_cpu(rx_packet->len) - R502A_CHECKSUM_LEN;
105 
106 	recv_cks = sys_get_be16(&rx_packet->data[cks_start_idx]);
107 
108 	calc_cks += rx_packet->pid + (sys_be16_to_cpu(rx_packet->len) >> 8) +
109 					(sys_be16_to_cpu(rx_packet->len) & 0xFF);
110 
111 	for (int i = 0; i < cks_start_idx; i++) {
112 		calc_cks += rx_packet->data[i];
113 	}
114 
115 	if (recv_cks == calc_cks) {
116 		LOG_DBG("Checksum matched calculated 0x%x received 0x%x", calc_cks, recv_cks);
117 	} else {
118 		LOG_ERR("Checksum mismatch calculated 0x%x received 0x%x", calc_cks, recv_cks);
119 		return -EINVAL;
120 	}
121 
122 	return 0;
123 }
124 
uart_cb_tx_handler(const struct device * dev)125 static void uart_cb_tx_handler(const struct device *dev)
126 {
127 	const struct grow_r502a_config *config = dev->config;
128 	struct grow_r502a_data *drv_data = dev->data;
129 	int sent = 0;
130 
131 	if (drv_data->tx_buf.len > 0) {
132 		sent = uart_fifo_fill(config->dev, drv_data->tx_buf.data,
133 							drv_data->tx_buf.len);
134 		drv_data->tx_buf.data += sent;
135 		drv_data->tx_buf.len -= sent;
136 	}
137 
138 	if (!drv_data->tx_buf.len && uart_irq_tx_complete(config->dev) > 0) {
139 		uart_irq_tx_disable(config->dev);
140 		k_sem_give(&drv_data->uart_tx_sem);
141 		return;
142 	}
143 }
144 
uart_cb_handler(const struct device * dev,void * user_data)145 static void uart_cb_handler(const struct device *dev, void *user_data)
146 {
147 	const struct device *uart_dev = user_data;
148 	struct grow_r502a_data *drv_data = uart_dev->data;
149 	int len = 0;
150 	int offset = drv_data->rx_buf.len;
151 
152 	if ((uart_irq_update(dev) > 0) && (uart_irq_is_pending(dev) > 0)) {
153 		if (uart_irq_tx_ready(dev)) {
154 			uart_cb_tx_handler(uart_dev);
155 		}
156 
157 		while (uart_irq_rx_ready(dev)) {
158 			len = uart_fifo_read(dev, &drv_data->rx_buf.data[offset],
159 								drv_data->pkt_len);
160 			offset += len;
161 			drv_data->rx_buf.len = offset;
162 
163 			if (drv_data->pkt_len != len) {
164 				drv_data->pkt_len -= len;
165 				continue;
166 			}
167 
168 			if (offset == R502A_HEADER_LEN) {
169 				drv_data->pkt_len = sys_get_be16(
170 							&drv_data->rx_buf.data[R502A_PKG_LEN_IDX]
171 							);
172 				continue;
173 			}
174 
175 			LOG_HEXDUMP_DBG(drv_data->rx_buf.data, offset, "RX");
176 			uart_irq_rx_disable(dev);
177 			k_sem_give(&drv_data->uart_rx_sem);
178 			break;
179 		}
180 	}
181 }
182 
183 /**
184  * @brief	Set sensor device's basic parameters like baud rate, security level
185  *		and data package length.
186  */
fps_set_sys_param(const struct device * dev,const struct sensor_value * val)187 static int fps_set_sys_param(const struct device *dev, const struct sensor_value *val)
188 {
189 	union r502a_packet rx_packet = {0};
190 	int ret = 0;
191 	char const set_sys_param_len = 3;
192 
193 	union r502a_packet tx_packet = {
194 		.pid = R502A_COMMAND_PACKET,
195 		.data = { R502A_SETSYSPARAM, val->val1, val->val2}
196 	};
197 
198 	ret = transceive_packet(dev, &tx_packet, &rx_packet, set_sys_param_len);
199 	if (ret != 0) {
200 		return ret;
201 	}
202 
203 	ret = r502a_validate_rx_packet(&rx_packet);
204 	if (ret != 0) {
205 		return ret;
206 	}
207 
208 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
209 		LOG_DBG("R502A set system parameter success");
210 	} else {
211 		LOG_ERR("R502A set system parameter error %d", rx_packet.buf[R502A_CC_IDX]);
212 		return -EIO;
213 	}
214 
215 	return 0;
216 }
217 
r502a_read_sys_param(const struct device * dev,struct r502a_sys_param * val)218 int r502a_read_sys_param(const struct device *dev, struct r502a_sys_param *val)
219 {
220 	struct grow_r502a_data *drv_data = dev->data;
221 
222 	union r502a_packet rx_packet = {0};
223 	int offset = 0, ret = 0;
224 	char const read_sys_param_len = 1;
225 
226 	union r502a_packet tx_packet = {
227 		.pid = R502A_COMMAND_PACKET,
228 		.data = {R502A_READSYSPARAM}
229 	};
230 
231 	k_mutex_lock(&drv_data->lock, K_FOREVER);
232 
233 	ret = transceive_packet(dev, &tx_packet, &rx_packet, read_sys_param_len);
234 	if (ret != 0) {
235 		goto unlock;
236 	}
237 
238 	ret = r502a_validate_rx_packet(&rx_packet);
239 	if (ret != 0) {
240 		goto unlock;
241 	}
242 
243 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
244 		LOG_DBG("R502A read system parameter success");
245 	} else {
246 		LOG_ERR("R502A read system parameter error %d", rx_packet.buf[R502A_CC_IDX]);
247 		ret = -EIO;
248 		goto unlock;
249 	}
250 
251 	val->status_reg = sys_get_be16(
252 				&rx_packet.data[offsetof(struct r502a_sys_param, status_reg) + 1]
253 				);
254 	val->system_id = sys_get_be16(
255 				&rx_packet.data[offsetof(struct r502a_sys_param, system_id) + 1]
256 				);
257 	val->lib_size = sys_get_be16(
258 				&rx_packet.data[offsetof(struct r502a_sys_param, lib_size) + 1]
259 				);
260 	val->sec_level = sys_get_be16(
261 				&rx_packet.data[offsetof(struct r502a_sys_param, sec_level) + 1]
262 				);
263 	val->addr = sys_get_be32(
264 			&rx_packet.data[offsetof(struct r502a_sys_param, addr) + 1]
265 			);
266 	offset = sys_get_be16(
267 			&rx_packet.data[offsetof(struct r502a_sys_param, data_pkt_size) + 1]
268 			);
269 	val->data_pkt_size = 32 * (1 << offset);
270 	val->baud = sys_get_be16(
271 			&rx_packet.data[offsetof(struct r502a_sys_param, baud) + 1]
272 			) * 9600;
273 
274 unlock:
275 	k_mutex_unlock(&drv_data->lock);
276 	return ret;
277 }
278 
fps_led_control(const struct device * dev,struct r502a_led_params * led_control)279 static int fps_led_control(const struct device *dev, struct r502a_led_params *led_control)
280 {
281 	union r502a_packet rx_packet = {0};
282 	char const led_ctrl_len = 5;
283 	int ret = 0;
284 
285 	union r502a_packet tx_packet = {
286 		.pid = R502A_COMMAND_PACKET,
287 		.data = { R502A_LED_CONFIG, led_control->ctrl_code,
288 				led_control->speed, led_control->color_idx, led_control->cycle}
289 	};
290 
291 	ret = transceive_packet(dev, &tx_packet, &rx_packet, led_ctrl_len);
292 	if (ret != 0) {
293 		return ret;
294 	}
295 
296 	ret = r502a_validate_rx_packet(&rx_packet);
297 	if (ret != 0) {
298 		return ret;
299 	}
300 
301 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
302 		LOG_DBG("R502A LED ON");
303 		k_sleep(K_MSEC(R502A_DELAY));
304 	} else {
305 		LOG_ERR("R502A LED control error %d", rx_packet.buf[R502A_CC_IDX]);
306 		return -EIO;
307 	}
308 
309 	return 0;
310 }
311 
fps_verify_password(const struct device * dev)312 static int fps_verify_password(const struct device *dev)
313 {
314 	union r502a_packet rx_packet = {0};
315 	char const verify_pwd_len = 5;
316 	int ret = 0;
317 
318 	union r502a_packet tx_packet = {
319 		.pid = R502A_COMMAND_PACKET,
320 		.data[0] = R502A_VERIFYPASSWORD,
321 	};
322 
323 	sys_put_be32(R502A_DEFAULT_PASSWORD, &tx_packet.data[1]);
324 
325 	ret = transceive_packet(dev, &tx_packet, &rx_packet, verify_pwd_len);
326 	if (ret != 0) {
327 		return ret;
328 	}
329 
330 	ret = r502a_validate_rx_packet(&rx_packet);
331 	if (ret != 0) {
332 		return ret;
333 	}
334 
335 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
336 		LOG_DBG("Correct password, R502A verified");
337 	} else {
338 		LOG_ERR("Password verification error 0x%X", rx_packet.buf[R502A_CC_IDX]);
339 		return -EIO;
340 	}
341 
342 	return 0;
343 }
344 
fps_get_template_count(const struct device * dev)345 static int fps_get_template_count(const struct device *dev)
346 {
347 	struct grow_r502a_data *drv_data = dev->data;
348 	union r502a_packet rx_packet = {0};
349 	char const get_temp_cnt_len = 1;
350 	int ret = 0;
351 
352 	union r502a_packet tx_packet = {
353 		.pid = R502A_COMMAND_PACKET,
354 		.data = {R502A_TEMPLATECOUNT},
355 	};
356 
357 	ret = transceive_packet(dev, &tx_packet, &rx_packet, get_temp_cnt_len);
358 	if (ret != 0) {
359 		return ret;
360 	}
361 
362 	ret = r502a_validate_rx_packet(&rx_packet);
363 	if (ret != 0) {
364 		return ret;
365 	}
366 
367 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
368 		LOG_DBG("Read success");
369 		drv_data->template_count = sys_get_be16(&rx_packet.data[1]);
370 		LOG_INF("Remaining templates count : %d", drv_data->template_count);
371 	} else {
372 		LOG_ERR("R502A template count get error");
373 		return -EIO;
374 	}
375 
376 	return 0;
377 }
378 
fps_read_template_table(const struct device * dev,uint32_t * free_idx)379 static int fps_read_template_table(const struct device *dev, uint32_t *free_idx)
380 {
381 	struct grow_r502a_data *drv_data = dev->data;
382 	union r502a_packet rx_packet = {0};
383 	char const temp_table_len = 2;
384 	int ret = 0;
385 
386 	union r502a_packet tx_packet = {
387 		.pid = R502A_COMMAND_PACKET,
388 		.data = {R502A_READTEMPLATEINDEX, 0x00}
389 	};
390 
391 	k_mutex_lock(&drv_data->lock, K_FOREVER);
392 
393 	ret = transceive_packet(dev, &tx_packet, &rx_packet, temp_table_len);
394 	if (ret != 0) {
395 		goto unlock;
396 	}
397 
398 	ret = r502a_validate_rx_packet(&rx_packet);
399 	if (ret != 0) {
400 		goto unlock;
401 	}
402 
403 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
404 		LOG_DBG("Read success");
405 	} else {
406 		LOG_ERR("R502A template table get error");
407 		ret = -EIO;
408 		goto unlock;
409 	}
410 
411 	for (int group_idx = 0; group_idx < R502A_TEMP_TABLE_BUF_SIZE; group_idx++) {
412 		uint8_t group = rx_packet.data[group_idx + 1];
413 
414 		/* if group is all occupied */
415 		if (group == 0xff) {
416 			continue;
417 		}
418 
419 		*free_idx = (group_idx * 8) + find_lsb_set(~group) - 1;
420 		goto unlock;
421 	}
422 
423 unlock:
424 	k_mutex_unlock(&drv_data->lock);
425 	return ret;
426 }
427 
fps_get_image(const struct device * dev)428 static int fps_get_image(const struct device *dev)
429 {
430 	union r502a_packet rx_packet = {0};
431 	char const get_img_len = 1;
432 	int ret = 0;
433 
434 	struct r502a_led_params led_ctrl = {
435 		.ctrl_code = R502A_LED_CTRL_BREATHING,
436 		.color_idx = R502A_LED_COLOR_BLUE,
437 		.speed = R502A_LED_SPEED_HALF,
438 		.cycle = 0x01,
439 	};
440 
441 	union r502a_packet tx_packet = {
442 		.pid = R502A_COMMAND_PACKET,
443 		.data = {R502A_GENIMAGE},
444 	};
445 
446 	ret = transceive_packet(dev, &tx_packet, &rx_packet, get_img_len);
447 	if (ret != 0) {
448 		return ret;
449 	}
450 
451 	ret = r502a_validate_rx_packet(&rx_packet);
452 	if (ret != 0) {
453 		return ret;
454 	}
455 
456 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
457 		fps_led_control(dev, &led_ctrl);
458 		LOG_DBG("Image taken");
459 	} else {
460 		led_ctrl.ctrl_code = R502A_LED_CTRL_ON_ALWAYS;
461 		led_ctrl.color_idx = R502A_LED_COLOR_RED;
462 		fps_led_control(dev, &led_ctrl);
463 		LOG_ERR("Error getting image 0x%X", rx_packet.buf[R502A_CC_IDX]);
464 		return -EIO;
465 	}
466 
467 	return 0;
468 }
469 
fps_image_to_char(const struct device * dev,uint8_t char_buf_idx)470 static int fps_image_to_char(const struct device *dev, uint8_t char_buf_idx)
471 {
472 	union r502a_packet rx_packet = {0};
473 	char const img_to_char_len = 2;
474 	int ret = 0;
475 
476 	union r502a_packet tx_packet = {
477 		.pid = R502A_COMMAND_PACKET,
478 		.data = {R502A_IMAGE2TZ, char_buf_idx}
479 	};
480 
481 	ret = transceive_packet(dev, &tx_packet, &rx_packet, img_to_char_len);
482 	if (ret != 0) {
483 		return ret;
484 	}
485 
486 	ret = r502a_validate_rx_packet(&rx_packet);
487 	if (ret != 0) {
488 		return ret;
489 	}
490 
491 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
492 		LOG_DBG("Image converted");
493 	} else {
494 		LOG_ERR("Error converting image 0x%X", rx_packet.buf[R502A_CC_IDX]);
495 		return -EIO;
496 	}
497 
498 	return 0;
499 }
500 
fps_create_model(const struct device * dev)501 static int fps_create_model(const struct device *dev)
502 {
503 	union r502a_packet rx_packet = {0};
504 	char const create_model_len = 1;
505 	int ret = 0;
506 
507 	union r502a_packet tx_packet = {
508 		.pid = R502A_COMMAND_PACKET,
509 		.data = {R502A_REGMODEL}
510 	};
511 
512 	ret = transceive_packet(dev, &tx_packet, &rx_packet, create_model_len);
513 	if (ret != 0) {
514 		return ret;
515 	}
516 
517 	ret = r502a_validate_rx_packet(&rx_packet);
518 	if (ret != 0) {
519 		return ret;
520 	}
521 
522 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
523 		LOG_DBG("Model Created");
524 	} else {
525 		LOG_ERR("Error creating model 0x%X", rx_packet.buf[R502A_CC_IDX]);
526 		return -EIO;
527 	}
528 
529 	return 0;
530 }
531 
fps_store_model(const struct device * dev,uint16_t id)532 static int fps_store_model(const struct device *dev, uint16_t id)
533 {
534 	struct grow_r502a_data *drv_data = dev->data;
535 	union r502a_packet rx_packet = {0};
536 	char const store_model_len = 4;
537 	int ret = 0;
538 
539 	struct r502a_led_params led_ctrl = {
540 		.ctrl_code = R502A_LED_CTRL_BREATHING,
541 		.color_idx = R502A_LED_COLOR_BLUE,
542 		.speed = R502A_LED_SPEED_HALF,
543 		.cycle = 0x01,
544 	};
545 
546 	union r502a_packet tx_packet = {
547 		.pid = R502A_COMMAND_PACKET,
548 		.data = {R502A_STORE, R502A_CHAR_BUF_1}
549 	};
550 	sys_put_be16(id, &tx_packet.data[2]);
551 
552 	k_mutex_lock(&drv_data->lock, K_FOREVER);
553 
554 	ret = transceive_packet(dev, &tx_packet, &rx_packet, store_model_len);
555 	if (ret != 0) {
556 		goto unlock;
557 	}
558 
559 	ret = r502a_validate_rx_packet(&rx_packet);
560 	if (ret != 0) {
561 		goto unlock;
562 	}
563 
564 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
565 		led_ctrl.color_idx = R502A_LED_COLOR_BLUE;
566 		led_ctrl.ctrl_code = R502A_LED_CTRL_FLASHING;
567 		led_ctrl.cycle = 0x03;
568 		fps_led_control(dev, &led_ctrl);
569 		LOG_INF("Fingerprint stored! at ID #%d", id);
570 	} else {
571 		LOG_ERR("Error storing model 0x%X", rx_packet.buf[R502A_CC_IDX]);
572 		ret = -EIO;
573 	}
574 unlock:
575 	k_mutex_unlock(&drv_data->lock);
576 	return ret;
577 }
578 
fps_delete_model(const struct device * dev,uint16_t id,uint16_t count)579 static int fps_delete_model(const struct device *dev, uint16_t id, uint16_t count)
580 {
581 	struct grow_r502a_data *drv_data = dev->data;
582 	union r502a_packet rx_packet = {0};
583 	char const delete_model_len = 5;
584 	int ret = 0;
585 
586 	union r502a_packet tx_packet = {
587 		.pid = R502A_COMMAND_PACKET,
588 		.data = {R502A_DELETE}
589 	};
590 	sys_put_be16(id, &tx_packet.data[1]);
591 	sys_put_be16(count + R502A_DELETE_COUNT_OFFSET, &tx_packet.data[3]);
592 
593 	k_mutex_lock(&drv_data->lock, K_FOREVER);
594 
595 	ret = transceive_packet(dev, &tx_packet, &rx_packet, delete_model_len);
596 	if (ret != 0) {
597 		goto unlock;
598 	}
599 
600 	ret = r502a_validate_rx_packet(&rx_packet);
601 	if (ret != 0) {
602 		goto unlock;
603 	}
604 
605 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
606 		LOG_INF("Fingerprint Deleted from ID #%d to #%d", id, (id + count));
607 	} else {
608 		LOG_ERR("Error deleting image 0x%X", rx_packet.buf[R502A_CC_IDX]);
609 		ret = -EIO;
610 	}
611 unlock:
612 	k_mutex_unlock(&drv_data->lock);
613 	return ret;
614 }
615 
fps_empty_db(const struct device * dev)616 static int fps_empty_db(const struct device *dev)
617 {
618 	struct grow_r502a_data *drv_data = dev->data;
619 	union r502a_packet rx_packet = {0};
620 	char const empty_db_len = 1;
621 	int ret = 0;
622 
623 	union r502a_packet tx_packet = {
624 		.pid = R502A_COMMAND_PACKET,
625 		.data = {R502A_EMPTYLIBRARY}
626 	};
627 
628 	k_mutex_lock(&drv_data->lock, K_FOREVER);
629 
630 	ret = transceive_packet(dev, &tx_packet, &rx_packet, empty_db_len);
631 	if (ret != 0) {
632 		goto unlock;
633 	}
634 
635 	ret = r502a_validate_rx_packet(&rx_packet);
636 	if (ret != 0) {
637 		goto unlock;
638 	}
639 
640 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
641 		LOG_INF("Emptied Fingerprint Library");
642 	} else {
643 		LOG_ERR("Error emptying fingerprint library 0x%X",
644 					rx_packet.buf[R502A_CC_IDX]);
645 		ret = -EIO;
646 	}
647 
648 unlock:
649 	k_mutex_unlock(&drv_data->lock);
650 	return ret;
651 }
652 
fps_search(const struct device * dev,struct sensor_value * val)653 static int fps_search(const struct device *dev, struct sensor_value *val)
654 {
655 	struct grow_r502a_data *drv_data = dev->data;
656 	union r502a_packet rx_packet = {0};
657 	char const search_len = 6;
658 	int ret = 0;
659 
660 	struct r502a_led_params led_ctrl = {
661 		.ctrl_code = R502A_LED_CTRL_BREATHING,
662 		.color_idx = R502A_LED_COLOR_BLUE,
663 		.speed = R502A_LED_SPEED_HALF,
664 		.cycle = 0x01,
665 	};
666 
667 	union r502a_packet tx_packet = {
668 		.pid = R502A_COMMAND_PACKET,
669 		.data = {R502A_SEARCH, R502A_CHAR_BUF_1}
670 	};
671 	sys_put_be16(R02A_LIBRARY_START_IDX, &tx_packet.data[2]);
672 	sys_put_be16(R502A_DEFAULT_CAPACITY, &tx_packet.data[4]);
673 
674 	k_mutex_lock(&drv_data->lock, K_FOREVER);
675 
676 	ret = transceive_packet(dev, &tx_packet, &rx_packet, search_len);
677 	if (ret != 0) {
678 		goto unlock;
679 	}
680 
681 	ret = r502a_validate_rx_packet(&rx_packet);
682 	if (ret != 0) {
683 		goto unlock;
684 	}
685 
686 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
687 		led_ctrl.ctrl_code = R502A_LED_CTRL_FLASHING;
688 		led_ctrl.color_idx = R502A_LED_COLOR_PURPLE;
689 		led_ctrl.cycle = 0x01;
690 		fps_led_control(dev, &led_ctrl);
691 		val->val1 = sys_get_be16(&rx_packet.data[1]);
692 		val->val2 = sys_get_be16(&rx_packet.data[3]);
693 		LOG_INF("Found a matching print! at ID #%d", val->val1);
694 	} else if (rx_packet.buf[R502A_CC_IDX] == R502A_NOT_FOUND_CC) {
695 		led_ctrl.ctrl_code = R502A_LED_CTRL_BREATHING;
696 		led_ctrl.color_idx = R502A_LED_COLOR_RED;
697 		led_ctrl.cycle = 0x02;
698 		fps_led_control(dev, &led_ctrl);
699 		LOG_ERR("Did not find a match");
700 		ret = -ENOENT;
701 	} else {
702 		led_ctrl.ctrl_code = R502A_LED_CTRL_ON_ALWAYS;
703 		led_ctrl.color_idx = R502A_LED_COLOR_RED;
704 		fps_led_control(dev, &led_ctrl);
705 		LOG_ERR("Error searching for image 0x%X", rx_packet.buf[R502A_CC_IDX]);
706 		ret = -EIO;
707 	}
708 unlock:
709 	k_mutex_unlock(&drv_data->lock);
710 	return ret;
711 }
712 
fps_load_template(const struct device * dev,uint16_t id)713 static int fps_load_template(const struct device *dev, uint16_t id)
714 {
715 	struct grow_r502a_data *drv_data = dev->data;
716 	union r502a_packet rx_packet = {0};
717 	char const load_tmp_len = 4;
718 	int ret = 0;
719 
720 	union r502a_packet tx_packet = {
721 		.pid = R502A_COMMAND_PACKET,
722 		.data = {R502A_LOAD, R502A_CHAR_BUF_1}
723 	};
724 	sys_put_be16(id, &tx_packet.data[2]);
725 
726 	k_mutex_lock(&drv_data->lock, K_FOREVER);
727 
728 	ret = transceive_packet(dev, &tx_packet, &rx_packet, load_tmp_len);
729 	if (ret != 0) {
730 		goto unlock;
731 	}
732 
733 	ret = r502a_validate_rx_packet(&rx_packet);
734 	if (ret != 0) {
735 		goto unlock;
736 	}
737 
738 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
739 		LOG_DBG("Load template data from id #%d to Char_buffer2", id);
740 	} else {
741 		LOG_ERR("Error Loading template 0x%X",
742 					rx_packet.buf[R502A_CC_IDX]);
743 		ret = -EIO;
744 	}
745 
746 unlock:
747 	k_mutex_unlock(&drv_data->lock);
748 	return ret;
749 }
750 
fps_match_templates(const struct device * dev,struct sensor_value * val)751 static int fps_match_templates(const struct device *dev, struct sensor_value *val)
752 {
753 	struct grow_r502a_data *drv_data = dev->data;
754 	union r502a_packet rx_packet = {0};
755 	char const match_templates_len = 1;
756 	int ret = 0;
757 
758 	struct r502a_led_params led_ctrl = {
759 		.ctrl_code = R502A_LED_CTRL_BREATHING,
760 		.color_idx = R502A_LED_COLOR_BLUE,
761 		.speed = R502A_LED_SPEED_HALF,
762 		.cycle = 0x01,
763 	};
764 
765 	union r502a_packet tx_packet = {
766 		.pid = R502A_COMMAND_PACKET,
767 		.data = {R502A_MATCH}
768 	};
769 
770 	k_mutex_lock(&drv_data->lock, K_FOREVER);
771 
772 	ret = transceive_packet(dev, &tx_packet, &rx_packet, match_templates_len);
773 	if (ret != 0) {
774 		goto unlock;
775 	}
776 
777 	ret = r502a_validate_rx_packet(&rx_packet);
778 	if (ret != 0) {
779 		goto unlock;
780 	}
781 
782 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
783 		fps_led_control(dev, &led_ctrl);
784 		val->val1 = R502A_FINGER_MATCH_FOUND;
785 		val->val2 = sys_get_be16(&rx_packet.data[1]);
786 		LOG_INF("Fingerprint matched with a score %d", val->val2);
787 	} else if (rx_packet.buf[R502A_CC_IDX] == R502A_NOT_MATCH_CC) {
788 		val->val1 = R502A_FINGER_MATCH_NOT_FOUND;
789 		LOG_ERR("Fingerprint not matched");
790 		ret = -ENOENT;
791 	} else {
792 		led_ctrl.ctrl_code = R502A_LED_CTRL_ON_ALWAYS;
793 		led_ctrl.color_idx = R502A_LED_COLOR_RED;
794 		fps_led_control(dev, &led_ctrl);
795 		LOG_ERR("Error Matching templates 0x%X",
796 					rx_packet.buf[R502A_CC_IDX]);
797 		ret = -EIO;
798 	}
799 unlock:
800 	k_mutex_unlock(&drv_data->lock);
801 	return ret;
802 }
803 
fps_capture(const struct device * dev)804 static int fps_capture(const struct device *dev)
805 {
806 	struct grow_r502a_data *drv_data = dev->data;
807 	int ret;
808 
809 	k_mutex_lock(&drv_data->lock, K_FOREVER);
810 
811 	ret = fps_get_image(dev);
812 	if (ret != 0) {
813 		goto unlock;
814 	}
815 
816 	ret = fps_image_to_char(dev, R502A_CHAR_BUF_1);
817 	if (ret != 0) {
818 		goto unlock;
819 	}
820 
821 	ret = fps_get_image(dev);
822 	if (ret != 0) {
823 		goto unlock;
824 	}
825 
826 	ret = fps_image_to_char(dev, R502A_CHAR_BUF_2);
827 
828 unlock:
829 	k_mutex_unlock(&drv_data->lock);
830 	return ret;
831 }
832 
833 /**
834  * @brief	upload template from sensor device's RAM buffer 1 to controller.
835  *
836  * @result	temp->data	holds the template to be uploaded to controller.
837  *		temp->len	holds the length of the template.
838  */
fps_upload_char_buf(const struct device * dev,struct r502a_template * temp)839 int fps_upload_char_buf(const struct device *dev, struct r502a_template *temp)
840 {
841 	struct grow_r502a_data *drv_data = dev->data;
842 	union r502a_packet rx_packet = {0};
843 	char const upload_temp_len = 2;
844 	int ret = 0, idx = 0;
845 
846 	if (!temp->data || (temp->len < R502A_TEMPLATE_MAX_SIZE)) {
847 		LOG_ERR("Invalid temp data");
848 		return -EINVAL;
849 	}
850 
851 	union r502a_packet tx_packet = {
852 		.pid = R502A_COMMAND_PACKET,
853 		.data = {R502A_UPCHAR, R502A_CHAR_BUF_1}
854 	};
855 
856 	k_mutex_lock(&drv_data->lock, K_FOREVER);
857 
858 	ret = transceive_packet(dev, &tx_packet, &rx_packet, upload_temp_len);
859 	if (ret != 0) {
860 		goto unlock;
861 	}
862 
863 	ret = r502a_validate_rx_packet(&rx_packet);
864 	if (ret != 0) {
865 		goto unlock;
866 	}
867 
868 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
869 		LOG_DBG("Upload to host controller");
870 	} else {
871 		LOG_ERR("Error uploading template 0x%X",
872 					rx_packet.buf[R502A_CC_IDX]);
873 		ret = -EIO;
874 		goto unlock;
875 	}
876 
877 	do {
878 		ret = transceive_packet(dev, NULL, &rx_packet, 0);
879 		if (ret != 0) {
880 			goto unlock;
881 		}
882 
883 		ret = r502a_validate_rx_packet(&rx_packet);
884 		if (ret != 0) {
885 			goto unlock;
886 		}
887 
888 		memcpy(&temp->data[idx], &rx_packet.data,
889 				sys_be16_to_cpu(rx_packet.len) - R502A_CHECKSUM_LEN);
890 		idx += sys_be16_to_cpu(rx_packet.len) - R502A_CHECKSUM_LEN;
891 	} while (rx_packet.pid != R502A_END_DATA_PACKET);
892 
893 	temp->len = idx;
894 
895 unlock:
896 	k_mutex_unlock(&drv_data->lock);
897 	return ret;
898 }
899 
900 /**
901  * @brief	download template from controller to sensor device's RAM buffer.
902  * @Notes	char_buf_id - other than value 1 will be considered as value 2
903  *				by R502A sensor.
904  */
fps_download_char_buf(const struct device * dev,uint8_t char_buf_id,const struct r502a_template * temp)905 int fps_download_char_buf(const struct device *dev, uint8_t char_buf_id,
906 						const struct r502a_template *temp)
907 {
908 	struct grow_r502a_data *drv_data = dev->data;
909 	union r502a_packet rx_packet = {0};
910 	char const down_temp_len = 2;
911 	int ret = 0, i = 0;
912 
913 	if (!temp->data || (temp->len < R502A_TEMPLATE_MAX_SIZE)) {
914 		LOG_ERR("Invalid temp data");
915 		return -EINVAL;
916 	}
917 
918 	union r502a_packet tx_packet = {
919 		.pid = R502A_COMMAND_PACKET,
920 		.data = {R502A_DOWNCHAR, char_buf_id}
921 	};
922 
923 	k_mutex_lock(&drv_data->lock, K_FOREVER);
924 
925 	ret = transceive_packet(dev, &tx_packet, &rx_packet, down_temp_len);
926 	if (ret != 0) {
927 		goto unlock;
928 	}
929 
930 	ret = r502a_validate_rx_packet(&rx_packet);
931 	if (ret != 0) {
932 		goto unlock;
933 	}
934 
935 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
936 		LOG_DBG("Download to R502A sensor");
937 	} else {
938 		LOG_ERR("Error downloading template 0x%X",
939 					rx_packet.buf[R502A_CC_IDX]);
940 		ret = -EIO;
941 		goto unlock;
942 	}
943 
944 	while (i < (R502A_TEMPLATE_MAX_SIZE - CONFIG_R502A_DATA_PKT_SIZE)) {
945 		tx_packet.pid = R502A_DATA_PACKET;
946 		memcpy(tx_packet.data, &temp->data[i], CONFIG_R502A_DATA_PKT_SIZE);
947 
948 		ret = transceive_packet(dev, &tx_packet, NULL, CONFIG_R502A_DATA_PKT_SIZE);
949 		if (ret != 0) {
950 			goto unlock;
951 		}
952 
953 		i += CONFIG_R502A_DATA_PKT_SIZE;
954 	}
955 
956 	memcpy(tx_packet.data, &temp->data[i], (R502A_TEMPLATE_MAX_SIZE - i));
957 	tx_packet.pid = R502A_END_DATA_PACKET;
958 	ret = transceive_packet(dev, &tx_packet, NULL, (R502A_TEMPLATE_MAX_SIZE - i));
959 
960 unlock:
961 	k_mutex_unlock(&drv_data->lock);
962 	return ret;
963 }
964 
fps_init(const struct device * dev)965 static int fps_init(const struct device *dev)
966 {
967 	struct grow_r502a_data *drv_data = dev->data;
968 	struct sensor_value val;
969 	int ret;
970 
971 	struct r502a_led_params led_ctrl = {
972 		.ctrl_code = R502A_LED_CTRL_FLASHING,
973 		.color_idx = R502A_LED_COLOR_PURPLE,
974 		.speed = R502A_LED_SPEED_HALF,
975 		.cycle = 0x02,
976 	};
977 
978 	k_mutex_lock(&drv_data->lock, K_FOREVER);
979 
980 	ret = fps_verify_password(dev);
981 	if (ret != 0) {
982 		goto unlock;
983 	}
984 
985 	val.val1 = R502A_DATA_PKG_LEN;
986 	val.val2 = LOG2(CONFIG_R502A_DATA_PKT_SIZE >> 5);
987 	ret = fps_set_sys_param(dev, &val);
988 	if (ret != 0) {
989 		goto unlock;
990 	}
991 
992 	ret = fps_led_control(dev, &led_ctrl);
993 
994 unlock:
995 	k_mutex_unlock(&drv_data->lock);
996 	return ret;
997 }
998 
grow_r502a_sample_fetch(const struct device * dev,enum sensor_channel chan)999 static int grow_r502a_sample_fetch(const struct device *dev, enum sensor_channel chan)
1000 {
1001 	struct grow_r502a_data *drv_data = dev->data;
1002 	int ret;
1003 
1004 	k_mutex_lock(&drv_data->lock, K_FOREVER);
1005 	ret = fps_get_template_count(dev);
1006 	k_mutex_unlock(&drv_data->lock);
1007 
1008 	return ret;
1009 }
1010 
grow_r502a_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)1011 static int grow_r502a_channel_get(const struct device *dev, enum sensor_channel chan,
1012 				  struct sensor_value *val)
1013 {
1014 	struct grow_r502a_data *drv_data = dev->data;
1015 
1016 	if ((enum sensor_channel_grow_r502a)chan == SENSOR_CHAN_FINGERPRINT) {
1017 		val->val1 = drv_data->template_count;
1018 	} else {
1019 		LOG_ERR("Invalid channel");
1020 		return -ENOTSUP;
1021 	}
1022 
1023 	return 0;
1024 }
1025 
grow_r502a_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)1026 static int grow_r502a_attr_set(const struct device *dev, enum sensor_channel chan,
1027 			       enum sensor_attribute attr, const struct sensor_value *val)
1028 {
1029 	struct grow_r502a_data *drv_data = dev->data;
1030 
1031 	if ((enum sensor_channel_grow_r502a)chan != SENSOR_CHAN_FINGERPRINT) {
1032 		LOG_ERR("Channel not supported");
1033 		return -ENOTSUP;
1034 	}
1035 
1036 	switch ((enum sensor_attribute_grow_r502a)attr) {
1037 	case SENSOR_ATTR_R502A_CAPTURE:
1038 		return fps_capture(dev);
1039 	case SENSOR_ATTR_R502A_TEMPLATE_CREATE:
1040 		return fps_create_model(dev);
1041 	case SENSOR_ATTR_R502A_RECORD_ADD:
1042 		return fps_store_model(dev, val->val1);
1043 	case SENSOR_ATTR_R502A_RECORD_DEL:
1044 		return fps_delete_model(dev, val->val1, val->val2);
1045 	case SENSOR_ATTR_R502A_RECORD_EMPTY:
1046 		return fps_empty_db(dev);
1047 	case SENSOR_ATTR_R502A_RECORD_LOAD:
1048 		return fps_load_template(dev, val->val1);
1049 	case SENSOR_ATTR_R502A_SYS_PARAM: {
1050 		int ret = 0;
1051 
1052 		if (val->val1 == R502A_DATA_PKG_LEN) {
1053 			LOG_ERR("Data package length should not be runtime configurable");
1054 			return -EINVAL;
1055 		};
1056 		k_mutex_lock(&drv_data->lock, K_FOREVER);
1057 		ret = fps_set_sys_param(dev, val);
1058 		if (ret != 0) {
1059 			k_mutex_unlock(&drv_data->lock);
1060 			return ret;
1061 		}
1062 		k_mutex_unlock(&drv_data->lock);
1063 		return 0;
1064 	}
1065 	default:
1066 		LOG_ERR("Sensor attribute not supported");
1067 		return -ENOTSUP;
1068 	}
1069 
1070 }
1071 
grow_r502a_attr_get(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,struct sensor_value * val)1072 static int grow_r502a_attr_get(const struct device *dev, enum sensor_channel chan,
1073 			       enum sensor_attribute attr, struct sensor_value *val)
1074 {
1075 	int ret;
1076 
1077 	if ((enum sensor_channel_grow_r502a)chan != SENSOR_CHAN_FINGERPRINT) {
1078 		LOG_ERR("Channel not supported");
1079 		return -ENOTSUP;
1080 	}
1081 
1082 	switch ((enum sensor_attribute_grow_r502a)attr) {
1083 	case SENSOR_ATTR_R502A_RECORD_FIND:
1084 		ret = fps_search(dev, val);
1085 		break;
1086 	case SENSOR_ATTR_R502A_RECORD_FREE_IDX:
1087 		ret = fps_read_template_table(dev, &val->val1);
1088 		break;
1089 	case SENSOR_ATTR_R502A_COMPARE:
1090 		ret = fps_match_templates(dev, val);
1091 		break;
1092 	default:
1093 		LOG_ERR("Sensor attribute not supported");
1094 		ret = -ENOTSUP;
1095 		break;
1096 	}
1097 
1098 	return ret;
1099 }
1100 
grow_r502a_uart_flush(const struct device * dev)1101 static void grow_r502a_uart_flush(const struct device *dev)
1102 {
1103 	uint8_t c;
1104 
1105 	while (uart_fifo_read(dev, &c, 1) > 0) {
1106 		continue;
1107 	}
1108 }
1109 
grow_r502a_init(const struct device * dev)1110 static int grow_r502a_init(const struct device *dev)
1111 {
1112 	const struct grow_r502a_config *cfg = dev->config;
1113 	struct grow_r502a_data *drv_data = dev->data;
1114 	int ret;
1115 
1116 	if (!device_is_ready(cfg->dev)) {
1117 		LOG_ERR("%s: grow_r502a device not ready", dev->name);
1118 		return -ENODEV;
1119 	}
1120 
1121 	if (IS_ENABLED(CONFIG_GROW_R502A_GPIO_POWER)) {
1122 		if (!gpio_is_ready_dt(&cfg->vin_gpios)) {
1123 			LOG_ERR("GPIO port %s not ready", cfg->vin_gpios.port->name);
1124 			return -ENODEV;
1125 		}
1126 
1127 		ret = gpio_pin_configure_dt(&cfg->vin_gpios, GPIO_OUTPUT_ACTIVE);
1128 
1129 		if (ret < 0) {
1130 			return ret;
1131 		}
1132 
1133 		k_sleep(K_MSEC(R502A_DELAY));
1134 
1135 		if (!gpio_is_ready_dt(&cfg->act_gpios)) {
1136 			LOG_ERR("GPIO port %s not ready", cfg->act_gpios.port->name);
1137 			return -ENODEV;
1138 		}
1139 
1140 		ret = gpio_pin_configure_dt(&cfg->act_gpios, GPIO_OUTPUT_ACTIVE);
1141 		if (ret < 0) {
1142 			return ret;
1143 		}
1144 
1145 		k_sleep(K_MSEC(R502A_DELAY));
1146 	}
1147 
1148 	grow_r502a_uart_flush(cfg->dev);
1149 
1150 	k_mutex_init(&drv_data->lock);
1151 	k_sem_init(&drv_data->uart_rx_sem, 0, 1);
1152 	k_sem_init(&drv_data->uart_tx_sem, 0, 1);
1153 
1154 	uart_irq_callback_user_data_set(cfg->dev, uart_cb_handler, (void *)dev);
1155 
1156 	uart_irq_rx_disable(cfg->dev);
1157 	uart_irq_tx_disable(cfg->dev);
1158 
1159 #ifdef CONFIG_GROW_R502A_TRIGGER
1160 	ret = grow_r502a_init_interrupt(dev);
1161 
1162 	if (ret < 0) {
1163 		LOG_ERR("Failed to initialize interrupt!");
1164 		return ret;
1165 	}
1166 #endif
1167 
1168 	return fps_init(dev);
1169 }
1170 
1171 static const struct sensor_driver_api grow_r502a_api = {
1172 	.sample_fetch = grow_r502a_sample_fetch,
1173 	.channel_get = grow_r502a_channel_get,
1174 	.attr_set = grow_r502a_attr_set,
1175 	.attr_get = grow_r502a_attr_get,
1176 #ifdef CONFIG_GROW_R502A_TRIGGER
1177 	.trigger_set = grow_r502a_trigger_set,
1178 #endif
1179 };
1180 
1181 #ifdef CONFIG_LED
grow_r502a_led_set_color(const struct device * dev,uint32_t led,uint8_t num_colors,const uint8_t * color)1182 static int grow_r502a_led_set_color(const struct device *dev, uint32_t led,
1183 					uint8_t num_colors, const uint8_t *color)
1184 {
1185 	struct grow_r502a_data *drv_data = dev->data;
1186 
1187 	if (!(*color)) {
1188 		LOG_ERR("invalid color code value");
1189 		return -ENOTSUP;
1190 	}
1191 	drv_data->led_color = *color;
1192 
1193 	return 0;
1194 }
1195 
grow_r502a_led_on(const struct device * dev,uint32_t led)1196 static int grow_r502a_led_on(const struct device *dev, uint32_t led)
1197 {
1198 	struct grow_r502a_data *drv_data = dev->data;
1199 
1200 	if (!drv_data->led_color) {
1201 		drv_data->led_color = R502A_LED_COLOR_BLUE;
1202 	}
1203 
1204 	struct r502a_led_params led_ctrl = {
1205 		.ctrl_code = R502A_LED_CTRL_ON_ALWAYS,
1206 		.color_idx = drv_data->led_color,
1207 	};
1208 
1209 	return fps_led_control(dev, &led_ctrl);
1210 }
1211 
grow_r502a_led_off(const struct device * dev,uint32_t led)1212 static int grow_r502a_led_off(const struct device *dev, uint32_t led)
1213 {
1214 	struct r502a_led_params led_ctrl = {
1215 		.ctrl_code = R502A_LED_CTRL_OFF_ALWAYS,
1216 	};
1217 
1218 	return fps_led_control(dev, &led_ctrl);
1219 }
1220 
1221 static const struct led_driver_api grow_r502a_leds_api = {
1222 	.set_color = grow_r502a_led_set_color,
1223 	.on = grow_r502a_led_on,
1224 	.off = grow_r502a_led_off,
1225 };
1226 #endif
1227 
1228 #define GROW_R502A_INIT(index)									\
1229 	static struct grow_r502a_data grow_r502a_data_##index;					\
1230 												\
1231 	static struct grow_r502a_config grow_r502a_config_##index = {				\
1232 		.dev = DEVICE_DT_GET(DT_INST_BUS(index)),					\
1233 		.comm_addr = DT_INST_REG_ADDR(index),						\
1234 		IF_ENABLED(CONFIG_GROW_R502A_GPIO_POWER,					\
1235 		(.vin_gpios = GPIO_DT_SPEC_INST_GET_OR(index, vin_gpios, {}),			\
1236 		 .act_gpios = GPIO_DT_SPEC_INST_GET_OR(index, act_gpios, {}),))			\
1237 		IF_ENABLED(CONFIG_GROW_R502A_TRIGGER,						\
1238 		(.int_gpios = GPIO_DT_SPEC_INST_GET_OR(index, int_gpios, {}),))			\
1239 	};											\
1240 												\
1241 	DEVICE_DT_INST_DEFINE(index, &grow_r502a_init, NULL, &grow_r502a_data_##index,		\
1242 				&grow_r502a_config_##index, POST_KERNEL,			\
1243 				CONFIG_SENSOR_INIT_PRIORITY, &grow_r502a_api);			\
1244 
1245 #define GROW_R502A_LED_INIT(index)								\
1246 	DEVICE_DT_INST_DEFINE(index, NULL, NULL, &grow_r502a_data_##index,			\
1247 				&grow_r502a_config_##index, POST_KERNEL,			\
1248 				CONFIG_LED_INIT_PRIORITY, &grow_r502a_leds_api);		\
1249 
1250 #define DT_DRV_COMPAT hzgrow_r502a
1251 DT_INST_FOREACH_STATUS_OKAY(GROW_R502A_INIT)
1252 #undef DT_DRV_COMPAT
1253 
1254 #ifdef CONFIG_LED
1255 #define DT_DRV_COMPAT hzgrow_r502a_led
1256 DT_INST_FOREACH_STATUS_OKAY(GROW_R502A_LED_INIT)
1257 #undef DT_DRV_COMPAT
1258 #endif
1259