blob: b406bab32d1725091111e64bdb3078dc137a376f [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
7#include <common.h>
8#include <dm.h>
9#include <errno.h>
Simon Glass0f2af882020-05-10 11:40:05 -060010#include <log.h>
Simon Glassd9050b52015-04-20 12:37:23 -060011#include <rtc.h>
12
13int dm_rtc_get(struct udevice *dev, struct rtc_time *time)
14{
15 struct rtc_ops *ops = rtc_get_ops(dev);
16
17 assert(ops);
18 if (!ops->get)
19 return -ENOSYS;
20 return ops->get(dev, time);
21}
22
23int dm_rtc_set(struct udevice *dev, struct rtc_time *time)
24{
25 struct rtc_ops *ops = rtc_get_ops(dev);
26
27 assert(ops);
28 if (!ops->set)
29 return -ENOSYS;
30 return ops->set(dev, time);
31}
32
33int dm_rtc_reset(struct udevice *dev)
34{
35 struct rtc_ops *ops = rtc_get_ops(dev);
36
37 assert(ops);
38 if (!ops->reset)
39 return -ENOSYS;
40 return ops->reset(dev);
41}
42
Rasmus Villemoesb9e40a22020-07-06 22:01:10 +020043int dm_rtc_read(struct udevice *dev, unsigned int reg, u8 *buf, unsigned int len)
44{
45 struct rtc_ops *ops = rtc_get_ops(dev);
46
47 assert(ops);
48 if (ops->read)
49 return ops->read(dev, reg, buf, len);
50 if (!ops->read8)
51 return -ENOSYS;
52 while (len--) {
53 int ret = ops->read8(dev, reg++);
54
55 if (ret < 0)
56 return ret;
57 *buf++ = ret;
58 }
59 return 0;
60}
61
Rasmus Villemoes579c9922020-07-06 22:01:11 +020062int dm_rtc_write(struct udevice *dev, unsigned int reg,
63 const u8 *buf, unsigned int len)
64{
65 struct rtc_ops *ops = rtc_get_ops(dev);
66
67 assert(ops);
68 if (ops->write)
69 return ops->write(dev, reg, buf, len);
70 if (!ops->write8)
71 return -ENOSYS;
72 while (len--) {
73 int ret = ops->write8(dev, reg++, *buf++);
74
75 if (ret < 0)
76 return ret;
77 }
78 return 0;
79}
80
Simon Glassd9050b52015-04-20 12:37:23 -060081int rtc_read8(struct udevice *dev, unsigned int reg)
82{
83 struct rtc_ops *ops = rtc_get_ops(dev);
84
85 assert(ops);
Rasmus Villemoes6f0854e2020-07-06 22:01:12 +020086 if (ops->read8)
87 return ops->read8(dev, reg);
88 if (ops->read) {
89 u8 buf[1];
90 int ret = ops->read(dev, reg, buf, 1);
91
92 if (ret < 0)
93 return ret;
94 return buf[0];
95 }
96 return -ENOSYS;
Simon Glassd9050b52015-04-20 12:37:23 -060097}
98
99int rtc_write8(struct udevice *dev, unsigned int reg, int val)
100{
101 struct rtc_ops *ops = rtc_get_ops(dev);
102
103 assert(ops);
Rasmus Villemoes6f0854e2020-07-06 22:01:12 +0200104 if (ops->write8)
105 return ops->write8(dev, reg, val);
106 if (ops->write) {
107 u8 buf[1] = { val };
108
109 return ops->write(dev, reg, buf, 1);
110 }
111 return -ENOSYS;
Simon Glassd9050b52015-04-20 12:37:23 -0600112}
113
Bin Mengfbfe53d2017-03-16 07:26:27 -0700114int rtc_read16(struct udevice *dev, unsigned int reg, u16 *valuep)
115{
116 u16 value = 0;
117 int ret;
118 int i;
119
120 for (i = 0; i < sizeof(value); i++) {
121 ret = rtc_read8(dev, reg + i);
122 if (ret < 0)
123 return ret;
124 value |= ret << (i << 3);
125 }
126
127 *valuep = value;
128 return 0;
129}
130
131int rtc_write16(struct udevice *dev, unsigned int reg, u16 value)
132{
133 int i, ret;
134
135 for (i = 0; i < sizeof(value); i++) {
136 ret = rtc_write8(dev, reg + i, (value >> (i << 3)) & 0xff);
137 if (ret)
138 return ret;
139 }
140
141 return 0;
142}
143
Simon Glassd9050b52015-04-20 12:37:23 -0600144int rtc_read32(struct udevice *dev, unsigned int reg, u32 *valuep)
145{
146 u32 value = 0;
147 int ret;
148 int i;
149
150 for (i = 0; i < sizeof(value); i++) {
151 ret = rtc_read8(dev, reg + i);
Simon Glassc60a5bc2015-10-18 15:55:31 -0600152 if (ret < 0)
Simon Glassd9050b52015-04-20 12:37:23 -0600153 return ret;
154 value |= ret << (i << 3);
155 }
156
157 *valuep = value;
158 return 0;
159}
160
161int rtc_write32(struct udevice *dev, unsigned int reg, u32 value)
162{
163 int i, ret;
164
165 for (i = 0; i < sizeof(value); i++) {
166 ret = rtc_write8(dev, reg + i, (value >> (i << 3)) & 0xff);
167 if (ret)
168 return ret;
169 }
170
171 return 0;
172}
173
174UCLASS_DRIVER(rtc) = {
175 .name = "rtc",
176 .id = UCLASS_RTC,
Simon Glasse45710b2020-10-03 11:31:34 -0600177#if !CONFIG_IS_ENABLED(OF_PLATDATA)
Simon Glass302ea782018-11-18 08:14:35 -0700178 .post_bind = dm_scan_fdt_dev,
Simon Glasse45710b2020-10-03 11:31:34 -0600179#endif
Simon Glassd9050b52015-04-20 12:37:23 -0600180};