Library files for AD7606

Dependents:   EVAL-AD7606

Committer:
mahphalke
Date:
Mon Oct 05 14:14:46 2020 +0530
Revision:
2:77e214c5c02e
AD7606 No-OS driver library- Initial Revision

Who changed what in which revision?

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