root/drivers/rtc/rtc-ab3100.c

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

DEFINITIONS

This source file includes following definitions.
  1. ab3100_rtc_set_time
  2. ab3100_rtc_read_time
  3. ab3100_rtc_read_alarm
  4. ab3100_rtc_set_alarm
  5. ab3100_rtc_irq_enable
  6. ab3100_rtc_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (C) 2007-2009 ST-Ericsson AB
   4  * RTC clock driver for the AB3100 Analog Baseband Chip
   5  * Author: Linus Walleij <linus.walleij@stericsson.com>
   6  */
   7 #include <linux/module.h>
   8 #include <linux/kernel.h>
   9 #include <linux/init.h>
  10 #include <linux/platform_device.h>
  11 #include <linux/rtc.h>
  12 #include <linux/mfd/abx500.h>
  13 
  14 /* Clock rate in Hz */
  15 #define AB3100_RTC_CLOCK_RATE   32768
  16 
  17 /*
  18  * The AB3100 RTC registers. These are the same for
  19  * AB3000 and AB3100.
  20  * Control register:
  21  * Bit 0: RTC Monitor cleared=0, active=1, if you set it
  22  *        to 1 it remains active until RTC power is lost.
  23  * Bit 1: 32 kHz Oscillator, 0 = on, 1 = bypass
  24  * Bit 2: Alarm on, 0 = off, 1 = on
  25  * Bit 3: 32 kHz buffer disabling, 0 = enabled, 1 = disabled
  26  */
  27 #define AB3100_RTC              0x53
  28 /* default setting, buffer disabled, alarm on */
  29 #define RTC_SETTING             0x30
  30 /* Alarm when AL0-AL3 == TI0-TI3  */
  31 #define AB3100_AL0              0x56
  32 #define AB3100_AL1              0x57
  33 #define AB3100_AL2              0x58
  34 #define AB3100_AL3              0x59
  35 /* This 48-bit register that counts up at 32768 Hz */
  36 #define AB3100_TI0              0x5a
  37 #define AB3100_TI1              0x5b
  38 #define AB3100_TI2              0x5c
  39 #define AB3100_TI3              0x5d
  40 #define AB3100_TI4              0x5e
  41 #define AB3100_TI5              0x5f
  42 
  43 /*
  44  * RTC clock functions and device struct declaration
  45  */
  46 static int ab3100_rtc_set_time(struct device *dev, struct rtc_time *tm)
  47 {
  48         u8 regs[] = {AB3100_TI0, AB3100_TI1, AB3100_TI2,
  49                      AB3100_TI3, AB3100_TI4, AB3100_TI5};
  50         unsigned char buf[6];
  51         u64 hw_counter = rtc_tm_to_time64(tm) * AB3100_RTC_CLOCK_RATE * 2;
  52         int err = 0;
  53         int i;
  54 
  55         buf[0] = (hw_counter) & 0xFF;
  56         buf[1] = (hw_counter >> 8) & 0xFF;
  57         buf[2] = (hw_counter >> 16) & 0xFF;
  58         buf[3] = (hw_counter >> 24) & 0xFF;
  59         buf[4] = (hw_counter >> 32) & 0xFF;
  60         buf[5] = (hw_counter >> 40) & 0xFF;
  61 
  62         for (i = 0; i < 6; i++) {
  63                 err = abx500_set_register_interruptible(dev, 0,
  64                                                         regs[i], buf[i]);
  65                 if (err)
  66                         return err;
  67         }
  68 
  69         /* Set the flag to mark that the clock is now set */
  70         return abx500_mask_and_set_register_interruptible(dev, 0,
  71                                                           AB3100_RTC,
  72                                                           0x01, 0x01);
  73 
  74 }
  75 
  76 static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm)
  77 {
  78         time64_t time;
  79         u8 rtcval;
  80         int err;
  81 
  82         err = abx500_get_register_interruptible(dev, 0,
  83                                                 AB3100_RTC, &rtcval);
  84         if (err)
  85                 return err;
  86 
  87         if (!(rtcval & 0x01)) {
  88                 dev_info(dev, "clock not set (lost power)");
  89                 return -EINVAL;
  90         } else {
  91                 u64 hw_counter;
  92                 u8 buf[6];
  93 
  94                 /* Read out time registers */
  95                 err = abx500_get_register_page_interruptible(dev, 0,
  96                                                              AB3100_TI0,
  97                                                              buf, 6);
  98                 if (err != 0)
  99                         return err;
 100 
 101                 hw_counter = ((u64) buf[5] << 40) | ((u64) buf[4] << 32) |
 102                         ((u64) buf[3] << 24) | ((u64) buf[2] << 16) |
 103                         ((u64) buf[1] << 8) | (u64) buf[0];
 104                 time = hw_counter / (u64) (AB3100_RTC_CLOCK_RATE * 2);
 105         }
 106 
 107         rtc_time64_to_tm(time, tm);
 108 
 109         return 0;
 110 }
 111 
 112 static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 113 {
 114         time64_t time;
 115         u64 hw_counter;
 116         u8 buf[6];
 117         u8 rtcval;
 118         int err;
 119 
 120         /* Figure out if alarm is enabled or not */
 121         err = abx500_get_register_interruptible(dev, 0,
 122                                                 AB3100_RTC, &rtcval);
 123         if (err)
 124                 return err;
 125         if (rtcval & 0x04)
 126                 alarm->enabled = 1;
 127         else
 128                 alarm->enabled = 0;
 129         /* No idea how this could be represented */
 130         alarm->pending = 0;
 131         /* Read out alarm registers, only 4 bytes */
 132         err = abx500_get_register_page_interruptible(dev, 0,
 133                                                      AB3100_AL0, buf, 4);
 134         if (err)
 135                 return err;
 136         hw_counter = ((u64) buf[3] << 40) | ((u64) buf[2] << 32) |
 137                 ((u64) buf[1] << 24) | ((u64) buf[0] << 16);
 138         time = hw_counter / (u64) (AB3100_RTC_CLOCK_RATE * 2);
 139 
 140         rtc_time64_to_tm(time, &alarm->time);
 141 
 142         return rtc_valid_tm(&alarm->time);
 143 }
 144 
 145 static int ab3100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 146 {
 147         u8 regs[] = {AB3100_AL0, AB3100_AL1, AB3100_AL2, AB3100_AL3};
 148         unsigned char buf[4];
 149         time64_t secs;
 150         u64 hw_counter;
 151         int err;
 152         int i;
 153 
 154         secs = rtc_tm_to_time64(&alarm->time);
 155         hw_counter = secs * AB3100_RTC_CLOCK_RATE * 2;
 156         buf[0] = (hw_counter >> 16) & 0xFF;
 157         buf[1] = (hw_counter >> 24) & 0xFF;
 158         buf[2] = (hw_counter >> 32) & 0xFF;
 159         buf[3] = (hw_counter >> 40) & 0xFF;
 160 
 161         /* Set the alarm */
 162         for (i = 0; i < 4; i++) {
 163                 err = abx500_set_register_interruptible(dev, 0,
 164                                                         regs[i], buf[i]);
 165                 if (err)
 166                         return err;
 167         }
 168         /* Then enable the alarm */
 169         return abx500_mask_and_set_register_interruptible(dev, 0,
 170                                                           AB3100_RTC, (1 << 2),
 171                                                           alarm->enabled << 2);
 172 }
 173 
 174 static int ab3100_rtc_irq_enable(struct device *dev, unsigned int enabled)
 175 {
 176         /*
 177          * It's not possible to enable/disable the alarm IRQ for this RTC.
 178          * It does not actually trigger any IRQ: instead its only function is
 179          * to power up the system, if it wasn't on. This will manifest as
 180          * a "power up cause" in the AB3100 power driver (battery charging etc)
 181          * and need to be handled there instead.
 182          */
 183         if (enabled)
 184                 return abx500_mask_and_set_register_interruptible(dev, 0,
 185                                                     AB3100_RTC, (1 << 2),
 186                                                     1 << 2);
 187         else
 188                 return abx500_mask_and_set_register_interruptible(dev, 0,
 189                                                     AB3100_RTC, (1 << 2),
 190                                                     0);
 191 }
 192 
 193 static const struct rtc_class_ops ab3100_rtc_ops = {
 194         .read_time      = ab3100_rtc_read_time,
 195         .set_time       = ab3100_rtc_set_time,
 196         .read_alarm     = ab3100_rtc_read_alarm,
 197         .set_alarm      = ab3100_rtc_set_alarm,
 198         .alarm_irq_enable = ab3100_rtc_irq_enable,
 199 };
 200 
 201 static int __init ab3100_rtc_probe(struct platform_device *pdev)
 202 {
 203         int err;
 204         u8 regval;
 205         struct rtc_device *rtc;
 206 
 207         /* The first RTC register needs special treatment */
 208         err = abx500_get_register_interruptible(&pdev->dev, 0,
 209                                                 AB3100_RTC, &regval);
 210         if (err) {
 211                 dev_err(&pdev->dev, "unable to read RTC register\n");
 212                 return -ENODEV;
 213         }
 214 
 215         if ((regval & 0xFE) != RTC_SETTING) {
 216                 dev_warn(&pdev->dev, "not default value in RTC reg 0x%x\n",
 217                          regval);
 218         }
 219 
 220         if ((regval & 1) == 0) {
 221                 /*
 222                  * Set bit to detect power loss.
 223                  * This bit remains until RTC power is lost.
 224                  */
 225                 regval = 1 | RTC_SETTING;
 226                 err = abx500_set_register_interruptible(&pdev->dev, 0,
 227                                                         AB3100_RTC, regval);
 228                 /* Ignore any error on this write */
 229         }
 230 
 231         rtc = devm_rtc_allocate_device(&pdev->dev);
 232         if (IS_ERR(rtc))
 233                 return PTR_ERR(rtc);
 234 
 235         rtc->ops = &ab3100_rtc_ops;
 236         /* 48bit counter at (AB3100_RTC_CLOCK_RATE * 2) */
 237         rtc->range_max = U32_MAX;
 238 
 239         platform_set_drvdata(pdev, rtc);
 240 
 241         return rtc_register_device(rtc);
 242 }
 243 
 244 static struct platform_driver ab3100_rtc_driver = {
 245         .driver = {
 246                 .name = "ab3100-rtc",
 247         },
 248 };
 249 
 250 module_platform_driver_probe(ab3100_rtc_driver, ab3100_rtc_probe);
 251 
 252 MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
 253 MODULE_DESCRIPTION("AB3100 RTC Driver");
 254 MODULE_LICENSE("GPL");

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