From: Antoni Pokusinski <apokusinski01@gmail.com>
To: alexandre.belloni@bootlin.com, robh@kernel.org,
krzk+dt@kernel.org, conor+dt@kernel.org
Cc: linux-rtc@vger.kernel.org, devicetree@vger.kernel.org,
Antoni Pokusinski <apokusinski01@gmail.com>
Subject: [PATCH 3/6] rtc: abx80x: use regmap instead of I2C specific API
Date: Wed, 22 Jul 2026 21:58:11 +0200 [thread overview]
Message-ID: <20260722195814.298552-4-apokusinski01@gmail.com> (raw)
In-Reply-To: <20260722195814.298552-1-apokusinski01@gmail.com>
Rework the driver so that it uses regmap_* functions for communication
with the device instead of the i2c_smbus_* API. This way the support for
ABX81X RTCs which use SPI can be added later.
Signed-off-by: Antoni Pokusinski <apokusinski01@gmail.com>
---
drivers/rtc/Kconfig | 1 +
drivers/rtc/rtc-abx80x.c | 331 +++++++++++++++++++++------------------
2 files changed, 180 insertions(+), 152 deletions(-)
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 01def8231873..4d14bcba616e 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -215,6 +215,7 @@ config RTC_DRV_ABEOZ9
config RTC_DRV_ABX80X
tristate "Abracon ABx80x"
select WATCHDOG_CORE if WATCHDOG
+ select REGMAP_I2C
help
If you say yes here you get support for Abracon AB080X and AB180X
families of ultra-low-power battery- and capacitor-backed real-time
diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c
index 9b0e1d48d9ba..e5ba821a6768 100644
--- a/drivers/rtc/rtc-abx80x.c
+++ b/drivers/rtc/rtc-abx80x.c
@@ -16,6 +16,7 @@
#include <linux/kstrtox.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/regmap.h>
#include <linux/rtc.h>
#include <linux/watchdog.h>
@@ -125,52 +126,53 @@ static struct abx80x_cap abx80x_caps[] = {
struct abx80x_priv {
struct rtc_device *rtc;
- struct i2c_client *client;
+ struct regmap *regmap;
struct watchdog_device wdog;
int irq;
};
-static int abx80x_write_config_key(struct i2c_client *client, u8 key)
+static int abx80x_write_config_key(struct device *dev, u8 key)
{
- if (i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY, key) < 0) {
- dev_err(&client->dev, "Unable to write configuration key\n");
+ struct abx80x_priv *priv = dev_get_drvdata(dev);
+
+ if (regmap_write(priv->regmap, ABX8XX_REG_CFG_KEY, key) < 0) {
+ dev_err(dev, "Unable to write configuration key\n");
return -EIO;
}
return 0;
}
-static int abx80x_is_rc_mode(struct i2c_client *client)
+static int abx80x_is_rc_mode(struct device *dev)
{
- int flags = 0;
+ struct abx80x_priv *priv = dev_get_drvdata(dev);
+ int err, flags = 0;
- flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSS);
- if (flags < 0) {
- dev_err(&client->dev,
- "Failed to read autocalibration attribute\n");
- return flags;
+ err = regmap_read(priv->regmap, ABX8XX_REG_OSS, &flags);
+ if (err < 0) {
+ dev_err(dev, "Failed to read autocalibration attribute\n");
+ return err;
}
return (flags & ABX8XX_OSS_OMODE) ? 1 : 0;
}
-static int abx80x_enable_trickle_charger(struct i2c_client *client,
- u8 trickle_cfg)
+static int abx80x_enable_trickle_charger(struct device *dev, u8 trickle_cfg)
{
+ struct abx80x_priv *priv = dev_get_drvdata(dev);
int err;
/*
* Write the configuration key register to enable access to the Trickle
* register
*/
- if (abx80x_write_config_key(client, ABX8XX_CFG_KEY_MISC) < 0)
+ if (abx80x_write_config_key(dev, ABX8XX_CFG_KEY_MISC) < 0)
return -EIO;
- err = i2c_smbus_write_byte_data(client, ABX8XX_REG_TRICKLE,
- ABX8XX_TRICKLE_CHARGE_ENABLE |
- trickle_cfg);
+ err = regmap_write(priv->regmap, ABX8XX_REG_TRICKLE,
+ ABX8XX_TRICKLE_CHARGE_ENABLE | trickle_cfg);
if (err < 0) {
- dev_err(&client->dev, "Unable to write trickle register\n");
+ dev_err(dev, "Unable to write trickle register\n");
return -EIO;
}
@@ -179,19 +181,19 @@ static int abx80x_enable_trickle_charger(struct i2c_client *client,
static int abx80x_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
- struct i2c_client *client = to_i2c_client(dev);
+ struct abx80x_priv *priv = dev_get_drvdata(dev);
unsigned char buf[8];
int err, flags, rc_mode = 0;
/* Read the Oscillator Failure only in XT mode */
- rc_mode = abx80x_is_rc_mode(client);
+ rc_mode = abx80x_is_rc_mode(dev);
if (rc_mode < 0)
return rc_mode;
if (!rc_mode) {
- flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSS);
- if (flags < 0)
- return flags;
+ err = regmap_read(priv->regmap, ABX8XX_REG_OSS, &flags);
+ if (err < 0)
+ return err;
if (flags & ABX8XX_OSS_OF) {
dev_err(dev, "Oscillator failure, data is invalid.\n");
@@ -199,10 +201,9 @@ static int abx80x_rtc_read_time(struct device *dev, struct rtc_time *tm)
}
}
- err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_HTH,
- sizeof(buf), buf);
+ err = regmap_bulk_read(priv->regmap, ABX8XX_REG_HTH, buf, sizeof(buf));
if (err < 0) {
- dev_err(&client->dev, "Unable to read date\n");
+ dev_err(dev, "Unable to read date\n");
return -EIO;
}
@@ -219,7 +220,7 @@ static int abx80x_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
- struct i2c_client *client = to_i2c_client(dev);
+ struct abx80x_priv *priv = dev_get_drvdata(dev);
unsigned char buf[8];
int err, flags;
@@ -235,22 +236,22 @@ static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
buf[ABX8XX_REG_YR] = bin2bcd(tm->tm_year - 100);
buf[ABX8XX_REG_WD] = tm->tm_wday;
- err = i2c_smbus_write_i2c_block_data(client, ABX8XX_REG_HTH,
- sizeof(buf), buf);
+ err = regmap_bulk_write(priv->regmap, ABX8XX_REG_HTH, buf,
+ sizeof(buf));
if (err < 0) {
- dev_err(&client->dev, "Unable to write to date registers\n");
+ dev_err(dev, "Unable to write to date registers\n");
return -EIO;
}
/* Clear the OF bit of Oscillator Status Register */
- flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSS);
- if (flags < 0)
- return flags;
+ err = regmap_read(priv->regmap, ABX8XX_REG_OSS, &flags);
+ if (err < 0)
+ return err;
- err = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSS,
- flags & ~ABX8XX_OSS_OF);
+ err = regmap_write(priv->regmap, ABX8XX_REG_OSS,
+ flags & ~ABX8XX_OSS_OF);
if (err < 0) {
- dev_err(&client->dev, "Unable to write oscillator status register\n");
+ dev_err(dev, "Unable to write oscillator status register\n");
return err;
}
@@ -259,13 +260,13 @@ static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
static irqreturn_t abx80x_handle_irq(int irq, void *dev_id)
{
- struct i2c_client *client = dev_id;
- struct abx80x_priv *priv = i2c_get_clientdata(client);
+ struct device *dev = dev_id;
+ struct abx80x_priv *priv = dev_get_drvdata(dev);
struct rtc_device *rtc = priv->rtc;
- int status;
+ int err, status;
- status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
- if (status < 0)
+ err = regmap_read(priv->regmap, ABX8XX_REG_STATUS, &status);
+ if (err < 0)
return IRQ_NONE;
if (status & ABX8XX_STATUS_AF)
@@ -276,17 +277,16 @@ static irqreturn_t abx80x_handle_irq(int irq, void *dev_id)
* reset kicks in.
*/
if (status & ABX8XX_STATUS_WDT)
- dev_alert(&client->dev, "watchdog timeout interrupt.\n");
+ dev_alert(dev, "watchdog timeout interrupt.\n");
- i2c_smbus_write_byte_data(client, ABX8XX_REG_STATUS, 0);
+ regmap_write(priv->regmap, ABX8XX_REG_STATUS, 0);
return IRQ_HANDLED;
}
static int abx80x_read_alarm(struct device *dev, struct rtc_wkalrm *t)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct abx80x_priv *priv = i2c_get_clientdata(client);
+ struct abx80x_priv *priv = dev_get_drvdata(dev);
unsigned char buf[7];
int irq_mask, err;
@@ -294,14 +294,13 @@ static int abx80x_read_alarm(struct device *dev, struct rtc_wkalrm *t)
if (priv->irq <= 0)
return -EINVAL;
- err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_ASC,
- sizeof(buf), buf);
+ err = regmap_bulk_read(priv->regmap, ABX8XX_REG_ASC, buf, sizeof(buf));
if (err)
return err;
- irq_mask = i2c_smbus_read_byte_data(client, ABX8XX_REG_IRQ);
- if (irq_mask < 0)
- return irq_mask;
+ err = regmap_read(priv->regmap, ABX8XX_REG_IRQ, &irq_mask);
+ if (err < 0)
+ return err;
t->time.tm_sec = bcd2bin(buf[0] & 0x7F);
t->time.tm_min = bcd2bin(buf[1] & 0x7F);
@@ -318,8 +317,7 @@ static int abx80x_read_alarm(struct device *dev, struct rtc_wkalrm *t)
static int abx80x_set_alarm(struct device *dev, struct rtc_wkalrm *t)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct abx80x_priv *priv = i2c_get_clientdata(client);
+ struct abx80x_priv *priv = dev_get_drvdata(dev);
u8 alarm[6];
int err;
@@ -333,17 +331,16 @@ static int abx80x_set_alarm(struct device *dev, struct rtc_wkalrm *t)
alarm[4] = bin2bcd(t->time.tm_mday);
alarm[5] = bin2bcd(t->time.tm_mon + 1);
- err = i2c_smbus_write_i2c_block_data(client, ABX8XX_REG_AHTH,
- sizeof(alarm), alarm);
+ err = regmap_bulk_write(priv->regmap, ABX8XX_REG_AHTH,
+ alarm, sizeof(alarm));
if (err < 0) {
- dev_err(&client->dev, "Unable to write alarm registers\n");
+ dev_err(dev, "Unable to write alarm registers\n");
return -EIO;
}
if (t->enabled) {
- err = i2c_smbus_write_byte_data(client, ABX8XX_REG_IRQ,
- (ABX8XX_IRQ_IM_1_4 |
- ABX8XX_IRQ_AIE));
+ err = regmap_write(priv->regmap, ABX8XX_REG_IRQ,
+ ABX8XX_IRQ_IM_1_4 | ABX8XX_IRQ_AIE);
if (err)
return err;
}
@@ -354,7 +351,7 @@ static int abx80x_set_alarm(struct device *dev, struct rtc_wkalrm *t)
static int abx80x_rtc_set_autocalibration(struct device *dev,
int autocalibration)
{
- struct i2c_client *client = to_i2c_client(dev);
+ struct abx80x_priv *priv = dev_get_drvdata(dev);
int retval, flags = 0;
if ((autocalibration != 0) && (autocalibration != 1024) &&
@@ -363,9 +360,9 @@ static int abx80x_rtc_set_autocalibration(struct device *dev,
return -EINVAL;
}
- flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSC);
- if (flags < 0)
- return flags;
+ retval = regmap_read(priv->regmap, ABX8XX_REG_OSC, &flags);
+ if (retval < 0)
+ return retval;
if (autocalibration == 0) {
flags &= ~(ABX8XX_OSC_ACAL_512 | ABX8XX_OSC_ACAL_1024);
@@ -379,22 +376,22 @@ static int abx80x_rtc_set_autocalibration(struct device *dev,
}
/* Unlock write access to Oscillator Control Register */
- if (abx80x_write_config_key(client, ABX8XX_CFG_KEY_OSC) < 0)
+ if (abx80x_write_config_key(dev, ABX8XX_CFG_KEY_OSC) < 0)
return -EIO;
- retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSC, flags);
+ retval = regmap_write(priv->regmap, ABX8XX_REG_OSC, flags);
return retval;
}
static int abx80x_rtc_get_autocalibration(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- int flags = 0, autocalibration;
+ struct abx80x_priv *priv = dev_get_drvdata(dev);
+ int flags = 0, autocalibration, err;
- flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSC);
- if (flags < 0)
- return flags;
+ err = regmap_read(priv->regmap, ABX8XX_REG_OSC, &flags);
+ if (err < 0)
+ return err;
if (flags & ABX8XX_OSC_ACAL_512)
autocalibration = 512;
@@ -445,7 +442,7 @@ static ssize_t oscillator_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev->parent);
+ struct abx80x_priv *priv = dev_get_drvdata(dev->parent);
int retval, flags, rc_mode = 0;
if (strncmp(buf, "rc", 2) == 0) {
@@ -457,9 +454,9 @@ static ssize_t oscillator_store(struct device *dev,
return -EINVAL;
}
- flags = i2c_smbus_read_byte_data(client, ABX8XX_REG_OSC);
- if (flags < 0)
- return flags;
+ retval = regmap_read(priv->regmap, ABX8XX_REG_OSC, &flags);
+ if (retval < 0)
+ return retval;
if (rc_mode == 0)
flags &= ~(ABX8XX_OSC_OSEL);
@@ -467,10 +464,10 @@ static ssize_t oscillator_store(struct device *dev,
flags |= (ABX8XX_OSC_OSEL);
/* Unlock write access on Oscillator Control register */
- if (abx80x_write_config_key(client, ABX8XX_CFG_KEY_OSC) < 0)
+ if (abx80x_write_config_key(dev->parent, ABX8XX_CFG_KEY_OSC) < 0)
return -EIO;
- retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSC, flags);
+ retval = regmap_write(priv->regmap, ABX8XX_REG_OSC, flags);
if (retval < 0) {
dev_err(dev, "Failed to write Oscillator Control register\n");
return retval;
@@ -483,9 +480,8 @@ static ssize_t oscillator_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int rc_mode = 0;
- struct i2c_client *client = to_i2c_client(dev->parent);
- rc_mode = abx80x_is_rc_mode(client);
+ rc_mode = abx80x_is_rc_mode(dev->parent);
if (rc_mode < 0) {
dev_err(dev, "Failed to read RTC oscillator selection\n");
@@ -513,45 +509,43 @@ static const struct attribute_group rtc_calib_attr_group = {
static int abx80x_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
- struct i2c_client *client = to_i2c_client(dev);
+ struct abx80x_priv *priv = dev_get_drvdata(dev);
int err;
if (enabled)
- err = i2c_smbus_write_byte_data(client, ABX8XX_REG_IRQ,
- (ABX8XX_IRQ_IM_1_4 |
- ABX8XX_IRQ_AIE));
+ err = regmap_write(priv->regmap, ABX8XX_REG_IRQ,
+ ABX8XX_IRQ_IM_1_4 | ABX8XX_IRQ_AIE);
else
- err = i2c_smbus_write_byte_data(client, ABX8XX_REG_IRQ,
- ABX8XX_IRQ_IM_1_4);
+ err = regmap_write(priv->regmap, ABX8XX_REG_IRQ,
+ ABX8XX_IRQ_IM_1_4);
return err;
}
static int abx80x_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
- struct i2c_client *client = to_i2c_client(dev);
- int status, tmp;
+ struct abx80x_priv *priv = dev_get_drvdata(dev);
+ int err, status, tmp;
switch (cmd) {
case RTC_VL_READ:
- status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
- if (status < 0)
- return status;
+ err = regmap_read(priv->regmap, ABX8XX_REG_STATUS, &status);
+ if (err < 0)
+ return err;
tmp = status & ABX8XX_STATUS_BLF ? RTC_VL_BACKUP_LOW : 0;
return put_user(tmp, (unsigned int __user *)arg);
case RTC_VL_CLR:
- status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
- if (status < 0)
- return status;
+ err = regmap_read(priv->regmap, ABX8XX_REG_STATUS, &status);
+ if (err < 0)
+ return err;
status &= ~ABX8XX_STATUS_BLF;
- tmp = i2c_smbus_write_byte_data(client, ABX8XX_REG_STATUS,
- status);
- if (tmp < 0)
- return tmp;
+ err = regmap_write(priv->regmap, ABX8XX_REG_STATUS, status);
+ if (err < 0)
+ return err;
return 0;
@@ -569,9 +563,9 @@ static const struct rtc_class_ops abx80x_rtc_ops = {
.ioctl = abx80x_ioctl,
};
-static int abx80x_dt_trickle_cfg(struct i2c_client *client)
+static int abx80x_dt_trickle_cfg(struct device *dev)
{
- struct device_node *np = client->dev.of_node;
+ struct device_node *np = dev->of_node;
const char *diode;
int trickle_cfg = 0;
int i, ret;
@@ -586,7 +580,7 @@ static int abx80x_dt_trickle_cfg(struct i2c_client *client)
} else if (!strcmp(diode, "schottky")) {
trickle_cfg |= ABX8XX_TRICKLE_SCHOTTKY_DIODE;
} else {
- dev_dbg(&client->dev, "Invalid tc-diode value: %s\n", diode);
+ dev_dbg(dev, "Invalid tc-diode value: %s\n", diode);
return -EINVAL;
}
@@ -599,7 +593,7 @@ static int abx80x_dt_trickle_cfg(struct i2c_client *client)
break;
if (i == sizeof(trickle_resistors)) {
- dev_dbg(&client->dev, "Invalid tc-resistor value: %u\n", tmp);
+ dev_dbg(dev, "Invalid tc-resistor value: %u\n", tmp);
return -EINVAL;
}
@@ -624,7 +618,7 @@ static int __abx80x_wdog_set_timeout(struct watchdog_device *wdog,
* Writing any timeout to the WDT register resets the watchdog timer.
* Writing 0 disables it.
*/
- return i2c_smbus_write_byte_data(priv->client, ABX8XX_REG_WDT, val);
+ return regmap_write(priv->regmap, ABX8XX_REG_WDT, val);
}
static int abx80x_wdog_set_timeout(struct watchdog_device *wdog,
@@ -669,9 +663,11 @@ static const struct watchdog_ops abx80x_wdog_ops = {
.set_timeout = abx80x_wdog_set_timeout,
};
-static int abx80x_setup_watchdog(struct abx80x_priv *priv)
+static int abx80x_setup_watchdog(struct device *dev)
{
- priv->wdog.parent = &priv->client->dev;
+ struct abx80x_priv *priv = dev_get_drvdata(dev);
+
+ priv->wdog.parent = dev;
priv->wdog.ops = &abx80x_wdog_ops;
priv->wdog.info = &abx80x_wdog_info;
priv->wdog.min_timeout = 1;
@@ -680,10 +676,10 @@ static int abx80x_setup_watchdog(struct abx80x_priv *priv)
watchdog_set_drvdata(&priv->wdog, priv);
- return devm_watchdog_register_device(&priv->client->dev, &priv->wdog);
+ return devm_watchdog_register_device(dev, &priv->wdog);
}
#else
-static int abx80x_setup_watchdog(struct abx80x_priv *priv)
+static int abx80x_setup_watchdog(struct device *dev)
{
return 0;
}
@@ -695,31 +691,27 @@ static int abx80x_nvmem_xfer(struct abx80x_priv *priv, unsigned int offset,
int ret;
while (bytes) {
- u8 extram, reg, len, lower, upper;
+ u8 reg, len, lower, upper;
lower = FIELD_GET(NVMEM_ADDR_LOWER, offset);
upper = FIELD_GET(NVMEM_ADDR_UPPER, offset);
- extram = FIELD_PREP(ABX8XX_EXTRAM_XADS, upper);
reg = ABX8XX_SRAM_BASE + lower;
len = min(lower + bytes, (size_t)ABX8XX_SRAM_WIN_SIZE) - lower;
len = min_t(u8, len, I2C_SMBUS_BLOCK_MAX);
- ret = i2c_smbus_write_byte_data(priv->client, ABX8XX_REG_EXTRAM,
- extram);
+ ret = regmap_update_bits(priv->regmap, ABX8XX_REG_EXTRAM,
+ ABX8XX_EXTRAM_XADS, upper);
if (ret)
return ret;
if (write) {
- ret = i2c_smbus_write_i2c_block_data(priv->client, reg,
- len, val);
+ ret = regmap_bulk_write(priv->regmap, reg, val, len);
if (ret)
return ret;
} else {
- ret = i2c_smbus_read_i2c_block_data(priv->client, reg,
- len, val);
- if (ret <= 0)
- return ret ? ret : -EIO;
- len = ret;
+ ret = regmap_bulk_read(priv->regmap, reg, val, len);
+ if (ret)
+ return ret;
}
offset += len;
@@ -755,6 +747,38 @@ static int abx80x_setup_nvmem(struct abx80x_priv *priv)
return devm_rtc_nvmem_register(priv->rtc, &config);
}
+static const struct regmap_range abx80x_no_read_ranges[] = {
+ regmap_reg_range(0x1e, 0x1e),
+ regmap_reg_range(0x22, 0x25),
+ regmap_reg_range(0x31, 0x3e),
+};
+
+static const struct regmap_range abx80x_no_write_ranges[] = {
+ regmap_reg_range(0x1e, 0x1e),
+ regmap_reg_range(0x22, 0x25),
+ regmap_reg_range(ABX8XX_REG_ID0, ABX8XX_REG_ID0 + 6),
+ regmap_reg_range(0x31, 0x3e),
+};
+
+static const struct regmap_access_table abx80x_read_table = {
+ .no_ranges = abx80x_no_read_ranges,
+ .n_no_ranges = ARRAY_SIZE(abx80x_no_read_ranges),
+};
+
+static const struct regmap_access_table abx80x_write_table = {
+ .no_ranges = abx80x_no_write_ranges,
+ .n_no_ranges = ARRAY_SIZE(abx80x_no_write_ranges),
+};
+
+static const struct regmap_config abx80x_regmap_config_i2c = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = ABX8XX_SRAM_BASE + ABX8XX_SRAM_WIN_SIZE - 1,
+
+ .rd_table = &abx80x_read_table,
+ .wr_table = &abx80x_write_table,
+};
+
static const struct i2c_device_id abx80x_id[] = {
{ .name = "abx80x", .driver_data = ABX80X },
{ .name = "ab0801", .driver_data = AB0801 },
@@ -772,6 +796,7 @@ MODULE_DEVICE_TABLE(i2c, abx80x_id);
static int abx80x_probe(struct i2c_client *client)
{
+ struct regmap *regmap;
struct device_node *np = client->dev.of_node;
struct abx80x_priv *priv;
int i, data, err, trickle_cfg = -EINVAL;
@@ -786,8 +811,27 @@ static int abx80x_probe(struct i2c_client *client)
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -ENODEV;
- err = i2c_smbus_read_i2c_block_data(client, ABX8XX_REG_ID0,
- sizeof(buf), buf);
+ regmap = devm_regmap_init_i2c(client, &abx80x_regmap_config_i2c);
+ if (IS_ERR(regmap)) {
+ dev_err(&client->dev, "Unable to allocate regmap\n");
+ return -EIO;
+ }
+
+ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+ if (priv == NULL)
+ return -ENOMEM;
+
+ priv->rtc = devm_rtc_allocate_device(&client->dev);
+ if (IS_ERR(priv->rtc))
+ return PTR_ERR(priv->rtc);
+
+ priv->rtc->ops = &abx80x_rtc_ops;
+ priv->irq = client->irq;
+ priv->regmap = regmap;
+
+ dev_set_drvdata(&client->dev, priv);
+
+ err = regmap_bulk_read(regmap, ABX8XX_REG_ID0, buf, sizeof(buf));
if (err < 0) {
dev_err(&client->dev, "Unable to read partnumber\n");
return -EIO;
@@ -802,16 +846,14 @@ static int abx80x_probe(struct i2c_client *client)
dev_info(&client->dev, "model %04x, revision %u.%u, lot %x, wafer %x, uid %x\n",
partnumber, majrev, minrev, lot, wafer, uid);
- data = i2c_smbus_read_byte_data(client, ABX8XX_REG_CTRL1);
- if (data < 0) {
+ err = regmap_read(regmap, ABX8XX_REG_CTRL1, &data);
+ if (err < 0) {
dev_err(&client->dev, "Unable to read control register\n");
return -EIO;
}
- err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CTRL1,
- ((data & ~(ABX8XX_CTRL_12_24 |
- ABX8XX_CTRL_ARST)) |
- ABX8XX_CTRL_WRITE));
+ err = regmap_write(regmap, ABX8XX_REG_CTRL1,
+ (data & ~(ABX8XX_CTRL_12_24 | ABX8XX_CTRL_ARST)) | ABX8XX_CTRL_WRITE);
if (err < 0) {
dev_err(&client->dev, "Unable to write control register\n");
return -EIO;
@@ -825,15 +867,15 @@ static int abx80x_probe(struct i2c_client *client)
* register is set. RV-1805-C3 datasheet indicates that
* the bit should be cleared in section 11h - Control2.
*/
- data = i2c_smbus_read_byte_data(client, ABX8XX_REG_CTRL2);
- if (data < 0) {
+ err = regmap_read(regmap, ABX8XX_REG_CTRL2, &data);
+ if (err < 0) {
dev_err(&client->dev,
"Unable to read control2 register\n");
return -EIO;
}
- err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CTRL2,
- data & ~ABX8XX_CTRL2_RSVD);
+ err = regmap_write(regmap, ABX8XX_REG_CTRL2,
+ data & ~ABX8XX_CTRL2_RSVD);
if (err < 0) {
dev_err(&client->dev,
"Unable to write control2 register\n");
@@ -845,8 +887,8 @@ static int abx80x_probe(struct i2c_client *client)
* 10pin package and the EXTI input is not present.
* Disable it to avoid leakage.
*/
- data = i2c_smbus_read_byte_data(client, ABX8XX_REG_OUT_CTRL);
- if (data < 0) {
+ err = regmap_read(regmap, ABX8XX_REG_OUT_CTRL, &data);
+ if (err < 0) {
dev_err(&client->dev,
"Unable to read output control register\n");
return -EIO;
@@ -856,11 +898,11 @@ static int abx80x_probe(struct i2c_client *client)
* Write the configuration key register to enable access to
* the config2 register
*/
- if (abx80x_write_config_key(client, ABX8XX_CFG_KEY_MISC) < 0)
+ if (abx80x_write_config_key(&client->dev, ABX8XX_CFG_KEY_MISC) < 0)
return -EIO;
- err = i2c_smbus_write_byte_data(client, ABX8XX_REG_OUT_CTRL,
- data | ABX8XX_OUT_CTRL_EXDS);
+ err = regmap_write(regmap, ABX8XX_REG_OUT_CTRL,
+ data | ABX8XX_OUT_CTRL_EXDS);
if (err < 0) {
dev_err(&client->dev,
"Unable to write output control register\n");
@@ -888,35 +930,20 @@ static int abx80x_probe(struct i2c_client *client)
}
if (np && abx80x_caps[part].has_tc)
- trickle_cfg = abx80x_dt_trickle_cfg(client);
+ trickle_cfg = abx80x_dt_trickle_cfg(&client->dev);
if (trickle_cfg > 0) {
dev_info(&client->dev, "Enabling trickle charger: %02x\n",
trickle_cfg);
- abx80x_enable_trickle_charger(client, trickle_cfg);
+ abx80x_enable_trickle_charger(&client->dev, trickle_cfg);
}
- err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CD_TIMER_CTL,
- BIT(2));
+ err = regmap_write(regmap, ABX8XX_REG_CD_TIMER_CTL, BIT(2));
if (err)
return err;
- priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
- if (priv == NULL)
- return -ENOMEM;
-
- priv->rtc = devm_rtc_allocate_device(&client->dev);
- if (IS_ERR(priv->rtc))
- return PTR_ERR(priv->rtc);
-
- priv->rtc->ops = &abx80x_rtc_ops;
- priv->client = client;
- priv->irq = client->irq;
-
- i2c_set_clientdata(client, priv);
-
if (abx80x_caps[part].has_wdog) {
- err = abx80x_setup_watchdog(priv);
+ err = abx80x_setup_watchdog(&client->dev);
if (err)
return err;
}
@@ -931,7 +958,7 @@ static int abx80x_probe(struct i2c_client *client)
abx80x_handle_irq,
IRQF_SHARED | IRQF_ONESHOT,
"abx8xx",
- client);
+ &client->dev);
if (err) {
dev_err(&client->dev, "unable to request IRQ, alarms disabled\n");
priv->irq = 0;
--
2.55.0
next prev parent reply other threads:[~2026-07-22 20:00 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-22 19:58 [PATCH 0/6] rtc: abx80x: add support for ABX81X Antoni Pokusinski
2026-07-22 19:58 ` [PATCH 1/6] dt-bindings: rtc: abx80x: document ABX81X RTCs Antoni Pokusinski
2026-07-22 20:09 ` sashiko-bot
2026-07-22 19:58 ` [PATCH 2/6] rtc: abx80x: add irq to struct abx80x_priv Antoni Pokusinski
2026-07-22 20:13 ` sashiko-bot
2026-07-22 19:58 ` Antoni Pokusinski [this message]
2026-07-22 20:16 ` [PATCH 3/6] rtc: abx80x: use regmap instead of I2C specific API sashiko-bot
2026-07-22 19:58 ` [PATCH 4/6] rtc: abx80x: replace read-modify-write pattern with regmap helpers Antoni Pokusinski
2026-07-22 20:11 ` sashiko-bot
2026-07-22 19:58 ` [PATCH 5/6] rtc: abx80x: create abx80x_i2c_probe() Antoni Pokusinski
2026-07-22 20:10 ` sashiko-bot
2026-07-22 19:58 ` [PATCH 6/6] rtc: abx80x: add support for ABX81X Antoni Pokusinski
2026-07-22 20:09 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260722195814.298552-4-apokusinski01@gmail.com \
--to=apokusinski01@gmail.com \
--cc=alexandre.belloni@bootlin.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=krzk+dt@kernel.org \
--cc=linux-rtc@vger.kernel.org \
--cc=robh@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox