rtc-wm8350.c (11657B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Real Time Clock driver for Wolfson Microelectronics WM8350 4 * 5 * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC. 6 * 7 * Author: Liam Girdwood 8 * linux@wolfsonmicro.com 9 */ 10 11#include <linux/module.h> 12#include <linux/kernel.h> 13#include <linux/time.h> 14#include <linux/rtc.h> 15#include <linux/bcd.h> 16#include <linux/interrupt.h> 17#include <linux/ioctl.h> 18#include <linux/completion.h> 19#include <linux/mfd/wm8350/rtc.h> 20#include <linux/mfd/wm8350/core.h> 21#include <linux/delay.h> 22#include <linux/platform_device.h> 23 24#define WM8350_SET_ALM_RETRIES 5 25#define WM8350_SET_TIME_RETRIES 5 26#define WM8350_GET_TIME_RETRIES 5 27 28/* 29 * Read current time and date in RTC 30 */ 31static int wm8350_rtc_readtime(struct device *dev, struct rtc_time *tm) 32{ 33 struct wm8350 *wm8350 = dev_get_drvdata(dev); 34 u16 time1[4], time2[4]; 35 int retries = WM8350_GET_TIME_RETRIES, ret; 36 37 /* 38 * Read the time twice and compare. 39 * If time1 == time2, then time is valid else retry. 40 */ 41 do { 42 ret = wm8350_block_read(wm8350, WM8350_RTC_SECONDS_MINUTES, 43 4, time1); 44 if (ret < 0) 45 return ret; 46 ret = wm8350_block_read(wm8350, WM8350_RTC_SECONDS_MINUTES, 47 4, time2); 48 if (ret < 0) 49 return ret; 50 51 if (memcmp(time1, time2, sizeof(time1)) == 0) { 52 tm->tm_sec = time1[0] & WM8350_RTC_SECS_MASK; 53 54 tm->tm_min = (time1[0] & WM8350_RTC_MINS_MASK) 55 >> WM8350_RTC_MINS_SHIFT; 56 57 tm->tm_hour = time1[1] & WM8350_RTC_HRS_MASK; 58 59 tm->tm_wday = ((time1[1] >> WM8350_RTC_DAY_SHIFT) 60 & 0x7) - 1; 61 62 tm->tm_mon = ((time1[2] & WM8350_RTC_MTH_MASK) 63 >> WM8350_RTC_MTH_SHIFT) - 1; 64 65 tm->tm_mday = (time1[2] & WM8350_RTC_DATE_MASK); 66 67 tm->tm_year = ((time1[3] & WM8350_RTC_YHUNDREDS_MASK) 68 >> WM8350_RTC_YHUNDREDS_SHIFT) * 100; 69 tm->tm_year += time1[3] & WM8350_RTC_YUNITS_MASK; 70 71 tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, 72 tm->tm_year); 73 tm->tm_year -= 1900; 74 75 dev_dbg(dev, "Read (%d left): %04x %04x %04x %04x\n", 76 retries, 77 time1[0], time1[1], time1[2], time1[3]); 78 79 return 0; 80 } 81 } while (retries--); 82 83 dev_err(dev, "timed out reading RTC time\n"); 84 return -EIO; 85} 86 87/* 88 * Set current time and date in RTC 89 */ 90static int wm8350_rtc_settime(struct device *dev, struct rtc_time *tm) 91{ 92 struct wm8350 *wm8350 = dev_get_drvdata(dev); 93 u16 time[4]; 94 u16 rtc_ctrl; 95 int ret, retries = WM8350_SET_TIME_RETRIES; 96 97 time[0] = tm->tm_sec; 98 time[0] |= tm->tm_min << WM8350_RTC_MINS_SHIFT; 99 time[1] = tm->tm_hour; 100 time[1] |= (tm->tm_wday + 1) << WM8350_RTC_DAY_SHIFT; 101 time[2] = tm->tm_mday; 102 time[2] |= (tm->tm_mon + 1) << WM8350_RTC_MTH_SHIFT; 103 time[3] = ((tm->tm_year + 1900) / 100) << WM8350_RTC_YHUNDREDS_SHIFT; 104 time[3] |= (tm->tm_year + 1900) % 100; 105 106 dev_dbg(dev, "Setting: %04x %04x %04x %04x\n", 107 time[0], time[1], time[2], time[3]); 108 109 /* Set RTC_SET to stop the clock */ 110 ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL, WM8350_RTC_SET); 111 if (ret < 0) 112 return ret; 113 114 /* Wait until confirmation of stopping */ 115 do { 116 rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); 117 schedule_timeout_uninterruptible(msecs_to_jiffies(1)); 118 } while (--retries && !(rtc_ctrl & WM8350_RTC_STS)); 119 120 if (!retries) { 121 dev_err(dev, "timed out on set confirmation\n"); 122 return -EIO; 123 } 124 125 /* Write time to RTC */ 126 ret = wm8350_block_write(wm8350, WM8350_RTC_SECONDS_MINUTES, 4, time); 127 if (ret < 0) 128 return ret; 129 130 /* Clear RTC_SET to start the clock */ 131 ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL, 132 WM8350_RTC_SET); 133 return ret; 134} 135 136/* 137 * Read alarm time and date in RTC 138 */ 139static int wm8350_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) 140{ 141 struct wm8350 *wm8350 = dev_get_drvdata(dev); 142 struct rtc_time *tm = &alrm->time; 143 u16 time[4]; 144 int ret; 145 146 ret = wm8350_block_read(wm8350, WM8350_ALARM_SECONDS_MINUTES, 4, time); 147 if (ret < 0) 148 return ret; 149 150 tm->tm_sec = time[0] & WM8350_RTC_ALMSECS_MASK; 151 if (tm->tm_sec == WM8350_RTC_ALMSECS_MASK) 152 tm->tm_sec = -1; 153 154 tm->tm_min = time[0] & WM8350_RTC_ALMMINS_MASK; 155 if (tm->tm_min == WM8350_RTC_ALMMINS_MASK) 156 tm->tm_min = -1; 157 else 158 tm->tm_min >>= WM8350_RTC_ALMMINS_SHIFT; 159 160 tm->tm_hour = time[1] & WM8350_RTC_ALMHRS_MASK; 161 if (tm->tm_hour == WM8350_RTC_ALMHRS_MASK) 162 tm->tm_hour = -1; 163 164 tm->tm_wday = ((time[1] >> WM8350_RTC_ALMDAY_SHIFT) & 0x7) - 1; 165 if (tm->tm_wday > 7) 166 tm->tm_wday = -1; 167 168 tm->tm_mon = time[2] & WM8350_RTC_ALMMTH_MASK; 169 if (tm->tm_mon == WM8350_RTC_ALMMTH_MASK) 170 tm->tm_mon = -1; 171 else 172 tm->tm_mon = (tm->tm_mon >> WM8350_RTC_ALMMTH_SHIFT) - 1; 173 174 tm->tm_mday = (time[2] & WM8350_RTC_ALMDATE_MASK); 175 if (tm->tm_mday == WM8350_RTC_ALMDATE_MASK) 176 tm->tm_mday = -1; 177 178 tm->tm_year = -1; 179 180 alrm->enabled = !(time[3] & WM8350_RTC_ALMSTS); 181 182 return 0; 183} 184 185static int wm8350_rtc_stop_alarm(struct wm8350 *wm8350) 186{ 187 int retries = WM8350_SET_ALM_RETRIES; 188 u16 rtc_ctrl; 189 int ret; 190 191 /* Set RTC_SET to stop the clock */ 192 ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL, 193 WM8350_RTC_ALMSET); 194 if (ret < 0) 195 return ret; 196 197 /* Wait until confirmation of stopping */ 198 do { 199 rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); 200 schedule_timeout_uninterruptible(msecs_to_jiffies(1)); 201 } while (retries-- && !(rtc_ctrl & WM8350_RTC_ALMSTS)); 202 203 if (!(rtc_ctrl & WM8350_RTC_ALMSTS)) 204 return -ETIMEDOUT; 205 206 return 0; 207} 208 209static int wm8350_rtc_start_alarm(struct wm8350 *wm8350) 210{ 211 int ret; 212 int retries = WM8350_SET_ALM_RETRIES; 213 u16 rtc_ctrl; 214 215 ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL, 216 WM8350_RTC_ALMSET); 217 if (ret < 0) 218 return ret; 219 220 /* Wait until confirmation */ 221 do { 222 rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); 223 schedule_timeout_uninterruptible(msecs_to_jiffies(1)); 224 } while (retries-- && rtc_ctrl & WM8350_RTC_ALMSTS); 225 226 if (rtc_ctrl & WM8350_RTC_ALMSTS) 227 return -ETIMEDOUT; 228 229 return 0; 230} 231 232static int wm8350_rtc_alarm_irq_enable(struct device *dev, 233 unsigned int enabled) 234{ 235 struct wm8350 *wm8350 = dev_get_drvdata(dev); 236 237 if (enabled) 238 return wm8350_rtc_start_alarm(wm8350); 239 else 240 return wm8350_rtc_stop_alarm(wm8350); 241} 242 243static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) 244{ 245 struct wm8350 *wm8350 = dev_get_drvdata(dev); 246 struct rtc_time *tm = &alrm->time; 247 u16 time[3]; 248 int ret; 249 250 memset(time, 0, sizeof(time)); 251 252 if (tm->tm_sec != -1) 253 time[0] |= tm->tm_sec; 254 else 255 time[0] |= WM8350_RTC_ALMSECS_MASK; 256 257 if (tm->tm_min != -1) 258 time[0] |= tm->tm_min << WM8350_RTC_ALMMINS_SHIFT; 259 else 260 time[0] |= WM8350_RTC_ALMMINS_MASK; 261 262 if (tm->tm_hour != -1) 263 time[1] |= tm->tm_hour; 264 else 265 time[1] |= WM8350_RTC_ALMHRS_MASK; 266 267 if (tm->tm_wday != -1) 268 time[1] |= (tm->tm_wday + 1) << WM8350_RTC_ALMDAY_SHIFT; 269 else 270 time[1] |= WM8350_RTC_ALMDAY_MASK; 271 272 if (tm->tm_mday != -1) 273 time[2] |= tm->tm_mday; 274 else 275 time[2] |= WM8350_RTC_ALMDATE_MASK; 276 277 if (tm->tm_mon != -1) 278 time[2] |= (tm->tm_mon + 1) << WM8350_RTC_ALMMTH_SHIFT; 279 else 280 time[2] |= WM8350_RTC_ALMMTH_MASK; 281 282 ret = wm8350_rtc_stop_alarm(wm8350); 283 if (ret < 0) 284 return ret; 285 286 /* Write time to RTC */ 287 ret = wm8350_block_write(wm8350, WM8350_ALARM_SECONDS_MINUTES, 288 3, time); 289 if (ret < 0) 290 return ret; 291 292 if (alrm->enabled) 293 ret = wm8350_rtc_start_alarm(wm8350); 294 295 return ret; 296} 297 298static irqreturn_t wm8350_rtc_alarm_handler(int irq, void *data) 299{ 300 struct wm8350 *wm8350 = data; 301 struct rtc_device *rtc = wm8350->rtc.rtc; 302 int ret; 303 304 rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); 305 306 /* Make it one shot */ 307 ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL, 308 WM8350_RTC_ALMSET); 309 if (ret != 0) { 310 dev_err(&(wm8350->rtc.pdev->dev), 311 "Failed to disable alarm: %d\n", ret); 312 } 313 314 return IRQ_HANDLED; 315} 316 317static irqreturn_t wm8350_rtc_update_handler(int irq, void *data) 318{ 319 struct wm8350 *wm8350 = data; 320 struct rtc_device *rtc = wm8350->rtc.rtc; 321 322 rtc_update_irq(rtc, 1, RTC_IRQF | RTC_UF); 323 324 return IRQ_HANDLED; 325} 326 327static const struct rtc_class_ops wm8350_rtc_ops = { 328 .read_time = wm8350_rtc_readtime, 329 .set_time = wm8350_rtc_settime, 330 .read_alarm = wm8350_rtc_readalarm, 331 .set_alarm = wm8350_rtc_setalarm, 332 .alarm_irq_enable = wm8350_rtc_alarm_irq_enable, 333}; 334 335#ifdef CONFIG_PM_SLEEP 336static int wm8350_rtc_suspend(struct device *dev) 337{ 338 struct wm8350 *wm8350 = dev_get_drvdata(dev); 339 int ret = 0; 340 u16 reg; 341 342 reg = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); 343 344 if (device_may_wakeup(&wm8350->rtc.pdev->dev) && 345 reg & WM8350_RTC_ALMSTS) { 346 ret = wm8350_rtc_stop_alarm(wm8350); 347 if (ret != 0) 348 dev_err(dev, "Failed to stop RTC alarm: %d\n", ret); 349 } 350 351 return ret; 352} 353 354static int wm8350_rtc_resume(struct device *dev) 355{ 356 struct wm8350 *wm8350 = dev_get_drvdata(dev); 357 int ret; 358 359 if (wm8350->rtc.alarm_enabled) { 360 ret = wm8350_rtc_start_alarm(wm8350); 361 if (ret != 0) 362 dev_err(dev, "Failed to restart RTC alarm: %d\n", ret); 363 } 364 365 return 0; 366} 367#endif 368 369static int wm8350_rtc_probe(struct platform_device *pdev) 370{ 371 struct wm8350 *wm8350 = platform_get_drvdata(pdev); 372 struct wm8350_rtc *wm_rtc = &wm8350->rtc; 373 int ret = 0; 374 u16 timectl, power5; 375 376 timectl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); 377 if (timectl & WM8350_RTC_BCD) { 378 dev_err(&pdev->dev, "RTC BCD mode not supported\n"); 379 return -EINVAL; 380 } 381 if (timectl & WM8350_RTC_12HR) { 382 dev_err(&pdev->dev, "RTC 12 hour mode not supported\n"); 383 return -EINVAL; 384 } 385 386 /* enable the RTC if it's not already enabled */ 387 power5 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_5); 388 if (!(power5 & WM8350_RTC_TICK_ENA)) { 389 dev_info(wm8350->dev, "Starting RTC\n"); 390 391 wm8350_reg_unlock(wm8350); 392 393 ret = wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, 394 WM8350_RTC_TICK_ENA); 395 if (ret < 0) { 396 dev_err(&pdev->dev, "failed to enable RTC: %d\n", ret); 397 return ret; 398 } 399 400 wm8350_reg_lock(wm8350); 401 } 402 403 if (timectl & WM8350_RTC_STS) { 404 int retries; 405 406 ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL, 407 WM8350_RTC_SET); 408 if (ret < 0) { 409 dev_err(&pdev->dev, "failed to start: %d\n", ret); 410 return ret; 411 } 412 413 retries = WM8350_SET_TIME_RETRIES; 414 do { 415 timectl = wm8350_reg_read(wm8350, 416 WM8350_RTC_TIME_CONTROL); 417 } while (timectl & WM8350_RTC_STS && --retries); 418 419 if (retries == 0) { 420 dev_err(&pdev->dev, "failed to start: timeout\n"); 421 return -ENODEV; 422 } 423 } 424 425 device_init_wakeup(&pdev->dev, 1); 426 427 wm_rtc->rtc = devm_rtc_device_register(&pdev->dev, "wm8350", 428 &wm8350_rtc_ops, THIS_MODULE); 429 if (IS_ERR(wm_rtc->rtc)) { 430 ret = PTR_ERR(wm_rtc->rtc); 431 dev_err(&pdev->dev, "failed to register RTC: %d\n", ret); 432 return ret; 433 } 434 435 ret = wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC, 436 wm8350_rtc_update_handler, 0, 437 "RTC Seconds", wm8350); 438 if (ret) 439 return ret; 440 441 wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); 442 443 ret = wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM, 444 wm8350_rtc_alarm_handler, 0, 445 "RTC Alarm", wm8350); 446 if (ret) { 447 wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350); 448 return ret; 449 } 450 451 return 0; 452} 453 454static int wm8350_rtc_remove(struct platform_device *pdev) 455{ 456 struct wm8350 *wm8350 = platform_get_drvdata(pdev); 457 458 wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350); 459 wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM, wm8350); 460 461 return 0; 462} 463 464static SIMPLE_DEV_PM_OPS(wm8350_rtc_pm_ops, wm8350_rtc_suspend, 465 wm8350_rtc_resume); 466 467static struct platform_driver wm8350_rtc_driver = { 468 .probe = wm8350_rtc_probe, 469 .remove = wm8350_rtc_remove, 470 .driver = { 471 .name = "wm8350-rtc", 472 .pm = &wm8350_rtc_pm_ops, 473 }, 474}; 475 476module_platform_driver(wm8350_rtc_driver); 477 478MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 479MODULE_DESCRIPTION("RTC driver for the WM8350"); 480MODULE_LICENSE("GPL"); 481MODULE_ALIAS("platform:wm8350-rtc");