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