1 // SPDX-License-Identifier: GPL-2.0-only OR MIT
2 /*
3 * Apple SPMI NVMEM driver
4 *
5 * Copyright The Asahi Linux Contributors
6 */
7
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/nvmem-provider.h>
11 #include <linux/of.h>
12 #include <linux/spmi.h>
13 #include <linux/regmap.h>
14
15 static const struct regmap_config apple_spmi_regmap_config = {
16 .reg_bits = 16,
17 .val_bits = 8,
18 .max_register = 0xffff,
19 };
20
apple_spmi_nvmem_probe(struct spmi_device * sdev)21 static int apple_spmi_nvmem_probe(struct spmi_device *sdev)
22 {
23 struct regmap *regmap;
24 struct nvmem_config nvmem_cfg = {
25 .dev = &sdev->dev,
26 .name = "spmi_nvmem",
27 .id = NVMEM_DEVID_AUTO,
28 .word_size = 1,
29 .stride = 1,
30 .size = 0xffff,
31 .reg_read = (void *)regmap_bulk_read,
32 .reg_write = (void *)regmap_bulk_write,
33 };
34
35 regmap = devm_regmap_init_spmi_ext(sdev, &apple_spmi_regmap_config);
36 if (IS_ERR(regmap))
37 return PTR_ERR(regmap);
38
39 nvmem_cfg.priv = regmap;
40
41 return PTR_ERR_OR_ZERO(devm_nvmem_register(&sdev->dev, &nvmem_cfg));
42 }
43
44 static const struct of_device_id apple_spmi_nvmem_id_table[] = {
45 { .compatible = "apple,spmi-nvmem" },
46 { },
47 };
48 MODULE_DEVICE_TABLE(of, apple_spmi_nvmem_id_table);
49
50 static struct spmi_driver apple_spmi_nvmem_driver = {
51 .probe = apple_spmi_nvmem_probe,
52 .driver = {
53 .name = "apple-spmi-nvmem",
54 .of_match_table = apple_spmi_nvmem_id_table,
55 },
56 };
57
58 module_spmi_driver(apple_spmi_nvmem_driver);
59
60 MODULE_LICENSE("Dual MIT/GPL");
61 MODULE_AUTHOR("Hector Martin <marcan@marcan.st>");
62 MODULE_DESCRIPTION("Apple SPMI NVMEM driver");
63