forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 145
ASoC/SoundWire: add SDCA helper library #5128
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
Closed
plbossart
wants to merge
13
commits into
thesofproject:topic/sof-dev
from
plbossart:sdw/sdca-library
Closed
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
c351382
ASoC/soundwire: remove sdw_slave_extended_id
plbossart b207983
ASoC: SDCA: add initial module
plbossart 8593b9f
soundwire: slave: lookup SDCA version and functions
plbossart 853635d
ASoC: SDCA: add quirk function for RT712_VB match
plbossart 06d30f4
ASoC: rt712-sdca: detect the SMART_MIC function during the probe stage
plbossart 92eceb9
ASoC: soc-acpi: introduce new 'machine check' callback
plbossart b41f72b
ASoC: sdw_utils: add SmartMic DAI for RT712 VB
plbossart 44628c7
ASoC: sdw_utils: add SmartMic DAI for RT713 VB
plbossart 0fa12e5
ASoC: Intel: soc-acpi: add is_device_rt712_vb() helper
plbossart 35c14a4
ASoC: SOF: Intel: hda: use machine_check() for SoundWire
plbossart e72da87
ASoC: SDCA: add helpers to handle SDCA interrupt sources
plbossart 43c3910
ASoC: rt711-sdca: use generic SDCA interrupt handler
plbossart 3ab9b70
ASoC: rt712-sdca: use generic SDCA interrupt handler
plbossart File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,162 @@ | ||
| /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ | ||
| /* | ||
| * The MIPI SDCA specification is available for public downloads at | ||
| * https://www.mipi.org/mipi-sdca-v1-0-download | ||
| * | ||
| * Copyright(c) 2024 Intel Corporation | ||
| */ | ||
|
|
||
| #ifndef __SDCA_H__ | ||
| #define __SDCA_H__ | ||
|
|
||
| struct sdw_slave; | ||
|
|
||
| #define SDCA_MAX_INTERRUPTS 31 /* the last bit is reserved for future extensions */ | ||
|
|
||
| /** | ||
| * struct sdca_interrupt_source - interface between interrupt source and | ||
| * SoundWire SDCA interrupt handler | ||
| * | ||
| * @index: SDCA interrupt number in [0, SDCA_MAX_INTERRUPTS - 1] | ||
| * @context: source-specific information, used by @callback | ||
| * @callback: provided by interrupt source for source-specific handling. | ||
| */ | ||
| struct sdca_interrupt_source { | ||
| int index; | ||
| void *context; | ||
| void (*callback)(void *context); | ||
| }; | ||
|
|
||
| /** | ||
| * struct sdca_interrupt_info - Peripheral device-level information | ||
| * used for interrupt handler | ||
| * | ||
| * @sources: array of pointers, addressed with an interrupt index | ||
| * matching @registered_source_mask bits. | ||
| * @irqs_lock: mutex protecting concurrent access to @sources, | ||
| * @registered_source_mask and reventing SDCA interrupts from being disabled | ||
| * on suspend while being handled. | ||
| * @enabled_interrupt_mask: mask indicating which interrupts from @registered_source_mask | ||
| * are currently enabled. | ||
| * @detected_interrupt_mask: bitfields set in interrupt handler, and accessible | ||
| * in deferred processing. | ||
| * @supported_hw_register_mask: Up to 4 registers may be implemented | ||
| */ | ||
| struct sdca_interrupt_info { | ||
| struct sdca_interrupt_source *sources[SDCA_MAX_INTERRUPTS]; | ||
| struct mutex irqs_lock; /* protects SDCA interrupts */ | ||
| u32 registered_source_mask; | ||
| u32 enabled_interrupt_mask; | ||
| u32 detected_interrupt_mask; | ||
| int supported_hw_register_mask; | ||
| }; | ||
|
|
||
| #define SDCA_MAX_FUNCTION_COUNT 8 | ||
|
|
||
| /** | ||
| * sdca_device_desc - short descriptor for an SDCA Function | ||
| * @adr: ACPI address (used for SDCA register access) | ||
| * @type: Function topology type | ||
| * @name: human-readable string | ||
| */ | ||
| struct sdca_function_desc { | ||
| u64 adr; | ||
| u32 type; | ||
| const char *name; | ||
| }; | ||
|
|
||
| /** | ||
| * sdca_device_data - structure containing all SDCA related information | ||
| * @sdca_interface_revision: value read from _DSD property, mainly to check | ||
| * for changes between silicon versions | ||
| * @num_functions: total number of supported SDCA functions. Invalid/unsupported | ||
| * functions will be skipped. | ||
| * @sdca_func: array of function descriptors | ||
| * @interrupt_info: device-level interrupt configuration/handling | ||
| */ | ||
| struct sdca_device_data { | ||
| u32 interface_revision; | ||
| int num_functions; | ||
| struct sdca_function_desc sdca_func[SDCA_MAX_FUNCTION_COUNT]; | ||
| struct sdca_interrupt_info *interrupt_info; | ||
|
plbossart marked this conversation as resolved.
|
||
| }; | ||
|
|
||
| enum sdca_quirk { | ||
| SDCA_QUIRKS_RT712_VB, | ||
| }; | ||
|
|
||
| #if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SDCA) | ||
|
|
||
| void sdca_lookup_functions(struct sdw_slave *slave); | ||
| void sdca_lookup_interface_revision(struct sdw_slave *slave); | ||
| bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk); | ||
|
|
||
| #else | ||
|
|
||
| static inline void sdca_lookup_functions(struct sdw_slave *slave) {} | ||
| static inline void sdca_lookup_interface_revision(struct sdw_slave *slave) {} | ||
| static inline bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| #endif | ||
|
|
||
| #if IS_ENABLED(CONFIG_SND_SOC_SDCA_IRQ_HANDLER) | ||
|
|
||
| int sdca_interrupt_info_alloc(struct sdw_slave *slave); | ||
| void sdca_interrupt_info_release(struct sdw_slave *slave); | ||
| int sdca_interrupt_info_reset(struct sdw_slave *slave); | ||
| int sdca_interrupt_initialize(struct sdw_slave *slave, | ||
| int supported_hw_register_mask); | ||
| int sdca_interrupt_register_source(struct sdw_slave *slave, | ||
| struct sdca_interrupt_source *source); | ||
| int sdca_interrupt_enable(struct sdw_slave *slave, | ||
| u32 source_mask, | ||
| bool enable); | ||
| void sdca_interrupt_clear_history(struct sdw_slave *slave, u32 preserve_mask); | ||
| int sdca_interrupt_handler(struct sdw_slave *slave); | ||
|
|
||
| #else | ||
|
|
||
| static inline int sdca_interrupt_info_alloc(struct sdw_slave *slave) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| static inline void sdca_interrupt_info_release(struct sdw_slave *slave) {} | ||
|
|
||
| static inline int sdca_interrupt_info_reset(struct sdw_slave *slave) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| static inline int sdca_interrupt_initialize(struct sdw_slave *slave, | ||
| int supported_hw_register_mask) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| static inline int sdca_interrupt_register_source(struct sdw_slave *slave, | ||
| struct sdca_interrupt_source *source) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| static inline int sdca_interrupt_enable(struct sdw_slave *slave, | ||
| u32 source_mask, | ||
| bool enable) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| static inline void sdca_interrupt_clear_history(struct sdw_slave *slave, u32 preserve_mask) {} | ||
|
|
||
| static inline int sdca_interrupt_handler(struct sdw_slave *slave) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| #endif /* IS_ENABLED(CONFIG_SND_SOC_SDCA_IRQ_HANDLER) */ | ||
|
|
||
| #endif | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this really need to be called from the core, feels like it makes things a lot nicer if it is called from the end driver rather than the soundwire core?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You missed my note in the commit message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah the machine match stuff is kinda interesting I kinda wonder if it could actually be handy for some of the cs42l43 quirks, but I really don't like the way it splits the disco parsing and kinda forces one to rely on a disco constant for the function type. Whilst I imagine most parts will use a disco constant for that I think it would be totally fine for that not to be a constant no?
Just to make sure I understand the situation you have with this part, the part has all the same IDs etc, but the later version of the part adds a smart mic feature? I guess I can't help but wonder if this is actually being driven by a larger issue in the machine driver, in that really with a class device one probably wants to add all the DAI links conditionally on the disco.
I am still pretty deep in a noodling session based on one of your slightly earlier pull requests, still focusing on the register map stuff. Think I have mostly got to the point where I can parse the whole register map from DisCo and handle the disco constants and fixed/default values. I will try to tidy things up a bit and port stuff onto your newer pull here. Hopefully I can then push a series for some discussion, the reason I am looking at this bit is the splitting of the disco parsing is a little tricky for the regmap stuff as it wants to see all the disco and well it feels a bit like the wrong layer to be parsing it at the soundwire layer. Also in keeping with the library concept feel nicer to have the driver call something to parse it. Will do some more thinking and report back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the problem statement is that the part has all the same IDs etc, but the later version of the part adds a smart mic
featurefunction. that means we need a topology that adds the mic path.We could add the dailink for the mic conditionally, but it's not necessary. The rule is that the machine driver needs to expose all the dailinks referenced by the topology, but it's ok to expose additional dailinks not used by the topology. So if the machine driver exposes a mic path with RT713 VA, it'd be just fine. Nothing bad would happen. In other words, exposing all links unconditionally actually makes the machine driver less complex.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re: the parsing stuff, I don't disagree that it should be handled in a codec driver for all disco properties,
The main issue is that the hardware discovery MUST work reliably without depending on if/when the codec driver probe happens. if the codec driver is blacklisted and modprobe'd manually 'later', we still want the information on topology to be available on the SOF PCI driver side. That's the reason why I added this short parsing of ACPI stuff before the codec driver probe happens.