Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>

authored by

Charles Keepax and committed by
Lee Jones
f594d01b 1cd7b935

+21 -5
+20 -5
drivers/mfd/madera-core.c
··· 38 38 #define MADERA_RESET_MIN_US 2000 39 39 #define MADERA_RESET_MAX_US 3000 40 40 41 + #define ERRATA_DCVDD_MIN_US 10000 42 + #define ERRATA_DCVDD_MAX_US 15000 43 + 41 44 static const char * const madera_core_supplies[] = { 42 45 "AVDD", 43 46 "DBVDD1", ··· 294 291 295 292 dev_dbg(dev, "Leaving sleep mode\n"); 296 293 297 - madera_enable_hard_reset(madera); 294 + if (!madera->reset_errata) 295 + madera_enable_hard_reset(madera); 298 296 299 297 ret = regulator_enable(madera->dcvdd); 300 298 if (ret) { ··· 306 302 regcache_cache_only(madera->regmap, false); 307 303 regcache_cache_only(madera->regmap_32bit, false); 308 304 309 - madera_disable_hard_reset(madera); 305 + if (madera->reset_errata) 306 + usleep_range(ERRATA_DCVDD_MIN_US, ERRATA_DCVDD_MAX_US); 307 + else 308 + madera_disable_hard_reset(madera); 310 309 311 - if (!madera->pdata.reset) { 310 + if (!madera->pdata.reset || madera->reset_errata) { 312 311 ret = madera_wait_for_boot(madera); 313 312 if (ret) 314 313 goto err; ··· 510 503 */ 511 504 switch (madera->type) { 512 505 case CS47L15: 506 + madera->reset_errata = true; 507 + break; 513 508 case CS47L35: 514 509 case CS47L90: 515 510 case CS47L91: ··· 562 553 goto err_dcvdd; 563 554 } 564 555 556 + if (madera->reset_errata) 557 + madera_disable_hard_reset(madera); 558 + 565 559 ret = regulator_enable(madera->dcvdd); 566 560 if (ret) { 567 561 dev_err(dev, "Failed to enable DCVDD: %d\n", ret); 568 562 goto err_enable; 569 563 } 570 564 571 - madera_disable_hard_reset(madera); 565 + if (madera->reset_errata) 566 + usleep_range(ERRATA_DCVDD_MIN_US, ERRATA_DCVDD_MAX_US); 567 + else 568 + madera_disable_hard_reset(madera); 572 569 573 570 regcache_cache_only(madera->regmap, false); 574 571 regcache_cache_only(madera->regmap_32bit, false); ··· 682 667 * It looks like a device we support. If we don't have a hard reset 683 668 * we can now attempt a soft reset. 684 669 */ 685 - if (!madera->pdata.reset) { 670 + if (!madera->pdata.reset || madera->reset_errata) { 686 671 ret = madera_soft_reset(madera); 687 672 if (ret) 688 673 goto err_reset;
+1
include/linux/mfd/madera/core.h
··· 186 186 struct regulator_bulk_data core_supplies[MADERA_MAX_CORE_SUPPLIES]; 187 187 struct regulator *dcvdd; 188 188 bool internal_dcvdd; 189 + bool reset_errata; 189 190 190 191 struct madera_pdata pdata; 191 192