From 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 13 May 2024 10:30:14 +0000 Subject: [PATCH] modify sin led gpio --- kernel/drivers/iio/dac/ad5758.c | 126 ++++++++++++++++++++++------------------- 1 files changed, 67 insertions(+), 59 deletions(-) diff --git a/kernel/drivers/iio/dac/ad5758.c b/kernel/drivers/iio/dac/ad5758.c index bd36333..bd9ac83 100644 --- a/kernel/drivers/iio/dac/ad5758.c +++ b/kernel/drivers/iio/dac/ad5758.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +// SPDX-License-Identifier: GPL-2.0 /* * AD5758 Digital to analog converters driver * @@ -11,7 +11,10 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/property.h> +#include <linux/of.h> +#include <linux/of_device.h> #include <linux/spi/spi.h> +#include <linux/gpio/consumer.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -71,8 +74,6 @@ #define AD5758_DCDC_CONFIG1_DCDC_VPROG_MODE(x) (((x) & 0x1F) << 0) #define AD5758_DCDC_CONFIG1_DCDC_MODE_MSK GENMASK(6, 5) #define AD5758_DCDC_CONFIG1_DCDC_MODE_MODE(x) (((x) & 0x3) << 5) -#define AD5758_DCDC_CONFIG1_PROT_SW_EN_MSK BIT(7) -#define AD5758_DCDC_CONFIG1_PROT_SW_EN_MODE(x) (((x) & 0x1) << 7) /* AD5758_DCDC_CONFIG2 */ #define AD5758_DCDC_CONFIG2_ILIMIT_MSK GENMASK(3, 1) @@ -83,21 +84,13 @@ /* AD5758_DIGITAL_DIAG_RESULTS */ #define AD5758_CAL_MEM_UNREFRESHED_MSK BIT(15) +/* AD5758_ADC_CONFIG */ +#define AD5758_ADC_CONFIG_PPC_BUF_EN(x) (((x) & 0x1) << 11) +#define AD5758_ADC_CONFIG_PPC_BUF_MSK BIT(11) + #define AD5758_WR_FLAG_MSK(x) (0x80 | ((x) & 0x1F)) #define AD5758_FULL_SCALE_MICRO 65535000000ULL - -/** - * struct ad5758_state - driver instance specific data - * @spi: spi_device - * @lock: mutex lock - * @out_range: struct which stores the output range - * @dc_dc_mode: variable which stores the mode of operation - * @dc_dc_ilim: variable which stores the dc-to-dc converter current limit - * @slew_time: variable which stores the target slew time - * @pwr_down: variable which contains whether a channel is powered down or not - * @data: spi transfer buffers - */ struct ad5758_range { int reg; @@ -105,9 +98,22 @@ int max; }; +/** + * struct ad5758_state - driver instance specific data + * @spi: spi_device + * @lock: mutex lock + * @gpio_reset: gpio descriptor for the reset line + * @out_range: struct which stores the output range + * @dc_dc_mode: variable which stores the mode of operation + * @dc_dc_ilim: variable which stores the dc-to-dc converter current limit + * @slew_time: variable which stores the target slew time + * @pwr_down: variable which contains whether a channel is powered down or not + * @d32: spi transfer buffers + */ struct ad5758_state { struct spi_device *spi; struct mutex lock; + struct gpio_desc *gpio_reset; struct ad5758_range out_range; unsigned int dc_dc_mode; unsigned int dc_dc_ilim; @@ -116,7 +122,7 @@ __be32 d32[3]; }; -/** +/* * Output ranges corresponding to bits [3:0] from DAC_CONFIG register * 0000: 0 V to 5 V voltage range * 0001: 0 V to 10 V voltage range @@ -313,6 +319,18 @@ { int ret; + /* + * The ENABLE_PPC_BUFFERS bit must be set prior to enabling PPC current + * mode. + */ + if (mode == AD5758_DCDC_MODE_PPC_CURRENT) { + ret = ad5758_spi_write_mask(st, AD5758_ADC_CONFIG, + AD5758_ADC_CONFIG_PPC_BUF_MSK, + AD5758_ADC_CONFIG_PPC_BUF_EN(1)); + if (ret < 0) + return ret; + } + ret = ad5758_spi_write_mask(st, AD5758_DCDC_CONFIG1, AD5758_DCDC_CONFIG1_DCDC_MODE_MSK, AD5758_DCDC_CONFIG1_DCDC_MODE_MODE(mode)); @@ -442,23 +460,6 @@ AD5758_CAL_MEM_UNREFRESHED_MSK); } -static int ad5758_fault_prot_switch_en(struct ad5758_state *st, bool enable) -{ - int ret; - - ret = ad5758_spi_write_mask(st, AD5758_DCDC_CONFIG1, - AD5758_DCDC_CONFIG1_PROT_SW_EN_MSK, - AD5758_DCDC_CONFIG1_PROT_SW_EN_MODE(enable)); - if (ret < 0) - return ret; - /* - * Poll the BUSY_3WI bit in the DCDC_CONFIG2 register until it is 0. - * This allows the 3-wire interface communication to complete. - */ - return ad5758_wait_for_task_complete(st, AD5758_DCDC_CONFIG2, - AD5758_DCDC_CONFIG2_BUSY_3WI_MSK); -} - static int ad5758_internal_buffers_en(struct ad5758_state *st, bool enable) { int ret; @@ -472,6 +473,21 @@ /* Wait to allow time for the internal calibrations to complete */ return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS, AD5758_CAL_MEM_UNREFRESHED_MSK); +} + +static int ad5758_reset(struct ad5758_state *st) +{ + if (st->gpio_reset) { + gpiod_set_value(st->gpio_reset, 0); + usleep_range(100, 1000); + gpiod_set_value(st->gpio_reset, 1); + usleep_range(100, 1000); + + return 0; + } else { + /* Perform a software reset */ + return ad5758_soft_reset(st); + } } static int ad5758_reg_access(struct iio_dev *indio_dev, @@ -568,8 +584,8 @@ { struct ad5758_state *st = iio_priv(indio_dev); bool pwr_down; - unsigned int dcdc_config1_mode, dc_dc_mode, dac_config_mode, val; - unsigned long int dcdc_config1_msk, dac_config_msk; + unsigned int dac_config_mode, val; + unsigned long int dac_config_msk; int ret; ret = kstrtobool(buf, &pwr_down); @@ -577,24 +593,10 @@ return ret; mutex_lock(&st->lock); - if (pwr_down) { - dc_dc_mode = AD5758_DCDC_MODE_POWER_OFF; + if (pwr_down) val = 0; - } else { - dc_dc_mode = st->dc_dc_mode; + else val = 1; - } - - dcdc_config1_mode = AD5758_DCDC_CONFIG1_DCDC_MODE_MODE(dc_dc_mode) | - AD5758_DCDC_CONFIG1_PROT_SW_EN_MODE(val); - dcdc_config1_msk = AD5758_DCDC_CONFIG1_DCDC_MODE_MSK | - AD5758_DCDC_CONFIG1_PROT_SW_EN_MSK; - - ret = ad5758_spi_write_mask(st, AD5758_DCDC_CONFIG1, - dcdc_config1_msk, - dcdc_config1_mode); - if (ret < 0) - goto err_unlock; dac_config_mode = AD5758_DAC_CONFIG_OUT_EN_MODE(val) | AD5758_DAC_CONFIG_INT_EN_MODE(val); @@ -768,13 +770,18 @@ { int regval, ret; + st->gpio_reset = devm_gpiod_get_optional(&st->spi->dev, "reset", + GPIOD_OUT_HIGH); + if (IS_ERR(st->gpio_reset)) + return PTR_ERR(st->gpio_reset); + /* Disable CRC checks */ ret = ad5758_crc_disable(st); if (ret < 0) return ret; - /* Perform a software reset */ - ret = ad5758_soft_reset(st); + /* Perform a reset */ + ret = ad5758_reset(st); if (ret < 0) return ret; @@ -819,11 +826,6 @@ return ret; } - /* Enable the VIOUT fault protection switch (FPS is closed) */ - ret = ad5758_fault_prot_switch_en(st, 1); - if (ret < 0) - return ret; - /* Power up the DAC and internal (INT) amplifiers */ ret = ad5758_internal_buffers_en(st, 1); if (ret < 0) @@ -852,7 +854,6 @@ mutex_init(&st->lock); - indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; indio_dev->info = &ad5758_info; indio_dev->modes = INDIO_DIRECT_MODE; @@ -882,9 +883,16 @@ }; MODULE_DEVICE_TABLE(spi, ad5758_id); +static const struct of_device_id ad5758_of_match[] = { + { .compatible = "adi,ad5758" }, + { }, +}; +MODULE_DEVICE_TABLE(of, ad5758_of_match); + static struct spi_driver ad5758_driver = { .driver = { .name = KBUILD_MODNAME, + .of_match_table = ad5758_of_match, }, .probe = ad5758_probe, .id_table = ad5758_id, -- Gitblit v1.6.2