root/drivers/rtc/rtc-da9055.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. da9055_rtc_enable_alarm
  2. da9055_rtc_alm_irq
  3. da9055_read_alarm
  4. da9055_set_alarm
  5. da9055_rtc_get_alarm_status
  6. da9055_rtc_read_time
  7. da9055_rtc_set_time
  8. da9055_rtc_read_alarm
  9. da9055_rtc_set_alarm
  10. da9055_rtc_alarm_irq_enable
  11. da9055_rtc_device_init
  12. da9055_rtc_probe
  13. da9055_rtc_suspend
  14. da9055_rtc_resume
  15. da9055_rtc_freeze

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Real time clock driver for DA9055
   4  *
   5  * Copyright(c) 2012 Dialog Semiconductor Ltd.
   6  *
   7  * Author: Dajun Dajun Chen <dajun.chen@diasemi.com>
   8  */
   9 
  10 #include <linux/module.h>
  11 #include <linux/platform_device.h>
  12 #include <linux/rtc.h>
  13 
  14 #include <linux/mfd/da9055/core.h>
  15 #include <linux/mfd/da9055/reg.h>
  16 #include <linux/mfd/da9055/pdata.h>
  17 
  18 struct da9055_rtc {
  19         struct rtc_device *rtc;
  20         struct da9055 *da9055;
  21         int alarm_enable;
  22 };
  23 
  24 static int da9055_rtc_enable_alarm(struct da9055_rtc *rtc, bool enable)
  25 {
  26         int ret;
  27         if (enable) {
  28                 ret = da9055_reg_update(rtc->da9055, DA9055_REG_ALARM_Y,
  29                                         DA9055_RTC_ALM_EN,
  30                                         DA9055_RTC_ALM_EN);
  31                 if (ret != 0)
  32                         dev_err(rtc->da9055->dev, "Failed to enable ALM: %d\n",
  33                                 ret);
  34                 rtc->alarm_enable = 1;
  35         } else {
  36                 ret = da9055_reg_update(rtc->da9055, DA9055_REG_ALARM_Y,
  37                                         DA9055_RTC_ALM_EN, 0);
  38                 if (ret != 0)
  39                         dev_err(rtc->da9055->dev,
  40                                 "Failed to disable ALM: %d\n", ret);
  41                 rtc->alarm_enable = 0;
  42         }
  43         return ret;
  44 }
  45 
  46 static irqreturn_t da9055_rtc_alm_irq(int irq, void *data)
  47 {
  48         struct da9055_rtc *rtc = data;
  49 
  50         da9055_rtc_enable_alarm(rtc, 0);
  51         rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
  52 
  53         return IRQ_HANDLED;
  54 }
  55 
  56 static int da9055_read_alarm(struct da9055 *da9055, struct rtc_time *rtc_tm)
  57 {
  58         int ret;
  59         uint8_t v[5];
  60 
  61         ret = da9055_group_read(da9055, DA9055_REG_ALARM_MI, 5, v);
  62         if (ret != 0) {
  63                 dev_err(da9055->dev, "Failed to group read ALM: %d\n", ret);
  64                 return ret;
  65         }
  66 
  67         rtc_tm->tm_year = (v[4] & DA9055_RTC_ALM_YEAR) + 100;
  68         rtc_tm->tm_mon  = (v[3] & DA9055_RTC_ALM_MONTH) - 1;
  69         rtc_tm->tm_mday = v[2] & DA9055_RTC_ALM_DAY;
  70         rtc_tm->tm_hour = v[1] & DA9055_RTC_ALM_HOUR;
  71         rtc_tm->tm_min  = v[0] & DA9055_RTC_ALM_MIN;
  72         rtc_tm->tm_sec = 0;
  73 
  74         return rtc_valid_tm(rtc_tm);
  75 }
  76 
  77 static int da9055_set_alarm(struct da9055 *da9055, struct rtc_time *rtc_tm)
  78 {
  79         int ret;
  80         uint8_t v[2];
  81 
  82         rtc_tm->tm_year -= 100;
  83         rtc_tm->tm_mon += 1;
  84 
  85         ret = da9055_reg_update(da9055, DA9055_REG_ALARM_MI,
  86                                 DA9055_RTC_ALM_MIN, rtc_tm->tm_min);
  87         if (ret != 0) {
  88                 dev_err(da9055->dev, "Failed to write ALRM MIN: %d\n", ret);
  89                 return ret;
  90         }
  91 
  92         v[0] = rtc_tm->tm_hour;
  93         v[1] = rtc_tm->tm_mday;
  94 
  95         ret = da9055_group_write(da9055, DA9055_REG_ALARM_H, 2, v);
  96         if (ret < 0)
  97                 return ret;
  98 
  99         ret = da9055_reg_update(da9055, DA9055_REG_ALARM_MO,
 100                                 DA9055_RTC_ALM_MONTH, rtc_tm->tm_mon);
 101         if (ret < 0)
 102                 dev_err(da9055->dev, "Failed to write ALM Month:%d\n", ret);
 103 
 104         ret = da9055_reg_update(da9055, DA9055_REG_ALARM_Y,
 105                                 DA9055_RTC_ALM_YEAR, rtc_tm->tm_year);
 106         if (ret < 0)
 107                 dev_err(da9055->dev, "Failed to write ALM Year:%d\n", ret);
 108 
 109         return ret;
 110 }
 111 
 112 static int da9055_rtc_get_alarm_status(struct da9055 *da9055)
 113 {
 114         int ret;
 115 
 116         ret = da9055_reg_read(da9055, DA9055_REG_ALARM_Y);
 117         if (ret < 0) {
 118                 dev_err(da9055->dev, "Failed to read ALM: %d\n", ret);
 119                 return ret;
 120         }
 121         ret &= DA9055_RTC_ALM_EN;
 122         return (ret > 0) ? 1 : 0;
 123 }
 124 
 125 static int da9055_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
 126 {
 127         struct da9055_rtc *rtc = dev_get_drvdata(dev);
 128         uint8_t v[6];
 129         int ret;
 130 
 131         ret = da9055_reg_read(rtc->da9055, DA9055_REG_COUNT_S);
 132         if (ret < 0)
 133                 return ret;
 134 
 135         /*
 136          * Registers are only valid when RTC_READ
 137          * status bit is asserted
 138          */
 139         if (!(ret & DA9055_RTC_READ))
 140                 return -EBUSY;
 141 
 142         ret = da9055_group_read(rtc->da9055, DA9055_REG_COUNT_S, 6, v);
 143         if (ret < 0) {
 144                 dev_err(rtc->da9055->dev, "Failed to read RTC time : %d\n",
 145                         ret);
 146                 return ret;
 147         }
 148 
 149         rtc_tm->tm_year = (v[5] & DA9055_RTC_YEAR) + 100;
 150         rtc_tm->tm_mon  = (v[4] & DA9055_RTC_MONTH) - 1;
 151         rtc_tm->tm_mday = v[3] & DA9055_RTC_DAY;
 152         rtc_tm->tm_hour = v[2] & DA9055_RTC_HOUR;
 153         rtc_tm->tm_min  = v[1] & DA9055_RTC_MIN;
 154         rtc_tm->tm_sec  = v[0] & DA9055_RTC_SEC;
 155 
 156         return 0;
 157 }
 158 
 159 static int da9055_rtc_set_time(struct device *dev, struct rtc_time *tm)
 160 {
 161         struct da9055_rtc *rtc;
 162         uint8_t v[6];
 163 
 164         rtc = dev_get_drvdata(dev);
 165 
 166         v[0] = tm->tm_sec;
 167         v[1] = tm->tm_min;
 168         v[2] = tm->tm_hour;
 169         v[3] = tm->tm_mday;
 170         v[4] = tm->tm_mon + 1;
 171         v[5] = tm->tm_year - 100;
 172 
 173         return da9055_group_write(rtc->da9055, DA9055_REG_COUNT_S, 6, v);
 174 }
 175 
 176 static int da9055_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 177 {
 178         int ret;
 179         struct rtc_time *tm = &alrm->time;
 180         struct da9055_rtc *rtc = dev_get_drvdata(dev);
 181 
 182         ret = da9055_read_alarm(rtc->da9055, tm);
 183 
 184         if (ret)
 185                 return ret;
 186 
 187         alrm->enabled = da9055_rtc_get_alarm_status(rtc->da9055);
 188 
 189         return 0;
 190 }
 191 
 192 static int da9055_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 193 {
 194         int ret;
 195         struct rtc_time *tm = &alrm->time;
 196         struct da9055_rtc *rtc = dev_get_drvdata(dev);
 197 
 198         ret = da9055_rtc_enable_alarm(rtc, 0);
 199         if (ret < 0)
 200                 return ret;
 201 
 202         ret = da9055_set_alarm(rtc->da9055, tm);
 203         if (ret)
 204                 return ret;
 205 
 206         ret = da9055_rtc_enable_alarm(rtc, 1);
 207 
 208         return ret;
 209 }
 210 
 211 static int da9055_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 212 {
 213         struct da9055_rtc *rtc = dev_get_drvdata(dev);
 214 
 215         return da9055_rtc_enable_alarm(rtc, enabled);
 216 }
 217 
 218 static const struct rtc_class_ops da9055_rtc_ops = {
 219         .read_time      = da9055_rtc_read_time,
 220         .set_time       = da9055_rtc_set_time,
 221         .read_alarm     = da9055_rtc_read_alarm,
 222         .set_alarm      = da9055_rtc_set_alarm,
 223         .alarm_irq_enable = da9055_rtc_alarm_irq_enable,
 224 };
 225 
 226 static int da9055_rtc_device_init(struct da9055 *da9055,
 227                                         struct da9055_pdata *pdata)
 228 {
 229         int ret;
 230 
 231         /* Enable RTC and the internal Crystal */
 232         ret = da9055_reg_update(da9055, DA9055_REG_CONTROL_B,
 233                                 DA9055_RTC_EN, DA9055_RTC_EN);
 234         if (ret < 0)
 235                 return ret;
 236         ret = da9055_reg_update(da9055, DA9055_REG_EN_32K,
 237                                 DA9055_CRYSTAL_EN, DA9055_CRYSTAL_EN);
 238         if (ret < 0)
 239                 return ret;
 240 
 241         /* Enable RTC in Power Down mode */
 242         ret = da9055_reg_update(da9055, DA9055_REG_CONTROL_B,
 243                                 DA9055_RTC_MODE_PD, DA9055_RTC_MODE_PD);
 244         if (ret < 0)
 245                 return ret;
 246 
 247         /* Enable RTC in Reset mode */
 248         if (pdata && pdata->reset_enable) {
 249                 ret = da9055_reg_update(da9055, DA9055_REG_CONTROL_B,
 250                                         DA9055_RTC_MODE_SD,
 251                                         DA9055_RTC_MODE_SD <<
 252                                         DA9055_RTC_MODE_SD_SHIFT);
 253                 if (ret < 0)
 254                         return ret;
 255         }
 256 
 257         /* Disable the RTC TICK ALM */
 258         ret = da9055_reg_update(da9055, DA9055_REG_ALARM_MO,
 259                                 DA9055_RTC_TICK_WAKE_MASK, 0);
 260         if (ret < 0)
 261                 return ret;
 262 
 263         return 0;
 264 }
 265 
 266 static int da9055_rtc_probe(struct platform_device *pdev)
 267 {
 268         struct da9055_rtc *rtc;
 269         struct da9055_pdata *pdata = NULL;
 270         int ret, alm_irq;
 271 
 272         rtc = devm_kzalloc(&pdev->dev, sizeof(struct da9055_rtc), GFP_KERNEL);
 273         if (!rtc)
 274                 return -ENOMEM;
 275 
 276         rtc->da9055 = dev_get_drvdata(pdev->dev.parent);
 277         pdata = dev_get_platdata(rtc->da9055->dev);
 278         platform_set_drvdata(pdev, rtc);
 279 
 280         ret = da9055_rtc_device_init(rtc->da9055, pdata);
 281         if (ret < 0)
 282                 goto err_rtc;
 283 
 284         ret = da9055_reg_read(rtc->da9055, DA9055_REG_ALARM_Y);
 285         if (ret < 0)
 286                 goto err_rtc;
 287 
 288         if (ret & DA9055_RTC_ALM_EN)
 289                 rtc->alarm_enable = 1;
 290 
 291         device_init_wakeup(&pdev->dev, 1);
 292 
 293         rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
 294                                         &da9055_rtc_ops, THIS_MODULE);
 295         if (IS_ERR(rtc->rtc)) {
 296                 ret = PTR_ERR(rtc->rtc);
 297                 goto err_rtc;
 298         }
 299 
 300         alm_irq = platform_get_irq_byname(pdev, "ALM");
 301         if (alm_irq < 0)
 302                 return alm_irq;
 303 
 304         ret = devm_request_threaded_irq(&pdev->dev, alm_irq, NULL,
 305                                         da9055_rtc_alm_irq,
 306                                         IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 307                                         "ALM", rtc);
 308         if (ret != 0)
 309                 dev_err(rtc->da9055->dev, "irq registration failed: %d\n", ret);
 310 
 311 err_rtc:
 312         return ret;
 313 
 314 }
 315 
 316 #ifdef CONFIG_PM
 317 /* Turn off the alarm if it should not be a wake source. */
 318 static int da9055_rtc_suspend(struct device *dev)
 319 {
 320         struct platform_device *pdev = to_platform_device(dev);
 321         struct da9055_rtc *rtc = dev_get_drvdata(&pdev->dev);
 322         int ret;
 323 
 324         if (!device_may_wakeup(&pdev->dev)) {
 325                 /* Disable the ALM IRQ */
 326                 ret = da9055_rtc_enable_alarm(rtc, 0);
 327                 if (ret < 0)
 328                         dev_err(&pdev->dev, "Failed to disable RTC ALM\n");
 329         }
 330 
 331         return 0;
 332 }
 333 
 334 /* Enable the alarm if it should be enabled (in case it was disabled to
 335  * prevent use as a wake source).
 336  */
 337 static int da9055_rtc_resume(struct device *dev)
 338 {
 339         struct platform_device *pdev = to_platform_device(dev);
 340         struct da9055_rtc *rtc = dev_get_drvdata(&pdev->dev);
 341         int ret;
 342 
 343         if (!device_may_wakeup(&pdev->dev)) {
 344                 if (rtc->alarm_enable) {
 345                         ret = da9055_rtc_enable_alarm(rtc, 1);
 346                         if (ret < 0)
 347                                 dev_err(&pdev->dev,
 348                                         "Failed to restart RTC ALM\n");
 349                 }
 350         }
 351 
 352         return 0;
 353 }
 354 
 355 /* Unconditionally disable the alarm */
 356 static int da9055_rtc_freeze(struct device *dev)
 357 {
 358         struct platform_device *pdev = to_platform_device(dev);
 359         struct da9055_rtc *rtc = dev_get_drvdata(&pdev->dev);
 360         int ret;
 361 
 362         ret = da9055_rtc_enable_alarm(rtc, 0);
 363         if (ret < 0)
 364                 dev_err(&pdev->dev, "Failed to freeze RTC ALMs\n");
 365 
 366         return 0;
 367 
 368 }
 369 #else
 370 #define da9055_rtc_suspend NULL
 371 #define da9055_rtc_resume NULL
 372 #define da9055_rtc_freeze NULL
 373 #endif
 374 
 375 static const struct dev_pm_ops da9055_rtc_pm_ops = {
 376         .suspend = da9055_rtc_suspend,
 377         .resume = da9055_rtc_resume,
 378 
 379         .freeze = da9055_rtc_freeze,
 380         .thaw = da9055_rtc_resume,
 381         .restore = da9055_rtc_resume,
 382 
 383         .poweroff = da9055_rtc_suspend,
 384 };
 385 
 386 static struct platform_driver da9055_rtc_driver = {
 387         .probe  = da9055_rtc_probe,
 388         .driver = {
 389                 .name   = "da9055-rtc",
 390                 .pm = &da9055_rtc_pm_ops,
 391         },
 392 };
 393 
 394 module_platform_driver(da9055_rtc_driver);
 395 
 396 MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
 397 MODULE_DESCRIPTION("RTC driver for Dialog DA9055 PMIC");
 398 MODULE_LICENSE("GPL");
 399 MODULE_ALIAS("platform:da9055-rtc");

/* [<][>][^][v][top][bottom][index][help] */