Lines Matching +full:spi +full:- +full:rx +full:- +full:delay +full:- +full:us

2  * rtc-ds1305.c -- driver for DS1305 and DS1306 SPI RTC chips
18 #include <linux/spi/spi.h>
19 #include <linux/spi/ds1305.h>
25 * otherwise you're reading it. All non-bitmask values are BCD.
31 * - Need fancy "hours" encoding in 12hour mode
32 * - Don't rely on the "day-of-week" field (or tm_wday)
33 * - Are a 21st-century clock (2000 <= year < 2100)
54 * NOTE ALSO that while we could generate once-a-second IRQs (UIE), we
80 /* trickle bits are defined in <linux/spi/ds1305.h> */
89 struct spi_device *spi; member
102 /*----------------------------------------------------------------------*/
105 * Utilities ... tolerate 12-hour AM/PM notation in case of non-Linux
120 return hour - 1; in bcd2hour()
131 hour -= 12; in hour2bcd()
137 /*----------------------------------------------------------------------*/
147 long err = -EINVAL; in ds1305_alarm_irq_enable()
150 buf[1] = ds1305->ctrl[0]; in ds1305_alarm_irq_enable()
153 if (ds1305->ctrl[0] & DS1305_AEI0) in ds1305_alarm_irq_enable()
161 err = spi_write_then_read(ds1305->spi, buf, sizeof buf, NULL, 0); in ds1305_alarm_irq_enable()
163 ds1305->ctrl[0] = buf[1]; in ds1305_alarm_irq_enable()
181 /* Use write-then-read to get all the date/time registers in ds1305_get_time()
184 status = spi_write_then_read(ds1305->spi, &addr, sizeof addr, in ds1305_get_time()
194 time->tm_sec = bcd2bin(buf[DS1305_SEC]); in ds1305_get_time()
195 time->tm_min = bcd2bin(buf[DS1305_MIN]); in ds1305_get_time()
196 time->tm_hour = bcd2hour(buf[DS1305_HOUR]); in ds1305_get_time()
197 time->tm_wday = buf[DS1305_WDAY] - 1; in ds1305_get_time()
198 time->tm_mday = bcd2bin(buf[DS1305_MDAY]); in ds1305_get_time()
199 time->tm_mon = bcd2bin(buf[DS1305_MON]) - 1; in ds1305_get_time()
200 time->tm_year = bcd2bin(buf[DS1305_YEAR]) + 100; in ds1305_get_time()
204 "read", time->tm_sec, time->tm_min, in ds1305_get_time()
205 time->tm_hour, time->tm_mday, in ds1305_get_time()
206 time->tm_mon, time->tm_year, time->tm_wday); in ds1305_get_time()
220 "write", time->tm_sec, time->tm_min, in ds1305_set_time()
221 time->tm_hour, time->tm_mday, in ds1305_set_time()
222 time->tm_mon, time->tm_year, time->tm_wday); in ds1305_set_time()
227 *bp++ = bin2bcd(time->tm_sec); in ds1305_set_time()
228 *bp++ = bin2bcd(time->tm_min); in ds1305_set_time()
229 *bp++ = hour2bcd(ds1305->hr12, time->tm_hour); in ds1305_set_time()
230 *bp++ = (time->tm_wday < 7) ? (time->tm_wday + 1) : 1; in ds1305_set_time()
231 *bp++ = bin2bcd(time->tm_mday); in ds1305_set_time()
232 *bp++ = bin2bcd(time->tm_mon + 1); in ds1305_set_time()
233 *bp++ = bin2bcd(time->tm_year - 100); in ds1305_set_time()
239 /* use write-then-read since dma from stack is nonportable */ in ds1305_set_time()
240 return spi_write_then_read(ds1305->spi, buf, sizeof buf, in ds1305_set_time()
247 * - First there's the inherent raciness of getting the (partitioned)
251 * - Second there's its limited range (we could increase it a bit by
254 * - Third there's the choice of two alarms and alarm signals.
259 * - Fourth, there's also ALM1, and a second interrupt signal:
268 * - Fifth, we support the polled mode (as well as possible; why not?)
273 * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl)
278 struct spi_device *spi = ds1305->spi; in ds1305_get_alarm() local
289 status = spi_write_then_read(spi, &addr, sizeof addr, in ds1305_get_alarm()
290 ds1305->ctrl, sizeof ds1305->ctrl); in ds1305_get_alarm()
294 alm->enabled = !!(ds1305->ctrl[0] & DS1305_AEI0); in ds1305_get_alarm()
295 alm->pending = !!(ds1305->ctrl[1] & DS1305_AEI0); in ds1305_get_alarm()
299 status = spi_write_then_read(spi, &addr, sizeof addr, in ds1305_get_alarm()
311 return -EIO; in ds1305_get_alarm()
313 /* Stuff these values into alm->time and let RTC framework code in ds1305_get_alarm()
317 alm->time.tm_sec = bcd2bin(buf[DS1305_SEC]); in ds1305_get_alarm()
318 alm->time.tm_min = bcd2bin(buf[DS1305_MIN]); in ds1305_get_alarm()
319 alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]); in ds1305_get_alarm()
320 alm->time.tm_mday = -1; in ds1305_get_alarm()
321 alm->time.tm_mon = -1; in ds1305_get_alarm()
322 alm->time.tm_year = -1; in ds1305_get_alarm()
324 alm->time.tm_wday = -1; in ds1305_get_alarm()
325 alm->time.tm_mday = -1; in ds1305_get_alarm()
326 alm->time.tm_isdst = -1; in ds1305_get_alarm()
332 * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl)
337 struct spi_device *spi = ds1305->spi; in ds1305_set_alarm() local
344 status = rtc_tm_to_time(&alm->time, &later); in ds1305_set_alarm()
358 return -EINVAL; in ds1305_set_alarm()
359 if ((later - now) > 24 * 60 * 60) in ds1305_set_alarm()
360 return -EDOM; in ds1305_set_alarm()
363 if (ds1305->ctrl[0] & DS1305_AEI0) { in ds1305_set_alarm()
364 ds1305->ctrl[0] &= ~DS1305_AEI0; in ds1305_set_alarm()
367 buf[1] = ds1305->ctrl[0]; in ds1305_set_alarm()
368 status = spi_write_then_read(ds1305->spi, buf, 2, NULL, 0); in ds1305_set_alarm()
375 buf[1 + DS1305_SEC] = bin2bcd(alm->time.tm_sec); in ds1305_set_alarm()
376 buf[1 + DS1305_MIN] = bin2bcd(alm->time.tm_min); in ds1305_set_alarm()
377 buf[1 + DS1305_HOUR] = hour2bcd(ds1305->hr12, alm->time.tm_hour); in ds1305_set_alarm()
384 status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); in ds1305_set_alarm()
389 if (alm->enabled) { in ds1305_set_alarm()
390 ds1305->ctrl[0] |= DS1305_AEI0; in ds1305_set_alarm()
393 buf[1] = ds1305->ctrl[0]; in ds1305_set_alarm()
394 status = spi_write_then_read(ds1305->spi, buf, 2, NULL, 0); in ds1305_set_alarm()
408 /* ctrl[2] is treated as read-only; no locking needed */ in ds1305_proc()
409 if ((ds1305->ctrl[2] & 0xf0) == DS1305_TRICKLE_MAGIC) { in ds1305_proc()
410 switch (ds1305->ctrl[2] & 0x0c) { in ds1305_proc()
420 switch (ds1305->ctrl[2] & 0x03) { in ds1305_proc()
458 struct mutex *lock = &ds1305->rtc->ops_lock; in ds1305_work()
459 struct spi_device *spi = ds1305->spi; in ds1305_work() local
463 /* lock to protect ds1305->ctrl */ in ds1305_work()
470 ds1305->ctrl[0] &= ~(DS1305_AEI1 | DS1305_AEI0); in ds1305_work()
471 ds1305->ctrl[1] = 0; in ds1305_work()
474 buf[1] = ds1305->ctrl[0]; in ds1305_work()
477 status = spi_write_then_read(spi, buf, sizeof buf, in ds1305_work()
480 dev_dbg(&spi->dev, "clear irq --> %d\n", status); in ds1305_work()
484 if (!test_bit(FLAG_EXITING, &ds1305->flags)) in ds1305_work()
485 enable_irq(spi->irq); in ds1305_work()
487 rtc_update_irq(ds1305->rtc, 1, RTC_AF | RTC_IRQF); in ds1305_work()
492 * mutex locking for ds1305->ctrl ... unlike I2C, we could issue async
500 schedule_work(&ds1305->work); in ds1305_irq()
504 /*----------------------------------------------------------------------*/
511 u8 *addr, size_t count, char *tx, char *rx) in msg_init() argument
516 x->tx_buf = addr; in msg_init()
517 x->len = 1; in msg_init()
522 x->tx_buf = tx; in msg_init()
523 x->rx_buf = rx; in msg_init()
524 x->len = count; in msg_init()
533 struct spi_device *spi; in ds1305_nvram_read() local
539 spi = container_of(kobj, struct spi_device, dev.kobj); in ds1305_nvram_read()
546 count = DS1305_NVRAM_LEN - off; in ds1305_nvram_read()
553 status = spi_sync(spi, &m); in ds1305_nvram_read()
555 dev_err(&spi->dev, "nvram %s error %d\n", "read", status); in ds1305_nvram_read()
564 struct spi_device *spi; in ds1305_nvram_write() local
570 spi = container_of(kobj, struct spi_device, dev.kobj); in ds1305_nvram_write()
573 return -EFBIG; in ds1305_nvram_write()
577 count = DS1305_NVRAM_LEN - off; in ds1305_nvram_write()
584 status = spi_sync(spi, &m); in ds1305_nvram_write()
586 dev_err(&spi->dev, "nvram %s error %d\n", "write", status); in ds1305_nvram_write()
598 /*----------------------------------------------------------------------*/
601 * Interface to SPI stack
604 static int __devinit ds1305_probe(struct spi_device *spi) in ds1305_probe() argument
609 struct ds1305_platform_data *pdata = spi->dev.platform_data; in ds1305_probe()
616 if ((spi->bits_per_word && spi->bits_per_word != 8) in ds1305_probe()
617 || (spi->max_speed_hz > 2000000) in ds1305_probe()
618 || !(spi->mode & SPI_CPHA)) in ds1305_probe()
619 return -EINVAL; in ds1305_probe()
624 return -ENOMEM; in ds1305_probe()
625 ds1305->spi = spi; in ds1305_probe()
626 spi_set_drvdata(spi, ds1305); in ds1305_probe()
630 status = spi_write_then_read(spi, &addr, sizeof addr, in ds1305_probe()
631 ds1305->ctrl, sizeof ds1305->ctrl); in ds1305_probe()
633 dev_dbg(&spi->dev, "can't %s, %d\n", in ds1305_probe()
638 dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n", in ds1305_probe()
639 "read", ds1305->ctrl[0], in ds1305_probe()
640 ds1305->ctrl[1], ds1305->ctrl[2]); in ds1305_probe()
643 * fact that SPI has no device handshake. A pullup on MISO would in ds1305_probe()
647 if ((ds1305->ctrl[0] & 0x38) != 0 || (ds1305->ctrl[1] & 0xfc) != 0) { in ds1305_probe()
648 dev_dbg(&spi->dev, "RTC chip is not present\n"); in ds1305_probe()
649 status = -ENODEV; in ds1305_probe()
652 if (ds1305->ctrl[2] == 0) in ds1305_probe()
653 dev_dbg(&spi->dev, "chip may not be present\n"); in ds1305_probe()
658 if (ds1305->ctrl[0] & DS1305_WP) { in ds1305_probe()
661 ds1305->ctrl[0] &= ~DS1305_WP; in ds1305_probe()
664 buf[1] = ds1305->ctrl[0]; in ds1305_probe()
665 status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); in ds1305_probe()
667 dev_dbg(&spi->dev, "clear WP --> %d\n", status); in ds1305_probe()
675 if (ds1305->ctrl[0] & DS1305_nEOSC) { in ds1305_probe()
676 ds1305->ctrl[0] &= ~DS1305_nEOSC; in ds1305_probe()
678 dev_warn(&spi->dev, "SET TIME!\n"); in ds1305_probe()
682 if (ds1305->ctrl[1]) { in ds1305_probe()
683 ds1305->ctrl[1] = 0; in ds1305_probe()
687 /* this may need one-time (re)init */ in ds1305_probe()
690 if (((ds1305->ctrl[2] & 0xf0) != DS1305_TRICKLE_MAGIC)) { in ds1305_probe()
691 ds1305->ctrl[2] = DS1305_TRICKLE_MAGIC in ds1305_probe()
692 | pdata->trickle; in ds1305_probe()
697 if (pdata->is_ds1306) { in ds1305_probe()
698 if (pdata->en_1hz) { in ds1305_probe()
699 if (!(ds1305->ctrl[0] & DS1306_1HZ)) { in ds1305_probe()
700 ds1305->ctrl[0] |= DS1306_1HZ; in ds1305_probe()
704 if (ds1305->ctrl[0] & DS1306_1HZ) { in ds1305_probe()
705 ds1305->ctrl[0] &= ~DS1306_1HZ; in ds1305_probe()
716 buf[1] = ds1305->ctrl[0]; in ds1305_probe()
717 buf[2] = ds1305->ctrl[1]; in ds1305_probe()
718 buf[3] = ds1305->ctrl[2]; in ds1305_probe()
719 status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); in ds1305_probe()
721 dev_dbg(&spi->dev, "can't %s, %d\n", in ds1305_probe()
726 dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n", in ds1305_probe()
727 "write", ds1305->ctrl[0], in ds1305_probe()
728 ds1305->ctrl[1], ds1305->ctrl[2]); in ds1305_probe()
731 /* see if non-Linux software set up AM/PM mode */ in ds1305_probe()
733 status = spi_write_then_read(spi, &addr, sizeof addr, in ds1305_probe()
736 dev_dbg(&spi->dev, "read HOUR --> %d\n", status); in ds1305_probe()
740 ds1305->hr12 = (DS1305_HR_12 & value) != 0; in ds1305_probe()
741 if (ds1305->hr12) in ds1305_probe()
742 dev_dbg(&spi->dev, "AM/PM\n"); in ds1305_probe()
744 /* register RTC ... from here on, ds1305->ctrl needs locking */ in ds1305_probe()
745 ds1305->rtc = rtc_device_register("ds1305", &spi->dev, in ds1305_probe()
747 if (IS_ERR(ds1305->rtc)) { in ds1305_probe()
748 status = PTR_ERR(ds1305->rtc); in ds1305_probe()
749 dev_dbg(&spi->dev, "register rtc --> %d\n", status); in ds1305_probe()
755 * and we can't ack it before a SPI message delay. We temporarily in ds1305_probe()
756 * disable the IRQ until it's acked, which lets us work with more in ds1305_probe()
759 if (spi->irq) { in ds1305_probe()
760 INIT_WORK(&ds1305->work, ds1305_work); in ds1305_probe()
761 status = request_irq(spi->irq, ds1305_irq, in ds1305_probe()
762 0, dev_name(&ds1305->rtc->dev), ds1305); in ds1305_probe()
764 dev_dbg(&spi->dev, "request_irq %d --> %d\n", in ds1305_probe()
765 spi->irq, status); in ds1305_probe()
769 device_set_wakeup_capable(&spi->dev, 1); in ds1305_probe()
773 status = sysfs_create_bin_file(&spi->dev.kobj, &nvram); in ds1305_probe()
775 dev_dbg(&spi->dev, "register nvram --> %d\n", status); in ds1305_probe()
782 free_irq(spi->irq, ds1305); in ds1305_probe()
784 rtc_device_unregister(ds1305->rtc); in ds1305_probe()
790 static int __devexit ds1305_remove(struct spi_device *spi) in ds1305_remove() argument
792 struct ds1305 *ds1305 = spi_get_drvdata(spi); in ds1305_remove()
794 sysfs_remove_bin_file(&spi->dev.kobj, &nvram); in ds1305_remove()
797 if (spi->irq) { in ds1305_remove()
798 set_bit(FLAG_EXITING, &ds1305->flags); in ds1305_remove()
799 free_irq(spi->irq, ds1305); in ds1305_remove()
800 cancel_work_sync(&ds1305->work); in ds1305_remove()
803 rtc_device_unregister(ds1305->rtc); in ds1305_remove()
804 spi_set_drvdata(spi, NULL); in ds1305_remove()
810 .driver.name = "rtc-ds1305",
831 MODULE_ALIAS("spi:rtc-ds1305");