Lines Matching +full:charge +full:- +full:ctrl +full:- +full:value
1 // SPDX-License-Identifier: GPL-2.0-only
3 * rtc-ds1305.c -- driver for DS1305 and DS1306 SPI RTC chips
21 * otherwise you're reading it. All non-bitmask values are BCD.
27 * - Need fancy "hours" encoding in 12hour mode
28 * - Don't rely on the "day-of-week" field (or tm_wday)
29 * - Are a 21st-century clock (2000 <= year < 2100)
50 * NOTE ALSO that while we could generate once-a-second IRQs (UIE), we
94 u8 ctrl[DS1305_CONTROL_LEN]; member
98 /*----------------------------------------------------------------------*/
101 * Utilities ... tolerate 12-hour AM/PM notation in case of non-Linux
116 return hour - 1; in bcd2hour()
127 hour -= 12; in hour2bcd()
133 /*----------------------------------------------------------------------*/
143 long err = -EINVAL; in ds1305_alarm_irq_enable()
146 buf[1] = ds1305->ctrl[0]; in ds1305_alarm_irq_enable()
149 if (ds1305->ctrl[0] & DS1305_AEI0) in ds1305_alarm_irq_enable()
157 err = spi_write_then_read(ds1305->spi, buf, sizeof(buf), NULL, 0); in ds1305_alarm_irq_enable()
159 ds1305->ctrl[0] = buf[1]; in ds1305_alarm_irq_enable()
177 /* Use write-then-read to get all the date/time registers in ds1305_get_time()
180 status = spi_write_then_read(ds1305->spi, &addr, sizeof(addr), in ds1305_get_time()
188 time->tm_sec = bcd2bin(buf[DS1305_SEC]); in ds1305_get_time()
189 time->tm_min = bcd2bin(buf[DS1305_MIN]); in ds1305_get_time()
190 time->tm_hour = bcd2hour(buf[DS1305_HOUR]); in ds1305_get_time()
191 time->tm_wday = buf[DS1305_WDAY] - 1; in ds1305_get_time()
192 time->tm_mday = bcd2bin(buf[DS1305_MDAY]); in ds1305_get_time()
193 time->tm_mon = bcd2bin(buf[DS1305_MON]) - 1; in ds1305_get_time()
194 time->tm_year = bcd2bin(buf[DS1305_YEAR]) + 100; in ds1305_get_time()
198 "read", time->tm_sec, time->tm_min, in ds1305_get_time()
199 time->tm_hour, time->tm_mday, in ds1305_get_time()
200 time->tm_mon, time->tm_year, time->tm_wday); in ds1305_get_time()
213 "write", time->tm_sec, time->tm_min, in ds1305_set_time()
214 time->tm_hour, time->tm_mday, in ds1305_set_time()
215 time->tm_mon, time->tm_year, time->tm_wday); in ds1305_set_time()
220 *bp++ = bin2bcd(time->tm_sec); in ds1305_set_time()
221 *bp++ = bin2bcd(time->tm_min); in ds1305_set_time()
222 *bp++ = hour2bcd(ds1305->hr12, time->tm_hour); in ds1305_set_time()
223 *bp++ = (time->tm_wday < 7) ? (time->tm_wday + 1) : 1; in ds1305_set_time()
224 *bp++ = bin2bcd(time->tm_mday); in ds1305_set_time()
225 *bp++ = bin2bcd(time->tm_mon + 1); in ds1305_set_time()
226 *bp++ = bin2bcd(time->tm_year - 100); in ds1305_set_time()
230 /* use write-then-read since dma from stack is nonportable */ in ds1305_set_time()
231 return spi_write_then_read(ds1305->spi, buf, sizeof(buf), in ds1305_set_time()
238 * - First there's the inherent raciness of getting the (partitioned)
242 * - Second there's its limited range (we could increase it a bit by
245 * - Third there's the choice of two alarms and alarm signals.
250 * - Fourth, there's also ALM1, and a second interrupt signal:
256 * same value, letting ALM1 be the wakeup event source on DS1306
259 * - Fifth, we support the polled mode (as well as possible; why not?)
264 * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl)
269 struct spi_device *spi = ds1305->spi; in ds1305_get_alarm()
281 ds1305->ctrl, sizeof(ds1305->ctrl)); in ds1305_get_alarm()
285 alm->enabled = !!(ds1305->ctrl[0] & DS1305_AEI0); in ds1305_get_alarm()
286 alm->pending = !!(ds1305->ctrl[1] & DS1305_AEI0); in ds1305_get_alarm()
302 return -EIO; in ds1305_get_alarm()
304 /* Stuff these values into alm->time and let RTC framework code in ds1305_get_alarm()
308 alm->time.tm_sec = bcd2bin(buf[DS1305_SEC]); in ds1305_get_alarm()
309 alm->time.tm_min = bcd2bin(buf[DS1305_MIN]); in ds1305_get_alarm()
310 alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]); in ds1305_get_alarm()
316 * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl)
321 struct spi_device *spi = ds1305->spi; in ds1305_set_alarm()
328 later = rtc_tm_to_time64(&alm->time); in ds1305_set_alarm()
338 return -EINVAL; in ds1305_set_alarm()
339 if ((later - now) > 24 * 60 * 60) in ds1305_set_alarm()
340 return -EDOM; in ds1305_set_alarm()
343 if (ds1305->ctrl[0] & DS1305_AEI0) { in ds1305_set_alarm()
344 ds1305->ctrl[0] &= ~DS1305_AEI0; in ds1305_set_alarm()
347 buf[1] = ds1305->ctrl[0]; in ds1305_set_alarm()
348 status = spi_write_then_read(ds1305->spi, buf, 2, NULL, 0); in ds1305_set_alarm()
355 buf[1 + DS1305_SEC] = bin2bcd(alm->time.tm_sec); in ds1305_set_alarm()
356 buf[1 + DS1305_MIN] = bin2bcd(alm->time.tm_min); in ds1305_set_alarm()
357 buf[1 + DS1305_HOUR] = hour2bcd(ds1305->hr12, alm->time.tm_hour); in ds1305_set_alarm()
369 if (alm->enabled) { in ds1305_set_alarm()
370 ds1305->ctrl[0] |= DS1305_AEI0; in ds1305_set_alarm()
373 buf[1] = ds1305->ctrl[0]; in ds1305_set_alarm()
374 status = spi_write_then_read(ds1305->spi, buf, 2, NULL, 0); in ds1305_set_alarm()
388 /* ctrl[2] is treated as read-only; no locking needed */ in ds1305_proc()
389 if ((ds1305->ctrl[2] & 0xf0) == DS1305_TRICKLE_MAGIC) { in ds1305_proc()
390 switch (ds1305->ctrl[2] & 0x0c) { in ds1305_proc()
400 switch (ds1305->ctrl[2] & 0x03) { in ds1305_proc()
438 struct mutex *lock = &ds1305->rtc->ops_lock; in ds1305_work()
439 struct spi_device *spi = ds1305->spi; in ds1305_work()
443 /* lock to protect ds1305->ctrl */ in ds1305_work()
450 ds1305->ctrl[0] &= ~(DS1305_AEI1 | DS1305_AEI0); in ds1305_work()
451 ds1305->ctrl[1] = 0; in ds1305_work()
454 buf[1] = ds1305->ctrl[0]; in ds1305_work()
460 dev_dbg(&spi->dev, "clear irq --> %d\n", status); in ds1305_work()
464 if (!test_bit(FLAG_EXITING, &ds1305->flags)) in ds1305_work()
465 enable_irq(spi->irq); in ds1305_work()
467 rtc_update_irq(ds1305->rtc, 1, RTC_AF | RTC_IRQF); in ds1305_work()
472 * mutex locking for ds1305->ctrl ... unlike I2C, we could issue async
480 schedule_work(&ds1305->work); in ds1305_irq()
484 /*----------------------------------------------------------------------*/
496 x->tx_buf = addr; in msg_init()
497 x->len = 1; in msg_init()
502 x->tx_buf = tx; in msg_init()
503 x->rx_buf = rx; in msg_init()
504 x->len = count; in msg_init()
512 struct spi_device *spi = ds1305->spi; in ds1305_nvram_read()
527 struct spi_device *spi = ds1305->spi; in ds1305_nvram_write()
538 /*----------------------------------------------------------------------*/
548 u8 addr, value; in ds1305_probe() local
549 struct ds1305_platform_data *pdata = dev_get_platdata(&spi->dev); in ds1305_probe()
564 if ((spi->bits_per_word && spi->bits_per_word != 8) in ds1305_probe()
565 || (spi->max_speed_hz > 2000000) in ds1305_probe()
566 || !(spi->mode & SPI_CPHA)) in ds1305_probe()
567 return -EINVAL; in ds1305_probe()
570 ds1305 = devm_kzalloc(&spi->dev, sizeof(*ds1305), GFP_KERNEL); in ds1305_probe()
572 return -ENOMEM; in ds1305_probe()
573 ds1305->spi = spi; in ds1305_probe()
579 ds1305->ctrl, sizeof(ds1305->ctrl)); in ds1305_probe()
581 dev_dbg(&spi->dev, "can't %s, %d\n", in ds1305_probe()
586 dev_dbg(&spi->dev, "ctrl %s: %3ph\n", "read", ds1305->ctrl); in ds1305_probe()
593 if ((ds1305->ctrl[0] & 0x38) != 0 || (ds1305->ctrl[1] & 0xfc) != 0) { in ds1305_probe()
594 dev_dbg(&spi->dev, "RTC chip is not present\n"); in ds1305_probe()
595 return -ENODEV; in ds1305_probe()
597 if (ds1305->ctrl[2] == 0) in ds1305_probe()
598 dev_dbg(&spi->dev, "chip may not be present\n"); in ds1305_probe()
603 if (ds1305->ctrl[0] & DS1305_WP) { in ds1305_probe()
606 ds1305->ctrl[0] &= ~DS1305_WP; in ds1305_probe()
609 buf[1] = ds1305->ctrl[0]; in ds1305_probe()
612 dev_dbg(&spi->dev, "clear WP --> %d\n", status); in ds1305_probe()
620 if (ds1305->ctrl[0] & DS1305_nEOSC) { in ds1305_probe()
621 ds1305->ctrl[0] &= ~DS1305_nEOSC; in ds1305_probe()
623 dev_warn(&spi->dev, "SET TIME!\n"); in ds1305_probe()
627 if (ds1305->ctrl[1]) { in ds1305_probe()
628 ds1305->ctrl[1] = 0; in ds1305_probe()
632 /* this may need one-time (re)init */ in ds1305_probe()
634 /* maybe enable trickle charge */ in ds1305_probe()
635 if (((ds1305->ctrl[2] & 0xf0) != DS1305_TRICKLE_MAGIC)) { in ds1305_probe()
636 ds1305->ctrl[2] = DS1305_TRICKLE_MAGIC in ds1305_probe()
637 | pdata->trickle; in ds1305_probe()
642 if (pdata->is_ds1306) { in ds1305_probe()
643 if (pdata->en_1hz) { in ds1305_probe()
644 if (!(ds1305->ctrl[0] & DS1306_1HZ)) { in ds1305_probe()
645 ds1305->ctrl[0] |= DS1306_1HZ; in ds1305_probe()
649 if (ds1305->ctrl[0] & DS1306_1HZ) { in ds1305_probe()
650 ds1305->ctrl[0] &= ~DS1306_1HZ; in ds1305_probe()
661 buf[1] = ds1305->ctrl[0]; in ds1305_probe()
662 buf[2] = ds1305->ctrl[1]; in ds1305_probe()
663 buf[3] = ds1305->ctrl[2]; in ds1305_probe()
666 dev_dbg(&spi->dev, "can't %s, %d\n", in ds1305_probe()
671 dev_dbg(&spi->dev, "ctrl %s: %3ph\n", "write", ds1305->ctrl); in ds1305_probe()
674 /* see if non-Linux software set up AM/PM mode */ in ds1305_probe()
677 &value, sizeof(value)); in ds1305_probe()
679 dev_dbg(&spi->dev, "read HOUR --> %d\n", status); in ds1305_probe()
683 ds1305->hr12 = (DS1305_HR_12 & value) != 0; in ds1305_probe()
684 if (ds1305->hr12) in ds1305_probe()
685 dev_dbg(&spi->dev, "AM/PM\n"); in ds1305_probe()
687 /* register RTC ... from here on, ds1305->ctrl needs locking */ in ds1305_probe()
688 ds1305->rtc = devm_rtc_allocate_device(&spi->dev); in ds1305_probe()
689 if (IS_ERR(ds1305->rtc)) in ds1305_probe()
690 return PTR_ERR(ds1305->rtc); in ds1305_probe()
692 ds1305->rtc->ops = &ds1305_ops; in ds1305_probe()
693 ds1305->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; in ds1305_probe()
694 ds1305->rtc->range_max = RTC_TIMESTAMP_END_2099; in ds1305_probe()
697 ds1305->rtc->nvram_old_abi = true; in ds1305_probe()
698 status = rtc_register_device(ds1305->rtc); in ds1305_probe()
702 rtc_nvmem_register(ds1305->rtc, &ds1305_nvmem_cfg); in ds1305_probe()
710 if (spi->irq) { in ds1305_probe()
711 INIT_WORK(&ds1305->work, ds1305_work); in ds1305_probe()
712 status = devm_request_irq(&spi->dev, spi->irq, ds1305_irq, in ds1305_probe()
713 0, dev_name(&ds1305->rtc->dev), ds1305); in ds1305_probe()
715 dev_err(&spi->dev, "request_irq %d --> %d\n", in ds1305_probe()
716 spi->irq, status); in ds1305_probe()
718 device_set_wakeup_capable(&spi->dev, 1); in ds1305_probe()
730 if (spi->irq) { in ds1305_remove()
731 set_bit(FLAG_EXITING, &ds1305->flags); in ds1305_remove()
732 devm_free_irq(&spi->dev, spi->irq, ds1305); in ds1305_remove()
733 cancel_work_sync(&ds1305->work); in ds1305_remove()
740 .driver.name = "rtc-ds1305",
750 MODULE_ALIAS("spi:rtc-ds1305");