* [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support @ 2025-05-07 7:26 Pankit Garg 2025-05-07 7:26 ` [PATCH v3 2/2] rtc: Add NXP PCF85053A driver support Pankit Garg 2025-05-07 14:22 ` [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support Conor Dooley 0 siblings, 2 replies; 8+ messages in thread From: Pankit Garg @ 2025-05-07 7:26 UTC (permalink / raw) To: linux-rtc, devicetree, linux-kernel, conor+dt, robh, alexandre.belloni Cc: vikash.bansal, priyanka.jain, daniel.aguirre, shashank.rebbapragada, aman.kumarpandey, Pankit Garg Add device tree bindings for NXP PCF85053a RTC chip. Signed-off-by: Pankit Garg <pankit.garg@nxp.com> --- V2 -> V3: Moved MAINTAINERS file changes to the driver patch V1 -> V2: Handled dt-bindings by trivial-rtc.yaml --- Documentation/devicetree/bindings/rtc/trivial-rtc.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml index 7330a7200831..47be7bbbfedd 100644 --- a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml @@ -65,6 +65,8 @@ properties: - microcrystal,rv8523 # NXP LPC32xx SoC Real-time Clock - nxp,lpc3220-rtc + # NXP PCF85053A Real Time Clock Module with I2C-Bus + - nxp,pcf85053a # I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC - ricoh,r2025sd # I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC -- 2.25.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v3 2/2] rtc: Add NXP PCF85053A driver support 2025-05-07 7:26 [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support Pankit Garg @ 2025-05-07 7:26 ` Pankit Garg 2025-07-23 20:35 ` Alexandre Belloni 2025-05-07 14:22 ` [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support Conor Dooley 1 sibling, 1 reply; 8+ messages in thread From: Pankit Garg @ 2025-05-07 7:26 UTC (permalink / raw) To: linux-rtc, devicetree, linux-kernel, conor+dt, robh, alexandre.belloni Cc: vikash.bansal, priyanka.jain, daniel.aguirre, shashank.rebbapragada, aman.kumarpandey, Pankit Garg PCF85053A is i2c based RTC which supports timer and calendar functionality. Features supported: 1. Read/Write time 2. Get/Set Alarm 3. Wakeup Source 4. Generate 32768Hz clock output 5. Secondary i2c bus Signed-off-by: Daniel Aguirre <daniel.aguirre@nxp.com> Signed-off-by: Pankit Garg <pankit.garg@nxp.com> --- V2 -> V3: Add MAINTAINERS file changes to this patch V1 -> V2: no changes --- MAINTAINERS | 6 + drivers/rtc/Kconfig | 10 + drivers/rtc/Makefile | 1 + drivers/rtc/rtc-pcf85053a.c | 594 ++++++++++++++++++++++++++++++++++++ 4 files changed, 611 insertions(+) create mode 100644 drivers/rtc/rtc-pcf85053a.c diff --git a/MAINTAINERS b/MAINTAINERS index 0737dcb2e411..fa342615831d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17782,6 +17782,12 @@ S: Maintained F: Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml F: sound/soc/codecs/tfa989x.c +NXP RTC PCF85053A DRIVER +M: Pankit Garg<pankit.garg@nxp.com> +L: linux-kernel@vger.kernel.org +S: Maintained +F: drivers/rtc/rtc-pcf85053a.c + NZXT-KRAKEN2 HARDWARE MONITORING DRIVER M: Jonas Malaco <jonas@protocubo.io> L: linux-hwmon@vger.kernel.org diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 838bdc138ffe..669470e92a7d 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -492,6 +492,16 @@ config RTC_DRV_PCF85063 This driver can also be built as a module. If so, the module will be called rtc-pcf85063. +config RTC_DRV_PCF85053A + tristate "NXP PCF85053A" + depends on OF + help + If you say yes here you get support for the NXP PCF85053A I2C Bootable CPU RTC + chip. + + This driver can also be built as a module. If so, the module + will be called rtc-pcf85053a. + config RTC_DRV_PCF85363 tristate "NXP PCF85363" select REGMAP_I2C diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 31473b3276d9..64ae988e7fa6 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -127,6 +127,7 @@ obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o obj-$(CONFIG_RTC_DRV_PCF2127) += rtc-pcf2127.o obj-$(CONFIG_RTC_DRV_PCF85063) += rtc-pcf85063.o +obj-$(CONFIG_RTC_DRV_PCF85053A) += rtc-pcf85053a.o obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o obj-$(CONFIG_RTC_DRV_PCF85363) += rtc-pcf85363.o obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o diff --git a/drivers/rtc/rtc-pcf85053a.c b/drivers/rtc/rtc-pcf85053a.c new file mode 100644 index 000000000000..83e2bcbca4d4 --- /dev/null +++ b/drivers/rtc/rtc-pcf85053a.c @@ -0,0 +1,594 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright 2025 NXP + +#include <linux/bcd.h> +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/rtc.h> +#include <linux/slab.h> +#include <linux/pm_wakeirq.h> +#include <linux/regmap.h> + +#define PCF85053A_REG_SC 0x00 /* seconds */ +#define PCF85053A_REG_SCA 0x01 /* alarm */ +#define PCF85053A_REG_MN 0x02 /* minutes */ +#define PCF85053A_REG_MNA 0x03 /* alarm */ +#define PCF85053A_REG_HR 0x04 /* hour */ +#define PCF85053A_REG_HRA 0x05 /* alarm */ +#define PCF85053A_REG_DW 0x06 /* day of week */ +#define PCF85053A_REG_DM 0x07 /* day of month */ +#define PCF85053A_REG_MO 0x08 /* month */ +#define PCF85053A_REG_YR 0x09 /* year */ +#define PCF85053A_REG_CTRL 0x0A /* timer control */ +#define PCF85053A_REG_ST 0x0B /* status */ +#define PCF85053A_REG_CLKO 0x0C /* clock out */ +#define PCF85053A_REG_ACC 0x14 /* xclk access */ + +#define PCF85053A_BIT_AF BIT(7) +#define PCF85053A_BIT_ST BIT(7) +#define PCF85053A_BIT_DM BIT(6) +#define PCF85053A_BIT_HF BIT(5) +#define PCF85053A_BIT_DSM BIT(4) +#define PCF85053A_BIT_AIE BIT(3) +#define PCF85053A_BIT_OFIE BIT(2) +#define PCF85053A_BIT_CIE BIT(1) +#define PCF85053A_BIT_TWO BIT(0) +#define PCF85053A_BIT_XCLK BIT(7) + +#define PCF85053A_REG_BAT_MASK 0x07 /* Battery mask */ +#define PCF85053A_REG_CLKO_F_MASK 0x03 /* Frequenc mask */ +#define PCF85053A_REG_CLKO_CKE 0x80 /* clock out enabled */ + +struct pcf85053a_config { + const struct regmap_config regmap; + unsigned has_alarms:1; +}; + +struct pcf85053a { + struct rtc_device *rtc; + struct i2c_client *client; + struct regmap *regmap; +#ifdef CONFIG_COMMON_CLK + struct clk_hw clkout_hw; +#endif +}; + +static int pcf85053a_set_alarm_mode(struct device *dev, bool on) +{ + struct pcf85053a *pcf85053a = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + unsigned int val; + int err; + + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_CTRL, &val); + if (err) + return err; + + if (on) + val |= PCF85053A_BIT_AIE; + else + val &= ~PCF85053A_BIT_AIE; + + val |= PCF85053A_BIT_CIE; + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_CTRL, val); + if (err < 0) { + dev_err(&client->dev, "Unable to write PCF85053A_REG_CTRL\n"); + return err; + } + + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_ST, &val); + if (err) + return err; + + val &= ~(PCF85053A_BIT_AF); + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_ST, val); + if (err < 0) { + dev_err(&client->dev, "Unable to write PCF85053A_REG_ST\n"); + return err; + } + + return 0; +} + +static int pcf85053a_get_alarm_mode(struct device *dev, + unsigned char *alarm_enable, unsigned char *alarm_flag) +{ + struct pcf85053a *pcf85053a = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + unsigned int val; + int err; + + if (alarm_enable) { + dev_dbg(&client->dev, "%s:PCF85053A_REG_CTRL\n", __func__); + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_CTRL, &val); + if (err) + return err; + *alarm_enable = val & PCF85053A_BIT_AIE; + } + + if (alarm_flag) { + dev_dbg(&client->dev, "%s:PCF85053A_REG_ST\n", __func__); + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_ST, &val); + if (err) + return err; + *alarm_flag = val & PCF85053A_BIT_AF; + } + + dev_dbg(&client->dev, "%s:alarm_enable:%x alarm_flag:%x\n", + __func__, *alarm_enable, *alarm_flag); + + return 0; +} + +static irqreturn_t pcf85053a_irq(int irq, void *dev_id) +{ + struct pcf85053a *pcf85053a = i2c_get_clientdata(dev_id); + struct i2c_client *client = pcf85053a->client; + int err; + unsigned char alarm_flag; + unsigned char alarm_enable; + + err = pcf85053a_get_alarm_mode(&client->dev, &alarm_enable, &alarm_flag); + if (err) + return IRQ_NONE; + + if (alarm_flag) { + rtc_update_irq(pcf85053a->rtc, 1, RTC_IRQF | RTC_AF); + pcf85053a_set_alarm_mode(&client->dev, 0); + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +/* + * In the routines that deal directly with the PCF85053A hardware, we use + * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. + */ +static int pcf85053a_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct pcf85053a *pcf85053a = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + unsigned char regs[10]; + unsigned int val; + int err; + + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_ST, &val); + if (err) + return err; + + if (0 == (val & PCF85053A_REG_BAT_MASK)) { + dev_err(&client->dev, " BVL[2:0] value is 0x0 (Battery Voltage <= 1.7V), information is not reliable.\n"); + return -EINVAL; + } + + err = regmap_bulk_read(pcf85053a->regmap, PCF85053A_REG_SC, regs, + sizeof(regs)); + if (err) + return err; + + tm->tm_sec = bcd2bin(regs[PCF85053A_REG_SC] & 0x7F); + tm->tm_min = bcd2bin(regs[PCF85053A_REG_MN] & 0x7F); + tm->tm_hour = bcd2bin(regs[PCF85053A_REG_HR] & 0x3F); + tm->tm_wday = regs[PCF85053A_REG_DW] & 0x07; + tm->tm_mday = bcd2bin(regs[PCF85053A_REG_DM] & 0x3F); + tm->tm_mon = bcd2bin(regs[PCF85053A_REG_MO] & 0x1F) - 1; + tm->tm_year = bcd2bin(regs[PCF85053A_REG_YR]) + 100; + + return 0; +} + +static int pcf85053a_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct pcf85053a *pcf85053a = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + int err; + + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_SC, bin2bcd(tm->tm_sec)); + if (err < 0) { + dev_err(&client->dev, "Unable to write PCF85053A_REG_SC\n"); + return err; + } + + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_MN, bin2bcd(tm->tm_min)); + if (err < 0) { + dev_err(&client->dev, "Unable to write PCF85053A_REG_MN\n"); + return err; + } + + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_HR, bin2bcd(tm->tm_hour)); + if (err < 0) { + dev_err(&client->dev, "Unable to write PCF85053A_REG_HR\n"); + return err; + } + + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_DW, tm->tm_wday & 0x07); + if (err < 0) { + dev_err(&client->dev, "Unable to write PCF85053A_REG_DW\n"); + return err; + } + + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_DM, bin2bcd(tm->tm_mday)); + if (err < 0) { + dev_err(&client->dev, "Unable to write PCF85053A_REG_DM\n"); + return err; + } + + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_MO, bin2bcd(tm->tm_mon + 1)); + if (err < 0) { + dev_err(&client->dev, "Unable to write PCF85053A_REG_MO\n"); + return err; + } + + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_YR, bin2bcd(tm->tm_year - 100)); + if (err < 0) { + dev_err(&client->dev, "Unable to write PCF85053A_REG_YR\n"); + return err; + } + + return err; +} + +static int pcf85053a_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm) +{ + struct pcf85053a *pcf85053a = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + unsigned char buf[5]; + int err; + + err = regmap_bulk_read(pcf85053a->regmap, PCF85053A_REG_SCA, buf, + sizeof(buf)); + if (err) + return err; + + dev_dbg(&client->dev, "%s: raw data is sec=%02x, min=%02x hr=%02x\n", + __func__, buf[0], buf[2], buf[4]); + + tm->time.tm_sec = bcd2bin(buf[0] & 0x7F); + tm->time.tm_min = bcd2bin(buf[2] & 0x7F); + tm->time.tm_hour = bcd2bin(buf[4] & 0x3F); + + err = pcf85053a_get_alarm_mode(dev, &tm->enabled, &tm->pending); + if (err < 0) + return err; + + dev_dbg(&client->dev, "%s:s=%d m=%d, hr=%d, enabled=%d, pending=%d\n", + __func__, tm->time.tm_sec, tm->time.tm_min, + tm->time.tm_hour, tm->enabled, tm->pending); + + return 0; +} + +static int pcf85053a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm) +{ + struct pcf85053a *pcf85053a = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + int err; + + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_SCA, bin2bcd(tm->time.tm_sec)); + if (err < 0) { + dev_err(&client->dev, "Unable to write PCF85053A_REG_SCA\n"); + return err; + } + + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_MNA, bin2bcd(tm->time.tm_min)); + if (err < 0) { + dev_dbg(&client->dev, "Unable to write PCF85053A_REG_MNA\n"); + return err; + } + + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_HRA, bin2bcd(tm->time.tm_hour)); + if (err < 0) { + dev_dbg(&client->dev, "Unable to write PCF85053A_REG_HRA\n"); + return err; + } + + return pcf85053a_set_alarm_mode(dev, tm->enabled); +} + +static int pcf85053a_irq_enable(struct device *dev, unsigned int enabled) +{ + dev_dbg(dev, "%s: alarm enable=%d\n", __func__, enabled); + + return pcf85053a_set_alarm_mode(dev, enabled); +} + +static int pcf85053a_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) +{ + struct pcf85053a *pcf85053a = dev_get_drvdata(dev); + int status; + unsigned int val = 0; + + switch (cmd) { + case RTC_VL_READ: + status = regmap_read(pcf85053a->regmap, PCF85053A_REG_ST, &val); + if (status) + return status; + + if (!(status & PCF85053A_REG_BAT_MASK)) + val |= RTC_VL_DATA_INVALID; + + return put_user(val, (unsigned int __user *)arg); + + default: + return -ENOIOCTLCMD; + } +} + +#ifdef CONFIG_COMMON_CLK +/* + * Handling of the clkout + */ + +#define clkout_hw_to_pcf85053a(_hw) container_of(_hw, struct pcf85053a, clkout_hw) + +static const int clkout_rates[] = { + 32768, + 1024, + 32, + 1, +}; + +static unsigned long pcf85053a_clkout_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct pcf85053a *pcf85053a = clkout_hw_to_pcf85053a(hw); + int err; + unsigned int val = 0; + + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_CLKO, &val); + if (err) + return 0; + + val &= PCF85053A_REG_CLKO_F_MASK; + return clkout_rates[val]; +} + +static long pcf85053a_clkout_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) + if (clkout_rates[i] <= rate) + return clkout_rates[i]; + + return 0; +} + +static int pcf85053a_clkout_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct pcf85053a *pcf85053a = clkout_hw_to_pcf85053a(hw); + int err, i; + unsigned int val = 0; + + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_CLKO, &val); + if (err) + return err; + + for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) + if (clkout_rates[i] == rate) { + val &= ~PCF85053A_REG_CLKO_F_MASK; + val |= i; + return regmap_write(pcf85053a->regmap, PCF85053A_REG_CLKO, val); + } + + return -EINVAL; +} + +static int pcf85053a_clkout_control(struct clk_hw *hw, bool enable) +{ + struct pcf85053a *pcf85053a = clkout_hw_to_pcf85053a(hw); + int err; + unsigned int val = 0; + + val = PCF85053A_BIT_XCLK; + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_ACC, val); + if (err) + return err; + + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_CLKO, &val); + if (err) + return err; + + if (enable) + val |= PCF85053A_REG_CLKO_CKE; + else + val &= ~PCF85053A_REG_CLKO_CKE; + + return regmap_write(pcf85053a->regmap, PCF85053A_REG_CLKO, val); +} + +static int pcf85053a_clkout_prepare(struct clk_hw *hw) +{ + return pcf85053a_clkout_control(hw, 1); +} + +static void pcf85053a_clkout_unprepare(struct clk_hw *hw) +{ + pcf85053a_clkout_control(hw, 0); +} + +static int pcf85053a_clkout_is_prepared(struct clk_hw *hw) +{ + struct pcf85053a *pcf85053a = clkout_hw_to_pcf85053a(hw); + int err; + unsigned int val = 0; + + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_CLKO, &val); + if (err) + return err; + + return val & PCF85053A_REG_CLKO_CKE; +} + +static const struct clk_ops pcf85053a_clkout_ops = { + .prepare = pcf85053a_clkout_prepare, + .unprepare = pcf85053a_clkout_unprepare, + .is_prepared = pcf85053a_clkout_is_prepared, + .recalc_rate = pcf85053a_clkout_recalc_rate, + .round_rate = pcf85053a_clkout_round_rate, + .set_rate = pcf85053a_clkout_set_rate, +}; + +static struct clk *pcf85053a_clkout_register_clk(struct pcf85053a *pcf85053a) +{ + struct i2c_client *client = pcf85053a->client; + struct device_node *node = client->dev.of_node; + struct clk *clk; + struct clk_init_data init; + + init.name = "pcf85053a-clkout"; + init.ops = &pcf85053a_clkout_ops; + init.flags = 0; + init.parent_names = NULL; + init.num_parents = 0; + pcf85053a->clkout_hw.init = &init; + + /* optional override of the clockname */ + of_property_read_string(node, "clock-output-names", &init.name); + + /* register the clock */ + clk = devm_clk_register(&client->dev, &pcf85053a->clkout_hw); + + if (!IS_ERR(clk)) + of_clk_add_provider(node, of_clk_src_simple_get, clk); + + return clk; +} +#endif + +static const struct rtc_class_ops pcf85053a_rtc_ops = { + .read_time = pcf85053a_rtc_read_time, + .set_time = pcf85053a_rtc_set_time, + .read_alarm = pcf85053a_rtc_read_alarm, + .set_alarm = pcf85053a_rtc_set_alarm, + .alarm_irq_enable = pcf85053a_irq_enable, + .ioctl = pcf85053a_ioctl, +}; + +static const struct pcf85053a_config config_pcf85053a = { + .regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x1D, + }, + .has_alarms = 1, +}; + +static int pcf85053a_probe(struct i2c_client *client) +{ + struct pcf85053a *pcf85053a; + int err; + unsigned int flags; + const struct pcf85053a_config *config; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | + I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BLOCK_DATA)) + return -ENODEV; + + pcf85053a = devm_kzalloc(&client->dev, sizeof(struct pcf85053a), + GFP_KERNEL); + if (!pcf85053a) + return -ENOMEM; + + config = i2c_get_match_data(client); + if (!config) + return -ENODEV; + + pcf85053a->regmap = devm_regmap_init_i2c(client, &config->regmap); + if (IS_ERR(pcf85053a->regmap)) + return PTR_ERR(pcf85053a->regmap); + + i2c_set_clientdata(client, pcf85053a); + + pcf85053a->client = client; + device_set_wakeup_capable(&client->dev, 1); + + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_CTRL, &flags); + if (err) { + dev_err(&client->dev, "RTC chip is not present\n"); + return err; + } + if (flags & PCF85053A_BIT_TWO) + dev_dbg(&client->dev, "%s: PCF85053A_BIT_TWO is set\n", __func__); + + flags = PCF85053A_BIT_TWO; + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_CTRL, flags); + if (err) { + dev_err(&client->dev, "Unable to write PCF85053A_REG_CTRL\n"); + return err; + } + + flags = 0; + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_ST, flags); + if (err) { + dev_err(&client->dev, "%s: write error\n", __func__); + return err; + } + + pcf85053a->rtc = devm_rtc_allocate_device(&client->dev); + if (IS_ERR(pcf85053a->rtc)) + return PTR_ERR(pcf85053a->rtc); + + pcf85053a->rtc->ops = &pcf85053a_rtc_ops; + pcf85053a->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; + pcf85053a->rtc->range_max = RTC_TIMESTAMP_END_2099; + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, pcf85053a->rtc->features); + clear_bit(RTC_FEATURE_ALARM, pcf85053a->rtc->features); + + if (config->has_alarms && client->irq > 0) { + err = devm_request_threaded_irq(&client->dev, client->irq, + NULL, pcf85053a_irq, + IRQF_ONESHOT | IRQF_TRIGGER_FALLING, + "pcf85053a", client); + if (err) { + dev_err(&client->dev, "unable to request IRQ %d\n", client->irq); + } else { + set_bit(RTC_FEATURE_ALARM, pcf85053a->rtc->features); + device_init_wakeup(&client->dev, true); + err = dev_pm_set_wake_irq(&client->dev, client->irq); + if (err) + dev_err(&client->dev, "failed to enable irq wake\n"); + } + } + +#ifdef CONFIG_COMMON_CLK + /* register clk in common clk framework */ + pcf85053a_clkout_register_clk(pcf85053a); +#endif + + return devm_rtc_register_device(pcf85053a->rtc); +} + +static const struct i2c_device_id pcf85053a_id[] = { + { "pcf85053a", .driver_data = (kernel_ulong_t)&config_pcf85053a }, + { } +}; +MODULE_DEVICE_TABLE(i2c, pcf85053a_id); + +static const struct of_device_id pcf85053a_of_match[] = { + { .compatible = "nxp,pcf85053a", .data = &config_pcf85053a }, + {} +}; +MODULE_DEVICE_TABLE(of, pcf85053a_of_match); + +static struct i2c_driver pcf85053a_driver = { + .driver = { + .name = "rtc-pcf85053a", + .of_match_table = of_match_ptr(pcf85053a_of_match), + }, + .probe = pcf85053a_probe, + .id_table = pcf85053a_id, +}; + +module_i2c_driver(pcf85053a_driver); + +MODULE_AUTHOR("Pankit Garg <pankit.garg@nxp.com>"); +MODULE_DESCRIPTION("NXP pcf85053a RTC driver"); +MODULE_LICENSE("GPL"); -- 2.25.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v3 2/2] rtc: Add NXP PCF85053A driver support 2025-05-07 7:26 ` [PATCH v3 2/2] rtc: Add NXP PCF85053A driver support Pankit Garg @ 2025-07-23 20:35 ` Alexandre Belloni 0 siblings, 0 replies; 8+ messages in thread From: Alexandre Belloni @ 2025-07-23 20:35 UTC (permalink / raw) To: Pankit Garg Cc: linux-rtc, devicetree, linux-kernel, conor+dt, robh, vikash.bansal, priyanka.jain, daniel.aguirre, shashank.rebbapragada, aman.kumarpandey Hello, On 07/05/2025 12:56:18+0530, Pankit Garg wrote: > PCF85053A is i2c based RTC which supports timer and calendar > functionality. > > Features supported: > 1. Read/Write time > 2. Get/Set Alarm > 3. Wakeup Source > 4. Generate 32768Hz clock output > 5. Secondary i2c bus > > Signed-off-by: Daniel Aguirre <daniel.aguirre@nxp.com> > Signed-off-by: Pankit Garg <pankit.garg@nxp.com> > --- > V2 -> V3: Add MAINTAINERS file changes to this patch > V1 -> V2: no changes > > --- > MAINTAINERS | 6 + > drivers/rtc/Kconfig | 10 + > drivers/rtc/Makefile | 1 + > drivers/rtc/rtc-pcf85053a.c | 594 ++++++++++++++++++++++++++++++++++++ I don't think a should be part of the various names (filename, macros, structs, functions) as all the PCF85063 variants have the same register set. > +static int pcf85053a_set_alarm_mode(struct device *dev, bool on) > +{ > + struct pcf85053a *pcf85053a = dev_get_drvdata(dev); > + struct i2c_client *client = to_i2c_client(dev); You can remove this from most of the functions as they already get a struct device that uniquely identifies the device. > + unsigned int val; > + int err; > + > + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_CTRL, &val); > + if (err) > + return err; > + > + if (on) > + val |= PCF85053A_BIT_AIE; > + else > + val &= ~PCF85053A_BIT_AIE; > + > + val |= PCF85053A_BIT_CIE; > + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_CTRL, val); > + if (err < 0) { > + dev_err(&client->dev, "Unable to write PCF85053A_REG_CTRL\n"); Most of the error messages like this are not necessary because the only action for the user would be to restart the action and anyway, they probably won't ever be read by anyone on an embedded system. > + return err; > + } > + > + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_ST, &val); > + if (err) > + return err; > + > + val &= ~(PCF85053A_BIT_AF); > + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_ST, val); Maybe use regmap_update_bits ? > + if (err < 0) { > + dev_err(&client->dev, "Unable to write PCF85053A_REG_ST\n"); > + return err; > + } > + > + return 0; > +} > + > +static int pcf85053a_get_alarm_mode(struct device *dev, > + unsigned char *alarm_enable, unsigned char *alarm_flag) > +{ > + struct pcf85053a *pcf85053a = dev_get_drvdata(dev); > + struct i2c_client *client = to_i2c_client(dev); > + unsigned int val; > + int err; > + > + if (alarm_enable) { > + dev_dbg(&client->dev, "%s:PCF85053A_REG_CTRL\n", __func__); > + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_CTRL, &val); > + if (err) > + return err; > + *alarm_enable = val & PCF85053A_BIT_AIE; > + } > + > + if (alarm_flag) { > + dev_dbg(&client->dev, "%s:PCF85053A_REG_ST\n", __func__); > + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_ST, &val); > + if (err) > + return err; > + *alarm_flag = val & PCF85053A_BIT_AF; > + } > + > + dev_dbg(&client->dev, "%s:alarm_enable:%x alarm_flag:%x\n", > + __func__, *alarm_enable, *alarm_flag); > + > + return 0; > +} > + > +static irqreturn_t pcf85053a_irq(int irq, void *dev_id) > +{ > + struct pcf85053a *pcf85053a = i2c_get_clientdata(dev_id); > + struct i2c_client *client = pcf85053a->client; > + int err; > + unsigned char alarm_flag; > + unsigned char alarm_enable; > + > + err = pcf85053a_get_alarm_mode(&client->dev, &alarm_enable, &alarm_flag); > + if (err) > + return IRQ_NONE; > + > + if (alarm_flag) { You should probably test for !alarm_flag > + rtc_update_irq(pcf85053a->rtc, 1, RTC_IRQF | RTC_AF); > + pcf85053a_set_alarm_mode(&client->dev, 0); > + return IRQ_HANDLED; > + } > + > + return IRQ_NONE; > +} > + > +/* > + * In the routines that deal directly with the PCF85053A hardware, we use > + * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. > + */ > +static int pcf85053a_rtc_read_time(struct device *dev, struct rtc_time *tm) > +{ > + struct pcf85053a *pcf85053a = dev_get_drvdata(dev); > + struct i2c_client *client = to_i2c_client(dev); > + unsigned char regs[10]; > + unsigned int val; > + int err; > + > + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_ST, &val); > + if (err) > + return err; > + > + if (0 == (val & PCF85053A_REG_BAT_MASK)) { The 0 should be on the RHS > + dev_err(&client->dev, " BVL[2:0] value is 0x0 (Battery Voltage <= 1.7V), information is not reliable.\n"); > + return -EINVAL; > + } This is not correct, the battery may be empty but the time correct, you must rather check for ST and OF > + > + err = regmap_bulk_read(pcf85053a->regmap, PCF85053A_REG_SC, regs, > + sizeof(regs)); > + if (err) > + return err; > + > + tm->tm_sec = bcd2bin(regs[PCF85053A_REG_SC] & 0x7F); > + tm->tm_min = bcd2bin(regs[PCF85053A_REG_MN] & 0x7F); > + tm->tm_hour = bcd2bin(regs[PCF85053A_REG_HR] & 0x3F); > + tm->tm_wday = regs[PCF85053A_REG_DW] & 0x07; > + tm->tm_mday = bcd2bin(regs[PCF85053A_REG_DM] & 0x3F); > + tm->tm_mon = bcd2bin(regs[PCF85053A_REG_MO] & 0x1F) - 1; > + tm->tm_year = bcd2bin(regs[PCF85053A_REG_YR]) + 100; > + > + return 0; > +} > + > +static int pcf85053a_rtc_set_time(struct device *dev, struct rtc_time *tm) > +{ > + struct pcf85053a *pcf85053a = dev_get_drvdata(dev); > + struct i2c_client *client = to_i2c_client(dev); > + int err; > + > + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_SC, bin2bcd(tm->tm_sec)); > + if (err < 0) { > + dev_err(&client->dev, "Unable to write PCF85053A_REG_SC\n"); > + return err; > + } > + > + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_MN, bin2bcd(tm->tm_min)); > + if (err < 0) { > + dev_err(&client->dev, "Unable to write PCF85053A_REG_MN\n"); > + return err; > + } > + > + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_HR, bin2bcd(tm->tm_hour)); > + if (err < 0) { > + dev_err(&client->dev, "Unable to write PCF85053A_REG_HR\n"); > + return err; > + } > + > + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_DW, tm->tm_wday & 0x07); > + if (err < 0) { > + dev_err(&client->dev, "Unable to write PCF85053A_REG_DW\n"); > + return err; > + } > + > + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_DM, bin2bcd(tm->tm_mday)); > + if (err < 0) { > + dev_err(&client->dev, "Unable to write PCF85053A_REG_DM\n"); > + return err; > + } > + > + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_MO, bin2bcd(tm->tm_mon + 1)); > + if (err < 0) { > + dev_err(&client->dev, "Unable to write PCF85053A_REG_MO\n"); > + return err; > + } > + > + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_YR, bin2bcd(tm->tm_year - 100)); > + if (err < 0) { > + dev_err(&client->dev, "Unable to write PCF85053A_REG_YR\n"); > + return err; > + } For accurate timings, you must set ST, then the time registers and then clear ST, see 7.4.1.1 > + > + return err; > +} > + > +static int pcf85053a_irq_enable(struct device *dev, unsigned int enabled) > +{ > + dev_dbg(dev, "%s: alarm enable=%d\n", __func__, enabled); > + > + return pcf85053a_set_alarm_mode(dev, enabled); > +} > + > +static int pcf85053a_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) > +{ > + struct pcf85053a *pcf85053a = dev_get_drvdata(dev); > + int status; > + unsigned int val = 0; > + > + switch (cmd) { > + case RTC_VL_READ: > + status = regmap_read(pcf85053a->regmap, PCF85053A_REG_ST, &val); > + if (status) > + return status; > + > + if (!(status & PCF85053A_REG_BAT_MASK)) > + val |= RTC_VL_DATA_INVALID; You need to use RTC_VL_BACKUP_EMPTY, RTC_VL_DATA_INVALID would be for OF. You should also return RTC_VL_BACKUP_LOW for some threshold. > + > + return put_user(val, (unsigned int __user *)arg); > + > + default: > + return -ENOIOCTLCMD; > + } > +} > + > +#ifdef CONFIG_COMMON_CLK > +/* > + * Handling of the clkout > + */ > + > +#define clkout_hw_to_pcf85053a(_hw) container_of(_hw, struct pcf85053a, clkout_hw) > + > +static const int clkout_rates[] = { > + 32768, > + 1024, > + 32, > + 1, > +}; > + > +static unsigned long pcf85053a_clkout_recalc_rate(struct clk_hw *hw, > + unsigned long parent_rate) > +{ > + struct pcf85053a *pcf85053a = clkout_hw_to_pcf85053a(hw); > + int err; > + unsigned int val = 0; > + > + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_CLKO, &val); > + if (err) > + return 0; > + > + val &= PCF85053A_REG_CLKO_F_MASK; > + return clkout_rates[val]; > +} > + > +static long pcf85053a_clkout_round_rate(struct clk_hw *hw, unsigned long rate, > + unsigned long *prate) > +{ > + int i; > + > + for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) > + if (clkout_rates[i] <= rate) > + return clkout_rates[i]; > + > + return 0; > +} > + > +static int pcf85053a_clkout_set_rate(struct clk_hw *hw, unsigned long rate, > + unsigned long parent_rate) > +{ > + struct pcf85053a *pcf85053a = clkout_hw_to_pcf85053a(hw); > + int err, i; > + unsigned int val = 0; > + > + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_CLKO, &val); > + if (err) > + return err; > + > + for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) > + if (clkout_rates[i] == rate) { > + val &= ~PCF85053A_REG_CLKO_F_MASK; > + val |= i; > + return regmap_write(pcf85053a->regmap, PCF85053A_REG_CLKO, val); > + } > + > + return -EINVAL; > +} > + > +static int pcf85053a_clkout_control(struct clk_hw *hw, bool enable) > +{ > + struct pcf85053a *pcf85053a = clkout_hw_to_pcf85053a(hw); > + int err; > + unsigned int val = 0; > + > + val = PCF85053A_BIT_XCLK; > + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_ACC, val); > + if (err) > + return err; > + > + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_CLKO, &val); > + if (err) > + return err; > + > + if (enable) > + val |= PCF85053A_REG_CLKO_CKE; > + else > + val &= ~PCF85053A_REG_CLKO_CKE; > + > + return regmap_write(pcf85053a->regmap, PCF85053A_REG_CLKO, val); > +} > + > +static int pcf85053a_clkout_prepare(struct clk_hw *hw) > +{ > + return pcf85053a_clkout_control(hw, 1); > +} > + > +static void pcf85053a_clkout_unprepare(struct clk_hw *hw) > +{ > + pcf85053a_clkout_control(hw, 0); > +} > + > +static int pcf85053a_clkout_is_prepared(struct clk_hw *hw) > +{ > + struct pcf85053a *pcf85053a = clkout_hw_to_pcf85053a(hw); > + int err; > + unsigned int val = 0; > + > + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_CLKO, &val); > + if (err) > + return err; > + > + return val & PCF85053A_REG_CLKO_CKE; > +} > + > +static const struct clk_ops pcf85053a_clkout_ops = { > + .prepare = pcf85053a_clkout_prepare, > + .unprepare = pcf85053a_clkout_unprepare, > + .is_prepared = pcf85053a_clkout_is_prepared, > + .recalc_rate = pcf85053a_clkout_recalc_rate, > + .round_rate = pcf85053a_clkout_round_rate, Please use determine_rate instead, see https://lore.kernel.org/all/20250710-rtc-clk-round-rate-v1-0-33140bb2278e@redhat.com/ > + .set_rate = pcf85053a_clkout_set_rate, > +}; > + > +static struct clk *pcf85053a_clkout_register_clk(struct pcf85053a *pcf85053a) > +{ > + struct i2c_client *client = pcf85053a->client; > + struct device_node *node = client->dev.of_node; > + struct clk *clk; > + struct clk_init_data init; > + > + init.name = "pcf85053a-clkout"; > + init.ops = &pcf85053a_clkout_ops; > + init.flags = 0; > + init.parent_names = NULL; > + init.num_parents = 0; > + pcf85053a->clkout_hw.init = &init; > + > + /* optional override of the clockname */ > + of_property_read_string(node, "clock-output-names", &init.name); > + > + /* register the clock */ > + clk = devm_clk_register(&client->dev, &pcf85053a->clkout_hw); > + > + if (!IS_ERR(clk)) > + of_clk_add_provider(node, of_clk_src_simple_get, clk); > + > + return clk; > +} > +#endif > + > +static const struct rtc_class_ops pcf85053a_rtc_ops = { > + .read_time = pcf85053a_rtc_read_time, > + .set_time = pcf85053a_rtc_set_time, > + .read_alarm = pcf85053a_rtc_read_alarm, > + .set_alarm = pcf85053a_rtc_set_alarm, > + .alarm_irq_enable = pcf85053a_irq_enable, > + .ioctl = pcf85053a_ioctl, > +}; > + > +static const struct pcf85053a_config config_pcf85053a = { > + .regmap = { > + .reg_bits = 8, > + .val_bits = 8, > + .max_register = 0x1D, > + }, > + .has_alarms = 1, > +}; > + > +static int pcf85053a_probe(struct i2c_client *client) > +{ > + struct pcf85053a *pcf85053a; > + int err; > + unsigned int flags; > + const struct pcf85053a_config *config; > + > + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | > + I2C_FUNC_SMBUS_BYTE | > + I2C_FUNC_SMBUS_BLOCK_DATA)) > + return -ENODEV; > + > + pcf85053a = devm_kzalloc(&client->dev, sizeof(struct pcf85053a), > + GFP_KERNEL); > + if (!pcf85053a) > + return -ENOMEM; > + > + config = i2c_get_match_data(client); > + if (!config) > + return -ENODEV; > + > + pcf85053a->regmap = devm_regmap_init_i2c(client, &config->regmap); > + if (IS_ERR(pcf85053a->regmap)) > + return PTR_ERR(pcf85053a->regmap); > + > + i2c_set_clientdata(client, pcf85053a); > + > + pcf85053a->client = client; > + device_set_wakeup_capable(&client->dev, 1); > + > + err = regmap_read(pcf85053a->regmap, PCF85053A_REG_CTRL, &flags); > + if (err) { > + dev_err(&client->dev, "RTC chip is not present\n"); > + return err; > + } > + if (flags & PCF85053A_BIT_TWO) > + dev_dbg(&client->dev, "%s: PCF85053A_BIT_TWO is set\n", __func__); > + > + flags = PCF85053A_BIT_TWO; > + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_CTRL, flags); > + if (err) { > + dev_err(&client->dev, "Unable to write PCF85053A_REG_CTRL\n"); > + return err; > + } You must not overwrite anything in PCF85053A_REG_CTRL unless it is explicitly requested by the user. For example, ST must not be cleared unless the time is set, also how do you know TWO must be set? 12h vs 24h must be handled in reads. You seem to be setting the RTC in 12h mode and to set/read time in 24h mode which probably doesn't work properly. The interrupts should probably not be cleared, else you are going to missing interrupts across reboots. We probably want to clear DSM though. Wouldn't it be nicer to have the RTC in binary vs BCD? > + > + flags = 0; > + err = regmap_write(pcf85053a->regmap, PCF85053A_REG_ST, flags); > + if (err) { > + dev_err(&client->dev, "%s: write error\n", __func__); > + return err; > + } > + Ditto, you need to be smarter with this register. > + pcf85053a->rtc = devm_rtc_allocate_device(&client->dev); > + if (IS_ERR(pcf85053a->rtc)) > + return PTR_ERR(pcf85053a->rtc); > + > + pcf85053a->rtc->ops = &pcf85053a_rtc_ops; > + pcf85053a->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; > + pcf85053a->rtc->range_max = RTC_TIMESTAMP_END_2099; > + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, pcf85053a->rtc->features); > + clear_bit(RTC_FEATURE_ALARM, pcf85053a->rtc->features); > + > + if (config->has_alarms && client->irq > 0) { > + err = devm_request_threaded_irq(&client->dev, client->irq, > + NULL, pcf85053a_irq, > + IRQF_ONESHOT | IRQF_TRIGGER_FALLING, > + "pcf85053a", client); > + if (err) { > + dev_err(&client->dev, "unable to request IRQ %d\n", client->irq); > + } else { > + set_bit(RTC_FEATURE_ALARM, pcf85053a->rtc->features); > + device_init_wakeup(&client->dev, true); > + err = dev_pm_set_wake_irq(&client->dev, client->irq); > + if (err) > + dev_err(&client->dev, "failed to enable irq wake\n"); > + } > + } > + > +#ifdef CONFIG_COMMON_CLK > + /* register clk in common clk framework */ > + pcf85053a_clkout_register_clk(pcf85053a); > +#endif > + > + return devm_rtc_register_device(pcf85053a->rtc); > +} > + > +static const struct i2c_device_id pcf85053a_id[] = { > + { "pcf85053a", .driver_data = (kernel_ulong_t)&config_pcf85053a }, > + { } > +}; > +MODULE_DEVICE_TABLE(i2c, pcf85053a_id); > + > +static const struct of_device_id pcf85053a_of_match[] = { > + { .compatible = "nxp,pcf85053a", .data = &config_pcf85053a }, > + {} > +}; > +MODULE_DEVICE_TABLE(of, pcf85053a_of_match); > + > +static struct i2c_driver pcf85053a_driver = { > + .driver = { > + .name = "rtc-pcf85053a", > + .of_match_table = of_match_ptr(pcf85053a_of_match), > + }, > + .probe = pcf85053a_probe, > + .id_table = pcf85053a_id, > +}; > + > +module_i2c_driver(pcf85053a_driver); > + > +MODULE_AUTHOR("Pankit Garg <pankit.garg@nxp.com>"); > +MODULE_DESCRIPTION("NXP pcf85053a RTC driver"); > +MODULE_LICENSE("GPL"); > -- > 2.25.1 > -- Alexandre Belloni, co-owner and COO, Bootlin Embedded Linux and Kernel engineering https://bootlin.com ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support 2025-05-07 7:26 [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support Pankit Garg 2025-05-07 7:26 ` [PATCH v3 2/2] rtc: Add NXP PCF85053A driver support Pankit Garg @ 2025-05-07 14:22 ` Conor Dooley 2025-05-08 5:21 ` [EXT] " Pankit Garg 1 sibling, 1 reply; 8+ messages in thread From: Conor Dooley @ 2025-05-07 14:22 UTC (permalink / raw) To: Pankit Garg Cc: linux-rtc, devicetree, linux-kernel, conor+dt, robh, alexandre.belloni, vikash.bansal, priyanka.jain, daniel.aguirre, shashank.rebbapragada, aman.kumarpandey [-- Attachment #1: Type: text/plain, Size: 1182 bytes --] On Wed, May 07, 2025 at 12:56:17PM +0530, Pankit Garg wrote: > Add device tree bindings for NXP PCF85053a RTC chip. > > Signed-off-by: Pankit Garg <pankit.garg@nxp.com> > --- > V2 -> V3: Moved MAINTAINERS file changes to the driver patch > V1 -> V2: Handled dt-bindings by trivial-rtc.yaml You forgot to add my ack. Acked-by: Conor Dooley <conor.dooley@microchip.com> > > --- > Documentation/devicetree/bindings/rtc/trivial-rtc.yaml | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml > index 7330a7200831..47be7bbbfedd 100644 > --- a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml > +++ b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml > @@ -65,6 +65,8 @@ properties: > - microcrystal,rv8523 > # NXP LPC32xx SoC Real-time Clock > - nxp,lpc3220-rtc > + # NXP PCF85053A Real Time Clock Module with I2C-Bus > + - nxp,pcf85053a > # I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC > - ricoh,r2025sd > # I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC > -- > 2.25.1 > [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 228 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [EXT] Re: [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support 2025-05-07 14:22 ` [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support Conor Dooley @ 2025-05-08 5:21 ` Pankit Garg 2025-05-08 6:38 ` liudalin 2025-05-08 14:23 ` Conor Dooley 0 siblings, 2 replies; 8+ messages in thread From: Pankit Garg @ 2025-05-08 5:21 UTC (permalink / raw) To: Conor Dooley Cc: linux-rtc@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, conor+dt@kernel.org, robh@kernel.org, alexandre.belloni@bootlin.com, Vikash Bansal, Priyanka Jain, Daniel Aguirre, Shashank Rebbapragada, Aman Kumar Pandey > -----Original Message----- > From: Conor Dooley <conor@kernel.org> > Sent: Wednesday, May 7, 2025 7:53 PM > To: Pankit Garg <pankit.garg@nxp.com> > Cc: linux-rtc@vger.kernel.org; devicetree@vger.kernel.org; linux- > kernel@vger.kernel.org; conor+dt@kernel.org; robh@kernel.org; > alexandre.belloni@bootlin.com; Vikash Bansal <vikash.bansal@nxp.com>; > Priyanka Jain <priyanka.jain@nxp.com>; Daniel Aguirre > <daniel.aguirre@nxp.com>; Shashank Rebbapragada > <shashank.rebbapragada@nxp.com>; Aman Kumar Pandey > <aman.kumarpandey@nxp.com> > Subject: [EXT] Re: [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support > > On Wed, May 07, 2025 at 12:56:17PM +0530, Pankit Garg wrote: > > Add device tree bindings for NXP PCF85053a RTC chip. > > > > Signed-off-by: Pankit Garg <pankit.garg@nxp.com> > > --- > > V2 -> V3: Moved MAINTAINERS file changes to the driver patch > > V1 -> V2: Handled dt-bindings by trivial-rtc.yaml > > You forgot to add my ack. > Acked-by: Conor Dooley <conor.dooley@microchip.com> Yes, I forgot. I will add it in v4. Let me wait for more review/comments for couple of days. > > > > > --- > > Documentation/devicetree/bindings/rtc/trivial-rtc.yaml | 2 ++ > > 1 file changed, 2 insertions(+) > > > > diff --git a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml > b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml > > index 7330a7200831..47be7bbbfedd 100644 > > --- a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml > > +++ b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml > > @@ -65,6 +65,8 @@ properties: > > - microcrystal,rv8523 > > # NXP LPC32xx SoC Real-time Clock > > - nxp,lpc3220-rtc > > + # NXP PCF85053A Real Time Clock Module with I2C-Bus > > + - nxp,pcf85053a > > # I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC > > - ricoh,r2025sd > > # I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC > > -- > > 2.25.1 > > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RE: [EXT] Re: [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support 2025-05-08 5:21 ` [EXT] " Pankit Garg @ 2025-05-08 6:38 ` liudalin 2025-05-08 14:23 ` Conor Dooley 1 sibling, 0 replies; 8+ messages in thread From: liudalin @ 2025-05-08 6:38 UTC (permalink / raw) To: Pankit Garg, Conor Dooley Cc: linux-rtc, devicetree@vger.kernel.org, linux-kernel, conor+dt@kernel.org, robh@kernel.org, alexandre.belloni, Vikash Bansal, Priyanka Jain, Daniel Aguirre, Shashank Rebbapragada, Aman Kumar Pandey Hi Binbin: The described issue does not happened with or without the patch by test, as the interrupt is managed by acpi. The device info and test result are as follows. 1. Device info [系统未激活][root@mail test]# dmidecode -q BIOS Information Vendor: ZD-TECH Version: V09 Release Date: 06/15/2022 ROM Size: 8 MB Characteristics: PCI is supported BIOS is upgradeable BIOS shadowing is allowed Boot from CD is supported Selectable boot is supported BIOS ROM is socketed Serial services are supported (int 14h) USB legacy is supported Function key-initiated network boot is supported UEFI is supported BIOS Revision: 4.0 Firmware Revision: 0.4 System Information Manufacturer: GEIT Product Name: UT6000-LB5 Version: 1.0 Serial Number: TBD by OEM UUID: 00112233-4455-6677-8899-aabbccddeeff Wake-up Type: Power Switch SKU Number: Loongson_SKU Family: Type1Family Base Board Information Manufacturer: GEIT Product Name: GG-3A5000-02 Version: 1.0 Serial Number: Chassis Board Serial#To Be Filled By O.E.M Asset Tag: Type2 - Board Asset Tag Features: Board is a hosting board Board is replaceable Location In Chassis: Type2 - Board Chassis Location Type: Motherboard ... 2. The system exhibits a timeout error when waiting for alarm signal response without the patch. [系统未激活][root@mail test]# cat /proc/interrupts |grep acpi 21: 3 0 0 0 PCH PIC 1 acpi [系统未激活][root@mail test]# [系统未激活][root@mail test]# ./rtc01 RTC READ TEST: RTC READ TEST Passed Current RTC date/time is 8-5-2025, 05:50:05. RTC ALARM TEST :Alarm time set to 05:50:10. Waiting 5 seconds for the alarm... Timed out waiting for the alarm RTC UPDATE INTERRUPTS TEST : RTC_UIE_ON not supported RTC Tests Done! [系统未激活][root@mail test]# [系统未激活][root@mail test]# cat /proc/interrupts |grep acpi 21: 4 0 0 0 PCH PIC 1 acpi [系统未激活][root@mail test]# 3. There is no error with the patch applied and the interrupts are triggered ok [系统未激活][root@mail test]# cat /proc/interrupts |grep acpi 21: 0 0 0 0 PCH PIC 1 acpi [系统未激活][root@mail test]# [系统未激活][root@mail test]# ./rtc01 RTC READ TEST: RTC READ TEST Passed Current RTC date/time is 8-5-2025, 06:09:03. RTC ALARM TEST :Alarm time set to 06:09:08. Waiting 5 seconds for the alarm... Alarm rang. RTC ALARM TEST Passed RTC UPDATE INTERRUPTS TEST : RTC_UIE_ON not supported RTC Tests Done! [系统未激活][root@mail test]# [系统未激活][root@mail test]# cat /proc/interrupts |grep acpi 21: 1 0 0 0 PCH PIC 1 acpi [系统未激活][root@mail test]# From: Pankit Garg Date: 2025-05-08 13:21 To: Conor Dooley CC: linux-rtc@vger.kernel.org; devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; conor+dt@kernel.org; robh@kernel.org; alexandre.belloni@bootlin.com; Vikash Bansal; Priyanka Jain; Daniel Aguirre; Shashank Rebbapragada; Aman Kumar Pandey Subject: RE: [EXT] Re: [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support > -----Original Message----- > From: Conor Dooley <conor@kernel.org> > Sent: Wednesday, May 7, 2025 7:53 PM > To: Pankit Garg <pankit.garg@nxp.com> > Cc: linux-rtc@vger.kernel.org; devicetree@vger.kernel.org; linux- > kernel@vger.kernel.org; conor+dt@kernel.org; robh@kernel.org; > alexandre.belloni@bootlin.com; Vikash Bansal <vikash.bansal@nxp.com>; > Priyanka Jain <priyanka.jain@nxp.com>; Daniel Aguirre > <daniel.aguirre@nxp.com>; Shashank Rebbapragada > <shashank.rebbapragada@nxp.com>; Aman Kumar Pandey > <aman.kumarpandey@nxp.com> > Subject: [EXT] Re: [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support > > On Wed, May 07, 2025 at 12:56:17PM +0530, Pankit Garg wrote: > > Add device tree bindings for NXP PCF85053a RTC chip. > > > > Signed-off-by: Pankit Garg <pankit.garg@nxp.com> > > --- > > V2 -> V3: Moved MAINTAINERS file changes to the driver patch > > V1 -> V2: Handled dt-bindings by trivial-rtc.yaml > > You forgot to add my ack. > Acked-by: Conor Dooley <conor.dooley@microchip.com> Yes, I forgot. I will add it in v4. Let me wait for more review/comments for couple of days. > > > > > --- > > Documentation/devicetree/bindings/rtc/trivial-rtc.yaml | 2 ++ > > 1 file changed, 2 insertions(+) > > > > diff --git a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml > b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml > > index 7330a7200831..47be7bbbfedd 100644 > > --- a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml > > +++ b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml > > @@ -65,6 +65,8 @@ properties: > > - microcrystal,rv8523 > > # NXP LPC32xx SoC Real-time Clock > > - nxp,lpc3220-rtc > > + # NXP PCF85053A Real Time Clock Module with I2C-Bus > > + - nxp,pcf85053a > > # I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC > > - ricoh,r2025sd > > # I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC > > -- > > 2.25.1 > > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [EXT] Re: [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support 2025-05-08 5:21 ` [EXT] " Pankit Garg 2025-05-08 6:38 ` liudalin @ 2025-05-08 14:23 ` Conor Dooley 2025-06-09 7:07 ` Pankit Garg 1 sibling, 1 reply; 8+ messages in thread From: Conor Dooley @ 2025-05-08 14:23 UTC (permalink / raw) To: Pankit Garg Cc: linux-rtc@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, conor+dt@kernel.org, robh@kernel.org, alexandre.belloni@bootlin.com, Vikash Bansal, Priyanka Jain, Daniel Aguirre, Shashank Rebbapragada, Aman Kumar Pandey [-- Attachment #1: Type: text/plain, Size: 1346 bytes --] On Thu, May 08, 2025 at 05:21:47AM +0000, Pankit Garg wrote: > > > > -----Original Message----- > > From: Conor Dooley <conor@kernel.org> > > Sent: Wednesday, May 7, 2025 7:53 PM > > To: Pankit Garg <pankit.garg@nxp.com> > > Cc: linux-rtc@vger.kernel.org; devicetree@vger.kernel.org; linux- > > kernel@vger.kernel.org; conor+dt@kernel.org; robh@kernel.org; > > alexandre.belloni@bootlin.com; Vikash Bansal <vikash.bansal@nxp.com>; > > Priyanka Jain <priyanka.jain@nxp.com>; Daniel Aguirre > > <daniel.aguirre@nxp.com>; Shashank Rebbapragada > > <shashank.rebbapragada@nxp.com>; Aman Kumar Pandey > > <aman.kumarpandey@nxp.com> > > Subject: [EXT] Re: [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support > > > > On Wed, May 07, 2025 at 12:56:17PM +0530, Pankit Garg wrote: > > > Add device tree bindings for NXP PCF85053a RTC chip. > > > > > > Signed-off-by: Pankit Garg <pankit.garg@nxp.com> > > > --- > > > V2 -> V3: Moved MAINTAINERS file changes to the driver patch > > > V1 -> V2: Handled dt-bindings by trivial-rtc.yaml > > > > You forgot to add my ack. > > Acked-by: Conor Dooley <conor.dooley@microchip.com> > > Yes, I forgot. I will add it in v4. Let me wait for more review/comments for couple of days. And if you don't get comments, don't resend just for that, the maintainer will gather the tag. [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 228 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [EXT] Re: [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support 2025-05-08 14:23 ` Conor Dooley @ 2025-06-09 7:07 ` Pankit Garg 0 siblings, 0 replies; 8+ messages in thread From: Pankit Garg @ 2025-06-09 7:07 UTC (permalink / raw) To: Conor Dooley, linux-rtc@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, conor+dt@kernel.org, robh@kernel.org, alexandre.belloni@bootlin.com Cc: Vikash Bansal, Priyanka Jain, Daniel Aguirre, Shashank Rebbapragada, Aman Kumar Pandey > -----Original Message----- > From: Conor Dooley <conor@kernel.org> > Sent: Thursday, May 8, 2025 7:54 PM > To: Pankit Garg <pankit.garg@nxp.com> > Cc: linux-rtc@vger.kernel.org; devicetree@vger.kernel.org; linux- > kernel@vger.kernel.org; conor+dt@kernel.org; robh@kernel.org; > alexandre.belloni@bootlin.com; Vikash Bansal <vikash.bansal@nxp.com>; > Priyanka Jain <priyanka.jain@nxp.com>; Daniel Aguirre > <daniel.aguirre@nxp.com>; Shashank Rebbapragada > <shashank.rebbapragada@nxp.com>; Aman Kumar Pandey > <aman.kumarpandey@nxp.com> > Subject: Re: [EXT] Re: [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support > > On Thu, May 08, 2025 at 05:21:47AM +0000, Pankit Garg wrote: > > > > > > > -----Original Message----- > > > From: Conor Dooley <conor@kernel.org> > > > Sent: Wednesday, May 7, 2025 7:53 PM > > > To: Pankit Garg <pankit.garg@nxp.com> > > > Cc: linux-rtc@vger.kernel.org; devicetree@vger.kernel.org; linux- > > > kernel@vger.kernel.org; conor+dt@kernel.org; robh@kernel.org; > > > alexandre.belloni@bootlin.com; Vikash Bansal > > > <vikash.bansal@nxp.com>; Priyanka Jain <priyanka.jain@nxp.com>; > > > Daniel Aguirre <daniel.aguirre@nxp.com>; Shashank Rebbapragada > > > <shashank.rebbapragada@nxp.com>; Aman Kumar Pandey > > > <aman.kumarpandey@nxp.com> > > > Subject: [EXT] Re: [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a > > > support > > > > > > On Wed, May 07, 2025 at 12:56:17PM +0530, Pankit Garg wrote: > > > > Add device tree bindings for NXP PCF85053a RTC chip. > > > > > > > > Signed-off-by: Pankit Garg <pankit.garg@nxp.com> > > > > --- > > > > V2 -> V3: Moved MAINTAINERS file changes to the driver patch > > > > V1 -> V2: Handled dt-bindings by trivial-rtc.yaml > > > > > > You forgot to add my ack. > > > Acked-by: Conor Dooley <conor.dooley@microchip.com> > > > > Yes, I forgot. I will add it in v4. Let me wait for more review/comments for > couple of days. > > And if you don't get comments, don't resend just for that, the maintainer will > gather the tag. Since there wasn't any feedback for this patch, i want to send a gentle reminder ... Regards ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-07-23 20:35 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-05-07 7:26 [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support Pankit Garg 2025-05-07 7:26 ` [PATCH v3 2/2] rtc: Add NXP PCF85053A driver support Pankit Garg 2025-07-23 20:35 ` Alexandre Belloni 2025-05-07 14:22 ` [PATCH v3 1/2] dt-bindings: rtc: Add pcf85053a support Conor Dooley 2025-05-08 5:21 ` [EXT] " Pankit Garg 2025-05-08 6:38 ` liudalin 2025-05-08 14:23 ` Conor Dooley 2025-06-09 7:07 ` Pankit Garg
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).