1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * rtc-palmas.c -- Palmas Real Time Clock driver. 4 5 * RTC driver for TI Palma series devices like TPS65913, 6 * TPS65914 power management IC. 7 * 8 * Copyright (c) 2012, NVIDIA Corporation. 9 * 10 * Author: Laxman Dewangan <ldewangan@nvidia.com> 11 */ 12 13 #include <linux/bcd.h> 14 #include <linux/errno.h> 15 #include <linux/init.h> 16 #include <linux/interrupt.h> 17 #include <linux/kernel.h> 18 #include <linux/mfd/palmas.h> 19 #include <linux/module.h> 20 #include <linux/of.h> 21 #include <linux/rtc.h> 22 #include <linux/types.h> 23 #include <linux/platform_device.h> 24 #include <linux/pm.h> 25 26 struct palmas_rtc { 27 struct rtc_device *rtc; 28 struct device *dev; 29 unsigned int irq; 30 }; 31 32 /* Total number of RTC registers needed to set time*/ 33 #define PALMAS_NUM_TIME_REGS (PALMAS_YEARS_REG - PALMAS_SECONDS_REG + 1) 34 35 static int palmas_rtc_read_time(struct device *dev, struct rtc_time *tm) 36 { 37 unsigned char rtc_data[PALMAS_NUM_TIME_REGS]; 38 struct palmas *palmas = dev_get_drvdata(dev->parent); 39 int ret; 40 41 /* Copy RTC counting registers to static registers or latches */ 42 ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG, 43 PALMAS_RTC_CTRL_REG_GET_TIME, PALMAS_RTC_CTRL_REG_GET_TIME); 44 if (ret < 0) { 45 dev_err(dev, "RTC CTRL reg update failed, err: %d\n", ret); 46 return ret; 47 } 48 49 ret = palmas_bulk_read(palmas, PALMAS_RTC_BASE, PALMAS_SECONDS_REG, 50 rtc_data, PALMAS_NUM_TIME_REGS); 51 if (ret < 0) { 52 dev_err(dev, "RTC_SECONDS reg read failed, err = %d\n", ret); 53 return ret; 54 } 55 56 tm->tm_sec = bcd2bin(rtc_data[0]); 57 tm->tm_min = bcd2bin(rtc_data[1]); 58 tm->tm_hour = bcd2bin(rtc_data[2]); 59 tm->tm_mday = bcd2bin(rtc_data[3]); 60 tm->tm_mon = bcd2bin(rtc_data[4]) - 1; 61 tm->tm_year = bcd2bin(rtc_data[5]) + 100; 62 63 return ret; 64 } 65 66 static int palmas_rtc_set_time(struct device *dev, struct rtc_time *tm) 67 { 68 unsigned char rtc_data[PALMAS_NUM_TIME_REGS]; 69 struct palmas *palmas = dev_get_drvdata(dev->parent); 70 int ret; 71 72 rtc_data[0] = bin2bcd(tm->tm_sec); 73 rtc_data[1] = bin2bcd(tm->tm_min); 74 rtc_data[2] = bin2bcd(tm->tm_hour); 75 rtc_data[3] = bin2bcd(tm->tm_mday); 76 rtc_data[4] = bin2bcd(tm->tm_mon + 1); 77 rtc_data[5] = bin2bcd(tm->tm_year - 100); 78 79 /* Stop RTC while updating the RTC time registers */ 80 ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG, 81 PALMAS_RTC_CTRL_REG_STOP_RTC, 0); 82 if (ret < 0) { 83 dev_err(dev, "RTC stop failed, err = %d\n", ret); 84 return ret; 85 } 86 87 ret = palmas_bulk_write(palmas, PALMAS_RTC_BASE, PALMAS_SECONDS_REG, 88 rtc_data, PALMAS_NUM_TIME_REGS); 89 if (ret < 0) { 90 dev_err(dev, "RTC_SECONDS reg write failed, err = %d\n", ret); 91 return ret; 92 } 93 94 /* Start back RTC */ 95 ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG, 96 PALMAS_RTC_CTRL_REG_STOP_RTC, PALMAS_RTC_CTRL_REG_STOP_RTC); 97 if (ret < 0) 98 dev_err(dev, "RTC start failed, err = %d\n", ret); 99 return ret; 100 } 101 102 static int palmas_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) 103 { 104 struct palmas *palmas = dev_get_drvdata(dev->parent); 105 u8 val; 106 107 val = enabled ? PALMAS_RTC_INTERRUPTS_REG_IT_ALARM : 0; 108 return palmas_write(palmas, PALMAS_RTC_BASE, 109 PALMAS_RTC_INTERRUPTS_REG, val); 110 } 111 112 static int palmas_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) 113 { 114 unsigned char alarm_data[PALMAS_NUM_TIME_REGS]; 115 u32 int_val; 116 struct palmas *palmas = dev_get_drvdata(dev->parent); 117 int ret; 118 119 ret = palmas_bulk_read(palmas, PALMAS_RTC_BASE, 120 PALMAS_ALARM_SECONDS_REG, 121 alarm_data, PALMAS_NUM_TIME_REGS); 122 if (ret < 0) { 123 dev_err(dev, "RTC_ALARM_SECONDS read failed, err = %d\n", ret); 124 return ret; 125 } 126 127 alm->time.tm_sec = bcd2bin(alarm_data[0]); 128 alm->time.tm_min = bcd2bin(alarm_data[1]); 129 alm->time.tm_hour = bcd2bin(alarm_data[2]); 130 alm->time.tm_mday = bcd2bin(alarm_data[3]); 131 alm->time.tm_mon = bcd2bin(alarm_data[4]) - 1; 132 alm->time.tm_year = bcd2bin(alarm_data[5]) + 100; 133 134 ret = palmas_read(palmas, PALMAS_RTC_BASE, PALMAS_RTC_INTERRUPTS_REG, 135 &int_val); 136 if (ret < 0) { 137 dev_err(dev, "RTC_INTERRUPTS reg read failed, err = %d\n", ret); 138 return ret; 139 } 140 141 if (int_val & PALMAS_RTC_INTERRUPTS_REG_IT_ALARM) 142 alm->enabled = 1; 143 return ret; 144 } 145 146 static int palmas_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) 147 { 148 unsigned char alarm_data[PALMAS_NUM_TIME_REGS]; 149 struct palmas *palmas = dev_get_drvdata(dev->parent); 150 int ret; 151 152 ret = palmas_rtc_alarm_irq_enable(dev, 0); 153 if (ret < 0) { 154 dev_err(dev, "Disable RTC alarm failed\n"); 155 return ret; 156 } 157 158 alarm_data[0] = bin2bcd(alm->time.tm_sec); 159 alarm_data[1] = bin2bcd(alm->time.tm_min); 160 alarm_data[2] = bin2bcd(alm->time.tm_hour); 161 alarm_data[3] = bin2bcd(alm->time.tm_mday); 162 alarm_data[4] = bin2bcd(alm->time.tm_mon + 1); 163 alarm_data[5] = bin2bcd(alm->time.tm_year - 100); 164 165 ret = palmas_bulk_write(palmas, PALMAS_RTC_BASE, 166 PALMAS_ALARM_SECONDS_REG, alarm_data, PALMAS_NUM_TIME_REGS); 167 if (ret < 0) { 168 dev_err(dev, "ALARM_SECONDS_REG write failed, err = %d\n", ret); 169 return ret; 170 } 171 172 if (alm->enabled) 173 ret = palmas_rtc_alarm_irq_enable(dev, 1); 174 return ret; 175 } 176 177 static int palmas_clear_interrupts(struct device *dev) 178 { 179 struct palmas *palmas = dev_get_drvdata(dev->parent); 180 unsigned int rtc_reg; 181 int ret; 182 183 ret = palmas_read(palmas, PALMAS_RTC_BASE, PALMAS_RTC_STATUS_REG, 184 &rtc_reg); 185 if (ret < 0) { 186 dev_err(dev, "RTC_STATUS read failed, err = %d\n", ret); 187 return ret; 188 } 189 190 ret = palmas_write(palmas, PALMAS_RTC_BASE, PALMAS_RTC_STATUS_REG, 191 rtc_reg); 192 if (ret < 0) { 193 dev_err(dev, "RTC_STATUS write failed, err = %d\n", ret); 194 return ret; 195 } 196 return 0; 197 } 198 199 static irqreturn_t palmas_rtc_interrupt(int irq, void *context) 200 { 201 struct palmas_rtc *palmas_rtc = context; 202 struct device *dev = palmas_rtc->dev; 203 int ret; 204 205 ret = palmas_clear_interrupts(dev); 206 if (ret < 0) { 207 dev_err(dev, "RTC interrupt clear failed, err = %d\n", ret); 208 return IRQ_NONE; 209 } 210 211 rtc_update_irq(palmas_rtc->rtc, 1, RTC_IRQF | RTC_AF); 212 return IRQ_HANDLED; 213 } 214 215 static const struct rtc_class_ops palmas_rtc_ops = { 216 .read_time = palmas_rtc_read_time, 217 .set_time = palmas_rtc_set_time, 218 .read_alarm = palmas_rtc_read_alarm, 219 .set_alarm = palmas_rtc_set_alarm, 220 .alarm_irq_enable = palmas_rtc_alarm_irq_enable, 221 }; 222 223 static int palmas_rtc_probe(struct platform_device *pdev) 224 { 225 struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); 226 struct palmas_rtc *palmas_rtc = NULL; 227 int ret; 228 bool enable_bb_charging = false; 229 bool high_bb_charging = false; 230 231 if (pdev->dev.of_node) { 232 enable_bb_charging = of_property_read_bool(pdev->dev.of_node, 233 "ti,backup-battery-chargeable"); 234 high_bb_charging = of_property_read_bool(pdev->dev.of_node, 235 "ti,backup-battery-charge-high-current"); 236 } 237 238 palmas_rtc = devm_kzalloc_obj(&pdev->dev, struct palmas_rtc); 239 if (!palmas_rtc) 240 return -ENOMEM; 241 242 /* Clear pending interrupts */ 243 ret = palmas_clear_interrupts(&pdev->dev); 244 if (ret < 0) { 245 dev_err(&pdev->dev, "clear RTC int failed, err = %d\n", ret); 246 return ret; 247 } 248 249 palmas_rtc->dev = &pdev->dev; 250 platform_set_drvdata(pdev, palmas_rtc); 251 252 if (enable_bb_charging) { 253 unsigned reg = PALMAS_BACKUP_BATTERY_CTRL_BBS_BBC_LOW_ICHRG; 254 255 if (high_bb_charging) 256 reg = 0; 257 258 ret = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE, 259 PALMAS_BACKUP_BATTERY_CTRL, 260 PALMAS_BACKUP_BATTERY_CTRL_BBS_BBC_LOW_ICHRG, reg); 261 if (ret < 0) { 262 dev_err(&pdev->dev, 263 "BACKUP_BATTERY_CTRL update failed, %d\n", ret); 264 return ret; 265 } 266 267 ret = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE, 268 PALMAS_BACKUP_BATTERY_CTRL, 269 PALMAS_BACKUP_BATTERY_CTRL_BB_CHG_EN, 270 PALMAS_BACKUP_BATTERY_CTRL_BB_CHG_EN); 271 if (ret < 0) { 272 dev_err(&pdev->dev, 273 "BACKUP_BATTERY_CTRL update failed, %d\n", ret); 274 return ret; 275 } 276 } 277 278 /* Start RTC */ 279 ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG, 280 PALMAS_RTC_CTRL_REG_STOP_RTC, 281 PALMAS_RTC_CTRL_REG_STOP_RTC); 282 if (ret < 0) { 283 dev_err(&pdev->dev, "RTC_CTRL write failed, err = %d\n", ret); 284 return ret; 285 } 286 287 palmas_rtc->irq = platform_get_irq(pdev, 0); 288 289 device_init_wakeup(&pdev->dev, true); 290 palmas_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, 291 &palmas_rtc_ops, THIS_MODULE); 292 if (IS_ERR(palmas_rtc->rtc)) { 293 ret = PTR_ERR(palmas_rtc->rtc); 294 dev_err(&pdev->dev, "RTC register failed, err = %d\n", ret); 295 return ret; 296 } 297 298 ret = devm_request_threaded_irq(&pdev->dev, palmas_rtc->irq, NULL, 299 palmas_rtc_interrupt, 300 IRQF_TRIGGER_LOW | IRQF_ONESHOT, 301 dev_name(&pdev->dev), palmas_rtc); 302 if (ret < 0) { 303 dev_err(&pdev->dev, "IRQ request failed, err = %d\n", ret); 304 return ret; 305 } 306 307 return 0; 308 } 309 310 static void palmas_rtc_remove(struct platform_device *pdev) 311 { 312 palmas_rtc_alarm_irq_enable(&pdev->dev, 0); 313 } 314 315 #ifdef CONFIG_PM_SLEEP 316 static int palmas_rtc_suspend(struct device *dev) 317 { 318 struct palmas_rtc *palmas_rtc = dev_get_drvdata(dev); 319 320 if (device_may_wakeup(dev)) 321 enable_irq_wake(palmas_rtc->irq); 322 return 0; 323 } 324 325 static int palmas_rtc_resume(struct device *dev) 326 { 327 struct palmas_rtc *palmas_rtc = dev_get_drvdata(dev); 328 329 if (device_may_wakeup(dev)) 330 disable_irq_wake(palmas_rtc->irq); 331 return 0; 332 } 333 #endif 334 335 static SIMPLE_DEV_PM_OPS(palmas_rtc_pm_ops, palmas_rtc_suspend, 336 palmas_rtc_resume); 337 338 #ifdef CONFIG_OF 339 static const struct of_device_id of_palmas_rtc_match[] = { 340 { .compatible = "ti,palmas-rtc"}, 341 { }, 342 }; 343 MODULE_DEVICE_TABLE(of, of_palmas_rtc_match); 344 #endif 345 346 static struct platform_driver palmas_rtc_driver = { 347 .probe = palmas_rtc_probe, 348 .remove = palmas_rtc_remove, 349 .driver = { 350 .name = "palmas-rtc", 351 .pm = &palmas_rtc_pm_ops, 352 .of_match_table = of_match_ptr(of_palmas_rtc_match), 353 }, 354 }; 355 356 module_platform_driver(palmas_rtc_driver); 357 358 MODULE_ALIAS("platform:palmas_rtc"); 359 MODULE_DESCRIPTION("TI PALMAS series RTC driver"); 360 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); 361 MODULE_LICENSE("GPL v2"); 362