[PATCH v1 0/3] Add pcf2131 rtc support

The patchset supports pcf2131 rtc. For the details, please check the patch commit log.
Joy Zou (3): configs: Enable RTC pcf2131 support imx: imx93_evk: add rtc pcf2131 drivers: rtc: add pcf2131 rtc driver
arch/arm/dts/imx93-11x11-evk-u-boot.dtsi | 8 + arch/arm/dts/imx93-11x11-evk.dts | 25 +++ arch/arm/dts/imx93.dtsi | 2 +- configs/imx93_11x11_evk_defconfig | 2 +- drivers/rtc/Kconfig | 10 ++ drivers/rtc/Makefile | 1 + drivers/rtc/pcf2131.c | 189 +++++++++++++++++++++++ 7 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 drivers/rtc/pcf2131.c

Enable CONFIG_RTC_PCF2131 configs to support pcf2131.
Disable CONFIG_RTC_EMULATION configs. The default rtc0 change into pcf2131.
Signed-off-by: Joy Zou joy.zou@nxp.com --- configs/imx93_11x11_evk_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configs/imx93_11x11_evk_defconfig b/configs/imx93_11x11_evk_defconfig index 4f8777161e..ccb6999369 100644 --- a/configs/imx93_11x11_evk_defconfig +++ b/configs/imx93_11x11_evk_defconfig @@ -13,6 +13,7 @@ CONFIG_DEFAULT_DEVICE_TREE="imx93-11x11-evk" CONFIG_SPL_TEXT_BASE=0x2049A000 CONFIG_TARGET_IMX93_11X11_EVK=y CONFIG_SYS_PROMPT="u-boot=> " +CONFIG_RTC_PCF2131=y CONFIG_SPL_SERIAL=y CONFIG_SPL_DRIVERS_MISC=y CONFIG_SPL_STACK=0x2051ddd0 @@ -107,7 +108,6 @@ CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y CONFIG_DM_RTC=y -CONFIG_RTC_EMULATION=y CONFIG_DM_SERIAL=y CONFIG_FSL_LPUART=y CONFIG_ULP_WATCHDOG=y

support rtc pcf2131 for imx93.
Signed-off-by: Joy Zou joy.zou@nxp.com --- arch/arm/dts/imx93-11x11-evk-u-boot.dtsi | 8 ++++++++ arch/arm/dts/imx93-11x11-evk.dts | 25 ++++++++++++++++++++++++ arch/arm/dts/imx93.dtsi | 2 +- 3 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/arch/arm/dts/imx93-11x11-evk-u-boot.dtsi b/arch/arm/dts/imx93-11x11-evk-u-boot.dtsi index 89e64344c6..4165a9b6b1 100644 --- a/arch/arm/dts/imx93-11x11-evk-u-boot.dtsi +++ b/arch/arm/dts/imx93-11x11-evk-u-boot.dtsi @@ -113,6 +113,10 @@ bootph-pre-ram; };
+&lpi2c3 { + u-boot,dm-spl; +}; + &{/soc@0/bus@44000000/i2c@44350000/pmic@25} { bootph-pre-ram; }; @@ -125,6 +129,10 @@ bootph-pre-ram; };
+&pinctrl_lpi2c3 { + u-boot,dm-spl; +}; + &fec { phy-reset-gpios = <&pcal6524 16 GPIO_ACTIVE_LOW>; phy-reset-duration = <15>; diff --git a/arch/arm/dts/imx93-11x11-evk.dts b/arch/arm/dts/imx93-11x11-evk.dts index b3a5a3d71e..421041757e 100644 --- a/arch/arm/dts/imx93-11x11-evk.dts +++ b/arch/arm/dts/imx93-11x11-evk.dts @@ -244,6 +244,24 @@ }; };
+&lpi2c3 { + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <400000>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pinctrl_lpi2c3>; + pinctrl-1 = <&pinctrl_lpi2c3>; + status = "okay"; + + pcf2131: rtc@53 { + compatible = "nxp,pcf2131"; + reg = <0x53>; + interrupt-parent = <&pcal6524>; + interrupts = <1 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; + }; +}; + &lpuart1 { /* console */ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; @@ -461,6 +479,13 @@ >; };
+ pinctrl_lpi2c3: lpi2c3grp { + fsl,pins = < + MX93_PAD_GPIO_IO28__LPI2C3_SDA 0x40000b9e + MX93_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e + >; + }; + pinctrl_pcal6524: pcal6524grp { fsl,pins = < MX93_PAD_CCM_CLKO2__GPIO3_IO27 0x31e diff --git a/arch/arm/dts/imx93.dtsi b/arch/arm/dts/imx93.dtsi index 28026ccecc..ac4b81c02f 100644 --- a/arch/arm/dts/imx93.dtsi +++ b/arch/arm/dts/imx93.dtsi @@ -319,7 +319,7 @@ reg = <0x42530000 0x10000>; interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX93_CLK_LPI2C3_GATE>, - <&clk IMX93_CLK_LPI2C3_GATE>; + <&clk IMX93_CLK_BUS_WAKEUP>; clock-names = "per", "ipg"; status = "disabled"; };

On 5/30/2023 9:41 AM, Joy Zou wrote:
Caution: This is an external email. Please take care when clicking links or opening attachments. When in doubt, report the message using the 'Report this email' button
support rtc pcf2131 for imx93.
Signed-off-by: Joy Zou joy.zou@nxp.com
arch/arm/dts/imx93-11x11-evk-u-boot.dtsi | 8 ++++++++ arch/arm/dts/imx93-11x11-evk.dts | 25 ++++++++++++++++++++++++ arch/arm/dts/imx93.dtsi | 2 +- 3 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/arch/arm/dts/imx93-11x11-evk-u-boot.dtsi b/arch/arm/dts/imx93-11x11-evk-u-boot.dtsi index 89e64344c6..4165a9b6b1 100644 --- a/arch/arm/dts/imx93-11x11-evk-u-boot.dtsi +++ b/arch/arm/dts/imx93-11x11-evk-u-boot.dtsi @@ -113,6 +113,10 @@ bootph-pre-ram; };
+&lpi2c3 {
u-boot,dm-spl;
+};
Do you need rtc in SPL stage or only in U-Boot proper?
- &{/soc@0/bus@44000000/i2c@44350000/pmic@25} { bootph-pre-ram; };
@@ -125,6 +129,10 @@ bootph-pre-ram; };
+&pinctrl_lpi2c3 {
u-boot,dm-spl;
+};
Ditto.
- &fec { phy-reset-gpios = <&pcal6524 16 GPIO_ACTIVE_LOW>; phy-reset-duration = <15>;
diff --git a/arch/arm/dts/imx93-11x11-evk.dts b/arch/arm/dts/imx93-11x11-evk.dts index b3a5a3d71e..421041757e 100644 --- a/arch/arm/dts/imx93-11x11-evk.dts +++ b/arch/arm/dts/imx93-11x11-evk.dts @@ -244,6 +244,24 @@ }; };
+&lpi2c3 {
#address-cells = <1>;
#size-cells = <0>;
clock-frequency = <400000>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&pinctrl_lpi2c3>;
pinctrl-1 = <&pinctrl_lpi2c3>;
status = "okay";
pcf2131: rtc@53 {
compatible = "nxp,pcf2131";
reg = <0x53>;
interrupt-parent = <&pcal6524>;
interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
status = "okay";
};
+};
- &lpuart1 { /* console */ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>;
@@ -461,6 +479,13 @@ >; };
pinctrl_lpi2c3: lpi2c3grp {
fsl,pins = <
MX93_PAD_GPIO_IO28__LPI2C3_SDA 0x40000b9e
MX93_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e
>;
};
pinctrl_pcal6524: pcal6524grp { fsl,pins = < MX93_PAD_CCM_CLKO2__GPIO3_IO27 0x31e
diff --git a/arch/arm/dts/imx93.dtsi b/arch/arm/dts/imx93.dtsi index 28026ccecc..ac4b81c02f 100644 --- a/arch/arm/dts/imx93.dtsi +++ b/arch/arm/dts/imx93.dtsi @@ -319,7 +319,7 @@ reg = <0x42530000 0x10000>; interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX93_CLK_LPI2C3_GATE>,
<&clk IMX93_CLK_LPI2C3_GATE>;
<&clk IMX93_CLK_BUS_WAKEUP>;
What is this change for?
Regards, Peng.
clock-names = "per", "ipg"; status = "disabled"; };
-- 2.37.1

-----Original Message----- From: Peng Fan (OSS) peng.fan@oss.nxp.com Sent: 2023年5月31日 9:37 To: Joy Zou joy.zou@nxp.com; Peng Fan peng.fan@nxp.com; Ye Li ye.li@nxp.com; sbabic@denx.de; festevam@gmail.com; sjg@chromium.org; saproj@gmail.com; judge.packham@gmail.com Cc: dl-uboot-imx uboot-imx@nxp.com; u-boot@lists.denx.de Subject: Re: [PATCH v1 2/3] imx: imx93_evk: add rtc pcf2131
On 5/30/2023 9:41 AM, Joy Zou wrote:
Caution: This is an external email. Please take care when clicking links or opening attachments. When in doubt, report the message using the 'Report this email' button
support rtc pcf2131 for imx93.
Signed-off-by: Joy Zou joy.zou@nxp.com
arch/arm/dts/imx93-11x11-evk-u-boot.dtsi | 8 ++++++++ arch/arm/dts/imx93-11x11-evk.dts | 25
++++++++++++++++++++++++
arch/arm/dts/imx93.dtsi | 2 +- 3 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/arch/arm/dts/imx93-11x11-evk-u-boot.dtsi b/arch/arm/dts/imx93-11x11-evk-u-boot.dtsi index 89e64344c6..4165a9b6b1 100644 --- a/arch/arm/dts/imx93-11x11-evk-u-boot.dtsi +++ b/arch/arm/dts/imx93-11x11-evk-u-boot.dtsi @@ -113,6 +113,10 @@ bootph-pre-ram; };
+&lpi2c3 {
u-boot,dm-spl;
+};
Do you need rtc in SPL stage or only in U-Boot proper?
only in U-Boot proper.
- &{/soc@0/bus@44000000/i2c@44350000/pmic@25} { bootph-pre-ram; };
@@ -125,6 +129,10 @@ bootph-pre-ram; };
+&pinctrl_lpi2c3 {
u-boot,dm-spl;
+};
Ditto.
only in U-Boot proper.
- &fec { phy-reset-gpios = <&pcal6524 16 GPIO_ACTIVE_LOW>; phy-reset-duration = <15>;
diff --git a/arch/arm/dts/imx93-11x11-evk.dts b/arch/arm/dts/imx93-11x11-evk.dts index b3a5a3d71e..421041757e 100644 --- a/arch/arm/dts/imx93-11x11-evk.dts +++ b/arch/arm/dts/imx93-11x11-evk.dts @@ -244,6 +244,24 @@ }; };
+&lpi2c3 {
#address-cells = <1>;
#size-cells = <0>;
clock-frequency = <400000>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&pinctrl_lpi2c3>;
pinctrl-1 = <&pinctrl_lpi2c3>;
status = "okay";
pcf2131: rtc@53 {
compatible = "nxp,pcf2131";
reg = <0x53>;
interrupt-parent = <&pcal6524>;
interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
status = "okay";
};
+};
&lpuart1 { /* console */ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; @@ -461,6 +479,13 @@ >; };
pinctrl_lpi2c3: lpi2c3grp {
fsl,pins = <
MX93_PAD_GPIO_IO28__LPI2C3_SDA
0x40000b9e
MX93_PAD_GPIO_IO29__LPI2C3_SCL
0x40000b9e
>;
};
pinctrl_pcal6524: pcal6524grp { fsl,pins = < MX93_PAD_CCM_CLKO2__GPIO3_IO27
0x31e
diff --git a/arch/arm/dts/imx93.dtsi b/arch/arm/dts/imx93.dtsi index 28026ccecc..ac4b81c02f 100644 --- a/arch/arm/dts/imx93.dtsi +++ b/arch/arm/dts/imx93.dtsi @@ -319,7 +319,7 @@ reg = <0x42530000 0x10000>; interrupts = <GIC_SPI 62
IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk
IMX93_CLK_LPI2C3_GATE>,
<&clk
IMX93_CLK_LPI2C3_GATE>;
<&clk
IMX93_CLK_BUS_WAKEUP>;
What is this change for?
Because the lpi2c3 ipg clk only need bus_wakeup_clk_root according to the imx93 RM. Thanks peng! BR Joy Zou
Regards, Peng.
clock-names = "per", "ipg"; status = "disabled"; };
-- 2.37.1

Adding support for pcf2131 RTC chip.
The pcf2131 is similar to the pcf2127. The driver support rtc register read/write by using rtc cmd and rtc date set/get by using date cmd.
Signed-off-by: Joy Zou joy.zou@nxp.com --- drivers/rtc/Kconfig | 10 +++ drivers/rtc/Makefile | 1 + drivers/rtc/pcf2131.c | 189 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 200 insertions(+) create mode 100644 drivers/rtc/pcf2131.c
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 23173139e0..507dc6cbcb 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -64,6 +64,16 @@ config RTC_PCF2127 has a selectable I2C-bus or SPI-bus, a backup battery switch-over circuit, a programmable watchdog function, a timestamp function, and many other features.
+config RTC_PCF2131 + bool "Enable PCF2131 driver" + depends on DM_RTC + help + The PCF2131 is a CMOS Real Time Clock (RTC) and calendar with an integrated + Temperature Compensated Crystal (Xtal) Oscillator (TCXO) and a 32.768 kHz quartz + crystal optimized for very high accuracy and very low power consumption. The PCF2127 + has a selectable I2C-bus or SPI-bus, a backup battery switch-over circuit, a + programmable watchdog function, a timestamp function, and many other features. + config RTC_DS1307 bool "Enable DS1307 driver" depends on DM_RTC diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 308fab8da9..722f2be98f 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_RTC_MV) += mvrtc.o obj-$(CONFIG_RTC_MXS) += mxsrtc.o obj-$(CONFIG_RTC_PCF8563) += pcf8563.o obj-$(CONFIG_RTC_PCF2127) += pcf2127.o +obj-$(CONFIG_RTC_PCF2131) += pcf2131.o obj-$(CONFIG_RTC_PL031) += pl031.o obj-$(CONFIG_RTC_PT7C4338) += pt7c4338.o obj-$(CONFIG_RTC_RV3028) += rv3028.o diff --git a/drivers/rtc/pcf2131.c b/drivers/rtc/pcf2131.c new file mode 100644 index 0000000000..8b9c17a2c8 --- /dev/null +++ b/drivers/rtc/pcf2131.c @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * The NXP PCF2131 RTC uboot driver. + * Copyright 2023 NXP + * Date & Time support for PCF2131 RTC + */ + +/* #define DEBUG */ + +#include <common.h> +#include <command.h> +#include <dm.h> +#include <i2c.h> +#include <log.h> +#include <rtc.h> + +#define PCF2131_REG_CTRL1 0x00 +#define PCF2131_BIT_CTRL1_STOP BIT(5) +#define PCF2131_BIT_CTRL1_100TH_S_DIS BIT(4) +#define PCF2131_REG_CTRL2 0x01 +#define PCF2131_REG_CTRL3 0x02 +#define PCF2131_REG_SR_RESET 0x05 +#define PCF2131_SR_VAL_Clr_Pres 0xa4 +#define PCF2131_REG_SC 0x07 +#define PCF2131_REG_MN 0x08 +#define PCF2131_REG_HR 0x09 +#define PCF2131_REG_DM 0x0a +#define PCF2131_REG_DW 0x0b +#define PCF2131_REG_MO 0x0c +#define PCF2131_REG_YR 0x0d + +static int pcf2131_rtc_read(struct udevice *dev, uint offset, u8 *buffer, uint len) +{ + struct dm_i2c_chip *chip = dev_get_parent_plat(dev); + struct i2c_msg msg; + int ret; + + /* Set the address of the start register to be read */ + ret = dm_i2c_write(dev, offset, NULL, 0); + if (ret < 0) + return ret; + + /* Read register's data */ + msg.addr = chip->chip_addr; + msg.flags |= I2C_M_RD; + msg.len = len; + msg.buf = buffer; + + return dm_i2c_xfer(dev, &msg, 1); +} + +static int pcf2131_rtc_lock(struct udevice *dev) +{ + int ret = 0; + uchar buf[6] = { PCF2131_REG_CTRL1 }; + + ret = pcf2131_rtc_read(dev, PCF2131_REG_CTRL1, buf, sizeof(buf)); + if (ret < 0) + return ret; + + buf[PCF2131_REG_CTRL1] |= PCF2131_BIT_CTRL1_STOP; + ret = dm_i2c_write(dev, PCF2131_REG_CTRL1, &buf[PCF2131_REG_CTRL1], 1); + if (ret < 0) + return ret; + + buf[PCF2131_REG_SR_RESET] = PCF2131_SR_VAL_Clr_Pres; + ret = dm_i2c_write(dev, PCF2131_REG_SR_RESET, &buf[PCF2131_REG_SR_RESET], 1); + return ret; +} + +static int pcf2131_rtc_unlock(struct udevice *dev) +{ + int ret = 0; + uchar buf[6] = { PCF2131_REG_CTRL1 }; + + ret = pcf2131_rtc_read(dev, PCF2131_REG_CTRL1, buf, sizeof(buf)); + if (ret < 0) + return ret; + + buf[PCF2131_REG_CTRL1] &= ~PCF2131_BIT_CTRL1_STOP; + ret = dm_i2c_write(dev, PCF2131_REG_CTRL1, &buf[PCF2131_REG_CTRL1], 1); + return ret; +} + +static int pcf2131_rtc_write(struct udevice *dev, uint offset, + const u8 *buffer, uint len) +{ + int ret = 0; + + ret = pcf2131_rtc_lock(dev); + if (ret < 0) + return ret; + + ret = dm_i2c_write(dev, offset, buffer, len); + if (ret < 0) + return ret; + + ret = pcf2131_rtc_unlock(dev); + return ret; +} + +static int pcf2131_rtc_set(struct udevice *dev, const struct rtc_time *tm) +{ + uchar buf[7] = {0}; + int i = 0, ret; + + /* hours, minutes and seconds */ + buf[i++] = bin2bcd(tm->tm_sec); + buf[i++] = bin2bcd(tm->tm_min); + buf[i++] = bin2bcd(tm->tm_hour); + buf[i++] = bin2bcd(tm->tm_mday); + buf[i++] = tm->tm_wday & 0x07; + + /* month, 1 - 12 */ + buf[i++] = bin2bcd(tm->tm_mon); + + /* year */ + buf[i++] = bin2bcd(tm->tm_year % 100); + + ret = pcf2131_rtc_lock(dev); + if (ret < 0) + return ret; + + /* write register's data */ + ret = dm_i2c_write(dev, PCF2131_REG_SC, buf, i); + if (ret < 0) + return ret; + + ret = pcf2131_rtc_unlock(dev); + return ret; +} + +static int pcf2131_rtc_get(struct udevice *dev, struct rtc_time *tm) +{ + int ret = 0; + uchar buf[16] = { PCF2131_REG_CTRL1 }; + + ret = pcf2131_rtc_read(dev, PCF2131_REG_CTRL1, buf, sizeof(buf)); + if (ret < 0) + return ret; + + if (buf[PCF2131_REG_CTRL3] & 0x04) + puts("### Warning: RTC Low Voltage - date/time not reliable\n"); + + tm->tm_sec = bcd2bin(buf[PCF2131_REG_SC] & 0x7F); + tm->tm_min = bcd2bin(buf[PCF2131_REG_MN] & 0x7F); + tm->tm_hour = bcd2bin(buf[PCF2131_REG_HR] & 0x3F); + tm->tm_mday = bcd2bin(buf[PCF2131_REG_DM] & 0x3F); + tm->tm_mon = bcd2bin(buf[PCF2131_REG_MO] & 0x1F); + tm->tm_year = bcd2bin(buf[PCF2131_REG_YR]) + 1900; + if (tm->tm_year < 1970) + tm->tm_year += 100; /* assume we are in 1970...2069 */ + tm->tm_wday = buf[PCF2131_REG_DW] & 0x07; + tm->tm_yday = 0; + tm->tm_isdst = 0; + + debug("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + + return ret; +} + +static int pcf2131_rtc_reset(struct udevice *dev) +{ + /*Doing nothing here*/ + + return 0; +} + +static const struct rtc_ops pcf2131_rtc_ops = { + .get = pcf2131_rtc_get, + .set = pcf2131_rtc_set, + .reset = pcf2131_rtc_reset, + .read = pcf2131_rtc_read, + .write = pcf2131_rtc_write, +}; + +static const struct udevice_id pcf2131_rtc_ids[] = { + { .compatible = "nxp,pcf2131" }, + { } +}; + +U_BOOT_DRIVER(rtc_pcf2131) = { + .name = "rtc-pcf2131", + .id = UCLASS_RTC, + .of_match = pcf2131_rtc_ids, + .ops = &pcf2131_rtc_ops, +};

On 5/30/2023 9:41 AM, Joy Zou wrote:
Caution: This is an external email. Please take care when clicking links or opening attachments. When in doubt, report the message using the 'Report this email' button
Adding support for pcf2131 RTC chip.
The pcf2131 is similar to the pcf2127. The driver support rtc register read/write by using rtc cmd and rtc date set/get by using date cmd.
Signed-off-by: Joy Zou joy.zou@nxp.com
drivers/rtc/Kconfig | 10 +++ drivers/rtc/Makefile | 1 + drivers/rtc/pcf2131.c | 189 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 200 insertions(+) create mode 100644 drivers/rtc/pcf2131.c
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 23173139e0..507dc6cbcb 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -64,6 +64,16 @@ config RTC_PCF2127 has a selectable I2C-bus or SPI-bus, a backup battery switch-over circuit, a programmable watchdog function, a timestamp function, and many other features.
+config RTC_PCF2131
bool "Enable PCF2131 driver"
depends on DM_RTC
help
The PCF2131 is a CMOS Real Time Clock (RTC) and calendar with an integrated
Temperature Compensated Crystal (Xtal) Oscillator (TCXO) and a 32.768 kHz quartz
crystal optimized for very high accuracy and very low power consumption. The PCF2127
has a selectable I2C-bus or SPI-bus, a backup battery switch-over circuit, a
programmable watchdog function, a timestamp function, and many other features.
- config RTC_DS1307 bool "Enable DS1307 driver" depends on DM_RTC
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 308fab8da9..722f2be98f 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_RTC_MV) += mvrtc.o obj-$(CONFIG_RTC_MXS) += mxsrtc.o obj-$(CONFIG_RTC_PCF8563) += pcf8563.o obj-$(CONFIG_RTC_PCF2127) += pcf2127.o +obj-$(CONFIG_RTC_PCF2131) += pcf2131.o obj-$(CONFIG_RTC_PL031) += pl031.o obj-$(CONFIG_RTC_PT7C4338) += pt7c4338.o obj-$(CONFIG_RTC_RV3028) += rv3028.o diff --git a/drivers/rtc/pcf2131.c b/drivers/rtc/pcf2131.c new file mode 100644 index 0000000000..8b9c17a2c8 --- /dev/null +++ b/drivers/rtc/pcf2131.c @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- The NXP PCF2131 RTC uboot driver.
- Copyright 2023 NXP
- Date & Time support for PCF2131 RTC
- */
+/* #define DEBUG */
Drop this line.
+#include <common.h> +#include <command.h> +#include <dm.h> +#include <i2c.h> +#include <log.h> +#include <rtc.h>
+#define PCF2131_REG_CTRL1 0x00 +#define PCF2131_BIT_CTRL1_STOP BIT(5) +#define PCF2131_BIT_CTRL1_100TH_S_DIS BIT(4) +#define PCF2131_REG_CTRL2 0x01 +#define PCF2131_REG_CTRL3 0x02 +#define PCF2131_REG_SR_RESET 0x05 +#define PCF2131_SR_VAL_Clr_Pres 0xa4 +#define PCF2131_REG_SC 0x07 +#define PCF2131_REG_MN 0x08 +#define PCF2131_REG_HR 0x09 +#define PCF2131_REG_DM 0x0a +#define PCF2131_REG_DW 0x0b +#define PCF2131_REG_MO 0x0c +#define PCF2131_REG_YR 0x0d
+static int pcf2131_rtc_read(struct udevice *dev, uint offset, u8 *buffer, uint len) +{
struct dm_i2c_chip *chip = dev_get_parent_plat(dev);
struct i2c_msg msg;
int ret;
/* Set the address of the start register to be read */
ret = dm_i2c_write(dev, offset, NULL, 0);
if (ret < 0)
return ret;
/* Read register's data */
msg.addr = chip->chip_addr;
msg.flags |= I2C_M_RD;
msg.len = len;
msg.buf = buffer;
return dm_i2c_xfer(dev, &msg, 1);
+}
+static int pcf2131_rtc_lock(struct udevice *dev) +{
int ret = 0;
uchar buf[6] = { PCF2131_REG_CTRL1 };
ret = pcf2131_rtc_read(dev, PCF2131_REG_CTRL1, buf, sizeof(buf));
if (ret < 0)
return ret;
buf[PCF2131_REG_CTRL1] |= PCF2131_BIT_CTRL1_STOP;
ret = dm_i2c_write(dev, PCF2131_REG_CTRL1, &buf[PCF2131_REG_CTRL1], 1);
if (ret < 0)
return ret;
buf[PCF2131_REG_SR_RESET] = PCF2131_SR_VAL_Clr_Pres;
ret = dm_i2c_write(dev, PCF2131_REG_SR_RESET, &buf[PCF2131_REG_SR_RESET], 1);
return ret;
Just "return dm_i2c_write..." is ok.
+}
+static int pcf2131_rtc_unlock(struct udevice *dev) +{
int ret = 0;
uchar buf[6] = { PCF2131_REG_CTRL1 };
ret = pcf2131_rtc_read(dev, PCF2131_REG_CTRL1, buf, sizeof(buf));
if (ret < 0)
return ret;
buf[PCF2131_REG_CTRL1] &= ~PCF2131_BIT_CTRL1_STOP;
ret = dm_i2c_write(dev, PCF2131_REG_CTRL1, &buf[PCF2131_REG_CTRL1], 1);
return ret;
Ditto.
+}
+static int pcf2131_rtc_write(struct udevice *dev, uint offset,
const u8 *buffer, uint len)
+{
int ret = 0;
ret = pcf2131_rtc_lock(dev);
if (ret < 0)
return ret;
ret = dm_i2c_write(dev, offset, buffer, len);
if (ret < 0)
return ret;
ret = pcf2131_rtc_unlock(dev);
return ret;
Ditto.
+}
+static int pcf2131_rtc_set(struct udevice *dev, const struct rtc_time *tm) +{ > + uchar buf[7] = {0};
No need init is to 0?
int i = 0, ret;
/* hours, minutes and seconds */
buf[i++] = bin2bcd(tm->tm_sec);
buf[i++] = bin2bcd(tm->tm_min);
buf[i++] = bin2bcd(tm->tm_hour);
buf[i++] = bin2bcd(tm->tm_mday);
buf[i++] = tm->tm_wday & 0x07;
/* month, 1 - 12 */
buf[i++] = bin2bcd(tm->tm_mon);
/* year */
buf[i++] = bin2bcd(tm->tm_year % 100);
ret = pcf2131_rtc_lock(dev);
if (ret < 0)
return ret;
/* write register's data */
ret = dm_i2c_write(dev, PCF2131_REG_SC, buf, i);
if (ret < 0)
return ret;
ret = pcf2131_rtc_unlock(dev);
return ret;
Just "return pfc2131_rtc_unlock..." is ok.
+}
+static int pcf2131_rtc_get(struct udevice *dev, struct rtc_time *tm) +{
int ret = 0;
uchar buf[16] = { PCF2131_REG_CTRL1 };
No need initialize buf?
ret = pcf2131_rtc_read(dev, PCF2131_REG_CTRL1, buf, sizeof(buf));
if (ret < 0)
return ret;
if (buf[PCF2131_REG_CTRL3] & 0x04)
puts("### Warning: RTC Low Voltage - date/time not reliable\n");
tm->tm_sec = bcd2bin(buf[PCF2131_REG_SC] & 0x7F);
tm->tm_min = bcd2bin(buf[PCF2131_REG_MN] & 0x7F);
tm->tm_hour = bcd2bin(buf[PCF2131_REG_HR] & 0x3F);
tm->tm_mday = bcd2bin(buf[PCF2131_REG_DM] & 0x3F);
tm->tm_mon = bcd2bin(buf[PCF2131_REG_MO] & 0x1F);
tm->tm_year = bcd2bin(buf[PCF2131_REG_YR]) + 1900;
if (tm->tm_year < 1970)
tm->tm_year += 100; /* assume we are in 1970...2069 */
tm->tm_wday = buf[PCF2131_REG_DW] & 0x07;
tm->tm_yday = 0;
tm->tm_isdst = 0;
debug("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
return ret;
+}
+static int pcf2131_rtc_reset(struct udevice *dev) +{
/*Doing nothing here*/
return 0;
+}
+static const struct rtc_ops pcf2131_rtc_ops = {
.get = pcf2131_rtc_get,
.set = pcf2131_rtc_set,
.reset = pcf2131_rtc_reset,
.read = pcf2131_rtc_read,
.write = pcf2131_rtc_write,
+};
+static const struct udevice_id pcf2131_rtc_ids[] = {
{ .compatible = "nxp,pcf2131" },
{ }
+};
+U_BOOT_DRIVER(rtc_pcf2131) = {
.name = "rtc-pcf2131",
.id = UCLASS_RTC,
.of_match = pcf2131_rtc_ids,
.ops = &pcf2131_rtc_ops,
+};
2.37.1
Regards, Peng.

-----Original Message----- From: Peng Fan (OSS) peng.fan@oss.nxp.com Sent: 2023年5月31日 9:35 To: Joy Zou joy.zou@nxp.com; Peng Fan peng.fan@nxp.com; Ye Li ye.li@nxp.com; sbabic@denx.de; festevam@gmail.com; sjg@chromium.org; saproj@gmail.com; judge.packham@gmail.com Cc: dl-uboot-imx uboot-imx@nxp.com; u-boot@lists.denx.de Subject: Re: [PATCH v1 3/3] drivers: rtc: add pcf2131 rtc driver
On 5/30/2023 9:41 AM, Joy Zou wrote:
Caution: This is an external email. Please take care when clicking links or opening attachments. When in doubt, report the message using the 'Report this email' button
Adding support for pcf2131 RTC chip.
The pcf2131 is similar to the pcf2127. The driver support rtc register read/write by using rtc cmd and rtc date set/get by using date cmd.
Signed-off-by: Joy Zou joy.zou@nxp.com
drivers/rtc/Kconfig | 10 +++ drivers/rtc/Makefile | 1 + drivers/rtc/pcf2131.c | 189
++++++++++++++++++++++++++++++++++++++++++
3 files changed, 200 insertions(+) create mode 100644 drivers/rtc/pcf2131.c
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 23173139e0..507dc6cbcb 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -64,6 +64,16 @@ config RTC_PCF2127 has a selectable I2C-bus or SPI-bus, a backup battery
switch-over circuit, a
programmable watchdog function, a timestamp function, and
many other features.
+config RTC_PCF2131
bool "Enable PCF2131 driver"
depends on DM_RTC
help
The PCF2131 is a CMOS Real Time Clock (RTC) and calendar with
an integrated
Temperature Compensated Crystal (Xtal) Oscillator (TCXO) and a
32.768 kHz quartz
crystal optimized for very high accuracy and very low power
consumption. The PCF2127
has a selectable I2C-bus or SPI-bus, a backup battery switch-over
circuit, a
programmable watchdog function, a timestamp function, and
many other features.
- config RTC_DS1307 bool "Enable DS1307 driver" depends on DM_RTC
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 308fab8da9..722f2be98f 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_RTC_MV) += mvrtc.o obj-$(CONFIG_RTC_MXS) += mxsrtc.o obj-$(CONFIG_RTC_PCF8563) += pcf8563.o obj-$(CONFIG_RTC_PCF2127) += pcf2127.o +obj-$(CONFIG_RTC_PCF2131) += pcf2131.o obj-$(CONFIG_RTC_PL031) += pl031.o obj-$(CONFIG_RTC_PT7C4338) += pt7c4338.o obj-$(CONFIG_RTC_RV3028) += rv3028.o diff --git a/drivers/rtc/pcf2131.c b/drivers/rtc/pcf2131.c new file mode 100644 index 0000000000..8b9c17a2c8 --- /dev/null +++ b/drivers/rtc/pcf2131.c @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- The NXP PCF2131 RTC uboot driver.
- Copyright 2023 NXP
- Date & Time support for PCF2131 RTC */
+/* #define DEBUG */
Drop this line.
Okay. Have dropped in patch v2.
+#include <common.h> +#include <command.h> +#include <dm.h> +#include <i2c.h> +#include <log.h> +#include <rtc.h>
+#define PCF2131_REG_CTRL1 0x00 +#define PCF2131_BIT_CTRL1_STOP BIT(5) +#define PCF2131_BIT_CTRL1_100TH_S_DIS BIT(4) +#define PCF2131_REG_CTRL2 0x01 +#define PCF2131_REG_CTRL3 0x02 +#define PCF2131_REG_SR_RESET 0x05 +#define PCF2131_SR_VAL_Clr_Pres 0xa4 +#define PCF2131_REG_SC 0x07 +#define PCF2131_REG_MN 0x08 +#define PCF2131_REG_HR 0x09 +#define PCF2131_REG_DM 0x0a +#define PCF2131_REG_DW 0x0b +#define PCF2131_REG_MO 0x0c +#define PCF2131_REG_YR 0x0d
+static int pcf2131_rtc_read(struct udevice *dev, uint offset, u8 +*buffer, uint len) {
struct dm_i2c_chip *chip = dev_get_parent_plat(dev);
struct i2c_msg msg;
int ret;
/* Set the address of the start register to be read */
ret = dm_i2c_write(dev, offset, NULL, 0);
if (ret < 0)
return ret;
/* Read register's data */
msg.addr = chip->chip_addr;
msg.flags |= I2C_M_RD;
msg.len = len;
msg.buf = buffer;
return dm_i2c_xfer(dev, &msg, 1); }
+static int pcf2131_rtc_lock(struct udevice *dev) {
int ret = 0;
uchar buf[6] = { PCF2131_REG_CTRL1 };
ret = pcf2131_rtc_read(dev, PCF2131_REG_CTRL1, buf, sizeof(buf));
if (ret < 0)
return ret;
buf[PCF2131_REG_CTRL1] |= PCF2131_BIT_CTRL1_STOP;
ret = dm_i2c_write(dev, PCF2131_REG_CTRL1,
&buf[PCF2131_REG_CTRL1], 1);
if (ret < 0)
return ret;
buf[PCF2131_REG_SR_RESET] = PCF2131_SR_VAL_Clr_Pres;
ret = dm_i2c_write(dev, PCF2131_REG_SR_RESET,
&buf[PCF2131_REG_SR_RESET], 1);
return ret;
Just "return dm_i2c_write..." is ok.
Okay. Have changed in patch v2.
+}
+static int pcf2131_rtc_unlock(struct udevice *dev) {
int ret = 0;
uchar buf[6] = { PCF2131_REG_CTRL1 };
ret = pcf2131_rtc_read(dev, PCF2131_REG_CTRL1, buf, sizeof(buf));
if (ret < 0)
return ret;
buf[PCF2131_REG_CTRL1] &= ~PCF2131_BIT_CTRL1_STOP;
ret = dm_i2c_write(dev, PCF2131_REG_CTRL1,
&buf[PCF2131_REG_CTRL1], 1);
return ret;
Ditto.
Have changed in patch v2.
+}
+static int pcf2131_rtc_write(struct udevice *dev, uint offset,
const u8 *buffer, uint len) {
int ret = 0;
ret = pcf2131_rtc_lock(dev);
if (ret < 0)
return ret;
ret = dm_i2c_write(dev, offset, buffer, len);
if (ret < 0)
return ret;
ret = pcf2131_rtc_unlock(dev);
return ret;
Ditto.
Have changed in patch v2.
+}
+static int pcf2131_rtc_set(struct udevice *dev, const struct rtc_time *tm) +{ > + uchar buf[7] = {0};
No need init is to 0?
Have deleted the unnecessary initialization in patch v2
int i = 0, ret;
/* hours, minutes and seconds */
buf[i++] = bin2bcd(tm->tm_sec);
buf[i++] = bin2bcd(tm->tm_min);
buf[i++] = bin2bcd(tm->tm_hour);
buf[i++] = bin2bcd(tm->tm_mday);
buf[i++] = tm->tm_wday & 0x07;
/* month, 1 - 12 */
buf[i++] = bin2bcd(tm->tm_mon);
/* year */
buf[i++] = bin2bcd(tm->tm_year % 100);
ret = pcf2131_rtc_lock(dev);
if (ret < 0)
return ret;
/* write register's data */
ret = dm_i2c_write(dev, PCF2131_REG_SC, buf, i);
if (ret < 0)
return ret;
ret = pcf2131_rtc_unlock(dev);
return ret;
Just "return pfc2131_rtc_unlock..." is ok.
Have changed in patch v2.
+}
+static int pcf2131_rtc_get(struct udevice *dev, struct rtc_time *tm) +{
int ret = 0;
uchar buf[16] = { PCF2131_REG_CTRL1 };
No need initialize buf?
Have deleted the unnecessary initialization in patch v2. Thanks peng! BR Joy Zou
ret = pcf2131_rtc_read(dev, PCF2131_REG_CTRL1, buf, sizeof(buf));
if (ret < 0)
return ret;
if (buf[PCF2131_REG_CTRL3] & 0x04)
puts("### Warning: RTC Low Voltage - date/time not
- reliable\n");
tm->tm_sec = bcd2bin(buf[PCF2131_REG_SC] & 0x7F);
tm->tm_min = bcd2bin(buf[PCF2131_REG_MN] & 0x7F);
tm->tm_hour = bcd2bin(buf[PCF2131_REG_HR] & 0x3F);
tm->tm_mday = bcd2bin(buf[PCF2131_REG_DM] & 0x3F);
tm->tm_mon = bcd2bin(buf[PCF2131_REG_MO] & 0x1F);
tm->tm_year = bcd2bin(buf[PCF2131_REG_YR]) + 1900;
if (tm->tm_year < 1970)
tm->tm_year += 100; /* assume we are in
1970...2069 */
tm->tm_wday = buf[PCF2131_REG_DW] & 0x07;
tm->tm_yday = 0;
tm->tm_isdst = 0;
debug("Get DATE: %4d-%02d-%02d (wday=%d)
TIME: %2d:%02d:%02d\n",
tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
return ret;
+}
+static int pcf2131_rtc_reset(struct udevice *dev) {
/*Doing nothing here*/
return 0;
+}
+static const struct rtc_ops pcf2131_rtc_ops = {
.get = pcf2131_rtc_get,
.set = pcf2131_rtc_set,
.reset = pcf2131_rtc_reset,
.read = pcf2131_rtc_read,
.write = pcf2131_rtc_write,
+};
+static const struct udevice_id pcf2131_rtc_ids[] = {
{ .compatible = "nxp,pcf2131" },
{ }
+};
+U_BOOT_DRIVER(rtc_pcf2131) = {
.name = "rtc-pcf2131",
.id = UCLASS_RTC,
.of_match = pcf2131_rtc_ids,
.ops = &pcf2131_rtc_ops,
+};
2.37.1
Regards, Peng.

On 5/30/2023 9:41 AM, Joy Zou wrote:
Caution: This is an external email. Please take care when clicking links or opening attachments. When in doubt, report the message using the 'Report this email' button
The patchset supports pcf2131 rtc. For the details, please check the patch commit log.
Joy Zou (3): configs: Enable RTC pcf2131 support imx: imx93_evk: add rtc pcf2131 drivers: rtc: add pcf2131 rtc driver
Please reorder your patches, with drivers as 1st, imx as 2nd, configs as 3rd to avoid bisect issue.
Thanks, Peng.
arch/arm/dts/imx93-11x11-evk-u-boot.dtsi | 8 + arch/arm/dts/imx93-11x11-evk.dts | 25 +++ arch/arm/dts/imx93.dtsi | 2 +- configs/imx93_11x11_evk_defconfig | 2 +- drivers/rtc/Kconfig | 10 ++ drivers/rtc/Makefile | 1 + drivers/rtc/pcf2131.c | 189 +++++++++++++++++++++++ 7 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 drivers/rtc/pcf2131.c
-- 2.37.1

-----Original Message----- From: Peng Fan (OSS) peng.fan@oss.nxp.com Sent: 2023年5月31日 9:38 To: Joy Zou joy.zou@nxp.com; Peng Fan peng.fan@nxp.com; Ye Li ye.li@nxp.com; sbabic@denx.de; festevam@gmail.com; sjg@chromium.org; saproj@gmail.com; judge.packham@gmail.com Cc: dl-uboot-imx uboot-imx@nxp.com; u-boot@lists.denx.de Subject: Re: [PATCH v1 0/3] Add pcf2131 rtc support
On 5/30/2023 9:41 AM, Joy Zou wrote:
Caution: This is an external email. Please take care when clicking links or opening attachments. When in doubt, report the message using the 'Report this email' button
The patchset supports pcf2131 rtc. For the details, please check the patch commit log.
Joy Zou (3): configs: Enable RTC pcf2131 support imx: imx93_evk: add rtc pcf2131 drivers: rtc: add pcf2131 rtc driver
Please reorder your patches, with drivers as 1st, imx as 2nd, configs as 3rd to avoid bisect issue.
Have reordered the patchset. Thanks peng! BR Joy Zou
Thanks, Peng.
arch/arm/dts/imx93-11x11-evk-u-boot.dtsi | 8 + arch/arm/dts/imx93-11x11-evk.dts | 25 +++ arch/arm/dts/imx93.dtsi | 2 +- configs/imx93_11x11_evk_defconfig | 2 +- drivers/rtc/Kconfig | 10 ++ drivers/rtc/Makefile | 1 + drivers/rtc/pcf2131.c | 189
+++++++++++++++++++++++
7 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 drivers/rtc/pcf2131.c
-- 2.37.1
participants (2)
-
Joy Zou
-
Peng Fan