Skip to content

Conversation

@jansunil
Copy link
Collaborator

@jansunil jansunil commented Nov 7, 2025

PR Description

  • Please replace this comment with a summary of your changes, and add any context
    necessary to understand them. List any dependencies required for this change.
  • To check the checkboxes below, insert a 'x' between square brackets (without
    any space), or simply check them after publishing the PR.
  • If you changes include a breaking change, please specify dependent PRs in the
    description and try to push all related PRs simultaneously.

PR Type

  • Bug fix (a change that fixes an issue)
  • New feature (a change that adds new functionality)
  • Breaking change (a change that affects other repos or cause CIs to fail)

PR Checklist

  • I have conducted a self-review of my own code changes
  • I have compiled my changes, including the documentation
  • I have tested the changes on the relevant hardware
  • I have updated the documentation outside this repo accordingly
  • I have provided links for the relevant upstream lore

Copy link
Contributor

@gastmaier gastmaier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jansunil overall looks good, just some comments from my side.
I believe we can drop the crc feature and really streamline the driver reg access as a consequence.

Best regards,

@nunojsa
Copy link
Collaborator

nunojsa commented Nov 12, 2025

I'll wait this getting out of draft to jump in :)

Copy link
Collaborator

@nunojsa nunojsa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here it goes my first round. Couple more points:

  • In the bindings patch do not day "...Add MAX22007 DAC bindings". I mean, dont mention "bindings". Its already obvious from the prefix. So instead say something like "Document MAX22007 DAC". Also refactor a bit the message and add a small description of the device.
  • Also refactor the driver patch commit message. See git log for other examples. Give a small description of the device. It is also a fairly simple driver so I do not think there is any meaningful to state about the implementation in the commit message.

Regarding process, note that I expect this PR to be opened against main (without the overlay). Then after merged with main, you can open a PR against the PI branch only with the overlay.

@jansunil jansunil force-pushed the max22007-dev branch 2 times, most recently from ae84b9d to bb72180 Compare November 14, 2025 10:42
@jansunil
Copy link
Collaborator Author

Changelog V2:

    1) Remove description for spi max frequency in the yaml
2) Remove "|" character in the yaml
3) Add a default field in the properties wherever required
4) Add regmap in the Kconfig
5) Correct copyright year in the driver
6) Rearrange includes in alphabetical order and add  missing includes
7) Pass SPI buffers into state structure
8) Reformat code to meet 80 column limit
9) Remove redundant masking of buffer elements in max22007_spi_reg_write()
10) Remove locking within APIs
11) Remove explicit function for softreset and use regmap directly
12) Add macros for MAX value check for DAC Raw data
13) Implement custom regmap bus
14) Removed caching of channel configuration as it is not used again
15) Add validation for values passed from devicetree
16) Remove spi_setup
17) Add extra spaces at necessary lines of code
18) Parse CRC value from devicetree inside the max22007_configure_crc()
19) Return error code from max22007_parse_channel_cfg() and add an argument to capture the number of channels
20) Add RESET pin gpio support
21) Switch the CRC functionality to use adi,crc-disable instead of adi,crc-enable
22) Remove CRC from the Tx buffer during SPI read operations
    23) Add ABI documentation for per channel LDAC update

Copy link
Contributor

@machschmitt machschmitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jansunil ,

Commenting mostly about the dt docs and proposed ABI. Only superficially looked into the driver code as that might change significantly depending on the discussion about the dt properties and IIO ABI.

Comment on lines 48 to 52
adi,crc-disable:
type: boolean
description:
Disable CRC8 error checking for SPI communications. By default, CRC8 is
enabled for data integrity verification. Set this property to disable it.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see in the data sheet that SPI transfers can run with CRC disabled (set CRC_EN field to 0x0 within the configuration register (0x03) ). For max22007, CRC is a runtime configuration and has nothing to do with how hardware is set up. Drop this property.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The property here was added so that it enables the user to take a decision on the state of the CRC and not hardcoding it in the driver. Do you still suggest removing the CRC property and hardcoding it in the driver?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not about hardcoding, it's about hardware description. Devicetree is useful because it follows a specification that makes it easier to describe hardware such that the description is both readable to humans and compilable by machines. Some info clearly relates to the hardware, e.g. pins that have device-specific functionality, specific types of inputs/outputs to/from device pins (clocks, voltage/current supplies, GPIOs, ...), non-conventional hardware connections (e.g. controller CS connected to peripheral SDI), characteristics intrinsic to a design (e.g. max transfer clock frequency, chip address, etc.). Other info might not need to be encoded into the hardware description (note: in some platforms, the only way to update the hardware device tree is with a system reboot).
IMHO, the ideal for MAX22007 CRC would be to have some sort of CRC toggle device property. That way, the user would be able to enable/disable CRC at runtime, and there would be no need to have a CRC property in dt. Though I didn't find any documented ABI for that so it would have to be proposed. An alternative might be to always have CRC checking enabled on initial MAX22007 support.

That said, there is indeed some precedent for CRC dt properties.
regulator/nxp,pf0900.yaml (nxp,i2c-crc-enable)
net/adi,adin1110.yaml (adi,spi-crc)
mtd/qcom,nandc.yaml (qcom,cmd-crci and qcom,data-crci) (looks like CRC but not really sure)
qcom/qcom,gsbi.yaml (qcom,crci) (not sure it's about CRC either)
If you are confident that you do need a CRC dt prop for MAX22007, then please use adi,spi-crc (so we may at least try to keep only a few property names).

Copy link
Collaborator

@nunojsa nunojsa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more comments from me. An additional note regarding commits. Your git subject for the bindings is nok. Please run git log --oneline Documentation/devicetree/bindings/ and follow the sytle.

@jansunil jansunil force-pushed the max22007-dev branch 3 times, most recently from b39e6d8 to 7d8c82d Compare December 10, 2025 12:50
krzk and others added 3 commits December 27, 2025 17:43
Simplify the probe function by using a local 'dev' variable instead of
full pointer dereference.  This makes several lines shorter, which
allows to avoid wrapping making code more readable.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Use a local struct device variable to improve readability in some code
paths during probe. While at it, fix some line breaks not properly
aligned to the open parenthesis.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Be consistent and use dev_err_probe() as in all other places in the
.probe() path.

While at it, remove the line break in the version condition. Yes, it
goes over the 80 column limit but I do think the line break hurts
readability in this case.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
@github-actions github-actions bot force-pushed the mirror_ci/jic23/iio/testing branch 4 times, most recently from 1b01b7c to 3425aa5 Compare December 31, 2025 00:03
The code for this never went upstream. It was replaced by other code,
so this should be dropped.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=216748
Fixes: cf996f0 ("iio: test: test gain-time-scale helpers")
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
@github-actions github-actions bot force-pushed the mirror_ci/jic23/iio/testing branch 2 times, most recently from c7fdb3b to 55cf059 Compare January 2, 2026 00:09
@github-actions github-actions bot force-pushed the mirror_ci/jic23/iio/testing branch 5 times, most recently from d6de80f to a67bdd8 Compare January 7, 2026 00:00
patch ci

Signed-off-by: CSE CI <cse-ci-notifications@analog.com>
@github-actions github-actions bot force-pushed the mirror_ci/jic23/iio/testing branch from a67bdd8 to b009fd5 Compare January 8, 2026 00:10
@jansunil jansunil force-pushed the max22007-dev branch 2 times, most recently from 2bb86cf to 5636039 Compare January 8, 2026 13:47
@github-actions github-actions bot force-pushed the mirror_ci/jic23/iio/testing branch from b009fd5 to 79dff6b Compare January 9, 2026 00:11
This patch series introduces support for the Analog Devices MAX22007, a
quad-channel, 12-bit digital-to-analog converter (DAC) with integrated
precision output amplifiers and configurable voltage/current output capability.

**Device Overview:**
The MAX22007 features four independent DAC channels that can each be configured
for either voltage output (0-12.5V) or current output (0-25mA) mode. The device
communicates via SPI interface with built-in CRC8 error checking for data integrity.

**Features Implemented:**
- Support for all 4 DAC channels with 12-bit resolution
- Per-channel voltage/current mode configuration via device tree
  property `adi,ch-func = [voltage, current]`
- Independent power control for each channel (attribute)
- Hardware reset support via GPIO (during probe)
- CRC8 error checking for SPI communication

**Patch Summary:**
1. dt-bindings: Binding documentation with channel configuration
2. driver: Implement IIO DAC driver

**Testing:**
The driver was hardware tested on a Raspberry Pi4 on top of v6.12.y
kernel using the MAX22007EVKIT evaluation board.

Janani Sunil (3):
dt-bindings: iio: dac: Add max22007
iio: dac: Add MAX22007 DAC driver support
---

To: Lars-Peter Clausen <lars@metafoo.de>
To: Michael Hennerich <Michael.Hennerich@analog.com>
To: Alexandru Ardelean <alexandru.ardelean@analog.com>
To: Jonathan Cameron <jic23@kernel.org>
To: Rob Herring <robh@kernel.org>
To: Krzysztof Kozlowski <krzk+dt@kernel.org>
To: Conor Dooley <conor+dt@kernel.org>
To: Jonathan Corbet <corbet@lwn.net>
Cc: linux-iio@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-doc@vger.kernel.org
Cc: jan.sun97@gmail.com
Signed-off-by: Janani Sunil <janani.sunil@analog.com>

---

Changes in v3:
- Remove node defined for power supplies in the devicetree documentaiton
- Made use of CRC8_TABLE_SIZE macro in the crc table definition
- Corrected casting of reg address in the SPI read function
- Applied reverse christmas tree variable ordering
- Added a macro fro the reference voltage and reused the same in the
  scale factor
- Removed usage of 'supplies' in enabling bulk regulator and removed
  unused variable 'i'
- Link to v2: https://lore.kernel.org/r/20260108-max22007-dev-v2-0-2506c738784f@analog.com/

Changes in v2:
- Wrap commit messages as per coding guidelines
- Removed all driver references from the hardware
- Update property description for reset-gpio
- Removed allOf
- Added minimum/maximum limits for channel number in the devicetree
  binding
- Replaced adi,type with adi,ch-func.
- Added reference to required supplies in the binding, configured them
  in the driver
- Channels are not a required property anymore.
- Replaced instances of 'channel' in macros to just 'ch'
- Added trailing commas wherever necessary, removed them as per comments
- Add explicit values for enum- max22007_channel_power
- Replace channel spec structure member 'iio_chan' with 'iio_chans'
- Use spi_write_then_read() API in the max22007_spi_read() API
- Check for reg_size ==1 and hardcode the size otherwise
- Wrap lines in the driver to 80 characters
- Update in-line comment on the resolution
- Separate declarations with assignment, from the ones that don't
- Update the usage of channel template
- Add a local device descriptor to point to the SPI device
- Add a transition of the Reset GPIO from low to high in the probe
- Make use of regmap_set_bits() instead of regmap_update_bits during CRC
  Enable function call.
- Remove the documentation commit, as it is not needed anymore.
- Link to v1: https://lore.kernel.org/r/20251219-max22007-dev-v1-0-242da2c2b868@analog.com

--- b4-submit-tracking ---
{
  "series": {
    "revision": 3,
    "change-id": "20251219-max22007-dev-1aaf08db7890",
    "prefixes": [],
    "history": {
      "v1": [
        "20251219-max22007-dev-v1-0-242da2c2b868@analog.com"
      ]
    }
  }
}
Devicetree bindings for MAX22007 4-channel 12-bit DAC that drives a
voltage or current output on each channel

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Janani Sunil <janani.sunil@analog.com>
Add support for the MAX22007, a 4-channel 12-bit DAC that drives
voltage or current output on each channel.

Signed-off-by: Janani Sunil <janani.sunil@analog.com>
@github-actions github-actions bot force-pushed the mirror_ci/jic23/iio/testing branch 3 times, most recently from 4eff7cb to 76e2b67 Compare January 12, 2026 00:03
Copy link
Contributor

@gastmaier gastmaier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding here to also note that to avoid the merge conflicts due to the mirror_ci head, base your work on the common stable commit, in this case

Linux 6.19-rc1 8f0b4cc

Comment on lines +46 to +48
#define MAX22007_CH_PWRON_CH_MASK(ch) BIT(8 + (ch))
#define MAX22007_DAC_LATCH_MODE_MASK(ch) BIT(12 + (ch))
#define MAX22007_LDAC_UPDATE_MASK(ch) BIT(12 + (ch))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define MAX22007_CH_PWRON_CH_MASK(ch) BIT(8 + (ch))
#define MAX22007_DAC_LATCH_MODE_MASK(ch) BIT(12 + (ch))
#define MAX22007_LDAC_UPDATE_MASK(ch) BIT(12 + (ch))
#define MAX22007_CH_PWRON_CH_MASK(ch) BIT(8 + (ch))
#define MAX22007_DAC_LATCH_MODE_MASK(ch) BIT(12 + (ch))
#define MAX22007_LDAC_UPDATE_MASK(ch) BIT(12 + (ch))

note: github gui sets tabsize to 4 instead of the 8, MAX22007_DAC_LATCH_MODE_MASK is missing a tab


static int max22007_spi_write(void *context, const void *data, size_t count)
{
struct max22007_state *st = context;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some parts of the code are using

struct max22007_state *state

instead of st, use always the same name, in my preference, st

Comment on lines +364 to +374
if (ch_func == 1) {
mode = MAX22007_VOLTAGE_MODE;
chan_type = IIO_VOLTAGE;
} else if (ch_func == 2) {
mode = MAX22007_CURRENT_MODE;
chan_type = IIO_CURRENT;
} else {
return dev_err_probe(dev, -EINVAL,
"invalid adi,ch-func %u for %pfwP\n",
ch_func, child);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The values are defined at

#include <dt-bindings/iio/addac/adi,ad74413r.h>

as mentioned in the dt-binding
I would use the defines from the header, and drop the magic numbers 1 and 2, as well as the translation to mode (store CH_FUNC_VOLTAGE_OUTPUT, CH_FUNC_CURRENT_OUTPUT directly) attention to the 1 value increment.

Suggested change
if (ch_func == 1) {
mode = MAX22007_VOLTAGE_MODE;
chan_type = IIO_VOLTAGE;
} else if (ch_func == 2) {
mode = MAX22007_CURRENT_MODE;
chan_type = IIO_CURRENT;
} else {
return dev_err_probe(dev, -EINVAL,
"invalid adi,ch-func %u for %pfwP\n",
ch_func, child);
}
switch (ch_func) {
case CH_FUNC_VOLTAGE_OUTPUT:
chan_type = IIO_VOLTAGE;
break;
case CH_FUNC_CURRENT_OUTPUT:
chan_type = IIO_CURRENT;
break;
default:
return dev_err_probe(dev, -EINVAL,
"invalid adi,ch-func %u for %pfwP\n",
ch_func, child);
}

the add the

regmap_update_bits(st->regmap, MAX22007_CHANNEL_MODE_REG

you could just subtract 1

		ret = regmap_update_bits(st->regmap, MAX22007_CHANNEL_MODE_REG,
					 MAX22007_CH_MODE_CH_MASK(reg),
					 MAX22007_CH_MODE_VAL(reg, ch_func - 1));

Comment on lines +75 to +78
enum max22007_channel_mode {
MAX22007_VOLTAGE_MODE = 0,
MAX22007_CURRENT_MODE = 1,
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dt-binding uses

#include <dt-bindings/iio/addac/adi,ad74413r.h>

to define similar value (1-incremented)

Comment on lines +63 to +65
#define MAX22007_CH_PWR_VAL(ch, val) (((val) & 0x1) << (8 + (ch)))
#define MAX22007_CH_MODE_VAL(ch, val) (((val) & 0x1) << (12 + (ch)))
#define MAX22007_DAC_LATCH_MODE_VAL(ch, val) (((val) & 0x1) << (12 + (ch)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define MAX22007_CH_PWR_VAL(ch, val) (((val) & 0x1) << (8 + (ch)))
#define MAX22007_CH_MODE_VAL(ch, val) (((val) & 0x1) << (12 + (ch)))
#define MAX22007_DAC_LATCH_MODE_VAL(ch, val) (((val) & 0x1) << (12 + (ch)))
#define MAX22007_CH_PWR_VAL(ch, val) (((val) & 0x1) << (8 + (ch)))
#define MAX22007_CH_MODE_VAL(ch, val) (((val) & 0x1) << (12 + (ch)))
#define MAX22007_DAC_LATCH_MODE_VAL(ch, val) (((val) & 0x1) << (12 + (ch)))

also just indentation

crc_data[1] = rx_buf[0];
crc_data[2] = rx_buf[1];

calculated_crc = crc8(max22007_crc8_table, crc_data, 3, 0x00);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As jonathan suggested

I think you can chain CRCs as follows and avoid the need for a local array
just to marshal the data.

	calculated_crc = crc8(max22007_crc8_table, &reg_byte, 1, 0x00);
	calculated_crc = crc8(max22007_crc8_table, rx_buf, 2, calculated_crc);

then you can remove the intermediary variable crc_data
The last value is

lib/crc/crc8.c 
 * @crc: previous returned crc8 value.

Comment on lines +306 to +313
if (powerdown)
ret = regmap_update_bits(st->regmap, MAX22007_CHANNEL_MODE_REG,
MAX22007_CH_PWRON_CH_MASK(chan->channel),
MAX22007_CH_PWR_VAL(chan->channel, 0));
else
ret = regmap_update_bits(st->regmap, MAX22007_CHANNEL_MODE_REG,
MAX22007_CH_PWRON_CH_MASK(chan->channel),
MAX22007_CH_PWR_VAL(chan->channel, 1));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be simplified into a single statement, as jonathan suggested

Something like the following reduces duplication:

	ret = regmap_update_bits(st->regmap, MAX22007_CHANNEL_MODE_REG,
				 MAX2207_CH_PWRON_CH_MASK(chan->channel),
				 MAX2207_CH_PWR_VAL(chan->channel, powerdown ? 1 : 0);

Comment on lines +91 to +96
struct max22007_state *st = context;
u8 reg_byte;
u8 calculated_crc, received_crc;
u8 crc_data[3];
u8 rx_buf[4];
int ret;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reorder for inverted tree

-----------
-------
---

@github-actions github-actions bot force-pushed the mirror_ci/jic23/iio/testing branch from 76e2b67 to 12aeb0c Compare January 13, 2026 00:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants