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