rtc-ds1374.c 11 KB

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