Example Program for EVAL-AD7606

Dependencies:   platform_drivers

Revision:
6:32de160dce43
Parent:
3:83b3133f544a
Child:
7:054dbd5e1f45
--- a/app/iio_ad7606.c	Mon Oct 19 07:54:56 2020 +0000
+++ b/app/iio_ad7606.c	Wed Jul 21 11:16:56 2021 +0100
@@ -3,7 +3,7 @@
  *   @brief   Implementation of AD7606 IIO application interfaces
  *   @details This module acts as an interface for AD7606 IIO application
 ********************************************************************************
- * Copyright (c) 2020 Analog Devices, Inc.
+ * Copyright (c) 2020-2021 Analog Devices, Inc.
  *
  * This software is proprietary to Analog Devices, Inc. and its licensors.
  * By using this software you agree to the terms of the associated
@@ -20,18 +20,13 @@
 #include <math.h>
 
 #include "app_config.h"
-
-#include "tinyiiod.h"
 #include "iio_ad7606.h"
-#include "iio_ad7606_attr.h"
-#include "iio_app.h"
-#include "iio_transport.h"
-
 #include "platform_support.h"
 #include "spi_extra.h"
 #include "gpio_extra.h"
 #include "uart_extra.h"
 #include "irq_extra.h"
+#include "error.h"
 
 #include "ad7606.h"
 #include "ad7606_data_capture.h"
@@ -73,21 +68,12 @@
 #define	OFFSET_REG_RESOLUTION		1
 #endif
 
-/* Default sampling frequency for AD7606 (in SPS) to define IIO client timeout period.
- * Note: The actual sampling frequncy is much higher (~30KSPS per channel), however the
- * data transmission back to IIO client is limited by the serial (UART) link, which
- * can provide max transmission rate of ~3-4KSPS. Hence sampling frequency is set to 1Khz
- * for safer side */
-#define AD7606_DEFLT_SAMPLING_FREQEUNCY		(1000)
-
 /******************************************************************************/
 /*************************** Types Declarations *******************************/
 /******************************************************************************/
 
-/**
-* IIO application instance descriptor.
-*/
-static struct iio_app_desc *iio_app_desc;
+/* IIO interface descriptor */
+static struct iio_desc *p_ad7606_iio_desc;
 
 /**
  * Device name.
@@ -97,7 +83,7 @@
 /**
  * Pointer to the struct representing the AD7606 IIO device
  */
-static struct ad7606_dev *p_ad7606_dev = NULL;
+static struct ad7606_dev *p_ad7606_dev_inst = NULL;
 
 
 /* Device attributes with default values */
@@ -188,14 +174,8 @@
 	0
 };
 
-/* Device register value */
-static uint8_t device_reg_val;
-
-/* GPIO LED descriptor and init structure */
-static struct gpio_desc *gpio_led;
-
 /* Flag to trigger new background conversion and capture when READBUFF command is issued */
-static bool adc_background_data_capture_started = false;
+static bool adc_data_capture_started = false;
 
 /* Gain calibration status */
 static bool gain_calibration_done = false;
@@ -205,9 +185,6 @@
 static bool open_circuit_detection_error = false;
 static bool open_circuit_detect_read_done = false;
 
-/* Sampling frequency of device */
-static uint16_t sampling_frequency = AD7606_DEFLT_SAMPLING_FREQEUNCY;
-
 /******************************************************************************/
 /************************ Functions Prototypes ********************************/
 /******************************************************************************/
@@ -227,25 +204,27 @@
  * @param	channel- pointer to IIO channel structure
  * @return	Number of characters read/written
  */
-ssize_t get_chn_scale(void *device,
-		      char *buf,
-		      size_t len,
-		      const struct iio_ch_info *channel)
+static ssize_t get_chn_scale(void *device,
+			     char *buf,
+			     size_t len,
+			     const struct iio_ch_info *channel,
+			     intptr_t id)
 {
-	return (ssize_t) sprintf(buf, "%f", attr_scale_val[channel->ch_num - 1]);
+	return (ssize_t) sprintf(buf, "%f", attr_scale_val[channel->ch_num]);
 }
 
-ssize_t set_chn_scale(void *device,
-		      char *buf,
-		      size_t len,
-		      const struct iio_ch_info *channel)
+static ssize_t set_chn_scale(void *device,
+			     char *buf,
+			     size_t len,
+			     const struct iio_ch_info *channel,
+			     intptr_t id)
 {
 	float scale;
 
 	(void)sscanf(buf, "%f", &scale);
 
 	if (scale > 0.0) {
-		attr_scale_val[channel->ch_num - 1] = scale;
+		attr_scale_val[channel->ch_num] = scale;
 		return len;
 	}
 
@@ -266,18 +245,20 @@
  *			e.g. if sampling frequency = 1KSPS and requested samples = 400
  *			Timeout = (400 * 0.001) + 1 = 1.4sec
  */
-ssize_t get_sampling_frequency(void *device,
-			       char *buf,
-			       size_t len,
-			       const struct iio_ch_info *channel)
+static ssize_t get_sampling_frequency(void *device,
+				      char *buf,
+				      size_t len,
+				      const struct iio_ch_info *channel,
+				      intptr_t id)
 {
-	return (ssize_t) sprintf(buf, "%d", sampling_frequency);
+	return (ssize_t) sprintf(buf, "%d", SAMPLING_RATE);
 }
 
-ssize_t set_sampling_frequency(void *device,
-			       char *buf,
-			       size_t len,
-			       const struct iio_ch_info *channel)
+static ssize_t set_sampling_frequency(void *device,
+				      char *buf,
+				      size_t len,
+				      const struct iio_ch_info *channel,
+				      intptr_t id)
 {
 	/* NA- Can't set sampling frequency value */
 	return len;
@@ -292,24 +273,26 @@
  * @param	channel- pointer to IIO channel structure
  * @return	Number of characters read/written
  */
-ssize_t get_chn_raw(void *device,
-		    char *buf,
-		    size_t len,
-		    const struct iio_ch_info *channel)
+static ssize_t get_chn_raw(void *device,
+			   char *buf,
+			   size_t len,
+			   const struct iio_ch_info *channel,
+			   intptr_t id)
 {
 	int32_t adc_data_raw;
 
 	/* Capture the raw adc data */
-	adc_data_raw = single_data_read(device, channel->ch_num - 1,
-					attr_polarity_val[channel->ch_num - 1]);
+	adc_data_raw = single_data_read(device, channel->ch_num,
+					attr_polarity_val[channel->ch_num]);
 
 	return (ssize_t) sprintf(buf, "%d", adc_data_raw);
 }
 
-ssize_t set_chn_raw(void *device,
-		    char *buf,
-		    size_t len,
-		    const struct iio_ch_info *channel)
+static ssize_t set_chn_raw(void *device,
+			   char *buf,
+			   size_t len,
+			   const struct iio_ch_info *channel,
+			   intptr_t id)
 {
 	/* NA- Can't set raw value */
 	return len;
@@ -325,10 +308,11 @@
  * @return	Number of characters read/written
  * @note	Available only for AD7606B and AD7606C
  */
-ssize_t get_operating_mode(void *device,
-			   char *buf,
-			   size_t len,
-			   const struct iio_ch_info *channel)
+static ssize_t get_operating_mode(void *device,
+				  char *buf,
+				  size_t len,
+				  const struct iio_ch_info *channel,
+				  intptr_t id)
 {
 	uint8_t read_val;
 	uint8_t operating_mode_value;
@@ -345,10 +329,11 @@
 	return -EINVAL;
 }
 
-ssize_t set_operating_mode(void *device,
-			   char *buf,
-			   size_t len,
-			   const struct iio_ch_info *channel)
+static ssize_t set_operating_mode(void *device,
+				  char *buf,
+				  size_t len,
+				  const struct iio_ch_info *channel,
+				  intptr_t id)
 {
 	uint8_t operating_mode_value;
 
@@ -377,10 +362,11 @@
  * @return	Number of characters read/written
  * @note	Available for all devices except AD7606B and AD7606C
  */
-ssize_t get_power_down_mode(void *device,
-			    char *buf,
-			    size_t len,
-			    const struct iio_ch_info *channel)
+static ssize_t get_power_down_mode(void *device,
+				   char *buf,
+				   size_t len,
+				   const struct iio_ch_info *channel,
+				   intptr_t id)
 {
 	uint8_t gpio_stby_val;
 	uint8_t gpio_range_val;
@@ -405,10 +391,11 @@
 	return -EINVAL;
 }
 
-ssize_t set_power_down_mode(void *device,
-			    char *buf,
-			    size_t len,
-			    const struct iio_ch_info *channel)
+static ssize_t set_power_down_mode(void *device,
+				   char *buf,
+				   size_t len,
+				   const struct iio_ch_info *channel,
+				   intptr_t id)
 {
 	uint8_t power_down_mode_value;
 	static enum ad7606_op_mode prev_power_down_mode = AD7606_NORMAL;
@@ -478,10 +465,11 @@
  * @return	Number of characters read/written
  * @note	Available for all devices except AD7606B and AD7606C
  */
-ssize_t get_range(void *device,
-		  char *buf,
-		  size_t len,
-		  const struct iio_ch_info *channel)
+static ssize_t get_range(void *device,
+			 char *buf,
+			 size_t len,
+			 const struct iio_ch_info *channel,
+			 intptr_t id)
 {
 	uint8_t gpio_range_val;
 	struct ad7606_dev *dev = device;
@@ -497,10 +485,11 @@
 	return -EINVAL;
 }
 
-ssize_t set_range(void *device,
-		  char *buf,
-		  size_t len,
-		  const struct iio_ch_info *channel)
+static ssize_t set_range(void *device,
+			 char *buf,
+			 size_t len,
+			 const struct iio_ch_info *channel,
+			 intptr_t id)
 {
 	uint8_t range_value;
 	struct ad7606_dev *dev = device;
@@ -532,10 +521,11 @@
  * @return	Number of characters read/written
  * @note	Available for all devices except AD7606B and AD7606C
  */
-ssize_t get_oversampling(void *device,
-			 char *buf,
-			 size_t len,
-			 const struct iio_ch_info *channel)
+static ssize_t get_oversampling(void *device,
+				char *buf,
+				size_t len,
+				const struct iio_ch_info *channel,
+				intptr_t id)
 {
 	uint8_t oversampling_value;
 	uint8_t read_val;
@@ -574,10 +564,11 @@
 	return -EINVAL;
 }
 
-ssize_t set_oversampling(void *device,
-			 char *buf,
-			 size_t len,
-			 const struct iio_ch_info *channel)
+static ssize_t set_oversampling(void *device,
+				char *buf,
+				size_t len,
+				const struct iio_ch_info *channel,
+				intptr_t id)
 {
 	uint8_t oversampling_value;
 	struct ad7606_oversampling oversampling_cfg;
@@ -608,10 +599,11 @@
  * @return	Number of characters read/written
  * @note	Available for only AD7606C
  */
-ssize_t get_bandwidth(void *device,
-		      char *buf,
-		      size_t len,
-		      const struct iio_ch_info *channel)
+static ssize_t get_bandwidth(void *device,
+			     char *buf,
+			     size_t len,
+			     const struct iio_ch_info *channel,
+			     intptr_t id)
 {
 	uint8_t bw_value;
 	uint8_t read_val;
@@ -619,7 +611,7 @@
 	if (ad7606_spi_reg_read(device,
 				AD7606_REG_BANDWIDTH,
 				&read_val) == SUCCESS) {
-		bw_value = (read_val >> (channel->ch_num - 1)) & 0x1;
+		bw_value = (read_val >> (channel->ch_num)) & 0x1;
 
 		if (bw_value < sizeof(bandwidth_str) / sizeof(
 			    bandwidth_str[0])) {
@@ -630,10 +622,11 @@
 	return -EINVAL;
 }
 
-ssize_t set_bandwidth(void *device,
-		      char *buf,
-		      size_t len,
-		      const struct iio_ch_info *channel)
+static ssize_t set_bandwidth(void *device,
+			     char *buf,
+			     size_t len,
+			     const struct iio_ch_info *channel,
+			     intptr_t id)
 {
 	uint8_t bw_value;
 	uint8_t read_val;
@@ -646,9 +639,9 @@
 					AD7606_REG_BANDWIDTH,
 					&read_val) == SUCCESS) {
 			if (bw_value) {
-				read_val |= (1 << (channel->ch_num - 1));
+				read_val |= (1 << (channel->ch_num));
 			} else {
-				read_val &= (~(1 << (channel->ch_num - 1)));
+				read_val &= (~(1 << (channel->ch_num)));
 			}
 
 			if (ad7606_spi_reg_write(device,
@@ -672,26 +665,27 @@
  * @return	Number of characters read/written
  * @note	Available only for AD7606B and AD7606C
  */
-ssize_t get_chn_range(void *device,
-		      char *buf,
-		      size_t len,
-		      const struct iio_ch_info *channel)
+static ssize_t get_chn_range(void *device,
+			     char *buf,
+			     size_t len,
+			     const struct iio_ch_info *channel,
+			     intptr_t id)
 {
 	uint8_t read_val;
 	uint8_t chn_range;
 
-	if (ad7606_spi_reg_read(device, AD7606_REG_RANGE_CH_ADDR(channel->ch_num-1),
+	if (ad7606_spi_reg_read(device, AD7606_REG_RANGE_CH_ADDR(channel->ch_num),
 				&read_val) == SUCCESS) {
-		if (((channel->ch_num - 1) % 2) != 0) {
+		if (((channel->ch_num) % 2) != 0) {
 			read_val >>= CHANNEL_RANGE_MSK_OFFSET;
 			chn_range = read_val;
 		} else {
-			chn_range = (read_val & AD7606_RANGE_CH_MSK(channel->ch_num - 1));
+			chn_range = (read_val & AD7606_RANGE_CH_MSK(channel->ch_num));
 		}
 
 		if (chn_range < sizeof(chn_range_str) / sizeof(chn_range_str[0])) {
-			attr_chn_range[channel->ch_num - 1] = chn_range_val[chn_range];
-			attr_polarity_val[channel->ch_num - 1] = ad7606_get_input_polarity(chn_range);
+			attr_chn_range[channel->ch_num] = chn_range_val[chn_range];
+			attr_polarity_val[channel->ch_num] = ad7606_get_input_polarity(chn_range);
 
 			return (ssize_t)sprintf(buf, "%s", chn_range_str[chn_range]);
 		}
@@ -700,10 +694,11 @@
 	return -EINVAL;
 }
 
-ssize_t set_chn_range(void *device,
-		      char *buf,
-		      size_t len,
-		      const struct iio_ch_info *channel)
+static ssize_t set_chn_range(void *device,
+			     char *buf,
+			     size_t len,
+			     const struct iio_ch_info *channel,
+			     intptr_t id)
 {
 	uint8_t chn_range;
 
@@ -712,20 +707,20 @@
 	if (chn_range < sizeof(chn_range_val) / sizeof(chn_range_val[0])) {
 
 		/* Get the polarity of channel */
-		attr_polarity_val[channel->ch_num - 1] = ad7606_get_input_polarity(chn_range);
+		attr_polarity_val[channel->ch_num] = ad7606_get_input_polarity(chn_range);
 
-		attr_chn_range[channel->ch_num - 1] = chn_range_val[chn_range];
-		attr_scale_val[channel->ch_num - 1] = get_vltg_conv_scale_factor(
+		attr_chn_range[channel->ch_num] = chn_range_val[chn_range];
+		attr_scale_val[channel->ch_num] = get_vltg_conv_scale_factor(
 				chn_range_val[chn_range],
-				attr_polarity_val[channel->ch_num - 1]);
+				attr_polarity_val[channel->ch_num]);
 
-		if (((channel->ch_num - 1) % 2) != 0) {
+		if (((channel->ch_num) % 2) != 0) {
 			chn_range <<= CHANNEL_RANGE_MSK_OFFSET;
 		}
 
 		if (ad7606_spi_write_mask(device,
-					  AD7606_REG_RANGE_CH_ADDR(channel->ch_num-1),
-					  AD7606_RANGE_CH_MSK(channel->ch_num-1),
+					  AD7606_REG_RANGE_CH_ADDR(channel->ch_num),
+					  AD7606_RANGE_CH_MSK(channel->ch_num),
 					  chn_range) == SUCCESS) {
 			return len;
 		}
@@ -744,14 +739,15 @@
  * @return	Number of characters read/written
  * @note	Available only for AD7606B and AD7606C
  */
-ssize_t get_chn_offset(void *device,
-		       char *buf,
-		       size_t len,
-		       const struct iio_ch_info *channel)
+static ssize_t get_chn_offset(void *device,
+			      char *buf,
+			      size_t len,
+			      const struct iio_ch_info *channel,
+			      intptr_t id)
 {
 	uint8_t chn_offset_value;
 
-	if (ad7606_spi_reg_read(device, AD7606_REG_OFFSET_CH(channel->ch_num-1),
+	if (ad7606_spi_reg_read(device, AD7606_REG_OFFSET_CH(channel->ch_num),
 				&chn_offset_value) == SUCCESS) {
 		return (ssize_t)sprintf(buf, "%d", chn_offset_value);
 	}
@@ -759,16 +755,17 @@
 	return -EINVAL;
 }
 
-ssize_t set_chn_offset(void *device,
-		       char *buf,
-		       size_t len,
-		       const struct iio_ch_info *channel)
+static ssize_t set_chn_offset(void *device,
+			      char *buf,
+			      size_t len,
+			      const struct iio_ch_info *channel,
+			      intptr_t id)
 {
 	uint8_t chn_offset_value = 0;
 
 	(void)sscanf(buf, "%d", &chn_offset_value);
 
-	if (ad7606_set_ch_offset(device, channel->ch_num - 1,
+	if (ad7606_set_ch_offset(device, channel->ch_num,
 				 chn_offset_value) == SUCCESS) {
 		return len;
 	}
@@ -786,15 +783,16 @@
  * @return	Number of characters read/written
  * @note	Available only for AD7606B and AD7606C
  */
-ssize_t get_chn_phase_offset(void *device,
-			     char *buf,
-			     size_t len,
-			     const struct iio_ch_info *channel)
+static ssize_t get_chn_phase_offset(void *device,
+				    char *buf,
+				    size_t len,
+				    const struct iio_ch_info *channel,
+				    intptr_t id)
 {
 	uint8_t chn_phase_offset_value;
 
 	if (ad7606_spi_reg_read(device,
-				AD7606_REG_PHASE_CH(channel->ch_num - 1),
+				AD7606_REG_PHASE_CH(channel->ch_num),
 				&chn_phase_offset_value) == SUCCESS) {
 		return (ssize_t)sprintf(buf, "%d", chn_phase_offset_value);
 	}
@@ -802,16 +800,17 @@
 	return -EINVAL;
 }
 
-ssize_t set_chn_phase_offset(void *device,
-			     char *buf,
-			     size_t len,
-			     const struct iio_ch_info *channel)
+static ssize_t set_chn_phase_offset(void *device,
+				    char *buf,
+				    size_t len,
+				    const struct iio_ch_info *channel,
+				    intptr_t id)
 {
 	uint8_t chn_phase_offset_value = 0;
 
 	(void)sscanf(buf, "%d", &chn_phase_offset_value);
 
-	if (ad7606_set_ch_phase(device, channel->ch_num - 1,
+	if (ad7606_set_ch_phase(device, channel->ch_num,
 				chn_phase_offset_value) == SUCCESS) {
 		return len;
 	}
@@ -829,10 +828,11 @@
  * @return	Number of characters read/written
  * @note	Available only for AD7606B and AD7606C
  */
-ssize_t get_chn_temperature(void *device,
-			    char *buf,
-			    size_t len,
-			    const struct iio_ch_info *channel)
+static ssize_t get_chn_temperature(void *device,
+				   char *buf,
+				   size_t len,
+				   const struct iio_ch_info *channel,
+				   intptr_t id)
 {
 	int32_t adc_chn_data = 0;
 	float temperature;
@@ -840,30 +840,30 @@
 
 	/* Configure the channel multiplexer to select temperature read */
 	if (ad7606_spi_write_mask(device,
-				  AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
-				  AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
-				  AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+				  AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num),
+				  AD7606_DIAGN_MUX_CH_MSK(channel->ch_num),
+				  AD7606_DIAGN_MUX_CH_VAL((channel->ch_num),
 						  TEMPERATURE_MUX)) == SUCCESS) {
 
 		/* Allow to settle Mux channel */
 		udelay(100);
 
 		/* Sample the channel and read conversion result */
-		adc_chn_data = single_data_read(device, channel->ch_num - 1,
-						attr_polarity_val[channel->ch_num - 1]);
+		adc_chn_data = single_data_read(device, channel->ch_num,
+						attr_polarity_val[channel->ch_num]);
 
 		/* Convert ADC data into equivalent voltage */
 		voltage = convert_adc_raw_to_voltage(adc_chn_data,
-						     attr_scale_val[channel->ch_num - 1]);
+						     attr_scale_val[channel->ch_num]);
 
 		/* Obtain the temperature using equation specified in device datasheet */
 		temperature = ((voltage - 0.69068) / 0.019328) + 25.0;
 
 		/* Change channel mux back to analog input */
 		(void)ad7606_spi_write_mask(device,
-					    AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
-					    AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
-					    AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+					    AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num),
+					    AD7606_DIAGN_MUX_CH_MSK(channel->ch_num),
+					    AD7606_DIAGN_MUX_CH_VAL((channel->ch_num),
 							    ANALOG_INPUT_MUX));
 
 		return (ssize_t)sprintf(buf, "%f", temperature);
@@ -872,10 +872,11 @@
 	return -EINVAL;
 }
 
-ssize_t set_chn_temperature(void *device,
-			    char *buf,
-			    size_t len,
-			    const struct iio_ch_info *channel)
+static ssize_t set_chn_temperature(void *device,
+				   char *buf,
+				   size_t len,
+				   const struct iio_ch_info *channel,
+				   intptr_t id)
 {
 	// NA- Can't set temperature
 	return -EINVAL;
@@ -891,40 +892,41 @@
  * @return	Number of characters read/written
  * @note	Available only for AD7606B and AD7606C
  */
-ssize_t get_chn_vref(void *device,
-		     char *buf,
-		     size_t len,
-		     const struct iio_ch_info *channel)
+static ssize_t get_chn_vref(void *device,
+			    char *buf,
+			    size_t len,
+			    const struct iio_ch_info *channel,
+			    intptr_t id)
 {
 	float vref_voltge;
 	int32_t adc_chn_data;
 
 	/* Configure the channel multiplexer to select Vref read */
 	if (ad7606_spi_write_mask(device,
-				  AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
-				  AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
-				  AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+				  AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num),
+				  AD7606_DIAGN_MUX_CH_MSK(channel->ch_num),
+				  AD7606_DIAGN_MUX_CH_VAL((channel->ch_num),
 						  VREF_MUX)) == SUCCESS) {
 
 		/* Allow to settle Mux channel */
 		udelay(100);
 
 		/* Sample the channel and read conversion result */
-		adc_chn_data = single_data_read(device, channel->ch_num - 1,
-						attr_polarity_val[channel->ch_num - 1]);
+		adc_chn_data = single_data_read(device, channel->ch_num,
+						attr_polarity_val[channel->ch_num]);
 
 		/* Convert ADC data into equivalent voltage */
 		vref_voltge = convert_adc_raw_to_voltage(adc_chn_data,
-				attr_scale_val[channel->ch_num - 1]);
+				attr_scale_val[channel->ch_num]);
 
 		/* Divide by 4 since Vref Mux has 4x multiplier on it */
 		vref_voltge /= VREF_MUX_MULTIPLIER;
 
 		/* Change channel mux back to analog input */
 		(void)ad7606_spi_write_mask(device,
-					    AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
-					    AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
-					    AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+					    AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num),
+					    AD7606_DIAGN_MUX_CH_MSK(channel->ch_num),
+					    AD7606_DIAGN_MUX_CH_VAL((channel->ch_num),
 							    ANALOG_INPUT_MUX));
 
 		return (ssize_t)sprintf(buf, "%f", vref_voltge);
@@ -933,10 +935,11 @@
 	return -EINVAL;
 }
 
-ssize_t set_chn_vref(void *device,
-		     char *buf,
-		     size_t len,
-		     const struct iio_ch_info *channel)
+static ssize_t set_chn_vref(void *device,
+			    char *buf,
+			    size_t len,
+			    const struct iio_ch_info *channel,
+			    intptr_t id)
 {
 	// NA- Can't set Vref
 	return - EINVAL;
@@ -952,37 +955,38 @@
  * @return	Number of characters read/written
  * @note	Available only for AD7606B and AD7606C
  */
-ssize_t get_chn_vdrive(void *device,
-		       char *buf,
-		       size_t len,
-		       const struct iio_ch_info *channel)
+static ssize_t get_chn_vdrive(void *device,
+			      char *buf,
+			      size_t len,
+			      const struct iio_ch_info *channel,
+			      intptr_t id)
 {
 	float vdrive_voltge;
 	int32_t adc_chn_data;
 
 	/* Configure the channel multiplexer to select Vdrive read */
 	if (ad7606_spi_write_mask(device,
-				  AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
-				  AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
-				  AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+				  AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num),
+				  AD7606_DIAGN_MUX_CH_MSK(channel->ch_num),
+				  AD7606_DIAGN_MUX_CH_VAL((channel->ch_num),
 						  VDRIVE_MUX)) == SUCCESS) {
 
 		/* Allow to settle Mux channel */
 		udelay(100);
 
 		/* Sample the channel and read conversion result */
-		adc_chn_data = single_data_read(device, channel->ch_num - 1,
-						attr_polarity_val[channel->ch_num - 1]);
+		adc_chn_data = single_data_read(device, channel->ch_num,
+						attr_polarity_val[channel->ch_num]);
 
 		/* Convert ADC data into equivalent voltage */
 		vdrive_voltge = convert_adc_raw_to_voltage(adc_chn_data,
-				attr_scale_val[channel->ch_num - 1]);
+				attr_scale_val[channel->ch_num]);
 
 		/* Change channel mux back to analog input */
 		(void)ad7606_spi_write_mask(device,
-					    AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
-					    AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
-					    AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+					    AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num),
+					    AD7606_DIAGN_MUX_CH_MSK(channel->ch_num),
+					    AD7606_DIAGN_MUX_CH_VAL((channel->ch_num),
 							    ANALOG_INPUT_MUX));
 
 		return (ssize_t)sprintf(buf, "%f", vdrive_voltge);
@@ -991,10 +995,11 @@
 	return -EINVAL;
 }
 
-ssize_t set_chn_vdrive(void *device,
-		       char *buf,
-		       size_t len,
-		       const struct iio_ch_info *channel)
+static ssize_t set_chn_vdrive(void *device,
+			      char *buf,
+			      size_t len,
+			      const struct iio_ch_info *channel,
+			      intptr_t id)
 {
 	// NA- Can't set Vdrive
 	return - EINVAL;
@@ -1010,40 +1015,41 @@
  * @return	Number of characters read/written
  * @note	Available only for AD7606B and AD7606C
  */
-ssize_t get_chn_aldo(void *device,
-		     char *buf,
-		     size_t len,
-		     const struct iio_ch_info *channel)
+static ssize_t get_chn_aldo(void *device,
+			    char *buf,
+			    size_t len,
+			    const struct iio_ch_info *channel,
+			    intptr_t id)
 {
 	float aldo_voltge;
 	int32_t adc_chn_data;
 
 	/* Configure the channel multiplexer to select ALDO read */
 	if (ad7606_spi_write_mask(device,
-				  AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
-				  AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
-				  AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+				  AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num),
+				  AD7606_DIAGN_MUX_CH_MSK(channel->ch_num),
+				  AD7606_DIAGN_MUX_CH_VAL((channel->ch_num),
 						  ALDO_MUX)) == SUCCESS) {
 
 		/* Allow to settle Mux channel */
 		udelay(100);
 
 		/* Sample the channel and read conversion result */
-		adc_chn_data = single_data_read(device, channel->ch_num - 1,
-						attr_polarity_val[channel->ch_num - 1]);
+		adc_chn_data = single_data_read(device, channel->ch_num,
+						attr_polarity_val[channel->ch_num]);
 
 		/* Convert ADC data into equivalent voltage */
 		aldo_voltge = convert_adc_raw_to_voltage(adc_chn_data,
-				attr_scale_val[channel->ch_num - 1]);
+				attr_scale_val[channel->ch_num]);
 
 		/* Divide by 4 since ALDO Mux has 4x multiplier on it */
 		aldo_voltge /= VREF_MUX_MULTIPLIER;
 
 		/* Change channel mux back to analog input */
 		(void)ad7606_spi_write_mask(device,
-					    AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
-					    AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
-					    AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+					    AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num),
+					    AD7606_DIAGN_MUX_CH_MSK(channel->ch_num),
+					    AD7606_DIAGN_MUX_CH_VAL((channel->ch_num),
 							    ANALOG_INPUT_MUX));
 
 		return (ssize_t)sprintf(buf, "%f", aldo_voltge);
@@ -1052,10 +1058,11 @@
 	return -EINVAL;
 }
 
-ssize_t set_chn_aldo(void *device,
-		     char *buf,
-		     size_t len,
-		     const struct iio_ch_info *channel)
+static ssize_t set_chn_aldo(void *device,
+			    char *buf,
+			    size_t len,
+			    const struct iio_ch_info *channel,
+			    intptr_t id)
 {
 	// NA- Can't set ALDO
 	return - EINVAL;
@@ -1071,19 +1078,20 @@
  * @return	Number of characters read/written
  * @note	Available only for AD7606B and AD7606C
  */
-ssize_t get_chn_dldo(void *device,
-		     char *buf,
-		     size_t len,
-		     const struct iio_ch_info *channel)
+static ssize_t get_chn_dldo(void *device,
+			    char *buf,
+			    size_t len,
+			    const struct iio_ch_info *channel,
+			    intptr_t id)
 {
 	float dldo_voltge;
 	int32_t adc_chn_data;
 
 	/* Configure the channel multiplexer to select DLDO read */
 	if (ad7606_spi_write_mask(device,
-				  AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
-				  AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
-				  AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+				  AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num),
+				  AD7606_DIAGN_MUX_CH_MSK(channel->ch_num),
+				  AD7606_DIAGN_MUX_CH_VAL((channel->ch_num),
 						  DLDO_MUX)) == SUCCESS) {
 
 		/* Allow to settle Mux channel */
@@ -1091,21 +1099,21 @@
 
 		/* Sample the channel and read conversion result */
 		adc_chn_data = single_data_read(device,
-						channel->ch_num - 1,
-						attr_polarity_val[channel->ch_num - 1]);
+						channel->ch_num,
+						attr_polarity_val[channel->ch_num]);
 
 		/* Convert ADC data into equivalent voltage */
 		dldo_voltge = convert_adc_raw_to_voltage(adc_chn_data,
-				attr_scale_val[channel->ch_num - 1]);
+				attr_scale_val[channel->ch_num]);
 
 		/* Divide by 4 since ALDO Mux has 4x multiplier on it */
 		dldo_voltge /= VREF_MUX_MULTIPLIER;
 
 		/* Change channel mux back to analog input */
 		(void)ad7606_spi_write_mask(device,
-					    AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
-					    AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
-					    AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+					    AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num),
+					    AD7606_DIAGN_MUX_CH_MSK(channel->ch_num),
+					    AD7606_DIAGN_MUX_CH_VAL((channel->ch_num),
 							    ANALOG_INPUT_MUX));
 
 		return (ssize_t)sprintf(buf, "%f", dldo_voltge);
@@ -1114,10 +1122,11 @@
 	return -EINVAL;
 }
 
-ssize_t set_chn_dldo(void *device,
-		     char *buf,
-		     size_t len,
-		     const struct iio_ch_info *channel)
+static ssize_t set_chn_dldo(void *device,
+			    char *buf,
+			    size_t len,
+			    const struct iio_ch_info *channel,
+			    intptr_t id)
 {
 	// NA- Can't set DLDO
 	return - EINVAL;
@@ -1132,10 +1141,11 @@
  * @param	channel- pointer to IIO channel structure
  * @return	Number of characters read/written
  */
-ssize_t get_chn_open_circuit_detect_manual(void *device,
+static ssize_t get_chn_open_circuit_detect_manual(void *device,
 		char *buf,
 		size_t len,
-		const struct iio_ch_info *channel)
+		const struct iio_ch_info *channel,
+		intptr_t id)
 {
 	int32_t prev_adc_code, curr_adc_code;
 	bool open_detect_flag = false;
@@ -1147,8 +1157,8 @@
 		if (ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_QUEUE, 1) == SUCCESS) {
 			/* Read the ADC on selected chnnel (first reading post open circuit detection start) */
 			prev_adc_code = single_data_read(device,
-							 channel->ch_num - 1,
-							 attr_polarity_val[channel->ch_num - 1]);
+							 channel->ch_num,
+							 attr_polarity_val[channel->ch_num]);
 
 			/* Perform N conversions and monitor the code delta */
 			for (cnt = 0; cnt < MANUAL_OPEN_DETECT_CONV_CNTS; cnt++) {
@@ -1156,8 +1166,8 @@
 				if (prev_adc_code >= 0 && prev_adc_code < MANUAL_OPEN_DETECT_ENTRY_TRHLD) {
 					/* Perform next conversion and read the result */
 					curr_adc_code = single_data_read(device,
-									 channel->ch_num - 1,
-									 attr_polarity_val[channel->ch_num - 1]);
+									 channel->ch_num,
+									 attr_polarity_val[channel->ch_num]);
 
 					/* Check if delta b/w current and previus reading is within 10 LSB code */
 					if (abs(curr_adc_code - prev_adc_code) > MANUAL_OPEN_DETECT_CONV_TRSHLD) {
@@ -1180,14 +1190,14 @@
 			/* Set common mode high (enabling open circuit detect on selected channel) */
 			if (ad7606_spi_reg_write(device,
 						 AD7606_REG_OPEN_DETECT_ENABLE,
-						 (1 << ((channel->ch_num) - 1))) == SUCCESS) {
+						 (1 << (channel->ch_num))) == SUCCESS) {
 
 				/* Perform next conversions (~2-3) and read the result (with common mode set high) */
 				for (cnt = 0; cnt < MANUAL_OPEN_DETECT_CM_CNV_CNT; cnt++) {
 					udelay(100);
 					curr_adc_code = single_data_read(device,
-									 channel->ch_num - 1,
-									 attr_polarity_val[channel->ch_num - 1]);
+									 channel->ch_num,
+									 attr_polarity_val[channel->ch_num]);
 				}
 
 				/* Check if delta b/w common mode high code and previous N conversion code is > threshold */
@@ -1209,8 +1219,8 @@
 						 0) == SUCCESS) {
 				/* Perform next conversion and read the result (with common mode set low) */
 				curr_adc_code = single_data_read(device,
-								 channel->ch_num - 1,
-								 attr_polarity_val[channel->ch_num - 1]);
+								 channel->ch_num,
+								 attr_polarity_val[channel->ch_num]);
 
 				/* Check if delta b/w common mode low code and previous N conversion code is < threshold */
 				if (abs(curr_adc_code - prev_adc_code) < MANUAL_OPEN_DETECT_THRESHOLD_RPD50K) {
@@ -1241,10 +1251,11 @@
 	return -EINVAL;
 }
 
-ssize_t set_chn_open_circuit_detect_manual(void *device,
+static ssize_t set_chn_open_circuit_detect_manual(void *device,
 		char *buf,
 		size_t len,
-		const struct iio_ch_info *channel)
+		const struct iio_ch_info *channel,
+		intptr_t id)
 {
 	// NA- Can't set open circuit detect
 	return - EINVAL;
@@ -1259,10 +1270,11 @@
  * @param	channel- pointer to IIO channel structure
  * @return	Number of characters read/written
  */
-ssize_t get_chn_open_circuit_detect_auto(void *device,
+static ssize_t get_chn_open_circuit_detect_auto(void *device,
 		char *buf,
 		size_t len,
-		const struct iio_ch_info *channel)
+		const struct iio_ch_info *channel,
+		intptr_t id)
 {
 	if (open_circuit_detect_read_done) {
 		open_circuit_detect_read_done = false;
@@ -1281,13 +1293,14 @@
 	}
 
 	return (ssize_t)sprintf(buf, "OPEN_DETECT_QUEUE: %d",
-				open_detect_queue_cnts[channel->ch_num - 1]);
+				open_detect_queue_cnts[channel->ch_num]);
 }
 
-ssize_t set_chn_open_circuit_detect_auto(void *device,
+static ssize_t set_chn_open_circuit_detect_auto(void *device,
 		char *buf,
 		size_t len,
-		const struct iio_ch_info *channel)
+		const struct iio_ch_info *channel,
+		intptr_t id)
 {
 	uint8_t data;
 	uint8_t open_detect_flag = false;
@@ -1299,21 +1312,21 @@
 
 	if ((data > 1 && data <= AUTO_OPEN_DETECT_QUEUE_MAX_CNT) && (buf[0] >= '0'
 			&& buf[0] <= '9')) {
-		open_detect_queue_cnts[channel->ch_num - 1] = data;
+		open_detect_queue_cnts[channel->ch_num] = data;
 
 		/* Enter into open circuit auto open detect mode */
 		if (ad7606_spi_reg_write(device,
 					 AD7606_REG_OPEN_DETECT_QUEUE,
-					 open_detect_queue_cnts[channel->ch_num - 1]) == SUCCESS) {
+					 open_detect_queue_cnts[channel->ch_num]) == SUCCESS) {
 			/* Enable open circuit detection on selected channel */
 			if (ad7606_spi_reg_write(device,
 						 AD7606_REG_OPEN_DETECT_ENABLE,
-						 (1 << ((channel->ch_num) - 1))) == SUCCESS) {
+						 (1 << (channel->ch_num))) == SUCCESS) {
 				/* Monitor the open detect flag for max N+15 (open detect queue count) conversions.
 				 * Note: In ideal scenario, the open detect flash should be monitored continuously while
 				 * background N conversions are in progress */
 				for (conv_cnts = 0;
-				     conv_cnts < (open_detect_queue_cnts[channel->ch_num - 1] +
+				     conv_cnts < (open_detect_queue_cnts[channel->ch_num] +
 						  AUTO_OPEN_DETECT_QUEUE_EXTRA_CONV_CNT);
 				     conv_cnts++) {
 					if (ad7606_convst(device) == SUCCESS) {
@@ -1323,7 +1336,7 @@
 						if (ad7606_spi_reg_read(device,
 									AD7606_REG_OPEN_DETECTED,
 									&open_detect_flag) == SUCCESS) {
-							open_detect_flag >>= (channel->ch_num - 1);
+							open_detect_flag >>= (channel->ch_num);
 							open_detect_flag &= 0x1;
 
 							rw_status = SUCCESS;
@@ -1346,7 +1359,7 @@
 		(void)ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_QUEUE, 0);
 		(void)ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECTED, 0xFF);
 
-		open_detect_queue_cnts[channel->ch_num - 1] = 0;
+		open_detect_queue_cnts[channel->ch_num] = 0;
 
 		if (rw_status == SUCCESS) {
 			if (open_detect_flag) {
@@ -1373,37 +1386,38 @@
  * @param	channel- pointer to IIO channel structure
  * @return	Number of characters read/written
  */
-ssize_t get_chn_calibrate_adc_offset(void *device,
-				     char *buf,
-				     size_t len,
-				     const struct iio_ch_info *channel)
+static ssize_t get_chn_calibrate_adc_offset(void *device,
+		char *buf,
+		size_t len,
+		const struct iio_ch_info *channel,
+		intptr_t id)
 {
 	float lsb_voltage;
 	float adc_voltage;
-	polarity_e polarity = attr_polarity_val[channel->ch_num - 1];
+	polarity_e polarity = attr_polarity_val[channel->ch_num];
 	int32_t adc_data;
 	int8_t chn_offset;
 
 	/* Perform the system offset calibration */
 
 	if (polarity == UNIPOLAR) {
-		lsb_voltage = attr_chn_range[channel->ch_num - 1] / ADC_MAX_COUNT_UNIPOLAR;
+		lsb_voltage = attr_chn_range[channel->ch_num] / ADC_MAX_COUNT_UNIPOLAR;
 	} else {
-		lsb_voltage = attr_chn_range[channel->ch_num - 1] / ADC_MAX_COUNT_BIPOLAR;
+		lsb_voltage = attr_chn_range[channel->ch_num] / ADC_MAX_COUNT_BIPOLAR;
 	}
 
 	/* Sample and read the ADC channel */
-	adc_data = single_data_read(device, channel->ch_num - 1,
+	adc_data = single_data_read(device, channel->ch_num,
 				    polarity);
 
 	/* Get an equivalent ADC voltage */
 	adc_voltage = convert_adc_raw_to_voltage(adc_data,
-			attr_scale_val[channel->ch_num - 1]);
+			attr_scale_val[channel->ch_num]);
 
 	/* Calculate the channel offset and write it to offset register */
 	chn_offset = -(adc_voltage / lsb_voltage / OFFSET_REG_RESOLUTION);
 
-	if (ad7606_set_ch_offset(device, channel->ch_num - 1,
+	if (ad7606_set_ch_offset(device, channel->ch_num,
 				 chn_offset) == SUCCESS) {
 		return sprintf(buf, "%s", "ADC Calibration Done");
 	}
@@ -1411,10 +1425,11 @@
 	return -EINVAL;
 }
 
-ssize_t set_chn_calibrate_adc_offset(void *device,
-				     char *buf,
-				     size_t len,
-				     const struct iio_ch_info *channel)
+static ssize_t set_chn_calibrate_adc_offset(void *device,
+		char *buf,
+		size_t len,
+		const struct iio_ch_info *channel,
+		intptr_t id)
 {
 	// NA- Can't set open circuit detect
 	return - EINVAL;
@@ -1429,10 +1444,11 @@
  * @param	channel- pointer to IIO channel structure
  * @return	Number of characters read/written
  */
-ssize_t get_chn_calibrate_adc_gain(void *device,
-				   char *buf,
-				   size_t len,
-				   const struct iio_ch_info *channel)
+static ssize_t get_chn_calibrate_adc_gain(void *device,
+		char *buf,
+		size_t len,
+		const struct iio_ch_info *channel,
+		intptr_t id)
 {
 	uint8_t read_val;
 
@@ -1440,25 +1456,26 @@
 		/* Get calibration status for previous gain value write event */
 		gain_calibration_done = false;
 		return sprintf(buf, "Calibration Done (Rfilter=%d K)",
-			       gain_calibration_reg_val[channel->ch_num - 1]);
+			       gain_calibration_reg_val[channel->ch_num]);
 	}
 
 	/* Return gain value when normal read event is triggered */
 	if (ad7606_spi_reg_read(device,
-				AD7606_REG_GAIN_CH(channel->ch_num - 1),
+				AD7606_REG_GAIN_CH(channel->ch_num),
 				&read_val) == SUCCESS) {
-		gain_calibration_reg_val[channel->ch_num - 1] = (read_val & AD7606_GAIN_MSK);
+		gain_calibration_reg_val[channel->ch_num] = (read_val & AD7606_GAIN_MSK);
 		return sprintf(buf, "Rfilter= %d K",
-			       gain_calibration_reg_val[channel->ch_num - 1]);
+			       gain_calibration_reg_val[channel->ch_num]);
 	}
 
 	return -EINVAL;
 }
 
-ssize_t set_chn_calibrate_adc_gain(void *device,
-				   char *buf,
-				   size_t len,
-				   const struct iio_ch_info *channel)
+static ssize_t set_chn_calibrate_adc_gain(void *device,
+		char *buf,
+		size_t len,
+		const struct iio_ch_info *channel,
+		intptr_t id)
 {
 	float data;
 
@@ -1467,12 +1484,12 @@
 
 		if (data >= 0 && data < ADC_CALIBRATION_GAIN_MAX) {
 			/* Get the nearest value of unsigned integer */
-			gain_calibration_reg_val[channel->ch_num - 1] = (uint8_t)(round(data));
+			gain_calibration_reg_val[channel->ch_num] = (uint8_t)(round(data));
 
 			/* Perform the gain calibration by writing gain value into gain register */
 			if (ad7606_set_ch_gain(device,
-					       channel->ch_num - 1,
-					       gain_calibration_reg_val[channel->ch_num - 1]) == SUCCESS) {
+					       channel->ch_num,
+					       gain_calibration_reg_val[channel->ch_num]) == SUCCESS) {
 				gain_calibration_done = true;
 				return len;
 			}
@@ -1484,79 +1501,42 @@
 
 
 /*!
- * @brief	Getter/Setter for the direct register access attribute value
- * @param	device- pointer to IIO device structure
- * @param	buf- pointer to buffer holding attribute value
- * @param	len- length of buffer string data
- * @param	channel- pointer to IIO channel structure
- * @return	Number of characters read/written
+ * @brief	Read the debug register value
+ * @param	dev- Pointer to IIO device instance
+ * @param	reg- Register address to read from
+ * @param	readval- Pointer to variable to read data into
+ * @return	SUCCESS in case of success, negative value otherwise
  */
-ssize_t get_direct_reg_access(void *device,
-			      char *buf,
-			      size_t len,
-			      const struct iio_ch_info *channel)
-{
-	return (ssize_t)sprintf(buf, "%d", device_reg_val);
-}
-
-ssize_t set_direct_reg_access(void *device,
-			      char *buf,
-			      size_t len,
-			      const struct iio_ch_info *channel)
+int32_t debug_reg_read(void *dev, uint32_t reg, uint32_t *readval)
 {
-	uint8_t reg_address;
-	char *token;
-	uint8_t offset = strlen("0x");
-	char str[10] = "";
-	uint8_t i=0;
-	uint8_t reg_data;
-
-	if (buf[1] == 'x') {
-		/* Write a data to device */
-
-		/* Extract the register address from received string */
-		strcpy(str, buf);
-		token = strtok(str, " ");
-		(void)sscanf(token + offset, "%x", &reg_address);
-
-		/* Extract the register data from received string */
-		i = (strlen(str) + 1) + offset;
-		(void)sscanf(str + i, "%x", &reg_data);
-
-		if (reg_address <= NUM_OF_REGISTERS) {
-			if ((ad7606_spi_reg_write(device, reg_address, reg_data) == SUCCESS)) {
-				save_local_attributes();
-				return len;
-			}
-		}
-	} else {
-		/* Read the data from device */
-		(void)sscanf(buf, "%d", &reg_address);
-		if ((ad7606_spi_reg_read(device, reg_address, &device_reg_val) == SUCCESS)) {
-			return len;
+	/* Read the data from device */
+	if (reg <= NUM_OF_REGISTERS) {
+		if ((ad7606_spi_reg_read(dev, reg, (uint8_t *)readval) == SUCCESS)) {
+			return SUCCESS;
 		}
 	}
 
-	return -EINVAL;
+	return FAILURE;
 }
 
 
-/**
- * @brief Get xml corresponding to an AD7606 device.
- * @param xml - Xml containing description of a device.
- * @param iio_dev - Structure describing a device, channels and attributes.
- * @return SUCCESS in case of success or negative value otherwise.
+/*!
+ * @brief	Write into the debug register
+ * @param	dev- Pointer to IIO device instance
+ * @param	reg- Register address to write into
+ * @param	writeval- Register value to write
+ * @return	SUCCESS in case of success, negative value otherwise
  */
-static ssize_t iio_ad7606_get_xml(char **xml, struct iio_device *iio_dev)
+int32_t debug_reg_write(void *dev, uint32_t reg, uint32_t writeval)
 {
-	*xml = (char*)calloc(1, strlen(ad7606_phy_xml) + 1);
-	if (!(*xml)) {
-		return -ENOMEM;
+	if (reg <= NUM_OF_REGISTERS) {
+		if ((ad7606_spi_reg_write(dev, reg, (uint8_t)writeval) == SUCCESS)) {
+			save_local_attributes();
+			return SUCCESS;
+		}
 	}
 
-	memcpy(*xml, ad7606_phy_xml, strlen(ad7606_phy_xml));
-
-	return SUCCESS;
+	return FAILURE;
 }
 
 
@@ -1572,9 +1552,9 @@
 				    size_t bytes_count,
 				    uint32_t ch_mask)
 {
-	if (adc_background_data_capture_started == false) {
+	if (adc_data_capture_started == false) {
 		start_background_data_capture(ch_mask, bytes_count);
-		adc_background_data_capture_started = true;
+		adc_data_capture_started = true;
 	}
 
 	/* Read the buffered data */
@@ -1583,60 +1563,287 @@
 
 
 /**
- * @brief	Read requested samples count
+ * @brief	Transfer the device data into memory (optional)
  * @param	dev_instance[in] - IIO device instance
- * @param	pbuf[out] - Pointer to output data buffer
+ * @param	bytes_count[in] - Number of bytes to read
+ * @param	ch_mask[in] - Channels select mask
  * @return	SUCCESS in case of success or negative value otherwise
  */
-static ssize_t iio_ad7606_get_samples_count(void *dev_instance,
+static ssize_t iio_ad7606_transfer_dev_data(void *dev_instance,
 		size_t bytes_count,
 		uint32_t ch_mask)
 {
+	/* The function insures that data is first read into memory from the device.
+	 * This function doesn't do any sort of data transfer but it make sure data
+	 * read and it's transfer to memory from device is happening in application through
+	 * iio_ad7606_read_data() function */
+
+	/* Store the requested samples count value for data capture */
 	store_requested_samples_count(bytes_count);
+
+	return SUCCESS;
+}
+
+
+/**
+ * @brief	Perform tasks before new data transfer
+ * @param	dev_instance[in] - IIO device instance
+ * @param	ch_mask[in] - Channels select mask
+ * @return	SUCCESS in case of success or negative value otherwise
+ */
+static int32_t iio_ad7606_start_transfer(void *dev_instance, uint32_t ch_mask)
+{
 	return SUCCESS;
 }
 
 
 /**
- * @brief	Create structure describing a device, channels and attributes
- * @param	device_name[in] - Device name
- * @return	iio_device or NULL, in case of failure
- */
-static struct iio_device *iio_ad7606_create_device(const char *device_name)
-{
-	struct iio_device *iio_ad7606_device;
-
-	iio_ad7606_device = calloc(1, sizeof(struct iio_device));
-	if (!iio_ad7606_device) {
-		return NULL;
-	}
-
-	iio_ad7606_device->name = device_name;
-	iio_ad7606_device->num_ch = sizeof(iio_ad7606_channels) / sizeof(
-					    iio_ad7606_channels[0]);
-	iio_ad7606_device->channels = iio_ad7606_channels;
-	iio_ad7606_device->attributes = global_attributes;
-
-	return iio_ad7606_device;
-}
-
-
-/**
- * @brief	Delete IIO device.
- * @param	iio_device - Structure describing a device, channels and attributes
+ * @brief	Perform tasks before end of current data transfer
+ * @param	dev_instance[in] - IIO device instance
  * @return	SUCCESS in case of success or negative value otherwise
  */
-static ssize_t iio_ad7606_delete_device(struct iio_device *iio_device)
+static int32_t iio_ad7606_stop_transfer(void *dev)
 {
-	if (!iio_device) {
-		return FAILURE;
-	}
-
-	free(iio_device);
+	adc_data_capture_started = false;
+	stop_background_data_capture();
 
 	return SUCCESS;
 }
 
+/*********************************************************
+ *               IIO Attributes and Structures
+ ********************************************************/
+
+/* IIOD channels attributes list */
+struct iio_attribute channel_input_attributes[] = {
+	{
+		.name = "raw",
+		.show = get_chn_raw,
+		.store = set_chn_raw,
+	},
+	{
+		.name = "scale",
+		.show = get_chn_scale,
+		.store = set_chn_scale,
+	},
+#if defined(DEV_AD7606B) || defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+	{
+		.name = "chn_range",
+		.show = get_chn_range,
+		.store = set_chn_range,
+	},
+	{
+		.name = "offset",
+		.show = get_chn_offset,
+		.store = set_chn_offset,
+	},
+	{
+		.name = "chn_phase offset",
+		.show = get_chn_phase_offset,
+		.store = set_chn_phase_offset,
+	},
+	{
+		.name = "temperature",
+		.show = get_chn_temperature,
+		.store = set_chn_temperature,
+	},
+	{
+		.name = "vref",
+		.show = get_chn_vref,
+		.store = set_chn_vref,
+	},
+	{
+		.name = "vdrive",
+		.show = get_chn_vdrive,
+		.store = set_chn_vdrive,
+	},
+	{
+		.name = "ALDO",
+		.show = get_chn_aldo,
+		.store = set_chn_aldo,
+	},
+	{
+		.name = "DLDO",
+		.show = get_chn_dldo,
+		.store = set_chn_dldo,
+	},
+	{
+		.name = "open_circuit_detect_manual",
+		.show = get_chn_open_circuit_detect_manual,
+		.store = set_chn_open_circuit_detect_manual,
+	},
+	{
+		.name = "open_circuit_detect_auto",
+		.show = get_chn_open_circuit_detect_auto,
+		.store = set_chn_open_circuit_detect_auto,
+	},
+	{
+		.name = "calibrate_adc_offset",
+		.show = get_chn_calibrate_adc_offset,
+		.store = set_chn_calibrate_adc_offset,
+	},
+	{
+		.name = "calibrate_adc_gain",
+		.show = get_chn_calibrate_adc_gain,
+		.store = set_chn_calibrate_adc_gain,
+	},
+#if defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+	&iio_attr_bandwidth
+	{
+		.name = "bandwidth",
+		.show = get_bandwidth,
+		.store = set_bandwidth,
+	},
+#endif
+#endif
+
+	END_ATTRIBUTES_ARRAY
+};
+
+/* IIOD device (global) attributes list */
+static struct iio_attribute global_attributes[] = {
+#if defined(DEV_AD7606B) || defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+	{
+		.name = "operating_mode",
+		.show = get_operating_mode,
+		.store = set_operating_mode,
+	},
+	{
+		.name = "oversampling_ratio",
+		.show = get_oversampling,
+		.store = set_oversampling,
+	},
+#else
+	{
+		.name = "power_down_mode",
+		.show = get_power_down_mode,
+		.store = set_power_down_mode,
+	},
+	{
+		.name = "dev_range",
+		.show = get_range,
+		.store = set_range,
+	},
+#endif
+	{
+		.name = "sampling_frequency",
+		.show = get_sampling_frequency,
+		.store = set_sampling_frequency,
+	},
+
+	END_ATTRIBUTES_ARRAY
+};
+
+/* IIOD debug attributes list */
+static struct iio_attribute debug_attributes[] = {
+#if defined(DEV_AD7606B) || defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+	{
+		.name = "direct_reg_access",
+		.show = NULL,
+		.store = NULL,
+	},
+#endif
+
+	END_ATTRIBUTES_ARRAY
+};
+
+/* IIOD channels configurations */
+struct scan_type chn_scan = {
+	.sign = 's',
+#if (AD7606X_ADC_RESOLUTION == 18)
+	.realbits = 18,
+	.storagebits = 18,
+#else
+	.realbits = 16,
+	.storagebits = 16,
+#endif
+	.shift = 0,
+	.is_big_endian = false
+};
+
+static struct iio_channel iio_ad7606_channels[] = {
+	{
+		.name = "voltage0",
+		.ch_type = IIO_VOLTAGE,
+		.channel = 0,
+		.scan_index = 0,
+		.scan_type = &chn_scan,
+		.attributes = channel_input_attributes,
+		.ch_out = false,
+		.indexed = true,
+	},
+	{
+		.name = "voltage1",
+		.ch_type = IIO_VOLTAGE,
+		.channel = 1,
+		.scan_index = 1,
+		.scan_type = &chn_scan,
+		.attributes = channel_input_attributes,
+		.ch_out = false,
+		.indexed = true
+	},
+	{
+		.name = "voltage2",
+		.ch_type = IIO_VOLTAGE,
+		.channel = 2,
+		.scan_index = 2,
+		.scan_type = &chn_scan,
+		.attributes = channel_input_attributes,
+		.ch_out = false,
+		.indexed = true
+	},
+	{
+		.name = "voltage3",
+		.ch_type = IIO_VOLTAGE,
+		.channel = 3,
+		.scan_index = 3,
+		.scan_type = &chn_scan,
+		.attributes = channel_input_attributes,
+		.ch_out = false,
+		.indexed = true
+	},
+	{
+		.name = "voltage4",
+		.ch_type = IIO_VOLTAGE,
+		.channel = 4,
+		.scan_index = 4,
+		.scan_type = &chn_scan,
+		.attributes = channel_input_attributes,
+		.ch_out = false,
+		.indexed = true
+	},
+	{
+		.name = "voltage5",
+		.ch_type = IIO_VOLTAGE,
+		.channel = 5,
+		.scan_index = 5,
+		.scan_type = &chn_scan,
+		.attributes = channel_input_attributes,
+		.ch_out = false,
+		.indexed = true
+	},
+	{
+		.name = "voltage6",
+		.ch_type = IIO_VOLTAGE,
+		.channel = 6,
+		.scan_index = 6,
+		.scan_type = &chn_scan,
+		.attributes = channel_input_attributes,
+		.ch_out = false,
+		.indexed = true
+	},
+	{
+		.name = "voltage7",
+		.ch_type = IIO_VOLTAGE,
+		.channel = 7,
+		.scan_index = 7,
+		.scan_type = &chn_scan,
+		.attributes = channel_input_attributes,
+		.ch_out = false,
+		.indexed = true
+	}
+};
+
 
 /**
  * @brief	Init for reading/writing and parameterization of a
@@ -1645,42 +1852,31 @@
  * @param	init[in] - Configuration structure
  * @return	SUCCESS in case of success, FAILURE otherwise
  */
-int32_t iio_ad7606_init(struct iio_ad7606_desc **desc,
-			struct iio_ad7606_init_param *init)
+static int32_t iio_ad7606_init(struct iio_device **desc)
 {
-	int32_t status;
-	struct iio_interface *iio_interface;
-
-	iio_interface = (struct iio_interface *)calloc(1, sizeof(struct iio_interface));
-	if (!iio_interface) {
-		return -ENOMEM;
-	}
+	struct iio_device *iio_ad7606_inst;
 
-	*iio_interface = (struct iio_interface) {
-		.name = dev_name,
-		.dev_instance = init->ad7606_phy,
-		.iio = iio_ad7606_create_device(dev_name),
-		.get_xml = iio_ad7606_get_xml,
-		.transfer_dev_to_mem = iio_ad7606_get_samples_count,
-		.transfer_mem_to_dev = NULL,
-		.read_data = iio_ad7606_read_data,
-		.write_data = NULL,
-	};
-
-	status = iio_register(iio_interface);
-	if (status < 0) {
-		free(iio_interface);
+	iio_ad7606_inst = calloc(1, sizeof(struct iio_device));
+	if (!iio_ad7606_inst) {
 		return FAILURE;
 	}
 
-	*desc = calloc(1, sizeof(struct iio_ad7606_desc));
-	if (!(*desc)) {
-		iio_unregister(iio_interface);
-		free(iio_interface);
-		return FAILURE;
-	}
+	iio_ad7606_inst->num_ch = sizeof(iio_ad7606_channels) / sizeof(
+					  iio_ad7606_channels[0]);
+	iio_ad7606_inst->channels = iio_ad7606_channels;
+	iio_ad7606_inst->attributes = global_attributes;
+	iio_ad7606_inst->debug_attributes = debug_attributes;
 
-	(*desc)->iio_interface = iio_interface;
+	iio_ad7606_inst->transfer_dev_to_mem = iio_ad7606_transfer_dev_data;
+	iio_ad7606_inst->transfer_mem_to_dev = NULL;
+	iio_ad7606_inst->read_data = iio_ad7606_read_data;
+	iio_ad7606_inst->write_data = NULL;
+	iio_ad7606_inst->prepare_transfer = iio_ad7606_start_transfer;
+	iio_ad7606_inst->end_transfer = iio_ad7606_stop_transfer;
+	iio_ad7606_inst->debug_reg_read = debug_reg_read;
+	iio_ad7606_inst->debug_reg_write = debug_reg_write;
+
+	*desc = iio_ad7606_inst;
 
 	return SUCCESS;
 }
@@ -1691,7 +1887,7 @@
  * @param desc[in] - IIO device descriptor
  * @return SUCCESS in case of success, FAILURE otherwise
  */
-int32_t iio_ad7606_remove(struct iio_ad7606_desc *desc)
+static int32_t iio_ad7606_remove(struct iio_desc *desc)
 {
 	int32_t status;
 
@@ -1699,19 +1895,11 @@
 		return FAILURE;
 	}
 
-	status = iio_unregister(desc->iio_interface);
-	if (status < 0) {
+	status = iio_unregister(desc, (char *)dev_name);
+	if (status != SUCCESS) {
 		return FAILURE;
 	}
 
-	status = iio_ad7606_delete_device(desc->iio_interface->iio);
-	if (status < 0) {
-		return FAILURE;
-	}
-
-	free(desc->iio_interface);
-	free(desc);
-
 	return SUCCESS;
 }
 
@@ -1749,102 +1937,21 @@
 	char buf[50];
 	struct iio_ch_info channel;
 
-	for (uint8_t chn = 1; chn <= AD7606X_ADC_CHANNELS; chn++) {
+	for (uint8_t chn = 0; chn < AD7606X_ADC_CHANNELS; chn++) {
 		channel.ch_num = chn;
 
 		/* Get channel range */
-		(void)get_chn_range(p_ad7606_dev, buf, 0, &channel);
+		(void)get_chn_range(p_ad7606_dev_inst, buf, 0, &channel, 0);
 
 		/* Get scale */
-		attr_scale_val[channel.ch_num - 1] = get_vltg_conv_scale_factor(
-				attr_chn_range[channel.ch_num - 1],
-				attr_polarity_val[channel.ch_num - 1]);
+		attr_scale_val[channel.ch_num] = get_vltg_conv_scale_factor(
+				attr_chn_range[channel.ch_num],
+				attr_polarity_val[channel.ch_num]);
 	}
 }
 
 
 /**
- * @brief 	Initialize the IRQ contoller
- * @param	uart_desc[in] - UART descriptor for UART Rx IRQ event init
- * @return	none
- * @details	This function initialize the interrupt controller
- */
-static int32_t iio_interrupt_handler_init(mbed_uart_desc *uart_desc)
-{
-	/* Pin to generate external interrupt */
-	PinName ext_int_pin = BUSY_PIN;
-
-	/* External interrupt descriptor */
-	struct irq_ctrl_desc *external_int_desc;
-
-	/* Define external interrupt platform specific parameters structure */
-	mbed_irq_init_param mbed_ext_int_init_param = {
-		.int_mode = EXT_IRQ_FALL,
-		.int_obj_type = &ext_int_pin
-	};
-
-	/* External interrupt init parameters */
-	struct irq_init_param external_int_init_param = {
-		.irq_ctrl_id = EXTERNAL_INT_ID,
-		.extra = &mbed_ext_int_init_param
-	};
-
-	/* External interrupt callback descriptor */
-	struct callback_desc external_int_callback_desc = {
-		&do_conversion_callback,
-		NULL,
-		NULL
-	};
-
-	/* UART Rx interrupt descriptor */
-	struct irq_ctrl_desc *uart_rx_int_desc;
-
-	/* Define external interrupt platform specific parameters structure */
-	mbed_irq_init_param mbed_uart_rx_int_init_param = {
-		.int_mode = 0,
-		.int_obj_type = uart_desc->uart_port
-	};
-
-	/* UART Rx interrupt init parameters */
-	struct irq_init_param uart_rx_int_init_param = {
-		.irq_ctrl_id = UART_RX_INT_ID,
-		.extra = &mbed_uart_rx_int_init_param
-	};
-
-	/* UART Rx interrupt callback descriptor */
-	struct callback_desc uart_rx_int_callback_desc = {
-		&iio_uart_rx_callback,
-		NULL,
-		NULL
-	};
-
-	/* Init interrupt controller for external interrupt */
-	if (irq_ctrl_init(&external_int_desc, &external_int_init_param) == FAILURE) {
-		return FAILURE;
-	}
-
-	/* Init interrupt controller for UART Rx interrupt */
-	if (irq_ctrl_init(&uart_rx_int_desc, &uart_rx_int_init_param) == FAILURE) {
-		return FAILURE;
-	}
-
-	/* Register a callback function for external interrupt */
-	if (irq_register_callback(external_int_desc, EXTERNAL_INT_ID,
-				  &external_int_callback_desc) == FAILURE) {
-		return FAILURE;
-	}
-
-	/* Register a callback function for UART Rx interrupt */
-	if (irq_register_callback(uart_rx_int_desc, UART_RX_INT_ID,
-				  &uart_rx_int_callback_desc) == FAILURE) {
-		return FAILURE;
-	}
-
-	return SUCCESS;
-}
-
-
-/**
  * @brief	Initialize the IIO interface for AD7606 IIO device
  * @return	none
  * @return	SUCCESS in case of success, FAILURE otherwise
@@ -1853,121 +1960,56 @@
 {
 	int32_t init_status;
 
-	/**
-	* AD7606 IIO instance descriptor
-	*/
-	struct iio_ad7606_desc *piio_ad7606_desc;
-
-	/**
-	 * AD7606 IIO init parameters
-	 */
-	struct iio_ad7606_init_param iio_ad7606_init_param;
-
-	/**
-	 * IIO application init parameters
-	 */
-	struct iio_app_init_param iio_app_init_par;
-
-	/**
-	 * UART serial interface read/write callback
-	 */
-	struct iio_server_ops uart_iio_server_ops;
-
-	/*
-	 * UART Mbed init extra parameters structure
-	 */
-	mbed_uart_init_param uart_extra_init_param;
-
-	/*
-	 * UART init parameters structure
-	 */
-	struct uart_init_param uart_init_param;
+	/* IIO device descriptor */
+	struct iio_device *p_iio_ad7606_dev;
 
 	/**
-	 * IIO application UART descriptor
-	 */
-	struct uart_desc *uart_desc = NULL;
-
-	/*
-	 * GPIO LED Init parameters structure
-	 */
-	struct gpio_init_param gpio_init_led;
-
-	iio_ad7606_init_param = (struct iio_ad7606_init_param) {
-		.ad7606_phy = NULL,
-	};
-
-	uart_extra_init_param = (mbed_uart_init_param) {
-		.uart_tx_pin = UART_TX,
-		.uart_rx_pin = UART_RX
-	};
-
-	uart_init_param = (struct uart_init_param ) {
-		.device_id = NULL,
-		.baud_rate = IIO_UART_BAUD_RATE,
-		.extra = &uart_extra_init_param
-	};
-
-	uart_iio_server_ops = (struct iio_server_ops) {
-		.read = iio_uart_read,
-		.write = iio_uart_write,
-	};
-
-	gpio_init_led = (struct gpio_init_param) {
-		.number = LED_GREEN,
-		.extra = NULL
-	};
-
-	iio_app_init_par = (struct iio_app_init_param) {
-		.iio_server_ops = &uart_iio_server_ops,
+	* IIO interface init parameters
+	*/
+	struct iio_init_param iio_init_params = {
+		.phy_type = USE_UART,
+		{
+			&uart_init_params
+		}
 	};
 
 	/* Initialize AD7606 device and peripheral interface */
-	init_status = ad7606_init(&p_ad7606_dev, &ad7606_init_str);
+	init_status = ad7606_init(&p_ad7606_dev_inst, &ad7606_init_str);
 	if (init_status != SUCCESS) {
 		return init_status;
 	}
 
-	/* Initialize the LED GPIO descriptor */
-	init_status = gpio_get_optional(&gpio_led, &gpio_init_led);
+	/* Initialize the IIO interface */
+	init_status = iio_init(&p_ad7606_iio_desc, &iio_init_params);
 	if (init_status != SUCCESS) {
 		return init_status;
-	} else {
-		init_status = gpio_direction_output(gpio_led, GPIO_HIGH);
-		if (init_status != SUCCESS) {
-			return init_status;
-		}
 	}
 
-	/* Get the AD7606 IIO device instance */
-	iio_ad7606_init_param.ad7606_phy = p_ad7606_dev;
-
-	/* Initialize the UART interface for IIO application */
-	init_status = iio_uart_init(&uart_desc, &uart_init_param);
+	/* Initialize the AD7606 IIO application interface */
+	init_status = iio_ad7606_init(&p_iio_ad7606_dev);
 	if (init_status != SUCCESS) {
 		return init_status;
 	}
 
-	/* Initialize the IIO application interface */
-	init_status = iio_app_init(&iio_app_desc, &iio_app_init_par);
+	/* Register AD7606 IIO interface */
+	init_status = iio_register(p_ad7606_iio_desc,
+				   p_iio_ad7606_dev,
+				   (char *)dev_name,
+				   p_ad7606_dev_inst,
+				   NULL,
+				   NULL);
 	if (init_status != SUCCESS) {
 		return init_status;
 	}
 
-	/* Register and initialize the AD7606 device into IIO interface */
-	init_status = iio_ad7606_init(&piio_ad7606_desc, &iio_ad7606_init_param);
+	/* Init the system peripherals */
+	init_status = init_system();
 	if (init_status != SUCCESS) {
 		return init_status;
 	}
 
 	/* Init the data capture for AD7606 IIO app */
-	init_status = iio_data_capture_init(p_ad7606_dev);
-	if (init_status != SUCCESS) {
-		return init_status;
-	}
-
-	/* Init the interrupt event handler for AD7606 IIO app */
-	init_status = iio_interrupt_handler_init(uart_desc->extra);
+	init_status = iio_data_capture_init(&p_ad7606_dev_inst);
 	if (init_status != SUCCESS) {
 		return init_status;
 	}
@@ -1983,18 +2025,7 @@
  */
 void ad7606_iio_event_handler(void)
 {
-	/* Handle new IIO command */
-	if (is_new_iio_command_detected()) {
-		/* Stop the background data capture if it is running before and any
-		 * iio command except READBUF is received */
-		if (adc_background_data_capture_started) {
-			if (!check_iio_cmd("READBUF", 7)) {
-				stop_background_data_capture();
-				adc_background_data_capture_started = false;
-			}
-		}
-
-		/* Run the IIO interface when new command is detected */
-		(void)iio_app(iio_app_desc);
+	while (1) {
+		(void)iio_step(p_ad7606_iio_desc);
 	}
 }