clk: rk3399: Set empty for vopl assigned-clocks
[oweals/u-boot.git] / drivers / rtc / ds3232.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2019, Vaisala Oyj
4  */
5
6 #include <common.h>
7 #include <command.h>
8 #include <dm.h>
9 #include <i2c.h>
10 #include <rtc.h>
11 #include <dm/device_compat.h>
12
13 /*
14  * RTC register addresses
15  */
16 #define RTC_SEC_REG_ADDR        0x00
17 #define RTC_MIN_REG_ADDR        0x01
18 #define RTC_HR_REG_ADDR 0x02
19 #define RTC_DAY_REG_ADDR        0x03
20 #define RTC_DATE_REG_ADDR       0x04
21 #define RTC_MON_REG_ADDR        0x05
22 #define RTC_YR_REG_ADDR 0x06
23 #define RTC_CTL_REG_ADDR        0x0e
24 #define RTC_STAT_REG_ADDR       0x0f
25 #define RTC_TEST_REG_ADDR       0x13
26
27 /*
28  * RTC control register bits
29  */
30 #define RTC_CTL_BIT_A1IE        BIT(0)  /* Alarm 1 interrupt enable     */
31 #define RTC_CTL_BIT_A2IE        BIT(1)  /* Alarm 2 interrupt enable     */
32 #define RTC_CTL_BIT_INTCN       BIT(2)  /* Interrupt control            */
33 #define RTC_CTL_BIT_DOSC        BIT(7)  /* Disable Oscillator           */
34
35 /*
36  * RTC status register bits
37  */
38 #define RTC_STAT_BIT_A1F        BIT(0)  /* Alarm 1 flag                 */
39 #define RTC_STAT_BIT_A2F        BIT(1)  /* Alarm 2 flag                 */
40 #define RTC_STAT_BIT_EN32KHZ    BIT(3)  /* Enable 32KHz Output  */
41 #define RTC_STAT_BIT_BB32KHZ    BIT(6)  /* Battery backed 32KHz Output  */
42 #define RTC_STAT_BIT_OSF        BIT(7)  /* Oscillator stop flag         */
43
44 /*
45  * RTC test register bits
46  */
47 #define RTC_TEST_BIT_SWRST      BIT(7)  /* Software reset */
48
49 #define RTC_DATE_TIME_REG_SIZE 7
50 #define RTC_SRAM_START 0x14
51 #define RTC_SRAM_END 0xFF
52 #define RTC_SRAM_SIZE 236
53
54 struct ds3232_priv_data {
55         u8 max_register;
56         u8 sram_start;
57         int sram_size;
58 };
59
60 static int ds3232_rtc_read8(struct udevice *dev, unsigned int reg)
61 {
62         int ret;
63         u8 buf;
64         struct ds3232_priv_data *priv_data;
65
66         priv_data = dev_get_priv(dev);
67         if (!priv_data)
68                 return -EINVAL;
69
70         if (reg > priv_data->max_register)
71                 return -EINVAL;
72
73         ret = dm_i2c_read(dev, reg, &buf, sizeof(buf));
74         if (ret < 0)
75                 return ret;
76
77         return buf;
78 }
79
80 static int ds3232_rtc_write8(struct udevice *dev, unsigned int reg, int val)
81 {
82         u8 buf = (u8)val;
83         struct ds3232_priv_data *priv_data;
84
85         priv_data = dev_get_priv(dev);
86         if (!priv_data)
87                 return -EINVAL;
88
89         if (reg > priv_data->max_register)
90                 return -EINVAL;
91
92         return dm_i2c_write(dev, reg, &buf, sizeof(buf));
93 }
94
95 static int reset_sram(struct udevice *dev)
96 {
97         int ret, sram_end, reg;
98         struct ds3232_priv_data *priv_data;
99
100         priv_data = dev_get_priv(dev);
101         if (!priv_data)
102                 return -EINVAL;
103
104         sram_end = priv_data->sram_start + priv_data->sram_size;
105
106         for (reg = priv_data->sram_start; reg < sram_end; reg++) {
107                 ret = ds3232_rtc_write8(dev, reg, 0x00);
108                 if (ret < 0)
109                         return ret;
110         }
111
112         return 0;
113 }
114
115 static int verify_osc(struct udevice *dev)
116 {
117         int ret, rtc_status;
118
119         ret = ds3232_rtc_read8(dev, RTC_STAT_REG_ADDR);
120         if (ret < 0)
121                 return ret;
122
123         rtc_status = ret;
124
125         if (rtc_status & RTC_STAT_BIT_OSF) {
126                 dev_warn(dev,
127                          "oscillator discontinuity flagged, time unreliable\n");
128                 /*
129                  * In case OSC was off we cannot trust the SRAM data anymore.
130                  * Reset it to 0x00.
131                  */
132                 ret = reset_sram(dev);
133                 if (ret < 0)
134                         return ret;
135         }
136
137         return 0;
138 }
139
140 static int ds3232_rtc_set(struct udevice *dev, const struct rtc_time *tm)
141 {
142         u8 buf[RTC_DATE_TIME_REG_SIZE];
143         u8 is_century;
144
145         if (tm->tm_year < 1900 || tm->tm_year > 2099)
146                 dev_warn(dev, "WARNING: year should be between 1900 and 2099!\n");
147
148         is_century = (tm->tm_year >= 2000) ? 0x80 : 0;
149
150         buf[RTC_SEC_REG_ADDR] = bin2bcd(tm->tm_sec);
151         buf[RTC_MIN_REG_ADDR] = bin2bcd(tm->tm_min);
152         buf[RTC_HR_REG_ADDR] = bin2bcd(tm->tm_hour);
153         buf[RTC_DAY_REG_ADDR] = bin2bcd(tm->tm_wday + 1);
154         buf[RTC_DATE_REG_ADDR] = bin2bcd(tm->tm_mday);
155         buf[RTC_MON_REG_ADDR] = bin2bcd(tm->tm_mon) | is_century;
156         buf[RTC_YR_REG_ADDR] = bin2bcd(tm->tm_year % 100);
157
158         return dm_i2c_write(dev, 0, buf, sizeof(buf));
159 }
160
161 static int ds3232_rtc_get(struct udevice *dev, struct rtc_time *tm)
162 {
163         int ret;
164         u8 buf[RTC_DATE_TIME_REG_SIZE];
165         u8 is_twelve_hr;
166         u8 is_pm;
167         u8 is_century;
168
169         ret = verify_osc(dev);
170         if (ret < 0)
171                 return ret;
172
173         ret = dm_i2c_read(dev, 0, buf, sizeof(buf));
174         if (ret < 0)
175                 return ret;
176
177         /* Extract additional information for AM/PM and century */
178         is_twelve_hr = buf[RTC_HR_REG_ADDR] & 0x40;
179         is_pm = buf[RTC_HR_REG_ADDR] & 0x20;
180         is_century = buf[RTC_MON_REG_ADDR] & 0x80;
181
182         tm->tm_sec  = bcd2bin(buf[RTC_SEC_REG_ADDR] & 0x7F);
183         tm->tm_min  = bcd2bin(buf[RTC_MIN_REG_ADDR] & 0x7F);
184
185         if (is_twelve_hr)
186                 tm->tm_hour = bcd2bin(buf[RTC_HR_REG_ADDR] & 0x1F)
187                         + (is_pm ? 12 : 0);
188         else
189                 tm->tm_hour = bcd2bin(buf[RTC_HR_REG_ADDR]);
190
191         tm->tm_wday = bcd2bin((buf[RTC_DAY_REG_ADDR] & 0x07) - 1);
192         tm->tm_mday = bcd2bin(buf[RTC_DATE_REG_ADDR] & 0x3F);
193         tm->tm_mon  = bcd2bin((buf[RTC_MON_REG_ADDR] & 0x7F));
194         tm->tm_year = bcd2bin(buf[RTC_YR_REG_ADDR])
195                 + (is_century ? 2000 : 1900);
196         tm->tm_yday = 0;
197         tm->tm_isdst = 0;
198
199         return 0;
200 }
201
202 static int ds3232_rtc_reset(struct udevice *dev)
203 {
204         int ret;
205
206         ret = reset_sram(dev);
207         if (ret < 0)
208                 return ret;
209
210         /*
211          * From datasheet
212          * (https://datasheets.maximintegrated.com/en/ds/DS3232M.pdf):
213          *
214          * The device reset occurs during the normal acknowledge time slot
215          * following the receipt of the data byte carrying that
216          * SWRST instruction a NACK occurs due to the resetting action.
217          *
218          * Therefore we don't verify the result of I2C write operation since it
219          * will fail due the NACK.
220          */
221         ds3232_rtc_write8(dev, RTC_TEST_REG_ADDR, RTC_TEST_BIT_SWRST);
222
223         return 0;
224 }
225
226 static int ds3232_probe(struct udevice *dev)
227 {
228         int rtc_status;
229         int ret;
230         struct ds3232_priv_data *priv_data;
231
232         priv_data = dev_get_priv(dev);
233         if (!priv_data)
234                 return -EINVAL;
235
236         priv_data->sram_start = RTC_SRAM_START;
237         priv_data->max_register = RTC_SRAM_END;
238         priv_data->sram_size = RTC_SRAM_SIZE;
239
240         ret = ds3232_rtc_read8(dev, RTC_STAT_REG_ADDR);
241         if (ret < 0)
242                 return ret;
243
244         rtc_status = ret;
245
246         ret = verify_osc(dev);
247         if (ret < 0)
248                 return ret;
249
250         rtc_status &= ~(RTC_STAT_BIT_OSF | RTC_STAT_BIT_A1F | RTC_STAT_BIT_A2F);
251
252         return ds3232_rtc_write8(dev, RTC_STAT_REG_ADDR, rtc_status);
253 }
254
255 static const struct rtc_ops ds3232_rtc_ops = {
256         .get = ds3232_rtc_get,
257         .set = ds3232_rtc_set,
258         .reset = ds3232_rtc_reset,
259         .read8 = ds3232_rtc_read8,
260         .write8 = ds3232_rtc_write8
261 };
262
263 static const struct udevice_id ds3232_rtc_ids[] = {
264         { .compatible = "dallas,ds3232" },
265         { }
266 };
267
268 U_BOOT_DRIVER(rtc_ds3232) = {
269         .name = "rtc-ds3232",
270         .id = UCLASS_RTC,
271         .probe = ds3232_probe,
272         .of_match = ds3232_rtc_ids,
273         .ops = &ds3232_rtc_ops,
274         .priv_auto_alloc_size = sizeof(struct ds3232_priv_data),
275 };