1/* 2 * rtc-rc5t583.c -- RICOH RC5T583 Real Time Clock 3 * 4 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. 5 * Author: Venu Byravarasu <vbyravarasu@nvidia.com> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms and conditions of the GNU General Public License, 9 * version 2, as published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 * more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 19#include <linux/kernel.h> 20#include <linux/errno.h> 21#include <linux/init.h> 22#include <linux/module.h> 23#include <linux/types.h> 24#include <linux/rtc.h> 25#include <linux/bcd.h> 26#include <linux/platform_device.h> 27#include <linux/interrupt.h> 28#include <linux/mfd/rc5t583.h> 29 30struct rc5t583_rtc { 31 struct rtc_device *rtc; 32 /* To store the list of enabled interrupts, during system suspend */ 33 u32 irqen; 34}; 35 36/* Total number of RTC registers needed to set time*/ 37#define NUM_TIME_REGS (RC5T583_RTC_YEAR - RC5T583_RTC_SEC + 1) 38 39/* Total number of RTC registers needed to set Y-Alarm*/ 40#define NUM_YAL_REGS (RC5T583_RTC_AY_YEAR - RC5T583_RTC_AY_MIN + 1) 41 42/* Set Y-Alarm interrupt */ 43#define SET_YAL BIT(5) 44 45/* Get Y-Alarm interrupt status*/ 46#define GET_YAL_STATUS BIT(3) 47 48static int rc5t583_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) 49{ 50 struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); 51 u8 val; 52 53 /* Set Y-Alarm, based on 'enabled' */ 54 val = enabled ? SET_YAL : 0; 55 56 return regmap_update_bits(rc5t583->regmap, RC5T583_RTC_CTL1, SET_YAL, 57 val); 58} 59 60/* 61 * Gets current rc5t583 RTC time and date parameters. 62 * 63 * The RTC's time/alarm representation is not what gmtime(3) requires 64 * Linux to use: 65 * 66 * - Months are 1..12 vs Linux 0-11 67 * - Years are 0..99 vs Linux 1900..N (we assume 21st century) 68 */ 69static int rc5t583_rtc_read_time(struct device *dev, struct rtc_time *tm) 70{ 71 struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); 72 u8 rtc_data[NUM_TIME_REGS]; 73 int ret; 74 75 ret = regmap_bulk_read(rc5t583->regmap, RC5T583_RTC_SEC, rtc_data, 76 NUM_TIME_REGS); 77 if (ret < 0) { 78 dev_err(dev, "RTC read time failed with err:%d\n", ret); 79 return ret; 80 } 81 82 tm->tm_sec = bcd2bin(rtc_data[0]); 83 tm->tm_min = bcd2bin(rtc_data[1]); 84 tm->tm_hour = bcd2bin(rtc_data[2]); 85 tm->tm_wday = bcd2bin(rtc_data[3]); 86 tm->tm_mday = bcd2bin(rtc_data[4]); 87 tm->tm_mon = bcd2bin(rtc_data[5]) - 1; 88 tm->tm_year = bcd2bin(rtc_data[6]) + 100; 89 90 return ret; 91} 92 93static int rc5t583_rtc_set_time(struct device *dev, struct rtc_time *tm) 94{ 95 struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); 96 unsigned char rtc_data[NUM_TIME_REGS]; 97 int ret; 98 99 rtc_data[0] = bin2bcd(tm->tm_sec); 100 rtc_data[1] = bin2bcd(tm->tm_min); 101 rtc_data[2] = bin2bcd(tm->tm_hour); 102 rtc_data[3] = bin2bcd(tm->tm_wday); 103 rtc_data[4] = bin2bcd(tm->tm_mday); 104 rtc_data[5] = bin2bcd(tm->tm_mon + 1); 105 rtc_data[6] = bin2bcd(tm->tm_year - 100); 106 107 ret = regmap_bulk_write(rc5t583->regmap, RC5T583_RTC_SEC, rtc_data, 108 NUM_TIME_REGS); 109 if (ret < 0) { 110 dev_err(dev, "RTC set time failed with error %d\n", ret); 111 return ret; 112 } 113 114 return ret; 115} 116 117static int rc5t583_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) 118{ 119 struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); 120 unsigned char alarm_data[NUM_YAL_REGS]; 121 u32 interrupt_enable; 122 int ret; 123 124 ret = regmap_bulk_read(rc5t583->regmap, RC5T583_RTC_AY_MIN, alarm_data, 125 NUM_YAL_REGS); 126 if (ret < 0) { 127 dev_err(dev, "rtc_read_alarm error %d\n", ret); 128 return ret; 129 } 130 131 alm->time.tm_min = bcd2bin(alarm_data[0]); 132 alm->time.tm_hour = bcd2bin(alarm_data[1]); 133 alm->time.tm_mday = bcd2bin(alarm_data[2]); 134 alm->time.tm_mon = bcd2bin(alarm_data[3]) - 1; 135 alm->time.tm_year = bcd2bin(alarm_data[4]) + 100; 136 137 ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL1, &interrupt_enable); 138 if (ret < 0) 139 return ret; 140 141 /* check if YALE is set */ 142 if (interrupt_enable & SET_YAL) 143 alm->enabled = 1; 144 145 return ret; 146} 147 148static int rc5t583_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) 149{ 150 struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); 151 unsigned char alarm_data[NUM_YAL_REGS]; 152 int ret; 153 154 ret = rc5t583_rtc_alarm_irq_enable(dev, 0); 155 if (ret) 156 return ret; 157 158 alarm_data[0] = bin2bcd(alm->time.tm_min); 159 alarm_data[1] = bin2bcd(alm->time.tm_hour); 160 alarm_data[2] = bin2bcd(alm->time.tm_mday); 161 alarm_data[3] = bin2bcd(alm->time.tm_mon + 1); 162 alarm_data[4] = bin2bcd(alm->time.tm_year - 100); 163 164 ret = regmap_bulk_write(rc5t583->regmap, RC5T583_RTC_AY_MIN, alarm_data, 165 NUM_YAL_REGS); 166 if (ret) { 167 dev_err(dev, "rtc_set_alarm error %d\n", ret); 168 return ret; 169 } 170 171 if (alm->enabled) 172 ret = rc5t583_rtc_alarm_irq_enable(dev, 1); 173 174 return ret; 175} 176 177static irqreturn_t rc5t583_rtc_interrupt(int irq, void *rtc) 178{ 179 struct device *dev = rtc; 180 struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); 181 struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev); 182 unsigned long events = 0; 183 int ret; 184 u32 rtc_reg; 185 186 ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL2, &rtc_reg); 187 if (ret < 0) 188 return IRQ_NONE; 189 190 if (rtc_reg & GET_YAL_STATUS) { 191 events = RTC_IRQF | RTC_AF; 192 /* clear pending Y-alarm interrupt bit */ 193 rtc_reg &= ~GET_YAL_STATUS; 194 } 195 196 ret = regmap_write(rc5t583->regmap, RC5T583_RTC_CTL2, rtc_reg); 197 if (ret) 198 return IRQ_NONE; 199 200 /* Notify RTC core on event */ 201 rtc_update_irq(rc5t583_rtc->rtc, 1, events); 202 203 return IRQ_HANDLED; 204} 205 206static const struct rtc_class_ops rc5t583_rtc_ops = { 207 .read_time = rc5t583_rtc_read_time, 208 .set_time = rc5t583_rtc_set_time, 209 .read_alarm = rc5t583_rtc_read_alarm, 210 .set_alarm = rc5t583_rtc_set_alarm, 211 .alarm_irq_enable = rc5t583_rtc_alarm_irq_enable, 212}; 213 214static int rc5t583_rtc_probe(struct platform_device *pdev) 215{ 216 struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); 217 struct rc5t583_rtc *ricoh_rtc; 218 struct rc5t583_platform_data *pmic_plat_data; 219 int ret; 220 int irq; 221 222 ricoh_rtc = devm_kzalloc(&pdev->dev, sizeof(struct rc5t583_rtc), 223 GFP_KERNEL); 224 if (!ricoh_rtc) 225 return -ENOMEM; 226 227 platform_set_drvdata(pdev, ricoh_rtc); 228 229 /* Clear pending interrupts */ 230 ret = regmap_write(rc5t583->regmap, RC5T583_RTC_CTL2, 0); 231 if (ret < 0) 232 return ret; 233 234 /* clear RTC Adjust register */ 235 ret = regmap_write(rc5t583->regmap, RC5T583_RTC_ADJ, 0); 236 if (ret < 0) { 237 dev_err(&pdev->dev, "unable to program rtc_adjust reg\n"); 238 return -EBUSY; 239 } 240 241 pmic_plat_data = dev_get_platdata(rc5t583->dev); 242 irq = pmic_plat_data->irq_base; 243 if (irq <= 0) { 244 dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n", 245 irq); 246 return ret; 247 } 248 249 irq += RC5T583_IRQ_YALE; 250 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, 251 rc5t583_rtc_interrupt, IRQF_TRIGGER_LOW, 252 "rtc-rc5t583", &pdev->dev); 253 if (ret < 0) { 254 dev_err(&pdev->dev, "IRQ is not free.\n"); 255 return ret; 256 } 257 device_init_wakeup(&pdev->dev, 1); 258 259 ricoh_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, 260 &rc5t583_rtc_ops, THIS_MODULE); 261 if (IS_ERR(ricoh_rtc->rtc)) { 262 ret = PTR_ERR(ricoh_rtc->rtc); 263 dev_err(&pdev->dev, "RTC device register: err %d\n", ret); 264 return ret; 265 } 266 267 return 0; 268} 269 270/* 271 * Disable rc5t583 RTC interrupts. 272 * Sets status flag to free. 273 */ 274static int rc5t583_rtc_remove(struct platform_device *pdev) 275{ 276 struct rc5t583_rtc *rc5t583_rtc = platform_get_drvdata(pdev); 277 278 rc5t583_rtc_alarm_irq_enable(&rc5t583_rtc->rtc->dev, 0); 279 return 0; 280} 281 282#ifdef CONFIG_PM_SLEEP 283static int rc5t583_rtc_suspend(struct device *dev) 284{ 285 struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); 286 struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev); 287 int ret; 288 289 /* Store current list of enabled interrupts*/ 290 ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL1, 291 &rc5t583_rtc->irqen); 292 return ret; 293} 294 295static int rc5t583_rtc_resume(struct device *dev) 296{ 297 struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); 298 struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev); 299 300 /* Restore list of enabled interrupts before suspend */ 301 return regmap_write(rc5t583->regmap, RC5T583_RTC_CTL1, 302 rc5t583_rtc->irqen); 303} 304#endif 305 306static SIMPLE_DEV_PM_OPS(rc5t583_rtc_pm_ops, rc5t583_rtc_suspend, 307 rc5t583_rtc_resume); 308 309static struct platform_driver rc5t583_rtc_driver = { 310 .probe = rc5t583_rtc_probe, 311 .remove = rc5t583_rtc_remove, 312 .driver = { 313 .name = "rtc-rc5t583", 314 .pm = &rc5t583_rtc_pm_ops, 315 }, 316}; 317 318module_platform_driver(rc5t583_rtc_driver); 319MODULE_ALIAS("platform:rtc-rc5t583"); 320MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>"); 321MODULE_LICENSE("GPL v2"); 322