rtc-ds1374.c 10 KB

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