2022-02-24 01:06:03

by Luca Ceresoli

[permalink] [raw]
Subject: [PATCH v6 0/8] Add MAX77714 PMIC minimal driver (RTC and watchdog only)

Hi,

this series adds minimal drivers for the Maxim Semiconductor MAX77714
(https://www.maximintegrated.com/en/products/power/power-management-ics/MAX77714.html).
Only RTC and watchdog are implemented by these patches.

This is almost a bare resend of v5. Changes are minimal, trivial and only
in comments (see list below).

All implemented functionality is tested and working: RTC read/write,
watchdog start/stop/ping/set_timeout.

Patches 1-3 are trivial cleanups to the max77686 drivers.

Patches 4-8 add dt bindings, mfd driver, watchdog driver and rtc driver.

Changes in v6:
- patch 6: removed, now in mainline
- patch 5: describe as "Core driver", not "MFD driver" in comment
(Lee Jones)
- update copyright years
- add review tags

Changes in v5:
- patch 7: fix (and simplify) watchdog_info code
- patch 8: remove amibguity in comment

Changes in v4:
- do not add a new wdog driver for MAX77714, extend the MAX77620 wdog
driver; this means removing v3 patch 7, now replaced by patches 7+8
- added review tags

Changes in v3:
- fixed all issues reported on v1 patches
- removed patch 1 of v2, already applied
("mfd: max77686: Correct tab-based alignment of register addresses")

Changes in v2:
- fixed all issues reported on v1 patches
- added patch 7 ("watchdog: Kconfig: fix help text indentation")
- additional minor improvements

Luca

Luca Ceresoli (8):
rtc: max77686: convert comments to kernel-doc format
rtc: max77686: rename day-of-month defines
rtc: max77686: remove unused code to read in 12-hour mode
dt-bindings: mfd: add Maxim MAX77714 PMIC
mfd: max77714: Add driver for Maxim MAX77714 PMIC
watchdog: max77620: add support for the max77714 variant
watchdog: max77620: add comment to clarify set_timeout procedure
rtc: max77686: add MAX77714 support

.../bindings/mfd/maxim,max77714.yaml | 68 ++++++++
MAINTAINERS | 7 +
drivers/mfd/Kconfig | 14 ++
drivers/mfd/Makefile | 1 +
drivers/mfd/max77686.c | 2 +-
drivers/mfd/max77714.c | 152 ++++++++++++++++++
drivers/rtc/Kconfig | 2 +-
drivers/rtc/rtc-max77686.c | 75 +++++----
drivers/watchdog/Kconfig | 2 +-
drivers/watchdog/max77620_wdt.c | 85 ++++++++--
include/linux/mfd/max77686-private.h | 4 +-
include/linux/mfd/max77714.h | 60 +++++++
12 files changed, 421 insertions(+), 51 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mfd/maxim,max77714.yaml
create mode 100644 drivers/mfd/max77714.c
create mode 100644 include/linux/mfd/max77714.h

--
2.25.1


2022-02-24 01:08:37

by Luca Ceresoli

[permalink] [raw]
Subject: [PATCH v6 3/8] rtc: max77686: remove unused code to read in 12-hour mode

The MAX77714 RTC chip is explicitly set to 24-hour mode in
max77686_rtc_probe() -> max77686_rtc_init_reg() and never changed back to
12-hour mode. Accordingly info->rtc_24hr_mode is set to 1 in the same place
and never modified later, so it is de facto a constant. Yet there is code
to read 12-hour time, which is unreachable.

Remove the unused variable, the unreachable code to manage 12-hour mode and
the defines that become unused due to the above changes.

Signed-off-by: Luca Ceresoli <[email protected]>
Reviewed-by: Krzysztof Kozlowski <[email protected]>
Acked-by: Alexandre Belloni <[email protected]>

---

Changes in v6: none

Changes in v5: none

Changes in v4: none

Changes in v3: none

Changes in v2:
- remove the now-unused defines too (Alexandre Belloni)
- improve the commit message
---
drivers/rtc/rtc-max77686.c | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c
index 7e765207f28e..5c64d08c0732 100644
--- a/drivers/rtc/rtc-max77686.c
+++ b/drivers/rtc/rtc-max77686.c
@@ -34,9 +34,6 @@
#define RTC_UDR_MASK BIT(RTC_UDR_SHIFT)
#define RTC_RBUDR_SHIFT 4
#define RTC_RBUDR_MASK BIT(RTC_RBUDR_SHIFT)
-/* RTC Hour register */
-#define HOUR_PM_SHIFT 6
-#define HOUR_PM_MASK BIT(HOUR_PM_SHIFT)
/* RTC Alarm Enable */
#define ALARM_ENABLE_SHIFT 7
#define ALARM_ENABLE_MASK BIT(ALARM_ENABLE_SHIFT)
@@ -99,7 +96,6 @@ struct max77686_rtc_info {

int rtc_irq;
int virq;
- int rtc_24hr_mode;
};

enum MAX77686_RTC_OP {
@@ -278,13 +274,7 @@ static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm,

tm->tm_sec = data[RTC_SEC] & mask;
tm->tm_min = data[RTC_MIN] & mask;
- if (info->rtc_24hr_mode) {
- tm->tm_hour = data[RTC_HOUR] & 0x1f;
- } else {
- tm->tm_hour = data[RTC_HOUR] & 0x0f;
- if (data[RTC_HOUR] & HOUR_PM_MASK)
- tm->tm_hour += 12;
- }
+ tm->tm_hour = data[RTC_HOUR] & 0x1f;

/* Only a single bit is set in data[], so fls() would be equivalent */
tm->tm_wday = ffs(data[RTC_WEEKDAY] & mask) - 1;
@@ -662,8 +652,6 @@ static int max77686_rtc_init_reg(struct max77686_rtc_info *info)
data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);

- info->rtc_24hr_mode = 1;
-
ret = regmap_bulk_write(info->rtc_regmap,
info->drv_data->map[REG_RTC_CONTROLM],
data, ARRAY_SIZE(data));
--
2.25.1

2022-02-24 01:29:12

by Luca Ceresoli

[permalink] [raw]
Subject: [PATCH v6 6/8] watchdog: max77620: add support for the max77714 variant

The MAX77714 is a MFD chip whose watchdog has the same programming
procedures as the MAX77620 watchdog, but most register offsets and bit
masks are different, as well as some features.

Support the MAX77714 watchdog by adding a variant description table holding
the differences.

All the features implemented by this driver are available on the MAX77714
except for the lack of a WDTOFFC bit. Instead of using a "HAS_*" flag we
handle this by holding in the cnfg_glbl2_cfg_bits struct field the bits
(i.e. the features) to enable in the CNFG_GLBL2 register. These bits differ
among the two models. This implementation allows to avoid any conditional
code, keeping the execution flow unchanged.

Signed-off-by: Luca Ceresoli <[email protected]>
Reviewed-by: Guenter Roeck <[email protected]>

---

Changes in v6:
- Update copyright year

Changes in v5:
- keep a unique watchdog_info for both models (Guenter Roeck)

This patch is new in v4. It replaces v3 patch 7 ("watchdog: max77714: add
driver for the watchdog in the MAX77714 PMIC") by adding MAX77714 wdog
support to the existing MAX77620 wdog driver instead of adding a new
driver. Suggested by Guenter Roeck and Krzysztof Kozlowski.
---
drivers/watchdog/Kconfig | 2 +-
drivers/watchdog/max77620_wdt.c | 80 ++++++++++++++++++++++++++-------
2 files changed, 65 insertions(+), 17 deletions(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index c8fa79da23b3..5373ecdec58e 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -678,7 +678,7 @@ config MAX63XX_WATCHDOG

config MAX77620_WATCHDOG
tristate "Maxim Max77620 Watchdog Timer"
- depends on MFD_MAX77620 || COMPILE_TEST
+ depends on MFD_MAX77620 || MFD_MAX77714 || COMPILE_TEST
select WATCHDOG_CORE
help
This is the driver for the Max77620 watchdog timer.
diff --git a/drivers/watchdog/max77620_wdt.c b/drivers/watchdog/max77620_wdt.c
index be6a53c30002..cd321c7e0d59 100644
--- a/drivers/watchdog/max77620_wdt.c
+++ b/drivers/watchdog/max77620_wdt.c
@@ -3,8 +3,10 @@
* Maxim MAX77620 Watchdog Driver
*
* Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2022 Luca Ceresoli
*
* Author: Laxman Dewangan <[email protected]>
+ * Author: Luca Ceresoli <[email protected]>
*/

#include <linux/err.h>
@@ -13,6 +15,7 @@
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/mfd/max77620.h>
+#include <linux/mfd/max77714.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
@@ -20,17 +23,57 @@

static bool nowayout = WATCHDOG_NOWAYOUT;

+/**
+ * struct max77620_variant - Data specific to a chip variant
+ * @wdt_info: watchdog descriptor
+ * @reg_onoff_cnfg2: ONOFF_CNFG2 register offset
+ * @reg_cnfg_glbl2: CNFG_GLBL2 register offset
+ * @reg_cnfg_glbl3: CNFG_GLBL3 register offset
+ * @wdtc_mask: WDTC bit mask in CNFG_GLBL3 (=bits to update to ping the watchdog)
+ * @bit_wd_rst_wk: WD_RST_WK bit offset within ONOFF_CNFG2
+ * @cnfg_glbl2_cfg_bits: configuration bits to enable in CNFG_GLBL2 register
+ */
+struct max77620_variant {
+ u8 reg_onoff_cnfg2;
+ u8 reg_cnfg_glbl2;
+ u8 reg_cnfg_glbl3;
+ u8 wdtc_mask;
+ u8 bit_wd_rst_wk;
+ u8 cnfg_glbl2_cfg_bits;
+};
+
struct max77620_wdt {
struct device *dev;
struct regmap *rmap;
+ const struct max77620_variant *drv_data;
struct watchdog_device wdt_dev;
};

+static const struct max77620_variant max77620_wdt_data = {
+ .reg_onoff_cnfg2 = MAX77620_REG_ONOFFCNFG2,
+ .reg_cnfg_glbl2 = MAX77620_REG_CNFGGLBL2,
+ .reg_cnfg_glbl3 = MAX77620_REG_CNFGGLBL3,
+ .wdtc_mask = MAX77620_WDTC_MASK,
+ .bit_wd_rst_wk = MAX77620_ONOFFCNFG2_WD_RST_WK,
+ /* Set WDT clear in OFF and sleep mode */
+ .cnfg_glbl2_cfg_bits = MAX77620_WDTSLPC | MAX77620_WDTOFFC,
+};
+
+static const struct max77620_variant max77714_wdt_data = {
+ .reg_onoff_cnfg2 = MAX77714_CNFG2_ONOFF,
+ .reg_cnfg_glbl2 = MAX77714_CNFG_GLBL2,
+ .reg_cnfg_glbl3 = MAX77714_CNFG_GLBL3,
+ .wdtc_mask = MAX77714_WDTC,
+ .bit_wd_rst_wk = MAX77714_WD_RST_WK,
+ /* Set WDT clear in sleep mode (there is no WDTOFFC on MAX77714) */
+ .cnfg_glbl2_cfg_bits = MAX77714_WDTSLPC,
+};
+
static int max77620_wdt_start(struct watchdog_device *wdt_dev)
{
struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev);

- return regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2,
+ return regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2,
MAX77620_WDTEN, MAX77620_WDTEN);
}

@@ -38,7 +81,7 @@ static int max77620_wdt_stop(struct watchdog_device *wdt_dev)
{
struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev);

- return regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2,
+ return regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2,
MAX77620_WDTEN, 0);
}

@@ -46,8 +89,8 @@ static int max77620_wdt_ping(struct watchdog_device *wdt_dev)
{
struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev);

- return regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL3,
- MAX77620_WDTC_MASK, 0x1);
+ return regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl3,
+ wdt->drv_data->wdtc_mask, 0x1);
}

static int max77620_wdt_set_timeout(struct watchdog_device *wdt_dev,
@@ -80,12 +123,12 @@ static int max77620_wdt_set_timeout(struct watchdog_device *wdt_dev,
break;
}

- ret = regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL3,
- MAX77620_WDTC_MASK, 0x1);
+ ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl3,
+ wdt->drv_data->wdtc_mask, 0x1);
if (ret < 0)
return ret;

- ret = regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2,
+ ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2,
MAX77620_TWD_MASK, regval);
if (ret < 0)
return ret;
@@ -109,6 +152,7 @@ static const struct watchdog_ops max77620_wdt_ops = {

static int max77620_wdt_probe(struct platform_device *pdev)
{
+ const struct platform_device_id *id = platform_get_device_id(pdev);
struct device *dev = &pdev->dev;
struct max77620_wdt *wdt;
struct watchdog_device *wdt_dev;
@@ -120,6 +164,8 @@ static int max77620_wdt_probe(struct platform_device *pdev)
return -ENOMEM;

wdt->dev = dev;
+ wdt->drv_data = (const struct max77620_variant *) id->driver_data;
+
wdt->rmap = dev_get_regmap(dev->parent, NULL);
if (!wdt->rmap) {
dev_err(wdt->dev, "Failed to get parent regmap\n");
@@ -136,25 +182,25 @@ static int max77620_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, wdt);

/* Enable WD_RST_WK - WDT expire results in a restart */
- ret = regmap_update_bits(wdt->rmap, MAX77620_REG_ONOFFCNFG2,
- MAX77620_ONOFFCNFG2_WD_RST_WK,
- MAX77620_ONOFFCNFG2_WD_RST_WK);
+ ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_onoff_cnfg2,
+ wdt->drv_data->bit_wd_rst_wk,
+ wdt->drv_data->bit_wd_rst_wk);
if (ret < 0) {
dev_err(wdt->dev, "Failed to set WD_RST_WK: %d\n", ret);
return ret;
}

- /* Set WDT clear in OFF and sleep mode */
- ret = regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2,
- MAX77620_WDTOFFC | MAX77620_WDTSLPC,
- MAX77620_WDTOFFC | MAX77620_WDTSLPC);
+ /* Set the "auto WDT clear" bits available on the chip */
+ ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2,
+ wdt->drv_data->cnfg_glbl2_cfg_bits,
+ wdt->drv_data->cnfg_glbl2_cfg_bits);
if (ret < 0) {
dev_err(wdt->dev, "Failed to set WDT OFF mode: %d\n", ret);
return ret;
}

/* Check if WDT running and if yes then set flags properly */
- ret = regmap_read(wdt->rmap, MAX77620_REG_CNFGGLBL2, &regval);
+ ret = regmap_read(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, &regval);
if (ret < 0) {
dev_err(wdt->dev, "Failed to read WDT CFG register: %d\n", ret);
return ret;
@@ -186,7 +232,8 @@ static int max77620_wdt_probe(struct platform_device *pdev)
}

static const struct platform_device_id max77620_wdt_devtype[] = {
- { .name = "max77620-watchdog", },
+ { "max77620-watchdog", (kernel_ulong_t)&max77620_wdt_data },
+ { "max77714-watchdog", (kernel_ulong_t)&max77714_wdt_data },
{ },
};
MODULE_DEVICE_TABLE(platform, max77620_wdt_devtype);
@@ -208,4 +255,5 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
"(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");

MODULE_AUTHOR("Laxman Dewangan <[email protected]>");
+MODULE_AUTHOR("Luca Ceresoli <[email protected]>");
MODULE_LICENSE("GPL v2");
--
2.25.1

2022-03-08 00:48:39

by Lee Jones

[permalink] [raw]
Subject: [GIT PULL] Immutable branch between MFD, RTC and Watchdog due for the v5.18 merge window

Enjoy!

The following changes since commit e783362eb54cd99b2cac8b3a9aeac942e6f6ac07:

Linux 5.17-rc1 (2022-01-23 10:12:53 +0200)

are available in the Git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git ib-mfd-rtc-watchdog-v5.18

for you to fetch changes up to c58e496311a50c087eeeaaae81083cd643fe5128:

rtc: max77686: Add MAX77714 support (2022-03-07 13:55:04 +0000)

----------------------------------------------------------------
Immutable branch between MFD, RTC and Watchdog due for the v5.18 merge window

----------------------------------------------------------------
Luca Ceresoli (8):
rtc: max77686: Convert comments to kernel-doc format
rtc: max77686: Rename day-of-month defines
rtc: max77686: Remove unused code to read in 12-hour mode
dt-bindings: mfd: Add Maxim MAX77714 PMIC
mfd: max77714: Add driver for Maxim MAX77714 PMIC
watchdog: max77620: Add support for the max77714 variant
watchdog: max77620: Add comment to clarify set_timeout procedure
rtc: max77686: Add MAX77714 support

.../devicetree/bindings/mfd/maxim,max77714.yaml | 68 +++++++++
MAINTAINERS | 7 +
drivers/mfd/Kconfig | 14 ++
drivers/mfd/Makefile | 1 +
drivers/mfd/max77686.c | 2 +-
drivers/mfd/max77714.c | 152 +++++++++++++++++++++
drivers/rtc/Kconfig | 2 +-
drivers/rtc/rtc-max77686.c | 75 ++++++----
drivers/watchdog/Kconfig | 2 +-
drivers/watchdog/max77620_wdt.c | 85 +++++++++---
include/linux/mfd/max77686-private.h | 4 +-
include/linux/mfd/max77714.h | 60 ++++++++
12 files changed, 421 insertions(+), 51 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mfd/maxim,max77714.yaml
create mode 100644 drivers/mfd/max77714.c
create mode 100644 include/linux/mfd/max77714.h

--
Lee Jones [李琼斯]
Principal Technical Lead - Developer Services
Linaro.org │ Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog