Analog Devices / Mbed OS EVAL-AD7606

Dependencies:   platform_drivers

Files at this revision

API Documentation at this revision

Comitter:
mahphalke
Date:
Mon Oct 05 13:45:15 2020 +0530
Parent:
0:3791805e8370
Child:
2:26002766580b
Commit message:
AD7606 IIO Application- Initial Revision

Changed in this revision

AD7606.lib Show annotated file Show diff for this revision Revisions of this file
License.txt Show annotated file Show diff for this revision Revisions of this file
README.txt Show annotated file Show diff for this revision Revisions of this file
app/ad7606_data_capture.c Show annotated file Show diff for this revision Revisions of this file
app/ad7606_data_capture.h Show annotated file Show diff for this revision Revisions of this file
app/ad7606_support.c Show annotated file Show diff for this revision Revisions of this file
app/ad7606_support.h Show annotated file Show diff for this revision Revisions of this file
app/ad7606_user_config.c Show annotated file Show diff for this revision Revisions of this file
app/ad7606_user_config.h Show annotated file Show diff for this revision Revisions of this file
app/app_config.h Show annotated file Show diff for this revision Revisions of this file
app/iio_ad7606.c Show annotated file Show diff for this revision Revisions of this file
app/iio_ad7606.h Show annotated file Show diff for this revision Revisions of this file
app/iio_ad7606_attr.h Show annotated file Show diff for this revision Revisions of this file
app/iio_transport.c Show annotated file Show diff for this revision Revisions of this file
app/iio_transport.h Show annotated file Show diff for this revision Revisions of this file
app/main.c Show annotated file Show diff for this revision Revisions of this file
iio.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
mbed_app.json Show annotated file Show diff for this revision Revisions of this file
platform_drivers.lib Show annotated file Show diff for this revision Revisions of this file
tinyiiod.lib Show annotated file Show diff for this revision Revisions of this file
--- a/AD7606.lib	Thu Aug 06 19:49:32 2020 +0000
+++ b/AD7606.lib	Mon Oct 05 13:45:15 2020 +0530
@@ -1,1 +1,1 @@
-https://os.mbed.com/teams/AnalogDevices/code/AD7606/#84d38108c7b4
+https://os.mbed.com/teams/AnalogDevices/code/AD7606
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/License.txt	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,26 @@
+Analog Devices, Inc. (“ADI”)
+Source Code Software License Agreement
+20190709-LWSC-CTSLA
+BEFORE YOU SELECT THE "I ACCEPT" BUTTON AT THE BOTTOM OF THIS WINDOW, CAREFULLY READ THE TERMS AND CONDITIONS SET FORTH BELOW.  BY SELECTING THE “I ACCEPT” BUTTON BELOW, OR DOWNLOADING, REPRODUCING, DISTRIBUTING OR OTHERWISE USING THE SOFTWARE, YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS SET FORTH BELOW.  IF YOU DO NOT AGREE TO ALL OF THE TERMS AND CONDITIONS, SELECT THE 'I DO NOT ACCEPT' BUTTON AND YOU MUST NOT DOWNLOAD, INSTALL OR OTHERWISE USE THE SOFTWARE.
+
+DOWNLOADING, REPRODUCING, DISTRIBUTING OR OTHERWISE USING THE SOFTWARE CONSTITUTES ACCEPTANCE OF THIS LICENSE.  THE SOFTWARE MAY NOT BE USED EXCEPT AS EXPRESSLY AUTHORIZED UNDER THIS LICENSE. 
+
+The software is protected by copyright law and international copyright treaties.  
+
+1. License:  Subject to the terms and conditions of this license, the software may be reproduced, modified and distributed in source code and object code form.
+
+2. Conditions: 
+(a) Any distribution of the software must include a complete copy of this license and retain all copyright and other proprietary notices.  The software that is distributed (including modified versions of the software) shall be subject to the terms and conditions of this license.  
+(b) The software may not be combined or merged with other software in any manner that would cause the software to become subject to terms and conditions which differ from those of this license.
+(c) The software is licensed solely and exclusively for use with processors manufactured by or for ADI.
+(d) Licensee shall not use the name or any trademark of ADI (including those of its licensors) or any contributor to endorse or promote products without prior written consent of the owner of the name or trademark.  The term “contributor” means any person or entity that modifies or distributes the software.  
+(e) Modified versions of the Software must be conspicuously marked as such.
+(f) Use of the software may or may not infringe patent rights of one or more patent holders.  This license does not alleviate the obligation to obtain separate licenses from patent holders to use the software.
+(g) All rights not expressly granted hereunder are reserved.  
+(h) This license shall be governed by the laws of Massachusetts, without regard to its conflict of laws rules.  The software shall only be used in compliance with all applicable laws and regulations, including without limitation export control laws.  
+
+3. WARRANTY DISCLAIMER: THE SOFTWARE AND ANY RELATED INFORMATION AND/OR ADVICE IS PROVIDED ON AN “AS IS” BASIS, WITHOUT REPRESENTATIONS, GUARANTEES OR WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, ORAL OR WRITTEN, INCLUDING WITHOUT LIMITATION, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. There is no obligation to provide software support or updates.  The Software is not fault-tolerant and is not intended for use in high risk applications, including without limitation in the operation of nuclear facilities, aircraft navigation or control systems, air traffic control, life support machines, weapons systems, autonomous driving or other safety critical automotive applications, or any other application in which the failure of the software could lead to death, personal injury, or severe physical or environmental damages.  The software is not authorized to be used under such circumstances.
+
+4. LIMITATION OF LIABILITY: TO THE MAXIMUM EXTENT PERMITTED BY LAW ADI (INCLUDING ITS LICENSORS) AND CONTRIBUTORS SHALL NOT BE LIABLE FOR ANY DAMAGES ARISING FROM OR RELATED TO THE SOFTWARE, ITS USE OR ANY RELATED INFORMATION AND/OR SERVICES, INCLUDING BUT NOT LIMITED TO ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE, EXEMPLARY, CONSEQUENTIAL OR ANALOGOUS DAMAGES (INCLUDING WITHOUT LIMITATION ANY DAMAGES RESULTING FROM LOSS OF USE, DATA, REVENUE, PROFITS, OR SAVINGS, COMPUTER DAMAGE OR ANY OTHER CAUSE), UNDER ANY LEGAL THEORY (INCLUDING WITHOUT LIMITATION CONTRACT, WARRANTY, TORT, NEGLIGENCE, STRICT OR PRODUCT LIABILITY), EVEN IF IT HAS BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES.  Some jurisdictions do not permit the exclusion or limitation of liability for consequential, incidental or other damages, and, as such, some portion of the above limitation may not apply.  In such jurisdictions, liability is limited to the greatest extent permitted by law.
+5. Third Party Software:  The software may be accompanied by or include software made available by one or more third parties (“Third Party Software”).  Each portion of Third Party Software is subject to its own separate software license terms and conditions (“Third Party Licenses”).  The Third Party Licenses for Third Party Software delivered with the software are set forth or identified (by url or otherwise) in (i) Appendix A to this license (if any), (ii) the applicable software header or footer text, (iii) a text file located in the directory of the applicable Third Party Software component and/or (iv) such other location customarily used for licensing terms. The use of each portion of Third Party Software is subject to the Third Party Licenses, and you agree that your use of any Third Party Software is bound by the applicable Third Party License.  You agree to review and comply with all applicable Third Party Licenses prior to any use or distribution of any Third Party Software.  Third Party Software is provided on an “as is” basis without any representation, warranty or liability of any kind.  ADI (including its licensors) and contributors shall have no liability or responsibility for the operation or performance of the Third Party Software and shall not be liable for any damages, costs, or expenses, direct or indirect, arising out of the performance or failure to perform of the Third Party Software.  ADI (including its licensors) and contributors shall be entitled to the benefit of any and all limitations of liability and disclaimers of warranties contained in the Third Party Licenses. For the avoidance of doubt, this license does not alter, limit or expand the terms and conditions of, or rights granted to you pursuant to, Third Party Licenses.  
+
--- a/README.txt	Thu Aug 06 19:49:32 2020 +0000
+++ b/README.txt	Mon Oct 05 13:45:15 2020 +0530
@@ -1,40 +1,32 @@
 Evaluation Boards/Products Supported
 ------------------------------------ 
-EVAL-AD1234 (AD1234)
-EVAL-AD1256 (AD1256)
-<< add more here >>
+-Products supported: AD7606B, AD7606C, AD7605-4, AD7606-4, AD7606-6, AD7606-8, AD7608, AD7609
+-EVAL-AD7606B-FMCZ
+
 
 Overview
 --------
-These code files provide drivers to interface with AD1234 and communicate with 
-EVAL-AD1234 board. This code was developed and tested on SDP-K1 controller board 
-https://os.mbed.com/platforms/SDP_K1/. 
-
-Product details: https://www.analog.com/en/products/ad1234.html
-Eval board details: https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/EVAL-AD1234.html
+This is an IIO ecosystem based firmware application to evalute the AD7606 family ADCs.
+The ARM GCC compiler is used for firmware development on ARM Mbed platform.
+The ADI developed ARM Mbed SDP-K1 controlled board acts as a target device, where firmware application is running.
+The AD7606-Eval board is interfaced with SDP-K1 (or any Arduino compatible board) controller board using on-board Arduino Headers.
 
 
 Hardware Setup
 --------------
-Required: SDP-K1, EVAL-AD1234, USB cable, 12 V power supply, 60 MHz external 
-clock supply.
-Plug in the EVAL-AD124 board on SDP-K1 board (or any other Mbed enabled 
-controller board) using the SDP connector and screws.
-Connect SDP-K1 board to the PC using the USB cable.
+Refer "Hardware Connections" section from below wiki page link:
+https://wiki.analog.com/resources/tools-software/product-support-software/ad7606_mbed_iio_application
 
 
 How to Get Started
 ------------------
 Open Mbed online compiler. https://ide.mbed.com/compiler
-Import Code into compiler from here: https://os.mbed.com/teams/AnalogDevices/code/EVAL-AD1234/
-instructions on how to import code are here: https://os.mbed.com/docs/mbed-os/v5.12/tools/importing-code.html
-Compile code. Drag and drop binary into SDP-K1 controller board. Find detailed instructions 
-here: https://os.mbed.com/docs/mbed-os/v5.12/tools/getting-your-program-on-your-board.html
-Open Tera Term (or alternative), select 9600 baud rate, and the applicable COM port to see the 
-list of options.
+Import Code into compiler from here. Instructions on how to import code are here: https://os.mbed.com/docs/mbed-os/v5.12/tools/importing-code.html
+Compile code. Drag and drop binary into SDP-K1 controller board. Find detailed 
+instructions here: https://os.mbed.com/docs/mbed-os/v5.12/tools/getting-your-program-on-your-board.html
 
-A detailed user guide on how to use SDP-K1 board on Mbed platform is available 
-here: https://wiki.analog.com/resources/tools-software/mbed
+Refere project wiki page to find detailed guide on how to use firmware:
+https://wiki.analog.com/resources/tools-software/product-support-software/ad7606_mbed_iio_application
 
 
 Notes
@@ -43,40 +35,4 @@
 A detailed user guide on SDP-K1 controller board is available here https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/SDP-K1.html.
 
 
-License
--------
-Copyright (c) 2019 Analog Devices, Inc.  All rights reserved.
- 
-Redistribution and use in source and binary forms, with or without modification, 
-are permitted provided that the following conditions are met:
-  - Redistributions of source code must retain the above copyright notice, 
-  this list of conditions and the following disclaimer.
-  - Redistributions in binary form must reproduce the above copyright notice, 
-  this list of conditions and the following disclaimer in the documentation 
-  and/or other materials provided with the distribution.  
-  - Modified versions of the software must be conspicuously marked as such.
-  - This software is licensed solely and exclusively for use with processors/products 
-  manufactured by or for Analog Devices, Inc.
-  - This software may not be combined or merged with other code in any manner 
-  that would cause the software to become subject to terms and conditions which 
-  differ from those listed here.
-  - Neither the name of Analog Devices, Inc. nor the names of its contributors 
-  may be used to endorse or promote products derived from this software without 
-  specific prior written permission.
-  - The use of this software may or may not infringe the patent rights of one or 
-  more patent holders.  This license does not release you from the requirement 
-  that you obtain separate licenses from these patent holders to use this software.
- 
-THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS" AND 
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, 
-TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 
-NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES 
-(INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF CLAIMS OF INTELLECTUAL 
-PROPERTY RIGHTS INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- 
-2019-01-10-7CBSD SLA
\ No newline at end of file
+Copyright (c) 2020 Analog Devices, Inc.  All rights reserved.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/ad7606_data_capture.c	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,429 @@
+/***************************************************************************//**
+ *   @file    ad7606_data_capture.c
+ *   @brief   Data capture interface for AD7606 IIO application
+ *   @details This module handles the AD7606 data capturing
+********************************************************************************
+ * Copyright (c) 2020 Analog Devices, Inc.
+ *
+ * All rights reserved.
+ *
+ * This software is proprietary to Analog Devices, Inc. and its licensors.
+ * By using this software you agree to the terms of the associated
+ * Analog Devices Software License Agreement.
+*******************************************************************************/
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "app_config.h"
+#include "ad7606_data_capture.h"
+#include "ad7606_support.h"
+#include "gpio_extra.h"
+
+/******************************************************************************/
+/********************** Macros and Constants Definition ***********************/
+/******************************************************************************/
+
+#if (AD7606X_ADC_RESOLUTION > 16)
+#define		BYTES_PER_SAMPLE	sizeof(uint32_t)
+#else
+#define		BYTES_PER_SAMPLE	sizeof(uint16_t)
+#endif
+
+/* Max size of the acquisition buffer (in terms of samples) */
+#define DATA_BUFFER_SIZE		(8192)
+
+/******************************************************************************/
+/********************** Variables and User Defined Data Types *****************/
+/******************************************************************************/
+
+/* Device instance for background adc conversion callback */
+static volatile struct ad7606_dev *dev = NULL;
+
+/*
+ *@enum		acq_buffer_state_e
+ *@details	Enum holding the data acquisition buffer states
+ **/
+typedef enum {
+	BUF_EMPTY,
+	BUF_AVAILABLE,
+	BUF_FULL
+} acq_buffer_state_e;
+
+/*
+ *@struct	acq_buf_t
+ *@details	Structure holding the data acquisition buffer parameters
+ **/
+typedef struct {
+	acq_buffer_state_e state;	// buffer state
+	uint32_t rd_indx;			// buffer read index
+	uint32_t wr_indx;			// buffer write index
+	uint32_t align_cnt;			// buffer alignment counter
+#if (AD7606X_ADC_RESOLUTION > 16)
+	uint32_t data[DATA_BUFFER_SIZE];
+#else
+	uint16_t data[DATA_BUFFER_SIZE];
+#endif
+} acq_buf_t;
+
+/* ADC data acquisition buffers */
+static volatile acq_buf_t acq_buffer;
+
+/* Flag to indicate background data capture status */
+static volatile bool start_adc_data_capture = false;
+
+/* Active channels to be captured */
+static volatile uint32_t active_channels = 0;
+
+/* Number of active channels */
+static uint8_t num_of_active_channels = 0;
+
+/* Minimum number of bytes to be read from device over digital interface */
+static volatile uint8_t min_bytes_to_read = 0;
+
+/* Number of channels requested for read into acquisition buffer */
+static volatile uint8_t chn_read_cnt = 0;
+
+/* Number of samples requested by IIO client */
+static uint16_t num_of_samples = 0;
+
+/* Max available size of buffer */
+static uint16_t max_available_buffer_size = 0;
+
+/******************************************************************************/
+/************************ Functions Declarations ******************************/
+/******************************************************************************/
+
+static void adjust_buffer_offset(uint8_t *arr_indx, uint8_t *offset_end,
+				 uint8_t *mask);
+
+/******************************************************************************/
+/************************ Functions Definitions *******************************/
+/******************************************************************************/
+
+/*!
+ * @brief	Function to init the data capture for AD7606 device
+ * @param	device[in]- Device instance
+ * @return	none
+ */
+int32_t iio_data_capture_init(struct ad7606_dev *device)
+{
+	/* Save the device structure for background conversion */
+	dev = malloc(sizeof(struct ad7606_dev *));
+	if (!dev) {
+		return FAILURE;
+	}
+
+	memcpy(&dev, &device, sizeof(dev));
+
+	return SUCCESS;
+}
+
+
+/*!
+ * @brief	Function to read the ADC raw data for single channel
+ * @param	device[in]- Device instance
+ * @param	chn[in] - Input channel
+ * @return	adc raw data/sample
+ */
+int32_t single_data_read(void *device, uint8_t chn, polarity_e polarity)
+{
+	int32_t adc_data = 0;
+	uint32_t adc_raw[AD7606X_ADC_RESOLUTION] = { 0 };
+
+	if (ad7606_read(device, adc_raw) != SUCCESS) {
+		adc_raw[chn] = 0;
+	}
+
+	if (polarity == BIPOLAR) {
+		/* Check for negative adc value for bipolar inputs */
+		if (adc_raw[chn] >= ADC_MAX_COUNT_BIPOLAR) {
+			/* Take the 2s complement for the negative counts (>full scale value) */
+			adc_data = ADC_MAX_COUNT_UNIPOLAR - adc_raw[chn];
+			adc_data = 0 - adc_data;
+		} else {
+			adc_data = adc_raw[chn];
+		}
+	} else {
+		adc_data = adc_raw[chn];
+	}
+
+	return adc_data;
+}
+
+
+/*!
+ * @brief	Function to store the number of requested samples from IIO client
+ * @param	bytes[in] - Number of bytes corresponding to requested samples
+ * @return	none
+ */
+void store_requested_samples_count(size_t bytes)
+{
+	/* This gets the number of samples requested by IIO client for all active channels */
+	num_of_samples = bytes / BYTES_PER_SAMPLE;
+
+	/* Get the actual available size of buffer by aligning with number of requested samples.
+	 * e.g. if requested samples are 1050, the max available size of buffer is:
+	 * available size = (8192 / 1050) * 1050 = 7 * 1050 = 7350.
+	 * The max samples to be requested should always be less than half the max size of buffer
+	 * (in this case: 8192 / 2 = 4096).
+	 * */
+	max_available_buffer_size = ((DATA_BUFFER_SIZE / num_of_samples) *
+				     num_of_samples);
+}
+
+
+/*!
+ * @brief	Function to read new samples into buffer without timeout IIO request
+ * @param	input_buffer[in] - Input data acquisition buffer
+ * @param	output_buffer[in, out] - Output data buffer
+ * @param	samples_to_read[in] - Number of samples to read
+ * @return	none
+ */
+static void wait_and_read_new_samples(volatile acq_buf_t *input_buffer,
+				      char *output_buffer,
+				      size_t samples_to_read)
+{
+	int32_t buff_rd_wr_indx_offset; 			// Offset b/w buffer read and write indexes
+	uint32_t timeout = 5000000; 				// To avoid IIO data request timeout
+	size_t bytes = samples_to_read * BYTES_PER_SAMPLE;
+
+	/* Copy the bytes into buffer provided there is enough offset b/w read and write counts.
+	* If there is overlap b/w read and write indexes (read is faster than write), empty buffer
+	* should be returned to IIO client to avoid IIO request timeout */
+	do {
+		buff_rd_wr_indx_offset = (int32_t)input_buffer->wr_indx -
+					 (int32_t)input_buffer->rd_indx;
+		timeout--;
+	} while (((buff_rd_wr_indx_offset < (int32_t)(samples_to_read))
+		  || (input_buffer->wr_indx < input_buffer->rd_indx)) && (timeout > 0));
+
+	if ((timeout == 0) || (input_buffer->wr_indx <= 0)) {
+		/* This returns the empty buffer */
+		return;
+	}
+
+	memcpy(output_buffer,
+	       (void const *)&input_buffer->data[input_buffer->rd_indx],
+	       bytes);
+	input_buffer->rd_indx += samples_to_read;
+}
+
+
+/*!
+ * @brief	Function to read and align the ADC buffered raw data
+ * @param	device[in]- Device instance
+ * @param	pbuf[out] - Buffer to load ADC raw data
+ * @param	bytes[in] - Number of bytes to be read
+ * @param	active_chns_mask[in] - Active channels mask
+ * @return	Number of bytes read
+ */
+size_t buffered_data_read(char *pbuf, size_t bytes, size_t offset,
+			  uint32_t active_chns_mask)
+{
+	size_t samples_to_read = bytes / BYTES_PER_SAMPLE;	// Bytes to sample conversion
+
+	/* Make sure requested samples size is less than ADC buffer size. Return constant
+	 * value to avoid IIO client getting timed-out */
+	if (num_of_samples >= max_available_buffer_size) {
+		memset(pbuf, 1, bytes);
+		return bytes;
+	}
+
+	wait_and_read_new_samples(&acq_buffer, pbuf, samples_to_read);
+
+	/* Make buffer available again once read completely */
+	if (acq_buffer.rd_indx >= max_available_buffer_size) {
+		acq_buffer.rd_indx = 0;
+		acq_buffer.wr_indx = 0;
+		acq_buffer.align_cnt = 0;
+		acq_buffer.state = BUF_AVAILABLE;
+	}
+
+	return bytes;
+}
+
+
+/*!
+ * @brief	Function to perform background ADC conversion and data capture
+ * @return	none
+ * @details	This is an External Interrupt callback function/ISR, which is tied up to
+ *			falling edge trigger of BUSY pin. It is trigered when previous data
+ *			conversion is over and BUSY line goes low. Upon trigger, conversion
+ *			results are read into acquisition buffer and next conversion is triggered.
+ *			This continues until background conversion is stopped.
+ */
+void do_conversion_callback(void)
+{
+#if (AD7606X_ADC_RESOLUTION == 18)
+	uint8_t arr_indx = 0;
+	uint8_t offset_end = 2;
+	uint8_t mask = 0xff;
+#else
+	uint8_t mask = 0x01;
+#endif
+
+	if (start_adc_data_capture == true) {
+
+		/* Read the conversion result for required number of bytes */
+		if (ad7606_read_conversion_data(dev, min_bytes_to_read) == SUCCESS) {
+
+			/* Extract the data based on the active channels selected in IIO client.
+			 * Note: The extraction of data based on active channel needs
+			 * to be done since its not possible to capture individual
+			 * channel in AD7606 devices */
+			for (uint8_t chn = 0; chn < chn_read_cnt; chn++) {
+				if (active_channels & mask) {
+					if (acq_buffer.state == BUF_AVAILABLE) {
+#if (AD7606X_ADC_RESOLUTION == 18)
+						/* For AD7606C device (18-bit resolution) */
+						acq_buffer.data[acq_buffer.wr_indx++] =
+							(((uint32_t)(dev->data[arr_indx] & mask) << 16) |    			// MSB
+							 ((uint32_t)dev->data[arr_indx + 1] << 8) |
+							 ((uint32_t)(dev->data[arr_indx + 2] >> (8 - offset_end))));   	// LSB
+#else
+
+						acq_buffer.data[acq_buffer.wr_indx++] =
+							(uint16_t)(((uint16_t)dev->data[chn << 1] << 8) |   // MSB
+								   dev->data[(chn << 1) + 1]);     				// LSB
+#endif
+
+						acq_buffer.align_cnt++;
+
+						/* Monitor primary buffer full state */
+						if (acq_buffer.wr_indx >= max_available_buffer_size) {
+							acq_buffer.state = BUF_FULL;
+
+							/* This aligns the buffer to first active channel once all requested samples are transmitted */
+							if (acq_buffer.align_cnt >= num_of_samples) {
+								acq_buffer.align_cnt = 0;
+							}
+#if (AD7606X_ADC_RESOLUTION == 18)
+							adjust_buffer_offset(&arr_indx, &offset_end, &mask);
+#endif
+							mask <<= 1;
+							continue;
+						}
+
+						/* This aligns the buffer to first active channel once all requested samples are transmitted */
+						if (acq_buffer.align_cnt >= num_of_samples) {
+							acq_buffer.align_cnt = 0;
+							break;
+						}
+					}
+				}
+
+#if (AD7606X_ADC_RESOLUTION == 18)
+				adjust_buffer_offset(&arr_indx, &offset_end, &mask);
+#endif
+
+				mask <<= 1;
+			}
+
+			/* Trigger next conversion */
+			if (ad7606_convst(dev) != SUCCESS) {
+				start_adc_data_capture = false;
+			}
+		} else {
+			start_adc_data_capture = false;
+		}
+	}
+}
+
+
+/*!
+ * @brief	Function to trigger bakground ADC conversion for new READBUFF
+ *              request from IIO client (for active channels)
+ * @return	Conversion start status
+ */
+void start_background_data_capture(uint32_t ch_mask, size_t bytes_count)
+{
+	uint8_t mask = 0x1;
+
+	/* Make sure requested samples size is less than ADC buffer size */
+	if (num_of_samples >= max_available_buffer_size)
+		return;
+
+	active_channels = ch_mask;
+
+	stop_background_data_capture();
+
+	/* Find the minimum number of bytes to be read from device during
+	 * background conversion (Reading all bytes/channels adds extra overhead,
+	 * so restrict the minimum reads to whatever is possible).
+	 * Note: This happens only at the start of buffer read request. */
+	for (uint8_t chn = 1, indx = 0; chn <= AD7606X_ADC_CHANNELS; chn++, indx++) {
+		if (ch_mask & mask) {
+			/* 1 sample = 2 or 4 bytes */
+			min_bytes_to_read = chn * BYTES_PER_SAMPLE;
+			if (min_bytes_to_read > AD7606X_ADC_RESOLUTION) {
+				min_bytes_to_read = AD7606X_ADC_RESOLUTION;
+			}
+
+			/* Get the count for number of samples to be stored into acquisition buffer */
+			chn_read_cnt = chn;
+			num_of_active_channels++;
+		}
+
+		mask <<= 1;
+	}
+
+	/* Make primary acquisition buffer available and start conversion */
+	acq_buffer.state = BUF_AVAILABLE;
+	if (ad7606_convst(dev) == SUCCESS) {
+		start_adc_data_capture = true;
+	} else {
+		start_adc_data_capture = false;
+	}
+}
+
+
+/*!
+ * @brief	Function to stop background ADC data capture
+ * @return	none
+ */
+void stop_background_data_capture(void)
+{
+	/* Reset data capture flags */
+	start_adc_data_capture = false;
+	num_of_active_channels = 0;
+	min_bytes_to_read = 0;
+	chn_read_cnt = 0;
+
+	/* Reset acquisition buffer states and clear old data */
+	acq_buffer.state = BUF_EMPTY;
+
+	memset((void *)acq_buffer.data, 0, sizeof(acq_buffer.data));
+
+	acq_buffer.wr_indx = 0;
+	acq_buffer.rd_indx = 0;
+	acq_buffer.align_cnt = 0;
+}
+
+
+/*!
+ * @brief	Function to adjust the data buffer offset
+ * @param	*arr_indx[in, out]- Array index
+ * @param	*offset_end[out] - offset to extract LSB from 18-bit data
+ * @param	*mask[out] - channel select mask
+ * @return	none
+ */
+static void adjust_buffer_offset(uint8_t *arr_indx, uint8_t *offset_end,
+				 uint8_t *mask)
+{
+	*arr_indx += 2;
+
+	/* Track array to reach at the middle (9 bytes apart) to change the offsets */
+	if (*arr_indx == ((AD7606X_ADC_RESOLUTION / 2) - 1)) {
+		(*arr_indx)++;
+		*offset_end = 2;
+		*mask = 0xff;
+	} else {
+		*mask = (0xff >> *offset_end);
+		*offset_end += 2;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/ad7606_data_capture.h	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,46 @@
+/***************************************************************************//**
+ *   @file   ad7606_data_capture.h
+ *   @brief  Header for AD7606 data capture interfaces
+********************************************************************************
+ * Copyright (c) 2020 Analog Devices, Inc.
+ *
+ * All rights reserved.
+ *
+ * This software is proprietary to Analog Devices, Inc. and its licensors.
+ * By using this software you agree to the terms of the associated
+ * Analog Devices Software License Agreement.
+*******************************************************************************/
+
+#ifndef AD7606_DATA_CAPTURE_H_
+#define AD7606_DATA_CAPTURE_H_
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+#include <stddef.h>
+
+#include "ad7606.h"
+#include "ad7606_support.h"
+
+/******************************************************************************/
+/********************** Macros and Constants Definition ***********************/
+/******************************************************************************/
+
+/******************************************************************************/
+/********************** Variables and User Defined Data Types *****************/
+/******************************************************************************/
+
+/******************************************************************************/
+/************************ Public Declarations *********************************/
+/******************************************************************************/
+
+int32_t iio_data_capture_init(struct ad7606_dev *device);
+int32_t single_data_read(void *device, uint8_t chn, polarity_e polarity);
+size_t buffered_data_read(char *pbuf, size_t bytes, size_t offset,
+			  uint32_t chn_mask);
+void store_requested_samples_count(size_t bytes);
+void do_conversion_callback(void);
+void start_background_data_capture(uint32_t ch_mask, size_t bytes_count);
+void stop_background_data_capture(void);
+
+#endif /* AD7606_DATA_CAPTURE_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/ad7606_support.c	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,86 @@
+/*************************************************************************//**
+ *   @file   ad7606_support.c
+ *   @brief  AD7606 device No-OS driver supports
+******************************************************************************
+* Copyright (c) 2020 Analog Devices, Inc.
+*
+* All rights reserved.
+*
+* This software is proprietary to Analog Devices, Inc. and its licensors.
+* By using this software you agree to the terms of the associated
+* Analog Devices Software License Agreement.
+*****************************************************************************/
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+
+#include <stdint.h>
+
+#include "app_config.h"
+#include "ad7606_support.h"
+#include "ad7606_data_capture.h"
+
+/******************************************************************************/
+/********************** Macros and Constants Definition ***********************/
+/******************************************************************************/
+
+/******************************************************************************/
+/********************** Variables and User Defined Data Types *****************/
+/******************************************************************************/
+
+/******************************************************************************/
+/************************ Functions Definitions *******************************/
+/******************************************************************************/
+
+/*!
+ * @brief	Function to convert adc raw data into equivalent voltage
+ * @param	adc_raw[in] - ADC raw data
+ * @param	scale[in] - ADC raw to voltage conversion scale
+ * @return	equivalent voltage
+ */
+float convert_adc_raw_to_voltage(int32_t adc_raw, float scale)
+{
+	float voltage;
+
+	/* Convert adc data into equivalent voltage.
+	 * scale = (chn_range / MAX_ADC_CNT * 1000) as defined in iio_ad7606.c
+	 * */
+	voltage = (adc_raw  * (scale / 1000));
+
+	return voltage;
+}
+
+
+/*!
+ * @brief	Function to get the polarity of analog input
+ * @param	chn_range_bits[in] - Bits from the channel range register
+ * @return	UNIPOLAR or BIPOLAR
+ */
+polarity_e ad7606_get_input_polarity(uint8_t chn_range_bits)
+{
+	polarity_e polarity;
+
+	if (chn_range_bits >= AD7606C_UNIPOLAR_RANGE_MIN
+	    && chn_range_bits <= AD7606C_UNIPOLAR_RANGE_MAX) {
+		polarity = UNIPOLAR;
+	} else {
+		polarity = BIPOLAR;
+	}
+
+	return polarity;
+}
+
+
+/*!
+ * @brief	Read the num_of_bytes from previous conversion
+ * @param	dev[in]- Device instance
+ * @param	num_of_bytes[in] - Number of bytes to read from previous conversion
+ * @return	SUCCESS in case of success, FAILURE otherwise
+ */
+int32_t ad7606_read_conversion_data(struct ad7606_dev *dev,
+				    uint8_t num_of_bytes)
+{
+	memset(dev->data, 0, sizeof(dev->data));
+	return spi_write_and_read(dev->spi_desc, dev->data, num_of_bytes);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/ad7606_support.h	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,78 @@
+/***************************************************************************//**
+ *   @file   ad7606_support.h
+ *   @brief  Header for AD7606 No-OS driver supports
+********************************************************************************
+ * Copyright (c) 2020 Analog Devices, Inc.
+ *
+ * All rights reserved.
+ *
+ * This software is proprietary to Analog Devices, Inc. and its licensors.
+ * By using this software you agree to the terms of the associated
+ * Analog Devices Software License Agreement.
+*******************************************************************************/
+
+#ifndef AD7606_SUPPORT_H_
+#define AD7606_SUPPORT_H_
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+
+#include "ad7606.h"
+
+/******************************************************************************/
+/********************** Macros and Constants Definition ***********************/
+/******************************************************************************/
+
+/* Offset b/w two channel selections in CHx_RANGE register */
+#define CHANNEL_RANGE_MSK_OFFSET	4
+
+/* AD7606_REG_OVERSAMPLING */
+#define AD7606_OVERSAMPLING_MSK		GENMASK(3,0)
+
+/* Default channel range for AD7606 devices */
+#define DEFAULT_CHN_RANGE	(10.0)
+
+/* Diagnostic channels Mux configurations */
+#define AD7606_DIAGN_MUX_CH_MSK(ch)			(GENMASK(2, 0) << (3 * ((ch) % 2)))
+#define AD7606_DIAGN_MUX_CH_VAL(ch, val)	(val << (3 * ((ch) % 2)))
+
+#define AD7606_OPEN_DETECT_ENABLE_MSK(ch)	(GENMASK(7,0) & (~(1 << ch)))
+
+/* Diagnostic channels Mux select bits */
+#define ANALOG_INPUT_MUX	0X00
+#define TEMPERATURE_MUX		0x01
+#define VREF_MUX			0X02
+#define ALDO_MUX			0X03
+#define DLDO_MUX			0X04
+#define	VDRIVE_MUX			0x05
+
+/* Diagnostic Mux multiplers */
+#define VREF_MUX_MULTIPLIER		4.0
+
+/* Unipolar inputs range bits for AD7606C */
+#define AD7606C_UNIPOLAR_RANGE_MIN	5
+#define AD7606C_UNIPOLAR_RANGE_MAX	7
+
+/* Number of AD7606 registers */
+#define NUM_OF_REGISTERS	0x2F
+
+/******************************************************************************/
+/********************** Variables and User Defined Data Types *****************/
+/******************************************************************************/
+
+/* Analog input polarity */
+typedef enum {
+	UNIPOLAR,
+	BIPOLAR
+} polarity_e;
+
+/******************************************************************************/
+/************************ Public Declarations *********************************/
+/******************************************************************************/
+
+float convert_adc_raw_to_voltage(int32_t adc_raw, float scale);
+int32_t ad7606_read_conversion_data(struct ad7606_dev *dev, uint8_t bytes);
+polarity_e ad7606_get_input_polarity(uint8_t chn_range_bits);
+
+#endif /* AD7606_SUPPORT_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/ad7606_user_config.c	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,161 @@
+/*************************************************************************//**
+ *   @file   ad7606_user_config.c
+ *   @brief  User configuration file for AD7606 device
+******************************************************************************
+* Copyright (c) 2020 Analog Devices, Inc.
+*
+* All rights reserved.
+*
+* This software is proprietary to Analog Devices, Inc. and its licensors.
+* By using this software you agree to the terms of the associated
+* Analog Devices Software License Agreement.
+*****************************************************************************/
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+
+#include <stdint.h>
+
+#include "app_config.h"
+#include "ad7606_user_config.h"
+#include "ad7606_support.h"
+#include "spi_extra.h"
+#include "gpio_extra.h"
+
+/******************************************************************************/
+/********************** Macros and Constants Definition ***********************/
+/******************************************************************************/
+
+#define		USER_CONFIG_RANGE	(DEFAULT_CHN_RANGE * 1000)
+
+/******************************************************************************/
+/********************** Variables and User Defined Data Types *****************/
+/******************************************************************************/
+
+struct gpio_init_param gpio_init_reset = {
+	.number = RESET_PIN,
+	.extra = NULL
+};
+
+struct gpio_init_param gpio_init_convst = {
+	.number = CONVST_PIN,
+	.extra = NULL
+};
+
+struct gpio_init_param gpio_init_busy = {
+	.number = BUSY_PIN,
+	.extra = NULL
+};
+
+struct gpio_init_param gpio_init_osr0 = {
+	.number = OSR0_PIN,
+	.extra = NULL
+};
+
+struct gpio_init_param gpio_init_osr1 = {
+	.number = OSR1_PIN,
+	.extra = NULL
+};
+
+struct gpio_init_param gpio_init_osr2 = {
+	.number = OSR2_PIN,
+	.extra = NULL
+};
+
+struct gpio_init_param gpio_init_range= {
+	.number = RANGE_PIN,
+	.extra = NULL
+};
+
+struct gpio_init_param gpio_init_stdby = {
+	.number = STDBY_PIN,
+	.extra = NULL
+};
+
+
+/* Define SPI extra init parameters structure */
+mbed_spi_init_param spi_init_extra_params = {
+	.spi_clk_pin = SPI_SCK,
+	.spi_miso_pin = SPI_MISO,
+	.spi_mosi_pin = SPI_MOSI
+};
+
+/* Initialize the AD7606 device structure */
+struct ad7606_init_param ad7606_init_str = {
+	// Define SPI init parameters structure
+	{
+		.max_speed_hz = 22500000,   	// Max SPI Speed
+		.chip_select = SPI_SS,   		// Chip Select
+		.mode = SPI_MODE_2,   			// CPOL = 1, CPHA = 1
+		.extra = &spi_init_extra_params	// SPI extra configurations
+	},
+
+	.gpio_reset = &gpio_init_reset,
+	.gpio_convst = &gpio_init_convst,
+	.gpio_busy = &gpio_init_busy,
+	.gpio_stby_n = &gpio_init_stdby,
+	.gpio_range = &gpio_init_range,
+	.gpio_os0 = &gpio_init_osr0,
+	.gpio_os1 = &gpio_init_osr1,
+	.gpio_os2 = &gpio_init_osr2,
+	.gpio_par_ser = NULL,
+
+	.device_id = ACTIVE_DEVICE,
+	.oversampling = { 0, AD7606_OSR_1 },
+	.sw_mode = true,
+
+	// Below settings (except range) applies only to AD7606B and AD7606C devices
+
+	/* Device Configs */
+	{
+		.op_mode = AD7606_NORMAL,
+		.dout_format = AD7606_1_DOUT,
+		.ext_os_clock = false,
+		.status_header = false
+	},
+
+	/* Diagnostic flags setting */
+	{
+		.rom_crc_err_en = false,
+		.mm_crc_err_en = false,
+		.int_crc_err_en = false,
+		.spi_write_err_en = false,
+		.spi_read_err_en = false,
+		.busy_stuck_high_err_en = false,
+		.clk_fs_os_counter_en = false,
+		.interface_check_en = false
+	},
+
+	/* Default offset for all channels */
+	.offset_ch = { 0, 0, 0, 0, 0, 0, 0, 0 },
+
+	/* Default phase (0x00) for all channels */
+	.phase_ch = { 0, 0, 0, 0, 0, 0, 0, 0 },
+
+	/* Default gain (0x00) for all channels */
+	.gain_ch = { 0, 0, 0, 0, 0, 0, 0, 0 },
+
+	/* Default range for all channels */
+	.range_ch = {
+#if defined(DEV_AD7609)
+		{-USER_CONFIG_RANGE, USER_CONFIG_RANGE, true},
+		{-USER_CONFIG_RANGE, USER_CONFIG_RANGE, true},
+		{-USER_CONFIG_RANGE, USER_CONFIG_RANGE, true},
+		{-USER_CONFIG_RANGE, USER_CONFIG_RANGE, true},
+		{-USER_CONFIG_RANGE, USER_CONFIG_RANGE, true},
+		{-USER_CONFIG_RANGE, USER_CONFIG_RANGE, true},
+		{-USER_CONFIG_RANGE, USER_CONFIG_RANGE, true},
+		{-USER_CONFIG_RANGE, USER_CONFIG_RANGE, true},
+#else
+		{-USER_CONFIG_RANGE, USER_CONFIG_RANGE, false},
+		{-USER_CONFIG_RANGE, USER_CONFIG_RANGE, false},
+		{-USER_CONFIG_RANGE, USER_CONFIG_RANGE, false},
+		{-USER_CONFIG_RANGE, USER_CONFIG_RANGE, false},
+		{-USER_CONFIG_RANGE, USER_CONFIG_RANGE, false},
+		{-USER_CONFIG_RANGE, USER_CONFIG_RANGE, false},
+		{-USER_CONFIG_RANGE, USER_CONFIG_RANGE, false},
+		{-USER_CONFIG_RANGE, USER_CONFIG_RANGE, false}
+#endif
+	}
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/ad7606_user_config.h	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,34 @@
+/*************************************************************************//**
+ *   @file   ad7606_user_config.h
+ *   @brief  Header for AD7606 user configuration file
+******************************************************************************
+* Copyright (c) 2020 Analog Devices, Inc.
+*
+* All rights reserved.
+*
+* This software is proprietary to Analog Devices, Inc. and its licensors.
+* By using this software you agree to the terms of the associated
+* Analog Devices Software License Agreement.
+*****************************************************************************/
+
+#ifndef _AD7606_USER_CONFIG_H_
+#define _AD7606_USER_CONFIG_H_
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+
+#include <stdint.h>
+#include "ad7606.h"
+
+/******************************************************************************/
+/********************** Macros and Constants Definition ***********************/
+/******************************************************************************/
+
+/******************************************************************************/
+/********************** Variables and User Defined Data Types *****************/
+/******************************************************************************/
+
+extern struct ad7606_init_param ad7606_init_str;
+
+#endif /* end of _AD7606_USER_CONFIG_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/app_config.h	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,124 @@
+/*************************************************************************//**
+ *   @file   app_config.h
+ *   @brief  Configuration file for AD7606 device applications
+******************************************************************************
+* Copyright (c) 2020 Analog Devices, Inc.
+*
+* All rights reserved.
+*
+* This software is proprietary to Analog Devices, Inc. and its licensors.
+* By using this software you agree to the terms of the associated
+* Analog Devices Software License Agreement.
+*****************************************************************************/
+
+#ifndef _APP_CONFIG_H_
+#define _APP_CONFIG_H_
+
+#include <stdint.h>
+#include <PinNames.h>
+
+// **** Note for User: ACTIVE_DEVICE selection ****//
+/* Define the device type here from the list of below device type defines
+ * (one at a time. Defining more than one device can result into compile error).
+ * e.g. #define DEV_AD7606B -> This will make AD7606B as an ACTIVE_DEVICE.
+ * The ACTIVE_DEVICE is default set to AD7606B if device type is not defined.
+ * */
+
+//#define DEV_AD7606B
+
+#if defined(DEV_AD7605_4)
+#define ACTIVE_DEVICE		ID_AD7605_4
+#define ACTIVE_DEVICE_NAME	"AD7605-4-phy"
+#elif defined(DEV_AD7606_4)
+#define ACTIVE_DEVICE		ID_AD7606_4
+#define ACTIVE_DEVICE_NAME	"AD7606-4-phy"
+#elif defined(DEV_AD7606_6)
+#define ACTIVE_DEVICE		ID_AD7606_6
+#define ACTIVE_DEVICE_NAME	"AD7606-6-phy"
+#elif defined(DEV_AD7606_8)
+#define ACTIVE_DEVICE		ID_AD7606_8
+#define ACTIVE_DEVICE_NAME	"AD7606-8-phy"
+#elif defined(DEV_AD7606B)
+#define ACTIVE_DEVICE		ID_AD7606B
+#define ACTIVE_DEVICE_NAME	"AD7606B-phy"
+#elif defined(DEV_AD7606C_16)
+#define ACTIVE_DEVICE		ID_AD7606C_16
+#define ACTIVE_DEVICE_NAME	"AD7606C-16-phy"
+#elif defined(DEV_AD7606C_18)
+#define ACTIVE_DEVICE		ID_AD7606C_18
+#define ACTIVE_DEVICE_NAME	"AD7606C-18-phy"
+#elif defined(DEV_AD7608)
+#define ACTIVE_DEVICE		ID_AD7608
+#define ACTIVE_DEVICE_NAME	"AD7608-phy"
+#elif defined(DEV_AD7609)
+#define ACTIVE_DEVICE		ID_AD7609
+#define ACTIVE_DEVICE_NAME	"AD7609-phy"
+#else
+#warning No/Unsupported ADxxxxy symbol defined. AD7606B defined
+#define DEV_AD7606B
+#define ACTIVE_DEVICE		ID_AD7606B
+#define ACTIVE_DEVICE_NAME	"AD7606B-phy"
+#endif
+
+
+#if defined(DEV_AD7605_4)
+#define	AD7606X_ADC_CHANNELS	4
+#define AD7606X_ADC_RESOLUTION	16
+#elif defined(DEV_AD7606_4)
+#define	AD7606X_ADC_CHANNELS	4
+#define AD7606X_ADC_RESOLUTION	16
+#elif defined(DEV_AD7606_6)
+#define	AD7606X_ADC_CHANNELS	6
+#define AD7606X_ADC_RESOLUTION	16
+#elif defined(DEV_AD7606_8)
+#define	AD7606X_ADC_CHANNELS	8
+#define AD7606X_ADC_RESOLUTION	16
+#elif defined(DEV_AD7606B)
+#define	AD7606X_ADC_CHANNELS	8
+#define AD7606X_ADC_RESOLUTION	16
+#elif defined(DEV_AD7606C_16)
+#define	AD7606X_ADC_CHANNELS	8
+#define AD7606X_ADC_RESOLUTION	16
+#elif defined(DEV_AD7606C_18)
+#define	AD7606X_ADC_CHANNELS	8
+#define AD7606X_ADC_RESOLUTION	18
+#elif defined(DEV_AD7608)
+#define	AD7606X_ADC_CHANNELS	8
+#define AD7606X_ADC_RESOLUTION	18
+#elif defined(DEV_AD7609)
+#define	AD7606X_ADC_CHANNELS	8
+#define AD7606X_ADC_RESOLUTION	18
+#else
+/* Default config for AD7606B */
+#define	AD7606X_ADC_CHANNELS	8
+#define AD7606X_ADC_RESOLUTION	16
+#endif
+
+/* ADC max count (full scale value) for unipolar inputs */
+#define ADC_MAX_COUNT_UNIPOLAR	(uint32_t)((1 << AD7606X_ADC_RESOLUTION) - 1)
+
+/* ADC max count (full scale value) for bipolar inputs */
+#define ADC_MAX_COUNT_BIPOLAR	(uint32_t)(1 << (AD7606X_ADC_RESOLUTION-1))
+
+// Pin mapping of AD7606 w.r.t Arduino (reference: PinNames.h)
+#define SPI_SS		D10
+#define SPI_MOSI	D11
+#define SPI_MISO	D12
+#define SPI_SCK		D13
+
+#define UART_TX		USBTX
+#define	UART_RX		USBRX
+
+#define	OSR0_PIN	D2
+#define	OSR1_PIN	D3
+#define	OSR2_PIN	D4
+#define RESET_PIN	D5
+#define CONVST_PIN	D6
+#define BUSY_PIN	D7
+#define RANGE_PIN	D8
+#define STDBY_PIN	D9
+
+#define LED_GREEN	LED3
+
+
+#endif //_APP_CONFIG_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/iio_ad7606.c	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,1851 @@
+/***************************************************************************//**
+ *   @file    iio_ad7606.c
+ *   @brief   Implementation of AD7606 IIO application interfaces
+ *   @details This module acts as an interface for AD7606 IIO application
+********************************************************************************
+ * Copyright (c) 2020 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
+ * Analog Devices Software License Agreement.
+*******************************************************************************/
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+
+#include <inttypes.h>
+#include <string.h>
+#include <errno.h>
+#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 "ad7606.h"
+#include "ad7606_data_capture.h"
+#include "ad7606_support.h"
+#include "ad7606_user_config.h"
+
+/******************************************************************************/
+/************************ Macros/Constants ************************************/
+/******************************************************************************/
+
+/* ADC data to Voltage conversion scale factor for IIO client */
+#define DEFAULT_SCALE		((DEFAULT_CHN_RANGE / ADC_MAX_COUNT_BIPOLAR) * 1000)
+
+/* LSB Threshold to entry into open wire detection as per datasheet */
+#define OPEN_DETECT_ENTRY_THRESHOLD		350
+
+/* Open detect LSB threshold @50K Rpd as per datasheet */
+#define OPEN_DETECT_THRESHOLD_RPD50K	15
+
+/* Maximum ADC calibration gain value */
+#define ADC_CALIBRATION_GAIN_MAX		64.0
+
+/******************************************************************************/
+/*************************** Types Declarations *******************************/
+/******************************************************************************/
+
+/**
+* IIO application instance descriptor.
+*/
+static struct iio_app_desc *iio_app_desc;
+
+/**
+ * Device name.
+ */
+static const char dev_name[] = ACTIVE_DEVICE_NAME;
+
+/**
+ * Pointer to the struct representing the AD7606 IIO device
+ */
+static struct ad7606_dev *p_ad7606_dev = NULL;
+
+
+/* Device attributes with default values */
+
+/* Power down mode values string representation (possible values specified in datasheet) */
+static char *operating_mode_str[] = {
+	"0  (Normal Mode)",
+	"1  (Standby Mode)",
+	"2  (Auto Standby Mode)",
+	"3  (Shutdown Mode)"
+};
+
+/* Bandwidth values string */
+static char *bandwidth_str[] = {
+	"0  (Low)",
+	"1  (High)"
+};
+
+/* Channel range values string representation (possible values specified in datasheet) */
+static char *chn_range_str[] = {
+#if defined(DEV_AD7606B)
+	"0  (+/-2.5V SE)", "1  (+/-5.0V SE)", "2  (+/-10.0V SE)", "3  (+/-10.0V SE)",
+	"4  (+/-10.0V SE)", "5  (+/-10.0V SE)", "6  (+/-10.0V SE)", "7  (+/-10.0V SE)",
+	"8  (+/-10.0V SE)", "9  (+/-10.0V SE)", "10  (+/-10.0V SE)", "11  (+/-10.0V SE)",
+#elif defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+	"0  (+/-2.5V SE)", "1  (+/-5.0V SE)", "2  (+/-6.25V SE)", "3  (+/-10.0V SE)",
+	"4  (+/-12.5V SE)", "5  (+5.0V SE)", "6  (+10.0V SE)", "7  (+12.5V SE)",
+	"8  (+/-5.0V DE)", "9  (+/-10.0V DE)", "10  (+/-12.5V DE)", "11  (+/-20.0V DE)"
+#elif defined(DEV_AD7609)
+	"0  (+/-10.0V SE)", "1  (+/-20.0V SE)"
+#else
+	"0  (+/-5.0V SE)", "1  (+/-10.0V SE)"
+#endif
+};
+
+/* Oversampling values string representation (possible values specified in datasheet) */
+static char *oversampling_val_str[] = {
+	"0 (no oversampling)", "1 (oversampling by 2)", "2 (oversampling by 4)",
+	"3 (oversampling by 8)", "4 (oversampling by 16)", "5 (oversampling by 32)",
+	"6 (oversampling by 64)", "7 (oversampling by 128)", "8 (oversampling by 256)"
+};
+
+
+/* Channel range values string representation (possible values specified in datasheet) */
+static float chn_range_val[] = {
+#if defined(DEV_AD7606B)
+	2.5, 5.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0
+#elif defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+	2.5, 5.0, 6.25, 10.0, 12.5, 5.0, 10.0, 12.5, 5.0, 10.0, 12.5, 20.0
+#elif defined(DEV_AD7609)
+	10.0, 20.0
+#else
+	5.0, 10.0
+#endif
+};
+
+/* Range value per channel */
+static float attr_chn_range[AD7606X_ADC_CHANNELS] = {
+	DEFAULT_CHN_RANGE, DEFAULT_CHN_RANGE, DEFAULT_CHN_RANGE, DEFAULT_CHN_RANGE,
+	DEFAULT_CHN_RANGE, DEFAULT_CHN_RANGE, DEFAULT_CHN_RANGE, DEFAULT_CHN_RANGE
+};
+
+/* Scale value per channel */
+static float attr_scale_val[AD7606X_ADC_CHANNELS] = {
+	DEFAULT_SCALE, DEFAULT_SCALE, DEFAULT_SCALE, DEFAULT_SCALE,
+	DEFAULT_SCALE, DEFAULT_SCALE, DEFAULT_SCALE, DEFAULT_SCALE
+};
+
+/* Scale value per channel */
+static polarity_e attr_polarity_val[AD7606X_ADC_CHANNELS] = {
+	BIPOLAR, BIPOLAR, BIPOLAR, BIPOLAR,
+	BIPOLAR, BIPOLAR, BIPOLAR, BIPOLAR
+};
+
+/* Channel range */
+typedef enum {
+	LOW,
+	HIGH
+} range_e;
+
+/* Open detect auto mode QUEUE register count */
+static uint8_t open_detect_queue_cnts[AD7606X_ADC_CHANNELS] = {
+	0
+};
+
+/* ADC gain calibration Rfilter value (in Kohms) */
+static uint8_t gain_calibration_reg_val[AD7606X_ADC_CHANNELS] = {
+	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;
+
+/******************************************************************************/
+/************************ Functions Prototypes ********************************/
+/******************************************************************************/
+
+static float get_vltg_conv_scale_factor(float chn_range, polarity_e polarity);
+static void save_local_attributes(void);
+
+/******************************************************************************/
+/************************ Functions Definitions *******************************/
+/******************************************************************************/
+
+/*!
+ * @brief	Getter/Setter for the scale 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
+ */
+ssize_t get_chn_scale(void *device,
+		      char *buf,
+		      size_t len,
+		      const struct iio_ch_info *channel)
+{
+	return (ssize_t) sprintf(buf, "%f", attr_scale_val[channel->ch_num - 1]);
+}
+
+ssize_t set_chn_scale(void *device,
+		      char *buf,
+		      size_t len,
+		      const struct iio_ch_info *channel)
+{
+	float scale;
+
+	(void)sscanf(buf, "%f", &scale);
+
+	if (scale > 0.0) {
+		attr_scale_val[channel->ch_num - 1] = scale;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the raw 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
+ */
+ssize_t get_chn_raw(void *device,
+		    char *buf,
+		    size_t len,
+		    const struct iio_ch_info *channel)
+{
+	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]);
+
+	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)
+{
+	/* NA- Can't set raw value */
+	return len;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the operating mode 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
+ * @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)
+{
+	uint8_t read_val;
+	uint8_t operating_mode_value;
+
+	if (ad7606_spi_reg_read(device, AD7606_REG_CONFIG, &read_val) == SUCCESS) {
+		operating_mode_value = (read_val & AD7606_CONFIG_OPERATION_MODE_MSK);
+
+		if (operating_mode_value < sizeof(operating_mode_str) / sizeof(
+			    operating_mode_str[0])) {
+			return (ssize_t)sprintf(buf, "%s", operating_mode_str[operating_mode_value]);
+		}
+	}
+
+	return -EINVAL;
+}
+
+ssize_t set_operating_mode(void *device,
+			   char *buf,
+			   size_t len,
+			   const struct iio_ch_info *channel)
+{
+	uint8_t operating_mode_value;
+
+	(void)sscanf(buf, "%d", &operating_mode_value);
+
+	if (operating_mode_value < sizeof(operating_mode_str) / sizeof(
+		    operating_mode_str[0])) {
+		if (ad7606_spi_write_mask(device,
+					  AD7606_REG_CONFIG,
+					  AD7606_CONFIG_OPERATION_MODE_MSK,
+					  operating_mode_value) == SUCCESS) {
+			return len;
+		}
+	}
+
+	return -EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the power down mode 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
+ * @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)
+{
+	uint8_t gpio_stby_val;
+	uint8_t gpio_range_val;
+
+	if (gpio_get_value(((struct ad7606_dev *)device)->gpio_stby_n,
+			   &gpio_stby_val) == SUCCESS) {
+		if (gpio_get_value(((struct ad7606_dev *)device)->gpio_range,
+				   &gpio_range_val) == SUCCESS) {
+
+			if (gpio_stby_val) {
+				return sprintf(buf, "%s", operating_mode_str[AD7606_NORMAL]);
+			} else {
+				if (gpio_range_val) {
+					return sprintf(buf, "%s", operating_mode_str[AD7606_STANDBY]);
+				} else {
+					return sprintf(buf, "%s", operating_mode_str[AD7606_SHUTDOWN]);
+				}
+			}
+		}
+	}
+
+	return -EINVAL;
+}
+
+ssize_t set_power_down_mode(void *device,
+			    char *buf,
+			    size_t len,
+			    const struct iio_ch_info *channel)
+{
+	uint8_t power_down_mode_value;
+	static enum ad7606_op_mode prev_power_down_mode = AD7606_NORMAL;
+	struct ad7606_config dev_config;
+
+	sscanf(buf, "%d", &power_down_mode_value);
+
+	if (power_down_mode_value < (sizeof(operating_mode_str) / sizeof(
+					     operating_mode_str[0]))) {
+
+		dev_config.op_mode = power_down_mode_value;
+
+		switch (power_down_mode_value) {
+		case AD7606_NORMAL:
+			if (ad7606_set_config(device, dev_config) == SUCCESS) {
+				/* Reset the device if previous power down mode was either standby
+				 * or shutdown */
+				if (prev_power_down_mode != AD7606_NORMAL) {
+
+					/* Power-up wait time */
+					mdelay(1);
+
+					/* Toggle reset pin */
+					if (gpio_set_value(((struct ad7606_dev *)device)->gpio_reset,
+							   GPIO_HIGH) == SUCCESS) {
+						mdelay(1);
+
+						if (gpio_set_value(((struct ad7606_dev *)device)->gpio_reset,
+								   GPIO_LOW) == SUCCESS) {
+							prev_power_down_mode = AD7606_NORMAL;
+							return len;
+						}
+					}
+				}
+			}
+			break;
+
+		case AD7606_STANDBY:
+			if (ad7606_set_config(device, dev_config) == SUCCESS) {
+				prev_power_down_mode = AD7606_STANDBY;
+				return len;
+			}
+			break;
+
+		case AD7606_SHUTDOWN:
+			if (ad7606_set_config(device, dev_config) == SUCCESS) {
+				prev_power_down_mode = AD7606_SHUTDOWN;
+				return len;
+			}
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	return -EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the range 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
+ * @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)
+{
+	uint8_t gpio_range_val;
+	struct ad7606_dev *dev = device;
+
+	if (gpio_get_value(dev->gpio_range, &gpio_range_val) == SUCCESS) {
+		if (gpio_range_val) {
+			return sprintf(buf, "%s", chn_range_str[HIGH]);
+		} else {
+			return sprintf(buf, "%s", chn_range_str[LOW]);
+		}
+	}
+
+	return -EINVAL;
+}
+
+ssize_t set_range(void *device,
+		  char *buf,
+		  size_t len,
+		  const struct iio_ch_info *channel)
+{
+	uint8_t range_value;
+	struct ad7606_dev *dev = device;
+
+	(void)sscanf(buf, "%d", &range_value);
+
+	if (range_value < (sizeof(chn_range_str) / sizeof(chn_range_str[0]))) {
+		if (range_value == LOW) {
+			if (gpio_set_value(dev->gpio_range, GPIO_LOW) == SUCCESS) {
+				return len;
+			}
+		} else {
+			if (gpio_set_value(dev->gpio_range, GPIO_HIGH) == SUCCESS) {
+				return len;
+			}
+		}
+	}
+
+	return -EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the oversampling 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
+ * @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)
+{
+	uint8_t oversampling_value;
+	uint8_t read_val;
+	uint8_t gpio_osr0_val;
+	uint8_t gpio_osr1_val;
+	uint8_t gpio_osr2_val;
+	struct ad7606_dev *dev = device;
+
+#if defined(DEV_AD7606B) || defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+	if (ad7606_spi_reg_read(device,
+				AD7606_REG_OVERSAMPLING,
+				&read_val) == SUCCESS) {
+		oversampling_value = (read_val & AD7606_OVERSAMPLING_MSK);
+
+		if (oversampling_value < sizeof(oversampling_val_str) / sizeof(
+			    oversampling_val_str[0])) {
+			return (ssize_t)sprintf(buf, "%s", oversampling_val_str[oversampling_value]);
+		}
+	}
+#else
+	if (gpio_get_value(dev->gpio_os0, &gpio_osr0_val) == SUCCESS) {
+		if (gpio_get_value(dev->gpio_os1, &gpio_osr1_val) == SUCCESS) {
+			if (gpio_get_value(dev->gpio_os2, &gpio_osr2_val) == SUCCESS) {
+				oversampling_value = (gpio_osr2_val << 2) | (gpio_osr1_val << 1) |
+						     gpio_osr0_val;
+
+				if (oversampling_value < (sizeof(oversampling_val_str) / sizeof(
+								  oversampling_val_str[0]))) {
+					return sprintf(buf, "%s", oversampling_val_str[oversampling_value]);
+				}
+			}
+		}
+	}
+#endif
+
+	return -EINVAL;
+}
+
+ssize_t set_oversampling(void *device,
+			 char *buf,
+			 size_t len,
+			 const struct iio_ch_info *channel)
+{
+	uint8_t oversampling_value;
+	struct ad7606_oversampling oversampling_cfg;
+
+	(void)sscanf(buf, "%d", &oversampling_value);
+
+	if (oversampling_value < (sizeof(oversampling_val_str) / sizeof(
+					  oversampling_val_str[0]))) {
+
+		oversampling_cfg.os_pad = 0;
+		oversampling_cfg.os_ratio = oversampling_value;
+
+		ad7606_set_oversampling(device, oversampling_cfg);
+
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the bandwidth 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
+ * @note	Available for only AD7606C
+ */
+ssize_t get_bandwidth(void *device,
+		      char *buf,
+		      size_t len,
+		      const struct iio_ch_info *channel)
+{
+	uint8_t bw_value;
+	uint8_t read_val;
+
+	if (ad7606_spi_reg_read(device,
+				AD7606_REG_BANDWIDTH,
+				&read_val) == SUCCESS) {
+		bw_value = (read_val >> (channel->ch_num - 1)) & 0x1;
+
+		if (bw_value < sizeof(bandwidth_str) / sizeof(
+			    bandwidth_str[0])) {
+			return (ssize_t)sprintf(buf, "%s", bandwidth_str[bw_value]);
+		}
+	}
+
+	return -EINVAL;
+}
+
+ssize_t set_bandwidth(void *device,
+		      char *buf,
+		      size_t len,
+		      const struct iio_ch_info *channel)
+{
+	uint8_t bw_value;
+	uint8_t read_val;
+
+	(void)sscanf(buf, "%d", &bw_value);
+
+	if (bw_value < sizeof(bandwidth_str) / sizeof(
+		    bandwidth_str[0])) {
+		if (ad7606_spi_reg_read(device,
+					AD7606_REG_BANDWIDTH,
+					&read_val) == SUCCESS) {
+			if (bw_value) {
+				read_val |= (1 << (channel->ch_num - 1));
+			} else {
+				read_val &= (~(1 << (channel->ch_num - 1)));
+			}
+
+			if (ad7606_spi_reg_write(device,
+						 AD7606_REG_BANDWIDTH,
+						 read_val) == SUCCESS) {
+				return len;
+			}
+		}
+	}
+
+	return -EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the channel range 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
+ * @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)
+{
+	uint8_t read_val;
+	uint8_t chn_range;
+
+	if (ad7606_spi_reg_read(device, AD7606_REG_RANGE_CH_ADDR(channel->ch_num-1),
+				&read_val) == SUCCESS) {
+		if (((channel->ch_num - 1) % 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));
+		}
+
+		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);
+
+			return (ssize_t)sprintf(buf, "%s", chn_range_str[chn_range]);
+		}
+	}
+
+	return -EINVAL;
+}
+
+ssize_t set_chn_range(void *device,
+		      char *buf,
+		      size_t len,
+		      const struct iio_ch_info *channel)
+{
+	uint8_t chn_range;
+
+	(void)sscanf(buf, "%d", &chn_range);
+
+	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_chn_range[channel->ch_num - 1] = chn_range_val[chn_range];
+		attr_scale_val[channel->ch_num - 1] = get_vltg_conv_scale_factor(
+				chn_range_val[chn_range],
+				attr_polarity_val[channel->ch_num - 1]);
+
+		if (((channel->ch_num - 1) % 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),
+					  chn_range) == SUCCESS) {
+			return len;
+		}
+	}
+
+	return -EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the channel offset 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
+ * @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)
+{
+	uint8_t chn_offset_value;
+
+	if (ad7606_spi_reg_read(device, AD7606_REG_OFFSET_CH(channel->ch_num-1),
+				&chn_offset_value) == SUCCESS) {
+		return (ssize_t)sprintf(buf, "%d", chn_offset_value);
+	}
+
+	return -EINVAL;
+}
+
+ssize_t set_chn_offset(void *device,
+		       char *buf,
+		       size_t len,
+		       const struct iio_ch_info *channel)
+{
+	uint8_t chn_offset_value = 0;
+
+	(void)sscanf(buf, "%d", &chn_offset_value);
+
+	if (ad7606_set_ch_offset(device, channel->ch_num - 1,
+				 chn_offset_value) == SUCCESS) {
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the channel pahse offset 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
+ * @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)
+{
+	uint8_t chn_phase_offset_value;
+
+	if (ad7606_spi_reg_read(device,
+				AD7606_REG_PHASE_CH(channel->ch_num - 1),
+				&chn_phase_offset_value) == SUCCESS) {
+		return (ssize_t)sprintf(buf, "%d", chn_phase_offset_value);
+	}
+
+	return -EINVAL;
+}
+
+ssize_t set_chn_phase_offset(void *device,
+			     char *buf,
+			     size_t len,
+			     const struct iio_ch_info *channel)
+{
+	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,
+				chn_phase_offset_value) == SUCCESS) {
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the channel temperature 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
+ * @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)
+{
+	int32_t adc_chn_data = 0;
+	float temperature;
+	float voltage;
+
+	/* 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),
+						  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]);
+
+		/* Convert ADC data into equivalent voltage */
+		voltage = convert_adc_raw_to_voltage(adc_chn_data,
+						     attr_scale_val[channel->ch_num - 1]);
+
+		/* 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),
+							    ANALOG_INPUT_MUX));
+
+		return (ssize_t)sprintf(buf, "%f", temperature);
+	}
+
+	return -EINVAL;
+}
+
+ssize_t set_chn_temperature(void *device,
+			    char *buf,
+			    size_t len,
+			    const struct iio_ch_info *channel)
+{
+	// NA- Can't set temperature
+	return -EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the channel Vref 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
+ * @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)
+{
+	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),
+						  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]);
+
+		/* Convert ADC data into equivalent voltage */
+		vref_voltge = convert_adc_raw_to_voltage(adc_chn_data,
+				attr_scale_val[channel->ch_num - 1]);
+
+		/* 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),
+							    ANALOG_INPUT_MUX));
+
+		return (ssize_t)sprintf(buf, "%f", vref_voltge);
+	}
+
+	return -EINVAL;
+}
+
+ssize_t set_chn_vref(void *device,
+		     char *buf,
+		     size_t len,
+		     const struct iio_ch_info *channel)
+{
+	// NA- Can't set Vref
+	return - EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the channel Vdrive 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
+ * @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)
+{
+	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),
+						  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]);
+
+		/* Convert ADC data into equivalent voltage */
+		vdrive_voltge = convert_adc_raw_to_voltage(adc_chn_data,
+				attr_scale_val[channel->ch_num - 1]);
+
+		/* 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),
+							    ANALOG_INPUT_MUX));
+
+		return (ssize_t)sprintf(buf, "%f", vdrive_voltge);
+	}
+
+	return -EINVAL;
+}
+
+ssize_t set_chn_vdrive(void *device,
+		       char *buf,
+		       size_t len,
+		       const struct iio_ch_info *channel)
+{
+	// NA- Can't set Vdrive
+	return - EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the channel ALDO 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
+ * @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)
+{
+	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),
+						  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]);
+
+		/* Convert ADC data into equivalent voltage */
+		aldo_voltge = convert_adc_raw_to_voltage(adc_chn_data,
+				attr_scale_val[channel->ch_num - 1]);
+
+		/* 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),
+							    ANALOG_INPUT_MUX));
+
+		return (ssize_t)sprintf(buf, "%f", aldo_voltge);
+	}
+
+	return -EINVAL;
+}
+
+ssize_t set_chn_aldo(void *device,
+		     char *buf,
+		     size_t len,
+		     const struct iio_ch_info *channel)
+{
+	// NA- Can't set ALDO
+	return - EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the channel DLDO 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
+ * @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)
+{
+	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),
+						  DLDO_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]);
+
+		/* Convert ADC data into equivalent voltage */
+		dldo_voltge = convert_adc_raw_to_voltage(adc_chn_data,
+				attr_scale_val[channel->ch_num - 1]);
+
+		/* 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),
+							    ANALOG_INPUT_MUX));
+
+		return (ssize_t)sprintf(buf, "%f", dldo_voltge);
+	}
+
+	return -EINVAL;
+}
+
+ssize_t set_chn_dldo(void *device,
+		     char *buf,
+		     size_t len,
+		     const struct iio_ch_info *channel)
+{
+	// NA- Can't set DLDO
+	return - EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the channel open wire detect manual 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
+ */
+ssize_t get_chn_open_wire_detect_manual(void *device,
+					char *buf,
+					size_t len,
+					const struct iio_ch_info *channel)
+{
+	static volatile int32_t data[2];
+	uint8_t open_detect_flag = false;
+	int32_t rw_status = FAILURE;
+
+	/* Read the ADC on selected channel (before open wire detection start) */
+	data[0] = single_data_read(device,
+				   channel->ch_num - 1,
+				   attr_polarity_val[channel->ch_num - 1]);
+
+	/* Enter into manual open wire detect mode */
+	if (ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_QUEUE, 1) == SUCCESS) {
+		/* Set common mode high (enabling open wire detect on selected channel) */
+		if (ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_ENABLE,
+					 (1 << ((channel->ch_num) - 1))) == SUCCESS) {
+			/* Read the ADC on selected chnnel (post open wire detection) */
+			data[1] = single_data_read(device, channel->ch_num - 1,
+						   attr_polarity_val[channel->ch_num - 1]);
+
+			/* Check for up shift in common mode output voltage */
+			if ((data[1] - data[0]) > OPEN_DETECT_THRESHOLD_RPD50K) {
+				/* Set common mode low (disabling open wire detect on channels) */
+				if (ad7606_spi_reg_write(device,
+							 AD7606_REG_OPEN_DETECT_ENABLE,
+							 0) == SUCCESS) {
+
+					/* Let channel settle down */
+					mdelay(1);
+
+					/* Read the ADC output after open wire detection */
+					data[1] = single_data_read(device,
+								   channel->ch_num - 1,
+								   attr_polarity_val[channel->ch_num - 1]);
+
+					/* Check if code returns back to original (with some threshold) */
+					if (abs(data[1] - data[0]) <= OPEN_DETECT_THRESHOLD_RPD50K) {
+						open_detect_flag = true;
+					}
+				}
+			}
+
+			rw_status = SUCCESS;
+		}
+	}
+
+	/* Disable open detect mode */
+	(void)ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_QUEUE, 0);
+
+	if (rw_status == SUCCESS) {
+		if (open_detect_flag) {
+			strcpy(buf, "Open Wire Detected");
+		} else {
+			strcpy(buf, "Open Wire Not Detected");
+		}
+
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+ssize_t set_chn_open_wire_detect_manual(void *device,
+					char *buf,
+					size_t len,
+					const struct iio_ch_info *channel)
+{
+	// NA- Can't set open wire detect
+	return - EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the channel open wire detect auto 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
+ */
+ssize_t get_chn_open_wire_detect_auto(void *device,
+				      char *buf,
+				      size_t len,
+				      const struct iio_ch_info *channel)
+{
+	uint8_t open_detect_flag = false;
+	int32_t rw_status = FAILURE;
+	uint8_t conv_cnts;
+
+	if (open_detect_queue_cnts[channel->ch_num-1] <= 1) {
+		strcpy(buf, "Err: OPEN_DETECT_QUEUE Invalid");
+		return len;
+	}
+
+	/* Enter into auto open detect mode */
+	if (ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_QUEUE,
+				 open_detect_queue_cnts[channel->ch_num-1]) == SUCCESS) {
+		/* Enable open wire detection on selected channel */
+		if (ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_ENABLE,
+					 (1 << ((channel->ch_num) - 1))) == SUCCESS) {
+			/* Monitor the open detect flag for max N (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++) {
+				if (ad7606_convst(device) == SUCCESS) {
+					udelay(100);
+
+					/* Monitor the open detect flag */
+					if (ad7606_spi_reg_read(device,
+								AD7606_REG_OPEN_DETECTED,
+								&open_detect_flag) == SUCCESS) {
+						open_detect_flag >>= (channel->ch_num - 1);
+						open_detect_flag &= 0x1;
+
+						rw_status = SUCCESS;
+						if (open_detect_flag) {
+							break;
+						}
+					} else {
+						rw_status = FAILURE;
+						break;
+					}
+				} else {
+					rw_status = FAILURE;
+					break;
+				}
+			}
+		}
+	}
+
+	/* Disable open detect mode */
+	(void)ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_QUEUE, 0);
+
+	if (rw_status == SUCCESS) {
+		if (open_detect_flag) {
+			strcpy(buf, "Open Wire Detected");
+		} else {
+			strcpy(buf, "Open Wire Not Detected");
+		}
+
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+ssize_t set_chn_open_wire_detect_auto(void *device,
+				      char *buf,
+				      size_t len,
+				      const struct iio_ch_info *channel)
+{
+	uint8_t data;
+
+	(void)sscanf(buf, "%d", &data);
+
+	if (data > 1) {
+		open_detect_queue_cnts[channel->ch_num - 1] = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the adc offset calibration
+ * @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
+ */
+ssize_t get_chn_calibrate_adc_offset(void *device,
+				     char *buf,
+				     size_t len,
+				     const struct iio_ch_info *channel)
+{
+	float lsb_voltage;
+	float adc_voltage;
+	polarity_e polarity = attr_polarity_val[channel->ch_num - 1];
+	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;
+	} else {
+		lsb_voltage = attr_chn_range[channel->ch_num - 1] / ADC_MAX_COUNT_BIPOLAR;
+	}
+
+	/* Sample and read the ADC channel */
+	adc_data = single_data_read(device, channel->ch_num - 1,
+				    polarity);
+
+	/* Get an equivalent ADC voltage */
+	adc_voltage = convert_adc_raw_to_voltage(adc_data,
+			attr_scale_val[channel->ch_num - 1]);
+
+	/* Calculate the channel offset and write it to offset register */
+	chn_offset = -(adc_voltage / lsb_voltage);
+
+	if (ad7606_set_ch_offset(device, channel->ch_num - 1,
+				 chn_offset) == SUCCESS) {
+		return sprintf(buf, "%s", "ADC Calibration Done");
+	}
+
+	return -EINVAL;
+}
+
+ssize_t set_chn_calibrate_adc_offset(void *device,
+				     char *buf,
+				     size_t len,
+				     const struct iio_ch_info *channel)
+{
+	// NA- Can't set open wire detect
+	return - EINVAL;
+}
+
+
+/*!
+ * @brief	Getter/Setter for the adc gain calibration
+ * @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
+ */
+ssize_t get_chn_calibrate_adc_gain(void *device,
+				   char *buf,
+				   size_t len,
+				   const struct iio_ch_info *channel)
+{
+	uint8_t chn_gain;
+
+	/* Perform the gain calibration */
+	chn_gain = gain_calibration_reg_val[channel->ch_num - 1];
+
+	if (ad7606_set_ch_gain(device,
+			       channel->ch_num - 1,
+			       chn_gain) == SUCCESS) {
+		return sprintf(buf, "Calibration Done (Rfilter=%d K)", chn_gain);
+	}
+
+	return -EINVAL;
+}
+
+ssize_t set_chn_calibrate_adc_gain(void *device,
+				   char *buf,
+				   size_t len,
+				   const struct iio_ch_info *channel)
+{
+	float data;
+
+	(void)sscanf(buf, "%f", &data);
+
+	if (data < ADC_CALIBRATION_GAIN_MAX) {
+		/* Get the nearest value of unsigned integer */
+		gain_calibration_reg_val[channel->ch_num - 1] = (uint8_t)(round(data));
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+
+/*!
+ * @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
+ */
+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)
+{
+	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;
+		}
+	}
+
+	return -EINVAL;
+}
+
+
+/**
+ * @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.
+ */
+static ssize_t iio_ad7606_get_xml(char **xml, struct iio_device *iio_dev)
+{
+	*xml = (char*)calloc(1, strlen(ad7606_phy_xml) + 1);
+	if (!(*xml)) {
+		return -ENOMEM;
+	}
+
+	memcpy(*xml, ad7606_phy_xml, strlen(ad7606_phy_xml));
+
+	return SUCCESS;
+}
+
+
+/**
+ * @brief	Read buffer data corresponding to AD7606 IIO device
+ * @param	dev_instance[in] - IIO device instance
+ * @param	pbuf[out] - Pointer to output data buffer
+ * @return	SUCCESS in case of success or negative value otherwise
+ */
+static ssize_t iio_ad7606_read_data(void *dev_instance,
+				    char *pbuf,
+				    size_t offset,
+				    size_t bytes_count,
+				    uint32_t ch_mask)
+{
+	if (adc_background_data_capture_started == false) {
+		start_background_data_capture(ch_mask, bytes_count);
+		adc_background_data_capture_started = true;
+	}
+
+	/* Read the buffered data */
+	return (ssize_t)buffered_data_read(pbuf, bytes_count, offset, ch_mask);
+}
+
+
+/**
+ * @brief	Read requested samples count
+ * @param	dev_instance[in] - IIO device instance
+ * @param	pbuf[out] - Pointer to output data buffer
+ * @return	SUCCESS in case of success or negative value otherwise
+ */
+static ssize_t iio_ad7606_get_samples_count(void *dev_instance,
+		size_t bytes_count,
+		uint32_t ch_mask)
+{
+	store_requested_samples_count(bytes_count);
+	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
+ * @return	SUCCESS in case of success or negative value otherwise
+ */
+static ssize_t iio_ad7606_delete_device(struct iio_device *iio_device)
+{
+	if (!iio_device) {
+		return FAILURE;
+	}
+
+	free(iio_device);
+
+	return SUCCESS;
+}
+
+
+/**
+ * @brief	Init for reading/writing and parameterization of a
+ * 			ad7606 IIO device
+ * @param 	desc[in,out] - IIO device descriptor
+ * @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)
+{
+	int32_t status;
+	struct iio_interface *iio_interface;
+
+	iio_interface = (struct iio_interface *)calloc(1, sizeof(struct iio_interface));
+	if (!iio_interface) {
+		return -ENOMEM;
+	}
+
+	*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);
+		return FAILURE;
+	}
+
+	*desc = calloc(1, sizeof(struct iio_ad7606_desc));
+	if (!(*desc)) {
+		iio_unregister(iio_interface);
+		free(iio_interface);
+		return FAILURE;
+	}
+
+	(*desc)->iio_interface = iio_interface;
+
+	return SUCCESS;
+}
+
+
+/**
+ * @brief Release resources allocated for IIO device
+ * @param desc[in] - IIO device descriptor
+ * @return SUCCESS in case of success, FAILURE otherwise
+ */
+int32_t iio_ad7606_remove(struct iio_ad7606_desc *desc)
+{
+	int32_t status;
+
+	if (!desc) {
+		return FAILURE;
+	}
+
+	status = iio_unregister(desc->iio_interface);
+	if (status < 0) {
+		return FAILURE;
+	}
+
+	status = iio_ad7606_delete_device(desc->iio_interface->iio);
+	if (status < 0) {
+		return FAILURE;
+	}
+
+	free(desc->iio_interface);
+	free(desc);
+
+	return SUCCESS;
+}
+
+
+/*!
+ * @brief	Get scale factor for adc data to voltage conversion for IIO client
+ * @param	chn_range[in] - Current channel voltage range
+ * @param	chn_range_bits[in] - Channel range register bits
+ * @return	scale
+ * @details	This function samples and capture the new data when previous data
+ * 			is transmitted to IIO client
+ */
+static float get_vltg_conv_scale_factor(float chn_range, polarity_e polarity)
+{
+	float scale;
+
+	/* Get the scale factor for voltage conversion from range */
+	if (polarity == UNIPOLAR) {
+		scale = (chn_range / ADC_MAX_COUNT_UNIPOLAR) * 1000;
+	} else {
+		scale = (chn_range / ADC_MAX_COUNT_BIPOLAR) * 1000;
+	}
+
+	return scale;
+}
+
+
+/**
+ * @brief 	Save local variables
+ * @return	none
+ * @details	This function saves the local parameters with updated device values
+ */
+static void save_local_attributes(void)
+{
+	char buf[50];
+	struct iio_ch_info channel;
+
+	for (uint8_t chn = 1; chn <= AD7606X_ADC_CHANNELS; chn++) {
+		channel.ch_num = chn;
+
+		/* Get channel range */
+		(void)get_chn_range(p_ad7606_dev, buf, 0, &channel);
+
+		/* 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]);
+	}
+}
+
+
+/**
+ * @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
+ */
+int32_t ad7606_iio_initialize(void)
+{
+	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 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,
+	};
+
+	/* Initialize AD7606 device and peripheral interface */
+	init_status = ad7606_init(&p_ad7606_dev, &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);
+	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);
+	if (init_status != SUCCESS) {
+		return init_status;
+	}
+
+	/* Initialize the IIO application interface */
+	init_status = iio_app_init(&iio_app_desc, &iio_app_init_par);
+	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);
+	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);
+	if (init_status != SUCCESS) {
+		return init_status;
+	}
+
+	return init_status;
+}
+
+
+/**
+ * @brief 	Run the AD7606 IIO event handler
+ * @return	none
+ * @details	This function monitors the new IIO client event
+ */
+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);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/iio_ad7606.h	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,70 @@
+/***************************************************************************//**
+*   @file   iio_ad7606.h
+*   @brief  Header file of iio_ad7606
+********************************************************************************
+* Copyright (c) 2020 Analog Devices, Inc.
+*
+* All rights reserved.
+* This software is proprietary to Analog Devices, Inc. and its licensors.
+* By using this software you agree to the terms of the associated
+* Analog Devices Software License Agreement.
+*******************************************************************************/
+#ifndef IIO_AD7606_H_
+#define IIO_AD7606_H_
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+
+#include <stdio.h>
+#include <stdbool.h>
+#include "iio.h"
+#include "iio_types.h"
+
+/******************************************************************************/
+/****************************** Macros ****************************************/
+/******************************************************************************/
+
+/******************************************************************************/
+/*************************** Types Declarations *******************************/
+/******************************************************************************/
+
+/**
+ * @struct iio_ad7606_init_param
+ * @brief Device configuration structure.
+ */
+struct iio_ad7606_init_param {
+	/** ad7606 device instance pointer */
+	struct ad7606_dev *ad7606_phy;
+};
+
+/**
+ * @struct iio_ad7606_desc
+ * @brief Structure holding IIO descriptor.
+ */
+struct iio_ad7606_desc {
+	/** iio_interface instance pointer */
+	struct iio_interface *iio_interface;
+};
+
+/******************************************************************************/
+/************************ Functions Declarations ******************************/
+/******************************************************************************/
+
+/* Init AD7606 IIO interface */
+int32_t iio_ad7606_init(struct iio_ad7606_desc **desc,
+			struct iio_ad7606_init_param *init);
+
+/* Free the resources allocated for IIO device */
+int32_t iio_ad7606_remove(struct iio_ad7606_desc *desc);
+
+/* Init the IIO interface */
+int32_t ad7606_iio_initialize(void);
+
+/* Run the IIO event handler */
+void ad7606_iio_event_handler(void);
+
+/* Init the IIO application */
+int32_t ad7606_app_initialize(void);
+
+#endif /* IIO_AD7606_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/iio_ad7606_attr.h	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,510 @@
+/***************************************************************************//**
+*   @file   iio_ad7606_attr.h
+*   @brief  File for AD7606 IIO Attributes
+********************************************************************************
+* Copyright (c) 2020 Analog Devices, Inc.
+*
+* All rights reserved.
+* This software is proprietary to Analog Devices, Inc. and its licensors.
+* By using this software you agree to the terms of the associated
+* Analog Devices Software License Agreement.
+*******************************************************************************/
+#ifndef IIO_AD7606_ATTR_H_
+#define IIO_AD7606_ATTR_H_
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+
+#include <stdio.h>
+#include <stdbool.h>
+
+#include "app_config.h"
+#include "iio.h"
+#include "iio_types.h"
+
+/******************************************************************************/
+/****************************** Macros ****************************************/
+/******************************************************************************/
+
+extern ssize_t get_chn_scale(void *device, char *buf, size_t len,
+			     const struct iio_ch_info *channel);
+extern ssize_t set_chn_scale(void *device, char *buf, size_t len,
+			     const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_range(void *device, char *buf, size_t len,
+			     const struct iio_ch_info *channel);
+extern ssize_t set_chn_range(void *device, char *buf, size_t len,
+			     const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_offset(void *device, char *buf, size_t len,
+			      const struct iio_ch_info *channel);
+extern ssize_t set_chn_offset(void *device, char *buf, size_t len,
+			      const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_phase_offset(void *device, char *buf, size_t len,
+				    const struct iio_ch_info *channel);
+extern ssize_t set_chn_phase_offset(void *device, char *buf, size_t len,
+				    const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_temperature(void *device, char *buf, size_t len,
+				   const struct iio_ch_info *channel);
+extern ssize_t set_chn_temperature(void *device, char *buf, size_t len,
+				   const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_vref(void *device, char *buf, size_t len,
+			    const struct iio_ch_info *channel);
+extern ssize_t set_chn_vref(void *device, char *buf, size_t len,
+			    const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_vdrive(void *device, char *buf, size_t len,
+			      const struct iio_ch_info *channel);
+extern ssize_t set_chn_vdrive(void *device, char *buf, size_t len,
+			      const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_aldo(void *device, char *buf, size_t len,
+			    const struct iio_ch_info *channel);
+extern ssize_t set_chn_aldo(void *device, char *buf, size_t len,
+			    const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_dldo(void *device, char *buf, size_t len,
+			    const struct iio_ch_info *channel);
+extern ssize_t set_chn_dldo(void *device, char *buf, size_t len,
+			    const struct iio_ch_info *channel);
+
+extern ssize_t get_bandwidth(void *device, char *buf, size_t len,
+			     const struct iio_ch_info *channel);
+extern ssize_t set_bandwidth(void *device, char *buf, size_t len,
+			     const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_open_wire_detect_manual(void *device, char *buf,
+		size_t len,
+		const struct iio_ch_info *channel);
+extern ssize_t set_chn_open_wire_detect_manual(void *device, char *buf,
+		size_t len,
+		const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_open_wire_detect_auto(void *device, char *buf,
+		size_t len,
+		const struct iio_ch_info *channel);
+extern ssize_t set_chn_open_wire_detect_auto(void *device, char *buf,
+		size_t len,
+		const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_calibrate_adc_offset(void *device, char *buf, size_t len,
+		const struct iio_ch_info *channel);
+extern ssize_t set_chn_calibrate_adc_offset(void *device, char *buf, size_t len,
+		const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_calibrate_adc_gain(void *device, char *buf, size_t len,
+		const struct iio_ch_info *channel);
+extern ssize_t set_chn_calibrate_adc_gain(void *device, char *buf, size_t len,
+		const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_raw(void *device, char *buf, size_t len,
+			   const struct iio_ch_info *channel);
+extern ssize_t set_chn_raw(void *device, char *buf, size_t len,
+			   const struct iio_ch_info *channel);
+
+extern ssize_t get_operating_mode(void *device, char *buf, size_t len,
+				  const struct iio_ch_info *channel);
+extern ssize_t set_operating_mode(void *device, char *buf, size_t len,
+				  const struct iio_ch_info *channel);
+
+extern ssize_t get_power_down_mode(void *device, char *buf, size_t len,
+				   const struct iio_ch_info *channel);
+extern ssize_t set_power_down_mode(void *device, char *buf, size_t len,
+				   const struct iio_ch_info *channel);
+
+extern ssize_t get_range(void *device, char *buf, size_t len,
+			 const struct iio_ch_info *channel);
+extern ssize_t set_range(void *device, char *buf, size_t len,
+			 const struct iio_ch_info *channel);
+
+extern ssize_t get_oversampling(void *device, char *buf, size_t len,
+				const struct iio_ch_info *channel);
+extern ssize_t set_oversampling(void *device, char *buf, size_t len,
+				const struct iio_ch_info *channel);
+
+extern ssize_t get_direct_reg_access(void *device, char *buf, size_t len,
+				     const struct iio_ch_info *channel);
+extern ssize_t set_direct_reg_access(void *device, char *buf, size_t len,
+				     const struct iio_ch_info *channel);
+
+/******************************************************************************/
+/*************************** Types Declarations *******************************/
+/******************************************************************************/
+
+#if defined(DEV_AD7605_4)
+#define AD7606X_DEVICE_ID	"<device id=\"AD7605-4-phy\" name=\"ID_AD7605-4-phy\" >"
+#elif defined(DEV_AD7606_4)
+#define AD7606X_DEVICE_ID	"<device id=\"AD7606-4-phy\" name=\"AD7606-4-phy\" >"
+#elif defined(DEV_AD7606_6)
+#define AD7606X_DEVICE_ID	"<device id=\"AD7606-6-phy\" name=\"AD7606-6-phy\" >"
+#elif defined(DEV_AD7606_8)
+#define AD7606X_DEVICE_ID	"<device id=\"AD7606-8-phy\" name=\"AD7606-8-phy\" >"
+#elif defined(DEV_AD7606B)
+#define AD7606X_DEVICE_ID	"<device id=\"AD7606B-phy\" name=\"AD7606B-phy\" >"
+#elif defined(DEV_AD7606C_16)
+#define AD7606X_DEVICE_ID	"<device id=\"AD7606C-phy\" name=\"AD7606C-16-phy\" >"
+#elif defined(DEV_AD7606C_18)
+#define AD7606X_DEVICE_ID	"<device id=\"AD7606C-phy\" name=\"AD7606C-18-phy\" >"
+#elif defined(DEV_AD7608)
+#define AD7606X_DEVICE_ID	"<device id=\"AD7608-phy\" name=\"AD7608-phy\" >"
+#elif defined(DEV_AD7609)
+#define AD7606X_DEVICE_ID	"<device id=\"AD7609-phy\" name=\"AD7609-phy\" >"
+#else
+#endif
+
+#define AD7606X_COMMON_ATTRB	"<attribute name=\"raw\" />" \
+								"<attribute name=\"scale\" />"
+
+#if defined(DEV_AD7606B)
+#define AD7606X_CHANNELS_ATTRB	"<attribute name=\"chn_range\" />" \
+								"<attribute name=\"chn_offset\" />" \
+								"<attribute name=\"Temperature\" />" \
+								"<attribute name=\"Vref\" />" \
+								"<attribute name=\"Vdrive\" />" \
+								"<attribute name=\"ALDO\" />" \
+								"<attribute name=\"DLDO\" />" \
+								"<attribute name=\"open_wire_detect_manual\" />" \
+								"<attribute name=\"open_wire_detect_auto\" />" \
+								"<attribute name=\"calibrate_adc_offset\" />" \
+								"<attribute name=\"calibrate_adc_gain\" />"
+#elif defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+#define AD7606X_CHANNELS_ATTRB	"<attribute name=\"chn_range\" />" \
+								"<attribute name=\"chn_offset\" />" \
+								"<attribute name=\"Temperature\" />" \
+								"<attribute name=\"Vref\" />" \
+								"<attribute name=\"Vdrive\" />" \
+								"<attribute name=\"ALDO\" />" \
+								"<attribute name=\"DLDO\" />" \
+								"<attribute name=\"open_wire_detect_manual\" />" \
+								"<attribute name=\"open_wire_detect_auto\" />" \
+								"<attribute name=\"calibrate_adc_offset\" />" \
+								"<attribute name=\"calibrate_adc_gain\" />" \
+								"<attribute name=\"bandwidth\" />"
+#endif
+
+#if defined(DEV_AD7606B) || defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+#define AD7606X_GLOBAL_ATTRB	"<attribute name=\"operating_mode\" />" \
+								"<attribute name=\"oversampling\" />" \
+								"<debug-attribute name =\"direct_reg_access\" />"
+#else
+#define AD7606X_GLOBAL_ATTRB	"<attribute name=\"power_down_mode\" />" \
+								"<attribute name=\"range\" />"
+#endif
+
+
+// XML describes the IIO context hierarchy for AD7606 family devices
+static const char * const ad7606_phy_xml =
+	AD7606X_DEVICE_ID
+	"<channel id=\"voltage1\" type=\"input\" >"
+#if (AD7606X_ADC_RESOLUTION == 18)
+	"<scan-element scale=\"0.1525\" format=\"le:s18/18>>0\" index = \"0\" />"
+#else
+	"<scan-element scale=\"0.1525\" format=\"le:s16/16>>0\" index = \"0\" />"
+#endif
+	AD7606X_COMMON_ATTRB
+	AD7606X_CHANNELS_ATTRB
+	"</channel>"
+	"<channel id=\"voltage2\" type=\"input\" >"
+#if (AD7606X_ADC_RESOLUTION == 18)
+	"<scan-element scale=\"0.1525\" format=\"le:s18/18>>0\" index = \"1\" />"
+#else
+	"<scan-element scale=\"0.1525\" format=\"le:s16/16>>0\" index = \"1\" />"
+#endif
+	AD7606X_COMMON_ATTRB
+	AD7606X_CHANNELS_ATTRB
+	"</channel>"
+	"<channel id=\"voltage3\" type=\"input\" >"
+#if (AD7606X_ADC_RESOLUTION == 18)
+	"<scan-element scale=\"0.1525\" format=\"le:s18/18>>0\" index = \"2\" />"
+#else
+	"<scan-element scale=\"0.1525\" format=\"le:s16/16>>0\" index = \"2\" />"
+#endif
+	AD7606X_COMMON_ATTRB
+	AD7606X_CHANNELS_ATTRB
+	"</channel>"
+	"<channel id=\"voltage4\" type=\"input\" >"
+#if (AD7606X_ADC_RESOLUTION == 18)
+	"<scan-element scale=\"0.1525\" format=\"le:s18/18>>0\" index = \"3\" />"
+#else
+	"<scan-element scale=\"0.1525\" format=\"le:s16/16>>0\" index = \"3\" />"
+#endif
+	AD7606X_COMMON_ATTRB
+	AD7606X_CHANNELS_ATTRB
+	"</channel>"
+#if (AD7606X_ADC_CHANNELS > 4)
+	"<channel id=\"voltage5\" type=\"input\" >"
+#if (AD7606X_ADC_RESOLUTION == 18)
+	"<scan-element scale=\"0.1525\" format=\"le:s18/18>>0\" index = \"4\" />"
+#else
+	"<scan-element scale=\"0.1525\" format=\"le:s16/16>>0\" index = \"4\" />"
+#endif
+	AD7606X_COMMON_ATTRB
+	AD7606X_CHANNELS_ATTRB
+	"</channel>"
+	"<channel id=\"voltage6\" type=\"input\" >"
+#if (AD7606X_ADC_RESOLUTION == 18)
+	"<scan-element scale=\"0.1525\" format=\"le:s18/18>>0\" index = \"5\" />"
+#else
+	"<scan-element scale=\"0.1525\" format=\"le:s16/16>>0\" index = \"5\" />"
+#endif
+	AD7606X_COMMON_ATTRB
+	AD7606X_CHANNELS_ATTRB
+	"</channel>"
+#endif
+#if (AD7606X_ADC_CHANNELS > 6)
+	"<channel id=\"voltage7\" type=\"input\" >"
+#if (AD7606X_ADC_RESOLUTION == 18)
+	"<scan-element scale=\"0.1525\" format=\"le:s18/18>>0\" index = \"6\" />"
+#else
+	"<scan-element scale=\"0.1525\" format=\"le:s16/16>>0\" index = \"6\" />"
+#endif
+	AD7606X_COMMON_ATTRB
+	AD7606X_CHANNELS_ATTRB
+	"</channel>"
+	"<channel id=\"voltage8\" type=\"input\" >"
+#if (AD7606X_ADC_RESOLUTION == 18)
+	"<scan-element scale=\"0.1525\" format=\"le:s18/18>>0\" index = \"7\" />"
+#else
+	"<scan-element scale=\"0.1525\" format=\"le:s16/16>>0\" index = \"7\" />"
+#endif
+	AD7606X_COMMON_ATTRB
+	AD7606X_CHANNELS_ATTRB
+	"</channel>"
+#endif
+	AD7606X_GLOBAL_ATTRB
+	"</device>";
+
+
+/* Channels IIO attribute structures */
+
+static struct iio_attribute iio_attr_chn_scale = {
+	.name = "scale",
+	.show = get_chn_scale,
+	.store = set_chn_scale,
+};
+
+static struct iio_attribute iio_attr_chn_raw = {
+	.name = "raw",
+	.show = get_chn_raw,
+	.store = set_chn_raw,
+};
+
+static struct iio_attribute iio_attr_chn_range = {
+	.name = "chn_range",
+	.show = get_chn_range,
+	.store = set_chn_range,
+};
+
+static struct iio_attribute iio_attr_chn_offset = {
+	.name = "chn_offset",
+	.show = get_chn_offset,
+	.store = set_chn_offset,
+};
+
+static struct iio_attribute iio_attr_chn_phase_offset = {
+	.name = "chn_phase offset",
+	.show = get_chn_phase_offset,
+	.store = set_chn_phase_offset,
+};
+
+static struct iio_attribute iio_attr_chn_temperature = {
+	.name = "Temperature",
+	.show = get_chn_temperature,
+	.store = set_chn_temperature,
+};
+
+static struct iio_attribute iio_attr_chn_vref = {
+	.name = "Vref",
+	.show = get_chn_vref,
+	.store = set_chn_vref,
+};
+
+static struct iio_attribute iio_attr_chn_vdrive = {
+	.name = "Vdrive",
+	.show = get_chn_vdrive,
+	.store = set_chn_vdrive,
+};
+
+static struct iio_attribute iio_attr_chn_aldo = {
+	.name = "ALDO",
+	.show = get_chn_aldo,
+	.store = set_chn_aldo,
+};
+
+static struct iio_attribute iio_attr_chn_dldo = {
+	.name = "DLDO",
+	.show = get_chn_dldo,
+	.store = set_chn_dldo,
+};
+
+static struct iio_attribute iio_attr_bandwidth = {
+	.name = "bandwidth",
+	.show = get_bandwidth,
+	.store = set_bandwidth,
+};
+
+static struct iio_attribute iio_attr_chn_open_wire_detect_manual = {
+	.name = "open_wire_detect_manual",
+	.show = get_chn_open_wire_detect_manual,
+	.store = set_chn_open_wire_detect_manual,
+};
+
+static struct iio_attribute iio_attr_chn_open_wire_detect_auto = {
+	.name = "open_wire_detect_auto",
+	.show = get_chn_open_wire_detect_auto,
+	.store = set_chn_open_wire_detect_auto,
+};
+
+static struct iio_attribute iio_attr_calibrate_adc_offset= {
+	.name = "calibrate_adc_offset",
+	.show = get_chn_calibrate_adc_offset,
+	.store = set_chn_calibrate_adc_offset,
+};
+
+static struct iio_attribute iio_attr_calibrate_adc_gain = {
+	.name = "calibrate_adc_gain",
+	.show = get_chn_calibrate_adc_gain,
+	.store = set_chn_calibrate_adc_gain,
+};
+
+
+struct iio_attribute *channel_input_attributes[] = {
+	&iio_attr_chn_raw,
+	&iio_attr_chn_scale,
+#if defined(DEV_AD7606B) || defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+	&iio_attr_chn_range,
+	&iio_attr_chn_offset,
+	&iio_attr_chn_phase_offset,
+	&iio_attr_chn_temperature,
+	&iio_attr_chn_vref,
+	&iio_attr_chn_vdrive,
+	&iio_attr_chn_aldo,
+	&iio_attr_chn_dldo,
+	&iio_attr_chn_open_wire_detect_manual,
+	&iio_attr_chn_open_wire_detect_auto,
+	&iio_attr_calibrate_adc_offset,
+	&iio_attr_calibrate_adc_gain,
+#if defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+	&iio_attr_bandwidth
+#endif
+#endif
+};
+
+
+/* Device IIO attribute structures */
+
+static struct iio_attribute iio_attr_operating_mode = {
+	.name = "operating_mode",
+	.show = get_operating_mode,
+	.store = set_operating_mode,
+};
+
+static struct iio_attribute iio_attr_power_down_mode = {
+	.name = "power_down_mode",
+	.show = get_power_down_mode,
+	.store = set_power_down_mode,
+};
+
+static struct iio_attribute iio_attr_range = {
+	.name = "range",
+	.show = get_range,
+	.store = set_range,
+};
+
+static struct iio_attribute iio_attr_oversampling = {
+	.name = "oversampling",
+	.show = get_oversampling,
+	.store = set_oversampling,
+};
+
+static struct iio_attribute iio_attr_direct_reg_access = {
+	.name = "direct_reg_access",
+	.show = get_direct_reg_access,
+	.store = set_direct_reg_access,
+};
+
+static struct iio_attribute *global_attributes[] = {
+#if defined(DEV_AD7606B) || defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+	&iio_attr_operating_mode,
+	&iio_attr_oversampling,
+	&iio_attr_direct_reg_access,
+#else
+	&iio_attr_power_down_mode,
+	&iio_attr_range,
+#endif
+};
+
+
+static struct iio_channel iio_channel_ch1_in = {
+	.name = "voltage1",
+	.attributes = channel_input_attributes,
+	.ch_out = false,
+};
+
+static struct iio_channel iio_channel_ch2_in = {
+	.name = "voltage2",
+	.attributes = channel_input_attributes,
+	.ch_out = false,
+};
+
+static struct iio_channel iio_channel_ch3_in = {
+	.name = "voltage3",
+	.attributes = channel_input_attributes,
+	.ch_out = false,
+};
+
+static struct iio_channel iio_channel_ch4_in = {
+	.name = "voltage4",
+	.attributes = channel_input_attributes,
+	.ch_out = false,
+};
+
+static struct iio_channel iio_channel_ch5_in = {
+	.name = "voltage5",
+	.attributes = channel_input_attributes,
+	.ch_out = false,
+};
+
+static struct iio_channel iio_channel_ch6_in = {
+	.name = "voltage6",
+	.attributes = channel_input_attributes,
+	.ch_out = false,
+};
+
+static struct iio_channel iio_channel_ch7_in = {
+	.name = "voltage7",
+	.attributes = channel_input_attributes,
+	.ch_out = false,
+};
+
+static struct iio_channel iio_channel_ch8_in = {
+	.name = "voltage8",
+	.attributes = channel_input_attributes,
+	.ch_out = false,
+};
+
+
+static struct iio_channel *iio_ad7606_channels[] = {
+	&iio_channel_ch1_in,
+	&iio_channel_ch2_in,
+	&iio_channel_ch3_in,
+	&iio_channel_ch4_in,
+#if (AD7606X_ADC_CHANNELS > 4)
+	&iio_channel_ch5_in,
+	&iio_channel_ch6_in,
+#endif
+#if (AD7606X_ADC_CHANNELS > 6)
+	&iio_channel_ch7_in,
+	&iio_channel_ch8_in,
+#endif
+};
+
+/******************************************************************************/
+/************************ Functions Declarations ******************************/
+/******************************************************************************/
+
+#endif /* IIO_AD7606_ATTR_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/iio_transport.c	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,184 @@
+/***************************************************************************//**
+ *   @file   iio_transport.c
+ *   @brief  Implementation of iio transport layer interface for AD7606
+********************************************************************************
+ * Copyright (c) 2020 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
+ * Analog Devices Software License Agreement.
+*******************************************************************************/
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+
+#include "iio_transport.h"
+
+/******************************************************************************/
+/********************** Macros and Constants Definition ***********************/
+/******************************************************************************/
+
+/* Max buffer length to hold IIO client data/command */
+#define IIO_CMD_DATA_BUFF_SIZE	(100)
+
+/******************************************************************************/
+/*************************** Types Declarations *******************************/
+/******************************************************************************/
+
+/* UART descriptor to read/write UART peripheral data */
+static struct uart_desc *uart_desc = NULL;
+
+/* IIO command buffer */
+static volatile char iio_cmd_buffer[IIO_CMD_DATA_BUFF_SIZE];
+
+/* IIO data buffer */
+static volatile char iio_data_buffer[IIO_CMD_DATA_BUFF_SIZE];
+
+/* New IIO command detect flag */
+static volatile bool new_iio_cmd_detected = false;
+
+/* Data buffer index */
+volatile static uint8_t data_buff_indx = 0;
+
+/* Command buffer index */
+volatile static uint8_t cmd_buff_indx = 0;
+
+/******************************************************************************/
+/************************ Functions Declarations ******************************/
+/******************************************************************************/
+
+/******************************************************************************/
+/************************ Functions Definitions *******************************/
+/******************************************************************************/
+
+/**
+ * @brief	IIO Wrapper to initialize the UART peripheral
+ * @param	desc- Pointer UART descriptor structure
+ * @param	param- Pointer to UART init param structure
+ * @return	uart init status (SUCCESS/FAILURE)
+ */
+int32_t iio_uart_init(struct uart_desc **desc, struct uart_init_param *param)
+{
+	if (uart_init(desc, param) == SUCCESS) {
+		/* Save the descriptor for data read/write operation */
+		uart_desc = *desc;
+
+		return SUCCESS;
+	} else {
+		return FAILURE;
+	}
+}
+
+
+/**
+ * @brief	IIO Wrapper to wrire data to UART peripheral
+ * @param	buf- Pointer to buffer containing data
+ * @param	len- Number of bytes to write
+ * @return	bytes len in case of success, 0 otherwise
+ */
+ssize_t iio_uart_write(const char *buf, size_t len)
+{
+	if (uart_write(uart_desc, (uint8_t *)buf, len) == SUCCESS) {
+		return len;
+	} else {
+		return 0;
+	}
+}
+
+
+/**
+ * @brief	IIO Wrapper to read iio data/command from UART peripheral
+ * @param	buf- Pointer to buffer containing data
+ * @param	len- Number of bytes to read
+ * @return	bytes len in case of success, 0 otherwise
+ */
+ssize_t iio_uart_read(char *buf, size_t len)
+{
+	size_t i = 0;
+
+	if (len > 1) {
+		do {
+			/* Wait until new data of expected length is received
+			 * from UART Rx interrupt event */
+		} while (data_buff_indx < len);
+
+		/* Get the data into local buffer (entire data) */
+		while (i < len) {
+			buf[i] = iio_data_buffer[i];
+			i++;
+		}
+		data_buff_indx = 0;
+	} else {
+		/* Get the iio command into local buffer (1 character at a time) */
+		buf[i] = iio_cmd_buffer[cmd_buff_indx];
+
+		/* Reset buffer index after reading whole command */
+		if (iio_cmd_buffer[cmd_buff_indx] == '\n') {
+			cmd_buff_indx = 0;
+		} else {
+			cmd_buff_indx++;
+		}
+	}
+
+	return len;
+}
+
+
+/*!
+ * @brief	Callback function to receive IIO command
+ * @return	None
+ * @details	This function is an UART Rx ISR registered by IIO application
+ *			to invoke upon receipt og new character over UART link.
+ */
+void iio_uart_rx_callback(void)
+{
+	uint8_t rx_char;
+
+	if (uart_read(uart_desc, &rx_char, 1) == SUCCESS) {
+
+		iio_data_buffer[data_buff_indx++] = rx_char;
+
+		if (rx_char == '\n') {
+			/* The iio command is identified with new line character */
+			memcpy(iio_cmd_buffer, iio_data_buffer, data_buff_indx);
+			data_buff_indx = 0;
+			new_iio_cmd_detected = true;
+		}
+	}
+}
+
+
+/*!
+ * @brief	Function to check for newer IIO command
+ * @return	IIO command status (true/false)
+ */
+bool is_new_iio_command_detected(void)
+{
+	if (new_iio_cmd_detected) {
+		new_iio_cmd_detected = false;
+		return true;
+	} else {
+		return false;
+	}
+}
+
+
+/*!
+ * @brief	Function to check for expected IIO command
+ * @param	cmd_str[in] - Expected IIO command string
+ * @param	len[in] - Length of IIO command
+ * @return	IIO command status (true/false)
+ */
+bool check_iio_cmd(const char *cmd_str, uint8_t len)
+{
+	int ret;
+
+	ret = strncmp(cmd_str, iio_cmd_buffer, len);
+	if (ret == 0) {
+		/* String matches, return true */
+		return true;
+	}
+
+	return false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/iio_transport.h	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,56 @@
+/***************************************************************************//**
+ *   @file   iio_transport.h
+ *   @brief  Header file of iio_transport.
+ *   @author
+********************************************************************************
+ * Copyright (c) 2020 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
+ * Analog Devices Software License Agreement.
+*******************************************************************************/
+
+#ifndef IIO_TRANSPORT_H_
+#define IIO_TRANSPORT_H_
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+
+#include "iio.h"
+#include "platform_drivers.h"
+
+/******************************************************************************/
+/********************** Macros and Constants Definition ***********************/
+/******************************************************************************/
+
+/* Baud rate for IIO UART interface */
+#define IIO_UART_BAUD_RATE	(230400U)
+
+/******************************************************************************/
+/*************************** Types Declarations *******************************/
+/******************************************************************************/
+
+/******************************************************************************/
+/************************ Functions Declarations ******************************/
+/******************************************************************************/
+
+/* UART peripheral init wrapper */
+int32_t iio_uart_init(struct uart_desc **desc, struct uart_init_param *param);
+
+/* UART data write wrapper */
+ssize_t iio_uart_write(const char *buf, size_t len);
+
+/* UART data read wrapper */
+ssize_t iio_uart_read(char *buf, size_t len);
+
+/* IIO command detect monitor */
+bool is_new_iio_command_detected(void);
+
+/* Check for specific IIO command */
+bool check_iio_cmd(const char *cmd_str, uint8_t len);
+
+/* IIO UART receive interrupt callback function */
+void iio_uart_rx_callback(void);
+
+#endif /* IIO_TRANSPORT_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/main.c	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,50 @@
+/***************************************************************************//**
+ *   @file    main.c
+ *   @brief   Main module for AD7606 IIO application
+ *   @details This module invokes the AD7606 IIO interfaces
+ *            through forever loop.
+********************************************************************************
+ * Copyright (c) 2020 Analog Devices, Inc.
+ *
+ * All rights reserved.
+ *
+ * This software is proprietary to Analog Devices, Inc. and its licensors.
+ * By using this software you agree to the terms of the associated
+ * Analog Devices Software License Agreement.
+*******************************************************************************/
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+#include <stdio.h>
+#include <stdint.h>
+#include <assert.h>
+
+#include "platform_support.h"
+#include "iio_ad7606.h"
+#include "error.h"
+
+/******************************************************************************/
+/********************** Macros and Constants Definitions **********************/
+/******************************************************************************/
+
+/******************************************************************************/
+/************************ Functions Definitions *******************************/
+/******************************************************************************/
+
+/**
+ * @brief	Main entry point to application
+ * @return	none
+ */
+int main(void)
+{
+	/* Initialize the AD7606 IIO interface */
+	if (ad7606_iio_initialize() == FAILURE) {
+		assert(false);
+	}
+
+	while (1) {
+		/* Monitor the IIO client events */
+		ad7606_iio_event_handler();
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/iio.lib	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,1 @@
+https://os.mbed.com/teams/AnalogDevices/code/iio/
\ No newline at end of file
--- a/main.cpp	Thu Aug 06 19:49:32 2020 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/* Copyright (c) 2019 Analog Devices, Inc.  All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification, 
-are permitted provided that the following conditions are met:
-  - Redistributions of source code must retain the above copyright notice, 
-  this list of conditions and the following disclaimer.
-  - Redistributions in binary form must reproduce the above copyright notice, 
-  this list of conditions and the following disclaimer in the documentation 
-  and/or other materials provided with the distribution.  
-  - Modified versions of the software must be conspicuously marked as such.
-  - This software is licensed solely and exclusively for use with processors/products 
-  manufactured by or for Analog Devices, Inc.
-  - This software may not be combined or merged with other code in any manner 
-  that would cause the software to become subject to terms and conditions which 
-  differ from those listed here.
-  - Neither the name of Analog Devices, Inc. nor the names of its contributors 
-  may be used to endorse or promote products derived from this software without 
-  specific prior written permission.
-  - The use of this software ma     y or may not infringe the patent rights of one or 
-  more patent holders.  This license does not release you from the requirement 
-  that you obtain separate licenses from these patent holders to use this software.
-
-THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS" AND 
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, 
-TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 
-NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES 
-(INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF CLAIMS OF INTELLECTUAL 
-PROPERTY RIGHTS INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-2019-01-10-7CBSD SLA
-
-*/
-
-/***Libraries***/
-#include <stdio.h> /*Standard Library*/
-#include "mbed.h" /*mbed header file*/
-
-/***Defines for UART Protocol***/
-#define BAUD_RATE                   115200                    /*Baud Rate*/
-
-/*Configure and instantiate UART protocol
-  and baud rate*/
-Serial port(USBTX, USBRX, BAUD_RATE);
-
-/***Function Declarations***/
-
-/*Print Information about Program's purpose*/
-static void print_title(void);
-
-/*Print Instructions on how to use Program*/
-static void print_prompt(void);
-
-int main()
-{
-    uint8_t user_command; /*User input variable*/
-    uint8_t connected = 1; /*Initialize SPI*/
-
-    print_title();
-
-    while(connected == 1) {
-        print_prompt();
-        port.scanf("%2d", (int *) &user_command);
-        switch (user_command) {
-            case 1:
-                port.printf("Case 1\n\n");
-                break;
-
-            case 2:
-                port.printf("Case 2\n\n");
-                //menu_item_1_conversion_read(dev);
-                break;
-
-            default:
-                port.printf("   ***Illegal Entry****\n\n");
-                break;
-
-        }
-    }
-    return 0;
-}
-
-/***Function Definitions***/
-
-
-/*Function to print the title block when program first starts.
-  Parameters: None
-  Return Value: None*/
-void print_title()
-{
-  port.printf("\n*****************************************************************\n");
-  port.printf("* EVAL-AD1234 Demonstration Program                             *\n");
-  port.printf("*                                                               *\n");
-  port.printf("* This program demonstrates how to measure strain gauge or      *\n");
-  port.printf("* other form of a Wheatstone bridge sensors with the AD1234     *\n");
-  port.printf("*                                                               *\n");
-  port.printf("*                                                               *\n");
-  port.printf("* Set the baud rate to 115200 and select the newline terminator.*\n");
-  port.printf("*                                                               *\n");
-  port.printf("*****************************************************************\n");
-}
-
-/*Function to Print Command Summary
-  Parameters: None
-  Return Value: None */
-static void print_prompt() {
-    port.printf("Command Summary\n");
-    port.printf("   1 - Select ADC\n");
-    port.printf("   2 - Select Power Mode\n");
-    port.printf("   x - Put More Menu Items Here\n");       
-}
-
-void menu_1_function1()
-{
-    port.printf("In function 1\n");
-}
-
-void menu_2_function2()
-{
-    port.printf("In function 2\n");
-}
-
--- a/mbed-os.lib	Thu Aug 06 19:49:32 2020 +0000
+++ b/mbed-os.lib	Mon Oct 05 13:45:15 2020 +0530
@@ -1,1 +1,1 @@
-https://github.com/ARMmbed/mbed-os/#3a57ec7401a77b8b98f6356a1498cb154229483f
+https://github.com/ARMmbed/mbed-os/#a6207cadad0acd1876f436dc6baeddf46c42af06
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_app.json	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,9 @@
+{
+	"requires": ["bare-metal"],
+    "target_overrides": {
+        "*": {
+            "platform.default-serial-baud-rate": 115200,
+			"target.printf_lib": "std"
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/platform_drivers.lib	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,1 @@
+https://os.mbed.com/teams/AnalogDevices/code/platform_drivers/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tinyiiod.lib	Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,1 @@
+https://os.mbed.com/teams/AnalogDevices/code/Tinyiiod/
\ No newline at end of file