blob: 44da500c0385a2f8c5b50138f93f3f775bafe9b1 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glassdbeda5b2015-04-20 12:37:23 -06002/*
3 * (C) Copyright 2015 Google, Inc
4 * Written by Simon Glass <sjg@chromium.org>
Simon Glassdbeda5b2015-04-20 12:37:23 -06005 */
6
7#include <common.h>
8#include <dm.h>
9#include <errno.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060010#include <log.h>
Simon Glassdbeda5b2015-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 Villemoesd8be0882020-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 Villemoes09381822020-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 Glassdbeda5b2015-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);
86 if (!ops->read8)
87 return -ENOSYS;
88 return ops->read8(dev, reg);
89}
90
91int rtc_write8(struct udevice *dev, unsigned int reg, int val)
92{
93 struct rtc_ops *ops = rtc_get_ops(dev);
94
95 assert(ops);
96 if (!ops->write8)
97 return -ENOSYS;
98 return ops->write8(dev, reg, val);
99}
100
Bin Mengd24c7fb2017-03-16 07:26:27 -0700101int rtc_read16(struct udevice *dev, unsigned int reg, u16 *valuep)
102{
103 u16 value = 0;
104 int ret;
105 int i;
106
107 for (i = 0; i < sizeof(value); i++) {
108 ret = rtc_read8(dev, reg + i);
109 if (ret < 0)
110 return ret;
111 value |= ret << (i << 3);
112 }
113
114 *valuep = value;
115 return 0;
116}
117
118int rtc_write16(struct udevice *dev, unsigned int reg, u16 value)
119{
120 int i, ret;
121
122 for (i = 0; i < sizeof(value); i++) {
123 ret = rtc_write8(dev, reg + i, (value >> (i << 3)) & 0xff);
124 if (ret)
125 return ret;
126 }
127
128 return 0;
129}
130
Simon Glassdbeda5b2015-04-20 12:37:23 -0600131int rtc_read32(struct udevice *dev, unsigned int reg, u32 *valuep)
132{
133 u32 value = 0;
134 int ret;
135 int i;
136
137 for (i = 0; i < sizeof(value); i++) {
138 ret = rtc_read8(dev, reg + i);
Simon Glass9a4eb592015-10-18 15:55:31 -0600139 if (ret < 0)
Simon Glassdbeda5b2015-04-20 12:37:23 -0600140 return ret;
141 value |= ret << (i << 3);
142 }
143
144 *valuep = value;
145 return 0;
146}
147
148int rtc_write32(struct udevice *dev, unsigned int reg, u32 value)
149{
150 int i, ret;
151
152 for (i = 0; i < sizeof(value); i++) {
153 ret = rtc_write8(dev, reg + i, (value >> (i << 3)) & 0xff);
154 if (ret)
155 return ret;
156 }
157
158 return 0;
159}
160
161UCLASS_DRIVER(rtc) = {
162 .name = "rtc",
163 .id = UCLASS_RTC,
Simon Glass68c81fb2018-11-18 08:14:35 -0700164 .post_bind = dm_scan_fdt_dev,
Simon Glassdbeda5b2015-04-20 12:37:23 -0600165};