Skip to content

Commit d57d12d

Browse files
Villemoesalexandrebelloni
authored andcommitted
rtc: isl12022: implement support for the #clock-cells DT property
If device tree implies that the chip's IRQ/F_OUT pin is used as a clock, expose that in the driver. For now, pretend it is a fixed-rate (32kHz) clock; if other use cases appear the driver can be updated to provide its own clk_ops etc. When the clock output is not used on a given board, one can prolong the battery life by ensuring that the FOx bits are 0. For the hardware I'm currently working on, the RTC draws 1.2uA with the FOx bits at their default 0001 value, dropping to 0.88uA when those bits are cleared. Signed-off-by: Rasmus Villemoes <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Belloni <[email protected]>
1 parent ab246c8 commit d57d12d

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

drivers/rtc/rtc-isl12022.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <linux/bcd.h>
1212
#include <linux/bitfield.h>
13+
#include <linux/clk-provider.h>
1314
#include <linux/err.h>
1415
#include <linux/hwmon.h>
1516
#include <linux/i2c.h>
@@ -44,6 +45,9 @@
4445
#define ISL12022_SR_LBAT75 (1 << 1)
4546

4647
#define ISL12022_INT_WRTC (1 << 6)
48+
#define ISL12022_INT_FO_MASK GENMASK(3, 0)
49+
#define ISL12022_INT_FO_OFF 0x0
50+
#define ISL12022_INT_FO_32K 0x1
4751

4852
#define ISL12022_REG_VB85_MASK GENMASK(5, 3)
4953
#define ISL12022_REG_VB75_MASK GENMASK(2, 0)
@@ -242,6 +246,41 @@ static const struct regmap_config regmap_config = {
242246
.use_single_write = true,
243247
};
244248

249+
static int isl12022_register_clock(struct device *dev)
250+
{
251+
struct regmap *regmap = dev_get_drvdata(dev);
252+
struct clk_hw *hw;
253+
int ret;
254+
255+
if (!device_property_present(dev, "#clock-cells")) {
256+
/*
257+
* Disabling the F_OUT pin reduces the power
258+
* consumption in battery mode by ~25%.
259+
*/
260+
regmap_update_bits(regmap, ISL12022_REG_INT, ISL12022_INT_FO_MASK,
261+
ISL12022_INT_FO_OFF);
262+
263+
return 0;
264+
}
265+
266+
if (!IS_ENABLED(CONFIG_COMMON_CLK))
267+
return 0;
268+
269+
/*
270+
* For now, only support a fixed clock of 32768Hz (the reset default).
271+
*/
272+
ret = regmap_update_bits(regmap, ISL12022_REG_INT,
273+
ISL12022_INT_FO_MASK, ISL12022_INT_FO_32K);
274+
if (ret)
275+
return ret;
276+
277+
hw = devm_clk_hw_register_fixed_rate(dev, "isl12022", NULL, 0, 32768);
278+
if (IS_ERR(hw))
279+
return PTR_ERR(hw);
280+
281+
return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
282+
}
283+
245284
static const u32 trip_levels[2][7] = {
246285
{ 2125000, 2295000, 2550000, 2805000, 3060000, 4250000, 4675000 },
247286
{ 1875000, 2025000, 2250000, 2475000, 2700000, 3750000, 4125000 },
@@ -288,6 +327,7 @@ static int isl12022_probe(struct i2c_client *client)
288327
{
289328
struct rtc_device *rtc;
290329
struct regmap *regmap;
330+
int ret;
291331

292332
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
293333
return -ENODEV;
@@ -300,6 +340,10 @@ static int isl12022_probe(struct i2c_client *client)
300340

301341
dev_set_drvdata(&client->dev, regmap);
302342

343+
ret = isl12022_register_clock(&client->dev);
344+
if (ret)
345+
return ret;
346+
303347
isl12022_set_trip_levels(&client->dev);
304348
isl12022_hwmon_register(&client->dev);
305349

0 commit comments

Comments
 (0)