Skip to content

Commit 06d6bf1

Browse files
committed
Merge branch 'bits/120-spmi' into asahi-wip
2 parents 2d5ed56 + 95888cb commit 06d6bf1

File tree

9 files changed

+424
-0
lines changed

9 files changed

+424
-0
lines changed

drivers/mfd/Kconfig

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,21 @@ config MFD_ACT8945A
5252
linear regulators, along with a complete ActivePath battery
5353
charger.
5454

55+
config MFD_APPLE_SPMI_PMU
56+
tristate "Apple SPMI PMUs"
57+
depends on SPMI
58+
depends on ARCH_APPLE || COMPILE_TEST
59+
default ARCH_APPLE
60+
select MFD_SIMPLE_MFD_SPMI
61+
help
62+
Say yes here to enable support for Apple PMUs attached via the
63+
SPMI bus. These can be found on Apple devices such as Apple
64+
Silicon Macs.
65+
66+
This driver itself only attaches to the core device, and relies
67+
on subsystem drivers for individual device functions. You must
68+
enable those for it to be useful.
69+
5570
config MFD_SUN4I_GPADC
5671
tristate "Allwinner sunxi platforms' GPADC MFD driver"
5772
select MFD_CORE
@@ -1312,6 +1327,19 @@ config MFD_SIMPLE_MFD_I2C
13121327
sub-devices represented by child nodes in Device Tree will be
13131328
subsequently registered.
13141329

1330+
config MFD_SIMPLE_MFD_SPMI
1331+
tristate
1332+
depends on SPMI
1333+
select MFD_CORE
1334+
select REGMAP_SPMI
1335+
help
1336+
This driver creates a single register map with the intention for it
1337+
to be shared by all sub-devices.
1338+
1339+
Once the register map has been successfully initialised, any
1340+
sub-devices represented by child nodes in Device Tree will be
1341+
subsequently registered.
1342+
13151343
config MFD_SL28CPLD
13161344
tristate "Kontron sl28cpld Board Management Controller"
13171345
depends on I2C

drivers/mfd/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ obj-$(CONFIG_MFD_QCOM_PM8008) += qcom-pm8008.o
271271

272272
obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o
273273
obj-$(CONFIG_MFD_SIMPLE_MFD_I2C) += simple-mfd-i2c.o
274+
obj-$(CONFIG_MFD_SIMPLE_MFD_SPMI) += simple-mfd-spmi.o
274275
obj-$(CONFIG_MFD_SMPRO) += smpro-core.o
275276

276277
obj-$(CONFIG_MFD_INTEL_M10_BMC_CORE) += intel-m10-bmc-core.o

drivers/mfd/simple-mfd-spmi.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// SPDX-License-Identifier: GPL-2.0-only OR MIT
2+
/*
3+
* Simple MFD - SPMI
4+
*
5+
* Copyright The Asahi Linux Contributors
6+
*/
7+
8+
#include <linux/kernel.h>
9+
#include <linux/module.h>
10+
#include <linux/regmap.h>
11+
#include <linux/spmi.h>
12+
#include <linux/of_platform.h>
13+
14+
static const struct regmap_config spmi_regmap_config = {
15+
.reg_bits = 16,
16+
.val_bits = 8,
17+
.max_register = 0xffff,
18+
};
19+
20+
static int simple_spmi_probe(struct spmi_device *sdev)
21+
{
22+
struct regmap *regmap;
23+
24+
regmap = devm_regmap_init_spmi_ext(sdev, &spmi_regmap_config);
25+
if (IS_ERR(regmap))
26+
return PTR_ERR(regmap);
27+
28+
return devm_of_platform_populate(&sdev->dev);
29+
}
30+
31+
static const struct of_device_id simple_spmi_id_table[] = {
32+
{ .compatible = "apple,spmi-pmu" },
33+
{}
34+
};
35+
MODULE_DEVICE_TABLE(of, simple_spmi_id_table);
36+
37+
static struct spmi_driver pmic_spmi_driver = {
38+
.probe = simple_spmi_probe,
39+
.driver = {
40+
.name = "simple-mfd-spmi",
41+
.owner = THIS_MODULE,
42+
.of_match_table = simple_spmi_id_table,
43+
},
44+
};
45+
module_spmi_driver(pmic_spmi_driver);
46+
47+
MODULE_LICENSE("Dual MIT/GPL");
48+
MODULE_DESCRIPTION("Simple MFD - SPMI driver");
49+
MODULE_AUTHOR("Hector Martin <[email protected]>");

drivers/nvmem/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,19 @@ config NVMEM_SNVS_LPGPR
299299
This driver can also be built as a module. If so, the module
300300
will be called nvmem-snvs-lpgpr.
301301

302+
config NVMEM_SPMI_MFD
303+
tristate "Generic SPMI MFD NVMEM"
304+
depends on MFD_SIMPLE_MFD_SPMI || COMPILE_TEST
305+
default ARCH_APPLE
306+
help
307+
Say y here to build a generic driver to expose an SPMI MFD device
308+
as a NVMEM provider. This can be used for PMIC/PMU devices which
309+
are used to store power and RTC-related settings on certain
310+
platforms, such as Apple Silicon Macs.
311+
312+
This driver can also be built as a module. If so, the module
313+
will be called nvmem-spmi-mfd.
314+
302315
config NVMEM_SPMI_SDAM
303316
tristate "SPMI SDAM Support"
304317
depends on SPMI

drivers/nvmem/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ obj-$(CONFIG_NVMEM_SC27XX_EFUSE) += nvmem-sc27xx-efuse.o
6262
nvmem-sc27xx-efuse-y := sc27xx-efuse.o
6363
obj-$(CONFIG_NVMEM_SNVS_LPGPR) += nvmem_snvs_lpgpr.o
6464
nvmem_snvs_lpgpr-y := snvs_lpgpr.o
65+
obj-$(CONFIG_NVMEM_SPMI_MFD) += nvmem_spmi_mfd.o
66+
nvmem_spmi_mfd-y := spmi-mfd-nvmem.o
6567
obj-$(CONFIG_NVMEM_SPMI_SDAM) += nvmem_qcom-spmi-sdam.o
6668
nvmem_qcom-spmi-sdam-y += qcom-spmi-sdam.o
6769
obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem_sprd_efuse.o

drivers/nvmem/spmi-mfd-nvmem.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// SPDX-License-Identifier: GPL-2.0-only OR MIT
2+
/*
3+
* Generic SPMI MFD 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/platform_device.h>
13+
#include <linux/regmap.h>
14+
15+
struct spmi_mfd_nvmem {
16+
struct regmap *regmap;
17+
unsigned int base;
18+
};
19+
20+
static int spmi_mfd_nvmem_read(void *priv, unsigned int offset,
21+
void *val, size_t bytes)
22+
{
23+
struct spmi_mfd_nvmem *nvmem = priv;
24+
25+
return regmap_bulk_read(nvmem->regmap, nvmem->base + offset, val, bytes);
26+
}
27+
28+
static int spmi_mfd_nvmem_write(void *priv, unsigned int offset,
29+
void *val, size_t bytes)
30+
{
31+
struct spmi_mfd_nvmem *nvmem = priv;
32+
33+
return regmap_bulk_write(nvmem->regmap, nvmem->base + offset, val, bytes);
34+
}
35+
36+
static int spmi_mfd_nvmem_probe(struct platform_device *pdev)
37+
{
38+
struct spmi_mfd_nvmem *nvmem;
39+
const __be32 *addr;
40+
int len;
41+
struct nvmem_config nvmem_cfg = {
42+
.dev = &pdev->dev,
43+
.name = "spmi_mfd_nvmem",
44+
.id = NVMEM_DEVID_AUTO,
45+
.word_size = 1,
46+
.stride = 1,
47+
.reg_read = spmi_mfd_nvmem_read,
48+
.reg_write = spmi_mfd_nvmem_write,
49+
.add_legacy_fixed_of_cells = true,
50+
};
51+
52+
nvmem = devm_kzalloc(&pdev->dev, sizeof(*nvmem), GFP_KERNEL);
53+
if (!nvmem)
54+
return -ENOMEM;
55+
56+
nvmem_cfg.priv = nvmem;
57+
58+
nvmem->regmap = dev_get_regmap(pdev->dev.parent, NULL);
59+
if (!nvmem->regmap) {
60+
dev_err(&pdev->dev, "Parent regmap unavailable.\n");
61+
return -ENXIO;
62+
}
63+
64+
addr = of_get_property(pdev->dev.of_node, "reg", &len);
65+
if (!addr) {
66+
dev_err(&pdev->dev, "no reg property\n");
67+
return -EINVAL;
68+
}
69+
if (len != 2 * sizeof(u32)) {
70+
dev_err(&pdev->dev, "invalid reg property\n");
71+
return -EINVAL;
72+
}
73+
74+
nvmem->base = be32_to_cpup(&addr[0]);
75+
nvmem_cfg.size = be32_to_cpup(&addr[1]);
76+
77+
return PTR_ERR_OR_ZERO(devm_nvmem_register(&pdev->dev, &nvmem_cfg));
78+
}
79+
80+
static const struct of_device_id spmi_mfd_nvmem_id_table[] = {
81+
{ .compatible = "apple,spmi-pmu-nvmem" },
82+
{ .compatible = "spmi-mfd-nvmem" },
83+
{ },
84+
};
85+
MODULE_DEVICE_TABLE(of, spmi_mfd_nvmem_id_table);
86+
87+
static struct platform_driver spmi_mfd_nvmem_driver = {
88+
.probe = spmi_mfd_nvmem_probe,
89+
.driver = {
90+
.name = "spmi-mfd-nvmem",
91+
.of_match_table = spmi_mfd_nvmem_id_table,
92+
},
93+
};
94+
95+
module_platform_driver(spmi_mfd_nvmem_driver);
96+
97+
MODULE_LICENSE("Dual MIT/GPL");
98+
MODULE_AUTHOR("Hector Martin <[email protected]>");
99+
MODULE_DESCRIPTION("SPMI MFD NVMEM driver");

drivers/spmi/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,12 @@ config SPMI_MTK_PMIF
4545
This is required for communicating with Mediatek PMICs and
4646
other devices that have the SPMI interface.
4747

48+
config SPMI_APPLE
49+
tristate "Apple SoC SPMI Controller platform driver"
50+
depends on ARCH_APPLE || COMPILE_TEST
51+
help
52+
This enables basic support for the SPMI controller present on
53+
many Apple SoCs, including the t8103 (M1) and t600x
54+
(M1 Pro/Max).
55+
4856
endif

drivers/spmi/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ obj-$(CONFIG_SPMI) += spmi.o spmi-devres.o
77
obj-$(CONFIG_SPMI_HISI3670) += hisi-spmi-controller.o
88
obj-$(CONFIG_SPMI_MSM_PMIC_ARB) += spmi-pmic-arb.o
99
obj-$(CONFIG_SPMI_MTK_PMIF) += spmi-mtk-pmif.o
10+
obj-$(CONFIG_SPMI_APPLE) += spmi-apple-controller.o

0 commit comments

Comments
 (0)