497 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * drivers/rtc/rtc-pcf85363.c4 *5 * Driver for NXP PCF85363 real-time clock.6 *7 * Copyright (C) 2017 Eric Nelson8 */9#include <linux/module.h>10#include <linux/i2c.h>11#include <linux/slab.h>12#include <linux/rtc.h>13#include <linux/init.h>14#include <linux/err.h>15#include <linux/errno.h>16#include <linux/bcd.h>17#include <linux/of.h>18#include <linux/regmap.h>19 20/*21 * Date/Time registers22 */23#define DT_100THS 0x0024#define DT_SECS 0x0125#define DT_MINUTES 0x0226#define DT_HOURS 0x0327#define DT_DAYS 0x0428#define DT_WEEKDAYS 0x0529#define DT_MONTHS 0x0630#define DT_YEARS 0x0731 32/*33 * Alarm registers34 */35#define DT_SECOND_ALM1 0x0836#define DT_MINUTE_ALM1 0x0937#define DT_HOUR_ALM1 0x0a38#define DT_DAY_ALM1 0x0b39#define DT_MONTH_ALM1 0x0c40#define DT_MINUTE_ALM2 0x0d41#define DT_HOUR_ALM2 0x0e42#define DT_WEEKDAY_ALM2 0x0f43#define DT_ALARM_EN 0x1044 45/*46 * Time stamp registers47 */48#define DT_TIMESTAMP1 0x1149#define DT_TIMESTAMP2 0x1750#define DT_TIMESTAMP3 0x1d51#define DT_TS_MODE 0x2352 53/*54 * control registers55 */56#define CTRL_OFFSET 0x2457#define CTRL_OSCILLATOR 0x2558#define CTRL_BATTERY 0x2659#define CTRL_PIN_IO 0x2760#define CTRL_FUNCTION 0x2861#define CTRL_INTA_EN 0x2962#define CTRL_INTB_EN 0x2a63#define CTRL_FLAGS 0x2b64#define CTRL_RAMBYTE 0x2c65#define CTRL_WDOG 0x2d66#define CTRL_STOP_EN 0x2e67#define CTRL_RESETS 0x2f68#define CTRL_RAM 0x4069 70#define ALRM_SEC_A1E BIT(0)71#define ALRM_MIN_A1E BIT(1)72#define ALRM_HR_A1E BIT(2)73#define ALRM_DAY_A1E BIT(3)74#define ALRM_MON_A1E BIT(4)75#define ALRM_MIN_A2E BIT(5)76#define ALRM_HR_A2E BIT(6)77#define ALRM_DAY_A2E BIT(7)78 79#define INT_WDIE BIT(0)80#define INT_BSIE BIT(1)81#define INT_TSRIE BIT(2)82#define INT_A2IE BIT(3)83#define INT_A1IE BIT(4)84#define INT_OIE BIT(5)85#define INT_PIE BIT(6)86#define INT_ILP BIT(7)87 88#define FLAGS_TSR1F BIT(0)89#define FLAGS_TSR2F BIT(1)90#define FLAGS_TSR3F BIT(2)91#define FLAGS_BSF BIT(3)92#define FLAGS_WDF BIT(4)93#define FLAGS_A1F BIT(5)94#define FLAGS_A2F BIT(6)95#define FLAGS_PIF BIT(7)96 97#define PIN_IO_INTAPM GENMASK(1, 0)98#define PIN_IO_INTA_CLK 099#define PIN_IO_INTA_BAT 1100#define PIN_IO_INTA_OUT 2101#define PIN_IO_INTA_HIZ 3102 103#define OSC_CAP_SEL GENMASK(1, 0)104#define OSC_CAP_6000 0x01105#define OSC_CAP_12500 0x02106 107#define STOP_EN_STOP BIT(0)108 109#define RESET_CPR 0xa4110 111#define NVRAM_SIZE 0x40112 113struct pcf85363 {114 struct rtc_device *rtc;115 struct regmap *regmap;116};117 118struct pcf85x63_config {119 struct regmap_config regmap;120 unsigned int num_nvram;121};122 123static int pcf85363_load_capacitance(struct pcf85363 *pcf85363, struct device_node *node)124{125 u32 load = 7000;126 u8 value = 0;127 128 of_property_read_u32(node, "quartz-load-femtofarads", &load);129 130 switch (load) {131 default:132 dev_warn(&pcf85363->rtc->dev, "Unknown quartz-load-femtofarads value: %d. Assuming 7000",133 load);134 fallthrough;135 case 7000:136 break;137 case 6000:138 value = OSC_CAP_6000;139 break;140 case 12500:141 value = OSC_CAP_12500;142 break;143 }144 145 return regmap_update_bits(pcf85363->regmap, CTRL_OSCILLATOR,146 OSC_CAP_SEL, value);147}148 149static int pcf85363_rtc_read_time(struct device *dev, struct rtc_time *tm)150{151 struct pcf85363 *pcf85363 = dev_get_drvdata(dev);152 unsigned char buf[DT_YEARS + 1];153 int ret, len = sizeof(buf);154 155 /* read the RTC date and time registers all at once */156 ret = regmap_bulk_read(pcf85363->regmap, DT_100THS, buf, len);157 if (ret) {158 dev_err(dev, "%s: error %d\n", __func__, ret);159 return ret;160 }161 162 tm->tm_year = bcd2bin(buf[DT_YEARS]);163 /* adjust for 1900 base of rtc_time */164 tm->tm_year += 100;165 166 tm->tm_wday = buf[DT_WEEKDAYS] & 7;167 buf[DT_SECS] &= 0x7F;168 tm->tm_sec = bcd2bin(buf[DT_SECS]);169 buf[DT_MINUTES] &= 0x7F;170 tm->tm_min = bcd2bin(buf[DT_MINUTES]);171 tm->tm_hour = bcd2bin(buf[DT_HOURS]);172 tm->tm_mday = bcd2bin(buf[DT_DAYS]);173 tm->tm_mon = bcd2bin(buf[DT_MONTHS]) - 1;174 175 return 0;176}177 178static int pcf85363_rtc_set_time(struct device *dev, struct rtc_time *tm)179{180 struct pcf85363 *pcf85363 = dev_get_drvdata(dev);181 unsigned char tmp[11];182 unsigned char *buf = &tmp[2];183 int ret;184 185 tmp[0] = STOP_EN_STOP;186 tmp[1] = RESET_CPR;187 188 buf[DT_100THS] = 0;189 buf[DT_SECS] = bin2bcd(tm->tm_sec);190 buf[DT_MINUTES] = bin2bcd(tm->tm_min);191 buf[DT_HOURS] = bin2bcd(tm->tm_hour);192 buf[DT_DAYS] = bin2bcd(tm->tm_mday);193 buf[DT_WEEKDAYS] = tm->tm_wday;194 buf[DT_MONTHS] = bin2bcd(tm->tm_mon + 1);195 buf[DT_YEARS] = bin2bcd(tm->tm_year % 100);196 197 ret = regmap_bulk_write(pcf85363->regmap, CTRL_STOP_EN,198 tmp, 2);199 if (ret)200 return ret;201 202 ret = regmap_bulk_write(pcf85363->regmap, DT_100THS,203 buf, sizeof(tmp) - 2);204 if (ret)205 return ret;206 207 return regmap_write(pcf85363->regmap, CTRL_STOP_EN, 0);208}209 210static int pcf85363_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)211{212 struct pcf85363 *pcf85363 = dev_get_drvdata(dev);213 unsigned char buf[DT_MONTH_ALM1 - DT_SECOND_ALM1 + 1];214 unsigned int val;215 int ret;216 217 ret = regmap_bulk_read(pcf85363->regmap, DT_SECOND_ALM1, buf,218 sizeof(buf));219 if (ret)220 return ret;221 222 alrm->time.tm_sec = bcd2bin(buf[0]);223 alrm->time.tm_min = bcd2bin(buf[1]);224 alrm->time.tm_hour = bcd2bin(buf[2]);225 alrm->time.tm_mday = bcd2bin(buf[3]);226 alrm->time.tm_mon = bcd2bin(buf[4]) - 1;227 228 ret = regmap_read(pcf85363->regmap, CTRL_INTA_EN, &val);229 if (ret)230 return ret;231 232 alrm->enabled = !!(val & INT_A1IE);233 234 return 0;235}236 237static int _pcf85363_rtc_alarm_irq_enable(struct pcf85363 *pcf85363, unsigned238 int enabled)239{240 unsigned int alarm_flags = ALRM_SEC_A1E | ALRM_MIN_A1E | ALRM_HR_A1E |241 ALRM_DAY_A1E | ALRM_MON_A1E;242 int ret;243 244 ret = regmap_update_bits(pcf85363->regmap, DT_ALARM_EN, alarm_flags,245 enabled ? alarm_flags : 0);246 if (ret)247 return ret;248 249 ret = regmap_update_bits(pcf85363->regmap, CTRL_INTA_EN,250 INT_A1IE, enabled ? INT_A1IE : 0);251 252 if (ret || enabled)253 return ret;254 255 /* clear current flags */256 return regmap_update_bits(pcf85363->regmap, CTRL_FLAGS, FLAGS_A1F, 0);257}258 259static int pcf85363_rtc_alarm_irq_enable(struct device *dev,260 unsigned int enabled)261{262 struct pcf85363 *pcf85363 = dev_get_drvdata(dev);263 264 return _pcf85363_rtc_alarm_irq_enable(pcf85363, enabled);265}266 267static int pcf85363_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)268{269 struct pcf85363 *pcf85363 = dev_get_drvdata(dev);270 unsigned char buf[DT_MONTH_ALM1 - DT_SECOND_ALM1 + 1];271 int ret;272 273 buf[0] = bin2bcd(alrm->time.tm_sec);274 buf[1] = bin2bcd(alrm->time.tm_min);275 buf[2] = bin2bcd(alrm->time.tm_hour);276 buf[3] = bin2bcd(alrm->time.tm_mday);277 buf[4] = bin2bcd(alrm->time.tm_mon + 1);278 279 /*280 * Disable the alarm interrupt before changing the value to avoid281 * spurious interrupts282 */283 ret = _pcf85363_rtc_alarm_irq_enable(pcf85363, 0);284 if (ret)285 return ret;286 287 ret = regmap_bulk_write(pcf85363->regmap, DT_SECOND_ALM1, buf,288 sizeof(buf));289 if (ret)290 return ret;291 292 return _pcf85363_rtc_alarm_irq_enable(pcf85363, alrm->enabled);293}294 295static irqreturn_t pcf85363_rtc_handle_irq(int irq, void *dev_id)296{297 struct pcf85363 *pcf85363 = i2c_get_clientdata(dev_id);298 unsigned int flags;299 int err;300 301 err = regmap_read(pcf85363->regmap, CTRL_FLAGS, &flags);302 if (err)303 return IRQ_NONE;304 305 if (flags & FLAGS_A1F) {306 rtc_update_irq(pcf85363->rtc, 1, RTC_IRQF | RTC_AF);307 regmap_update_bits(pcf85363->regmap, CTRL_FLAGS, FLAGS_A1F, 0);308 return IRQ_HANDLED;309 }310 311 return IRQ_NONE;312}313 314static const struct rtc_class_ops rtc_ops = {315 .read_time = pcf85363_rtc_read_time,316 .set_time = pcf85363_rtc_set_time,317 .read_alarm = pcf85363_rtc_read_alarm,318 .set_alarm = pcf85363_rtc_set_alarm,319 .alarm_irq_enable = pcf85363_rtc_alarm_irq_enable,320};321 322static int pcf85363_nvram_read(void *priv, unsigned int offset, void *val,323 size_t bytes)324{325 struct pcf85363 *pcf85363 = priv;326 327 return regmap_bulk_read(pcf85363->regmap, CTRL_RAM + offset,328 val, bytes);329}330 331static int pcf85363_nvram_write(void *priv, unsigned int offset, void *val,332 size_t bytes)333{334 struct pcf85363 *pcf85363 = priv;335 336 return regmap_bulk_write(pcf85363->regmap, CTRL_RAM + offset,337 val, bytes);338}339 340static int pcf85x63_nvram_read(void *priv, unsigned int offset, void *val,341 size_t bytes)342{343 struct pcf85363 *pcf85363 = priv;344 unsigned int tmp_val;345 int ret;346 347 ret = regmap_read(pcf85363->regmap, CTRL_RAMBYTE, &tmp_val);348 (*(unsigned char *) val) = (unsigned char) tmp_val;349 350 return ret;351}352 353static int pcf85x63_nvram_write(void *priv, unsigned int offset, void *val,354 size_t bytes)355{356 struct pcf85363 *pcf85363 = priv;357 unsigned char tmp_val;358 359 tmp_val = *((unsigned char *)val);360 return regmap_write(pcf85363->regmap, CTRL_RAMBYTE,361 (unsigned int)tmp_val);362}363 364static const struct pcf85x63_config pcf_85263_config = {365 .regmap = {366 .reg_bits = 8,367 .val_bits = 8,368 .max_register = 0x2f,369 },370 .num_nvram = 1371};372 373static const struct pcf85x63_config pcf_85363_config = {374 .regmap = {375 .reg_bits = 8,376 .val_bits = 8,377 .max_register = 0x7f,378 },379 .num_nvram = 2380};381 382static int pcf85363_probe(struct i2c_client *client)383{384 struct pcf85363 *pcf85363;385 const struct pcf85x63_config *config = &pcf_85363_config;386 const void *data = of_device_get_match_data(&client->dev);387 static struct nvmem_config nvmem_cfg[] = {388 {389 .name = "pcf85x63-",390 .word_size = 1,391 .stride = 1,392 .size = 1,393 .reg_read = pcf85x63_nvram_read,394 .reg_write = pcf85x63_nvram_write,395 }, {396 .name = "pcf85363-",397 .word_size = 1,398 .stride = 1,399 .size = NVRAM_SIZE,400 .reg_read = pcf85363_nvram_read,401 .reg_write = pcf85363_nvram_write,402 },403 };404 int ret, i, err;405 bool wakeup_source;406 407 if (data)408 config = data;409 410 pcf85363 = devm_kzalloc(&client->dev, sizeof(struct pcf85363),411 GFP_KERNEL);412 if (!pcf85363)413 return -ENOMEM;414 415 pcf85363->regmap = devm_regmap_init_i2c(client, &config->regmap);416 if (IS_ERR(pcf85363->regmap)) {417 dev_err(&client->dev, "regmap allocation failed\n");418 return PTR_ERR(pcf85363->regmap);419 }420 421 i2c_set_clientdata(client, pcf85363);422 423 pcf85363->rtc = devm_rtc_allocate_device(&client->dev);424 if (IS_ERR(pcf85363->rtc))425 return PTR_ERR(pcf85363->rtc);426 427 err = pcf85363_load_capacitance(pcf85363, client->dev.of_node);428 if (err < 0)429 dev_warn(&client->dev, "failed to set xtal load capacitance: %d",430 err);431 432 pcf85363->rtc->ops = &rtc_ops;433 pcf85363->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;434 pcf85363->rtc->range_max = RTC_TIMESTAMP_END_2099;435 436 wakeup_source = device_property_read_bool(&client->dev,437 "wakeup-source");438 if (client->irq > 0 || wakeup_source) {439 regmap_write(pcf85363->regmap, CTRL_FLAGS, 0);440 regmap_update_bits(pcf85363->regmap, CTRL_PIN_IO,441 PIN_IO_INTAPM, PIN_IO_INTA_OUT);442 }443 444 if (client->irq > 0) {445 unsigned long irqflags = IRQF_TRIGGER_LOW;446 447 if (dev_fwnode(&client->dev))448 irqflags = 0;449 ret = devm_request_threaded_irq(&client->dev, client->irq,450 NULL, pcf85363_rtc_handle_irq,451 irqflags | IRQF_ONESHOT,452 "pcf85363", client);453 if (ret) {454 dev_warn(&client->dev,455 "unable to request IRQ, alarms disabled\n");456 client->irq = 0;457 }458 }459 460 if (client->irq > 0 || wakeup_source) {461 device_init_wakeup(&client->dev, true);462 set_bit(RTC_FEATURE_ALARM, pcf85363->rtc->features);463 } else {464 clear_bit(RTC_FEATURE_ALARM, pcf85363->rtc->features);465 }466 467 ret = devm_rtc_register_device(pcf85363->rtc);468 469 for (i = 0; i < config->num_nvram; i++) {470 nvmem_cfg[i].priv = pcf85363;471 devm_rtc_nvmem_register(pcf85363->rtc, &nvmem_cfg[i]);472 }473 474 return ret;475}476 477static const __maybe_unused struct of_device_id dev_ids[] = {478 { .compatible = "nxp,pcf85263", .data = &pcf_85263_config },479 { .compatible = "nxp,pcf85363", .data = &pcf_85363_config },480 { /* sentinel */ }481};482MODULE_DEVICE_TABLE(of, dev_ids);483 484static struct i2c_driver pcf85363_driver = {485 .driver = {486 .name = "pcf85363",487 .of_match_table = of_match_ptr(dev_ids),488 },489 .probe = pcf85363_probe,490};491 492module_i2c_driver(pcf85363_driver);493 494MODULE_AUTHOR("Eric Nelson");495MODULE_DESCRIPTION("pcf85263/pcf85363 I2C RTC driver");496MODULE_LICENSE("GPL");497