1 // SPDX-License-Identifier: GPL-2.0-or-later 2 // 3 // Copyright (C) 2018 ROHM Semiconductors 4 // 5 // RTC driver for ROHM BD71828 and BD71815 PMIC 6 7 #include <linux/bcd.h> 8 #include <linux/mfd/rohm-bd71815.h> 9 #include <linux/mfd/rohm-bd71828.h> 10 #include <linux/mfd/rohm-bd72720.h> 11 #include <linux/mfd/rohm-bd73800.h> 12 #include <linux/module.h> 13 #include <linux/of.h> 14 #include <linux/platform_device.h> 15 #include <linux/pm_wakeirq.h> 16 #include <linux/regmap.h> 17 #include <linux/rtc.h> 18 19 /* 20 * On BD71828 and BD71815 the ALM0 MASK is 14 bytes after the ALM0 21 * block start 22 */ 23 #define BD718XX_ALM_EN_OFFSET 14 24 25 /* 26 * We read regs RTC_SEC => RTC_YEAR 27 * this struct is ordered according to chip registers. 28 * Keep it u8 only (or packed) to avoid padding issues. 29 */ 30 struct bd70528_rtc_day { 31 u8 sec; 32 u8 min; 33 u8 hour; 34 } __packed; 35 36 struct bd70528_rtc_data { 37 struct bd70528_rtc_day time; 38 u8 week; 39 u8 day; 40 u8 month; 41 u8 year; 42 } __packed; 43 44 struct bd71828_rtc_alm { 45 struct bd70528_rtc_data alm0; 46 struct bd70528_rtc_data alm1; 47 u8 alm_mask; 48 u8 alm1_mask; 49 } __packed; 50 51 struct bd70528_rtc { 52 struct rohm_regmap_dev *parent; 53 struct regmap *regmap; 54 struct device *dev; 55 u8 reg_time_start; 56 u8 bd718xx_alm_block_start; 57 }; 58 59 static inline void tmday2rtc(struct rtc_time *t, struct bd70528_rtc_day *d) 60 { 61 d->sec &= ~BD70528_MASK_RTC_SEC; 62 d->min &= ~BD70528_MASK_RTC_MINUTE; 63 d->hour &= ~BD70528_MASK_RTC_HOUR; 64 d->sec |= bin2bcd(t->tm_sec); 65 d->min |= bin2bcd(t->tm_min); 66 d->hour |= bin2bcd(t->tm_hour); 67 } 68 69 static inline void tm2rtc(struct rtc_time *t, struct bd70528_rtc_data *r) 70 { 71 r->day &= ~BD70528_MASK_RTC_DAY; 72 r->week &= ~BD70528_MASK_RTC_WEEK; 73 r->month &= ~BD70528_MASK_RTC_MONTH; 74 /* 75 * PM and 24H bits are not used by Wake - thus we clear them 76 * here and not in tmday2rtc() which is also used by wake. 77 */ 78 r->time.hour &= ~(BD70528_MASK_RTC_HOUR_PM | BD70528_MASK_RTC_HOUR_24H); 79 80 tmday2rtc(t, &r->time); 81 /* 82 * We do always set time in 24H mode. 83 */ 84 r->time.hour |= BD70528_MASK_RTC_HOUR_24H; 85 r->day |= bin2bcd(t->tm_mday); 86 r->week |= bin2bcd(t->tm_wday); 87 r->month |= bin2bcd(t->tm_mon + 1); 88 r->year = bin2bcd(t->tm_year - 100); 89 } 90 91 static inline void rtc2tm(struct bd70528_rtc_data *r, struct rtc_time *t) 92 { 93 t->tm_sec = bcd2bin(r->time.sec & BD70528_MASK_RTC_SEC); 94 t->tm_min = bcd2bin(r->time.min & BD70528_MASK_RTC_MINUTE); 95 t->tm_hour = bcd2bin(r->time.hour & BD70528_MASK_RTC_HOUR); 96 /* 97 * If RTC is in 12H mode, then bit BD70528_MASK_RTC_HOUR_PM 98 * is not BCD value but tells whether it is AM or PM 99 */ 100 if (!(r->time.hour & BD70528_MASK_RTC_HOUR_24H)) { 101 t->tm_hour %= 12; 102 if (r->time.hour & BD70528_MASK_RTC_HOUR_PM) 103 t->tm_hour += 12; 104 } 105 t->tm_mday = bcd2bin(r->day & BD70528_MASK_RTC_DAY); 106 t->tm_mon = bcd2bin(r->month & BD70528_MASK_RTC_MONTH) - 1; 107 t->tm_year = 100 + bcd2bin(r->year & BD70528_MASK_RTC_YEAR); 108 t->tm_wday = bcd2bin(r->week & BD70528_MASK_RTC_WEEK); 109 } 110 111 static int bd71828_set_alarm(struct device *dev, struct rtc_wkalrm *a) 112 { 113 int ret; 114 struct bd71828_rtc_alm alm; 115 struct bd70528_rtc *r = dev_get_drvdata(dev); 116 117 ret = regmap_bulk_read(r->regmap, r->bd718xx_alm_block_start, &alm, 118 sizeof(alm)); 119 if (ret) { 120 dev_err(dev, "Failed to read alarm regs\n"); 121 return ret; 122 } 123 124 tm2rtc(&a->time, &alm.alm0); 125 126 if (!a->enabled) 127 alm.alm_mask &= ~BD70528_MASK_ALM_EN; 128 else 129 alm.alm_mask |= BD70528_MASK_ALM_EN; 130 131 ret = regmap_bulk_write(r->regmap, r->bd718xx_alm_block_start, &alm, 132 sizeof(alm)); 133 if (ret) 134 dev_err(dev, "Failed to set alarm time\n"); 135 136 return ret; 137 138 } 139 140 static int bd71828_read_alarm(struct device *dev, struct rtc_wkalrm *a) 141 { 142 int ret; 143 struct bd71828_rtc_alm alm; 144 struct bd70528_rtc *r = dev_get_drvdata(dev); 145 146 ret = regmap_bulk_read(r->regmap, r->bd718xx_alm_block_start, &alm, 147 sizeof(alm)); 148 if (ret) { 149 dev_err(dev, "Failed to read alarm regs\n"); 150 return ret; 151 } 152 153 rtc2tm(&alm.alm0, &a->time); 154 a->time.tm_mday = -1; 155 a->time.tm_mon = -1; 156 a->time.tm_year = -1; 157 a->enabled = !!(alm.alm_mask & BD70528_MASK_ALM_EN); 158 a->pending = 0; 159 160 return 0; 161 } 162 163 static int bd71828_set_time(struct device *dev, struct rtc_time *t) 164 { 165 int ret; 166 struct bd70528_rtc_data rtc_data; 167 struct bd70528_rtc *r = dev_get_drvdata(dev); 168 169 ret = regmap_bulk_read(r->regmap, r->reg_time_start, &rtc_data, 170 sizeof(rtc_data)); 171 if (ret) { 172 dev_err(dev, "Failed to read RTC time registers\n"); 173 return ret; 174 } 175 tm2rtc(t, &rtc_data); 176 177 ret = regmap_bulk_write(r->regmap, r->reg_time_start, &rtc_data, 178 sizeof(rtc_data)); 179 if (ret) 180 dev_err(dev, "Failed to set RTC time\n"); 181 182 return ret; 183 } 184 185 static int bd70528_get_time(struct device *dev, struct rtc_time *t) 186 { 187 struct bd70528_rtc *r = dev_get_drvdata(dev); 188 struct bd70528_rtc_data rtc_data; 189 int ret; 190 191 /* read the RTC date and time registers all at once */ 192 ret = regmap_bulk_read(r->regmap, r->reg_time_start, &rtc_data, 193 sizeof(rtc_data)); 194 if (ret) { 195 dev_err(dev, "Failed to read RTC time (err %d)\n", ret); 196 return ret; 197 } 198 199 rtc2tm(&rtc_data, t); 200 201 return 0; 202 } 203 204 static int bd71828_alm_enable(struct device *dev, unsigned int enabled) 205 { 206 int ret; 207 struct bd70528_rtc *r = dev_get_drvdata(dev); 208 unsigned int enableval = BD70528_MASK_ALM_EN; 209 210 if (!enabled) 211 enableval = 0; 212 213 ret = regmap_update_bits(r->regmap, r->bd718xx_alm_block_start + 214 BD718XX_ALM_EN_OFFSET, BD70528_MASK_ALM_EN, 215 enableval); 216 if (ret) 217 dev_err(dev, "Failed to change alarm state\n"); 218 219 return ret; 220 } 221 222 static const struct rtc_class_ops bd71828_rtc_ops = { 223 .read_time = bd70528_get_time, 224 .set_time = bd71828_set_time, 225 .read_alarm = bd71828_read_alarm, 226 .set_alarm = bd71828_set_alarm, 227 .alarm_irq_enable = bd71828_alm_enable, 228 }; 229 230 static irqreturn_t alm_hndlr(int irq, void *data) 231 { 232 struct rtc_device *rtc = data; 233 234 rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF | RTC_PF); 235 return IRQ_HANDLED; 236 } 237 238 static int bd70528_probe(struct platform_device *pdev) 239 { 240 struct bd70528_rtc *bd_rtc; 241 const struct rtc_class_ops *rtc_ops; 242 int ret; 243 struct rtc_device *rtc; 244 int irq; 245 unsigned int hr; 246 u8 hour_reg; 247 enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data; 248 249 bd_rtc = devm_kzalloc_obj(&pdev->dev, *bd_rtc); 250 if (!bd_rtc) 251 return -ENOMEM; 252 253 bd_rtc->regmap = dev_get_regmap(pdev->dev.parent, NULL); 254 if (!bd_rtc->regmap) { 255 dev_err(&pdev->dev, "No regmap\n"); 256 return -EINVAL; 257 } 258 259 bd_rtc->dev = &pdev->dev; 260 rtc_ops = &bd71828_rtc_ops; 261 262 switch (chip) { 263 case ROHM_CHIP_TYPE_BD71815: 264 bd_rtc->reg_time_start = BD71815_REG_RTC_START; 265 266 /* 267 * See also BD718XX_ALM_EN_OFFSET: 268 * This works for BD71828, BD71815, and BD72720 as they all 269 * have same offset between the ALM0 start and the ALM0_MASK. 270 * If new ICs are to be added this requires proper check as 271 * the ALM0_MASK is not located at the end of ALM0 block - 272 * but after all ALM blocks. If amount of ALMs differ, the 273 * offset to enable/disable is likely to be incorrect and 274 * enable/disable must be given as own reg address here. 275 */ 276 bd_rtc->bd718xx_alm_block_start = BD71815_REG_RTC_ALM_START; 277 hour_reg = BD71815_REG_HOUR; 278 break; 279 case ROHM_CHIP_TYPE_BD71828: 280 bd_rtc->reg_time_start = BD71828_REG_RTC_START; 281 bd_rtc->bd718xx_alm_block_start = BD71828_REG_RTC_ALM_START; 282 hour_reg = BD71828_REG_RTC_HOUR; 283 break; 284 case ROHM_CHIP_TYPE_BD72720: 285 bd_rtc->reg_time_start = BD72720_REG_RTC_START; 286 bd_rtc->bd718xx_alm_block_start = BD72720_REG_RTC_ALM_START; 287 hour_reg = BD72720_REG_RTC_HOUR; 288 break; 289 case ROHM_CHIP_TYPE_BD73800: 290 bd_rtc->reg_time_start = BD73800_REG_RTC_START; 291 bd_rtc->bd718xx_alm_block_start = BD73800_REG_RTC_ALM_START; 292 hour_reg = BD73800_REG_RTC_HOUR; 293 break; 294 295 default: 296 dev_err(&pdev->dev, "Unknown chip\n"); 297 return -ENOENT; 298 } 299 300 irq = platform_get_irq_byname(pdev, "bd70528-rtc-alm-0"); 301 302 if (irq < 0) 303 return irq; 304 305 platform_set_drvdata(pdev, bd_rtc); 306 307 ret = regmap_read(bd_rtc->regmap, hour_reg, &hr); 308 309 if (ret) { 310 dev_err(&pdev->dev, "Failed to reag RTC clock\n"); 311 return ret; 312 } 313 314 if (!(hr & BD70528_MASK_RTC_HOUR_24H)) { 315 struct rtc_time t; 316 317 ret = rtc_ops->read_time(&pdev->dev, &t); 318 319 if (!ret) 320 ret = rtc_ops->set_time(&pdev->dev, &t); 321 322 if (ret) { 323 dev_err(&pdev->dev, 324 "Setting 24H clock for RTC failed\n"); 325 return ret; 326 } 327 } 328 329 device_set_wakeup_capable(&pdev->dev, true); 330 device_wakeup_enable(&pdev->dev); 331 332 ret = devm_pm_set_wake_irq(&pdev->dev, irq); 333 if (ret) 334 return ret; 335 336 rtc = devm_rtc_allocate_device(&pdev->dev); 337 if (IS_ERR(rtc)) { 338 dev_err(&pdev->dev, "RTC device creation failed\n"); 339 return PTR_ERR(rtc); 340 } 341 342 rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 343 rtc->range_max = RTC_TIMESTAMP_END_2099; 344 rtc->ops = rtc_ops; 345 346 /* Request alarm IRQ prior to registerig the RTC */ 347 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, &alm_hndlr, 348 IRQF_ONESHOT, "bd70528-rtc", rtc); 349 if (ret) 350 return ret; 351 352 return devm_rtc_register_device(rtc); 353 } 354 355 static const struct platform_device_id bd718x7_rtc_id[] = { 356 { .name = "bd71828-rtc", .driver_data = ROHM_CHIP_TYPE_BD71828 }, 357 { .name = "bd71815-rtc", .driver_data = ROHM_CHIP_TYPE_BD71815 }, 358 { .name = "bd72720-rtc", .driver_data = ROHM_CHIP_TYPE_BD72720 }, 359 { .name = "bd73800-rtc", .driver_data = ROHM_CHIP_TYPE_BD73800 }, 360 { } 361 }; 362 MODULE_DEVICE_TABLE(platform, bd718x7_rtc_id); 363 364 static struct platform_driver bd70528_rtc = { 365 .driver = { 366 .name = "bd70528-rtc" 367 }, 368 .probe = bd70528_probe, 369 .id_table = bd718x7_rtc_id, 370 }; 371 372 module_platform_driver(bd70528_rtc); 373 374 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 375 MODULE_DESCRIPTION("ROHM BD71828 and BD71815 PMIC RTC driver"); 376 MODULE_LICENSE("GPL"); 377 MODULE_ALIAS("platform:bd70528-rtc"); 378