diff options
| -rw-r--r-- | include/sound/sdca_interrupts.h | 3 | ||||
| -rw-r--r-- | sound/soc/sdca/sdca_interrupts.c | 71 |
2 files changed, 74 insertions, 0 deletions
diff --git a/include/sound/sdca_interrupts.h b/include/sound/sdca_interrupts.h index 3983f515349a..8f13417d129a 100644 --- a/include/sound/sdca_interrupts.h +++ b/include/sound/sdca_interrupts.h @@ -75,6 +75,9 @@ int sdca_irq_data_populate(struct device *dev, struct regmap *function_regmap, struct sdca_entity *entity, struct sdca_control *control, struct sdca_interrupt *interrupt); +int sdca_irq_populate_early(struct device *dev, struct regmap *function_regmap, + struct sdca_function_data *function, + struct sdca_interrupt_info *info); int sdca_irq_populate(struct sdca_function_data *function, struct snd_soc_component *component, struct sdca_interrupt_info *info); diff --git a/sound/soc/sdca/sdca_interrupts.c b/sound/soc/sdca/sdca_interrupts.c index 3a3b966b5782..51342b8aacae 100644 --- a/sound/soc/sdca/sdca_interrupts.c +++ b/sound/soc/sdca/sdca_interrupts.c @@ -397,6 +397,77 @@ static struct sdca_interrupt *get_interrupt_data(struct device *dev, int irq, } /** + * sdca_irq_populate_early - process pre-audio card IRQ registrations + * @dev: Device pointer for SDCA Function. + * @regmap: Regmap pointer for the SDCA Function. + * @function: Pointer to the SDCA Function. + * @info: Pointer to the SDCA interrupt info for this device. + * + * This is intended to be used as part of the Function boot process. It + * can be called before the soundcard is registered (ie. doesn't depend + * on component) and will register the FDL interrupts. + * + * Return: Zero on success, and a negative error code on failure. + */ +int sdca_irq_populate_early(struct device *dev, struct regmap *regmap, + struct sdca_function_data *function, + struct sdca_interrupt_info *info) +{ + int i, j; + + guard(mutex)(&info->irq_lock); + + for (i = 0; i < function->num_entities; i++) { + struct sdca_entity *entity = &function->entities[i]; + + for (j = 0; j < entity->num_controls; j++) { + struct sdca_control *control = &entity->controls[j]; + int irq = control->interrupt_position; + struct sdca_interrupt *interrupt; + int ret; + + interrupt = get_interrupt_data(dev, irq, info); + if (IS_ERR(interrupt)) + return PTR_ERR(interrupt); + else if (!interrupt) + continue; + + switch (entity->type) { + case SDCA_ENTITY_TYPE_XU: + if (control->sel != SDCA_CTL_XU_FDL_CURRENTOWNER) + break; + + ret = sdca_irq_data_populate(dev, regmap, NULL, + function, entity, + control, interrupt); + if (ret) + return ret; + + ret = sdca_fdl_alloc_state(interrupt); + if (ret) + return ret; + + ret = sdca_irq_request_locked(dev, info, irq, + interrupt->name, + fdl_owner_handler, + interrupt); + if (ret) { + dev_err(dev, "failed to request irq %s: %d\n", + interrupt->name, ret); + return ret; + } + break; + default: + break; + } + } + } + + return 0; +} +EXPORT_SYMBOL_NS_GPL(sdca_irq_populate_early, "SND_SOC_SDCA"); + +/** * sdca_irq_populate - Request all the individual IRQs for an SDCA Function * @function: Pointer to the SDCA Function. * @component: Pointer to the ASoC component for the Function. |