1 /* 2 * RTC driver for Maxim MAX8925 3 * 4 * Copyright (C) 2009-2010 Marvell International Ltd. 5 * Haojian Zhuang <haojian.zhuang@marvell.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 12 #include <linux/module.h> 13 #include <linux/i2c.h> 14 #include <linux/slab.h> 15 #include <linux/rtc.h> 16 #include <linux/platform_device.h> 17 #include <linux/mfd/max8925.h> 18 19 enum { 20 RTC_SEC = 0, 21 RTC_MIN, 22 RTC_HOUR, 23 RTC_WEEKDAY, 24 RTC_DATE, 25 RTC_MONTH, 26 RTC_YEAR1, 27 RTC_YEAR2, 28 }; 29 30 #define MAX8925_RTC_SEC 0x00 31 #define MAX8925_RTC_MIN 0x01 32 #define MAX8925_RTC_HOUR 0x02 33 #define MAX8925_RTC_WEEKDAY 0x03 34 #define MAX8925_RTC_DATE 0x04 35 #define MAX8925_RTC_MONTH 0x05 36 #define MAX8925_RTC_YEAR1 0x06 37 #define MAX8925_RTC_YEAR2 0x07 38 #define MAX8925_ALARM0_SEC 0x08 39 #define MAX8925_ALARM0_MIN 0x09 40 #define MAX8925_ALARM0_HOUR 0x0a 41 #define MAX8925_ALARM0_WEEKDAY 0x0b 42 #define MAX8925_ALARM0_DATE 0x0c 43 #define MAX8925_ALARM0_MON 0x0d 44 #define MAX8925_ALARM0_YEAR1 0x0e 45 #define MAX8925_ALARM0_YEAR2 0x0f 46 #define MAX8925_ALARM1_SEC 0x10 47 #define MAX8925_ALARM1_MIN 0x11 48 #define MAX8925_ALARM1_HOUR 0x12 49 #define MAX8925_ALARM1_WEEKDAY 0x13 50 #define MAX8925_ALARM1_DATE 0x14 51 #define MAX8925_ALARM1_MON 0x15 52 #define MAX8925_ALARM1_YEAR1 0x16 53 #define MAX8925_ALARM1_YEAR2 0x17 54 #define MAX8925_RTC_CNTL 0x1b 55 #define MAX8925_RTC_STATUS 0x20 56 57 #define TIME_NUM 8 58 #define ALARM_1SEC (1 << 7) 59 #define HOUR_12 (1 << 7) 60 #define HOUR_AM_PM (1 << 5) 61 #define ALARM0_IRQ (1 << 3) 62 #define ALARM1_IRQ (1 << 2) 63 #define ALARM0_STATUS (1 << 2) 64 #define ALARM1_STATUS (1 << 1) 65 66 67 struct max8925_rtc_info { 68 struct rtc_device *rtc_dev; 69 struct max8925_chip *chip; 70 struct i2c_client *rtc; 71 struct device *dev; 72 int irq; 73 }; 74 75 static irqreturn_t rtc_update_handler(int irq, void *data) 76 { 77 struct max8925_rtc_info *info = (struct max8925_rtc_info *)data; 78 79 /* disable ALARM0 except for 1SEC alarm */ 80 max8925_set_bits(info->rtc, MAX8925_ALARM0_CNTL, 0x7f, 0); 81 rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF); 82 return IRQ_HANDLED; 83 } 84 85 static int tm_calc(struct rtc_time *tm, unsigned char *buf, int len) 86 { 87 if (len < TIME_NUM) 88 return -EINVAL; 89 tm->tm_year = (buf[RTC_YEAR2] >> 4) * 1000 90 + (buf[RTC_YEAR2] & 0xf) * 100 91 + (buf[RTC_YEAR1] >> 4) * 10 92 + (buf[RTC_YEAR1] & 0xf); 93 tm->tm_year -= 1900; 94 tm->tm_mon = ((buf[RTC_MONTH] >> 4) & 0x01) * 10 95 + (buf[RTC_MONTH] & 0x0f); 96 tm->tm_mday = ((buf[RTC_DATE] >> 4) & 0x03) * 10 97 + (buf[RTC_DATE] & 0x0f); 98 tm->tm_wday = buf[RTC_WEEKDAY] & 0x07; 99 if (buf[RTC_HOUR] & HOUR_12) { 100 tm->tm_hour = ((buf[RTC_HOUR] >> 4) & 0x1) * 10 101 + (buf[RTC_HOUR] & 0x0f); 102 if (buf[RTC_HOUR] & HOUR_AM_PM) 103 tm->tm_hour += 12; 104 } else 105 tm->tm_hour = ((buf[RTC_HOUR] >> 4) & 0x03) * 10 106 + (buf[RTC_HOUR] & 0x0f); 107 tm->tm_min = ((buf[RTC_MIN] >> 4) & 0x7) * 10 108 + (buf[RTC_MIN] & 0x0f); 109 tm->tm_sec = ((buf[RTC_SEC] >> 4) & 0x7) * 10 110 + (buf[RTC_SEC] & 0x0f); 111 return 0; 112 } 113 114 static int data_calc(unsigned char *buf, struct rtc_time *tm, int len) 115 { 116 unsigned char high, low; 117 118 if (len < TIME_NUM) 119 return -EINVAL; 120 121 high = (tm->tm_year + 1900) / 1000; 122 low = (tm->tm_year + 1900) / 100; 123 low = low - high * 10; 124 buf[RTC_YEAR2] = (high << 4) + low; 125 high = (tm->tm_year + 1900) / 10; 126 low = tm->tm_year + 1900; 127 low = low - high * 10; 128 high = high - (high / 10) * 10; 129 buf[RTC_YEAR1] = (high << 4) + low; 130 high = tm->tm_mon / 10; 131 low = tm->tm_mon; 132 low = low - high * 10; 133 buf[RTC_MONTH] = (high << 4) + low; 134 high = tm->tm_mday / 10; 135 low = tm->tm_mday; 136 low = low - high * 10; 137 buf[RTC_DATE] = (high << 4) + low; 138 buf[RTC_WEEKDAY] = tm->tm_wday; 139 high = tm->tm_hour / 10; 140 low = tm->tm_hour; 141 low = low - high * 10; 142 buf[RTC_HOUR] = (high << 4) + low; 143 high = tm->tm_min / 10; 144 low = tm->tm_min; 145 low = low - high * 10; 146 buf[RTC_MIN] = (high << 4) + low; 147 high = tm->tm_sec / 10; 148 low = tm->tm_sec; 149 low = low - high * 10; 150 buf[RTC_SEC] = (high << 4) + low; 151 return 0; 152 } 153 154 static int max8925_rtc_read_time(struct device *dev, struct rtc_time *tm) 155 { 156 struct max8925_rtc_info *info = dev_get_drvdata(dev); 157 unsigned char buf[TIME_NUM]; 158 int ret; 159 160 ret = max8925_bulk_read(info->rtc, MAX8925_RTC_SEC, TIME_NUM, buf); 161 if (ret < 0) 162 goto out; 163 ret = tm_calc(tm, buf, TIME_NUM); 164 out: 165 return ret; 166 } 167 168 static int max8925_rtc_set_time(struct device *dev, struct rtc_time *tm) 169 { 170 struct max8925_rtc_info *info = dev_get_drvdata(dev); 171 unsigned char buf[TIME_NUM]; 172 int ret; 173 174 ret = data_calc(buf, tm, TIME_NUM); 175 if (ret < 0) 176 goto out; 177 ret = max8925_bulk_write(info->rtc, MAX8925_RTC_SEC, TIME_NUM, buf); 178 out: 179 return ret; 180 } 181 182 static int max8925_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 183 { 184 struct max8925_rtc_info *info = dev_get_drvdata(dev); 185 unsigned char buf[TIME_NUM]; 186 int ret; 187 188 ret = max8925_bulk_read(info->rtc, MAX8925_ALARM0_SEC, TIME_NUM, buf); 189 if (ret < 0) 190 goto out; 191 ret = tm_calc(&alrm->time, buf, TIME_NUM); 192 if (ret < 0) 193 goto out; 194 ret = max8925_reg_read(info->rtc, MAX8925_RTC_IRQ_MASK); 195 if (ret < 0) 196 goto out; 197 if (ret & ALARM0_IRQ) { 198 alrm->enabled = 0; 199 } else { 200 ret = max8925_reg_read(info->rtc, MAX8925_ALARM0_CNTL); 201 if (ret < 0) 202 goto out; 203 if (!ret) 204 alrm->enabled = 0; 205 else 206 alrm->enabled = 1; 207 } 208 ret = max8925_reg_read(info->rtc, MAX8925_RTC_STATUS); 209 if (ret < 0) 210 goto out; 211 if (ret & ALARM0_STATUS) 212 alrm->pending = 1; 213 else 214 alrm->pending = 0; 215 return 0; 216 out: 217 return ret; 218 } 219 220 static int max8925_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 221 { 222 struct max8925_rtc_info *info = dev_get_drvdata(dev); 223 unsigned char buf[TIME_NUM]; 224 int ret; 225 226 ret = data_calc(buf, &alrm->time, TIME_NUM); 227 if (ret < 0) 228 goto out; 229 ret = max8925_bulk_write(info->rtc, MAX8925_ALARM0_SEC, TIME_NUM, buf); 230 if (ret < 0) 231 goto out; 232 if (alrm->enabled) 233 /* only enable alarm on year/month/day/hour/min/sec */ 234 ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x77); 235 else 236 ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x0); 237 out: 238 return ret; 239 } 240 241 static const struct rtc_class_ops max8925_rtc_ops = { 242 .read_time = max8925_rtc_read_time, 243 .set_time = max8925_rtc_set_time, 244 .read_alarm = max8925_rtc_read_alarm, 245 .set_alarm = max8925_rtc_set_alarm, 246 }; 247 248 static int max8925_rtc_probe(struct platform_device *pdev) 249 { 250 struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); 251 struct max8925_rtc_info *info; 252 int ret; 253 254 info = devm_kzalloc(&pdev->dev, sizeof(struct max8925_rtc_info), 255 GFP_KERNEL); 256 if (!info) 257 return -ENOMEM; 258 info->chip = chip; 259 info->rtc = chip->rtc; 260 info->dev = &pdev->dev; 261 info->irq = platform_get_irq(pdev, 0); 262 263 ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, 264 rtc_update_handler, IRQF_ONESHOT, 265 "rtc-alarm0", info); 266 if (ret < 0) { 267 dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", 268 info->irq, ret); 269 return ret; 270 } 271 272 dev_set_drvdata(&pdev->dev, info); 273 /* XXX - isn't this redundant? */ 274 platform_set_drvdata(pdev, info); 275 276 device_init_wakeup(&pdev->dev, 1); 277 278 info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max8925-rtc", 279 &max8925_rtc_ops, THIS_MODULE); 280 ret = PTR_ERR(info->rtc_dev); 281 if (IS_ERR(info->rtc_dev)) { 282 dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); 283 return ret; 284 } 285 286 return 0; 287 } 288 289 #ifdef CONFIG_PM_SLEEP 290 static int max8925_rtc_suspend(struct device *dev) 291 { 292 struct platform_device *pdev = to_platform_device(dev); 293 struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); 294 295 if (device_may_wakeup(dev)) 296 chip->wakeup_flag |= 1 << MAX8925_IRQ_RTC_ALARM0; 297 return 0; 298 } 299 static int max8925_rtc_resume(struct device *dev) 300 { 301 struct platform_device *pdev = to_platform_device(dev); 302 struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); 303 304 if (device_may_wakeup(dev)) 305 chip->wakeup_flag &= ~(1 << MAX8925_IRQ_RTC_ALARM0); 306 return 0; 307 } 308 #endif 309 310 static SIMPLE_DEV_PM_OPS(max8925_rtc_pm_ops, max8925_rtc_suspend, max8925_rtc_resume); 311 312 static struct platform_driver max8925_rtc_driver = { 313 .driver = { 314 .name = "max8925-rtc", 315 .pm = &max8925_rtc_pm_ops, 316 }, 317 .probe = max8925_rtc_probe, 318 }; 319 320 module_platform_driver(max8925_rtc_driver); 321 322 MODULE_DESCRIPTION("Maxim MAX8925 RTC driver"); 323 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 324 MODULE_LICENSE("GPL"); 325 326