814-rtc-support-layerscape.patch 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. From 7e7944c484954ff7b5d53047194e59bfffd1540a Mon Sep 17 00:00:00 2001
  2. From: Yangbo Lu <[email protected]>
  3. Date: Mon, 25 Sep 2017 12:20:55 +0800
  4. Subject: [PATCH] rtc: support layerscape
  5. This is a integrated patch for layerscape rtc support.
  6. Signed-off-by: Zhang Ying-22455 <[email protected]>
  7. Signed-off-by: Yangbo Lu <[email protected]>
  8. ---
  9. drivers/rtc/rtc-pcf85263.c | 665 +++++++++++++++++++++++++++++++++++++++++++++
  10. 1 file changed, 665 insertions(+)
  11. create mode 100644 drivers/rtc/rtc-pcf85263.c
  12. --- /dev/null
  13. +++ b/drivers/rtc/rtc-pcf85263.c
  14. @@ -0,0 +1,665 @@
  15. +/*
  16. + * rtc-pcf85263 Driver for the NXP PCF85263 RTC
  17. + * Copyright 2016 Parkeon
  18. + *
  19. + * This program is free software; you can redistribute it and/or modify
  20. + * it under the terms of the GNU General Public License version 2 as
  21. + * published by the Free Software Foundation.
  22. + */
  23. +
  24. +#include <linux/module.h>
  25. +#include <linux/mutex.h>
  26. +#include <linux/rtc.h>
  27. +#include <linux/i2c.h>
  28. +#include <linux/bcd.h>
  29. +#include <linux/of.h>
  30. +#include <linux/of_device.h>
  31. +#include <linux/regmap.h>
  32. +
  33. +
  34. +#define DRV_NAME "rtc-pcf85263"
  35. +
  36. +/* Quartz capacitance */
  37. +#define PCF85263_QUARTZCAP_7pF 0
  38. +#define PCF85263_QUARTZCAP_6pF 1
  39. +#define PCF85263_QUARTZCAP_12p5pF 2
  40. +
  41. +/* Quartz drive strength */
  42. +#define PCF85263_QUARTZDRIVE_NORMAL 0
  43. +#define PCF85263_QUARTZDRIVE_LOW 1
  44. +#define PCF85263_QUARTZDRIVE_HIGH 2
  45. +
  46. +
  47. +#define PCF85263_REG_RTC_SC 0x01 /* Seconds */
  48. +#define PCF85263_REG_RTC_SC_OS BIT(7) /* Oscilator stopped flag */
  49. +
  50. +#define PCF85263_REG_RTC_MN 0x02 /* Minutes */
  51. +#define PCF85263_REG_RTC_HR 0x03 /* Hours */
  52. +#define PCF85263_REG_RTC_DT 0x04 /* Day of month 1-31 */
  53. +#define PCF85263_REG_RTC_DW 0x05 /* Day of week 0-6 */
  54. +#define PCF85263_REG_RTC_MO 0x06 /* Month 1-12 */
  55. +#define PCF85263_REG_RTC_YR 0x07 /* Year 0-99 */
  56. +
  57. +#define PCF85263_REG_ALM1_SC 0x08 /* Seconds */
  58. +#define PCF85263_REG_ALM1_MN 0x09 /* Minutes */
  59. +#define PCF85263_REG_ALM1_HR 0x0a /* Hours */
  60. +#define PCF85263_REG_ALM1_DT 0x0b /* Day of month 1-31 */
  61. +#define PCF85263_REG_ALM1_MO 0x0c /* Month 1-12 */
  62. +
  63. +#define PCF85263_REG_ALM_CTL 0x10
  64. +#define PCF85263_REG_ALM_CTL_ALL_A1E 0x1f /* sec,min,hr,day,mon alarm 1 */
  65. +
  66. +#define PCF85263_REG_OSC 0x25
  67. +#define PCF85263_REG_OSC_CL_MASK (BIT(0) | BIT(1))
  68. +#define PCF85263_REG_OSC_CL_SHIFT 0
  69. +#define PCF85263_REG_OSC_OSCD_MASK (BIT(2) | BIT(3))
  70. +#define PCF85263_REG_OSC_OSCD_SHIFT 2
  71. +#define PCF85263_REG_OSC_LOWJ BIT(4)
  72. +#define PCF85263_REG_OSC_12H BIT(5)
  73. +
  74. +#define PCF85263_REG_PINIO 0x27
  75. +#define PCF85263_REG_PINIO_INTAPM_MASK (BIT(0) | BIT(1))
  76. +#define PCF85263_REG_PINIO_INTAPM_SHIFT 0
  77. +#define PCF85263_INTAPM_INTA (0x2 << PCF85263_REG_PINIO_INTAPM_SHIFT)
  78. +#define PCF85263_INTAPM_HIGHZ (0x3 << PCF85263_REG_PINIO_INTAPM_SHIFT)
  79. +#define PCF85263_REG_PINIO_TSPM_MASK (BIT(2) | BIT(3))
  80. +#define PCF85263_REG_PINIO_TSPM_SHIFT 2
  81. +#define PCF85263_TSPM_DISABLED (0x0 << PCF85263_REG_PINIO_TSPM_SHIFT)
  82. +#define PCF85263_TSPM_INTB (0x1 << PCF85263_REG_PINIO_TSPM_SHIFT)
  83. +#define PCF85263_REG_PINIO_CLKDISABLE BIT(7)
  84. +
  85. +#define PCF85263_REG_FUNCTION 0x28
  86. +#define PCF85263_REG_FUNCTION_COF_MASK 0x7
  87. +#define PCF85263_REG_FUNCTION_COF_OFF 0x7 /* No clock output */
  88. +
  89. +#define PCF85263_REG_INTA_CTL 0x29
  90. +#define PCF85263_REG_INTB_CTL 0x2A
  91. +#define PCF85263_REG_INTx_CTL_A1E BIT(4) /* Alarm 1 */
  92. +#define PCF85263_REG_INTx_CTL_ILP BIT(7) /* 0=pulse, 1=level */
  93. +
  94. +#define PCF85263_REG_FLAGS 0x2B
  95. +#define PCF85263_REG_FLAGS_A1F BIT(5)
  96. +
  97. +#define PCF85263_REG_RAM_BYTE 0x2c
  98. +
  99. +#define PCF85263_REG_STOPENABLE 0x2e
  100. +#define PCF85263_REG_STOPENABLE_STOP BIT(0)
  101. +
  102. +#define PCF85263_REG_RESET 0x2f /* Reset command */
  103. +#define PCF85263_REG_RESET_CMD_CPR 0xa4 /* Clear prescaler */
  104. +
  105. +#define PCF85263_MAX_REG 0x2f
  106. +
  107. +#define PCF85263_HR_PM BIT(5)
  108. +
  109. +enum pcf85263_irqpin {
  110. + PCF85263_IRQPIN_NONE,
  111. + PCF85263_IRQPIN_INTA,
  112. + PCF85263_IRQPIN_INTB
  113. +};
  114. +
  115. +static const char *const pcf85263_irqpin_names[] = {
  116. + [PCF85263_IRQPIN_NONE] = "None",
  117. + [PCF85263_IRQPIN_INTA] = "INTA",
  118. + [PCF85263_IRQPIN_INTB] = "INTB"
  119. +};
  120. +
  121. +struct pcf85263 {
  122. + struct device *dev;
  123. + struct rtc_device *rtc;
  124. + struct regmap *regmap;
  125. + enum pcf85263_irqpin irq_pin;
  126. + int irq;
  127. + bool mode_12h;
  128. +};
  129. +
  130. +/*
  131. + * Helpers to convert 12h to 24h and vice versa.
  132. + * Values in register are stored in BCD with a PM flag in bit 5
  133. + *
  134. + * 23:00 <=> 11PM <=> 0x31
  135. + * 00:00 <=> 12AM <=> 0x12
  136. + * 01:00 <=> 1AM <=> 0x01
  137. + * 12:00 <=> 12PM <=> 0x32
  138. + * 13:00 <=> 1PM <=> 0x21
  139. + */
  140. +static int pcf85263_bcd12h_to_bin24h(int regval)
  141. +{
  142. + int hr = bcd2bin(regval & 0x1f);
  143. + bool pm = regval & PCF85263_HR_PM;
  144. +
  145. + if (hr == 12)
  146. + return pm ? 12 : 0;
  147. +
  148. + return pm ? hr + 12 : hr;
  149. +}
  150. +
  151. +static int pcf85263_bin24h_to_bcd12h(int hr24)
  152. +{
  153. + bool pm = hr24 >= 12;
  154. + int hr12 = hr24 % 12;
  155. +
  156. + if (!hr12)
  157. + hr12++;
  158. +
  159. + return bin2bcd(hr12) | pm ? 0 : PCF85263_HR_PM;
  160. +}
  161. +
  162. +static int pcf85263_read_time(struct device *dev, struct rtc_time *tm)
  163. +{
  164. + struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
  165. + const int first = PCF85263_REG_RTC_SC;
  166. + const int last = PCF85263_REG_RTC_YR;
  167. + const int len = last - first + 1;
  168. + u8 regs[len];
  169. + u8 hr_reg;
  170. + int ret;
  171. +
  172. + ret = regmap_bulk_read(pcf85263->regmap, first, regs, len);
  173. + if (ret)
  174. + return ret;
  175. +
  176. + if (regs[PCF85263_REG_RTC_SC - first] & PCF85263_REG_RTC_SC_OS) {
  177. + dev_warn(dev, "Oscillator stop detected, date/time is not reliable.\n");
  178. + return -EINVAL;
  179. + }
  180. +
  181. + tm->tm_sec = bcd2bin(regs[PCF85263_REG_RTC_SC - first] & 0x7f);
  182. + tm->tm_min = bcd2bin(regs[PCF85263_REG_RTC_MN - first] & 0x7f);
  183. +
  184. + hr_reg = regs[PCF85263_REG_RTC_HR - first];
  185. + if (pcf85263->mode_12h)
  186. + tm->tm_hour = pcf85263_bcd12h_to_bin24h(hr_reg);
  187. + else
  188. + tm->tm_hour = bcd2bin(hr_reg & 0x3f);
  189. +
  190. + tm->tm_mday = bcd2bin(regs[PCF85263_REG_RTC_DT - first]);
  191. + tm->tm_wday = bcd2bin(regs[PCF85263_REG_RTC_DW - first]);
  192. + tm->tm_mon = bcd2bin(regs[PCF85263_REG_RTC_MO - first]) - 1;
  193. + tm->tm_year = bcd2bin(regs[PCF85263_REG_RTC_YR - first]);
  194. +
  195. + tm->tm_year += 100; /* Assume 21st century */
  196. +
  197. + return 0;
  198. +}
  199. +
  200. +static int pcf85263_set_time(struct device *dev, struct rtc_time *tm)
  201. +{
  202. + struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
  203. +
  204. + /*
  205. + * Before setting time need to stop RTC and disable prescaler
  206. + * Do this all in a single I2C transaction exploiting wraparound
  207. + * as described in data sheet.
  208. + * This means that the array below must be in register order
  209. + */
  210. + u8 regs[] = {
  211. + PCF85263_REG_STOPENABLE_STOP, /* STOP */
  212. + PCF85263_REG_RESET_CMD_CPR, /* Disable prescaler */
  213. + /* Wrap around to register 0 (1/100s) */
  214. + 0, /* 1/100s always zero. */
  215. + bin2bcd(tm->tm_sec),
  216. + bin2bcd(tm->tm_min),
  217. + bin2bcd(tm->tm_hour), /* 24-hour */
  218. + bin2bcd(tm->tm_mday),
  219. + bin2bcd(tm->tm_wday + 1),
  220. + bin2bcd(tm->tm_mon + 1),
  221. + bin2bcd(tm->tm_year % 100)
  222. + };
  223. + int ret;
  224. +
  225. + ret = regmap_bulk_write(pcf85263->regmap, PCF85263_REG_STOPENABLE,
  226. + regs, sizeof(regs));
  227. + if (ret)
  228. + return ret;
  229. +
  230. + /* As we have set the time in 24H update the hardware for that */
  231. + if (pcf85263->mode_12h) {
  232. + pcf85263->mode_12h = false;
  233. + ret = regmap_update_bits(pcf85263->regmap, PCF85263_REG_OSC,
  234. + PCF85263_REG_OSC_12H, 0);
  235. + if (ret)
  236. + return ret;
  237. + }
  238. +
  239. + /* Start it again */
  240. + return regmap_write(pcf85263->regmap, PCF85263_REG_STOPENABLE, 0);
  241. +}
  242. +
  243. +static int pcf85263_enable_alarm(struct pcf85263 *pcf85263, bool enable)
  244. +{
  245. + int reg;
  246. + int ret;
  247. +
  248. + ret = regmap_update_bits(pcf85263->regmap, PCF85263_REG_ALM_CTL,
  249. + PCF85263_REG_ALM_CTL_ALL_A1E,
  250. + enable ? PCF85263_REG_ALM_CTL_ALL_A1E : 0);
  251. + if (ret)
  252. + return ret;
  253. +
  254. + switch (pcf85263->irq_pin) {
  255. + case PCF85263_IRQPIN_NONE:
  256. + return 0;
  257. +
  258. + case PCF85263_IRQPIN_INTA:
  259. + reg = PCF85263_REG_INTA_CTL;
  260. + break;
  261. +
  262. + case PCF85263_IRQPIN_INTB:
  263. + reg = PCF85263_REG_INTB_CTL;
  264. + break;
  265. +
  266. + default:
  267. + return -EINVAL;
  268. + }
  269. +
  270. + return regmap_update_bits(pcf85263->regmap, reg,
  271. + PCF85263_REG_INTx_CTL_A1E,
  272. + enable ? PCF85263_REG_INTx_CTL_A1E : 0);
  273. +}
  274. +
  275. +static int pcf85263_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
  276. +{
  277. + struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
  278. + struct rtc_time *tm = &alarm->time;
  279. + const int first = PCF85263_REG_ALM1_SC;
  280. + const int last = PCF85263_REG_ALM1_MO;
  281. + const int len = last - first + 1;
  282. + u8 regs[len];
  283. + u8 hr_reg;
  284. + unsigned int regval;
  285. + int ret;
  286. +
  287. + ret = regmap_bulk_read(pcf85263->regmap, first, regs, len);
  288. + if (ret)
  289. + return ret;
  290. +
  291. + tm->tm_sec = bcd2bin(regs[PCF85263_REG_ALM1_SC - first] & 0x7f);
  292. + tm->tm_min = bcd2bin(regs[PCF85263_REG_ALM1_MN - first] & 0x7f);
  293. +
  294. + hr_reg = regs[PCF85263_REG_ALM1_HR - first];
  295. + if (pcf85263->mode_12h)
  296. + tm->tm_hour = pcf85263_bcd12h_to_bin24h(hr_reg);
  297. + else
  298. + tm->tm_hour = bcd2bin(hr_reg & 0x3f);
  299. +
  300. + tm->tm_mday = bcd2bin(regs[PCF85263_REG_ALM1_DT - first]);
  301. + tm->tm_mon = bcd2bin(regs[PCF85263_REG_ALM1_MO - first]) - 1;
  302. + tm->tm_year = -1;
  303. + tm->tm_wday = -1;
  304. +
  305. + ret = regmap_read(pcf85263->regmap, PCF85263_REG_ALM_CTL, &regval);
  306. + if (ret)
  307. + return ret;
  308. + alarm->enabled = !!(regval & PCF85263_REG_ALM_CTL_ALL_A1E);
  309. +
  310. + ret = regmap_read(pcf85263->regmap, PCF85263_REG_FLAGS, &regval);
  311. + if (ret)
  312. + return ret;
  313. + alarm->pending = !!(regval & PCF85263_REG_FLAGS_A1F);
  314. +
  315. + return 0;
  316. +}
  317. +
  318. +static int pcf85263_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
  319. +{
  320. + struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
  321. + struct rtc_time *tm = &alarm->time;
  322. + const int first = PCF85263_REG_ALM1_SC;
  323. + const int last = PCF85263_REG_ALM1_MO;
  324. + const int len = last - first + 1;
  325. + u8 regs[len];
  326. + int ret;
  327. +
  328. + /* Disable alarm comparison during update */
  329. + ret = pcf85263_enable_alarm(pcf85263, false);
  330. + if (ret)
  331. + return ret;
  332. +
  333. + /* Clear any pending alarm (write 0=>clr, 1=>no change) */
  334. + ret = regmap_write(pcf85263->regmap, PCF85263_REG_FLAGS,
  335. + (unsigned int)(~PCF85263_REG_FLAGS_A1F));
  336. + if (ret)
  337. + return ret;
  338. +
  339. + /* Set the alarm time registers */
  340. + regs[PCF85263_REG_ALM1_SC - first] = bin2bcd(tm->tm_sec);
  341. + regs[PCF85263_REG_ALM1_MN - first] = bin2bcd(tm->tm_min);
  342. + regs[PCF85263_REG_ALM1_HR - first] = pcf85263->mode_12h ?
  343. + pcf85263_bin24h_to_bcd12h(tm->tm_hour) :
  344. + bin2bcd(tm->tm_hour);
  345. + regs[PCF85263_REG_ALM1_DT - first] = bin2bcd(tm->tm_mday);
  346. + regs[PCF85263_REG_ALM1_MO - first] = bin2bcd(tm->tm_mon + 1);
  347. +
  348. + ret = regmap_bulk_write(pcf85263->regmap, first, regs, sizeof(regs));
  349. + if (ret)
  350. + return ret;
  351. +
  352. + if (alarm->enabled)
  353. + ret = pcf85263_enable_alarm(pcf85263, true);
  354. +
  355. + return ret;
  356. +}
  357. +
  358. +static int pcf85263_alarm_irq_enable(struct device *dev, unsigned int enable)
  359. +{
  360. + struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
  361. +
  362. + return pcf85263_enable_alarm(pcf85263, !!enable);
  363. +}
  364. +
  365. +static irqreturn_t pcf85263_irq(int irq, void *data)
  366. +{
  367. + struct pcf85263 *pcf85263 = data;
  368. + unsigned int regval;
  369. + int ret;
  370. +
  371. + ret = regmap_read(pcf85263->regmap, PCF85263_REG_FLAGS, &regval);
  372. + if (ret)
  373. + return IRQ_NONE;
  374. +
  375. + if (regval & PCF85263_REG_FLAGS_A1F) {
  376. + regmap_write(pcf85263->regmap, PCF85263_REG_FLAGS,
  377. + (unsigned int)(~PCF85263_REG_FLAGS_A1F));
  378. +
  379. + rtc_update_irq(pcf85263->rtc, 1, RTC_IRQF | RTC_AF);
  380. +
  381. + return IRQ_HANDLED;
  382. + }
  383. +
  384. + return IRQ_NONE;
  385. +}
  386. +
  387. +static int pcf85263_check_osc_stopped(struct pcf85263 *pcf85263)
  388. +{
  389. + unsigned int regval;
  390. + int ret;
  391. +
  392. + ret = regmap_read(pcf85263->regmap, PCF85263_REG_RTC_SC, &regval);
  393. + if (ret)
  394. + return ret;
  395. +
  396. + ret = regval & PCF85263_REG_RTC_SC_OS ? 1 : 0;
  397. + if (ret)
  398. + dev_warn(pcf85263->dev, "Oscillator stop detected, date/time is not reliable.\n");
  399. +
  400. + return ret;
  401. +}
  402. +
  403. +#ifdef CONFIG_RTC_INTF_DEV
  404. +static int pcf85263_ioctl(struct device *dev,
  405. + unsigned int cmd, unsigned long arg)
  406. +{
  407. + struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
  408. + int ret;
  409. +
  410. + switch (cmd) {
  411. + case RTC_VL_READ:
  412. + ret = pcf85263_check_osc_stopped(pcf85263);
  413. + if (ret < 0)
  414. + return ret;
  415. +
  416. + if (copy_to_user((void __user *)arg, &ret, sizeof(int)))
  417. + return -EFAULT;
  418. + return 0;
  419. +
  420. + case RTC_VL_CLR:
  421. + return regmap_update_bits(pcf85263->regmap,
  422. + PCF85263_REG_RTC_SC,
  423. + PCF85263_REG_RTC_SC_OS, 0);
  424. + default:
  425. + return -ENOIOCTLCMD;
  426. + }
  427. +}
  428. +#else
  429. +#define pcf85263_ioctl NULL
  430. +#endif
  431. +
  432. +static int pcf85263_init_hw(struct pcf85263 *pcf85263)
  433. +{
  434. + struct device_node *np = pcf85263->dev->of_node;
  435. + unsigned int regval;
  436. + u32 propval;
  437. + int ret;
  438. +
  439. + /* Determine if oscilator has been stopped (probably low power) */
  440. + ret = pcf85263_check_osc_stopped(pcf85263);
  441. + if (ret < 0) {
  442. + /* Log here since this is the first hw access on probe */
  443. + dev_err(pcf85263->dev, "Unable to read register\n");
  444. +
  445. + return ret;
  446. + }
  447. +
  448. + /* Determine 12/24H mode */
  449. + ret = regmap_read(pcf85263->regmap, PCF85263_REG_OSC, &regval);
  450. + if (ret)
  451. + return ret;
  452. + pcf85263->mode_12h = !!(regval & PCF85263_REG_OSC_12H);
  453. +
  454. + /* Set oscilator register */
  455. + regval &= ~PCF85263_REG_OSC_12H; /* keep current 12/24 h setting */
  456. +
  457. + propval = PCF85263_QUARTZCAP_12p5pF;
  458. + of_property_read_u32(np, "quartz-load-capacitance", &propval);
  459. + regval |= ((propval << PCF85263_REG_OSC_CL_SHIFT)
  460. + & PCF85263_REG_OSC_CL_MASK);
  461. +
  462. + propval = PCF85263_QUARTZDRIVE_NORMAL;
  463. + of_property_read_u32(np, "quartz-drive-strength", &propval);
  464. + regval |= ((propval << PCF85263_REG_OSC_OSCD_SHIFT)
  465. + & PCF85263_REG_OSC_OSCD_MASK);
  466. +
  467. + if (of_property_read_bool(np, "quartz-low-jitter"))
  468. + regval |= PCF85263_REG_OSC_LOWJ;
  469. +
  470. + ret = regmap_write(pcf85263->regmap, PCF85263_REG_OSC, regval);
  471. + if (ret)
  472. + return ret;
  473. +
  474. + /* Set function register (RTC mode, 1s tick, clock output static) */
  475. + ret = regmap_write(pcf85263->regmap, PCF85263_REG_FUNCTION,
  476. + PCF85263_REG_FUNCTION_COF_OFF);
  477. + if (ret)
  478. + return ret;
  479. +
  480. + /* Set all interrupts to disabled, level mode */
  481. + ret = regmap_write(pcf85263->regmap, PCF85263_REG_INTA_CTL,
  482. + PCF85263_REG_INTx_CTL_ILP);
  483. + if (ret)
  484. + return ret;
  485. + ret = regmap_write(pcf85263->regmap, PCF85263_REG_INTB_CTL,
  486. + PCF85263_REG_INTx_CTL_ILP);
  487. + if (ret)
  488. + return ret;
  489. +
  490. + /* Setup IO pin config register */
  491. + regval = PCF85263_REG_PINIO_CLKDISABLE;
  492. + switch (pcf85263->irq_pin) {
  493. + case PCF85263_IRQPIN_INTA:
  494. + regval |= (PCF85263_INTAPM_INTA | PCF85263_TSPM_DISABLED);
  495. + break;
  496. + case PCF85263_IRQPIN_INTB:
  497. + regval |= (PCF85263_INTAPM_HIGHZ | PCF85263_TSPM_INTB);
  498. + break;
  499. + case PCF85263_IRQPIN_NONE:
  500. + regval |= (PCF85263_INTAPM_HIGHZ | PCF85263_TSPM_DISABLED);
  501. + break;
  502. + }
  503. + ret = regmap_write(pcf85263->regmap, PCF85263_REG_PINIO, regval);
  504. +
  505. + return ret;
  506. +}
  507. +
  508. +static const struct rtc_class_ops rtc_ops = {
  509. + .ioctl = pcf85263_ioctl,
  510. + .read_time = pcf85263_read_time,
  511. + .set_time = pcf85263_set_time,
  512. + .read_alarm = pcf85263_read_alarm,
  513. + .set_alarm = pcf85263_set_alarm,
  514. + .alarm_irq_enable = pcf85263_alarm_irq_enable,
  515. +};
  516. +
  517. +static const struct regmap_config pcf85263_regmap_cfg = {
  518. + .reg_bits = 8,
  519. + .val_bits = 8,
  520. + .max_register = PCF85263_MAX_REG,
  521. +};
  522. +
  523. +/*
  524. + * On some boards the interrupt line may not be wired to the CPU but only to
  525. + * a power supply circuit.
  526. + * In that case no interrupt will be specified in the device tree but the
  527. + * wakeup-source DT property may be used to enable wakeup programming in
  528. + * sysfs
  529. + */
  530. +static bool pcf85263_can_wakeup_machine(struct pcf85263 *pcf85263)
  531. +{
  532. + return pcf85263->irq ||
  533. + of_property_read_bool(pcf85263->dev->of_node, "wakeup-source");
  534. +}
  535. +
  536. +static int pcf85263_probe(struct i2c_client *client,
  537. + const struct i2c_device_id *id)
  538. +{
  539. + struct device *dev = &client->dev;
  540. + struct pcf85263 *pcf85263;
  541. + int ret;
  542. +
  543. + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
  544. + I2C_FUNC_SMBUS_BYTE_DATA |
  545. + I2C_FUNC_SMBUS_I2C_BLOCK))
  546. + return -ENODEV;
  547. +
  548. + pcf85263 = devm_kzalloc(dev, sizeof(*pcf85263), GFP_KERNEL);
  549. + if (!pcf85263)
  550. + return -ENOMEM;
  551. +
  552. + pcf85263->dev = dev;
  553. + pcf85263->irq = client->irq;
  554. + dev_set_drvdata(dev, pcf85263);
  555. +
  556. + pcf85263->regmap = devm_regmap_init_i2c(client, &pcf85263_regmap_cfg);
  557. + if (IS_ERR(pcf85263->regmap)) {
  558. + ret = PTR_ERR(pcf85263->regmap);
  559. + dev_err(dev, "regmap allocation failed (%d)\n", ret);
  560. +
  561. + return ret;
  562. + }
  563. +
  564. + /* Determine which interrupt pin the board uses */
  565. + if (pcf85263_can_wakeup_machine(pcf85263)) {
  566. + if (of_property_match_string(dev->of_node,
  567. + "interrupt-names", "INTB") >= 0)
  568. + pcf85263->irq_pin = PCF85263_IRQPIN_INTB;
  569. + else
  570. + pcf85263->irq_pin = PCF85263_IRQPIN_INTA;
  571. + } else {
  572. + pcf85263->irq_pin = PCF85263_IRQPIN_NONE;
  573. + }
  574. +
  575. + ret = pcf85263_init_hw(pcf85263);
  576. + if (ret)
  577. + return ret;
  578. +
  579. + if (pcf85263->irq) {
  580. + ret = devm_request_threaded_irq(dev, pcf85263->irq, NULL,
  581. + pcf85263_irq,
  582. + IRQF_ONESHOT,
  583. + dev->driver->name, pcf85263);
  584. + if (ret) {
  585. + dev_err(dev, "irq %d unavailable (%d)\n",
  586. + pcf85263->irq, ret);
  587. + pcf85263->irq = 0;
  588. + }
  589. + }
  590. +
  591. + if (pcf85263_can_wakeup_machine(pcf85263))
  592. + device_init_wakeup(dev, true);
  593. +
  594. + pcf85263->rtc = devm_rtc_device_register(dev, dev->driver->name,
  595. + &rtc_ops, THIS_MODULE);
  596. + ret = PTR_ERR_OR_ZERO(pcf85263->rtc);
  597. + if (ret)
  598. + return ret;
  599. +
  600. + /* We cannot support UIE mode if we do not have an IRQ line */
  601. + if (!pcf85263->irq)
  602. + pcf85263->rtc->uie_unsupported = 1;
  603. +
  604. + dev_info(pcf85263->dev,
  605. + "PCF85263 RTC (irqpin=%s irq=%d)\n",
  606. + pcf85263_irqpin_names[pcf85263->irq_pin],
  607. + pcf85263->irq);
  608. +
  609. + return 0;
  610. +}
  611. +
  612. +static int pcf85263_remove(struct i2c_client *client)
  613. +{
  614. + struct pcf85263 *pcf85263 = i2c_get_clientdata(client);
  615. +
  616. + if (pcf85263_can_wakeup_machine(pcf85263))
  617. + device_init_wakeup(pcf85263->dev, false);
  618. +
  619. + return 0;
  620. +}
  621. +
  622. +#ifdef CONFIG_PM_SLEEP
  623. +static int pcf85263_suspend(struct device *dev)
  624. +{
  625. + struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
  626. + int ret = 0;
  627. +
  628. + if (device_may_wakeup(dev))
  629. + ret = enable_irq_wake(pcf85263->irq);
  630. +
  631. + return ret;
  632. +}
  633. +
  634. +static int pcf85263_resume(struct device *dev)
  635. +{
  636. + struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
  637. + int ret = 0;
  638. +
  639. + if (device_may_wakeup(dev))
  640. + ret = disable_irq_wake(pcf85263->irq);
  641. +
  642. + return ret;
  643. +}
  644. +
  645. +#endif
  646. +
  647. +static const struct i2c_device_id pcf85263_id[] = {
  648. + { "pcf85263", 0 },
  649. + { }
  650. +};
  651. +MODULE_DEVICE_TABLE(i2c, pcf85263_id);
  652. +
  653. +#ifdef CONFIG_OF
  654. +static const struct of_device_id pcf85263_of_match[] = {
  655. + { .compatible = "nxp,pcf85263" },
  656. + {}
  657. +};
  658. +MODULE_DEVICE_TABLE(of, pcf85263_of_match);
  659. +#endif
  660. +
  661. +static SIMPLE_DEV_PM_OPS(pcf85263_pm_ops, pcf85263_suspend, pcf85263_resume);
  662. +
  663. +static struct i2c_driver pcf85263_driver = {
  664. + .driver = {
  665. + .name = "rtc-pcf85263",
  666. + .of_match_table = of_match_ptr(pcf85263_of_match),
  667. + .pm = &pcf85263_pm_ops,
  668. + },
  669. + .probe = pcf85263_probe,
  670. + .remove = pcf85263_remove,
  671. + .id_table = pcf85263_id,
  672. +};
  673. +
  674. +module_i2c_driver(pcf85263_driver);
  675. +
  676. +MODULE_AUTHOR("Martin Fuzzey <[email protected]>");
  677. +MODULE_DESCRIPTION("PCF85263 RTC Driver");
  678. +MODULE_LICENSE("GPL");
  679. +