Skip to content

Commit b1a1baa

Browse files
Villemoesalexandrebelloni
authored andcommitted
rtc: isl12022: switch to using regmap API
The regmap abstraction allows us to avoid the private i2c transfer helpers, and also offers some nice utility functions such as the regmap_update_bits family. While at it, simplify the code even more by not keeping track of ->write_enabled: rtc_set_time is not a hot path, so one extra i2c read doesn't hurt (regmap_update_bits elides the write when the bits are already as desired). Signed-off-by: Rasmus Villemoes <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Belloni <[email protected]>
1 parent 0a2abbf commit b1a1baa

File tree

2 files changed

+26
-85
lines changed

2 files changed

+26
-85
lines changed

drivers/rtc/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ config RTC_DRV_ISL1208
423423

424424
config RTC_DRV_ISL12022
425425
tristate "Intersil ISL12022"
426+
select REGMAP_I2C
426427
help
427428
If you say yes here you get support for the
428429
Intersil ISL12022 RTC chip.

drivers/rtc/rtc-isl12022.c

Lines changed: 25 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/err.h>
1717
#include <linux/of.h>
1818
#include <linux/of_device.h>
19+
#include <linux/regmap.h>
1920

2021
/* ISL register offsets */
2122
#define ISL12022_REG_SC 0x00
@@ -42,72 +43,21 @@ static struct i2c_driver isl12022_driver;
4243

4344
struct isl12022 {
4445
struct rtc_device *rtc;
45-
46-
bool write_enabled; /* true if write enable is set */
46+
struct regmap *regmap;
4747
};
4848

49-
50-
static int isl12022_read_regs(struct i2c_client *client, uint8_t reg,
51-
uint8_t *data, size_t n)
52-
{
53-
struct i2c_msg msgs[] = {
54-
{
55-
.addr = client->addr,
56-
.flags = 0,
57-
.len = 1,
58-
.buf = data
59-
}, /* setup read ptr */
60-
{
61-
.addr = client->addr,
62-
.flags = I2C_M_RD,
63-
.len = n,
64-
.buf = data
65-
}
66-
};
67-
68-
int ret;
69-
70-
data[0] = reg;
71-
ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
72-
if (ret != ARRAY_SIZE(msgs)) {
73-
dev_err(&client->dev, "%s: read error, ret=%d\n",
74-
__func__, ret);
75-
return -EIO;
76-
}
77-
78-
return 0;
79-
}
80-
81-
82-
static int isl12022_write_reg(struct i2c_client *client,
83-
uint8_t reg, uint8_t val)
84-
{
85-
uint8_t data[2] = { reg, val };
86-
int err;
87-
88-
err = i2c_master_send(client, data, sizeof(data));
89-
if (err != sizeof(data)) {
90-
dev_err(&client->dev,
91-
"%s: err=%d addr=%02x, data=%02x\n",
92-
__func__, err, data[0], data[1]);
93-
return -EIO;
94-
}
95-
96-
return 0;
97-
}
98-
99-
10049
/*
10150
* In the routines that deal directly with the isl12022 hardware, we use
10251
* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
10352
*/
10453
static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm)
10554
{
106-
struct i2c_client *client = to_i2c_client(dev);
55+
struct isl12022 *isl12022 = dev_get_drvdata(dev);
56+
struct regmap *regmap = isl12022->regmap;
10757
uint8_t buf[ISL12022_REG_INT + 1];
10858
int ret;
10959

110-
ret = isl12022_read_regs(client, ISL12022_REG_SC, buf, sizeof(buf));
60+
ret = regmap_bulk_read(regmap, ISL12022_REG_SC, buf, sizeof(buf));
11161
if (ret)
11262
return ret;
11363

@@ -148,33 +98,18 @@ static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm)
14898

14999
static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm)
150100
{
151-
struct i2c_client *client = to_i2c_client(dev);
152101
struct isl12022 *isl12022 = dev_get_drvdata(dev);
153-
size_t i;
102+
struct regmap *regmap = isl12022->regmap;
154103
int ret;
155104
uint8_t buf[ISL12022_REG_DW + 1];
156105

157106
dev_dbg(dev, "%s: %ptR\n", __func__, tm);
158107

159-
if (!isl12022->write_enabled) {
160-
161-
ret = isl12022_read_regs(client, ISL12022_REG_INT, buf, 1);
162-
if (ret)
163-
return ret;
164-
165-
/* Check if WRTC (write rtc enable) is set factory default is
166-
* 0 (not set) */
167-
if (!(buf[0] & ISL12022_INT_WRTC)) {
168-
/* Set the write enable bit. */
169-
ret = isl12022_write_reg(client,
170-
ISL12022_REG_INT,
171-
buf[0] | ISL12022_INT_WRTC);
172-
if (ret)
173-
return ret;
174-
}
175-
176-
isl12022->write_enabled = true;
177-
}
108+
/* Ensure the write enable bit is set. */
109+
ret = regmap_update_bits(regmap, ISL12022_REG_INT,
110+
ISL12022_INT_WRTC, ISL12022_INT_WRTC);
111+
if (ret)
112+
return ret;
178113

179114
/* hours, minutes and seconds */
180115
buf[ISL12022_REG_SC] = bin2bcd(tm->tm_sec);
@@ -191,22 +126,21 @@ static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm)
191126

192127
buf[ISL12022_REG_DW] = tm->tm_wday & 0x07;
193128

194-
/* write register's data */
195-
for (i = 0; i < ARRAY_SIZE(buf); i++) {
196-
ret = isl12022_write_reg(client, ISL12022_REG_SC + i,
197-
buf[ISL12022_REG_SC + i]);
198-
if (ret)
199-
return -EIO;
200-
}
201-
202-
return 0;
129+
return regmap_bulk_write(isl12022->regmap, ISL12022_REG_SC,
130+
buf, sizeof(buf));
203131
}
204132

205133
static const struct rtc_class_ops isl12022_rtc_ops = {
206134
.read_time = isl12022_rtc_read_time,
207135
.set_time = isl12022_rtc_set_time,
208136
};
209137

138+
static const struct regmap_config regmap_config = {
139+
.reg_bits = 8,
140+
.val_bits = 8,
141+
.use_single_write = true,
142+
};
143+
210144
static int isl12022_probe(struct i2c_client *client)
211145
{
212146
struct isl12022 *isl12022;
@@ -220,6 +154,12 @@ static int isl12022_probe(struct i2c_client *client)
220154
return -ENOMEM;
221155
dev_set_drvdata(&client->dev, isl12022);
222156

157+
isl12022->regmap = devm_regmap_init_i2c(client, &regmap_config);
158+
if (IS_ERR(isl12022->regmap)) {
159+
dev_err(&client->dev, "regmap allocation failed\n");
160+
return PTR_ERR(isl12022->regmap);
161+
}
162+
223163
isl12022->rtc = devm_rtc_allocate_device(&client->dev);
224164
if (IS_ERR(isl12022->rtc))
225165
return PTR_ERR(isl12022->rtc);

0 commit comments

Comments
 (0)