tree: drop last paragraph of GPL copyright header
[coreboot.git] / src / drivers / ti / tps65913 / tps65913rtc.c
blobf6fed9822b4292e033f9a82cbbfedad22447b434
1 /*
2 * This file is part of the coreboot project.
4 * Copyright 2014 Google Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <bcd.h>
17 #include <console/console.h>
18 #include <device/i2c.h>
19 #include <rtc.h>
20 #include <stdint.h>
22 enum TPS65913_RTC_REG {
23 TPS65913_SECONDS_REG = 0x00,
24 TPS65913_MINUTES_REG = 0x01,
25 TPS65913_HOURS_REG = 0x02,
26 TPS65913_DAYS_REG = 0x03,
27 TPS65913_MONTHS_REG = 0x04,
28 TPS65913_YEARS_REG = 0x05,
29 TPS65913_WEEKS_REG = 0x06,
30 TPS65913_RTC_CTRL_REG = 0x10,
31 TPS65913_RTC_STATUS_REG = 0x11,
32 TPS65913_RTC_INTERRUPS_REG = 0x12,
35 enum {
36 TPS65913_RTC_CTRL_STOP = (1 << 0),
37 TPS65913_RTC_CTRL_GET_TIME = (1 << 6),
39 TPS65913_RTC_STATUS_RUN = (1 << 1),
40 TPS65913_RTC_RUNNING = (1 << 1),
41 TPS65913_RTC_FROZEN = (0 << 1),
44 static inline uint8_t tps65913_read(enum TPS65913_RTC_REG reg)
46 uint8_t val;
47 i2c_readb(CONFIG_DRIVERS_TI_TPS65913_RTC_BUS,
48 CONFIG_DRIVERS_TI_TPS65913_RTC_ADDR, reg, &val);
49 return val;
52 static inline void tps65913_write(enum TPS65913_RTC_REG reg, uint8_t val)
54 i2c_writeb(CONFIG_DRIVERS_TI_TPS65913_RTC_BUS,
55 CONFIG_DRIVERS_TI_TPS65913_RTC_ADDR, reg, val);
58 static void tps65913_rtc_ctrl_clear(uint8_t bit)
60 uint8_t control = tps65913_read(TPS65913_RTC_CTRL_REG);
62 control &= ~bit;
63 tps65913_write(TPS65913_RTC_CTRL_REG, control);
66 static void tps65913_rtc_ctrl_set(uint8_t bit)
68 uint8_t control = tps65913_read(TPS65913_RTC_CTRL_REG);
70 control |= TPS65913_RTC_CTRL_GET_TIME;
71 tps65913_write(TPS65913_RTC_CTRL_REG, control);
74 static int tps65913_is_rtc_running(void)
76 uint8_t status = tps65913_read(TPS65913_RTC_STATUS_REG);
77 return ((status & TPS65913_RTC_STATUS_RUN) == TPS65913_RTC_RUNNING);
81 * This function ensures that current time is copied to shadow registers. Then a
82 * normal read on TC registers reads from the shadow instead of current TC
83 * registers. This helps prevent the accidental change in counters while
84 * reading. In order to ensure that the current TC registers are copied into
85 * shadow registers, GET_TIME bit needs to be set to 0 and then to 1.
87 static void tps65913_rtc_shadow(void)
89 tps65913_rtc_ctrl_clear(TPS65913_RTC_CTRL_GET_TIME);
90 tps65913_rtc_ctrl_set(TPS65913_RTC_CTRL_GET_TIME);
93 static int tps65913_rtc_stop(void)
95 /* Clearing stop bit freezes RTC */
96 tps65913_rtc_ctrl_clear(TPS65913_RTC_CTRL_STOP);
98 if (tps65913_is_rtc_running()) {
99 printk(BIOS_ERR, "Could not stop RTC\n");
100 return 1;
103 return 0;
106 static int tps65913_rtc_start(void)
108 /* Setting stop bit starts RTC */
109 tps65913_rtc_ctrl_set(TPS65913_RTC_CTRL_STOP);
111 if (!tps65913_is_rtc_running()) {
112 printk(BIOS_ERR, "Could not start RTC\n");
113 return 1;
116 return 0;
119 int rtc_set(const struct rtc_time *time)
121 /* Before setting the time, ensure that rtc is stopped */
122 if (tps65913_rtc_stop())
123 return 1;
125 tps65913_write(TPS65913_SECONDS_REG, bin2bcd(time->sec));
126 tps65913_write(TPS65913_MINUTES_REG, bin2bcd(time->min));
127 tps65913_write(TPS65913_HOURS_REG, bin2bcd(time->hour));
128 tps65913_write(TPS65913_DAYS_REG, bin2bcd(time->mday));
129 tps65913_write(TPS65913_MONTHS_REG, bin2bcd(time->mon));
130 tps65913_write(TPS65913_YEARS_REG, bin2bcd(time->year));
132 /* Re-start rtc */
133 if (tps65913_rtc_start())
134 return 1;
136 return 0;
139 int rtc_get(struct rtc_time *time)
141 tps65913_rtc_shadow();
143 time->sec = bcd2bin(tps65913_read(TPS65913_SECONDS_REG) & 0x7f);
144 time->min = bcd2bin(tps65913_read(TPS65913_MINUTES_REG) & 0x7f);
145 time->hour = bcd2bin(tps65913_read(TPS65913_HOURS_REG) & 0x3f);
146 time->mday = bcd2bin(tps65913_read(TPS65913_DAYS_REG) & 0x3f);
147 time->mon = bcd2bin(tps65913_read(TPS65913_MONTHS_REG) & 0x1f);
148 time->year = bcd2bin(tps65913_read(TPS65913_YEARS_REG) & 0xff);
150 return 0;