sound/soc/sdca/sdca_interrupts.c

Source file repositories/reference/linux-study-clean/sound/soc/sdca/sdca_interrupts.c

File Facts

System
Linux kernel
Corpus path
sound/soc/sdca/sdca_interrupts.c
Extension
.c
Size
18845 bytes
Lines
712
Domain
Driver Families
Bucket
sound/soc
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (BIT(mask)) {
		case SDCA_CTL_ENTITY_0_FUNCTION_NEEDS_INITIALIZATION:
/*
 * FIXME: Should this do init writes?
 *
 * Currently init writes/cache sync are done from the suspend/resume
 * infrastructure. It is unclear in what situations one would receive this
 * IRQ outside of that flow. Presumably it would be something like the chip
 * crashing. In that case however doing the init writes and a cache sync might
 * not be sufficient, for example if the failure was during audio playback
 * there could be ordering constraints on the register writes to restore the
 * state that are not handled by a simple cache sync.
 */
			break;
		case SDCA_CTL_ENTITY_0_FUNCTION_FAULT:
			dev_err(dev, "function fault\n");
			break;
		case SDCA_CTL_ENTITY_0_UMP_SEQUENCE_FAULT:
			dev_err(dev, "ump sequence fault\n");
			break;
		case SDCA_CTL_ENTITY_0_FUNCTION_BUSY:
			dev_info(dev, "unexpected function busy\n");
			break;
		case SDCA_CTL_ENTITY_0_DEVICE_NEWLY_ATTACHED:
		case SDCA_CTL_ENTITY_0_INTS_DISABLED_ABNORMALLY:
		case SDCA_CTL_ENTITY_0_STREAMING_STOPPED_ABNORMALLY:
		case SDCA_CTL_ENTITY_0_FUNCTION_HAS_BEEN_RESET:
			break;
		}
	}

	ret = regmap_write(interrupt->function_regmap, reg, val & 0x7F);
	if (ret < 0) {
		dev_err(dev, "failed to clear function status: %d\n", ret);
		goto error;
	}

	irqret = IRQ_HANDLED;
error:
	pm_runtime_put(dev);
	return irqret;
}

static irqreturn_t detected_mode_handler(int irq, void *data)
{
	struct sdca_interrupt *interrupt = data;
	struct device *dev = interrupt->dev;
	irqreturn_t irqret = IRQ_NONE;
	int ret;

	ret = pm_runtime_get_sync(dev);
	if (ret < 0) {
		dev_err(dev, "failed to resume for detected mode: %d\n", ret);
		goto error;
	}

	ret = sdca_jack_process(interrupt);
	if (ret)
		goto error;

	irqret = IRQ_HANDLED;
error:
	pm_runtime_put(dev);
	return irqret;
}

static irqreturn_t hid_handler(int irq, void *data)
{
	struct sdca_interrupt *interrupt = data;
	struct device *dev = interrupt->dev;
	irqreturn_t irqret = IRQ_NONE;
	int ret;

	ret = pm_runtime_get_sync(dev);
	if (ret < 0) {
		dev_err(dev, "failed to resume for hid: %d\n", ret);
		goto error;
	}

	ret = sdca_hid_process_report(interrupt);
	if (ret)
		goto error;

	irqret = IRQ_HANDLED;
error:
	pm_runtime_put(dev);
	return irqret;
}

#ifdef CONFIG_PM_SLEEP

Annotation

Implementation Notes