* [PATCH v4 1/7] dt-bindings: rtc: add new type for epson,rx8901
2025-05-21 9:05 [PATCH v4 0/7] rtc-rv8803: Implement timestamp trigger over event pins Markus Burri
@ 2025-05-21 9:05 ` Markus Burri
2025-05-27 6:43 ` Krzysztof Kozlowski
2025-05-21 9:05 ` [PATCH v4 2/7] rtc-rv8803: add new type for rv8901 Markus Burri
` (5 subsequent siblings)
6 siblings, 1 reply; 10+ messages in thread
From: Markus Burri @ 2025-05-21 9:05 UTC (permalink / raw)
To: linux-kernel
Cc: Markus Burri, Alexandre Belloni, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manuel Traut, Marek Vasut, linux-rtc, devicetree,
Markus Burri, Krzysztof Kozlowski
Document compatibles for:
- RX8803: already used by the driver
- RX8901: new device supporting also tamper detection and pinctrl
Signed-off-by: Markus Burri <markus.burri@mt.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Reviewed-by: Manuel Traut <manuel.traut@mt.com>
---
Documentation/devicetree/bindings/rtc/epson,rx8900.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/rtc/epson,rx8900.yaml b/Documentation/devicetree/bindings/rtc/epson,rx8900.yaml
index b770149c5fd6..03af81754482 100644
--- a/Documentation/devicetree/bindings/rtc/epson,rx8900.yaml
+++ b/Documentation/devicetree/bindings/rtc/epson,rx8900.yaml
@@ -15,8 +15,10 @@ allOf:
properties:
compatible:
enum:
+ - epson,rx8803
- epson,rx8804
- epson,rx8900
+ - epson,rx8901
- microcrystal,rv8803
reg:
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v4 1/7] dt-bindings: rtc: add new type for epson,rx8901
2025-05-21 9:05 ` [PATCH v4 1/7] dt-bindings: rtc: add new type for epson,rx8901 Markus Burri
@ 2025-05-27 6:43 ` Krzysztof Kozlowski
0 siblings, 0 replies; 10+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-27 6:43 UTC (permalink / raw)
To: Markus Burri
Cc: linux-kernel, Alexandre Belloni, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manuel Traut, Marek Vasut, linux-rtc, devicetree,
Markus Burri
On Wed, May 21, 2025 at 11:05:46AM GMT, Markus Burri wrote:
> Document compatibles for:
> - RX8803: already used by the driver
> - RX8901: new device supporting also tamper detection and pinctrl
>
> Signed-off-by: Markus Burri <markus.burri@mt.com>
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> Reviewed-by: Manuel Traut <manuel.traut@mt.com>
> ---
> Documentation/devicetree/bindings/rtc/epson,rx8900.yaml | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/rtc/epson,rx8900.yaml b/Documentation/devicetree/bindings/rtc/epson,rx8900.yaml
> index b770149c5fd6..03af81754482 100644
> --- a/Documentation/devicetree/bindings/rtc/epson,rx8900.yaml
> +++ b/Documentation/devicetree/bindings/rtc/epson,rx8900.yaml
> @@ -15,8 +15,10 @@ allOf:
> properties:
> compatible:
> enum:
> + - epson,rx8803
> - epson,rx8804
> - epson,rx8900
> + - epson,rx8901
This has to be squashed with your other patch. Adding new variant with
new features is one commit.
Drop the tag and reviews then.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 2/7] rtc-rv8803: add new type for rv8901
2025-05-21 9:05 [PATCH v4 0/7] rtc-rv8803: Implement timestamp trigger over event pins Markus Burri
2025-05-21 9:05 ` [PATCH v4 1/7] dt-bindings: rtc: add new type for epson,rx8901 Markus Burri
@ 2025-05-21 9:05 ` Markus Burri
2025-05-21 9:05 ` [PATCH v4 3/7] rtc-rv8803: add tamper function to sysfs " Markus Burri
` (4 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Markus Burri @ 2025-05-21 9:05 UTC (permalink / raw)
To: linux-kernel
Cc: Markus Burri, Alexandre Belloni, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manuel Traut, Marek Vasut, linux-rtc, devicetree,
Markus Burri
The rtc-rv8901 has additional functionality (tamper detection).
To support this additional functionality the type must be extended.
Signed-off-by: Markus Burri <markus.burri@mt.com>
Reviewed-by: Manuel Traut <manuel.traut@mt.com>
---
drivers/rtc/rtc-rv8803.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c
index 1327251e527c..50fbae931cb2 100644
--- a/drivers/rtc/rtc-rv8803.c
+++ b/drivers/rtc/rtc-rv8803.c
@@ -62,7 +62,8 @@ enum rv8803_type {
rv_8803,
rx_8803,
rx_8804,
- rx_8900
+ rx_8900,
+ rx_8901,
};
struct rv8803_data {
@@ -173,7 +174,8 @@ static int rv8803_regs_reset(struct rv8803_data *rv8803, bool full)
* The RV-8803 resets all registers to POR defaults after voltage-loss,
* the Epson RTCs don't, so we manually reset the remainder here.
*/
- if (full || rv8803->type == rx_8803 || rv8803->type == rx_8900) {
+ if (full || rv8803->type == rx_8803 || rv8803->type == rx_8900 ||
+ rv8803->type == rx_8901) {
int ret = rv8803_regs_init(rv8803);
if (ret)
return ret;
@@ -635,6 +637,7 @@ static const struct i2c_device_id rv8803_id[] = {
{ "rv8804", rx_8804 },
{ "rx8803", rx_8803 },
{ "rx8900", rx_8900 },
+ { "rx8901", rx_8901 },
{ }
};
MODULE_DEVICE_TABLE(i2c, rv8803_id);
@@ -760,6 +763,10 @@ static const __maybe_unused struct of_device_id rv8803_of_match[] = {
.compatible = "epson,rx8900",
.data = (void *)rx_8900
},
+ {
+ .compatible = "epson,rx8901",
+ .data = (void *)rx_8901
+ },
{ }
};
MODULE_DEVICE_TABLE(of, rv8803_of_match);
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 3/7] rtc-rv8803: add tamper function to sysfs for rv8901
2025-05-21 9:05 [PATCH v4 0/7] rtc-rv8803: Implement timestamp trigger over event pins Markus Burri
2025-05-21 9:05 ` [PATCH v4 1/7] dt-bindings: rtc: add new type for epson,rx8901 Markus Burri
2025-05-21 9:05 ` [PATCH v4 2/7] rtc-rv8803: add new type for rv8901 Markus Burri
@ 2025-05-21 9:05 ` Markus Burri
2025-05-21 9:05 ` [PATCH v4 4/7] rtc-rv8803: extend sysfs to trigger internal ts-event Markus Burri
` (3 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Markus Burri @ 2025-05-21 9:05 UTC (permalink / raw)
To: linux-kernel
Cc: Markus Burri, Alexandre Belloni, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manuel Traut, Marek Vasut, linux-rtc, devicetree,
Markus Burri
Add sysfs interface to enable the EVINx pins and read the time-stamp
events from EVINX.
Signed-off-by: Markus Burri <markus.burri@mt.com>
Reviewed-by: Manuel Traut <manuel.traut@mt.com>
---
.../ABI/testing/sysfs-class-rtc-tamper | 21 +
drivers/rtc/rtc-rv8803.c | 391 ++++++++++++++++++
2 files changed, 412 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-class-rtc-tamper
diff --git a/Documentation/ABI/testing/sysfs-class-rtc-tamper b/Documentation/ABI/testing/sysfs-class-rtc-tamper
new file mode 100644
index 000000000000..3e61ed628c17
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-rtc-tamper
@@ -0,0 +1,21 @@
+What: /sys/class/rtc/rtcX/tamper/enable
+Date: May 2025
+KernelVersion: 6.15
+Contact: Markus Burri <markus.burri@mt.com>
+Description: (WO) Attribute to enable and disable the rtc tamper function.
+ Write a '1' to enable tamper detection or a '0' to disable.
+
+What: /sys/class/rtc/rtcX/tamper/read
+Date: May 2025
+KernelVersion: 6.15
+Contact: Markus Burri <markus.burri@mt.com>
+Description: (RO) Attribute to read the stored timestamps form buffer FIFO.
+ The timestamps are returned one by one
+ Format is 'seconds.milliseconds' since the epoch followed by the trigger events.
+ The value of the event is the current pin value.
+
+ Example values:
+ - "1234.567 EVIN1=1" for a trigger from EVIN1 changed from low to high
+ - "1234.567 EVIN1=0 EVIN2=1 for a simultaneous trigger of EVIN1 changed to low and
+ EVIN2 changed to high.
+
diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c
index 50fbae931cb2..e367d37e6a8f 100644
--- a/drivers/rtc/rtc-rv8803.c
+++ b/drivers/rtc/rtc-rv8803.c
@@ -10,6 +10,7 @@
#include <linux/bcd.h>
#include <linux/bitops.h>
#include <linux/bitfield.h>
+#include <linux/delay.h>
#include <linux/log2.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
@@ -41,6 +42,7 @@
#define RV8803_FLAG_V1F BIT(0)
#define RV8803_FLAG_V2F BIT(1)
+#define RV8901_FLAG_EVF BIT(2)
#define RV8803_FLAG_AF BIT(3)
#define RV8803_FLAG_TF BIT(4)
#define RV8803_FLAG_UF BIT(5)
@@ -58,6 +60,35 @@
#define RX8900_FLAG_SWOFF BIT(2)
#define RX8900_FLAG_VDETOFF BIT(3)
+#define RX8901_EVIN_EN 0x20
+#define RX8901_EVIN1_CFG 0x21
+#define RX8901_EVIN1_FLT 0x22
+#define RX8901_EVIN2_CFG 0x23
+#define RX8901_EVIN2_FLT 0x24
+#define RX8901_EVIN3_CFG 0x25
+#define RX8901_EVIN3_FLT 0x26
+
+#define RX8901_EVENTx_CFG_POL GENMASK(1, 0)
+#define RX8901_EVENTx_CFG_PUPD GENMASK(4, 2)
+
+#define RX8901_BUF1_CFG1 0x27
+
+#define RX8901_BUF1_STAT 0x28
+#define RX8901_BUFx_STAT_PTR GENMASK(5, 0)
+#define RX8901_WRCMD_CFG 0x41
+#define RX8901_WRCMD_TRG 0x42
+
+#define RX8901_EVNT_INTE 0x43
+
+#define RX8901_BUF_INTF 0x46
+#define RX8901_BUF_INTF_BUF1F BIT(5)
+
+#define RX8901_EVNT_INTF 0x47
+
+#define NO_OF_EVIN 3
+
+#define EVIN_FILTER_MAX 40
+
enum rv8803_type {
rv_8803,
rx_8803,
@@ -66,6 +97,50 @@ enum rv8803_type {
rx_8901,
};
+enum evin_pull_resistor {
+ no = 0b000,
+ pull_up_500k = 0b001,
+ pull_up_1M = 0b010,
+ pull_up_10M = 0b011,
+ pull_down_500k = 0b100,
+};
+
+enum evin_trigger {
+ falling_edge = 0b00,
+ rising_edge = 0b01,
+ both_edges = 0b10,
+};
+
+struct cfg_val_txt {
+ char *txt;
+ u8 val;
+ bool hide;
+};
+
+static const struct cfg_val_txt trg_status_txt[] = {
+ { "EVIN1", BIT(5) },
+ { "EVIN2", BIT(6) },
+ { "EVIN3", BIT(7) },
+ { "CMD", BIT(4) },
+ { "VBATL", BIT(3) },
+ { "VTMPL", BIT(2) },
+ { "VDDL", BIT(1) },
+ { "OSCSTP", BIT(0) },
+ { NULL }
+};
+
+static const u8 evin_cfg_regs[] = {
+ RX8901_EVIN1_CFG,
+ RX8901_EVIN2_CFG,
+ RX8901_EVIN3_CFG
+};
+
+static const u8 evin_flt_regs[] = {
+ RX8901_EVIN1_FLT,
+ RX8901_EVIN2_FLT,
+ RX8901_EVIN3_FLT
+};
+
struct rv8803_data {
struct i2c_client *client;
struct rtc_device *rtc;
@@ -558,6 +633,316 @@ static int rv8803_nvram_read(void *priv, unsigned int offset,
return 0;
}
+static int rv8803_ts_event_write_evin(int evin, struct rv8803_data *rv8803,
+ enum evin_pull_resistor pullup_down,
+ enum evin_trigger trigger, int filter)
+{
+ int ret;
+ u8 reg_mask;
+ struct i2c_client *client = rv8803->client;
+
+ /* according to data-sheet, "1" is not valid for filter */
+ if (evin >= NO_OF_EVIN || filter == 1 || filter > EVIN_FILTER_MAX)
+ return -EINVAL;
+
+ guard(mutex)(&rv8803->flags_lock);
+
+ /* set EVENTx pull-up edge trigger */
+ ret = rv8803_read_reg(client, evin_cfg_regs[evin]);
+ if (ret < 0)
+ return ret;
+ reg_mask = ret;
+ reg_mask &= ~(RX8901_EVENTx_CFG_PUPD | RX8901_EVENTx_CFG_POL);
+ reg_mask |= FIELD_PREP(RX8901_EVENTx_CFG_PUPD, pullup_down);
+ reg_mask |= FIELD_PREP(RX8901_EVENTx_CFG_POL, trigger);
+ ret = rv8803_write_reg(client, evin_cfg_regs[evin], reg_mask);
+ if (ret < 0)
+ return ret;
+
+ /* set EVENTx noise filter */
+ if (filter != -1) {
+ ret = rv8803_write_reg(client, evin_flt_regs[evin], filter);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int rv8803_ts_enable_events(struct rv8803_data *rv8803, u8 event_enable_mask)
+{
+ int ret;
+ u8 reg_mask;
+ struct i2c_client *client = rv8803->client;
+
+ guard(mutex)(&rv8803->flags_lock);
+
+ /* event detection interrupt */
+ ret = rv8803_read_reg(client, RV8803_CTRL);
+ if (ret < 0)
+ return ret;
+
+ reg_mask = ret & ~RV8803_CTRL_EIE;
+ if (event_enable_mask)
+ reg_mask |= RV8803_CTRL_EIE;
+
+ ret = rv8803_write_reg(client, RV8803_CTRL, reg_mask);
+ if (ret)
+ return ret;
+
+ /* events for configuration */
+ ret = rv8803_write_reg(client, RX8901_EVIN_EN, event_enable_mask);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int rv8803_ts_enable(struct rv8803_data *rv8803, u8 enable)
+{
+ int ret;
+ int i;
+ unsigned long tmo;
+ u8 reg;
+ u8 reg_mask;
+ struct i2c_client *client = rv8803->client;
+
+ /* EVINxCPEN | EVINxEN */;
+ const u8 reg_mask_evin_en = GENMASK(5, 3) | GENMASK(2, 0);
+
+ /* check if event detection status match requested mode */
+ ret = rv8803_read_reg(client, RX8901_EVIN_EN);
+ if (ret < 0)
+ return ret;
+
+ /* requested mode match current state -> nothing to do */
+ if (ret == (enable ? reg_mask_evin_en : 0))
+ return 0;
+
+ dev_info(&client->dev, "%s time-stamp event detection\n",
+ (enable) ? "configure" : "disable");
+
+ /*
+ * 1. disable event detection interrupt
+ * 2. disable events during configuration
+ */
+ ret = rv8803_ts_enable_events(rv8803, 0);
+ if (ret < 0)
+ return ret;
+
+ /* for disable no configuration is needed */
+ if (!enable)
+ return 0;
+
+ /* 3. set EVENTx pull-up edge trigger and noise filter */
+ for (i = 0; i < NO_OF_EVIN; ++i) {
+ ret = rv8803_ts_event_write_evin(i, rv8803, pull_up_1M, falling_edge, 0);
+ if (ret < 0)
+ return ret;
+ }
+
+ scoped_guard(mutex, &rv8803->flags_lock) {
+ /* 4. enable EVENTx interrupt */
+ ret = rv8803_read_reg(client, RX8901_EVNT_INTE);
+ if (ret < 0)
+ return ret;
+ reg_mask = BIT(5) | BIT(6) | BIT(7); /* EVINxIEN 1-3 */
+ reg = (ret & ~reg_mask) | reg_mask;
+ ret = rv8803_write_reg(client, RX8901_EVNT_INTE, reg);
+ if (ret < 0)
+ return ret;
+ }
+
+ /*
+ * 5. set BUF1 inhibit and interrupt every 1 event
+ * NOTE: BUF2-3 are not used in FIFO-mode
+ */
+ ret = rv8803_write_reg(client, RX8901_BUF1_CFG1, 0x01);
+ if (ret < 0)
+ return ret;
+
+ /* 6. clean and init for BUFx and event counter 1-3 and trigger cmd */
+ reg = BIT(7) | GENMASK(6, 4);
+ reg |= BIT(0); /* CMDTRGEN */
+ ret = rv8803_write_reg(client, RX8901_WRCMD_CFG, reg);
+ if (ret < 0)
+ return ret;
+ ret = rv8803_write_reg(client, RX8901_WRCMD_TRG, 0xFF);
+ if (ret < 0)
+ return ret;
+ tmo = jiffies + msecs_to_jiffies(100); /* timeout 100ms */
+ do {
+ usleep_range(10, 2000);
+ ret = rv8803_read_reg(client, RX8901_WRCMD_TRG);
+ if (ret < 0)
+ return ret;
+ if (time_after(jiffies, tmo))
+ return -EBUSY;
+ } while (ret);
+
+ /*
+ * 7. enable event detection interrupt
+ * 8. / 10. enable events for configuration in FIFO mode
+ */
+ ret = rv8803_ts_enable_events(rv8803, reg_mask_evin_en);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static ssize_t enable_store(struct device *dev, struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct rv8803_data *rv8803 = dev_get_drvdata(dev->parent);
+
+ bool enable = (strstr(buf, "1") == buf) ? true : false;
+
+ int ret = rv8803_ts_enable(rv8803, enable);
+
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static ssize_t read_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int ret;
+ int ev_idx;
+ int num_events;
+ unsigned long long time_s;
+ int time_ms;
+ int offset = 0;
+ u8 reg_mask;
+ u8 data[10];
+ struct rtc_time tm;
+
+ struct i2c_client *client = to_i2c_client(dev->parent);
+ struct rv8803_data *rv8803 = dev_get_drvdata(dev->parent);
+
+ guard(mutex)(&rv8803->flags_lock);
+
+ /*
+ * For detailed description see datasheet:
+ * - Reading Time Stamp Data (FIFO mode)
+ */
+
+ /* CHECK for EVF bit */
+ ret = rv8803_read_reg(client, RV8803_FLAG);
+ if (ret < 0)
+ return ret;
+
+ if (ret & RV8901_FLAG_EVF) {
+ /* clear EVF */
+ reg_mask = RV8901_FLAG_EVF;
+ ret = rv8803_write_reg(client, RV8803_FLAG, ~reg_mask);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* check interrupt source is from event 1-3 */
+ ret = rv8803_read_reg(client, RX8901_EVNT_INTF);
+ if (ret < 0)
+ return ret;
+
+ /* CHECK for EVINx bit */
+ if (ret & GENMASK(7, 5)) {
+ /* clear EVINxF 1-3 */
+ reg_mask = GENMASK(7, 5);
+ ret = rv8803_write_reg(client, RX8901_EVNT_INTF, ~reg_mask);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* check interrupt source is from event 1-3 */
+ ret = rv8803_read_reg(client, RX8901_BUF_INTF);
+ if (ret < 0)
+ return ret;
+ if (ret & RX8901_BUF_INTF_BUF1F) {
+ /* disable interrupts */
+ ret = rv8803_read_reg(client, RV8803_CTRL);
+ if (ret < 0)
+ return ret;
+ ret = rv8803_write_reg(client, RV8803_CTRL, ret & ~RV8803_CTRL_EIE);
+ if (ret < 0)
+ return ret;
+
+ /* clear interrupt flag */
+ ret = rv8803_read_reg(client, RX8901_BUF_INTF);
+ if (ret < 0)
+ return ret;
+ ret = rv8803_write_reg(client, RX8901_BUF_INTF, ret & ~RX8901_BUF_INTF_BUF1F);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* test if there are events available */
+ ret = rv8803_read_reg(client, RX8901_BUF1_STAT);
+ if (ret < 0)
+ return ret;
+ num_events = ret & RX8901_BUFx_STAT_PTR;
+
+ if (num_events) {
+ ret = rv8803_read_regs(client, 0x60, ARRAY_SIZE(data), data);
+ if (ret < 0)
+ return ret;
+
+ tm.tm_sec = bcd2bin(data[2]);
+ tm.tm_min = bcd2bin(data[3]);
+ tm.tm_hour = bcd2bin(data[4]);
+ tm.tm_mday = bcd2bin(data[5]);
+ tm.tm_mon = bcd2bin(data[6]) - 1;
+ tm.tm_year = bcd2bin(data[7]) + 100;
+ tm.tm_wday = -1;
+ tm.tm_yday = -1;
+ tm.tm_isdst = -1;
+
+ ret = rtc_valid_tm(&tm);
+ if (ret)
+ return ret;
+
+ /* calculate 1/1024 -> ms */
+ time_ms = (1000 * ((data[1] << 2) | (data[0] >> 6))) / 1024;
+ time_s = rtc_tm_to_time64(&tm);
+
+ offset += snprintf(buf + offset, PAGE_SIZE - offset, "%llu.%03d", time_s, time_ms);
+ for (ev_idx = 0; trg_status_txt[ev_idx].txt; ++ev_idx)
+ if (data[9] & trg_status_txt[ev_idx].val)
+ offset += snprintf(buf + offset, PAGE_SIZE - offset, " %s=%d",
+ trg_status_txt[ev_idx].txt,
+ !!(trg_status_txt[ev_idx].val & data[8]));
+ offset += snprintf(buf + offset, PAGE_SIZE - offset, "\n");
+
+ /* according to the datasheet we have to wait for 1ms */
+ usleep_range(1000, 2000);
+ }
+
+ /* re-enable interrupts */
+ ret = rv8803_read_reg(client, RV8803_CTRL);
+ if (ret < 0)
+ return ret;
+ ret = rv8803_write_reg(client, RV8803_CTRL, ret | RV8803_CTRL_EIE);
+ if (ret < 0)
+ return ret;
+
+ return offset;
+}
+
+static DEVICE_ATTR_WO(enable);
+static DEVICE_ATTR_ADMIN_RO(read);
+
+static struct attribute *rv8803_rtc_event_attrs[] = {
+ &dev_attr_enable.attr,
+ &dev_attr_read.attr,
+ NULL
+};
+
+static const struct attribute_group rv8803_rtc_sysfs_event_files = {
+ .name = "tamper",
+ .attrs = rv8803_rtc_event_attrs,
+};
+
static const struct rtc_class_ops rv8803_rtc_ops = {
.read_time = rv8803_get_time,
.set_time = rv8803_set_time,
@@ -732,6 +1117,12 @@ static int rv8803_probe(struct i2c_client *client)
if (err)
return err;
+ if (rv8803->type == rx_8901) {
+ err = rtc_add_group(rv8803->rtc, &rv8803_rtc_sysfs_event_files);
+ if (err)
+ return err;
+ }
+
rv8803->rtc->ops = &rv8803_rtc_ops;
rv8803->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
rv8803->rtc->range_max = RTC_TIMESTAMP_END_2099;
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 4/7] rtc-rv8803: extend sysfs to trigger internal ts-event
2025-05-21 9:05 [PATCH v4 0/7] rtc-rv8803: Implement timestamp trigger over event pins Markus Burri
` (2 preceding siblings ...)
2025-05-21 9:05 ` [PATCH v4 3/7] rtc-rv8803: add tamper function to sysfs " Markus Burri
@ 2025-05-21 9:05 ` Markus Burri
2025-05-21 9:05 ` [PATCH v4 5/7] rtc-rv8803: extend sysfs to read status Markus Burri
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Markus Burri @ 2025-05-21 9:05 UTC (permalink / raw)
To: linux-kernel
Cc: Markus Burri, Alexandre Belloni, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manuel Traut, Marek Vasut, linux-rtc, devicetree,
Markus Burri
Extend sysfs to trigger an internal time-stamp event.
The trigger function can be used from an application to trigger an
internal time-stamp event.
Signed-off-by: Markus Burri <markus.burri@mt.com>
Reviewed-by: Manuel Traut <manuel.traut@mt.com>
---
.../ABI/testing/sysfs-class-rtc-tamper | 7 ++++
drivers/rtc/rtc-rv8803.c | 33 +++++++++++++++++++
2 files changed, 40 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-class-rtc-tamper b/Documentation/ABI/testing/sysfs-class-rtc-tamper
index 3e61ed628c17..83b2fae1fc6e 100644
--- a/Documentation/ABI/testing/sysfs-class-rtc-tamper
+++ b/Documentation/ABI/testing/sysfs-class-rtc-tamper
@@ -18,4 +18,11 @@ Description: (RO) Attribute to read the stored timestamps form buffer FIFO.
- "1234.567 EVIN1=1" for a trigger from EVIN1 changed from low to high
- "1234.567 EVIN1=0 EVIN2=1 for a simultaneous trigger of EVIN1 changed to low and
EVIN2 changed to high.
+ - "1234.567 CMD=0" for a internal trigger
+What: /sys/class/rtc/rtcX/tamper/trigger
+Date: May 2025
+KernelVersion: 6.15
+Contact: Markus Burri <markus.burri@mt.com>
+Description: (WO) Attribute to trigger an internal timestamp event
+ Write a '1' to trigger an internal event and store a timestamp.
diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c
index e367d37e6a8f..d0aac250774a 100644
--- a/drivers/rtc/rtc-rv8803.c
+++ b/drivers/rtc/rtc-rv8803.c
@@ -929,12 +929,45 @@ static ssize_t read_show(struct device *dev, struct device_attribute *attr, char
return offset;
}
+static ssize_t trigger_store(struct device *dev, struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct rv8803_data *rv8803 = dev_get_drvdata(dev->parent);
+ struct i2c_client *client = rv8803->client;
+ int ret;
+ unsigned long tmo;
+
+ guard(mutex)(&rv8803->flags_lock);
+
+ /* CMDTRGEN */
+ ret = rv8803_write_reg(client, RX8901_WRCMD_CFG, BIT(0));
+ if (ret < 0)
+ return ret;
+ ret = rv8803_write_reg(client, RX8901_WRCMD_TRG, 0xFF);
+ if (ret < 0)
+ return ret;
+
+ tmo = jiffies + msecs_to_jiffies(100); /* timeout 100ms */
+ do {
+ usleep_range(10, 2000);
+ ret = rv8803_read_reg(client, RX8901_WRCMD_TRG);
+ if (ret < 0)
+ return ret;
+ if (time_after(jiffies, tmo))
+ return -EBUSY;
+ } while (ret);
+
+ return count;
+}
+
static DEVICE_ATTR_WO(enable);
static DEVICE_ATTR_ADMIN_RO(read);
+static DEVICE_ATTR_WO(trigger);
static struct attribute *rv8803_rtc_event_attrs[] = {
&dev_attr_enable.attr,
&dev_attr_read.attr,
+ &dev_attr_trigger.attr,
NULL
};
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 5/7] rtc-rv8803: extend sysfs to read status
2025-05-21 9:05 [PATCH v4 0/7] rtc-rv8803: Implement timestamp trigger over event pins Markus Burri
` (3 preceding siblings ...)
2025-05-21 9:05 ` [PATCH v4 4/7] rtc-rv8803: extend sysfs to trigger internal ts-event Markus Burri
@ 2025-05-21 9:05 ` Markus Burri
2025-05-21 9:05 ` [PATCH v4 6/7] dt-bindings: rtc-rv8803: add tamper detection property node Markus Burri
2025-05-21 9:05 ` [PATCH v4 7/7] rtc-rv8803: make tamper function configurable via dt Markus Burri
6 siblings, 0 replies; 10+ messages in thread
From: Markus Burri @ 2025-05-21 9:05 UTC (permalink / raw)
To: linux-kernel
Cc: Markus Burri, Alexandre Belloni, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manuel Traut, Marek Vasut, linux-rtc, devicetree,
Markus Burri
Add sysfs functionality to read the status and configuration.
The functions provide the number of stored timestamp events, the current
EVIN pin configuration and the enabled/disabled status.
Signed-off-by: Markus Burri <markus.burri@mt.com>
Reviewed-by: Manuel Traut <manuel.traut@mt.com>
---
.../ABI/testing/sysfs-class-rtc-tamper | 8 ++
drivers/rtc/rtc-rv8803.c | 115 ++++++++++++++++++
2 files changed, 123 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-class-rtc-tamper b/Documentation/ABI/testing/sysfs-class-rtc-tamper
index 83b2fae1fc6e..ef6d5f43abd8 100644
--- a/Documentation/ABI/testing/sysfs-class-rtc-tamper
+++ b/Documentation/ABI/testing/sysfs-class-rtc-tamper
@@ -26,3 +26,11 @@ KernelVersion: 6.15
Contact: Markus Burri <markus.burri@mt.com>
Description: (WO) Attribute to trigger an internal timestamp event
Write a '1' to trigger an internal event and store a timestamp.
+
+What: /sys/class/rtc/rtcX/tamper/status
+Date: May 2025
+KernelVersion: 6.15
+Contact: Markus Burri <markus.burri@mt.com>
+Description: (RO) Attribute to read configuration and status for EVINx and buffer.
+ Provide the number of stored timestamp events, the current EVIN pin configuration
+ and the enabled/disabled status.
diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c
index d0aac250774a..39d5881ba261 100644
--- a/drivers/rtc/rtc-rv8803.c
+++ b/drivers/rtc/rtc-rv8803.c
@@ -85,8 +85,11 @@
#define RX8901_EVNT_INTF 0x47
+#define RX8901_BUF_OVWF 0x4F
+
#define NO_OF_EVIN 3
+#define EVIN_FILTER_FACTOR 125
#define EVIN_FILTER_MAX 40
enum rv8803_type {
@@ -117,6 +120,26 @@ struct cfg_val_txt {
bool hide;
};
+static const struct cfg_val_txt pull_resistor_txt[] = {
+ { "no", no },
+ { "PU/500k", pull_up_500k },
+ { "PU/1M", pull_up_1M },
+ { "PU/10M", pull_up_10M },
+ { "PD/500k", pull_down_500k },
+ { "no", 0b101, 1 },
+ { "no", 0b110, 1 },
+ { "no", 0b111, 1 },
+ { NULL }
+};
+
+static const struct cfg_val_txt trigger_txt[] = {
+ { "falling", falling_edge },
+ { "rising", rising_edge },
+ { "both", both_edges },
+ { "both", 0b11, 1 },
+ { NULL }
+};
+
static const struct cfg_val_txt trg_status_txt[] = {
{ "EVIN1", BIT(5) },
{ "EVIN2", BIT(6) },
@@ -633,6 +656,16 @@ static int rv8803_nvram_read(void *priv, unsigned int offset,
return 0;
}
+static char *cfg2txt(const struct cfg_val_txt *cfg, u8 value)
+{
+ do {
+ if (cfg->val == value)
+ return cfg->txt;
+ } while (++cfg && cfg->txt);
+
+ return NULL;
+}
+
static int rv8803_ts_event_write_evin(int evin, struct rv8803_data *rv8803,
enum evin_pull_resistor pullup_down,
enum evin_trigger trigger, int filter)
@@ -960,14 +993,96 @@ static ssize_t trigger_store(struct device *dev, struct device_attribute *attr,
return count;
}
+static ssize_t status_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ int evin_en;
+ int evin_cfg, evin_flt;
+ int buf1_cfg, buf1_stat, buf_ovwf;
+ int inte;
+ int i;
+ int offset = 0;
+ u8 ev_pullupdown[NO_OF_EVIN];
+ u8 ev_trigger[NO_OF_EVIN];
+ int ev_filter[NO_OF_EVIN];
+
+ struct i2c_client *client = to_i2c_client(dev->parent);
+ struct rv8803_data *rv8803 = dev_get_drvdata(dev->parent);
+
+ scoped_guard(mutex, &rv8803->flags_lock) {
+ evin_en = rv8803_read_reg(client, RX8901_EVIN_EN);
+ if (evin_en < 0)
+ return evin_en;
+
+ inte = rv8803_read_reg(client, RX8901_EVNT_INTE);
+ if (inte < 0)
+ return evin_en;
+
+ for (i = 0; i < NO_OF_EVIN; ++i) {
+ evin_cfg = rv8803_read_reg(client, evin_cfg_regs[i]);
+ evin_flt = rv8803_read_reg(client, evin_flt_regs[i]);
+ if (evin_cfg < 0 || evin_flt < 0)
+ return -EIO;
+
+ ev_pullupdown[i] = FIELD_GET(RX8901_EVENTx_CFG_PUPD, evin_cfg);
+ ev_trigger[i] = FIELD_GET(RX8901_EVENTx_CFG_POL, evin_cfg);
+ ev_filter[i] = EVIN_FILTER_FACTOR * evin_flt;
+ }
+
+ buf1_cfg = rv8803_read_reg(client, RX8901_BUF1_CFG1);
+ buf1_stat = rv8803_read_reg(client, RX8901_BUF1_STAT);
+ buf_ovwf = rv8803_read_reg(client, RX8901_BUF_OVWF);
+ if (buf1_stat < 0 || buf1_stat < 0 || buf_ovwf < 0)
+ return -EIO;
+ }
+
+ offset += sprintf(buf + offset, "Mode: %s\n",
+ FIELD_GET(BIT(6), evin_en) ? "direct" : "fifo");
+ offset += sprintf(buf + offset, "\nExternal Event config:\n");
+ offset += sprintf(buf + offset, " %-13s %-7s %-7s %-7s\n", "", "EVIN1", "EVIN2", "EVIN3");
+ offset += sprintf(buf + offset, " %-13s %-7ld %-7ld %-7ld\n", "Enable",
+ FIELD_GET(BIT(0), evin_en), FIELD_GET(BIT(1), evin_en),
+ FIELD_GET(BIT(2), evin_en));
+ offset += sprintf(buf + offset, " %-13s %-7ld %-7ld %-7ld\n", "Capture",
+ FIELD_GET(BIT(3), evin_en), FIELD_GET(BIT(4), evin_en),
+ FIELD_GET(BIT(5), evin_en));
+ offset += sprintf(buf + offset, " %-13s %-7ld %-7ld %-7ld\n", "Interrupt",
+ FIELD_GET(BIT(5), inte), FIELD_GET(BIT(6), inte),
+ FIELD_GET(BIT(7), inte));
+ offset += sprintf(buf + offset, " %-13s %-7s %-7s %-7s\n", "Pull-resistor",
+ cfg2txt(pull_resistor_txt, ev_pullupdown[0]),
+ cfg2txt(pull_resistor_txt, ev_pullupdown[1]),
+ cfg2txt(pull_resistor_txt, ev_pullupdown[2]));
+ offset += sprintf(buf + offset, " %-13s %-7s %-7s %-7s\n", "Edge",
+ cfg2txt(trigger_txt, ev_trigger[0]),
+ cfg2txt(trigger_txt, ev_trigger[1]),
+ cfg2txt(trigger_txt, ev_trigger[2]));
+ offset += sprintf(buf + offset, " %-13s %-7d %-7d %-7d\n", "Filter [ms]",
+ ev_filter[0], ev_filter[1], ev_filter[2]);
+
+ offset += sprintf(buf + offset, "\nBuffer config:\n");
+ offset += sprintf(buf + offset, " %-13s %-10s\n", "Mode",
+ (FIELD_GET(BIT(6), buf1_cfg) ? "overwrite" : "inhibit"));
+ offset += sprintf(buf + offset, " %-13s %-10s\n", "Status",
+ (FIELD_GET(BIT(7), buf1_stat) ? "full" : "free"));
+ offset += sprintf(buf + offset, " %-13s %-10ld\n", "Overrun",
+ (FIELD_GET(BIT(4), buf_ovwf)));
+ offset += sprintf(buf + offset, " %-13s %-10ld\n", "No of data",
+ (FIELD_GET(GENMASK(5, 0), buf1_stat)));
+
+ return offset;
+}
+
static DEVICE_ATTR_WO(enable);
static DEVICE_ATTR_ADMIN_RO(read);
static DEVICE_ATTR_WO(trigger);
+static DEVICE_ATTR_RO(status);
static struct attribute *rv8803_rtc_event_attrs[] = {
&dev_attr_enable.attr,
&dev_attr_read.attr,
&dev_attr_trigger.attr,
+ &dev_attr_status.attr,
NULL
};
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 6/7] dt-bindings: rtc-rv8803: add tamper detection property node
2025-05-21 9:05 [PATCH v4 0/7] rtc-rv8803: Implement timestamp trigger over event pins Markus Burri
` (4 preceding siblings ...)
2025-05-21 9:05 ` [PATCH v4 5/7] rtc-rv8803: extend sysfs to read status Markus Burri
@ 2025-05-21 9:05 ` Markus Burri
2025-05-27 6:42 ` Krzysztof Kozlowski
2025-05-21 9:05 ` [PATCH v4 7/7] rtc-rv8803: make tamper function configurable via dt Markus Burri
6 siblings, 1 reply; 10+ messages in thread
From: Markus Burri @ 2025-05-21 9:05 UTC (permalink / raw)
To: linux-kernel
Cc: Markus Burri, Alexandre Belloni, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manuel Traut, Marek Vasut, linux-rtc, devicetree,
Markus Burri
The RV8901 RTC chip provides a function to store timestamp events.
There are three input pins (EVIN1-3) available for triggering.
The input pins can be configured and adapted according to the connected
hardware.
Add document of tamper detection properties for epson,rx8901 rtc chip.
Signed-off-by: Markus Burri <markus.burri@mt.com>
---
.../devicetree/bindings/rtc/epson,rx8900.yaml | 37 +++++++++++++++++--
1 file changed, 34 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/rtc/epson,rx8900.yaml b/Documentation/devicetree/bindings/rtc/epson,rx8900.yaml
index 03af81754482..2682cbb9097d 100644
--- a/Documentation/devicetree/bindings/rtc/epson,rx8900.yaml
+++ b/Documentation/devicetree/bindings/rtc/epson,rx8900.yaml
@@ -9,9 +9,6 @@ title: EPSON RX8900 / Microcrystal RV8803 Real-Time Clock
maintainers:
- Marek Vasut <marex@denx.de>
-allOf:
- - $ref: rtc.yaml#
-
properties:
compatible:
enum:
@@ -33,6 +30,40 @@ properties:
wakeup-source: true
+ tamper:
+ description: Subnode for tamper configuration.
+ This subnode is only available for epson,rx8901.
+ type: object
+ additionalProperties: false
+
+ properties:
+ buffer-overwrite:
+ type: boolean
+ description: Set the buffer mode to overwrite. Default is inhibit.
+
+ patternProperties:
+ "^evin-[0-3]$":
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 3
+ maxItems: 3
+ description: External event input pin configuration.
+ The configuration is an array of tree values and contains
+ "pull-resistor", "trigger" and "filter".
+ For a detailed description, see epson-rx8901 datasheet.
+
+allOf:
+ - $ref: rtc.yaml#
+ - if:
+ properties:
+ compatible:
+ not:
+ contains:
+ enum:
+ - epson,rx8901
+ then:
+ properties:
+ tamper: false
+
required:
- compatible
- reg
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v4 6/7] dt-bindings: rtc-rv8803: add tamper detection property node
2025-05-21 9:05 ` [PATCH v4 6/7] dt-bindings: rtc-rv8803: add tamper detection property node Markus Burri
@ 2025-05-27 6:42 ` Krzysztof Kozlowski
0 siblings, 0 replies; 10+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-27 6:42 UTC (permalink / raw)
To: Markus Burri
Cc: linux-kernel, Alexandre Belloni, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manuel Traut, Marek Vasut, linux-rtc, devicetree,
Markus Burri
On Wed, May 21, 2025 at 11:05:51AM GMT, Markus Burri wrote:
> The RV8901 RTC chip provides a function to store timestamp events.
> There are three input pins (EVIN1-3) available for triggering.
> The input pins can be configured and adapted according to the connected
> hardware.
> Add document of tamper detection properties for epson,rx8901 rtc chip.
>
> Signed-off-by: Markus Burri <markus.burri@mt.com>
> ---
> .../devicetree/bindings/rtc/epson,rx8900.yaml | 37 +++++++++++++++++--
> 1 file changed, 34 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/rtc/epson,rx8900.yaml b/Documentation/devicetree/bindings/rtc/epson,rx8900.yaml
> index 03af81754482..2682cbb9097d 100644
> --- a/Documentation/devicetree/bindings/rtc/epson,rx8900.yaml
> +++ b/Documentation/devicetree/bindings/rtc/epson,rx8900.yaml
> @@ -9,9 +9,6 @@ title: EPSON RX8900 / Microcrystal RV8803 Real-Time Clock
> maintainers:
> - Marek Vasut <marex@denx.de>
>
> -allOf:
> - - $ref: rtc.yaml#
> -
> properties:
> compatible:
> enum:
> @@ -33,6 +30,40 @@ properties:
>
> wakeup-source: true
>
> + tamper:
> + description: Subnode for tamper configuration.
> + This subnode is only available for epson,rx8901.
Drop last sentence. Don't repeat constraints in free form text.
> + type: object
> + additionalProperties: false
> +
> + properties:
> + buffer-overwrite:
Missing vendor prefix or where is this property defined?
> + type: boolean
> + description: Set the buffer mode to overwrite. Default is inhibit.
Why woould this be a board configuration? You described the desired
Linux feature or behavior, not the actual hardware. The bindings are
about the latter, so instead you need to rephrase the property and its
description to match actual hardware capabilities/features/configuration
etc.
> +
> + patternProperties:
> + "^evin-[0-3]$":
Commit says three, schema says four.
Where is this property defined? Which common schema? Or is it vendor
property?
> + $ref: /schemas/types.yaml#/definitions/uint32-array
> + minItems: 3
> + maxItems: 3
> + description: External event input pin configuration.
> + The configuration is an array of tree values and contains
> + "pull-resistor", "trigger" and "filter".
What are the values here? Missing constraints, missing defaults.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 7/7] rtc-rv8803: make tamper function configurable via dt
2025-05-21 9:05 [PATCH v4 0/7] rtc-rv8803: Implement timestamp trigger over event pins Markus Burri
` (5 preceding siblings ...)
2025-05-21 9:05 ` [PATCH v4 6/7] dt-bindings: rtc-rv8803: add tamper detection property node Markus Burri
@ 2025-05-21 9:05 ` Markus Burri
6 siblings, 0 replies; 10+ messages in thread
From: Markus Burri @ 2025-05-21 9:05 UTC (permalink / raw)
To: linux-kernel
Cc: Markus Burri, Alexandre Belloni, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Manuel Traut, Marek Vasut, linux-rtc, devicetree,
Markus Burri
The settings are depending on hardware connected to the input pin.
Make this settings configurable in the device-tree:
- for the input pins: input resistor, trigger edge, de-jitter filter
- for the buffer: overwrite or inhibit mode for the FIFO
Signed-off-by: Markus Burri <markus.burri@mt.com>
---
drivers/rtc/rtc-rv8803.c | 95 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 92 insertions(+), 3 deletions(-)
diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c
index 39d5881ba261..e3a4e9eaccb1 100644
--- a/drivers/rtc/rtc-rv8803.c
+++ b/drivers/rtc/rtc-rv8803.c
@@ -114,6 +114,11 @@ enum evin_trigger {
both_edges = 0b10,
};
+enum evin_buffer_mode {
+ inhibit = 0,
+ overwrite = 1,
+};
+
struct cfg_val_txt {
char *txt;
u8 val;
@@ -164,6 +169,16 @@ static const u8 evin_flt_regs[] = {
RX8901_EVIN3_FLT
};
+struct tamper_cfg {
+ struct {
+ u8 enable;
+ u8 pull_resistor;
+ u8 trigger;
+ u8 filter;
+ } evin[NO_OF_EVIN];
+ u8 buffer_mode;
+};
+
struct rv8803_data {
struct i2c_client *client;
struct rtc_device *rtc;
@@ -171,6 +186,7 @@ struct rv8803_data {
u8 ctrl;
u8 backup;
u8 alarm_invalid:1;
+ struct tamper_cfg tamper_cfg;
enum rv8803_type type;
};
@@ -769,7 +785,10 @@ static int rv8803_ts_enable(struct rv8803_data *rv8803, u8 enable)
/* 3. set EVENTx pull-up edge trigger and noise filter */
for (i = 0; i < NO_OF_EVIN; ++i) {
- ret = rv8803_ts_event_write_evin(i, rv8803, pull_up_1M, falling_edge, 0);
+ ret = rv8803_ts_event_write_evin(i, rv8803,
+ rv8803->tamper_cfg.evin[i].pull_resistor,
+ rv8803->tamper_cfg.evin[i].trigger,
+ rv8803->tamper_cfg.evin[i].filter);
if (ret < 0)
return ret;
}
@@ -787,10 +806,11 @@ static int rv8803_ts_enable(struct rv8803_data *rv8803, u8 enable)
}
/*
- * 5. set BUF1 inhibit and interrupt every 1 event
+ * 5. set BUF1 inhibit/overwrite mode and interrupt every 1 event
* NOTE: BUF2-3 are not used in FIFO-mode
*/
- ret = rv8803_write_reg(client, RX8901_BUF1_CFG1, 0x01);
+ reg_mask = 0x01 | FIELD_PREP(BIT(6), rv8803->tamper_cfg.buffer_mode);
+ ret = rv8803_write_reg(client, RX8901_BUF1_CFG1, reg_mask);
if (ret < 0)
return ret;
@@ -1125,6 +1145,71 @@ static int rx8900_trickle_charger_init(struct rv8803_data *rv8803)
flags);
}
+static int rx8900_tamper_init(struct rv8803_data *rv8803)
+{
+ int i;
+ int err;
+ u8 flags;
+ struct device_node *of_tamper;
+ struct i2c_client *client = rv8803->client;
+ struct tamper_cfg *tamper_cfg = &rv8803->tamper_cfg;
+
+ rv8803->tamper_cfg.buffer_mode = inhibit;
+ for (i = 0; i < NO_OF_EVIN; ++i) {
+ tamper_cfg->evin[i].enable = true;
+ tamper_cfg->evin[i].pull_resistor = pull_up_1M;
+ tamper_cfg->evin[i].trigger = falling_edge;
+ tamper_cfg->evin[i].filter = 0;
+ }
+
+ of_tamper = of_get_child_by_name(client->dev.of_node, "tamper");
+ if (of_tamper) {
+ if (of_property_read_bool(of_tamper, "buffer-overwrite"))
+ tamper_cfg->buffer_mode = overwrite;
+
+ for (i = 0; i < NO_OF_EVIN; ++i) {
+ char of_evin_name[10];
+ u32 evin_val[3];
+
+ snprintf(of_evin_name, sizeof(of_evin_name), "evin-%d", i + 1);
+ if (!of_property_read_u32_array(of_tamper, of_evin_name, evin_val,
+ ARRAY_SIZE(evin_val))) {
+ tamper_cfg->evin[i].enable = true;
+ tamper_cfg->evin[i].pull_resistor = evin_val[0];
+ tamper_cfg->evin[i].trigger = evin_val[1];
+ tamper_cfg->evin[i].filter = evin_val[2];
+ } else {
+ tamper_cfg->evin[i].enable = false;
+ }
+ }
+ of_node_put(of_tamper);
+ }
+
+ scoped_guard(mutex, &rv8803->flags_lock) {
+ err = rv8803_read_reg(client, RX8901_BUF1_CFG1);
+ if (err < 0)
+ return err;
+ flags = (err & ~BIT(6)) | FIELD_PREP(BIT(6), tamper_cfg->buffer_mode);
+ err = rv8803_write_reg(client, RX8901_BUF1_CFG1, flags);
+ if (err < 0)
+ return err;
+ }
+
+ for (i = 0; i < NO_OF_EVIN; ++i) {
+ err = rv8803_ts_event_write_evin(i, rv8803,
+ tamper_cfg->evin[i].pull_resistor,
+ tamper_cfg->evin[i].trigger,
+ tamper_cfg->evin[i].filter);
+ if (err)
+ return err;
+ }
+
+ if (of_tamper)
+ rv8803_ts_enable(rv8803, true);
+
+ return 0;
+}
+
/* configure registers with values different than the Power-On reset defaults */
static int rv8803_regs_configure(struct rv8803_data *rv8803)
{
@@ -1266,6 +1351,10 @@ static int rv8803_probe(struct i2c_client *client)
return err;
if (rv8803->type == rx_8901) {
+ err = rx8900_tamper_init(rv8803);
+ if (err)
+ return err;
+
err = rtc_add_group(rv8803->rtc, &rv8803_rtc_sysfs_event_files);
if (err)
return err;
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread