Lines Matching +full:soc +full:- +full:rtc
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Driver for MediaTek SoC based RTC
14 #include <linux/rtc.h>
49 * Ranges from 0x40 to 0x78 provide RTC time setup for year, month,
65 * The lowest value for the valid tm_year. RTC hardware would take incorrectly
72 * The most year the RTC can hold is 99 and the next to 99 in year register
84 /* Types of the function the RTC provides are time counter and alarm. */
102 struct rtc_device *rtc; member
108 static void mtk_w32(struct mtk_rtc *rtc, u32 reg, u32 val) in mtk_w32() argument
110 writel_relaxed(val, rtc->base + reg); in mtk_w32()
113 static u32 mtk_r32(struct mtk_rtc *rtc, u32 reg) in mtk_r32() argument
115 return readl_relaxed(rtc->base + reg); in mtk_r32()
118 static void mtk_rmw(struct mtk_rtc *rtc, u32 reg, u32 mask, u32 set) in mtk_rmw() argument
122 val = mtk_r32(rtc, reg); in mtk_rmw()
125 mtk_w32(rtc, reg, val); in mtk_rmw()
128 static void mtk_set(struct mtk_rtc *rtc, u32 reg, u32 val) in mtk_set() argument
130 mtk_rmw(rtc, reg, 0, val); in mtk_set()
133 static void mtk_clr(struct mtk_rtc *rtc, u32 reg, u32 val) in mtk_clr() argument
135 mtk_rmw(rtc, reg, val, 0); in mtk_clr()
140 /* The setup of the init sequence is for allowing RTC got to work */ in mtk_rtc_hw_init()
173 tm->tm_sec = sec; in mtk_rtc_get_alarm_or_time()
174 tm->tm_min = min; in mtk_rtc_get_alarm_or_time()
175 tm->tm_hour = hour; in mtk_rtc_get_alarm_or_time()
176 tm->tm_wday = wday; in mtk_rtc_get_alarm_or_time()
177 tm->tm_mday = mday; in mtk_rtc_get_alarm_or_time()
178 tm->tm_mon = mon - 1; in mtk_rtc_get_alarm_or_time()
181 tm->tm_year = year + MTK_RTC_TM_YR_OFFSET; in mtk_rtc_get_alarm_or_time()
189 /* Rebase to the relative year which RTC hardware requires */ in mtk_rtc_set_alarm_or_time()
190 year = tm->tm_year - MTK_RTC_TM_YR_OFFSET; in mtk_rtc_set_alarm_or_time()
193 mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_MON), tm->tm_mon + 1); in mtk_rtc_set_alarm_or_time()
194 mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_DOW), tm->tm_wday); in mtk_rtc_set_alarm_or_time()
195 mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_DOM), tm->tm_mday); in mtk_rtc_set_alarm_or_time()
196 mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_HOU), tm->tm_hour); in mtk_rtc_set_alarm_or_time()
197 mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_MIN), tm->tm_min); in mtk_rtc_set_alarm_or_time()
198 mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_SEC), tm->tm_sec); in mtk_rtc_set_alarm_or_time()
210 rtc_update_irq(hw->rtc, 1, RTC_IRQF | RTC_AF); in mtk_rtc_alarmirq()
233 if (!MTK_RTC_TM_YR_VALID(tm->tm_year)) in mtk_rtc_settime()
234 return -EINVAL; in mtk_rtc_settime()
250 struct rtc_time *alrm_tm = &wkalrm->time; in mtk_rtc_getalarm()
254 wkalrm->enabled = !!(mtk_r32(hw, MTK_RTC_AL_CTL) & RTC_AL_EN); in mtk_rtc_getalarm()
255 wkalrm->pending = !!(mtk_r32(hw, MTK_RTC_INT) & RTC_INT_AL_STA); in mtk_rtc_getalarm()
263 struct rtc_time *alrm_tm = &wkalrm->time; in mtk_rtc_setalarm()
265 if (!MTK_RTC_TM_YR_VALID(alrm_tm->tm_year)) in mtk_rtc_setalarm()
266 return -EINVAL; in mtk_rtc_setalarm()
279 synchronize_irq(hw->irq); in mtk_rtc_setalarm()
297 { .compatible = "mediatek,mt7622-rtc" },
298 { .compatible = "mediatek,soc-rtc" },
308 hw = devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL); in mtk_rtc_probe()
310 return -ENOMEM; in mtk_rtc_probe()
314 hw->base = devm_platform_ioremap_resource(pdev, 0); in mtk_rtc_probe()
315 if (IS_ERR(hw->base)) in mtk_rtc_probe()
316 return PTR_ERR(hw->base); in mtk_rtc_probe()
318 hw->clk = devm_clk_get(&pdev->dev, "rtc"); in mtk_rtc_probe()
319 if (IS_ERR(hw->clk)) { in mtk_rtc_probe()
320 dev_err(&pdev->dev, "No clock\n"); in mtk_rtc_probe()
321 return PTR_ERR(hw->clk); in mtk_rtc_probe()
324 ret = clk_prepare_enable(hw->clk); in mtk_rtc_probe()
328 hw->irq = platform_get_irq(pdev, 0); in mtk_rtc_probe()
329 if (hw->irq < 0) { in mtk_rtc_probe()
330 ret = hw->irq; in mtk_rtc_probe()
334 ret = devm_request_irq(&pdev->dev, hw->irq, mtk_rtc_alarmirq, in mtk_rtc_probe()
335 0, dev_name(&pdev->dev), hw); in mtk_rtc_probe()
337 dev_err(&pdev->dev, "Can't request IRQ\n"); in mtk_rtc_probe()
343 device_init_wakeup(&pdev->dev, true); in mtk_rtc_probe()
345 hw->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, in mtk_rtc_probe()
347 if (IS_ERR(hw->rtc)) { in mtk_rtc_probe()
348 ret = PTR_ERR(hw->rtc); in mtk_rtc_probe()
349 dev_err(&pdev->dev, "Unable to register device\n"); in mtk_rtc_probe()
355 clk_disable_unprepare(hw->clk); in mtk_rtc_probe()
364 clk_disable_unprepare(hw->clk); in mtk_rtc_remove()
373 enable_irq_wake(hw->irq); in mtk_rtc_suspend()
383 disable_irq_wake(hw->irq); in mtk_rtc_resume()
407 MODULE_DESCRIPTION("MediaTek SoC based RTC Driver");