| @@ -0,0 +1,1138 @@ |
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
| 2 | +/* |
| 3 | + * Analog Devices AD3552R |
| 4 | + * Digital to Analog converter driver |
| 5 | + * |
| 6 | + * Copyright 2021 Analog Devices Inc. |
| 7 | + */ |
| 8 | +#include <asm/unaligned.h> |
| 9 | +#include <linux/device.h> |
| 10 | +#include <linux/iio/triggered_buffer.h> |
| 11 | +#include <linux/iio/trigger_consumer.h> |
| 12 | +#include <linux/iopoll.h> |
| 13 | +#include <linux/kernel.h> |
| 14 | +#include <linux/regulator/consumer.h> |
| 15 | +#include <linux/spi/spi.h> |
| 16 | + |
| 17 | +/* Register addresses */ |
| 18 | +/* Primary address space */ |
| 19 | +#define AD3552R_REG_ADDR_INTERFACE_CONFIG_A 0x00 |
| 20 | +#define AD3552R_MASK_SOFTWARE_RESET (BIT(7) | BIT(0)) |
| 21 | +#define AD3552R_MASK_ADDR_ASCENSION BIT(5) |
| 22 | +#define AD3552R_MASK_SDO_ACTIVE BIT(4) |
| 23 | +#define AD3552R_REG_ADDR_INTERFACE_CONFIG_B 0x01 |
| 24 | +#define AD3552R_MASK_SINGLE_INST BIT(7) |
| 25 | +#define AD3552R_MASK_SHORT_INSTRUCTION BIT(3) |
| 26 | +#define AD3552R_REG_ADDR_DEVICE_CONFIG 0x02 |
| 27 | +#define AD3552R_MASK_DEVICE_STATUS(n) BIT(4 + (n)) |
| 28 | +#define AD3552R_MASK_CUSTOM_MODES GENMASK(3, 2) |
| 29 | +#define AD3552R_MASK_OPERATING_MODES GENMASK(1, 0) |
| 30 | +#define AD3552R_REG_ADDR_CHIP_TYPE 0x03 |
| 31 | +#define AD3552R_MASK_CLASS GENMASK(7, 0) |
| 32 | +#define AD3552R_REG_ADDR_PRODUCT_ID_L 0x04 |
| 33 | +#define AD3552R_REG_ADDR_PRODUCT_ID_H 0x05 |
| 34 | +#define AD3552R_REG_ADDR_CHIP_GRADE 0x06 |
| 35 | +#define AD3552R_MASK_GRADE GENMASK(7, 4) |
| 36 | +#define AD3552R_MASK_DEVICE_REVISION GENMASK(3, 0) |
| 37 | +#define AD3552R_REG_ADDR_SCRATCH_PAD 0x0A |
| 38 | +#define AD3552R_REG_ADDR_SPI_REVISION 0x0B |
| 39 | +#define AD3552R_REG_ADDR_VENDOR_L 0x0C |
| 40 | +#define AD3552R_REG_ADDR_VENDOR_H 0x0D |
| 41 | +#define AD3552R_REG_ADDR_STREAM_MODE 0x0E |
| 42 | +#define AD3552R_MASK_LENGTH GENMASK(7, 0) |
| 43 | +#define AD3552R_REG_ADDR_TRANSFER_REGISTER 0x0F |
| 44 | +#define AD3552R_MASK_MULTI_IO_MODE GENMASK(7, 6) |
| 45 | +#define AD3552R_MASK_STREAM_LENGTH_KEEP_VALUE BIT(2) |
| 46 | +#define AD3552R_REG_ADDR_INTERFACE_CONFIG_C 0x10 |
| 47 | +#define AD3552R_MASK_CRC_ENABLE (GENMASK(7, 6) |\ |
| 48 | + GENMASK(1, 0)) |
| 49 | +#define AD3552R_MASK_STRICT_REGISTER_ACCESS BIT(5) |
| 50 | +#define AD3552R_REG_ADDR_INTERFACE_STATUS_A 0x11 |
| 51 | +#define AD3552R_MASK_INTERFACE_NOT_READY BIT(7) |
| 52 | +#define AD3552R_MASK_CLOCK_COUNTING_ERROR BIT(5) |
| 53 | +#define AD3552R_MASK_INVALID_OR_NO_CRC BIT(3) |
| 54 | +#define AD3552R_MASK_WRITE_TO_READ_ONLY_REGISTER BIT(2) |
| 55 | +#define AD3552R_MASK_PARTIAL_REGISTER_ACCESS BIT(1) |
| 56 | +#define AD3552R_MASK_REGISTER_ADDRESS_INVALID BIT(0) |
| 57 | +#define AD3552R_REG_ADDR_INTERFACE_CONFIG_D 0x14 |
| 58 | +#define AD3552R_MASK_ALERT_ENABLE_PULLUP BIT(6) |
| 59 | +#define AD3552R_MASK_MEM_CRC_EN BIT(4) |
| 60 | +#define AD3552R_MASK_SDO_DRIVE_STRENGTH GENMASK(3, 2) |
| 61 | +#define AD3552R_MASK_DUAL_SPI_SYNCHROUNOUS_EN BIT(1) |
| 62 | +#define AD3552R_MASK_SPI_CONFIG_DDR BIT(0) |
| 63 | +#define AD3552R_REG_ADDR_SH_REFERENCE_CONFIG 0x15 |
| 64 | +#define AD3552R_MASK_IDUMP_FAST_MODE BIT(6) |
| 65 | +#define AD3552R_MASK_SAMPLE_HOLD_DIFFERENTIAL_USER_EN BIT(5) |
| 66 | +#define AD3552R_MASK_SAMPLE_HOLD_USER_TRIM GENMASK(4, 3) |
| 67 | +#define AD3552R_MASK_SAMPLE_HOLD_USER_ENABLE BIT(2) |
| 68 | +#define AD3552R_MASK_REFERENCE_VOLTAGE_SEL GENMASK(1, 0) |
| 69 | +#define AD3552R_REG_ADDR_ERR_ALARM_MASK 0x16 |
| 70 | +#define AD3552R_MASK_REF_RANGE_ALARM BIT(6) |
| 71 | +#define AD3552R_MASK_CLOCK_COUNT_ERR_ALARM BIT(5) |
| 72 | +#define AD3552R_MASK_MEM_CRC_ERR_ALARM BIT(4) |
| 73 | +#define AD3552R_MASK_SPI_CRC_ERR_ALARM BIT(3) |
| 74 | +#define AD3552R_MASK_WRITE_TO_READ_ONLY_ALARM BIT(2) |
| 75 | +#define AD3552R_MASK_PARTIAL_REGISTER_ACCESS_ALARM BIT(1) |
| 76 | +#define AD3552R_MASK_REGISTER_ADDRESS_INVALID_ALARM BIT(0) |
| 77 | +#define AD3552R_REG_ADDR_ERR_STATUS 0x17 |
| 78 | +#define AD3552R_MASK_REF_RANGE_ERR_STATUS BIT(6) |
| 79 | +#define AD3552R_MASK_DUAL_SPI_STREAM_EXCEEDS_DAC_ERR_STATUS BIT(5) |
| 80 | +#define AD3552R_MASK_MEM_CRC_ERR_STATUS BIT(4) |
| 81 | +#define AD3552R_MASK_RESET_STATUS BIT(0) |
| 82 | +#define AD3552R_REG_ADDR_POWERDOWN_CONFIG 0x18 |
| 83 | +#define AD3552R_MASK_CH_DAC_POWERDOWN(ch) BIT(4 + (ch)) |
| 84 | +#define AD3552R_MASK_CH_AMPLIFIER_POWERDOWN(ch) BIT(ch) |
| 85 | +#define AD3552R_REG_ADDR_CH0_CH1_OUTPUT_RANGE 0x19 |
| 86 | +#define AD3552R_MASK_CH_OUTPUT_RANGE_SEL(ch) ((ch) ? GENMASK(7, 4) :\ |
| 87 | + GENMASK(3, 0)) |
| 88 | +#define AD3552R_REG_ADDR_CH_OFFSET(ch) (0x1B + (ch) * 2) |
| 89 | +#define AD3552R_MASK_CH_OFFSET_BITS_0_7 GENMASK(7, 0) |
| 90 | +#define AD3552R_REG_ADDR_CH_GAIN(ch) (0x1C + (ch) * 2) |
| 91 | +#define AD3552R_MASK_CH_RANGE_OVERRIDE BIT(7) |
| 92 | +#define AD3552R_MASK_CH_GAIN_SCALING_N GENMASK(6, 5) |
| 93 | +#define AD3552R_MASK_CH_GAIN_SCALING_P GENMASK(4, 3) |
| 94 | +#define AD3552R_MASK_CH_OFFSET_POLARITY BIT(2) |
| 95 | +#define AD3552R_MASK_CH_OFFSET_BIT_8 BIT(0) |
| 96 | +/* |
| 97 | + * Secondary region |
| 98 | + * For multibyte registers specify the highest address because the access is |
| 99 | + * done in descending order |
| 100 | + */ |
| 101 | +#define AD3552R_SECONDARY_REGION_START 0x28 |
| 102 | +#define AD3552R_REG_ADDR_HW_LDAC_16B 0x28 |
| 103 | +#define AD3552R_REG_ADDR_CH_DAC_16B(ch) (0x2C - (1 - ch) * 2) |
| 104 | +#define AD3552R_REG_ADDR_DAC_PAGE_MASK_16B 0x2E |
| 105 | +#define AD3552R_REG_ADDR_CH_SELECT_16B 0x2F |
| 106 | +#define AD3552R_REG_ADDR_INPUT_PAGE_MASK_16B 0x31 |
| 107 | +#define AD3552R_REG_ADDR_SW_LDAC_16B 0x32 |
| 108 | +#define AD3552R_REG_ADDR_CH_INPUT_16B(ch) (0x36 - (1 - ch) * 2) |
| 109 | +/* 3 bytes registers */ |
| 110 | +#define AD3552R_REG_START_24B 0x37 |
| 111 | +#define AD3552R_REG_ADDR_HW_LDAC_24B 0x37 |
| 112 | +#define AD3552R_REG_ADDR_CH_DAC_24B(ch) (0x3D - (1 - ch) * 3) |
| 113 | +#define AD3552R_REG_ADDR_DAC_PAGE_MASK_24B 0x40 |
| 114 | +#define AD3552R_REG_ADDR_CH_SELECT_24B 0x41 |
| 115 | +#define AD3552R_REG_ADDR_INPUT_PAGE_MASK_24B 0x44 |
| 116 | +#define AD3552R_REG_ADDR_SW_LDAC_24B 0x45 |
| 117 | +#define AD3552R_REG_ADDR_CH_INPUT_24B(ch) (0x4B - (1 - ch) * 3) |
| 118 | + |
| 119 | +/* Useful defines */ |
| 120 | +#define AD3552R_NUM_CH 2 |
| 121 | +#define AD3552R_MASK_CH(ch) BIT(ch) |
| 122 | +#define AD3552R_MASK_ALL_CH GENMASK(1, 0) |
| 123 | +#define AD3552R_MAX_REG_SIZE 3 |
| 124 | +#define AD3552R_READ_BIT BIT(7) |
| 125 | +#define AD3552R_ADDR_MASK GENMASK(6, 0) |
| 126 | +#define AD3552R_MASK_DAC_12B 0xFFF0 |
| 127 | +#define AD3552R_DEFAULT_CONFIG_B_VALUE 0x8 |
| 128 | +#define AD3552R_SCRATCH_PAD_TEST_VAL1 0x34 |
| 129 | +#define AD3552R_SCRATCH_PAD_TEST_VAL2 0xB2 |
| 130 | +#define AD3552R_GAIN_SCALE 1000 |
| 131 | +#define AD3552R_LDAC_PULSE_US 100 |
| 132 | + |
| 133 | +enum ad3552r_ch_vref_select { |
| 134 | + /* Internal source with Vref I/O floating */ |
| 135 | + AD3552R_INTERNAL_VREF_PIN_FLOATING, |
| 136 | + /* Internal source with Vref I/O at 2.5V */ |
| 137 | + AD3552R_INTERNAL_VREF_PIN_2P5V, |
| 138 | + /* External source with Vref I/O as input */ |
| 139 | + AD3552R_EXTERNAL_VREF_PIN_INPUT |
| 140 | +}; |
| 141 | + |
| 142 | +enum ad3542r_id { |
| 143 | + AD3542R_ID = 0x4008, |
| 144 | + AD3552R_ID = 0x4009, |
| 145 | +}; |
| 146 | + |
| 147 | +enum ad3552r_ch_output_range { |
| 148 | + /* Range from 0 V to 2.5 V. Requires Rfb1x connection */ |
| 149 | + AD3552R_CH_OUTPUT_RANGE_0__2P5V, |
| 150 | + /* Range from 0 V to 5 V. Requires Rfb1x connection */ |
| 151 | + AD3552R_CH_OUTPUT_RANGE_0__5V, |
| 152 | + /* Range from 0 V to 10 V. Requires Rfb2x connection */ |
| 153 | + AD3552R_CH_OUTPUT_RANGE_0__10V, |
| 154 | + /* Range from -5 V to 5 V. Requires Rfb2x connection */ |
| 155 | + AD3552R_CH_OUTPUT_RANGE_NEG_5__5V, |
| 156 | + /* Range from -10 V to 10 V. Requires Rfb4x connection */ |
| 157 | + AD3552R_CH_OUTPUT_RANGE_NEG_10__10V, |
| 158 | +}; |
| 159 | + |
| 160 | +static const s32 ad3552r_ch_ranges[][2] = { |
| 161 | + [AD3552R_CH_OUTPUT_RANGE_0__2P5V] = {0, 2500}, |
| 162 | + [AD3552R_CH_OUTPUT_RANGE_0__5V] = {0, 5000}, |
| 163 | + [AD3552R_CH_OUTPUT_RANGE_0__10V] = {0, 10000}, |
| 164 | + [AD3552R_CH_OUTPUT_RANGE_NEG_5__5V] = {-5000, 5000}, |
| 165 | + [AD3552R_CH_OUTPUT_RANGE_NEG_10__10V] = {-10000, 10000} |
| 166 | +}; |
| 167 | + |
| 168 | +enum ad3542r_ch_output_range { |
| 169 | + /* Range from 0 V to 2.5 V. Requires Rfb1x connection */ |
| 170 | + AD3542R_CH_OUTPUT_RANGE_0__2P5V, |
| 171 | + /* Range from 0 V to 3 V. Requires Rfb1x connection */ |
| 172 | + AD3542R_CH_OUTPUT_RANGE_0__3V, |
| 173 | + /* Range from 0 V to 5 V. Requires Rfb1x connection */ |
| 174 | + AD3542R_CH_OUTPUT_RANGE_0__5V, |
| 175 | + /* Range from 0 V to 10 V. Requires Rfb2x connection */ |
| 176 | + AD3542R_CH_OUTPUT_RANGE_0__10V, |
| 177 | + /* Range from -2.5 V to 7.5 V. Requires Rfb2x connection */ |
| 178 | + AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V, |
| 179 | + /* Range from -5 V to 5 V. Requires Rfb2x connection */ |
| 180 | + AD3542R_CH_OUTPUT_RANGE_NEG_5__5V, |
| 181 | +}; |
| 182 | + |
| 183 | +static const s32 ad3542r_ch_ranges[][2] = { |
| 184 | + [AD3542R_CH_OUTPUT_RANGE_0__2P5V] = {0, 2500}, |
| 185 | + [AD3542R_CH_OUTPUT_RANGE_0__3V] = {0, 3000}, |
| 186 | + [AD3542R_CH_OUTPUT_RANGE_0__5V] = {0, 5000}, |
| 187 | + [AD3542R_CH_OUTPUT_RANGE_0__10V] = {0, 10000}, |
| 188 | + [AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V] = {-2500, 7500}, |
| 189 | + [AD3542R_CH_OUTPUT_RANGE_NEG_5__5V] = {-5000, 5000} |
| 190 | +}; |
| 191 | + |
| 192 | +enum ad3552r_ch_gain_scaling { |
| 193 | + /* Gain scaling of 1 */ |
| 194 | + AD3552R_CH_GAIN_SCALING_1, |
| 195 | + /* Gain scaling of 0.5 */ |
| 196 | + AD3552R_CH_GAIN_SCALING_0_5, |
| 197 | + /* Gain scaling of 0.25 */ |
| 198 | + AD3552R_CH_GAIN_SCALING_0_25, |
| 199 | + /* Gain scaling of 0.125 */ |
| 200 | + AD3552R_CH_GAIN_SCALING_0_125, |
| 201 | +}; |
| 202 | + |
| 203 | +/* Gain * AD3552R_GAIN_SCALE */ |
| 204 | +static const s32 gains_scaling_table[] = { |
| 205 | + [AD3552R_CH_GAIN_SCALING_1] = 1000, |
| 206 | + [AD3552R_CH_GAIN_SCALING_0_5] = 500, |
| 207 | + [AD3552R_CH_GAIN_SCALING_0_25] = 250, |
| 208 | + [AD3552R_CH_GAIN_SCALING_0_125] = 125 |
| 209 | +}; |
| 210 | + |
| 211 | +enum ad3552r_dev_attributes { |
| 212 | + /* - Direct register values */ |
| 213 | + /* From 0-3 */ |
| 214 | + AD3552R_SDO_DRIVE_STRENGTH, |
| 215 | + /* |
| 216 | + * 0 -> Internal Vref, vref_io pin floating (default) |
| 217 | + * 1 -> Internal Vref, vref_io driven by internal vref |
| 218 | + * 2 or 3 -> External Vref |
| 219 | + */ |
| 220 | + AD3552R_VREF_SELECT, |
| 221 | + /* Read registers in ascending order if set. Else descending */ |
| 222 | + AD3552R_ADDR_ASCENSION, |
| 223 | +}; |
| 224 | + |
| 225 | +enum ad3552r_ch_attributes { |
| 226 | + /* DAC powerdown */ |
| 227 | + AD3552R_CH_DAC_POWERDOWN, |
| 228 | + /* DAC amplifier powerdown */ |
| 229 | + AD3552R_CH_AMPLIFIER_POWERDOWN, |
| 230 | + /* Select the output range. Select from enum ad3552r_ch_output_range */ |
| 231 | + AD3552R_CH_OUTPUT_RANGE_SEL, |
| 232 | + /* |
| 233 | + * Over-rider the range selector in order to manually set the output |
| 234 | + * voltage range |
| 235 | + */ |
| 236 | + AD3552R_CH_RANGE_OVERRIDE, |
| 237 | + /* Manually set the offset voltage */ |
| 238 | + AD3552R_CH_GAIN_OFFSET, |
| 239 | + /* Sets the polarity of the offset. */ |
| 240 | + AD3552R_CH_GAIN_OFFSET_POLARITY, |
| 241 | + /* PDAC gain scaling */ |
| 242 | + AD3552R_CH_GAIN_SCALING_P, |
| 243 | + /* NDAC gain scaling */ |
| 244 | + AD3552R_CH_GAIN_SCALING_N, |
| 245 | + /* Rfb value */ |
| 246 | + AD3552R_CH_RFB, |
| 247 | + /* Channel select. When set allow Input -> DAC and Mask -> DAC */ |
| 248 | + AD3552R_CH_SELECT, |
| 249 | +}; |
| 250 | + |
| 251 | +struct ad3552r_ch_data { |
| 252 | + s32 scale_int; |
| 253 | + s32 scale_dec; |
| 254 | + s32 offset_int; |
| 255 | + s32 offset_dec; |
| 256 | + s16 gain_offset; |
| 257 | + u16 rfb; |
| 258 | + u8 n; |
| 259 | + u8 p; |
| 260 | + u8 range; |
| 261 | + bool range_override; |
| 262 | +}; |
| 263 | + |
| 264 | +struct ad3552r_desc { |
| 265 | + /* Used to look the spi bus for atomic operations where needed */ |
| 266 | + struct mutex lock; |
| 267 | + struct gpio_desc *gpio_reset; |
| 268 | + struct gpio_desc *gpio_ldac; |
| 269 | + struct spi_device *spi; |
| 270 | + struct ad3552r_ch_data ch_data[AD3552R_NUM_CH]; |
| 271 | + struct iio_chan_spec channels[AD3552R_NUM_CH + 1]; |
| 272 | + unsigned long enabled_ch; |
| 273 | + unsigned int num_ch; |
| 274 | + enum ad3542r_id chip_id; |
| 275 | +}; |
| 276 | + |
| 277 | +static const u16 addr_mask_map[][2] = { |
| 278 | + [AD3552R_ADDR_ASCENSION] = { |
| 279 | + AD3552R_REG_ADDR_INTERFACE_CONFIG_A, |
| 280 | + AD3552R_MASK_ADDR_ASCENSION |
| 281 | + }, |
| 282 | + [AD3552R_SDO_DRIVE_STRENGTH] = { |
| 283 | + AD3552R_REG_ADDR_INTERFACE_CONFIG_D, |
| 284 | + AD3552R_MASK_SDO_DRIVE_STRENGTH |
| 285 | + }, |
| 286 | + [AD3552R_VREF_SELECT] = { |
| 287 | + AD3552R_REG_ADDR_SH_REFERENCE_CONFIG, |
| 288 | + AD3552R_MASK_REFERENCE_VOLTAGE_SEL |
| 289 | + }, |
| 290 | +}; |
| 291 | + |
| 292 | +/* 0 -> reg addr, 1->ch0 mask, 2->ch1 mask */ |
| 293 | +static const u16 addr_mask_map_ch[][3] = { |
| 294 | + [AD3552R_CH_DAC_POWERDOWN] = { |
| 295 | + AD3552R_REG_ADDR_POWERDOWN_CONFIG, |
| 296 | + AD3552R_MASK_CH_DAC_POWERDOWN(0), |
| 297 | + AD3552R_MASK_CH_DAC_POWERDOWN(1) |
| 298 | + }, |
| 299 | + [AD3552R_CH_AMPLIFIER_POWERDOWN] = { |
| 300 | + AD3552R_REG_ADDR_POWERDOWN_CONFIG, |
| 301 | + AD3552R_MASK_CH_AMPLIFIER_POWERDOWN(0), |
| 302 | + AD3552R_MASK_CH_AMPLIFIER_POWERDOWN(1) |
| 303 | + }, |
| 304 | + [AD3552R_CH_OUTPUT_RANGE_SEL] = { |
| 305 | + AD3552R_REG_ADDR_CH0_CH1_OUTPUT_RANGE, |
| 306 | + AD3552R_MASK_CH_OUTPUT_RANGE_SEL(0), |
| 307 | + AD3552R_MASK_CH_OUTPUT_RANGE_SEL(1) |
| 308 | + }, |
| 309 | + [AD3552R_CH_SELECT] = { |
| 310 | + AD3552R_REG_ADDR_CH_SELECT_16B, |
| 311 | + AD3552R_MASK_CH(0), |
| 312 | + AD3552R_MASK_CH(1) |
| 313 | + } |
| 314 | +}; |
| 315 | + |
| 316 | +static u8 _ad3552r_reg_len(u8 addr) |
| 317 | +{ |
| 318 | + switch (addr) { |
| 319 | + case AD3552R_REG_ADDR_HW_LDAC_16B: |
| 320 | + case AD3552R_REG_ADDR_CH_SELECT_16B: |
| 321 | + case AD3552R_REG_ADDR_SW_LDAC_16B: |
| 322 | + case AD3552R_REG_ADDR_HW_LDAC_24B: |
| 323 | + case AD3552R_REG_ADDR_CH_SELECT_24B: |
| 324 | + case AD3552R_REG_ADDR_SW_LDAC_24B: |
| 325 | + return 1; |
| 326 | + default: |
| 327 | + break; |
| 328 | + } |
| 329 | + |
| 330 | + if (addr > AD3552R_REG_ADDR_HW_LDAC_24B) |
| 331 | + return 3; |
| 332 | + if (addr > AD3552R_REG_ADDR_HW_LDAC_16B) |
| 333 | + return 2; |
| 334 | + |
| 335 | + return 1; |
| 336 | +} |
| 337 | + |
| 338 | +/* SPI transfer to device */ |
| 339 | +static int ad3552r_transfer(struct ad3552r_desc *dac, u8 addr, u32 len, |
| 340 | + u8 *data, bool is_read) |
| 341 | +{ |
| 342 | + /* Maximum transfer: Addr (1B) + 2 * (Data Reg (3B)) + SW LDAC(1B) */ |
| 343 | + u8 buf[8]; |
| 344 | + |
| 345 | + buf[0] = addr & AD3552R_ADDR_MASK; |
| 346 | + buf[0] |= is_read ? AD3552R_READ_BIT : 0; |
| 347 | + if (is_read) |
| 348 | + return spi_write_then_read(dac->spi, buf, 1, data, len); |
| 349 | + |
| 350 | + memcpy(buf + 1, data, len); |
| 351 | + return spi_write_then_read(dac->spi, buf, len + 1, NULL, 0); |
| 352 | +} |
| 353 | + |
| 354 | +static int ad3552r_write_reg(struct ad3552r_desc *dac, u8 addr, u16 val) |
| 355 | +{ |
| 356 | + u8 reg_len; |
| 357 | + u8 buf[AD3552R_MAX_REG_SIZE] = { 0 }; |
| 358 | + |
| 359 | + reg_len = _ad3552r_reg_len(addr); |
| 360 | + if (reg_len == 2) |
| 361 | + /* Only DAC register are 2 bytes wide */ |
| 362 | + val &= AD3552R_MASK_DAC_12B; |
| 363 | + if (reg_len == 1) |
| 364 | + buf[0] = val & 0xFF; |
| 365 | + else |
| 366 | + /* reg_len can be 2 or 3, but 3rd bytes needs to be set to 0 */ |
| 367 | + put_unaligned_be16(val, buf); |
| 368 | + |
| 369 | + return ad3552r_transfer(dac, addr, reg_len, buf, false); |
| 370 | +} |
| 371 | + |
| 372 | +static int ad3552r_read_reg(struct ad3552r_desc *dac, u8 addr, u16 *val) |
| 373 | +{ |
| 374 | + int err; |
| 375 | + u8 reg_len, buf[AD3552R_MAX_REG_SIZE] = { 0 }; |
| 376 | + |
| 377 | + reg_len = _ad3552r_reg_len(addr); |
| 378 | + err = ad3552r_transfer(dac, addr, reg_len, buf, true); |
| 379 | + if (err) |
| 380 | + return err; |
| 381 | + |
| 382 | + if (reg_len == 1) |
| 383 | + *val = buf[0]; |
| 384 | + else |
| 385 | + /* reg_len can be 2 or 3, but only first 2 bytes are relevant */ |
| 386 | + *val = get_unaligned_be16(buf); |
| 387 | + |
| 388 | + return 0; |
| 389 | +} |
| 390 | + |
| 391 | +static u16 ad3552r_field_prep(u16 val, u16 mask) |
| 392 | +{ |
| 393 | + return (val << __ffs(mask)) & mask; |
| 394 | +} |
| 395 | + |
| 396 | +/* Update field of a register, shift val if needed */ |
| 397 | +static int ad3552r_update_reg_field(struct ad3552r_desc *dac, u8 addr, u16 mask, |
| 398 | + u16 val) |
| 399 | +{ |
| 400 | + int ret; |
| 401 | + u16 reg; |
| 402 | + |
| 403 | + ret = ad3552r_read_reg(dac, addr, ®); |
| 404 | + if (ret < 0) |
| 405 | + return ret; |
| 406 | + |
| 407 | + reg &= ~mask; |
| 408 | + reg |= ad3552r_field_prep(val, mask); |
| 409 | + |
| 410 | + return ad3552r_write_reg(dac, addr, reg); |
| 411 | +} |
| 412 | + |
| 413 | +static int ad3552r_set_ch_value(struct ad3552r_desc *dac, |
| 414 | + enum ad3552r_ch_attributes attr, |
| 415 | + u8 ch, |
| 416 | + u16 val) |
| 417 | +{ |
| 418 | + /* Update register related to attributes in chip */ |
| 419 | + return ad3552r_update_reg_field(dac, addr_mask_map_ch[attr][0], |
| 420 | + addr_mask_map_ch[attr][ch + 1], val); |
| 421 | +} |
| 422 | + |
| 423 | +#define AD3552R_CH_DAC(_idx) ((struct iio_chan_spec) { \ |
| 424 | + .type = IIO_VOLTAGE, \ |
| 425 | + .output = true, \ |
| 426 | + .indexed = true, \ |
| 427 | + .channel = _idx, \ |
| 428 | + .scan_index = _idx, \ |
| 429 | + .scan_type = { \ |
| 430 | + .sign = 'u', \ |
| 431 | + .realbits = 16, \ |
| 432 | + .storagebits = 16, \ |
| 433 | + .endianness = IIO_BE, \ |
| 434 | + }, \ |
| 435 | + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
| 436 | + BIT(IIO_CHAN_INFO_SCALE) | \ |
| 437 | + BIT(IIO_CHAN_INFO_ENABLE) | \ |
| 438 | + BIT(IIO_CHAN_INFO_OFFSET), \ |
| 439 | +}) |
| 440 | + |
| 441 | +static int ad3552r_read_raw(struct iio_dev *indio_dev, |
| 442 | + struct iio_chan_spec const *chan, |
| 443 | + int *val, |
| 444 | + int *val2, |
| 445 | + long mask) |
| 446 | +{ |
| 447 | + struct ad3552r_desc *dac = iio_priv(indio_dev); |
| 448 | + u16 tmp_val; |
| 449 | + int err; |
| 450 | + u8 ch = chan->channel; |
| 451 | + |
| 452 | + switch (mask) { |
| 453 | + case IIO_CHAN_INFO_RAW: |
| 454 | + mutex_lock(&dac->lock); |
| 455 | + err = ad3552r_read_reg(dac, AD3552R_REG_ADDR_CH_DAC_24B(ch), |
| 456 | + &tmp_val); |
| 457 | + mutex_unlock(&dac->lock); |
| 458 | + if (err < 0) |
| 459 | + return err; |
| 460 | + *val = tmp_val; |
| 461 | + return IIO_VAL_INT; |
| 462 | + case IIO_CHAN_INFO_ENABLE: |
| 463 | + mutex_lock(&dac->lock); |
| 464 | + err = ad3552r_read_reg(dac, AD3552R_REG_ADDR_POWERDOWN_CONFIG, |
| 465 | + &tmp_val); |
| 466 | + mutex_unlock(&dac->lock); |
| 467 | + if (err < 0) |
| 468 | + return err; |
| 469 | + *val = !((tmp_val & AD3552R_MASK_CH_DAC_POWERDOWN(ch)) >> |
| 470 | + __ffs(AD3552R_MASK_CH_DAC_POWERDOWN(ch))); |
| 471 | + return IIO_VAL_INT; |
| 472 | + case IIO_CHAN_INFO_SCALE: |
| 473 | + *val = dac->ch_data[ch].scale_int; |
| 474 | + *val2 = dac->ch_data[ch].scale_dec; |
| 475 | + return IIO_VAL_INT_PLUS_MICRO; |
| 476 | + case IIO_CHAN_INFO_OFFSET: |
| 477 | + *val = dac->ch_data[ch].offset_int; |
| 478 | + *val2 = dac->ch_data[ch].offset_dec; |
| 479 | + return IIO_VAL_INT_PLUS_MICRO; |
| 480 | + default: |
| 481 | + return -EINVAL; |
| 482 | + } |
| 483 | +} |
| 484 | + |
| 485 | +static int ad3552r_write_raw(struct iio_dev *indio_dev, |
| 486 | + struct iio_chan_spec const *chan, |
| 487 | + int val, |
| 488 | + int val2, |
| 489 | + long mask) |
| 490 | +{ |
| 491 | + struct ad3552r_desc *dac = iio_priv(indio_dev); |
| 492 | + int err; |
| 493 | + |
| 494 | + mutex_lock(&dac->lock); |
| 495 | + switch (mask) { |
| 496 | + case IIO_CHAN_INFO_RAW: |
| 497 | + err = ad3552r_write_reg(dac, |
| 498 | + AD3552R_REG_ADDR_CH_DAC_24B(chan->channel), |
| 499 | + val); |
| 500 | + break; |
| 501 | + case IIO_CHAN_INFO_ENABLE: |
| 502 | + err = ad3552r_set_ch_value(dac, AD3552R_CH_DAC_POWERDOWN, |
| 503 | + chan->channel, !val); |
| 504 | + break; |
| 505 | + default: |
| 506 | + err = -EINVAL; |
| 507 | + break; |
| 508 | + } |
| 509 | + mutex_unlock(&dac->lock); |
| 510 | + |
| 511 | + return err; |
| 512 | +} |
| 513 | + |
| 514 | +static const struct iio_info ad3552r_iio_info = { |
| 515 | + .read_raw = ad3552r_read_raw, |
| 516 | + .write_raw = ad3552r_write_raw |
| 517 | +}; |
| 518 | + |
| 519 | +static int32_t ad3552r_trigger_hw_ldac(struct gpio_desc *ldac) |
| 520 | +{ |
| 521 | + gpiod_set_value_cansleep(ldac, 0); |
| 522 | + usleep_range(AD3552R_LDAC_PULSE_US, AD3552R_LDAC_PULSE_US + 10); |
| 523 | + gpiod_set_value_cansleep(ldac, 1); |
| 524 | + |
| 525 | + return 0; |
| 526 | +} |
| 527 | + |
| 528 | +static int ad3552r_write_all_channels(struct ad3552r_desc *dac, u8 *data) |
| 529 | +{ |
| 530 | + int err, len; |
| 531 | + u8 addr, buff[AD3552R_NUM_CH * AD3552R_MAX_REG_SIZE + 1]; |
| 532 | + |
| 533 | + addr = AD3552R_REG_ADDR_CH_INPUT_24B(1); |
| 534 | + /* CH1 */ |
| 535 | + memcpy(buff, data + 2, 2); |
| 536 | + buff[2] = 0; |
| 537 | + /* CH0 */ |
| 538 | + memcpy(buff + 3, data, 2); |
| 539 | + buff[5] = 0; |
| 540 | + len = 6; |
| 541 | + if (!dac->gpio_ldac) { |
| 542 | + /* Software LDAC */ |
| 543 | + buff[6] = AD3552R_MASK_ALL_CH; |
| 544 | + ++len; |
| 545 | + } |
| 546 | + err = ad3552r_transfer(dac, addr, len, buff, false); |
| 547 | + if (err) |
| 548 | + return err; |
| 549 | + |
| 550 | + if (dac->gpio_ldac) |
| 551 | + return ad3552r_trigger_hw_ldac(dac->gpio_ldac); |
| 552 | + |
| 553 | + return 0; |
| 554 | +} |
| 555 | + |
| 556 | +static int ad3552r_write_codes(struct ad3552r_desc *dac, u32 mask, u8 *data) |
| 557 | +{ |
| 558 | + int err; |
| 559 | + u8 addr, buff[AD3552R_MAX_REG_SIZE]; |
| 560 | + |
| 561 | + if (mask == AD3552R_MASK_ALL_CH) { |
| 562 | + if (memcmp(data, data + 2, 2) != 0) |
| 563 | + return ad3552r_write_all_channels(dac, data); |
| 564 | + |
| 565 | + addr = AD3552R_REG_ADDR_INPUT_PAGE_MASK_24B; |
| 566 | + } else { |
| 567 | + addr = AD3552R_REG_ADDR_CH_INPUT_24B(__ffs(mask)); |
| 568 | + } |
| 569 | + |
| 570 | + memcpy(buff, data, 2); |
| 571 | + buff[2] = 0; |
| 572 | + err = ad3552r_transfer(dac, addr, 3, data, false); |
| 573 | + if (err) |
| 574 | + return err; |
| 575 | + |
| 576 | + if (dac->gpio_ldac) |
| 577 | + return ad3552r_trigger_hw_ldac(dac->gpio_ldac); |
| 578 | + |
| 579 | + return ad3552r_write_reg(dac, AD3552R_REG_ADDR_SW_LDAC_24B, mask); |
| 580 | +} |
| 581 | + |
| 582 | +static irqreturn_t ad3552r_trigger_handler(int irq, void *p) |
| 583 | +{ |
| 584 | + struct iio_poll_func *pf = p; |
| 585 | + struct iio_dev *indio_dev = pf->indio_dev; |
| 586 | + struct iio_buffer *buf = indio_dev->buffer; |
| 587 | + struct ad3552r_desc *dac = iio_priv(indio_dev); |
| 588 | + /* Maximum size of a scan */ |
| 589 | + u8 buff[AD3552R_NUM_CH * AD3552R_MAX_REG_SIZE]; |
| 590 | + int err; |
| 591 | + |
| 592 | + memset(buff, 0, sizeof(buff)); |
| 593 | + err = iio_pop_from_buffer(buf, buff); |
| 594 | + if (err) |
| 595 | + goto end; |
| 596 | + |
| 597 | + mutex_lock(&dac->lock); |
| 598 | + ad3552r_write_codes(dac, *indio_dev->active_scan_mask, buff); |
| 599 | + mutex_unlock(&dac->lock); |
| 600 | +end: |
| 601 | + iio_trigger_notify_done(indio_dev->trig); |
| 602 | + |
| 603 | + return IRQ_HANDLED; |
| 604 | +} |
| 605 | + |
| 606 | +static int ad3552r_check_scratch_pad(struct ad3552r_desc *dac) |
| 607 | +{ |
| 608 | + const u16 val1 = AD3552R_SCRATCH_PAD_TEST_VAL1; |
| 609 | + const u16 val2 = AD3552R_SCRATCH_PAD_TEST_VAL2; |
| 610 | + u16 val; |
| 611 | + int err; |
| 612 | + |
| 613 | + err = ad3552r_write_reg(dac, AD3552R_REG_ADDR_SCRATCH_PAD, val1); |
| 614 | + if (err < 0) |
| 615 | + return err; |
| 616 | + |
| 617 | + err = ad3552r_read_reg(dac, AD3552R_REG_ADDR_SCRATCH_PAD, &val); |
| 618 | + if (err < 0) |
| 619 | + return err; |
| 620 | + |
| 621 | + if (val1 != val) |
| 622 | + return -ENODEV; |
| 623 | + |
| 624 | + err = ad3552r_write_reg(dac, AD3552R_REG_ADDR_SCRATCH_PAD, val2); |
| 625 | + if (err < 0) |
| 626 | + return err; |
| 627 | + |
| 628 | + err = ad3552r_read_reg(dac, AD3552R_REG_ADDR_SCRATCH_PAD, &val); |
| 629 | + if (err < 0) |
| 630 | + return err; |
| 631 | + |
| 632 | + if (val2 != val) |
| 633 | + return -ENODEV; |
| 634 | + |
| 635 | + return 0; |
| 636 | +} |
| 637 | + |
| 638 | +struct reg_addr_pool { |
| 639 | + struct ad3552r_desc *dac; |
| 640 | + u8 addr; |
| 641 | +}; |
| 642 | + |
| 643 | +static int ad3552r_read_reg_wrapper(struct reg_addr_pool *addr) |
| 644 | +{ |
| 645 | + int err; |
| 646 | + u16 val; |
| 647 | + |
| 648 | + err = ad3552r_read_reg(addr->dac, addr->addr, &val); |
| 649 | + if (err) |
| 650 | + return err; |
| 651 | + |
| 652 | + return val; |
| 653 | +} |
| 654 | + |
| 655 | +static int ad3552r_reset(struct ad3552r_desc *dac) |
| 656 | +{ |
| 657 | + struct reg_addr_pool addr; |
| 658 | + int ret; |
| 659 | + u16 val; |
| 660 | + |
| 661 | + dac->gpio_reset = devm_gpiod_get_optional(&dac->spi->dev, "reset", |
| 662 | + GPIOD_OUT_LOW); |
| 663 | + if (IS_ERR(dac->gpio_reset)) |
| 664 | + return dev_err_probe(&dac->spi->dev, PTR_ERR(dac->gpio_reset), |
| 665 | + "Error while getting gpio reset"); |
| 666 | + |
| 667 | + if (dac->gpio_reset) { |
| 668 | + /* Perform hardware reset */ |
| 669 | + usleep_range(10, 20); |
| 670 | + gpiod_set_value_cansleep(dac->gpio_reset, 1); |
| 671 | + } else { |
| 672 | + /* Perform software reset if no GPIO provided */ |
| 673 | + ret = ad3552r_update_reg_field(dac, |
| 674 | + AD3552R_REG_ADDR_INTERFACE_CONFIG_A, |
| 675 | + AD3552R_MASK_SOFTWARE_RESET, |
| 676 | + AD3552R_MASK_SOFTWARE_RESET); |
| 677 | + if (ret < 0) |
| 678 | + return ret; |
| 679 | + |
| 680 | + } |
| 681 | + |
| 682 | + addr.dac = dac; |
| 683 | + addr.addr = AD3552R_REG_ADDR_INTERFACE_CONFIG_B; |
| 684 | + ret = readx_poll_timeout(ad3552r_read_reg_wrapper, &addr, val, |
| 685 | + val == AD3552R_DEFAULT_CONFIG_B_VALUE || |
| 686 | + val < 0, |
| 687 | + 5000, 50000); |
| 688 | + if (val < 0) |
| 689 | + ret = val; |
| 690 | + if (ret) { |
| 691 | + dev_err(&dac->spi->dev, "Error while resetting"); |
| 692 | + return ret; |
| 693 | + } |
| 694 | + |
| 695 | + ret = readx_poll_timeout(ad3552r_read_reg_wrapper, &addr, val, |
| 696 | + !(val & AD3552R_MASK_INTERFACE_NOT_READY) || |
| 697 | + val < 0, |
| 698 | + 5000, 50000); |
| 699 | + if (val < 0) |
| 700 | + ret = val; |
| 701 | + if (ret) { |
| 702 | + dev_err(&dac->spi->dev, "Error while resetting"); |
| 703 | + return ret; |
| 704 | + } |
| 705 | + |
| 706 | + return ad3552r_update_reg_field(dac, |
| 707 | + addr_mask_map[AD3552R_ADDR_ASCENSION][0], |
| 708 | + addr_mask_map[AD3552R_ADDR_ASCENSION][1], |
| 709 | + val); |
| 710 | +} |
| 711 | + |
| 712 | +static void ad3552r_get_custom_range(struct ad3552r_desc *dac, s32 i, s32 *v_min, |
| 713 | + s32 *v_max) |
| 714 | +{ |
| 715 | + s64 vref, tmp, common, offset, gn, gp; |
| 716 | + /* |
| 717 | + * From datasheet formula (In Volts): |
| 718 | + * Vmin = 2.5 + [(GainN + Offset / 1024) * 2.5 * Rfb * 1.03] |
| 719 | + * Vmax = 2.5 - [(GainP + Offset / 1024) * 2.5 * Rfb * 1.03] |
| 720 | + * Calculus are converted to milivolts |
| 721 | + */ |
| 722 | + vref = 2500; |
| 723 | + /* 2.5 * 1.03 * 1000 (To mV) */ |
| 724 | + common = 2575 * dac->ch_data[i].rfb; |
| 725 | + offset = dac->ch_data[i].gain_offset; |
| 726 | + |
| 727 | + gn = gains_scaling_table[dac->ch_data[i].n]; |
| 728 | + tmp = (1024 * gn + AD3552R_GAIN_SCALE * offset) * common; |
| 729 | + tmp = div_s64(tmp, 1024 * AD3552R_GAIN_SCALE); |
| 730 | + *v_max = vref + tmp; |
| 731 | + |
| 732 | + gp = gains_scaling_table[dac->ch_data[i].p]; |
| 733 | + tmp = (1024 * gp - AD3552R_GAIN_SCALE * offset) * common; |
| 734 | + tmp = div_s64(tmp, 1024 * AD3552R_GAIN_SCALE); |
| 735 | + *v_min = vref - tmp; |
| 736 | +} |
| 737 | + |
| 738 | +static void ad3552r_calc_gain_and_offset(struct ad3552r_desc *dac, s32 ch) |
| 739 | +{ |
| 740 | + s32 idx, v_max, v_min, span, rem; |
| 741 | + s64 tmp; |
| 742 | + |
| 743 | + if (dac->ch_data[ch].range_override) { |
| 744 | + ad3552r_get_custom_range(dac, ch, &v_min, &v_max); |
| 745 | + } else { |
| 746 | + /* Normal range */ |
| 747 | + idx = dac->ch_data[ch].range; |
| 748 | + if (dac->chip_id == AD3542R_ID) { |
| 749 | + v_min = ad3542r_ch_ranges[idx][0]; |
| 750 | + v_max = ad3542r_ch_ranges[idx][1]; |
| 751 | + } else { |
| 752 | + v_min = ad3552r_ch_ranges[idx][0]; |
| 753 | + v_max = ad3552r_ch_ranges[idx][1]; |
| 754 | + } |
| 755 | + } |
| 756 | + |
| 757 | + /* |
| 758 | + * From datasheet formula: |
| 759 | + * Vout = Span * (D / 65536) + Vmin |
| 760 | + * Converted to scale and offset: |
| 761 | + * Scale = Span / 65536 |
| 762 | + * Offset = 65536 * Vmin / Span |
| 763 | + * |
| 764 | + * Reminders are in micros in order to be printed as |
| 765 | + * IIO_VAL_INT_PLUS_MICRO |
| 766 | + */ |
| 767 | + span = v_max - v_min; |
| 768 | + dac->ch_data[ch].scale_int = div_s64_rem(span, 65536, &rem); |
| 769 | + /* Do operations in microvolts */ |
| 770 | + dac->ch_data[ch].scale_dec = DIV_ROUND_CLOSEST((s64)rem * 1000000, |
| 771 | + 65536); |
| 772 | + |
| 773 | + dac->ch_data[ch].offset_int = div_s64_rem(v_min * 65536, span, &rem); |
| 774 | + tmp = (s64)rem * 1000000; |
| 775 | + dac->ch_data[ch].offset_dec = div_s64(tmp, span); |
| 776 | +} |
| 777 | + |
| 778 | +static int ad3552r_find_range(u16 id, s32 *vals) |
| 779 | +{ |
| 780 | + int i, len; |
| 781 | + const s32 (*ranges)[2]; |
| 782 | + |
| 783 | + if (id == AD3542R_ID) { |
| 784 | + len = ARRAY_SIZE(ad3542r_ch_ranges); |
| 785 | + ranges = ad3542r_ch_ranges; |
| 786 | + } else { |
| 787 | + len = ARRAY_SIZE(ad3552r_ch_ranges); |
| 788 | + ranges = ad3552r_ch_ranges; |
| 789 | + } |
| 790 | + |
| 791 | + for (i = 0; i < len; i++) |
| 792 | + if (vals[0] == ranges[i][0] * 1000 && |
| 793 | + vals[1] == ranges[i][1] * 1000) |
| 794 | + return i; |
| 795 | + |
| 796 | + return -EINVAL; |
| 797 | +} |
| 798 | + |
| 799 | +static int ad3552r_configure_custom_gain(struct ad3552r_desc *dac, |
| 800 | + struct fwnode_handle *child, |
| 801 | + u32 ch) |
| 802 | +{ |
| 803 | + struct device *dev = &dac->spi->dev; |
| 804 | + struct fwnode_handle *gain_child; |
| 805 | + u32 val; |
| 806 | + int err; |
| 807 | + u8 addr; |
| 808 | + u16 reg = 0, offset; |
| 809 | + |
| 810 | + gain_child = fwnode_get_named_child_node(child, |
| 811 | + "custom-output-range-config"); |
| 812 | + if (IS_ERR(gain_child)) { |
| 813 | + dev_err(dev, |
| 814 | + "mandatory custom-output-range-config property missing\n"); |
| 815 | + return PTR_ERR(gain_child); |
| 816 | + } |
| 817 | + |
| 818 | + dac->ch_data[ch].range_override = 1; |
| 819 | + reg |= ad3552r_field_prep(1, AD3552R_MASK_CH_RANGE_OVERRIDE); |
| 820 | + |
| 821 | + err = fwnode_property_read_u32(gain_child, "adi,gain-scaling-p", &val); |
| 822 | + if (err) { |
| 823 | + dev_err(dev, "mandatory adi,gain-scaling-p property missing\n"); |
| 824 | + goto put_child; |
| 825 | + } |
| 826 | + reg |= ad3552r_field_prep(val, AD3552R_MASK_CH_GAIN_SCALING_P); |
| 827 | + dac->ch_data[ch].p = val; |
| 828 | + |
| 829 | + err = fwnode_property_read_u32(gain_child, "adi,gain-scaling-n", &val); |
| 830 | + if (err) { |
| 831 | + dev_err(dev, "mandatory adi,gain-scaling-n property missing\n"); |
| 832 | + goto put_child; |
| 833 | + } |
| 834 | + reg |= ad3552r_field_prep(val, AD3552R_MASK_CH_GAIN_SCALING_N); |
| 835 | + dac->ch_data[ch].n = val; |
| 836 | + |
| 837 | + err = fwnode_property_read_u32(gain_child, "adi,rfb-ohms", &val); |
| 838 | + if (err) { |
| 839 | + dev_err(dev, "mandatory adi,rfb-ohms property missing\n"); |
| 840 | + goto put_child; |
| 841 | + } |
| 842 | + dac->ch_data[ch].rfb = val; |
| 843 | + |
| 844 | + err = fwnode_property_read_u32(gain_child, "adi,gain-offset", &val); |
| 845 | + if (err) { |
| 846 | + dev_err(dev, "mandatory adi,gain-offset property missing\n"); |
| 847 | + goto put_child; |
| 848 | + } |
| 849 | + dac->ch_data[ch].gain_offset = val; |
| 850 | + |
| 851 | + offset = abs((s32)val); |
| 852 | + reg |= ad3552r_field_prep((offset >> 8), AD3552R_MASK_CH_OFFSET_BIT_8); |
| 853 | + |
| 854 | + reg |= ad3552r_field_prep((s32)val < 0, AD3552R_MASK_CH_OFFSET_POLARITY); |
| 855 | + addr = AD3552R_REG_ADDR_CH_GAIN(ch); |
| 856 | + err = ad3552r_write_reg(dac, addr, |
| 857 | + offset & AD3552R_MASK_CH_OFFSET_BITS_0_7); |
| 858 | + if (err) { |
| 859 | + dev_err(dev, "Error writing register\n"); |
| 860 | + goto put_child; |
| 861 | + } |
| 862 | + |
| 863 | + err = ad3552r_write_reg(dac, addr, reg); |
| 864 | + if (err) { |
| 865 | + dev_err(dev, "Error writing register\n"); |
| 866 | + goto put_child; |
| 867 | + } |
| 868 | + |
| 869 | +put_child: |
| 870 | + fwnode_handle_put(gain_child); |
| 871 | + |
| 872 | + return err; |
| 873 | +} |
| 874 | + |
| 875 | +static void ad3552r_reg_disable(void *reg) |
| 876 | +{ |
| 877 | + regulator_disable(reg); |
| 878 | +} |
| 879 | + |
| 880 | +static int ad3552r_configure_device(struct ad3552r_desc *dac) |
| 881 | +{ |
| 882 | + struct device *dev = &dac->spi->dev; |
| 883 | + struct fwnode_handle *child; |
| 884 | + struct regulator *vref; |
| 885 | + int err, cnt = 0, voltage, delta = 100000; |
| 886 | + u32 vals[2], val, ch; |
| 887 | + |
| 888 | + dac->gpio_ldac = devm_gpiod_get_optional(dev, "ldac", GPIOD_OUT_HIGH); |
| 889 | + if (IS_ERR(dac->gpio_ldac)) |
| 890 | + return dev_err_probe(dev, PTR_ERR(dac->gpio_ldac), |
| 891 | + "Error getting gpio ldac"); |
| 892 | + |
| 893 | + vref = devm_regulator_get_optional(dev, "vref"); |
| 894 | + if (IS_ERR(vref)) { |
| 895 | + if (PTR_ERR(vref) != -ENODEV) |
| 896 | + return dev_err_probe(dev, PTR_ERR(vref), |
| 897 | + "Error getting vref"); |
| 898 | + |
| 899 | + if (device_property_read_bool(dev, "adi,vref-out-en")) |
| 900 | + val = AD3552R_INTERNAL_VREF_PIN_2P5V; |
| 901 | + else |
| 902 | + val = AD3552R_INTERNAL_VREF_PIN_FLOATING; |
| 903 | + } else { |
| 904 | + err = regulator_enable(vref); |
| 905 | + if (err) { |
| 906 | + dev_err(dev, "Failed to enable external vref supply\n"); |
| 907 | + return err; |
| 908 | + } |
| 909 | + |
| 910 | + err = devm_add_action_or_reset(dev, ad3552r_reg_disable, vref); |
| 911 | + if (err) { |
| 912 | + regulator_disable(vref); |
| 913 | + return err; |
| 914 | + } |
| 915 | + |
| 916 | + voltage = regulator_get_voltage(vref); |
| 917 | + if (voltage > 2500000 + delta || voltage < 2500000 - delta) { |
| 918 | + dev_warn(dev, "vref-supply must be 2.5V"); |
| 919 | + return -EINVAL; |
| 920 | + } |
| 921 | + val = AD3552R_EXTERNAL_VREF_PIN_INPUT; |
| 922 | + } |
| 923 | + |
| 924 | + err = ad3552r_update_reg_field(dac, |
| 925 | + addr_mask_map[AD3552R_VREF_SELECT][0], |
| 926 | + addr_mask_map[AD3552R_VREF_SELECT][1], |
| 927 | + val); |
| 928 | + if (err) |
| 929 | + return err; |
| 930 | + |
| 931 | + err = device_property_read_u32(dev, "adi,sdo-drive-strength", &val); |
| 932 | + if (!err) { |
| 933 | + if (val > 3) { |
| 934 | + dev_err(dev, "adi,sdo-drive-strength must be less than 4\n"); |
| 935 | + return -EINVAL; |
| 936 | + } |
| 937 | + |
| 938 | + err = ad3552r_update_reg_field(dac, |
| 939 | + addr_mask_map[AD3552R_SDO_DRIVE_STRENGTH][0], |
| 940 | + addr_mask_map[AD3552R_SDO_DRIVE_STRENGTH][1], |
| 941 | + val); |
| 942 | + if (err) |
| 943 | + return err; |
| 944 | + } |
| 945 | + |
| 946 | + dac->num_ch = device_get_child_node_count(dev); |
| 947 | + if (!dac->num_ch) { |
| 948 | + dev_err(dev, "No channels defined\n"); |
| 949 | + return -ENODEV; |
| 950 | + } |
| 951 | + |
| 952 | + device_for_each_child_node(dev, child) { |
| 953 | + err = fwnode_property_read_u32(child, "reg", &ch); |
| 954 | + if (err) { |
| 955 | + dev_err(dev, "mandatory reg property missing\n"); |
| 956 | + goto put_child; |
| 957 | + } |
| 958 | + if (ch >= AD3552R_NUM_CH) { |
| 959 | + dev_err(dev, "reg must be less than %d\n", |
| 960 | + AD3552R_NUM_CH); |
| 961 | + err = -EINVAL; |
| 962 | + goto put_child; |
| 963 | + } |
| 964 | + |
| 965 | + if (fwnode_property_present(child, "adi,output-range-microvolt")) { |
| 966 | + err = fwnode_property_read_u32_array(child, |
| 967 | + "adi,output-range-microvolt", |
| 968 | + vals, |
| 969 | + 2); |
| 970 | + if (err) { |
| 971 | + dev_err(dev, |
| 972 | + "adi,output-range-microvolt property could not be parsed\n"); |
| 973 | + goto put_child; |
| 974 | + } |
| 975 | + |
| 976 | + err = ad3552r_find_range(dac->chip_id, vals); |
| 977 | + if (err < 0) { |
| 978 | + dev_err(dev, |
| 979 | + "Invalid adi,output-range-microvolt value\n"); |
| 980 | + goto put_child; |
| 981 | + } |
| 982 | + val = err; |
| 983 | + err = ad3552r_set_ch_value(dac, |
| 984 | + AD3552R_CH_OUTPUT_RANGE_SEL, |
| 985 | + ch, val); |
| 986 | + if (err) |
| 987 | + goto put_child; |
| 988 | + |
| 989 | + dac->ch_data[ch].range = val; |
| 990 | + } else if (dac->chip_id == AD3542R_ID) { |
| 991 | + dev_err(dev, |
| 992 | + "adi,output-range-microvolt is required for ad3542r\n"); |
| 993 | + err = -EINVAL; |
| 994 | + goto put_child; |
| 995 | + } else { |
| 996 | + err = ad3552r_configure_custom_gain(dac, child, ch); |
| 997 | + if (err) |
| 998 | + goto put_child; |
| 999 | + } |
| 1000 | + |
| 1001 | + ad3552r_calc_gain_and_offset(dac, ch); |
| 1002 | + dac->enabled_ch |= BIT(ch); |
| 1003 | + |
| 1004 | + err = ad3552r_set_ch_value(dac, AD3552R_CH_SELECT, ch, 1); |
| 1005 | + if (err < 0) |
| 1006 | + goto put_child; |
| 1007 | + |
| 1008 | + dac->channels[cnt] = AD3552R_CH_DAC(ch); |
| 1009 | + ++cnt; |
| 1010 | + |
| 1011 | + } |
| 1012 | + |
| 1013 | + /* Disable unused channels */ |
| 1014 | + for_each_clear_bit(ch, &dac->enabled_ch, AD3552R_NUM_CH) { |
| 1015 | + err = ad3552r_set_ch_value(dac, AD3552R_CH_AMPLIFIER_POWERDOWN, |
| 1016 | + ch, 1); |
| 1017 | + if (err) |
| 1018 | + return err; |
| 1019 | + } |
| 1020 | + |
| 1021 | + dac->num_ch = cnt; |
| 1022 | + |
| 1023 | + return 0; |
| 1024 | +put_child: |
| 1025 | + fwnode_handle_put(child); |
| 1026 | + |
| 1027 | + return err; |
| 1028 | +} |
| 1029 | + |
| 1030 | +static int ad3552r_init(struct ad3552r_desc *dac) |
| 1031 | +{ |
| 1032 | + int err; |
| 1033 | + u16 val, id; |
| 1034 | + |
| 1035 | + err = ad3552r_reset(dac); |
| 1036 | + if (err) { |
| 1037 | + dev_err(&dac->spi->dev, "Reset failed\n"); |
| 1038 | + return err; |
| 1039 | + } |
| 1040 | + |
| 1041 | + err = ad3552r_check_scratch_pad(dac); |
| 1042 | + if (err) { |
| 1043 | + dev_err(&dac->spi->dev, "Scratch pad test failed\n"); |
| 1044 | + return err; |
| 1045 | + } |
| 1046 | + |
| 1047 | + err = ad3552r_read_reg(dac, AD3552R_REG_ADDR_PRODUCT_ID_L, &val); |
| 1048 | + if (err) { |
| 1049 | + dev_err(&dac->spi->dev, "Fail read PRODUCT_ID_L\n"); |
| 1050 | + return err; |
| 1051 | + } |
| 1052 | + |
| 1053 | + id = val; |
| 1054 | + err = ad3552r_read_reg(dac, AD3552R_REG_ADDR_PRODUCT_ID_H, &val); |
| 1055 | + if (err) { |
| 1056 | + dev_err(&dac->spi->dev, "Fail read PRODUCT_ID_H\n"); |
| 1057 | + return err; |
| 1058 | + } |
| 1059 | + |
| 1060 | + id |= val << 8; |
| 1061 | + if (id != dac->chip_id) { |
| 1062 | + dev_err(&dac->spi->dev, "Product id not matching\n"); |
| 1063 | + return -ENODEV; |
| 1064 | + } |
| 1065 | + |
| 1066 | + return ad3552r_configure_device(dac); |
| 1067 | +} |
| 1068 | + |
| 1069 | +static int ad3552r_probe(struct spi_device *spi) |
| 1070 | +{ |
| 1071 | + const struct spi_device_id *id = spi_get_device_id(spi); |
| 1072 | + struct ad3552r_desc *dac; |
| 1073 | + struct iio_dev *indio_dev; |
| 1074 | + int err; |
| 1075 | + |
| 1076 | + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*dac)); |
| 1077 | + if (!indio_dev) |
| 1078 | + return -ENOMEM; |
| 1079 | + |
| 1080 | + dac = iio_priv(indio_dev); |
| 1081 | + dac->spi = spi; |
| 1082 | + dac->chip_id = id->driver_data; |
| 1083 | + |
| 1084 | + mutex_init(&dac->lock); |
| 1085 | + |
| 1086 | + err = ad3552r_init(dac); |
| 1087 | + if (err) |
| 1088 | + return err; |
| 1089 | + |
| 1090 | + /* Config triggered buffer device */ |
| 1091 | + if (dac->chip_id == AD3552R_ID) |
| 1092 | + indio_dev->name = "ad3552r"; |
| 1093 | + else |
| 1094 | + indio_dev->name = "ad3542r"; |
| 1095 | + indio_dev->dev.parent = &spi->dev; |
| 1096 | + indio_dev->info = &ad3552r_iio_info; |
| 1097 | + indio_dev->num_channels = dac->num_ch; |
| 1098 | + indio_dev->channels = dac->channels; |
| 1099 | + indio_dev->modes = INDIO_DIRECT_MODE; |
| 1100 | + |
| 1101 | + err = devm_iio_triggered_buffer_setup_ext(&indio_dev->dev, indio_dev, NULL, |
| 1102 | + &ad3552r_trigger_handler, |
| 1103 | + IIO_BUFFER_DIRECTION_OUT, |
| 1104 | + NULL, |
| 1105 | + NULL); |
| 1106 | + if (err) |
| 1107 | + return err; |
| 1108 | + |
| 1109 | + return devm_iio_device_register(&spi->dev, indio_dev); |
| 1110 | +} |
| 1111 | + |
| 1112 | +static const struct spi_device_id ad3552r_id[] = { |
| 1113 | + { "ad3542r", AD3542R_ID }, |
| 1114 | + { "ad3552r", AD3552R_ID }, |
| 1115 | + { } |
| 1116 | +}; |
| 1117 | +MODULE_DEVICE_TABLE(spi, ad3552r_id); |
| 1118 | + |
| 1119 | +static const struct of_device_id ad3552r_of_match[] = { |
| 1120 | + { .compatible = "adi,ad3542r"}, |
| 1121 | + { .compatible = "adi,ad3552r"}, |
| 1122 | + { } |
| 1123 | +}; |
| 1124 | +MODULE_DEVICE_TABLE(of, ad3552r_of_match); |
| 1125 | + |
| 1126 | +static struct spi_driver ad3552r_driver = { |
| 1127 | + .driver = { |
| 1128 | + .name = "ad3552r", |
| 1129 | + .of_match_table = ad3552r_of_match, |
| 1130 | + }, |
| 1131 | + .probe = ad3552r_probe, |
| 1132 | + .id_table = ad3552r_id |
| 1133 | +}; |
| 1134 | +module_spi_driver(ad3552r_driver); |
| 1135 | + |
| 1136 | +MODULE_AUTHOR("Mihail Chindris <mihail.chindris@analog.com>"); |
| 1137 | +MODULE_DESCRIPTION("Analog Device AD3552R DAC"); |
| 1138 | +MODULE_LICENSE("GPL v2"); |