0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/module.h>
0012 #include <linux/kernel.h>
0013 #include <linux/time.h>
0014 #include <linux/rtc.h>
0015 #include <linux/bcd.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/ioctl.h>
0018 #include <linux/completion.h>
0019 #include <linux/mfd/wm8350/rtc.h>
0020 #include <linux/mfd/wm8350/core.h>
0021 #include <linux/delay.h>
0022 #include <linux/platform_device.h>
0023
0024 #define WM8350_SET_ALM_RETRIES 5
0025 #define WM8350_SET_TIME_RETRIES 5
0026 #define WM8350_GET_TIME_RETRIES 5
0027
0028
0029
0030
0031 static int wm8350_rtc_readtime(struct device *dev, struct rtc_time *tm)
0032 {
0033 struct wm8350 *wm8350 = dev_get_drvdata(dev);
0034 u16 time1[4], time2[4];
0035 int retries = WM8350_GET_TIME_RETRIES, ret;
0036
0037
0038
0039
0040
0041 do {
0042 ret = wm8350_block_read(wm8350, WM8350_RTC_SECONDS_MINUTES,
0043 4, time1);
0044 if (ret < 0)
0045 return ret;
0046 ret = wm8350_block_read(wm8350, WM8350_RTC_SECONDS_MINUTES,
0047 4, time2);
0048 if (ret < 0)
0049 return ret;
0050
0051 if (memcmp(time1, time2, sizeof(time1)) == 0) {
0052 tm->tm_sec = time1[0] & WM8350_RTC_SECS_MASK;
0053
0054 tm->tm_min = (time1[0] & WM8350_RTC_MINS_MASK)
0055 >> WM8350_RTC_MINS_SHIFT;
0056
0057 tm->tm_hour = time1[1] & WM8350_RTC_HRS_MASK;
0058
0059 tm->tm_wday = ((time1[1] >> WM8350_RTC_DAY_SHIFT)
0060 & 0x7) - 1;
0061
0062 tm->tm_mon = ((time1[2] & WM8350_RTC_MTH_MASK)
0063 >> WM8350_RTC_MTH_SHIFT) - 1;
0064
0065 tm->tm_mday = (time1[2] & WM8350_RTC_DATE_MASK);
0066
0067 tm->tm_year = ((time1[3] & WM8350_RTC_YHUNDREDS_MASK)
0068 >> WM8350_RTC_YHUNDREDS_SHIFT) * 100;
0069 tm->tm_year += time1[3] & WM8350_RTC_YUNITS_MASK;
0070
0071 tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon,
0072 tm->tm_year);
0073 tm->tm_year -= 1900;
0074
0075 dev_dbg(dev, "Read (%d left): %04x %04x %04x %04x\n",
0076 retries,
0077 time1[0], time1[1], time1[2], time1[3]);
0078
0079 return 0;
0080 }
0081 } while (retries--);
0082
0083 dev_err(dev, "timed out reading RTC time\n");
0084 return -EIO;
0085 }
0086
0087
0088
0089
0090 static int wm8350_rtc_settime(struct device *dev, struct rtc_time *tm)
0091 {
0092 struct wm8350 *wm8350 = dev_get_drvdata(dev);
0093 u16 time[4];
0094 u16 rtc_ctrl;
0095 int ret, retries = WM8350_SET_TIME_RETRIES;
0096
0097 time[0] = tm->tm_sec;
0098 time[0] |= tm->tm_min << WM8350_RTC_MINS_SHIFT;
0099 time[1] = tm->tm_hour;
0100 time[1] |= (tm->tm_wday + 1) << WM8350_RTC_DAY_SHIFT;
0101 time[2] = tm->tm_mday;
0102 time[2] |= (tm->tm_mon + 1) << WM8350_RTC_MTH_SHIFT;
0103 time[3] = ((tm->tm_year + 1900) / 100) << WM8350_RTC_YHUNDREDS_SHIFT;
0104 time[3] |= (tm->tm_year + 1900) % 100;
0105
0106 dev_dbg(dev, "Setting: %04x %04x %04x %04x\n",
0107 time[0], time[1], time[2], time[3]);
0108
0109
0110 ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL, WM8350_RTC_SET);
0111 if (ret < 0)
0112 return ret;
0113
0114
0115 do {
0116 rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
0117 schedule_timeout_uninterruptible(msecs_to_jiffies(1));
0118 } while (--retries && !(rtc_ctrl & WM8350_RTC_STS));
0119
0120 if (!retries) {
0121 dev_err(dev, "timed out on set confirmation\n");
0122 return -EIO;
0123 }
0124
0125
0126 ret = wm8350_block_write(wm8350, WM8350_RTC_SECONDS_MINUTES, 4, time);
0127 if (ret < 0)
0128 return ret;
0129
0130
0131 ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL,
0132 WM8350_RTC_SET);
0133 return ret;
0134 }
0135
0136
0137
0138
0139 static int wm8350_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
0140 {
0141 struct wm8350 *wm8350 = dev_get_drvdata(dev);
0142 struct rtc_time *tm = &alrm->time;
0143 u16 time[4];
0144 int ret;
0145
0146 ret = wm8350_block_read(wm8350, WM8350_ALARM_SECONDS_MINUTES, 4, time);
0147 if (ret < 0)
0148 return ret;
0149
0150 tm->tm_sec = time[0] & WM8350_RTC_ALMSECS_MASK;
0151 if (tm->tm_sec == WM8350_RTC_ALMSECS_MASK)
0152 tm->tm_sec = -1;
0153
0154 tm->tm_min = time[0] & WM8350_RTC_ALMMINS_MASK;
0155 if (tm->tm_min == WM8350_RTC_ALMMINS_MASK)
0156 tm->tm_min = -1;
0157 else
0158 tm->tm_min >>= WM8350_RTC_ALMMINS_SHIFT;
0159
0160 tm->tm_hour = time[1] & WM8350_RTC_ALMHRS_MASK;
0161 if (tm->tm_hour == WM8350_RTC_ALMHRS_MASK)
0162 tm->tm_hour = -1;
0163
0164 tm->tm_wday = ((time[1] >> WM8350_RTC_ALMDAY_SHIFT) & 0x7) - 1;
0165 if (tm->tm_wday > 7)
0166 tm->tm_wday = -1;
0167
0168 tm->tm_mon = time[2] & WM8350_RTC_ALMMTH_MASK;
0169 if (tm->tm_mon == WM8350_RTC_ALMMTH_MASK)
0170 tm->tm_mon = -1;
0171 else
0172 tm->tm_mon = (tm->tm_mon >> WM8350_RTC_ALMMTH_SHIFT) - 1;
0173
0174 tm->tm_mday = (time[2] & WM8350_RTC_ALMDATE_MASK);
0175 if (tm->tm_mday == WM8350_RTC_ALMDATE_MASK)
0176 tm->tm_mday = -1;
0177
0178 tm->tm_year = -1;
0179
0180 alrm->enabled = !(time[3] & WM8350_RTC_ALMSTS);
0181
0182 return 0;
0183 }
0184
0185 static int wm8350_rtc_stop_alarm(struct wm8350 *wm8350)
0186 {
0187 int retries = WM8350_SET_ALM_RETRIES;
0188 u16 rtc_ctrl;
0189 int ret;
0190
0191
0192 ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL,
0193 WM8350_RTC_ALMSET);
0194 if (ret < 0)
0195 return ret;
0196
0197
0198 do {
0199 rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
0200 schedule_timeout_uninterruptible(msecs_to_jiffies(1));
0201 } while (retries-- && !(rtc_ctrl & WM8350_RTC_ALMSTS));
0202
0203 if (!(rtc_ctrl & WM8350_RTC_ALMSTS))
0204 return -ETIMEDOUT;
0205
0206 return 0;
0207 }
0208
0209 static int wm8350_rtc_start_alarm(struct wm8350 *wm8350)
0210 {
0211 int ret;
0212 int retries = WM8350_SET_ALM_RETRIES;
0213 u16 rtc_ctrl;
0214
0215 ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL,
0216 WM8350_RTC_ALMSET);
0217 if (ret < 0)
0218 return ret;
0219
0220
0221 do {
0222 rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
0223 schedule_timeout_uninterruptible(msecs_to_jiffies(1));
0224 } while (retries-- && rtc_ctrl & WM8350_RTC_ALMSTS);
0225
0226 if (rtc_ctrl & WM8350_RTC_ALMSTS)
0227 return -ETIMEDOUT;
0228
0229 return 0;
0230 }
0231
0232 static int wm8350_rtc_alarm_irq_enable(struct device *dev,
0233 unsigned int enabled)
0234 {
0235 struct wm8350 *wm8350 = dev_get_drvdata(dev);
0236
0237 if (enabled)
0238 return wm8350_rtc_start_alarm(wm8350);
0239 else
0240 return wm8350_rtc_stop_alarm(wm8350);
0241 }
0242
0243 static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
0244 {
0245 struct wm8350 *wm8350 = dev_get_drvdata(dev);
0246 struct rtc_time *tm = &alrm->time;
0247 u16 time[3];
0248 int ret;
0249
0250 memset(time, 0, sizeof(time));
0251
0252 if (tm->tm_sec != -1)
0253 time[0] |= tm->tm_sec;
0254 else
0255 time[0] |= WM8350_RTC_ALMSECS_MASK;
0256
0257 if (tm->tm_min != -1)
0258 time[0] |= tm->tm_min << WM8350_RTC_ALMMINS_SHIFT;
0259 else
0260 time[0] |= WM8350_RTC_ALMMINS_MASK;
0261
0262 if (tm->tm_hour != -1)
0263 time[1] |= tm->tm_hour;
0264 else
0265 time[1] |= WM8350_RTC_ALMHRS_MASK;
0266
0267 if (tm->tm_wday != -1)
0268 time[1] |= (tm->tm_wday + 1) << WM8350_RTC_ALMDAY_SHIFT;
0269 else
0270 time[1] |= WM8350_RTC_ALMDAY_MASK;
0271
0272 if (tm->tm_mday != -1)
0273 time[2] |= tm->tm_mday;
0274 else
0275 time[2] |= WM8350_RTC_ALMDATE_MASK;
0276
0277 if (tm->tm_mon != -1)
0278 time[2] |= (tm->tm_mon + 1) << WM8350_RTC_ALMMTH_SHIFT;
0279 else
0280 time[2] |= WM8350_RTC_ALMMTH_MASK;
0281
0282 ret = wm8350_rtc_stop_alarm(wm8350);
0283 if (ret < 0)
0284 return ret;
0285
0286
0287 ret = wm8350_block_write(wm8350, WM8350_ALARM_SECONDS_MINUTES,
0288 3, time);
0289 if (ret < 0)
0290 return ret;
0291
0292 if (alrm->enabled)
0293 ret = wm8350_rtc_start_alarm(wm8350);
0294
0295 return ret;
0296 }
0297
0298 static irqreturn_t wm8350_rtc_alarm_handler(int irq, void *data)
0299 {
0300 struct wm8350 *wm8350 = data;
0301 struct rtc_device *rtc = wm8350->rtc.rtc;
0302 int ret;
0303
0304 rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF);
0305
0306
0307 ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL,
0308 WM8350_RTC_ALMSET);
0309 if (ret != 0) {
0310 dev_err(&(wm8350->rtc.pdev->dev),
0311 "Failed to disable alarm: %d\n", ret);
0312 }
0313
0314 return IRQ_HANDLED;
0315 }
0316
0317 static irqreturn_t wm8350_rtc_update_handler(int irq, void *data)
0318 {
0319 struct wm8350 *wm8350 = data;
0320 struct rtc_device *rtc = wm8350->rtc.rtc;
0321
0322 rtc_update_irq(rtc, 1, RTC_IRQF | RTC_UF);
0323
0324 return IRQ_HANDLED;
0325 }
0326
0327 static const struct rtc_class_ops wm8350_rtc_ops = {
0328 .read_time = wm8350_rtc_readtime,
0329 .set_time = wm8350_rtc_settime,
0330 .read_alarm = wm8350_rtc_readalarm,
0331 .set_alarm = wm8350_rtc_setalarm,
0332 .alarm_irq_enable = wm8350_rtc_alarm_irq_enable,
0333 };
0334
0335 #ifdef CONFIG_PM_SLEEP
0336 static int wm8350_rtc_suspend(struct device *dev)
0337 {
0338 struct wm8350 *wm8350 = dev_get_drvdata(dev);
0339 int ret = 0;
0340 u16 reg;
0341
0342 reg = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
0343
0344 if (device_may_wakeup(&wm8350->rtc.pdev->dev) &&
0345 reg & WM8350_RTC_ALMSTS) {
0346 ret = wm8350_rtc_stop_alarm(wm8350);
0347 if (ret != 0)
0348 dev_err(dev, "Failed to stop RTC alarm: %d\n", ret);
0349 }
0350
0351 return ret;
0352 }
0353
0354 static int wm8350_rtc_resume(struct device *dev)
0355 {
0356 struct wm8350 *wm8350 = dev_get_drvdata(dev);
0357 int ret;
0358
0359 if (wm8350->rtc.alarm_enabled) {
0360 ret = wm8350_rtc_start_alarm(wm8350);
0361 if (ret != 0)
0362 dev_err(dev, "Failed to restart RTC alarm: %d\n", ret);
0363 }
0364
0365 return 0;
0366 }
0367 #endif
0368
0369 static int wm8350_rtc_probe(struct platform_device *pdev)
0370 {
0371 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
0372 struct wm8350_rtc *wm_rtc = &wm8350->rtc;
0373 int ret = 0;
0374 u16 timectl, power5;
0375
0376 timectl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
0377 if (timectl & WM8350_RTC_BCD) {
0378 dev_err(&pdev->dev, "RTC BCD mode not supported\n");
0379 return -EINVAL;
0380 }
0381 if (timectl & WM8350_RTC_12HR) {
0382 dev_err(&pdev->dev, "RTC 12 hour mode not supported\n");
0383 return -EINVAL;
0384 }
0385
0386
0387 power5 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_5);
0388 if (!(power5 & WM8350_RTC_TICK_ENA)) {
0389 dev_info(wm8350->dev, "Starting RTC\n");
0390
0391 wm8350_reg_unlock(wm8350);
0392
0393 ret = wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5,
0394 WM8350_RTC_TICK_ENA);
0395 if (ret < 0) {
0396 dev_err(&pdev->dev, "failed to enable RTC: %d\n", ret);
0397 return ret;
0398 }
0399
0400 wm8350_reg_lock(wm8350);
0401 }
0402
0403 if (timectl & WM8350_RTC_STS) {
0404 int retries;
0405
0406 ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL,
0407 WM8350_RTC_SET);
0408 if (ret < 0) {
0409 dev_err(&pdev->dev, "failed to start: %d\n", ret);
0410 return ret;
0411 }
0412
0413 retries = WM8350_SET_TIME_RETRIES;
0414 do {
0415 timectl = wm8350_reg_read(wm8350,
0416 WM8350_RTC_TIME_CONTROL);
0417 } while (timectl & WM8350_RTC_STS && --retries);
0418
0419 if (retries == 0) {
0420 dev_err(&pdev->dev, "failed to start: timeout\n");
0421 return -ENODEV;
0422 }
0423 }
0424
0425 device_init_wakeup(&pdev->dev, 1);
0426
0427 wm_rtc->rtc = devm_rtc_device_register(&pdev->dev, "wm8350",
0428 &wm8350_rtc_ops, THIS_MODULE);
0429 if (IS_ERR(wm_rtc->rtc)) {
0430 ret = PTR_ERR(wm_rtc->rtc);
0431 dev_err(&pdev->dev, "failed to register RTC: %d\n", ret);
0432 return ret;
0433 }
0434
0435 ret = wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC,
0436 wm8350_rtc_update_handler, 0,
0437 "RTC Seconds", wm8350);
0438 if (ret)
0439 return ret;
0440
0441 wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
0442
0443 ret = wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM,
0444 wm8350_rtc_alarm_handler, 0,
0445 "RTC Alarm", wm8350);
0446 if (ret) {
0447 wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350);
0448 return ret;
0449 }
0450
0451 return 0;
0452 }
0453
0454 static int wm8350_rtc_remove(struct platform_device *pdev)
0455 {
0456 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
0457
0458 wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350);
0459 wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM, wm8350);
0460
0461 return 0;
0462 }
0463
0464 static SIMPLE_DEV_PM_OPS(wm8350_rtc_pm_ops, wm8350_rtc_suspend,
0465 wm8350_rtc_resume);
0466
0467 static struct platform_driver wm8350_rtc_driver = {
0468 .probe = wm8350_rtc_probe,
0469 .remove = wm8350_rtc_remove,
0470 .driver = {
0471 .name = "wm8350-rtc",
0472 .pm = &wm8350_rtc_pm_ops,
0473 },
0474 };
0475
0476 module_platform_driver(wm8350_rtc_driver);
0477
0478 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
0479 MODULE_DESCRIPTION("RTC driver for the WM8350");
0480 MODULE_LICENSE("GPL");
0481 MODULE_ALIAS("platform:wm8350-rtc");