forked from Minki/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>
This commit is contained in:
parent
1cd7b935d2
commit
f594d01bb4
@ -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,7 +294,8 @@ static int __maybe_unused madera_runtime_resume(struct device *dev)
|
||||
|
||||
dev_dbg(dev, "Leaving sleep mode\n");
|
||||
|
||||
madera_enable_hard_reset(madera);
|
||||
if (!madera->reset_errata)
|
||||
madera_enable_hard_reset(madera);
|
||||
|
||||
ret = regulator_enable(madera->dcvdd);
|
||||
if (ret) {
|
||||
@ -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);
|
||||
|
||||
madera_disable_hard_reset(madera);
|
||||
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,13 +562,19 @@ 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;
|
||||
}
|
||||
|
||||
madera_disable_hard_reset(madera);
|
||||
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);
|
||||
regcache_cache_only(madera->regmap_32bit, 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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user