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