.attrs = rv3028_attrs,
};
+static int rv3028_exit_eerd(struct rv3028_data *rv3028, u32 eerd)
+{
+ if (eerd)
+ return 0;
+
+ return regmap_update_bits(rv3028->regmap, RV3028_CTRL1, RV3028_CTRL1_EERD, 0);
+}
+
+static int rv3028_enter_eerd(struct rv3028_data *rv3028, u32 *eerd)
+{
+ u32 ctrl1, status;
+ int ret;
+
+ ret = regmap_read(rv3028->regmap, RV3028_CTRL1, &ctrl1);
+ if (ret)
+ return ret;
+
+ *eerd = ctrl1 & RV3028_CTRL1_EERD;
+ if (*eerd)
+ return 0;
+
+ ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL1,
+ RV3028_CTRL1_EERD, RV3028_CTRL1_EERD);
+ if (ret)
+ return ret;
+
+ ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status,
+ !(status & RV3028_STATUS_EEBUSY),
+ RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT);
+ if (ret) {
+ rv3028_exit_eerd(rv3028, *eerd);
+
+ return ret;
+ }
+
+ return 0;
+}
+
static irqreturn_t rv3028_handle_irq(int irq, void *dev_id)
{
struct rv3028_data *rv3028 = dev_id;
static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val,
size_t bytes)
{
- u32 status, ctrl1;
- int i, ret, err;
+ struct rv3028_data *rv3028 = priv;
+ u32 status, eerd;
+ int i, ret;
u8 *buf = val;
- ret = regmap_read(priv, RV3028_CTRL1, &ctrl1);
+ ret = rv3028_enter_eerd(rv3028, &eerd);
if (ret)
return ret;
- if (!(ctrl1 & RV3028_CTRL1_EERD)) {
- ret = regmap_update_bits(priv, RV3028_CTRL1,
- RV3028_CTRL1_EERD, RV3028_CTRL1_EERD);
- if (ret)
- return ret;
-
- ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
- !(status & RV3028_STATUS_EEBUSY),
- RV3028_EEBUSY_POLL,
- RV3028_EEBUSY_TIMEOUT);
- if (ret)
- goto restore_eerd;
- }
-
for (i = 0; i < bytes; i++) {
- ret = regmap_write(priv, RV3028_EEPROM_ADDR, offset + i);
+ ret = regmap_write(rv3028->regmap, RV3028_EEPROM_ADDR, offset + i);
if (ret)
goto restore_eerd;
- ret = regmap_write(priv, RV3028_EEPROM_DATA, buf[i]);
+ ret = regmap_write(rv3028->regmap, RV3028_EEPROM_DATA, buf[i]);
if (ret)
goto restore_eerd;
- ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0);
+ ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, 0x0);
if (ret)
goto restore_eerd;
- ret = regmap_write(priv, RV3028_EEPROM_CMD,
+ ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD,
RV3028_EEPROM_CMD_WRITE);
if (ret)
goto restore_eerd;
usleep_range(RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT);
- ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
+ ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status,
!(status & RV3028_STATUS_EEBUSY),
RV3028_EEBUSY_POLL,
RV3028_EEBUSY_TIMEOUT);
}
restore_eerd:
- if (!(ctrl1 & RV3028_CTRL1_EERD))
- {
- err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD,
- 0);
- if (err && !ret)
- ret = err;
- }
+ rv3028_exit_eerd(rv3028, eerd);
return ret;
}
static int rv3028_eeprom_read(void *priv, unsigned int offset, void *val,
size_t bytes)
{
- u32 status, ctrl1, data;
- int i, ret, err;
+ struct rv3028_data *rv3028 = priv;
+ u32 status, eerd, data;
+ int i, ret;
u8 *buf = val;
- ret = regmap_read(priv, RV3028_CTRL1, &ctrl1);
+ ret = rv3028_enter_eerd(rv3028, &eerd);
if (ret)
return ret;
- if (!(ctrl1 & RV3028_CTRL1_EERD)) {
- ret = regmap_update_bits(priv, RV3028_CTRL1,
- RV3028_CTRL1_EERD, RV3028_CTRL1_EERD);
- if (ret)
- return ret;
-
- ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
- !(status & RV3028_STATUS_EEBUSY),
- RV3028_EEBUSY_POLL,
- RV3028_EEBUSY_TIMEOUT);
- if (ret)
- goto restore_eerd;
- }
-
for (i = 0; i < bytes; i++) {
- ret = regmap_write(priv, RV3028_EEPROM_ADDR, offset + i);
+ ret = regmap_write(rv3028->regmap, RV3028_EEPROM_ADDR, offset + i);
if (ret)
goto restore_eerd;
- ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0);
+ ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, 0x0);
if (ret)
goto restore_eerd;
- ret = regmap_write(priv, RV3028_EEPROM_CMD,
+ ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD,
RV3028_EEPROM_CMD_READ);
if (ret)
goto restore_eerd;
- ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
+ ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status,
!(status & RV3028_STATUS_EEBUSY),
RV3028_EEBUSY_POLL,
RV3028_EEBUSY_TIMEOUT);
if (ret)
goto restore_eerd;
- ret = regmap_read(priv, RV3028_EEPROM_DATA, &data);
+ ret = regmap_read(rv3028->regmap, RV3028_EEPROM_DATA, &data);
if (ret)
goto restore_eerd;
buf[i] = data;
}
restore_eerd:
- if (!(ctrl1 & RV3028_CTRL1_EERD))
- {
- err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD,
- 0);
- if (err && !ret)
- ret = err;
- }
+ rv3028_exit_eerd(rv3028, eerd);
return ret;
}
nvmem_cfg.priv = rv3028->regmap;
rtc_nvmem_register(rv3028->rtc, &nvmem_cfg);
- eeprom_cfg.priv = rv3028->regmap;
+ eeprom_cfg.priv = rv3028;
rtc_nvmem_register(rv3028->rtc, &eeprom_cfg);
rv3028->rtc->max_user_freq = 1;