xref: /linux/drivers/rtc/rtc-raspberrypi.c (revision 4dd10fbbeb9c33709edc89916e19c03c780a0751)
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /**
3  * rtc-raspberrypi.c
4  *
5  * RTC driver using firmware mailbox
6  * Supports battery backed RTC and wake alarms
7  *
8  * Based on rtc-meson-vrtc by Neil Armstrong
9  *
10  * Copyright (c) 2023, Raspberry Pi Ltd.
11  */
12 
13 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/rtc.h>
16 #include <linux/of.h>
17 #include <soc/bcm2835/raspberrypi-firmware.h>
18 
19 #define	RTC_TIME		0
20 #define	RTC_ALARM		1
21 #define	RTC_ALARM_PENDING	2
22 #define	RTC_ALARM_ENABLE	3
23 #define	RTC_BBAT_CHG_VOLTS	4
24 #define	RTC_BBAT_CHG_VOLTS_MIN	5
25 #define	RTC_BBAT_CHG_VOLTS_MAX	6
26 #define	RTC_BBAT_VOLTS		7
27 
28 struct rpi_rtc_data {
29 	struct rtc_device *rtc;
30 	struct rpi_firmware *fw;
31 	u32 bbat_vchg_millivolts;
32 	u32 bbat_vchg_min_millivolts;
33 	u32 bbat_vchg_max_millivolts;
34 };
35 
36 struct rpi_rtc_reg {
37 	__le32 reg;
38 	__le32 val;
39 } __packed;
40 
41 static int rpi_rtc_read_time(struct device *dev, struct rtc_time *tm)
42 {
43 	struct rpi_rtc_data *rtc = dev_get_drvdata(dev);
44 	struct rpi_rtc_reg data = {
45 		.reg = cpu_to_le32(RTC_TIME)
46 	};
47 	int err;
48 
49 	err = rpi_firmware_property(rtc->fw, RPI_FIRMWARE_GET_RTC_REG,
50 				    &data, sizeof(data));
51 	rtc_time64_to_tm(le32_to_cpu(data.val), tm);
52 	return err;
53 }
54 
55 static int rpi_rtc_set_time(struct device *dev, struct rtc_time *tm)
56 {
57 	struct rpi_rtc_data *rtc = dev_get_drvdata(dev);
58 	struct rpi_rtc_reg data = {
59 		.reg = cpu_to_le32(RTC_TIME),
60 		.val = cpu_to_le32(rtc_tm_to_time64(tm))
61 	};
62 
63 	return rpi_firmware_property(rtc->fw, RPI_FIRMWARE_SET_RTC_REG,
64 				     &data, sizeof(data));
65 }
66 
67 static int rpi_rtc_alarm_irq_is_enabled(struct device *dev, unsigned char *enabled)
68 {
69 	struct rpi_rtc_data *rtc = dev_get_drvdata(dev);
70 	struct rpi_rtc_reg data = {
71 		.reg = cpu_to_le32(RTC_ALARM_ENABLE)
72 	};
73 	int err;
74 
75 	err = rpi_firmware_property(rtc->fw, RPI_FIRMWARE_GET_RTC_REG,
76 				    &data, sizeof(data));
77 	*enabled = le32_to_cpu(data.val) & 0x1;
78 	return err;
79 }
80 
81 static int rpi_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
82 {
83 	struct rpi_rtc_data *rtc = dev_get_drvdata(dev);
84 	struct rpi_rtc_reg data = {
85 		.reg = cpu_to_le32(RTC_ALARM_ENABLE),
86 		.val = cpu_to_le32(enabled)
87 	};
88 
89 	return rpi_firmware_property(rtc->fw, RPI_FIRMWARE_SET_RTC_REG,
90 				     &data, sizeof(data));
91 }
92 
93 static int rpi_rtc_alarm_clear_pending(struct device *dev)
94 {
95 	struct rpi_rtc_data *rtc = dev_get_drvdata(dev);
96 	struct rpi_rtc_reg data = {
97 		.reg = cpu_to_le32(RTC_ALARM_PENDING),
98 		.val = cpu_to_le32(1)
99 	};
100 
101 	return rpi_firmware_property(rtc->fw, RPI_FIRMWARE_SET_RTC_REG,
102 				     &data, sizeof(data));
103 }
104 
105 static int rpi_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
106 {
107 	struct rpi_rtc_data *rtc = dev_get_drvdata(dev);
108 	struct rpi_rtc_reg data = {
109 		.reg = cpu_to_le32(RTC_ALARM)
110 	};
111 	int err;
112 
113 	err = rpi_rtc_alarm_irq_is_enabled(dev, &alarm->enabled);
114 	if (!err)
115 		err = rpi_firmware_property(rtc->fw, RPI_FIRMWARE_GET_RTC_REG,
116 					    &data, sizeof(data));
117 	rtc_time64_to_tm(le32_to_cpu(data.val), &alarm->time);
118 
119 	return err;
120 }
121 
122 static int rpi_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
123 {
124 	struct rpi_rtc_data *rtc = dev_get_drvdata(dev);
125 	struct rpi_rtc_reg data = {
126 		.reg = cpu_to_le32(RTC_ALARM),
127 		.val = cpu_to_le32(rtc_tm_to_time64(&alarm->time))
128 	};
129 	int err;
130 
131 	err = rpi_rtc_alarm_clear_pending(dev);
132 
133 	if (!err)
134 		err = rpi_firmware_property(rtc->fw, RPI_FIRMWARE_SET_RTC_REG,
135 					    &data, sizeof(data));
136 
137 	if (!err)
138 		err = rpi_rtc_alarm_irq_enable(dev, alarm->enabled);
139 
140 	return err;
141 }
142 
143 static const struct rtc_class_ops rpi_rtc_ops = {
144 	.read_time = rpi_rtc_read_time,
145 	.set_time = rpi_rtc_set_time,
146 	.read_alarm = rpi_rtc_read_alarm,
147 	.set_alarm = rpi_rtc_set_alarm,
148 	.alarm_irq_enable = rpi_rtc_alarm_irq_enable,
149 };
150 
151 static void rpi_rtc_set_limits(struct device *dev)
152 {
153 	struct rpi_rtc_data *rtc = dev_get_drvdata(dev);
154 	struct rpi_rtc_reg data = {
155 		.reg = cpu_to_le32(RTC_BBAT_CHG_VOLTS_MIN)
156 	};
157 
158 	int err = rpi_firmware_property(rtc->fw, RPI_FIRMWARE_GET_RTC_REG,
159 					&data, sizeof(data));
160 	if (!err)
161 		rtc->bbat_vchg_min_millivolts = le32_to_cpu(data.val) / 1000U;
162 	else
163 		dev_warn(dev, "failed to get minimum trickle charge voltage\n");
164 
165 	data.reg = cpu_to_le32(RTC_BBAT_CHG_VOLTS_MAX);
166 	data.val = cpu_to_le32(0);
167 	err = rpi_firmware_property(rtc->fw, RPI_FIRMWARE_GET_RTC_REG,
168 				    &data, sizeof(data));
169 	if (!err)
170 		rtc->bbat_vchg_max_millivolts = le32_to_cpu(data.val) / 1000U;
171 	else
172 		dev_warn(dev, "failed to get maximum trickle charge voltage\n");
173 }
174 
175 static void rpi_rtc_set_charge_voltage(struct device *dev)
176 {
177 	struct rpi_rtc_data *rtc = dev_get_drvdata(dev);
178 	struct rpi_rtc_reg data = {
179 		.reg = cpu_to_le32(RTC_BBAT_CHG_VOLTS),
180 		.val = cpu_to_le32(rtc->bbat_vchg_millivolts * 1000U)
181 	};
182 	int err;
183 
184 	if (rtc->bbat_vchg_millivolts != 0 &&
185 	    (rtc->bbat_vchg_millivolts < rtc->bbat_vchg_min_millivolts ||
186 	    rtc->bbat_vchg_millivolts > rtc->bbat_vchg_max_millivolts)) {
187 		dev_warn(dev, "trickle charge voltage %umV is outside of the supported range (%umV - %umV)\n",
188 			 rtc->bbat_vchg_millivolts,
189 			 rtc->bbat_vchg_min_millivolts,
190 			 rtc->bbat_vchg_max_millivolts);
191 		return;
192 	}
193 
194 	err = rpi_firmware_property(rtc->fw, RPI_FIRMWARE_SET_RTC_REG,
195 				    &data, sizeof(data));
196 
197 	if (err)
198 		dev_err(dev, "failed to set trickle charge voltage to %umV: %d\n",
199 			rtc->bbat_vchg_millivolts, err);
200 	else if (rtc->bbat_vchg_millivolts)
201 		dev_info(dev, "trickle charging enabled at %umV\n",
202 			 rtc->bbat_vchg_millivolts);
203 }
204 
205 static int rpi_rtc_probe(struct platform_device *pdev)
206 {
207 	struct rpi_rtc_data *rtc;
208 	struct device *dev = &pdev->dev;
209 	struct rpi_firmware *firmware;
210 	int ret;
211 
212 	// Get the firmware device from the parent device
213 	firmware = devm_rpi_firmware_get(dev, dev->parent->of_node);
214 
215 	if (!firmware)
216 		return -EPROBE_DEFER;
217 
218 	rtc = devm_kzalloc_obj(dev, *rtc);
219 	if (!rtc)
220 		return -ENOMEM;
221 
222 	rtc->fw = firmware;
223 
224 	ret = devm_device_init_wakeup(dev);
225 	if (ret)
226 		return ret;
227 
228 	platform_set_drvdata(pdev, rtc);
229 
230 	rtc->rtc = devm_rtc_allocate_device(dev);
231 	if (IS_ERR(rtc->rtc))
232 		return PTR_ERR(rtc->rtc);
233 
234 	rtc->rtc->range_max = U32_MAX;           /* 2106-02-07 */
235 
236 	set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, rtc->rtc->features);
237 	clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtc->features);
238 
239 	rtc->rtc->ops = &rpi_rtc_ops;
240 
241 	rpi_rtc_alarm_clear_pending(dev);
242 
243 	/*
244 	 * The trickle-voltage property lives on the parent firmware node
245 	 * because we deliberately do not create a DT child node just to
246 	 * instantiate this driver (see DT maintainer guidance).
247 	 * The firmware driver registers us as a platform device at runtime.
248 	 */
249 	rtc->bbat_vchg_millivolts = 0;
250 	of_property_read_u32(dev->parent->of_node, "trickle-voltage-millivolt",
251 			     &rtc->bbat_vchg_millivolts);
252 
253 	rpi_rtc_set_limits(dev);
254 	rpi_rtc_set_charge_voltage(dev);
255 
256 	return devm_rtc_register_device(rtc->rtc);
257 }
258 
259 static const struct platform_device_id raspberrypi_rtc_id[] = {
260 	{ "raspberrypi-rtc" },
261 	{ }
262 };
263 MODULE_DEVICE_TABLE(platform, raspberrypi_rtc_id);
264 
265 static struct platform_driver rpi_rtc_driver = {
266 	.driver = {
267 		.name = "raspberrypi-rtc",
268 	},
269 	.id_table = raspberrypi_rtc_id,
270 	.probe = rpi_rtc_probe
271 };
272 
273 module_platform_driver(rpi_rtc_driver);
274 
275 MODULE_AUTHOR("Jonathan Bell <jonathan@raspberrypi.com>");
276 MODULE_AUTHOR("Sander Speetjens <sander.speetjens@gmail.com>");
277 MODULE_DESCRIPTION("Raspberry Pi RTC driver");
278 MODULE_LICENSE("Dual BSD/GPL");
279