diff options
Diffstat (limited to 'drivers/rtc/rtc-da9063.c')
-rw-r--r-- | drivers/rtc/rtc-da9063.c | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/drivers/rtc/rtc-da9063.c b/drivers/rtc/rtc-da9063.c index 595393098b09..731ed1a97f59 100644 --- a/drivers/rtc/rtc-da9063.c +++ b/drivers/rtc/rtc-da9063.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #define YEARS_FROM_DA9063(year) ((year) + 100) | 29 | #define YEARS_FROM_DA9063(year) ((year) + 100) |
30 | #define MONTHS_FROM_DA9063(month) ((month) - 1) | 30 | #define MONTHS_FROM_DA9063(month) ((month) - 1) |
31 | 31 | ||
32 | #define RTC_ALARM_DATA_LEN (DA9063_AD_REG_ALARM_Y - DA9063_AD_REG_ALARM_MI + 1) | ||
33 | |||
32 | #define RTC_DATA_LEN (DA9063_REG_COUNT_Y - DA9063_REG_COUNT_S + 1) | 34 | #define RTC_DATA_LEN (DA9063_REG_COUNT_Y - DA9063_REG_COUNT_S + 1) |
33 | #define RTC_SEC 0 | 35 | #define RTC_SEC 0 |
34 | #define RTC_MIN 1 | 36 | #define RTC_MIN 1 |
@@ -42,6 +44,10 @@ struct da9063_rtc { | |||
42 | struct da9063 *hw; | 44 | struct da9063 *hw; |
43 | struct rtc_time alarm_time; | 45 | struct rtc_time alarm_time; |
44 | bool rtc_sync; | 46 | bool rtc_sync; |
47 | int alarm_year; | ||
48 | int alarm_start; | ||
49 | int alarm_len; | ||
50 | int data_start; | ||
45 | }; | 51 | }; |
46 | 52 | ||
47 | static void da9063_data_to_tm(u8 *data, struct rtc_time *tm) | 53 | static void da9063_data_to_tm(u8 *data, struct rtc_time *tm) |
@@ -83,7 +89,7 @@ static int da9063_rtc_stop_alarm(struct device *dev) | |||
83 | { | 89 | { |
84 | struct da9063_rtc *rtc = dev_get_drvdata(dev); | 90 | struct da9063_rtc *rtc = dev_get_drvdata(dev); |
85 | 91 | ||
86 | return regmap_update_bits(rtc->hw->regmap, DA9063_REG_ALARM_Y, | 92 | return regmap_update_bits(rtc->hw->regmap, rtc->alarm_year, |
87 | DA9063_ALARM_ON, 0); | 93 | DA9063_ALARM_ON, 0); |
88 | } | 94 | } |
89 | 95 | ||
@@ -91,7 +97,7 @@ static int da9063_rtc_start_alarm(struct device *dev) | |||
91 | { | 97 | { |
92 | struct da9063_rtc *rtc = dev_get_drvdata(dev); | 98 | struct da9063_rtc *rtc = dev_get_drvdata(dev); |
93 | 99 | ||
94 | return regmap_update_bits(rtc->hw->regmap, DA9063_REG_ALARM_Y, | 100 | return regmap_update_bits(rtc->hw->regmap, rtc->alarm_year, |
95 | DA9063_ALARM_ON, DA9063_ALARM_ON); | 101 | DA9063_ALARM_ON, DA9063_ALARM_ON); |
96 | } | 102 | } |
97 | 103 | ||
@@ -151,8 +157,9 @@ static int da9063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
151 | int ret; | 157 | int ret; |
152 | unsigned int val; | 158 | unsigned int val; |
153 | 159 | ||
154 | ret = regmap_bulk_read(rtc->hw->regmap, DA9063_REG_ALARM_S, | 160 | data[RTC_SEC] = 0; |
155 | &data[RTC_SEC], RTC_DATA_LEN); | 161 | ret = regmap_bulk_read(rtc->hw->regmap, rtc->alarm_start, |
162 | &data[rtc->data_start], rtc->alarm_len); | ||
156 | if (ret < 0) | 163 | if (ret < 0) |
157 | return ret; | 164 | return ret; |
158 | 165 | ||
@@ -186,14 +193,14 @@ static int da9063_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
186 | return ret; | 193 | return ret; |
187 | } | 194 | } |
188 | 195 | ||
189 | ret = regmap_bulk_write(rtc->hw->regmap, DA9063_REG_ALARM_S, | 196 | ret = regmap_bulk_write(rtc->hw->regmap, rtc->alarm_start, |
190 | data, RTC_DATA_LEN); | 197 | &data[rtc->data_start], rtc->alarm_len); |
191 | if (ret < 0) { | 198 | if (ret < 0) { |
192 | dev_err(dev, "Failed to write alarm: %d\n", ret); | 199 | dev_err(dev, "Failed to write alarm: %d\n", ret); |
193 | return ret; | 200 | return ret; |
194 | } | 201 | } |
195 | 202 | ||
196 | rtc->alarm_time = alrm->time; | 203 | da9063_data_to_tm(data, &rtc->alarm_time); |
197 | 204 | ||
198 | if (alrm->enabled) { | 205 | if (alrm->enabled) { |
199 | ret = da9063_rtc_start_alarm(dev); | 206 | ret = da9063_rtc_start_alarm(dev); |
@@ -218,7 +225,7 @@ static irqreturn_t da9063_alarm_event(int irq, void *data) | |||
218 | { | 225 | { |
219 | struct da9063_rtc *rtc = data; | 226 | struct da9063_rtc *rtc = data; |
220 | 227 | ||
221 | regmap_update_bits(rtc->hw->regmap, DA9063_REG_ALARM_Y, | 228 | regmap_update_bits(rtc->hw->regmap, rtc->alarm_year, |
222 | DA9063_ALARM_ON, 0); | 229 | DA9063_ALARM_ON, 0); |
223 | 230 | ||
224 | rtc->rtc_sync = true; | 231 | rtc->rtc_sync = true; |
@@ -257,7 +264,23 @@ static int da9063_rtc_probe(struct platform_device *pdev) | |||
257 | goto err; | 264 | goto err; |
258 | } | 265 | } |
259 | 266 | ||
260 | ret = regmap_update_bits(da9063->regmap, DA9063_REG_ALARM_S, | 267 | rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); |
268 | if (!rtc) | ||
269 | return -ENOMEM; | ||
270 | |||
271 | if (da9063->variant_code == PMIC_DA9063_AD) { | ||
272 | rtc->alarm_year = DA9063_AD_REG_ALARM_Y; | ||
273 | rtc->alarm_start = DA9063_AD_REG_ALARM_MI; | ||
274 | rtc->alarm_len = RTC_ALARM_DATA_LEN; | ||
275 | rtc->data_start = RTC_MIN; | ||
276 | } else { | ||
277 | rtc->alarm_year = DA9063_BB_REG_ALARM_Y; | ||
278 | rtc->alarm_start = DA9063_BB_REG_ALARM_S; | ||
279 | rtc->alarm_len = RTC_DATA_LEN; | ||
280 | rtc->data_start = RTC_SEC; | ||
281 | } | ||
282 | |||
283 | ret = regmap_update_bits(da9063->regmap, rtc->alarm_start, | ||
261 | DA9063_ALARM_STATUS_TICK | DA9063_ALARM_STATUS_ALARM, | 284 | DA9063_ALARM_STATUS_TICK | DA9063_ALARM_STATUS_ALARM, |
262 | 0); | 285 | 0); |
263 | if (ret < 0) { | 286 | if (ret < 0) { |
@@ -265,7 +288,7 @@ static int da9063_rtc_probe(struct platform_device *pdev) | |||
265 | goto err; | 288 | goto err; |
266 | } | 289 | } |
267 | 290 | ||
268 | ret = regmap_update_bits(da9063->regmap, DA9063_REG_ALARM_S, | 291 | ret = regmap_update_bits(da9063->regmap, rtc->alarm_start, |
269 | DA9063_ALARM_STATUS_ALARM, | 292 | DA9063_ALARM_STATUS_ALARM, |
270 | DA9063_ALARM_STATUS_ALARM); | 293 | DA9063_ALARM_STATUS_ALARM); |
271 | if (ret < 0) { | 294 | if (ret < 0) { |
@@ -273,25 +296,22 @@ static int da9063_rtc_probe(struct platform_device *pdev) | |||
273 | goto err; | 296 | goto err; |
274 | } | 297 | } |
275 | 298 | ||
276 | ret = regmap_update_bits(da9063->regmap, DA9063_REG_ALARM_Y, | 299 | ret = regmap_update_bits(da9063->regmap, rtc->alarm_year, |
277 | DA9063_TICK_ON, 0); | 300 | DA9063_TICK_ON, 0); |
278 | if (ret < 0) { | 301 | if (ret < 0) { |
279 | dev_err(&pdev->dev, "Failed to disable TICKs\n"); | 302 | dev_err(&pdev->dev, "Failed to disable TICKs\n"); |
280 | goto err; | 303 | goto err; |
281 | } | 304 | } |
282 | 305 | ||
283 | ret = regmap_bulk_read(da9063->regmap, DA9063_REG_ALARM_S, | 306 | data[RTC_SEC] = 0; |
284 | data, RTC_DATA_LEN); | 307 | ret = regmap_bulk_read(da9063->regmap, rtc->alarm_start, |
308 | &data[rtc->data_start], rtc->alarm_len); | ||
285 | if (ret < 0) { | 309 | if (ret < 0) { |
286 | dev_err(&pdev->dev, "Failed to read initial alarm data: %d\n", | 310 | dev_err(&pdev->dev, "Failed to read initial alarm data: %d\n", |
287 | ret); | 311 | ret); |
288 | goto err; | 312 | goto err; |
289 | } | 313 | } |
290 | 314 | ||
291 | rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); | ||
292 | if (!rtc) | ||
293 | return -ENOMEM; | ||
294 | |||
295 | platform_set_drvdata(pdev, rtc); | 315 | platform_set_drvdata(pdev, rtc); |
296 | 316 | ||
297 | irq_alarm = platform_get_irq_byname(pdev, "ALARM"); | 317 | irq_alarm = platform_get_irq_byname(pdev, "ALARM"); |