rtc-ds1374.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  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. #include <linux/kernel.h>
  20. #include <linux/module.h>
  21. #include <linux/interrupt.h>
  22. #include <linux/i2c.h>
  23. #include <linux/rtc.h>
  24. #include <linux/bcd.h>
  25. #include <linux/workqueue.h>
  26. #include <linux/slab.h>
  27. #define DS1374_REG_TOD0 0x00 /* Time of Day */
  28. #define DS1374_REG_TOD1 0x01
  29. #define DS1374_REG_TOD2 0x02
  30. #define DS1374_REG_TOD3 0x03
  31. #define DS1374_REG_WDALM0 0x04 /* Watchdog/Alarm */
  32. #define DS1374_REG_WDALM1 0x05
  33. #define DS1374_REG_WDALM2 0x06
  34. #define DS1374_REG_CR 0x07 /* Control */
  35. #define DS1374_REG_CR_AIE 0x01 /* Alarm Int. Enable */
  36. #define DS1374_REG_CR_WDALM 0x20 /* 1=Watchdog, 0=Alarm */
  37. #define DS1374_REG_CR_WACE 0x40 /* WD/Alarm counter enable */
  38. #define DS1374_REG_SR 0x08 /* Status */
  39. #define DS1374_REG_SR_OSF 0x80 /* Oscillator Stop Flag */
  40. #define DS1374_REG_SR_AF 0x01 /* Alarm Flag */
  41. #define DS1374_REG_TCR 0x09 /* Trickle Charge */
  42. static const struct i2c_device_id ds1374_id[] = {
  43. { "ds1374", 0 },
  44. { }
  45. };
  46. MODULE_DEVICE_TABLE(i2c, ds1374_id);
  47. struct ds1374 {
  48. struct i2c_client *client;
  49. struct rtc_device *rtc;
  50. struct work_struct work;
  51. /* The mutex protects alarm operations, and prevents a race
  52. * between the enable_irq() in the workqueue and the free_irq()
  53. * in the remove function.
  54. */
  55. struct mutex mutex;
  56. int exiting;
  57. };
  58. static struct i2c_driver ds1374_driver;
  59. static int ds1374_read_rtc(struct i2c_client *client, u32 *time,
  60. int reg, int nbytes)
  61. {
  62. u8 buf[4];
  63. int ret;
  64. int i;
  65. if (nbytes > 4) {
  66. WARN_ON(1);
  67. return -EINVAL;
  68. }
  69. ret = i2c_smbus_read_i2c_block_data(client, reg, nbytes, buf);
  70. if (ret < 0)
  71. return ret;
  72. if (ret < nbytes)
  73. return -EIO;
  74. for (i = nbytes - 1, *time = 0; i >= 0; i--)
  75. *time = (*time << 8) | buf[i];
  76. return 0;
  77. }
  78. static int ds1374_write_rtc(struct i2c_client *client, u32 time,
  79. int reg, int nbytes)
  80. {
  81. u8 buf[4];
  82. int i;
  83. if (nbytes > 4) {
  84. WARN_ON(1);
  85. return -EINVAL;
  86. }
  87. for (i = 0; i < nbytes; i++) {
  88. buf[i] = time & 0xff;
  89. time >>= 8;
  90. }
  91. return i2c_smbus_write_i2c_block_data(client, reg, nbytes, buf);
  92. }
  93. static int ds1374_check_rtc_status(struct i2c_client *client)
  94. {
  95. int ret = 0;
  96. int control, stat;
  97. stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
  98. if (stat < 0)
  99. return stat;
  100. if (stat & DS1374_REG_SR_OSF)
  101. dev_warn(&client->dev,
  102. "oscillator discontinuity flagged, "
  103. "time unreliable\n");
  104. stat &= ~(DS1374_REG_SR_OSF | DS1374_REG_SR_AF);
  105. ret = i2c_smbus_write_byte_data(client, DS1374_REG_SR, stat);
  106. if (ret < 0)
  107. return ret;
  108. /* If the alarm is pending, clear it before requesting
  109. * the interrupt, so an interrupt event isn't reported
  110. * before everything is initialized.
  111. */
  112. control = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
  113. if (control < 0)
  114. return control;
  115. control &= ~(DS1374_REG_CR_WACE | DS1374_REG_CR_AIE);
  116. return i2c_smbus_write_byte_data(client, DS1374_REG_CR, control);
  117. }
  118. static int ds1374_read_time(struct device *dev, struct rtc_time *time)
  119. {
  120. struct i2c_client *client = to_i2c_client(dev);
  121. u32 itime;
  122. int ret;
  123. ret = ds1374_read_rtc(client, &itime, DS1374_REG_TOD0, 4);
  124. if (!ret)
  125. rtc_time_to_tm(itime, time);
  126. return ret;
  127. }
  128. static int ds1374_set_time(struct device *dev, struct rtc_time *time)
  129. {
  130. struct i2c_client *client = to_i2c_client(dev);
  131. unsigned long itime;
  132. rtc_tm_to_time(time, &itime);
  133. return ds1374_write_rtc(client, itime, DS1374_REG_TOD0, 4);
  134. }
  135. /* The ds1374 has a decrementer for an alarm, rather than a comparator.
  136. * If the time of day is changed, then the alarm will need to be
  137. * reset.
  138. */
  139. static int ds1374_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
  140. {
  141. struct i2c_client *client = to_i2c_client(dev);
  142. struct ds1374 *ds1374 = i2c_get_clientdata(client);
  143. u32 now, cur_alarm;
  144. int cr, sr;
  145. int ret = 0;
  146. if (client->irq <= 0)
  147. return -EINVAL;
  148. mutex_lock(&ds1374->mutex);
  149. cr = ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
  150. if (ret < 0)
  151. goto out;
  152. sr = ret = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
  153. if (ret < 0)
  154. goto out;
  155. ret = ds1374_read_rtc(client, &now, DS1374_REG_TOD0, 4);
  156. if (ret)
  157. goto out;
  158. ret = ds1374_read_rtc(client, &cur_alarm, DS1374_REG_WDALM0, 3);
  159. if (ret)
  160. goto out;
  161. rtc_time_to_tm(now + cur_alarm, &alarm->time);
  162. alarm->enabled = !!(cr & DS1374_REG_CR_WACE);
  163. alarm->pending = !!(sr & DS1374_REG_SR_AF);
  164. out:
  165. mutex_unlock(&ds1374->mutex);
  166. return ret;
  167. }
  168. static int ds1374_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
  169. {
  170. struct i2c_client *client = to_i2c_client(dev);
  171. struct ds1374 *ds1374 = i2c_get_clientdata(client);
  172. struct rtc_time now;
  173. unsigned long new_alarm, itime;
  174. int cr;
  175. int ret = 0;
  176. if (client->irq <= 0)
  177. return -EINVAL;
  178. ret = ds1374_read_time(dev, &now);
  179. if (ret < 0)
  180. return ret;
  181. rtc_tm_to_time(&alarm->time, &new_alarm);
  182. rtc_tm_to_time(&now, &itime);
  183. /* This can happen due to races, in addition to dates that are
  184. * truly in the past. To avoid requiring the caller to check for
  185. * races, dates in the past are assumed to be in the recent past
  186. * (i.e. not something that we'd rather the caller know about via
  187. * an error), and the alarm is set to go off as soon as possible.
  188. */
  189. if (time_before_eq(new_alarm, itime))
  190. new_alarm = 1;
  191. else
  192. new_alarm -= itime;
  193. mutex_lock(&ds1374->mutex);
  194. ret = cr = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
  195. if (ret < 0)
  196. goto out;
  197. /* Disable any existing alarm before setting the new one
  198. * (or lack thereof). */
  199. cr &= ~DS1374_REG_CR_WACE;
  200. ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr);
  201. if (ret < 0)
  202. goto out;
  203. ret = ds1374_write_rtc(client, new_alarm, DS1374_REG_WDALM0, 3);
  204. if (ret)
  205. goto out;
  206. if (alarm->enabled) {
  207. cr |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE;
  208. cr &= ~DS1374_REG_CR_WDALM;
  209. ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr);
  210. }
  211. out:
  212. mutex_unlock(&ds1374->mutex);
  213. return ret;
  214. }
  215. static irqreturn_t ds1374_irq(int irq, void *dev_id)
  216. {
  217. struct i2c_client *client = dev_id;
  218. struct ds1374 *ds1374 = i2c_get_clientdata(client);
  219. disable_irq_nosync(irq);
  220. schedule_work(&ds1374->work);
  221. return IRQ_HANDLED;
  222. }
  223. static void ds1374_work(struct work_struct *work)
  224. {
  225. struct ds1374 *ds1374 = container_of(work, struct ds1374, work);
  226. struct i2c_client *client = ds1374->client;
  227. int stat, control;
  228. mutex_lock(&ds1374->mutex);
  229. stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
  230. if (stat < 0)
  231. goto unlock;
  232. if (stat & DS1374_REG_SR_AF) {
  233. stat &= ~DS1374_REG_SR_AF;
  234. i2c_smbus_write_byte_data(client, DS1374_REG_SR, stat);
  235. control = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
  236. if (control < 0)
  237. goto out;
  238. control &= ~(DS1374_REG_CR_WACE | DS1374_REG_CR_AIE);
  239. i2c_smbus_write_byte_data(client, DS1374_REG_CR, control);
  240. rtc_update_irq(ds1374->rtc, 1, RTC_AF | RTC_IRQF);
  241. }
  242. out:
  243. if (!ds1374->exiting)
  244. enable_irq(client->irq);
  245. unlock:
  246. mutex_unlock(&ds1374->mutex);
  247. }
  248. static int ds1374_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
  249. {
  250. struct i2c_client *client = to_i2c_client(dev);
  251. struct ds1374 *ds1374 = i2c_get_clientdata(client);
  252. int ret = -ENOIOCTLCMD;
  253. mutex_lock(&ds1374->mutex);
  254. switch (cmd) {
  255. case RTC_AIE_OFF:
  256. ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
  257. if (ret < 0)
  258. goto out;
  259. ret &= ~DS1374_REG_CR_WACE;
  260. ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
  261. if (ret < 0)
  262. goto out;
  263. break;
  264. case RTC_AIE_ON:
  265. ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
  266. if (ret < 0)
  267. goto out;
  268. ret |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE;
  269. ret &= ~DS1374_REG_CR_WDALM;
  270. ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
  271. if (ret < 0)
  272. goto out;
  273. break;
  274. }
  275. out:
  276. mutex_unlock(&ds1374->mutex);
  277. return ret;
  278. }
  279. static const struct rtc_class_ops ds1374_rtc_ops = {
  280. .read_time = ds1374_read_time,
  281. .set_time = ds1374_set_time,
  282. .read_alarm = ds1374_read_alarm,
  283. .set_alarm = ds1374_set_alarm,
  284. .ioctl = ds1374_ioctl,
  285. };
  286. static int ds1374_probe(struct i2c_client *client,
  287. const struct i2c_device_id *id)
  288. {
  289. struct ds1374 *ds1374;
  290. int ret;
  291. ds1374 = kzalloc(sizeof(struct ds1374), GFP_KERNEL);
  292. if (!ds1374)
  293. return -ENOMEM;
  294. ds1374->client = client;
  295. i2c_set_clientdata(client, ds1374);
  296. INIT_WORK(&ds1374->work, ds1374_work);
  297. mutex_init(&ds1374->mutex);
  298. ret = ds1374_check_rtc_status(client);
  299. if (ret)
  300. goto out_free;
  301. if (client->irq > 0) {
  302. ret = request_irq(client->irq, ds1374_irq, 0,
  303. "ds1374", client);
  304. if (ret) {
  305. dev_err(&client->dev, "unable to request IRQ\n");
  306. goto out_free;
  307. }
  308. device_set_wakeup_capable(&client->dev, 1);
  309. }
  310. ds1374->rtc = rtc_device_register(client->name, &client->dev,
  311. &ds1374_rtc_ops, THIS_MODULE);
  312. if (IS_ERR(ds1374->rtc)) {
  313. ret = PTR_ERR(ds1374->rtc);
  314. dev_err(&client->dev, "unable to register the class device\n");
  315. goto out_irq;
  316. }
  317. return 0;
  318. out_irq:
  319. if (client->irq > 0)
  320. free_irq(client->irq, client);
  321. out_free:
  322. kfree(ds1374);
  323. return ret;
  324. }
  325. static int __devexit ds1374_remove(struct i2c_client *client)
  326. {
  327. struct ds1374 *ds1374 = i2c_get_clientdata(client);
  328. if (client->irq > 0) {
  329. mutex_lock(&ds1374->mutex);
  330. ds1374->exiting = 1;
  331. mutex_unlock(&ds1374->mutex);
  332. free_irq(client->irq, client);
  333. cancel_work_sync(&ds1374->work);
  334. }
  335. rtc_device_unregister(ds1374->rtc);
  336. kfree(ds1374);
  337. return 0;
  338. }
  339. #ifdef CONFIG_PM
  340. static int ds1374_suspend(struct i2c_client *client, pm_message_t state)
  341. {
  342. if (client->irq >= 0 && device_may_wakeup(&client->dev))
  343. enable_irq_wake(client->irq);
  344. return 0;
  345. }
  346. static int ds1374_resume(struct i2c_client *client)
  347. {
  348. if (client->irq >= 0 && device_may_wakeup(&client->dev))
  349. disable_irq_wake(client->irq);
  350. return 0;
  351. }
  352. #else
  353. #define ds1374_suspend NULL
  354. #define ds1374_resume NULL
  355. #endif
  356. static struct i2c_driver ds1374_driver = {
  357. .driver = {
  358. .name = "rtc-ds1374",
  359. .owner = THIS_MODULE,
  360. },
  361. .probe = ds1374_probe,
  362. .suspend = ds1374_suspend,
  363. .resume = ds1374_resume,
  364. .remove = __devexit_p(ds1374_remove),
  365. .id_table = ds1374_id,
  366. };
  367. static int __init ds1374_init(void)
  368. {
  369. return i2c_add_driver(&ds1374_driver);
  370. }
  371. static void __exit ds1374_exit(void)
  372. {
  373. i2c_del_driver(&ds1374_driver);
  374. }
  375. module_init(ds1374_init);
  376. module_exit(ds1374_exit);
  377. MODULE_AUTHOR("Scott Wood <scottwood@freescale.com>");
  378. MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC Driver");
  379. MODULE_LICENSE("GPL");