xref: /linux/sound/soc/sdca/sdca_interrupts.c (revision af0bc3ac9a9e830cb52b718ecb237c4e76a466be)
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2025 Cirrus Logic, Inc. and
3 //                    Cirrus Logic International Semiconductor Ltd.
4 
5 /*
6  * The MIPI SDCA specification is available for public downloads at
7  * https://www.mipi.org/mipi-sdca-v1-0-download
8  */
9 
10 #include <linux/bitmap.h>
11 #include <linux/bits.h>
12 #include <linux/cleanup.h>
13 #include <linux/device.h>
14 #include <linux/dev_printk.h>
15 #include <linux/interrupt.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/regmap.h>
18 #include <linux/soundwire/sdw.h>
19 #include <linux/soundwire/sdw_registers.h>
20 #include <sound/sdca.h>
21 #include <sound/sdca_fdl.h>
22 #include <sound/sdca_function.h>
23 #include <sound/sdca_hid.h>
24 #include <sound/sdca_interrupts.h>
25 #include <sound/sdca_jack.h>
26 #include <sound/sdca_ump.h>
27 #include <sound/soc-component.h>
28 #include <sound/soc.h>
29 
30 #define IRQ_SDCA(number) REGMAP_IRQ_REG(number, ((number) / BITS_PER_BYTE), \
31 					SDW_SCP_SDCA_INTMASK_SDCA_##number)
32 
33 static const struct regmap_irq regmap_irqs[SDCA_MAX_INTERRUPTS] = {
34 	IRQ_SDCA(0),
35 	IRQ_SDCA(1),
36 	IRQ_SDCA(2),
37 	IRQ_SDCA(3),
38 	IRQ_SDCA(4),
39 	IRQ_SDCA(5),
40 	IRQ_SDCA(6),
41 	IRQ_SDCA(7),
42 	IRQ_SDCA(8),
43 	IRQ_SDCA(9),
44 	IRQ_SDCA(10),
45 	IRQ_SDCA(11),
46 	IRQ_SDCA(12),
47 	IRQ_SDCA(13),
48 	IRQ_SDCA(14),
49 	IRQ_SDCA(15),
50 	IRQ_SDCA(16),
51 	IRQ_SDCA(17),
52 	IRQ_SDCA(18),
53 	IRQ_SDCA(19),
54 	IRQ_SDCA(20),
55 	IRQ_SDCA(21),
56 	IRQ_SDCA(22),
57 	IRQ_SDCA(23),
58 	IRQ_SDCA(24),
59 	IRQ_SDCA(25),
60 	IRQ_SDCA(26),
61 	IRQ_SDCA(27),
62 	IRQ_SDCA(28),
63 	IRQ_SDCA(29),
64 	IRQ_SDCA(30),
65 };
66 
67 static const struct regmap_irq_chip sdca_irq_chip = {
68 	.name = "sdca_irq",
69 
70 	.status_base = SDW_SCP_SDCA_INT1,
71 	.unmask_base = SDW_SCP_SDCA_INTMASK1,
72 	.ack_base = SDW_SCP_SDCA_INT1,
73 	.num_regs = 4,
74 
75 	.irqs = regmap_irqs,
76 	.num_irqs = SDCA_MAX_INTERRUPTS,
77 
78 	.runtime_pm = true,
79 };
80 
81 static irqreturn_t base_handler(int irq, void *data)
82 {
83 	struct sdca_interrupt *interrupt = data;
84 	struct device *dev = interrupt->dev;
85 
86 	dev_info(dev, "%s irq without full handling\n", interrupt->name);
87 
88 	return IRQ_HANDLED;
89 }
90 
91 static irqreturn_t function_status_handler(int irq, void *data)
92 {
93 	struct sdca_interrupt *interrupt = data;
94 	struct device *dev = interrupt->dev;
95 	irqreturn_t irqret = IRQ_NONE;
96 	unsigned int reg, val;
97 	unsigned long status;
98 	unsigned int mask;
99 	int ret;
100 
101 	ret = pm_runtime_get_sync(dev);
102 	if (ret < 0) {
103 		dev_err(dev, "failed to resume for function status: %d\n", ret);
104 		goto error;
105 	}
106 
107 	reg = SDW_SDCA_CTL(interrupt->function->desc->adr, interrupt->entity->id,
108 			   interrupt->control->sel, 0);
109 
110 	ret = regmap_read(interrupt->function_regmap, reg, &val);
111 	if (ret < 0) {
112 		dev_err(dev, "failed to read function status: %d\n", ret);
113 		goto error;
114 	}
115 
116 	dev_dbg(dev, "function status: %#x\n", val);
117 
118 	status = val;
119 	for_each_set_bit(mask, &status, BITS_PER_BYTE) {
120 		mask = 1 << mask;
121 
122 		switch (mask) {
123 		case SDCA_CTL_ENTITY_0_FUNCTION_NEEDS_INITIALIZATION:
124 			//FIXME: Add init writes
125 			break;
126 		case SDCA_CTL_ENTITY_0_FUNCTION_FAULT:
127 			dev_err(dev, "function fault\n");
128 			break;
129 		case SDCA_CTL_ENTITY_0_UMP_SEQUENCE_FAULT:
130 			dev_err(dev, "ump sequence fault\n");
131 			break;
132 		case SDCA_CTL_ENTITY_0_FUNCTION_BUSY:
133 			dev_info(dev, "unexpected function busy\n");
134 			break;
135 		case SDCA_CTL_ENTITY_0_DEVICE_NEWLY_ATTACHED:
136 		case SDCA_CTL_ENTITY_0_INTS_DISABLED_ABNORMALLY:
137 		case SDCA_CTL_ENTITY_0_STREAMING_STOPPED_ABNORMALLY:
138 		case SDCA_CTL_ENTITY_0_FUNCTION_HAS_BEEN_RESET:
139 			break;
140 		}
141 	}
142 
143 	ret = regmap_write(interrupt->function_regmap, reg, val);
144 	if (ret < 0) {
145 		dev_err(dev, "failed to clear function status: %d\n", ret);
146 		goto error;
147 	}
148 
149 	irqret = IRQ_HANDLED;
150 error:
151 	pm_runtime_put(dev);
152 	return irqret;
153 }
154 
155 static irqreturn_t detected_mode_handler(int irq, void *data)
156 {
157 	struct sdca_interrupt *interrupt = data;
158 	struct device *dev = interrupt->dev;
159 	irqreturn_t irqret = IRQ_NONE;
160 	int ret;
161 
162 	ret = pm_runtime_get_sync(dev);
163 	if (ret < 0) {
164 		dev_err(dev, "failed to resume for detected mode: %d\n", ret);
165 		goto error;
166 	}
167 
168 	ret = sdca_jack_process(interrupt);
169 	if (ret)
170 		goto error;
171 
172 	irqret = IRQ_HANDLED;
173 error:
174 	pm_runtime_put(dev);
175 	return irqret;
176 }
177 
178 static irqreturn_t hid_handler(int irq, void *data)
179 {
180 	struct sdca_interrupt *interrupt = data;
181 	struct device *dev = interrupt->dev;
182 	irqreturn_t irqret = IRQ_NONE;
183 	int ret;
184 
185 	ret = pm_runtime_get_sync(dev);
186 	if (ret < 0) {
187 		dev_err(dev, "failed to resume for hid: %d\n", ret);
188 		goto error;
189 	}
190 
191 	ret = sdca_hid_process_report(interrupt);
192 	if (ret)
193 		goto error;
194 
195 	irqret = IRQ_HANDLED;
196 error:
197 	pm_runtime_put(dev);
198 	return irqret;
199 }
200 
201 #ifdef CONFIG_PM_SLEEP
202 static bool no_pm_in_progress(struct device *dev)
203 {
204 	return completion_done(&dev->power.completion);
205 }
206 #else
207 static bool no_pm_in_progress(struct device *dev)
208 {
209 	return true;
210 }
211 #endif
212 
213 static irqreturn_t fdl_owner_handler(int irq, void *data)
214 {
215 	struct sdca_interrupt *interrupt = data;
216 	struct device *dev = interrupt->dev;
217 	irqreturn_t irqret = IRQ_NONE;
218 	int ret;
219 
220 	/*
221 	 * FDL has to run from the system resume handler, at which point
222 	 * we can't wait for the pm runtime.
223 	 */
224 	if (no_pm_in_progress(dev)) {
225 		ret = pm_runtime_get_sync(dev);
226 		if (ret < 0) {
227 			dev_err(dev, "failed to resume for fdl: %d\n", ret);
228 			goto error;
229 		}
230 	}
231 
232 	ret = sdca_fdl_process(interrupt);
233 	if (ret)
234 		goto error;
235 
236 	irqret = IRQ_HANDLED;
237 error:
238 	if (no_pm_in_progress(dev))
239 		pm_runtime_put(dev);
240 	return irqret;
241 }
242 
243 static int sdca_irq_request_locked(struct device *dev,
244 				   struct sdca_interrupt_info *info,
245 				   int sdca_irq, const char *name,
246 				   irq_handler_t handler, void *data)
247 {
248 	int irq;
249 	int ret;
250 
251 	irq = regmap_irq_get_virq(info->irq_data, sdca_irq);
252 	if (irq < 0)
253 		return irq;
254 
255 	ret = devm_request_threaded_irq(dev, irq, NULL, handler,
256 					IRQF_ONESHOT, name, data);
257 	if (ret)
258 		return ret;
259 
260 	info->irqs[sdca_irq].irq = irq;
261 
262 	dev_dbg(dev, "requested irq %d for %s\n", irq, name);
263 
264 	return 0;
265 }
266 
267 /**
268  * sdca_request_irq - request an individual SDCA interrupt
269  * @dev: Pointer to the struct device against which things should be allocated.
270  * @interrupt_info: Pointer to the interrupt information structure.
271  * @sdca_irq: SDCA interrupt position.
272  * @name: Name to be given to the IRQ.
273  * @handler: A callback thread function to be called for the IRQ.
274  * @data: Private data pointer that will be passed to the handler.
275  *
276  * Typically this is handled internally by sdca_irq_populate, however if
277  * a device requires custom IRQ handling this can be called manually before
278  * calling sdca_irq_populate, which will then skip that IRQ whilst processing.
279  *
280  * Return: Zero on success, and a negative error code on failure.
281  */
282 int sdca_irq_request(struct device *dev, struct sdca_interrupt_info *info,
283 		     int sdca_irq, const char *name, irq_handler_t handler,
284 		     void *data)
285 {
286 	int ret;
287 
288 	if (sdca_irq < 0 || sdca_irq >= SDCA_MAX_INTERRUPTS) {
289 		dev_err(dev, "bad irq request: %d\n", sdca_irq);
290 		return -EINVAL;
291 	}
292 
293 	guard(mutex)(&info->irq_lock);
294 
295 	ret = sdca_irq_request_locked(dev, info, sdca_irq, name, handler, data);
296 	if (ret) {
297 		dev_err(dev, "failed to request irq %s: %d\n", name, ret);
298 		return ret;
299 	}
300 
301 	return 0;
302 }
303 EXPORT_SYMBOL_NS_GPL(sdca_irq_request, "SND_SOC_SDCA");
304 
305 /**
306  * sdca_irq_data_populate - Populate common interrupt data
307  * @dev: Pointer to the Function device.
308  * @regmap: Pointer to the Function regmap.
309  * @component: Pointer to the ASoC component for the Function.
310  * @function: Pointer to the SDCA Function.
311  * @entity: Pointer to the SDCA Entity.
312  * @control: Pointer to the SDCA Control.
313  * @interrupt: Pointer to the SDCA interrupt for this IRQ.
314  *
315  * Return: Zero on success, and a negative error code on failure.
316  */
317 int sdca_irq_data_populate(struct device *dev, struct regmap *regmap,
318 			   struct snd_soc_component *component,
319 			   struct sdca_function_data *function,
320 			   struct sdca_entity *entity,
321 			   struct sdca_control *control,
322 			   struct sdca_interrupt *interrupt)
323 {
324 	const char *name;
325 
326 	if (!dev && component)
327 		dev = component->dev;
328 	if (!dev)
329 		return -ENODEV;
330 
331 	name = devm_kasprintf(dev, GFP_KERNEL, "%s %s %s", function->desc->name,
332 			      entity->label, control->label);
333 	if (!name)
334 		return -ENOMEM;
335 
336 	interrupt->name = name;
337 	interrupt->dev = dev;
338 	if (!regmap && component)
339 		interrupt->function_regmap = component->regmap;
340 	else
341 		interrupt->function_regmap = regmap;
342 	interrupt->component = component;
343 	interrupt->function = function;
344 	interrupt->entity = entity;
345 	interrupt->control = control;
346 
347 	return 0;
348 }
349 EXPORT_SYMBOL_NS_GPL(sdca_irq_data_populate, "SND_SOC_SDCA");
350 
351 static struct sdca_interrupt *get_interrupt_data(struct device *dev, int irq,
352 						 struct sdca_interrupt_info *info)
353 {
354 	if (irq == SDCA_NO_INTERRUPT) {
355 		return NULL;
356 	} else if (irq < 0 || irq >= SDCA_MAX_INTERRUPTS) {
357 		dev_err(dev, "bad irq position: %d\n", irq);
358 		return ERR_PTR(-EINVAL);
359 	}
360 
361 	if (info->irqs[irq].irq) {
362 		dev_dbg(dev, "skipping irq %d, already requested\n", irq);
363 		return NULL;
364 	}
365 
366 	return &info->irqs[irq];
367 }
368 
369 /**
370  * sdca_irq_populate_early - process pre-audio card IRQ registrations
371  * @dev: Device pointer for SDCA Function.
372  * @regmap: Regmap pointer for the SDCA Function.
373  * @function: Pointer to the SDCA Function.
374  * @info: Pointer to the SDCA interrupt info for this device.
375  *
376  * This is intended to be used as part of the Function boot process. It
377  * can be called before the soundcard is registered (ie. doesn't depend
378  * on component) and will register the FDL interrupts.
379  *
380  * Return: Zero on success, and a negative error code on failure.
381  */
382 int sdca_irq_populate_early(struct device *dev, struct regmap *regmap,
383 			    struct sdca_function_data *function,
384 			    struct sdca_interrupt_info *info)
385 {
386 	int i, j;
387 
388 	guard(mutex)(&info->irq_lock);
389 
390 	for (i = 0; i < function->num_entities; i++) {
391 		struct sdca_entity *entity = &function->entities[i];
392 
393 		for (j = 0; j < entity->num_controls; j++) {
394 			struct sdca_control *control = &entity->controls[j];
395 			int irq = control->interrupt_position;
396 			struct sdca_interrupt *interrupt;
397 			int ret;
398 
399 			interrupt = get_interrupt_data(dev, irq, info);
400 			if (IS_ERR(interrupt))
401 				return PTR_ERR(interrupt);
402 			else if (!interrupt)
403 				continue;
404 
405 			switch (SDCA_CTL_TYPE(entity->type, control->sel)) {
406 			case SDCA_CTL_TYPE_S(XU, FDL_CURRENTOWNER):
407 				ret = sdca_irq_data_populate(dev, regmap, NULL,
408 							     function, entity,
409 							     control, interrupt);
410 				if (ret)
411 					return ret;
412 
413 				ret = sdca_fdl_alloc_state(interrupt);
414 				if (ret)
415 					return ret;
416 
417 				ret = sdca_irq_request_locked(dev, info, irq,
418 							      interrupt->name,
419 							      fdl_owner_handler,
420 							      interrupt);
421 				if (ret) {
422 					dev_err(dev, "failed to request irq %s: %d\n",
423 						interrupt->name, ret);
424 					return ret;
425 				}
426 				break;
427 			default:
428 				break;
429 			}
430 		}
431 	}
432 
433 	return 0;
434 }
435 EXPORT_SYMBOL_NS_GPL(sdca_irq_populate_early, "SND_SOC_SDCA");
436 
437 /**
438  * sdca_irq_populate - Request all the individual IRQs for an SDCA Function
439  * @function: Pointer to the SDCA Function.
440  * @component: Pointer to the ASoC component for the Function.
441  * @info: Pointer to the SDCA interrupt info for this device.
442  *
443  * Typically this would be called from the driver for a single SDCA Function.
444  *
445  * Return: Zero on success, and a negative error code on failure.
446  */
447 int sdca_irq_populate(struct sdca_function_data *function,
448 		      struct snd_soc_component *component,
449 		      struct sdca_interrupt_info *info)
450 {
451 	struct device *dev = component->dev;
452 	int i, j;
453 
454 	guard(mutex)(&info->irq_lock);
455 
456 	for (i = 0; i < function->num_entities; i++) {
457 		struct sdca_entity *entity = &function->entities[i];
458 
459 		for (j = 0; j < entity->num_controls; j++) {
460 			struct sdca_control *control = &entity->controls[j];
461 			int irq = control->interrupt_position;
462 			struct sdca_interrupt *interrupt;
463 			irq_handler_t handler;
464 			int ret;
465 
466 			interrupt = get_interrupt_data(dev, irq, info);
467 			if (IS_ERR(interrupt))
468 				return PTR_ERR(interrupt);
469 			else if (!interrupt)
470 				continue;
471 
472 			ret = sdca_irq_data_populate(dev, NULL, component,
473 						     function, entity, control,
474 						     interrupt);
475 			if (ret)
476 				return ret;
477 
478 			handler = base_handler;
479 
480 			switch (SDCA_CTL_TYPE(entity->type, control->sel)) {
481 			case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_STATUS):
482 				handler = function_status_handler;
483 				break;
484 			case SDCA_CTL_TYPE_S(GE, DETECTED_MODE):
485 				ret = sdca_jack_alloc_state(interrupt);
486 				if (ret)
487 					return ret;
488 
489 				handler = detected_mode_handler;
490 				break;
491 			case SDCA_CTL_TYPE_S(XU, FDL_CURRENTOWNER):
492 				ret = sdca_fdl_alloc_state(interrupt);
493 				if (ret)
494 					return ret;
495 
496 				handler = fdl_owner_handler;
497 				break;
498 			case SDCA_CTL_TYPE_S(HIDE, HIDTX_CURRENTOWNER):
499 				handler = hid_handler;
500 				break;
501 			default:
502 				break;
503 			}
504 
505 			ret = sdca_irq_request_locked(dev, info, irq, interrupt->name,
506 						      handler, interrupt);
507 			if (ret) {
508 				dev_err(dev, "failed to request irq %s: %d\n",
509 					interrupt->name, ret);
510 				return ret;
511 			}
512 		}
513 	}
514 
515 	return 0;
516 }
517 EXPORT_SYMBOL_NS_GPL(sdca_irq_populate, "SND_SOC_SDCA");
518 
519 /**
520  * sdca_irq_allocate - allocate an SDCA interrupt structure for a device
521  * @sdev: Device pointer against which things should be allocated.
522  * @regmap: regmap to be used for accessing the SDCA IRQ registers.
523  * @irq: The interrupt number.
524  *
525  * Typically this would be called from the top level driver for the whole
526  * SDCA device, as only a single instance is required across all Functions
527  * on the device.
528  *
529  * Return: A pointer to the allocated sdca_interrupt_info struct, or an
530  * error code.
531  */
532 struct sdca_interrupt_info *sdca_irq_allocate(struct device *sdev,
533 					      struct regmap *regmap, int irq)
534 {
535 	struct sdca_interrupt_info *info;
536 	int ret, i;
537 
538 	info = devm_kzalloc(sdev, sizeof(*info), GFP_KERNEL);
539 	if (!info)
540 		return ERR_PTR(-ENOMEM);
541 
542 	info->irq_chip = sdca_irq_chip;
543 
544 	for (i = 0; i < ARRAY_SIZE(info->irqs); i++)
545 		info->irqs[i].device_regmap = regmap;
546 
547 	ret = devm_mutex_init(sdev, &info->irq_lock);
548 	if (ret)
549 		return ERR_PTR(ret);
550 
551 	ret = devm_regmap_add_irq_chip(sdev, regmap, irq, IRQF_ONESHOT, 0,
552 				       &info->irq_chip, &info->irq_data);
553 	if (ret) {
554 		dev_err(sdev, "failed to register irq chip: %d\n", ret);
555 		return ERR_PTR(ret);
556 	}
557 
558 	dev_dbg(sdev, "registered on irq %d\n", irq);
559 
560 	return info;
561 }
562 EXPORT_SYMBOL_NS_GPL(sdca_irq_allocate, "SND_SOC_SDCA");
563 
564 static void irq_enable_flags(struct sdca_function_data *function,
565 			     struct sdca_interrupt_info *info, bool early)
566 {
567 	struct sdca_interrupt *interrupt;
568 	int i;
569 
570 	for (i = 0; i < SDCA_MAX_INTERRUPTS; i++) {
571 		interrupt = &info->irqs[i];
572 
573 		if (!interrupt || interrupt->function != function)
574 			continue;
575 
576 		switch (SDCA_CTL_TYPE(interrupt->entity->type,
577 				      interrupt->control->sel)) {
578 		case SDCA_CTL_TYPE_S(XU, FDL_CURRENTOWNER):
579 			if (early)
580 				enable_irq(interrupt->irq);
581 			break;
582 		default:
583 			if (!early)
584 				enable_irq(interrupt->irq);
585 			break;
586 		}
587 	}
588 }
589 
590 /**
591  * sdca_irq_enable_early - Re-enable early SDCA IRQs for a given function
592  * @function: Pointer to the SDCA Function.
593  * @info: Pointer to the SDCA interrupt info for this device.
594  *
595  * The early version of the IRQ enable allows enabling IRQs which may be
596  * necessary to bootstrap functionality for other IRQs, such as the FDL
597  * process.
598  */
599 void sdca_irq_enable_early(struct sdca_function_data *function,
600 			   struct sdca_interrupt_info *info)
601 {
602 	irq_enable_flags(function, info, true);
603 }
604 EXPORT_SYMBOL_NS_GPL(sdca_irq_enable_early, "SND_SOC_SDCA");
605 
606 /**
607  * sdca_irq_enable - Re-enable SDCA IRQs for a given function
608  * @function: Pointer to the SDCA Function.
609  * @info: Pointer to the SDCA interrupt info for this device.
610  */
611 void sdca_irq_enable(struct sdca_function_data *function,
612 		     struct sdca_interrupt_info *info)
613 {
614 	irq_enable_flags(function, info, false);
615 }
616 EXPORT_SYMBOL_NS_GPL(sdca_irq_enable, "SND_SOC_SDCA");
617 
618 /**
619  * sdca_irq_disable - Disable SDCA IRQs for a given function
620  * @function: Pointer to the SDCA Function.
621  * @info: Pointer to the SDCA interrupt info for this device.
622  */
623 void sdca_irq_disable(struct sdca_function_data *function,
624 		      struct sdca_interrupt_info *info)
625 {
626 	struct sdca_interrupt *interrupt;
627 	int i;
628 
629 	for (i = 0; i < SDCA_MAX_INTERRUPTS; i++) {
630 		interrupt = &info->irqs[i];
631 
632 		if (!interrupt || interrupt->function != function)
633 			continue;
634 
635 		disable_irq(interrupt->irq);
636 	}
637 }
638 EXPORT_SYMBOL_NS_GPL(sdca_irq_disable, "SND_SOC_SDCA");
639