From 00491a30b1a4170b6cdd8f563828b6a55cd6e510 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Thu, 23 Feb 2023 07:03:47 +0100 Subject: powerpc/mpc85xx: disable legacy format booting disable CONFIG_LEGACY_IMAGE_FORMAT so prevent of booting not signed fitimages. Signed-off-by: Heiko Schocher --- configs/socrates_defconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'configs') diff --git a/configs/socrates_defconfig b/configs/socrates_defconfig index 24655131a8a..df8b31b4e7b 100644 --- a/configs/socrates_defconfig +++ b/configs/socrates_defconfig @@ -18,7 +18,6 @@ CONFIG_SYS_MONITOR_LEN=786432 CONFIG_FIT=y CONFIG_FIT_SIGNATURE=y CONFIG_FIT_VERBOSE=y -CONFIG_LEGACY_IMAGE_FORMAT=y CONFIG_OF_BOARD_SETUP=y CONFIG_BOOTDELAY=1 CONFIG_AUTOBOOT_KEYED=y -- cgit v1.3.1 From 447dfbc0638f65accaeba1afa3b33840bdb46b6e Mon Sep 17 00:00:00 2001 From: Stephen Carlson Date: Fri, 10 Mar 2023 11:07:15 -0800 Subject: test: Add test for new command pci_mps Adds a test for the new pci_mps command to ensure that it can set the Maximum Payload Size (MPS) of all devices to 256 bytes in the sandbox environment. Enables the pci_mps command in the sandbox environment so that this test can be run. Signed-off-by: Stephen Carlson --- MAINTAINERS | 6 ++++++ configs/sandbox_defconfig | 1 + include/test/suites.h | 2 ++ test/cmd/Makefile | 3 +++ test/cmd/pci_mps.c | 42 ++++++++++++++++++++++++++++++++++++++++++ test/cmd_ut.c | 6 ++++++ 6 files changed, 60 insertions(+) create mode 100644 test/cmd/pci_mps.c (limited to 'configs') diff --git a/MAINTAINERS b/MAINTAINERS index 91d40ea4b6e..d2e245e5e90 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1249,6 +1249,12 @@ M: Heiko Schocher S: Maintained F: drivers/pci/pci_mpc85xx.c +PCI MPS +M: Stephen Carlson +S: Maintained +F: cmd/pci_mps.c +F: test/cmd/pci_mps.c + POWER M: Jaehoon Chung S: Maintained diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index b0f588da32e..2141c3d4698 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -78,6 +78,7 @@ CONFIG_CMD_MMC=y CONFIG_CMD_MUX=y CONFIG_CMD_OSD=y CONFIG_CMD_PCI=y +CONFIG_CMD_PCI_MPS=y CONFIG_CMD_READ=y CONFIG_CMD_REMOTEPROC=y CONFIG_CMD_SPI=y diff --git a/include/test/suites.h b/include/test/suites.h index 7c4960c004d..7349ce5aa60 100644 --- a/include/test/suites.h +++ b/include/test/suites.h @@ -48,6 +48,8 @@ int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); +int do_ut_pci_mps(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]); int do_ut_print(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_ut_seama(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_ut_setexpr(struct cmd_tbl *cmdtp, int flag, int argc, diff --git a/test/cmd/Makefile b/test/cmd/Makefile index 7848f348bc4..055adc65a25 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -14,6 +14,9 @@ obj-$(CONFIG_CMD_FDT) += fdt.o obj-$(CONFIG_CONSOLE_TRUETYPE) += font.o obj-$(CONFIG_CMD_LOADM) += loadm.o obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o +ifdef CONFIG_CMD_PCI +obj-$(CONFIG_CMD_PCI_MPS) += pci_mps.o +endif obj-$(CONFIG_CMD_PINMUX) += pinmux.o obj-$(CONFIG_CMD_PWM) += pwm.o obj-$(CONFIG_CMD_SEAMA) += seama.o diff --git a/test/cmd/pci_mps.c b/test/cmd/pci_mps.c new file mode 100644 index 00000000000..fd96f4fba6c --- /dev/null +++ b/test/cmd/pci_mps.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Tests that the PCI Maximum Payload Size (MPS) command can set the sandbox + * PCI Express device to safe mode and determine the correct payload size. + * + * Copyright 2023 Microsoft + * Written by Stephen Carlson + */ + +#include +#include +#include +#include + +#define PCI_MPS_TEST(_name, _flags) UNIT_TEST(_name, _flags, pci_mps_test) + +/* Test "pci_mps" command in safe "s" mode */ +static int test_pci_mps_safe(struct unit_test_state *uts) +{ + /* Enumerate PCI Express first */ + ut_assertok(run_command("pci e", 0)); + ut_assert_console_end(); + + /* Test pci_mps s */ + ut_assertok(run_command("pci_mps s", 0)); + ut_assert_nextline("Setting MPS of all devices to 256B"); + ut_assert_console_end(); + + return 0; +} + +PCI_MPS_TEST(test_pci_mps_safe, UT_TESTF_CONSOLE_REC); + +int do_ut_pci_mps(struct cmd_tbl *cmdtp, int flag, int argc, + char * const argv[]) +{ + struct unit_test *tests = UNIT_TEST_SUITE_START(pci_mps_test); + const int n = UNIT_TEST_SUITE_COUNT(pci_mps_test); + + return cmd_ut_category("cmd_pci_mps", "pci_mps_test_", tests, n, + argc, argv); +} diff --git a/test/cmd_ut.c b/test/cmd_ut.c index 409c22bfd24..d440da833a9 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -110,6 +110,9 @@ static struct cmd_tbl cmd_ut_sub[] = { #ifdef CONFIG_CMD_LOADM U_BOOT_CMD_MKENT(loadm, CONFIG_SYS_MAXARGS, 1, do_ut_loadm, "", ""), #endif +#ifdef CONFIG_CMD_PCI_MPS + U_BOOT_CMD_MKENT(pci_mps, CONFIG_SYS_MAXARGS, 1, do_ut_pci_mps, "", ""), +#endif #ifdef CONFIG_CMD_SEAMA U_BOOT_CMD_MKENT(seama, CONFIG_SYS_MAXARGS, 1, do_ut_seama, "", ""), #endif @@ -209,6 +212,9 @@ static char ut_help_text[] = #endif #ifdef CONFIG_UT_OVERLAY "\noverlay - device tree overlays" +#endif +#ifdef CONFIG_CMD_PCI_MPS + "\npci_mps - PCI Express Maximum Payload Size" #endif "\nprint - printing things to the console" "\nsetexpr - setexpr command" -- cgit v1.3.1 From 0798a1ce0f6439dfb80d310e11bc8993e09baf08 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Mon, 20 Mar 2023 10:23:44 +1300 Subject: drivers: rtc: add max313xx series rtc driver Adding support for Analog Devices MAX313XX series RTCs. This is ported from the Linux driver and adapted for use in u-boot. Notable differences are - handling of tm_year and tm_mon differ - clock source support is omitted - hwmon support for the MAX31328 and MAX31343 is omitted - rtc_ops->reset is added Signed-off-by: Chris Packham Reviewed-by: Simon Glass --- configs/sandbox_defconfig | 1 + drivers/rtc/Kconfig | 13 ++ drivers/rtc/Makefile | 1 + drivers/rtc/max313xx.c | 459 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 474 insertions(+) create mode 100644 drivers/rtc/max313xx.c (limited to 'configs') diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 2141c3d4698..cbace259f80 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -269,6 +269,7 @@ CONFIG_SANDBOX_RESET=y CONFIG_RESET_SYSCON=y CONFIG_RESET_SCMI=y CONFIG_DM_RTC=y +CONFIG_RTC_MAX313XX=y CONFIG_RTC_RV8803=y CONFIG_RTC_HT1380=y CONFIG_SCSI=y diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index fcfda2847c8..23173139e01 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -134,6 +134,19 @@ config RTC_ISL1208 This driver supports reading and writing the RTC/calendar and detects total power failures. +config RTC_MAX313XX + bool "Analog Devices MAX313XX RTC driver" + depends on DM_RTC + depends on DM_I2C + help + If you say yes here you will get support for the + Analog Devices MAX313XX series RTC family. + + Chip features not currently supported: + - Timestamp registers as SRAM + - Temperature sensor + - CLKOUT generation + config RTC_PCF8563 tristate "Philips PCF8563" help diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index b6c9029c8f0..308fab8da9b 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_RTC_HT1380) += ht1380.o obj-$(CONFIG_$(SPL_TPL_)RTC_SANDBOX) += i2c_rtc_emul.o obj-$(CONFIG_RTC_ISL1208) += isl1208.o obj-$(CONFIG_RTC_M41T62) += m41t62.o +obj-$(CONFIG_RTC_MAX313XX) += max313xx.o obj-$(CONFIG_RTC_MC13XXX) += mc13xxx-rtc.o obj-$(CONFIG_RTC_MC146818) += mc146818.o obj-$(CONFIG_MCFRTC) += mcfrtc.o diff --git a/drivers/rtc/max313xx.c b/drivers/rtc/max313xx.c new file mode 100644 index 00000000000..748f3c42c30 --- /dev/null +++ b/drivers/rtc/max313xx.c @@ -0,0 +1,459 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Analog Devices MAX313XX series I2C RTC driver + * + * Copyright 2022 Analog Devices Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* common registers */ +#define MAX313XX_INT_ALARM1 BIT(0) +#define MAX313XX_INT_ALARM2 BIT(1) +#define MAX313XX_HRS_F_12_24 BIT(6) +#define MAX313XX_HRS_F_AM_PM BIT(5) +#define MAX313XX_MONTH_CENTURY BIT(7) + +#define MAX313XX_TMR_CFG_ENABLE BIT(4) +#define MAX313XX_TMR_CFG_FREQ_MASK GENMASK(1, 0) +#define MAX313XX_TMR_CFG_FREQ_16HZ 0x03 + +#define MAX313XX_REG_MINUTE 0x01 +#define MAX313XX_REG_HOUR 0x02 + +#define MAX313XX_TIME_SIZE 0x07 + +/* device specific registers */ +#define MAX3134X_CFG2_REG 0x01 +#define MAX3134X_CFG2_SET_RTC BIT(1) + +#define MAX31341_TRICKLE_RES_MASK GENMASK(1, 0) +#define MAX31341_TRICKLE_DIODE_EN BIT(2) +#define MAX31341_TRICKLE_ENABLE_BIT BIT(3) +#define MAX31341_POWER_MGMT_REG 0x56 +#define MAX31341_POWER_MGMT_TRICKLE_BIT BIT(0) + +#define MAX3133X_TRICKLE_RES_MASK GENMASK(2, 1) +#define MAX3133X_TRICKLE_DIODE_EN BIT(3) +#define MAX3133X_TRICKLE_ENABLE_BIT BIT(0) + +#define MAX31329_TRICKLE_ENABLE_BIT BIT(7) +#define MAX31343_TRICKLE_ENABLE_MASK GENMASK(7, 4) +#define MAX31343_TRICKLE_ENABLE_CODE 5 +#define MAX31329_43_TRICKLE_RES_MASK GENMASK(1, 0) +#define MAX31329_43_TRICKLE_DIODE_EN BIT(2) + +#define MAX31329_CONFIG2_REG 0x04 +#define MAX31329_CONFIG2_CLKIN_EN BIT(2) +#define MAX31329_CONFIG2_CLKIN_FREQ GENMASK(1, 0) + +#define MAX31341_42_CONFIG1_REG 0x00 +#define MAX31341_42_CONFIG1_CLKIN_EN BIT(7) +#define MAX31341_42_CONFIG1_CLKIN_FREQ GENMASK(5, 4) +#define MAX31341_42_CONFIG1_OSC_DISABLE BIT(3) +#define MAX31341_42_CONFIG1_SWRST BIT(0) + +enum max313xx_ids { + ID_MAX31328, + ID_MAX31329, + ID_MAX31331, + ID_MAX31334, + ID_MAX31341, + ID_MAX31342, + ID_MAX31343, + MAX313XX_ID_NR +}; + +/** + * struct chip_desc - descriptor for MAX313xx variants + * @sec_reg: Offset to seconds register. Used to denote the start of the + * current time registers. + * @alarm1_sec_reg: Offset to Alarm1 seconds register. Used to denote the + * start of the alarm registers. + * @int_en_reg: Offset to the interrupt enable register. + * @int_status_reg: Offset to the interrupt status register. + * @ram_reg: Offset to the timestamp RAM (which can be used as SRAM). + * @ram_size: Size of the timestamp RAM. + * @temp_reg: Offset to the temperature register (or 0 if temperature + * sensor is not supported). + * @trickle_reg: Offset to the trickle charger configuration register (or + * 0 if trickle charger is not supported). + * @rst_reg: Offset to the reset register. + * @rst_bit: Bit within the reset register for the software reset. + */ +struct chip_desc { + u8 sec_reg; + u8 alarm1_sec_reg; + + u8 int_en_reg; + u8 int_status_reg; + + u8 ram_reg; + u8 ram_size; + + u8 temp_reg; + + u8 trickle_reg; + + u8 rst_reg; + u8 rst_bit; +}; + +struct max313xx_priv { + enum max313xx_ids id; + const struct chip_desc *chip; +}; + +static const struct chip_desc chip[MAX313XX_ID_NR] = { + [ID_MAX31328] = { + .int_en_reg = 0x0E, + .int_status_reg = 0x0F, + .sec_reg = 0x00, + .alarm1_sec_reg = 0x07, + .temp_reg = 0x11, + }, + [ID_MAX31329] = { + .int_en_reg = 0x01, + .int_status_reg = 0x00, + .sec_reg = 0x06, + .alarm1_sec_reg = 0x0D, + .ram_reg = 0x22, + .ram_size = 64, + .trickle_reg = 0x19, + .rst_reg = 0x02, + .rst_bit = BIT(0), + }, + [ID_MAX31331] = { + .int_en_reg = 0x01, + .int_status_reg = 0x00, + .sec_reg = 0x08, + .alarm1_sec_reg = 0x0F, + .ram_reg = 0x20, + .ram_size = 32, + .trickle_reg = 0x1B, + .rst_reg = 0x02, + .rst_bit = BIT(0), + }, + [ID_MAX31334] = { + .int_en_reg = 0x01, + .int_status_reg = 0x00, + .sec_reg = 0x09, + .alarm1_sec_reg = 0x10, + .ram_reg = 0x30, + .ram_size = 32, + .trickle_reg = 0x1E, + .rst_reg = 0x02, + .rst_bit = BIT(0), + }, + [ID_MAX31341] = { + .int_en_reg = 0x04, + .int_status_reg = 0x05, + .sec_reg = 0x06, + .alarm1_sec_reg = 0x0D, + .ram_reg = 0x16, + .ram_size = 64, + .trickle_reg = 0x57, + .rst_reg = 0x00, + .rst_bit = BIT(0), + }, + [ID_MAX31342] = { + .int_en_reg = 0x04, + .int_status_reg = 0x05, + .sec_reg = 0x06, + .alarm1_sec_reg = 0x0D, + .rst_reg = 0x00, + .rst_bit = BIT(0), + }, + [ID_MAX31343] = { + .int_en_reg = 0x01, + .int_status_reg = 0x00, + .sec_reg = 0x06, + .alarm1_sec_reg = 0x0D, + .ram_reg = 0x22, + .ram_size = 64, + .temp_reg = 0x1A, + .trickle_reg = 0x19, + .rst_reg = 0x02, + .rst_bit = BIT(0), + }, +}; + +static const u32 max313xx_trickle_ohms[] = { 3000, 6000, 11000 }; + +static int max313xx_set_bits(struct udevice *dev, unsigned int reg, unsigned int bits) +{ + int ret; + + ret = dm_i2c_reg_read(dev, reg); + if (ret < 0) + return ret; + + return dm_i2c_reg_write(dev, reg, ret | bits); +} + +static int max313xx_clear_bits(struct udevice *dev, unsigned int reg, unsigned int bits) +{ + int ret; + + ret = dm_i2c_reg_read(dev, reg); + if (ret < 0) + return ret; + + return dm_i2c_reg_write(dev, reg, ret & ~bits); +} + +static int max313xx_get_hour(u8 hour_reg) +{ + int hour; + + /* 24Hr mode */ + if (!FIELD_GET(MAX313XX_HRS_F_12_24, hour_reg)) + return bcd2bin(hour_reg & 0x3f); + + /* 12Hr mode */ + hour = bcd2bin(hour_reg & 0x1f); + if (hour == 12) + hour = 0; + + if (FIELD_GET(MAX313XX_HRS_F_AM_PM, hour_reg)) + hour += 12; + + return hour; +} + +static int max313xx_read_time(struct udevice *dev, struct rtc_time *t) +{ + struct max313xx_priv *rtc = dev_get_priv(dev); + u8 regs[7]; + int ret; + + ret = dm_i2c_read(dev, rtc->chip->sec_reg, regs, 7); + if (ret) + return ret; + + t->tm_sec = bcd2bin(regs[0] & 0x7f); + t->tm_min = bcd2bin(regs[1] & 0x7f); + t->tm_hour = max313xx_get_hour(regs[2]); + t->tm_wday = bcd2bin(regs[3] & 0x07) - 1; + t->tm_mday = bcd2bin(regs[4] & 0x3f); + t->tm_mon = bcd2bin(regs[5] & 0x1f); + t->tm_year = bcd2bin(regs[6]) + 2000; + + if (FIELD_GET(MAX313XX_MONTH_CENTURY, regs[5])) + t->tm_year += 100; + + dev_dbg(dev, "read %4d-%02d-%02d (wday=%d) %2d:%02d:%02d\n", + t->tm_year, t->tm_mon, t->tm_mday, + t->tm_wday, t->tm_hour, t->tm_min, t->tm_sec); + + return 0; +} + +static int max313xx_set_time(struct udevice *dev, const struct rtc_time *t) +{ + struct max313xx_priv *rtc = dev_get_priv(dev); + u8 regs[7]; + int ret; + + dev_dbg(dev, "set %4d-%02d-%02d (wday=%d) %2d:%02d:%02d\n", + t->tm_year, t->tm_mon, t->tm_mday, + t->tm_wday, t->tm_hour, t->tm_min, t->tm_sec); + + if (t->tm_year < 2000) { + dev_err(dev, "year %d (before 2000) not supported\n", + t->tm_year); + return -EINVAL; + } + + if (rtc->chip->rst_bit) { + ret = max313xx_clear_bits(dev, rtc->chip->rst_reg, rtc->chip->rst_bit); + if (ret) + return ret; + } + + regs[0] = bin2bcd(t->tm_sec); + regs[1] = bin2bcd(t->tm_min); + regs[2] = bin2bcd(t->tm_hour); + regs[3] = bin2bcd(t->tm_wday + 1); + regs[4] = bin2bcd(t->tm_mday); + regs[5] = bin2bcd(t->tm_mon); + regs[6] = bin2bcd((t->tm_year - 2000) % 100); + + if ((t->tm_year - 2000) >= 200) + regs[5] |= FIELD_PREP(MAX313XX_MONTH_CENTURY, 1); + + ret = dm_i2c_write(dev, rtc->chip->sec_reg, regs, 7); + if (ret) + return ret; + + switch (rtc->id) { + case ID_MAX31341: + case ID_MAX31342: + ret = max313xx_set_bits(dev, MAX3134X_CFG2_REG, + MAX3134X_CFG2_SET_RTC); + if (ret) + return ret; + + udelay(10000); + + ret = max313xx_clear_bits(dev, MAX3134X_CFG2_REG, + MAX3134X_CFG2_SET_RTC); + if (ret) + return ret; + + break; + default: + break; + } + + return ret; +} + +static int max313xx_reset(struct udevice *dev) +{ + struct max313xx_priv *rtc = dev_get_priv(dev); + int ret = -EINVAL; + + if (rtc->chip->rst_bit) + ret = max313xx_set_bits(dev, rtc->chip->rst_reg, rtc->chip->rst_bit); + + return ret; +} + +static const struct rtc_ops max3133x_rtc_ops = { + .get = max313xx_read_time, + .set = max313xx_set_time, + .reset = max313xx_reset, +}; + +static int max313xx_init(struct udevice *dev) +{ + struct max313xx_priv *rtc = dev_get_priv(dev); + int ret; + + switch (rtc->id) { + case ID_MAX31341: + case ID_MAX31342: + ret = max313xx_clear_bits(dev, MAX31341_42_CONFIG1_REG, + MAX31341_42_CONFIG1_OSC_DISABLE); + if (ret) + return ret; + + return max313xx_set_bits(dev, MAX31341_42_CONFIG1_REG, + MAX31341_42_CONFIG1_SWRST); + default: + return 0; + } +} + +static int max313xx_trickle_charger_setup(struct udevice *dev) +{ + struct max313xx_priv *rtc = dev_get_priv(dev); + bool diode; + int index, reg; + u32 ohms; + u32 chargeable; + int ret; + + if (dev_read_u32(dev, "trickle-resistor-ohms", &ohms) || + dev_read_u32(dev, "aux-voltage-chargeable", &chargeable)) + return 0; + + switch (chargeable) { + case 0: + diode = false; + break; + case 1: + diode = true; + break; + default: + dev_dbg(dev, "unsupported aux-voltage-chargeable value\n"); + return -EINVAL; + } + + if (!rtc->chip->trickle_reg) { + dev_warn(dev, "device does not have trickle charger\n"); + return -ENOTSUPP; + } + + index = find_closest(ohms, max313xx_trickle_ohms, + ARRAY_SIZE(max313xx_trickle_ohms)) + 1; + + switch (rtc->id) { + case ID_MAX31329: + reg = FIELD_PREP(MAX31329_TRICKLE_ENABLE_BIT, 1) | + FIELD_PREP(MAX31329_43_TRICKLE_RES_MASK, index) | + FIELD_PREP(MAX31329_43_TRICKLE_DIODE_EN, diode); + break; + case ID_MAX31331: + case ID_MAX31334: + reg = FIELD_PREP(MAX3133X_TRICKLE_ENABLE_BIT, 1) | + FIELD_PREP(MAX3133X_TRICKLE_DIODE_EN, diode) | + FIELD_PREP(MAX3133X_TRICKLE_RES_MASK, index); + break; + case ID_MAX31341: + if (index == 1) + index = 0; + reg = FIELD_PREP(MAX31341_TRICKLE_ENABLE_BIT, 1) | + FIELD_PREP(MAX31341_TRICKLE_DIODE_EN, diode) | + FIELD_PREP(MAX31341_TRICKLE_RES_MASK, index); + + ret = max313xx_set_bits(dev, MAX31341_POWER_MGMT_REG, + MAX31341_POWER_MGMT_TRICKLE_BIT); + if (ret) + return ret; + + break; + case ID_MAX31343: + reg = FIELD_PREP(MAX31329_43_TRICKLE_RES_MASK, index) | + FIELD_PREP(MAX31329_43_TRICKLE_DIODE_EN, diode) | + FIELD_PREP(MAX31343_TRICKLE_ENABLE_MASK, + MAX31343_TRICKLE_ENABLE_CODE); + break; + default: + return -EOPNOTSUPP; + } + + return dm_i2c_reg_write(dev, rtc->chip->trickle_reg, reg); +} + +static int max313xx_probe(struct udevice *dev) +{ + struct max313xx_priv *max313xx = dev_get_priv(dev); + int ret; + + max313xx->id = dev_get_driver_data(dev); + max313xx->chip = &chip[max313xx->id]; + + ret = max313xx_init(dev); + if (ret) + return ret; + + return max313xx_trickle_charger_setup(dev); +} + +static const struct udevice_id max313xx_of_id[] = { + { .compatible = "adi,max31328", .data = ID_MAX31328 }, + { .compatible = "adi,max31329", .data = ID_MAX31329 }, + { .compatible = "adi,max31331", .data = ID_MAX31331 }, + { .compatible = "adi,max31334", .data = ID_MAX31334 }, + { .compatible = "adi,max31341", .data = ID_MAX31341 }, + { .compatible = "adi,max31342", .data = ID_MAX31342 }, + { .compatible = "adi,max31343", .data = ID_MAX31343 }, + { } +}; + +U_BOOT_DRIVER(rtc_max313xx) = { + .name = "rtc-max313xx", + .id = UCLASS_RTC, + .probe = max313xx_probe, + .of_match = max313xx_of_id, + .priv_auto = sizeof(struct max313xx_priv), + .ops = &max3133x_rtc_ops, +}; -- cgit v1.3.1