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. /* This can happen due to races, in addition to dates that are
  183. * truly in the past. To avoid requiring the caller to check for
  184. * races, dates in the past are assumed to be in the recent past
  185. * (i.e. not something that we'd rather the caller know about via
  186. * an error), and the alarm is set to go off as soon as possible.
  187. */
  188. if (time_before_eq(new_alarm, itime))
  189. new_alarm = 1;
  190. else
  191. new_alarm -= itime;
  192. mutex_lock(&ds1374->mutex);
  193. ret = cr = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
  194. if (ret < 0)
  195. goto out;
  196. /* Disable any existing alarm before setting the new one
  197. * (or lack thereof). */
  198. cr &= ~DS1374_REG_CR_WACE;
  199. ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr);
  200. if (ret < 0)
  201. goto out;
  202. ret = ds1374_write_rtc(client, new_alarm, DS1374_REG_WDALM0, 3);
  203. if (ret)
  204. goto out;
  205. if (alarm->enabled) {
  206. cr |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE;
  207. cr &= ~DS1374_REG_CR_WDALM;
  208. ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr);
  209. }
  210. out:
  211. mutex_unlock(&ds1374->mutex);
  212. return ret;
  213. }
  214. static irqreturn_t ds1374_irq(int irq, void *dev_id)
  215. {
  216. struct i2c_client *client = dev_id;
  217. struct ds1374 *ds1374 = i2c_get_clientdata(client);
  218. disable_irq_nosync(irq);
  219. schedule_work(&ds1374->work);
  220. return IRQ_HANDLED;
  221. }
  222. static void ds1374_work(struct work_struct *work)
  223. {
  224. struct ds1374 *ds1374 = container_of(work, struct ds1374, work);
  225. struct i2c_client *client = ds1374->client;
  226. int stat, control;
  227. mutex_lock(&ds1374->mutex);
  228. stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
  229. if (stat < 0)
  230. return;
  231. if (stat & DS1374_REG_SR_AF) {
  232. stat &= ~DS1374_REG_SR_AF;
  233. i2c_smbus_write_byte_data(client, DS1374_REG_SR, stat);
  234. control = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
  235. if (control < 0)
  236. goto out;
  237. control &= ~(DS1374_REG_CR_WACE | DS1374_REG_CR_AIE);
  238. i2c_smbus_write_byte_data(client, DS1374_REG_CR, control);
  239. /* rtc_update_irq() assumes that it is called
  240. * from IRQ-disabled context.
  241. */
  242. local_irq_disable();
  243. rtc_update_irq(ds1374->rtc, 1, RTC_AF | RTC_IRQF);
  244. local_irq_enable();
  245. }
  246. out:
  247. if (!ds1374->exiting)
  248. enable_irq(client->irq);
  249. mutex_unlock(&ds1374->mutex);
  250. }
  251. static int ds1374_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
  252. {
  253. struct i2c_client *client = to_i2c_client(dev);
  254. struct ds1374 *ds1374 = i2c_get_clientdata(client);
  255. int ret = -ENOIOCTLCMD;
  256. mutex_lock(&ds1374->mutex);
  257. switch (cmd) {
  258. case RTC_AIE_OFF:
  259. ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
  260. if (ret < 0)
  261. goto out;
  262. ret &= ~DS1374_REG_CR_WACE;
  263. ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
  264. if (ret < 0)
  265. goto out;
  266. break;
  267. case RTC_AIE_ON:
  268. ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
  269. if (ret < 0)
  270. goto out;
  271. ret |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE;
  272. ret &= ~DS1374_REG_CR_WDALM;
  273. ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
  274. if (ret < 0)
  275. goto out;
  276. break;
  277. }
  278. out:
  279. mutex_unlock(&ds1374->mutex);
  280. return ret;
  281. }
  282. static const struct rtc_class_ops ds1374_rtc_ops = {
  283. .read_time = ds1374_read_time,
  284. .set_time = ds1374_set_time,
  285. .read_alarm = ds1374_read_alarm,
  286. .set_alarm = ds1374_set_alarm,
  287. .ioctl = ds1374_ioctl,
  288. };
  289. static int ds1374_probe(struct i2c_client *client,
  290. const struct i2c_device_id *id)
  291. {
  292. struct ds1374 *ds1374;
  293. int ret;
  294. ds1374 = kzalloc(sizeof(struct ds1374), GFP_KERNEL);
  295. if (!ds1374)
  296. return -ENOMEM;
  297. ds1374->client = client;
  298. i2c_set_clientdata(client, ds1374);
  299. INIT_WORK(&ds1374->work, ds1374_work);
  300. mutex_init(&ds1374->mutex);
  301. ret = ds1374_check_rtc_status(client);
  302. if (ret)
  303. goto out_free;
  304. if (client->irq > 0) {
  305. ret = request_irq(client->irq, ds1374_irq, 0,
  306. "ds1374", client);
  307. if (ret) {
  308. dev_err(&client->dev, "unable to request IRQ\n");
  309. goto out_free;
  310. }
  311. }
  312. ds1374->rtc = rtc_device_register(client->name, &client->dev,
  313. &ds1374_rtc_ops, THIS_MODULE);
  314. if (IS_ERR(ds1374->rtc)) {
  315. ret = PTR_ERR(ds1374->rtc);
  316. dev_err(&client->dev, "unable to register the class device\n");
  317. goto out_irq;
  318. }
  319. return 0;
  320. out_irq:
  321. if (client->irq > 0)
  322. free_irq(client->irq, client);
  323. out_free:
  324. i2c_set_clientdata(client, NULL);
  325. kfree(ds1374);
  326. return ret;
  327. }
  328. static int __devexit ds1374_remove(struct i2c_client *client)
  329. {
  330. struct ds1374 *ds1374 = i2c_get_clientdata(client);
  331. if (client->irq > 0) {
  332. mutex_lock(&ds1374->mutex);
  333. ds1374->exiting = 1;
  334. mutex_unlock(&ds1374->mutex);
  335. free_irq(client->irq, client);
  336. flush_scheduled_work();
  337. }
  338. rtc_device_unregister(ds1374->rtc);
  339. i2c_set_clientdata(client, NULL);
  340. kfree(ds1374);
  341. return 0;
  342. }
  343. #ifdef CONFIG_PM
  344. static int ds1374_suspend(struct i2c_client *client, pm_message_t state)
  345. {
  346. if (client->irq >= 0 && device_may_wakeup(&client->dev))
  347. enable_irq_wake(client->irq);
  348. return 0;
  349. }
  350. static int ds1374_resume(struct i2c_client *client)
  351. {
  352. if (client->irq >= 0 && device_may_wakeup(&client->dev))
  353. disable_irq_wake(client->irq);
  354. return 0;
  355. }
  356. #else
  357. #define ds1374_suspend NULL
  358. #define ds1374_resume NULL
  359. #endif
  360. static struct i2c_driver ds1374_driver = {
  361. .driver = {
  362. .name = "rtc-ds1374",
  363. .owner = THIS_MODULE,
  364. },
  365. .probe = ds1374_probe,
  366. .suspend = ds1374_suspend,
  367. .resume = ds1374_resume,
  368. .remove = __devexit_p(ds1374_remove),
  369. .id_table = ds1374_id,
  370. };
  371. static int __init ds1374_init(void)
  372. {
  373. return i2c_add_driver(&ds1374_driver);
  374. }
  375. static void __exit ds1374_exit(void)
  376. {
  377. i2c_del_driver(&ds1374_driver);
  378. }
  379. module_init(ds1374_init);
  380. module_exit(ds1374_exit);
  381. MODULE_AUTHOR("Scott Wood <scottwood@freescale.com>");
  382. MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC Driver");
  383. MODULE_LICENSE("GPL");