aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-s5m.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-s5m.c')
-rw-r--r--drivers/rtc/rtc-s5m.c131
1 files changed, 101 insertions, 30 deletions
diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c
index f2504b4eef34..7407d7394bb4 100644
--- a/drivers/rtc/rtc-s5m.c
+++ b/drivers/rtc/rtc-s5m.c
@@ -38,7 +38,22 @@
38 */ 38 */
39#define UDR_READ_RETRY_CNT 5 39#define UDR_READ_RETRY_CNT 5
40 40
41/* Registers used by the driver which are different between chipsets. */ 41/*
42 * Registers used by the driver which are different between chipsets.
43 *
44 * Operations like read time and write alarm/time require updating
45 * specific fields in UDR register. These fields usually are auto-cleared
46 * (with some exceptions).
47 *
48 * Table of operations per device:
49 *
50 * Device | Write time | Read time | Write alarm
51 * =================================================
52 * S5M8767 | UDR + TIME | | UDR
53 * S2MPS11/14 | WUDR | RUDR | WUDR + RUDR
54 * S2MPS13 | WUDR | RUDR | WUDR + AUDR
55 * S2MPS15 | WUDR | RUDR | AUDR
56 */
42struct s5m_rtc_reg_config { 57struct s5m_rtc_reg_config {
43 /* Number of registers used for setting time/alarm0/alarm1 */ 58 /* Number of registers used for setting time/alarm0/alarm1 */
44 unsigned int regs_count; 59 unsigned int regs_count;
@@ -55,9 +70,16 @@ struct s5m_rtc_reg_config {
55 * will enable update of time or alarm register. Then it will be 70 * will enable update of time or alarm register. Then it will be
56 * auto-cleared after successful update. 71 * auto-cleared after successful update.
57 */ 72 */
58 unsigned int rtc_udr_update; 73 unsigned int udr_update;
59 /* Mask for UDR field in 'rtc_udr_update' register */ 74 /* Auto-cleared mask in UDR field for writing time and alarm */
60 unsigned int rtc_udr_mask; 75 unsigned int autoclear_udr_mask;
76 /*
77 * Masks in UDR field for time and alarm operations.
78 * The read time mask can be 0. Rest should not.
79 */
80 unsigned int read_time_udr_mask;
81 unsigned int write_time_udr_mask;
82 unsigned int write_alarm_udr_mask;
61}; 83};
62 84
63/* Register map for S5M8763 and S5M8767 */ 85/* Register map for S5M8763 and S5M8767 */
@@ -67,22 +89,56 @@ static const struct s5m_rtc_reg_config s5m_rtc_regs = {
67 .ctrl = S5M_ALARM1_CONF, 89 .ctrl = S5M_ALARM1_CONF,
68 .alarm0 = S5M_ALARM0_SEC, 90 .alarm0 = S5M_ALARM0_SEC,
69 .alarm1 = S5M_ALARM1_SEC, 91 .alarm1 = S5M_ALARM1_SEC,
70 .rtc_udr_update = S5M_RTC_UDR_CON, 92 .udr_update = S5M_RTC_UDR_CON,
71 .rtc_udr_mask = S5M_RTC_UDR_MASK, 93 .autoclear_udr_mask = S5M_RTC_UDR_MASK,
94 .read_time_udr_mask = 0, /* Not needed */
95 .write_time_udr_mask = S5M_RTC_UDR_MASK | S5M_RTC_TIME_EN_MASK,
96 .write_alarm_udr_mask = S5M_RTC_UDR_MASK,
97};
98
99/* Register map for S2MPS13 */
100static const struct s5m_rtc_reg_config s2mps13_rtc_regs = {
101 .regs_count = 7,
102 .time = S2MPS_RTC_SEC,
103 .ctrl = S2MPS_RTC_CTRL,
104 .alarm0 = S2MPS_ALARM0_SEC,
105 .alarm1 = S2MPS_ALARM1_SEC,
106 .udr_update = S2MPS_RTC_UDR_CON,
107 .autoclear_udr_mask = S2MPS_RTC_WUDR_MASK,
108 .read_time_udr_mask = S2MPS_RTC_RUDR_MASK,
109 .write_time_udr_mask = S2MPS_RTC_WUDR_MASK,
110 .write_alarm_udr_mask = S2MPS_RTC_WUDR_MASK | S2MPS13_RTC_AUDR_MASK,
111};
112
113/* Register map for S2MPS11/14 */
114static const struct s5m_rtc_reg_config s2mps14_rtc_regs = {
115 .regs_count = 7,
116 .time = S2MPS_RTC_SEC,
117 .ctrl = S2MPS_RTC_CTRL,
118 .alarm0 = S2MPS_ALARM0_SEC,
119 .alarm1 = S2MPS_ALARM1_SEC,
120 .udr_update = S2MPS_RTC_UDR_CON,
121 .autoclear_udr_mask = S2MPS_RTC_WUDR_MASK,
122 .read_time_udr_mask = S2MPS_RTC_RUDR_MASK,
123 .write_time_udr_mask = S2MPS_RTC_WUDR_MASK,
124 .write_alarm_udr_mask = S2MPS_RTC_WUDR_MASK | S2MPS_RTC_RUDR_MASK,
72}; 125};
73 126
74/* 127/*
75 * Register map for S2MPS14. 128 * Register map for S2MPS15 - in comparison to S2MPS14 the WUDR and AUDR bits
76 * It may be also suitable for S2MPS11 but this was not tested. 129 * are swapped.
77 */ 130 */
78static const struct s5m_rtc_reg_config s2mps_rtc_regs = { 131static const struct s5m_rtc_reg_config s2mps15_rtc_regs = {
79 .regs_count = 7, 132 .regs_count = 7,
80 .time = S2MPS_RTC_SEC, 133 .time = S2MPS_RTC_SEC,
81 .ctrl = S2MPS_RTC_CTRL, 134 .ctrl = S2MPS_RTC_CTRL,
82 .alarm0 = S2MPS_ALARM0_SEC, 135 .alarm0 = S2MPS_ALARM0_SEC,
83 .alarm1 = S2MPS_ALARM1_SEC, 136 .alarm1 = S2MPS_ALARM1_SEC,
84 .rtc_udr_update = S2MPS_RTC_UDR_CON, 137 .udr_update = S2MPS_RTC_UDR_CON,
85 .rtc_udr_mask = S2MPS_RTC_WUDR_MASK, 138 .autoclear_udr_mask = S2MPS_RTC_WUDR_MASK,
139 .read_time_udr_mask = S2MPS_RTC_RUDR_MASK,
140 .write_time_udr_mask = S2MPS15_RTC_WUDR_MASK,
141 .write_alarm_udr_mask = S2MPS15_RTC_AUDR_MASK,
86}; 142};
87 143
88struct s5m_rtc_info { 144struct s5m_rtc_info {
@@ -166,9 +222,8 @@ static inline int s5m8767_wait_for_udr_update(struct s5m_rtc_info *info)
166 unsigned int data; 222 unsigned int data;
167 223
168 do { 224 do {
169 ret = regmap_read(info->regmap, info->regs->rtc_udr_update, 225 ret = regmap_read(info->regmap, info->regs->udr_update, &data);
170 &data); 226 } while (--retry && (data & info->regs->autoclear_udr_mask) && !ret);
171 } while (--retry && (data & info->regs->rtc_udr_mask) && !ret);
172 227
173 if (!retry) 228 if (!retry)
174 dev_err(info->dev, "waiting for UDR update, reached max number of retries\n"); 229 dev_err(info->dev, "waiting for UDR update, reached max number of retries\n");
@@ -188,6 +243,7 @@ static inline int s5m_check_peding_alarm_interrupt(struct s5m_rtc_info *info,
188 ret = regmap_read(info->regmap, S5M_RTC_STATUS, &val); 243 ret = regmap_read(info->regmap, S5M_RTC_STATUS, &val);
189 val &= S5M_ALARM0_STATUS; 244 val &= S5M_ALARM0_STATUS;
190 break; 245 break;
246 case S2MPS15X:
191 case S2MPS14X: 247 case S2MPS14X:
192 case S2MPS13X: 248 case S2MPS13X:
193 ret = regmap_read(info->s5m87xx->regmap_pmic, S2MPS14_REG_ST2, 249 ret = regmap_read(info->s5m87xx->regmap_pmic, S2MPS14_REG_ST2,
@@ -213,17 +269,15 @@ static inline int s5m8767_rtc_set_time_reg(struct s5m_rtc_info *info)
213 int ret; 269 int ret;
214 unsigned int data; 270 unsigned int data;
215 271
216 ret = regmap_read(info->regmap, info->regs->rtc_udr_update, &data); 272 ret = regmap_read(info->regmap, info->regs->udr_update, &data);
217 if (ret < 0) { 273 if (ret < 0) {
218 dev_err(info->dev, "failed to read update reg(%d)\n", ret); 274 dev_err(info->dev, "failed to read update reg(%d)\n", ret);
219 return ret; 275 return ret;
220 } 276 }
221 277
222 data |= info->regs->rtc_udr_mask; 278 data |= info->regs->write_time_udr_mask;
223 if (info->device_type == S5M8763X || info->device_type == S5M8767X)
224 data |= S5M_RTC_TIME_EN_MASK;
225 279
226 ret = regmap_write(info->regmap, info->regs->rtc_udr_update, data); 280 ret = regmap_write(info->regmap, info->regs->udr_update, data);
227 if (ret < 0) { 281 if (ret < 0) {
228 dev_err(info->dev, "failed to write update reg(%d)\n", ret); 282 dev_err(info->dev, "failed to write update reg(%d)\n", ret);
229 return ret; 283 return ret;
@@ -239,30 +293,29 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
239 int ret; 293 int ret;
240 unsigned int data; 294 unsigned int data;
241 295
242 ret = regmap_read(info->regmap, info->regs->rtc_udr_update, &data); 296 ret = regmap_read(info->regmap, info->regs->udr_update, &data);
243 if (ret < 0) { 297 if (ret < 0) {
244 dev_err(info->dev, "%s: fail to read update reg(%d)\n", 298 dev_err(info->dev, "%s: fail to read update reg(%d)\n",
245 __func__, ret); 299 __func__, ret);
246 return ret; 300 return ret;
247 } 301 }
248 302
249 data |= info->regs->rtc_udr_mask; 303 data |= info->regs->write_alarm_udr_mask;
250 switch (info->device_type) { 304 switch (info->device_type) {
251 case S5M8763X: 305 case S5M8763X:
252 case S5M8767X: 306 case S5M8767X:
253 data &= ~S5M_RTC_TIME_EN_MASK; 307 data &= ~S5M_RTC_TIME_EN_MASK;
254 break; 308 break;
309 case S2MPS15X:
255 case S2MPS14X: 310 case S2MPS14X:
256 data |= S2MPS_RTC_RUDR_MASK;
257 break;
258 case S2MPS13X: 311 case S2MPS13X:
259 data |= S2MPS13_RTC_AUDR_MASK; 312 /* No exceptions needed */
260 break; 313 break;
261 default: 314 default:
262 return -EINVAL; 315 return -EINVAL;
263 } 316 }
264 317
265 ret = regmap_write(info->regmap, info->regs->rtc_udr_update, data); 318 ret = regmap_write(info->regmap, info->regs->udr_update, data);
266 if (ret < 0) { 319 if (ret < 0) {
267 dev_err(info->dev, "%s: fail to write update reg(%d)\n", 320 dev_err(info->dev, "%s: fail to write update reg(%d)\n",
268 __func__, ret); 321 __func__, ret);
@@ -273,7 +326,7 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
273 326
274 /* On S2MPS13 the AUDR is not auto-cleared */ 327 /* On S2MPS13 the AUDR is not auto-cleared */
275 if (info->device_type == S2MPS13X) 328 if (info->device_type == S2MPS13X)
276 regmap_update_bits(info->regmap, info->regs->rtc_udr_update, 329 regmap_update_bits(info->regmap, info->regs->udr_update,
277 S2MPS13_RTC_AUDR_MASK, 0); 330 S2MPS13_RTC_AUDR_MASK, 0);
278 331
279 return ret; 332 return ret;
@@ -317,10 +370,11 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
317 u8 data[info->regs->regs_count]; 370 u8 data[info->regs->regs_count];
318 int ret; 371 int ret;
319 372
320 if (info->device_type == S2MPS14X || info->device_type == S2MPS13X) { 373 if (info->regs->read_time_udr_mask) {
321 ret = regmap_update_bits(info->regmap, 374 ret = regmap_update_bits(info->regmap,
322 info->regs->rtc_udr_update, 375 info->regs->udr_update,
323 S2MPS_RTC_RUDR_MASK, S2MPS_RTC_RUDR_MASK); 376 info->regs->read_time_udr_mask,
377 info->regs->read_time_udr_mask);
324 if (ret) { 378 if (ret) {
325 dev_err(dev, 379 dev_err(dev,
326 "Failed to prepare registers for time reading: %d\n", 380 "Failed to prepare registers for time reading: %d\n",
@@ -339,6 +393,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
339 break; 393 break;
340 394
341 case S5M8767X: 395 case S5M8767X:
396 case S2MPS15X:
342 case S2MPS14X: 397 case S2MPS14X:
343 case S2MPS13X: 398 case S2MPS13X:
344 s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode); 399 s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode);
@@ -366,6 +421,7 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
366 s5m8763_tm_to_data(tm, data); 421 s5m8763_tm_to_data(tm, data);
367 break; 422 break;
368 case S5M8767X: 423 case S5M8767X:
424 case S2MPS15X:
369 case S2MPS14X: 425 case S2MPS14X:
370 case S2MPS13X: 426 case S2MPS13X:
371 ret = s5m8767_tm_to_data(tm, data); 427 ret = s5m8767_tm_to_data(tm, data);
@@ -414,6 +470,7 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
414 break; 470 break;
415 471
416 case S5M8767X: 472 case S5M8767X:
473 case S2MPS15X:
417 case S2MPS14X: 474 case S2MPS14X:
418 case S2MPS13X: 475 case S2MPS13X:
419 s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode); 476 s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode);
@@ -463,6 +520,7 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
463 break; 520 break;
464 521
465 case S5M8767X: 522 case S5M8767X:
523 case S2MPS15X:
466 case S2MPS14X: 524 case S2MPS14X:
467 case S2MPS13X: 525 case S2MPS13X:
468 for (i = 0; i < info->regs->regs_count; i++) 526 for (i = 0; i < info->regs->regs_count; i++)
@@ -508,6 +566,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
508 break; 566 break;
509 567
510 case S5M8767X: 568 case S5M8767X:
569 case S2MPS15X:
511 case S2MPS14X: 570 case S2MPS14X:
512 case S2MPS13X: 571 case S2MPS13X:
513 data[RTC_SEC] |= ALARM_ENABLE_MASK; 572 data[RTC_SEC] |= ALARM_ENABLE_MASK;
@@ -548,6 +607,7 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
548 break; 607 break;
549 608
550 case S5M8767X: 609 case S5M8767X:
610 case S2MPS15X:
551 case S2MPS14X: 611 case S2MPS14X:
552 case S2MPS13X: 612 case S2MPS13X:
553 s5m8767_tm_to_data(&alrm->time, data); 613 s5m8767_tm_to_data(&alrm->time, data);
@@ -631,6 +691,7 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
631 ret = regmap_raw_write(info->regmap, S5M_ALARM0_CONF, data, 2); 691 ret = regmap_raw_write(info->regmap, S5M_ALARM0_CONF, data, 2);
632 break; 692 break;
633 693
694 case S2MPS15X:
634 case S2MPS14X: 695 case S2MPS14X:
635 case S2MPS13X: 696 case S2MPS13X:
636 data[0] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); 697 data[0] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
@@ -679,10 +740,19 @@ static int s5m_rtc_probe(struct platform_device *pdev)
679 return -ENOMEM; 740 return -ENOMEM;
680 741
681 switch (platform_get_device_id(pdev)->driver_data) { 742 switch (platform_get_device_id(pdev)->driver_data) {
743 case S2MPS15X:
744 regmap_cfg = &s2mps14_rtc_regmap_config;
745 info->regs = &s2mps15_rtc_regs;
746 alarm_irq = S2MPS14_IRQ_RTCA0;
747 break;
682 case S2MPS14X: 748 case S2MPS14X:
749 regmap_cfg = &s2mps14_rtc_regmap_config;
750 info->regs = &s2mps14_rtc_regs;
751 alarm_irq = S2MPS14_IRQ_RTCA0;
752 break;
683 case S2MPS13X: 753 case S2MPS13X:
684 regmap_cfg = &s2mps14_rtc_regmap_config; 754 regmap_cfg = &s2mps14_rtc_regmap_config;
685 info->regs = &s2mps_rtc_regs; 755 info->regs = &s2mps13_rtc_regs;
686 alarm_irq = S2MPS14_IRQ_RTCA0; 756 alarm_irq = S2MPS14_IRQ_RTCA0;
687 break; 757 break;
688 case S5M8763X: 758 case S5M8763X:
@@ -805,6 +875,7 @@ static const struct platform_device_id s5m_rtc_id[] = {
805 { "s5m-rtc", S5M8767X }, 875 { "s5m-rtc", S5M8767X },
806 { "s2mps13-rtc", S2MPS13X }, 876 { "s2mps13-rtc", S2MPS13X },
807 { "s2mps14-rtc", S2MPS14X }, 877 { "s2mps14-rtc", S2MPS14X },
878 { "s2mps15-rtc", S2MPS15X },
808 { }, 879 { },
809}; 880};
810MODULE_DEVICE_TABLE(platform, s5m_rtc_id); 881MODULE_DEVICE_TABLE(platform, s5m_rtc_id);