mfd: da9052: Avoid multiwrite mode due to silicon errata
DA9053 (up to revision bc) can corrupt internal registers when multi-write mode is enabled and power is removed or during shutdown. Signed-off-by: David Jander <david@protonic.nl> Signed-off-by: Lee Jones <lee.jones@linaro.org>
This commit is contained in:
parent
61e6cfa80d
commit
43e30f23b5
2 changed files with 22 additions and 10 deletions
|
@ -86,7 +86,11 @@ static int da9052_i2c_fix(struct da9052 *da9052, unsigned char reg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int da9052_i2c_enable_multiwrite(struct da9052 *da9052)
|
||||
/*
|
||||
* According to errata item 24, multiwrite mode should be avoided
|
||||
* in order to prevent register data corruption after power-down.
|
||||
*/
|
||||
static int da9052_i2c_disable_multiwrite(struct da9052 *da9052)
|
||||
{
|
||||
int reg_val, ret;
|
||||
|
||||
|
@ -94,8 +98,8 @@ static int da9052_i2c_enable_multiwrite(struct da9052 *da9052)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (reg_val & DA9052_CONTROL_B_WRITEMODE) {
|
||||
reg_val &= ~DA9052_CONTROL_B_WRITEMODE;
|
||||
if (!(reg_val & DA9052_CONTROL_B_WRITEMODE)) {
|
||||
reg_val |= DA9052_CONTROL_B_WRITEMODE;
|
||||
ret = regmap_write(da9052->regmap, DA9052_CONTROL_B_REG,
|
||||
reg_val);
|
||||
if (ret < 0)
|
||||
|
@ -154,7 +158,7 @@ static int da9052_i2c_probe(struct i2c_client *client,
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = da9052_i2c_enable_multiwrite(da9052);
|
||||
ret = da9052_i2c_disable_multiwrite(da9052);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -148,10 +148,15 @@ static inline int da9052_group_read(struct da9052 *da9052, unsigned char reg,
|
|||
unsigned reg_cnt, unsigned char *val)
|
||||
{
|
||||
int ret;
|
||||
unsigned int tmp;
|
||||
int i;
|
||||
|
||||
ret = regmap_bulk_read(da9052->regmap, reg, val, reg_cnt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
for (i = 0; i < reg_cnt; i++) {
|
||||
ret = regmap_read(da9052->regmap, reg + i, &tmp);
|
||||
val[i] = (unsigned char)tmp;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (da9052->fix_io) {
|
||||
ret = da9052->fix_io(da9052, reg);
|
||||
|
@ -166,10 +171,13 @@ static inline int da9052_group_write(struct da9052 *da9052, unsigned char reg,
|
|||
unsigned reg_cnt, unsigned char *val)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
ret = regmap_raw_write(da9052->regmap, reg, val, reg_cnt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
for (i = 0; i < reg_cnt; i++) {
|
||||
ret = regmap_write(da9052->regmap, reg + i, val[i]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (da9052->fix_io) {
|
||||
ret = da9052->fix_io(da9052, reg);
|
||||
|
|
Loading…
Reference in a new issue