Commit ea1f3339 authored by Richard Fitzgerald's avatar Richard Fitzgerald Committed by Lee Jones
Browse files

mfd: arizona: Support Cirrus Logic CS47L24 and WM1831



This patch adds the regmap configuration tables and
core MFD handling for the CS47L24 and WM1831 codecs.

Note that compared to the other Arizona codecs, these devices
do not have an LDO1 or micsupp regulators, extcon driver, or
the DCVDD isolation control.

Signed-off-by: default avatarRichard Fitzgerald <rf@opensource.wolfsonmicro.com>
Signed-off-by: default avatarLee Jones <lee.jones@linaro.org>
parent 9a65a6d3
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -1370,24 +1370,30 @@ config MFD_ARIZONA
	bool

config MFD_ARIZONA_I2C
	tristate "Wolfson Microelectronics Arizona platform with I2C"
	tristate "Cirrus Logic/Wolfson Microelectronics Arizona platform with I2C"
	select MFD_ARIZONA
	select MFD_CORE
	select REGMAP_I2C
	depends on I2C
	help
	  Support for the Wolfson Microelectronics Arizona platform audio SoC
	  core functionality controlled via I2C.
	  Support for the Cirrus Logic/Wolfson Microelectronics Arizona platform
	  audio SoC core functionality controlled via I2C.

config MFD_ARIZONA_SPI
	tristate "Wolfson Microelectronics Arizona platform with SPI"
	tristate "Cirrus Logic/Wolfson Microelectronics Arizona platform with SPI"
	select MFD_ARIZONA
	select MFD_CORE
	select REGMAP_SPI
	depends on SPI_MASTER
	help
	  Support for the Wolfson Microelectronics Arizona platform audio SoC
	  core functionality controlled via I2C.
	  Support for the Cirrus Logic/Wolfson Microelectronics Arizona platform
	  audio SoC core functionality controlled via I2C.

config MFD_CS47L24
	bool "Cirrus Logic CS47L24 and WM1831"
	depends on MFD_ARIZONA
	help
	  Support for Cirrus Logic CS47L24 and WM1831 low power audio SoC

config MFD_WM5102
	bool "Wolfson Microelectronics WM5102"
+3 −0
Original line number Diff line number Diff line
@@ -51,6 +51,9 @@ endif
ifeq ($(CONFIG_MFD_WM8998),y)
obj-$(CONFIG_MFD_ARIZONA)	+= wm8998-tables.o
endif
ifeq ($(CONFIG_MFD_CS47L24),y)
obj-$(CONFIG_MFD_ARIZONA)	+= cs47l24-tables.o
endif
obj-$(CONFIG_MFD_WM8400)	+= wm8400-core.o
wm831x-objs			:= wm831x-core.o wm831x-irq.o wm831x-otp.o
wm831x-objs			+= wm831x-auxadc.o
+68 −6
Original line number Diff line number Diff line
@@ -598,6 +598,12 @@ static int arizona_runtime_resume(struct device *dev)
			goto err;
		}
		break;
	case WM1831:
	case CS47L24:
		ret = arizona_wait_for_boot(arizona);
		if (ret != 0)
			goto err;
		break;
	default:
		ret = arizona_wait_for_boot(arizona);
		if (ret != 0)
@@ -682,6 +688,9 @@ static int arizona_runtime_suspend(struct device *dev)
			}
		}
		break;
	case WM1831:
	case CS47L24:
		break;
	default:
		jd_active = arizona_is_jack_det_active(arizona);
		if (jd_active < 0)
@@ -862,6 +871,8 @@ const struct of_device_id arizona_of_match[] = {
	{ .compatible = "wlf,wm8997", .data = (void *)WM8997 },
	{ .compatible = "wlf,wm8998", .data = (void *)WM8998 },
	{ .compatible = "wlf,wm1814", .data = (void *)WM1814 },
	{ .compatible = "wlf,wm1831", .data = (void *)WM1831 },
	{ .compatible = "cirrus,cs47l24", .data = (void *)CS47L24 },
	{},
};
EXPORT_SYMBOL_GPL(arizona_of_match);
@@ -919,6 +930,23 @@ static const struct mfd_cell wm5110_devs[] = {
	},
};

static const char * const cs47l24_supplies[] = {
	"MICVDD",
	"CPVDD",
	"SPKVDD",
};

static const struct mfd_cell cs47l24_devs[] = {
	{ .name = "arizona-gpio" },
	{ .name = "arizona-haptics" },
	{ .name = "arizona-pwm" },
	{
		.name = "cs47l24-codec",
		.parent_supplies = cs47l24_supplies,
		.num_parent_supplies = ARRAY_SIZE(cs47l24_supplies),
	},
};

static const char * const wm8997_supplies[] = {
	"MICVDD",
	"DBVDD2",
@@ -963,7 +991,7 @@ static const struct mfd_cell wm8998_devs[] = {
int arizona_dev_init(struct arizona *arizona)
{
	struct device *dev = arizona->dev;
	const char *type_name;
	const char *type_name = NULL;
	unsigned int reg, val, mask;
	int (*apply_patch)(struct arizona *) = NULL;
	const struct mfd_cell *subdevs = NULL;
@@ -987,6 +1015,8 @@ int arizona_dev_init(struct arizona *arizona)
	case WM8997:
	case WM8998:
	case WM1814:
	case WM1831:
	case CS47L24:
		for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++)
			arizona->core_supplies[i].supply
				= wm5102_core_supplies[i];
@@ -1001,12 +1031,19 @@ int arizona_dev_init(struct arizona *arizona)
	/* Mark DCVDD as external, LDO1 driver will clear if internal */
	arizona->external_dcvdd = true;

	switch (arizona->type) {
	case WM1831:
	case CS47L24:
		break; /* No LDO1 regulator */
	default:
		ret = mfd_add_devices(arizona->dev, -1, early_devs,
				      ARRAY_SIZE(early_devs), NULL, 0, NULL);
		if (ret != 0) {
			dev_err(dev, "Failed to add early children: %d\n", ret);
			return ret;
		}
		break;
	}

	ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies,
				      arizona->core_supplies);
@@ -1069,6 +1106,7 @@ int arizona_dev_init(struct arizona *arizona)
	case 0x5102:
	case 0x5110:
	case 0x6349:
	case 0x6363:
	case 0x8997:
		break;
	default:
@@ -1167,6 +1205,30 @@ int arizona_dev_init(struct arizona *arizona)
			n_subdevs = ARRAY_SIZE(wm5110_devs);
		}
		break;
	case 0x6363:
		if (IS_ENABLED(CONFIG_MFD_CS47L24)) {
			switch (arizona->type) {
			case CS47L24:
				type_name = "CS47L24";
				break;

			case WM1831:
				type_name = "WM1831";
				break;

			default:
				dev_warn(arizona->dev,
					 "CS47L24 registered as %d\n",
					 arizona->type);
				arizona->type = CS47L24;
				break;
			}

			apply_patch = cs47l24_patch;
			subdevs = cs47l24_devs;
			n_subdevs = ARRAY_SIZE(cs47l24_devs);
		}
		break;
	case 0x8997:
		if (IS_ENABLED(CONFIG_MFD_WM8997)) {
			type_name = "WM8997";
+27 −13
Original line number Diff line number Diff line
@@ -30,13 +30,15 @@ static int arizona_map_irq(struct arizona *arizona, int irq)
{
	int ret;

	if (arizona->aod_irq_chip) {
		ret = regmap_irq_get_virq(arizona->aod_irq_chip, irq);
	if (ret < 0)
		ret = regmap_irq_get_virq(arizona->irq_chip, irq);

		if (ret >= 0)
			return ret;
	}

	return regmap_irq_get_virq(arizona->irq_chip, irq);
}

int arizona_request_irq(struct arizona *arizona, int irq, char *name,
			   irq_handler_t handler, void *data)
{
@@ -107,7 +109,7 @@ static irqreturn_t arizona_irq_thread(int irq, void *data)
	do {
		poll = false;

		/* Always handle the AoD domain */
		if (arizona->aod_irq_chip)
			handle_nested_irq(irq_find_mapping(arizona->virq, 0));

		/*
@@ -219,6 +221,15 @@ int arizona_irq_init(struct arizona *arizona)
		arizona->ctrlif_error = false;
		break;
#endif
#ifdef CONFIG_MFD_CS47L24
	case WM1831:
	case CS47L24:
		aod = NULL;
		irq = &cs47l24_irq;

		arizona->ctrlif_error = false;
		break;
#endif
#ifdef CONFIG_MFD_WM8997
	case WM8997:
		aod = &wm8997_aod;
@@ -291,14 +302,17 @@ int arizona_irq_init(struct arizona *arizona)
		goto err;
	}

	if (aod) {
		ret = regmap_add_irq_chip(arizona->regmap,
					  irq_create_mapping(arizona->virq, 0),
					  IRQF_ONESHOT, 0, aod,
					  &arizona->aod_irq_chip);
		if (ret != 0) {
		dev_err(arizona->dev, "Failed to add AOD IRQs: %d\n", ret);
			dev_err(arizona->dev,
				"Failed to add AOD IRQs: %d\n", ret);
			goto err_domain;
		}
	}

	ret = regmap_add_irq_chip(arizona->regmap,
				  irq_create_mapping(arizona->virq, 1),
+7 −0
Original line number Diff line number Diff line
@@ -46,6 +46,11 @@ static int arizona_spi_probe(struct spi_device *spi)
		if (IS_ENABLED(CONFIG_MFD_WM5110))
			regmap_config = &wm5110_spi_regmap;
		break;
	case WM1831:
	case CS47L24:
		if (IS_ENABLED(CONFIG_MFD_CS47L24))
			regmap_config = &cs47l24_spi_regmap;
		break;
	default:
		dev_err(&spi->dev, "Unknown device type %ld\n", type);
		return -EINVAL;
@@ -89,6 +94,8 @@ static const struct spi_device_id arizona_spi_ids[] = {
	{ "wm5102", WM5102 },
	{ "wm5110", WM5110 },
	{ "wm8280", WM8280 },
	{ "wm1831", WM1831 },
	{ "cs47l24", CS47L24 },
	{ },
};
MODULE_DEVICE_TABLE(spi, arizona_spi_ids);
Loading