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:
parent
9a65a6d3cb
commit
ea1f333990
8 changed files with 1753 additions and 25 deletions
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
1629
drivers/mfd/cs47l24-tables.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue