1*58714166SSimon Glass /*
2*58714166SSimon Glass * (C) Copyright 2015 Google, Inc
3*58714166SSimon Glass * Written by Simon Glass <sjg@chromium.org>
4*58714166SSimon Glass *
5*58714166SSimon Glass * SPDX-License-Identifier: GPL-2.0+
6*58714166SSimon Glass */
7*58714166SSimon Glass
8*58714166SSimon Glass #include <common.h>
9*58714166SSimon Glass #include <dm.h>
10*58714166SSimon Glass #include <i2c.h>
11*58714166SSimon Glass #include <rtc.h>
12*58714166SSimon Glass #include <asm/rtc.h>
13*58714166SSimon Glass
14*58714166SSimon Glass #define REG_COUNT 0x80
15*58714166SSimon Glass
sandbox_rtc_get(struct udevice * dev,struct rtc_time * time)16*58714166SSimon Glass static int sandbox_rtc_get(struct udevice *dev, struct rtc_time *time)
17*58714166SSimon Glass {
18*58714166SSimon Glass time->tm_sec = dm_i2c_reg_read(dev, REG_SEC);
19*58714166SSimon Glass if (time->tm_sec < 0)
20*58714166SSimon Glass return time->tm_sec;
21*58714166SSimon Glass time->tm_min = dm_i2c_reg_read(dev, REG_MIN);
22*58714166SSimon Glass if (time->tm_min < 0)
23*58714166SSimon Glass return time->tm_min;
24*58714166SSimon Glass time->tm_hour = dm_i2c_reg_read(dev, REG_HOUR);
25*58714166SSimon Glass if (time->tm_hour < 0)
26*58714166SSimon Glass return time->tm_hour;
27*58714166SSimon Glass time->tm_mday = dm_i2c_reg_read(dev, REG_MDAY);
28*58714166SSimon Glass if (time->tm_mday < 0)
29*58714166SSimon Glass return time->tm_mday;
30*58714166SSimon Glass time->tm_mon = dm_i2c_reg_read(dev, REG_MON);
31*58714166SSimon Glass if (time->tm_mon < 0)
32*58714166SSimon Glass return time->tm_mon;
33*58714166SSimon Glass time->tm_year = dm_i2c_reg_read(dev, REG_YEAR);
34*58714166SSimon Glass if (time->tm_year < 0)
35*58714166SSimon Glass return time->tm_year;
36*58714166SSimon Glass time->tm_year += 1900;
37*58714166SSimon Glass time->tm_wday = dm_i2c_reg_read(dev, REG_WDAY);
38*58714166SSimon Glass if (time->tm_wday < 0)
39*58714166SSimon Glass return time->tm_wday;
40*58714166SSimon Glass
41*58714166SSimon Glass return 0;
42*58714166SSimon Glass }
43*58714166SSimon Glass
sandbox_rtc_set(struct udevice * dev,const struct rtc_time * time)44*58714166SSimon Glass static int sandbox_rtc_set(struct udevice *dev, const struct rtc_time *time)
45*58714166SSimon Glass {
46*58714166SSimon Glass int ret;
47*58714166SSimon Glass
48*58714166SSimon Glass ret = dm_i2c_reg_write(dev, REG_SEC, time->tm_sec);
49*58714166SSimon Glass if (ret < 0)
50*58714166SSimon Glass return ret;
51*58714166SSimon Glass ret = dm_i2c_reg_write(dev, REG_MIN, time->tm_min);
52*58714166SSimon Glass if (ret < 0)
53*58714166SSimon Glass return ret;
54*58714166SSimon Glass ret = dm_i2c_reg_write(dev, REG_HOUR, time->tm_hour);
55*58714166SSimon Glass if (ret < 0)
56*58714166SSimon Glass return ret;
57*58714166SSimon Glass ret = dm_i2c_reg_write(dev, REG_MDAY, time->tm_mday);
58*58714166SSimon Glass if (ret < 0)
59*58714166SSimon Glass return ret;
60*58714166SSimon Glass ret = dm_i2c_reg_write(dev, REG_MON, time->tm_mon);
61*58714166SSimon Glass if (ret < 0)
62*58714166SSimon Glass return ret;
63*58714166SSimon Glass ret = dm_i2c_reg_write(dev, REG_YEAR, time->tm_year - 1900);
64*58714166SSimon Glass if (ret < 0)
65*58714166SSimon Glass return ret;
66*58714166SSimon Glass ret = dm_i2c_reg_write(dev, REG_WDAY, time->tm_wday);
67*58714166SSimon Glass if (ret < 0)
68*58714166SSimon Glass return ret;
69*58714166SSimon Glass
70*58714166SSimon Glass return 0;
71*58714166SSimon Glass }
72*58714166SSimon Glass
sandbox_rtc_reset(struct udevice * dev)73*58714166SSimon Glass static int sandbox_rtc_reset(struct udevice *dev)
74*58714166SSimon Glass {
75*58714166SSimon Glass return dm_i2c_reg_write(dev, REG_RESET, 0);
76*58714166SSimon Glass }
77*58714166SSimon Glass
sandbox_rtc_read8(struct udevice * dev,unsigned int reg)78*58714166SSimon Glass static int sandbox_rtc_read8(struct udevice *dev, unsigned int reg)
79*58714166SSimon Glass {
80*58714166SSimon Glass return dm_i2c_reg_read(dev, reg);
81*58714166SSimon Glass }
82*58714166SSimon Glass
sandbox_rtc_write8(struct udevice * dev,unsigned int reg,int val)83*58714166SSimon Glass static int sandbox_rtc_write8(struct udevice *dev, unsigned int reg, int val)
84*58714166SSimon Glass {
85*58714166SSimon Glass return dm_i2c_reg_write(dev, reg, val);
86*58714166SSimon Glass }
87*58714166SSimon Glass
88*58714166SSimon Glass static const struct rtc_ops sandbox_rtc_ops = {
89*58714166SSimon Glass .get = sandbox_rtc_get,
90*58714166SSimon Glass .set = sandbox_rtc_set,
91*58714166SSimon Glass .reset = sandbox_rtc_reset,
92*58714166SSimon Glass .read8 = sandbox_rtc_read8,
93*58714166SSimon Glass .write8 = sandbox_rtc_write8,
94*58714166SSimon Glass };
95*58714166SSimon Glass
96*58714166SSimon Glass static const struct udevice_id sandbox_rtc_ids[] = {
97*58714166SSimon Glass { .compatible = "sandbox-rtc" },
98*58714166SSimon Glass { }
99*58714166SSimon Glass };
100*58714166SSimon Glass
101*58714166SSimon Glass U_BOOT_DRIVER(rtc_sandbox) = {
102*58714166SSimon Glass .name = "rtc-sandbox",
103*58714166SSimon Glass .id = UCLASS_RTC,
104*58714166SSimon Glass .of_match = sandbox_rtc_ids,
105*58714166SSimon Glass .ops = &sandbox_rtc_ops,
106*58714166SSimon Glass };
107