1/* 2 * rtc-as3722.c - Real Time Clock driver for ams AS3722 PMICs 3 * 4 * Copyright (C) 2013 ams AG 5 * Copyright (c) 2013, NVIDIA Corporation. All rights reserved. 6 * 7 * Author: Florian Lobmaier <florian.lobmaier@ams.com> 8 * Author: Laxman Dewangan <ldewangan@nvidia.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 */ 20 21#include <linux/bcd.h> 22#include <linux/completion.h> 23#include <linux/delay.h> 24#include <linux/interrupt.h> 25#include <linux/ioctl.h> 26#include <linux/kernel.h> 27#include <linux/module.h> 28#include <linux/mfd/as3722.h> 29#include <linux/platform_device.h> 30#include <linux/rtc.h> 31#include <linux/time.h> 32 33#define AS3722_RTC_START_YEAR 2000 34struct as3722_rtc { 35 struct rtc_device *rtc; 36 struct device *dev; 37 struct as3722 *as3722; 38 int alarm_irq; 39 bool irq_enable; 40}; 41 42static void as3722_time_to_reg(u8 *rbuff, struct rtc_time *tm) 43{ 44 rbuff[0] = bin2bcd(tm->tm_sec); 45 rbuff[1] = bin2bcd(tm->tm_min); 46 rbuff[2] = bin2bcd(tm->tm_hour); 47 rbuff[3] = bin2bcd(tm->tm_mday); 48 rbuff[4] = bin2bcd(tm->tm_mon); 49 rbuff[5] = bin2bcd(tm->tm_year - (AS3722_RTC_START_YEAR - 1900)); 50} 51 52static void as3722_reg_to_time(u8 *rbuff, struct rtc_time *tm) 53{ 54 tm->tm_sec = bcd2bin(rbuff[0] & 0x7F); 55 tm->tm_min = bcd2bin(rbuff[1] & 0x7F); 56 tm->tm_hour = bcd2bin(rbuff[2] & 0x3F); 57 tm->tm_mday = bcd2bin(rbuff[3] & 0x3F); 58 tm->tm_mon = bcd2bin(rbuff[4] & 0x1F); 59 tm->tm_year = (AS3722_RTC_START_YEAR - 1900) + bcd2bin(rbuff[5] & 0x7F); 60 return; 61} 62 63static int as3722_rtc_read_time(struct device *dev, struct rtc_time *tm) 64{ 65 struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev); 66 struct as3722 *as3722 = as3722_rtc->as3722; 67 u8 as_time_array[6]; 68 int ret; 69 70 ret = as3722_block_read(as3722, AS3722_RTC_SECOND_REG, 71 6, as_time_array); 72 if (ret < 0) { 73 dev_err(dev, "RTC_SECOND reg block read failed %d\n", ret); 74 return ret; 75 } 76 as3722_reg_to_time(as_time_array, tm); 77 return 0; 78} 79 80static int as3722_rtc_set_time(struct device *dev, struct rtc_time *tm) 81{ 82 struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev); 83 struct as3722 *as3722 = as3722_rtc->as3722; 84 u8 as_time_array[6]; 85 int ret; 86 87 if (tm->tm_year < (AS3722_RTC_START_YEAR - 1900)) 88 return -EINVAL; 89 90 as3722_time_to_reg(as_time_array, tm); 91 ret = as3722_block_write(as3722, AS3722_RTC_SECOND_REG, 6, 92 as_time_array); 93 if (ret < 0) 94 dev_err(dev, "RTC_SECOND reg block write failed %d\n", ret); 95 return ret; 96} 97 98static int as3722_rtc_alarm_irq_enable(struct device *dev, 99 unsigned int enabled) 100{ 101 struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev); 102 103 if (enabled && !as3722_rtc->irq_enable) { 104 enable_irq(as3722_rtc->alarm_irq); 105 as3722_rtc->irq_enable = true; 106 } else if (!enabled && as3722_rtc->irq_enable) { 107 disable_irq(as3722_rtc->alarm_irq); 108 as3722_rtc->irq_enable = false; 109 } 110 return 0; 111} 112 113static int as3722_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 114{ 115 struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev); 116 struct as3722 *as3722 = as3722_rtc->as3722; 117 u8 as_time_array[6]; 118 int ret; 119 120 ret = as3722_block_read(as3722, AS3722_RTC_ALARM_SECOND_REG, 6, 121 as_time_array); 122 if (ret < 0) { 123 dev_err(dev, "RTC_ALARM_SECOND block read failed %d\n", ret); 124 return ret; 125 } 126 127 as3722_reg_to_time(as_time_array, &alrm->time); 128 return 0; 129} 130 131static int as3722_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 132{ 133 struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev); 134 struct as3722 *as3722 = as3722_rtc->as3722; 135 u8 as_time_array[6]; 136 int ret; 137 138 if (alrm->time.tm_year < (AS3722_RTC_START_YEAR - 1900)) 139 return -EINVAL; 140 141 ret = as3722_rtc_alarm_irq_enable(dev, 0); 142 if (ret < 0) { 143 dev_err(dev, "Disable RTC alarm failed\n"); 144 return ret; 145 } 146 147 as3722_time_to_reg(as_time_array, &alrm->time); 148 ret = as3722_block_write(as3722, AS3722_RTC_ALARM_SECOND_REG, 6, 149 as_time_array); 150 if (ret < 0) { 151 dev_err(dev, "RTC_ALARM_SECOND block write failed %d\n", ret); 152 return ret; 153 } 154 155 if (alrm->enabled) 156 ret = as3722_rtc_alarm_irq_enable(dev, alrm->enabled); 157 return ret; 158} 159 160static irqreturn_t as3722_alarm_irq(int irq, void *data) 161{ 162 struct as3722_rtc *as3722_rtc = data; 163 164 rtc_update_irq(as3722_rtc->rtc, 1, RTC_IRQF | RTC_AF); 165 return IRQ_HANDLED; 166} 167 168static const struct rtc_class_ops as3722_rtc_ops = { 169 .read_time = as3722_rtc_read_time, 170 .set_time = as3722_rtc_set_time, 171 .read_alarm = as3722_rtc_read_alarm, 172 .set_alarm = as3722_rtc_set_alarm, 173 .alarm_irq_enable = as3722_rtc_alarm_irq_enable, 174}; 175 176static int as3722_rtc_probe(struct platform_device *pdev) 177{ 178 struct as3722 *as3722 = dev_get_drvdata(pdev->dev.parent); 179 struct as3722_rtc *as3722_rtc; 180 int ret; 181 182 as3722_rtc = devm_kzalloc(&pdev->dev, sizeof(*as3722_rtc), GFP_KERNEL); 183 if (!as3722_rtc) 184 return -ENOMEM; 185 186 as3722_rtc->as3722 = as3722; 187 as3722_rtc->dev = &pdev->dev; 188 platform_set_drvdata(pdev, as3722_rtc); 189 190 /* Enable the RTC to make sure it is running. */ 191 ret = as3722_update_bits(as3722, AS3722_RTC_CONTROL_REG, 192 AS3722_RTC_ON | AS3722_RTC_ALARM_WAKEUP_EN, 193 AS3722_RTC_ON | AS3722_RTC_ALARM_WAKEUP_EN); 194 if (ret < 0) { 195 dev_err(&pdev->dev, "RTC_CONTROL reg write failed: %d\n", ret); 196 return ret; 197 } 198 199 device_init_wakeup(&pdev->dev, 1); 200 201 as3722_rtc->rtc = devm_rtc_device_register(&pdev->dev, "as3722-rtc", 202 &as3722_rtc_ops, THIS_MODULE); 203 if (IS_ERR(as3722_rtc->rtc)) { 204 ret = PTR_ERR(as3722_rtc->rtc); 205 dev_err(&pdev->dev, "RTC register failed: %d\n", ret); 206 return ret; 207 } 208 209 as3722_rtc->alarm_irq = platform_get_irq(pdev, 0); 210 dev_info(&pdev->dev, "RTC interrupt %d\n", as3722_rtc->alarm_irq); 211 212 ret = devm_request_threaded_irq(&pdev->dev, as3722_rtc->alarm_irq, NULL, 213 as3722_alarm_irq, IRQF_ONESHOT | IRQF_EARLY_RESUME, 214 "rtc-alarm", as3722_rtc); 215 if (ret < 0) { 216 dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", 217 as3722_rtc->alarm_irq, ret); 218 return ret; 219 } 220 disable_irq(as3722_rtc->alarm_irq); 221 return 0; 222} 223 224#ifdef CONFIG_PM_SLEEP 225static int as3722_rtc_suspend(struct device *dev) 226{ 227 struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev); 228 229 if (device_may_wakeup(dev)) 230 enable_irq_wake(as3722_rtc->alarm_irq); 231 232 return 0; 233} 234 235static int as3722_rtc_resume(struct device *dev) 236{ 237 struct as3722_rtc *as3722_rtc = dev_get_drvdata(dev); 238 239 if (device_may_wakeup(dev)) 240 disable_irq_wake(as3722_rtc->alarm_irq); 241 return 0; 242} 243#endif 244 245static SIMPLE_DEV_PM_OPS(as3722_rtc_pm_ops, as3722_rtc_suspend, 246 as3722_rtc_resume); 247 248static struct platform_driver as3722_rtc_driver = { 249 .probe = as3722_rtc_probe, 250 .driver = { 251 .name = "as3722-rtc", 252 .pm = &as3722_rtc_pm_ops, 253 }, 254}; 255module_platform_driver(as3722_rtc_driver); 256 257MODULE_DESCRIPTION("RTC driver for AS3722 PMICs"); 258MODULE_ALIAS("platform:as3722-rtc"); 259MODULE_AUTHOR("Florian Lobmaier <florian.lobmaier@ams.com>"); 260MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); 261MODULE_LICENSE("GPL"); 262