diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-12 12:46:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-12 12:46:32 -0400 |
commit | f47d633134f7033e3d0c667419d9f8afd69e308d (patch) | |
tree | a5242d86288599fda63ed79b2d131f5a298bb66f /drivers/rtc | |
parent | 004cc08675b761fd82288bab1b5ba5e1ca746eca (diff) | |
parent | 2794449576a6024e203eca5cc2c1a3ae33102b8e (diff) |
Merge tag 'tag-chrome-platform-for-v5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux
Pull chrome platform updates from Benson Leung:
- SPDX identifier cleanup for platform/chrome
- Cleanup series between mfd and chrome/platform, moving cros-ec
attributes from mfd/cros_ec_dev to sub-drivers in platform/chrome
- Wilco EC driver
- Maintainership change to new group repository
* tag 'tag-chrome-platform-for-v5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux:
platform/chrome: fix wilco-ec dependencies
platform/chrome: wilco_ec: Add RTC driver
platform/chrome: wilco_ec: Add support for raw commands in debugfs
platform/chrome: Add new driver for Wilco EC
platform/chrome: cros_ec: Remove cros_ec dependency in lpc_mec
MAINTAINERS: chrome-platform: change the git tree to a chrome-platform group git tree
platform/chrome: cros_ec_sysfs: remove pr_fmt() define
platform/chrome: cros_ec_lightbar: remove pr_fmt() define
platform/chrome: cros_kbd_led_backlight: switch to SPDX identifier
platform/chrome: cros_ec_spi: switch to SPDX identifier
platform/chrome: cros_ec_proto: switch to SPDX identifier
platform/chrome: cros_ec_lpc: switch to SPDX identifier
platform/chrome: cros_ec_i2c: switch to SPDX identifier
platform/chrome: cros_ec_vbc: switch to SPDX identifier
platform/chrome: cros_ec_sysfs: switch to SPDX identifier
platform/chrome: cros_ec_lightbar: switch to SPDX identifier
platform/chrome: cros_ec_debugfs: switch to SPDX identifier
platform/chrome: cromeos_pstore: switch to SPDX identifier
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/Kconfig | 11 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-wilco-ec.c | 177 |
3 files changed, 189 insertions, 0 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index e1a1f2b1cbba..a71734c41693 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -1864,4 +1864,15 @@ config RTC_DRV_GOLDFISH | |||
1864 | Goldfish is a code name for the virtual platform developed by Google | 1864 | Goldfish is a code name for the virtual platform developed by Google |
1865 | for Android emulation. | 1865 | for Android emulation. |
1866 | 1866 | ||
1867 | config RTC_DRV_WILCO_EC | ||
1868 | tristate "Wilco EC RTC" | ||
1869 | depends on WILCO_EC | ||
1870 | default m | ||
1871 | help | ||
1872 | If you say yes here, you get read/write support for the Real Time | ||
1873 | Clock on the Wilco Embedded Controller (Wilco is a kind of Chromebook) | ||
1874 | |||
1875 | This can also be built as a module. If so, the module will | ||
1876 | be named "rtc_wilco_ec". | ||
1877 | |||
1867 | endif # RTC_CLASS | 1878 | endif # RTC_CLASS |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 1bf9f75a7865..fe3962496685 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -177,6 +177,7 @@ obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o | |||
177 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o | 177 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o |
178 | obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o | 178 | obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o |
179 | obj-$(CONFIG_RTC_DRV_VT8500) += rtc-vt8500.o | 179 | obj-$(CONFIG_RTC_DRV_VT8500) += rtc-vt8500.o |
180 | obj-$(CONFIG_RTC_DRV_WILCO_EC) += rtc-wilco-ec.o | ||
180 | obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o | 181 | obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o |
181 | obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o | 182 | obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o |
182 | obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o | 183 | obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o |
diff --git a/drivers/rtc/rtc-wilco-ec.c b/drivers/rtc/rtc-wilco-ec.c new file mode 100644 index 000000000000..e62bda0cb53e --- /dev/null +++ b/drivers/rtc/rtc-wilco-ec.c | |||
@@ -0,0 +1,177 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * RTC interface for Wilco Embedded Controller with R/W abilities | ||
4 | * | ||
5 | * Copyright 2018 Google LLC | ||
6 | * | ||
7 | * The corresponding platform device is typically registered in | ||
8 | * drivers/platform/chrome/wilco_ec/core.c | ||
9 | */ | ||
10 | |||
11 | #include <linux/bcd.h> | ||
12 | #include <linux/err.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/platform_data/wilco-ec.h> | ||
17 | #include <linux/rtc.h> | ||
18 | #include <linux/timekeeping.h> | ||
19 | |||
20 | #define EC_COMMAND_CMOS 0x7c | ||
21 | #define EC_CMOS_TOD_WRITE 0x02 | ||
22 | #define EC_CMOS_TOD_READ 0x08 | ||
23 | |||
24 | /** | ||
25 | * struct ec_rtc_read - Format of RTC returned by EC. | ||
26 | * @second: Second value (0..59) | ||
27 | * @minute: Minute value (0..59) | ||
28 | * @hour: Hour value (0..23) | ||
29 | * @day: Day value (1..31) | ||
30 | * @month: Month value (1..12) | ||
31 | * @year: Year value (full year % 100) | ||
32 | * @century: Century value (full year / 100) | ||
33 | * | ||
34 | * All values are presented in binary (not BCD). | ||
35 | */ | ||
36 | struct ec_rtc_read { | ||
37 | u8 second; | ||
38 | u8 minute; | ||
39 | u8 hour; | ||
40 | u8 day; | ||
41 | u8 month; | ||
42 | u8 year; | ||
43 | u8 century; | ||
44 | } __packed; | ||
45 | |||
46 | /** | ||
47 | * struct ec_rtc_write - Format of RTC sent to the EC. | ||
48 | * @param: EC_CMOS_TOD_WRITE | ||
49 | * @century: Century value (full year / 100) | ||
50 | * @year: Year value (full year % 100) | ||
51 | * @month: Month value (1..12) | ||
52 | * @day: Day value (1..31) | ||
53 | * @hour: Hour value (0..23) | ||
54 | * @minute: Minute value (0..59) | ||
55 | * @second: Second value (0..59) | ||
56 | * @weekday: Day of the week (0=Saturday) | ||
57 | * | ||
58 | * All values are presented in BCD. | ||
59 | */ | ||
60 | struct ec_rtc_write { | ||
61 | u8 param; | ||
62 | u8 century; | ||
63 | u8 year; | ||
64 | u8 month; | ||
65 | u8 day; | ||
66 | u8 hour; | ||
67 | u8 minute; | ||
68 | u8 second; | ||
69 | u8 weekday; | ||
70 | } __packed; | ||
71 | |||
72 | static int wilco_ec_rtc_read(struct device *dev, struct rtc_time *tm) | ||
73 | { | ||
74 | struct wilco_ec_device *ec = dev_get_drvdata(dev->parent); | ||
75 | u8 param = EC_CMOS_TOD_READ; | ||
76 | struct ec_rtc_read rtc; | ||
77 | struct wilco_ec_message msg = { | ||
78 | .type = WILCO_EC_MSG_LEGACY, | ||
79 | .flags = WILCO_EC_FLAG_RAW_RESPONSE, | ||
80 | .command = EC_COMMAND_CMOS, | ||
81 | .request_data = ¶m, | ||
82 | .request_size = sizeof(param), | ||
83 | .response_data = &rtc, | ||
84 | .response_size = sizeof(rtc), | ||
85 | }; | ||
86 | int ret; | ||
87 | |||
88 | ret = wilco_ec_mailbox(ec, &msg); | ||
89 | if (ret < 0) | ||
90 | return ret; | ||
91 | |||
92 | tm->tm_sec = rtc.second; | ||
93 | tm->tm_min = rtc.minute; | ||
94 | tm->tm_hour = rtc.hour; | ||
95 | tm->tm_mday = rtc.day; | ||
96 | tm->tm_mon = rtc.month - 1; | ||
97 | tm->tm_year = rtc.year + (rtc.century * 100) - 1900; | ||
98 | tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); | ||
99 | |||
100 | /* Don't compute day of week, we don't need it. */ | ||
101 | tm->tm_wday = -1; | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static int wilco_ec_rtc_write(struct device *dev, struct rtc_time *tm) | ||
107 | { | ||
108 | struct wilco_ec_device *ec = dev_get_drvdata(dev->parent); | ||
109 | struct ec_rtc_write rtc; | ||
110 | struct wilco_ec_message msg = { | ||
111 | .type = WILCO_EC_MSG_LEGACY, | ||
112 | .flags = WILCO_EC_FLAG_RAW_RESPONSE, | ||
113 | .command = EC_COMMAND_CMOS, | ||
114 | .request_data = &rtc, | ||
115 | .request_size = sizeof(rtc), | ||
116 | }; | ||
117 | int year = tm->tm_year + 1900; | ||
118 | /* | ||
119 | * Convert from 0=Sunday to 0=Saturday for the EC | ||
120 | * We DO need to set weekday because the EC controls battery charging | ||
121 | * schedules that depend on the day of the week. | ||
122 | */ | ||
123 | int wday = tm->tm_wday == 6 ? 0 : tm->tm_wday + 1; | ||
124 | int ret; | ||
125 | |||
126 | rtc.param = EC_CMOS_TOD_WRITE; | ||
127 | rtc.century = bin2bcd(year / 100); | ||
128 | rtc.year = bin2bcd(year % 100); | ||
129 | rtc.month = bin2bcd(tm->tm_mon + 1); | ||
130 | rtc.day = bin2bcd(tm->tm_mday); | ||
131 | rtc.hour = bin2bcd(tm->tm_hour); | ||
132 | rtc.minute = bin2bcd(tm->tm_min); | ||
133 | rtc.second = bin2bcd(tm->tm_sec); | ||
134 | rtc.weekday = bin2bcd(wday); | ||
135 | |||
136 | ret = wilco_ec_mailbox(ec, &msg); | ||
137 | if (ret < 0) | ||
138 | return ret; | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static const struct rtc_class_ops wilco_ec_rtc_ops = { | ||
144 | .read_time = wilco_ec_rtc_read, | ||
145 | .set_time = wilco_ec_rtc_write, | ||
146 | }; | ||
147 | |||
148 | static int wilco_ec_rtc_probe(struct platform_device *pdev) | ||
149 | { | ||
150 | struct rtc_device *rtc; | ||
151 | |||
152 | rtc = devm_rtc_allocate_device(&pdev->dev); | ||
153 | if (IS_ERR(rtc)) | ||
154 | return PTR_ERR(rtc); | ||
155 | |||
156 | rtc->ops = &wilco_ec_rtc_ops; | ||
157 | /* EC only supports this century */ | ||
158 | rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; | ||
159 | rtc->range_max = RTC_TIMESTAMP_END_2099; | ||
160 | rtc->owner = THIS_MODULE; | ||
161 | |||
162 | return rtc_register_device(rtc); | ||
163 | } | ||
164 | |||
165 | static struct platform_driver wilco_ec_rtc_driver = { | ||
166 | .driver = { | ||
167 | .name = "rtc-wilco-ec", | ||
168 | }, | ||
169 | .probe = wilco_ec_rtc_probe, | ||
170 | }; | ||
171 | |||
172 | module_platform_driver(wilco_ec_rtc_driver); | ||
173 | |||
174 | MODULE_ALIAS("platform:rtc-wilco-ec"); | ||
175 | MODULE_AUTHOR("Nick Crews <ncrews@chromium.org>"); | ||
176 | MODULE_LICENSE("GPL v2"); | ||
177 | MODULE_DESCRIPTION("Wilco EC RTC driver"); | ||