drivers: sensor: grow_r502a: move enroll, search, delete to application

Removed fps_enroll, fps_search and fps_delete from
driver code, since they did application usage inside
driver. add the following attributes to achieve the
above functionality from application.
1. SENSOR_ATTR_R502A_CAPTURE
2. SENSOR_ATTR_R502A_TEMPLATE_CREATE
3. SENSOR_ATTR_R502A_RECORD_ADD
4. SENSOR_ATTR_R502A_RECORD_LOAD
5. SENSOR_ATTR_R502A_COMPARE

Signed-off-by: Dinesh Kumar K <dinesh@linumiz.com>
diff --git a/drivers/sensor/grow_r502a/grow_r502a.c b/drivers/sensor/grow_r502a/grow_r502a.c
index 0047f94..69b66ee 100644
--- a/drivers/sensor/grow_r502a/grow_r502a.c
+++ b/drivers/sensor/grow_r502a/grow_r502a.c
@@ -335,8 +335,10 @@
 
 static int fps_store_model(const struct device *dev, uint16_t id)
 {
+	struct grow_r502a_data *drv_data = dev->data;
 	union r502a_packet rx_packet = {0};
 	char const store_model_len = 4;
+	int ret = 0;
 
 	struct led_params led_ctrl = {
 		.ctrl_code = LED_CTRL_BREATHING,
@@ -351,11 +353,14 @@
 	};
 	sys_put_be16(id, &tx_packet.data[2]);
 
+	k_mutex_lock(&drv_data->lock, K_FOREVER);
+
 	transceive_packet(dev, &tx_packet, &rx_packet, store_model_len);
 
 	if (rx_packet.pid != R502A_ACK_PACKET) {
 		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
-		return -EIO;
+		ret = -EIO;
+		goto unlock;
 	}
 
 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
@@ -366,16 +371,19 @@
 		LOG_INF("Fingerprint stored! at ID #%d", id);
 	} else {
 		LOG_ERR("Error storing model 0x%X", rx_packet.buf[R502A_CC_IDX]);
-		return -EIO;
+		ret = -EIO;
 	}
-
-	return 0;
+unlock:
+	k_mutex_unlock(&drv_data->lock);
+	return ret;
 }
 
 static int fps_delete_model(const struct device *dev, uint16_t id, uint16_t count)
 {
+	struct grow_r502a_data *drv_data = dev->data;
 	union r502a_packet rx_packet = {0};
 	char const delete_model_len = 5;
+	int ret = 0;
 
 	union r502a_packet tx_packet = {
 		.pid = R502A_COMMAND_PACKET,
@@ -384,21 +392,25 @@
 	sys_put_be16(id, &tx_packet.data[1]);
 	sys_put_be16(count + R502A_DELETE_COUNT_OFFSET, &tx_packet.data[3]);
 
+	k_mutex_lock(&drv_data->lock, K_FOREVER);
+
 	transceive_packet(dev, &tx_packet, &rx_packet, delete_model_len);
 
 	if (rx_packet.pid != R502A_ACK_PACKET) {
 		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
-		return -EIO;
+		ret = -EIO;
+		goto unlock;
 	}
 
 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
 		LOG_INF("Fingerprint Deleted from ID #%d to #%d", id, (id + count));
 	} else {
 		LOG_ERR("Error deleting image 0x%X", rx_packet.buf[R502A_CC_IDX]);
-		return -EIO;
+		ret = -EIO;
 	}
-
-	return 0;
+unlock:
+	k_mutex_unlock(&drv_data->lock);
+	return ret;
 }
 
 static int fps_empty_db(const struct device *dev)
@@ -429,7 +441,6 @@
 		LOG_ERR("Error emptying fingerprint library 0x%X",
 					rx_packet.buf[R502A_CC_IDX]);
 		ret = -EIO;
-		goto unlock;
 	}
 
 unlock:
@@ -437,11 +448,12 @@
 	return ret;
 }
 
-static int fps_search(const struct device *dev, uint8_t char_buf_idx)
+static int fps_search(const struct device *dev, struct sensor_value *val)
 {
 	struct grow_r502a_data *drv_data = dev->data;
 	union r502a_packet rx_packet = {0};
 	char const search_len = 6;
+	int ret = 0;
 
 	struct led_params led_ctrl = {
 		.ctrl_code = LED_CTRL_BREATHING,
@@ -452,16 +464,19 @@
 
 	union r502a_packet tx_packet = {
 		.pid = R502A_COMMAND_PACKET,
-		.data = {R502A_SEARCH, char_buf_idx}
+		.data = {R502A_SEARCH, R502A_CHAR_BUF_1}
 	};
 	sys_put_be16(R02A_LIBRARY_START_IDX, &tx_packet.data[2]);
 	sys_put_be16(R502A_DEFAULT_CAPACITY, &tx_packet.data[4]);
 
+	k_mutex_lock(&drv_data->lock, K_FOREVER);
+
 	transceive_packet(dev, &tx_packet, &rx_packet, search_len);
 
 	if (rx_packet.pid != R502A_ACK_PACKET) {
 		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
-		return -EIO;
+		ret = -EIO;
+		goto unlock;
 	}
 
 	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
@@ -469,37 +484,120 @@
 		led_ctrl.color_idx = LED_COLOR_PURPLE;
 		led_ctrl.cycle = 0x01;
 		fps_led_control(dev, &led_ctrl);
-		drv_data->finger_id = sys_get_be16(&rx_packet.data[1]);
-		drv_data->matching_score = sys_get_be16(&rx_packet.data[3]);
-		LOG_INF("Found a matching print! at ID #%d", drv_data->finger_id);
-	} else if (rx_packet.buf[R502A_CC_IDX] == R502A_NOT_FOUND) {
+		val->val1 = sys_get_be16(&rx_packet.data[1]);
+		val->val2 = sys_get_be16(&rx_packet.data[3]);
+		LOG_INF("Found a matching print! at ID #%d", val->val1);
+	} else if (rx_packet.buf[R502A_CC_IDX] == R502A_NOT_FOUND_CC) {
 		led_ctrl.ctrl_code = LED_CTRL_BREATHING;
 		led_ctrl.color_idx = LED_COLOR_RED;
 		led_ctrl.cycle = 0x02;
 		fps_led_control(dev, &led_ctrl);
 		LOG_ERR("Did not find a match");
-		return -ENOENT;
+		ret = -ENOENT;
 	} else {
 		led_ctrl.ctrl_code = LED_CTRL_ON_ALWAYS;
 		led_ctrl.color_idx = LED_COLOR_RED;
 		fps_led_control(dev, &led_ctrl);
 		LOG_ERR("Error searching for image 0x%X", rx_packet.buf[R502A_CC_IDX]);
-		return -EIO;
+		ret = -EIO;
 	}
-
-	return 0;
+unlock:
+	k_mutex_unlock(&drv_data->lock);
+	return ret;
 }
 
-static int fps_enroll(const struct device *dev, const struct sensor_value *val)
+static int fps_load_template(const struct device *dev, uint16_t id)
 {
 	struct grow_r502a_data *drv_data = dev->data;
-	int ret = -1;
+	union r502a_packet rx_packet = {0};
+	char const load_tmp_len = 4;
+	int ret = 0;
 
-	if (val->val1 < 0 || val->val1 > R502A_DEFAULT_CAPACITY) {
-		LOG_ERR("Invalid ID number");
-		return -EINVAL;
+	union r502a_packet tx_packet = {
+		.pid = R502A_COMMAND_PACKET,
+		.data = {R502A_LOAD, R502A_CHAR_BUF_1}
+	};
+	sys_put_be16(id, &tx_packet.data[2]);
+
+	k_mutex_lock(&drv_data->lock, K_FOREVER);
+
+	transceive_packet(dev, &tx_packet, &rx_packet, load_tmp_len);
+
+	if (rx_packet.pid != R502A_ACK_PACKET) {
+		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
+		ret = -EIO;
+		goto unlock;
 	}
 
+	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
+		LOG_DBG("Load template data from id #%d to Char_buffer2", id);
+	} else {
+		LOG_ERR("Error Loading template 0x%X",
+					rx_packet.buf[R502A_CC_IDX]);
+		ret = -EIO;
+	}
+
+unlock:
+	k_mutex_unlock(&drv_data->lock);
+	return ret;
+}
+
+static int fps_match_templates(const struct device *dev, struct sensor_value *val)
+{
+	struct grow_r502a_data *drv_data = dev->data;
+	union r502a_packet rx_packet = {0};
+	char const match_templates_len = 1;
+	int ret = 0;
+
+	struct led_params led_ctrl = {
+		.ctrl_code = LED_CTRL_BREATHING,
+		.color_idx = LED_COLOR_BLUE,
+		.speed = LED_SPEED_HALF,
+		.cycle = 0x01,
+	};
+
+	union r502a_packet tx_packet = {
+		.pid = R502A_COMMAND_PACKET,
+		.data = {R502A_MATCH}
+	};
+
+	k_mutex_lock(&drv_data->lock, K_FOREVER);
+
+	transceive_packet(dev, &tx_packet, &rx_packet, match_templates_len);
+
+	if (rx_packet.pid != R502A_ACK_PACKET) {
+		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
+		ret = -EIO;
+		goto unlock;
+	}
+
+	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
+		fps_led_control(dev, &led_ctrl);
+		val->val1 = R502A_FINGER_MATCH_FOUND;
+		val->val2 = sys_get_be16(&rx_packet.data[1]);
+		LOG_INF("Fingerprint matched with a score %d", val->val2);
+	} else if (rx_packet.buf[R502A_CC_IDX] == R502A_NOT_MATCH_CC) {
+		val->val1 = R502A_FINGER_MATCH_NOT_FOUND;
+		LOG_ERR("Fingerprint not matched");
+		ret = -ENOENT;
+	} else {
+		led_ctrl.ctrl_code = LED_CTRL_ON_ALWAYS;
+		led_ctrl.color_idx = LED_COLOR_RED;
+		fps_led_control(dev, &led_ctrl);
+		LOG_ERR("Error Matching templates 0x%X",
+					rx_packet.buf[R502A_CC_IDX]);
+		ret = -EIO;
+	}
+unlock:
+	k_mutex_unlock(&drv_data->lock);
+	return ret;
+}
+
+static int fps_capture(const struct device *dev)
+{
+	struct grow_r502a_data *drv_data = dev->data;
+	int ret;
+
 	k_mutex_lock(&drv_data->lock, K_FOREVER);
 
 	ret = fps_get_image(dev);
@@ -518,63 +616,6 @@
 	}
 
 	ret = fps_image_to_char(dev, R502A_CHAR_BUF_2);
-	if (ret != 0) {
-		goto unlock;
-	}
-
-	ret = fps_create_model(dev);
-	if (ret != 0) {
-		goto unlock;
-	}
-
-	ret = fps_store_model(dev, val->val1);
-
-unlock:
-	k_mutex_unlock(&drv_data->lock);
-	return ret;
-}
-
-static int fps_delete(const struct device *dev, const struct sensor_value *val)
-{
-	struct grow_r502a_data *drv_data = dev->data;
-	int ret = -1;
-
-	k_mutex_lock(&drv_data->lock, K_FOREVER);
-
-	ret = fps_delete_model(dev, val->val1, val->val2);
-	if (ret != 0) {
-		goto unlock;
-	}
-
-	ret = fps_get_template_count(dev);
-
-unlock:
-	k_mutex_unlock(&drv_data->lock);
-	return ret;
-}
-
-static int fps_match(const struct device *dev, struct sensor_value *val)
-{
-	struct grow_r502a_data *drv_data = dev->data;
-	int ret = -1;
-
-	k_mutex_lock(&drv_data->lock, K_FOREVER);
-
-	ret = fps_get_image(dev);
-	if (ret != 0) {
-		goto unlock;
-	}
-
-	ret = fps_image_to_char(dev, R502A_CHAR_BUF_1);
-	if (ret != 0) {
-		goto unlock;
-	}
-
-	ret = fps_search(dev, R502A_CHAR_BUF_1);
-	if (ret == 0) {
-		val->val1 = drv_data->finger_id;
-		val->val2 = drv_data->matching_score;
-	}
 
 unlock:
 	k_mutex_unlock(&drv_data->lock);
@@ -643,12 +684,18 @@
 	}
 
 	switch ((enum sensor_attribute_grow_r502a)attr) {
+	case SENSOR_ATTR_R502A_CAPTURE:
+		return fps_capture(dev);
+	case SENSOR_ATTR_R502A_TEMPLATE_CREATE:
+		return fps_create_model(dev);
 	case SENSOR_ATTR_R502A_RECORD_ADD:
-		return fps_enroll(dev, val);
+		return fps_store_model(dev, val->val1);
 	case SENSOR_ATTR_R502A_RECORD_DEL:
-		return fps_delete(dev, val);
+		return fps_delete_model(dev, val->val1, val->val2);
 	case SENSOR_ATTR_R502A_RECORD_EMPTY:
 		return fps_empty_db(dev);
+	case SENSOR_ATTR_R502A_RECORD_LOAD:
+		return fps_load_template(dev, val->val1);
 	default:
 		LOG_ERR("Sensor attribute not supported");
 		return -ENOTSUP;
@@ -660,7 +707,6 @@
 			       enum sensor_attribute attr, struct sensor_value *val)
 {
 	int ret;
-	struct grow_r502a_data *drv_data = dev->data;
 
 	if ((enum sensor_channel_grow_r502a)chan != SENSOR_CHAN_FINGERPRINT) {
 		LOG_ERR("Channel not supported");
@@ -669,11 +715,14 @@
 
 	switch ((enum sensor_attribute_grow_r502a)attr) {
 	case SENSOR_ATTR_R502A_RECORD_FIND:
-		ret = fps_match(dev, val);
+		ret = fps_search(dev, val);
 		break;
 	case SENSOR_ATTR_R502A_RECORD_FREE_IDX:
 		ret = fps_read_template_table(dev, &val->val1);
 		break;
+	case SENSOR_ATTR_R502A_COMPARE:
+		ret = fps_match_templates(dev, val);
+		break;
 	default:
 		LOG_ERR("Sensor attribute not supported");
 		ret = -ENOTSUP;
diff --git a/drivers/sensor/grow_r502a/grow_r502a.h b/drivers/sensor/grow_r502a/grow_r502a.h
index f61e7ed..0004435 100644
--- a/drivers/sensor/grow_r502a/grow_r502a.h
+++ b/drivers/sensor/grow_r502a/grow_r502a.h
@@ -61,7 +61,6 @@
  */
 
 #define R502A_OK 0x00 /*commad execution complete*/
-#define R502A_NOT_FOUND 0x09 /*fail to find the matching finger*/
 
 /*Package Identifier's definition*/
 #define R502A_COMMAND_PACKET 0x1 /*Command packet*/
@@ -95,6 +94,11 @@
 #define R502A_HANDSHAKE 0x40 /*Handshake*/
 #define R502A_BADPACKET 0xFE /* Bad packet was sent*/
 
+#define R502A_NOT_MATCH_CC 0x08 /* templates of two buffers not matching*/
+#define R502A_NOT_FOUND_CC 0x09 /*fail to find the matching finger*/
+#define R502A_FINGER_MATCH_NOT_FOUND 0
+#define R502A_FINGER_MATCH_FOUND 1
+
 #define R502A_STARTCODE 0xEF01 /*Fixed value, High byte transferred first*/
 #define R502A_DEFAULT_PASSWORD 0x00000000
 #define R502A_DEFAULT_ADDRESS 0xFFFFFFFF
@@ -187,8 +191,6 @@
 	struct k_mutex lock;
 	struct k_sem uart_rx_sem;
 
-	uint16_t finger_id;
-	uint16_t matching_score;
 	uint16_t template_count;
 };
 
diff --git a/include/zephyr/drivers/sensor/grow_r502a.h b/include/zephyr/drivers/sensor/grow_r502a.h
index 8b0db47..fafcfd7 100644
--- a/include/zephyr/drivers/sensor/grow_r502a.h
+++ b/include/zephyr/drivers/sensor/grow_r502a.h
@@ -24,16 +24,53 @@
 };
 
 enum sensor_attribute_grow_r502a {
-	/** Add values to the sensor which are having record storage facility */
-	SENSOR_ATTR_R502A_RECORD_ADD = SENSOR_ATTR_PRIV_START,
+	/** To capture finger and store as feature file in
+	 * RAM buffers char_buf_1 and char_buf_2.
+	 */
+	SENSOR_ATTR_R502A_CAPTURE = SENSOR_ATTR_PRIV_START,
+	/** create template from feature files at RAM buffers
+	 * char_buf_1 & char_buf_2 and store a template data
+	 * back in both RAM buffers char_buf_1 and char_buf_2.
+	 */
+	SENSOR_ATTR_R502A_TEMPLATE_CREATE,
+	/** Add template to the sensor record storage */
+	/**
+	 * @param val->val1	record index for template to be
+	 *			stored in the sensor device's flash
+	 *			library.
+	 */
+	SENSOR_ATTR_R502A_RECORD_ADD,
 	/** To find requested data in record storage */
+	/**
+	 * @result val->val1	matched record index.
+	 *	   val->val2	matching score.
+	 */
 	SENSOR_ATTR_R502A_RECORD_FIND,
 	/** To delete mentioned data from record storage */
+	/**
+	 * @param val->val1	record start index to be deleted.
+	 * @param val->val2	number of records to be deleted.
+	 */
 	SENSOR_ATTR_R502A_RECORD_DEL,
 	/** To get available position to store data on record storage */
 	SENSOR_ATTR_R502A_RECORD_FREE_IDX,
 	/** To empty the storage record*/
 	SENSOR_ATTR_R502A_RECORD_EMPTY,
+	/** To load template from storage to RAM buffer of sensor*/
+	/**
+	 * @param val->val1	record start index to be loaded in
+	 *			device internal RAM buffer.
+	 */
+	SENSOR_ATTR_R502A_RECORD_LOAD,
+	/** To template data stored in sensor's RAM buffer*/
+	/**
+	 * @result
+	 *	val->val1	match result.
+	 *			[R502A_FINGER_MATCH_FOUND or
+	 *			R502A_FINGER_MATCH_NOT_FOUND]
+	 *	val->val2	matching score.
+	 */
+	SENSOR_ATTR_R502A_COMPARE,
 };
 
 #ifdef __cplusplus
diff --git a/samples/sensor/grow_r502a/src/main.c b/samples/sensor/grow_r502a/src/main.c
index 583d1ed..573a03a 100644
--- a/samples/sensor/grow_r502a/src/main.c
+++ b/samples/sensor/grow_r502a/src/main.c
@@ -11,32 +11,54 @@
 #include <zephyr/drivers/sensor/grow_r502a.h>
 
 static bool enroll;
-static struct sensor_value fid, val;
+static struct sensor_value fid_get, count, find, del;
 
-static void finger_match(const struct device *dev)
+static void finger_find(const struct device *dev)
 {
-	struct sensor_value input;
 	int ret;
 
-	ret = sensor_attr_get(dev, SENSOR_CHAN_FINGERPRINT,
-		SENSOR_ATTR_R502A_RECORD_FIND, &input);
+	ret = sensor_attr_set(dev, SENSOR_CHAN_FINGERPRINT,
+			SENSOR_ATTR_R502A_CAPTURE, NULL);
 	if (ret != 0) {
-		printk("Sensor attr get failed %d\n", ret);
+		printk("Capture fingerprint failed %d\n", ret);
 		return;
 	}
-	printk("Matched ID : %d\n", input.val1);
-	printk("confidence : %d\n", input.val2);
+
+	ret = sensor_attr_get(dev, SENSOR_CHAN_FINGERPRINT,
+		SENSOR_ATTR_R502A_RECORD_FIND, &find);
+	if (ret != 0) {
+		printk("Find fingerprint failed %d\n", ret);
+		return;
+	}
+	printk("Matched ID : %d\n", find.val1);
+	printk("confidence : %d\n", find.val2);
 }
 
 static void finger_enroll(const struct device *dev)
 {
 	int ret;
 
-	ret = sensor_attr_set(dev, SENSOR_CHAN_FINGERPRINT, SENSOR_ATTR_R502A_RECORD_ADD, &fid);
+	ret = sensor_attr_set(dev, SENSOR_CHAN_FINGERPRINT,
+			SENSOR_ATTR_R502A_CAPTURE, NULL);
+	if (ret != 0) {
+		printk("Capture fingerprint failed %d\n", ret);
+		return;
+	}
 
-	if (ret == 0) {
-		printk("Fingerprint successfully stored at #%d\n", fid.val1);
+	ret = sensor_attr_set(dev, SENSOR_CHAN_FINGERPRINT,
+			SENSOR_ATTR_R502A_TEMPLATE_CREATE, NULL);
+	if (ret != 0) {
+		printk("Create template failed %d\n", ret);
+		return;
+	}
+
+	ret = sensor_attr_set(dev, SENSOR_CHAN_FINGERPRINT,
+			SENSOR_ATTR_R502A_RECORD_ADD, &fid_get);
+	if (!ret) {
+		printk("Fingerprint successfully stored at #%d\n", fid_get.val1);
 		enroll = false;
+	} else {
+		printk("Fingerprint store failed %d\n", ret);
 	}
 }
 
@@ -49,12 +71,12 @@
 		printk("Sample Fetch Error %d\n", ret);
 		return;
 	}
-	ret = sensor_channel_get(dev, SENSOR_CHAN_FINGERPRINT, &val);
+	ret = sensor_channel_get(dev, SENSOR_CHAN_FINGERPRINT, &count);
 	if (ret < 0) {
 		printk("Channel Get Error %d\n", ret);
 		return;
 	}
-	printk("template count : %d\n", val.val1);
+	printk("template count : %d\n", count.val1);
 }
 
 static void trigger_handler(const struct device *dev,
@@ -64,13 +86,12 @@
 		finger_enroll(dev);
 	} else {
 		template_count_get(dev);
-		finger_match(dev);
+		finger_find(dev);
 	}
 }
 
 int main(void)
 {
-	static struct sensor_value del, fid_get;
 	int ret;
 
 	const struct device *dev =  DEVICE_DT_GET_ONE(hzgrow_r502a);
@@ -103,9 +124,8 @@
 	}
 	printk("Fingerprint template free idx at ID #%d\n", fid_get.val1);
 
-	fid.val1 = fid_get.val1;
 	printk("Waiting for valid finger to enroll as ID #%d\n"
-		"Place your finger\n", fid.val1);
+		"Place your finger\n", fid_get.val1);
 	enroll = true;
 
 	if (IS_ENABLED(CONFIG_GROW_R502A_TRIGGER)) {