Skip to content

Commit 04dcadb

Browse files
VCASTMalexandrebelloni
authored andcommitted
rtc: stm32: add alarm A out feature
STM32 RTC can pulse some SOC pins when an RTC alarm expires. This patch adds this functionality for alarm A. The pulse can out on three pins RTC_OUT1, RTC_OUT2, RTC_OUT2_RMP (PC13, PB2, PI8 on stm32mp15) (PC13, PB2, PI1 on stm32mp13) (PC13, PF4/PF6, PI8 on stm32mp25). This patch only adds the functionality for devices which are using st,stm32mp1-rtc and st,stm32mp25-rtc compatible. Add "alarm-a" in pinmux functions. Signed-off-by: Valentin Caron <[email protected]> Reviewed-by: Linus Walleij <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Belloni <[email protected]>
1 parent bb7b0df commit 04dcadb

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

drivers/rtc/rtc-stm32.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@
4747
#define STM32_RTC_CR_ALRAE BIT(8)
4848
#define STM32_RTC_CR_ALRAIE BIT(12)
4949
#define STM32_RTC_CR_OSEL GENMASK(22, 21)
50+
#define STM32_RTC_CR_OSEL_ALARM_A FIELD_PREP(STM32_RTC_CR_OSEL, 0x01)
5051
#define STM32_RTC_CR_COE BIT(23)
5152
#define STM32_RTC_CR_TAMPOE BIT(26)
53+
#define STM32_RTC_CR_TAMPALRM_TYPE BIT(30)
5254
#define STM32_RTC_CR_OUT2EN BIT(31)
5355

5456
/* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */
@@ -158,6 +160,7 @@ struct stm32_rtc_data {
158160
bool need_accuracy;
159161
bool rif_protected;
160162
bool has_lsco;
163+
bool has_alarm_out;
161164
};
162165

163166
struct stm32_rtc {
@@ -245,6 +248,47 @@ struct stm32_rtc_pinmux_func {
245248
int (*action)(struct pinctrl_dev *pctl_dev, unsigned int pin);
246249
};
247250

251+
static int stm32_rtc_pinmux_action_alarm(struct pinctrl_dev *pctldev, unsigned int pin)
252+
{
253+
struct stm32_rtc *rtc = pinctrl_dev_get_drvdata(pctldev);
254+
struct stm32_rtc_registers regs = rtc->data->regs;
255+
unsigned int cr = readl_relaxed(rtc->base + regs.cr);
256+
unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr);
257+
258+
if (!rtc->data->has_alarm_out)
259+
return -EPERM;
260+
261+
cr &= ~STM32_RTC_CR_OSEL;
262+
cr |= STM32_RTC_CR_OSEL_ALARM_A;
263+
cr &= ~STM32_RTC_CR_TAMPOE;
264+
cr &= ~STM32_RTC_CR_COE;
265+
cr &= ~STM32_RTC_CR_TAMPALRM_TYPE;
266+
267+
switch (pin) {
268+
case OUT1:
269+
cr &= ~STM32_RTC_CR_OUT2EN;
270+
cfgr &= ~STM32_RTC_CFGR_OUT2_RMP;
271+
break;
272+
case OUT2:
273+
cr |= STM32_RTC_CR_OUT2EN;
274+
cfgr &= ~STM32_RTC_CFGR_OUT2_RMP;
275+
break;
276+
case OUT2_RMP:
277+
cr |= STM32_RTC_CR_OUT2EN;
278+
cfgr |= STM32_RTC_CFGR_OUT2_RMP;
279+
break;
280+
default:
281+
return -EINVAL;
282+
}
283+
284+
stm32_rtc_wpr_unlock(rtc);
285+
writel_relaxed(cr, rtc->base + regs.cr);
286+
writel_relaxed(cfgr, rtc->base + regs.cfgr);
287+
stm32_rtc_wpr_lock(rtc);
288+
289+
return 0;
290+
}
291+
248292
static int stm32_rtc_pinmux_lsco_available(struct pinctrl_dev *pctldev, unsigned int pin)
249293
{
250294
struct stm32_rtc *rtc = pinctrl_dev_get_drvdata(pctldev);
@@ -307,6 +351,7 @@ static int stm32_rtc_pinmux_action_lsco(struct pinctrl_dev *pctldev, unsigned in
307351

308352
static const struct stm32_rtc_pinmux_func stm32_rtc_pinmux_functions[] = {
309353
STM32_RTC_PINMUX("lsco", &stm32_rtc_pinmux_action_lsco, "out1", "out2_rmp"),
354+
STM32_RTC_PINMUX("alarm-a", &stm32_rtc_pinmux_action_alarm, "out1", "out2", "out2_rmp"),
310355
};
311356

312357
static int stm32_rtc_pinmux_get_functions_count(struct pinctrl_dev *pctldev)
@@ -763,6 +808,7 @@ static const struct stm32_rtc_data stm32_rtc_data = {
763808
.need_accuracy = false,
764809
.rif_protected = false,
765810
.has_lsco = false,
811+
.has_alarm_out = false,
766812
.regs = {
767813
.tr = 0x00,
768814
.dr = 0x04,
@@ -788,6 +834,7 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
788834
.need_accuracy = false,
789835
.rif_protected = false,
790836
.has_lsco = false,
837+
.has_alarm_out = false,
791838
.regs = {
792839
.tr = 0x00,
793840
.dr = 0x04,
@@ -822,6 +869,7 @@ static const struct stm32_rtc_data stm32mp1_data = {
822869
.need_accuracy = true,
823870
.rif_protected = false,
824871
.has_lsco = true,
872+
.has_alarm_out = true,
825873
.regs = {
826874
.tr = 0x00,
827875
.dr = 0x04,
@@ -847,6 +895,7 @@ static const struct stm32_rtc_data stm32mp25_data = {
847895
.need_accuracy = true,
848896
.rif_protected = true,
849897
.has_lsco = true,
898+
.has_alarm_out = true,
850899
.regs = {
851900
.tr = 0x00,
852901
.dr = 0x04,
@@ -878,6 +927,17 @@ MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
878927
static void stm32_rtc_clean_outs(struct stm32_rtc *rtc)
879928
{
880929
struct stm32_rtc_registers regs = rtc->data->regs;
930+
unsigned int cr = readl_relaxed(rtc->base + regs.cr);
931+
932+
cr &= ~STM32_RTC_CR_OSEL;
933+
cr &= ~STM32_RTC_CR_TAMPOE;
934+
cr &= ~STM32_RTC_CR_COE;
935+
cr &= ~STM32_RTC_CR_TAMPALRM_TYPE;
936+
cr &= ~STM32_RTC_CR_OUT2EN;
937+
938+
stm32_rtc_wpr_unlock(rtc);
939+
writel_relaxed(cr, rtc->base + regs.cr);
940+
stm32_rtc_wpr_lock(rtc);
881941

882942
if (regs.cfgr != UNDEF_REG) {
883943
unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr);

0 commit comments

Comments
 (0)