Commit f594d01b authored by Charles Keepax's avatar Charles Keepax Committed by Lee Jones
Browse files

mfd: madera: Add special errata reset handling for cs47l15



An errata exists for cs47l15 where the reset must be handled
differently and removed before DCVDD is applied. A soft reset is used
for situations where a reset is required to reset state. This does
however, make this part unsuitable for DCVDD supplies with a rise time
greater than 2mS.

Signed-off-by: default avatarCharles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: default avatarLee Jones <lee.jones@linaro.org>
parent 1cd7b935
Loading
Loading
Loading
Loading
+20 −5
Original line number Diff line number Diff line
@@ -38,6 +38,9 @@
#define MADERA_RESET_MIN_US	2000
#define MADERA_RESET_MAX_US	3000

#define ERRATA_DCVDD_MIN_US	10000
#define ERRATA_DCVDD_MAX_US	15000

static const char * const madera_core_supplies[] = {
	"AVDD",
	"DBVDD1",
@@ -291,6 +294,7 @@ static int __maybe_unused madera_runtime_resume(struct device *dev)

	dev_dbg(dev, "Leaving sleep mode\n");

	if (!madera->reset_errata)
		madera_enable_hard_reset(madera);

	ret = regulator_enable(madera->dcvdd);
@@ -302,9 +306,12 @@ static int __maybe_unused madera_runtime_resume(struct device *dev)
	regcache_cache_only(madera->regmap, false);
	regcache_cache_only(madera->regmap_32bit, false);

	if (madera->reset_errata)
		usleep_range(ERRATA_DCVDD_MIN_US, ERRATA_DCVDD_MAX_US);
	else
		madera_disable_hard_reset(madera);

	if (!madera->pdata.reset) {
	if (!madera->pdata.reset || madera->reset_errata) {
		ret = madera_wait_for_boot(madera);
		if (ret)
			goto err;
@@ -503,6 +510,8 @@ int madera_dev_init(struct madera *madera)
	 */
	switch (madera->type) {
	case CS47L15:
		madera->reset_errata = true;
		break;
	case CS47L35:
	case CS47L90:
	case CS47L91:
@@ -553,12 +562,18 @@ int madera_dev_init(struct madera *madera)
		goto err_dcvdd;
	}

	if (madera->reset_errata)
		madera_disable_hard_reset(madera);

	ret = regulator_enable(madera->dcvdd);
	if (ret) {
		dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
		goto err_enable;
	}

	if (madera->reset_errata)
		usleep_range(ERRATA_DCVDD_MIN_US, ERRATA_DCVDD_MAX_US);
	else
		madera_disable_hard_reset(madera);

	regcache_cache_only(madera->regmap, false);
@@ -667,7 +682,7 @@ int madera_dev_init(struct madera *madera)
	 * It looks like a device we support. If we don't have a hard reset
	 * we can now attempt a soft reset.
	 */
	if (!madera->pdata.reset) {
	if (!madera->pdata.reset || madera->reset_errata) {
		ret = madera_soft_reset(madera);
		if (ret)
			goto err_reset;
+1 −0
Original line number Diff line number Diff line
@@ -186,6 +186,7 @@ struct madera {
	struct regulator_bulk_data core_supplies[MADERA_MAX_CORE_SUPPLIES];
	struct regulator *dcvdd;
	bool internal_dcvdd;
	bool reset_errata;

	struct madera_pdata pdata;