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

mfd: arizona: Add support for WM8998 and WM1814

parent bc00d68f
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -1379,6 +1379,12 @@ config MFD_WM8997
	help
	  Support for Wolfson Microelectronics WM8997 low power audio SoC

config MFD_WM8998
	bool "Wolfson Microelectronics WM8998"
	depends on MFD_ARIZONA
	help
	  Support for Wolfson Microelectronics WM8998 low power audio SoC

config MFD_WM8400
	bool "Wolfson Microelectronics WM8400"
	select MFD_CORE
+3 −0
Original line number Diff line number Diff line
@@ -48,6 +48,9 @@ endif
ifeq ($(CONFIG_MFD_WM8997),y)
obj-$(CONFIG_MFD_ARIZONA)	+= wm8997-tables.o
endif
ifeq ($(CONFIG_MFD_WM8998),y)
obj-$(CONFIG_MFD_ARIZONA)	+= wm8998-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
+97 −8
Original line number Diff line number Diff line
@@ -146,17 +146,31 @@ static irqreturn_t arizona_underclocked(int irq, void *data)
static irqreturn_t arizona_overclocked(int irq, void *data)
{
	struct arizona *arizona = data;
	unsigned int val[2];
	unsigned int val[3];
	int ret;
	
	ret = regmap_bulk_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_6,
			       &val[0], 2);
			       &val[0], 3);
	if (ret != 0) {
		dev_err(arizona->dev, "Failed to read overclock status: %d\n",
			ret);
		return IRQ_NONE;
	}

	switch (arizona->type) {
	case WM8998:
	case WM1814:
		/* Some bits are shifted on WM8998,
		 * rearrange to match the standard bit layout
		 */
		val[0] = ((val[0] & 0x60e0) >> 1) |
			 ((val[0] & 0x1e00) >> 2) |
			 (val[0] & 0x000f);
		break;
	default:
		break;
	}

	if (val[0] & ARIZONA_PWM_OVERCLOCKED_STS)
		dev_err(arizona->dev, "PWM overclocked\n");
	if (val[0] & ARIZONA_FX_CORE_OVERCLOCKED_STS)
@@ -201,6 +215,9 @@ static irqreturn_t arizona_overclocked(int irq, void *data)
	if (val[1] & ARIZONA_ISRC1_OVERCLOCKED_STS)
		dev_err(arizona->dev, "ISRC1 overclocked\n");

	if (val[2] & ARIZONA_SPDIF_OVERCLOCKED_STS)
		dev_err(arizona->dev, "SPDIF overclocked\n");

	return IRQ_HANDLED;
}

@@ -806,6 +823,8 @@ const struct of_device_id arizona_of_match[] = {
	{ .compatible = "wlf,wm5110", .data = (void *)WM5110 },
	{ .compatible = "wlf,wm8280", .data = (void *)WM8280 },
	{ .compatible = "wlf,wm8997", .data = (void *)WM8997 },
	{ .compatible = "wlf,wm8998", .data = (void *)WM8998 },
	{ .compatible = "wlf,wm1814", .data = (void *)WM1814 },
	{},
};
EXPORT_SYMBOL_GPL(arizona_of_match);
@@ -887,11 +906,28 @@ static const struct mfd_cell wm8997_devs[] = {
	},
};

static const struct mfd_cell wm8998_devs[] = {
	{
		.name = "arizona-extcon",
		.parent_supplies = wm5102_supplies,
		.num_parent_supplies = 1, /* We only need MICVDD */
	},
	{ .name = "arizona-gpio" },
	{ .name = "arizona-haptics" },
	{ .name = "arizona-pwm" },
	{
		.name = "wm8998-codec",
		.parent_supplies = wm5102_supplies,
		.num_parent_supplies = ARRAY_SIZE(wm5102_supplies),
	},
	{ .name = "arizona-micsupp" },
};

int arizona_dev_init(struct arizona *arizona)
{
	struct device *dev = arizona->dev;
	const char *type_name;
	unsigned int reg, val;
	unsigned int reg, val, mask;
	int (*apply_patch)(struct arizona *) = NULL;
	int ret, i;

@@ -911,6 +947,8 @@ int arizona_dev_init(struct arizona *arizona)
	case WM5110:
	case WM8280:
	case WM8997:
	case WM8998:
	case WM1814:
		for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++)
			arizona->core_supplies[i].supply
				= wm5102_core_supplies[i];
@@ -992,6 +1030,7 @@ int arizona_dev_init(struct arizona *arizona)
	switch (reg) {
	case 0x5102:
	case 0x5110:
	case 0x6349:
	case 0x8997:
		break;
	default:
@@ -1092,6 +1131,27 @@ int arizona_dev_init(struct arizona *arizona)
		}
		apply_patch = wm8997_patch;
		break;
#endif
#ifdef CONFIG_MFD_WM8998
	case 0x6349:
		switch (arizona->type) {
		case WM8998:
			type_name = "WM8998";
			break;

		case WM1814:
			type_name = "WM1814";
			break;

		default:
			type_name = "WM8998";
			dev_err(arizona->dev, "WM8998 registered as %d\n",
				arizona->type);
			arizona->type = WM8998;
		}

		apply_patch = wm8998_patch;
		break;
#endif
	default:
		dev_err(arizona->dev, "Unknown device ID %x\n", reg);
@@ -1208,14 +1268,38 @@ int arizona_dev_init(struct arizona *arizona)
			<< ARIZONA_IN1_DMIC_SUP_SHIFT;
		if (arizona->pdata.inmode[i] & ARIZONA_INMODE_DMIC)
			val |= 1 << ARIZONA_IN1_MODE_SHIFT;

		switch (arizona->type) {
		case WM8998:
		case WM1814:
			regmap_update_bits(arizona->regmap,
				ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 8),
				ARIZONA_IN1L_SRC_SE_MASK,
				(arizona->pdata.inmode[i] & ARIZONA_INMODE_SE)
					<< ARIZONA_IN1L_SRC_SE_SHIFT);

			regmap_update_bits(arizona->regmap,
				ARIZONA_ADC_DIGITAL_VOLUME_1R + (i * 8),
				ARIZONA_IN1R_SRC_SE_MASK,
				(arizona->pdata.inmode[i] & ARIZONA_INMODE_SE)
					<< ARIZONA_IN1R_SRC_SE_SHIFT);

			mask = ARIZONA_IN1_DMIC_SUP_MASK |
				ARIZONA_IN1_MODE_MASK;
			break;
		default:
			if (arizona->pdata.inmode[i] & ARIZONA_INMODE_SE)
				val |= 1 << ARIZONA_IN1_SINGLE_ENDED_SHIFT;

			mask = ARIZONA_IN1_DMIC_SUP_MASK |
				ARIZONA_IN1_MODE_MASK |
				ARIZONA_IN1_SINGLE_ENDED_MASK;
			break;
		}

		regmap_update_bits(arizona->regmap,
				   ARIZONA_IN1L_CONTROL + (i * 8),
				   ARIZONA_IN1_DMIC_SUP_MASK |
				   ARIZONA_IN1_MODE_MASK |
				   ARIZONA_IN1_SINGLE_ENDED_MASK, val);
				   mask, val);
	}

	for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) {
@@ -1271,6 +1355,11 @@ int arizona_dev_init(struct arizona *arizona)
		ret = mfd_add_devices(arizona->dev, -1, wm8997_devs,
				      ARRAY_SIZE(wm8997_devs), NULL, 0, NULL);
		break;
	case WM8998:
	case WM1814:
		ret = mfd_add_devices(arizona->dev, -1, wm8998_devs,
				      ARRAY_SIZE(wm8998_devs), NULL, 0, NULL);
		break;
	}

	if (ret != 0) {
+8 −0
Original line number Diff line number Diff line
@@ -52,6 +52,12 @@ static int arizona_i2c_probe(struct i2c_client *i2c,
	case WM8997:
		regmap_config = &wm8997_i2c_regmap;
		break;
#endif
#ifdef CONFIG_MFD_WM8998
	case WM8998:
	case WM1814:
		regmap_config = &wm8998_i2c_regmap;
		break;
#endif
	default:
		dev_err(&i2c->dev, "Unknown device type %ld\n",
@@ -90,6 +96,8 @@ static const struct i2c_device_id arizona_i2c_id[] = {
	{ "wm5110", WM5110 },
	{ "wm8280", WM8280 },
	{ "wm8997", WM8997 },
	{ "wm8998", WM8998 },
	{ "wm1814", WM1814 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, arizona_i2c_id);
+9 −0
Original line number Diff line number Diff line
@@ -234,6 +234,15 @@ int arizona_irq_init(struct arizona *arizona)
		arizona->ctrlif_error = false;
		break;
#endif
#ifdef CONFIG_MFD_WM8998
	case WM8998:
	case WM1814:
		aod = &wm8998_aod;
		irq = &wm8998_irq;

		arizona->ctrlif_error = false;
		break;
#endif
	default:
		BUG_ON("Unknown Arizona class device" == NULL);
		return -EINVAL;
Loading