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: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
This commit is contained in:
Richard Fitzgerald 2015-11-03 15:08:32 +00:00 committed by Lee Jones
parent 9a65a6d3cb
commit ea1f333990
8 changed files with 1753 additions and 25 deletions

View file

@ -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"

View file

@ -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

View file

@ -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,11 +1031,18 @@ int arizona_dev_init(struct arizona *arizona)
/* Mark DCVDD as external, LDO1 driver will clear if internal */
arizona->external_dcvdd = true;
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;
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,
@ -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";

View file

@ -30,11 +30,13 @@ static int arizona_map_irq(struct arizona *arizona, int irq)
{
int ret;
ret = regmap_irq_get_virq(arizona->aod_irq_chip, irq);
if (ret < 0)
ret = regmap_irq_get_virq(arizona->irq_chip, irq);
if (arizona->aod_irq_chip) {
ret = regmap_irq_get_virq(arizona->aod_irq_chip, irq);
if (ret >= 0)
return ret;
}
return ret;
return regmap_irq_get_virq(arizona->irq_chip, irq);
}
int arizona_request_irq(struct arizona *arizona, int irq, char *name,
@ -107,8 +109,8 @@ static irqreturn_t arizona_irq_thread(int irq, void *data)
do {
poll = false;
/* Always handle the AoD domain */
handle_nested_irq(irq_find_mapping(arizona->virq, 0));
if (arizona->aod_irq_chip)
handle_nested_irq(irq_find_mapping(arizona->virq, 0));
/*
* Check if one of the main interrupts is asserted and only
@ -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,13 +302,16 @@ int arizona_irq_init(struct arizona *arizona)
goto err;
}
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);
goto err_domain;
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);
goto err_domain;
}
}
ret = regmap_add_irq_chip(arizona->regmap,

View file

@ -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);

View file

@ -25,6 +25,8 @@ extern const struct regmap_config wm5102_spi_regmap;
extern const struct regmap_config wm5110_i2c_regmap;
extern const struct regmap_config wm5110_spi_regmap;
extern const struct regmap_config cs47l24_spi_regmap;
extern const struct regmap_config wm8997_i2c_regmap;
extern const struct regmap_config wm8998_i2c_regmap;
@ -40,6 +42,8 @@ extern const struct regmap_irq_chip wm5110_aod;
extern const struct regmap_irq_chip wm5110_irq;
extern const struct regmap_irq_chip wm5110_revd_irq;
extern const struct regmap_irq_chip cs47l24_irq;
extern const struct regmap_irq_chip wm8997_aod;
extern const struct regmap_irq_chip wm8997_irq;

1629
drivers/mfd/cs47l24-tables.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -27,6 +27,8 @@ enum arizona_type {
WM8280 = 4,
WM8998 = 5,
WM1814 = 6,
WM1831 = 7,
CS47L24 = 8,
};
#define ARIZONA_IRQ_GP1 0
@ -166,6 +168,7 @@ static inline int wm5102_patch(struct arizona *arizona)
#endif
int wm5110_patch(struct arizona *arizona);
int cs47l24_patch(struct arizona *arizona);
int wm8997_patch(struct arizona *arizona);
int wm8998_patch(struct arizona *arizona);