1/* 2 * RTC client/driver for the Maxim/Dallas DS1374 Real-Time Clock over I2C 3 * 4 * Based on code by Randy Vinson <rvinson@mvista.com>, 5 * which was based on the m41t00.c by Mark Greer <mgreer@mvista.com>. 6 * 7 * Copyright (C) 2006-2007 Freescale Semiconductor 8 * 9 * 2005 (c) MontaVista Software, Inc. This file is licensed under 10 * the terms of the GNU General Public License version 2. This program 11 * is licensed "as is" without any warranty of any kind, whether express 12 * or implied. 13 */ 14/* 15 * It would be more efficient to use i2c msgs/i2c_transfer directly but, as 16 * recommened in .../Documentation/i2c/writing-clients section 17 * "Sending and receiving", using SMBus level communication is preferred. 18 */ 19 20#include <linux/kernel.h> 21#include <linux/module.h> 22#include <linux/interrupt.h> 23#include <linux/i2c.h> 24#include <linux/rtc.h> 25#include <linux/bcd.h> 26#include <linux/workqueue.h> 27#include <linux/slab.h> 28#include <linux/pm.h> 29 30#define DS1374_REG_TOD0 0x00 /* Time of Day */ 31#define DS1374_REG_TOD1 0x01 32#define DS1374_REG_TOD2 0x02 33#define DS1374_REG_TOD3 0x03 34#define DS1374_REG_WDALM0 0x04 /* Watchdog/Alarm */ 35#define DS1374_REG_WDALM1 0x05 36#define DS1374_REG_WDALM2 0x06 37#define DS1374_REG_CR 0x07 /* Control */ 38#define DS1374_REG_CR_AIE 0x01 /* Alarm Int. Enable */ 39#define DS1374_REG_CR_WDALM 0x20 /* 1=Watchdog, 0=Alarm */ 40#define DS1374_REG_CR_WACE 0x40 /* WD/Alarm counter enable */ 41#define DS1374_REG_SR 0x08 /* Status */ 42#define DS1374_REG_SR_OSF 0x80 /* Oscillator Stop Flag */ 43#define DS1374_REG_SR_AF 0x01 /* Alarm Flag */ 44#define DS1374_REG_TCR 0x09 /* Trickle Charge */ 45 46static const struct i2c_device_id ds1374_id[] = { 47 { "ds1374", 0 }, 48 { } 49}; 50MODULE_DEVICE_TABLE(i2c, ds1374_id); 51 52struct ds1374 { 53 struct i2c_client *client; 54 struct rtc_device *rtc; 55 struct work_struct work; 56 57 /* The mutex protects alarm operations, and prevents a race 58 * between the enable_irq() in the workqueue and the free_irq() 59 * in the remove function. 60 */ 61 struct mutex mutex; 62 int exiting; 63}; 64 65static struct i2c_driver ds1374_driver; 66 67static int ds1374_read_rtc(struct i2c_client *client, u32 *time, 68 int reg, int nbytes) 69{ 70 u8 buf[4]; 71 int ret; 72 int i; 73 74 if (nbytes > 4) { 75 WARN_ON(1); 76 return -EINVAL; 77 } 78 79 ret = i2c_smbus_read_i2c_block_data(client, reg, nbytes, buf); 80 81 if (ret < 0) 82 return ret; 83 if (ret < nbytes) 84 return -EIO; 85 86 for (i = nbytes - 1, *time = 0; i >= 0; i--) 87 *time = (*time << 8) | buf[i]; 88 89 return 0; 90} 91 92static int ds1374_write_rtc(struct i2c_client *client, u32 time, 93 int reg, int nbytes) 94{ 95 u8 buf[4]; 96 int i; 97 98 if (nbytes > 4) { 99 WARN_ON(1); 100 return -EINVAL; 101 } 102 103 for (i = 0; i < nbytes; i++) { 104 buf[i] = time & 0xff; 105 time >>= 8; 106 } 107 108 return i2c_smbus_write_i2c_block_data(client, reg, nbytes, buf); 109} 110 111static int ds1374_check_rtc_status(struct i2c_client *client) 112{ 113 int ret = 0; 114 int control, stat; 115 116 stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR); 117 if (stat < 0) 118 return stat; 119 120 if (stat & DS1374_REG_SR_OSF) 121 dev_warn(&client->dev, 122 "oscillator discontinuity flagged, time unreliable\n"); 123 124 stat &= ~(DS1374_REG_SR_OSF | DS1374_REG_SR_AF); 125 126 ret = i2c_smbus_write_byte_data(client, DS1374_REG_SR, stat); 127 if (ret < 0) 128 return ret; 129 130 /* If the alarm is pending, clear it before requesting 131 * the interrupt, so an interrupt event isn't reported 132 * before everything is initialized. 133 */ 134 135 control = i2c_smbus_read_byte_data(client, DS1374_REG_CR); 136 if (control < 0) 137 return control; 138 139 control &= ~(DS1374_REG_CR_WACE | DS1374_REG_CR_AIE); 140 return i2c_smbus_write_byte_data(client, DS1374_REG_CR, control); 141} 142 143static int ds1374_read_time(struct device *dev, struct rtc_time *time) 144{ 145 struct i2c_client *client = to_i2c_client(dev); 146 u32 itime; 147 int ret; 148 149 ret = ds1374_read_rtc(client, &itime, DS1374_REG_TOD0, 4); 150 if (!ret) 151 rtc_time_to_tm(itime, time); 152 153 return ret; 154} 155 156static int ds1374_set_time(struct device *dev, struct rtc_time *time) 157{ 158 struct i2c_client *client = to_i2c_client(dev); 159 unsigned long itime; 160 161 rtc_tm_to_time(time, &itime); 162 return ds1374_write_rtc(client, itime, DS1374_REG_TOD0, 4); 163} 164 165/* The ds1374 has a decrementer for an alarm, rather than a comparator. 166 * If the time of day is changed, then the alarm will need to be 167 * reset. 168 */ 169static int ds1374_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) 170{ 171 struct i2c_client *client = to_i2c_client(dev); 172 struct ds1374 *ds1374 = i2c_get_clientdata(client); 173 u32 now, cur_alarm; 174 int cr, sr; 175 int ret = 0; 176 177 if (client->irq <= 0) 178 return -EINVAL; 179 180 mutex_lock(&ds1374->mutex); 181 182 cr = ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR); 183 if (ret < 0) 184 goto out; 185 186 sr = ret = i2c_smbus_read_byte_data(client, DS1374_REG_SR); 187 if (ret < 0) 188 goto out; 189 190 ret = ds1374_read_rtc(client, &now, DS1374_REG_TOD0, 4); 191 if (ret) 192 goto out; 193 194 ret = ds1374_read_rtc(client, &cur_alarm, DS1374_REG_WDALM0, 3); 195 if (ret) 196 goto out; 197 198 rtc_time_to_tm(now + cur_alarm, &alarm->time); 199 alarm->enabled = !!(cr & DS1374_REG_CR_WACE); 200 alarm->pending = !!(sr & DS1374_REG_SR_AF); 201 202out: 203 mutex_unlock(&ds1374->mutex); 204 return ret; 205} 206 207static int ds1374_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) 208{ 209 struct i2c_client *client = to_i2c_client(dev); 210 struct ds1374 *ds1374 = i2c_get_clientdata(client); 211 struct rtc_time now; 212 unsigned long new_alarm, itime; 213 int cr; 214 int ret = 0; 215 216 if (client->irq <= 0) 217 return -EINVAL; 218 219 ret = ds1374_read_time(dev, &now); 220 if (ret < 0) 221 return ret; 222 223 rtc_tm_to_time(&alarm->time, &new_alarm); 224 rtc_tm_to_time(&now, &itime); 225 226 /* This can happen due to races, in addition to dates that are 227 * truly in the past. To avoid requiring the caller to check for 228 * races, dates in the past are assumed to be in the recent past 229 * (i.e. not something that we'd rather the caller know about via 230 * an error), and the alarm is set to go off as soon as possible. 231 */ 232 if (time_before_eq(new_alarm, itime)) 233 new_alarm = 1; 234 else 235 new_alarm -= itime; 236 237 mutex_lock(&ds1374->mutex); 238 239 ret = cr = i2c_smbus_read_byte_data(client, DS1374_REG_CR); 240 if (ret < 0) 241 goto out; 242 243 /* Disable any existing alarm before setting the new one 244 * (or lack thereof). */ 245 cr &= ~DS1374_REG_CR_WACE; 246 247 ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr); 248 if (ret < 0) 249 goto out; 250 251 ret = ds1374_write_rtc(client, new_alarm, DS1374_REG_WDALM0, 3); 252 if (ret) 253 goto out; 254 255 if (alarm->enabled) { 256 cr |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE; 257 cr &= ~DS1374_REG_CR_WDALM; 258 259 ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr); 260 } 261 262out: 263 mutex_unlock(&ds1374->mutex); 264 return ret; 265} 266 267static irqreturn_t ds1374_irq(int irq, void *dev_id) 268{ 269 struct i2c_client *client = dev_id; 270 struct ds1374 *ds1374 = i2c_get_clientdata(client); 271 272 disable_irq_nosync(irq); 273 schedule_work(&ds1374->work); 274 return IRQ_HANDLED; 275} 276 277static void ds1374_work(struct work_struct *work) 278{ 279 struct ds1374 *ds1374 = container_of(work, struct ds1374, work); 280 struct i2c_client *client = ds1374->client; 281 int stat, control; 282 283 mutex_lock(&ds1374->mutex); 284 285 stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR); 286 if (stat < 0) 287 goto unlock; 288 289 if (stat & DS1374_REG_SR_AF) { 290 stat &= ~DS1374_REG_SR_AF; 291 i2c_smbus_write_byte_data(client, DS1374_REG_SR, stat); 292 293 control = i2c_smbus_read_byte_data(client, DS1374_REG_CR); 294 if (control < 0) 295 goto out; 296 297 control &= ~(DS1374_REG_CR_WACE | DS1374_REG_CR_AIE); 298 i2c_smbus_write_byte_data(client, DS1374_REG_CR, control); 299 300 rtc_update_irq(ds1374->rtc, 1, RTC_AF | RTC_IRQF); 301 } 302 303out: 304 if (!ds1374->exiting) 305 enable_irq(client->irq); 306unlock: 307 mutex_unlock(&ds1374->mutex); 308} 309 310static int ds1374_alarm_irq_enable(struct device *dev, unsigned int enabled) 311{ 312 struct i2c_client *client = to_i2c_client(dev); 313 struct ds1374 *ds1374 = i2c_get_clientdata(client); 314 int ret; 315 316 mutex_lock(&ds1374->mutex); 317 318 ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR); 319 if (ret < 0) 320 goto out; 321 322 if (enabled) { 323 ret |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE; 324 ret &= ~DS1374_REG_CR_WDALM; 325 } else { 326 ret &= ~DS1374_REG_CR_WACE; 327 } 328 ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret); 329 330out: 331 mutex_unlock(&ds1374->mutex); 332 return ret; 333} 334 335static const struct rtc_class_ops ds1374_rtc_ops = { 336 .read_time = ds1374_read_time, 337 .set_time = ds1374_set_time, 338 .read_alarm = ds1374_read_alarm, 339 .set_alarm = ds1374_set_alarm, 340 .alarm_irq_enable = ds1374_alarm_irq_enable, 341}; 342 343static int ds1374_probe(struct i2c_client *client, 344 const struct i2c_device_id *id) 345{ 346 struct ds1374 *ds1374; 347 int ret; 348 349 ds1374 = devm_kzalloc(&client->dev, sizeof(struct ds1374), GFP_KERNEL); 350 if (!ds1374) 351 return -ENOMEM; 352 353 ds1374->client = client; 354 i2c_set_clientdata(client, ds1374); 355 356 INIT_WORK(&ds1374->work, ds1374_work); 357 mutex_init(&ds1374->mutex); 358 359 ret = ds1374_check_rtc_status(client); 360 if (ret) 361 return ret; 362 363 if (client->irq > 0) { 364 ret = devm_request_irq(&client->dev, client->irq, ds1374_irq, 0, 365 "ds1374", client); 366 if (ret) { 367 dev_err(&client->dev, "unable to request IRQ\n"); 368 return ret; 369 } 370 371 device_set_wakeup_capable(&client->dev, 1); 372 } 373 374 ds1374->rtc = devm_rtc_device_register(&client->dev, client->name, 375 &ds1374_rtc_ops, THIS_MODULE); 376 if (IS_ERR(ds1374->rtc)) { 377 dev_err(&client->dev, "unable to register the class device\n"); 378 return PTR_ERR(ds1374->rtc); 379 } 380 381 return 0; 382} 383 384static int ds1374_remove(struct i2c_client *client) 385{ 386 struct ds1374 *ds1374 = i2c_get_clientdata(client); 387 388 if (client->irq > 0) { 389 mutex_lock(&ds1374->mutex); 390 ds1374->exiting = 1; 391 mutex_unlock(&ds1374->mutex); 392 393 devm_free_irq(&client->dev, client->irq, client); 394 cancel_work_sync(&ds1374->work); 395 } 396 397 return 0; 398} 399 400#ifdef CONFIG_PM_SLEEP 401static int ds1374_suspend(struct device *dev) 402{ 403 struct i2c_client *client = to_i2c_client(dev); 404 405 if (client->irq >= 0 && device_may_wakeup(&client->dev)) 406 enable_irq_wake(client->irq); 407 return 0; 408} 409 410static int ds1374_resume(struct device *dev) 411{ 412 struct i2c_client *client = to_i2c_client(dev); 413 414 if (client->irq >= 0 && device_may_wakeup(&client->dev)) 415 disable_irq_wake(client->irq); 416 return 0; 417} 418#endif 419 420static SIMPLE_DEV_PM_OPS(ds1374_pm, ds1374_suspend, ds1374_resume); 421 422static struct i2c_driver ds1374_driver = { 423 .driver = { 424 .name = "rtc-ds1374", 425 .owner = THIS_MODULE, 426 .pm = &ds1374_pm, 427 }, 428 .probe = ds1374_probe, 429 .remove = ds1374_remove, 430 .id_table = ds1374_id, 431}; 432 433module_i2c_driver(ds1374_driver); 434 435MODULE_AUTHOR("Scott Wood <scottwood@freescale.com>"); 436MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC Driver"); 437MODULE_LICENSE("GPL"); 438