359 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * DS1286 Real Time Clock interface for Linux4 *5 * Copyright (C) 1998, 1999, 2000 Ralf Baechle6 * Copyright (C) 2008 Thomas Bogendoerfer7 *8 * Based on code written by Paul Gortmaker.9 */10 11#include <linux/module.h>12#include <linux/rtc.h>13#include <linux/platform_device.h>14#include <linux/bcd.h>15#include <linux/rtc/ds1286.h>16#include <linux/io.h>17#include <linux/slab.h>18 19struct ds1286_priv {20 struct rtc_device *rtc;21 u32 __iomem *rtcregs;22 spinlock_t lock;23};24 25static inline u8 ds1286_rtc_read(struct ds1286_priv *priv, int reg)26{27 return __raw_readl(&priv->rtcregs[reg]) & 0xff;28}29 30static inline void ds1286_rtc_write(struct ds1286_priv *priv, u8 data, int reg)31{32 __raw_writel(data, &priv->rtcregs[reg]);33}34 35 36static int ds1286_alarm_irq_enable(struct device *dev, unsigned int enabled)37{38 struct ds1286_priv *priv = dev_get_drvdata(dev);39 unsigned long flags;40 unsigned char val;41 42 /* Allow or mask alarm interrupts */43 spin_lock_irqsave(&priv->lock, flags);44 val = ds1286_rtc_read(priv, RTC_CMD);45 if (enabled)46 val &= ~RTC_TDM;47 else48 val |= RTC_TDM;49 ds1286_rtc_write(priv, val, RTC_CMD);50 spin_unlock_irqrestore(&priv->lock, flags);51 52 return 0;53}54 55#ifdef CONFIG_RTC_INTF_DEV56 57static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)58{59 struct ds1286_priv *priv = dev_get_drvdata(dev);60 unsigned long flags;61 unsigned char val;62 63 switch (cmd) {64 case RTC_WIE_OFF:65 /* Mask watchdog int. enab. bit */66 spin_lock_irqsave(&priv->lock, flags);67 val = ds1286_rtc_read(priv, RTC_CMD);68 val |= RTC_WAM;69 ds1286_rtc_write(priv, val, RTC_CMD);70 spin_unlock_irqrestore(&priv->lock, flags);71 break;72 case RTC_WIE_ON:73 /* Allow watchdog interrupts. */74 spin_lock_irqsave(&priv->lock, flags);75 val = ds1286_rtc_read(priv, RTC_CMD);76 val &= ~RTC_WAM;77 ds1286_rtc_write(priv, val, RTC_CMD);78 spin_unlock_irqrestore(&priv->lock, flags);79 break;80 default:81 return -ENOIOCTLCMD;82 }83 return 0;84}85 86#else87#define ds1286_ioctl NULL88#endif89 90#ifdef CONFIG_PROC_FS91 92static int ds1286_proc(struct device *dev, struct seq_file *seq)93{94 struct ds1286_priv *priv = dev_get_drvdata(dev);95 unsigned char month, cmd, amode;96 const char *s;97 98 month = ds1286_rtc_read(priv, RTC_MONTH);99 seq_printf(seq,100 "oscillator\t: %s\n"101 "square_wave\t: %s\n",102 (month & RTC_EOSC) ? "disabled" : "enabled",103 (month & RTC_ESQW) ? "disabled" : "enabled");104 105 amode = ((ds1286_rtc_read(priv, RTC_MINUTES_ALARM) & 0x80) >> 5) |106 ((ds1286_rtc_read(priv, RTC_HOURS_ALARM) & 0x80) >> 6) |107 ((ds1286_rtc_read(priv, RTC_DAY_ALARM) & 0x80) >> 7);108 switch (amode) {109 case 7:110 s = "each minute";111 break;112 case 3:113 s = "minutes match";114 break;115 case 1:116 s = "hours and minutes match";117 break;118 case 0:119 s = "days, hours and minutes match";120 break;121 default:122 s = "invalid";123 break;124 }125 seq_printf(seq, "alarm_mode\t: %s\n", s);126 127 cmd = ds1286_rtc_read(priv, RTC_CMD);128 seq_printf(seq,129 "alarm_enable\t: %s\n"130 "wdog_alarm\t: %s\n"131 "alarm_mask\t: %s\n"132 "wdog_alarm_mask\t: %s\n"133 "interrupt_mode\t: %s\n"134 "INTB_mode\t: %s_active\n"135 "interrupt_pins\t: %s\n",136 (cmd & RTC_TDF) ? "yes" : "no",137 (cmd & RTC_WAF) ? "yes" : "no",138 (cmd & RTC_TDM) ? "disabled" : "enabled",139 (cmd & RTC_WAM) ? "disabled" : "enabled",140 (cmd & RTC_PU_LVL) ? "pulse" : "level",141 (cmd & RTC_IBH_LO) ? "low" : "high",142 (cmd & RTC_IPSW) ? "unswapped" : "swapped");143 return 0;144}145 146#else147#define ds1286_proc NULL148#endif149 150static int ds1286_read_time(struct device *dev, struct rtc_time *tm)151{152 struct ds1286_priv *priv = dev_get_drvdata(dev);153 unsigned char save_control;154 unsigned long flags;155 unsigned long uip_watchdog = jiffies;156 157 /*158 * read RTC once any update in progress is done. The update159 * can take just over 2ms. We wait 10 to 20ms. There is no need to160 * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.161 * If you need to know *exactly* when a second has started, enable162 * periodic update complete interrupts, (via ioctl) and then163 * immediately read /dev/rtc which will block until you get the IRQ.164 * Once the read clears, read the RTC time (again via ioctl). Easy.165 */166 167 if (ds1286_rtc_read(priv, RTC_CMD) & RTC_TE)168 while (time_before(jiffies, uip_watchdog + 2*HZ/100))169 barrier();170 171 /*172 * Only the values that we read from the RTC are set. We leave173 * tm_wday, tm_yday and tm_isdst untouched. Even though the174 * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated175 * by the RTC when initially set to a non-zero value.176 */177 spin_lock_irqsave(&priv->lock, flags);178 save_control = ds1286_rtc_read(priv, RTC_CMD);179 ds1286_rtc_write(priv, (save_control|RTC_TE), RTC_CMD);180 181 tm->tm_sec = ds1286_rtc_read(priv, RTC_SECONDS);182 tm->tm_min = ds1286_rtc_read(priv, RTC_MINUTES);183 tm->tm_hour = ds1286_rtc_read(priv, RTC_HOURS) & 0x3f;184 tm->tm_mday = ds1286_rtc_read(priv, RTC_DATE);185 tm->tm_mon = ds1286_rtc_read(priv, RTC_MONTH) & 0x1f;186 tm->tm_year = ds1286_rtc_read(priv, RTC_YEAR);187 188 ds1286_rtc_write(priv, save_control, RTC_CMD);189 spin_unlock_irqrestore(&priv->lock, flags);190 191 tm->tm_sec = bcd2bin(tm->tm_sec);192 tm->tm_min = bcd2bin(tm->tm_min);193 tm->tm_hour = bcd2bin(tm->tm_hour);194 tm->tm_mday = bcd2bin(tm->tm_mday);195 tm->tm_mon = bcd2bin(tm->tm_mon);196 tm->tm_year = bcd2bin(tm->tm_year);197 198 /*199 * Account for differences between how the RTC uses the values200 * and how they are defined in a struct rtc_time;201 */202 if (tm->tm_year < 45)203 tm->tm_year += 30;204 tm->tm_year += 40;205 if (tm->tm_year < 70)206 tm->tm_year += 100;207 208 tm->tm_mon--;209 210 return 0;211}212 213static int ds1286_set_time(struct device *dev, struct rtc_time *tm)214{215 struct ds1286_priv *priv = dev_get_drvdata(dev);216 unsigned char mon, day, hrs, min, sec;217 unsigned char save_control;218 unsigned int yrs;219 unsigned long flags;220 221 yrs = tm->tm_year + 1900;222 mon = tm->tm_mon + 1; /* tm_mon starts at zero */223 day = tm->tm_mday;224 hrs = tm->tm_hour;225 min = tm->tm_min;226 sec = tm->tm_sec;227 228 if (yrs < 1970)229 return -EINVAL;230 231 yrs -= 1940;232 if (yrs > 255) /* They are unsigned */233 return -EINVAL;234 235 if (yrs >= 100)236 yrs -= 100;237 238 sec = bin2bcd(sec);239 min = bin2bcd(min);240 hrs = bin2bcd(hrs);241 day = bin2bcd(day);242 mon = bin2bcd(mon);243 yrs = bin2bcd(yrs);244 245 spin_lock_irqsave(&priv->lock, flags);246 save_control = ds1286_rtc_read(priv, RTC_CMD);247 ds1286_rtc_write(priv, (save_control|RTC_TE), RTC_CMD);248 249 ds1286_rtc_write(priv, yrs, RTC_YEAR);250 ds1286_rtc_write(priv, mon, RTC_MONTH);251 ds1286_rtc_write(priv, day, RTC_DATE);252 ds1286_rtc_write(priv, hrs, RTC_HOURS);253 ds1286_rtc_write(priv, min, RTC_MINUTES);254 ds1286_rtc_write(priv, sec, RTC_SECONDS);255 ds1286_rtc_write(priv, 0, RTC_HUNDREDTH_SECOND);256 257 ds1286_rtc_write(priv, save_control, RTC_CMD);258 spin_unlock_irqrestore(&priv->lock, flags);259 return 0;260}261 262static int ds1286_read_alarm(struct device *dev, struct rtc_wkalrm *alm)263{264 struct ds1286_priv *priv = dev_get_drvdata(dev);265 unsigned long flags;266 267 /*268 * Only the values that we read from the RTC are set. That269 * means only tm_wday, tm_hour, tm_min.270 */271 spin_lock_irqsave(&priv->lock, flags);272 alm->time.tm_min = ds1286_rtc_read(priv, RTC_MINUTES_ALARM) & 0x7f;273 alm->time.tm_hour = ds1286_rtc_read(priv, RTC_HOURS_ALARM) & 0x1f;274 alm->time.tm_wday = ds1286_rtc_read(priv, RTC_DAY_ALARM) & 0x07;275 ds1286_rtc_read(priv, RTC_CMD);276 spin_unlock_irqrestore(&priv->lock, flags);277 278 alm->time.tm_min = bcd2bin(alm->time.tm_min);279 alm->time.tm_hour = bcd2bin(alm->time.tm_hour);280 alm->time.tm_sec = 0;281 return 0;282}283 284static int ds1286_set_alarm(struct device *dev, struct rtc_wkalrm *alm)285{286 struct ds1286_priv *priv = dev_get_drvdata(dev);287 unsigned char hrs, min, sec;288 289 hrs = alm->time.tm_hour;290 min = alm->time.tm_min;291 sec = alm->time.tm_sec;292 293 if (hrs >= 24)294 hrs = 0xff;295 296 if (min >= 60)297 min = 0xff;298 299 if (sec != 0)300 return -EINVAL;301 302 min = bin2bcd(min);303 hrs = bin2bcd(hrs);304 305 spin_lock(&priv->lock);306 ds1286_rtc_write(priv, hrs, RTC_HOURS_ALARM);307 ds1286_rtc_write(priv, min, RTC_MINUTES_ALARM);308 spin_unlock(&priv->lock);309 310 return 0;311}312 313static const struct rtc_class_ops ds1286_ops = {314 .ioctl = ds1286_ioctl,315 .proc = ds1286_proc,316 .read_time = ds1286_read_time,317 .set_time = ds1286_set_time,318 .read_alarm = ds1286_read_alarm,319 .set_alarm = ds1286_set_alarm,320 .alarm_irq_enable = ds1286_alarm_irq_enable,321};322 323static int ds1286_probe(struct platform_device *pdev)324{325 struct rtc_device *rtc;326 struct ds1286_priv *priv;327 328 priv = devm_kzalloc(&pdev->dev, sizeof(struct ds1286_priv), GFP_KERNEL);329 if (!priv)330 return -ENOMEM;331 332 priv->rtcregs = devm_platform_ioremap_resource(pdev, 0);333 if (IS_ERR(priv->rtcregs))334 return PTR_ERR(priv->rtcregs);335 336 spin_lock_init(&priv->lock);337 platform_set_drvdata(pdev, priv);338 rtc = devm_rtc_device_register(&pdev->dev, "ds1286", &ds1286_ops,339 THIS_MODULE);340 if (IS_ERR(rtc))341 return PTR_ERR(rtc);342 priv->rtc = rtc;343 return 0;344}345 346static struct platform_driver ds1286_platform_driver = {347 .driver = {348 .name = "rtc-ds1286",349 },350 .probe = ds1286_probe,351};352 353module_platform_driver(ds1286_platform_driver);354 355MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");356MODULE_DESCRIPTION("DS1286 RTC driver");357MODULE_LICENSE("GPL");358MODULE_ALIAS("platform:rtc-ds1286");359