1*53e84b67SDavid Brownell /* 2*53e84b67SDavid Brownell * rtc-ds1305.c -- driver for DS1305 and DS1306 SPI RTC chips 3*53e84b67SDavid Brownell * 4*53e84b67SDavid Brownell * Copyright (C) 2008 David Brownell 5*53e84b67SDavid Brownell * 6*53e84b67SDavid Brownell * This program is free software; you can redistribute it and/or modify 7*53e84b67SDavid Brownell * it under the terms of the GNU General Public License version 2 as 8*53e84b67SDavid Brownell * published by the Free Software Foundation. 9*53e84b67SDavid Brownell * 10*53e84b67SDavid Brownell */ 11*53e84b67SDavid Brownell #include <linux/kernel.h> 12*53e84b67SDavid Brownell #include <linux/init.h> 13*53e84b67SDavid Brownell #include <linux/bcd.h> 14*53e84b67SDavid Brownell #include <linux/rtc.h> 15*53e84b67SDavid Brownell #include <linux/workqueue.h> 16*53e84b67SDavid Brownell 17*53e84b67SDavid Brownell #include <linux/spi/spi.h> 18*53e84b67SDavid Brownell #include <linux/spi/ds1305.h> 19*53e84b67SDavid Brownell 20*53e84b67SDavid Brownell 21*53e84b67SDavid Brownell /* 22*53e84b67SDavid Brownell * Registers ... mask DS1305_WRITE into register address to write, 23*53e84b67SDavid Brownell * otherwise you're reading it. All non-bitmask values are BCD. 24*53e84b67SDavid Brownell */ 25*53e84b67SDavid Brownell #define DS1305_WRITE 0x80 26*53e84b67SDavid Brownell 27*53e84b67SDavid Brownell 28*53e84b67SDavid Brownell /* RTC date/time ... the main special cases are that we: 29*53e84b67SDavid Brownell * - Need fancy "hours" encoding in 12hour mode 30*53e84b67SDavid Brownell * - Don't rely on the "day-of-week" field (or tm_wday) 31*53e84b67SDavid Brownell * - Are a 21st-century clock (2000 <= year < 2100) 32*53e84b67SDavid Brownell */ 33*53e84b67SDavid Brownell #define DS1305_RTC_LEN 7 /* bytes for RTC regs */ 34*53e84b67SDavid Brownell 35*53e84b67SDavid Brownell #define DS1305_SEC 0x00 /* register addresses */ 36*53e84b67SDavid Brownell #define DS1305_MIN 0x01 37*53e84b67SDavid Brownell #define DS1305_HOUR 0x02 38*53e84b67SDavid Brownell # define DS1305_HR_12 0x40 /* set == 12 hr mode */ 39*53e84b67SDavid Brownell # define DS1305_HR_PM 0x20 /* set == PM (12hr mode) */ 40*53e84b67SDavid Brownell #define DS1305_WDAY 0x03 41*53e84b67SDavid Brownell #define DS1305_MDAY 0x04 42*53e84b67SDavid Brownell #define DS1305_MON 0x05 43*53e84b67SDavid Brownell #define DS1305_YEAR 0x06 44*53e84b67SDavid Brownell 45*53e84b67SDavid Brownell 46*53e84b67SDavid Brownell /* The two alarms have only sec/min/hour/wday fields (ALM_LEN). 47*53e84b67SDavid Brownell * DS1305_ALM_DISABLE disables a match field (some combos are bad). 48*53e84b67SDavid Brownell * 49*53e84b67SDavid Brownell * NOTE that since we don't use WDAY, we limit ourselves to alarms 50*53e84b67SDavid Brownell * only one day into the future (vs potentially up to a week). 51*53e84b67SDavid Brownell * 52*53e84b67SDavid Brownell * NOTE ALSO that while we could generate once-a-second IRQs (UIE), we 53*53e84b67SDavid Brownell * don't currently support them. We'd either need to do it only when 54*53e84b67SDavid Brownell * no alarm is pending (not the standard model), or to use the second 55*53e84b67SDavid Brownell * alarm (implying that this is a DS1305 not DS1306, *and* that either 56*53e84b67SDavid Brownell * it's wired up a second IRQ we know, or that INTCN is set) 57*53e84b67SDavid Brownell */ 58*53e84b67SDavid Brownell #define DS1305_ALM_LEN 4 /* bytes for ALM regs */ 59*53e84b67SDavid Brownell #define DS1305_ALM_DISABLE 0x80 60*53e84b67SDavid Brownell 61*53e84b67SDavid Brownell #define DS1305_ALM0(r) (0x07 + (r)) /* register addresses */ 62*53e84b67SDavid Brownell #define DS1305_ALM1(r) (0x0b + (r)) 63*53e84b67SDavid Brownell 64*53e84b67SDavid Brownell 65*53e84b67SDavid Brownell /* three control registers */ 66*53e84b67SDavid Brownell #define DS1305_CONTROL_LEN 3 /* bytes of control regs */ 67*53e84b67SDavid Brownell 68*53e84b67SDavid Brownell #define DS1305_CONTROL 0x0f /* register addresses */ 69*53e84b67SDavid Brownell # define DS1305_nEOSC 0x80 /* low enables oscillator */ 70*53e84b67SDavid Brownell # define DS1305_WP 0x40 /* write protect */ 71*53e84b67SDavid Brownell # define DS1305_INTCN 0x04 /* clear == only int0 used */ 72*53e84b67SDavid Brownell # define DS1306_1HZ 0x04 /* enable 1Hz output */ 73*53e84b67SDavid Brownell # define DS1305_AEI1 0x02 /* enable ALM1 IRQ */ 74*53e84b67SDavid Brownell # define DS1305_AEI0 0x01 /* enable ALM0 IRQ */ 75*53e84b67SDavid Brownell #define DS1305_STATUS 0x10 76*53e84b67SDavid Brownell /* status has just AEIx bits, mirrored as IRQFx */ 77*53e84b67SDavid Brownell #define DS1305_TRICKLE 0x11 78*53e84b67SDavid Brownell /* trickle bits are defined in <linux/spi/ds1305.h> */ 79*53e84b67SDavid Brownell 80*53e84b67SDavid Brownell /* a bunch of NVRAM */ 81*53e84b67SDavid Brownell #define DS1305_NVRAM_LEN 96 /* bytes of NVRAM */ 82*53e84b67SDavid Brownell 83*53e84b67SDavid Brownell #define DS1305_NVRAM 0x20 /* register addresses */ 84*53e84b67SDavid Brownell 85*53e84b67SDavid Brownell 86*53e84b67SDavid Brownell struct ds1305 { 87*53e84b67SDavid Brownell struct spi_device *spi; 88*53e84b67SDavid Brownell struct rtc_device *rtc; 89*53e84b67SDavid Brownell 90*53e84b67SDavid Brownell struct work_struct work; 91*53e84b67SDavid Brownell 92*53e84b67SDavid Brownell unsigned long flags; 93*53e84b67SDavid Brownell #define FLAG_EXITING 0 94*53e84b67SDavid Brownell 95*53e84b67SDavid Brownell bool hr12; 96*53e84b67SDavid Brownell u8 ctrl[DS1305_CONTROL_LEN]; 97*53e84b67SDavid Brownell }; 98*53e84b67SDavid Brownell 99*53e84b67SDavid Brownell 100*53e84b67SDavid Brownell /*----------------------------------------------------------------------*/ 101*53e84b67SDavid Brownell 102*53e84b67SDavid Brownell /* 103*53e84b67SDavid Brownell * Utilities ... tolerate 12-hour AM/PM notation in case of non-Linux 104*53e84b67SDavid Brownell * software (like a bootloader) which may require it. 105*53e84b67SDavid Brownell */ 106*53e84b67SDavid Brownell 107*53e84b67SDavid Brownell static unsigned bcd2hour(u8 bcd) 108*53e84b67SDavid Brownell { 109*53e84b67SDavid Brownell if (bcd & DS1305_HR_12) { 110*53e84b67SDavid Brownell unsigned hour = 0; 111*53e84b67SDavid Brownell 112*53e84b67SDavid Brownell bcd &= ~DS1305_HR_12; 113*53e84b67SDavid Brownell if (bcd & DS1305_HR_PM) { 114*53e84b67SDavid Brownell hour = 12; 115*53e84b67SDavid Brownell bcd &= ~DS1305_HR_PM; 116*53e84b67SDavid Brownell } 117*53e84b67SDavid Brownell hour += BCD2BIN(bcd); 118*53e84b67SDavid Brownell return hour - 1; 119*53e84b67SDavid Brownell } 120*53e84b67SDavid Brownell return BCD2BIN(bcd); 121*53e84b67SDavid Brownell } 122*53e84b67SDavid Brownell 123*53e84b67SDavid Brownell static u8 hour2bcd(bool hr12, int hour) 124*53e84b67SDavid Brownell { 125*53e84b67SDavid Brownell if (hr12) { 126*53e84b67SDavid Brownell hour++; 127*53e84b67SDavid Brownell if (hour <= 12) 128*53e84b67SDavid Brownell return DS1305_HR_12 | BIN2BCD(hour); 129*53e84b67SDavid Brownell hour -= 12; 130*53e84b67SDavid Brownell return DS1305_HR_12 | DS1305_HR_PM | BIN2BCD(hour); 131*53e84b67SDavid Brownell } 132*53e84b67SDavid Brownell return BIN2BCD(hour); 133*53e84b67SDavid Brownell } 134*53e84b67SDavid Brownell 135*53e84b67SDavid Brownell /*----------------------------------------------------------------------*/ 136*53e84b67SDavid Brownell 137*53e84b67SDavid Brownell /* 138*53e84b67SDavid Brownell * Interface to RTC framework 139*53e84b67SDavid Brownell */ 140*53e84b67SDavid Brownell 141*53e84b67SDavid Brownell #ifdef CONFIG_RTC_INTF_DEV 142*53e84b67SDavid Brownell 143*53e84b67SDavid Brownell /* 144*53e84b67SDavid Brownell * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl) 145*53e84b67SDavid Brownell */ 146*53e84b67SDavid Brownell static int ds1305_ioctl(struct device *dev, unsigned cmd, unsigned long arg) 147*53e84b67SDavid Brownell { 148*53e84b67SDavid Brownell struct ds1305 *ds1305 = dev_get_drvdata(dev); 149*53e84b67SDavid Brownell u8 buf[2]; 150*53e84b67SDavid Brownell int status = -ENOIOCTLCMD; 151*53e84b67SDavid Brownell 152*53e84b67SDavid Brownell buf[0] = DS1305_WRITE | DS1305_CONTROL; 153*53e84b67SDavid Brownell buf[1] = ds1305->ctrl[0]; 154*53e84b67SDavid Brownell 155*53e84b67SDavid Brownell switch (cmd) { 156*53e84b67SDavid Brownell case RTC_AIE_OFF: 157*53e84b67SDavid Brownell status = 0; 158*53e84b67SDavid Brownell if (!(buf[1] & DS1305_AEI0)) 159*53e84b67SDavid Brownell goto done; 160*53e84b67SDavid Brownell buf[1] &= ~DS1305_AEI0; 161*53e84b67SDavid Brownell break; 162*53e84b67SDavid Brownell 163*53e84b67SDavid Brownell case RTC_AIE_ON: 164*53e84b67SDavid Brownell status = 0; 165*53e84b67SDavid Brownell if (ds1305->ctrl[0] & DS1305_AEI0) 166*53e84b67SDavid Brownell goto done; 167*53e84b67SDavid Brownell buf[1] |= DS1305_AEI0; 168*53e84b67SDavid Brownell break; 169*53e84b67SDavid Brownell } 170*53e84b67SDavid Brownell if (status == 0) { 171*53e84b67SDavid Brownell status = spi_write_then_read(ds1305->spi, buf, sizeof buf, 172*53e84b67SDavid Brownell NULL, 0); 173*53e84b67SDavid Brownell if (status >= 0) 174*53e84b67SDavid Brownell ds1305->ctrl[0] = buf[1]; 175*53e84b67SDavid Brownell } 176*53e84b67SDavid Brownell 177*53e84b67SDavid Brownell done: 178*53e84b67SDavid Brownell return status; 179*53e84b67SDavid Brownell } 180*53e84b67SDavid Brownell 181*53e84b67SDavid Brownell #else 182*53e84b67SDavid Brownell #define ds1305_ioctl NULL 183*53e84b67SDavid Brownell #endif 184*53e84b67SDavid Brownell 185*53e84b67SDavid Brownell /* 186*53e84b67SDavid Brownell * Get/set of date and time is pretty normal. 187*53e84b67SDavid Brownell */ 188*53e84b67SDavid Brownell 189*53e84b67SDavid Brownell static int ds1305_get_time(struct device *dev, struct rtc_time *time) 190*53e84b67SDavid Brownell { 191*53e84b67SDavid Brownell struct ds1305 *ds1305 = dev_get_drvdata(dev); 192*53e84b67SDavid Brownell u8 addr = DS1305_SEC; 193*53e84b67SDavid Brownell u8 buf[DS1305_RTC_LEN]; 194*53e84b67SDavid Brownell int status; 195*53e84b67SDavid Brownell 196*53e84b67SDavid Brownell /* Use write-then-read to get all the date/time registers 197*53e84b67SDavid Brownell * since dma from stack is nonportable 198*53e84b67SDavid Brownell */ 199*53e84b67SDavid Brownell status = spi_write_then_read(ds1305->spi, &addr, sizeof addr, 200*53e84b67SDavid Brownell buf, sizeof buf); 201*53e84b67SDavid Brownell if (status < 0) 202*53e84b67SDavid Brownell return status; 203*53e84b67SDavid Brownell 204*53e84b67SDavid Brownell dev_vdbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n", 205*53e84b67SDavid Brownell "read", buf[0], buf[1], buf[2], buf[3], 206*53e84b67SDavid Brownell buf[4], buf[5], buf[6]); 207*53e84b67SDavid Brownell 208*53e84b67SDavid Brownell /* Decode the registers */ 209*53e84b67SDavid Brownell time->tm_sec = BCD2BIN(buf[DS1305_SEC]); 210*53e84b67SDavid Brownell time->tm_min = BCD2BIN(buf[DS1305_MIN]); 211*53e84b67SDavid Brownell time->tm_hour = bcd2hour(buf[DS1305_HOUR]); 212*53e84b67SDavid Brownell time->tm_wday = buf[DS1305_WDAY] - 1; 213*53e84b67SDavid Brownell time->tm_mday = BCD2BIN(buf[DS1305_MDAY]); 214*53e84b67SDavid Brownell time->tm_mon = BCD2BIN(buf[DS1305_MON]) - 1; 215*53e84b67SDavid Brownell time->tm_year = BCD2BIN(buf[DS1305_YEAR]) + 100; 216*53e84b67SDavid Brownell 217*53e84b67SDavid Brownell dev_vdbg(dev, "%s secs=%d, mins=%d, " 218*53e84b67SDavid Brownell "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", 219*53e84b67SDavid Brownell "read", time->tm_sec, time->tm_min, 220*53e84b67SDavid Brownell time->tm_hour, time->tm_mday, 221*53e84b67SDavid Brownell time->tm_mon, time->tm_year, time->tm_wday); 222*53e84b67SDavid Brownell 223*53e84b67SDavid Brownell /* Time may not be set */ 224*53e84b67SDavid Brownell return rtc_valid_tm(time); 225*53e84b67SDavid Brownell } 226*53e84b67SDavid Brownell 227*53e84b67SDavid Brownell static int ds1305_set_time(struct device *dev, struct rtc_time *time) 228*53e84b67SDavid Brownell { 229*53e84b67SDavid Brownell struct ds1305 *ds1305 = dev_get_drvdata(dev); 230*53e84b67SDavid Brownell u8 buf[1 + DS1305_RTC_LEN]; 231*53e84b67SDavid Brownell u8 *bp = buf; 232*53e84b67SDavid Brownell 233*53e84b67SDavid Brownell dev_vdbg(dev, "%s secs=%d, mins=%d, " 234*53e84b67SDavid Brownell "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", 235*53e84b67SDavid Brownell "write", time->tm_sec, time->tm_min, 236*53e84b67SDavid Brownell time->tm_hour, time->tm_mday, 237*53e84b67SDavid Brownell time->tm_mon, time->tm_year, time->tm_wday); 238*53e84b67SDavid Brownell 239*53e84b67SDavid Brownell /* Write registers starting at the first time/date address. */ 240*53e84b67SDavid Brownell *bp++ = DS1305_WRITE | DS1305_SEC; 241*53e84b67SDavid Brownell 242*53e84b67SDavid Brownell *bp++ = BIN2BCD(time->tm_sec); 243*53e84b67SDavid Brownell *bp++ = BIN2BCD(time->tm_min); 244*53e84b67SDavid Brownell *bp++ = hour2bcd(ds1305->hr12, time->tm_hour); 245*53e84b67SDavid Brownell *bp++ = (time->tm_wday < 7) ? (time->tm_wday + 1) : 1; 246*53e84b67SDavid Brownell *bp++ = BIN2BCD(time->tm_mday); 247*53e84b67SDavid Brownell *bp++ = BIN2BCD(time->tm_mon + 1); 248*53e84b67SDavid Brownell *bp++ = BIN2BCD(time->tm_year - 100); 249*53e84b67SDavid Brownell 250*53e84b67SDavid Brownell dev_dbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n", 251*53e84b67SDavid Brownell "write", buf[1], buf[2], buf[3], 252*53e84b67SDavid Brownell buf[4], buf[5], buf[6], buf[7]); 253*53e84b67SDavid Brownell 254*53e84b67SDavid Brownell /* use write-then-read since dma from stack is nonportable */ 255*53e84b67SDavid Brownell return spi_write_then_read(ds1305->spi, buf, sizeof buf, 256*53e84b67SDavid Brownell NULL, 0); 257*53e84b67SDavid Brownell } 258*53e84b67SDavid Brownell 259*53e84b67SDavid Brownell /* 260*53e84b67SDavid Brownell * Get/set of alarm is a bit funky: 261*53e84b67SDavid Brownell * 262*53e84b67SDavid Brownell * - First there's the inherent raciness of getting the (partitioned) 263*53e84b67SDavid Brownell * status of an alarm that could trigger while we're reading parts 264*53e84b67SDavid Brownell * of that status. 265*53e84b67SDavid Brownell * 266*53e84b67SDavid Brownell * - Second there's its limited range (we could increase it a bit by 267*53e84b67SDavid Brownell * relying on WDAY), which means it will easily roll over. 268*53e84b67SDavid Brownell * 269*53e84b67SDavid Brownell * - Third there's the choice of two alarms and alarm signals. 270*53e84b67SDavid Brownell * Here we use ALM0 and expect that nINT0 (open drain) is used; 271*53e84b67SDavid Brownell * that's the only real option for DS1306 runtime alarms, and is 272*53e84b67SDavid Brownell * natural on DS1305. 273*53e84b67SDavid Brownell * 274*53e84b67SDavid Brownell * - Fourth, there's also ALM1, and a second interrupt signal: 275*53e84b67SDavid Brownell * + On DS1305 ALM1 uses nINT1 (when INTCN=1) else nINT0; 276*53e84b67SDavid Brownell * + On DS1306 ALM1 only uses INT1 (an active high pulse) 277*53e84b67SDavid Brownell * and it won't work when VCC1 is active. 278*53e84b67SDavid Brownell * 279*53e84b67SDavid Brownell * So to be most general, we should probably set both alarms to the 280*53e84b67SDavid Brownell * same value, letting ALM1 be the wakeup event source on DS1306 281*53e84b67SDavid Brownell * and handling several wiring options on DS1305. 282*53e84b67SDavid Brownell * 283*53e84b67SDavid Brownell * - Fifth, we support the polled mode (as well as possible; why not?) 284*53e84b67SDavid Brownell * even when no interrupt line is wired to an IRQ. 285*53e84b67SDavid Brownell */ 286*53e84b67SDavid Brownell 287*53e84b67SDavid Brownell /* 288*53e84b67SDavid Brownell * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl) 289*53e84b67SDavid Brownell */ 290*53e84b67SDavid Brownell static int ds1305_get_alarm(struct device *dev, struct rtc_wkalrm *alm) 291*53e84b67SDavid Brownell { 292*53e84b67SDavid Brownell struct ds1305 *ds1305 = dev_get_drvdata(dev); 293*53e84b67SDavid Brownell struct spi_device *spi = ds1305->spi; 294*53e84b67SDavid Brownell u8 addr; 295*53e84b67SDavid Brownell int status; 296*53e84b67SDavid Brownell u8 buf[DS1305_ALM_LEN]; 297*53e84b67SDavid Brownell 298*53e84b67SDavid Brownell /* Refresh control register cache BEFORE reading ALM0 registers, 299*53e84b67SDavid Brownell * since reading alarm registers acks any pending IRQ. That 300*53e84b67SDavid Brownell * makes returning "pending" status a bit of a lie, but that bit 301*53e84b67SDavid Brownell * of EFI status is at best fragile anyway (given IRQ handlers). 302*53e84b67SDavid Brownell */ 303*53e84b67SDavid Brownell addr = DS1305_CONTROL; 304*53e84b67SDavid Brownell status = spi_write_then_read(spi, &addr, sizeof addr, 305*53e84b67SDavid Brownell ds1305->ctrl, sizeof ds1305->ctrl); 306*53e84b67SDavid Brownell if (status < 0) 307*53e84b67SDavid Brownell return status; 308*53e84b67SDavid Brownell 309*53e84b67SDavid Brownell alm->enabled = !!(ds1305->ctrl[0] & DS1305_AEI0); 310*53e84b67SDavid Brownell alm->pending = !!(ds1305->ctrl[1] & DS1305_AEI0); 311*53e84b67SDavid Brownell 312*53e84b67SDavid Brownell /* get and check ALM0 registers */ 313*53e84b67SDavid Brownell addr = DS1305_ALM0(DS1305_SEC); 314*53e84b67SDavid Brownell status = spi_write_then_read(spi, &addr, sizeof addr, 315*53e84b67SDavid Brownell buf, sizeof buf); 316*53e84b67SDavid Brownell if (status < 0) 317*53e84b67SDavid Brownell return status; 318*53e84b67SDavid Brownell 319*53e84b67SDavid Brownell dev_vdbg(dev, "%s: %02x %02x %02x %02x\n", 320*53e84b67SDavid Brownell "alm0 read", buf[DS1305_SEC], buf[DS1305_MIN], 321*53e84b67SDavid Brownell buf[DS1305_HOUR], buf[DS1305_WDAY]); 322*53e84b67SDavid Brownell 323*53e84b67SDavid Brownell if ((DS1305_ALM_DISABLE & buf[DS1305_SEC]) 324*53e84b67SDavid Brownell || (DS1305_ALM_DISABLE & buf[DS1305_MIN]) 325*53e84b67SDavid Brownell || (DS1305_ALM_DISABLE & buf[DS1305_HOUR])) 326*53e84b67SDavid Brownell return -EIO; 327*53e84b67SDavid Brownell 328*53e84b67SDavid Brownell /* Stuff these values into alm->time and let RTC framework code 329*53e84b67SDavid Brownell * fill in the rest ... and also handle rollover to tomorrow when 330*53e84b67SDavid Brownell * that's needed. 331*53e84b67SDavid Brownell */ 332*53e84b67SDavid Brownell alm->time.tm_sec = BCD2BIN(buf[DS1305_SEC]); 333*53e84b67SDavid Brownell alm->time.tm_min = BCD2BIN(buf[DS1305_MIN]); 334*53e84b67SDavid Brownell alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]); 335*53e84b67SDavid Brownell alm->time.tm_mday = -1; 336*53e84b67SDavid Brownell alm->time.tm_mon = -1; 337*53e84b67SDavid Brownell alm->time.tm_year = -1; 338*53e84b67SDavid Brownell /* next three fields are unused by Linux */ 339*53e84b67SDavid Brownell alm->time.tm_wday = -1; 340*53e84b67SDavid Brownell alm->time.tm_mday = -1; 341*53e84b67SDavid Brownell alm->time.tm_isdst = -1; 342*53e84b67SDavid Brownell 343*53e84b67SDavid Brownell return 0; 344*53e84b67SDavid Brownell } 345*53e84b67SDavid Brownell 346*53e84b67SDavid Brownell /* 347*53e84b67SDavid Brownell * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl) 348*53e84b67SDavid Brownell */ 349*53e84b67SDavid Brownell static int ds1305_set_alarm(struct device *dev, struct rtc_wkalrm *alm) 350*53e84b67SDavid Brownell { 351*53e84b67SDavid Brownell struct ds1305 *ds1305 = dev_get_drvdata(dev); 352*53e84b67SDavid Brownell struct spi_device *spi = ds1305->spi; 353*53e84b67SDavid Brownell unsigned long now, later; 354*53e84b67SDavid Brownell struct rtc_time tm; 355*53e84b67SDavid Brownell int status; 356*53e84b67SDavid Brownell u8 buf[1 + DS1305_ALM_LEN]; 357*53e84b67SDavid Brownell 358*53e84b67SDavid Brownell /* convert desired alarm to time_t */ 359*53e84b67SDavid Brownell status = rtc_tm_to_time(&alm->time, &later); 360*53e84b67SDavid Brownell if (status < 0) 361*53e84b67SDavid Brownell return status; 362*53e84b67SDavid Brownell 363*53e84b67SDavid Brownell /* Read current time as time_t */ 364*53e84b67SDavid Brownell status = ds1305_get_time(dev, &tm); 365*53e84b67SDavid Brownell if (status < 0) 366*53e84b67SDavid Brownell return status; 367*53e84b67SDavid Brownell status = rtc_tm_to_time(&tm, &now); 368*53e84b67SDavid Brownell if (status < 0) 369*53e84b67SDavid Brownell return status; 370*53e84b67SDavid Brownell 371*53e84b67SDavid Brownell /* make sure alarm fires within the next 24 hours */ 372*53e84b67SDavid Brownell if (later <= now) 373*53e84b67SDavid Brownell return -EINVAL; 374*53e84b67SDavid Brownell if ((later - now) > 24 * 60 * 60) 375*53e84b67SDavid Brownell return -EDOM; 376*53e84b67SDavid Brownell 377*53e84b67SDavid Brownell /* disable alarm if needed */ 378*53e84b67SDavid Brownell if (ds1305->ctrl[0] & DS1305_AEI0) { 379*53e84b67SDavid Brownell ds1305->ctrl[0] &= ~DS1305_AEI0; 380*53e84b67SDavid Brownell 381*53e84b67SDavid Brownell buf[0] = DS1305_WRITE | DS1305_CONTROL; 382*53e84b67SDavid Brownell buf[1] = ds1305->ctrl[0]; 383*53e84b67SDavid Brownell status = spi_write_then_read(ds1305->spi, buf, 2, NULL, 0); 384*53e84b67SDavid Brownell if (status < 0) 385*53e84b67SDavid Brownell return status; 386*53e84b67SDavid Brownell } 387*53e84b67SDavid Brownell 388*53e84b67SDavid Brownell /* write alarm */ 389*53e84b67SDavid Brownell buf[0] = DS1305_WRITE | DS1305_ALM0(DS1305_SEC); 390*53e84b67SDavid Brownell buf[1 + DS1305_SEC] = BIN2BCD(alm->time.tm_sec); 391*53e84b67SDavid Brownell buf[1 + DS1305_MIN] = BIN2BCD(alm->time.tm_min); 392*53e84b67SDavid Brownell buf[1 + DS1305_HOUR] = hour2bcd(ds1305->hr12, alm->time.tm_hour); 393*53e84b67SDavid Brownell buf[1 + DS1305_WDAY] = DS1305_ALM_DISABLE; 394*53e84b67SDavid Brownell 395*53e84b67SDavid Brownell dev_dbg(dev, "%s: %02x %02x %02x %02x\n", 396*53e84b67SDavid Brownell "alm0 write", buf[1 + DS1305_SEC], buf[1 + DS1305_MIN], 397*53e84b67SDavid Brownell buf[1 + DS1305_HOUR], buf[1 + DS1305_WDAY]); 398*53e84b67SDavid Brownell 399*53e84b67SDavid Brownell status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); 400*53e84b67SDavid Brownell if (status < 0) 401*53e84b67SDavid Brownell return status; 402*53e84b67SDavid Brownell 403*53e84b67SDavid Brownell /* enable alarm if requested */ 404*53e84b67SDavid Brownell if (alm->enabled) { 405*53e84b67SDavid Brownell ds1305->ctrl[0] |= DS1305_AEI0; 406*53e84b67SDavid Brownell 407*53e84b67SDavid Brownell buf[0] = DS1305_WRITE | DS1305_CONTROL; 408*53e84b67SDavid Brownell buf[1] = ds1305->ctrl[0]; 409*53e84b67SDavid Brownell status = spi_write_then_read(ds1305->spi, buf, 2, NULL, 0); 410*53e84b67SDavid Brownell } 411*53e84b67SDavid Brownell 412*53e84b67SDavid Brownell return status; 413*53e84b67SDavid Brownell } 414*53e84b67SDavid Brownell 415*53e84b67SDavid Brownell #ifdef CONFIG_PROC_FS 416*53e84b67SDavid Brownell 417*53e84b67SDavid Brownell static int ds1305_proc(struct device *dev, struct seq_file *seq) 418*53e84b67SDavid Brownell { 419*53e84b67SDavid Brownell struct ds1305 *ds1305 = dev_get_drvdata(dev); 420*53e84b67SDavid Brownell char *diodes = "no"; 421*53e84b67SDavid Brownell char *resistors = ""; 422*53e84b67SDavid Brownell 423*53e84b67SDavid Brownell /* ctrl[2] is treated as read-only; no locking needed */ 424*53e84b67SDavid Brownell if ((ds1305->ctrl[2] & 0xf0) == DS1305_TRICKLE_MAGIC) { 425*53e84b67SDavid Brownell switch (ds1305->ctrl[2] & 0x0c) { 426*53e84b67SDavid Brownell case DS1305_TRICKLE_DS2: 427*53e84b67SDavid Brownell diodes = "2 diodes, "; 428*53e84b67SDavid Brownell break; 429*53e84b67SDavid Brownell case DS1305_TRICKLE_DS1: 430*53e84b67SDavid Brownell diodes = "1 diode, "; 431*53e84b67SDavid Brownell break; 432*53e84b67SDavid Brownell default: 433*53e84b67SDavid Brownell goto done; 434*53e84b67SDavid Brownell } 435*53e84b67SDavid Brownell switch (ds1305->ctrl[2] & 0x03) { 436*53e84b67SDavid Brownell case DS1305_TRICKLE_2K: 437*53e84b67SDavid Brownell resistors = "2k Ohm"; 438*53e84b67SDavid Brownell break; 439*53e84b67SDavid Brownell case DS1305_TRICKLE_4K: 440*53e84b67SDavid Brownell resistors = "4k Ohm"; 441*53e84b67SDavid Brownell break; 442*53e84b67SDavid Brownell case DS1305_TRICKLE_8K: 443*53e84b67SDavid Brownell resistors = "8k Ohm"; 444*53e84b67SDavid Brownell break; 445*53e84b67SDavid Brownell default: 446*53e84b67SDavid Brownell diodes = "no"; 447*53e84b67SDavid Brownell break; 448*53e84b67SDavid Brownell } 449*53e84b67SDavid Brownell } 450*53e84b67SDavid Brownell 451*53e84b67SDavid Brownell done: 452*53e84b67SDavid Brownell return seq_printf(seq, 453*53e84b67SDavid Brownell "trickle_charge\t: %s%s\n", 454*53e84b67SDavid Brownell diodes, resistors); 455*53e84b67SDavid Brownell } 456*53e84b67SDavid Brownell 457*53e84b67SDavid Brownell #else 458*53e84b67SDavid Brownell #define ds1305_proc NULL 459*53e84b67SDavid Brownell #endif 460*53e84b67SDavid Brownell 461*53e84b67SDavid Brownell static const struct rtc_class_ops ds1305_ops = { 462*53e84b67SDavid Brownell .ioctl = ds1305_ioctl, 463*53e84b67SDavid Brownell .read_time = ds1305_get_time, 464*53e84b67SDavid Brownell .set_time = ds1305_set_time, 465*53e84b67SDavid Brownell .read_alarm = ds1305_get_alarm, 466*53e84b67SDavid Brownell .set_alarm = ds1305_set_alarm, 467*53e84b67SDavid Brownell .proc = ds1305_proc, 468*53e84b67SDavid Brownell }; 469*53e84b67SDavid Brownell 470*53e84b67SDavid Brownell static void ds1305_work(struct work_struct *work) 471*53e84b67SDavid Brownell { 472*53e84b67SDavid Brownell struct ds1305 *ds1305 = container_of(work, struct ds1305, work); 473*53e84b67SDavid Brownell struct mutex *lock = &ds1305->rtc->ops_lock; 474*53e84b67SDavid Brownell struct spi_device *spi = ds1305->spi; 475*53e84b67SDavid Brownell u8 buf[3]; 476*53e84b67SDavid Brownell int status; 477*53e84b67SDavid Brownell 478*53e84b67SDavid Brownell /* lock to protect ds1305->ctrl */ 479*53e84b67SDavid Brownell mutex_lock(lock); 480*53e84b67SDavid Brownell 481*53e84b67SDavid Brownell /* Disable the IRQ, and clear its status ... for now, we "know" 482*53e84b67SDavid Brownell * that if more than one alarm is active, they're in sync. 483*53e84b67SDavid Brownell * Note that reading ALM data registers also clears IRQ status. 484*53e84b67SDavid Brownell */ 485*53e84b67SDavid Brownell ds1305->ctrl[0] &= ~(DS1305_AEI1 | DS1305_AEI0); 486*53e84b67SDavid Brownell ds1305->ctrl[1] = 0; 487*53e84b67SDavid Brownell 488*53e84b67SDavid Brownell buf[0] = DS1305_WRITE | DS1305_CONTROL; 489*53e84b67SDavid Brownell buf[1] = ds1305->ctrl[0]; 490*53e84b67SDavid Brownell buf[2] = 0; 491*53e84b67SDavid Brownell 492*53e84b67SDavid Brownell status = spi_write_then_read(spi, buf, sizeof buf, 493*53e84b67SDavid Brownell NULL, 0); 494*53e84b67SDavid Brownell if (status < 0) 495*53e84b67SDavid Brownell dev_dbg(&spi->dev, "clear irq --> %d\n", status); 496*53e84b67SDavid Brownell 497*53e84b67SDavid Brownell mutex_unlock(lock); 498*53e84b67SDavid Brownell 499*53e84b67SDavid Brownell if (!test_bit(FLAG_EXITING, &ds1305->flags)) 500*53e84b67SDavid Brownell enable_irq(spi->irq); 501*53e84b67SDavid Brownell 502*53e84b67SDavid Brownell /* rtc_update_irq() requires an IRQ-disabled context */ 503*53e84b67SDavid Brownell local_irq_disable(); 504*53e84b67SDavid Brownell rtc_update_irq(ds1305->rtc, 1, RTC_AF | RTC_IRQF); 505*53e84b67SDavid Brownell local_irq_enable(); 506*53e84b67SDavid Brownell } 507*53e84b67SDavid Brownell 508*53e84b67SDavid Brownell /* 509*53e84b67SDavid Brownell * This "real" IRQ handler hands off to a workqueue mostly to allow 510*53e84b67SDavid Brownell * mutex locking for ds1305->ctrl ... unlike I2C, we could issue async 511*53e84b67SDavid Brownell * I/O requests in IRQ context (to clear the IRQ status). 512*53e84b67SDavid Brownell */ 513*53e84b67SDavid Brownell static irqreturn_t ds1305_irq(int irq, void *p) 514*53e84b67SDavid Brownell { 515*53e84b67SDavid Brownell struct ds1305 *ds1305 = p; 516*53e84b67SDavid Brownell 517*53e84b67SDavid Brownell disable_irq(irq); 518*53e84b67SDavid Brownell schedule_work(&ds1305->work); 519*53e84b67SDavid Brownell return IRQ_HANDLED; 520*53e84b67SDavid Brownell } 521*53e84b67SDavid Brownell 522*53e84b67SDavid Brownell /*----------------------------------------------------------------------*/ 523*53e84b67SDavid Brownell 524*53e84b67SDavid Brownell /* 525*53e84b67SDavid Brownell * Interface for NVRAM 526*53e84b67SDavid Brownell */ 527*53e84b67SDavid Brownell 528*53e84b67SDavid Brownell static void msg_init(struct spi_message *m, struct spi_transfer *x, 529*53e84b67SDavid Brownell u8 *addr, size_t count, char *tx, char *rx) 530*53e84b67SDavid Brownell { 531*53e84b67SDavid Brownell spi_message_init(m); 532*53e84b67SDavid Brownell memset(x, 0, 2 * sizeof(*x)); 533*53e84b67SDavid Brownell 534*53e84b67SDavid Brownell x->tx_buf = addr; 535*53e84b67SDavid Brownell x->len = 1; 536*53e84b67SDavid Brownell spi_message_add_tail(x, m); 537*53e84b67SDavid Brownell 538*53e84b67SDavid Brownell x++; 539*53e84b67SDavid Brownell 540*53e84b67SDavid Brownell x->tx_buf = tx; 541*53e84b67SDavid Brownell x->rx_buf = rx; 542*53e84b67SDavid Brownell x->len = count; 543*53e84b67SDavid Brownell spi_message_add_tail(x, m); 544*53e84b67SDavid Brownell } 545*53e84b67SDavid Brownell 546*53e84b67SDavid Brownell static ssize_t 547*53e84b67SDavid Brownell ds1305_nvram_read(struct kobject *kobj, struct bin_attribute *attr, 548*53e84b67SDavid Brownell char *buf, loff_t off, size_t count) 549*53e84b67SDavid Brownell { 550*53e84b67SDavid Brownell struct spi_device *spi; 551*53e84b67SDavid Brownell u8 addr; 552*53e84b67SDavid Brownell struct spi_message m; 553*53e84b67SDavid Brownell struct spi_transfer x[2]; 554*53e84b67SDavid Brownell int status; 555*53e84b67SDavid Brownell 556*53e84b67SDavid Brownell spi = container_of(kobj, struct spi_device, dev.kobj); 557*53e84b67SDavid Brownell 558*53e84b67SDavid Brownell if (unlikely(off >= DS1305_NVRAM_LEN)) 559*53e84b67SDavid Brownell return 0; 560*53e84b67SDavid Brownell if (count >= DS1305_NVRAM_LEN) 561*53e84b67SDavid Brownell count = DS1305_NVRAM_LEN; 562*53e84b67SDavid Brownell if ((off + count) > DS1305_NVRAM_LEN) 563*53e84b67SDavid Brownell count = DS1305_NVRAM_LEN - off; 564*53e84b67SDavid Brownell if (unlikely(!count)) 565*53e84b67SDavid Brownell return count; 566*53e84b67SDavid Brownell 567*53e84b67SDavid Brownell addr = DS1305_NVRAM + off; 568*53e84b67SDavid Brownell msg_init(&m, x, &addr, count, NULL, buf); 569*53e84b67SDavid Brownell 570*53e84b67SDavid Brownell status = spi_sync(spi, &m); 571*53e84b67SDavid Brownell if (status < 0) 572*53e84b67SDavid Brownell dev_err(&spi->dev, "nvram %s error %d\n", "read", status); 573*53e84b67SDavid Brownell return (status < 0) ? status : count; 574*53e84b67SDavid Brownell } 575*53e84b67SDavid Brownell 576*53e84b67SDavid Brownell static ssize_t 577*53e84b67SDavid Brownell ds1305_nvram_write(struct kobject *kobj, struct bin_attribute *attr, 578*53e84b67SDavid Brownell char *buf, loff_t off, size_t count) 579*53e84b67SDavid Brownell { 580*53e84b67SDavid Brownell struct spi_device *spi; 581*53e84b67SDavid Brownell u8 addr; 582*53e84b67SDavid Brownell struct spi_message m; 583*53e84b67SDavid Brownell struct spi_transfer x[2]; 584*53e84b67SDavid Brownell int status; 585*53e84b67SDavid Brownell 586*53e84b67SDavid Brownell spi = container_of(kobj, struct spi_device, dev.kobj); 587*53e84b67SDavid Brownell 588*53e84b67SDavid Brownell if (unlikely(off >= DS1305_NVRAM_LEN)) 589*53e84b67SDavid Brownell return -EFBIG; 590*53e84b67SDavid Brownell if (count >= DS1305_NVRAM_LEN) 591*53e84b67SDavid Brownell count = DS1305_NVRAM_LEN; 592*53e84b67SDavid Brownell if ((off + count) > DS1305_NVRAM_LEN) 593*53e84b67SDavid Brownell count = DS1305_NVRAM_LEN - off; 594*53e84b67SDavid Brownell if (unlikely(!count)) 595*53e84b67SDavid Brownell return count; 596*53e84b67SDavid Brownell 597*53e84b67SDavid Brownell addr = (DS1305_WRITE | DS1305_NVRAM) + off; 598*53e84b67SDavid Brownell msg_init(&m, x, &addr, count, buf, NULL); 599*53e84b67SDavid Brownell 600*53e84b67SDavid Brownell status = spi_sync(spi, &m); 601*53e84b67SDavid Brownell if (status < 0) 602*53e84b67SDavid Brownell dev_err(&spi->dev, "nvram %s error %d\n", "write", status); 603*53e84b67SDavid Brownell return (status < 0) ? status : count; 604*53e84b67SDavid Brownell } 605*53e84b67SDavid Brownell 606*53e84b67SDavid Brownell static struct bin_attribute nvram = { 607*53e84b67SDavid Brownell .attr.name = "nvram", 608*53e84b67SDavid Brownell .attr.mode = S_IRUGO | S_IWUSR, 609*53e84b67SDavid Brownell .attr.owner = THIS_MODULE, 610*53e84b67SDavid Brownell .read = ds1305_nvram_read, 611*53e84b67SDavid Brownell .write = ds1305_nvram_write, 612*53e84b67SDavid Brownell .size = DS1305_NVRAM_LEN, 613*53e84b67SDavid Brownell }; 614*53e84b67SDavid Brownell 615*53e84b67SDavid Brownell /*----------------------------------------------------------------------*/ 616*53e84b67SDavid Brownell 617*53e84b67SDavid Brownell /* 618*53e84b67SDavid Brownell * Interface to SPI stack 619*53e84b67SDavid Brownell */ 620*53e84b67SDavid Brownell 621*53e84b67SDavid Brownell static int __devinit ds1305_probe(struct spi_device *spi) 622*53e84b67SDavid Brownell { 623*53e84b67SDavid Brownell struct ds1305 *ds1305; 624*53e84b67SDavid Brownell struct rtc_device *rtc; 625*53e84b67SDavid Brownell int status; 626*53e84b67SDavid Brownell u8 addr, value; 627*53e84b67SDavid Brownell struct ds1305_platform_data *pdata = spi->dev.platform_data; 628*53e84b67SDavid Brownell bool write_ctrl = false; 629*53e84b67SDavid Brownell 630*53e84b67SDavid Brownell /* Sanity check board setup data. This may be hooked up 631*53e84b67SDavid Brownell * in 3wire mode, but we don't care. Note that unless 632*53e84b67SDavid Brownell * there's an inverter in place, this needs SPI_CS_HIGH! 633*53e84b67SDavid Brownell */ 634*53e84b67SDavid Brownell if ((spi->bits_per_word && spi->bits_per_word != 8) 635*53e84b67SDavid Brownell || (spi->max_speed_hz > 2000000) 636*53e84b67SDavid Brownell || !(spi->mode & SPI_CPHA)) 637*53e84b67SDavid Brownell return -EINVAL; 638*53e84b67SDavid Brownell 639*53e84b67SDavid Brownell /* set up driver data */ 640*53e84b67SDavid Brownell ds1305 = kzalloc(sizeof *ds1305, GFP_KERNEL); 641*53e84b67SDavid Brownell if (!ds1305) 642*53e84b67SDavid Brownell return -ENOMEM; 643*53e84b67SDavid Brownell ds1305->spi = spi; 644*53e84b67SDavid Brownell spi_set_drvdata(spi, ds1305); 645*53e84b67SDavid Brownell 646*53e84b67SDavid Brownell /* read and cache control registers */ 647*53e84b67SDavid Brownell addr = DS1305_CONTROL; 648*53e84b67SDavid Brownell status = spi_write_then_read(spi, &addr, sizeof addr, 649*53e84b67SDavid Brownell ds1305->ctrl, sizeof ds1305->ctrl); 650*53e84b67SDavid Brownell if (status < 0) { 651*53e84b67SDavid Brownell dev_dbg(&spi->dev, "can't %s, %d\n", 652*53e84b67SDavid Brownell "read", status); 653*53e84b67SDavid Brownell goto fail0; 654*53e84b67SDavid Brownell } 655*53e84b67SDavid Brownell 656*53e84b67SDavid Brownell dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n", 657*53e84b67SDavid Brownell "read", ds1305->ctrl[0], 658*53e84b67SDavid Brownell ds1305->ctrl[1], ds1305->ctrl[2]); 659*53e84b67SDavid Brownell 660*53e84b67SDavid Brownell /* Sanity check register values ... partially compensating for the 661*53e84b67SDavid Brownell * fact that SPI has no device handshake. A pullup on MISO would 662*53e84b67SDavid Brownell * make these tests fail; but not all systems will have one. If 663*53e84b67SDavid Brownell * some register is neither 0x00 nor 0xff, a chip is likely there. 664*53e84b67SDavid Brownell */ 665*53e84b67SDavid Brownell if ((ds1305->ctrl[0] & 0x38) != 0 || (ds1305->ctrl[1] & 0xfc) != 0) { 666*53e84b67SDavid Brownell dev_dbg(&spi->dev, "RTC chip is not present\n"); 667*53e84b67SDavid Brownell status = -ENODEV; 668*53e84b67SDavid Brownell goto fail0; 669*53e84b67SDavid Brownell } 670*53e84b67SDavid Brownell if (ds1305->ctrl[2] == 0) 671*53e84b67SDavid Brownell dev_dbg(&spi->dev, "chip may not be present\n"); 672*53e84b67SDavid Brownell 673*53e84b67SDavid Brownell /* enable writes if needed ... if we were paranoid it would 674*53e84b67SDavid Brownell * make sense to enable them only when absolutely necessary. 675*53e84b67SDavid Brownell */ 676*53e84b67SDavid Brownell if (ds1305->ctrl[0] & DS1305_WP) { 677*53e84b67SDavid Brownell u8 buf[2]; 678*53e84b67SDavid Brownell 679*53e84b67SDavid Brownell ds1305->ctrl[0] &= ~DS1305_WP; 680*53e84b67SDavid Brownell 681*53e84b67SDavid Brownell buf[0] = DS1305_WRITE | DS1305_CONTROL; 682*53e84b67SDavid Brownell buf[1] = ds1305->ctrl[0]; 683*53e84b67SDavid Brownell status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); 684*53e84b67SDavid Brownell 685*53e84b67SDavid Brownell dev_dbg(&spi->dev, "clear WP --> %d\n", status); 686*53e84b67SDavid Brownell if (status < 0) 687*53e84b67SDavid Brownell goto fail0; 688*53e84b67SDavid Brownell } 689*53e84b67SDavid Brownell 690*53e84b67SDavid Brownell /* on DS1305, maybe start oscillator; like most low power 691*53e84b67SDavid Brownell * oscillators, it may take a second to stabilize 692*53e84b67SDavid Brownell */ 693*53e84b67SDavid Brownell if (ds1305->ctrl[0] & DS1305_nEOSC) { 694*53e84b67SDavid Brownell ds1305->ctrl[0] &= ~DS1305_nEOSC; 695*53e84b67SDavid Brownell write_ctrl = true; 696*53e84b67SDavid Brownell dev_warn(&spi->dev, "SET TIME!\n"); 697*53e84b67SDavid Brownell } 698*53e84b67SDavid Brownell 699*53e84b67SDavid Brownell /* ack any pending IRQs */ 700*53e84b67SDavid Brownell if (ds1305->ctrl[1]) { 701*53e84b67SDavid Brownell ds1305->ctrl[1] = 0; 702*53e84b67SDavid Brownell write_ctrl = true; 703*53e84b67SDavid Brownell } 704*53e84b67SDavid Brownell 705*53e84b67SDavid Brownell /* this may need one-time (re)init */ 706*53e84b67SDavid Brownell if (pdata) { 707*53e84b67SDavid Brownell /* maybe enable trickle charge */ 708*53e84b67SDavid Brownell if (((ds1305->ctrl[2] & 0xf0) != DS1305_TRICKLE_MAGIC)) { 709*53e84b67SDavid Brownell ds1305->ctrl[2] = DS1305_TRICKLE_MAGIC 710*53e84b67SDavid Brownell | pdata->trickle; 711*53e84b67SDavid Brownell write_ctrl = true; 712*53e84b67SDavid Brownell } 713*53e84b67SDavid Brownell 714*53e84b67SDavid Brownell /* on DS1306, configure 1 Hz signal */ 715*53e84b67SDavid Brownell if (pdata->is_ds1306) { 716*53e84b67SDavid Brownell if (pdata->en_1hz) { 717*53e84b67SDavid Brownell if (!(ds1305->ctrl[0] & DS1306_1HZ)) { 718*53e84b67SDavid Brownell ds1305->ctrl[0] |= DS1306_1HZ; 719*53e84b67SDavid Brownell write_ctrl = true; 720*53e84b67SDavid Brownell } 721*53e84b67SDavid Brownell } else { 722*53e84b67SDavid Brownell if (ds1305->ctrl[0] & DS1306_1HZ) { 723*53e84b67SDavid Brownell ds1305->ctrl[0] &= ~DS1306_1HZ; 724*53e84b67SDavid Brownell write_ctrl = true; 725*53e84b67SDavid Brownell } 726*53e84b67SDavid Brownell } 727*53e84b67SDavid Brownell } 728*53e84b67SDavid Brownell } 729*53e84b67SDavid Brownell 730*53e84b67SDavid Brownell if (write_ctrl) { 731*53e84b67SDavid Brownell u8 buf[4]; 732*53e84b67SDavid Brownell 733*53e84b67SDavid Brownell buf[0] = DS1305_WRITE | DS1305_CONTROL; 734*53e84b67SDavid Brownell buf[1] = ds1305->ctrl[0]; 735*53e84b67SDavid Brownell buf[2] = ds1305->ctrl[1]; 736*53e84b67SDavid Brownell buf[3] = ds1305->ctrl[2]; 737*53e84b67SDavid Brownell status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); 738*53e84b67SDavid Brownell if (status < 0) { 739*53e84b67SDavid Brownell dev_dbg(&spi->dev, "can't %s, %d\n", 740*53e84b67SDavid Brownell "write", status); 741*53e84b67SDavid Brownell goto fail0; 742*53e84b67SDavid Brownell } 743*53e84b67SDavid Brownell 744*53e84b67SDavid Brownell dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n", 745*53e84b67SDavid Brownell "write", ds1305->ctrl[0], 746*53e84b67SDavid Brownell ds1305->ctrl[1], ds1305->ctrl[2]); 747*53e84b67SDavid Brownell } 748*53e84b67SDavid Brownell 749*53e84b67SDavid Brownell /* see if non-Linux software set up AM/PM mode */ 750*53e84b67SDavid Brownell addr = DS1305_HOUR; 751*53e84b67SDavid Brownell status = spi_write_then_read(spi, &addr, sizeof addr, 752*53e84b67SDavid Brownell &value, sizeof value); 753*53e84b67SDavid Brownell if (status < 0) { 754*53e84b67SDavid Brownell dev_dbg(&spi->dev, "read HOUR --> %d\n", status); 755*53e84b67SDavid Brownell goto fail0; 756*53e84b67SDavid Brownell } 757*53e84b67SDavid Brownell 758*53e84b67SDavid Brownell ds1305->hr12 = (DS1305_HR_12 & value) != 0; 759*53e84b67SDavid Brownell if (ds1305->hr12) 760*53e84b67SDavid Brownell dev_dbg(&spi->dev, "AM/PM\n"); 761*53e84b67SDavid Brownell 762*53e84b67SDavid Brownell /* register RTC ... from here on, ds1305->ctrl needs locking */ 763*53e84b67SDavid Brownell rtc = rtc_device_register("ds1305", &spi->dev, 764*53e84b67SDavid Brownell &ds1305_ops, THIS_MODULE); 765*53e84b67SDavid Brownell if (IS_ERR(rtc)) { 766*53e84b67SDavid Brownell status = PTR_ERR(rtc); 767*53e84b67SDavid Brownell dev_dbg(&spi->dev, "register rtc --> %d\n", status); 768*53e84b67SDavid Brownell goto fail0; 769*53e84b67SDavid Brownell } 770*53e84b67SDavid Brownell ds1305->rtc = rtc; 771*53e84b67SDavid Brownell 772*53e84b67SDavid Brownell /* Maybe set up alarm IRQ; be ready to handle it triggering right 773*53e84b67SDavid Brownell * away. NOTE that we don't share this. The signal is active low, 774*53e84b67SDavid Brownell * and we can't ack it before a SPI message delay. We temporarily 775*53e84b67SDavid Brownell * disable the IRQ until it's acked, which lets us work with more 776*53e84b67SDavid Brownell * IRQ trigger modes (not all IRQ controllers can do falling edge). 777*53e84b67SDavid Brownell */ 778*53e84b67SDavid Brownell if (spi->irq) { 779*53e84b67SDavid Brownell INIT_WORK(&ds1305->work, ds1305_work); 780*53e84b67SDavid Brownell status = request_irq(spi->irq, ds1305_irq, 781*53e84b67SDavid Brownell 0, dev_name(&rtc->dev), ds1305); 782*53e84b67SDavid Brownell if (status < 0) { 783*53e84b67SDavid Brownell dev_dbg(&spi->dev, "request_irq %d --> %d\n", 784*53e84b67SDavid Brownell spi->irq, status); 785*53e84b67SDavid Brownell goto fail1; 786*53e84b67SDavid Brownell } 787*53e84b67SDavid Brownell } 788*53e84b67SDavid Brownell 789*53e84b67SDavid Brownell /* export NVRAM */ 790*53e84b67SDavid Brownell status = sysfs_create_bin_file(&spi->dev.kobj, &nvram); 791*53e84b67SDavid Brownell if (status < 0) { 792*53e84b67SDavid Brownell dev_dbg(&spi->dev, "register nvram --> %d\n", status); 793*53e84b67SDavid Brownell goto fail2; 794*53e84b67SDavid Brownell } 795*53e84b67SDavid Brownell 796*53e84b67SDavid Brownell return 0; 797*53e84b67SDavid Brownell 798*53e84b67SDavid Brownell fail2: 799*53e84b67SDavid Brownell free_irq(spi->irq, ds1305); 800*53e84b67SDavid Brownell fail1: 801*53e84b67SDavid Brownell rtc_device_unregister(rtc); 802*53e84b67SDavid Brownell fail0: 803*53e84b67SDavid Brownell kfree(ds1305); 804*53e84b67SDavid Brownell return status; 805*53e84b67SDavid Brownell } 806*53e84b67SDavid Brownell 807*53e84b67SDavid Brownell static int __devexit ds1305_remove(struct spi_device *spi) 808*53e84b67SDavid Brownell { 809*53e84b67SDavid Brownell struct ds1305 *ds1305 = spi_get_drvdata(spi); 810*53e84b67SDavid Brownell 811*53e84b67SDavid Brownell sysfs_remove_bin_file(&spi->dev.kobj, &nvram); 812*53e84b67SDavid Brownell 813*53e84b67SDavid Brownell /* carefully shut down irq and workqueue, if present */ 814*53e84b67SDavid Brownell if (spi->irq) { 815*53e84b67SDavid Brownell set_bit(FLAG_EXITING, &ds1305->flags); 816*53e84b67SDavid Brownell free_irq(spi->irq, ds1305); 817*53e84b67SDavid Brownell flush_scheduled_work(); 818*53e84b67SDavid Brownell } 819*53e84b67SDavid Brownell 820*53e84b67SDavid Brownell rtc_device_unregister(ds1305->rtc); 821*53e84b67SDavid Brownell spi_set_drvdata(spi, NULL); 822*53e84b67SDavid Brownell kfree(ds1305); 823*53e84b67SDavid Brownell return 0; 824*53e84b67SDavid Brownell } 825*53e84b67SDavid Brownell 826*53e84b67SDavid Brownell static struct spi_driver ds1305_driver = { 827*53e84b67SDavid Brownell .driver.name = "rtc-ds1305", 828*53e84b67SDavid Brownell .driver.owner = THIS_MODULE, 829*53e84b67SDavid Brownell .probe = ds1305_probe, 830*53e84b67SDavid Brownell .remove = __devexit_p(ds1305_remove), 831*53e84b67SDavid Brownell /* REVISIT add suspend/resume */ 832*53e84b67SDavid Brownell }; 833*53e84b67SDavid Brownell 834*53e84b67SDavid Brownell static int __init ds1305_init(void) 835*53e84b67SDavid Brownell { 836*53e84b67SDavid Brownell return spi_register_driver(&ds1305_driver); 837*53e84b67SDavid Brownell } 838*53e84b67SDavid Brownell module_init(ds1305_init); 839*53e84b67SDavid Brownell 840*53e84b67SDavid Brownell static void __exit ds1305_exit(void) 841*53e84b67SDavid Brownell { 842*53e84b67SDavid Brownell spi_unregister_driver(&ds1305_driver); 843*53e84b67SDavid Brownell } 844*53e84b67SDavid Brownell module_exit(ds1305_exit); 845*53e84b67SDavid Brownell 846*53e84b67SDavid Brownell MODULE_DESCRIPTION("RTC driver for DS1305 and DS1306 chips"); 847*53e84b67SDavid Brownell MODULE_LICENSE("GPL"); 848