···11+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause22+%YAML 1.233+---44+$id: http://devicetree.org/schemas/leds/rohm,bd71828-leds.yaml#55+$schema: http://devicetree.org/meta-schemas/core.yaml#66+77+title: ROHM BD71828 Power Management Integrated Circuit LED driver88+99+maintainers:1010+ - Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>1111+1212+description: |1313+ This module is part of the ROHM BD71828 MFD device. For more details1414+ see Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml.1515+1616+ The LED controller is represented as a sub-node of the PMIC node on the device1717+ tree.1818+1919+ The device has two LED outputs referred as GRNLED and AMBLED in data-sheet.2020+2121+select: false2222+2323+properties:2424+ compatible:2525+ const: rohm,bd71828-leds2626+2727+patternProperties:2828+ "^led-[1-2]$":2929+ type: object3030+ description:3131+ Properties for a single LED.3232+ properties:3333+ #allOf:3434+ #- $ref: "common.yaml#"3535+ rohm,led-compatible:3636+ description: LED identification string3737+ allOf:3838+ - $ref: "/schemas/types.yaml#/definitions/string"3939+ - enum:4040+ - bd71828-ambled4141+ - bd71828-grnled4242+ function:4343+ description:4444+ Purpose of LED as defined in dt-bindings/leds/common.h4545+ $ref: "/schemas/types.yaml#/definitions/string"4646+ color:4747+ description:4848+ LED colour as defined in dt-bindings/leds/common.h4949+ $ref: "/schemas/types.yaml#/definitions/uint32"5050+5151+required:5252+ - compatible
···10211021 This driver can also be built as a module. If so, the module10221022 will be called gpio-bd70528.1023102310241024+config GPIO_BD7182810251025+ tristate "ROHM BD71828 GPIO support"10261026+ depends on MFD_ROHM_BD7182810271027+ help10281028+ Support for GPIOs on ROHM BD71828 PMIC. There are three GPIOs10291029+ available on the ROHM PMIC in total. The GPIOs are limited to10301030+ outputs only and pins must be configured to GPIO outputs by10311031+ OTP. Enable this only if you want to use these pins as outputs.10321032+10331033+ This driver can also be built as a module. If so, the module10341034+ will be called gpio-bd71828.10351035+10241036config GPIO_BD9571MWV10251037 tristate "ROHM BD9571 GPIO support"10261038 depends on MFD_BD9571MWV
···11+// SPDX-License-Identifier: GPL-2.0-only22+// Copyright (C) 2018 ROHM Semiconductors33+44+#include <linux/gpio/driver.h>55+#include <linux/mfd/rohm-bd71828.h>66+#include <linux/module.h>77+#include <linux/platform_device.h>88+#include <linux/regmap.h>99+1010+#define GPIO_OUT_REG(off) (BD71828_REG_GPIO_CTRL1 + (off))1111+#define HALL_GPIO_OFFSET 31212+1313+/*1414+ * These defines can be removed when1515+ * "gpio: Add definition for GPIO direction"1616+ * (9208b1e77d6e8e9776f34f46ef4079ecac9c3c25 in GPIO tree) gets merged,1717+ */1818+#ifndef GPIO_LINE_DIRECTION_IN1919+ #define GPIO_LINE_DIRECTION_IN 12020+ #define GPIO_LINE_DIRECTION_OUT 02121+#endif2222+2323+struct bd71828_gpio {2424+ struct rohm_regmap_dev chip;2525+ struct gpio_chip gpio;2626+};2727+2828+static void bd71828_gpio_set(struct gpio_chip *chip, unsigned int offset,2929+ int value)3030+{3131+ int ret;3232+ struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);3333+ u8 val = (value) ? BD71828_GPIO_OUT_HI : BD71828_GPIO_OUT_LO;3434+3535+ /*3636+ * The HALL input pin can only be used as input. If this is the pin3737+ * we are dealing with - then we are done3838+ */3939+ if (offset == HALL_GPIO_OFFSET)4040+ return;4141+4242+ ret = regmap_update_bits(bdgpio->chip.regmap, GPIO_OUT_REG(offset),4343+ BD71828_GPIO_OUT_MASK, val);4444+ if (ret)4545+ dev_err(bdgpio->chip.dev, "Could not set gpio to %d\n", value);4646+}4747+4848+static int bd71828_gpio_get(struct gpio_chip *chip, unsigned int offset)4949+{5050+ int ret;5151+ unsigned int val;5252+ struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);5353+5454+ if (offset == HALL_GPIO_OFFSET)5555+ ret = regmap_read(bdgpio->chip.regmap, BD71828_REG_IO_STAT,5656+ &val);5757+ else5858+ ret = regmap_read(bdgpio->chip.regmap, GPIO_OUT_REG(offset),5959+ &val);6060+ if (!ret)6161+ ret = (val & BD71828_GPIO_OUT_MASK);6262+6363+ return ret;6464+}6565+6666+static int bd71828_gpio_set_config(struct gpio_chip *chip, unsigned int offset,6767+ unsigned long config)6868+{6969+ struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);7070+7171+ if (offset == HALL_GPIO_OFFSET)7272+ return -ENOTSUPP;7373+7474+ switch (pinconf_to_config_param(config)) {7575+ case PIN_CONFIG_DRIVE_OPEN_DRAIN:7676+ return regmap_update_bits(bdgpio->chip.regmap,7777+ GPIO_OUT_REG(offset),7878+ BD71828_GPIO_DRIVE_MASK,7979+ BD71828_GPIO_OPEN_DRAIN);8080+ case PIN_CONFIG_DRIVE_PUSH_PULL:8181+ return regmap_update_bits(bdgpio->chip.regmap,8282+ GPIO_OUT_REG(offset),8383+ BD71828_GPIO_DRIVE_MASK,8484+ BD71828_GPIO_PUSH_PULL);8585+ default:8686+ break;8787+ }8888+ return -ENOTSUPP;8989+}9090+9191+static int bd71828_get_direction(struct gpio_chip *chip, unsigned int offset)9292+{9393+ /*9494+ * Pin usage is selected by OTP data. We can't read it runtime. Hence9595+ * we trust that if the pin is not excluded by "gpio-reserved-ranges"9696+ * the OTP configuration is set to OUT. (Other pins but HALL input pin9797+ * on BD71828 can't really be used for general purpose input - input9898+ * states are used for specific cases like regulator control or9999+ * PMIC_ON_REQ.100100+ */101101+ if (offset == HALL_GPIO_OFFSET)102102+ return GPIO_LINE_DIRECTION_IN;103103+104104+ return GPIO_LINE_DIRECTION_OUT;105105+}106106+107107+static int bd71828_probe(struct platform_device *pdev)108108+{109109+ struct bd71828_gpio *bdgpio;110110+ struct rohm_regmap_dev *bd71828;111111+112112+ bd71828 = dev_get_drvdata(pdev->dev.parent);113113+ if (!bd71828) {114114+ dev_err(&pdev->dev, "No MFD driver data\n");115115+ return -EINVAL;116116+ }117117+118118+ bdgpio = devm_kzalloc(&pdev->dev, sizeof(*bdgpio),119119+ GFP_KERNEL);120120+ if (!bdgpio)121121+ return -ENOMEM;122122+123123+ bdgpio->chip.dev = &pdev->dev;124124+ bdgpio->gpio.parent = pdev->dev.parent;125125+ bdgpio->gpio.label = "bd71828-gpio";126126+ bdgpio->gpio.owner = THIS_MODULE;127127+ bdgpio->gpio.get_direction = bd71828_get_direction;128128+ bdgpio->gpio.set_config = bd71828_gpio_set_config;129129+ bdgpio->gpio.can_sleep = true;130130+ bdgpio->gpio.get = bd71828_gpio_get;131131+ bdgpio->gpio.set = bd71828_gpio_set;132132+ bdgpio->gpio.base = -1;133133+134134+ /*135135+ * See if we need some implementation to mark some PINs as136136+ * not controllable based on DT info or if core can handle137137+ * "gpio-reserved-ranges" and exclude them from control138138+ */139139+ bdgpio->gpio.ngpio = 4;140140+ bdgpio->gpio.of_node = pdev->dev.parent->of_node;141141+ bdgpio->chip.regmap = bd71828->regmap;142142+143143+ return devm_gpiochip_add_data(&pdev->dev, &bdgpio->gpio,144144+ bdgpio);145145+}146146+147147+static struct platform_driver bd71828_gpio = {148148+ .driver = {149149+ .name = "bd71828-gpio"150150+ },151151+ .probe = bd71828_probe,152152+};153153+154154+module_platform_driver(bd71828_gpio);155155+156156+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");157157+MODULE_DESCRIPTION("BD71828 voltage regulator driver");158158+MODULE_LICENSE("GPL");159159+MODULE_ALIAS("platform:bd71828-gpio");
+15
drivers/mfd/Kconfig
···19061906 10 bits SAR ADC for battery temperature monitor and 1S battery19071907 charger.1908190819091909+config MFD_ROHM_BD7182819101910+ tristate "ROHM BD71828 Power Management IC"19111911+ depends on I2C=y19121912+ depends on OF19131913+ select REGMAP_I2C19141914+ select REGMAP_IRQ19151915+ select MFD_CORE19161916+ help19171917+ Select this option to get support for the ROHM BD71828 Power19181918+ Management IC. BD71828GW is a single-chip power management IC for19191919+ battery-powered portable devices. The IC integrates 7 buck19201920+ converters, 7 LDOs, and a 1500 mA single-cell linear charger.19211921+ Also included is a Coulomb counter, a real-time clock (RTC), and19221922+ a 32.768 kHz clock gate.19231923+19091924config MFD_STM32_LPTIMER19101925 tristate "Support for STM32 Low-Power Timer"19111926 depends on (ARCH_STM32 && OF) || COMPILE_TEST
···197197config REGULATOR_BD718XX198198 tristate "ROHM BD71837 Power Regulator"199199 depends on MFD_ROHM_BD718XX200200+ select REGULATOR_ROHM200201 help201202 This driver supports voltage regulators on ROHM BD71837 PMIC.202203 This will enable support for the software controllable buck···790789 help791790 Say y here to support the regulators found on Ricoh RN5T567,792791 RN5T618 or RC5T619 PMIC.792792+793793+config REGULATOR_ROHM794794+ tristate793795794796config REGULATOR_RT5033795797 tristate "Richtek RT5033 Regulators"
···11+// SPDX-License-Identifier: GPL-2.022+// Copyright (C) 2020 ROHM Semiconductors33+44+#include <linux/errno.h>55+#include <linux/mfd/rohm-generic.h>66+#include <linux/module.h>77+#include <linux/of.h>88+#include <linux/regmap.h>99+#include <linux/regulator/driver.h>1010+1111+static int set_dvs_level(const struct regulator_desc *desc,1212+ struct device_node *np, struct regmap *regmap,1313+ char *prop, unsigned int reg, unsigned int mask,1414+ unsigned int omask, unsigned int oreg)1515+{1616+ int ret, i;1717+ uint32_t uv;1818+1919+ ret = of_property_read_u32(np, prop, &uv);2020+ if (ret) {2121+ if (ret != -EINVAL)2222+ return ret;2323+ return 0;2424+ }2525+2626+ if (uv == 0) {2727+ if (omask)2828+ return regmap_update_bits(regmap, oreg, omask, 0);2929+ }3030+ for (i = 0; i < desc->n_voltages; i++) {3131+ ret = regulator_desc_list_voltage_linear_range(desc, i);3232+ if (ret < 0)3333+ continue;3434+ if (ret == uv) {3535+ i <<= ffs(desc->vsel_mask) - 1;3636+ ret = regmap_update_bits(regmap, reg, mask, i);3737+ if (omask && !ret)3838+ ret = regmap_update_bits(regmap, oreg, omask,3939+ omask);4040+ break;4141+ }4242+ }4343+ return ret;4444+}4545+4646+int rohm_regulator_set_dvs_levels(const struct rohm_dvs_config *dvs,4747+ struct device_node *np,4848+ const struct regulator_desc *desc,4949+ struct regmap *regmap)5050+{5151+ int i, ret = 0;5252+ char *prop;5353+ unsigned int reg, mask, omask, oreg = desc->enable_reg;5454+5555+ for (i = 0; i < ROHM_DVS_LEVEL_MAX && !ret; i++) {5656+ if (dvs->level_map & (1 << i)) {5757+ switch (i + 1) {5858+ case ROHM_DVS_LEVEL_RUN:5959+ prop = "rohm,dvs-run-voltage";6060+ reg = dvs->run_reg;6161+ mask = dvs->run_mask;6262+ omask = dvs->run_on_mask;6363+ break;6464+ case ROHM_DVS_LEVEL_IDLE:6565+ prop = "rohm,dvs-idle-voltage";6666+ reg = dvs->idle_reg;6767+ mask = dvs->idle_mask;6868+ omask = dvs->idle_on_mask;6969+ break;7070+ case ROHM_DVS_LEVEL_SUSPEND:7171+ prop = "rohm,dvs-suspend-voltage";7272+ reg = dvs->suspend_reg;7373+ mask = dvs->suspend_mask;7474+ omask = dvs->suspend_on_mask;7575+ break;7676+ case ROHM_DVS_LEVEL_LPSR:7777+ prop = "rohm,dvs-lpsr-voltage";7878+ reg = dvs->lpsr_reg;7979+ mask = dvs->lpsr_mask;8080+ omask = dvs->lpsr_on_mask;8181+ break;8282+ default:8383+ return -EINVAL;8484+ }8585+ ret = set_dvs_level(desc, np, regmap, prop, reg, mask,8686+ omask, oreg);8787+ }8888+ }8989+ return ret;9090+}9191+EXPORT_SYMBOL(rohm_regulator_set_dvs_levels);9292+9393+MODULE_LICENSE("GPL v2");9494+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");9595+MODULE_DESCRIPTION("Generic helpers for ROHM PMIC regulator drivers");
+2-1
drivers/rtc/Kconfig
···498498 help499499 If you say Y here you will get support for the500500 watchdog timer in the ST M41T60 and M41T80 RTC chips series.501501+501502config RTC_DRV_BD70528502503 tristate "ROHM BD70528 PMIC RTC"503504 depends on MFD_ROHM_BD70528 && (BD70528_WATCHDOG || !BD70528_WATCHDOG)504505 help505506 If you say Y here you will get support for the RTC506506- on ROHM BD70528 Power Management IC.507507+ block on ROHM BD70528 and BD71828 Power Management IC.507508508509 This driver can also be built as a module. If so, the module509510 will be called rtc-bd70528.
+179-41
drivers/rtc/rtc-bd70528.c
···6677#include <linux/bcd.h>88#include <linux/mfd/rohm-bd70528.h>99+#include <linux/mfd/rohm-bd71828.h>910#include <linux/module.h>1011#include <linux/of.h>1112#include <linux/platform_device.h>···1615/*1716 * We read regs RTC_SEC => RTC_YEAR1817 * this struct is ordered according to chip registers.1919- * Keep it u8 only to avoid padding issues.1818+ * Keep it u8 only (or packed) to avoid padding issues.2019 */2120struct bd70528_rtc_day {2221 u8 sec;···3736 u8 ctrl;3837} __packed;39383939+struct bd71828_rtc_alm {4040+ struct bd70528_rtc_data alm0;4141+ struct bd70528_rtc_data alm1;4242+ u8 alm_mask;4343+ u8 alm1_mask;4444+} __packed;4545+4046struct bd70528_rtc_alm {4147 struct bd70528_rtc_data data;4248 u8 alm_mask;···5143} __packed;52445345struct bd70528_rtc {5454- struct rohm_regmap_dev *mfd;4646+ struct rohm_regmap_dev *parent;5547 struct device *dev;4848+ u8 reg_time_start;4949+ bool has_rtc_timers;5650};57515852static int bd70528_set_wake(struct rohm_regmap_dev *bd70528,···133123{134124 int ret;135125136136- ret = bd70528_wdt_set(r->mfd, new_state & BD70528_WDT_STATE_BIT,126126+ ret = bd70528_wdt_set(r->parent, new_state & BD70528_WDT_STATE_BIT,137127 old_state);138128 if (ret) {139129 dev_err(r->dev,140130 "Failed to disable WDG for RTC setting (%d)\n", ret);141131 return ret;142132 }143143- ret = bd70528_set_elapsed_tmr(r->mfd,133133+ ret = bd70528_set_elapsed_tmr(r->parent,144134 new_state & BD70528_ELAPSED_STATE_BIT,145135 old_state);146136 if (ret) {···148138 "Failed to disable 'elapsed timer' for RTC setting\n");149139 return ret;150140 }151151- ret = bd70528_set_wake(r->mfd, new_state & BD70528_WAKE_STATE_BIT,141141+ ret = bd70528_set_wake(r->parent, new_state & BD70528_WAKE_STATE_BIT,152142 old_state);153143 if (ret) {154144 dev_err(r->dev,···162152static int bd70528_re_enable_rtc_based_timers(struct bd70528_rtc *r,163153 int old_state)164154{155155+ if (!r->has_rtc_timers)156156+ return 0;157157+165158 return bd70528_set_rtc_based_timers(r, old_state, NULL);166159}167160168161static int bd70528_disable_rtc_based_timers(struct bd70528_rtc *r,169162 int *old_state)170163{164164+ if (!r->has_rtc_timers)165165+ return 0;166166+171167 return bd70528_set_rtc_based_timers(r, 0, old_state);172168}173169···229213 t->tm_wday = bcd2bin(r->week & BD70528_MASK_RTC_WEEK);230214}231215216216+static int bd71828_set_alarm(struct device *dev, struct rtc_wkalrm *a)217217+{218218+ int ret;219219+ struct bd71828_rtc_alm alm;220220+ struct bd70528_rtc *r = dev_get_drvdata(dev);221221+ struct rohm_regmap_dev *parent = r->parent;222222+223223+ ret = regmap_bulk_read(parent->regmap, BD71828_REG_RTC_ALM_START,224224+ &alm, sizeof(alm));225225+ if (ret) {226226+ dev_err(dev, "Failed to read alarm regs\n");227227+ return ret;228228+ }229229+230230+ tm2rtc(&a->time, &alm.alm0);231231+232232+ if (!a->enabled)233233+ alm.alm_mask &= ~BD70528_MASK_ALM_EN;234234+ else235235+ alm.alm_mask |= BD70528_MASK_ALM_EN;236236+237237+ ret = regmap_bulk_write(parent->regmap, BD71828_REG_RTC_ALM_START,238238+ &alm, sizeof(alm));239239+ if (ret)240240+ dev_err(dev, "Failed to set alarm time\n");241241+242242+ return ret;243243+244244+}245245+232246static int bd70528_set_alarm(struct device *dev, struct rtc_wkalrm *a)233247{234248 struct bd70528_rtc_wake wake;235249 struct bd70528_rtc_alm alm;236250 int ret;237251 struct bd70528_rtc *r = dev_get_drvdata(dev);238238- struct rohm_regmap_dev *bd70528 = r->mfd;252252+ struct rohm_regmap_dev *parent = r->parent;239253240240- ret = regmap_bulk_read(bd70528->regmap, BD70528_REG_RTC_WAKE_START,254254+ ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_WAKE_START,241255 &wake, sizeof(wake));242256 if (ret) {243257 dev_err(dev, "Failed to read wake regs\n");244258 return ret;245259 }246260247247- ret = regmap_bulk_read(bd70528->regmap, BD70528_REG_RTC_ALM_START,261261+ ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_ALM_START,248262 &alm, sizeof(alm));249263 if (ret) {250264 dev_err(dev, "Failed to read alarm regs\n");···292246 wake.ctrl &= ~BD70528_MASK_WAKE_EN;293247 }294248295295- ret = regmap_bulk_write(bd70528->regmap,249249+ ret = regmap_bulk_write(parent->regmap,296250 BD70528_REG_RTC_WAKE_START, &wake,297251 sizeof(wake));298252 if (ret) {299253 dev_err(dev, "Failed to set wake time\n");300254 return ret;301255 }302302- ret = regmap_bulk_write(bd70528->regmap, BD70528_REG_RTC_ALM_START,256256+ ret = regmap_bulk_write(parent->regmap, BD70528_REG_RTC_ALM_START,303257 &alm, sizeof(alm));304258 if (ret)305259 dev_err(dev, "Failed to set alarm time\n");···307261 return ret;308262}309263264264+static int bd71828_read_alarm(struct device *dev, struct rtc_wkalrm *a)265265+{266266+ int ret;267267+ struct bd71828_rtc_alm alm;268268+ struct bd70528_rtc *r = dev_get_drvdata(dev);269269+ struct rohm_regmap_dev *parent = r->parent;270270+271271+ ret = regmap_bulk_read(parent->regmap, BD71828_REG_RTC_ALM_START,272272+ &alm, sizeof(alm));273273+ if (ret) {274274+ dev_err(dev, "Failed to read alarm regs\n");275275+ return ret;276276+ }277277+278278+ rtc2tm(&alm.alm0, &a->time);279279+ a->time.tm_mday = -1;280280+ a->time.tm_mon = -1;281281+ a->time.tm_year = -1;282282+ a->enabled = !!(alm.alm_mask & BD70528_MASK_ALM_EN);283283+ a->pending = 0;284284+285285+ return 0;286286+}287287+310288static int bd70528_read_alarm(struct device *dev, struct rtc_wkalrm *a)311289{312290 struct bd70528_rtc_alm alm;313291 int ret;314292 struct bd70528_rtc *r = dev_get_drvdata(dev);315315- struct rohm_regmap_dev *bd70528 = r->mfd;293293+ struct rohm_regmap_dev *parent = r->parent;316294317317- ret = regmap_bulk_read(bd70528->regmap, BD70528_REG_RTC_ALM_START,295295+ ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_ALM_START,318296 &alm, sizeof(alm));319297 if (ret) {320298 dev_err(dev, "Failed to read alarm regs\n");···360290 int ret, tmpret, old_states;361291 struct bd70528_rtc_data rtc_data;362292 struct bd70528_rtc *r = dev_get_drvdata(dev);363363- struct rohm_regmap_dev *bd70528 = r->mfd;293293+ struct rohm_regmap_dev *parent = r->parent;364294365295 ret = bd70528_disable_rtc_based_timers(r, &old_states);366296 if (ret)367297 return ret;368298369369- tmpret = regmap_bulk_read(bd70528->regmap,370370- BD70528_REG_RTC_START, &rtc_data,299299+ tmpret = regmap_bulk_read(parent->regmap,300300+ r->reg_time_start, &rtc_data,371301 sizeof(rtc_data));372302 if (tmpret) {373303 dev_err(dev, "Failed to read RTC time registers\n");···375305 }376306 tm2rtc(t, &rtc_data);377307378378- tmpret = regmap_bulk_write(bd70528->regmap,379379- BD70528_REG_RTC_START, &rtc_data,308308+ tmpret = regmap_bulk_write(parent->regmap,309309+ r->reg_time_start, &rtc_data,380310 sizeof(rtc_data));381311 if (tmpret) {382312 dev_err(dev, "Failed to set RTC time\n");···391321 return ret;392322}393323324324+static int bd71828_set_time(struct device *dev, struct rtc_time *t)325325+{326326+ return bd70528_set_time_locked(dev, t);327327+}328328+394329static int bd70528_set_time(struct device *dev, struct rtc_time *t)395330{396331 int ret;397332 struct bd70528_rtc *r = dev_get_drvdata(dev);398333399399- bd70528_wdt_lock(r->mfd);334334+ bd70528_wdt_lock(r->parent);400335 ret = bd70528_set_time_locked(dev, t);401401- bd70528_wdt_unlock(r->mfd);336336+ bd70528_wdt_unlock(r->parent);402337 return ret;403338}404339405340static int bd70528_get_time(struct device *dev, struct rtc_time *t)406341{407342 struct bd70528_rtc *r = dev_get_drvdata(dev);408408- struct rohm_regmap_dev *bd70528 = r->mfd;343343+ struct rohm_regmap_dev *parent = r->parent;409344 struct bd70528_rtc_data rtc_data;410345 int ret;411346412347 /* read the RTC date and time registers all at once */413413- ret = regmap_bulk_read(bd70528->regmap,414414- BD70528_REG_RTC_START, &rtc_data,348348+ ret = regmap_bulk_read(parent->regmap,349349+ r->reg_time_start, &rtc_data,415350 sizeof(rtc_data));416351 if (ret) {417352 dev_err(dev, "Failed to read RTC time (err %d)\n", ret);···437362 if (enabled)438363 enableval = 0;439364440440- bd70528_wdt_lock(r->mfd);441441- ret = bd70528_set_wake(r->mfd, enabled, NULL);365365+ bd70528_wdt_lock(r->parent);366366+ ret = bd70528_set_wake(r->parent, enabled, NULL);442367 if (ret) {443368 dev_err(dev, "Failed to change wake state\n");444369 goto out_unlock;445370 }446446- ret = regmap_update_bits(r->mfd->regmap, BD70528_REG_RTC_ALM_MASK,371371+ ret = regmap_update_bits(r->parent->regmap, BD70528_REG_RTC_ALM_MASK,447372 BD70528_MASK_ALM_EN, enableval);448373 if (ret)449374 dev_err(dev, "Failed to change alarm state\n");450375451376out_unlock:452452- bd70528_wdt_unlock(r->mfd);377377+ bd70528_wdt_unlock(r->parent);378378+ return ret;379379+}380380+381381+static int bd71828_alm_enable(struct device *dev, unsigned int enabled)382382+{383383+ int ret;384384+ struct bd70528_rtc *r = dev_get_drvdata(dev);385385+ unsigned int enableval = BD70528_MASK_ALM_EN;386386+387387+ if (!enabled)388388+ enableval = 0;389389+390390+ ret = regmap_update_bits(r->parent->regmap, BD71828_REG_RTC_ALM0_MASK,391391+ BD70528_MASK_ALM_EN, enableval);392392+ if (ret)393393+ dev_err(dev, "Failed to change alarm state\n");394394+453395 return ret;454396}455397···476384 .read_alarm = bd70528_read_alarm,477385 .set_alarm = bd70528_set_alarm,478386 .alarm_irq_enable = bd70528_alm_enable,387387+};388388+389389+static const struct rtc_class_ops bd71828_rtc_ops = {390390+ .read_time = bd70528_get_time,391391+ .set_time = bd71828_set_time,392392+ .read_alarm = bd71828_read_alarm,393393+ .set_alarm = bd71828_set_alarm,394394+ .alarm_irq_enable = bd71828_alm_enable,479395};480396481397static irqreturn_t alm_hndlr(int irq, void *data)···497397static int bd70528_probe(struct platform_device *pdev)498398{499399 struct bd70528_rtc *bd_rtc;500500- struct rohm_regmap_dev *mfd;400400+ const struct rtc_class_ops *rtc_ops;401401+ struct rohm_regmap_dev *parent;402402+ const char *irq_name;501403 int ret;502404 struct rtc_device *rtc;503405 int irq;504406 unsigned int hr;407407+ bool enable_main_irq = false;408408+ u8 hour_reg;409409+ enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;505410506506- mfd = dev_get_drvdata(pdev->dev.parent);507507- if (!mfd) {411411+ parent = dev_get_drvdata(pdev->dev.parent);412412+ if (!parent) {508413 dev_err(&pdev->dev, "No MFD driver data\n");509414 return -EINVAL;510415 }···517412 if (!bd_rtc)518413 return -ENOMEM;519414520520- bd_rtc->mfd = mfd;415415+ bd_rtc->parent = parent;521416 bd_rtc->dev = &pdev->dev;522417523523- irq = platform_get_irq_byname(pdev, "bd70528-rtc-alm");524524- if (irq < 0)418418+ switch (chip) {419419+ case ROHM_CHIP_TYPE_BD70528:420420+ irq_name = "bd70528-rtc-alm";421421+ bd_rtc->has_rtc_timers = true;422422+ bd_rtc->reg_time_start = BD70528_REG_RTC_START;423423+ hour_reg = BD70528_REG_RTC_HOUR;424424+ enable_main_irq = true;425425+ rtc_ops = &bd70528_rtc_ops;426426+ break;427427+ case ROHM_CHIP_TYPE_BD71828:428428+ irq_name = "bd71828-rtc-alm-0";429429+ bd_rtc->reg_time_start = BD71828_REG_RTC_START;430430+ hour_reg = BD71828_REG_RTC_HOUR;431431+ rtc_ops = &bd71828_rtc_ops;432432+ break;433433+ default:434434+ dev_err(&pdev->dev, "Unknown chip\n");435435+ return -ENOENT;436436+ }437437+438438+ irq = platform_get_irq_byname(pdev, irq_name);439439+440440+ if (irq < 0) {441441+ dev_err(&pdev->dev, "Failed to get irq\n");525442 return irq;443443+ }526444527445 platform_set_drvdata(pdev, bd_rtc);528446529529- ret = regmap_read(mfd->regmap, BD70528_REG_RTC_HOUR, &hr);447447+ ret = regmap_read(parent->regmap, hour_reg, &hr);530448531449 if (ret) {532450 dev_err(&pdev->dev, "Failed to reag RTC clock\n");···559431 if (!(hr & BD70528_MASK_RTC_HOUR_24H)) {560432 struct rtc_time t;561433562562- ret = bd70528_get_time(&pdev->dev, &t);434434+ ret = rtc_ops->read_time(&pdev->dev, &t);563435564436 if (!ret)565565- ret = bd70528_set_time(&pdev->dev, &t);437437+ ret = rtc_ops->set_time(&pdev->dev, &t);566438567439 if (ret) {568440 dev_err(&pdev->dev,···582454583455 rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;584456 rtc->range_max = RTC_TIMESTAMP_END_2099;585585- rtc->ops = &bd70528_rtc_ops;457457+ rtc->ops = rtc_ops;586458587459 /* Request alarm IRQ prior to registerig the RTC */588460 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, &alm_hndlr,···596468 * leave them enabled as irq-controller should disable irqs597469 * from sub-registers when IRQ is disabled or freed.598470 */599599- ret = regmap_update_bits(mfd->regmap,471471+ if (enable_main_irq) {472472+ ret = regmap_update_bits(parent->regmap,600473 BD70528_REG_INT_MAIN_MASK,601474 BD70528_INT_RTC_MASK, 0);602602- if (ret) {603603- dev_err(&pdev->dev, "Failed to enable RTC interrupts\n");604604- return ret;475475+ if (ret) {476476+ dev_err(&pdev->dev, "Failed to enable RTC interrupts\n");477477+ return ret;478478+ }605479 }606480607481 return rtc_register_device(rtc);608482}483483+484484+static const struct platform_device_id bd718x7_rtc_id[] = {485485+ { "bd70528-rtc", ROHM_CHIP_TYPE_BD70528 },486486+ { "bd71828-rtc", ROHM_CHIP_TYPE_BD71828 },487487+ { },488488+};489489+MODULE_DEVICE_TABLE(platform, bd718x7_rtc_id);609490610491static struct platform_driver bd70528_rtc = {611492 .driver = {612493 .name = "bd70528-rtc"613494 },614495 .probe = bd70528_probe,496496+ .id_table = bd718x7_rtc_id,615497};616498617499module_platform_driver(bd70528_rtc);618500619501MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");620620-MODULE_DESCRIPTION("BD70528 RTC driver");502502+MODULE_DESCRIPTION("ROHM BD70528 and BD71828 PMIC RTC driver");621503MODULE_LICENSE("GPL");622504MODULE_ALIAS("platform:bd70528-rtc");
+1-18
include/linux/mfd/rohm-bd70528.h
···77#include <linux/bits.h>88#include <linux/device.h>99#include <linux/mfd/rohm-generic.h>1010+#include <linux/mfd/rohm-shared.h>1011#include <linux/regmap.h>11121213enum {···8988#define BD70528_REG_GPIO2_OUT 0x509089#define BD70528_REG_GPIO3_OUT 0x529190#define BD70528_REG_GPIO4_OUT 0x549292-9393-/* clk control */9494-9595-#define BD70528_REG_CLK_OUT 0x2c96919792/* RTC */9893···306309307310#define BD70528_GPIO_IN_STATE_BASE 1308311309309-#define BD70528_CLK_OUT_EN_MASK 0x1310310-311312/* RTC masks to mask out reserved bits */312312-313313-#define BD70528_MASK_RTC_SEC 0x7f314314-#define BD70528_MASK_RTC_MINUTE 0x7f315315-#define BD70528_MASK_RTC_HOUR_24H 0x80316316-#define BD70528_MASK_RTC_HOUR_PM 0x20317317-#define BD70528_MASK_RTC_HOUR 0x1f318318-#define BD70528_MASK_RTC_DAY 0x3f319319-#define BD70528_MASK_RTC_WEEK 0x07320320-#define BD70528_MASK_RTC_MONTH 0x1f321321-#define BD70528_MASK_RTC_YEAR 0xff322322-#define BD70528_MASK_RTC_COUNT_L 0x7f323313324314#define BD70528_MASK_ELAPSED_TIMER_EN 0x1325315/* Mask second, min and hour fields···316332 * wake-up we limit ALM to 24H and only317333 * unmask sec, min and hour318334 */319319-#define BD70528_MASK_ALM_EN 0x7320335#define BD70528_MASK_WAKE_EN 0x1321336322337/* WDT masks */
···44#ifndef __LINUX_MFD_ROHM_H__55#define __LINUX_MFD_ROHM_H__6677-enum {77+#include <linux/regmap.h>88+#include <linux/regulator/driver.h>99+1010+enum rohm_chip_type {811 ROHM_CHIP_TYPE_BD71837 = 0,912 ROHM_CHIP_TYPE_BD71847,1013 ROHM_CHIP_TYPE_BD70528,1414+ ROHM_CHIP_TYPE_BD71828,1115 ROHM_CHIP_TYPE_AMOUNT1216};13171418struct rohm_regmap_dev {1515- unsigned int chip_type;1619 struct device *dev;1720 struct regmap *regmap;1821};2222+2323+enum {2424+ ROHM_DVS_LEVEL_UNKNOWN,2525+ ROHM_DVS_LEVEL_RUN,2626+ ROHM_DVS_LEVEL_IDLE,2727+ ROHM_DVS_LEVEL_SUSPEND,2828+ ROHM_DVS_LEVEL_LPSR,2929+ ROHM_DVS_LEVEL_MAX = ROHM_DVS_LEVEL_LPSR,3030+};3131+3232+/**3333+ * struct rohm_dvs_config - dynamic voltage scaling register descriptions3434+ *3535+ * @level_map: bitmap representing supported run-levels for this3636+ * regulator3737+ * @run_reg: register address for regulator config at 'run' state3838+ * @run_mask: value mask for regulator voltages at 'run' state3939+ * @run_on_mask: enable mask for regulator at 'run' state4040+ * @idle_reg: register address for regulator config at 'idle' state4141+ * @idle_mask: value mask for regulator voltages at 'idle' state4242+ * @idle_on_mask: enable mask for regulator at 'idle' state4343+ * @suspend_reg: register address for regulator config at 'suspend' state4444+ * @suspend_mask: value mask for regulator voltages at 'suspend' state4545+ * @suspend_on_mask: enable mask for regulator at 'suspend' state4646+ * @lpsr_reg: register address for regulator config at 'lpsr' state4747+ * @lpsr_mask: value mask for regulator voltages at 'lpsr' state4848+ * @lpsr_on_mask: enable mask for regulator at 'lpsr' state4949+ *5050+ * Description of ROHM PMICs voltage configuration registers for different5151+ * system states. This is used to correctly configure the PMIC at startup5252+ * based on values read from DT.5353+ */5454+struct rohm_dvs_config {5555+ uint64_t level_map;5656+ unsigned int run_reg;5757+ unsigned int run_mask;5858+ unsigned int run_on_mask;5959+ unsigned int idle_reg;6060+ unsigned int idle_mask;6161+ unsigned int idle_on_mask;6262+ unsigned int suspend_reg;6363+ unsigned int suspend_mask;6464+ unsigned int suspend_on_mask;6565+ unsigned int lpsr_reg;6666+ unsigned int lpsr_mask;6767+ unsigned int lpsr_on_mask;6868+};6969+7070+#if IS_ENABLED(CONFIG_REGULATOR_ROHM)7171+int rohm_regulator_set_dvs_levels(const struct rohm_dvs_config *dvs,7272+ struct device_node *np,7373+ const struct regulator_desc *desc,7474+ struct regmap *regmap);7575+7676+#else7777+static inline int rohm_regulator_set_dvs_levels(const struct rohm_dvs_config *dvs,7878+ struct device_node *np,7979+ const struct regulator_desc *desc,8080+ struct regmap *regmap)8181+{8282+ return 0;8383+}8484+#endif19852086#endif