rtc-rc5t619.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * drivers/rtc/rtc-rc5t619.c
  4. *
  5. * Real time clock driver for RICOH RC5T619 power management chip.
  6. *
  7. * Copyright (C) 2019 Andreas Kemnade
  8. */
  9. #include <linux/kernel.h>
  10. #include <linux/device.h>
  11. #include <linux/errno.h>
  12. #include <linux/init.h>
  13. #include <linux/module.h>
  14. #include <linux/mfd/rn5t618.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/regmap.h>
  17. #include <linux/bcd.h>
  18. #include <linux/rtc.h>
  19. #include <linux/slab.h>
  20. #include <linux/irqdomain.h>
  21. struct rc5t619_rtc {
  22. int irq;
  23. struct rtc_device *rtc;
  24. struct rn5t618 *rn5t618;
  25. };
  26. #define CTRL1_ALARM_ENABLED 0x40
  27. #define CTRL1_24HR 0x20
  28. #define CTRL1_PERIODIC_MASK 0xf
  29. #define CTRL2_PON 0x10
  30. #define CTRL2_ALARM_STATUS 0x80
  31. #define CTRL2_CTFG 0x4
  32. #define CTRL2_CTC 0x1
  33. #define MONTH_CENTFLAG 0x80
  34. #define HOUR_PMFLAG 0x20
  35. #define MDAY_DAL_EXT 0x80
  36. static uint8_t rtc5t619_12hour_bcd2bin(uint8_t hour)
  37. {
  38. if (hour & HOUR_PMFLAG) {
  39. hour = bcd2bin(hour & ~HOUR_PMFLAG);
  40. return hour == 12 ? 12 : 12 + hour;
  41. }
  42. hour = bcd2bin(hour);
  43. return hour == 12 ? 0 : hour;
  44. }
  45. static uint8_t rtc5t619_12hour_bin2bcd(uint8_t hour)
  46. {
  47. if (!hour)
  48. return 0x12;
  49. if (hour < 12)
  50. return bin2bcd(hour);
  51. if (hour == 12)
  52. return 0x12 | HOUR_PMFLAG;
  53. return bin2bcd(hour - 12) | HOUR_PMFLAG;
  54. }
  55. static int rc5t619_rtc_periodic_disable(struct device *dev)
  56. {
  57. struct rc5t619_rtc *rtc = dev_get_drvdata(dev);
  58. int err;
  59. /* disable function */
  60. err = regmap_update_bits(rtc->rn5t618->regmap,
  61. RN5T618_RTC_CTRL1, CTRL1_PERIODIC_MASK, 0);
  62. if (err < 0)
  63. return err;
  64. /* clear alarm flag and CTFG */
  65. err = regmap_update_bits(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2,
  66. CTRL2_ALARM_STATUS | CTRL2_CTFG | CTRL2_CTC,
  67. 0);
  68. if (err < 0)
  69. return err;
  70. return 0;
  71. }
  72. /* things to be done once after power on */
  73. static int rc5t619_rtc_pon_setup(struct device *dev)
  74. {
  75. struct rc5t619_rtc *rtc = dev_get_drvdata(dev);
  76. int err;
  77. unsigned int reg_data;
  78. err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, &reg_data);
  79. if (err < 0)
  80. return err;
  81. /* clear VDET PON */
  82. reg_data &= ~(CTRL2_PON | CTRL2_CTC | 0x4a); /* 0101-1011 */
  83. reg_data |= 0x20; /* 0010-0000 */
  84. err = regmap_write(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, reg_data);
  85. if (err < 0)
  86. return err;
  87. /* clearing RTC Adjust register */
  88. err = regmap_write(rtc->rn5t618->regmap, RN5T618_RTC_ADJUST, 0);
  89. if (err)
  90. return err;
  91. return regmap_update_bits(rtc->rn5t618->regmap,
  92. RN5T618_RTC_CTRL1,
  93. CTRL1_24HR, CTRL1_24HR);
  94. }
  95. static int rc5t619_rtc_read_time(struct device *dev, struct rtc_time *tm)
  96. {
  97. struct rc5t619_rtc *rtc = dev_get_drvdata(dev);
  98. u8 buff[7];
  99. int err;
  100. int cent_flag;
  101. unsigned int ctrl1;
  102. unsigned int ctrl2;
  103. err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, &ctrl2);
  104. if (err < 0)
  105. return err;
  106. if (ctrl2 & CTRL2_PON)
  107. return -EINVAL;
  108. err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL1, &ctrl1);
  109. if (err < 0)
  110. return err;
  111. err = regmap_bulk_read(rtc->rn5t618->regmap, RN5T618_RTC_SECONDS,
  112. buff, sizeof(buff));
  113. if (err < 0)
  114. return err;
  115. if (buff[5] & MONTH_CENTFLAG)
  116. cent_flag = 1;
  117. else
  118. cent_flag = 0;
  119. tm->tm_sec = bcd2bin(buff[0]);
  120. tm->tm_min = bcd2bin(buff[1]);
  121. if (ctrl1 & CTRL1_24HR)
  122. tm->tm_hour = bcd2bin(buff[2]);
  123. else
  124. tm->tm_hour = rtc5t619_12hour_bcd2bin(buff[2]);
  125. tm->tm_wday = bcd2bin(buff[3]);
  126. tm->tm_mday = bcd2bin(buff[4]);
  127. tm->tm_mon = bcd2bin(buff[5] & 0x1f) - 1; /* back to system 0-11 */
  128. tm->tm_year = bcd2bin(buff[6]) + 100 * cent_flag;
  129. return 0;
  130. }
  131. static int rc5t619_rtc_set_time(struct device *dev, struct rtc_time *tm)
  132. {
  133. struct rc5t619_rtc *rtc = dev_get_drvdata(dev);
  134. u8 buff[7];
  135. int err;
  136. int cent_flag;
  137. unsigned int ctrl1;
  138. unsigned int ctrl2;
  139. err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, &ctrl2);
  140. if (err < 0)
  141. return err;
  142. if (ctrl2 & CTRL2_PON)
  143. rc5t619_rtc_pon_setup(dev);
  144. err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL1, &ctrl1);
  145. if (err < 0)
  146. return err;
  147. if (tm->tm_year >= 100)
  148. cent_flag = 1;
  149. else
  150. cent_flag = 0;
  151. buff[0] = bin2bcd(tm->tm_sec);
  152. buff[1] = bin2bcd(tm->tm_min);
  153. if (ctrl1 & CTRL1_24HR)
  154. buff[2] = bin2bcd(tm->tm_hour);
  155. else
  156. buff[2] = rtc5t619_12hour_bin2bcd(tm->tm_hour);
  157. buff[3] = bin2bcd(tm->tm_wday);
  158. buff[4] = bin2bcd(tm->tm_mday);
  159. buff[5] = bin2bcd(tm->tm_mon + 1); /* system set 0-11 */
  160. buff[6] = bin2bcd(tm->tm_year - cent_flag * 100);
  161. if (cent_flag)
  162. buff[5] |= MONTH_CENTFLAG;
  163. err = regmap_bulk_write(rtc->rn5t618->regmap, RN5T618_RTC_SECONDS,
  164. buff, sizeof(buff));
  165. if (err < 0) {
  166. dev_err(dev, "failed to program new time: %d\n", err);
  167. return err;
  168. }
  169. return 0;
  170. }
  171. /* 0-disable, 1-enable */
  172. static int rc5t619_rtc_alarm_enable(struct device *dev, unsigned int enabled)
  173. {
  174. struct rc5t619_rtc *rtc = dev_get_drvdata(dev);
  175. return regmap_update_bits(rtc->rn5t618->regmap,
  176. RN5T618_RTC_CTRL1,
  177. CTRL1_ALARM_ENABLED,
  178. enabled ? CTRL1_ALARM_ENABLED : 0);
  179. }
  180. static int rc5t619_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
  181. {
  182. struct rc5t619_rtc *rtc = dev_get_drvdata(dev);
  183. u8 buff[6];
  184. unsigned int buff_cent;
  185. int err;
  186. int cent_flag;
  187. unsigned int ctrl1;
  188. err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL1, &ctrl1);
  189. if (err)
  190. return err;
  191. err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_MONTH, &buff_cent);
  192. if (err < 0) {
  193. dev_err(dev, "failed to read time: %d\n", err);
  194. return err;
  195. }
  196. if (buff_cent & MONTH_CENTFLAG)
  197. cent_flag = 1;
  198. else
  199. cent_flag = 0;
  200. err = regmap_bulk_read(rtc->rn5t618->regmap, RN5T618_RTC_ALARM_Y_SEC,
  201. buff, sizeof(buff));
  202. if (err)
  203. return err;
  204. buff[3] = buff[3] & 0x3f;
  205. alrm->time.tm_sec = bcd2bin(buff[0]);
  206. alrm->time.tm_min = bcd2bin(buff[1]);
  207. if (ctrl1 & CTRL1_24HR)
  208. alrm->time.tm_hour = bcd2bin(buff[2]);
  209. else
  210. alrm->time.tm_hour = rtc5t619_12hour_bcd2bin(buff[2]);
  211. alrm->time.tm_mday = bcd2bin(buff[3]);
  212. alrm->time.tm_mon = bcd2bin(buff[4]) - 1;
  213. alrm->time.tm_year = bcd2bin(buff[5]) + 100 * cent_flag;
  214. alrm->enabled = !!(ctrl1 & CTRL1_ALARM_ENABLED);
  215. dev_dbg(dev, "read alarm: %ptR\n", &alrm->time);
  216. return 0;
  217. }
  218. static int rc5t619_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
  219. {
  220. struct rc5t619_rtc *rtc = dev_get_drvdata(dev);
  221. u8 buff[6];
  222. int err;
  223. int cent_flag;
  224. unsigned int ctrl1;
  225. err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL1, &ctrl1);
  226. if (err)
  227. return err;
  228. err = rc5t619_rtc_alarm_enable(dev, 0);
  229. if (err < 0)
  230. return err;
  231. if (rtc->irq == -1)
  232. return -EINVAL;
  233. if (alrm->enabled == 0)
  234. return 0;
  235. if (alrm->time.tm_year >= 100)
  236. cent_flag = 1;
  237. else
  238. cent_flag = 0;
  239. alrm->time.tm_mon += 1;
  240. buff[0] = bin2bcd(alrm->time.tm_sec);
  241. buff[1] = bin2bcd(alrm->time.tm_min);
  242. if (ctrl1 & CTRL1_24HR)
  243. buff[2] = bin2bcd(alrm->time.tm_hour);
  244. else
  245. buff[2] = rtc5t619_12hour_bin2bcd(alrm->time.tm_hour);
  246. buff[3] = bin2bcd(alrm->time.tm_mday);
  247. buff[4] = bin2bcd(alrm->time.tm_mon);
  248. buff[5] = bin2bcd(alrm->time.tm_year - 100 * cent_flag);
  249. buff[3] |= MDAY_DAL_EXT;
  250. err = regmap_bulk_write(rtc->rn5t618->regmap, RN5T618_RTC_ALARM_Y_SEC,
  251. buff, sizeof(buff));
  252. if (err < 0)
  253. return err;
  254. return rc5t619_rtc_alarm_enable(dev, alrm->enabled);
  255. }
  256. static const struct rtc_class_ops rc5t619_rtc_ops = {
  257. .read_time = rc5t619_rtc_read_time,
  258. .set_time = rc5t619_rtc_set_time,
  259. .set_alarm = rc5t619_rtc_set_alarm,
  260. .read_alarm = rc5t619_rtc_read_alarm,
  261. .alarm_irq_enable = rc5t619_rtc_alarm_enable,
  262. };
  263. static int rc5t619_rtc_alarm_flag_clr(struct device *dev)
  264. {
  265. struct rc5t619_rtc *rtc = dev_get_drvdata(dev);
  266. /* clear alarm-D status bits.*/
  267. return regmap_update_bits(rtc->rn5t618->regmap,
  268. RN5T618_RTC_CTRL2,
  269. CTRL2_ALARM_STATUS | CTRL2_CTC, 0);
  270. }
  271. static irqreturn_t rc5t619_rtc_irq(int irq, void *data)
  272. {
  273. struct device *dev = data;
  274. struct rc5t619_rtc *rtc = dev_get_drvdata(dev);
  275. rc5t619_rtc_alarm_flag_clr(dev);
  276. rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
  277. return IRQ_HANDLED;
  278. }
  279. static int rc5t619_rtc_probe(struct platform_device *pdev)
  280. {
  281. struct device *dev = &pdev->dev;
  282. struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent);
  283. struct rc5t619_rtc *rtc;
  284. unsigned int ctrl2;
  285. int err;
  286. rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL);
  287. if (!rtc)
  288. return -ENOMEM;
  289. rtc->rn5t618 = rn5t618;
  290. dev_set_drvdata(dev, rtc);
  291. rtc->irq = -1;
  292. if (rn5t618->irq_data)
  293. rtc->irq = regmap_irq_get_virq(rn5t618->irq_data,
  294. RN5T618_IRQ_RTC);
  295. if (rtc->irq < 0)
  296. rtc->irq = -1;
  297. err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, &ctrl2);
  298. if (err < 0)
  299. return err;
  300. /* disable rtc periodic function */
  301. err = rc5t619_rtc_periodic_disable(&pdev->dev);
  302. if (err)
  303. return err;
  304. if (ctrl2 & CTRL2_PON) {
  305. err = rc5t619_rtc_alarm_flag_clr(&pdev->dev);
  306. if (err)
  307. return err;
  308. }
  309. rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
  310. if (IS_ERR(rtc->rtc)) {
  311. err = PTR_ERR(rtc->rtc);
  312. dev_err(dev, "RTC device register: err %d\n", err);
  313. return err;
  314. }
  315. rtc->rtc->ops = &rc5t619_rtc_ops;
  316. rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_1900;
  317. rtc->rtc->range_max = RTC_TIMESTAMP_END_2099;
  318. /* set interrupt and enable it */
  319. if (rtc->irq != -1) {
  320. err = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
  321. rc5t619_rtc_irq,
  322. IRQF_ONESHOT,
  323. "rtc-rc5t619",
  324. &pdev->dev);
  325. if (err < 0) {
  326. dev_err(&pdev->dev, "request IRQ:%d fail\n", rtc->irq);
  327. rtc->irq = -1;
  328. err = rc5t619_rtc_alarm_enable(&pdev->dev, 0);
  329. if (err)
  330. return err;
  331. } else {
  332. /* enable wake */
  333. device_init_wakeup(&pdev->dev, 1);
  334. enable_irq_wake(rtc->irq);
  335. }
  336. } else {
  337. /* system don't want to using alarm interrupt, so close it */
  338. err = rc5t619_rtc_alarm_enable(&pdev->dev, 0);
  339. if (err)
  340. return err;
  341. dev_warn(&pdev->dev, "rc5t619 interrupt is disabled\n");
  342. }
  343. return rtc_register_device(rtc->rtc);
  344. }
  345. static struct platform_driver rc5t619_rtc_driver = {
  346. .driver = {
  347. .name = "rc5t619-rtc",
  348. },
  349. .probe = rc5t619_rtc_probe,
  350. };
  351. module_platform_driver(rc5t619_rtc_driver);
  352. MODULE_ALIAS("platform:rc5t619-rtc");
  353. MODULE_DESCRIPTION("RICOH RC5T619 RTC driver");
  354. MODULE_LICENSE("GPL");