250 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Real time clocks driver for MStar/SigmaStar ARMv7 SoCs.4 * Based on "Real Time Clock driver for msb252x." that was contained5 * in various MStar kernels.6 *7 * (C) 2019 Daniel Palmer8 * (C) 2021 Romain Perier9 */10 11#include <linux/clk.h>12#include <linux/delay.h>13#include <linux/io.h>14#include <linux/module.h>15#include <linux/mod_devicetable.h>16#include <linux/platform_device.h>17#include <linux/rtc.h>18 19/* Registers */20#define REG_RTC_CTRL 0x0021#define REG_RTC_FREQ_CW_L 0x0422#define REG_RTC_FREQ_CW_H 0x0823#define REG_RTC_LOAD_VAL_L 0x0C24#define REG_RTC_LOAD_VAL_H 0x1025#define REG_RTC_MATCH_VAL_L 0x1426#define REG_RTC_MATCH_VAL_H 0x1827#define REG_RTC_STATUS_INT 0x1C28#define REG_RTC_CNT_VAL_L 0x2029#define REG_RTC_CNT_VAL_H 0x2430 31/* Control bits for REG_RTC_CTRL */32#define SOFT_RSTZ_BIT BIT(0)33#define CNT_EN_BIT BIT(1)34#define WRAP_EN_BIT BIT(2)35#define LOAD_EN_BIT BIT(3)36#define READ_EN_BIT BIT(4)37#define INT_MASK_BIT BIT(5)38#define INT_FORCE_BIT BIT(6)39#define INT_CLEAR_BIT BIT(7)40 41/* Control bits for REG_RTC_STATUS_INT */42#define RAW_INT_BIT BIT(0)43#define ALM_INT_BIT BIT(1)44 45struct msc313_rtc {46 struct rtc_device *rtc_dev;47 void __iomem *rtc_base;48};49 50static int msc313_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)51{52 struct msc313_rtc *priv = dev_get_drvdata(dev);53 unsigned long seconds;54 55 seconds = readw(priv->rtc_base + REG_RTC_MATCH_VAL_L)56 | ((unsigned long)readw(priv->rtc_base + REG_RTC_MATCH_VAL_H) << 16);57 58 rtc_time64_to_tm(seconds, &alarm->time);59 60 if (!(readw(priv->rtc_base + REG_RTC_CTRL) & INT_MASK_BIT))61 alarm->enabled = 1;62 63 return 0;64}65 66static int msc313_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)67{68 struct msc313_rtc *priv = dev_get_drvdata(dev);69 u16 reg;70 71 reg = readw(priv->rtc_base + REG_RTC_CTRL);72 if (enabled)73 reg &= ~INT_MASK_BIT;74 else75 reg |= INT_MASK_BIT;76 writew(reg, priv->rtc_base + REG_RTC_CTRL);77 return 0;78}79 80static int msc313_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)81{82 struct msc313_rtc *priv = dev_get_drvdata(dev);83 unsigned long seconds;84 85 seconds = rtc_tm_to_time64(&alarm->time);86 writew((seconds & 0xFFFF), priv->rtc_base + REG_RTC_MATCH_VAL_L);87 writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_MATCH_VAL_H);88 89 msc313_rtc_alarm_irq_enable(dev, alarm->enabled);90 91 return 0;92}93 94static bool msc313_rtc_get_enabled(struct msc313_rtc *priv)95{96 return readw(priv->rtc_base + REG_RTC_CTRL) & CNT_EN_BIT;97}98 99static void msc313_rtc_set_enabled(struct msc313_rtc *priv)100{101 u16 reg;102 103 reg = readw(priv->rtc_base + REG_RTC_CTRL);104 reg |= CNT_EN_BIT;105 writew(reg, priv->rtc_base + REG_RTC_CTRL);106}107 108static int msc313_rtc_read_time(struct device *dev, struct rtc_time *tm)109{110 struct msc313_rtc *priv = dev_get_drvdata(dev);111 u32 seconds;112 u16 reg;113 114 if (!msc313_rtc_get_enabled(priv))115 return -EINVAL;116 117 reg = readw(priv->rtc_base + REG_RTC_CTRL);118 writew(reg | READ_EN_BIT, priv->rtc_base + REG_RTC_CTRL);119 120 /* Wait for HW latch done */121 while (readw(priv->rtc_base + REG_RTC_CTRL) & READ_EN_BIT)122 udelay(1);123 124 seconds = readw(priv->rtc_base + REG_RTC_CNT_VAL_L)125 | ((unsigned long)readw(priv->rtc_base + REG_RTC_CNT_VAL_H) << 16);126 127 rtc_time64_to_tm(seconds, tm);128 129 return 0;130}131 132static int msc313_rtc_set_time(struct device *dev, struct rtc_time *tm)133{134 struct msc313_rtc *priv = dev_get_drvdata(dev);135 unsigned long seconds;136 u16 reg;137 138 seconds = rtc_tm_to_time64(tm);139 writew(seconds & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_L);140 writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_H);141 142 /* Enable load for loading value into internal RTC counter */143 reg = readw(priv->rtc_base + REG_RTC_CTRL);144 writew(reg | LOAD_EN_BIT, priv->rtc_base + REG_RTC_CTRL);145 146 /* Wait for HW latch done */147 while (readw(priv->rtc_base + REG_RTC_CTRL) & LOAD_EN_BIT)148 udelay(1);149 msc313_rtc_set_enabled(priv);150 return 0;151}152 153static const struct rtc_class_ops msc313_rtc_ops = {154 .read_time = msc313_rtc_read_time,155 .set_time = msc313_rtc_set_time,156 .read_alarm = msc313_rtc_read_alarm,157 .set_alarm = msc313_rtc_set_alarm,158 .alarm_irq_enable = msc313_rtc_alarm_irq_enable,159};160 161static irqreturn_t msc313_rtc_interrupt(s32 irq, void *dev_id)162{163 struct msc313_rtc *priv = dev_get_drvdata(dev_id);164 u16 reg;165 166 reg = readw(priv->rtc_base + REG_RTC_STATUS_INT);167 if (!(reg & ALM_INT_BIT))168 return IRQ_NONE;169 170 reg = readw(priv->rtc_base + REG_RTC_CTRL);171 reg |= INT_CLEAR_BIT;172 reg &= ~INT_FORCE_BIT;173 writew(reg, priv->rtc_base + REG_RTC_CTRL);174 175 rtc_update_irq(priv->rtc_dev, 1, RTC_IRQF | RTC_AF);176 177 return IRQ_HANDLED;178}179 180static int msc313_rtc_probe(struct platform_device *pdev)181{182 struct device *dev = &pdev->dev;183 struct msc313_rtc *priv;184 unsigned long rate;185 struct clk *clk;186 int ret;187 int irq;188 189 priv = devm_kzalloc(&pdev->dev, sizeof(struct msc313_rtc), GFP_KERNEL);190 if (!priv)191 return -ENOMEM;192 193 priv->rtc_base = devm_platform_ioremap_resource(pdev, 0);194 if (IS_ERR(priv->rtc_base))195 return PTR_ERR(priv->rtc_base);196 197 irq = platform_get_irq(pdev, 0);198 if (irq < 0)199 return -EINVAL;200 201 priv->rtc_dev = devm_rtc_allocate_device(dev);202 if (IS_ERR(priv->rtc_dev))203 return PTR_ERR(priv->rtc_dev);204 205 priv->rtc_dev->ops = &msc313_rtc_ops;206 priv->rtc_dev->range_max = U32_MAX;207 208 ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED,209 dev_name(&pdev->dev), &pdev->dev);210 if (ret) {211 dev_err(dev, "Could not request IRQ\n");212 return ret;213 }214 215 clk = devm_clk_get_enabled(dev, NULL);216 if (IS_ERR(clk)) {217 dev_err(dev, "No input reference clock\n");218 return PTR_ERR(clk);219 }220 221 rate = clk_get_rate(clk);222 writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);223 writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);224 225 platform_set_drvdata(pdev, priv);226 227 return devm_rtc_register_device(priv->rtc_dev);228}229 230static const struct of_device_id msc313_rtc_of_match_table[] = {231 { .compatible = "mstar,msc313-rtc" },232 { }233};234MODULE_DEVICE_TABLE(of, msc313_rtc_of_match_table);235 236static struct platform_driver msc313_rtc_driver = {237 .probe = msc313_rtc_probe,238 .driver = {239 .name = "msc313-rtc",240 .of_match_table = msc313_rtc_of_match_table,241 },242};243 244module_platform_driver(msc313_rtc_driver);245 246MODULE_AUTHOR("Daniel Palmer <daniel@thingy.jp>");247MODULE_AUTHOR("Romain Perier <romain.perier@gmail.com>");248MODULE_DESCRIPTION("MStar RTC Driver");249MODULE_LICENSE("GPL v2");250