Commit 8f3a8428c96cb8424afea68f86df83a4e07d63ff
Committed by
Simon Glass
1 parent
13f3fcac53
Exists in
v2017.01-smarct4x
and in
25 other branches
rtc: Add RTC chip pcf2127 support
This driver compatible with pcf2127 and pcf2129 Signed-off-by: Meng Yi <meng.yi@nxp.com> Reviewed-by: Simon Glass <sjg@chromium.org>
Showing 3 changed files with 114 additions and 0 deletions Side-by-side Diff
drivers/rtc/Kconfig
... | ... | @@ -13,5 +13,11 @@ |
13 | 13 | drivers to perform the actual functions. See rtc.h for a |
14 | 14 | description of the API. |
15 | 15 | |
16 | +config RTC_PCF2127 | |
17 | + bool "Enable PCF2127 driver" | |
18 | + depends on DM_RTC | |
19 | + help | |
20 | + Enable pcf2127 driver which provides rtc get and set function | |
21 | + | |
16 | 22 | endmenu |
drivers/rtc/Makefile
... | ... | @@ -45,6 +45,7 @@ |
45 | 45 | obj-$(CONFIG_RTC_MX27) += mx27rtc.o |
46 | 46 | obj-$(CONFIG_RTC_MXS) += mxsrtc.o |
47 | 47 | obj-$(CONFIG_RTC_PCF8563) += pcf8563.o |
48 | +obj-$(CONFIG_RTC_PCF2127) += pcf2127.o | |
48 | 49 | obj-$(CONFIG_RTC_PL031) += pl031.o |
49 | 50 | obj-$(CONFIG_RTC_PT7C4338) += pt7c4338.o |
50 | 51 | obj-$(CONFIG_RTC_RS5C372A) += rs5c372.o |
drivers/rtc/pcf2127.c
1 | +/* | |
2 | + * Copyright (C) 2016 by NXP Semiconductors Inc. | |
3 | + * Date & Time support for PCF2127 RTC | |
4 | + */ | |
5 | + | |
6 | +/* #define DEBUG */ | |
7 | + | |
8 | +#include <common.h> | |
9 | +#include <command.h> | |
10 | +#include <dm.h> | |
11 | +#include <i2c.h> | |
12 | +#include <rtc.h> | |
13 | + | |
14 | +#define PCF2127_REG_CTRL1 (0x00) | |
15 | +#define PCF2127_REG_CTRL2 (0x01) | |
16 | +#define PCF2127_REG_CTRL3 (0x02) | |
17 | +#define PCF2127_REG_SC (0x03) /* datetime */ | |
18 | +#define PCF2127_REG_MN (0x04) | |
19 | +#define PCF2127_REG_HR (0x05) | |
20 | +#define PCF2127_REG_DM (0x06) | |
21 | +#define PCF2127_REG_DW (0x07) | |
22 | +#define PCF2127_REG_MO (0x08) | |
23 | +#define PCF2127_REG_YR (0x09) | |
24 | + | |
25 | +static int pcf2127_rtc_set(struct udevice *dev, const struct rtc_time *tm) | |
26 | +{ | |
27 | + uchar buf[8]; | |
28 | + int i = 0; | |
29 | + | |
30 | + /* start register address */ | |
31 | + buf[i++] = PCF2127_REG_SC; | |
32 | + | |
33 | + /* hours, minutes and seconds */ | |
34 | + buf[i++] = bin2bcd(tm->tm_sec); | |
35 | + buf[i++] = bin2bcd(tm->tm_min); | |
36 | + buf[i++] = bin2bcd(tm->tm_hour); | |
37 | + buf[i++] = bin2bcd(tm->tm_mday); | |
38 | + buf[i++] = tm->tm_wday & 0x07; | |
39 | + | |
40 | + /* month, 1 - 12 */ | |
41 | + buf[i++] = bin2bcd(tm->tm_mon + 1); | |
42 | + | |
43 | + /* year */ | |
44 | + buf[i++] = bin2bcd(tm->tm_year % 100); | |
45 | + | |
46 | + /* write register's data */ | |
47 | + if (dm_i2c_write(dev, PCF2127_REG_CTRL1, buf, sizeof(buf)) < 0) | |
48 | + return -1; | |
49 | + | |
50 | + return 0; | |
51 | +} | |
52 | + | |
53 | +static int pcf2127_rtc_get(struct udevice *dev, struct rtc_time *tm) | |
54 | +{ | |
55 | + int rel = 0; | |
56 | + uchar buf[10] = { PCF2127_REG_CTRL1 }; | |
57 | + | |
58 | + if (dm_i2c_write(dev, PCF2127_REG_CTRL1, buf, 1) < 0) | |
59 | + return -1; | |
60 | + if (dm_i2c_read(dev, PCF2127_REG_CTRL1, buf, sizeof(buf)) < 0) | |
61 | + return -1; | |
62 | + | |
63 | + if (buf[PCF2127_REG_CTRL3] & 0x04) | |
64 | + puts("### Warning: RTC Low Voltage - date/time not reliable\n"); | |
65 | + | |
66 | + tm->tm_sec = bcd2bin(buf[PCF2127_REG_SC] & 0x7F); | |
67 | + tm->tm_min = bcd2bin(buf[PCF2127_REG_MN] & 0x7F); | |
68 | + tm->tm_hour = bcd2bin(buf[PCF2127_REG_HR] & 0x3F); | |
69 | + tm->tm_mday = bcd2bin(buf[PCF2127_REG_DM] & 0x3F); | |
70 | + tm->tm_mon = bcd2bin(buf[PCF2127_REG_MO] & 0x1F) - 1; | |
71 | + tm->tm_year = bcd2bin(buf[PCF2127_REG_YR]) + 1900; | |
72 | + if (tm->tm_year < 1970) | |
73 | + tm->tm_year += 100; /* assume we are in 1970...2069 */ | |
74 | + tm->tm_wday = buf[PCF2127_REG_DW] & 0x07; | |
75 | + tm->tm_yday = 0; | |
76 | + tm->tm_isdst = 0; | |
77 | + | |
78 | + debug("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", | |
79 | + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, | |
80 | + tm->tm_hour, tm->tm_min, tm->tm_sec); | |
81 | + | |
82 | + return rel; | |
83 | +} | |
84 | + | |
85 | +static int pcf2127_rtc_reset(struct udevice *dev) | |
86 | +{ | |
87 | + /*Doing nothing here*/ | |
88 | + return 0; | |
89 | +} | |
90 | + | |
91 | +static const struct rtc_ops pcf2127_rtc_ops = { | |
92 | + .get = pcf2127_rtc_get, | |
93 | + .set = pcf2127_rtc_set, | |
94 | + .reset = pcf2127_rtc_reset, | |
95 | +}; | |
96 | + | |
97 | +static const struct udevice_id pcf2127_rtc_ids[] = { | |
98 | + { .compatible = "pcf2127-rtc" }, | |
99 | + { } | |
100 | +}; | |
101 | + | |
102 | +U_BOOT_DRIVER(rtc_pcf2127) = { | |
103 | + .name = "rtc-pcf2127", | |
104 | + .id = UCLASS_RTC, | |
105 | + .of_match = pcf2127_rtc_ids, | |
106 | + .ops = &pcf2127_rtc_ops, | |
107 | +}; |