this is testing

Committer:
pmallick
Date:
Thu Jan 14 18:54:16 2021 +0530
Revision:
0:3afcd581558d
this is testing

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pmallick 0:3afcd581558d 1 /***************************************************************************//**
pmallick 0:3afcd581558d 2 * @file ad7606.c
pmallick 0:3afcd581558d 3 * @brief Implementation of ad7606 Driver.
pmallick 0:3afcd581558d 4 * @author Stefan Popa (stefan.popa@analog.com)
pmallick 0:3afcd581558d 5 * @author Darius Berghe (darius.berghe@analog.com)
pmallick 0:3afcd581558d 6 ********************************************************************************
pmallick 0:3afcd581558d 7 * Copyright 2020(c) Analog Devices, Inc.
pmallick 0:3afcd581558d 8 *
pmallick 0:3afcd581558d 9 * All rights reserved.
pmallick 0:3afcd581558d 10 *
pmallick 0:3afcd581558d 11 * Redistribution and use in source and binary forms, with or without
pmallick 0:3afcd581558d 12 * modification, are permitted provided that the following conditions are met:
pmallick 0:3afcd581558d 13 * - Redistributions of source code must retain the above copyright
pmallick 0:3afcd581558d 14 * notice, this list of conditions and the following disclaimer.
pmallick 0:3afcd581558d 15 * - Redistributions in binary form must reproduce the above copyright
pmallick 0:3afcd581558d 16 * notice, this list of conditions and the following disclaimer in
pmallick 0:3afcd581558d 17 * the documentation and/or other materials provided with the
pmallick 0:3afcd581558d 18 * distribution.
pmallick 0:3afcd581558d 19 * - Neither the name of Analog Devices, Inc. nor the names of its
pmallick 0:3afcd581558d 20 * contributors may be used to endorse or promote products derived
pmallick 0:3afcd581558d 21 * from this software without specific prior written permission.
pmallick 0:3afcd581558d 22 * - The use of this software may or may not infringe the patent rights
pmallick 0:3afcd581558d 23 * of one or more patent holders. This license does not release you
pmallick 0:3afcd581558d 24 * from the requirement that you obtain separate licenses from these
pmallick 0:3afcd581558d 25 * patent holders to use this software.
pmallick 0:3afcd581558d 26 * - Use of the software either in source or binary form, must be run
pmallick 0:3afcd581558d 27 * on or directly connected to an Analog Devices Inc. component.
pmallick 0:3afcd581558d 28 *
pmallick 0:3afcd581558d 29 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
pmallick 0:3afcd581558d 30 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
pmallick 0:3afcd581558d 31 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
pmallick 0:3afcd581558d 32 * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
pmallick 0:3afcd581558d 33 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
pmallick 0:3afcd581558d 34 * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
pmallick 0:3afcd581558d 35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
pmallick 0:3afcd581558d 36 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
pmallick 0:3afcd581558d 37 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
pmallick 0:3afcd581558d 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
pmallick 0:3afcd581558d 39 *******************************************************************************/
pmallick 0:3afcd581558d 40
pmallick 0:3afcd581558d 41 /******************************************************************************/
pmallick 0:3afcd581558d 42 /***************************** Include Files **********************************/
pmallick 0:3afcd581558d 43 /******************************************************************************/
pmallick 0:3afcd581558d 44 #include <stdio.h>
pmallick 0:3afcd581558d 45 #include <stdlib.h>
pmallick 0:3afcd581558d 46 #include <stdbool.h>
pmallick 0:3afcd581558d 47 #include <string.h>
pmallick 0:3afcd581558d 48 #include <errno.h>
pmallick 0:3afcd581558d 49 #include "ad7606.h"
pmallick 0:3afcd581558d 50 #include "error.h"
pmallick 0:3afcd581558d 51 #include "util.h"
pmallick 0:3afcd581558d 52 #include "crc.h"
pmallick 0:3afcd581558d 53
pmallick 0:3afcd581558d 54 struct ad7606_chip_info {
pmallick 0:3afcd581558d 55 uint8_t num_channels;
pmallick 0:3afcd581558d 56 uint8_t bits;
pmallick 0:3afcd581558d 57 uint8_t max_dout_lines;
pmallick 0:3afcd581558d 58 bool has_oversampling;
pmallick 0:3afcd581558d 59 bool has_registers;
pmallick 0:3afcd581558d 60 uint8_t device_id;
pmallick 0:3afcd581558d 61 const struct ad7606_range *hw_range_table;
pmallick 0:3afcd581558d 62 uint32_t hw_range_table_sz;
pmallick 0:3afcd581558d 63 const struct ad7606_range *sw_range_table;
pmallick 0:3afcd581558d 64 uint32_t sw_range_table_sz;
pmallick 0:3afcd581558d 65 };
pmallick 0:3afcd581558d 66
pmallick 0:3afcd581558d 67 DECLARE_CRC8_TABLE(ad7606_crc8);
pmallick 0:3afcd581558d 68 DECLARE_CRC16_TABLE(ad7606_crc16);
pmallick 0:3afcd581558d 69
pmallick 0:3afcd581558d 70 static const struct ad7606_range ad7606_range_table[] = {
pmallick 0:3afcd581558d 71 {-5000, 5000, false}, /* RANGE pin LOW */
pmallick 0:3afcd581558d 72 {-10000, 10000, false}, /* RANGE pin HIGH */
pmallick 0:3afcd581558d 73 };
pmallick 0:3afcd581558d 74
pmallick 0:3afcd581558d 75 static const struct ad7606_range ad7609_range_table[] = {
pmallick 0:3afcd581558d 76 {-10000, 10000, true}, /* RANGE pin LOW */
pmallick 0:3afcd581558d 77 {-20000, 20000, true}, /* RANGE pin HIGH */
pmallick 0:3afcd581558d 78 };
pmallick 0:3afcd581558d 79
pmallick 0:3afcd581558d 80 static const struct ad7606_range ad7606b_range_table[] = {
pmallick 0:3afcd581558d 81 {-2500, 2500, false}, /* 0000 */
pmallick 0:3afcd581558d 82 {-5000, 5000, false}, /* 0001 */
pmallick 0:3afcd581558d 83 {-10000, 10000, false}, /* 0010 */
pmallick 0:3afcd581558d 84 {-10000, 10000, false}, /* 0011 */
pmallick 0:3afcd581558d 85 {-10000, 10000, false}, /* 0100 */
pmallick 0:3afcd581558d 86 {-10000, 10000, false}, /* 0101 */
pmallick 0:3afcd581558d 87 {-10000, 10000, false}, /* 0110 */
pmallick 0:3afcd581558d 88 {-10000, 10000, false}, /* 0111 */
pmallick 0:3afcd581558d 89 {-10000, 10000, false}, /* 1000 */
pmallick 0:3afcd581558d 90 {-10000, 10000, false}, /* 1001 */
pmallick 0:3afcd581558d 91 {-10000, 10000, false}, /* 1010 */
pmallick 0:3afcd581558d 92 {-10000, 10000, false}, /* 1011 */
pmallick 0:3afcd581558d 93 };
pmallick 0:3afcd581558d 94
pmallick 0:3afcd581558d 95 static const struct ad7606_range ad7606c_range_table[] = {
pmallick 0:3afcd581558d 96 {-2500, 2500, false}, /* 0000 */
pmallick 0:3afcd581558d 97 {-5000, 5000, false}, /* 0001 */
pmallick 0:3afcd581558d 98 {-6250, 6250, false}, /* 0010 */
pmallick 0:3afcd581558d 99 {-10000, 10000, false}, /* 0011 */
pmallick 0:3afcd581558d 100 {-12500, 12500, false}, /* 0100 */
pmallick 0:3afcd581558d 101 {0, 5000, false}, /* 0101 */
pmallick 0:3afcd581558d 102 {0, 10000, false}, /* 0110 */
pmallick 0:3afcd581558d 103 {0, 12500, false}, /* 0111 */
pmallick 0:3afcd581558d 104 {-5000, 5000, true}, /* 1000 */
pmallick 0:3afcd581558d 105 {-10000, 10000, true}, /* 1001 */
pmallick 0:3afcd581558d 106 {-12500, 12500, true}, /* 1010 */
pmallick 0:3afcd581558d 107 {-20000, 20000, true}, /* 1011 */
pmallick 0:3afcd581558d 108 {-20000, 20000, true}, /* 1100 */
pmallick 0:3afcd581558d 109 {-20000, 20000, true}, /* 1101 */
pmallick 0:3afcd581558d 110 {-20000, 20000, true}, /* 1110 */
pmallick 0:3afcd581558d 111 {-20000, 20000, true}, /* 1111 */
pmallick 0:3afcd581558d 112 };
pmallick 0:3afcd581558d 113
pmallick 0:3afcd581558d 114 static const struct ad7606_chip_info ad7606_chip_info_tbl[] = {
pmallick 0:3afcd581558d 115 [ID_AD7605_4] = {
pmallick 0:3afcd581558d 116 .num_channels = 4,
pmallick 0:3afcd581558d 117 .bits = 16,
pmallick 0:3afcd581558d 118 .max_dout_lines = AD7606_2_DOUT,
pmallick 0:3afcd581558d 119 .has_oversampling = false,
pmallick 0:3afcd581558d 120 .hw_range_table = ad7606_range_table,
pmallick 0:3afcd581558d 121 .hw_range_table_sz = ARRAY_SIZE(ad7606_range_table),
pmallick 0:3afcd581558d 122 },
pmallick 0:3afcd581558d 123 [ID_AD7606_4] = {
pmallick 0:3afcd581558d 124 .num_channels = 4,
pmallick 0:3afcd581558d 125 .bits = 16,
pmallick 0:3afcd581558d 126 .max_dout_lines = AD7606_2_DOUT,
pmallick 0:3afcd581558d 127 .has_oversampling = true,
pmallick 0:3afcd581558d 128 .hw_range_table = ad7606_range_table,
pmallick 0:3afcd581558d 129 .hw_range_table_sz = ARRAY_SIZE(ad7606_range_table),
pmallick 0:3afcd581558d 130 },
pmallick 0:3afcd581558d 131 [ID_AD7606_6] = {
pmallick 0:3afcd581558d 132 .num_channels = 6,
pmallick 0:3afcd581558d 133 .bits = 16,
pmallick 0:3afcd581558d 134 .max_dout_lines = AD7606_2_DOUT,
pmallick 0:3afcd581558d 135 .has_oversampling = true,
pmallick 0:3afcd581558d 136 .hw_range_table = ad7606_range_table,
pmallick 0:3afcd581558d 137 .hw_range_table_sz = ARRAY_SIZE(ad7606_range_table),
pmallick 0:3afcd581558d 138 },
pmallick 0:3afcd581558d 139 [ID_AD7606_8] = {
pmallick 0:3afcd581558d 140 .num_channels = 8,
pmallick 0:3afcd581558d 141 .bits = 16,
pmallick 0:3afcd581558d 142 .max_dout_lines = AD7606_2_DOUT,
pmallick 0:3afcd581558d 143 .has_oversampling = true,
pmallick 0:3afcd581558d 144 .hw_range_table = ad7606_range_table,
pmallick 0:3afcd581558d 145 .hw_range_table_sz = ARRAY_SIZE(ad7606_range_table),
pmallick 0:3afcd581558d 146 },
pmallick 0:3afcd581558d 147 [ID_AD7606B] = {
pmallick 0:3afcd581558d 148 .num_channels = 8,
pmallick 0:3afcd581558d 149 .bits = 16,
pmallick 0:3afcd581558d 150 .max_dout_lines = AD7606_4_DOUT,
pmallick 0:3afcd581558d 151 .has_oversampling = true,
pmallick 0:3afcd581558d 152 .has_registers = true,
pmallick 0:3afcd581558d 153 .device_id = 0x1,
pmallick 0:3afcd581558d 154 .hw_range_table = ad7606_range_table,
pmallick 0:3afcd581558d 155 .hw_range_table_sz = ARRAY_SIZE(ad7606_range_table),
pmallick 0:3afcd581558d 156 .sw_range_table = ad7606b_range_table,
pmallick 0:3afcd581558d 157 .sw_range_table_sz = ARRAY_SIZE(ad7606b_range_table),
pmallick 0:3afcd581558d 158 },
pmallick 0:3afcd581558d 159 [ID_AD7606C_16] = {
pmallick 0:3afcd581558d 160 .num_channels = 8,
pmallick 0:3afcd581558d 161 .bits = 16,
pmallick 0:3afcd581558d 162 .max_dout_lines = AD7606_8_DOUT,
pmallick 0:3afcd581558d 163 .has_oversampling = true,
pmallick 0:3afcd581558d 164 .has_registers = true,
pmallick 0:3afcd581558d 165 .device_id = 0x3,
pmallick 0:3afcd581558d 166 .hw_range_table = ad7606_range_table,
pmallick 0:3afcd581558d 167 .hw_range_table_sz = ARRAY_SIZE(ad7606_range_table),
pmallick 0:3afcd581558d 168 .sw_range_table = ad7606c_range_table,
pmallick 0:3afcd581558d 169 .sw_range_table_sz = ARRAY_SIZE(ad7606c_range_table),
pmallick 0:3afcd581558d 170 },
pmallick 0:3afcd581558d 171 [ID_AD7606C_18] = {
pmallick 0:3afcd581558d 172 .num_channels = 8,
pmallick 0:3afcd581558d 173 .bits = 18,
pmallick 0:3afcd581558d 174 .max_dout_lines = AD7606_8_DOUT,
pmallick 0:3afcd581558d 175 .has_oversampling = true,
pmallick 0:3afcd581558d 176 .has_registers = true,
pmallick 0:3afcd581558d 177 .device_id = 0x3,
pmallick 0:3afcd581558d 178 .hw_range_table = ad7606_range_table,
pmallick 0:3afcd581558d 179 .hw_range_table_sz = ARRAY_SIZE(ad7606_range_table),
pmallick 0:3afcd581558d 180 .sw_range_table = ad7606c_range_table,
pmallick 0:3afcd581558d 181 .sw_range_table_sz = ARRAY_SIZE(ad7606c_range_table),
pmallick 0:3afcd581558d 182 },
pmallick 0:3afcd581558d 183 [ID_AD7608] = {
pmallick 0:3afcd581558d 184 .num_channels = 8,
pmallick 0:3afcd581558d 185 .bits = 18,
pmallick 0:3afcd581558d 186 .max_dout_lines = AD7606_2_DOUT,
pmallick 0:3afcd581558d 187 .has_oversampling = true,
pmallick 0:3afcd581558d 188 .hw_range_table = ad7606_range_table,
pmallick 0:3afcd581558d 189 .hw_range_table_sz = ARRAY_SIZE(ad7606_range_table),
pmallick 0:3afcd581558d 190 },
pmallick 0:3afcd581558d 191 [ID_AD7609] = {
pmallick 0:3afcd581558d 192 .num_channels = 8,
pmallick 0:3afcd581558d 193 .bits = 18,
pmallick 0:3afcd581558d 194 .max_dout_lines = AD7606_2_DOUT,
pmallick 0:3afcd581558d 195 .has_oversampling = true,
pmallick 0:3afcd581558d 196 .hw_range_table = ad7609_range_table,
pmallick 0:3afcd581558d 197 .hw_range_table_sz = ARRAY_SIZE(ad7609_range_table),
pmallick 0:3afcd581558d 198 },
pmallick 0:3afcd581558d 199 };
pmallick 0:3afcd581558d 200
pmallick 0:3afcd581558d 201 static const uint16_t tconv_max[] = {
pmallick 0:3afcd581558d 202 1, /* AD7606_OSR_1 */
pmallick 0:3afcd581558d 203 3, /* AD7606_OSR_2 */
pmallick 0:3afcd581558d 204 5, /* AD7606_OSR_4 */
pmallick 0:3afcd581558d 205 10, /* AD7606_OSR_8 */
pmallick 0:3afcd581558d 206 20, /* AD7606_OSR_16 */
pmallick 0:3afcd581558d 207 41, /* AD7606_OSR_32 */
pmallick 0:3afcd581558d 208 81, /* AD7606_OSR_64 */
pmallick 0:3afcd581558d 209 162, /* AD7606_OSR_128 */
pmallick 0:3afcd581558d 210 324 /* AD7606_OSR_256 */
pmallick 0:3afcd581558d 211 };
pmallick 0:3afcd581558d 212
pmallick 0:3afcd581558d 213
pmallick 0:3afcd581558d 214 /***************************************************************************//**
pmallick 0:3afcd581558d 215 * @brief Read a device register via SPI.
pmallick 0:3afcd581558d 216 *
pmallick 0:3afcd581558d 217 * This function performs CRC8 computation and checking if enabled in the device.
pmallick 0:3afcd581558d 218 *
pmallick 0:3afcd581558d 219 * @param dev - The device structure.
pmallick 0:3afcd581558d 220 * @param reg_addr - Register address in device memory.
pmallick 0:3afcd581558d 221 * @param reg_data - Pointer to the location where to store the register value.
pmallick 0:3afcd581558d 222 *
pmallick 0:3afcd581558d 223 * @return ret - return code.
pmallick 0:3afcd581558d 224 * Example: -EIO - SPI communication error.
pmallick 0:3afcd581558d 225 * -ENOTSUP - Device not in software mode.
pmallick 0:3afcd581558d 226 * -EBADMSG - CRC computation mismatch.
pmallick 0:3afcd581558d 227 * SUCCESS - No errors encountered.
pmallick 0:3afcd581558d 228 *******************************************************************************/
pmallick 0:3afcd581558d 229 int32_t ad7606_spi_reg_read(struct ad7606_dev *dev,
pmallick 0:3afcd581558d 230 uint8_t reg_addr,
pmallick 0:3afcd581558d 231 uint8_t *reg_data)
pmallick 0:3afcd581558d 232 {
pmallick 0:3afcd581558d 233 uint8_t buf[3];
pmallick 0:3afcd581558d 234 uint8_t crc;
pmallick 0:3afcd581558d 235 uint32_t sz = 2;
pmallick 0:3afcd581558d 236 int32_t ret;
pmallick 0:3afcd581558d 237
pmallick 0:3afcd581558d 238 if (!dev->sw_mode)
pmallick 0:3afcd581558d 239 return -ENOTSUP;
pmallick 0:3afcd581558d 240
pmallick 0:3afcd581558d 241 buf[0] = AD7606_RD_FLAG_MSK(reg_addr);
pmallick 0:3afcd581558d 242 buf[1] = 0x00;
pmallick 0:3afcd581558d 243 if (dev->digital_diag_enable.int_crc_err_en) {
pmallick 0:3afcd581558d 244 crc = crc8(ad7606_crc8, buf, 2, 0);
pmallick 0:3afcd581558d 245 buf[2] = crc;
pmallick 0:3afcd581558d 246 sz += 1;
pmallick 0:3afcd581558d 247 }
pmallick 0:3afcd581558d 248 ret = spi_write_and_read(dev->spi_desc, buf, sz);
pmallick 0:3afcd581558d 249 if (ret < 0)
pmallick 0:3afcd581558d 250 return ret;
pmallick 0:3afcd581558d 251
pmallick 0:3afcd581558d 252 dev->reg_mode = true;
pmallick 0:3afcd581558d 253
pmallick 0:3afcd581558d 254 buf[0] = AD7606_RD_FLAG_MSK(reg_addr);
pmallick 0:3afcd581558d 255 buf[1] = 0x00;
pmallick 0:3afcd581558d 256 if (dev->digital_diag_enable.int_crc_err_en) {
pmallick 0:3afcd581558d 257 crc = crc8(ad7606_crc8, buf, 2, 0);
pmallick 0:3afcd581558d 258 buf[2] = crc;
pmallick 0:3afcd581558d 259 }
pmallick 0:3afcd581558d 260 ret = spi_write_and_read(dev->spi_desc, buf, sz);
pmallick 0:3afcd581558d 261 if (ret < 0)
pmallick 0:3afcd581558d 262 return ret;
pmallick 0:3afcd581558d 263
pmallick 0:3afcd581558d 264 if (dev->digital_diag_enable.int_crc_err_en) {
pmallick 0:3afcd581558d 265 crc = crc8(ad7606_crc8, buf, 2, 0);
pmallick 0:3afcd581558d 266 if (crc != buf[2])
pmallick 0:3afcd581558d 267 return -EBADMSG;
pmallick 0:3afcd581558d 268 }
pmallick 0:3afcd581558d 269
pmallick 0:3afcd581558d 270 if (reg_data)
pmallick 0:3afcd581558d 271 *reg_data = buf[1];
pmallick 0:3afcd581558d 272
pmallick 0:3afcd581558d 273 return ret;
pmallick 0:3afcd581558d 274 }
pmallick 0:3afcd581558d 275
pmallick 0:3afcd581558d 276 /***************************************************************************//**
pmallick 0:3afcd581558d 277 * @brief Write a device register via SPI.
pmallick 0:3afcd581558d 278 *
pmallick 0:3afcd581558d 279 * This function performs CRC8 computation and checking if enabled in the device.
pmallick 0:3afcd581558d 280 *
pmallick 0:3afcd581558d 281 * @param dev - The device structure.
pmallick 0:3afcd581558d 282 * @param reg_addr - Register address in device memory.
pmallick 0:3afcd581558d 283 * @param reg_data - Value to write to register.
pmallick 0:3afcd581558d 284 *
pmallick 0:3afcd581558d 285 * @return ret - return code.
pmallick 0:3afcd581558d 286 * Example: -EIO - SPI communication error.
pmallick 0:3afcd581558d 287 * -ENOTSUP - Device not in software mode.
pmallick 0:3afcd581558d 288 * -EBADMSG - CRC computation mismatch.
pmallick 0:3afcd581558d 289 * SUCCESS - No errors encountered.
pmallick 0:3afcd581558d 290 *******************************************************************************/
pmallick 0:3afcd581558d 291 int32_t ad7606_spi_reg_write(struct ad7606_dev *dev,
pmallick 0:3afcd581558d 292 uint8_t reg_addr,
pmallick 0:3afcd581558d 293 uint8_t reg_data)
pmallick 0:3afcd581558d 294 {
pmallick 0:3afcd581558d 295 uint8_t buf[3];
pmallick 0:3afcd581558d 296 int32_t ret;
pmallick 0:3afcd581558d 297 uint8_t crc;
pmallick 0:3afcd581558d 298 uint32_t sz = 2;
pmallick 0:3afcd581558d 299
pmallick 0:3afcd581558d 300 if (!dev->sw_mode)
pmallick 0:3afcd581558d 301 return -ENOTSUP;
pmallick 0:3afcd581558d 302
pmallick 0:3afcd581558d 303 /* Dummy read to place the chip in register mode. */
pmallick 0:3afcd581558d 304 if (!dev->reg_mode) {
pmallick 0:3afcd581558d 305 ret = ad7606_spi_reg_read(dev, reg_addr, NULL);
pmallick 0:3afcd581558d 306 if (ret < 0)
pmallick 0:3afcd581558d 307 return ret;
pmallick 0:3afcd581558d 308 }
pmallick 0:3afcd581558d 309
pmallick 0:3afcd581558d 310 buf[0] = AD7606_WR_FLAG_MSK(reg_addr);
pmallick 0:3afcd581558d 311 buf[1] = reg_data;
pmallick 0:3afcd581558d 312 if (dev->digital_diag_enable.int_crc_err_en) {
pmallick 0:3afcd581558d 313 crc = crc8(ad7606_crc8, buf, 2, 0);
pmallick 0:3afcd581558d 314 buf[2] = crc;
pmallick 0:3afcd581558d 315 sz += 1;
pmallick 0:3afcd581558d 316 }
pmallick 0:3afcd581558d 317
pmallick 0:3afcd581558d 318 ret = spi_write_and_read(dev->spi_desc, buf, sz);
pmallick 0:3afcd581558d 319 if (ret < 0)
pmallick 0:3afcd581558d 320 return ret;
pmallick 0:3afcd581558d 321
pmallick 0:3afcd581558d 322 return ret;
pmallick 0:3afcd581558d 323 }
pmallick 0:3afcd581558d 324
pmallick 0:3afcd581558d 325 /***************************************************************************//**
pmallick 0:3afcd581558d 326 * @brief Write a device register via SPI with masking.
pmallick 0:3afcd581558d 327 *
pmallick 0:3afcd581558d 328 * @param dev - The device structure.
pmallick 0:3afcd581558d 329 * @param addr - Register address in device memory.
pmallick 0:3afcd581558d 330 * @param mask - Only bits set to 1 in mask will be modified.
pmallick 0:3afcd581558d 331 * @param val - Value to write to register.
pmallick 0:3afcd581558d 332 *
pmallick 0:3afcd581558d 333 * @return ret - return code.
pmallick 0:3afcd581558d 334 * Example: -EIO - SPI communication error.
pmallick 0:3afcd581558d 335 * -ENOTSUP - Device not in software mode.
pmallick 0:3afcd581558d 336 * -EBADMSG - CRC computation mismatch.
pmallick 0:3afcd581558d 337 * SUCCESS - No errors encountered.
pmallick 0:3afcd581558d 338 *******************************************************************************/
pmallick 0:3afcd581558d 339 int32_t ad7606_spi_write_mask(struct ad7606_dev *dev,
pmallick 0:3afcd581558d 340 uint32_t addr,
pmallick 0:3afcd581558d 341 uint32_t mask,
pmallick 0:3afcd581558d 342 uint32_t val)
pmallick 0:3afcd581558d 343 {
pmallick 0:3afcd581558d 344 uint8_t reg_data;
pmallick 0:3afcd581558d 345 int ret;
pmallick 0:3afcd581558d 346
pmallick 0:3afcd581558d 347 ret = ad7606_spi_reg_read(dev, addr, &reg_data);
pmallick 0:3afcd581558d 348 if (ret < 0)
pmallick 0:3afcd581558d 349 return ret;
pmallick 0:3afcd581558d 350
pmallick 0:3afcd581558d 351 reg_data &= ~mask;
pmallick 0:3afcd581558d 352 reg_data |= val;
pmallick 0:3afcd581558d 353
pmallick 0:3afcd581558d 354 return ad7606_spi_reg_write(dev, addr, reg_data);
pmallick 0:3afcd581558d 355 }
pmallick 0:3afcd581558d 356
pmallick 0:3afcd581558d 357 /* Internal function to copy the content of a buffer in 18-bit chunks to a 32-bit buffer by
pmallick 0:3afcd581558d 358 * extending the chunks to 32-bit size. */
pmallick 0:3afcd581558d 359 static int32_t cpy18b32b(uint8_t *psrc, uint32_t srcsz, uint32_t *pdst)
pmallick 0:3afcd581558d 360 {
pmallick 0:3afcd581558d 361 unsigned int i, j;
pmallick 0:3afcd581558d 362
pmallick 0:3afcd581558d 363 if (srcsz % 9)
pmallick 0:3afcd581558d 364 return -EINVAL;
pmallick 0:3afcd581558d 365
pmallick 0:3afcd581558d 366 for(i = 0; i < srcsz; i += 9) {
pmallick 0:3afcd581558d 367 j = 4 * (i / 9);
pmallick 0:3afcd581558d 368 pdst[j+0] = ((uint32_t)(psrc[i+0] & 0xff) << 10) | ((uint32_t)psrc[i+1] << 2)
pmallick 0:3afcd581558d 369 | ((uint32_t)psrc[i+2] >> 6);
pmallick 0:3afcd581558d 370 pdst[j+1] = ((uint32_t)(psrc[i+2] & 0x3f) << 12) | ((uint32_t)psrc[i+3] << 4)
pmallick 0:3afcd581558d 371 | ((uint32_t)psrc[i+4] >> 4);
pmallick 0:3afcd581558d 372 pdst[j+2] = ((uint32_t)(psrc[i+4] & 0x0f) << 14) | ((uint32_t)psrc[i+5] << 6)
pmallick 0:3afcd581558d 373 | ((uint32_t)psrc[i+6] >> 2);
pmallick 0:3afcd581558d 374 pdst[j+3] = ((uint32_t)(psrc[i+6] & 0x03) << 16) | ((uint32_t)psrc[i+7] << 8)
pmallick 0:3afcd581558d 375 | ((uint32_t)psrc[i+8] >> 0);
pmallick 0:3afcd581558d 376 }
pmallick 0:3afcd581558d 377 return SUCCESS;
pmallick 0:3afcd581558d 378 }
pmallick 0:3afcd581558d 379
pmallick 0:3afcd581558d 380 /* Internal function to copy the content of a buffer in 26-bit chunks to a 32-bit buffer by
pmallick 0:3afcd581558d 381 * extending the chunks to 32-bit size. */
pmallick 0:3afcd581558d 382 static int32_t cpy26b32b(uint8_t *psrc, uint32_t srcsz, uint32_t *pdst)
pmallick 0:3afcd581558d 383 {
pmallick 0:3afcd581558d 384 unsigned int i, j;
pmallick 0:3afcd581558d 385
pmallick 0:3afcd581558d 386 if (srcsz % 13)
pmallick 0:3afcd581558d 387 return -EINVAL;
pmallick 0:3afcd581558d 388
pmallick 0:3afcd581558d 389 for(i = 0; i < srcsz; i += 13) {
pmallick 0:3afcd581558d 390 j = 4 * (i / 13);
pmallick 0:3afcd581558d 391 pdst[j+0] = ((uint32_t)(psrc[i+0] & 0xff) << 18) | ((uint32_t)psrc[i+1] << 10)
pmallick 0:3afcd581558d 392 | ((uint32_t)psrc[i+2] << 2) | ((uint32_t)psrc[i+3] >> 6);
pmallick 0:3afcd581558d 393 pdst[j+1] = ((uint32_t)(psrc[i+3] & 0x3f) << 20) | ((uint32_t)psrc[i+4] << 12)
pmallick 0:3afcd581558d 394 | ((uint32_t)psrc[i+5] << 4) | ((uint32_t)psrc[i+6] >> 4);
pmallick 0:3afcd581558d 395 pdst[j+2] = ((uint32_t)(psrc[i+6] & 0x0f) << 22) | ((uint32_t)psrc[i+7] << 14)
pmallick 0:3afcd581558d 396 | ((uint32_t)psrc[i+8] << 6) | ((uint32_t)psrc[i+9] >> 2);
pmallick 0:3afcd581558d 397 pdst[j+3] = ((uint32_t)(psrc[i+9] & 0x03) << 24) | ((uint32_t)psrc[i+10] << 16)
pmallick 0:3afcd581558d 398 | ((uint32_t)psrc[i+11] << 8) | ((uint32_t)psrc[i+12] >> 0);
pmallick 0:3afcd581558d 399 }
pmallick 0:3afcd581558d 400 return SUCCESS;
pmallick 0:3afcd581558d 401 }
pmallick 0:3afcd581558d 402
pmallick 0:3afcd581558d 403 /***************************************************************************//**
pmallick 0:3afcd581558d 404 * @brief Toggle the CONVST pin to start a conversion.
pmallick 0:3afcd581558d 405 *
pmallick 0:3afcd581558d 406 * If needed, this function also puts the device in ADC reading mode by a write
pmallick 0:3afcd581558d 407 * at address zero.
pmallick 0:3afcd581558d 408 *
pmallick 0:3afcd581558d 409 * @param dev - The device structure.
pmallick 0:3afcd581558d 410 *
pmallick 0:3afcd581558d 411 * @return ret - return code.
pmallick 0:3afcd581558d 412 * Example: -EIO - SPI communication error.
pmallick 0:3afcd581558d 413 * -EIO - CONVST GPIO not available.
pmallick 0:3afcd581558d 414 * SUCCESS - No errors encountered.
pmallick 0:3afcd581558d 415 *******************************************************************************/
pmallick 0:3afcd581558d 416 int32_t ad7606_convst(struct ad7606_dev *dev)
pmallick 0:3afcd581558d 417 {
pmallick 0:3afcd581558d 418 int32_t ret;
pmallick 0:3afcd581558d 419
pmallick 0:3afcd581558d 420 if (dev->reg_mode) {
pmallick 0:3afcd581558d 421 /* Enter ADC reading mode by writing at address zero. */
pmallick 0:3afcd581558d 422 ret = ad7606_spi_reg_write(dev, 0, 0);
pmallick 0:3afcd581558d 423 if (ret < 0)
pmallick 0:3afcd581558d 424 return ret;
pmallick 0:3afcd581558d 425
pmallick 0:3afcd581558d 426 dev->reg_mode = false;
pmallick 0:3afcd581558d 427 }
pmallick 0:3afcd581558d 428
pmallick 0:3afcd581558d 429 ret = gpio_set_value(dev->gpio_convst, 0);
pmallick 0:3afcd581558d 430 if (ret < 0)
pmallick 0:3afcd581558d 431 return ret;
pmallick 0:3afcd581558d 432
pmallick 0:3afcd581558d 433 /* wait LP_CNV time */
pmallick 0:3afcd581558d 434 udelay(1);
pmallick 0:3afcd581558d 435
pmallick 0:3afcd581558d 436 return gpio_set_value(dev->gpio_convst, 1);
pmallick 0:3afcd581558d 437 }
pmallick 0:3afcd581558d 438
pmallick 0:3afcd581558d 439 /***************************************************************************//**
pmallick 0:3afcd581558d 440 * @brief Read conversion data.
pmallick 0:3afcd581558d 441 *
pmallick 0:3afcd581558d 442 * This function performs CRC16 computation and checking if enabled in the device.
pmallick 0:3afcd581558d 443 * If the status is enabled in device settings, each sample of data will contain
pmallick 0:3afcd581558d 444 * status information in the lowest 8 bits.
pmallick 0:3afcd581558d 445 *
pmallick 0:3afcd581558d 446 * The output buffer provided by the user should be as wide as to be able to
pmallick 0:3afcd581558d 447 * contain 1 sample from each channel since this function reads conversion data
pmallick 0:3afcd581558d 448 * across all channels.
pmallick 0:3afcd581558d 449 *
pmallick 0:3afcd581558d 450 * @param dev - The device structure.
pmallick 0:3afcd581558d 451 * @param data - Pointer to location of buffer where to store the data.
pmallick 0:3afcd581558d 452 *
pmallick 0:3afcd581558d 453 * @return ret - return code.
pmallick 0:3afcd581558d 454 * Example: -EIO - SPI communication error.
pmallick 0:3afcd581558d 455 * -EBADMSG - CRC computation mismatch.
pmallick 0:3afcd581558d 456 * -ENOTSUP - Device bits per sample not supported.
pmallick 0:3afcd581558d 457 * SUCCESS - No errors encountered.
pmallick 0:3afcd581558d 458 *******************************************************************************/
pmallick 0:3afcd581558d 459 int32_t ad7606_spi_data_read(struct ad7606_dev *dev, uint32_t *data)
pmallick 0:3afcd581558d 460 {
pmallick 0:3afcd581558d 461 uint32_t sz;
pmallick 0:3afcd581558d 462 int32_t ret, i;
pmallick 0:3afcd581558d 463 uint16_t crc, icrc;
pmallick 0:3afcd581558d 464 uint8_t bits = ad7606_chip_info_tbl[dev->device_id].bits;
pmallick 0:3afcd581558d 465 uint8_t sbits = dev->config.status_header ? 8 : 0;
pmallick 0:3afcd581558d 466 uint8_t nchannels = ad7606_chip_info_tbl[dev->device_id].num_channels;
pmallick 0:3afcd581558d 467
pmallick 0:3afcd581558d 468 sz = nchannels * (bits + sbits);
pmallick 0:3afcd581558d 469
pmallick 0:3afcd581558d 470 /* Number of bits to read, corresponds to SCLK cycles in transfer.
pmallick 0:3afcd581558d 471 * This should always be a multiple of 8 to work with most SPI's.
pmallick 0:3afcd581558d 472 * With this chip family this holds true because we either:
pmallick 0:3afcd581558d 473 * - multiply 8 channels * bits per sample
pmallick 0:3afcd581558d 474 * - multiply 4 channels * bits per sample (always multiple of 2)
pmallick 0:3afcd581558d 475 * Therefore, due to design reasons, we don't check for the
pmallick 0:3afcd581558d 476 * remainder of this division because it is zero by design.
pmallick 0:3afcd581558d 477 */
pmallick 0:3afcd581558d 478 sz /= 8;
pmallick 0:3afcd581558d 479
pmallick 0:3afcd581558d 480 if (dev->digital_diag_enable.int_crc_err_en) {
pmallick 0:3afcd581558d 481 sz += 2;
pmallick 0:3afcd581558d 482 }
pmallick 0:3afcd581558d 483
pmallick 0:3afcd581558d 484 memset(dev->data, 0, sz);
pmallick 0:3afcd581558d 485 ret = spi_write_and_read(dev->spi_desc, dev->data, sz);
pmallick 0:3afcd581558d 486 if (ret < 0)
pmallick 0:3afcd581558d 487 return ret;
pmallick 0:3afcd581558d 488
pmallick 0:3afcd581558d 489 if (dev->digital_diag_enable.int_crc_err_en) {
pmallick 0:3afcd581558d 490 sz -= 2;
pmallick 0:3afcd581558d 491 crc = crc16(ad7606_crc16, dev->data, sz, 0);
pmallick 0:3afcd581558d 492 icrc = ((uint16_t)dev->data[sz] << 8) |
pmallick 0:3afcd581558d 493 dev->data[sz+1];
pmallick 0:3afcd581558d 494 if (icrc != crc)
pmallick 0:3afcd581558d 495 return -EBADMSG;
pmallick 0:3afcd581558d 496 }
pmallick 0:3afcd581558d 497
pmallick 0:3afcd581558d 498 switch(bits) {
pmallick 0:3afcd581558d 499 case 18:
pmallick 0:3afcd581558d 500 if (dev->config.status_header)
pmallick 0:3afcd581558d 501 ret = cpy26b32b(dev->data, sz, data);
pmallick 0:3afcd581558d 502 else
pmallick 0:3afcd581558d 503 ret = cpy18b32b(dev->data, sz, data);
pmallick 0:3afcd581558d 504 if (ret < 0)
pmallick 0:3afcd581558d 505 return ret;
pmallick 0:3afcd581558d 506 break;
pmallick 0:3afcd581558d 507 case 16:
pmallick 0:3afcd581558d 508 for(i = 0; i < nchannels; i++) {
pmallick 0:3afcd581558d 509 if (dev->config.status_header) {
pmallick 0:3afcd581558d 510 data[i] = (uint32_t)dev->data[i*3] << 16;
pmallick 0:3afcd581558d 511 data[i] |= (uint32_t)dev->data[i*3+1] << 8;
pmallick 0:3afcd581558d 512 data[i] |= (uint32_t)dev->data[i*3+2];
pmallick 0:3afcd581558d 513 } else {
pmallick 0:3afcd581558d 514 data[i] = (uint32_t)dev->data[i*2] << 8;
pmallick 0:3afcd581558d 515 data[i] |= (uint32_t)dev->data[i*2+1];
pmallick 0:3afcd581558d 516 }
pmallick 0:3afcd581558d 517 }
pmallick 0:3afcd581558d 518 break;
pmallick 0:3afcd581558d 519 default:
pmallick 0:3afcd581558d 520 ret = -ENOTSUP;
pmallick 0:3afcd581558d 521 break;
pmallick 0:3afcd581558d 522 };
pmallick 0:3afcd581558d 523
pmallick 0:3afcd581558d 524 return ret;
pmallick 0:3afcd581558d 525 }
pmallick 0:3afcd581558d 526
pmallick 0:3afcd581558d 527 /***************************************************************************//**
pmallick 0:3afcd581558d 528 * @brief Blocking conversion start and data read.
pmallick 0:3afcd581558d 529 *
pmallick 0:3afcd581558d 530 * This function performs a conversion start and then proceeds to reading
pmallick 0:3afcd581558d 531 * the conversion data.
pmallick 0:3afcd581558d 532 *
pmallick 0:3afcd581558d 533 * @param dev - The device structure.
pmallick 0:3afcd581558d 534 * @param data - Pointer to location of buffer where to store the data.
pmallick 0:3afcd581558d 535 *
pmallick 0:3afcd581558d 536 * @return ret - return code.
pmallick 0:3afcd581558d 537 * Example: -EIO - SPI communication error.
pmallick 0:3afcd581558d 538 * -ETIME - Timeout while waiting for the BUSY signal.
pmallick 0:3afcd581558d 539 * -EBADMSG - CRC computation mismatch.
pmallick 0:3afcd581558d 540 * SUCCESS - No errors encountered.
pmallick 0:3afcd581558d 541 *******************************************************************************/
pmallick 0:3afcd581558d 542 int32_t ad7606_read(struct ad7606_dev *dev, uint32_t * data)
pmallick 0:3afcd581558d 543 {
pmallick 0:3afcd581558d 544 int32_t ret;
pmallick 0:3afcd581558d 545 uint8_t busy;
pmallick 0:3afcd581558d 546 uint32_t timeout = tconv_max[AD7606_OSR_256];
pmallick 0:3afcd581558d 547
pmallick 0:3afcd581558d 548 ret = ad7606_convst(dev);
pmallick 0:3afcd581558d 549 if (ret < 0)
pmallick 0:3afcd581558d 550 return ret;
pmallick 0:3afcd581558d 551
pmallick 0:3afcd581558d 552 if (dev->gpio_busy) {
pmallick 0:3afcd581558d 553 /* Wait for BUSY falling edge */
pmallick 0:3afcd581558d 554 while(timeout) {
pmallick 0:3afcd581558d 555 ret = gpio_get_value(dev->gpio_busy, &busy);
pmallick 0:3afcd581558d 556 if (ret < 0)
pmallick 0:3afcd581558d 557 return ret;
pmallick 0:3afcd581558d 558
pmallick 0:3afcd581558d 559 if (busy == 0)
pmallick 0:3afcd581558d 560 break;
pmallick 0:3afcd581558d 561
pmallick 0:3afcd581558d 562 udelay(1);
pmallick 0:3afcd581558d 563 timeout--;
pmallick 0:3afcd581558d 564 }
pmallick 0:3afcd581558d 565
pmallick 0:3afcd581558d 566 if (timeout == 0)
pmallick 0:3afcd581558d 567 return -ETIME;
pmallick 0:3afcd581558d 568 } else {
pmallick 0:3afcd581558d 569 /* wait CONV time */
pmallick 0:3afcd581558d 570 udelay(tconv_max[dev->oversampling.os_ratio]);
pmallick 0:3afcd581558d 571 }
pmallick 0:3afcd581558d 572
pmallick 0:3afcd581558d 573 return ad7606_spi_data_read(dev, data);
pmallick 0:3afcd581558d 574 }
pmallick 0:3afcd581558d 575
pmallick 0:3afcd581558d 576 /* Internal function to reset device settings to default state after chip reset. */
pmallick 0:3afcd581558d 577 static inline void ad7606_reset_settings(struct ad7606_dev *dev)
pmallick 0:3afcd581558d 578 {
pmallick 0:3afcd581558d 579 int i;
pmallick 0:3afcd581558d 580 const struct ad7606_range *rt = dev->sw_mode ?
pmallick 0:3afcd581558d 581 ad7606_chip_info_tbl[dev->device_id].sw_range_table:
pmallick 0:3afcd581558d 582 ad7606_chip_info_tbl[dev->device_id].hw_range_table;
pmallick 0:3afcd581558d 583
pmallick 0:3afcd581558d 584 for(i = 0; i < dev->num_channels; i++) {
pmallick 0:3afcd581558d 585 if (dev->sw_mode)
pmallick 0:3afcd581558d 586 dev->range_ch[i] = rt[3];
pmallick 0:3afcd581558d 587 else
pmallick 0:3afcd581558d 588 dev->range_ch[i] = rt[0];
pmallick 0:3afcd581558d 589
pmallick 0:3afcd581558d 590 dev->offset_ch[i] = 0;
pmallick 0:3afcd581558d 591 dev->phase_ch[i] = 0;
pmallick 0:3afcd581558d 592 dev->gain_ch[i] = 0;
pmallick 0:3afcd581558d 593 }
pmallick 0:3afcd581558d 594
pmallick 0:3afcd581558d 595 dev->oversampling.os_ratio = AD7606_OSR_1;
pmallick 0:3afcd581558d 596 dev->oversampling.os_pad = 0;
pmallick 0:3afcd581558d 597 dev->config.op_mode = AD7606_NORMAL;
pmallick 0:3afcd581558d 598 dev->config.dout_format = AD7606_2_DOUT;
pmallick 0:3afcd581558d 599 dev->config.ext_os_clock = false;
pmallick 0:3afcd581558d 600 dev->config.status_header = false;
pmallick 0:3afcd581558d 601 dev->digital_diag_enable.rom_crc_err_en = true;
pmallick 0:3afcd581558d 602 dev->digital_diag_enable.mm_crc_err_en = false;
pmallick 0:3afcd581558d 603 dev->digital_diag_enable.int_crc_err_en = false;
pmallick 0:3afcd581558d 604 dev->digital_diag_enable.spi_write_err_en = false;
pmallick 0:3afcd581558d 605 dev->digital_diag_enable.spi_read_err_en = false;
pmallick 0:3afcd581558d 606 dev->digital_diag_enable.busy_stuck_high_err_en = false;
pmallick 0:3afcd581558d 607 dev->digital_diag_enable.clk_fs_os_counter_en = false;
pmallick 0:3afcd581558d 608 dev->digital_diag_enable.interface_check_en = false;
pmallick 0:3afcd581558d 609 dev->reg_mode = false;
pmallick 0:3afcd581558d 610 }
pmallick 0:3afcd581558d 611
pmallick 0:3afcd581558d 612 /***************************************************************************//**
pmallick 0:3afcd581558d 613 * @brief Reset the device by toggling the reset GPIO.
pmallick 0:3afcd581558d 614 *
pmallick 0:3afcd581558d 615 * @param dev - The device structure.
pmallick 0:3afcd581558d 616 *
pmallick 0:3afcd581558d 617 * @return ret - return code.
pmallick 0:3afcd581558d 618 * Example: -EIO - Reset GPIO not available.
pmallick 0:3afcd581558d 619 * SUCCESS - No errors encountered.
pmallick 0:3afcd581558d 620 *******************************************************************************/
pmallick 0:3afcd581558d 621 int32_t ad7606_reset(struct ad7606_dev *dev)
pmallick 0:3afcd581558d 622 {
pmallick 0:3afcd581558d 623 int32_t ret;
pmallick 0:3afcd581558d 624
pmallick 0:3afcd581558d 625 ret = gpio_set_value(dev->gpio_reset, 1);
pmallick 0:3afcd581558d 626 if (ret < 0)
pmallick 0:3afcd581558d 627 return ret;
pmallick 0:3afcd581558d 628
pmallick 0:3afcd581558d 629 udelay(3);
pmallick 0:3afcd581558d 630
pmallick 0:3afcd581558d 631 ret = gpio_set_value(dev->gpio_reset, 0);
pmallick 0:3afcd581558d 632 if (ret < 0)
pmallick 0:3afcd581558d 633 return ret;
pmallick 0:3afcd581558d 634
pmallick 0:3afcd581558d 635 ad7606_reset_settings(dev);
pmallick 0:3afcd581558d 636
pmallick 0:3afcd581558d 637 return ret;
pmallick 0:3afcd581558d 638 }
pmallick 0:3afcd581558d 639
pmallick 0:3afcd581558d 640 /* Internal function that initializes GPIOs. */
pmallick 0:3afcd581558d 641 static int32_t ad7606_request_gpios(struct ad7606_dev *dev,
pmallick 0:3afcd581558d 642 struct ad7606_init_param *init_param)
pmallick 0:3afcd581558d 643 {
pmallick 0:3afcd581558d 644 int32_t ret;
pmallick 0:3afcd581558d 645
pmallick 0:3afcd581558d 646 ret = gpio_get_optional(&dev->gpio_reset, init_param->gpio_reset);
pmallick 0:3afcd581558d 647 if (ret < 0)
pmallick 0:3afcd581558d 648 return ret;
pmallick 0:3afcd581558d 649
pmallick 0:3afcd581558d 650 if (dev->gpio_reset) {
pmallick 0:3afcd581558d 651 ret = gpio_direction_output(dev->gpio_reset, GPIO_LOW);
pmallick 0:3afcd581558d 652 if (ret < 0)
pmallick 0:3afcd581558d 653 return ret;
pmallick 0:3afcd581558d 654 }
pmallick 0:3afcd581558d 655
pmallick 0:3afcd581558d 656 ret = gpio_get_optional(&dev->gpio_convst, init_param->gpio_convst);
pmallick 0:3afcd581558d 657 if (ret < 0)
pmallick 0:3afcd581558d 658 return ret;
pmallick 0:3afcd581558d 659
pmallick 0:3afcd581558d 660 if (dev->gpio_convst) {
pmallick 0:3afcd581558d 661 ret = gpio_direction_output(dev->gpio_convst, GPIO_LOW);
pmallick 0:3afcd581558d 662 if (ret < 0)
pmallick 0:3afcd581558d 663 return ret;
pmallick 0:3afcd581558d 664 }
pmallick 0:3afcd581558d 665
pmallick 0:3afcd581558d 666 ret = gpio_get_optional(&dev->gpio_busy, init_param->gpio_busy);
pmallick 0:3afcd581558d 667 if (ret < 0)
pmallick 0:3afcd581558d 668 return ret;
pmallick 0:3afcd581558d 669
pmallick 0:3afcd581558d 670 if (dev->gpio_busy) {
pmallick 0:3afcd581558d 671 ret = gpio_direction_input(dev->gpio_busy);
pmallick 0:3afcd581558d 672 if (ret < 0)
pmallick 0:3afcd581558d 673 return ret;
pmallick 0:3afcd581558d 674 }
pmallick 0:3afcd581558d 675
pmallick 0:3afcd581558d 676 ret = gpio_get_optional(&dev->gpio_stby_n, init_param->gpio_stby_n);
pmallick 0:3afcd581558d 677 if (ret < 0)
pmallick 0:3afcd581558d 678 return ret;
pmallick 0:3afcd581558d 679
pmallick 0:3afcd581558d 680 if (dev->gpio_stby_n) {
pmallick 0:3afcd581558d 681 ret = gpio_direction_output(dev->gpio_stby_n, GPIO_HIGH);
pmallick 0:3afcd581558d 682 if (ret < 0)
pmallick 0:3afcd581558d 683 return ret;
pmallick 0:3afcd581558d 684 }
pmallick 0:3afcd581558d 685
pmallick 0:3afcd581558d 686 ret = gpio_get_optional(&dev->gpio_range, init_param->gpio_range);
pmallick 0:3afcd581558d 687 if (ret < 0)
pmallick 0:3afcd581558d 688 return ret;
pmallick 0:3afcd581558d 689
pmallick 0:3afcd581558d 690 if (dev->gpio_range) {
pmallick 0:3afcd581558d 691 ret = gpio_direction_output(dev->gpio_range, GPIO_LOW);
pmallick 0:3afcd581558d 692 if (ret < 0)
pmallick 0:3afcd581558d 693 return ret;
pmallick 0:3afcd581558d 694 }
pmallick 0:3afcd581558d 695
pmallick 0:3afcd581558d 696 if (!ad7606_chip_info_tbl[dev->device_id].has_oversampling)
pmallick 0:3afcd581558d 697 return ret;
pmallick 0:3afcd581558d 698
pmallick 0:3afcd581558d 699 ret = gpio_get_optional(&dev->gpio_os0, init_param->gpio_os0);
pmallick 0:3afcd581558d 700 if (ret < 0)
pmallick 0:3afcd581558d 701 return ret;
pmallick 0:3afcd581558d 702
pmallick 0:3afcd581558d 703 if (dev->gpio_os0) {
pmallick 0:3afcd581558d 704 ret = gpio_direction_output(dev->gpio_os0, GPIO_LOW);
pmallick 0:3afcd581558d 705 if (ret < 0)
pmallick 0:3afcd581558d 706 return ret;
pmallick 0:3afcd581558d 707 }
pmallick 0:3afcd581558d 708
pmallick 0:3afcd581558d 709 ret = gpio_get_optional(&dev->gpio_os1, init_param->gpio_os1);
pmallick 0:3afcd581558d 710 if (ret < 0)
pmallick 0:3afcd581558d 711 return ret;
pmallick 0:3afcd581558d 712
pmallick 0:3afcd581558d 713 if (dev->gpio_os1) {
pmallick 0:3afcd581558d 714 ret = gpio_direction_output(dev->gpio_os1, GPIO_LOW);
pmallick 0:3afcd581558d 715 if (ret < 0)
pmallick 0:3afcd581558d 716 return ret;
pmallick 0:3afcd581558d 717 }
pmallick 0:3afcd581558d 718
pmallick 0:3afcd581558d 719 ret = gpio_get_optional(&dev->gpio_os2, init_param->gpio_os2);
pmallick 0:3afcd581558d 720 if (ret < 0)
pmallick 0:3afcd581558d 721 return ret;
pmallick 0:3afcd581558d 722
pmallick 0:3afcd581558d 723 if (dev->gpio_os2) {
pmallick 0:3afcd581558d 724 ret = gpio_direction_output(dev->gpio_os2, GPIO_LOW);
pmallick 0:3afcd581558d 725 if (ret < 0)
pmallick 0:3afcd581558d 726 return ret;
pmallick 0:3afcd581558d 727 }
pmallick 0:3afcd581558d 728
pmallick 0:3afcd581558d 729 ret = gpio_get_optional(&dev->gpio_par_ser, init_param->gpio_par_ser);
pmallick 0:3afcd581558d 730 if (ret < 0)
pmallick 0:3afcd581558d 731 return ret;
pmallick 0:3afcd581558d 732
pmallick 0:3afcd581558d 733 if (dev->gpio_par_ser) {
pmallick 0:3afcd581558d 734 /* Driver currently supports only serial interface, therefore,
pmallick 0:3afcd581558d 735 * if available, pull the GPIO HIGH. */
pmallick 0:3afcd581558d 736 ret = gpio_direction_output(dev->gpio_par_ser, GPIO_HIGH);
pmallick 0:3afcd581558d 737 if (ret < 0)
pmallick 0:3afcd581558d 738 return ret;
pmallick 0:3afcd581558d 739 }
pmallick 0:3afcd581558d 740
pmallick 0:3afcd581558d 741 return ret;
pmallick 0:3afcd581558d 742 }
pmallick 0:3afcd581558d 743
pmallick 0:3afcd581558d 744 /***************************************************************************//**
pmallick 0:3afcd581558d 745 * @brief Set the oversampling ratio.
pmallick 0:3afcd581558d 746 *
pmallick 0:3afcd581558d 747 * In hardware mode, it silently sets AD7606_OSR_64 if higher oversampling
pmallick 0:3afcd581558d 748 * is provided.
pmallick 0:3afcd581558d 749 *
pmallick 0:3afcd581558d 750 * @param dev - The device structure.
pmallick 0:3afcd581558d 751 * @param oversampling - Oversampling settings.
pmallick 0:3afcd581558d 752 *
pmallick 0:3afcd581558d 753 * @return ret - return code.
pmallick 0:3afcd581558d 754 * Example: -EIO - SPI communication error.
pmallick 0:3afcd581558d 755 * -EBADMSG - CRC computation mismatch.
pmallick 0:3afcd581558d 756 * SUCCESS - No errors encountered.
pmallick 0:3afcd581558d 757 *******************************************************************************/
pmallick 0:3afcd581558d 758 int32_t ad7606_set_oversampling(struct ad7606_dev *dev,
pmallick 0:3afcd581558d 759 struct ad7606_oversampling oversampling)
pmallick 0:3afcd581558d 760 {
pmallick 0:3afcd581558d 761 int32_t ret;
pmallick 0:3afcd581558d 762 uint8_t val;
pmallick 0:3afcd581558d 763
pmallick 0:3afcd581558d 764 if (dev->sw_mode) {
pmallick 0:3afcd581558d 765 val = field_prep(AD7606_OS_RATIO_MSK, oversampling.os_ratio);
pmallick 0:3afcd581558d 766 val |= field_prep(AD7606_OS_PAD_MSK, oversampling.os_pad);
pmallick 0:3afcd581558d 767 ret = ad7606_spi_reg_write(dev, AD7606_REG_OVERSAMPLING, val);
pmallick 0:3afcd581558d 768 if (ret < 0)
pmallick 0:3afcd581558d 769 return ret;
pmallick 0:3afcd581558d 770 } else {
pmallick 0:3afcd581558d 771 /* In hardware mode, OSR 128 and 256 are not avaialable */
pmallick 0:3afcd581558d 772 if (oversampling.os_ratio > AD7606_OSR_64)
pmallick 0:3afcd581558d 773 oversampling.os_ratio = AD7606_OSR_64;
pmallick 0:3afcd581558d 774
pmallick 0:3afcd581558d 775 ret = gpio_set_value(dev->gpio_os0, ((oversampling.os_ratio & 0x01) >> 0));
pmallick 0:3afcd581558d 776 if (ret < 0)
pmallick 0:3afcd581558d 777 return ret;
pmallick 0:3afcd581558d 778
pmallick 0:3afcd581558d 779 ret = gpio_set_value(dev->gpio_os1, ((oversampling.os_ratio & 0x02) >> 1));
pmallick 0:3afcd581558d 780 if (ret < 0)
pmallick 0:3afcd581558d 781 return ret;
pmallick 0:3afcd581558d 782
pmallick 0:3afcd581558d 783 ret = gpio_set_value(dev->gpio_os2, ((oversampling.os_ratio & 0x04) >> 2));
pmallick 0:3afcd581558d 784 if (ret < 0)
pmallick 0:3afcd581558d 785 return ret;
pmallick 0:3afcd581558d 786 }
pmallick 0:3afcd581558d 787
pmallick 0:3afcd581558d 788 dev->oversampling = oversampling;
pmallick 0:3afcd581558d 789
pmallick 0:3afcd581558d 790 return SUCCESS;
pmallick 0:3afcd581558d 791 }
pmallick 0:3afcd581558d 792
pmallick 0:3afcd581558d 793 /* Internal function to find the index of a given operation range in the
pmallick 0:3afcd581558d 794 * operation range table specific to a device. */
pmallick 0:3afcd581558d 795 static int8_t ad7606_find_range(struct ad7606_dev *dev,
pmallick 0:3afcd581558d 796 struct ad7606_range range)
pmallick 0:3afcd581558d 797 {
pmallick 0:3afcd581558d 798 uint8_t i;
pmallick 0:3afcd581558d 799 int8_t v = -1;
pmallick 0:3afcd581558d 800 const struct ad7606_range *rt = dev->sw_mode ?
pmallick 0:3afcd581558d 801 ad7606_chip_info_tbl[dev->device_id].sw_range_table:
pmallick 0:3afcd581558d 802 ad7606_chip_info_tbl[dev->device_id].hw_range_table;
pmallick 0:3afcd581558d 803
pmallick 0:3afcd581558d 804 uint32_t rtsz = dev->sw_mode ?
pmallick 0:3afcd581558d 805 ad7606_chip_info_tbl[dev->device_id].sw_range_table_sz:
pmallick 0:3afcd581558d 806 ad7606_chip_info_tbl[dev->device_id].hw_range_table_sz;
pmallick 0:3afcd581558d 807
pmallick 0:3afcd581558d 808 for (i = 0; i < rtsz; i++) {
pmallick 0:3afcd581558d 809 if (range.min != rt[i].min)
pmallick 0:3afcd581558d 810 continue;
pmallick 0:3afcd581558d 811 if (range.max != rt[i].max)
pmallick 0:3afcd581558d 812 continue;
pmallick 0:3afcd581558d 813 if (range.differential != rt[i].differential)
pmallick 0:3afcd581558d 814 continue;
pmallick 0:3afcd581558d 815 v = i;
pmallick 0:3afcd581558d 816 break;
pmallick 0:3afcd581558d 817 }
pmallick 0:3afcd581558d 818
pmallick 0:3afcd581558d 819 return v;
pmallick 0:3afcd581558d 820 }
pmallick 0:3afcd581558d 821
pmallick 0:3afcd581558d 822 /***************************************************************************//**
pmallick 0:3afcd581558d 823 * @brief Set the channel operation range.
pmallick 0:3afcd581558d 824 *
pmallick 0:3afcd581558d 825 * @param dev - The device structure.
pmallick 0:3afcd581558d 826 * @param ch - Channel number (0-7).
pmallick 0:3afcd581558d 827 * @param range - Operation range.
pmallick 0:3afcd581558d 828 *
pmallick 0:3afcd581558d 829 * @return ret - return code.
pmallick 0:3afcd581558d 830 * Example: -EIO - SPI communication error.
pmallick 0:3afcd581558d 831 * -EINVAL - Invalid input.
pmallick 0:3afcd581558d 832 * -EBADMSG - CRC computation mismatch.
pmallick 0:3afcd581558d 833 * SUCCESS - No errors encountered.
pmallick 0:3afcd581558d 834 *******************************************************************************/
pmallick 0:3afcd581558d 835 int32_t ad7606_set_ch_range(struct ad7606_dev *dev, uint8_t ch,
pmallick 0:3afcd581558d 836 struct ad7606_range range)
pmallick 0:3afcd581558d 837 {
pmallick 0:3afcd581558d 838 int value;
pmallick 0:3afcd581558d 839 int32_t ret;
pmallick 0:3afcd581558d 840
pmallick 0:3afcd581558d 841 if (range.min > range.max)
pmallick 0:3afcd581558d 842 return -EINVAL;
pmallick 0:3afcd581558d 843
pmallick 0:3afcd581558d 844 if (ch >= dev->num_channels)
pmallick 0:3afcd581558d 845 return -EINVAL;
pmallick 0:3afcd581558d 846
pmallick 0:3afcd581558d 847 value = ad7606_find_range(dev, range);
pmallick 0:3afcd581558d 848 if (value < 0)
pmallick 0:3afcd581558d 849 return -EINVAL;
pmallick 0:3afcd581558d 850
pmallick 0:3afcd581558d 851 if (dev->sw_mode)
pmallick 0:3afcd581558d 852 ret = ad7606_spi_write_mask(dev, AD7606_REG_RANGE_CH_ADDR(ch),
pmallick 0:3afcd581558d 853 AD7606_RANGE_CH_MSK(ch),
pmallick 0:3afcd581558d 854 AD7606_RANGE_CH_MODE(ch, value));
pmallick 0:3afcd581558d 855 else
pmallick 0:3afcd581558d 856 ret = gpio_set_value(dev->gpio_range, value);
pmallick 0:3afcd581558d 857
pmallick 0:3afcd581558d 858 if (ret)
pmallick 0:3afcd581558d 859 return ret;
pmallick 0:3afcd581558d 860
pmallick 0:3afcd581558d 861 dev->range_ch[ch] = range;
pmallick 0:3afcd581558d 862
pmallick 0:3afcd581558d 863 return ret;
pmallick 0:3afcd581558d 864 }
pmallick 0:3afcd581558d 865
pmallick 0:3afcd581558d 866 /***************************************************************************//**
pmallick 0:3afcd581558d 867 * @brief Set the channel offset.
pmallick 0:3afcd581558d 868 *
pmallick 0:3afcd581558d 869 * The offset parameter is a signed 8-bit integer ranging from -128 to 127 to
pmallick 0:3afcd581558d 870 * make it intuitive and user-friendly.
pmallick 0:3afcd581558d 871 *
pmallick 0:3afcd581558d 872 * This offset gets converted to the register representation where 0x80 is
pmallick 0:3afcd581558d 873 * calibration offset 0, 0x0 is calibration offset -128 and 0xFF is calibration
pmallick 0:3afcd581558d 874 * offset 127, etc.
pmallick 0:3afcd581558d 875 *
pmallick 0:3afcd581558d 876 * @param dev - The device structure.
pmallick 0:3afcd581558d 877 * @param ch - Channel number (0-7).
pmallick 0:3afcd581558d 878 * @param offset - Offset calibration amount (-128...127).
pmallick 0:3afcd581558d 879 *
pmallick 0:3afcd581558d 880 * @return ret - return code.
pmallick 0:3afcd581558d 881 * Example: -EIO - SPI communication error.
pmallick 0:3afcd581558d 882 * -EINVAL - Invalid input.
pmallick 0:3afcd581558d 883 * -ENOTSUP - Device not in software mode.
pmallick 0:3afcd581558d 884 * -EBADMSG - CRC computation mismatch.
pmallick 0:3afcd581558d 885 * SUCCESS - No errors encountered.
pmallick 0:3afcd581558d 886 *******************************************************************************/
pmallick 0:3afcd581558d 887 int32_t ad7606_set_ch_offset(struct ad7606_dev *dev, uint8_t ch,
pmallick 0:3afcd581558d 888 int8_t offset)
pmallick 0:3afcd581558d 889 {
pmallick 0:3afcd581558d 890 int ret;
pmallick 0:3afcd581558d 891 uint8_t value = (uint8_t)(offset - 0x80);
pmallick 0:3afcd581558d 892
pmallick 0:3afcd581558d 893 if (ch >= dev->num_channels)
pmallick 0:3afcd581558d 894 return -EINVAL;
pmallick 0:3afcd581558d 895
pmallick 0:3afcd581558d 896 if (!dev->sw_mode)
pmallick 0:3afcd581558d 897 return -ENOTSUP;
pmallick 0:3afcd581558d 898
pmallick 0:3afcd581558d 899 ret = ad7606_spi_reg_write(dev, AD7606_REG_OFFSET_CH(ch), value);
pmallick 0:3afcd581558d 900 if (ret < 0)
pmallick 0:3afcd581558d 901 return ret;
pmallick 0:3afcd581558d 902
pmallick 0:3afcd581558d 903 dev->offset_ch[ch] = offset;
pmallick 0:3afcd581558d 904
pmallick 0:3afcd581558d 905 return ret;
pmallick 0:3afcd581558d 906 }
pmallick 0:3afcd581558d 907
pmallick 0:3afcd581558d 908 /***************************************************************************//**
pmallick 0:3afcd581558d 909 * @brief Set the channel phase.
pmallick 0:3afcd581558d 910 *
pmallick 0:3afcd581558d 911 * @param dev - The device structure.
pmallick 0:3afcd581558d 912 * @param ch - Channel number (0-7).
pmallick 0:3afcd581558d 913 * @param phase - Phase calibration amount.
pmallick 0:3afcd581558d 914 *
pmallick 0:3afcd581558d 915 * @return ret - return code.
pmallick 0:3afcd581558d 916 * Example: -EIO - SPI communication error.
pmallick 0:3afcd581558d 917 * -EINVAL - Invalid input.
pmallick 0:3afcd581558d 918 * -ENOTSUP - Device not in software mode.
pmallick 0:3afcd581558d 919 * -EBADMSG - CRC computation mismatch.
pmallick 0:3afcd581558d 920 * SUCCESS - No errors encountered.
pmallick 0:3afcd581558d 921 *******************************************************************************/
pmallick 0:3afcd581558d 922 int32_t ad7606_set_ch_phase(struct ad7606_dev *dev, uint8_t ch,
pmallick 0:3afcd581558d 923 uint8_t phase)
pmallick 0:3afcd581558d 924 {
pmallick 0:3afcd581558d 925 int ret;
pmallick 0:3afcd581558d 926
pmallick 0:3afcd581558d 927 if (ch >= dev->num_channels)
pmallick 0:3afcd581558d 928 return -EINVAL;
pmallick 0:3afcd581558d 929
pmallick 0:3afcd581558d 930 if (!dev->sw_mode)
pmallick 0:3afcd581558d 931 return -ENOTSUP;
pmallick 0:3afcd581558d 932
pmallick 0:3afcd581558d 933 ret = ad7606_spi_reg_write(dev, AD7606_REG_PHASE_CH(ch), phase);
pmallick 0:3afcd581558d 934 if (ret < 0)
pmallick 0:3afcd581558d 935 return ret;
pmallick 0:3afcd581558d 936
pmallick 0:3afcd581558d 937 dev->phase_ch[ch] = phase;
pmallick 0:3afcd581558d 938
pmallick 0:3afcd581558d 939 return ret;
pmallick 0:3afcd581558d 940 }
pmallick 0:3afcd581558d 941
pmallick 0:3afcd581558d 942 /***************************************************************************//**
pmallick 0:3afcd581558d 943 * @brief Set the channel gain.
pmallick 0:3afcd581558d 944 *
pmallick 0:3afcd581558d 945 * @param dev - The device structure.
pmallick 0:3afcd581558d 946 * @param ch - Channel number (0-7).
pmallick 0:3afcd581558d 947 * @param gain - Gain calibration amount.
pmallick 0:3afcd581558d 948 *
pmallick 0:3afcd581558d 949 * @return ret - return code.
pmallick 0:3afcd581558d 950 * Example: -EIO - SPI communication error.
pmallick 0:3afcd581558d 951 * -EINVAL - Invalid input.
pmallick 0:3afcd581558d 952 * -ENOTSUP - Device not in software mode.
pmallick 0:3afcd581558d 953 * -EBADMSG - CRC computation mismatch.
pmallick 0:3afcd581558d 954 * SUCCESS - No errors encountered.
pmallick 0:3afcd581558d 955 *******************************************************************************/
pmallick 0:3afcd581558d 956 int32_t ad7606_set_ch_gain(struct ad7606_dev *dev, uint8_t ch,
pmallick 0:3afcd581558d 957 uint8_t gain)
pmallick 0:3afcd581558d 958 {
pmallick 0:3afcd581558d 959 int ret;
pmallick 0:3afcd581558d 960
pmallick 0:3afcd581558d 961 if (ch >= dev->num_channels)
pmallick 0:3afcd581558d 962 return -EINVAL;
pmallick 0:3afcd581558d 963
pmallick 0:3afcd581558d 964 if (!dev->sw_mode)
pmallick 0:3afcd581558d 965 return -ENOTSUP;
pmallick 0:3afcd581558d 966
pmallick 0:3afcd581558d 967 gain = field_get(AD7606_GAIN_MSK, gain);
pmallick 0:3afcd581558d 968 ret = ad7606_spi_reg_write(dev, AD7606_REG_GAIN_CH(ch), gain);
pmallick 0:3afcd581558d 969 if (ret < 0)
pmallick 0:3afcd581558d 970 return ret;
pmallick 0:3afcd581558d 971
pmallick 0:3afcd581558d 972 dev->gain_ch[ch] = gain;
pmallick 0:3afcd581558d 973
pmallick 0:3afcd581558d 974 return ret;
pmallick 0:3afcd581558d 975 }
pmallick 0:3afcd581558d 976
pmallick 0:3afcd581558d 977 /***************************************************************************//**
pmallick 0:3afcd581558d 978 * @brief Set the device config register.
pmallick 0:3afcd581558d 979 *
pmallick 0:3afcd581558d 980 * Configuration structure affects the CONFIG register of the device.
pmallick 0:3afcd581558d 981 *
pmallick 0:3afcd581558d 982 * @param dev - The device structure.
pmallick 0:3afcd581558d 983 * @param config - Configuration structure.
pmallick 0:3afcd581558d 984 *
pmallick 0:3afcd581558d 985 * @return ret - return code.
pmallick 0:3afcd581558d 986 * Example: -EIO - SPI communication error.
pmallick 0:3afcd581558d 987 * -EIO - GPIO not available.
pmallick 0:3afcd581558d 988 * -EINVAL - Invalid input.
pmallick 0:3afcd581558d 989 * -EBADMSG - CRC computation mismatch.
pmallick 0:3afcd581558d 990 * SUCCESS - No errors encountered.
pmallick 0:3afcd581558d 991 *******************************************************************************/
pmallick 0:3afcd581558d 992 int32_t ad7606_set_config(struct ad7606_dev *dev,
pmallick 0:3afcd581558d 993 struct ad7606_config config)
pmallick 0:3afcd581558d 994 {
pmallick 0:3afcd581558d 995 int32_t ret;
pmallick 0:3afcd581558d 996 uint8_t val = 0;
pmallick 0:3afcd581558d 997 uint8_t range_pin, stby_n_pin;
pmallick 0:3afcd581558d 998
pmallick 0:3afcd581558d 999 if (dev->sw_mode) {
pmallick 0:3afcd581558d 1000
pmallick 0:3afcd581558d 1001 val |= field_prep(AD7606_CONFIG_OPERATION_MODE_MSK, config.op_mode);
pmallick 0:3afcd581558d 1002 /* This driver currently supports only normal SPI with 1 DOUT line.
pmallick 0:3afcd581558d 1003 * TODO: remove this check when implementing multi-line DOUT. */
pmallick 0:3afcd581558d 1004 if ((uint8_t)config.dout_format > AD7606_1_DOUT)
pmallick 0:3afcd581558d 1005 return -EINVAL;
pmallick 0:3afcd581558d 1006 if ((uint8_t)config.dout_format > (uint8_t)dev->max_dout_lines)
pmallick 0:3afcd581558d 1007 return -EINVAL;
pmallick 0:3afcd581558d 1008 val |= field_prep(AD7606_CONFIG_DOUT_FORMAT_MSK, config.dout_format);
pmallick 0:3afcd581558d 1009 val |= field_prep(AD7606_CONFIG_EXT_OS_CLOCK_MSK, config.ext_os_clock);
pmallick 0:3afcd581558d 1010 val |= field_prep(AD7606_CONFIG_STATUS_HEADER_MSK, config.status_header);
pmallick 0:3afcd581558d 1011
pmallick 0:3afcd581558d 1012 ret = ad7606_spi_reg_write(dev, AD7606_REG_CONFIG, val);
pmallick 0:3afcd581558d 1013 if (ret)
pmallick 0:3afcd581558d 1014 return ret;
pmallick 0:3afcd581558d 1015 } else {
pmallick 0:3afcd581558d 1016 switch(config.op_mode) {
pmallick 0:3afcd581558d 1017 case AD7606_NORMAL:
pmallick 0:3afcd581558d 1018 range_pin = GPIO_LOW;
pmallick 0:3afcd581558d 1019 stby_n_pin = GPIO_HIGH;
pmallick 0:3afcd581558d 1020 break;
pmallick 0:3afcd581558d 1021 case AD7606_STANDBY:
pmallick 0:3afcd581558d 1022 range_pin = GPIO_LOW;
pmallick 0:3afcd581558d 1023 stby_n_pin = GPIO_LOW;
pmallick 0:3afcd581558d 1024 break;
pmallick 0:3afcd581558d 1025 case AD7606_SHUTDOWN:
pmallick 0:3afcd581558d 1026 range_pin = GPIO_HIGH;
pmallick 0:3afcd581558d 1027 stby_n_pin = GPIO_LOW;
pmallick 0:3afcd581558d 1028 break;
pmallick 0:3afcd581558d 1029 default:
pmallick 0:3afcd581558d 1030 return -EINVAL;
pmallick 0:3afcd581558d 1031 };
pmallick 0:3afcd581558d 1032
pmallick 0:3afcd581558d 1033 ret = gpio_set_value(dev->gpio_stby_n, stby_n_pin);
pmallick 0:3afcd581558d 1034 if (ret)
pmallick 0:3afcd581558d 1035 return ret;
pmallick 0:3afcd581558d 1036
pmallick 0:3afcd581558d 1037 ret = gpio_set_value(dev->gpio_range, range_pin);
pmallick 0:3afcd581558d 1038 if (ret)
pmallick 0:3afcd581558d 1039 return ret;
pmallick 0:3afcd581558d 1040 }
pmallick 0:3afcd581558d 1041
pmallick 0:3afcd581558d 1042 dev->config = config;
pmallick 0:3afcd581558d 1043
pmallick 0:3afcd581558d 1044 return ret;
pmallick 0:3afcd581558d 1045 }
pmallick 0:3afcd581558d 1046
pmallick 0:3afcd581558d 1047 /***************************************************************************//**
pmallick 0:3afcd581558d 1048 * @brief Set the device digital diagnostics configuration.
pmallick 0:3afcd581558d 1049 *
pmallick 0:3afcd581558d 1050 * Digital diagnostics structure affects the DIGITAL_DIAG register of the device.
pmallick 0:3afcd581558d 1051 *
pmallick 0:3afcd581558d 1052 * @param dev - The device structure.
pmallick 0:3afcd581558d 1053 * @param diag - Configuration structure.
pmallick 0:3afcd581558d 1054 *
pmallick 0:3afcd581558d 1055 * @return ret - return code.
pmallick 0:3afcd581558d 1056 * Example: -EIO - SPI communication error.
pmallick 0:3afcd581558d 1057 * -ENOTSUP - Device not in software mode.
pmallick 0:3afcd581558d 1058 * -EBADMSG - CRC computation mismatch.
pmallick 0:3afcd581558d 1059 * SUCCESS - No errors encountered.
pmallick 0:3afcd581558d 1060 *******************************************************************************/
pmallick 0:3afcd581558d 1061 int32_t ad7606_set_digital_diag(struct ad7606_dev *dev,
pmallick 0:3afcd581558d 1062 struct ad7606_digital_diag diag)
pmallick 0:3afcd581558d 1063 {
pmallick 0:3afcd581558d 1064 int32_t ret;
pmallick 0:3afcd581558d 1065 uint8_t val = 0;
pmallick 0:3afcd581558d 1066
pmallick 0:3afcd581558d 1067 if (!dev->sw_mode)
pmallick 0:3afcd581558d 1068 return -ENOTSUP;
pmallick 0:3afcd581558d 1069
pmallick 0:3afcd581558d 1070 val |= field_prep(AD7606_ROM_CRC_ERR_EN_MSK, diag.rom_crc_err_en);
pmallick 0:3afcd581558d 1071 val |= field_prep(AD7606_MM_CRC_ERR_EN_MSK, diag.mm_crc_err_en);
pmallick 0:3afcd581558d 1072 val |= field_prep(AD7606_INT_CRC_ERR_EN_MSK, diag.int_crc_err_en);
pmallick 0:3afcd581558d 1073 val |= field_prep(AD7606_SPI_WRITE_ERR_EN_MSK, diag.spi_write_err_en);
pmallick 0:3afcd581558d 1074 val |= field_prep(AD7606_SPI_READ_ERR_EN_MSK, diag.spi_read_err_en);
pmallick 0:3afcd581558d 1075 val |= field_prep(AD7606_BUSY_STUCK_HIGH_ERR_EN_MSK,
pmallick 0:3afcd581558d 1076 diag.busy_stuck_high_err_en);
pmallick 0:3afcd581558d 1077 val |= field_prep(AD7606_CLK_FS_OS_COUNTER_EN_MSK, diag.clk_fs_os_counter_en);
pmallick 0:3afcd581558d 1078 val |= field_prep(AD7606_INTERFACE_CHECK_EN_MSK, diag.interface_check_en);
pmallick 0:3afcd581558d 1079
pmallick 0:3afcd581558d 1080 ret = ad7606_spi_reg_write(dev, AD7606_REG_DIGITAL_DIAG_ENABLE, val);
pmallick 0:3afcd581558d 1081 if (ret < 0)
pmallick 0:3afcd581558d 1082 return ret;
pmallick 0:3afcd581558d 1083
pmallick 0:3afcd581558d 1084 dev->digital_diag_enable = diag;
pmallick 0:3afcd581558d 1085
pmallick 0:3afcd581558d 1086 return ret;
pmallick 0:3afcd581558d 1087 }
pmallick 0:3afcd581558d 1088
pmallick 0:3afcd581558d 1089 /***************************************************************************//**
pmallick 0:3afcd581558d 1090 * @brief Initialize the ad7606 device structure.
pmallick 0:3afcd581558d 1091 *
pmallick 0:3afcd581558d 1092 * Performs memory allocation of the device structure.
pmallick 0:3afcd581558d 1093 *
pmallick 0:3afcd581558d 1094 * @param device - Pointer to location of device structure to write.
pmallick 0:3afcd581558d 1095 * @param init_param - Pointer to configuration of the driver.
pmallick 0:3afcd581558d 1096 *
pmallick 0:3afcd581558d 1097 * @return ret - return code.
pmallick 0:3afcd581558d 1098 * Example: -ENOMEM - Memory allocation error.
pmallick 0:3afcd581558d 1099 * -EIO - SPI communication error.
pmallick 0:3afcd581558d 1100 * -EIO - GPIO initialization error.
pmallick 0:3afcd581558d 1101 * -ENODEV - Unexpected device id.
pmallick 0:3afcd581558d 1102 * -EBADMSG - CRC computation mismatch.
pmallick 0:3afcd581558d 1103 * SUCCESS - No errors encountered.
pmallick 0:3afcd581558d 1104 *******************************************************************************/
pmallick 0:3afcd581558d 1105 int32_t ad7606_init(struct ad7606_dev **device,
pmallick 0:3afcd581558d 1106 struct ad7606_init_param *init_param)
pmallick 0:3afcd581558d 1107 {
pmallick 0:3afcd581558d 1108 struct ad7606_dev *dev;
pmallick 0:3afcd581558d 1109 uint8_t reg, id;
pmallick 0:3afcd581558d 1110 int32_t i, ret;
pmallick 0:3afcd581558d 1111
pmallick 0:3afcd581558d 1112 crc8_populate_msb(ad7606_crc8, 0x7);
pmallick 0:3afcd581558d 1113 crc16_populate_msb(ad7606_crc16, 0x755b);
pmallick 0:3afcd581558d 1114
pmallick 0:3afcd581558d 1115 dev = (struct ad7606_dev *)calloc(1, sizeof(*dev));
pmallick 0:3afcd581558d 1116 if (!dev)
pmallick 0:3afcd581558d 1117 return -ENOMEM;
pmallick 0:3afcd581558d 1118
pmallick 0:3afcd581558d 1119 dev->device_id = init_param->device_id;
pmallick 0:3afcd581558d 1120 dev->num_channels = ad7606_chip_info_tbl[dev->device_id].num_channels;
pmallick 0:3afcd581558d 1121 dev->max_dout_lines = ad7606_chip_info_tbl[dev->device_id].max_dout_lines;
pmallick 0:3afcd581558d 1122 if (ad7606_chip_info_tbl[dev->device_id].has_registers)
pmallick 0:3afcd581558d 1123 dev->sw_mode = init_param->sw_mode;
pmallick 0:3afcd581558d 1124
pmallick 0:3afcd581558d 1125 ret = ad7606_request_gpios(dev, init_param);
pmallick 0:3afcd581558d 1126 if (ret < 0)
pmallick 0:3afcd581558d 1127 goto error;
pmallick 0:3afcd581558d 1128
pmallick 0:3afcd581558d 1129 if (init_param->sw_mode) {
pmallick 0:3afcd581558d 1130 ret = gpio_set_value(dev->gpio_os0, GPIO_HIGH);
pmallick 0:3afcd581558d 1131 if (ret < 0)
pmallick 0:3afcd581558d 1132 goto error;
pmallick 0:3afcd581558d 1133
pmallick 0:3afcd581558d 1134 ret = gpio_set_value(dev->gpio_os1, GPIO_HIGH);
pmallick 0:3afcd581558d 1135 if (ret < 0)
pmallick 0:3afcd581558d 1136 goto error;
pmallick 0:3afcd581558d 1137
pmallick 0:3afcd581558d 1138 ret = gpio_set_value(dev->gpio_os2, GPIO_HIGH);
pmallick 0:3afcd581558d 1139 if (ret < 0)
pmallick 0:3afcd581558d 1140 goto error;
pmallick 0:3afcd581558d 1141 }
pmallick 0:3afcd581558d 1142
pmallick 0:3afcd581558d 1143 ret = ad7606_reset(dev);
pmallick 0:3afcd581558d 1144 if (ret < 0)
pmallick 0:3afcd581558d 1145 goto error;
pmallick 0:3afcd581558d 1146
pmallick 0:3afcd581558d 1147 /* wait DEVICE_SETUP time */
pmallick 0:3afcd581558d 1148 udelay(253);
pmallick 0:3afcd581558d 1149
pmallick 0:3afcd581558d 1150 ret = spi_init(&dev->spi_desc, &init_param->spi_init);
pmallick 0:3afcd581558d 1151 if (ret < 0)
pmallick 0:3afcd581558d 1152 goto error;
pmallick 0:3afcd581558d 1153
pmallick 0:3afcd581558d 1154 if (dev->sw_mode) {
pmallick 0:3afcd581558d 1155 ret = ad7606_spi_reg_read(dev, AD7606_REG_ID, &reg);
pmallick 0:3afcd581558d 1156 if (ret < 0)
pmallick 0:3afcd581558d 1157 goto error;
pmallick 0:3afcd581558d 1158
pmallick 0:3afcd581558d 1159 id = ad7606_chip_info_tbl[dev->device_id].device_id;
pmallick 0:3afcd581558d 1160 if (field_get(AD7606_ID_DEVICE_ID_MSK, reg) != id) {
pmallick 0:3afcd581558d 1161 printf("ad7606: device id mismatch, expected 0x%.2x, got 0x%.2x\n",
pmallick 0:3afcd581558d 1162 id,
pmallick 0:3afcd581558d 1163 (int)field_get(AD7606_ID_DEVICE_ID_MSK, reg));
pmallick 0:3afcd581558d 1164 ret = -ENODEV;
pmallick 0:3afcd581558d 1165 goto error;
pmallick 0:3afcd581558d 1166 }
pmallick 0:3afcd581558d 1167
pmallick 0:3afcd581558d 1168 ret = ad7606_set_digital_diag(dev, init_param->digital_diag_enable);
pmallick 0:3afcd581558d 1169 if (ret < 0)
pmallick 0:3afcd581558d 1170 goto error;
pmallick 0:3afcd581558d 1171
pmallick 0:3afcd581558d 1172 ret = ad7606_set_config(dev, init_param->config);
pmallick 0:3afcd581558d 1173 if (ret < 0)
pmallick 0:3afcd581558d 1174 goto error;
pmallick 0:3afcd581558d 1175
pmallick 0:3afcd581558d 1176 for (i = 0; i < dev->num_channels; i++) {
pmallick 0:3afcd581558d 1177 ret = ad7606_set_ch_range(dev, i, init_param->range_ch[i]);
pmallick 0:3afcd581558d 1178 if (ret < 0)
pmallick 0:3afcd581558d 1179 goto error;
pmallick 0:3afcd581558d 1180 }
pmallick 0:3afcd581558d 1181
pmallick 0:3afcd581558d 1182 for(i = 0; i < dev->num_channels; i++) {
pmallick 0:3afcd581558d 1183 ret = ad7606_set_ch_offset(dev, i, init_param->offset_ch[i]);
pmallick 0:3afcd581558d 1184 if (ret < 0)
pmallick 0:3afcd581558d 1185 goto error;
pmallick 0:3afcd581558d 1186 }
pmallick 0:3afcd581558d 1187
pmallick 0:3afcd581558d 1188 for(i = 0; i < dev->num_channels; i++) {
pmallick 0:3afcd581558d 1189 ret = ad7606_set_ch_phase(dev, i, init_param->phase_ch[i]);
pmallick 0:3afcd581558d 1190 if (ret < 0)
pmallick 0:3afcd581558d 1191 goto error;
pmallick 0:3afcd581558d 1192 }
pmallick 0:3afcd581558d 1193
pmallick 0:3afcd581558d 1194 for(i = 0; i < dev->num_channels; i++) {
pmallick 0:3afcd581558d 1195 ret = ad7606_set_ch_gain(dev, i, init_param->gain_ch[i]);
pmallick 0:3afcd581558d 1196 if (ret < 0)
pmallick 0:3afcd581558d 1197 goto error;
pmallick 0:3afcd581558d 1198 }
pmallick 0:3afcd581558d 1199 } else {
pmallick 0:3afcd581558d 1200 ret = ad7606_set_ch_range(dev, 0, init_param->range_ch[0]);
pmallick 0:3afcd581558d 1201 if (ret < 0)
pmallick 0:3afcd581558d 1202 goto error;
pmallick 0:3afcd581558d 1203 }
pmallick 0:3afcd581558d 1204
pmallick 0:3afcd581558d 1205 ret = gpio_set_value(dev->gpio_convst, 1);
pmallick 0:3afcd581558d 1206 if (ret < 0)
pmallick 0:3afcd581558d 1207 goto error;
pmallick 0:3afcd581558d 1208
pmallick 0:3afcd581558d 1209 if (ad7606_chip_info_tbl[dev->device_id].has_oversampling)
pmallick 0:3afcd581558d 1210 ad7606_set_oversampling(dev, init_param->oversampling);
pmallick 0:3afcd581558d 1211
pmallick 0:3afcd581558d 1212 *device = dev;
pmallick 0:3afcd581558d 1213
pmallick 0:3afcd581558d 1214 printf("ad7606 successfully initialized\n");
pmallick 0:3afcd581558d 1215
pmallick 0:3afcd581558d 1216 return ret;
pmallick 0:3afcd581558d 1217 error:
pmallick 0:3afcd581558d 1218 printf("ad7606 initialization failed\n");
pmallick 0:3afcd581558d 1219 ad7606_remove(dev);
pmallick 0:3afcd581558d 1220 return ret;
pmallick 0:3afcd581558d 1221 }
pmallick 0:3afcd581558d 1222
pmallick 0:3afcd581558d 1223 /***************************************************************************//**
pmallick 0:3afcd581558d 1224 * @brief Free any resource used by the driver.
pmallick 0:3afcd581558d 1225 *
pmallick 0:3afcd581558d 1226 * @param dev - The device structure.
pmallick 0:3afcd581558d 1227 *
pmallick 0:3afcd581558d 1228 * @return ret - return code.
pmallick 0:3afcd581558d 1229 * Example: -EIO - SPI communication error.
pmallick 0:3afcd581558d 1230 * SUCCESS - No errors encountered.
pmallick 0:3afcd581558d 1231 *******************************************************************************/
pmallick 0:3afcd581558d 1232 int32_t ad7606_remove(struct ad7606_dev *dev)
pmallick 0:3afcd581558d 1233 {
pmallick 0:3afcd581558d 1234 int32_t ret;
pmallick 0:3afcd581558d 1235
pmallick 0:3afcd581558d 1236 gpio_remove(dev->gpio_reset);
pmallick 0:3afcd581558d 1237 gpio_remove(dev->gpio_convst);
pmallick 0:3afcd581558d 1238 gpio_remove(dev->gpio_busy);
pmallick 0:3afcd581558d 1239 gpio_remove(dev->gpio_stby_n);
pmallick 0:3afcd581558d 1240 gpio_remove(dev->gpio_range);
pmallick 0:3afcd581558d 1241 gpio_remove(dev->gpio_os0);
pmallick 0:3afcd581558d 1242 gpio_remove(dev->gpio_os1);
pmallick 0:3afcd581558d 1243 gpio_remove(dev->gpio_os2);
pmallick 0:3afcd581558d 1244 gpio_remove(dev->gpio_par_ser);
pmallick 0:3afcd581558d 1245
pmallick 0:3afcd581558d 1246 ret = spi_remove(dev->spi_desc);
pmallick 0:3afcd581558d 1247
pmallick 0:3afcd581558d 1248 free(dev);
pmallick 0:3afcd581558d 1249
pmallick 0:3afcd581558d 1250 return ret;
pmallick 0:3afcd581558d 1251 }