rtc-da9052.c revision 7c994c08c376eb96503dc6a7110fda95e24dbdb1
1fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam/*
2fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * Real time clock driver for DA9052
3fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam *
4fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * Copyright(c) 2012 Dialog Semiconductor Ltd.
5fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam *
6fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * Author: Dajun Dajun Chen <dajun.chen@diasemi.com>
7fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam *
8fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * This program is free software; you can redistribute it and/or modify
9fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * it under the terms of the GNU General Public License as published by
10fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * the Free Software Foundation; either version 2 of the License, or
11fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * (at your option) any later version.
12fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam *
13fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam */
14fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
15fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam#include <linux/module.h>
16fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam#include <linux/platform_device.h>
17fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam#include <linux/rtc.h>
1811f54d05865c009a468e9d7adaa7414749daa6caSachin Kamat#include <linux/err.h>
19fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
20fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam#include <linux/mfd/da9052/da9052.h>
21fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam#include <linux/mfd/da9052/reg.h>
22fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
237c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech#define rtc_err(rtc, fmt, ...) \
247c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		dev_err(rtc->da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__)
25fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
26fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstruct da9052_rtc {
27fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	struct rtc_device *rtc;
28fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	struct da9052 *da9052;
29fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam};
30fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
317c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olechstatic int da9052_rtc_enable_alarm(struct da9052_rtc *rtc, bool enable)
32fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{
33fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	int ret;
34fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	if (enable) {
357c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		ret = da9052_reg_update(rtc->da9052, DA9052_ALARM_Y_REG,
367c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech				DA9052_ALARM_Y_ALARM_ON|DA9052_ALARM_Y_TICK_ON,
377c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech				DA9052_ALARM_Y_ALARM_ON);
38fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam		if (ret != 0)
397c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech			rtc_err(rtc, "Failed to enable ALM: %d\n", ret);
40fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	} else {
417c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		ret = da9052_reg_update(rtc->da9052, DA9052_ALARM_Y_REG,
427c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech			DA9052_ALARM_Y_ALARM_ON|DA9052_ALARM_Y_TICK_ON, 0);
43fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam		if (ret != 0)
447c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech			rtc_err(rtc, "Write error: %d\n", ret);
45fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	}
46fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	return ret;
47fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam}
48fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
49fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstatic irqreturn_t da9052_rtc_irq(int irq, void *data)
50fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{
51fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	struct da9052_rtc *rtc = data;
52fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
537c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
54fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
55fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	return IRQ_HANDLED;
56fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam}
57fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
587c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olechstatic int da9052_read_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm)
59fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{
60fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	int ret;
61fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	uint8_t v[5];
62fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
637c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	ret = da9052_group_read(rtc->da9052, DA9052_ALARM_MI_REG, 5, v);
64fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	if (ret != 0) {
657c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		rtc_err(rtc, "Failed to group read ALM: %d\n", ret);
66fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam		return ret;
67fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	}
68fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
69fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	rtc_tm->tm_year = (v[4] & DA9052_RTC_YEAR) + 100;
70fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	rtc_tm->tm_mon  = (v[3] & DA9052_RTC_MONTH) - 1;
71fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	rtc_tm->tm_mday = v[2] & DA9052_RTC_DAY;
72fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	rtc_tm->tm_hour = v[1] & DA9052_RTC_HOUR;
73fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	rtc_tm->tm_min  = v[0] & DA9052_RTC_MIN;
74fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
75fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	ret = rtc_valid_tm(rtc_tm);
76fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	return ret;
77fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam}
78fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
797c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olechstatic int da9052_set_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm)
80fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{
817c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	struct da9052 *da9052 = rtc->da9052;
827c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	unsigned long alm_time;
83fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	int ret;
84fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	uint8_t v[3];
85fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
867c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	ret = rtc_tm_to_time(rtc_tm, &alm_time);
877c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	if (ret != 0)
887c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		return ret;
897c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech
907c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	if (rtc_tm->tm_sec > 0) {
917c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		alm_time += 60 - rtc_tm->tm_sec;
927c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		rtc_time_to_tm(alm_time, rtc_tm);
937c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	}
947c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	BUG_ON(rtc_tm->tm_sec); /* it will cause repeated irqs if not zero */
957c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech
96fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	rtc_tm->tm_year -= 100;
97fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	rtc_tm->tm_mon += 1;
98fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
99fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	ret = da9052_reg_update(da9052, DA9052_ALARM_MI_REG,
100fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam				DA9052_RTC_MIN, rtc_tm->tm_min);
101fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	if (ret != 0) {
1027c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		rtc_err(rtc, "Failed to write ALRM MIN: %d\n", ret);
103fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam		return ret;
104fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	}
105fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
106fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	v[0] = rtc_tm->tm_hour;
107fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	v[1] = rtc_tm->tm_mday;
108fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	v[2] = rtc_tm->tm_mon;
109fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
110fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	ret = da9052_group_write(da9052, DA9052_ALARM_H_REG, 3, v);
111fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	if (ret < 0)
112fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam		return ret;
113fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
114fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG,
115fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam				DA9052_RTC_YEAR, rtc_tm->tm_year);
116fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	if (ret != 0)
1177c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		rtc_err(rtc, "Failed to write ALRM YEAR: %d\n", ret);
118fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
119fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	return ret;
120fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam}
121fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
1227c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olechstatic int da9052_rtc_get_alarm_status(struct da9052_rtc *rtc)
123fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{
124fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	int ret;
125fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
1267c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	ret = da9052_reg_read(rtc->da9052, DA9052_ALARM_Y_REG);
127fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	if (ret < 0) {
1287c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		rtc_err(rtc, "Failed to read ALM: %d\n", ret);
129fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam		return ret;
130fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	}
1317c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech
1327c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	return !!(ret&DA9052_ALARM_Y_ALARM_ON);
133fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam}
134fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
135fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstatic int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
136fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{
137fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	struct da9052_rtc *rtc = dev_get_drvdata(dev);
138fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	uint8_t v[6];
139fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	int ret;
140fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
141fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, v);
142fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	if (ret < 0) {
1437c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		rtc_err(rtc, "Failed to read RTC time : %d\n", ret);
144fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam		return ret;
145fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	}
146fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
147fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	rtc_tm->tm_year = (v[5] & DA9052_RTC_YEAR) + 100;
148fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	rtc_tm->tm_mon  = (v[4] & DA9052_RTC_MONTH) - 1;
149fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	rtc_tm->tm_mday = v[3] & DA9052_RTC_DAY;
150fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	rtc_tm->tm_hour = v[2] & DA9052_RTC_HOUR;
151fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	rtc_tm->tm_min  = v[1] & DA9052_RTC_MIN;
152fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	rtc_tm->tm_sec  = v[0] & DA9052_RTC_SEC;
153fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
154fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	ret = rtc_valid_tm(rtc_tm);
1557c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	return ret;
156fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam}
157fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
158fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstatic int da9052_rtc_set_time(struct device *dev, struct rtc_time *tm)
159fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{
160fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	struct da9052_rtc *rtc;
161fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	uint8_t v[6];
1627c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	int ret;
163fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
164fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	rtc = dev_get_drvdata(dev);
165fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
166fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	v[0] = tm->tm_sec;
167fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	v[1] = tm->tm_min;
168fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	v[2] = tm->tm_hour;
169fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	v[3] = tm->tm_mday;
170fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	v[4] = tm->tm_mon + 1;
171fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	v[5] = tm->tm_year - 100;
172fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
1737c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	ret = da9052_group_write(rtc->da9052, DA9052_COUNT_S_REG, 6, v);
1747c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	if (ret < 0)
1757c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		rtc_err(rtc, "failed to set RTC time: %d\n", ret);
1767c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	return ret;
177fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam}
178fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
179fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstatic int da9052_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
180fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{
181fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	int ret;
182fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	struct rtc_time *tm = &alrm->time;
183fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	struct da9052_rtc *rtc = dev_get_drvdata(dev);
184fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
1857c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	ret = da9052_read_alarm(rtc, tm);
1867c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	if (ret < 0) {
1877c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		rtc_err(rtc, "failed to read RTC alarm: %d\n", ret);
188fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam		return ret;
1897c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	}
190fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
1917c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	alrm->enabled = da9052_rtc_get_alarm_status(rtc);
192fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	return 0;
193fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam}
194fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
195fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstatic int da9052_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
196fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{
197fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	int ret;
198fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	struct rtc_time *tm = &alrm->time;
199fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	struct da9052_rtc *rtc = dev_get_drvdata(dev);
200fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
2017c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	ret = da9052_rtc_enable_alarm(rtc, 0);
202fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	if (ret < 0)
203fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam		return ret;
204fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
2057c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	ret = da9052_set_alarm(rtc, tm);
2067c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	if (ret < 0)
207fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam		return ret;
208fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
2097c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	ret = da9052_rtc_enable_alarm(rtc, 1);
210fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	return ret;
211fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam}
212fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
213fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstatic int da9052_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
214fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{
215fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	struct da9052_rtc *rtc = dev_get_drvdata(dev);
216fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
2177c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	return da9052_rtc_enable_alarm(rtc, enabled);
218fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam}
219fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
220fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstatic const struct rtc_class_ops da9052_rtc_ops = {
221fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	.read_time	= da9052_rtc_read_time,
222fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	.set_time	= da9052_rtc_set_time,
223fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	.read_alarm	= da9052_rtc_read_alarm,
224fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	.set_alarm	= da9052_rtc_set_alarm,
225fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	.alarm_irq_enable = da9052_rtc_alarm_irq_enable,
226fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam};
227fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
2285a167f4543e45d45c5672a5cd6cb8ba5ddf4f3eaGreg Kroah-Hartmanstatic int da9052_rtc_probe(struct platform_device *pdev)
229fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{
230fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	struct da9052_rtc *rtc;
231fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	int ret;
232fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
233fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	rtc = devm_kzalloc(&pdev->dev, sizeof(struct da9052_rtc), GFP_KERNEL);
234fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	if (!rtc)
235fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam		return -ENOMEM;
236fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
237fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	rtc->da9052 = dev_get_drvdata(pdev->dev.parent);
238fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	platform_set_drvdata(pdev, rtc);
2397c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech
2407c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	ret = da9052_reg_write(rtc->da9052, DA9052_BBAT_CONT_REG, 0xFE);
2417c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	if (ret < 0) {
2427c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		rtc_err(rtc,
2437c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech			"Failed to setup RTC battery charging: %d\n", ret);
2447c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		return ret;
2457c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	}
2467c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech
2477c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	ret = da9052_reg_update(rtc->da9052, DA9052_ALARM_Y_REG,
2487c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech				DA9052_ALARM_Y_TICK_ON, 0);
2497c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech	if (ret != 0)
2507c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		rtc_err(rtc, "Failed to disable TICKS: %d\n", ret);
2517c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech
252c2c0eed7f20cbfb20b346f1854afaf485bc6c207Anthony Olech	ret = da9052_request_irq(rtc->da9052, DA9052_IRQ_ALARM, "ALM",
253925e8ea6bca2c9a590565634b27768d7042e089fAshish Jangam				da9052_rtc_irq, rtc);
254fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	if (ret != 0) {
2557c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech		rtc_err(rtc, "irq registration failed: %d\n", ret);
256007def046711479f3d19bec4016b65fd73deed6cDevendra Naga		return ret;
257fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	}
258fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
2593689cd741f627ee49a1a4d5c9aec49e120b6c291Jingoo Han	rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
260fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam				       &da9052_rtc_ops, THIS_MODULE);
261dac30a9843f8a6007e9d25cad2b5735679041397Sachin Kamat	return PTR_ERR_OR_ZERO(rtc->rtc);
262fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam}
263fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
264fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstatic struct platform_driver da9052_rtc_driver = {
265fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	.probe	= da9052_rtc_probe,
266fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	.driver = {
267fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam		.name	= "da9052-rtc",
268fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam		.owner	= THIS_MODULE,
269fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam	},
270fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam};
271fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
272fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangammodule_platform_driver(da9052_rtc_driver);
273fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam
2747c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony OlechMODULE_AUTHOR("Anthony Olech <Anthony.Olech@diasemi.com>");
275fef931ff98fe78bea804d9b4c49d410a7a97988cAshish JangamMODULE_DESCRIPTION("RTC driver for Dialog DA9052 PMIC");
276fef931ff98fe78bea804d9b4c49d410a7a97988cAshish JangamMODULE_LICENSE("GPL");
277fef931ff98fe78bea804d9b4c49d410a7a97988cAshish JangamMODULE_ALIAS("platform:da9052-rtc");
278