rtc-s5m.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792
  1. /*
  2. * Copyright (c) 2013-2014 Samsung Electronics Co., Ltd
  3. * http://www.samsung.com
  4. *
  5. * Copyright (C) 2013 Google, Inc
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. */
  17. #include <linux/module.h>
  18. #include <linux/i2c.h>
  19. #include <linux/slab.h>
  20. #include <linux/bcd.h>
  21. #include <linux/bitops.h>
  22. #include <linux/regmap.h>
  23. #include <linux/rtc.h>
  24. #include <linux/delay.h>
  25. #include <linux/platform_device.h>
  26. #include <linux/mfd/samsung/core.h>
  27. #include <linux/mfd/samsung/irq.h>
  28. #include <linux/mfd/samsung/rtc.h>
  29. /*
  30. * Maximum number of retries for checking changes in UDR field
  31. * of S5M_RTC_UDR_CON register (to limit possible endless loop).
  32. *
  33. * After writing to RTC registers (setting time or alarm) read the UDR field
  34. * in S5M_RTC_UDR_CON register. UDR is auto-cleared when data have
  35. * been transferred.
  36. */
  37. #define UDR_READ_RETRY_CNT 5
  38. /* Registers used by the driver which are different between chipsets. */
  39. struct s5m_rtc_reg_config {
  40. /* Number of registers used for setting time/alarm0/alarm1 */
  41. unsigned int regs_count;
  42. /* First register for time, seconds */
  43. unsigned int time;
  44. /* RTC control register */
  45. unsigned int ctrl;
  46. /* First register for alarm 0, seconds */
  47. unsigned int alarm0;
  48. /* First register for alarm 1, seconds */
  49. unsigned int alarm1;
  50. /* SMPL/WTSR register */
  51. unsigned int smpl_wtsr;
  52. /*
  53. * Register for update flag (UDR). Typically setting UDR field to 1
  54. * will enable update of time or alarm register. Then it will be
  55. * auto-cleared after successful update.
  56. */
  57. unsigned int rtc_udr_update;
  58. /* Mask for UDR field in 'rtc_udr_update' register */
  59. unsigned int rtc_udr_mask;
  60. };
  61. /* Register map for S5M8763 and S5M8767 */
  62. static const struct s5m_rtc_reg_config s5m_rtc_regs = {
  63. .regs_count = 8,
  64. .time = S5M_RTC_SEC,
  65. .ctrl = S5M_ALARM1_CONF,
  66. .alarm0 = S5M_ALARM0_SEC,
  67. .alarm1 = S5M_ALARM1_SEC,
  68. .smpl_wtsr = S5M_WTSR_SMPL_CNTL,
  69. .rtc_udr_update = S5M_RTC_UDR_CON,
  70. .rtc_udr_mask = S5M_RTC_UDR_MASK,
  71. };
  72. struct s5m_rtc_info {
  73. struct device *dev;
  74. struct i2c_client *i2c;
  75. struct sec_pmic_dev *s5m87xx;
  76. struct regmap *regmap;
  77. struct rtc_device *rtc_dev;
  78. int irq;
  79. int device_type;
  80. int rtc_24hr_mode;
  81. bool wtsr_smpl;
  82. const struct s5m_rtc_reg_config *regs;
  83. };
  84. static const struct regmap_config s5m_rtc_regmap_config = {
  85. .reg_bits = 8,
  86. .val_bits = 8,
  87. .max_register = S5M_RTC_REG_MAX,
  88. };
  89. static const struct regmap_config s2mps14_rtc_regmap_config = {
  90. .reg_bits = 8,
  91. .val_bits = 8,
  92. .max_register = S2MPS_RTC_REG_MAX,
  93. };
  94. static void s5m8767_data_to_tm(u8 *data, struct rtc_time *tm,
  95. int rtc_24hr_mode)
  96. {
  97. tm->tm_sec = data[RTC_SEC] & 0x7f;
  98. tm->tm_min = data[RTC_MIN] & 0x7f;
  99. if (rtc_24hr_mode) {
  100. tm->tm_hour = data[RTC_HOUR] & 0x1f;
  101. } else {
  102. tm->tm_hour = data[RTC_HOUR] & 0x0f;
  103. if (data[RTC_HOUR] & HOUR_PM_MASK)
  104. tm->tm_hour += 12;
  105. }
  106. tm->tm_wday = ffs(data[RTC_WEEKDAY] & 0x7f);
  107. tm->tm_mday = data[RTC_DATE] & 0x1f;
  108. tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1;
  109. tm->tm_year = (data[RTC_YEAR1] & 0x7f) + 100;
  110. tm->tm_yday = 0;
  111. tm->tm_isdst = 0;
  112. }
  113. static int s5m8767_tm_to_data(struct rtc_time *tm, u8 *data)
  114. {
  115. data[RTC_SEC] = tm->tm_sec;
  116. data[RTC_MIN] = tm->tm_min;
  117. if (tm->tm_hour >= 12)
  118. data[RTC_HOUR] = tm->tm_hour | HOUR_PM_MASK;
  119. else
  120. data[RTC_HOUR] = tm->tm_hour & ~HOUR_PM_MASK;
  121. data[RTC_WEEKDAY] = 1 << tm->tm_wday;
  122. data[RTC_DATE] = tm->tm_mday;
  123. data[RTC_MONTH] = tm->tm_mon + 1;
  124. data[RTC_YEAR1] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0;
  125. if (tm->tm_year < 100) {
  126. pr_err("s5m8767 RTC cannot handle the year %d.\n",
  127. 1900 + tm->tm_year);
  128. return -EINVAL;
  129. } else {
  130. return 0;
  131. }
  132. }
  133. /*
  134. * Read RTC_UDR_CON register and wait till UDR field is cleared.
  135. * This indicates that time/alarm update ended.
  136. */
  137. static inline int s5m8767_wait_for_udr_update(struct s5m_rtc_info *info)
  138. {
  139. int ret, retry = UDR_READ_RETRY_CNT;
  140. unsigned int data;
  141. do {
  142. ret = regmap_read(info->regmap, info->regs->rtc_udr_update,
  143. &data);
  144. } while (--retry && (data & info->regs->rtc_udr_mask) && !ret);
  145. if (!retry)
  146. dev_err(info->dev, "waiting for UDR update, reached max number of retries\n");
  147. return ret;
  148. }
  149. static inline int s5m_check_peding_alarm_interrupt(struct s5m_rtc_info *info,
  150. struct rtc_wkalrm *alarm)
  151. {
  152. int ret;
  153. unsigned int val;
  154. switch (info->device_type) {
  155. case S5M8767X:
  156. case S5M8763X:
  157. ret = regmap_read(info->regmap, S5M_RTC_STATUS, &val);
  158. val &= S5M_ALARM0_STATUS;
  159. break;
  160. default:
  161. return -EINVAL;
  162. }
  163. if (ret < 0)
  164. return ret;
  165. if (val)
  166. alarm->pending = 1;
  167. else
  168. alarm->pending = 0;
  169. return 0;
  170. }
  171. static inline int s5m8767_rtc_set_time_reg(struct s5m_rtc_info *info)
  172. {
  173. int ret;
  174. unsigned int data;
  175. ret = regmap_read(info->regmap, info->regs->rtc_udr_update, &data);
  176. if (ret < 0) {
  177. dev_err(info->dev, "failed to read update reg(%d)\n", ret);
  178. return ret;
  179. }
  180. data |= S5M_RTC_TIME_EN_MASK;
  181. data |= info->regs->rtc_udr_mask;
  182. ret = regmap_write(info->regmap, info->regs->rtc_udr_update, data);
  183. if (ret < 0) {
  184. dev_err(info->dev, "failed to write update reg(%d)\n", ret);
  185. return ret;
  186. }
  187. ret = s5m8767_wait_for_udr_update(info);
  188. return ret;
  189. }
  190. static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
  191. {
  192. int ret;
  193. unsigned int data;
  194. ret = regmap_read(info->regmap, info->regs->rtc_udr_update, &data);
  195. if (ret < 0) {
  196. dev_err(info->dev, "%s: fail to read update reg(%d)\n",
  197. __func__, ret);
  198. return ret;
  199. }
  200. data &= ~S5M_RTC_TIME_EN_MASK;
  201. data |= info->regs->rtc_udr_mask;
  202. ret = regmap_write(info->regmap, info->regs->rtc_udr_update, data);
  203. if (ret < 0) {
  204. dev_err(info->dev, "%s: fail to write update reg(%d)\n",
  205. __func__, ret);
  206. return ret;
  207. }
  208. ret = s5m8767_wait_for_udr_update(info);
  209. return ret;
  210. }
  211. static void s5m8763_data_to_tm(u8 *data, struct rtc_time *tm)
  212. {
  213. tm->tm_sec = bcd2bin(data[RTC_SEC]);
  214. tm->tm_min = bcd2bin(data[RTC_MIN]);
  215. if (data[RTC_HOUR] & HOUR_12) {
  216. tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x1f);
  217. if (data[RTC_HOUR] & HOUR_PM)
  218. tm->tm_hour += 12;
  219. } else {
  220. tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3f);
  221. }
  222. tm->tm_wday = data[RTC_WEEKDAY] & 0x07;
  223. tm->tm_mday = bcd2bin(data[RTC_DATE]);
  224. tm->tm_mon = bcd2bin(data[RTC_MONTH]);
  225. tm->tm_year = bcd2bin(data[RTC_YEAR1]) + bcd2bin(data[RTC_YEAR2]) * 100;
  226. tm->tm_year -= 1900;
  227. }
  228. static void s5m8763_tm_to_data(struct rtc_time *tm, u8 *data)
  229. {
  230. data[RTC_SEC] = bin2bcd(tm->tm_sec);
  231. data[RTC_MIN] = bin2bcd(tm->tm_min);
  232. data[RTC_HOUR] = bin2bcd(tm->tm_hour);
  233. data[RTC_WEEKDAY] = tm->tm_wday;
  234. data[RTC_DATE] = bin2bcd(tm->tm_mday);
  235. data[RTC_MONTH] = bin2bcd(tm->tm_mon);
  236. data[RTC_YEAR1] = bin2bcd(tm->tm_year % 100);
  237. data[RTC_YEAR2] = bin2bcd((tm->tm_year + 1900) / 100);
  238. }
  239. static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
  240. {
  241. struct s5m_rtc_info *info = dev_get_drvdata(dev);
  242. u8 data[info->regs->regs_count];
  243. int ret;
  244. ret = regmap_bulk_read(info->regmap, info->regs->time, data,
  245. info->regs->regs_count);
  246. if (ret < 0)
  247. return ret;
  248. switch (info->device_type) {
  249. case S5M8763X:
  250. s5m8763_data_to_tm(data, tm);
  251. break;
  252. case S5M8767X:
  253. s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode);
  254. break;
  255. default:
  256. return -EINVAL;
  257. }
  258. dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
  259. 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
  260. tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
  261. return rtc_valid_tm(tm);
  262. }
  263. static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
  264. {
  265. struct s5m_rtc_info *info = dev_get_drvdata(dev);
  266. u8 data[info->regs->regs_count];
  267. int ret = 0;
  268. switch (info->device_type) {
  269. case S5M8763X:
  270. s5m8763_tm_to_data(tm, data);
  271. break;
  272. case S5M8767X:
  273. ret = s5m8767_tm_to_data(tm, data);
  274. break;
  275. default:
  276. return -EINVAL;
  277. }
  278. if (ret < 0)
  279. return ret;
  280. dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
  281. 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
  282. tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
  283. ret = regmap_raw_write(info->regmap, info->regs->time, data,
  284. info->regs->regs_count);
  285. if (ret < 0)
  286. return ret;
  287. ret = s5m8767_rtc_set_time_reg(info);
  288. return ret;
  289. }
  290. static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
  291. {
  292. struct s5m_rtc_info *info = dev_get_drvdata(dev);
  293. u8 data[info->regs->regs_count];
  294. unsigned int val;
  295. int ret, i;
  296. ret = regmap_bulk_read(info->regmap, info->regs->alarm0, data,
  297. info->regs->regs_count);
  298. if (ret < 0)
  299. return ret;
  300. switch (info->device_type) {
  301. case S5M8763X:
  302. s5m8763_data_to_tm(data, &alrm->time);
  303. ret = regmap_read(info->regmap, S5M_ALARM0_CONF, &val);
  304. if (ret < 0)
  305. return ret;
  306. alrm->enabled = !!val;
  307. break;
  308. case S5M8767X:
  309. s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode);
  310. alrm->enabled = 0;
  311. for (i = 0; i < info->regs->regs_count; i++) {
  312. if (data[i] & ALARM_ENABLE_MASK) {
  313. alrm->enabled = 1;
  314. break;
  315. }
  316. }
  317. break;
  318. default:
  319. return -EINVAL;
  320. }
  321. dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
  322. 1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon,
  323. alrm->time.tm_mday, alrm->time.tm_hour,
  324. alrm->time.tm_min, alrm->time.tm_sec,
  325. alrm->time.tm_wday);
  326. ret = s5m_check_peding_alarm_interrupt(info, alrm);
  327. return 0;
  328. }
  329. static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
  330. {
  331. u8 data[info->regs->regs_count];
  332. int ret, i;
  333. struct rtc_time tm;
  334. ret = regmap_bulk_read(info->regmap, info->regs->alarm0, data,
  335. info->regs->regs_count);
  336. if (ret < 0)
  337. return ret;
  338. s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode);
  339. dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
  340. 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
  341. tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
  342. switch (info->device_type) {
  343. case S5M8763X:
  344. ret = regmap_write(info->regmap, S5M_ALARM0_CONF, 0);
  345. break;
  346. case S5M8767X:
  347. for (i = 0; i < info->regs->regs_count; i++)
  348. data[i] &= ~ALARM_ENABLE_MASK;
  349. ret = regmap_raw_write(info->regmap, info->regs->alarm0, data,
  350. info->regs->regs_count);
  351. if (ret < 0)
  352. return ret;
  353. ret = s5m8767_rtc_set_alarm_reg(info);
  354. break;
  355. default:
  356. return -EINVAL;
  357. }
  358. return ret;
  359. }
  360. static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
  361. {
  362. int ret;
  363. u8 data[info->regs->regs_count];
  364. u8 alarm0_conf;
  365. struct rtc_time tm;
  366. ret = regmap_bulk_read(info->regmap, info->regs->alarm0, data,
  367. info->regs->regs_count);
  368. if (ret < 0)
  369. return ret;
  370. s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode);
  371. dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
  372. 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
  373. tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
  374. switch (info->device_type) {
  375. case S5M8763X:
  376. alarm0_conf = 0x77;
  377. ret = regmap_write(info->regmap, S5M_ALARM0_CONF, alarm0_conf);
  378. break;
  379. case S5M8767X:
  380. data[RTC_SEC] |= ALARM_ENABLE_MASK;
  381. data[RTC_MIN] |= ALARM_ENABLE_MASK;
  382. data[RTC_HOUR] |= ALARM_ENABLE_MASK;
  383. data[RTC_WEEKDAY] &= ~ALARM_ENABLE_MASK;
  384. if (data[RTC_DATE] & 0x1f)
  385. data[RTC_DATE] |= ALARM_ENABLE_MASK;
  386. if (data[RTC_MONTH] & 0xf)
  387. data[RTC_MONTH] |= ALARM_ENABLE_MASK;
  388. if (data[RTC_YEAR1] & 0x7f)
  389. data[RTC_YEAR1] |= ALARM_ENABLE_MASK;
  390. ret = regmap_raw_write(info->regmap, info->regs->alarm0, data,
  391. info->regs->regs_count);
  392. if (ret < 0)
  393. return ret;
  394. ret = s5m8767_rtc_set_alarm_reg(info);
  395. break;
  396. default:
  397. return -EINVAL;
  398. }
  399. return ret;
  400. }
  401. static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
  402. {
  403. struct s5m_rtc_info *info = dev_get_drvdata(dev);
  404. u8 data[info->regs->regs_count];
  405. int ret;
  406. switch (info->device_type) {
  407. case S5M8763X:
  408. s5m8763_tm_to_data(&alrm->time, data);
  409. break;
  410. case S5M8767X:
  411. s5m8767_tm_to_data(&alrm->time, data);
  412. break;
  413. default:
  414. return -EINVAL;
  415. }
  416. dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
  417. 1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon,
  418. alrm->time.tm_mday, alrm->time.tm_hour, alrm->time.tm_min,
  419. alrm->time.tm_sec, alrm->time.tm_wday);
  420. ret = s5m_rtc_stop_alarm(info);
  421. if (ret < 0)
  422. return ret;
  423. ret = regmap_raw_write(info->regmap, info->regs->alarm0, data,
  424. info->regs->regs_count);
  425. if (ret < 0)
  426. return ret;
  427. ret = s5m8767_rtc_set_alarm_reg(info);
  428. if (ret < 0)
  429. return ret;
  430. if (alrm->enabled)
  431. ret = s5m_rtc_start_alarm(info);
  432. return ret;
  433. }
  434. static int s5m_rtc_alarm_irq_enable(struct device *dev,
  435. unsigned int enabled)
  436. {
  437. struct s5m_rtc_info *info = dev_get_drvdata(dev);
  438. if (enabled)
  439. return s5m_rtc_start_alarm(info);
  440. else
  441. return s5m_rtc_stop_alarm(info);
  442. }
  443. static irqreturn_t s5m_rtc_alarm_irq(int irq, void *data)
  444. {
  445. struct s5m_rtc_info *info = data;
  446. rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF);
  447. return IRQ_HANDLED;
  448. }
  449. static const struct rtc_class_ops s5m_rtc_ops = {
  450. .read_time = s5m_rtc_read_time,
  451. .set_time = s5m_rtc_set_time,
  452. .read_alarm = s5m_rtc_read_alarm,
  453. .set_alarm = s5m_rtc_set_alarm,
  454. .alarm_irq_enable = s5m_rtc_alarm_irq_enable,
  455. };
  456. static void s5m_rtc_enable_wtsr(struct s5m_rtc_info *info, bool enable)
  457. {
  458. int ret;
  459. ret = regmap_update_bits(info->regmap, info->regs->smpl_wtsr,
  460. WTSR_ENABLE_MASK,
  461. enable ? WTSR_ENABLE_MASK : 0);
  462. if (ret < 0)
  463. dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n",
  464. __func__, ret);
  465. }
  466. static void s5m_rtc_enable_smpl(struct s5m_rtc_info *info, bool enable)
  467. {
  468. int ret;
  469. ret = regmap_update_bits(info->regmap, info->regs->smpl_wtsr,
  470. SMPL_ENABLE_MASK,
  471. enable ? SMPL_ENABLE_MASK : 0);
  472. if (ret < 0)
  473. dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n",
  474. __func__, ret);
  475. }
  476. static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
  477. {
  478. u8 data[2];
  479. int ret;
  480. /* UDR update time. Default of 7.32 ms is too long. */
  481. ret = regmap_update_bits(info->regmap, S5M_RTC_UDR_CON,
  482. S5M_RTC_UDR_T_MASK, S5M_RTC_UDR_T_450_US);
  483. if (ret < 0)
  484. dev_err(info->dev, "%s: fail to change UDR time: %d\n",
  485. __func__, ret);
  486. /* Set RTC control register : Binary mode, 24hour mode */
  487. data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
  488. data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
  489. info->rtc_24hr_mode = 1;
  490. ret = regmap_raw_write(info->regmap, S5M_ALARM0_CONF, data, 2);
  491. if (ret < 0) {
  492. dev_err(info->dev, "%s: fail to write controlm reg(%d)\n",
  493. __func__, ret);
  494. return ret;
  495. }
  496. return ret;
  497. }
  498. static int s5m_rtc_probe(struct platform_device *pdev)
  499. {
  500. struct sec_pmic_dev *s5m87xx = dev_get_drvdata(pdev->dev.parent);
  501. struct sec_platform_data *pdata = s5m87xx->pdata;
  502. struct s5m_rtc_info *info;
  503. const struct regmap_config *regmap_cfg;
  504. int ret;
  505. if (!pdata) {
  506. dev_err(pdev->dev.parent, "Platform data not supplied\n");
  507. return -ENODEV;
  508. }
  509. info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
  510. if (!info)
  511. return -ENOMEM;
  512. switch (pdata->device_type) {
  513. case S2MPS14X:
  514. regmap_cfg = &s2mps14_rtc_regmap_config;
  515. break;
  516. case S5M8763X:
  517. regmap_cfg = &s5m_rtc_regmap_config;
  518. info->regs = &s5m_rtc_regs;
  519. break;
  520. case S5M8767X:
  521. regmap_cfg = &s5m_rtc_regmap_config;
  522. info->regs = &s5m_rtc_regs;
  523. break;
  524. default:
  525. dev_err(&pdev->dev, "Device type is not supported by RTC driver\n");
  526. return -ENODEV;
  527. }
  528. info->i2c = i2c_new_dummy(s5m87xx->i2c->adapter, RTC_I2C_ADDR);
  529. if (!info->i2c) {
  530. dev_err(&pdev->dev, "Failed to allocate I2C for RTC\n");
  531. return -ENODEV;
  532. }
  533. info->regmap = devm_regmap_init_i2c(info->i2c, regmap_cfg);
  534. if (IS_ERR(info->regmap)) {
  535. ret = PTR_ERR(info->regmap);
  536. dev_err(&pdev->dev, "Failed to allocate RTC register map: %d\n",
  537. ret);
  538. goto err;
  539. }
  540. info->dev = &pdev->dev;
  541. info->s5m87xx = s5m87xx;
  542. info->device_type = s5m87xx->device_type;
  543. info->wtsr_smpl = s5m87xx->wtsr_smpl;
  544. switch (pdata->device_type) {
  545. case S5M8763X:
  546. info->irq = regmap_irq_get_virq(s5m87xx->irq_data,
  547. S5M8763_IRQ_ALARM0);
  548. break;
  549. case S5M8767X:
  550. info->irq = regmap_irq_get_virq(s5m87xx->irq_data,
  551. S5M8767_IRQ_RTCA1);
  552. break;
  553. default:
  554. ret = -EINVAL;
  555. dev_err(&pdev->dev, "Unsupported device type: %d\n", ret);
  556. goto err;
  557. }
  558. platform_set_drvdata(pdev, info);
  559. ret = s5m8767_rtc_init_reg(info);
  560. if (info->wtsr_smpl) {
  561. s5m_rtc_enable_wtsr(info, true);
  562. s5m_rtc_enable_smpl(info, true);
  563. }
  564. device_init_wakeup(&pdev->dev, 1);
  565. info->rtc_dev = devm_rtc_device_register(&pdev->dev, "s5m-rtc",
  566. &s5m_rtc_ops, THIS_MODULE);
  567. if (IS_ERR(info->rtc_dev)) {
  568. ret = PTR_ERR(info->rtc_dev);
  569. goto err;
  570. }
  571. ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL,
  572. s5m_rtc_alarm_irq, 0, "rtc-alarm0",
  573. info);
  574. if (ret < 0) {
  575. dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
  576. info->irq, ret);
  577. goto err;
  578. }
  579. return 0;
  580. err:
  581. i2c_unregister_device(info->i2c);
  582. return ret;
  583. }
  584. static void s5m_rtc_shutdown(struct platform_device *pdev)
  585. {
  586. struct s5m_rtc_info *info = platform_get_drvdata(pdev);
  587. int i;
  588. unsigned int val = 0;
  589. if (info->wtsr_smpl) {
  590. for (i = 0; i < 3; i++) {
  591. s5m_rtc_enable_wtsr(info, false);
  592. regmap_read(info->regmap, info->regs->smpl_wtsr, &val);
  593. pr_debug("%s: WTSR_SMPL reg(0x%02x)\n", __func__, val);
  594. if (val & WTSR_ENABLE_MASK)
  595. pr_emerg("%s: fail to disable WTSR\n",
  596. __func__);
  597. else {
  598. pr_info("%s: success to disable WTSR\n",
  599. __func__);
  600. break;
  601. }
  602. }
  603. }
  604. /* Disable SMPL when power off */
  605. s5m_rtc_enable_smpl(info, false);
  606. }
  607. static int s5m_rtc_remove(struct platform_device *pdev)
  608. {
  609. struct s5m_rtc_info *info = platform_get_drvdata(pdev);
  610. /* Perform also all shutdown steps when removing */
  611. s5m_rtc_shutdown(pdev);
  612. i2c_unregister_device(info->i2c);
  613. return 0;
  614. }
  615. #ifdef CONFIG_PM_SLEEP
  616. static int s5m_rtc_resume(struct device *dev)
  617. {
  618. struct s5m_rtc_info *info = dev_get_drvdata(dev);
  619. int ret = 0;
  620. if (device_may_wakeup(dev))
  621. ret = disable_irq_wake(info->irq);
  622. return ret;
  623. }
  624. static int s5m_rtc_suspend(struct device *dev)
  625. {
  626. struct s5m_rtc_info *info = dev_get_drvdata(dev);
  627. int ret = 0;
  628. if (device_may_wakeup(dev))
  629. ret = enable_irq_wake(info->irq);
  630. return ret;
  631. }
  632. #endif /* CONFIG_PM_SLEEP */
  633. static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume);
  634. static const struct platform_device_id s5m_rtc_id[] = {
  635. { "s5m-rtc", 0 },
  636. };
  637. static struct platform_driver s5m_rtc_driver = {
  638. .driver = {
  639. .name = "s5m-rtc",
  640. .owner = THIS_MODULE,
  641. .pm = &s5m_rtc_pm_ops,
  642. },
  643. .probe = s5m_rtc_probe,
  644. .remove = s5m_rtc_remove,
  645. .shutdown = s5m_rtc_shutdown,
  646. .id_table = s5m_rtc_id,
  647. };
  648. module_platform_driver(s5m_rtc_driver);
  649. /* Module information */
  650. MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
  651. MODULE_DESCRIPTION("Samsung S5M RTC driver");
  652. MODULE_LICENSE("GPL");
  653. MODULE_ALIAS("platform:s5m-rtc");