* [PATCH v2 1/9] rtc: isl12022: stop using deprecated devm_rtc_device_register()
2022-09-21 11:46 ` [PATCH v2 0/9] " Rasmus Villemoes
@ 2022-09-21 11:46 ` Rasmus Villemoes
2022-09-21 11:46 ` [PATCH v2 2/9] rtc: isl12022: specify range_min and range_max Rasmus Villemoes
` (9 subsequent siblings)
10 siblings, 0 replies; 35+ messages in thread
From: Rasmus Villemoes @ 2022-09-21 11:46 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni
Cc: Rasmus Villemoes, linux-rtc, linux-kernel
The comments say that devm_rtc_device_register() is deprecated and
that one should instead use devm_rtc_allocate_device() and
[devm_]rtc_register_device. So do that.
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
drivers/rtc/rtc-isl12022.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index 79461ded1a48..2dc19061cf5f 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -246,10 +246,13 @@ static int isl12022_probe(struct i2c_client *client)
i2c_set_clientdata(client, isl12022);
- isl12022->rtc = devm_rtc_device_register(&client->dev,
- isl12022_driver.driver.name,
- &isl12022_rtc_ops, THIS_MODULE);
- return PTR_ERR_OR_ZERO(isl12022->rtc);
+ isl12022->rtc = devm_rtc_allocate_device(&client->dev);
+ if (IS_ERR(isl12022->rtc))
+ return PTR_ERR(isl12022->rtc);
+
+ isl12022->rtc->ops = &isl12022_rtc_ops;
+
+ return devm_rtc_register_device(isl12022->rtc);
}
#ifdef CONFIG_OF
--
2.37.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v2 2/9] rtc: isl12022: specify range_min and range_max
2022-09-21 11:46 ` [PATCH v2 0/9] " Rasmus Villemoes
2022-09-21 11:46 ` [PATCH v2 1/9] rtc: isl12022: stop using deprecated devm_rtc_device_register() Rasmus Villemoes
@ 2022-09-21 11:46 ` Rasmus Villemoes
2022-09-21 11:46 ` [PATCH v2 3/9] rtc: isl12022: drop a dev_info() Rasmus Villemoes
` (8 subsequent siblings)
10 siblings, 0 replies; 35+ messages in thread
From: Rasmus Villemoes @ 2022-09-21 11:46 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni
Cc: Rasmus Villemoes, linux-rtc, linux-kernel
The isl12022 can (only) keep track of times in the range
2000-2099. The data sheet says
The calendar registers track date, month, year, and day of the week
and are accurate through 2099, with automatic leap year correction.
The lower bound of 2000 is obtained by simply observing that its YR
register only counts from 00 through 99.
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
drivers/rtc/rtc-isl12022.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index 2dc19061cf5f..3bc197f5548f 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -251,6 +251,8 @@ static int isl12022_probe(struct i2c_client *client)
return PTR_ERR(isl12022->rtc);
isl12022->rtc->ops = &isl12022_rtc_ops;
+ isl12022->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ isl12022->rtc->range_max = RTC_TIMESTAMP_END_2099;
return devm_rtc_register_device(isl12022->rtc);
}
--
2.37.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v2 3/9] rtc: isl12022: drop a dev_info()
2022-09-21 11:46 ` [PATCH v2 0/9] " Rasmus Villemoes
2022-09-21 11:46 ` [PATCH v2 1/9] rtc: isl12022: stop using deprecated devm_rtc_device_register() Rasmus Villemoes
2022-09-21 11:46 ` [PATCH v2 2/9] rtc: isl12022: specify range_min and range_max Rasmus Villemoes
@ 2022-09-21 11:46 ` Rasmus Villemoes
2022-09-21 11:46 ` [PATCH v2 4/9] rtc: isl12022: simplify some expressions Rasmus Villemoes
` (7 subsequent siblings)
10 siblings, 0 replies; 35+ messages in thread
From: Rasmus Villemoes @ 2022-09-21 11:46 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni
Cc: Rasmus Villemoes, linux-rtc, linux-kernel
This dev_info() seems to be a debug leftover, and it would only get
printed once (or, once per battery change).
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
drivers/rtc/rtc-isl12022.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index 3bc197f5548f..2fc9fbefc6fc 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -173,9 +173,6 @@ static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm)
/* Check if WRTC (write rtc enable) is set factory default is
* 0 (not set) */
if (!(buf[0] & ISL12022_INT_WRTC)) {
- dev_info(&client->dev,
- "init write enable and 24 hour format\n");
-
/* Set the write enable bit. */
ret = isl12022_write_reg(client,
ISL12022_REG_INT,
--
2.37.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v2 4/9] rtc: isl12022: simplify some expressions
2022-09-21 11:46 ` [PATCH v2 0/9] " Rasmus Villemoes
` (2 preceding siblings ...)
2022-09-21 11:46 ` [PATCH v2 3/9] rtc: isl12022: drop a dev_info() Rasmus Villemoes
@ 2022-09-21 11:46 ` Rasmus Villemoes
2022-09-21 11:46 ` [PATCH v2 5/9] rtc: isl12022: use %ptR Rasmus Villemoes
` (6 subsequent siblings)
10 siblings, 0 replies; 35+ messages in thread
From: Rasmus Villemoes @ 2022-09-21 11:46 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni
Cc: Rasmus Villemoes, linux-rtc, linux-kernel
These instances of '&client->dev' might as well be spelled 'dev', since
'client' has been computed from 'dev' via 'client =
to_i2c_client(dev)'.
Later patches will get rid of that local variable 'client', so remove
these unnecessary references so those later patches become easier to
read.
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
drivers/rtc/rtc-isl12022.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index 2fc9fbefc6fc..7efe23fa74df 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -112,13 +112,13 @@ static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm)
return ret;
if (buf[ISL12022_REG_SR] & (ISL12022_SR_LBAT85 | ISL12022_SR_LBAT75)) {
- dev_warn(&client->dev,
+ dev_warn(dev,
"voltage dropped below %u%%, "
"date and time is not reliable.\n",
buf[ISL12022_REG_SR] & ISL12022_SR_LBAT85 ? 85 : 75);
}
- dev_dbg(&client->dev,
+ dev_dbg(dev,
"%s: raw data is sec=%02x, min=%02x, hr=%02x, "
"mday=%02x, mon=%02x, year=%02x, wday=%02x, "
"sr=%02x, int=%02x",
@@ -141,7 +141,7 @@ static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_mon = bcd2bin(buf[ISL12022_REG_MO] & 0x1F) - 1;
tm->tm_year = bcd2bin(buf[ISL12022_REG_YR]) + 100;
- dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
+ dev_dbg(dev, "%s: secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n",
__func__,
tm->tm_sec, tm->tm_min, tm->tm_hour,
@@ -158,7 +158,7 @@ static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm)
int ret;
uint8_t buf[ISL12022_REG_DW + 1];
- dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
+ dev_dbg(dev, "%s: secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n",
__func__,
tm->tm_sec, tm->tm_min, tm->tm_hour,
--
2.37.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v2 5/9] rtc: isl12022: use %ptR
2022-09-21 11:46 ` [PATCH v2 0/9] " Rasmus Villemoes
` (3 preceding siblings ...)
2022-09-21 11:46 ` [PATCH v2 4/9] rtc: isl12022: simplify some expressions Rasmus Villemoes
@ 2022-09-21 11:46 ` Rasmus Villemoes
2022-09-21 11:46 ` [PATCH v2 6/9] rtc: isl12022: use dev_set_drvdata() instead of i2c_set_clientdata() Rasmus Villemoes
` (5 subsequent siblings)
10 siblings, 0 replies; 35+ messages in thread
From: Rasmus Villemoes @ 2022-09-21 11:46 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni
Cc: Rasmus Villemoes, linux-rtc, linux-kernel
Simplify the code and make the output format consistent with other RTC
drivers by standardizing on using the %ptR printf extension.
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
drivers/rtc/rtc-isl12022.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index 7efe23fa74df..d396d6076db5 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -141,11 +141,7 @@ static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_mon = bcd2bin(buf[ISL12022_REG_MO] & 0x1F) - 1;
tm->tm_year = bcd2bin(buf[ISL12022_REG_YR]) + 100;
- dev_dbg(dev, "%s: secs=%d, mins=%d, hours=%d, "
- "mday=%d, mon=%d, year=%d, wday=%d\n",
- __func__,
- tm->tm_sec, tm->tm_min, tm->tm_hour,
- tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
+ dev_dbg(dev, "%s: %ptR\n", __func__, tm);
return 0;
}
@@ -158,11 +154,7 @@ static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm)
int ret;
uint8_t buf[ISL12022_REG_DW + 1];
- dev_dbg(dev, "%s: secs=%d, mins=%d, hours=%d, "
- "mday=%d, mon=%d, year=%d, wday=%d\n",
- __func__,
- tm->tm_sec, tm->tm_min, tm->tm_hour,
- tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
+ dev_dbg(dev, "%s: %ptR\n", __func__, tm);
if (!isl12022->write_enabled) {
--
2.37.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v2 6/9] rtc: isl12022: use dev_set_drvdata() instead of i2c_set_clientdata()
2022-09-21 11:46 ` [PATCH v2 0/9] " Rasmus Villemoes
` (4 preceding siblings ...)
2022-09-21 11:46 ` [PATCH v2 5/9] rtc: isl12022: use %ptR Rasmus Villemoes
@ 2022-09-21 11:46 ` Rasmus Villemoes
2022-09-21 11:46 ` [PATCH v2 7/9] rtc: isl12022: drop redundant write to HR register Rasmus Villemoes
` (4 subsequent siblings)
10 siblings, 0 replies; 35+ messages in thread
From: Rasmus Villemoes @ 2022-09-21 11:46 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni
Cc: Rasmus Villemoes, linux-rtc, linux-kernel
As another preparation for removing direct references to the
i2c_client in the helper functions, stash a pointer to the private
data via dev_set_drvdata() instead of i2c_set_clientdata().
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
drivers/rtc/rtc-isl12022.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index d396d6076db5..df6d91f4e8f3 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -149,7 +149,7 @@ static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct i2c_client *client = to_i2c_client(dev);
- struct isl12022 *isl12022 = i2c_get_clientdata(client);
+ struct isl12022 *isl12022 = dev_get_drvdata(dev);
size_t i;
int ret;
uint8_t buf[ISL12022_REG_DW + 1];
@@ -232,8 +232,7 @@ static int isl12022_probe(struct i2c_client *client)
GFP_KERNEL);
if (!isl12022)
return -ENOMEM;
-
- i2c_set_clientdata(client, isl12022);
+ dev_set_drvdata(&client->dev, isl12022);
isl12022->rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(isl12022->rtc))
--
2.37.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v2 7/9] rtc: isl12022: drop redundant write to HR register
2022-09-21 11:46 ` [PATCH v2 0/9] " Rasmus Villemoes
` (5 preceding siblings ...)
2022-09-21 11:46 ` [PATCH v2 6/9] rtc: isl12022: use dev_set_drvdata() instead of i2c_set_clientdata() Rasmus Villemoes
@ 2022-09-21 11:46 ` Rasmus Villemoes
2022-09-21 11:46 ` [PATCH v2 8/9] rtc: isl12022: switch to using regmap API Rasmus Villemoes
` (3 subsequent siblings)
10 siblings, 0 replies; 35+ messages in thread
From: Rasmus Villemoes @ 2022-09-21 11:46 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni
Cc: Rasmus Villemoes, linux-rtc, linux-kernel
There's nothing in the data sheet that says writing to one of the time
keeping registers is necessary to start the RTC. It does so at the
stop condition of the i2c transfer setting the WRTC bit:
Upon initialization or power-up, the WRTC must be set to "1" to
enable the RTC. Upon the completion of a valid write (STOP), the RTC
starts counting.
Moreover, even if such a write to one of the timekeeping registers was
necessary, that's exactly what we do anyway just below when we
actually write the given struct rtc_time to the device.
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
drivers/rtc/rtc-isl12022.c | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index df6d91f4e8f3..6fb13a5d17f1 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -171,20 +171,6 @@ static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm)
buf[0] | ISL12022_INT_WRTC);
if (ret)
return ret;
-
- /* Write to any RTC register to start RTC, we use the
- * HR register, setting the MIL bit to use the 24 hour
- * format. */
- ret = isl12022_read_regs(client, ISL12022_REG_HR,
- buf, 1);
- if (ret)
- return ret;
-
- ret = isl12022_write_reg(client,
- ISL12022_REG_HR,
- buf[0] | ISL12022_HR_MIL);
- if (ret)
- return ret;
}
isl12022->write_enabled = true;
--
2.37.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v2 8/9] rtc: isl12022: switch to using regmap API
2022-09-21 11:46 ` [PATCH v2 0/9] " Rasmus Villemoes
` (6 preceding siblings ...)
2022-09-21 11:46 ` [PATCH v2 7/9] rtc: isl12022: drop redundant write to HR register Rasmus Villemoes
@ 2022-09-21 11:46 ` Rasmus Villemoes
2022-09-21 11:46 ` [PATCH v2 9/9] rtc: isl12022: add support for temperature sensor Rasmus Villemoes
` (2 subsequent siblings)
10 siblings, 0 replies; 35+ messages in thread
From: Rasmus Villemoes @ 2022-09-21 11:46 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni
Cc: Rasmus Villemoes, linux-rtc, linux-kernel
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 <linux@rasmusvillemoes.dk>
---
drivers/rtc/Kconfig | 1 +
drivers/rtc/rtc-isl12022.c | 110 +++++++++----------------------------
2 files changed, 26 insertions(+), 85 deletions(-)
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index b8de25118ad0..bb63edb507da 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -423,6 +423,7 @@ config RTC_DRV_ISL1208
config RTC_DRV_ISL12022
tristate "Intersil ISL12022"
+ select REGMAP_I2C
help
If you say yes here you get support for the
Intersil ISL12022 RTC chip.
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index 6fb13a5d17f1..ca677c4265e6 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -16,6 +16,7 @@
#include <linux/err.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/regmap.h>
/* ISL register offsets */
#define ISL12022_REG_SC 0x00
@@ -42,72 +43,21 @@ static struct i2c_driver isl12022_driver;
struct isl12022 {
struct rtc_device *rtc;
-
- bool write_enabled; /* true if write enable is set */
+ struct regmap *regmap;
};
-
-static int isl12022_read_regs(struct i2c_client *client, uint8_t reg,
- uint8_t *data, size_t n)
-{
- struct i2c_msg msgs[] = {
- {
- .addr = client->addr,
- .flags = 0,
- .len = 1,
- .buf = data
- }, /* setup read ptr */
- {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .len = n,
- .buf = data
- }
- };
-
- int ret;
-
- data[0] = reg;
- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
- if (ret != ARRAY_SIZE(msgs)) {
- dev_err(&client->dev, "%s: read error, ret=%d\n",
- __func__, ret);
- return -EIO;
- }
-
- return 0;
-}
-
-
-static int isl12022_write_reg(struct i2c_client *client,
- uint8_t reg, uint8_t val)
-{
- uint8_t data[2] = { reg, val };
- int err;
-
- err = i2c_master_send(client, data, sizeof(data));
- if (err != sizeof(data)) {
- dev_err(&client->dev,
- "%s: err=%d addr=%02x, data=%02x\n",
- __func__, err, data[0], data[1]);
- return -EIO;
- }
-
- return 0;
-}
-
-
/*
* In the routines that deal directly with the isl12022 hardware, we use
* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
*/
static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
- struct i2c_client *client = to_i2c_client(dev);
+ struct isl12022 *isl12022 = dev_get_drvdata(dev);
+ struct regmap *regmap = isl12022->regmap;
uint8_t buf[ISL12022_REG_INT + 1];
int ret;
- ret = isl12022_read_regs(client, ISL12022_REG_SC, buf, sizeof(buf));
+ ret = regmap_bulk_read(regmap, ISL12022_REG_SC, buf, sizeof(buf));
if (ret)
return ret;
@@ -148,33 +98,18 @@ static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
- struct i2c_client *client = to_i2c_client(dev);
struct isl12022 *isl12022 = dev_get_drvdata(dev);
- size_t i;
+ struct regmap *regmap = isl12022->regmap;
int ret;
uint8_t buf[ISL12022_REG_DW + 1];
dev_dbg(dev, "%s: %ptR\n", __func__, tm);
- if (!isl12022->write_enabled) {
-
- ret = isl12022_read_regs(client, ISL12022_REG_INT, buf, 1);
- if (ret)
- return ret;
-
- /* Check if WRTC (write rtc enable) is set factory default is
- * 0 (not set) */
- if (!(buf[0] & ISL12022_INT_WRTC)) {
- /* Set the write enable bit. */
- ret = isl12022_write_reg(client,
- ISL12022_REG_INT,
- buf[0] | ISL12022_INT_WRTC);
- if (ret)
- return ret;
- }
-
- isl12022->write_enabled = true;
- }
+ /* Ensure the write enable bit is set. */
+ ret = regmap_update_bits(regmap, ISL12022_REG_INT,
+ ISL12022_INT_WRTC, ISL12022_INT_WRTC);
+ if (ret)
+ return ret;
/* hours, minutes and seconds */
buf[ISL12022_REG_SC] = bin2bcd(tm->tm_sec);
@@ -191,15 +126,8 @@ static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm)
buf[ISL12022_REG_DW] = tm->tm_wday & 0x07;
- /* write register's data */
- for (i = 0; i < ARRAY_SIZE(buf); i++) {
- ret = isl12022_write_reg(client, ISL12022_REG_SC + i,
- buf[ISL12022_REG_SC + i]);
- if (ret)
- return -EIO;
- }
-
- return 0;
+ return regmap_bulk_write(isl12022->regmap, ISL12022_REG_SC,
+ buf, sizeof(buf));
}
static const struct rtc_class_ops isl12022_rtc_ops = {
@@ -207,6 +135,12 @@ static const struct rtc_class_ops isl12022_rtc_ops = {
.set_time = isl12022_rtc_set_time,
};
+static const struct regmap_config regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .use_single_write = true,
+};
+
static int isl12022_probe(struct i2c_client *client)
{
struct isl12022 *isl12022;
@@ -220,6 +154,12 @@ static int isl12022_probe(struct i2c_client *client)
return -ENOMEM;
dev_set_drvdata(&client->dev, isl12022);
+ isl12022->regmap = devm_regmap_init_i2c(client, ®map_config);
+ if (IS_ERR(isl12022->regmap)) {
+ dev_err(&client->dev, "regmap allocation failed\n");
+ return PTR_ERR(isl12022->regmap);
+ }
+
isl12022->rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(isl12022->rtc))
return PTR_ERR(isl12022->rtc);
--
2.37.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v2 9/9] rtc: isl12022: add support for temperature sensor
2022-09-21 11:46 ` [PATCH v2 0/9] " Rasmus Villemoes
` (7 preceding siblings ...)
2022-09-21 11:46 ` [PATCH v2 8/9] rtc: isl12022: switch to using regmap API Rasmus Villemoes
@ 2022-09-21 11:46 ` Rasmus Villemoes
2022-09-21 14:13 ` Guenter Roeck
2022-10-26 13:38 ` [PATCH v3 " Rasmus Villemoes
2022-10-07 13:51 ` [PATCH v2 0/9] rtc: isl12022: cleanups and hwmon support Rasmus Villemoes
2022-10-13 21:31 ` Alexandre Belloni
10 siblings, 2 replies; 35+ messages in thread
From: Rasmus Villemoes @ 2022-09-21 11:46 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni, Jean Delvare, Guenter Roeck
Cc: Rasmus Villemoes, linux-rtc, linux-kernel, linux-hwmon
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
drivers/rtc/rtc-isl12022.c | 104 +++++++++++++++++++++++++++++++++++++
1 file changed, 104 insertions(+)
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index ca677c4265e6..f3efe61c81e5 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -17,6 +17,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
+#include <linux/hwmon.h>
/* ISL register offsets */
#define ISL12022_REG_SC 0x00
@@ -30,6 +31,9 @@
#define ISL12022_REG_SR 0x07
#define ISL12022_REG_INT 0x08
+#define ISL12022_REG_BETA 0x0d
+#define ISL12022_REG_TEMP_L 0x28
+
/* ISL register bits */
#define ISL12022_HR_MIL (1 << 7) /* military or 24 hour time */
@@ -38,6 +42,7 @@
#define ISL12022_INT_WRTC (1 << 6)
+#define ISL12022_BETA_TSE (1 << 7)
static struct i2c_driver isl12022_driver;
@@ -46,6 +51,103 @@ struct isl12022 {
struct regmap *regmap;
};
+static umode_t isl12022_hwmon_is_visible(const void *data,
+ enum hwmon_sensor_types type,
+ u32 attr, int channel)
+{
+ if (type == hwmon_chip && attr == hwmon_chip_update_interval)
+ return 0444;
+
+ if (type == hwmon_temp && attr == hwmon_temp_input)
+ return 0444;
+
+ return 0;
+}
+
+/*
+ * A user-initiated temperature conversion is not started by this function,
+ * so the temperature is updated once every ~60 seconds.
+ */
+static int isl12022_hwmon_read_temp(struct device *dev, long *mC)
+{
+ struct isl12022 *isl12022 = dev_get_drvdata(dev);
+ struct regmap *regmap = isl12022->regmap;
+ u8 temp_buf[2];
+ int temp, ret;
+
+ ret = regmap_bulk_read(regmap, ISL12022_REG_TEMP_L,
+ temp_buf, sizeof(temp_buf));
+ if (ret)
+ return ret;
+ /*
+ * Temperature is represented as a 10-bit number, unit half-Kelvins.
+ */
+ temp = (temp_buf[1] << 8) | temp_buf[0];
+ temp *= 500;
+ temp -= 273000;
+
+ *mC = temp;
+
+ return 0;
+}
+
+static int isl12022_hwmon_read(struct device *dev,
+ enum hwmon_sensor_types type,
+ u32 attr, int channel, long *val)
+{
+ if (type == hwmon_chip && attr == hwmon_chip_update_interval) {
+ *val = 60000;
+ return 0;
+ }
+
+ if (type == hwmon_temp && attr == hwmon_temp_input) {
+ return isl12022_hwmon_read_temp(dev, val);
+ }
+
+ return -EOPNOTSUPP;
+}
+
+static const struct hwmon_channel_info *isl12022_hwmon_info[] = {
+ HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL),
+ HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
+ NULL
+};
+
+static const struct hwmon_ops isl12022_hwmon_ops = {
+ .is_visible = isl12022_hwmon_is_visible,
+ .read = isl12022_hwmon_read,
+};
+
+static const struct hwmon_chip_info isl12022_hwmon_chip_info = {
+ .ops = &isl12022_hwmon_ops,
+ .info = isl12022_hwmon_info,
+};
+
+static void isl12022_hwmon_register(struct device *dev)
+{
+ struct isl12022 *isl12022;
+ struct device *hwmon;
+ int ret;
+
+ if (!IS_REACHABLE(CONFIG_HWMON))
+ return;
+
+ isl12022 = dev_get_drvdata(dev);
+
+ ret = regmap_update_bits(isl12022->regmap, ISL12022_REG_BETA,
+ ISL12022_BETA_TSE, ISL12022_BETA_TSE);
+ if (ret) {
+ dev_warn(dev, "unable to enable temperature sensor\n");
+ return;
+ }
+
+ hwmon = devm_hwmon_device_register_with_info(dev, "isl12022", isl12022,
+ &isl12022_hwmon_chip_info,
+ NULL);
+ if (IS_ERR(hwmon))
+ dev_warn(dev, "unable to register hwmon device: %pe\n", hwmon);
+}
+
/*
* In the routines that deal directly with the isl12022 hardware, we use
* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
@@ -160,6 +262,8 @@ static int isl12022_probe(struct i2c_client *client)
return PTR_ERR(isl12022->regmap);
}
+ isl12022_hwmon_register(&client->dev);
+
isl12022->rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(isl12022->rtc))
return PTR_ERR(isl12022->rtc);
--
2.37.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 9/9] rtc: isl12022: add support for temperature sensor
2022-09-21 11:46 ` [PATCH v2 9/9] rtc: isl12022: add support for temperature sensor Rasmus Villemoes
@ 2022-09-21 14:13 ` Guenter Roeck
2022-09-23 8:40 ` Rasmus Villemoes
2022-10-26 13:38 ` [PATCH v3 " Rasmus Villemoes
1 sibling, 1 reply; 35+ messages in thread
From: Guenter Roeck @ 2022-09-21 14:13 UTC (permalink / raw)
To: Rasmus Villemoes, Alessandro Zummo, Alexandre Belloni, Jean Delvare
Cc: linux-rtc, linux-kernel, linux-hwmon
On 9/21/22 04:46, Rasmus Villemoes wrote:
> Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
> ---
> drivers/rtc/rtc-isl12022.c | 104 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 104 insertions(+)
>
> diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
> index ca677c4265e6..f3efe61c81e5 100644
> --- a/drivers/rtc/rtc-isl12022.c
> +++ b/drivers/rtc/rtc-isl12022.c
> @@ -17,6 +17,7 @@
> #include <linux/of.h>
> #include <linux/of_device.h>
> #include <linux/regmap.h>
> +#include <linux/hwmon.h>
>
> /* ISL register offsets */
> #define ISL12022_REG_SC 0x00
> @@ -30,6 +31,9 @@
> #define ISL12022_REG_SR 0x07
> #define ISL12022_REG_INT 0x08
>
> +#define ISL12022_REG_BETA 0x0d
> +#define ISL12022_REG_TEMP_L 0x28
> +
> /* ISL register bits */
> #define ISL12022_HR_MIL (1 << 7) /* military or 24 hour time */
>
> @@ -38,6 +42,7 @@
>
> #define ISL12022_INT_WRTC (1 << 6)
>
> +#define ISL12022_BETA_TSE (1 << 7)
>
> static struct i2c_driver isl12022_driver;
>
> @@ -46,6 +51,103 @@ struct isl12022 {
> struct regmap *regmap;
> };
>
> +static umode_t isl12022_hwmon_is_visible(const void *data,
> + enum hwmon_sensor_types type,
> + u32 attr, int channel)
> +{
> + if (type == hwmon_chip && attr == hwmon_chip_update_interval)
> + return 0444;
> +
> + if (type == hwmon_temp && attr == hwmon_temp_input)
> + return 0444;
> +
> + return 0;
> +}
> +
> +/*
> + * A user-initiated temperature conversion is not started by this function,
> + * so the temperature is updated once every ~60 seconds.
> + */
> +static int isl12022_hwmon_read_temp(struct device *dev, long *mC)
> +{
> + struct isl12022 *isl12022 = dev_get_drvdata(dev);
> + struct regmap *regmap = isl12022->regmap;
> + u8 temp_buf[2];
> + int temp, ret;
> +
> + ret = regmap_bulk_read(regmap, ISL12022_REG_TEMP_L,
> + temp_buf, sizeof(temp_buf));
> + if (ret)
> + return ret;
> + /*
> + * Temperature is represented as a 10-bit number, unit half-Kelvins.
> + */
> + temp = (temp_buf[1] << 8) | temp_buf[0];
> + temp *= 500;
> + temp -= 273000;
> +
> + *mC = temp;
> +
> + return 0;
> +}
> +
> +static int isl12022_hwmon_read(struct device *dev,
> + enum hwmon_sensor_types type,
> + u32 attr, int channel, long *val)
> +{
> + if (type == hwmon_chip && attr == hwmon_chip_update_interval) {
> + *val = 60000;
> + return 0;
> + }
It is not the purpose of the update_interval attribute to inform the
user what the update interval of this chip happens to be. The purpose
of the attribute is to inform the chip what update interval it should use.
From the documentation:
Some devices have a variable update rate or interval.
This attribute can be used to change it to the desired value.
The patch is not in the hwmon subsystem, to it is up to the maintainers
to decide if they want to accept the patch anyway. Please don't expect
a reviewed tag, though.
> +
> + if (type == hwmon_temp && attr == hwmon_temp_input) {
> + return isl12022_hwmon_read_temp(dev, val);
> + }
Nit: { } is unnecessary.
Guenter
> +
> + return -EOPNOTSUPP;
> +}
> +
> +static const struct hwmon_channel_info *isl12022_hwmon_info[] = {
> + HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL),
> + HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
> + NULL
> +};
> +
> +static const struct hwmon_ops isl12022_hwmon_ops = {
> + .is_visible = isl12022_hwmon_is_visible,
> + .read = isl12022_hwmon_read,
> +};
> +
> +static const struct hwmon_chip_info isl12022_hwmon_chip_info = {
> + .ops = &isl12022_hwmon_ops,
> + .info = isl12022_hwmon_info,
> +};
> +
> +static void isl12022_hwmon_register(struct device *dev)
> +{
> + struct isl12022 *isl12022;
> + struct device *hwmon;
> + int ret;
> +
> + if (!IS_REACHABLE(CONFIG_HWMON))
> + return;
> +
> + isl12022 = dev_get_drvdata(dev);
> +
> + ret = regmap_update_bits(isl12022->regmap, ISL12022_REG_BETA,
> + ISL12022_BETA_TSE, ISL12022_BETA_TSE);
> + if (ret) {
> + dev_warn(dev, "unable to enable temperature sensor\n");
> + return;
> + }
> +
> + hwmon = devm_hwmon_device_register_with_info(dev, "isl12022", isl12022,
> + &isl12022_hwmon_chip_info,
> + NULL);
> + if (IS_ERR(hwmon))
> + dev_warn(dev, "unable to register hwmon device: %pe\n", hwmon);
> +}
> +
> /*
> * In the routines that deal directly with the isl12022 hardware, we use
> * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
> @@ -160,6 +262,8 @@ static int isl12022_probe(struct i2c_client *client)
> return PTR_ERR(isl12022->regmap);
> }
>
> + isl12022_hwmon_register(&client->dev);
> +
> isl12022->rtc = devm_rtc_allocate_device(&client->dev);
> if (IS_ERR(isl12022->rtc))
> return PTR_ERR(isl12022->rtc);
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 9/9] rtc: isl12022: add support for temperature sensor
2022-09-21 14:13 ` Guenter Roeck
@ 2022-09-23 8:40 ` Rasmus Villemoes
2022-09-23 13:51 ` Guenter Roeck
0 siblings, 1 reply; 35+ messages in thread
From: Rasmus Villemoes @ 2022-09-23 8:40 UTC (permalink / raw)
To: Guenter Roeck, Alessandro Zummo, Alexandre Belloni, Jean Delvare
Cc: linux-rtc, linux-kernel, linux-hwmon
On 21/09/2022 16.13, Guenter Roeck wrote:
> On 9/21/22 04:46, Rasmus Villemoes wrote:
>> +static int isl12022_hwmon_read(struct device *dev,
>> + enum hwmon_sensor_types type,
>> + u32 attr, int channel, long *val)
>> +{
>> + if (type == hwmon_chip && attr == hwmon_chip_update_interval) {
>> + *val = 60000;
>> + return 0;
>> + }
>
> It is not the purpose of the update_interval attribute to inform the
> user what the update interval of this chip happens to be. The purpose
> of the attribute is to inform the chip what update interval it should use.
Well, I think it's a completely natural thing to expose a fixed and
known update_interval as a 0444 property, and it might even be useful to
userspace to know that there's no point reading the sensor any more
often than that. And I didn't come up with this by myself, there's
already at least a couple of instances of a 0444 update_interval.
I'll leave it to the RTC maintainers to decide, it's easy enough to remove.
Rasmus
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 9/9] rtc: isl12022: add support for temperature sensor
2022-09-23 8:40 ` Rasmus Villemoes
@ 2022-09-23 13:51 ` Guenter Roeck
0 siblings, 0 replies; 35+ messages in thread
From: Guenter Roeck @ 2022-09-23 13:51 UTC (permalink / raw)
To: Rasmus Villemoes, Alessandro Zummo, Alexandre Belloni, Jean Delvare
Cc: linux-rtc, linux-kernel, linux-hwmon
On 9/23/22 01:40, Rasmus Villemoes wrote:
> On 21/09/2022 16.13, Guenter Roeck wrote:
>> On 9/21/22 04:46, Rasmus Villemoes wrote:
>
>>> +static int isl12022_hwmon_read(struct device *dev,
>>> + enum hwmon_sensor_types type,
>>> + u32 attr, int channel, long *val)
>>> +{
>>> + if (type == hwmon_chip && attr == hwmon_chip_update_interval) {
>>> + *val = 60000;
>>> + return 0;
>>> + }
>>
>> It is not the purpose of the update_interval attribute to inform the
>> user what the update interval of this chip happens to be. The purpose
>> of the attribute is to inform the chip what update interval it should use.
>
> Well, I think it's a completely natural thing to expose a fixed and
> known update_interval as a 0444 property, and it might even be useful to
> userspace to know that there's no point reading the sensor any more
> often than that. And I didn't come up with this by myself, there's
> already at least a couple of instances of a 0444 update_interval.
>
That doesn't make it better. It is still an abuse of the ABI.
Guenter
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v3 9/9] rtc: isl12022: add support for temperature sensor
2022-09-21 11:46 ` [PATCH v2 9/9] rtc: isl12022: add support for temperature sensor Rasmus Villemoes
2022-09-21 14:13 ` Guenter Roeck
@ 2022-10-26 13:38 ` Rasmus Villemoes
2022-10-26 14:46 ` Guenter Roeck
2022-11-04 11:02 ` [PATCH v4] " Rasmus Villemoes
1 sibling, 2 replies; 35+ messages in thread
From: Rasmus Villemoes @ 2022-10-26 13:38 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni, Jean Delvare, Guenter Roeck
Cc: Rasmus Villemoes, linux-rtc, linux-kernel, linux-hwmon
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
v3: drop 0444 update_interval property.
v2 of patches 1-8 are already upstream (b1a1baa657c7 and parents).
drivers/rtc/rtc-isl12022.c | 94 ++++++++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index ca677c4265e6..a3b0de3393f5 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -17,6 +17,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
+#include <linux/hwmon.h>
/* ISL register offsets */
#define ISL12022_REG_SC 0x00
@@ -30,6 +31,9 @@
#define ISL12022_REG_SR 0x07
#define ISL12022_REG_INT 0x08
+#define ISL12022_REG_BETA 0x0d
+#define ISL12022_REG_TEMP_L 0x28
+
/* ISL register bits */
#define ISL12022_HR_MIL (1 << 7) /* military or 24 hour time */
@@ -38,6 +42,7 @@
#define ISL12022_INT_WRTC (1 << 6)
+#define ISL12022_BETA_TSE (1 << 7)
static struct i2c_driver isl12022_driver;
@@ -46,6 +51,93 @@ struct isl12022 {
struct regmap *regmap;
};
+static umode_t isl12022_hwmon_is_visible(const void *data,
+ enum hwmon_sensor_types type,
+ u32 attr, int channel)
+{
+ if (type == hwmon_temp && attr == hwmon_temp_input)
+ return 0444;
+
+ return 0;
+}
+
+/*
+ * A user-initiated temperature conversion is not started by this function,
+ * so the temperature is updated once every ~60 seconds.
+ */
+static int isl12022_hwmon_read_temp(struct device *dev, long *mC)
+{
+ struct isl12022 *isl12022 = dev_get_drvdata(dev);
+ struct regmap *regmap = isl12022->regmap;
+ u8 temp_buf[2];
+ int temp, ret;
+
+ ret = regmap_bulk_read(regmap, ISL12022_REG_TEMP_L,
+ temp_buf, sizeof(temp_buf));
+ if (ret)
+ return ret;
+ /*
+ * Temperature is represented as a 10-bit number, unit half-Kelvins.
+ */
+ temp = (temp_buf[1] << 8) | temp_buf[0];
+ temp *= 500;
+ temp -= 273000;
+
+ *mC = temp;
+
+ return 0;
+}
+
+static int isl12022_hwmon_read(struct device *dev,
+ enum hwmon_sensor_types type,
+ u32 attr, int channel, long *val)
+{
+ if (type == hwmon_temp && attr == hwmon_temp_input)
+ return isl12022_hwmon_read_temp(dev, val);
+
+ return -EOPNOTSUPP;
+}
+
+static const struct hwmon_channel_info *isl12022_hwmon_info[] = {
+ HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
+ NULL
+};
+
+static const struct hwmon_ops isl12022_hwmon_ops = {
+ .is_visible = isl12022_hwmon_is_visible,
+ .read = isl12022_hwmon_read,
+};
+
+static const struct hwmon_chip_info isl12022_hwmon_chip_info = {
+ .ops = &isl12022_hwmon_ops,
+ .info = isl12022_hwmon_info,
+};
+
+static void isl12022_hwmon_register(struct device *dev)
+{
+ struct isl12022 *isl12022;
+ struct device *hwmon;
+ int ret;
+
+ if (!IS_REACHABLE(CONFIG_HWMON))
+ return;
+
+ isl12022 = dev_get_drvdata(dev);
+
+ ret = regmap_update_bits(isl12022->regmap, ISL12022_REG_BETA,
+ ISL12022_BETA_TSE, ISL12022_BETA_TSE);
+ if (ret) {
+ dev_warn(dev, "unable to enable temperature sensor\n");
+ return;
+ }
+
+ hwmon = devm_hwmon_device_register_with_info(dev, "isl12022", isl12022,
+ &isl12022_hwmon_chip_info,
+ NULL);
+ if (IS_ERR(hwmon))
+ dev_warn(dev, "unable to register hwmon device: %pe\n", hwmon);
+}
+
/*
* In the routines that deal directly with the isl12022 hardware, we use
* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
@@ -160,6 +252,8 @@ static int isl12022_probe(struct i2c_client *client)
return PTR_ERR(isl12022->regmap);
}
+ isl12022_hwmon_register(&client->dev);
+
isl12022->rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(isl12022->rtc))
return PTR_ERR(isl12022->rtc);
--
2.37.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v3 9/9] rtc: isl12022: add support for temperature sensor
2022-10-26 13:38 ` [PATCH v3 " Rasmus Villemoes
@ 2022-10-26 14:46 ` Guenter Roeck
2022-11-04 11:02 ` [PATCH v4] " Rasmus Villemoes
1 sibling, 0 replies; 35+ messages in thread
From: Guenter Roeck @ 2022-10-26 14:46 UTC (permalink / raw)
To: Rasmus Villemoes, Alessandro Zummo, Alexandre Belloni, Jean Delvare
Cc: linux-rtc, linux-kernel, linux-hwmon
On 10/26/22 06:38, Rasmus Villemoes wrote:
> Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
There should be some description above. Other than that,
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
> ---
> v3: drop 0444 update_interval property.
>
> v2 of patches 1-8 are already upstream (b1a1baa657c7 and parents).
>
> drivers/rtc/rtc-isl12022.c | 94 ++++++++++++++++++++++++++++++++++++++
> 1 file changed, 94 insertions(+)
>
> diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
> index ca677c4265e6..a3b0de3393f5 100644
> --- a/drivers/rtc/rtc-isl12022.c
> +++ b/drivers/rtc/rtc-isl12022.c
> @@ -17,6 +17,7 @@
> #include <linux/of.h>
> #include <linux/of_device.h>
> #include <linux/regmap.h>
> +#include <linux/hwmon.h>
>
> /* ISL register offsets */
> #define ISL12022_REG_SC 0x00
> @@ -30,6 +31,9 @@
> #define ISL12022_REG_SR 0x07
> #define ISL12022_REG_INT 0x08
>
> +#define ISL12022_REG_BETA 0x0d
> +#define ISL12022_REG_TEMP_L 0x28
> +
> /* ISL register bits */
> #define ISL12022_HR_MIL (1 << 7) /* military or 24 hour time */
>
> @@ -38,6 +42,7 @@
>
> #define ISL12022_INT_WRTC (1 << 6)
>
> +#define ISL12022_BETA_TSE (1 << 7)
>
> static struct i2c_driver isl12022_driver;
>
> @@ -46,6 +51,93 @@ struct isl12022 {
> struct regmap *regmap;
> };
>
> +static umode_t isl12022_hwmon_is_visible(const void *data,
> + enum hwmon_sensor_types type,
> + u32 attr, int channel)
> +{
> + if (type == hwmon_temp && attr == hwmon_temp_input)
> + return 0444;
> +
> + return 0;
> +}
> +
> +/*
> + * A user-initiated temperature conversion is not started by this function,
> + * so the temperature is updated once every ~60 seconds.
> + */
> +static int isl12022_hwmon_read_temp(struct device *dev, long *mC)
> +{
> + struct isl12022 *isl12022 = dev_get_drvdata(dev);
> + struct regmap *regmap = isl12022->regmap;
> + u8 temp_buf[2];
> + int temp, ret;
> +
> + ret = regmap_bulk_read(regmap, ISL12022_REG_TEMP_L,
> + temp_buf, sizeof(temp_buf));
> + if (ret)
> + return ret;
> + /*
> + * Temperature is represented as a 10-bit number, unit half-Kelvins.
> + */
> + temp = (temp_buf[1] << 8) | temp_buf[0];
> + temp *= 500;
> + temp -= 273000;
> +
> + *mC = temp;
> +
> + return 0;
> +}
> +
> +static int isl12022_hwmon_read(struct device *dev,
> + enum hwmon_sensor_types type,
> + u32 attr, int channel, long *val)
> +{
> + if (type == hwmon_temp && attr == hwmon_temp_input)
> + return isl12022_hwmon_read_temp(dev, val);
> +
> + return -EOPNOTSUPP;
> +}
> +
> +static const struct hwmon_channel_info *isl12022_hwmon_info[] = {
> + HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
> + NULL
> +};
> +
> +static const struct hwmon_ops isl12022_hwmon_ops = {
> + .is_visible = isl12022_hwmon_is_visible,
> + .read = isl12022_hwmon_read,
> +};
> +
> +static const struct hwmon_chip_info isl12022_hwmon_chip_info = {
> + .ops = &isl12022_hwmon_ops,
> + .info = isl12022_hwmon_info,
> +};
> +
> +static void isl12022_hwmon_register(struct device *dev)
> +{
> + struct isl12022 *isl12022;
> + struct device *hwmon;
> + int ret;
> +
> + if (!IS_REACHABLE(CONFIG_HWMON))
> + return;
> +
> + isl12022 = dev_get_drvdata(dev);
> +
> + ret = regmap_update_bits(isl12022->regmap, ISL12022_REG_BETA,
> + ISL12022_BETA_TSE, ISL12022_BETA_TSE);
> + if (ret) {
> + dev_warn(dev, "unable to enable temperature sensor\n");
> + return;
> + }
> +
> + hwmon = devm_hwmon_device_register_with_info(dev, "isl12022", isl12022,
> + &isl12022_hwmon_chip_info,
> + NULL);
> + if (IS_ERR(hwmon))
> + dev_warn(dev, "unable to register hwmon device: %pe\n", hwmon);
> +}
> +
> /*
> * In the routines that deal directly with the isl12022 hardware, we use
> * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
> @@ -160,6 +252,8 @@ static int isl12022_probe(struct i2c_client *client)
> return PTR_ERR(isl12022->regmap);
> }
>
> + isl12022_hwmon_register(&client->dev);
> +
> isl12022->rtc = devm_rtc_allocate_device(&client->dev);
> if (IS_ERR(isl12022->rtc))
> return PTR_ERR(isl12022->rtc);
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v4] rtc: isl12022: add support for temperature sensor
2022-10-26 13:38 ` [PATCH v3 " Rasmus Villemoes
2022-10-26 14:46 ` Guenter Roeck
@ 2022-11-04 11:02 ` Rasmus Villemoes
2022-11-14 21:41 ` Alexandre Belloni
1 sibling, 1 reply; 35+ messages in thread
From: Rasmus Villemoes @ 2022-11-04 11:02 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni, Jean Delvare, Guenter Roeck
Cc: Rasmus Villemoes, linux-rtc, linux-kernel, linux-hwmon
The isl12022 has built-in temperature compensation effective over the
range -40C to +85C. It exposes the average of the last two temperature
measurements as a 10-bit value in half-Kelvins. Make this available
via the hwmon framework.
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
v4: add a real commit log, include Guenter's R-b.
v3 at https://lore.kernel.org/lkml/20221026133847.1193422-1-linux@rasmusvillemoes.dk/
drivers/rtc/rtc-isl12022.c | 94 ++++++++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index ca677c4265e6..a3b0de3393f5 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -17,6 +17,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
+#include <linux/hwmon.h>
/* ISL register offsets */
#define ISL12022_REG_SC 0x00
@@ -30,6 +31,9 @@
#define ISL12022_REG_SR 0x07
#define ISL12022_REG_INT 0x08
+#define ISL12022_REG_BETA 0x0d
+#define ISL12022_REG_TEMP_L 0x28
+
/* ISL register bits */
#define ISL12022_HR_MIL (1 << 7) /* military or 24 hour time */
@@ -38,6 +42,7 @@
#define ISL12022_INT_WRTC (1 << 6)
+#define ISL12022_BETA_TSE (1 << 7)
static struct i2c_driver isl12022_driver;
@@ -46,6 +51,93 @@ struct isl12022 {
struct regmap *regmap;
};
+static umode_t isl12022_hwmon_is_visible(const void *data,
+ enum hwmon_sensor_types type,
+ u32 attr, int channel)
+{
+ if (type == hwmon_temp && attr == hwmon_temp_input)
+ return 0444;
+
+ return 0;
+}
+
+/*
+ * A user-initiated temperature conversion is not started by this function,
+ * so the temperature is updated once every ~60 seconds.
+ */
+static int isl12022_hwmon_read_temp(struct device *dev, long *mC)
+{
+ struct isl12022 *isl12022 = dev_get_drvdata(dev);
+ struct regmap *regmap = isl12022->regmap;
+ u8 temp_buf[2];
+ int temp, ret;
+
+ ret = regmap_bulk_read(regmap, ISL12022_REG_TEMP_L,
+ temp_buf, sizeof(temp_buf));
+ if (ret)
+ return ret;
+ /*
+ * Temperature is represented as a 10-bit number, unit half-Kelvins.
+ */
+ temp = (temp_buf[1] << 8) | temp_buf[0];
+ temp *= 500;
+ temp -= 273000;
+
+ *mC = temp;
+
+ return 0;
+}
+
+static int isl12022_hwmon_read(struct device *dev,
+ enum hwmon_sensor_types type,
+ u32 attr, int channel, long *val)
+{
+ if (type == hwmon_temp && attr == hwmon_temp_input)
+ return isl12022_hwmon_read_temp(dev, val);
+
+ return -EOPNOTSUPP;
+}
+
+static const struct hwmon_channel_info *isl12022_hwmon_info[] = {
+ HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
+ NULL
+};
+
+static const struct hwmon_ops isl12022_hwmon_ops = {
+ .is_visible = isl12022_hwmon_is_visible,
+ .read = isl12022_hwmon_read,
+};
+
+static const struct hwmon_chip_info isl12022_hwmon_chip_info = {
+ .ops = &isl12022_hwmon_ops,
+ .info = isl12022_hwmon_info,
+};
+
+static void isl12022_hwmon_register(struct device *dev)
+{
+ struct isl12022 *isl12022;
+ struct device *hwmon;
+ int ret;
+
+ if (!IS_REACHABLE(CONFIG_HWMON))
+ return;
+
+ isl12022 = dev_get_drvdata(dev);
+
+ ret = regmap_update_bits(isl12022->regmap, ISL12022_REG_BETA,
+ ISL12022_BETA_TSE, ISL12022_BETA_TSE);
+ if (ret) {
+ dev_warn(dev, "unable to enable temperature sensor\n");
+ return;
+ }
+
+ hwmon = devm_hwmon_device_register_with_info(dev, "isl12022", isl12022,
+ &isl12022_hwmon_chip_info,
+ NULL);
+ if (IS_ERR(hwmon))
+ dev_warn(dev, "unable to register hwmon device: %pe\n", hwmon);
+}
+
/*
* In the routines that deal directly with the isl12022 hardware, we use
* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
@@ -160,6 +252,8 @@ static int isl12022_probe(struct i2c_client *client)
return PTR_ERR(isl12022->regmap);
}
+ isl12022_hwmon_register(&client->dev);
+
isl12022->rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(isl12022->rtc))
return PTR_ERR(isl12022->rtc);
--
2.37.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v4] rtc: isl12022: add support for temperature sensor
2022-11-04 11:02 ` [PATCH v4] " Rasmus Villemoes
@ 2022-11-14 21:41 ` Alexandre Belloni
0 siblings, 0 replies; 35+ messages in thread
From: Alexandre Belloni @ 2022-11-14 21:41 UTC (permalink / raw)
To: Alessandro Zummo, Guenter Roeck, Jean Delvare, Rasmus Villemoes
Cc: linux-rtc, linux-hwmon, linux-kernel
On Fri, 4 Nov 2022 12:02:25 +0100, Rasmus Villemoes wrote:
> The isl12022 has built-in temperature compensation effective over the
> range -40C to +85C. It exposes the average of the last two temperature
> measurements as a 10-bit value in half-Kelvins. Make this available
> via the hwmon framework.
>
>
Applied, thanks!
[1/1] rtc: isl12022: add support for temperature sensor
commit: 1087656c079ddd3bb240a3c1f108c37b9b8f1457
Best regards,
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 0/9] rtc: isl12022: cleanups and hwmon support
2022-09-21 11:46 ` [PATCH v2 0/9] " Rasmus Villemoes
` (8 preceding siblings ...)
2022-09-21 11:46 ` [PATCH v2 9/9] rtc: isl12022: add support for temperature sensor Rasmus Villemoes
@ 2022-10-07 13:51 ` Rasmus Villemoes
2022-10-13 21:31 ` Alexandre Belloni
10 siblings, 0 replies; 35+ messages in thread
From: Rasmus Villemoes @ 2022-10-07 13:51 UTC (permalink / raw)
To: Alessandro Zummo, Alexandre Belloni, Jean Delvare, Guenter Roeck,
linux-rtc, linux-kernel, linux-hwmon
On 21/09/2022 13.46, Rasmus Villemoes wrote:
> This series does a few cleanups of the isl12022 driver,
>
> - removes use of deprecated function
> - removes some redundant code
> - switches to regmap API instead of private helpers
>
> It also provides range_min, range_max values and finally hooks up the
> temperatur sensor to hwmon.
>
Ping. Alexandre, anything I need to do to move this forward?
Thanks,
Rasmus
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH v2 0/9] rtc: isl12022: cleanups and hwmon support
2022-09-21 11:46 ` [PATCH v2 0/9] " Rasmus Villemoes
` (9 preceding siblings ...)
2022-10-07 13:51 ` [PATCH v2 0/9] rtc: isl12022: cleanups and hwmon support Rasmus Villemoes
@ 2022-10-13 21:31 ` Alexandre Belloni
10 siblings, 0 replies; 35+ messages in thread
From: Alexandre Belloni @ 2022-10-13 21:31 UTC (permalink / raw)
To: Alessandro Zummo, Rasmus Villemoes, linux-rtc, Jean Delvare,
Guenter Roeck, linux-hwmon, linux-kernel
On Wed, 21 Sep 2022 13:46:15 +0200, Rasmus Villemoes wrote:
> This series does a few cleanups of the isl12022 driver,
>
> - removes use of deprecated function
> - removes some redundant code
> - switches to regmap API instead of private helpers
>
> It also provides range_min, range_max values and finally hooks up the
> temperatur sensor to hwmon.
>
> [...]
Applied, thanks!
[1/9] rtc: isl12022: stop using deprecated devm_rtc_device_register()
commit: a35a2ad2b88a66732ac442ad5f86dc49af51673f
[2/9] rtc: isl12022: specify range_min and range_max
commit: ca03b7a2c0b098321365f69538823d1bcc860552
[3/9] rtc: isl12022: drop a dev_info()
commit: 43a96b9cf67770d4bb46267e1554d3d8b4cf78ac
[4/9] rtc: isl12022: simplify some expressions
commit: ca35887186b7c53f26c42aee1285ba213adb4365
[5/9] rtc: isl12022: use %ptR
commit: 7093b8a471f48d49891da2108f44fd64742408cb
[6/9] rtc: isl12022: use dev_set_drvdata() instead of i2c_set_clientdata()
commit: 31b108acc50cddf3d16472ead45c4cd0d1337289
[7/9] rtc: isl12022: drop redundant write to HR register
commit: 0a2abbfd8586d396a8581ebf9b96fd5746f08b14
[8/9] rtc: isl12022: switch to using regmap API
commit: b1a1baa657c738e8bb0107ce304f5e78b9847f37
Best regards,
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 35+ messages in thread