mfd: motorola-cpcap: Diverge configuration per-board

MFD have rigid subdevice structure which does not allow flexible dynamic
subdevice linking. Address this by diverging CPCAP subdevice composition
to take into account board specific configuration.

Create a common and default subdevice composition, rename edit existing
subdevice composition into cpcap_mapphone_devices since it targets mainly
Mapphone board.

Removed st,6556002 as it is no longer applicable to all cases and
duplicates motorola,cpcap, which is used as the default composition.

Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Link: https://patch.msgid.link/20260721095654.429346-6-clamor95@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>
This commit is contained in:
Svyatoslav Ryhel 2026-07-21 12:56:52 +03:00 committed by Lee Jones
parent a695b42656
commit 8b8035cbfb
2 changed files with 70 additions and 61 deletions

View File

@ -11,6 +11,7 @@
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/sysfs.h>
@ -29,6 +30,7 @@ struct cpcap_ddata {
struct regmap_irq_chip_data *irqdata[CPCAP_NR_IRQ_CHIPS];
const struct regmap_config *regmap_conf;
struct regmap *regmap;
enum cpcap_variant variant;
};
static int cpcap_sense_irq(struct regmap *regmap, int irq)
@ -194,20 +196,6 @@ static int cpcap_init_irq(struct cpcap_ddata *cpcap)
return 0;
}
static const struct of_device_id cpcap_of_match[] = {
{ .compatible = "motorola,cpcap", },
{ .compatible = "st,6556002", },
{},
};
MODULE_DEVICE_TABLE(of, cpcap_of_match);
static const struct spi_device_id cpcap_spi_ids[] = {
{ .name = "cpcap" },
{ .name = "6556002" },
{ }
};
MODULE_DEVICE_TABLE(spi, cpcap_spi_ids);
static const struct regmap_config cpcap_regmap_config = {
.reg_bits = 16,
.reg_stride = 4,
@ -240,62 +228,58 @@ static int cpcap_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(cpcap_pm, cpcap_suspend, cpcap_resume);
static const struct mfd_cell cpcap_mfd_devices[] = {
{
.name = "cpcap_adc",
.of_compatible = "motorola,mapphone-cpcap-adc",
}, {
.name = "cpcap_battery",
.of_compatible = "motorola,cpcap-battery",
}, {
.name = "cpcap-charger",
.of_compatible = "motorola,mapphone-cpcap-charger",
}, {
.name = "cpcap-regulator",
.of_compatible = "motorola,mapphone-cpcap-regulator",
}, {
.name = "cpcap-rtc",
.of_compatible = "motorola,cpcap-rtc",
}, {
.name = "cpcap-pwrbutton",
.of_compatible = "motorola,cpcap-pwrbutton",
}, {
.name = "cpcap-usb-phy",
.of_compatible = "motorola,mapphone-cpcap-usb-phy",
}, {
.name = "cpcap-led",
.id = 0,
.of_compatible = "motorola,cpcap-led-red",
}, {
.name = "cpcap-led",
.id = 1,
.of_compatible = "motorola,cpcap-led-green",
}, {
.name = "cpcap-led",
.id = 2,
.of_compatible = "motorola,cpcap-led-blue",
}, {
.name = "cpcap-led",
.id = 3,
.of_compatible = "motorola,cpcap-led-adl",
}, {
.name = "cpcap-led",
.id = 4,
.of_compatible = "motorola,cpcap-led-cp",
}, {
.name = "cpcap-codec",
}
static const struct mfd_cell cpcap_common_devices[] = {
MFD_CELL_OF("cpcap_battery", NULL, NULL, 0, 0, "motorola,cpcap-battery"),
MFD_CELL_OF("cpcap-rtc", NULL, NULL, 0, 0, "motorola,cpcap-rtc"),
MFD_CELL_OF("cpcap-pwrbutton", NULL, NULL, 0, 0, "motorola,cpcap-pwrbutton"),
MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 0, "motorola,cpcap-led-red"),
MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 1, "motorola,cpcap-led-green"),
MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 2, "motorola,cpcap-led-blue"),
MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 3, "motorola,cpcap-led-adl"),
MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 4, "motorola,cpcap-led-cp"),
MFD_CELL_NAME("cpcap-codec"),
};
static const struct mfd_cell cpcap_default_devices[] = {
MFD_CELL_OF("cpcap_adc", NULL, NULL, 0, 0, "motorola,cpcap-adc"),
MFD_CELL_OF("cpcap-regulator", NULL, NULL, 0, 0, "motorola,cpcap-regulator"),
MFD_CELL_OF("cpcap-usb-phy", NULL, NULL, 0, 0, "motorola,cpcap-usb-phy"),
};
static const struct mfd_cell cpcap_mapphone_devices[] = {
MFD_CELL_OF("cpcap_adc", NULL, NULL, 0, 0, "motorola,mapphone-cpcap-adc"),
MFD_CELL_OF("cpcap-charger", NULL, NULL, 0, 0, "motorola,mapphone-cpcap-charger"),
MFD_CELL_OF("cpcap-regulator", NULL, NULL, 0, 0, "motorola,mapphone-cpcap-regulator"),
MFD_CELL_OF("cpcap-usb-phy", NULL, NULL, 0, 0, "motorola,mapphone-cpcap-usb-phy"),
};
static int cpcap_probe(struct spi_device *spi)
{
struct cpcap_ddata *cpcap;
const struct mfd_cell *cells;
unsigned int num_cells;
int ret;
cpcap = devm_kzalloc(&spi->dev, sizeof(*cpcap), GFP_KERNEL);
if (!cpcap)
return -ENOMEM;
cpcap->variant = (enum cpcap_variant)spi_get_device_match_data(spi);
switch (cpcap->variant) {
case CPCAP_DEFAULT:
cells = cpcap_default_devices;
num_cells = ARRAY_SIZE(cpcap_default_devices);
break;
case CPCAP_MAPPHONE:
cells = cpcap_mapphone_devices;
num_cells = ARRAY_SIZE(cpcap_mapphone_devices);
break;
default:
return dev_err_probe(&spi->dev, -ENODEV,
"Unknown device %d\n", cpcap->variant);
}
cpcap->spi = spi;
spi_set_drvdata(spi, cpcap);
@ -330,10 +314,29 @@ static int cpcap_probe(struct spi_device *spi)
spi->dev.coherent_dma_mask = 0;
spi->dev.dma_mask = &spi->dev.coherent_dma_mask;
return devm_mfd_add_devices(&spi->dev, 0, cpcap_mfd_devices,
ARRAY_SIZE(cpcap_mfd_devices), NULL, 0, NULL);
ret = devm_mfd_add_devices(&spi->dev, 0, cpcap_common_devices,
ARRAY_SIZE(cpcap_common_devices), NULL, 0, NULL);
if (ret)
return dev_err_probe(&spi->dev, ret,
"Failed to add common child devices\n");
return devm_mfd_add_devices(&spi->dev, 0, cells, num_cells, NULL, 0, NULL);
}
static const struct of_device_id cpcap_of_match[] = {
{ .compatible = "motorola,cpcap", .data = (void *)CPCAP_DEFAULT },
{ .compatible = "motorola,mapphone-cpcap", .data = (void *)CPCAP_MAPPHONE },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, cpcap_of_match);
static const struct spi_device_id cpcap_spi_ids[] = {
{ .name = "cpcap", .driver_data = CPCAP_DEFAULT },
{ .name = "mapphone-cpcap", .driver_data = CPCAP_MAPPHONE },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(spi, cpcap_spi_ids);
static struct spi_driver cpcap_driver = {
.driver = {
.name = "cpcap-core",

View File

@ -25,6 +25,12 @@
#define CPCAP_REVISION_2_0 0x10
#define CPCAP_REVISION_2_1 0x11
enum cpcap_variant {
CPCAP_DEFAULT = 1,
CPCAP_MAPPHONE,
CPCAP_MAX
};
/* CPCAP registers */
#define CPCAP_REG_INT1 0x0000 /* Interrupt 1 */
#define CPCAP_REG_INT2 0x0004 /* Interrupt 2 */