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 30 struct 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 48 static 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 */ 69 static 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 93 static 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 117 static 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_sec = 0; 132 alm->time.tm_min = bcd2bin(alarm_data[0]); 133 alm->time.tm_hour = bcd2bin(alarm_data[1]); 134 alm->time.tm_mday = bcd2bin(alarm_data[2]); 135 alm->time.tm_mon = bcd2bin(alarm_data[3]) - 1; 136 alm->time.tm_year = bcd2bin(alarm_data[4]) + 100; 137 138 ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL1, &interrupt_enable); 139 if (ret < 0) 140 return ret; 141 142 /* check if YALE is set */ 143 if (interrupt_enable & SET_YAL) 144 alm->enabled = 1; 145 146 return ret; 147 } 148 149 static int rc5t583_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) 150 { 151 struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); 152 unsigned char alarm_data[NUM_YAL_REGS]; 153 int ret; 154 155 ret = rc5t583_rtc_alarm_irq_enable(dev, 0); 156 if (ret) 157 return ret; 158 159 alarm_data[0] = bin2bcd(alm->time.tm_min); 160 alarm_data[1] = bin2bcd(alm->time.tm_hour); 161 alarm_data[2] = bin2bcd(alm->time.tm_mday); 162 alarm_data[3] = bin2bcd(alm->time.tm_mon + 1); 163 alarm_data[4] = bin2bcd(alm->time.tm_year - 100); 164 165 ret = regmap_bulk_write(rc5t583->regmap, RC5T583_RTC_AY_MIN, alarm_data, 166 NUM_YAL_REGS); 167 if (ret) { 168 dev_err(dev, "rtc_set_alarm error %d\n", ret); 169 return ret; 170 } 171 172 if (alm->enabled) 173 ret = rc5t583_rtc_alarm_irq_enable(dev, 1); 174 175 return ret; 176 } 177 178 static irqreturn_t rc5t583_rtc_interrupt(int irq, void *rtc) 179 { 180 struct device *dev = rtc; 181 struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); 182 struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev); 183 unsigned long events = 0; 184 int ret; 185 u32 rtc_reg; 186 187 ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL2, &rtc_reg); 188 if (ret < 0) 189 return IRQ_NONE; 190 191 if (rtc_reg & GET_YAL_STATUS) { 192 events = RTC_IRQF | RTC_AF; 193 /* clear pending Y-alarm interrupt bit */ 194 rtc_reg &= ~GET_YAL_STATUS; 195 } 196 197 ret = regmap_write(rc5t583->regmap, RC5T583_RTC_CTL2, rtc_reg); 198 if (ret) 199 return IRQ_NONE; 200 201 /* Notify RTC core on event */ 202 rtc_update_irq(rc5t583_rtc->rtc, 1, events); 203 204 return IRQ_HANDLED; 205 } 206 207 static const struct rtc_class_ops rc5t583_rtc_ops = { 208 .read_time = rc5t583_rtc_read_time, 209 .set_time = rc5t583_rtc_set_time, 210 .read_alarm = rc5t583_rtc_read_alarm, 211 .set_alarm = rc5t583_rtc_set_alarm, 212 .alarm_irq_enable = rc5t583_rtc_alarm_irq_enable, 213 }; 214 215 static int rc5t583_rtc_probe(struct platform_device *pdev) 216 { 217 struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); 218 struct rc5t583_rtc *ricoh_rtc; 219 struct rc5t583_platform_data *pmic_plat_data; 220 int ret; 221 int irq; 222 223 ricoh_rtc = devm_kzalloc(&pdev->dev, sizeof(struct rc5t583_rtc), 224 GFP_KERNEL); 225 if (!ricoh_rtc) 226 return -ENOMEM; 227 228 platform_set_drvdata(pdev, ricoh_rtc); 229 230 /* Clear pending interrupts */ 231 ret = regmap_write(rc5t583->regmap, RC5T583_RTC_CTL2, 0); 232 if (ret < 0) 233 return ret; 234 235 /* clear RTC Adjust register */ 236 ret = regmap_write(rc5t583->regmap, RC5T583_RTC_ADJ, 0); 237 if (ret < 0) { 238 dev_err(&pdev->dev, "unable to program rtc_adjust reg\n"); 239 return -EBUSY; 240 } 241 242 pmic_plat_data = dev_get_platdata(rc5t583->dev); 243 irq = pmic_plat_data->irq_base; 244 if (irq <= 0) { 245 dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n", 246 irq); 247 return ret; 248 } 249 250 irq += RC5T583_IRQ_YALE; 251 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, 252 rc5t583_rtc_interrupt, IRQF_TRIGGER_LOW, 253 "rtc-rc5t583", &pdev->dev); 254 if (ret < 0) { 255 dev_err(&pdev->dev, "IRQ is not free.\n"); 256 return ret; 257 } 258 device_init_wakeup(&pdev->dev, 1); 259 260 ricoh_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, 261 &rc5t583_rtc_ops, THIS_MODULE); 262 if (IS_ERR(ricoh_rtc->rtc)) { 263 ret = PTR_ERR(ricoh_rtc->rtc); 264 dev_err(&pdev->dev, "RTC device register: err %d\n", ret); 265 return ret; 266 } 267 268 return 0; 269 } 270 271 /* 272 * Disable rc5t583 RTC interrupts. 273 * Sets status flag to free. 274 */ 275 static int rc5t583_rtc_remove(struct platform_device *pdev) 276 { 277 struct rc5t583_rtc *rc5t583_rtc = platform_get_drvdata(pdev); 278 279 rc5t583_rtc_alarm_irq_enable(&rc5t583_rtc->rtc->dev, 0); 280 return 0; 281 } 282 283 #ifdef CONFIG_PM_SLEEP 284 static int rc5t583_rtc_suspend(struct device *dev) 285 { 286 struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); 287 struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev); 288 int ret; 289 290 /* Store current list of enabled interrupts*/ 291 ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL1, 292 &rc5t583_rtc->irqen); 293 return ret; 294 } 295 296 static int rc5t583_rtc_resume(struct device *dev) 297 { 298 struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); 299 struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev); 300 301 /* Restore list of enabled interrupts before suspend */ 302 return regmap_write(rc5t583->regmap, RC5T583_RTC_CTL1, 303 rc5t583_rtc->irqen); 304 } 305 #endif 306 307 static SIMPLE_DEV_PM_OPS(rc5t583_rtc_pm_ops, rc5t583_rtc_suspend, 308 rc5t583_rtc_resume); 309 310 static struct platform_driver rc5t583_rtc_driver = { 311 .probe = rc5t583_rtc_probe, 312 .remove = rc5t583_rtc_remove, 313 .driver = { 314 .name = "rtc-rc5t583", 315 .pm = &rc5t583_rtc_pm_ops, 316 }, 317 }; 318 319 module_platform_driver(rc5t583_rtc_driver); 320 MODULE_ALIAS("platform:rtc-rc5t583"); 321 MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>"); 322 MODULE_LICENSE("GPL v2"); 323