Commit fe5a591b authored by Matti Vaittinen's avatar Matti Vaittinen Committed by Lee Jones

rtc: bd70528: add BD71828 support

ROHM BD71828 PMIC RTC block is from many parts similar to one
on BD70528. Support BD71828 RTC using BD70528 RTC driver and
avoid re-inventing the wheel.
Signed-off-by: default avatarMatti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
Acked-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: default avatarLee Jones <lee.jones@linaro.org>
parent 6c883472
...@@ -498,12 +498,13 @@ config RTC_DRV_M41T80_WDT ...@@ -498,12 +498,13 @@ config RTC_DRV_M41T80_WDT
help help
If you say Y here you will get support for the If you say Y here you will get support for the
watchdog timer in the ST M41T60 and M41T80 RTC chips series. watchdog timer in the ST M41T60 and M41T80 RTC chips series.
config RTC_DRV_BD70528 config RTC_DRV_BD70528
tristate "ROHM BD70528 PMIC RTC" tristate "ROHM BD70528 PMIC RTC"
depends on MFD_ROHM_BD70528 && (BD70528_WATCHDOG || !BD70528_WATCHDOG) depends on MFD_ROHM_BD70528 && (BD70528_WATCHDOG || !BD70528_WATCHDOG)
help help
If you say Y here you will get support for the RTC If you say Y here you will get support for the RTC
on ROHM BD70528 Power Management IC. block on ROHM BD70528 and BD71828 Power Management IC.
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called rtc-bd70528. will be called rtc-bd70528.
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/bcd.h> #include <linux/bcd.h>
#include <linux/mfd/rohm-bd70528.h> #include <linux/mfd/rohm-bd70528.h>
#include <linux/mfd/rohm-bd71828.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -15,7 +16,7 @@ ...@@ -15,7 +16,7 @@
/* /*
* We read regs RTC_SEC => RTC_YEAR * We read regs RTC_SEC => RTC_YEAR
* this struct is ordered according to chip registers. * this struct is ordered according to chip registers.
* Keep it u8 only to avoid padding issues. * Keep it u8 only (or packed) to avoid padding issues.
*/ */
struct bd70528_rtc_day { struct bd70528_rtc_day {
u8 sec; u8 sec;
...@@ -36,6 +37,13 @@ struct bd70528_rtc_wake { ...@@ -36,6 +37,13 @@ struct bd70528_rtc_wake {
u8 ctrl; u8 ctrl;
} __packed; } __packed;
struct bd71828_rtc_alm {
struct bd70528_rtc_data alm0;
struct bd70528_rtc_data alm1;
u8 alm_mask;
u8 alm1_mask;
} __packed;
struct bd70528_rtc_alm { struct bd70528_rtc_alm {
struct bd70528_rtc_data data; struct bd70528_rtc_data data;
u8 alm_mask; u8 alm_mask;
...@@ -43,8 +51,10 @@ struct bd70528_rtc_alm { ...@@ -43,8 +51,10 @@ struct bd70528_rtc_alm {
} __packed; } __packed;
struct bd70528_rtc { struct bd70528_rtc {
struct rohm_regmap_dev *mfd; struct rohm_regmap_dev *parent;
struct device *dev; struct device *dev;
u8 reg_time_start;
bool has_rtc_timers;
}; };
static int bd70528_set_wake(struct rohm_regmap_dev *bd70528, static int bd70528_set_wake(struct rohm_regmap_dev *bd70528,
...@@ -123,14 +133,14 @@ static int bd70528_set_rtc_based_timers(struct bd70528_rtc *r, int new_state, ...@@ -123,14 +133,14 @@ static int bd70528_set_rtc_based_timers(struct bd70528_rtc *r, int new_state,
{ {
int ret; int ret;
ret = bd70528_wdt_set(r->mfd, new_state & BD70528_WDT_STATE_BIT, ret = bd70528_wdt_set(r->parent, new_state & BD70528_WDT_STATE_BIT,
old_state); old_state);
if (ret) { if (ret) {
dev_err(r->dev, dev_err(r->dev,
"Failed to disable WDG for RTC setting (%d)\n", ret); "Failed to disable WDG for RTC setting (%d)\n", ret);
return ret; return ret;
} }
ret = bd70528_set_elapsed_tmr(r->mfd, ret = bd70528_set_elapsed_tmr(r->parent,
new_state & BD70528_ELAPSED_STATE_BIT, new_state & BD70528_ELAPSED_STATE_BIT,
old_state); old_state);
if (ret) { if (ret) {
...@@ -138,7 +148,7 @@ static int bd70528_set_rtc_based_timers(struct bd70528_rtc *r, int new_state, ...@@ -138,7 +148,7 @@ static int bd70528_set_rtc_based_timers(struct bd70528_rtc *r, int new_state,
"Failed to disable 'elapsed timer' for RTC setting\n"); "Failed to disable 'elapsed timer' for RTC setting\n");
return ret; return ret;
} }
ret = bd70528_set_wake(r->mfd, new_state & BD70528_WAKE_STATE_BIT, ret = bd70528_set_wake(r->parent, new_state & BD70528_WAKE_STATE_BIT,
old_state); old_state);
if (ret) { if (ret) {
dev_err(r->dev, dev_err(r->dev,
...@@ -152,12 +162,18 @@ static int bd70528_set_rtc_based_timers(struct bd70528_rtc *r, int new_state, ...@@ -152,12 +162,18 @@ static int bd70528_set_rtc_based_timers(struct bd70528_rtc *r, int new_state,
static int bd70528_re_enable_rtc_based_timers(struct bd70528_rtc *r, static int bd70528_re_enable_rtc_based_timers(struct bd70528_rtc *r,
int old_state) int old_state)
{ {
if (!r->has_rtc_timers)
return 0;
return bd70528_set_rtc_based_timers(r, old_state, NULL); return bd70528_set_rtc_based_timers(r, old_state, NULL);
} }
static int bd70528_disable_rtc_based_timers(struct bd70528_rtc *r, static int bd70528_disable_rtc_based_timers(struct bd70528_rtc *r,
int *old_state) int *old_state)
{ {
if (!r->has_rtc_timers)
return 0;
return bd70528_set_rtc_based_timers(r, 0, old_state); return bd70528_set_rtc_based_timers(r, 0, old_state);
} }
...@@ -213,22 +229,52 @@ static inline void rtc2tm(struct bd70528_rtc_data *r, struct rtc_time *t) ...@@ -213,22 +229,52 @@ static inline void rtc2tm(struct bd70528_rtc_data *r, struct rtc_time *t)
t->tm_wday = bcd2bin(r->week & BD70528_MASK_RTC_WEEK); t->tm_wday = bcd2bin(r->week & BD70528_MASK_RTC_WEEK);
} }
static int bd71828_set_alarm(struct device *dev, struct rtc_wkalrm *a)
{
int ret;
struct bd71828_rtc_alm alm;
struct bd70528_rtc *r = dev_get_drvdata(dev);
struct rohm_regmap_dev *parent = r->parent;
ret = regmap_bulk_read(parent->regmap, BD71828_REG_RTC_ALM_START,
&alm, sizeof(alm));
if (ret) {
dev_err(dev, "Failed to read alarm regs\n");
return ret;
}
tm2rtc(&a->time, &alm.alm0);
if (!a->enabled)
alm.alm_mask &= ~BD70528_MASK_ALM_EN;
else
alm.alm_mask |= BD70528_MASK_ALM_EN;
ret = regmap_bulk_write(parent->regmap, BD71828_REG_RTC_ALM_START,
&alm, sizeof(alm));
if (ret)
dev_err(dev, "Failed to set alarm time\n");
return ret;
}
static int bd70528_set_alarm(struct device *dev, struct rtc_wkalrm *a) static int bd70528_set_alarm(struct device *dev, struct rtc_wkalrm *a)
{ {
struct bd70528_rtc_wake wake; struct bd70528_rtc_wake wake;
struct bd70528_rtc_alm alm; struct bd70528_rtc_alm alm;
int ret; int ret;
struct bd70528_rtc *r = dev_get_drvdata(dev); struct bd70528_rtc *r = dev_get_drvdata(dev);
struct rohm_regmap_dev *bd70528 = r->mfd; struct rohm_regmap_dev *parent = r->parent;
ret = regmap_bulk_read(bd70528->regmap, BD70528_REG_RTC_WAKE_START, ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_WAKE_START,
&wake, sizeof(wake)); &wake, sizeof(wake));
if (ret) { if (ret) {
dev_err(dev, "Failed to read wake regs\n"); dev_err(dev, "Failed to read wake regs\n");
return ret; return ret;
} }
ret = regmap_bulk_read(bd70528->regmap, BD70528_REG_RTC_ALM_START, ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_ALM_START,
&alm, sizeof(alm)); &alm, sizeof(alm));
if (ret) { if (ret) {
dev_err(dev, "Failed to read alarm regs\n"); dev_err(dev, "Failed to read alarm regs\n");
...@@ -246,14 +292,14 @@ static int bd70528_set_alarm(struct device *dev, struct rtc_wkalrm *a) ...@@ -246,14 +292,14 @@ static int bd70528_set_alarm(struct device *dev, struct rtc_wkalrm *a)
wake.ctrl &= ~BD70528_MASK_WAKE_EN; wake.ctrl &= ~BD70528_MASK_WAKE_EN;
} }
ret = regmap_bulk_write(bd70528->regmap, ret = regmap_bulk_write(parent->regmap,
BD70528_REG_RTC_WAKE_START, &wake, BD70528_REG_RTC_WAKE_START, &wake,
sizeof(wake)); sizeof(wake));
if (ret) { if (ret) {
dev_err(dev, "Failed to set wake time\n"); dev_err(dev, "Failed to set wake time\n");
return ret; return ret;
} }
ret = regmap_bulk_write(bd70528->regmap, BD70528_REG_RTC_ALM_START, ret = regmap_bulk_write(parent->regmap, BD70528_REG_RTC_ALM_START,
&alm, sizeof(alm)); &alm, sizeof(alm));
if (ret) if (ret)
dev_err(dev, "Failed to set alarm time\n"); dev_err(dev, "Failed to set alarm time\n");
...@@ -261,14 +307,38 @@ static int bd70528_set_alarm(struct device *dev, struct rtc_wkalrm *a) ...@@ -261,14 +307,38 @@ static int bd70528_set_alarm(struct device *dev, struct rtc_wkalrm *a)
return ret; return ret;
} }
static int bd71828_read_alarm(struct device *dev, struct rtc_wkalrm *a)
{
int ret;
struct bd71828_rtc_alm alm;
struct bd70528_rtc *r = dev_get_drvdata(dev);
struct rohm_regmap_dev *parent = r->parent;
ret = regmap_bulk_read(parent->regmap, BD71828_REG_RTC_ALM_START,
&alm, sizeof(alm));
if (ret) {
dev_err(dev, "Failed to read alarm regs\n");
return ret;
}
rtc2tm(&alm.alm0, &a->time);
a->time.tm_mday = -1;
a->time.tm_mon = -1;
a->time.tm_year = -1;
a->enabled = !!(alm.alm_mask & BD70528_MASK_ALM_EN);
a->pending = 0;
return 0;
}
static int bd70528_read_alarm(struct device *dev, struct rtc_wkalrm *a) static int bd70528_read_alarm(struct device *dev, struct rtc_wkalrm *a)
{ {
struct bd70528_rtc_alm alm; struct bd70528_rtc_alm alm;
int ret; int ret;
struct bd70528_rtc *r = dev_get_drvdata(dev); struct bd70528_rtc *r = dev_get_drvdata(dev);
struct rohm_regmap_dev *bd70528 = r->mfd; struct rohm_regmap_dev *parent = r->parent;
ret = regmap_bulk_read(bd70528->regmap, BD70528_REG_RTC_ALM_START, ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_ALM_START,
&alm, sizeof(alm)); &alm, sizeof(alm));
if (ret) { if (ret) {
dev_err(dev, "Failed to read alarm regs\n"); dev_err(dev, "Failed to read alarm regs\n");
...@@ -290,14 +360,14 @@ static int bd70528_set_time_locked(struct device *dev, struct rtc_time *t) ...@@ -290,14 +360,14 @@ static int bd70528_set_time_locked(struct device *dev, struct rtc_time *t)
int ret, tmpret, old_states; int ret, tmpret, old_states;
struct bd70528_rtc_data rtc_data; struct bd70528_rtc_data rtc_data;
struct bd70528_rtc *r = dev_get_drvdata(dev); struct bd70528_rtc *r = dev_get_drvdata(dev);
struct rohm_regmap_dev *bd70528 = r->mfd; struct rohm_regmap_dev *parent = r->parent;
ret = bd70528_disable_rtc_based_timers(r, &old_states); ret = bd70528_disable_rtc_based_timers(r, &old_states);
if (ret) if (ret)
return ret; return ret;
tmpret = regmap_bulk_read(bd70528->regmap, tmpret = regmap_bulk_read(parent->regmap,
BD70528_REG_RTC_START, &rtc_data, r->reg_time_start, &rtc_data,
sizeof(rtc_data)); sizeof(rtc_data));
if (tmpret) { if (tmpret) {
dev_err(dev, "Failed to read RTC time registers\n"); dev_err(dev, "Failed to read RTC time registers\n");
...@@ -305,8 +375,8 @@ static int bd70528_set_time_locked(struct device *dev, struct rtc_time *t) ...@@ -305,8 +375,8 @@ static int bd70528_set_time_locked(struct device *dev, struct rtc_time *t)
} }
tm2rtc(t, &rtc_data); tm2rtc(t, &rtc_data);
tmpret = regmap_bulk_write(bd70528->regmap, tmpret = regmap_bulk_write(parent->regmap,
BD70528_REG_RTC_START, &rtc_data, r->reg_time_start, &rtc_data,
sizeof(rtc_data)); sizeof(rtc_data));
if (tmpret) { if (tmpret) {
dev_err(dev, "Failed to set RTC time\n"); dev_err(dev, "Failed to set RTC time\n");
...@@ -321,27 +391,32 @@ static int bd70528_set_time_locked(struct device *dev, struct rtc_time *t) ...@@ -321,27 +391,32 @@ static int bd70528_set_time_locked(struct device *dev, struct rtc_time *t)
return ret; return ret;
} }
static int bd71828_set_time(struct device *dev, struct rtc_time *t)
{
return bd70528_set_time_locked(dev, t);
}
static int bd70528_set_time(struct device *dev, struct rtc_time *t) static int bd70528_set_time(struct device *dev, struct rtc_time *t)
{ {
int ret; int ret;
struct bd70528_rtc *r = dev_get_drvdata(dev); struct bd70528_rtc *r = dev_get_drvdata(dev);
bd70528_wdt_lock(r->mfd); bd70528_wdt_lock(r->parent);
ret = bd70528_set_time_locked(dev, t); ret = bd70528_set_time_locked(dev, t);
bd70528_wdt_unlock(r->mfd); bd70528_wdt_unlock(r->parent);
return ret; return ret;
} }
static int bd70528_get_time(struct device *dev, struct rtc_time *t) static int bd70528_get_time(struct device *dev, struct rtc_time *t)
{ {
struct bd70528_rtc *r = dev_get_drvdata(dev); struct bd70528_rtc *r = dev_get_drvdata(dev);
struct rohm_regmap_dev *bd70528 = r->mfd; struct rohm_regmap_dev *parent = r->parent;
struct bd70528_rtc_data rtc_data; struct bd70528_rtc_data rtc_data;
int ret; int ret;
/* read the RTC date and time registers all at once */ /* read the RTC date and time registers all at once */
ret = regmap_bulk_read(bd70528->regmap, ret = regmap_bulk_read(parent->regmap,
BD70528_REG_RTC_START, &rtc_data, r->reg_time_start, &rtc_data,
sizeof(rtc_data)); sizeof(rtc_data));
if (ret) { if (ret) {
dev_err(dev, "Failed to read RTC time (err %d)\n", ret); dev_err(dev, "Failed to read RTC time (err %d)\n", ret);
...@@ -362,19 +437,36 @@ static int bd70528_alm_enable(struct device *dev, unsigned int enabled) ...@@ -362,19 +437,36 @@ static int bd70528_alm_enable(struct device *dev, unsigned int enabled)
if (enabled) if (enabled)
enableval = 0; enableval = 0;
bd70528_wdt_lock(r->mfd); bd70528_wdt_lock(r->parent);
ret = bd70528_set_wake(r->mfd, enabled, NULL); ret = bd70528_set_wake(r->parent, enabled, NULL);
if (ret) { if (ret) {
dev_err(dev, "Failed to change wake state\n"); dev_err(dev, "Failed to change wake state\n");
goto out_unlock; goto out_unlock;
} }
ret = regmap_update_bits(r->mfd->regmap, BD70528_REG_RTC_ALM_MASK, ret = regmap_update_bits(r->parent->regmap, BD70528_REG_RTC_ALM_MASK,
BD70528_MASK_ALM_EN, enableval); BD70528_MASK_ALM_EN, enableval);
if (ret) if (ret)
dev_err(dev, "Failed to change alarm state\n"); dev_err(dev, "Failed to change alarm state\n");
out_unlock: out_unlock:
bd70528_wdt_unlock(r->mfd); bd70528_wdt_unlock(r->parent);
return ret;
}
static int bd71828_alm_enable(struct device *dev, unsigned int enabled)
{
int ret;
struct bd70528_rtc *r = dev_get_drvdata(dev);
unsigned int enableval = BD70528_MASK_ALM_EN;
if (!enabled)
enableval = 0;
ret = regmap_update_bits(r->parent->regmap, BD71828_REG_RTC_ALM0_MASK,
BD70528_MASK_ALM_EN, enableval);
if (ret)
dev_err(dev, "Failed to change alarm state\n");
return ret; return ret;
} }
...@@ -386,6 +478,14 @@ static const struct rtc_class_ops bd70528_rtc_ops = { ...@@ -386,6 +478,14 @@ static const struct rtc_class_ops bd70528_rtc_ops = {
.alarm_irq_enable = bd70528_alm_enable, .alarm_irq_enable = bd70528_alm_enable,
}; };
static const struct rtc_class_ops bd71828_rtc_ops = {
.read_time = bd70528_get_time,
.set_time = bd71828_set_time,
.read_alarm = bd71828_read_alarm,
.set_alarm = bd71828_set_alarm,
.alarm_irq_enable = bd71828_alm_enable,
};
static irqreturn_t alm_hndlr(int irq, void *data) static irqreturn_t alm_hndlr(int irq, void *data)
{ {
struct rtc_device *rtc = data; struct rtc_device *rtc = data;
...@@ -397,14 +497,19 @@ static irqreturn_t alm_hndlr(int irq, void *data) ...@@ -397,14 +497,19 @@ static irqreturn_t alm_hndlr(int irq, void *data)
static int bd70528_probe(struct platform_device *pdev) static int bd70528_probe(struct platform_device *pdev)
{ {
struct bd70528_rtc *bd_rtc; struct bd70528_rtc *bd_rtc;
struct rohm_regmap_dev *mfd; const struct rtc_class_ops *rtc_ops;
struct rohm_regmap_dev *parent;
const char *irq_name;
int ret; int ret;
struct rtc_device *rtc; struct rtc_device *rtc;
int irq; int irq;
unsigned int hr; unsigned int hr;
bool enable_main_irq = false;
u8 hour_reg;
enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;
mfd = dev_get_drvdata(pdev->dev.parent); parent = dev_get_drvdata(pdev->dev.parent);
if (!mfd) { if (!parent) {
dev_err(&pdev->dev, "No MFD driver data\n"); dev_err(&pdev->dev, "No MFD driver data\n");
return -EINVAL; return -EINVAL;
} }
...@@ -412,16 +517,39 @@ static int bd70528_probe(struct platform_device *pdev) ...@@ -412,16 +517,39 @@ static int bd70528_probe(struct platform_device *pdev)
if (!bd_rtc) if (!bd_rtc)
return -ENOMEM; return -ENOMEM;
bd_rtc->mfd = mfd; bd_rtc->parent = parent;
bd_rtc->dev = &pdev->dev; bd_rtc->dev = &pdev->dev;
irq = platform_get_irq_byname(pdev, "bd70528-rtc-alm"); switch (chip) {
if (irq < 0) case ROHM_CHIP_TYPE_BD70528:
irq_name = "bd70528-rtc-alm";
bd_rtc->has_rtc_timers = true;
bd_rtc->reg_time_start = BD70528_REG_RTC_START;
hour_reg = BD70528_REG_RTC_HOUR;
enable_main_irq = true;
rtc_ops = &bd70528_rtc_ops;
break;
case ROHM_CHIP_TYPE_BD71828:
irq_name = "bd71828-rtc-alm-0";
bd_rtc->reg_time_start = BD71828_REG_RTC_START;
hour_reg = BD71828_REG_RTC_HOUR;
rtc_ops = &bd71828_rtc_ops;
break;
default:
dev_err(&pdev->dev, "Unknown chip\n");
return -ENOENT;
}
irq = platform_get_irq_byname(pdev, irq_name);
if (irq < 0) {
dev_err(&pdev->dev, "Failed to get irq\n");
return irq; return irq;
}
platform_set_drvdata(pdev, bd_rtc); platform_set_drvdata(pdev, bd_rtc);
ret = regmap_read(mfd->regmap, BD70528_REG_RTC_HOUR, &hr); ret = regmap_read(parent->regmap, hour_reg, &hr);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Failed to reag RTC clock\n"); dev_err(&pdev->dev, "Failed to reag RTC clock\n");
...@@ -431,10 +559,10 @@ static int bd70528_probe(struct platform_device *pdev) ...@@ -431,10 +559,10 @@ static int bd70528_probe(struct platform_device *pdev)
if (!(hr & BD70528_MASK_RTC_HOUR_24H)) { if (!(hr & BD70528_MASK_RTC_HOUR_24H)) {
struct rtc_time t; struct rtc_time t;
ret = bd70528_get_time(&pdev->dev, &t); ret = rtc_ops->read_time(&pdev->dev, &t);
if (!ret) if (!ret)
ret = bd70528_set_time(&pdev->dev, &t); ret = rtc_ops->set_time(&pdev->dev, &t);
if (ret) { if (ret) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
...@@ -454,7 +582,7 @@ static int bd70528_probe(struct platform_device *pdev) ...@@ -454,7 +582,7 @@ static int bd70528_probe(struct platform_device *pdev)
rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
rtc->range_max = RTC_TIMESTAMP_END_2099; rtc->range_max = RTC_TIMESTAMP_END_2099;
rtc->ops = &bd70528_rtc_ops; rtc->ops = rtc_ops;
/* Request alarm IRQ prior to registerig the RTC */ /* Request alarm IRQ prior to registerig the RTC */
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, &alm_hndlr, ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, &alm_hndlr,
...@@ -468,27 +596,37 @@ static int bd70528_probe(struct platform_device *pdev) ...@@ -468,27 +596,37 @@ static int bd70528_probe(struct platform_device *pdev)
* leave them enabled as irq-controller should disable irqs * leave them enabled as irq-controller should disable irqs
* from sub-registers when IRQ is disabled or freed. * from sub-registers when IRQ is disabled or freed.
*/ */
ret = regmap_update_bits(mfd->regmap, if (enable_main_irq) {
ret = regmap_update_bits(parent->regmap,
BD70528_REG_INT_MAIN_MASK, BD70528_REG_INT_MAIN_MASK,
BD70528_INT_RTC_MASK, 0); BD70528_INT_RTC_MASK, 0);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Failed to enable RTC interrupts\n"); dev_err(&pdev->dev, "Failed to enable RTC interrupts\n");
return ret; return ret;
} }
}
return rtc_register_device(rtc); return rtc_register_device(rtc);
} }
static const struct platform_device_id bd718x7_rtc_id[] = {
{ "bd70528-rtc", ROHM_CHIP_TYPE_BD70528 },
{ "bd71828-rtc", ROHM_CHIP_TYPE_BD71828 },
{ },
};
MODULE_DEVICE_TABLE(platform, bd718x7_rtc_id);
static struct platform_driver bd70528_rtc = { static struct platform_driver bd70528_rtc = {
.driver = { .driver = {
.name = "bd70528-rtc" .name = "bd70528-rtc"
}, },
.probe = bd70528_probe, .probe = bd70528_probe,
.id_table = bd718x7_rtc_id,
}; };
module_platform_driver(bd70528_rtc); module_platform_driver(bd70528_rtc);
MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
MODULE_DESCRIPTION("BD70528 RTC driver"); MODULE_DESCRIPTION("ROHM BD70528 and BD71828 PMIC RTC driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:bd70528-rtc"); MODULE_ALIAS("platform:bd70528-rtc");
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/bits.h> #include <linux/bits.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/mfd/rohm-generic.h> #include <linux/mfd/rohm-generic.h>
#include <linux/mfd/rohm-shared.h>
#include <linux/regmap.h> #include <linux/regmap.h>
enum { enum {
...@@ -307,17 +308,6 @@ enum { ...@@ -307,17 +308,6 @@ enum {
/* RTC masks to mask out reserved bits */ /* RTC masks to mask out reserved bits */
#define BD70528_MASK_RTC_SEC 0x7f
#define BD70528_MASK_RTC_MINUTE 0x7f
#define BD70528_MASK_RTC_HOUR_24H 0x80
#define BD70528_MASK_RTC_HOUR_PM 0x20
#define BD70528_MASK_RTC_HOUR 0x3f
#define BD70528_MASK_RTC_DAY 0x3f
#define BD70528_MASK_RTC_WEEK 0x07
#define BD70528_MASK_RTC_MONTH 0x1f
#define BD70528_MASK_RTC_YEAR 0xff
#define BD70528_MASK_RTC_COUNT_L 0x7f
#define BD70528_MASK_ELAPSED_TIMER_EN 0x1 #define BD70528_MASK_ELAPSED_TIMER_EN 0x1
/* Mask second, min and hour fields /* Mask second, min and hour fields
* HW would support ALM irq for over 24h * HW would support ALM irq for over 24h
...@@ -326,7 +316,6 @@ enum { ...@@ -326,7 +316,6 @@ enum {
* wake-up we limit ALM to 24H and only * wake-up we limit ALM to 24H and only
* unmask sec, min and hour * unmask sec, min and hour
*/ */
#define BD70528_MASK_ALM_EN 0x7
#define BD70528_MASK_WAKE_EN 0x1 #define BD70528_MASK_WAKE_EN 0x1
/* WDT masks */ /* WDT masks */
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#define __LINUX_MFD_BD71828_H__ #define __LINUX_MFD_BD71828_H__
#include <linux/mfd/rohm-generic.h> #include <linux/mfd/rohm-generic.h>
#include <linux/mfd/rohm-shared.h>
/* Regulator IDs */ /* Regulator IDs */
enum { enum {
...@@ -160,6 +161,7 @@ enum { ...@@ -160,6 +161,7 @@ enum {
#define BD71828_REG_RTC_YEAR 0x52 #define BD71828_REG_RTC_YEAR 0x52
#define BD71828_REG_RTC_ALM0_SEC 0x53 #define BD71828_REG_RTC_ALM0_SEC 0x53
#define BD71828_REG_RTC_ALM_START BD71828_REG_RTC_ALM0_SEC
#define BD71828_REG_RTC_ALM0_MINUTE 0x54 #define BD71828_REG_RTC_ALM0_MINUTE 0x54
#define BD71828_REG_RTC_ALM0_HOUR 0x55 #define BD71828_REG_RTC_ALM0_HOUR 0x55
#define BD71828_REG_RTC_ALM0_WEEK 0x56 #define BD71828_REG_RTC_ALM0_WEEK 0x56
...@@ -178,6 +180,7 @@ enum { ...@@ -178,6 +180,7 @@ enum {
#define BD71828_REG_RTC_ALM1_MASK 0x62 #define BD71828_REG_RTC_ALM1_MASK 0x62
#define BD71828_REG_RTC_ALM2 0x63 #define BD71828_REG_RTC_ALM2 0x63
#define BD71828_REG_RTC_START BD71828_REG_RTC_SEC
/* Charger/Battey */ /* Charger/Battey */
#define BD71828_REG_CHG_STATE 0x65 #define BD71828_REG_CHG_STATE 0x65
...@@ -204,7 +207,6 @@ enum { ...@@ -204,7 +207,6 @@ enum {
#define BD71828_REG_INT_MASK_TEMP 0xdd #define BD71828_REG_INT_MASK_TEMP 0xdd
#define BD71828_REG_INT_MASK_RTC 0xde #define BD71828_REG_INT_MASK_RTC 0xde
#define BD71828_REG_INT_MAIN 0xdf #define BD71828_REG_INT_MAIN 0xdf
#define BD71828_REG_INT_BUCK 0xe0 #define BD71828_REG_INT_BUCK 0xe0
#define BD71828_REG_INT_DCIN1 0xe1 #define BD71828_REG_INT_DCIN1 0xe1
......
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Copyright (C) 2020 ROHM Semiconductors */
#ifndef __LINUX_MFD_ROHM_SHARED_H__
#define __LINUX_MFD_ROHM_SHARED_H__
/* RTC definitions shared between BD70528 and BD71828 */
#define BD70528_MASK_RTC_SEC 0x7f
#define BD70528_MASK_RTC_MINUTE 0x7f
#define BD70528_MASK_RTC_HOUR_24H 0x80
#define BD70528_MASK_RTC_HOUR_PM 0x20
#define BD70528_MASK_RTC_HOUR 0x3f
#define BD70528_MASK_RTC_DAY 0x3f
#define BD70528_MASK_RTC_WEEK 0x07
#define BD70528_MASK_RTC_MONTH 0x1f
#define BD70528_MASK_RTC_YEAR 0xff
#define BD70528_MASK_ALM_EN 0x7
#endif /* __LINUX_MFD_ROHM_SHARED_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment