* [PATCH v4 0/2] staging: iio: frequency: ad9832: Fix and
@ 2025-04-24 22:32 Gabriel Shahrouzi
2025-04-24 22:32 ` [PATCH v4 1/2] staging: iio: frequency: ad9832: Use SLEEP bit instead of RESET to disable output Gabriel Shahrouzi
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Gabriel Shahrouzi @ 2025-04-24 22:32 UTC (permalink / raw)
To: andy, dlechner, gregkh, jic23, lars, linux-iio, linux-kernel,
linux-staging, Michael.Hennerich, nuno.sa
Cc: gshahrouzi, skhan, linux-kernel-mentees
Patch 1 includes the initial fix.
Patch 2 refactors the code to use the out_altvoltage_powerdown ABI via
an extended attribute.
Gabriel Shahrouzi (2):
iio: frequency: Use SLEEP bit instead of RESET to disable output
staging: iio: ad9832: Refactor powerdown control
drivers/staging/iio/frequency/ad9832.c | 69 +++++++++++++++++++-------
1 file changed, 51 insertions(+), 18 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH v4 1/2] staging: iio: frequency: ad9832: Use SLEEP bit instead of RESET to disable output 2025-04-24 22:32 [PATCH v4 0/2] staging: iio: frequency: ad9832: Fix and Gabriel Shahrouzi @ 2025-04-24 22:32 ` Gabriel Shahrouzi 2025-04-25 4:21 ` Andy Shevchenko 2025-04-24 22:32 ` [PATCH v4 2/2] staging: iio: frequency: ad9832: Refactor powerdown control Gabriel Shahrouzi 2025-04-24 22:38 ` [PATCH v4 0/2] staging: iio: frequency: ad9832: Fix and Gabriel Shahrouzi 2 siblings, 1 reply; 7+ messages in thread From: Gabriel Shahrouzi @ 2025-04-24 22:32 UTC (permalink / raw) To: andy, dlechner, gregkh, jic23, lars, linux-iio, linux-kernel, linux-staging, Michael.Hennerich, nuno.sa Cc: gshahrouzi, skhan, linux-kernel-mentees, stable According to the AD9832 datasheet (Table 10, D12 description), setting the RESET bit forces the phase accumulator to zero, which corresponds to a full-scale DC output, rather than disabling the output signal. The correct way to disable the output and enter a low-power state is to set the AD9832_SLEEP bit (Table 10, D13 description), which powers down the internal DAC current sources and disables internal clocks. Fixes: ea707584bac1 ("Staging: IIO: DDS: AD9832 / AD9835 driver") Cc: stable@vger.kernel.org Signed-off-by: Gabriel Shahrouzi <gshahrouzi@gmail.com> --- v3 -> v4: - Rebase changes ontop of most recent changes. v2 -> v3: v1 -> v2: --- drivers/staging/iio/frequency/ad9832.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c index 49388da5a684a..2e555084ff98a 100644 --- a/drivers/staging/iio/frequency/ad9832.c +++ b/drivers/staging/iio/frequency/ad9832.c @@ -236,7 +236,7 @@ static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr, if (val) st->ctrl_src &= ~(AD9832_RESET | AD9832_SLEEP | AD9832_CLR); else - st->ctrl_src |= FIELD_PREP(AD9832_RESET, 1); + st->ctrl_src |= FIELD_PREP(AD9832_SLEEP, 1); st->data = cpu_to_be16(FIELD_PREP(AD9832_CMD_MSK, AD9832_CMD_SLEEPRESCLR) | st->ctrl_src); -- 2.43.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v4 1/2] staging: iio: frequency: ad9832: Use SLEEP bit instead of RESET to disable output 2025-04-24 22:32 ` [PATCH v4 1/2] staging: iio: frequency: ad9832: Use SLEEP bit instead of RESET to disable output Gabriel Shahrouzi @ 2025-04-25 4:21 ` Andy Shevchenko 0 siblings, 0 replies; 7+ messages in thread From: Andy Shevchenko @ 2025-04-25 4:21 UTC (permalink / raw) To: Gabriel Shahrouzi Cc: andy, dlechner, gregkh, jic23, lars, linux-iio, linux-kernel, linux-staging, Michael.Hennerich, nuno.sa, skhan, linux-kernel-mentees, stable On Fri, Apr 25, 2025 at 1:34 AM Gabriel Shahrouzi <gshahrouzi@gmail.com> wrote: > > According to the AD9832 datasheet (Table 10, D12 description), setting > the RESET bit forces the phase accumulator to zero, which corresponds to > a full-scale DC output, rather than disabling the output signal. > > The correct way to disable the output and enter a low-power state is to > set the AD9832_SLEEP bit (Table 10, D13 description), which powers down > the internal DAC current sources and disables internal clocks. ... > if (val) > st->ctrl_src &= ~(AD9832_RESET | AD9832_SLEEP | AD9832_CLR); > else > - st->ctrl_src |= FIELD_PREP(AD9832_RESET, 1); > + st->ctrl_src |= FIELD_PREP(AD9832_SLEEP, 1); From the code perspective this allows combinations of the bits to be set. So, what does the datasheet say about SLEEP+RESET, or RESET+CLR, or other combinations of these 3 bits? -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v4 2/2] staging: iio: frequency: ad9832: Refactor powerdown control 2025-04-24 22:32 [PATCH v4 0/2] staging: iio: frequency: ad9832: Fix and Gabriel Shahrouzi 2025-04-24 22:32 ` [PATCH v4 1/2] staging: iio: frequency: ad9832: Use SLEEP bit instead of RESET to disable output Gabriel Shahrouzi @ 2025-04-24 22:32 ` Gabriel Shahrouzi 2025-04-25 4:25 ` Andy Shevchenko 2025-04-25 13:18 ` Dan Carpenter 2025-04-24 22:38 ` [PATCH v4 0/2] staging: iio: frequency: ad9832: Fix and Gabriel Shahrouzi 2 siblings, 2 replies; 7+ messages in thread From: Gabriel Shahrouzi @ 2025-04-24 22:32 UTC (permalink / raw) To: andy, dlechner, gregkh, jic23, lars, linux-iio, linux-kernel, linux-staging, Michael.Hennerich, nuno.sa Cc: gshahrouzi, skhan, linux-kernel-mentees Replace custom implementation with out_altvoltage_powerdown ABI. The attribute's logic is inverted (1 now enables powerdown) to match the standard. Signed-off-by: Gabriel Shahrouzi <gshahrouzi@gmail.com> --- V3 -> v4: - Use guard(mutex) for simplified locking. - Use an extended attribute. v2 -> v3: v1 -> v2: Refactor powerdown functionality. --- drivers/staging/iio/frequency/ad9832.c | 69 +++++++++++++++++++------- 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c index 2e555084ff98a..b8b52302abf36 100644 --- a/drivers/staging/iio/frequency/ad9832.c +++ b/drivers/staging/iio/frequency/ad9832.c @@ -174,6 +174,32 @@ static int ad9832_write_phase(struct ad9832_state *st, return spi_sync(st->spi, &st->phase_msg); } +static ssize_t ad9832_write_powerdown(struct iio_dev *indio_dev, uintptr_t private, + const struct iio_chan_spec *chan, + const char *buf, size_t len) +{ + struct ad9832_state *st = iio_priv(indio_dev); + int ret; + bool val; + + ret = kstrtobool(buf, &val); + if (ret) + return ret; + + guard(mutex)(&st->lock); + if (val) + st->ctrl_src |= AD9832_SLEEP; + else + st->ctrl_src &= ~(AD9832_RESET | AD9832_SLEEP | + AD9832_CLR); + + st->data = cpu_to_be16(FIELD_PREP(AD9832_CMD_MSK, AD9832_CMD_SLEEPRESCLR) | + st->ctrl_src); + ret = spi_sync(st->spi, &st->msg); + + return ret ? ret : len; +} + static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { @@ -185,9 +211,9 @@ static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr, ret = kstrtoul(buf, 10, &val); if (ret) - goto error_ret; + return ret; - mutex_lock(&st->lock); + guard(mutex)(&st->lock); switch ((u32)this_attr->address) { case AD9832_FREQ0HM: case AD9832_FREQ1HM: @@ -232,22 +258,9 @@ static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr, st->ctrl_fp); ret = spi_sync(st->spi, &st->msg); break; - case AD9832_OUTPUT_EN: - if (val) - st->ctrl_src &= ~(AD9832_RESET | AD9832_SLEEP | AD9832_CLR); - else - st->ctrl_src |= FIELD_PREP(AD9832_SLEEP, 1); - - st->data = cpu_to_be16(FIELD_PREP(AD9832_CMD_MSK, AD9832_CMD_SLEEPRESCLR) | - st->ctrl_src); - ret = spi_sync(st->spi, &st->msg); - break; default: ret = -ENODEV; } - mutex_unlock(&st->lock); - -error_ret: return ret ? ret : len; } @@ -270,8 +283,6 @@ static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/ static IIO_DEV_ATTR_PINCONTROL_EN(0, 0200, NULL, ad9832_write, AD9832_PINCTRL_EN); -static IIO_DEV_ATTR_OUT_ENABLE(0, 0200, NULL, - ad9832_write, AD9832_OUTPUT_EN); static struct attribute *ad9832_attributes[] = { &iio_dev_attr_out_altvoltage0_frequency0.dev_attr.attr, @@ -285,7 +296,6 @@ static struct attribute *ad9832_attributes[] = { &iio_dev_attr_out_altvoltage0_pincontrol_en.dev_attr.attr, &iio_dev_attr_out_altvoltage0_frequencysymbol.dev_attr.attr, &iio_dev_attr_out_altvoltage0_phasesymbol.dev_attr.attr, - &iio_dev_attr_out_altvoltage0_out_enable.dev_attr.attr, NULL, }; @@ -293,6 +303,27 @@ static const struct attribute_group ad9832_attribute_group = { .attrs = ad9832_attributes, }; +static const struct iio_chan_spec_ext_info ad9832_ext_info[] = { + { + .name = "powerdown", + .shared = IIO_SEPARATE, + .write = ad9832_write_powerdown, + }, + { }, +}; + +#define AD9832_CHANNEL(chan) { \ + .type = IIO_ALTVOLTAGE, \ + .indexed = 1, \ + .output = 1, \ + .channel = (chan), \ + .ext_info = ad9832_ext_info, \ +} + +static const struct iio_chan_spec ad9832_channels[] = { + AD9832_CHANNEL(0), +}; + static const struct iio_info ad9832_info = { .attrs = &ad9832_attribute_group, }; @@ -333,6 +364,8 @@ static int ad9832_probe(struct spi_device *spi) indio_dev->name = spi_get_device_id(spi)->name; indio_dev->info = &ad9832_info; indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ad9832_channels; + indio_dev->num_channels = ARRAY_SIZE(ad9832_channels); /* Setup default messages */ -- 2.43.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v4 2/2] staging: iio: frequency: ad9832: Refactor powerdown control 2025-04-24 22:32 ` [PATCH v4 2/2] staging: iio: frequency: ad9832: Refactor powerdown control Gabriel Shahrouzi @ 2025-04-25 4:25 ` Andy Shevchenko 2025-04-25 13:18 ` Dan Carpenter 1 sibling, 0 replies; 7+ messages in thread From: Andy Shevchenko @ 2025-04-25 4:25 UTC (permalink / raw) To: Gabriel Shahrouzi Cc: andy, dlechner, gregkh, jic23, lars, linux-iio, linux-kernel, linux-staging, Michael.Hennerich, nuno.sa, skhan, linux-kernel-mentees On Fri, Apr 25, 2025 at 1:34 AM Gabriel Shahrouzi <gshahrouzi@gmail.com> wrote: > > Replace custom implementation with out_altvoltage_powerdown ABI. The > attribute's logic is inverted (1 now enables powerdown) to match the > standard. > +static ssize_t ad9832_write_powerdown(struct iio_dev *indio_dev, uintptr_t private, > + const struct iio_chan_spec *chan, > + const char *buf, size_t len) > +{ > + struct ad9832_state *st = iio_priv(indio_dev); > + int ret; > + bool val; > + > + ret = kstrtobool(buf, &val); > + if (ret) > + return ret; > + > + guard(mutex)(&st->lock); > + if (val) > + st->ctrl_src |= AD9832_SLEEP; > + else > + st->ctrl_src &= ~(AD9832_RESET | AD9832_SLEEP | > + AD9832_CLR); Why out of a sudden this went backwards in style and format (no FIELD_PREP(), two lines, ...)? > + > + st->data = cpu_to_be16(FIELD_PREP(AD9832_CMD_MSK, AD9832_CMD_SLEEPRESCLR) | > + st->ctrl_src); > + ret = spi_sync(st->spi, &st->msg); > + > + return ret ? ret : len; > +} Use Elvis? ... > - mutex_lock(&st->lock); > + guard(mutex)(&st->lock); This should be done in a separate patch for all locking. ... > - st->ctrl_src |= FIELD_PREP(AD9832_SLEEP, 1); Btw, I do not see this in v6.15-tcX, is this part of Linux Next? ... > &iio_dev_attr_out_altvoltage0_pincontrol_en.dev_attr.attr, > &iio_dev_attr_out_altvoltage0_frequencysymbol.dev_attr.attr, > &iio_dev_attr_out_altvoltage0_phasesymbol.dev_attr.attr, > - &iio_dev_attr_out_altvoltage0_out_enable.dev_attr.attr, > NULL, Also drop the trailing comma at some point. ... > +static const struct iio_chan_spec_ext_info ad9832_ext_info[] = { > + { > + .name = "powerdown", > + .shared = IIO_SEPARATE, > + .write = ad9832_write_powerdown, > + }, > + { }, Ditto. > +}; -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v4 2/2] staging: iio: frequency: ad9832: Refactor powerdown control 2025-04-24 22:32 ` [PATCH v4 2/2] staging: iio: frequency: ad9832: Refactor powerdown control Gabriel Shahrouzi 2025-04-25 4:25 ` Andy Shevchenko @ 2025-04-25 13:18 ` Dan Carpenter 1 sibling, 0 replies; 7+ messages in thread From: Dan Carpenter @ 2025-04-25 13:18 UTC (permalink / raw) To: Gabriel Shahrouzi Cc: andy, dlechner, gregkh, jic23, lars, linux-iio, linux-kernel, linux-staging, Michael.Hennerich, nuno.sa, skhan, linux-kernel-mentees On Thu, Apr 24, 2025 at 06:32:09PM -0400, Gabriel Shahrouzi wrote: > Replace custom implementation with out_altvoltage_powerdown ABI. The > attribute's logic is inverted (1 now enables powerdown) to match the > standard. > > Signed-off-by: Gabriel Shahrouzi <gshahrouzi@gmail.com> > --- > V3 -> v4: > - Use guard(mutex) for simplified locking. > - Use an extended attribute. > v2 -> v3: > v1 -> v2: > Refactor powerdown functionality. > --- > drivers/staging/iio/frequency/ad9832.c | 69 +++++++++++++++++++------- > 1 file changed, 51 insertions(+), 18 deletions(-) > > diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c > index 2e555084ff98a..b8b52302abf36 100644 > --- a/drivers/staging/iio/frequency/ad9832.c > +++ b/drivers/staging/iio/frequency/ad9832.c > @@ -174,6 +174,32 @@ static int ad9832_write_phase(struct ad9832_state *st, > return spi_sync(st->spi, &st->phase_msg); > } > > +static ssize_t ad9832_write_powerdown(struct iio_dev *indio_dev, uintptr_t private, > + const struct iio_chan_spec *chan, > + const char *buf, size_t len) > +{ > + struct ad9832_state *st = iio_priv(indio_dev); > + int ret; > + bool val; Declare val before ret. Use reverse Christmas tree order. long long long_name; medium name; short name; > + > + ret = kstrtobool(buf, &val); > + if (ret) > + return ret; > + > + guard(mutex)(&st->lock); > + if (val) > + st->ctrl_src |= AD9832_SLEEP; > + else > + st->ctrl_src &= ~(AD9832_RESET | AD9832_SLEEP | > + AD9832_CLR); > + > + st->data = cpu_to_be16(FIELD_PREP(AD9832_CMD_MSK, AD9832_CMD_SLEEPRESCLR) | > + st->ctrl_src); > + ret = spi_sync(st->spi, &st->msg); > + > + return ret ? ret : len; > +} > + > static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr, > const char *buf, size_t len) > { > @@ -185,9 +211,9 @@ static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr, > > ret = kstrtoul(buf, 10, &val); > if (ret) > - goto error_ret; > + return ret; This is unrelated. Do this in a separate patch. > > - mutex_lock(&st->lock); > + guard(mutex)(&st->lock); same. > switch ((u32)this_attr->address) { > case AD9832_FREQ0HM: > case AD9832_FREQ1HM: > @@ -232,22 +258,9 @@ static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr, > st->ctrl_fp); > ret = spi_sync(st->spi, &st->msg); > break; > - case AD9832_OUTPUT_EN: > - if (val) > - st->ctrl_src &= ~(AD9832_RESET | AD9832_SLEEP | AD9832_CLR); > - else > - st->ctrl_src |= FIELD_PREP(AD9832_SLEEP, 1); > - > - st->data = cpu_to_be16(FIELD_PREP(AD9832_CMD_MSK, AD9832_CMD_SLEEPRESCLR) | > - st->ctrl_src); > - ret = spi_sync(st->spi, &st->msg); > - break; This is related. Keep this. > default: > ret = -ENODEV; > } > - mutex_unlock(&st->lock); > - > -error_ret: > return ret ? ret : len; Unrelated. > } > > @@ -270,8 +283,6 @@ static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/ > > static IIO_DEV_ATTR_PINCONTROL_EN(0, 0200, NULL, > ad9832_write, AD9832_PINCTRL_EN); > -static IIO_DEV_ATTR_OUT_ENABLE(0, 0200, NULL, > - ad9832_write, AD9832_OUTPUT_EN); > > static struct attribute *ad9832_attributes[] = { > &iio_dev_attr_out_altvoltage0_frequency0.dev_attr.attr, > @@ -285,7 +296,6 @@ static struct attribute *ad9832_attributes[] = { > &iio_dev_attr_out_altvoltage0_pincontrol_en.dev_attr.attr, > &iio_dev_attr_out_altvoltage0_frequencysymbol.dev_attr.attr, > &iio_dev_attr_out_altvoltage0_phasesymbol.dev_attr.attr, > - &iio_dev_attr_out_altvoltage0_out_enable.dev_attr.attr, > NULL, > }; > > @@ -293,6 +303,27 @@ static const struct attribute_group ad9832_attribute_group = { > .attrs = ad9832_attributes, > }; > > +static const struct iio_chan_spec_ext_info ad9832_ext_info[] = { > + { > + .name = "powerdown", > + .shared = IIO_SEPARATE, > + .write = ad9832_write_powerdown, > + }, > + { }, ^ No comma after a sentinal. > +}; > + regards, dan carpenter ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v4 0/2] staging: iio: frequency: ad9832: Fix and 2025-04-24 22:32 [PATCH v4 0/2] staging: iio: frequency: ad9832: Fix and Gabriel Shahrouzi 2025-04-24 22:32 ` [PATCH v4 1/2] staging: iio: frequency: ad9832: Use SLEEP bit instead of RESET to disable output Gabriel Shahrouzi 2025-04-24 22:32 ` [PATCH v4 2/2] staging: iio: frequency: ad9832: Refactor powerdown control Gabriel Shahrouzi @ 2025-04-24 22:38 ` Gabriel Shahrouzi 2 siblings, 0 replies; 7+ messages in thread From: Gabriel Shahrouzi @ 2025-04-24 22:38 UTC (permalink / raw) To: andy, dlechner, gregkh, jic23, lars, linux-iio, linux-kernel, linux-staging, Michael.Hennerich, nuno.sa Cc: skhan, linux-kernel-mentees On Thu, Apr 24, 2025 at 6:34 PM Gabriel Shahrouzi <gshahrouzi@gmail.com> wrote: > > Patch 1 includes the initial fix. > > Patch 2 refactors the code to use the out_altvoltage_powerdown ABI via > an extended attribute. > > Gabriel Shahrouzi (2): > iio: frequency: Use SLEEP bit instead of RESET to disable output > staging: iio: ad9832: Refactor powerdown control > > drivers/staging/iio/frequency/ad9832.c | 69 +++++++++++++++++++------- > 1 file changed, 51 insertions(+), 18 deletions(-) > > -- > 2.43.0 > Whoops. Didn't realize reformatting the title on the cover letter so it fits within the width requirement would cause part of title to be omitted. Title should be: Subject: [PATCH v4 0/2] staging: iio: frequency: ad9832: Fix and refactor output disable logic. ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-04-25 13:18 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-04-24 22:32 [PATCH v4 0/2] staging: iio: frequency: ad9832: Fix and Gabriel Shahrouzi 2025-04-24 22:32 ` [PATCH v4 1/2] staging: iio: frequency: ad9832: Use SLEEP bit instead of RESET to disable output Gabriel Shahrouzi 2025-04-25 4:21 ` Andy Shevchenko 2025-04-24 22:32 ` [PATCH v4 2/2] staging: iio: frequency: ad9832: Refactor powerdown control Gabriel Shahrouzi 2025-04-25 4:25 ` Andy Shevchenko 2025-04-25 13:18 ` Dan Carpenter 2025-04-24 22:38 ` [PATCH v4 0/2] staging: iio: frequency: ad9832: Fix and Gabriel Shahrouzi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox