/* * Registers ... mask DS1305_WRITE into register address to write, * otherwise you're reading it. All non-bitmask values are BCD.
*/ #define DS1305_WRITE 0x80
/* RTC date/time ... the main special cases are that we: * - Need fancy "hours" encoding in 12hour mode * - Don't rely on the "day-of-week" field (or tm_wday) * - Are a 21st-century clock (2000 <= year < 2100)
*/ #define DS1305_RTC_LEN 7 /* bytes for RTC regs */
/* The two alarms have only sec/min/hour/wday fields (ALM_LEN). * DS1305_ALM_DISABLE disables a match field (some combos are bad). * * NOTE that since we don't use WDAY, we limit ourselves to alarms * only one day into the future (vs potentially up to a week). * * NOTE ALSO that while we could generate once-a-second IRQs (UIE), we * don't currently support them. We'd either need to do it only when * no alarm is pending (not the standard model), or to use the second * alarm (implying that this is a DS1305 not DS1306, *and* that either * it's wired up a second IRQ we know, or that INTCN is set)
*/ #define DS1305_ALM_LEN 4 /* bytes for ALM regs */ #define DS1305_ALM_DISABLE 0x80
/* Use write-then-read to get all the date/time registers * since dma from stack is nonportable
*/
status = spi_write_then_read(ds1305->spi, &addr, sizeof(addr),
buf, sizeof(buf)); if (status < 0) return status;
/* use write-then-read since dma from stack is nonportable */ return spi_write_then_read(ds1305->spi, buf, sizeof(buf),
NULL, 0);
}
/* * Get/set of alarm is a bit funky: * * - First there's the inherent raciness of getting the (partitioned) * status of an alarm that could trigger while we're reading parts * of that status. * * - Second there's its limited range (we could increase it a bit by * relying on WDAY), which means it will easily roll over. * * - Third there's the choice of two alarms and alarm signals. * Here we use ALM0 and expect that nINT0 (open drain) is used; * that's the only real option for DS1306 runtime alarms, and is * natural on DS1305. * * - Fourth, there's also ALM1, and a second interrupt signal: * + On DS1305 ALM1 uses nINT1 (when INTCN=1) else nINT0; * + On DS1306 ALM1 only uses INT1 (an active high pulse) * and it won't work when VCC1 is active. * * So to be most general, we should probably set both alarms to the * same value, letting ALM1 be the wakeup event source on DS1306 * and handling several wiring options on DS1305. * * - Fifth, we support the polled mode (as well as possible; why not?) * even when no interrupt line is wired to an IRQ.
*/
/* Refresh control register cache BEFORE reading ALM0 registers, * since reading alarm registers acks any pending IRQ. That * makes returning "pending" status a bit of a lie, but that bit * of EFI status is at best fragile anyway (given IRQ handlers).
*/
addr = DS1305_CONTROL;
status = spi_write_then_read(spi, &addr, sizeof(addr),
ds1305->ctrl, sizeof(ds1305->ctrl)); if (status < 0) return status;
/* Stuff these values into alm->time and let RTC framework code * fill in the rest ... and also handle rollover to tomorrow when * that's needed.
*/
alm->time.tm_sec = bcd2bin(buf[DS1305_SEC]);
alm->time.tm_min = bcd2bin(buf[DS1305_MIN]);
alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]);
/* convert desired alarm to time_t */
later = rtc_tm_to_time64(&alm->time);
/* Read current time as time_t */
status = ds1305_get_time(dev, &tm); if (status < 0) return status;
now = rtc_tm_to_time64(&tm);
/* make sure alarm fires within the next 24 hours */ if (later <= now) return -EINVAL; if ((later - now) > ds1305->rtc->alarm_offset_max) return -ERANGE;
/* disable alarm if needed */ if (ds1305->ctrl[0] & DS1305_AEI0) {
ds1305->ctrl[0] &= ~DS1305_AEI0;
/* lock to protect ds1305->ctrl */
rtc_lock(ds1305->rtc);
/* Disable the IRQ, and clear its status ... for now, we "know" * that if more than one alarm is active, they're in sync. * Note that reading ALM data registers also clears IRQ status.
*/
ds1305->ctrl[0] &= ~(DS1305_AEI1 | DS1305_AEI0);
ds1305->ctrl[1] = 0;
/* * This "real" IRQ handler hands off to a workqueue mostly to allow * mutex locking for ds1305->ctrl ... unlike I2C, we could issue async * I/O requests in IRQ context (to clear the IRQ status).
*/ static irqreturn_t ds1305_irq(int irq, void *p)
{ struct ds1305 *ds1305 = p;
/* Sanity check board setup data. This may be hooked up * in 3wire mode, but we don't care. Note that unless * there's an inverter in place, this needs SPI_CS_HIGH!
*/ if ((spi->bits_per_word && spi->bits_per_word != 8)
|| (spi->max_speed_hz > 2000000)
|| !(spi->mode & SPI_CPHA)) return -EINVAL;
/* set up driver data */
ds1305 = devm_kzalloc(&spi->dev, sizeof(*ds1305), GFP_KERNEL); if (!ds1305) return -ENOMEM;
ds1305->spi = spi;
spi_set_drvdata(spi, ds1305);
/* read and cache control registers */
addr = DS1305_CONTROL;
status = spi_write_then_read(spi, &addr, sizeof(addr),
ds1305->ctrl, sizeof(ds1305->ctrl)); if (status < 0) {
dev_dbg(&spi->dev, "can't %s, %d\n", "read", status); return status;
}
/* Sanity check register values ... partially compensating for the * fact that SPI has no device handshake. A pullup on MISO would * make these tests fail; but not all systems will have one. If * some register is neither 0x00 nor 0xff, a chip is likely there.
*/ if ((ds1305->ctrl[0] & 0x38) != 0 || (ds1305->ctrl[1] & 0xfc) != 0) {
dev_dbg(&spi->dev, "RTC chip is not present\n"); return -ENODEV;
} if (ds1305->ctrl[2] == 0)
dev_dbg(&spi->dev, "chip may not be present\n");
/* enable writes if needed ... if we were paranoid it would * make sense to enable them only when absolutely necessary.
*/ if (ds1305->ctrl[0] & DS1305_WP) {
u8 buf[2];
/* on DS1305, maybe start oscillator; like most low power * oscillators, it may take a second to stabilize
*/ if (ds1305->ctrl[0] & DS1305_nEOSC) {
ds1305->ctrl[0] &= ~DS1305_nEOSC;
write_ctrl = true;
dev_warn(&spi->dev, "SET TIME!\n");
}
/* ack any pending IRQs */ if (ds1305->ctrl[1]) {
ds1305->ctrl[1] = 0;
write_ctrl = true;
}
/* this may need one-time (re)init */ if (pdata) { /* maybe enable trickle charge */ if (((ds1305->ctrl[2] & 0xf0) != DS1305_TRICKLE_MAGIC)) {
ds1305->ctrl[2] = DS1305_TRICKLE_MAGIC
| pdata->trickle;
write_ctrl = true;
}
/* on DS1306, configure 1 Hz signal */ if (pdata->is_ds1306) { if (pdata->en_1hz) { if (!(ds1305->ctrl[0] & DS1306_1HZ)) {
ds1305->ctrl[0] |= DS1306_1HZ;
write_ctrl = true;
}
} else { if (ds1305->ctrl[0] & DS1306_1HZ) {
ds1305->ctrl[0] &= ~DS1306_1HZ;
write_ctrl = true;
}
}
}
}
/* register RTC ... from here on, ds1305->ctrl needs locking */
ds1305->rtc = devm_rtc_allocate_device(&spi->dev); if (IS_ERR(ds1305->rtc)) return PTR_ERR(ds1305->rtc);
/* Maybe set up alarm IRQ; be ready to handle it triggering right * away. NOTE that we don't share this. The signal is active low, * and we can't ack it before a SPI message delay. We temporarily * disable the IRQ until it's acked, which lets us work with more * IRQ trigger modes (not all IRQ controllers can do falling edge).
*/ if (spi->irq) {
INIT_WORK(&ds1305->work, ds1305_work);
status = devm_request_irq(&spi->dev, spi->irq, ds1305_irq,
0, dev_name(&ds1305->rtc->dev), ds1305); if (status < 0) {
dev_err(&spi->dev, "request_irq %d --> %d\n",
spi->irq, status);
} else {
device_set_wakeup_capable(&spi->dev, 1);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.