static int ds1305_set_time(struct device *dev, struct rtc_time *time) { struct ds1305 *ds1305 = dev_get_drvdata(dev); u8 buf[1 + DS1305_RTC_LEN]; u8 *bp = buf; dev_vdbg(dev, "%s secs=%d, mins=%d, " "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", "write", time->tm_sec, time->tm_min, time->tm_hour, time->tm_mday, time->tm_mon, time->tm_year, time->tm_wday); /* Write registers starting at the first time/date address. */ *bp++ = DS1305_WRITE | DS1305_SEC; *bp++ = bin2bcd(time->tm_sec); *bp++ = bin2bcd(time->tm_min); *bp++ = hour2bcd(ds1305->hr12, time->tm_hour); *bp++ = (time->tm_wday < 7) ? (time->tm_wday + 1) : 1; *bp++ = bin2bcd(time->tm_mday); *bp++ = bin2bcd(time->tm_mon + 1); *bp++ = bin2bcd(time->tm_year - 100); dev_dbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n", "write", buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); /* use write-then-read since dma from stack is nonportable */ return spi_write_then_read(ds1305->spi, buf, sizeof buf, NULL, 0); }
/* * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl) */ static int ds1305_set_alarm(struct device *dev, struct rtc_wkalrm *alm) { struct ds1305 *ds1305 = dev_get_drvdata(dev); struct spi_device *spi = ds1305->spi; unsigned long now, later; struct rtc_time tm; int status; u8 buf[1 + DS1305_ALM_LEN]; /* convert desired alarm to time_t */ status = rtc_tm_to_time(&alm->time, &later); if (status < 0) return status; /* Read current time as time_t */ status = ds1305_get_time(dev, &tm); if (status < 0) return status; status = rtc_tm_to_time(&tm, &now); if (status < 0) return status; /* make sure alarm fires within the next 24 hours */ if (later <= now) return -EINVAL; if ((later - now) > 24 * 60 * 60) return -EDOM; /* disable alarm if needed */ if (ds1305->ctrl[0] & DS1305_AEI0) { ds1305->ctrl[0] &= ~DS1305_AEI0; buf[0] = DS1305_WRITE | DS1305_CONTROL; buf[1] = ds1305->ctrl[0]; status = spi_write_then_read(ds1305->spi, buf, 2, NULL, 0); if (status < 0) return status; } /* write alarm */ buf[0] = DS1305_WRITE | DS1305_ALM0(DS1305_SEC); buf[1 + DS1305_SEC] = bin2bcd(alm->time.tm_sec); buf[1 + DS1305_MIN] = bin2bcd(alm->time.tm_min); buf[1 + DS1305_HOUR] = hour2bcd(ds1305->hr12, alm->time.tm_hour); buf[1 + DS1305_WDAY] = DS1305_ALM_DISABLE; dev_dbg(dev, "%s: %02x %02x %02x %02x\n", "alm0 write", buf[1 + DS1305_SEC], buf[1 + DS1305_MIN], buf[1 + DS1305_HOUR], buf[1 + DS1305_WDAY]); status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); if (status < 0) return status; /* enable alarm if requested */ if (alm->enabled) { ds1305->ctrl[0] |= DS1305_AEI0; buf[0] = DS1305_WRITE | DS1305_CONTROL; buf[1] = ds1305->ctrl[0]; status = spi_write_then_read(ds1305->spi, buf, 2, NULL, 0); } return status; }