^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * AD5758 Digital to analog converters driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2018 Analog Devices Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * TODO: Currently CRC is not supported in this driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/bsearch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/property.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* AD5758 registers definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define AD5758_NOP 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define AD5758_DAC_INPUT 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define AD5758_DAC_OUTPUT 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define AD5758_CLEAR_CODE 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define AD5758_USER_GAIN 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define AD5758_USER_OFFSET 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define AD5758_DAC_CONFIG 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define AD5758_SW_LDAC 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define AD5758_KEY 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define AD5758_GP_CONFIG1 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define AD5758_GP_CONFIG2 0x0A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define AD5758_DCDC_CONFIG1 0x0B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define AD5758_DCDC_CONFIG2 0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define AD5758_WDT_CONFIG 0x0F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define AD5758_DIGITAL_DIAG_CONFIG 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define AD5758_ADC_CONFIG 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define AD5758_FAULT_PIN_CONFIG 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define AD5758_TWO_STAGE_READBACK_SELECT 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define AD5758_DIGITAL_DIAG_RESULTS 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define AD5758_ANALOG_DIAG_RESULTS 0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define AD5758_STATUS 0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define AD5758_CHIP_ID 0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define AD5758_FREQ_MONITOR 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define AD5758_DEVICE_ID_0 0x19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define AD5758_DEVICE_ID_1 0x1A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define AD5758_DEVICE_ID_2 0x1B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define AD5758_DEVICE_ID_3 0x1C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* AD5758_DAC_CONFIG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define AD5758_DAC_CONFIG_RANGE_MSK GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define AD5758_DAC_CONFIG_RANGE_MODE(x) (((x) & 0xF) << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define AD5758_DAC_CONFIG_INT_EN_MSK BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define AD5758_DAC_CONFIG_INT_EN_MODE(x) (((x) & 0x1) << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define AD5758_DAC_CONFIG_OUT_EN_MSK BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define AD5758_DAC_CONFIG_OUT_EN_MODE(x) (((x) & 0x1) << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define AD5758_DAC_CONFIG_SR_EN_MSK BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define AD5758_DAC_CONFIG_SR_EN_MODE(x) (((x) & 0x1) << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define AD5758_DAC_CONFIG_SR_CLOCK_MSK GENMASK(12, 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define AD5758_DAC_CONFIG_SR_CLOCK_MODE(x) (((x) & 0xF) << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define AD5758_DAC_CONFIG_SR_STEP_MSK GENMASK(15, 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define AD5758_DAC_CONFIG_SR_STEP_MODE(x) (((x) & 0x7) << 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* AD5758_KEY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define AD5758_KEY_CODE_RESET_1 0x15FA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define AD5758_KEY_CODE_RESET_2 0xAF51
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define AD5758_KEY_CODE_SINGLE_ADC_CONV 0x1ADC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define AD5758_KEY_CODE_RESET_WDT 0x0D06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define AD5758_KEY_CODE_CALIB_MEM_REFRESH 0xFCBA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* AD5758_DCDC_CONFIG1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define AD5758_DCDC_CONFIG1_DCDC_VPROG_MSK GENMASK(4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define AD5758_DCDC_CONFIG1_DCDC_VPROG_MODE(x) (((x) & 0x1F) << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define AD5758_DCDC_CONFIG1_DCDC_MODE_MSK GENMASK(6, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define AD5758_DCDC_CONFIG1_DCDC_MODE_MODE(x) (((x) & 0x3) << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* AD5758_DCDC_CONFIG2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define AD5758_DCDC_CONFIG2_ILIMIT_MSK GENMASK(3, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define AD5758_DCDC_CONFIG2_ILIMIT_MODE(x) (((x) & 0x7) << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define AD5758_DCDC_CONFIG2_INTR_SAT_3WI_MSK BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define AD5758_DCDC_CONFIG2_BUSY_3WI_MSK BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* AD5758_DIGITAL_DIAG_RESULTS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define AD5758_CAL_MEM_UNREFRESHED_MSK BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* AD5758_ADC_CONFIG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define AD5758_ADC_CONFIG_PPC_BUF_EN(x) (((x) & 0x1) << 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define AD5758_ADC_CONFIG_PPC_BUF_MSK BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define AD5758_WR_FLAG_MSK(x) (0x80 | ((x) & 0x1F))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define AD5758_FULL_SCALE_MICRO 65535000000ULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct ad5758_range {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * struct ad5758_state - driver instance specific data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * @spi: spi_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * @lock: mutex lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * @gpio_reset: gpio descriptor for the reset line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * @out_range: struct which stores the output range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * @dc_dc_mode: variable which stores the mode of operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * @dc_dc_ilim: variable which stores the dc-to-dc converter current limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * @slew_time: variable which stores the target slew time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * @pwr_down: variable which contains whether a channel is powered down or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * @d32: spi transfer buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct ad5758_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct spi_device *spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct gpio_desc *gpio_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct ad5758_range out_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) unsigned int dc_dc_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) unsigned int dc_dc_ilim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) unsigned int slew_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) bool pwr_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) __be32 d32[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * Output ranges corresponding to bits [3:0] from DAC_CONFIG register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * 0000: 0 V to 5 V voltage range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * 0001: 0 V to 10 V voltage range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * 0010: ±5 V voltage range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * 0011: ±10 V voltage range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * 1000: 0 mA to 20 mA current range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * 1001: 0 mA to 24 mA current range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * 1010: 4 mA to 20 mA current range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * 1011: ±20 mA current range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * 1100: ±24 mA current range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * 1101: -1 mA to +22 mA current range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) enum ad5758_output_range {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) AD5758_RANGE_0V_5V,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) AD5758_RANGE_0V_10V,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) AD5758_RANGE_PLUSMINUS_5V,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) AD5758_RANGE_PLUSMINUS_10V,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) AD5758_RANGE_0mA_20mA = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) AD5758_RANGE_0mA_24mA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) AD5758_RANGE_4mA_24mA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) AD5758_RANGE_PLUSMINUS_20mA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) AD5758_RANGE_PLUSMINUS_24mA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) AD5758_RANGE_MINUS_1mA_PLUS_22mA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) enum ad5758_dc_dc_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) AD5758_DCDC_MODE_POWER_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) AD5758_DCDC_MODE_DPC_CURRENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) AD5758_DCDC_MODE_DPC_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) AD5758_DCDC_MODE_PPC_CURRENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static const struct ad5758_range ad5758_voltage_range[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) { AD5758_RANGE_0V_5V, 0, 5000000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) { AD5758_RANGE_0V_10V, 0, 10000000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) { AD5758_RANGE_PLUSMINUS_5V, -5000000, 5000000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) { AD5758_RANGE_PLUSMINUS_10V, -10000000, 10000000 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static const struct ad5758_range ad5758_current_range[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) { AD5758_RANGE_0mA_20mA, 0, 20000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) { AD5758_RANGE_0mA_24mA, 0, 24000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) { AD5758_RANGE_4mA_24mA, 4, 24000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) { AD5758_RANGE_PLUSMINUS_20mA, -20000, 20000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) { AD5758_RANGE_PLUSMINUS_24mA, -24000, 24000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) { AD5758_RANGE_MINUS_1mA_PLUS_22mA, -1000, 22000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static const int ad5758_sr_clk[16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 240000, 200000, 150000, 128000, 64000, 32000, 16000, 8000, 4000, 2000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 1000, 512, 256, 128, 64, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static const int ad5758_sr_step[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 4, 12, 64, 120, 256, 500, 1820, 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static const int ad5758_dc_dc_ilim[6] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 150000, 200000, 250000, 300000, 350000, 400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static int ad5758_spi_reg_read(struct ad5758_state *st, unsigned int addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct spi_transfer t[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .tx_buf = &st->d32[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .len = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .cs_change = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .tx_buf = &st->d32[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .rx_buf = &st->d32[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .len = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) st->d32[0] = cpu_to_be32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) (AD5758_WR_FLAG_MSK(AD5758_TWO_STAGE_READBACK_SELECT) << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) (addr << 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) st->d32[1] = cpu_to_be32(AD5758_WR_FLAG_MSK(AD5758_NOP) << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return (be32_to_cpu(st->d32[2]) >> 8) & 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static int ad5758_spi_reg_write(struct ad5758_state *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) unsigned int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) st->d32[0] = cpu_to_be32((AD5758_WR_FLAG_MSK(addr) << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ((val & 0xFFFF) << 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return spi_write(st->spi, &st->d32[0], sizeof(st->d32[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static int ad5758_spi_write_mask(struct ad5758_state *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) unsigned int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) unsigned long int mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) int regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) regval = ad5758_spi_reg_read(st, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (regval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) regval &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) regval |= val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return ad5758_spi_reg_write(st, addr, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int cmpfunc(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return *(int *)a - *(int *)b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static int ad5758_find_closest_match(const int *array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) unsigned int size, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (val <= array[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static int ad5758_wait_for_task_complete(struct ad5758_state *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) unsigned int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) unsigned int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ret = ad5758_spi_reg_read(st, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (!(ret & mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) usleep_range(100, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) } while (--timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) dev_err(&st->spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) "Error reading bit 0x%x in 0x%x register\n", mask, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static int ad5758_calib_mem_refresh(struct ad5758_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ret = ad5758_spi_reg_write(st, AD5758_KEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) AD5758_KEY_CODE_CALIB_MEM_REFRESH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) dev_err(&st->spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) "Failed to initiate a calibration memory refresh\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* Wait to allow time for the internal calibrations to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) AD5758_CAL_MEM_UNREFRESHED_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static int ad5758_soft_reset(struct ad5758_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) ret = ad5758_spi_reg_write(st, AD5758_KEY, AD5758_KEY_CODE_RESET_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ret = ad5758_spi_reg_write(st, AD5758_KEY, AD5758_KEY_CODE_RESET_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* Perform a software reset and wait at least 100us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) usleep_range(100, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static int ad5758_set_dc_dc_conv_mode(struct ad5758_state *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) enum ad5758_dc_dc_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * The ENABLE_PPC_BUFFERS bit must be set prior to enabling PPC current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (mode == AD5758_DCDC_MODE_PPC_CURRENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) ret = ad5758_spi_write_mask(st, AD5758_ADC_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) AD5758_ADC_CONFIG_PPC_BUF_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) AD5758_ADC_CONFIG_PPC_BUF_EN(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) ret = ad5758_spi_write_mask(st, AD5758_DCDC_CONFIG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) AD5758_DCDC_CONFIG1_DCDC_MODE_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) AD5758_DCDC_CONFIG1_DCDC_MODE_MODE(mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * Poll the BUSY_3WI bit in the DCDC_CONFIG2 register until it is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * This allows the 3-wire interface communication to complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) ret = ad5758_wait_for_task_complete(st, AD5758_DCDC_CONFIG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) AD5758_DCDC_CONFIG2_BUSY_3WI_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) st->dc_dc_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static int ad5758_set_dc_dc_ilim(struct ad5758_state *st, unsigned int ilim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ret = ad5758_spi_write_mask(st, AD5758_DCDC_CONFIG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) AD5758_DCDC_CONFIG2_ILIMIT_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) AD5758_DCDC_CONFIG2_ILIMIT_MODE(ilim));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * Poll the BUSY_3WI bit in the DCDC_CONFIG2 register until it is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * This allows the 3-wire interface communication to complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return ad5758_wait_for_task_complete(st, AD5758_DCDC_CONFIG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) AD5758_DCDC_CONFIG2_BUSY_3WI_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static int ad5758_slew_rate_set(struct ad5758_state *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) unsigned int sr_clk_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) unsigned int sr_step_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) unsigned int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) unsigned long int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) mask = AD5758_DAC_CONFIG_SR_EN_MSK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) AD5758_DAC_CONFIG_SR_CLOCK_MSK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) AD5758_DAC_CONFIG_SR_STEP_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) mode = AD5758_DAC_CONFIG_SR_EN_MODE(1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) AD5758_DAC_CONFIG_SR_STEP_MODE(sr_step_idx) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) AD5758_DAC_CONFIG_SR_CLOCK_MODE(sr_clk_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG, mask, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /* Wait to allow time for the internal calibrations to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) AD5758_CAL_MEM_UNREFRESHED_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static int ad5758_slew_rate_config(struct ad5758_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) unsigned int sr_clk_idx, sr_step_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) int i, res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) s64 diff_new, diff_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) u64 sr_step, calc_slew_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) sr_clk_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) sr_step_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) diff_old = S64_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * The slew time can be determined by using the formula:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * Slew Time = (Full Scale Out / (Step Size x Update Clk Freq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * where Slew time is expressed in microseconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * Given the desired slew time, the following algorithm determines the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * best match for the step size and the update clock frequency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) for (i = 0; i < ARRAY_SIZE(ad5758_sr_clk); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * Go through each valid update clock freq and determine a raw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * value for the step size by using the formula:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * Step Size = Full Scale Out / (Update Clk Freq * Slew Time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) sr_step = AD5758_FULL_SCALE_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) do_div(sr_step, ad5758_sr_clk[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) do_div(sr_step, st->slew_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * After a raw value for step size was determined, find the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * closest valid match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) res = ad5758_find_closest_match(ad5758_sr_step,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) ARRAY_SIZE(ad5758_sr_step),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) sr_step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* Calculate the slew time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) calc_slew_time = AD5758_FULL_SCALE_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) do_div(calc_slew_time, ad5758_sr_step[res]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) do_div(calc_slew_time, ad5758_sr_clk[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * Determine with how many microseconds the calculated slew time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * is different from the desired slew time and store the diff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * for the next iteration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) diff_new = abs(st->slew_time - calc_slew_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (diff_new < diff_old) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) diff_old = diff_new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) sr_clk_idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) sr_step_idx = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return ad5758_slew_rate_set(st, sr_clk_idx, sr_step_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static int ad5758_set_out_range(struct ad5758_state *st, int range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) AD5758_DAC_CONFIG_RANGE_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) AD5758_DAC_CONFIG_RANGE_MODE(range));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) /* Wait to allow time for the internal calibrations to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) AD5758_CAL_MEM_UNREFRESHED_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static int ad5758_internal_buffers_en(struct ad5758_state *st, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) AD5758_DAC_CONFIG_INT_EN_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) AD5758_DAC_CONFIG_INT_EN_MODE(enable));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /* Wait to allow time for the internal calibrations to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) AD5758_CAL_MEM_UNREFRESHED_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static int ad5758_reset(struct ad5758_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (st->gpio_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) gpiod_set_value(st->gpio_reset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) usleep_range(100, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) gpiod_set_value(st->gpio_reset, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) usleep_range(100, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /* Perform a software reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return ad5758_soft_reset(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) static int ad5758_reg_access(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) unsigned int writeval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) unsigned int *readval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct ad5758_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) mutex_lock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (readval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) ret = ad5758_spi_reg_read(st, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) mutex_unlock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) *readval = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) ret = ad5758_spi_reg_write(st, reg, writeval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) mutex_unlock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static int ad5758_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) int *val, int *val2, long info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct ad5758_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) int max, min, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) switch (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) mutex_lock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) ret = ad5758_spi_reg_read(st, AD5758_DAC_INPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) mutex_unlock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) *val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) min = st->out_range.min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) max = st->out_range.max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) *val = (max - min) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) *val2 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return IIO_VAL_FRACTIONAL_LOG2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) case IIO_CHAN_INFO_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) min = st->out_range.min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) max = st->out_range.max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) *val = ((min * (1 << 16)) / (max - min)) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static int ad5758_write_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) int val, int val2, long info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) struct ad5758_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) switch (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) mutex_lock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) ret = ad5758_spi_reg_write(st, AD5758_DAC_INPUT, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) mutex_unlock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static ssize_t ad5758_read_powerdown(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) uintptr_t priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) struct ad5758_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return sprintf(buf, "%d\n", st->pwr_down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static ssize_t ad5758_write_powerdown(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) uintptr_t priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct ad5758_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) bool pwr_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) unsigned int dac_config_mode, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) unsigned long int dac_config_msk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ret = kstrtobool(buf, &pwr_down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) mutex_lock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (pwr_down)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) val = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) dac_config_mode = AD5758_DAC_CONFIG_OUT_EN_MODE(val) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) AD5758_DAC_CONFIG_INT_EN_MODE(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) dac_config_msk = AD5758_DAC_CONFIG_OUT_EN_MSK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) AD5758_DAC_CONFIG_INT_EN_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) dac_config_msk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) dac_config_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) st->pwr_down = pwr_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) err_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) mutex_unlock(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return ret ? ret : len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static const struct iio_info ad5758_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) .read_raw = ad5758_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) .write_raw = ad5758_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) .debugfs_reg_access = &ad5758_reg_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static const struct iio_chan_spec_ext_info ad5758_ext_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) .name = "powerdown",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) .read = ad5758_read_powerdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) .write = ad5758_write_powerdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) .shared = IIO_SHARED_BY_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) #define AD5758_DAC_CHAN(_chan_type) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .type = (_chan_type), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_RAW) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) BIT(IIO_CHAN_INFO_SCALE) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) BIT(IIO_CHAN_INFO_OFFSET), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) .indexed = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) .output = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .ext_info = ad5758_ext_info, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static const struct iio_chan_spec ad5758_voltage_ch[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) AD5758_DAC_CHAN(IIO_VOLTAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) static const struct iio_chan_spec ad5758_current_ch[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) AD5758_DAC_CHAN(IIO_CURRENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) static bool ad5758_is_valid_mode(enum ad5758_dc_dc_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) case AD5758_DCDC_MODE_DPC_CURRENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) case AD5758_DCDC_MODE_DPC_VOLTAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) case AD5758_DCDC_MODE_PPC_CURRENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) static int ad5758_crc_disable(struct ad5758_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) unsigned int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) mask = (AD5758_WR_FLAG_MSK(AD5758_DIGITAL_DIAG_CONFIG) << 24) | 0x5C3A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) st->d32[0] = cpu_to_be32(mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return spi_write(st->spi, &st->d32[0], 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) static int ad5758_find_out_range(struct ad5758_state *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) const struct ad5758_range *range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) unsigned int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) int min, int max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if ((min == range[i].min) && (max == range[i].max)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) st->out_range.reg = range[i].reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) st->out_range.min = range[i].min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) st->out_range.max = range[i].max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) static int ad5758_parse_dt(struct ad5758_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) unsigned int tmp, tmparray[2], size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) const struct ad5758_range *range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) int *index, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) st->dc_dc_ilim = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) ret = device_property_read_u32(&st->spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) "adi,dc-dc-ilim-microamp", &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) dev_dbg(&st->spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) "Missing \"dc-dc-ilim-microamp\" property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) index = bsearch(&tmp, ad5758_dc_dc_ilim,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) ARRAY_SIZE(ad5758_dc_dc_ilim),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) sizeof(int), cmpfunc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (!index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) dev_dbg(&st->spi->dev, "dc-dc-ilim out of range\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) st->dc_dc_ilim = index - ad5758_dc_dc_ilim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) ret = device_property_read_u32(&st->spi->dev, "adi,dc-dc-mode",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) &st->dc_dc_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) dev_err(&st->spi->dev, "Missing \"dc-dc-mode\" property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (!ad5758_is_valid_mode(st->dc_dc_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (st->dc_dc_mode == AD5758_DCDC_MODE_DPC_VOLTAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) ret = device_property_read_u32_array(&st->spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) "adi,range-microvolt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) tmparray, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) dev_err(&st->spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) "Missing \"range-microvolt\" property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) range = ad5758_voltage_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) size = ARRAY_SIZE(ad5758_voltage_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) ret = device_property_read_u32_array(&st->spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) "adi,range-microamp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) tmparray, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) dev_err(&st->spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) "Missing \"range-microamp\" property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) range = ad5758_current_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) size = ARRAY_SIZE(ad5758_current_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) ret = ad5758_find_out_range(st, range, size, tmparray[0], tmparray[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) dev_err(&st->spi->dev, "range invalid\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) ret = device_property_read_u32(&st->spi->dev, "adi,slew-time-us", &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) dev_dbg(&st->spi->dev, "Missing \"slew-time-us\" property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) st->slew_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) st->slew_time = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static int ad5758_init(struct ad5758_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) int regval, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) st->gpio_reset = devm_gpiod_get_optional(&st->spi->dev, "reset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) GPIOD_OUT_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (IS_ERR(st->gpio_reset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return PTR_ERR(st->gpio_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) /* Disable CRC checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) ret = ad5758_crc_disable(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) /* Perform a reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) ret = ad5758_reset(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* Disable CRC checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) ret = ad5758_crc_disable(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /* Perform a calibration memory refresh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) ret = ad5758_calib_mem_refresh(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) regval = ad5758_spi_reg_read(st, AD5758_DIGITAL_DIAG_RESULTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (regval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) return regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) /* Clear all the error flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) ret = ad5758_spi_reg_write(st, AD5758_DIGITAL_DIAG_RESULTS, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) /* Set the dc-to-dc current limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) ret = ad5758_set_dc_dc_ilim(st, st->dc_dc_ilim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) /* Configure the dc-to-dc controller mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) ret = ad5758_set_dc_dc_conv_mode(st, st->dc_dc_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) /* Configure the output range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ret = ad5758_set_out_range(st, st->out_range.reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /* Enable Slew Rate Control, set the slew rate clock and step */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (st->slew_time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) ret = ad5758_slew_rate_config(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /* Power up the DAC and internal (INT) amplifiers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) ret = ad5758_internal_buffers_en(st, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) /* Enable VIOUT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) AD5758_DAC_CONFIG_OUT_EN_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) AD5758_DAC_CONFIG_OUT_EN_MODE(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) static int ad5758_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) struct ad5758_state *st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) spi_set_drvdata(spi, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) st->spi = spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) mutex_init(&st->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) indio_dev->name = spi_get_device_id(spi)->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) indio_dev->info = &ad5758_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) indio_dev->num_channels = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) ret = ad5758_parse_dt(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (st->dc_dc_mode == AD5758_DCDC_MODE_DPC_VOLTAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) indio_dev->channels = ad5758_voltage_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) indio_dev->channels = ad5758_current_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) ret = ad5758_init(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) dev_err(&spi->dev, "AD5758 init failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) return devm_iio_device_register(&st->spi->dev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) static const struct spi_device_id ad5758_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) { "ad5758", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) MODULE_DEVICE_TABLE(spi, ad5758_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) static const struct of_device_id ad5758_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) { .compatible = "adi,ad5758" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) MODULE_DEVICE_TABLE(of, ad5758_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) static struct spi_driver ad5758_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) .name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) .of_match_table = ad5758_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) .probe = ad5758_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) .id_table = ad5758_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) module_spi_driver(ad5758_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) MODULE_DESCRIPTION("Analog Devices AD5758 DAC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) MODULE_LICENSE("GPL v2");