Lines Matching +full:irq +full:- +full:device
1 // SPDX-License-Identifier: GPL-2.0
7 * https://www.mipi.org/mipi-sdca-v1-0-download
13 #include <linux/device.h>
21 #include <sound/soc-component.h>
75 static irqreturn_t base_handler(int irq, void *data) in base_handler() argument
78 struct device *dev = interrupt->component->dev; in base_handler()
80 dev_info(dev, "%s irq without full handling\n", interrupt->name); in base_handler()
85 static irqreturn_t function_status_handler(int irq, void *data) in function_status_handler() argument
88 struct device *dev = interrupt->component->dev; in function_status_handler()
94 reg = SDW_SDCA_CTL(interrupt->function->desc->adr, interrupt->entity->id, in function_status_handler()
95 interrupt->control->sel, 0); in function_status_handler()
97 ret = regmap_read(interrupt->component->regmap, reg, &val); in function_status_handler()
130 ret = regmap_write(interrupt->component->regmap, reg, val); in function_status_handler()
139 static irqreturn_t detected_mode_handler(int irq, void *data) in detected_mode_handler() argument
142 struct snd_soc_component *component = interrupt->component; in detected_mode_handler()
143 struct device *dev = component->dev; in detected_mode_handler()
144 struct snd_soc_card *card = component->card; in detected_mode_handler()
145 struct rw_semaphore *rwsem = &card->snd_card->controls_rwsem; in detected_mode_handler()
146 struct snd_kcontrol *kctl = interrupt->priv; in detected_mode_handler()
154 interrupt->entity->label, in detected_mode_handler()
166 interrupt->priv = kctl; in detected_mode_handler()
169 soc_enum = (struct soc_enum *)kctl->private_value; in detected_mode_handler()
171 reg = SDW_SDCA_CTL(interrupt->function->desc->adr, interrupt->entity->id, in detected_mode_handler()
172 interrupt->control->sel, 0); in detected_mode_handler()
174 ret = regmap_read(component->regmap, reg, &val); in detected_mode_handler()
183 reg = SDW_SDCA_CTL(interrupt->function->desc->adr, in detected_mode_handler()
184 interrupt->entity->id, in detected_mode_handler()
190 * detected mode is unknown we need to see what the device in detected_mode_handler()
193 regcache_drop_region(component->regmap, reg, reg); in detected_mode_handler()
195 ret = regmap_read(component->regmap, reg, &val); in detected_mode_handler()
197 dev_err(dev, "failed to re-check selected mode: %d\n", ret); in detected_mode_handler()
205 dev_dbg(dev, "%s: %#x\n", interrupt->name, val); in detected_mode_handler()
211 ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(soc_enum, val); in detected_mode_handler()
214 ret = kctl->put(kctl, ucontrol); in detected_mode_handler()
221 snd_ctl_notify(card->snd_card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); in detected_mode_handler()
226 static int sdca_irq_request_locked(struct device *dev, in sdca_irq_request_locked()
231 int irq; in sdca_irq_request_locked() local
234 irq = regmap_irq_get_virq(info->irq_data, sdca_irq); in sdca_irq_request_locked()
235 if (irq < 0) in sdca_irq_request_locked()
236 return irq; in sdca_irq_request_locked()
238 ret = devm_request_threaded_irq(dev, irq, NULL, handler, in sdca_irq_request_locked()
243 dev_dbg(dev, "requested irq %d for %s\n", irq, name); in sdca_irq_request_locked()
249 * sdca_request_irq - request an individual SDCA interrupt
250 * @dev: Pointer to the struct device against which things should be allocated.
253 * @name: Name to be given to the IRQ.
254 * @handler: A callback thread function to be called for the IRQ.
258 * a device requires custom IRQ handling this can be called manually before
259 * calling sdca_irq_populate, which will then skip that IRQ whilst processing.
263 int sdca_irq_request(struct device *dev, struct sdca_interrupt_info *info, in sdca_irq_request()
270 dev_err(dev, "bad irq request: %d\n", sdca_irq); in sdca_irq_request()
271 return -EINVAL; in sdca_irq_request()
274 guard(mutex)(&info->irq_lock); in sdca_irq_request()
278 dev_err(dev, "failed to request irq %s: %d\n", name, ret); in sdca_irq_request()
282 info->irqs[sdca_irq].externally_requested = true; in sdca_irq_request()
289 * sdca_irq_data_populate - Populate common interrupt data
294 * @interrupt: Pointer to the SDCA interrupt for this IRQ.
304 struct device *dev = component->dev; in sdca_irq_data_populate()
307 name = devm_kasprintf(dev, GFP_KERNEL, "%s %s %s", function->desc->name, in sdca_irq_data_populate()
308 entity->label, control->label); in sdca_irq_data_populate()
310 return -ENOMEM; in sdca_irq_data_populate()
312 interrupt->name = name; in sdca_irq_data_populate()
313 interrupt->component = component; in sdca_irq_data_populate()
314 interrupt->function = function; in sdca_irq_data_populate()
315 interrupt->entity = entity; in sdca_irq_data_populate()
316 interrupt->control = control; in sdca_irq_data_populate()
323 * sdca_irq_populate - Request all the individual IRQs for an SDCA Function
326 * @info: Pointer to the SDCA interrupt info for this device.
336 struct device *dev = component->dev; in sdca_irq_populate()
339 guard(mutex)(&info->irq_lock); in sdca_irq_populate()
341 for (i = 0; i < function->num_entities; i++) { in sdca_irq_populate()
342 struct sdca_entity *entity = &function->entities[i]; in sdca_irq_populate()
344 for (j = 0; j < entity->num_controls; j++) { in sdca_irq_populate()
345 struct sdca_control *control = &entity->controls[j]; in sdca_irq_populate()
346 int irq = control->interrupt_position; in sdca_irq_populate() local
351 if (irq == SDCA_NO_INTERRUPT) { in sdca_irq_populate()
353 } else if (irq < 0 || irq >= SDCA_MAX_INTERRUPTS) { in sdca_irq_populate()
354 dev_err(dev, "bad irq position: %d\n", irq); in sdca_irq_populate()
355 return -EINVAL; in sdca_irq_populate()
358 interrupt = &info->irqs[irq]; in sdca_irq_populate()
360 if (interrupt->externally_requested) { in sdca_irq_populate()
362 "skipping irq %d, externally requested\n", in sdca_irq_populate()
363 irq); in sdca_irq_populate()
374 switch (entity->type) { in sdca_irq_populate()
376 if (control->sel == SDCA_CTL_ENTITY_0_FUNCTION_STATUS) in sdca_irq_populate()
380 if (control->sel == SDCA_CTL_GE_DETECTED_MODE) in sdca_irq_populate()
387 ret = sdca_irq_request_locked(dev, info, irq, interrupt->name, in sdca_irq_populate()
390 dev_err(dev, "failed to request irq %s: %d\n", in sdca_irq_populate()
391 interrupt->name, ret); in sdca_irq_populate()
402 * sdca_irq_allocate - allocate an SDCA interrupt structure for a device
403 * @dev: Device pointer against which things should be allocated.
404 * @regmap: regmap to be used for accessing the SDCA IRQ registers.
405 * @irq: The interrupt number.
408 * SDCA device, as only a single instance is required across all Functions
409 * on the device.
414 struct sdca_interrupt_info *sdca_irq_allocate(struct device *dev, in sdca_irq_allocate()
415 struct regmap *regmap, int irq) in sdca_irq_allocate() argument
422 return ERR_PTR(-ENOMEM); in sdca_irq_allocate()
424 info->irq_chip = sdca_irq_chip; in sdca_irq_allocate()
426 ret = devm_mutex_init(dev, &info->irq_lock); in sdca_irq_allocate()
430 ret = devm_regmap_add_irq_chip(dev, regmap, irq, IRQF_ONESHOT, 0, in sdca_irq_allocate()
431 &info->irq_chip, &info->irq_data); in sdca_irq_allocate()
433 dev_err(dev, "failed to register irq chip: %d\n", ret); in sdca_irq_allocate()
437 dev_dbg(dev, "registered on irq %d\n", irq); in sdca_irq_allocate()
444 MODULE_DESCRIPTION("SDCA IRQ library");