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