hc
2023-12-11 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4
kernel/drivers/rtc/rtc-rx8581.c
....@@ -1,12 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * An I2C driver for the Epson RX8581 RTC
34 *
45 * Author: Martyn Welch <martyn.welch@ge.com>
56 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License version 2 as
9
- * published by the Free Software Foundation.
107 *
118 * Based on: rtc-pcf8563.c (An I2C driver for the Philips PCF8563 RTC)
129 * Copyright 2005-06 Tower Technologies
....@@ -15,6 +12,8 @@
1512 #include <linux/module.h>
1613 #include <linux/i2c.h>
1714 #include <linux/bcd.h>
15
+#include <linux/of.h>
16
+#include <linux/of_device.h>
1817 #include <linux/regmap.h>
1918 #include <linux/rtc.h>
2019 #include <linux/log2.h>
....@@ -51,9 +50,17 @@
5150 #define RX8581_CTRL_STOP 0x02 /* STOP bit */
5251 #define RX8581_CTRL_RESET 0x01 /* RESET bit */
5352
53
+#define RX8571_USER_RAM 0x10
54
+#define RX8571_NVRAM_SIZE 0x10
55
+
5456 struct rx8581 {
5557 struct regmap *regmap;
5658 struct rtc_device *rtc;
59
+};
60
+
61
+struct rx85x1_config {
62
+ struct regmap_config regmap;
63
+ unsigned int num_nvram;
5764 };
5865
5966 /*
....@@ -181,17 +188,95 @@
181188 .set_time = rx8581_rtc_set_time,
182189 };
183190
184
-static int rx8581_probe(struct i2c_client *client,
185
- const struct i2c_device_id *id)
191
+static int rx8571_nvram_read(void *priv, unsigned int offset, void *val,
192
+ size_t bytes)
186193 {
187
- struct rx8581 *rx8581;
188
- static const struct regmap_config config = {
194
+ struct rx8581 *rx8581 = priv;
195
+
196
+ return regmap_bulk_read(rx8581->regmap, RX8571_USER_RAM + offset,
197
+ val, bytes);
198
+}
199
+
200
+static int rx8571_nvram_write(void *priv, unsigned int offset, void *val,
201
+ size_t bytes)
202
+{
203
+ struct rx8581 *rx8581 = priv;
204
+
205
+ return regmap_bulk_write(rx8581->regmap, RX8571_USER_RAM + offset,
206
+ val, bytes);
207
+}
208
+
209
+static int rx85x1_nvram_read(void *priv, unsigned int offset, void *val,
210
+ size_t bytes)
211
+{
212
+ struct rx8581 *rx8581 = priv;
213
+ unsigned int tmp_val;
214
+ int ret;
215
+
216
+ ret = regmap_read(rx8581->regmap, RX8581_REG_RAM, &tmp_val);
217
+ (*(unsigned char *)val) = (unsigned char) tmp_val;
218
+
219
+ return ret;
220
+}
221
+
222
+static int rx85x1_nvram_write(void *priv, unsigned int offset, void *val,
223
+ size_t bytes)
224
+{
225
+ struct rx8581 *rx8581 = priv;
226
+ unsigned char tmp_val;
227
+
228
+ tmp_val = *((unsigned char *)val);
229
+ return regmap_write(rx8581->regmap, RX8581_REG_RAM,
230
+ (unsigned int)tmp_val);
231
+}
232
+
233
+static const struct rx85x1_config rx8581_config = {
234
+ .regmap = {
189235 .reg_bits = 8,
190236 .val_bits = 8,
191237 .max_register = 0xf,
238
+ },
239
+ .num_nvram = 1
240
+};
241
+
242
+static const struct rx85x1_config rx8571_config = {
243
+ .regmap = {
244
+ .reg_bits = 8,
245
+ .val_bits = 8,
246
+ .max_register = 0x1f,
247
+ },
248
+ .num_nvram = 2
249
+};
250
+
251
+static int rx8581_probe(struct i2c_client *client,
252
+ const struct i2c_device_id *id)
253
+{
254
+ struct rx8581 *rx8581;
255
+ const struct rx85x1_config *config = &rx8581_config;
256
+ const void *data = of_device_get_match_data(&client->dev);
257
+ static struct nvmem_config nvmem_cfg[] = {
258
+ {
259
+ .name = "rx85x1-",
260
+ .word_size = 1,
261
+ .stride = 1,
262
+ .size = 1,
263
+ .reg_read = rx85x1_nvram_read,
264
+ .reg_write = rx85x1_nvram_write,
265
+ }, {
266
+ .name = "rx8571-",
267
+ .word_size = 1,
268
+ .stride = 1,
269
+ .size = RX8571_NVRAM_SIZE,
270
+ .reg_read = rx8571_nvram_read,
271
+ .reg_write = rx8571_nvram_write,
272
+ },
192273 };
274
+ int ret, i;
193275
194276 dev_dbg(&client->dev, "%s\n", __func__);
277
+
278
+ if (data)
279
+ config = data;
195280
196281 rx8581 = devm_kzalloc(&client->dev, sizeof(struct rx8581), GFP_KERNEL);
197282 if (!rx8581)
....@@ -199,7 +284,7 @@
199284
200285 i2c_set_clientdata(client, rx8581);
201286
202
- rx8581->regmap = devm_regmap_init_i2c(client, &config);
287
+ rx8581->regmap = devm_regmap_init_i2c(client, &config->regmap);
203288 if (IS_ERR(rx8581->regmap))
204289 return PTR_ERR(rx8581->regmap);
205290
....@@ -213,7 +298,14 @@
213298 rx8581->rtc->start_secs = 0;
214299 rx8581->rtc->set_start_time = true;
215300
216
- return rtc_register_device(rx8581->rtc);
301
+ ret = rtc_register_device(rx8581->rtc);
302
+
303
+ for (i = 0; i < config->num_nvram; i++) {
304
+ nvmem_cfg[i].priv = rx8581;
305
+ rtc_nvmem_register(rx8581->rtc, &nvmem_cfg[i]);
306
+ }
307
+
308
+ return ret;
217309 }
218310
219311 static const struct i2c_device_id rx8581_id[] = {
....@@ -223,8 +315,9 @@
223315 MODULE_DEVICE_TABLE(i2c, rx8581_id);
224316
225317 static const struct of_device_id rx8581_of_match[] = {
226
- { .compatible = "epson,rx8581" },
227
- { }
318
+ { .compatible = "epson,rx8571", .data = &rx8571_config },
319
+ { .compatible = "epson,rx8581", .data = &rx8581_config },
320
+ { /* sentinel */ }
228321 };
229322 MODULE_DEVICE_TABLE(of, rx8581_of_match);
230323
....@@ -240,5 +333,5 @@
240333 module_i2c_driver(rx8581_driver);
241334
242335 MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>");
243
-MODULE_DESCRIPTION("Epson RX-8581 RTC driver");
336
+MODULE_DESCRIPTION("Epson RX-8571/RX-8581 RTC driver");
244337 MODULE_LICENSE("GPL");