Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtc-ds1307: alarm support for ds1337/ds1339

Update the ds1307 driver with alarm support for ds1337/ds1339. This uses
the first alarm (there are two), and matches on seconds, minutes, hours,
and day-of-month. Tested on ds1339.

[dbrownell@users.sourceforge.net: add comments; fixup style, valid irq
checks, debug dumps; lock; more careful IRQ shutdown; switch BCD2BIN to
bcd2bin (and vice versa); ENOTTY not EINVAL.]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Rodolfo Giometti <giometti@linux.it>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Rodolfo Giometti and committed by
Linus Torvalds
cb49a5e9 2f9b75e0

+295 -13
+295 -13
drivers/rtc/rtc-ds1307.c
··· 23 23 * to have set the chip up as a clock (turning on the oscillator and 24 24 * setting the date and time), Linux can ignore the non-clock features. 25 25 * That's a natural job for a factory or repair bench. 26 - * 27 - * This is currently a simple no-alarms driver. If your board has the 28 - * alarm irq wired up on a ds1337 or ds1339, and you want to use that, 29 - * then look at the rtc-rs5c372 driver for code to steal... 30 26 */ 31 27 enum ds_type { 32 28 ds_1307, ··· 63 67 # define DS1307_BIT_RS0 0x01 64 68 #define DS1337_REG_CONTROL 0x0e 65 69 # define DS1337_BIT_nEOSC 0x80 70 + # define DS1339_BIT_BBSQI 0x20 66 71 # define DS1337_BIT_RS2 0x10 67 72 # define DS1337_BIT_RS1 0x08 68 73 # define DS1337_BIT_INTCN 0x04 ··· 80 83 # define DS1337_BIT_OSF 0x80 81 84 # define DS1337_BIT_A2I 0x02 82 85 # define DS1337_BIT_A1I 0x01 86 + #define DS1339_REG_ALARM1_SECS 0x07 83 87 #define DS1339_REG_TRICKLE 0x10 84 88 85 89 86 90 87 91 struct ds1307 { 88 92 u8 reg_addr; 89 - bool has_nvram; 90 - u8 regs[8]; 93 + u8 regs[11]; 91 94 enum ds_type type; 95 + unsigned long flags; 96 + #define HAS_NVRAM 0 /* bit 0 == sysfs file active */ 97 + #define HAS_ALARM 1 /* bit 1 == irq claimed */ 92 98 struct i2c_msg msg[2]; 93 99 struct i2c_client *client; 94 - struct i2c_client dev; 95 100 struct rtc_device *rtc; 101 + struct work_struct work; 96 102 }; 97 103 98 104 struct chip_desc { ··· 132 132 }; 133 133 MODULE_DEVICE_TABLE(i2c, ds1307_id); 134 134 135 + /*----------------------------------------------------------------------*/ 136 + 137 + /* 138 + * The IRQ logic includes a "real" handler running in IRQ context just 139 + * long enough to schedule this workqueue entry. We need a task context 140 + * to talk to the RTC, since I2C I/O calls require that; and disable the 141 + * IRQ until we clear its status on the chip, so that this handler can 142 + * work with any type of triggering (not just falling edge). 143 + * 144 + * The ds1337 and ds1339 both have two alarms, but we only use the first 145 + * one (with a "seconds" field). For ds1337 we expect nINTA is our alarm 146 + * signal; ds1339 chips have only one alarm signal. 147 + */ 148 + static void ds1307_work(struct work_struct *work) 149 + { 150 + struct ds1307 *ds1307; 151 + struct i2c_client *client; 152 + struct mutex *lock; 153 + int stat, control; 154 + 155 + ds1307 = container_of(work, struct ds1307, work); 156 + client = ds1307->client; 157 + lock = &ds1307->rtc->ops_lock; 158 + 159 + mutex_lock(lock); 160 + stat = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS); 161 + if (stat < 0) 162 + goto out; 163 + 164 + if (stat & DS1337_BIT_A1I) { 165 + stat &= ~DS1337_BIT_A1I; 166 + i2c_smbus_write_byte_data(client, DS1337_REG_STATUS, stat); 167 + 168 + control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); 169 + if (control < 0) 170 + goto out; 171 + 172 + control &= ~DS1337_BIT_A1IE; 173 + i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, control); 174 + 175 + /* rtc_update_irq() assumes that it is called 176 + * from IRQ-disabled context. 177 + */ 178 + local_irq_disable(); 179 + rtc_update_irq(ds1307->rtc, 1, RTC_AF | RTC_IRQF); 180 + local_irq_enable(); 181 + } 182 + 183 + out: 184 + if (test_bit(HAS_ALARM, &ds1307->flags)) 185 + enable_irq(client->irq); 186 + mutex_unlock(lock); 187 + } 188 + 189 + static irqreturn_t ds1307_irq(int irq, void *dev_id) 190 + { 191 + struct i2c_client *client = dev_id; 192 + struct ds1307 *ds1307 = i2c_get_clientdata(client); 193 + 194 + disable_irq_nosync(irq); 195 + schedule_work(&ds1307->work); 196 + return IRQ_HANDLED; 197 + } 198 + 199 + /*----------------------------------------------------------------------*/ 200 + 135 201 static int ds1307_get_time(struct device *dev, struct rtc_time *t) 136 202 { 137 203 struct ds1307 *ds1307 = dev_get_drvdata(dev); 138 204 int tmp; 139 205 140 206 /* read the RTC date and time registers all at once */ 207 + ds1307->reg_addr = 0; 141 208 ds1307->msg[1].flags = I2C_M_RD; 142 209 ds1307->msg[1].len = 7; 143 210 ··· 298 231 return 0; 299 232 } 300 233 234 + static int ds1307_read_alarm(struct device *dev, struct rtc_wkalrm *t) 235 + { 236 + struct i2c_client *client = to_i2c_client(dev); 237 + struct ds1307 *ds1307 = i2c_get_clientdata(client); 238 + int ret; 239 + 240 + if (!test_bit(HAS_ALARM, &ds1307->flags)) 241 + return -EINVAL; 242 + 243 + /* read all ALARM1, ALARM2, and status registers at once */ 244 + ds1307->reg_addr = DS1339_REG_ALARM1_SECS; 245 + ds1307->msg[1].flags = I2C_M_RD; 246 + ds1307->msg[1].len = 9; 247 + 248 + ret = i2c_transfer(to_i2c_adapter(client->dev.parent), 249 + ds1307->msg, 2); 250 + if (ret != 2) { 251 + dev_err(dev, "%s error %d\n", "alarm read", ret); 252 + return -EIO; 253 + } 254 + 255 + dev_dbg(dev, "%s: %02x %02x %02x %02x, %02x %02x %02x, %02x %02x\n", 256 + "alarm read", 257 + ds1307->regs[0], ds1307->regs[1], 258 + ds1307->regs[2], ds1307->regs[3], 259 + ds1307->regs[4], ds1307->regs[5], 260 + ds1307->regs[6], ds1307->regs[7], 261 + ds1307->regs[8]); 262 + 263 + /* report alarm time (ALARM1); assume 24 hour and day-of-month modes, 264 + * and that all four fields are checked matches 265 + */ 266 + t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f); 267 + t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f); 268 + t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f); 269 + t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f); 270 + t->time.tm_mon = -1; 271 + t->time.tm_year = -1; 272 + t->time.tm_wday = -1; 273 + t->time.tm_yday = -1; 274 + t->time.tm_isdst = -1; 275 + 276 + /* ... and status */ 277 + t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE); 278 + t->pending = !!(ds1307->regs[8] & DS1337_BIT_A1I); 279 + 280 + dev_dbg(dev, "%s secs=%d, mins=%d, " 281 + "hours=%d, mday=%d, enabled=%d, pending=%d\n", 282 + "alarm read", t->time.tm_sec, t->time.tm_min, 283 + t->time.tm_hour, t->time.tm_mday, 284 + t->enabled, t->pending); 285 + 286 + return 0; 287 + } 288 + 289 + static int ds1307_set_alarm(struct device *dev, struct rtc_wkalrm *t) 290 + { 291 + struct i2c_client *client = to_i2c_client(dev); 292 + struct ds1307 *ds1307 = i2c_get_clientdata(client); 293 + unsigned char *buf = ds1307->regs; 294 + u8 control, status; 295 + int ret; 296 + 297 + if (!test_bit(HAS_ALARM, &ds1307->flags)) 298 + return -EINVAL; 299 + 300 + dev_dbg(dev, "%s secs=%d, mins=%d, " 301 + "hours=%d, mday=%d, enabled=%d, pending=%d\n", 302 + "alarm set", t->time.tm_sec, t->time.tm_min, 303 + t->time.tm_hour, t->time.tm_mday, 304 + t->enabled, t->pending); 305 + 306 + /* read current status of both alarms and the chip */ 307 + ds1307->reg_addr = DS1339_REG_ALARM1_SECS; 308 + ds1307->msg[1].flags = I2C_M_RD; 309 + ds1307->msg[1].len = 9; 310 + 311 + ret = i2c_transfer(to_i2c_adapter(client->dev.parent), 312 + ds1307->msg, 2); 313 + if (ret != 2) { 314 + dev_err(dev, "%s error %d\n", "alarm write", ret); 315 + return -EIO; 316 + } 317 + control = ds1307->regs[7]; 318 + status = ds1307->regs[8]; 319 + 320 + dev_dbg(dev, "%s: %02x %02x %02x %02x, %02x %02x %02x, %02x %02x\n", 321 + "alarm set (old status)", 322 + ds1307->regs[0], ds1307->regs[1], 323 + ds1307->regs[2], ds1307->regs[3], 324 + ds1307->regs[4], ds1307->regs[5], 325 + ds1307->regs[6], control, status); 326 + 327 + /* set ALARM1, using 24 hour and day-of-month modes */ 328 + *buf++ = DS1339_REG_ALARM1_SECS; /* first register addr */ 329 + buf[0] = bin2bcd(t->time.tm_sec); 330 + buf[1] = bin2bcd(t->time.tm_min); 331 + buf[2] = bin2bcd(t->time.tm_hour); 332 + buf[3] = bin2bcd(t->time.tm_mday); 333 + 334 + /* set ALARM2 to non-garbage */ 335 + buf[4] = 0; 336 + buf[5] = 0; 337 + buf[6] = 0; 338 + 339 + /* optionally enable ALARM1 */ 340 + buf[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE); 341 + if (t->enabled) { 342 + dev_dbg(dev, "alarm IRQ armed\n"); 343 + buf[7] |= DS1337_BIT_A1IE; /* only ALARM1 is used */ 344 + } 345 + buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I); 346 + 347 + ds1307->msg[1].flags = 0; 348 + ds1307->msg[1].len = 10; 349 + 350 + ret = i2c_transfer(to_i2c_adapter(client->dev.parent), 351 + &ds1307->msg[1], 1); 352 + if (ret != 1) { 353 + dev_err(dev, "can't set alarm time\n"); 354 + return -EIO; 355 + } 356 + 357 + return 0; 358 + } 359 + 360 + static int ds1307_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 361 + { 362 + struct i2c_client *client = to_i2c_client(dev); 363 + struct ds1307 *ds1307 = i2c_get_clientdata(client); 364 + int ret; 365 + 366 + switch (cmd) { 367 + case RTC_AIE_OFF: 368 + if (!test_bit(HAS_ALARM, &ds1307->flags)) 369 + return -ENOTTY; 370 + 371 + ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); 372 + if (ret < 0) 373 + return ret; 374 + 375 + ret &= ~DS1337_BIT_A1IE; 376 + 377 + ret = i2c_smbus_write_byte_data(client, 378 + DS1337_REG_CONTROL, ret); 379 + if (ret < 0) 380 + return ret; 381 + 382 + break; 383 + 384 + case RTC_AIE_ON: 385 + if (!test_bit(HAS_ALARM, &ds1307->flags)) 386 + return -ENOTTY; 387 + 388 + ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); 389 + if (ret < 0) 390 + return ret; 391 + 392 + ret |= DS1337_BIT_A1IE; 393 + 394 + ret = i2c_smbus_write_byte_data(client, 395 + DS1337_REG_CONTROL, ret); 396 + if (ret < 0) 397 + return ret; 398 + 399 + break; 400 + 401 + default: 402 + return -ENOIOCTLCMD; 403 + } 404 + 405 + return 0; 406 + } 407 + 301 408 static const struct rtc_class_ops ds13xx_rtc_ops = { 302 409 .read_time = ds1307_get_time, 303 410 .set_time = ds1307_set_time, 411 + .read_alarm = ds1307_read_alarm, 412 + .set_alarm = ds1307_set_alarm, 413 + .ioctl = ds1307_ioctl, 304 414 }; 305 415 306 416 /*----------------------------------------------------------------------*/ ··· 571 327 int tmp; 572 328 const struct chip_desc *chip = &chips[id->driver_data]; 573 329 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 330 + int want_irq = false; 574 331 575 332 if (!i2c_check_functionality(adapter, 576 333 I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) ··· 598 353 switch (ds1307->type) { 599 354 case ds_1337: 600 355 case ds_1339: 356 + /* has IRQ? */ 357 + if (ds1307->client->irq > 0 && chip->alarm) { 358 + INIT_WORK(&ds1307->work, ds1307_work); 359 + want_irq = true; 360 + } 361 + 601 362 ds1307->reg_addr = DS1337_REG_CONTROL; 602 363 ds1307->msg[1].len = 2; 603 364 ··· 620 369 621 370 /* oscillator off? turn it on, so clock can tick. */ 622 371 if (ds1307->regs[0] & DS1337_BIT_nEOSC) 623 - i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, 624 - ds1307->regs[0] & ~DS1337_BIT_nEOSC); 372 + ds1307->regs[0] &= ~DS1337_BIT_nEOSC; 373 + 374 + /* Using IRQ? Disable the square wave and both alarms. 375 + * For ds1339, be sure alarms can trigger when we're 376 + * running on Vbackup (BBSQI); we assume ds1337 will 377 + * ignore that bit 378 + */ 379 + if (want_irq) { 380 + ds1307->regs[0] |= DS1337_BIT_INTCN | DS1339_BIT_BBSQI; 381 + ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); 382 + } 383 + 384 + i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, 385 + ds1307->regs[0]); 625 386 626 387 /* oscillator fault? clear flag, and warn */ 627 388 if (ds1307->regs[1] & DS1337_BIT_OSF) { ··· 758 495 goto exit_free; 759 496 } 760 497 498 + if (want_irq) { 499 + err = request_irq(client->irq, ds1307_irq, 0, 500 + ds1307->rtc->name, client); 501 + if (err) { 502 + dev_err(&client->dev, 503 + "unable to request IRQ!\n"); 504 + goto exit_irq; 505 + } 506 + set_bit(HAS_ALARM, &ds1307->flags); 507 + dev_dbg(&client->dev, "got IRQ %d\n", client->irq); 508 + } 509 + 761 510 if (chip->nvram56) { 762 511 err = sysfs_create_bin_file(&client->dev.kobj, &nvram); 763 512 if (err == 0) { 764 - ds1307->has_nvram = true; 513 + set_bit(HAS_NVRAM, &ds1307->flags); 765 514 dev_info(&client->dev, "56 bytes nvram\n"); 766 515 } 767 516 } ··· 787 512 ds1307->regs[2], ds1307->regs[3], 788 513 ds1307->regs[4], ds1307->regs[5], 789 514 ds1307->regs[6]); 790 - 515 + exit_irq: 516 + if (ds1307->rtc) 517 + rtc_device_unregister(ds1307->rtc); 791 518 exit_free: 792 519 kfree(ds1307); 793 520 return err; ··· 797 520 798 521 static int __devexit ds1307_remove(struct i2c_client *client) 799 522 { 800 - struct ds1307 *ds1307 = i2c_get_clientdata(client); 523 + struct ds1307 *ds1307 = i2c_get_clientdata(client); 801 524 802 - if (ds1307->has_nvram) 525 + if (test_and_clear_bit(HAS_ALARM, &ds1307->flags)) { 526 + free_irq(client->irq, client); 527 + cancel_work_sync(&ds1307->work); 528 + } 529 + 530 + if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags)) 803 531 sysfs_remove_bin_file(&client->dev.kobj, &nvram); 804 532 805 533 rtc_device_unregister(ds1307->rtc);