blob: 4a0e3c5643dd62ad7c414ddd4139fa776baad19a [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
Simon Glassdbeda5b2015-04-20 12:37:23 -060062int rtc_read8(struct udevice *dev, unsigned int reg)
63{
64 struct rtc_ops *ops = rtc_get_ops(dev);
65
66 assert(ops);
67 if (!ops->read8)
68 return -ENOSYS;
69 return ops->read8(dev, reg);
70}
71
72int rtc_write8(struct udevice *dev, unsigned int reg, int val)
73{
74 struct rtc_ops *ops = rtc_get_ops(dev);
75
76 assert(ops);
77 if (!ops->write8)
78 return -ENOSYS;
79 return ops->write8(dev, reg, val);
80}
81
Bin Mengd24c7fb2017-03-16 07:26:27 -070082int rtc_read16(struct udevice *dev, unsigned int reg, u16 *valuep)
83{
84 u16 value = 0;
85 int ret;
86 int i;
87
88 for (i = 0; i < sizeof(value); i++) {
89 ret = rtc_read8(dev, reg + i);
90 if (ret < 0)
91 return ret;
92 value |= ret << (i << 3);
93 }
94
95 *valuep = value;
96 return 0;
97}
98
99int rtc_write16(struct udevice *dev, unsigned int reg, u16 value)
100{
101 int i, ret;
102
103 for (i = 0; i < sizeof(value); i++) {
104 ret = rtc_write8(dev, reg + i, (value >> (i << 3)) & 0xff);
105 if (ret)
106 return ret;
107 }
108
109 return 0;
110}
111
Simon Glassdbeda5b2015-04-20 12:37:23 -0600112int rtc_read32(struct udevice *dev, unsigned int reg, u32 *valuep)
113{
114 u32 value = 0;
115 int ret;
116 int i;
117
118 for (i = 0; i < sizeof(value); i++) {
119 ret = rtc_read8(dev, reg + i);
Simon Glass9a4eb592015-10-18 15:55:31 -0600120 if (ret < 0)
Simon Glassdbeda5b2015-04-20 12:37:23 -0600121 return ret;
122 value |= ret << (i << 3);
123 }
124
125 *valuep = value;
126 return 0;
127}
128
129int rtc_write32(struct udevice *dev, unsigned int reg, u32 value)
130{
131 int i, ret;
132
133 for (i = 0; i < sizeof(value); i++) {
134 ret = rtc_write8(dev, reg + i, (value >> (i << 3)) & 0xff);
135 if (ret)
136 return ret;
137 }
138
139 return 0;
140}
141
142UCLASS_DRIVER(rtc) = {
143 .name = "rtc",
144 .id = UCLASS_RTC,
Simon Glass68c81fb2018-11-18 08:14:35 -0700145 .post_bind = dm_scan_fdt_dev,
Simon Glassdbeda5b2015-04-20 12:37:23 -0600146};