Lines Matching +full:battery +full:- +full:backed
1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright 2013 Til-Technologies
6 * Author: Renaud Cerrato <r.cerrato@til-technologies.fr>
79 * PCF2127 has 512 bytes general-purpose static RAM (SRAM) that is
80 * battery backed and can survive a power outage.
101 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
113 ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_CTRL3, in pcf2127_rtc_read_time()
115 ARRAY_SIZE(buf) - PCF2127_REG_CTRL3); in pcf2127_rtc_read_time()
123 "low voltage detected, check/replace RTC battery.\n"); in pcf2127_rtc_read_time()
133 return -EINVAL; in pcf2127_rtc_read_time()
144 tm->tm_sec = bcd2bin(buf[PCF2127_REG_SC] & 0x7F); in pcf2127_rtc_read_time()
145 tm->tm_min = bcd2bin(buf[PCF2127_REG_MN] & 0x7F); in pcf2127_rtc_read_time()
146 tm->tm_hour = bcd2bin(buf[PCF2127_REG_HR] & 0x3F); /* rtc hr 0-23 */ in pcf2127_rtc_read_time()
147 tm->tm_mday = bcd2bin(buf[PCF2127_REG_DM] & 0x3F); in pcf2127_rtc_read_time()
148 tm->tm_wday = buf[PCF2127_REG_DW] & 0x07; in pcf2127_rtc_read_time()
149 tm->tm_mon = bcd2bin(buf[PCF2127_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */ in pcf2127_rtc_read_time()
150 tm->tm_year = bcd2bin(buf[PCF2127_REG_YR]); in pcf2127_rtc_read_time()
151 tm->tm_year += 100; in pcf2127_rtc_read_time()
156 tm->tm_sec, tm->tm_min, tm->tm_hour, in pcf2127_rtc_read_time()
157 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); in pcf2127_rtc_read_time()
171 tm->tm_sec, tm->tm_min, tm->tm_hour, in pcf2127_rtc_set_time()
172 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); in pcf2127_rtc_set_time()
175 buf[i++] = bin2bcd(tm->tm_sec); /* this will also clear OSF flag */ in pcf2127_rtc_set_time()
176 buf[i++] = bin2bcd(tm->tm_min); in pcf2127_rtc_set_time()
177 buf[i++] = bin2bcd(tm->tm_hour); in pcf2127_rtc_set_time()
178 buf[i++] = bin2bcd(tm->tm_mday); in pcf2127_rtc_set_time()
179 buf[i++] = tm->tm_wday & 0x07; in pcf2127_rtc_set_time()
181 /* month, 1 - 12 */ in pcf2127_rtc_set_time()
182 buf[i++] = bin2bcd(tm->tm_mon + 1); in pcf2127_rtc_set_time()
185 buf[i++] = bin2bcd(tm->tm_year - 100); in pcf2127_rtc_set_time()
188 err = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_SC, buf, i); in pcf2127_rtc_set_time()
207 ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL3, &val); in pcf2127_rtc_ioctl()
220 return regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL3, in pcf2127_rtc_ioctl()
224 return -ENOIOCTLCMD; in pcf2127_rtc_ioctl()
241 ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_ADDR_MSB, in pcf2127_nvmem_read()
246 return regmap_bulk_read(pcf2127->regmap, PCF2127_REG_RAM_RD_CMD, in pcf2127_nvmem_read()
257 ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_ADDR_MSB, in pcf2127_nvmem_write()
262 return regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_WRT_CMD, in pcf2127_nvmem_write()
272 return regmap_write(pcf2127->regmap, PCF2127_REG_WD_VAL, wdd->timeout); in pcf2127_wdt_ping()
289 dev_err(wdd->parent, in pcf2127_wdt_active_ping()
306 return regmap_write(pcf2127->regmap, PCF2127_REG_WD_VAL, in pcf2127_wdt_stop()
313 dev_dbg(wdd->parent, "new watchdog timeout: %is (old: %is)\n", in pcf2127_wdt_set_timeout()
314 new_timeout, wdd->timeout); in pcf2127_wdt_set_timeout()
316 wdd->timeout = new_timeout; in pcf2127_wdt_set_timeout()
340 !device_property_read_bool(dev, "reset-source")) in pcf2127_watchdog_init()
343 pcf2127->wdd.parent = dev; in pcf2127_watchdog_init()
344 pcf2127->wdd.info = &pcf2127_wdt_info; in pcf2127_watchdog_init()
345 pcf2127->wdd.ops = &pcf2127_watchdog_ops; in pcf2127_watchdog_init()
346 pcf2127->wdd.min_timeout = PCF2127_WD_VAL_MIN; in pcf2127_watchdog_init()
347 pcf2127->wdd.max_timeout = PCF2127_WD_VAL_MAX; in pcf2127_watchdog_init()
348 pcf2127->wdd.timeout = PCF2127_WD_VAL_DEFAULT; in pcf2127_watchdog_init()
349 pcf2127->wdd.min_hw_heartbeat_ms = 500; in pcf2127_watchdog_init()
350 pcf2127->wdd.status = WATCHDOG_NOWAYOUT_INIT_STATUS; in pcf2127_watchdog_init()
352 watchdog_set_drvdata(&pcf2127->wdd, pcf2127); in pcf2127_watchdog_init()
355 ret = regmap_read(pcf2127->regmap, PCF2127_REG_WD_VAL, &wdd_timeout); in pcf2127_watchdog_init()
360 set_bit(WDOG_HW_RUNNING, &pcf2127->wdd.status); in pcf2127_watchdog_init()
362 return devm_watchdog_register_device(dev, &pcf2127->wdd); in pcf2127_watchdog_init()
373 ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL2, &ctrl2); in pcf2127_rtc_read_alarm()
377 ret = pcf2127_wdt_active_ping(&pcf2127->wdd); in pcf2127_rtc_read_alarm()
381 ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_ALARM_SC, buf, in pcf2127_rtc_read_alarm()
386 alrm->enabled = ctrl2 & PCF2127_BIT_CTRL2_AIE; in pcf2127_rtc_read_alarm()
387 alrm->pending = ctrl2 & PCF2127_BIT_CTRL2_AF; in pcf2127_rtc_read_alarm()
389 alrm->time.tm_sec = bcd2bin(buf[0] & 0x7F); in pcf2127_rtc_read_alarm()
390 alrm->time.tm_min = bcd2bin(buf[1] & 0x7F); in pcf2127_rtc_read_alarm()
391 alrm->time.tm_hour = bcd2bin(buf[2] & 0x3F); in pcf2127_rtc_read_alarm()
392 alrm->time.tm_mday = bcd2bin(buf[3] & 0x3F); in pcf2127_rtc_read_alarm()
402 ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL2, in pcf2127_rtc_alarm_irq_enable()
408 return pcf2127_wdt_active_ping(&pcf2127->wdd); in pcf2127_rtc_alarm_irq_enable()
417 ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL2, in pcf2127_rtc_set_alarm()
422 ret = pcf2127_wdt_active_ping(&pcf2127->wdd); in pcf2127_rtc_set_alarm()
426 buf[0] = bin2bcd(alrm->time.tm_sec); in pcf2127_rtc_set_alarm()
427 buf[1] = bin2bcd(alrm->time.tm_min); in pcf2127_rtc_set_alarm()
428 buf[2] = bin2bcd(alrm->time.tm_hour); in pcf2127_rtc_set_alarm()
429 buf[3] = bin2bcd(alrm->time.tm_mday); in pcf2127_rtc_set_alarm()
432 ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_ALARM_SC, buf, in pcf2127_rtc_set_alarm()
437 return pcf2127_rtc_alarm_irq_enable(dev, alrm->enabled); in pcf2127_rtc_set_alarm()
446 ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL2, &ctrl2); in pcf2127_rtc_irq()
453 regmap_write(pcf2127->regmap, PCF2127_REG_CTRL2, in pcf2127_rtc_irq()
456 rtc_update_irq(pcf2127->rtc, 1, RTC_IRQF | RTC_AF); in pcf2127_rtc_irq()
458 pcf2127_wdt_active_ping(&pcf2127->wdd); in pcf2127_rtc_irq()
478 struct pcf2127 *pcf2127 = dev_get_drvdata(dev->parent); in timestamp0_store()
481 ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL1, in timestamp0_store()
488 ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL2, in timestamp0_store()
495 ret = pcf2127_wdt_active_ping(&pcf2127->wdd); in timestamp0_store()
505 struct pcf2127 *pcf2127 = dev_get_drvdata(dev->parent); in timestamp0_show()
510 ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_CTRL1, data, in timestamp0_show()
526 ret = pcf2127_wdt_active_ping(&pcf2127->wdd); in timestamp0_show()
538 /* TS_MO register (month) value range: 1-12 */ in timestamp0_show()
539 tm.tm_mon = bcd2bin(data[PCF2127_REG_TS_MO] & 0x1F) - 1; in timestamp0_show()
573 return -ENOMEM; in pcf2127_probe()
575 pcf2127->regmap = regmap; in pcf2127_probe()
579 pcf2127->rtc = devm_rtc_allocate_device(dev); in pcf2127_probe()
580 if (IS_ERR(pcf2127->rtc)) in pcf2127_probe()
581 return PTR_ERR(pcf2127->rtc); in pcf2127_probe()
583 pcf2127->rtc->ops = &pcf2127_rtc_ops; in pcf2127_probe()
584 pcf2127->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; in pcf2127_probe()
585 pcf2127->rtc->range_max = RTC_TIMESTAMP_END_2099; in pcf2127_probe()
586 pcf2127->rtc->set_start_time = true; /* Sets actual start to 1970 */ in pcf2127_probe()
587 pcf2127->rtc->uie_unsupported = 1; in pcf2127_probe()
600 if (alarm_irq > 0 || device_property_read_bool(dev, "wakeup-source")) { in pcf2127_probe()
602 pcf2127->rtc->ops = &pcf2127_rtc_alrm_ops; in pcf2127_probe()
613 ret = rtc_nvmem_register(pcf2127->rtc, &nvmem_cfg); in pcf2127_probe()
621 ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_WD_CTL, in pcf2127_probe()
637 * Disable battery low/switch-over timestamp and interrupts. in pcf2127_probe()
638 * Clear battery interrupt flags which can block new trigger events. in pcf2127_probe()
642 ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL3, in pcf2127_probe()
656 ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_TS_CTRL, in pcf2127_probe()
668 * are set. Interrupt signal is an open-drain output and can be in pcf2127_probe()
671 ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL2, in pcf2127_probe()
680 ret = rtc_add_group(pcf2127->rtc, &pcf2127_attr_group); in pcf2127_probe()
687 return rtc_register_device(pcf2127->rtc); in pcf2127_probe()
710 return ret < 0 ? ret : -EIO; in pcf2127_i2c_write()
725 return -EINVAL; in pcf2127_i2c_gather_write()
729 return -ENOMEM; in pcf2127_i2c_gather_write()
739 return ret < 0 ? ret : -EIO; in pcf2127_i2c_gather_write()
752 return -EINVAL; in pcf2127_i2c_read()
756 return ret < 0 ? ret : -EIO; in pcf2127_i2c_read()
760 return ret < 0 ? ret : -EIO; in pcf2127_i2c_read()
788 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) in pcf2127_i2c_probe()
789 return -ENODEV; in pcf2127_i2c_probe()
791 regmap = devm_regmap_init(&client->dev, &pcf2127_i2c_regmap, in pcf2127_i2c_probe()
792 &client->dev, &config); in pcf2127_i2c_probe()
794 dev_err(&client->dev, "%s: regmap allocation failed: %ld\n", in pcf2127_i2c_probe()
799 return pcf2127_probe(&client->dev, regmap, client->irq, in pcf2127_i2c_probe()
800 pcf2127_i2c_driver.driver.name, id->driver_data); in pcf2127_i2c_probe()
813 .name = "rtc-pcf2127-i2c",
860 dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n", in pcf2127_spi_probe()
865 return pcf2127_probe(&spi->dev, regmap, spi->irq, in pcf2127_spi_probe()
867 spi_get_device_id(spi)->driver_data); in pcf2127_spi_probe()
880 .name = "rtc-pcf2127-spi",
937 MODULE_AUTHOR("Renaud Cerrato <r.cerrato@til-technologies.fr>");