Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");