root/drivers/rtc/rtc-max8907.c

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

DEFINITIONS

This source file includes following definitions.
  1. max8907_irq_handler
  2. regs_to_tm
  3. tm_to_regs
  4. max8907_rtc_read_time
  5. max8907_rtc_set_time
  6. max8907_rtc_read_alarm
  7. max8907_rtc_set_alarm
  8. max8907_rtc_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * RTC driver for Maxim MAX8907
   4  *
   5  * Copyright (c) 2011-2012, NVIDIA Corporation.
   6  *
   7  * Based on drivers/rtc/rtc-max8925.c,
   8  * Copyright (C) 2009-2010 Marvell International Ltd.
   9  */
  10 
  11 #include <linux/bcd.h>
  12 #include <linux/i2c.h>
  13 #include <linux/mfd/max8907.h>
  14 #include <linux/module.h>
  15 #include <linux/platform_device.h>
  16 #include <linux/regmap.h>
  17 #include <linux/rtc.h>
  18 #include <linux/slab.h>
  19 
  20 enum {
  21         RTC_SEC = 0,
  22         RTC_MIN,
  23         RTC_HOUR,
  24         RTC_WEEKDAY,
  25         RTC_DATE,
  26         RTC_MONTH,
  27         RTC_YEAR1,
  28         RTC_YEAR2,
  29 };
  30 
  31 #define TIME_NUM                        8
  32 #define ALARM_1SEC                      (1 << 7)
  33 #define HOUR_12                         (1 << 7)
  34 #define HOUR_AM_PM                      (1 << 5)
  35 #define ALARM0_IRQ                      (1 << 3)
  36 #define ALARM1_IRQ                      (1 << 2)
  37 #define ALARM0_STATUS                   (1 << 2)
  38 #define ALARM1_STATUS                   (1 << 1)
  39 
  40 struct max8907_rtc {
  41         struct max8907          *max8907;
  42         struct regmap           *regmap;
  43         struct rtc_device       *rtc_dev;
  44         int                     irq;
  45 };
  46 
  47 static irqreturn_t max8907_irq_handler(int irq, void *data)
  48 {
  49         struct max8907_rtc *rtc = data;
  50 
  51         regmap_write(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0);
  52 
  53         rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
  54 
  55         return IRQ_HANDLED;
  56 }
  57 
  58 static void regs_to_tm(u8 *regs, struct rtc_time *tm)
  59 {
  60         tm->tm_year = bcd2bin(regs[RTC_YEAR2]) * 100 +
  61                 bcd2bin(regs[RTC_YEAR1]) - 1900;
  62         tm->tm_mon = bcd2bin(regs[RTC_MONTH] & 0x1f) - 1;
  63         tm->tm_mday = bcd2bin(regs[RTC_DATE] & 0x3f);
  64         tm->tm_wday = (regs[RTC_WEEKDAY] & 0x07);
  65         if (regs[RTC_HOUR] & HOUR_12) {
  66                 tm->tm_hour = bcd2bin(regs[RTC_HOUR] & 0x01f);
  67                 if (tm->tm_hour == 12)
  68                         tm->tm_hour = 0;
  69                 if (regs[RTC_HOUR] & HOUR_AM_PM)
  70                         tm->tm_hour += 12;
  71         } else {
  72                 tm->tm_hour = bcd2bin(regs[RTC_HOUR] & 0x03f);
  73         }
  74         tm->tm_min = bcd2bin(regs[RTC_MIN] & 0x7f);
  75         tm->tm_sec = bcd2bin(regs[RTC_SEC] & 0x7f);
  76 }
  77 
  78 static void tm_to_regs(struct rtc_time *tm, u8 *regs)
  79 {
  80         u8 high, low;
  81 
  82         high = (tm->tm_year + 1900) / 100;
  83         low = tm->tm_year % 100;
  84         regs[RTC_YEAR2] = bin2bcd(high);
  85         regs[RTC_YEAR1] = bin2bcd(low);
  86         regs[RTC_MONTH] = bin2bcd(tm->tm_mon + 1);
  87         regs[RTC_DATE] = bin2bcd(tm->tm_mday);
  88         regs[RTC_WEEKDAY] = tm->tm_wday;
  89         regs[RTC_HOUR] = bin2bcd(tm->tm_hour);
  90         regs[RTC_MIN] = bin2bcd(tm->tm_min);
  91         regs[RTC_SEC] = bin2bcd(tm->tm_sec);
  92 }
  93 
  94 static int max8907_rtc_read_time(struct device *dev, struct rtc_time *tm)
  95 {
  96         struct max8907_rtc *rtc = dev_get_drvdata(dev);
  97         u8 regs[TIME_NUM];
  98         int ret;
  99 
 100         ret = regmap_bulk_read(rtc->regmap, MAX8907_REG_RTC_SEC, regs,
 101                                TIME_NUM);
 102         if (ret < 0)
 103                 return ret;
 104 
 105         regs_to_tm(regs, tm);
 106 
 107         return 0;
 108 }
 109 
 110 static int max8907_rtc_set_time(struct device *dev, struct rtc_time *tm)
 111 {
 112         struct max8907_rtc *rtc = dev_get_drvdata(dev);
 113         u8 regs[TIME_NUM];
 114 
 115         tm_to_regs(tm, regs);
 116 
 117         return regmap_bulk_write(rtc->regmap, MAX8907_REG_RTC_SEC, regs,
 118                                  TIME_NUM);
 119 }
 120 
 121 static int max8907_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 122 {
 123         struct max8907_rtc *rtc = dev_get_drvdata(dev);
 124         u8 regs[TIME_NUM];
 125         unsigned int val;
 126         int ret;
 127 
 128         ret = regmap_bulk_read(rtc->regmap, MAX8907_REG_ALARM0_SEC, regs,
 129                                TIME_NUM);
 130         if (ret < 0)
 131                 return ret;
 132 
 133         regs_to_tm(regs, &alrm->time);
 134 
 135         ret = regmap_read(rtc->regmap, MAX8907_REG_ALARM0_CNTL, &val);
 136         if (ret < 0)
 137                 return ret;
 138 
 139         alrm->enabled = !!(val & 0x7f);
 140 
 141         return 0;
 142 }
 143 
 144 static int max8907_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 145 {
 146         struct max8907_rtc *rtc = dev_get_drvdata(dev);
 147         u8 regs[TIME_NUM];
 148         int ret;
 149 
 150         tm_to_regs(&alrm->time, regs);
 151 
 152         /* Disable alarm while we update the target time */
 153         ret = regmap_write(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0);
 154         if (ret < 0)
 155                 return ret;
 156 
 157         ret = regmap_bulk_write(rtc->regmap, MAX8907_REG_ALARM0_SEC, regs,
 158                                 TIME_NUM);
 159         if (ret < 0)
 160                 return ret;
 161 
 162         if (alrm->enabled)
 163                 ret = regmap_write(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0x77);
 164 
 165         return ret;
 166 }
 167 
 168 static const struct rtc_class_ops max8907_rtc_ops = {
 169         .read_time      = max8907_rtc_read_time,
 170         .set_time       = max8907_rtc_set_time,
 171         .read_alarm     = max8907_rtc_read_alarm,
 172         .set_alarm      = max8907_rtc_set_alarm,
 173 };
 174 
 175 static int max8907_rtc_probe(struct platform_device *pdev)
 176 {
 177         struct max8907 *max8907 = dev_get_drvdata(pdev->dev.parent);
 178         struct max8907_rtc *rtc;
 179         int ret;
 180 
 181         rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
 182         if (!rtc)
 183                 return -ENOMEM;
 184         platform_set_drvdata(pdev, rtc);
 185 
 186         rtc->max8907 = max8907;
 187         rtc->regmap = max8907->regmap_rtc;
 188 
 189         rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, "max8907-rtc",
 190                                         &max8907_rtc_ops, THIS_MODULE);
 191         if (IS_ERR(rtc->rtc_dev)) {
 192                 ret = PTR_ERR(rtc->rtc_dev);
 193                 dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
 194                 return ret;
 195         }
 196 
 197         rtc->irq = regmap_irq_get_virq(max8907->irqc_rtc,
 198                                        MAX8907_IRQ_RTC_ALARM0);
 199         if (rtc->irq < 0)
 200                 return rtc->irq;
 201 
 202         ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
 203                                 max8907_irq_handler,
 204                                 IRQF_ONESHOT, "max8907-alarm0", rtc);
 205         if (ret < 0)
 206                 dev_err(&pdev->dev, "Failed to request IRQ%d: %d\n",
 207                         rtc->irq, ret);
 208 
 209         return ret;
 210 }
 211 
 212 static struct platform_driver max8907_rtc_driver = {
 213         .driver = {
 214                 .name = "max8907-rtc",
 215         },
 216         .probe = max8907_rtc_probe,
 217 };
 218 module_platform_driver(max8907_rtc_driver);
 219 
 220 MODULE_DESCRIPTION("Maxim MAX8907 RTC driver");
 221 MODULE_LICENSE("GPL v2");

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