38
38
*/
39
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
+ */
42
57
struct s5m_rtc_reg_config {
43
58
/* Number of registers used for setting time/alarm0/alarm1 */
44
59
unsigned int regs_count ;
@@ -58,8 +73,13 @@ struct s5m_rtc_reg_config {
58
73
unsigned int udr_update ;
59
74
/* Auto-cleared mask in UDR field for writing time and alarm */
60
75
unsigned int autoclear_udr_mask ;
61
- /* Mask for UDR field in 'udr_update' register */
62
- unsigned int 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 ;
63
83
};
64
84
65
85
/* Register map for S5M8763 and S5M8767 */
@@ -71,22 +91,54 @@ static const struct s5m_rtc_reg_config s5m_rtc_regs = {
71
91
.alarm1 = S5M_ALARM1_SEC ,
72
92
.udr_update = S5M_RTC_UDR_CON ,
73
93
.autoclear_udr_mask = S5M_RTC_UDR_MASK ,
74
- .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 */
100
+ static 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 */
114
+ static 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 ,
75
125
};
76
126
77
127
/*
78
- * Register map for S2MPS14.
79
- * It may be also suitable for S2MPS11 but this was not tested .
128
+ * Register map for S2MPS15 - in comparison to S2MPS14 the WUDR and AUDR bits
129
+ * are swapped .
80
130
*/
81
- static const struct s5m_rtc_reg_config s2mps_rtc_regs = {
131
+ static const struct s5m_rtc_reg_config s2mps15_rtc_regs = {
82
132
.regs_count = 7 ,
83
133
.time = S2MPS_RTC_SEC ,
84
134
.ctrl = S2MPS_RTC_CTRL ,
85
135
.alarm0 = S2MPS_ALARM0_SEC ,
86
136
.alarm1 = S2MPS_ALARM1_SEC ,
87
137
.udr_update = S2MPS_RTC_UDR_CON ,
88
138
.autoclear_udr_mask = S2MPS_RTC_WUDR_MASK ,
89
- .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 ,
90
142
};
91
143
92
144
struct s5m_rtc_info {
@@ -223,21 +275,7 @@ static inline int s5m8767_rtc_set_time_reg(struct s5m_rtc_info *info)
223
275
return ret ;
224
276
}
225
277
226
- switch (info -> device_type ) {
227
- case S5M8763X :
228
- case S5M8767X :
229
- data |= info -> regs -> udr_mask | S5M_RTC_TIME_EN_MASK ;
230
- case S2MPS15X :
231
- /* As per UM, for write time register, set WUDR bit to high */
232
- data |= S2MPS15_RTC_WUDR_MASK ;
233
- break ;
234
- case S2MPS14X :
235
- case S2MPS13X :
236
- data |= info -> regs -> udr_mask ;
237
- break ;
238
- default :
239
- return - EINVAL ;
240
- }
278
+ data |= info -> regs -> write_time_udr_mask ;
241
279
242
280
ret = regmap_write (info -> regmap , info -> regs -> udr_update , data );
243
281
if (ret < 0 ) {
@@ -262,22 +300,16 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
262
300
return ret ;
263
301
}
264
302
265
- data |= info -> regs -> udr_mask ;
303
+ data |= info -> regs -> write_alarm_udr_mask ;
266
304
switch (info -> device_type ) {
267
305
case S5M8763X :
268
306
case S5M8767X :
269
307
data &= ~S5M_RTC_TIME_EN_MASK ;
270
308
break ;
271
309
case S2MPS15X :
272
- /* As per UM, for write alarm, set A_UDR(bit[4]) to high
273
- * udr_mask above sets bit[4]
274
- */
275
- break ;
276
310
case S2MPS14X :
277
- data |= S2MPS_RTC_RUDR_MASK ;
278
- break ;
279
311
case S2MPS13X :
280
- data |= S2MPS13_RTC_AUDR_MASK ;
312
+ /* No exceptions needed */
281
313
break ;
282
314
default :
283
315
return - EINVAL ;
@@ -338,11 +370,11 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
338
370
u8 data [info -> regs -> regs_count ];
339
371
int ret ;
340
372
341
- if (info -> device_type == S2MPS15X || info -> device_type == S2MPS14X ||
342
- info -> device_type == S2MPS13X ) {
373
+ if (info -> regs -> read_time_udr_mask ) {
343
374
ret = regmap_update_bits (info -> regmap ,
344
375
info -> regs -> udr_update ,
345
- S2MPS_RTC_RUDR_MASK , S2MPS_RTC_RUDR_MASK );
376
+ info -> regs -> read_time_udr_mask ,
377
+ info -> regs -> read_time_udr_mask );
346
378
if (ret ) {
347
379
dev_err (dev ,
348
380
"Failed to prepare registers for time reading: %d\n" ,
@@ -709,10 +741,18 @@ static int s5m_rtc_probe(struct platform_device *pdev)
709
741
710
742
switch (platform_get_device_id (pdev )-> driver_data ) {
711
743
case S2MPS15X :
744
+ regmap_cfg = & s2mps14_rtc_regmap_config ;
745
+ info -> regs = & s2mps15_rtc_regs ;
746
+ alarm_irq = S2MPS14_IRQ_RTCA0 ;
747
+ break ;
712
748
case S2MPS14X :
749
+ regmap_cfg = & s2mps14_rtc_regmap_config ;
750
+ info -> regs = & s2mps14_rtc_regs ;
751
+ alarm_irq = S2MPS14_IRQ_RTCA0 ;
752
+ break ;
713
753
case S2MPS13X :
714
754
regmap_cfg = & s2mps14_rtc_regmap_config ;
715
- info -> regs = & s2mps_rtc_regs ;
755
+ info -> regs = & s2mps13_rtc_regs ;
716
756
alarm_irq = S2MPS14_IRQ_RTCA0 ;
717
757
break ;
718
758
case S5M8763X :
0 commit comments