Skip to content

Introduce opamp device driver api #94040

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

ZhaoxiangJin
Copy link
Contributor

@ZhaoxiangJin ZhaoxiangJin commented Aug 3, 2025

What is OPAMP

The operational amplifier (OPAMP) is an analog device that amplifies differential input signals (difference between inverting
and non-inverting input) to give a resulting output voltage. OPAMP can amplify small voltage signals across shunt resistors in motor applications.

The core of the OPAMP includes:

  1. Inverting and non-inverting input.
  2. OPAMP mode (including programmable gain (PGA), inverting, non-inverting, follower mode).
  3. OPAMP inverting and non-inverting gain.
    OPAMPs from different vendors may have different peripheral circuit designs. Users can set the necessary properties in the device driver and bindings.

Functions implemented in device driver API

The OPAMP device driver API includes:

  1. OPAMP enable.
  2. OPAMP disable.
  3. OPAMP inverting and non-inverting gain configuration.
    In actual applications, the OPAMP mode will not change at runtime, so there is no device driver API to change the OPAMP mode.

Hardware references

  1. NXP MCXA153 OPAMP
  2. NXP MCXA276 OPAMP_FAST
  3. STM32 L47xxx OPAMP
  4. STM32 G4 OPAMP
  5. Infineon PSoC6 OPAMP
  6. Renesas RA2A1 OPAMP

Work List

  • Present this to the Architecture WG.
  • Implement OPAMP device driver APIs.
  • Implement vendors' OPAMP driver.
    • NXP has OPAMP and NXP OPAMP_FAST IPs, I have enabled them in this PR and tested them using opamp_output_measure example.
    • @KozhinovAlexander has already enabled STM32G4 and STM32H7 OPAMP driver in draft state. He will then add the driver to this PR.
    • For Renesas and Infineon OPAMP, @soburi, @ifyall @sreeramIfx for awareness.
  • Add samples for OPAMP to test APIs usage and integration with other IPs (such as ADC).
  • Add test case for OPAMP device drivers, @KozhinovAlexander has done a lot of work in this area, and he will add his work to this PR.
  • Added documentation for OPAMP device driver APIs and added related instructions to the release notes.

@ZhaoxiangJin ZhaoxiangJin force-pushed the feature/create-opamp-device-driver-api branch from 3e77ba6 to 4c49202 Compare August 3, 2025 15:31
@ZhaoxiangJin ZhaoxiangJin marked this pull request as ready for review August 3, 2025 15:31
@zephyrbot zephyrbot added area: Samples Samples platform: NXP NXP area: Devicetree Release Notes To be mentioned in the release notes platform: NXP Drivers NXP Semiconductors, drivers labels Aug 3, 2025
@decsny
Copy link
Member

decsny commented Aug 3, 2025

It's not clear to me what the value of an op amp API is, especially since they are generally used as part of a higher level circuit. What consumers would you expect to use this API, and what do they gain from it. What are the specific use cases of the op amp you're trying to implement under this API that can't be done without this API

@ZhaoxiangJin
Copy link
Contributor Author

It's not clear to me what the value of an op amp API is, especially since they are generally used as part of a higher level circuit.

Could you explain or give an example of what a ‘higher level circuit’ is in real engineering?

What consumers would you expect to use this API, and what do they gain from it. What are the specific use cases of the op amp you're trying to implement under this API that can't be done without this API

OPAMP is used to amplify small voltage signals in motor applications. If Zephyr does not have a device driver API for OPAMP, then users can only call vendor HAL directly in the application layer. I think this is an ugly way. Instead of this, why not provide an OPAMP device driver API after considering all vendor OPAMPs?

@ZhaoxiangJin ZhaoxiangJin force-pushed the feature/create-opamp-device-driver-api branch from 4c49202 to 9a4ada0 Compare August 4, 2025 02:16
Copy link
Contributor

@KozhinovAlexander KozhinovAlexander left a comment

Choose a reason for hiding this comment

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

Great addition. Thanks.
I've added few comments and will do more reviews later.
I think samples could be safely replaced by tests. Or you may leave samples, but tests are must-have imho.
Take a look at opamp branch in my fork of zephyr. I have there tests - feel free to grab them ;) main...KozhinovAlexander:zephyr:opamp
The test will be also fairly simple, since API is simple too.
UPD: General documentation for opamp (an .rst file) is also missed. I think with such documentation the questions from @decsny could be answerde simpler ;)

- base.yaml

properties:
functional-mode:
Copy link
Contributor

@KozhinovAlexander KozhinovAlexander Aug 4, 2025

Choose a reason for hiding this comment

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

Maybe renaming to mod would be better. The other mode in vendor related .yaml could be renamed to speed related to slew-rate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renaming to mode is not clear. I suggest dividing the mode into functional mode in opamp-controller (such as inverting mode, non-inverting mode, etc.) and operation mode in vendor_opamp.yml (such as high speed, slow speed mode, etc.).

Copy link
Contributor

Choose a reason for hiding this comment

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

In that case operation mode will be nothing else as a speed. :) This is why I am suggesting to rename it to speed. Maybe we agree on speed mode? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

operation mode is sometimes not completely the same as speed mode. For example, NXP OPAMP has operation mode named high performance mode and low performance mode, voltage noise and startup time will be shortened in high performance mode. In this case, if we do not use operation mode but use speed mode, will it look strange?


typedef int (*opamp_api_enable_t)(const struct device *dev);
typedef int (*opamp_api_disable_t)(const struct device *dev);
typedef int (*opamp_api_set_gain_t)(const struct device *dev, const struct opamp_gain_cfg *cfg);
Copy link
Contributor

Choose a reason for hiding this comment

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

I am for either adding additional opamp_api_configure function or renaming the set function to it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd like to know if there is anything else that needs to be changed in the OPAMP runtime besides gain?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd like to know if there is anything else that needs to be changed in the OPAMP runtime besides gain?

This is a good question. I think either we agree here that no parameters shall be changed at runtime or every parameter (except pin mapping and clock) are allowed to be changed at runtime. If lall parameters are allowed to be changed, then opamp_api_configure_t has more meaning.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

From a practical engineering perspective, the input pins or opamp functional mode will not be changed during runtime. Generally, only the gain will be changed.

@henrikbrixandersen henrikbrixandersen added the Architecture Review Discussion in the Architecture WG required label Aug 4, 2025
@KozhinovAlexander
Copy link
Contributor

A question to all participants: Do you see twister tests as must-have in context of this PR? Just thumbs up if so.

@decsny
Copy link
Member

decsny commented Aug 4, 2025

A question to all participants: Do you see twister tests as must-have in context of this PR? Just thumbs up if so.

yes but author can wait for arch wg approval of the idea first before adding everything like that I think

@ZhaoxiangJin
Copy link
Contributor Author

Great addition. Thanks. I've added few comments and will do more reviews later. I think samples could be safely replaced by tests. Or you may leave samples, but tests are must-have imho. Take a look at opamp branch in my fork of zephyr. I have there tests - feel free to grab them ;) main...KozhinovAlexander:zephyr:opamp The test will be also fairly simple, since API is simple too. UPD: General documentation for opamp (an .rst file) is also missed. I think with such documentation the questions from @decsny could be answerde simpler ;)

Hello @KozhinovAlexander, you also do some excellent work, I looked your commit, and you have done a better job in testing side. If you are willing, I would like to invite you to add your test part based on this PR.

@KozhinovAlexander
Copy link
Contributor

Great addition. Thanks. I've added few comments and will do more reviews later. I think samples could be safely replaced by tests. Or you may leave samples, but tests are must-have imho. Take a look at opamp branch in my fork of zephyr. I have there tests - feel free to grab them ;) main...KozhinovAlexander:zephyr:opamp The test will be also fairly simple, since API is simple too. UPD: General documentation for opamp (an .rst file) is also missed. I think with such documentation the questions from @decsny could be answerde simpler ;)

Hello @KozhinovAlexander, you also do some excellent work, I looked your commit, and you have done a better job in testing side. If you are willing, I would like to invite you to add your test part based on this PR.

Hi. Thank you for your feedback. I'll prepare today anyways everything reworked on top of your branch and try to stay synched with this PR holding my changes back until a review of the architecture proposed here is done.

Add opamp API header.

Signed-off-by: Zhaoxiang Jin <Zhaoxiang.Jin_1@nxp.com>
Add opamp and opamp_fast driver to zephyr build tree.

Signed-off-by: Zhaoxiang Jin <Zhaoxiang.Jin_1@nxp.com>
@ZhaoxiangJin ZhaoxiangJin force-pushed the feature/create-opamp-device-driver-api branch 2 times, most recently from abe8f40 to 6fd2d8d Compare August 10, 2025 10:14
This commit includes the following changes:
1. Add top level CMakeLists.txt entry and Kconfig.
2. Add bindings for opamp-controller, it includes
    opamp functional mode property.
2. Add bindings for nxp,opamp and nxp,opamp_fast.
3. Implemented NXP opamp and opamp_fast device driver.

Signed-off-by: Zhaoxiang Jin <Zhaoxiang.Jin_1@nxp.com>
Add opamp node for mcxa156.
Support opamp for frdm_mcxa156.

Signed-off-by: Zhaoxiang Jin <Zhaoxiang.Jin_1@nxp.com>
Add opamp node for mcxa166.
Support opamp for frdm_mcxa166.

Signed-off-by: Zhaoxiang Jin <Zhaoxiang.Jin_1@nxp.com>
Add opamp node for mcxa276.
Support opamp for frdm_mcxa276.

Signed-off-by: Zhaoxiang Jin <Zhaoxiang.Jin_1@nxp.com>
Add opamp node for mcxn947.
Support opamp for frdm_mcxn947.

Signed-off-by: Zhaoxiang Jin <Zhaoxiang.Jin_1@nxp.com>
Add opamp node for lpc55S36.
Support opamp for lpcxpresso55s36.

Signed-off-by: Zhaoxiang Jin <Zhaoxiang.Jin_1@nxp.com>
Add output_measure exmaple, enabled on frdm_mcxa156,
frdm_mcxa166, frdm_mcxa276, frdm_mcxn947_mcxn947_cpu0,
lpcxpresso55s36.

Signed-off-by: Zhaoxiang Jin <Zhaoxiang.Jin_1@nxp.com>
Add documentation for the opamp peripheral.

Signed-off-by: Zhaoxiang Jin <Zhaoxiang.Jin_1@nxp.com>
Added opamp driver and example support to release
notes for release 4.3

Signed-off-by: Zhaoxiang Jin <Zhaoxiang.Jin_1@nxp.com>
@ZhaoxiangJin ZhaoxiangJin force-pushed the feature/create-opamp-device-driver-api branch from 6fd2d8d to b045046 Compare August 10, 2025 13:56
Copy link

@KozhinovAlexander
Copy link
Contributor

KozhinovAlexander commented Aug 10, 2025

@ZhaoxiangJin Thank you for the review request. I think first two major things shall be done: 1. Fix CI failures. 2. Take care of architecture review.
Afterwards I hope we will proceed faster here.

@kartben kartben removed their assignment Aug 10, 2025
Comment on lines +17 to +20
- "Input0" # MCU internal DAC out
- "Input1" # VDD / 2
- "Input2" # MCU internal VREF out
- "Input3" # Fixed 520mv
Copy link
Contributor

Choose a reason for hiding this comment

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

You can refer to the following for the enumeration description:

from i3c/renesas,ra-i3c.yaml

  clock-names:
    required: true
    enum:
      - "pclk"
      - "tclk"
    description: |
      Clocks must be given corresponding names so that the shim driver can recognize them.
      "pclk": peripheral clock source
      "tclk": transfer clock source

(Even better if we keep the style the same.)

operation-mode:
type: string
enum:
- "low_noise" # OPAMP in low noise mode
Copy link
Contributor

Choose a reason for hiding this comment

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

+1

bias-current:
type: int
enum:
- 0 # Default value. Keep power consumption constant
Copy link
Contributor

Choose a reason for hiding this comment

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

+1

Comment on lines +44 to +47
/** Inverting gain identifier of the OPAMP that should be configured. */
uint8_t inverting_gain;
/** Non-inverting gain identifier of the OPAMP that should be configured. */
uint8_t non_inverting_gain;
Copy link
Contributor

Choose a reason for hiding this comment

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

For this to be portable, these values need to be SI units of some sort, like ADC_GAIN_1_5 (1/5) etc. or an actual fixed point fraction in micro or something (micro_gain)

Copy link
Contributor

Choose a reason for hiding this comment

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

Looking at STM32 they support gains of 2, 4, 8 ... and -1, -3, ... which seems rather common

Copy link
Contributor Author

Choose a reason for hiding this comment

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

STM32 support inverting mode and non-inverting mode, for inverting mode, it support 2,4,8...for non-inverting it support -1, -3.
So under the OPAMP device driver model, we need to first determine the OPAMP functional mode in DT, and then determine the gain. For inverting mode, we need to set the gain to 1, 3...
I haven't seen any fractional gain, if you know, please let me know.

Copy link
Contributor

@KozhinovAlexander KozhinovAlexander Aug 12, 2025

Choose a reason for hiding this comment

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

Great discussion here. My two cents:

  • I have also not seen fractional gain so far.
  • To keep API interface as long as possible stable from beginning - it could be better to typedef an arbitrary integer type with some opamp_gain_t type. This shall allow all the API functions always accept this gain only, while it's type could be adjusted later as API approaches more stable status.

Copy link
Contributor

Choose a reason for hiding this comment

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

the issue with this approach is portability, if the value passed to the API is an opaque soc/driver specific value, its not actually portable, unless the value is defined in the devicetree or something similar. just an integer could mean anything.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you. Makes sense. I think we shall wait for the architecture review, as it was proposed earlier.

Copy link
Member

Choose a reason for hiding this comment

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

@KozhinovAlexander architecture review call already just happened, that's why he was commenting. that is the review.

Comment on lines +56 to +57
typedef int (*opamp_api_enable_t)(const struct device *dev);
typedef int (*opamp_api_disable_t)(const struct device *dev);
Copy link
Contributor

Choose a reason for hiding this comment

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

Enable and disable are synonymous with PM resume and suspend. If the reason to disable the opamp is to preserve power, PM can be used instead.

Copy link
Contributor

Choose a reason for hiding this comment

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

Would pm then disable clock over MCUs clock system?
ST has two types of disabling for example: An older stm32h745 will disable clock system driving opamps logic, while newer stm32g4 will not have any disable bits, since it is kind of asynchronous driven in terms of configuration.

Copy link
Contributor

Choose a reason for hiding this comment

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

The PM suspend and resume would have the same logic which disable() and enable() would have I would assume. RESUME means device is operational, so if that requires a clock, the clock would be on in this case. Not sure what "kind of asynchronous driven in terms of configuration" means :)

@carlescufi
Copy link
Member

carlescufi commented Aug 12, 2025

Architecture WG meeting:

  • @ZhaoxiangJin presents the API and concepts with slides
  • Using io-channels and io-channel-cells to connect different peripherals is introduced in this PR, although this has also been conceptually done before by just using phandles
  • @bjarki-andreasen points out that we may not need 2 gain values in the config structure. @ZhaoxiangJin will look into other hw implementations to see if this is generalizable
  • @carlescufi suggests to make opamp_functional_mode private since it's not used in the API
  • @bjarki-andreasen to check if PM can be used instead of having enable() and disable(), but @henrikbrixandersen states that requiring the PM subsystem may be overkill

@decsny
Copy link
Member

decsny commented Aug 12, 2025

  • Using io-channels and io-channel-cells to connect different peripherals is introduced in this PR, although this has also been conceptually done before by just using phandles

This is not true, it's already been done plenty of times, most common is having ADC input to another peripheral

@decsny
Copy link
Member

decsny commented Aug 12, 2025

Other comment from arch WG not listed above from @bjarki-andreasen was that the API may not be generic enough, the config structure seems tailored to NXP op amp. The reason is likely because NXP op amp can configure positive and negative side of op amp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Architecture Review Discussion in the Architecture WG required area: Devicetree area: Samples Samples platform: NXP Drivers NXP Semiconductors, drivers platform: NXP NXP Release Notes To be mentioned in the release notes RFC Request For Comments: want input from the community
Projects
Status: Todo
Development

Successfully merging this pull request may close these issues.