rtc-max8907.c (5180B)
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 20enum { 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 40struct max8907_rtc { 41 struct max8907 *max8907; 42 struct regmap *regmap; 43 struct rtc_device *rtc_dev; 44 int irq; 45}; 46 47static 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 58static 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 78static 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 94static 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 110static 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 121static 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 144static 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 168static 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 175static 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 212static struct platform_driver max8907_rtc_driver = { 213 .driver = { 214 .name = "max8907-rtc", 215 }, 216 .probe = max8907_rtc_probe, 217}; 218module_platform_driver(max8907_rtc_driver); 219 220MODULE_DESCRIPTION("Maxim MAX8907 RTC driver"); 221MODULE_LICENSE("GPL v2");