0001
0002
0003
0004
0005
0006 #include <linux/init.h>
0007 #include <linux/kernel.h>
0008 #include <linux/rtc.h>
0009 #include <linux/bcd.h>
0010 #include <linux/bitops.h>
0011 #include <linux/io.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/of.h>
0014 #include <linux/delay.h>
0015 #include <linux/clk.h>
0016 #include <linux/gfp.h>
0017 #include <linux/module.h>
0018
0019
0020 #define RTC_TIME_REG_OFFS 0
0021 #define RTC_SECONDS_OFFS 0
0022 #define RTC_MINUTES_OFFS 8
0023 #define RTC_HOURS_OFFS 16
0024 #define RTC_WDAY_OFFS 24
0025 #define RTC_HOURS_12H_MODE BIT(22)
0026
0027 #define RTC_DATE_REG_OFFS 4
0028 #define RTC_MDAY_OFFS 0
0029 #define RTC_MONTH_OFFS 8
0030 #define RTC_YEAR_OFFS 16
0031
0032 #define RTC_ALARM_TIME_REG_OFFS 8
0033 #define RTC_ALARM_DATE_REG_OFFS 0xc
0034 #define RTC_ALARM_VALID BIT(7)
0035
0036 #define RTC_ALARM_INTERRUPT_MASK_REG_OFFS 0x10
0037 #define RTC_ALARM_INTERRUPT_CASUE_REG_OFFS 0x14
0038
0039 struct rtc_plat_data {
0040 struct rtc_device *rtc;
0041 void __iomem *ioaddr;
0042 int irq;
0043 struct clk *clk;
0044 };
0045
0046 static int mv_rtc_set_time(struct device *dev, struct rtc_time *tm)
0047 {
0048 struct rtc_plat_data *pdata = dev_get_drvdata(dev);
0049 void __iomem *ioaddr = pdata->ioaddr;
0050 u32 rtc_reg;
0051
0052 rtc_reg = (bin2bcd(tm->tm_sec) << RTC_SECONDS_OFFS) |
0053 (bin2bcd(tm->tm_min) << RTC_MINUTES_OFFS) |
0054 (bin2bcd(tm->tm_hour) << RTC_HOURS_OFFS) |
0055 (bin2bcd(tm->tm_wday) << RTC_WDAY_OFFS);
0056 writel(rtc_reg, ioaddr + RTC_TIME_REG_OFFS);
0057
0058 rtc_reg = (bin2bcd(tm->tm_mday) << RTC_MDAY_OFFS) |
0059 (bin2bcd(tm->tm_mon + 1) << RTC_MONTH_OFFS) |
0060 (bin2bcd(tm->tm_year - 100) << RTC_YEAR_OFFS);
0061 writel(rtc_reg, ioaddr + RTC_DATE_REG_OFFS);
0062
0063 return 0;
0064 }
0065
0066 static int mv_rtc_read_time(struct device *dev, struct rtc_time *tm)
0067 {
0068 struct rtc_plat_data *pdata = dev_get_drvdata(dev);
0069 void __iomem *ioaddr = pdata->ioaddr;
0070 u32 rtc_time, rtc_date;
0071 unsigned int year, month, day, hour, minute, second, wday;
0072
0073 rtc_time = readl(ioaddr + RTC_TIME_REG_OFFS);
0074 rtc_date = readl(ioaddr + RTC_DATE_REG_OFFS);
0075
0076 second = rtc_time & 0x7f;
0077 minute = (rtc_time >> RTC_MINUTES_OFFS) & 0x7f;
0078 hour = (rtc_time >> RTC_HOURS_OFFS) & 0x3f;
0079 wday = (rtc_time >> RTC_WDAY_OFFS) & 0x7;
0080
0081 day = rtc_date & 0x3f;
0082 month = (rtc_date >> RTC_MONTH_OFFS) & 0x3f;
0083 year = (rtc_date >> RTC_YEAR_OFFS) & 0xff;
0084
0085 tm->tm_sec = bcd2bin(second);
0086 tm->tm_min = bcd2bin(minute);
0087 tm->tm_hour = bcd2bin(hour);
0088 tm->tm_mday = bcd2bin(day);
0089 tm->tm_wday = bcd2bin(wday);
0090 tm->tm_mon = bcd2bin(month) - 1;
0091
0092 tm->tm_year = bcd2bin(year) + 100;
0093
0094 return 0;
0095 }
0096
0097 static int mv_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
0098 {
0099 struct rtc_plat_data *pdata = dev_get_drvdata(dev);
0100 void __iomem *ioaddr = pdata->ioaddr;
0101 u32 rtc_time, rtc_date;
0102 unsigned int year, month, day, hour, minute, second, wday;
0103
0104 rtc_time = readl(ioaddr + RTC_ALARM_TIME_REG_OFFS);
0105 rtc_date = readl(ioaddr + RTC_ALARM_DATE_REG_OFFS);
0106
0107 second = rtc_time & 0x7f;
0108 minute = (rtc_time >> RTC_MINUTES_OFFS) & 0x7f;
0109 hour = (rtc_time >> RTC_HOURS_OFFS) & 0x3f;
0110 wday = (rtc_time >> RTC_WDAY_OFFS) & 0x7;
0111
0112 day = rtc_date & 0x3f;
0113 month = (rtc_date >> RTC_MONTH_OFFS) & 0x3f;
0114 year = (rtc_date >> RTC_YEAR_OFFS) & 0xff;
0115
0116 alm->time.tm_sec = bcd2bin(second);
0117 alm->time.tm_min = bcd2bin(minute);
0118 alm->time.tm_hour = bcd2bin(hour);
0119 alm->time.tm_mday = bcd2bin(day);
0120 alm->time.tm_wday = bcd2bin(wday);
0121 alm->time.tm_mon = bcd2bin(month) - 1;
0122
0123 alm->time.tm_year = bcd2bin(year) + 100;
0124
0125 alm->enabled = !!readl(ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
0126
0127 return rtc_valid_tm(&alm->time);
0128 }
0129
0130 static int mv_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
0131 {
0132 struct rtc_plat_data *pdata = dev_get_drvdata(dev);
0133 void __iomem *ioaddr = pdata->ioaddr;
0134 u32 rtc_reg = 0;
0135
0136 if (alm->time.tm_sec >= 0)
0137 rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_sec))
0138 << RTC_SECONDS_OFFS;
0139 if (alm->time.tm_min >= 0)
0140 rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_min))
0141 << RTC_MINUTES_OFFS;
0142 if (alm->time.tm_hour >= 0)
0143 rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_hour))
0144 << RTC_HOURS_OFFS;
0145
0146 writel(rtc_reg, ioaddr + RTC_ALARM_TIME_REG_OFFS);
0147
0148 if (alm->time.tm_mday >= 0)
0149 rtc_reg = (RTC_ALARM_VALID | bin2bcd(alm->time.tm_mday))
0150 << RTC_MDAY_OFFS;
0151 else
0152 rtc_reg = 0;
0153
0154 if (alm->time.tm_mon >= 0)
0155 rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_mon + 1))
0156 << RTC_MONTH_OFFS;
0157
0158 if (alm->time.tm_year >= 0)
0159 rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_year - 100))
0160 << RTC_YEAR_OFFS;
0161
0162 writel(rtc_reg, ioaddr + RTC_ALARM_DATE_REG_OFFS);
0163 writel(0, ioaddr + RTC_ALARM_INTERRUPT_CASUE_REG_OFFS);
0164 writel(alm->enabled ? 1 : 0,
0165 ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
0166
0167 return 0;
0168 }
0169
0170 static int mv_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
0171 {
0172 struct rtc_plat_data *pdata = dev_get_drvdata(dev);
0173 void __iomem *ioaddr = pdata->ioaddr;
0174
0175 if (pdata->irq < 0)
0176 return -EINVAL;
0177
0178 if (enabled)
0179 writel(1, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
0180 else
0181 writel(0, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
0182 return 0;
0183 }
0184
0185 static irqreturn_t mv_rtc_interrupt(int irq, void *data)
0186 {
0187 struct rtc_plat_data *pdata = data;
0188 void __iomem *ioaddr = pdata->ioaddr;
0189
0190
0191 if (!readl(ioaddr + RTC_ALARM_INTERRUPT_CASUE_REG_OFFS))
0192 return IRQ_NONE;
0193
0194
0195 writel(0, ioaddr + RTC_ALARM_INTERRUPT_CASUE_REG_OFFS);
0196 rtc_update_irq(pdata->rtc, 1, RTC_IRQF | RTC_AF);
0197 return IRQ_HANDLED;
0198 }
0199
0200 static const struct rtc_class_ops mv_rtc_ops = {
0201 .read_time = mv_rtc_read_time,
0202 .set_time = mv_rtc_set_time,
0203 .read_alarm = mv_rtc_read_alarm,
0204 .set_alarm = mv_rtc_set_alarm,
0205 .alarm_irq_enable = mv_rtc_alarm_irq_enable,
0206 };
0207
0208 static int __init mv_rtc_probe(struct platform_device *pdev)
0209 {
0210 struct rtc_plat_data *pdata;
0211 u32 rtc_time;
0212 int ret = 0;
0213
0214 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
0215 if (!pdata)
0216 return -ENOMEM;
0217
0218 pdata->ioaddr = devm_platform_ioremap_resource(pdev, 0);
0219 if (IS_ERR(pdata->ioaddr))
0220 return PTR_ERR(pdata->ioaddr);
0221
0222 pdata->clk = devm_clk_get(&pdev->dev, NULL);
0223
0224 if (!IS_ERR(pdata->clk))
0225 clk_prepare_enable(pdata->clk);
0226
0227
0228 rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
0229 if (rtc_time & RTC_HOURS_12H_MODE) {
0230 dev_err(&pdev->dev, "12 Hour mode is enabled but not supported.\n");
0231 ret = -EINVAL;
0232 goto out;
0233 }
0234
0235
0236 if (rtc_time == 0x01000000) {
0237 ssleep(1);
0238 rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
0239 if (rtc_time == 0x01000000) {
0240 dev_err(&pdev->dev, "internal RTC not ticking\n");
0241 ret = -ENODEV;
0242 goto out;
0243 }
0244 }
0245
0246 pdata->irq = platform_get_irq(pdev, 0);
0247
0248 platform_set_drvdata(pdev, pdata);
0249
0250 pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
0251 if (IS_ERR(pdata->rtc)) {
0252 ret = PTR_ERR(pdata->rtc);
0253 goto out;
0254 }
0255
0256 if (pdata->irq >= 0) {
0257 writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
0258 if (devm_request_irq(&pdev->dev, pdata->irq, mv_rtc_interrupt,
0259 IRQF_SHARED,
0260 pdev->name, pdata) < 0) {
0261 dev_warn(&pdev->dev, "interrupt not available.\n");
0262 pdata->irq = -1;
0263 }
0264 }
0265
0266 if (pdata->irq >= 0)
0267 device_init_wakeup(&pdev->dev, 1);
0268 else
0269 clear_bit(RTC_FEATURE_ALARM, pdata->rtc->features);
0270
0271 pdata->rtc->ops = &mv_rtc_ops;
0272 pdata->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
0273 pdata->rtc->range_max = RTC_TIMESTAMP_END_2099;
0274
0275 ret = devm_rtc_register_device(pdata->rtc);
0276 if (!ret)
0277 return 0;
0278 out:
0279 if (!IS_ERR(pdata->clk))
0280 clk_disable_unprepare(pdata->clk);
0281
0282 return ret;
0283 }
0284
0285 static int __exit mv_rtc_remove(struct platform_device *pdev)
0286 {
0287 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
0288
0289 if (pdata->irq >= 0)
0290 device_init_wakeup(&pdev->dev, 0);
0291
0292 if (!IS_ERR(pdata->clk))
0293 clk_disable_unprepare(pdata->clk);
0294
0295 return 0;
0296 }
0297
0298 #ifdef CONFIG_OF
0299 static const struct of_device_id rtc_mv_of_match_table[] = {
0300 { .compatible = "marvell,orion-rtc", },
0301 {}
0302 };
0303 MODULE_DEVICE_TABLE(of, rtc_mv_of_match_table);
0304 #endif
0305
0306 static struct platform_driver mv_rtc_driver = {
0307 .remove = __exit_p(mv_rtc_remove),
0308 .driver = {
0309 .name = "rtc-mv",
0310 .of_match_table = of_match_ptr(rtc_mv_of_match_table),
0311 },
0312 };
0313
0314 module_platform_driver_probe(mv_rtc_driver, mv_rtc_probe);
0315
0316 MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>");
0317 MODULE_DESCRIPTION("Marvell RTC driver");
0318 MODULE_LICENSE("GPL");
0319 MODULE_ALIAS("platform:rtc-mv");