drivers/mfd/madera-core.c

Source file repositories/reference/linux-study-clean/drivers/mfd/madera-core.c

File Facts

System
Linux kernel
Corpus path
drivers/mfd/madera-core.c
Extension
.c
Size
19171 bytes
Lines
799
Domain
Driver Families
Bucket
drivers/mfd
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

if (ret) {
			dev_err(dev, "Failed to reset: %d\n", ret);
			goto err;
		}
	}

	ret = madera_wait_for_boot(madera);
	if (ret)
		goto err;

	ret = regcache_sync(madera->regmap);
	if (ret) {
		dev_err(dev, "Failed to restore 16-bit register cache\n");
		goto err;
	}

	ret = regcache_sync(madera->regmap_32bit);
	if (ret) {
		dev_err(dev, "Failed to restore 32-bit register cache\n");
		goto err;
	}

	return 0;

err:
	regcache_cache_only(madera->regmap_32bit, true);
	regcache_cache_only(madera->regmap, true);
	regulator_disable(madera->dcvdd);

	return ret;
}

static int __maybe_unused madera_runtime_suspend(struct device *dev)
{
	struct madera *madera = dev_get_drvdata(dev);

	dev_dbg(madera->dev, "Entering sleep mode\n");

	regcache_cache_only(madera->regmap, true);
	regcache_mark_dirty(madera->regmap);
	regcache_cache_only(madera->regmap_32bit, true);
	regcache_mark_dirty(madera->regmap_32bit);

	regulator_disable(madera->dcvdd);

	return 0;
}

const struct dev_pm_ops madera_pm_ops = {
	SET_RUNTIME_PM_OPS(madera_runtime_suspend,
			   madera_runtime_resume,
			   NULL)
};
EXPORT_SYMBOL_GPL(madera_pm_ops);

const struct of_device_id madera_of_match[] = {
	{ .compatible = "cirrus,cs47l15", .data = (void *)CS47L15 },
	{ .compatible = "cirrus,cs47l35", .data = (void *)CS47L35 },
	{ .compatible = "cirrus,cs47l85", .data = (void *)CS47L85 },
	{ .compatible = "cirrus,cs47l90", .data = (void *)CS47L90 },
	{ .compatible = "cirrus,cs47l91", .data = (void *)CS47L91 },
	{ .compatible = "cirrus,cs42l92", .data = (void *)CS42L92 },
	{ .compatible = "cirrus,cs47l92", .data = (void *)CS47L92 },
	{ .compatible = "cirrus,cs47l93", .data = (void *)CS47L93 },
	{ .compatible = "cirrus,wm1840", .data = (void *)WM1840 },
	{}
};
MODULE_DEVICE_TABLE(of, madera_of_match);
EXPORT_SYMBOL_GPL(madera_of_match);

static int madera_get_reset_gpio(struct madera *madera)
{
	struct gpio_desc *reset;

	if (madera->pdata.reset)
		return 0;

	reset = devm_gpiod_get_optional(madera->dev, "reset", GPIOD_OUT_LOW);
	if (IS_ERR(reset))
		return dev_err_probe(madera->dev, PTR_ERR(reset),
				"Failed to request /RESET");

	/*
	 * A hard reset is needed for full reset of the chip. We allow running
	 * without hard reset only because it can be useful for early
	 * prototyping and some debugging, but we need to warn it's not ideal.
	 */
	if (!reset)
		dev_warn(madera->dev,
			 "Running without reset GPIO is not recommended\n");

Annotation

Implementation Notes