From: Bartosz Golaszewski <brgl@bgdev.pl>
To: Alessandro Zummo <a.zummo@towertech.it>,
Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: linux-rtc@vger.kernel.org, linux-kernel@vger.kernel.org,
Bartosz Golaszewski <bgolaszewski@baylibre.com>
Subject: [PATCH 8/8] rtc: rx8010: convert to using regmap
Date: Fri, 4 Sep 2020 17:21:16 +0200 [thread overview]
Message-ID: <20200904152116.2157-9-brgl@bgdev.pl> (raw)
In-Reply-To: <20200904152116.2157-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
This driver requires SMBUS to work. We can relax this requirement if we
switch to using i2c regmap and let the regmap sub-system figure out how
to talk to the bus.
This also has the advantage of shrinking the code for register updates.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/rtc/rtc-rx8010.c | 200 ++++++++++++++++-----------------------
1 file changed, 81 insertions(+), 119 deletions(-)
diff --git a/drivers/rtc/rtc-rx8010.c b/drivers/rtc/rtc-rx8010.c
index ed8ba38b4991..9be3ea88e86d 100644
--- a/drivers/rtc/rtc-rx8010.c
+++ b/drivers/rtc/rtc-rx8010.c
@@ -11,6 +11,7 @@
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/regmap.h>
#include <linux/rtc.h>
#define RX8010_SEC 0x10
@@ -63,7 +64,7 @@ static const struct of_device_id rx8010_of_match[] = {
MODULE_DEVICE_TABLE(of, rx8010_of_match);
struct rx8010_data {
- struct i2c_client *client;
+ struct regmap *regs;
struct rtc_device *rtc;
u8 ctrlreg;
};
@@ -72,13 +73,12 @@ static irqreturn_t rx8010_irq_1_handler(int irq, void *dev_id)
{
struct i2c_client *client = dev_id;
struct rx8010_data *rx8010 = i2c_get_clientdata(client);
- int flagreg;
+ int flagreg, err;
mutex_lock(&rx8010->rtc->ops_lock);
- flagreg = i2c_smbus_read_byte_data(client, RX8010_FLAG);
-
- if (flagreg <= 0) {
+ err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
+ if (err) {
mutex_unlock(&rx8010->rtc->ops_lock);
return IRQ_NONE;
}
@@ -101,10 +101,9 @@ static irqreturn_t rx8010_irq_1_handler(int irq, void *dev_id)
rtc_update_irq(rx8010->rtc, 1, RTC_UF | RTC_IRQF);
}
- i2c_smbus_write_byte_data(client, RX8010_FLAG, flagreg);
-
+ err = regmap_write(rx8010->regs, RX8010_FLAG, flagreg);
mutex_unlock(&rx8010->rtc->ops_lock);
- return IRQ_HANDLED;
+ return err ? IRQ_NONE : IRQ_HANDLED;
}
static int rx8010_get_time(struct device *dev, struct rtc_time *dt)
@@ -113,19 +112,19 @@ static int rx8010_get_time(struct device *dev, struct rtc_time *dt)
u8 date[RX8010_TIME_BUF_LEN];
int flagreg, err;
- flagreg = i2c_smbus_read_byte_data(rx8010->client, RX8010_FLAG);
- if (flagreg < 0)
- return flagreg;
+ err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
+ if (err)
+ return err;
if (flagreg & RX8010_FLAG_VLF) {
dev_warn(dev, "Frequency stop detected\n");
return -EINVAL;
}
- err = i2c_smbus_read_i2c_block_data(rx8010->client, RX8010_SEC,
- RX8010_TIME_BUF_LEN, date);
- if (err != RX8010_TIME_BUF_LEN)
- return err < 0 ? err : -EIO;
+ err = regmap_bulk_read(rx8010->regs, RX8010_SEC,
+ date, RX8010_TIME_BUF_LEN);
+ if (err)
+ return err;
dt->tm_sec = bcd2bin(date[RX8010_SEC - RX8010_SEC] & 0x7f);
dt->tm_min = bcd2bin(date[RX8010_MIN - RX8010_SEC] & 0x7f);
@@ -142,19 +141,14 @@ static int rx8010_set_time(struct device *dev, struct rtc_time *dt)
{
struct rx8010_data *rx8010 = dev_get_drvdata(dev);
u8 date[RX8010_TIME_BUF_LEN];
- int ctrl, flagreg, err;
+ int err;
if ((dt->tm_year < 100) || (dt->tm_year > 199))
return -EINVAL;
/* set STOP bit before changing clock/calendar */
- ctrl = i2c_smbus_read_byte_data(rx8010->client, RX8010_CTRL);
- if (ctrl < 0)
- return ctrl;
- rx8010->ctrlreg = ctrl | RX8010_CTRL_STOP;
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_CTRL,
- rx8010->ctrlreg);
- if (err < 0)
+ err = regmap_set_bits(rx8010->regs, RX8010_CTRL, RX8010_CTRL_STOP);
+ if (err)
return err;
date[RX8010_SEC - RX8010_SEC] = bin2bcd(dt->tm_sec);
@@ -165,66 +159,55 @@ static int rx8010_set_time(struct device *dev, struct rtc_time *dt)
date[RX8010_YEAR - RX8010_SEC] = bin2bcd(dt->tm_year - 100);
date[RX8010_WDAY - RX8010_SEC] = bin2bcd(1 << dt->tm_wday);
- err = i2c_smbus_write_i2c_block_data(rx8010->client,
- RX8010_SEC, RX8010_TIME_BUF_LEN,
- date);
- if (err < 0)
+ err = regmap_bulk_write(rx8010->regs, RX8010_SEC,
+ date, RX8010_TIME_BUF_LEN);
+ if (err)
return err;
/* clear STOP bit after changing clock/calendar */
- ctrl = i2c_smbus_read_byte_data(rx8010->client, RX8010_CTRL);
- if (ctrl < 0)
- return ctrl;
- rx8010->ctrlreg = ctrl & ~RX8010_CTRL_STOP;
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_CTRL,
- rx8010->ctrlreg);
- if (err < 0)
+ err = regmap_clear_bits(rx8010->regs, RX8010_CTRL, RX8010_CTRL_STOP);
+ if (err)
return err;
- flagreg = i2c_smbus_read_byte_data(rx8010->client, RX8010_FLAG);
- if (flagreg < 0)
- return flagreg;
-
- if (flagreg & RX8010_FLAG_VLF)
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_FLAG,
- flagreg & ~RX8010_FLAG_VLF);
+ err = regmap_clear_bits(rx8010->regs, RX8010_FLAG, RX8010_FLAG_VLF);
+ if (err)
+ return err;
return 0;
}
-static int rx8010_init_client(struct i2c_client *client)
+static int rx8010_init_client(struct device *dev)
{
- struct rx8010_data *rx8010 = i2c_get_clientdata(client);
+ struct rx8010_data *rx8010 = dev_get_drvdata(dev);
u8 ctrl[2];
int need_clear = 0, err;
/* Initialize reserved registers as specified in datasheet */
- err = i2c_smbus_write_byte_data(client, RX8010_RESV17, 0xD8);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_RESV17, 0xD8);
+ if (err)
return err;
- err = i2c_smbus_write_byte_data(client, RX8010_RESV30, 0x00);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_RESV30, 0x00);
+ if (err)
return err;
- err = i2c_smbus_write_byte_data(client, RX8010_RESV31, 0x08);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_RESV31, 0x08);
+ if (err)
return err;
- err = i2c_smbus_write_byte_data(client, RX8010_IRQ, 0x00);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_IRQ, 0x00);
+ if (err)
return err;
- err = i2c_smbus_read_i2c_block_data(rx8010->client, RX8010_FLAG,
- 2, ctrl);
- if (err != 2)
- return err < 0 ? err : -EIO;
+ err = regmap_bulk_read(rx8010->regs, RX8010_FLAG, ctrl, 2);
+ if (err)
+ return err;
if (ctrl[0] & RX8010_FLAG_VLF)
- dev_warn(&client->dev, "Frequency stop was detected\n");
+ dev_warn(dev, "Frequency stop was detected\n");
if (ctrl[0] & RX8010_FLAG_AF) {
- dev_warn(&client->dev, "Alarm was detected\n");
+ dev_warn(dev, "Alarm was detected\n");
need_clear = 1;
}
@@ -236,8 +219,8 @@ static int rx8010_init_client(struct i2c_client *client)
if (need_clear) {
ctrl[0] &= ~(RX8010_FLAG_AF | RX8010_FLAG_TF | RX8010_FLAG_UF);
- err = i2c_smbus_write_byte_data(client, RX8010_FLAG, ctrl[0]);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_FLAG, ctrl[0]);
+ if (err)
return err;
}
@@ -249,17 +232,16 @@ static int rx8010_init_client(struct i2c_client *client)
static int rx8010_read_alarm(struct device *dev, struct rtc_wkalrm *t)
{
struct rx8010_data *rx8010 = dev_get_drvdata(dev);
- struct i2c_client *client = rx8010->client;
u8 alarmvals[3];
int flagreg, err;
- err = i2c_smbus_read_i2c_block_data(client, RX8010_ALMIN, 3, alarmvals);
- if (err != 3)
- return err < 0 ? err : -EIO;
+ err = regmap_bulk_read(rx8010->regs, RX8010_ALMIN, alarmvals, 3);
+ if (err)
+ return err;
- flagreg = i2c_smbus_read_byte_data(client, RX8010_FLAG);
- if (flagreg < 0)
- return flagreg;
+ err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
+ if (err)
+ return err;
t->time.tm_sec = 0;
t->time.tm_min = bcd2bin(alarmvals[0] & 0x7f);
@@ -276,52 +258,38 @@ static int rx8010_read_alarm(struct device *dev, struct rtc_wkalrm *t)
static int rx8010_set_alarm(struct device *dev, struct rtc_wkalrm *t)
{
- struct i2c_client *client = to_i2c_client(dev);
struct rx8010_data *rx8010 = dev_get_drvdata(dev);
u8 alarmvals[3];
- int extreg, flagreg, err;
-
- flagreg = i2c_smbus_read_byte_data(client, RX8010_FLAG);
- if (flagreg < 0)
- return flagreg;
+ int err;
if (rx8010->ctrlreg & (RX8010_CTRL_AIE | RX8010_CTRL_UIE)) {
rx8010->ctrlreg &= ~(RX8010_CTRL_AIE | RX8010_CTRL_UIE);
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_CTRL,
- rx8010->ctrlreg);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_CTRL, rx8010->ctrlreg);
+ if (err)
return err;
}
- flagreg &= ~RX8010_FLAG_AF;
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_FLAG, flagreg);
- if (err < 0)
+ err = regmap_clear_bits(rx8010->regs, RX8010_FLAG, RX8010_FLAG_AF);
+ if (err)
return err;
alarmvals[0] = bin2bcd(t->time.tm_min);
alarmvals[1] = bin2bcd(t->time.tm_hour);
alarmvals[2] = bin2bcd(t->time.tm_mday);
- err = i2c_smbus_write_i2c_block_data(rx8010->client, RX8010_ALMIN,
- 2, alarmvals);
- if (err < 0)
+ err = regmap_bulk_write(rx8010->regs, RX8010_ALMIN, alarmvals, 2);
+ if (err)
return err;
- extreg = i2c_smbus_read_byte_data(client, RX8010_EXT);
- if (extreg < 0)
- return extreg;
-
- extreg |= RX8010_EXT_WADA;
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_EXT, extreg);
- if (err < 0)
+ err = regmap_clear_bits(rx8010->regs, RX8010_EXT, RX8010_EXT_WADA);
+ if (err)
return err;
if (alarmvals[2] == 0)
alarmvals[2] |= RX8010_ALARM_AE;
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_ALWDAY,
- alarmvals[2]);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_ALWDAY, alarmvals[2]);
+ if (err)
return err;
if (t->enabled) {
@@ -331,9 +299,8 @@ static int rx8010_set_alarm(struct device *dev, struct rtc_wkalrm *t)
rx8010->ctrlreg |=
(RX8010_CTRL_AIE | RX8010_CTRL_UIE);
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_CTRL,
- rx8010->ctrlreg);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_CTRL, rx8010->ctrlreg);
+ if (err)
return err;
}
@@ -343,9 +310,8 @@ static int rx8010_set_alarm(struct device *dev, struct rtc_wkalrm *t)
static int rx8010_alarm_irq_enable(struct device *dev,
unsigned int enabled)
{
- struct i2c_client *client = to_i2c_client(dev);
struct rx8010_data *rx8010 = dev_get_drvdata(dev);
- int flagreg, err;
+ int err;
u8 ctrl;
ctrl = rx8010->ctrlreg;
@@ -362,20 +328,14 @@ static int rx8010_alarm_irq_enable(struct device *dev,
ctrl &= ~RX8010_CTRL_AIE;
}
- flagreg = i2c_smbus_read_byte_data(client, RX8010_FLAG);
- if (flagreg < 0)
- return flagreg;
-
- flagreg &= ~RX8010_FLAG_AF;
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_FLAG, flagreg);
- if (err < 0)
+ err = regmap_clear_bits(rx8010->regs, RX8010_FLAG, RX8010_FLAG_AF);
+ if (err)
return err;
if (ctrl != rx8010->ctrlreg) {
rx8010->ctrlreg = ctrl;
- err = i2c_smbus_write_byte_data(rx8010->client, RX8010_CTRL,
- rx8010->ctrlreg);
- if (err < 0)
+ err = regmap_write(rx8010->regs, RX8010_CTRL, rx8010->ctrlreg);
+ if (err)
return err;
}
@@ -385,13 +345,13 @@ static int rx8010_alarm_irq_enable(struct device *dev,
static int rx8010_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct rx8010_data *rx8010 = dev_get_drvdata(dev);
- int tmp, flagreg;
+ int tmp, flagreg, err;
switch (cmd) {
case RTC_VL_READ:
- flagreg = i2c_smbus_read_byte_data(rx8010->client, RX8010_FLAG);
- if (flagreg < 0)
- return flagreg;
+ err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
+ if (err)
+ return err;
tmp = flagreg & RX8010_FLAG_VLF ? RTC_VL_DATA_INVALID : 0;
return put_user(tmp, (unsigned int __user *)arg);
@@ -407,28 +367,30 @@ static struct rtc_class_ops rx8010_rtc_ops = {
.ioctl = rx8010_ioctl,
};
+static const struct regmap_config rx8010_regmap_config = {
+ .name = "rx8010-rtc",
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
static int rx8010_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct i2c_adapter *adapter = client->adapter;
struct rx8010_data *rx8010;
int err = 0;
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
- | I2C_FUNC_SMBUS_I2C_BLOCK)) {
- dev_err(&adapter->dev, "doesn't support required functionality\n");
- return -EIO;
- }
-
rx8010 = devm_kzalloc(&client->dev, sizeof(struct rx8010_data),
GFP_KERNEL);
if (!rx8010)
return -ENOMEM;
- rx8010->client = client;
i2c_set_clientdata(client, rx8010);
- err = rx8010_init_client(client);
+ rx8010->regs = devm_regmap_init_i2c(client, &rx8010_regmap_config);
+ if (IS_ERR(rx8010->regs))
+ return PTR_ERR(rx8010->regs);
+
+ err = rx8010_init_client(&client->dev);
if (err)
return err;
--
2.26.1
prev parent reply other threads:[~2020-09-04 15:22 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-04 15:21 [PATCH 0/8] rtc: rx8010: use regmap instead of i2c smbus API Bartosz Golaszewski
2020-09-04 15:21 ` [PATCH 1/8] rtc: rx8010: remove unnecessary parentheses Bartosz Golaszewski
2020-09-04 15:32 ` Alexandre Belloni
2020-09-04 15:21 ` [PATCH 2/8] rtc: rx8010: consolidate local variables of the same type Bartosz Golaszewski
2020-09-04 15:21 ` [PATCH 3/8] rtc: rx8010: use tabs for instead of spaces for code formatting Bartosz Golaszewski
2020-09-04 15:21 ` [PATCH 4/8] rtc: rx8010: rename ret to err in rx8010_set_time() Bartosz Golaszewski
2020-09-04 15:21 ` [PATCH 5/8] rtc: rx8010: don't use magic values for time buffer length Bartosz Golaszewski
2020-09-04 15:39 ` Alexandre Belloni
2020-09-04 15:21 ` [PATCH 6/8] rtc: rx8010: drop unnecessary initialization Bartosz Golaszewski
2020-09-04 15:21 ` [PATCH 7/8] rtc: rx8010: fix indentation in probe() Bartosz Golaszewski
2020-09-04 15:41 ` Alexandre Belloni
2020-09-07 9:34 ` Bartosz Golaszewski
2020-09-11 12:28 ` Alexandre Belloni
2020-09-11 12:33 ` Bartosz Golaszewski
2020-09-11 12:44 ` Alexandre Belloni
2020-09-04 15:21 ` Bartosz Golaszewski [this message]
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=20200904152116.2157-9-brgl@bgdev.pl \
--to=brgl@bgdev.pl \
--cc=a.zummo@towertech.it \
--cc=alexandre.belloni@bootlin.com \
--cc=bgolaszewski@baylibre.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rtc@vger.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.