1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * drivers/rtc/rtc-rc5t619.c 4 * 5 * Real time clock driver for RICOH RC5T619 power management chip. 6 * 7 * Copyright (C) 2019 Andreas Kemnade 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/device.h> 12 #include <linux/errno.h> 13 #include <linux/init.h> 14 #include <linux/module.h> 15 #include <linux/mfd/rn5t618.h> 16 #include <linux/platform_device.h> 17 #include <linux/regmap.h> 18 #include <linux/bcd.h> 19 #include <linux/rtc.h> 20 #include <linux/slab.h> 21 #include <linux/irqdomain.h> 22 23 struct rc5t619_rtc { 24 int irq; 25 struct rtc_device *rtc; 26 struct rn5t618 *rn5t618; 27 }; 28 29 #define CTRL1_ALARM_ENABLED 0x40 30 #define CTRL1_24HR 0x20 31 #define CTRL1_PERIODIC_MASK 0xf 32 33 #define CTRL2_PON 0x10 34 #define CTRL2_ALARM_STATUS 0x80 35 #define CTRL2_CTFG 0x4 36 #define CTRL2_CTC 0x1 37 38 #define MONTH_CENTFLAG 0x80 39 #define HOUR_PMFLAG 0x20 40 #define MDAY_DAL_EXT 0x80 41 42 static uint8_t rtc5t619_12hour_bcd2bin(uint8_t hour) 43 { 44 if (hour & HOUR_PMFLAG) { 45 hour = bcd2bin(hour & ~HOUR_PMFLAG); 46 return hour == 12 ? 12 : 12 + hour; 47 } 48 49 hour = bcd2bin(hour); 50 return hour == 12 ? 0 : hour; 51 } 52 53 static uint8_t rtc5t619_12hour_bin2bcd(uint8_t hour) 54 { 55 if (!hour) 56 return 0x12; 57 58 if (hour < 12) 59 return bin2bcd(hour); 60 61 if (hour == 12) 62 return 0x12 | HOUR_PMFLAG; 63 64 return bin2bcd(hour - 12) | HOUR_PMFLAG; 65 } 66 67 static int rc5t619_rtc_periodic_disable(struct device *dev) 68 { 69 struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 70 int err; 71 72 /* disable function */ 73 err = regmap_update_bits(rtc->rn5t618->regmap, 74 RN5T618_RTC_CTRL1, CTRL1_PERIODIC_MASK, 0); 75 if (err < 0) 76 return err; 77 78 /* clear alarm flag and CTFG */ 79 err = regmap_update_bits(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, 80 CTRL2_ALARM_STATUS | CTRL2_CTFG | CTRL2_CTC, 81 0); 82 if (err < 0) 83 return err; 84 85 return 0; 86 } 87 88 /* things to be done once after power on */ 89 static int rc5t619_rtc_pon_setup(struct device *dev) 90 { 91 struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 92 int err; 93 unsigned int reg_data; 94 95 err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, ®_data); 96 if (err < 0) 97 return err; 98 99 /* clear VDET PON */ 100 reg_data &= ~(CTRL2_PON | CTRL2_CTC | 0x4a); /* 0101-1011 */ 101 reg_data |= 0x20; /* 0010-0000 */ 102 err = regmap_write(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, reg_data); 103 if (err < 0) 104 return err; 105 106 /* clearing RTC Adjust register */ 107 err = regmap_write(rtc->rn5t618->regmap, RN5T618_RTC_ADJUST, 0); 108 if (err) 109 return err; 110 111 return regmap_update_bits(rtc->rn5t618->regmap, 112 RN5T618_RTC_CTRL1, 113 CTRL1_24HR, CTRL1_24HR); 114 } 115 116 static int rc5t619_rtc_read_time(struct device *dev, struct rtc_time *tm) 117 { 118 struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 119 u8 buff[7]; 120 int err; 121 int cent_flag; 122 unsigned int ctrl1; 123 unsigned int ctrl2; 124 125 err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, &ctrl2); 126 if (err < 0) 127 return err; 128 129 if (ctrl2 & CTRL2_PON) 130 return -EINVAL; 131 132 err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL1, &ctrl1); 133 if (err < 0) 134 return err; 135 136 err = regmap_bulk_read(rtc->rn5t618->regmap, RN5T618_RTC_SECONDS, 137 buff, sizeof(buff)); 138 if (err < 0) 139 return err; 140 141 if (buff[5] & MONTH_CENTFLAG) 142 cent_flag = 1; 143 else 144 cent_flag = 0; 145 146 tm->tm_sec = bcd2bin(buff[0]); 147 tm->tm_min = bcd2bin(buff[1]); 148 149 if (ctrl1 & CTRL1_24HR) 150 tm->tm_hour = bcd2bin(buff[2]); 151 else 152 tm->tm_hour = rtc5t619_12hour_bcd2bin(buff[2]); 153 154 tm->tm_wday = bcd2bin(buff[3]); 155 tm->tm_mday = bcd2bin(buff[4]); 156 tm->tm_mon = bcd2bin(buff[5] & 0x1f) - 1; /* back to system 0-11 */ 157 tm->tm_year = bcd2bin(buff[6]) + 100 * cent_flag; 158 159 return 0; 160 } 161 162 static int rc5t619_rtc_set_time(struct device *dev, struct rtc_time *tm) 163 { 164 struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 165 u8 buff[7]; 166 int err; 167 int cent_flag; 168 unsigned int ctrl1; 169 unsigned int ctrl2; 170 171 err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, &ctrl2); 172 if (err < 0) 173 return err; 174 175 if (ctrl2 & CTRL2_PON) 176 rc5t619_rtc_pon_setup(dev); 177 178 err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL1, &ctrl1); 179 if (err < 0) 180 return err; 181 182 if (tm->tm_year >= 100) 183 cent_flag = 1; 184 else 185 cent_flag = 0; 186 187 buff[0] = bin2bcd(tm->tm_sec); 188 buff[1] = bin2bcd(tm->tm_min); 189 190 if (ctrl1 & CTRL1_24HR) 191 buff[2] = bin2bcd(tm->tm_hour); 192 else 193 buff[2] = rtc5t619_12hour_bin2bcd(tm->tm_hour); 194 195 buff[3] = bin2bcd(tm->tm_wday); 196 buff[4] = bin2bcd(tm->tm_mday); 197 buff[5] = bin2bcd(tm->tm_mon + 1); /* system set 0-11 */ 198 buff[6] = bin2bcd(tm->tm_year - cent_flag * 100); 199 200 if (cent_flag) 201 buff[5] |= MONTH_CENTFLAG; 202 203 err = regmap_bulk_write(rtc->rn5t618->regmap, RN5T618_RTC_SECONDS, 204 buff, sizeof(buff)); 205 if (err < 0) { 206 dev_err(dev, "failed to program new time: %d\n", err); 207 return err; 208 } 209 210 return 0; 211 } 212 213 /* 0-disable, 1-enable */ 214 static int rc5t619_rtc_alarm_enable(struct device *dev, unsigned int enabled) 215 { 216 struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 217 218 return regmap_update_bits(rtc->rn5t618->regmap, 219 RN5T618_RTC_CTRL1, 220 CTRL1_ALARM_ENABLED, 221 enabled ? CTRL1_ALARM_ENABLED : 0); 222 } 223 224 static int rc5t619_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 225 { 226 struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 227 u8 buff[6]; 228 unsigned int buff_cent; 229 int err; 230 int cent_flag; 231 unsigned int ctrl1; 232 233 err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL1, &ctrl1); 234 if (err) 235 return err; 236 237 err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_MONTH, &buff_cent); 238 if (err < 0) { 239 dev_err(dev, "failed to read time: %d\n", err); 240 return err; 241 } 242 243 if (buff_cent & MONTH_CENTFLAG) 244 cent_flag = 1; 245 else 246 cent_flag = 0; 247 248 err = regmap_bulk_read(rtc->rn5t618->regmap, RN5T618_RTC_ALARM_Y_SEC, 249 buff, sizeof(buff)); 250 if (err) 251 return err; 252 253 buff[3] = buff[3] & 0x3f; 254 255 alrm->time.tm_sec = bcd2bin(buff[0]); 256 alrm->time.tm_min = bcd2bin(buff[1]); 257 258 if (ctrl1 & CTRL1_24HR) 259 alrm->time.tm_hour = bcd2bin(buff[2]); 260 else 261 alrm->time.tm_hour = rtc5t619_12hour_bcd2bin(buff[2]); 262 263 alrm->time.tm_mday = bcd2bin(buff[3]); 264 alrm->time.tm_mon = bcd2bin(buff[4]) - 1; 265 alrm->time.tm_year = bcd2bin(buff[5]) + 100 * cent_flag; 266 alrm->enabled = !!(ctrl1 & CTRL1_ALARM_ENABLED); 267 dev_dbg(dev, "read alarm: %ptR\n", &alrm->time); 268 269 return 0; 270 } 271 272 static int rc5t619_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 273 { 274 struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 275 u8 buff[6]; 276 int err; 277 int cent_flag; 278 unsigned int ctrl1; 279 280 err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL1, &ctrl1); 281 if (err) 282 return err; 283 284 err = rc5t619_rtc_alarm_enable(dev, 0); 285 if (err < 0) 286 return err; 287 288 if (rtc->irq == -1) 289 return -EINVAL; 290 291 if (alrm->enabled == 0) 292 return 0; 293 294 if (alrm->time.tm_year >= 100) 295 cent_flag = 1; 296 else 297 cent_flag = 0; 298 299 alrm->time.tm_mon += 1; 300 buff[0] = bin2bcd(alrm->time.tm_sec); 301 buff[1] = bin2bcd(alrm->time.tm_min); 302 303 if (ctrl1 & CTRL1_24HR) 304 buff[2] = bin2bcd(alrm->time.tm_hour); 305 else 306 buff[2] = rtc5t619_12hour_bin2bcd(alrm->time.tm_hour); 307 308 buff[3] = bin2bcd(alrm->time.tm_mday); 309 buff[4] = bin2bcd(alrm->time.tm_mon); 310 buff[5] = bin2bcd(alrm->time.tm_year - 100 * cent_flag); 311 buff[3] |= MDAY_DAL_EXT; 312 313 err = regmap_bulk_write(rtc->rn5t618->regmap, RN5T618_RTC_ALARM_Y_SEC, 314 buff, sizeof(buff)); 315 if (err < 0) 316 return err; 317 318 return rc5t619_rtc_alarm_enable(dev, alrm->enabled); 319 } 320 321 static const struct rtc_class_ops rc5t619_rtc_ops = { 322 .read_time = rc5t619_rtc_read_time, 323 .set_time = rc5t619_rtc_set_time, 324 .set_alarm = rc5t619_rtc_set_alarm, 325 .read_alarm = rc5t619_rtc_read_alarm, 326 .alarm_irq_enable = rc5t619_rtc_alarm_enable, 327 }; 328 329 static int rc5t619_rtc_alarm_flag_clr(struct device *dev) 330 { 331 struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 332 333 /* clear alarm-D status bits.*/ 334 return regmap_update_bits(rtc->rn5t618->regmap, 335 RN5T618_RTC_CTRL2, 336 CTRL2_ALARM_STATUS | CTRL2_CTC, 0); 337 } 338 339 static irqreturn_t rc5t619_rtc_irq(int irq, void *data) 340 { 341 struct device *dev = data; 342 struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 343 344 rc5t619_rtc_alarm_flag_clr(dev); 345 346 rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); 347 return IRQ_HANDLED; 348 } 349 350 static int rc5t619_rtc_probe(struct platform_device *pdev) 351 { 352 struct device *dev = &pdev->dev; 353 struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent); 354 struct rc5t619_rtc *rtc; 355 unsigned int ctrl2; 356 int err; 357 358 rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL); 359 if (IS_ERR(rtc)) { 360 err = PTR_ERR(rtc); 361 return -ENOMEM; 362 } 363 364 rtc->rn5t618 = rn5t618; 365 366 dev_set_drvdata(dev, rtc); 367 rtc->irq = -1; 368 369 if (rn5t618->irq_data) 370 rtc->irq = regmap_irq_get_virq(rn5t618->irq_data, 371 RN5T618_IRQ_RTC); 372 373 if (rtc->irq < 0) 374 rtc->irq = -1; 375 376 err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, &ctrl2); 377 if (err < 0) 378 return err; 379 380 /* disable rtc periodic function */ 381 err = rc5t619_rtc_periodic_disable(&pdev->dev); 382 if (err) 383 return err; 384 385 if (ctrl2 & CTRL2_PON) { 386 err = rc5t619_rtc_alarm_flag_clr(&pdev->dev); 387 if (err) 388 return err; 389 } 390 391 rtc->rtc = devm_rtc_allocate_device(&pdev->dev); 392 if (IS_ERR(rtc->rtc)) { 393 err = PTR_ERR(rtc->rtc); 394 dev_err(dev, "RTC device register: err %d\n", err); 395 return err; 396 } 397 398 rtc->rtc->ops = &rc5t619_rtc_ops; 399 rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_1900; 400 rtc->rtc->range_max = RTC_TIMESTAMP_END_2099; 401 402 /* set interrupt and enable it */ 403 if (rtc->irq != -1) { 404 err = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, 405 rc5t619_rtc_irq, 406 IRQF_ONESHOT, 407 "rtc-rc5t619", 408 &pdev->dev); 409 if (err < 0) { 410 dev_err(&pdev->dev, "request IRQ:%d fail\n", rtc->irq); 411 rtc->irq = -1; 412 413 err = rc5t619_rtc_alarm_enable(&pdev->dev, 0); 414 if (err) 415 return err; 416 417 } else { 418 /* enable wake */ 419 device_init_wakeup(&pdev->dev, 1); 420 enable_irq_wake(rtc->irq); 421 } 422 } else { 423 /* system don't want to using alarm interrupt, so close it */ 424 err = rc5t619_rtc_alarm_enable(&pdev->dev, 0); 425 if (err) 426 return err; 427 428 dev_warn(&pdev->dev, "rc5t619 interrupt is disabled\n"); 429 } 430 431 return rtc_register_device(rtc->rtc); 432 } 433 434 static struct platform_driver rc5t619_rtc_driver = { 435 .driver = { 436 .name = "rc5t619-rtc", 437 }, 438 .probe = rc5t619_rtc_probe, 439 }; 440 441 module_platform_driver(rc5t619_rtc_driver); 442 MODULE_ALIAS("platform:rc5t619-rtc"); 443 MODULE_DESCRIPTION("RICOH RC5T619 RTC driver"); 444 MODULE_LICENSE("GPL"); 445