blob: 8f6c0c6a0a78702398e84207b5197ccab794fb95 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glassd9050b52015-04-20 12:37:23 -06002/*
3 * (C) Copyright 2015 Google, Inc
4 * Written by Simon Glass <sjg@chromium.org>
Simon Glassd9050b52015-04-20 12:37:23 -06005 */
6
Patrick Delaunay81313352021-04-27 11:02:19 +02007#define LOG_CATEGORY UCLASS_RTC
8
Simon Glassd9050b52015-04-20 12:37:23 -06009#include <dm.h>
10#include <errno.h>
Simon Glass0f2af882020-05-10 11:40:05 -060011#include <log.h>
Simon Glassd9050b52015-04-20 12:37:23 -060012#include <rtc.h>
13
14int dm_rtc_get(struct udevice *dev, struct rtc_time *time)
15{
16 struct rtc_ops *ops = rtc_get_ops(dev);
17
18 assert(ops);
19 if (!ops->get)
20 return -ENOSYS;
21 return ops->get(dev, time);
22}
23
24int dm_rtc_set(struct udevice *dev, struct rtc_time *time)
25{
26 struct rtc_ops *ops = rtc_get_ops(dev);
27
28 assert(ops);
29 if (!ops->set)
30 return -ENOSYS;
31 return ops->set(dev, time);
32}
33
34int dm_rtc_reset(struct udevice *dev)
35{
36 struct rtc_ops *ops = rtc_get_ops(dev);
37
38 assert(ops);
39 if (!ops->reset)
40 return -ENOSYS;
41 return ops->reset(dev);
42}
43
Rasmus Villemoesb9e40a22020-07-06 22:01:10 +020044int dm_rtc_read(struct udevice *dev, unsigned int reg, u8 *buf, unsigned int len)
45{
46 struct rtc_ops *ops = rtc_get_ops(dev);
47
48 assert(ops);
49 if (ops->read)
50 return ops->read(dev, reg, buf, len);
51 if (!ops->read8)
52 return -ENOSYS;
53 while (len--) {
54 int ret = ops->read8(dev, reg++);
55
56 if (ret < 0)
57 return ret;
58 *buf++ = ret;
59 }
60 return 0;
61}
62
Rasmus Villemoes579c9922020-07-06 22:01:11 +020063int dm_rtc_write(struct udevice *dev, unsigned int reg,
64 const u8 *buf, unsigned int len)
65{
66 struct rtc_ops *ops = rtc_get_ops(dev);
67
68 assert(ops);
69 if (ops->write)
70 return ops->write(dev, reg, buf, len);
71 if (!ops->write8)
72 return -ENOSYS;
73 while (len--) {
74 int ret = ops->write8(dev, reg++, *buf++);
75
76 if (ret < 0)
77 return ret;
78 }
79 return 0;
80}
81
Simon Glassd9050b52015-04-20 12:37:23 -060082int rtc_read8(struct udevice *dev, unsigned int reg)
83{
84 struct rtc_ops *ops = rtc_get_ops(dev);
85
86 assert(ops);
Rasmus Villemoes6f0854e2020-07-06 22:01:12 +020087 if (ops->read8)
88 return ops->read8(dev, reg);
89 if (ops->read) {
90 u8 buf[1];
91 int ret = ops->read(dev, reg, buf, 1);
92
93 if (ret < 0)
94 return ret;
95 return buf[0];
96 }
97 return -ENOSYS;
Simon Glassd9050b52015-04-20 12:37:23 -060098}
99
100int rtc_write8(struct udevice *dev, unsigned int reg, int val)
101{
102 struct rtc_ops *ops = rtc_get_ops(dev);
103
104 assert(ops);
Rasmus Villemoes6f0854e2020-07-06 22:01:12 +0200105 if (ops->write8)
106 return ops->write8(dev, reg, val);
107 if (ops->write) {
108 u8 buf[1] = { val };
109
110 return ops->write(dev, reg, buf, 1);
111 }
112 return -ENOSYS;
Simon Glassd9050b52015-04-20 12:37:23 -0600113}
114
Bin Mengfbfe53d2017-03-16 07:26:27 -0700115int rtc_read16(struct udevice *dev, unsigned int reg, u16 *valuep)
116{
117 u16 value = 0;
118 int ret;
119 int i;
120
121 for (i = 0; i < sizeof(value); i++) {
122 ret = rtc_read8(dev, reg + i);
123 if (ret < 0)
124 return ret;
125 value |= ret << (i << 3);
126 }
127
128 *valuep = value;
129 return 0;
130}
131
132int rtc_write16(struct udevice *dev, unsigned int reg, u16 value)
133{
134 int i, ret;
135
136 for (i = 0; i < sizeof(value); i++) {
137 ret = rtc_write8(dev, reg + i, (value >> (i << 3)) & 0xff);
138 if (ret)
139 return ret;
140 }
141
142 return 0;
143}
144
Simon Glassd9050b52015-04-20 12:37:23 -0600145int rtc_read32(struct udevice *dev, unsigned int reg, u32 *valuep)
146{
147 u32 value = 0;
148 int ret;
149 int i;
150
151 for (i = 0; i < sizeof(value); i++) {
152 ret = rtc_read8(dev, reg + i);
Simon Glassc60a5bc2015-10-18 15:55:31 -0600153 if (ret < 0)
Simon Glassd9050b52015-04-20 12:37:23 -0600154 return ret;
155 value |= ret << (i << 3);
156 }
157
158 *valuep = value;
159 return 0;
160}
161
162int rtc_write32(struct udevice *dev, unsigned int reg, u32 value)
163{
164 int i, ret;
165
166 for (i = 0; i < sizeof(value); i++) {
167 ret = rtc_write8(dev, reg + i, (value >> (i << 3)) & 0xff);
168 if (ret)
169 return ret;
170 }
171
172 return 0;
173}
174
175UCLASS_DRIVER(rtc) = {
176 .name = "rtc",
177 .id = UCLASS_RTC,
Michal Simek13bbcf42021-07-29 12:57:12 +0200178 .flags = DM_UC_FLAG_SEQ_ALIAS,
Simon Glass92882652021-08-07 07:24:04 -0600179#if CONFIG_IS_ENABLED(OF_REAL)
Simon Glass302ea782018-11-18 08:14:35 -0700180 .post_bind = dm_scan_fdt_dev,
Simon Glasse45710b2020-10-03 11:31:34 -0600181#endif
Simon Glassd9050b52015-04-20 12:37:23 -0600182};