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

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
...@@ -1370,24 +1370,30 @@ config MFD_ARIZONA ...@@ -1370,24 +1370,30 @@ config MFD_ARIZONA
bool bool
config MFD_ARIZONA_I2C 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_ARIZONA
select MFD_CORE select MFD_CORE
select REGMAP_I2C select REGMAP_I2C
depends on I2C depends on I2C
help help
Support for the Wolfson Microelectronics Arizona platform audio SoC Support for the Cirrus Logic/Wolfson Microelectronics Arizona platform
core functionality controlled via I2C. audio SoC core functionality controlled via I2C.
config MFD_ARIZONA_SPI 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_ARIZONA
select MFD_CORE select MFD_CORE
select REGMAP_SPI select REGMAP_SPI
depends on SPI_MASTER depends on SPI_MASTER
help help
Support for the Wolfson Microelectronics Arizona platform audio SoC Support for the Cirrus Logic/Wolfson Microelectronics Arizona platform
core functionality controlled via I2C. 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 config MFD_WM5102
bool "Wolfson Microelectronics WM5102" bool "Wolfson Microelectronics WM5102"
......
...@@ -51,6 +51,9 @@ endif ...@@ -51,6 +51,9 @@ endif
ifeq ($(CONFIG_MFD_WM8998),y) ifeq ($(CONFIG_MFD_WM8998),y)
obj-$(CONFIG_MFD_ARIZONA) += wm8998-tables.o obj-$(CONFIG_MFD_ARIZONA) += wm8998-tables.o
endif endif
ifeq ($(CONFIG_MFD_CS47L24),y)
obj-$(CONFIG_MFD_ARIZONA) += cs47l24-tables.o
endif
obj-$(CONFIG_MFD_WM8400) += wm8400-core.o obj-$(CONFIG_MFD_WM8400) += wm8400-core.o
wm831x-objs := wm831x-core.o wm831x-irq.o wm831x-otp.o wm831x-objs := wm831x-core.o wm831x-irq.o wm831x-otp.o
wm831x-objs += wm831x-auxadc.o wm831x-objs += wm831x-auxadc.o
......
...@@ -598,6 +598,12 @@ static int arizona_runtime_resume(struct device *dev) ...@@ -598,6 +598,12 @@ static int arizona_runtime_resume(struct device *dev)
goto err; goto err;
} }
break; break;
case WM1831:
case CS47L24:
ret = arizona_wait_for_boot(arizona);
if (ret != 0)
goto err;
break;
default: default:
ret = arizona_wait_for_boot(arizona); ret = arizona_wait_for_boot(arizona);
if (ret != 0) if (ret != 0)
...@@ -682,6 +688,9 @@ static int arizona_runtime_suspend(struct device *dev) ...@@ -682,6 +688,9 @@ static int arizona_runtime_suspend(struct device *dev)
} }
} }
break; break;
case WM1831:
case CS47L24:
break;
default: default:
jd_active = arizona_is_jack_det_active(arizona); jd_active = arizona_is_jack_det_active(arizona);
if (jd_active < 0) if (jd_active < 0)
...@@ -862,6 +871,8 @@ const struct of_device_id arizona_of_match[] = { ...@@ -862,6 +871,8 @@ const struct of_device_id arizona_of_match[] = {
{ .compatible = "wlf,wm8997", .data = (void *)WM8997 }, { .compatible = "wlf,wm8997", .data = (void *)WM8997 },
{ .compatible = "wlf,wm8998", .data = (void *)WM8998 }, { .compatible = "wlf,wm8998", .data = (void *)WM8998 },
{ .compatible = "wlf,wm1814", .data = (void *)WM1814 }, { .compatible = "wlf,wm1814", .data = (void *)WM1814 },
{ .compatible = "wlf,wm1831", .data = (void *)WM1831 },
{ .compatible = "cirrus,cs47l24", .data = (void *)CS47L24 },
{}, {},
}; };
EXPORT_SYMBOL_GPL(arizona_of_match); EXPORT_SYMBOL_GPL(arizona_of_match);
...@@ -919,6 +930,23 @@ static const struct mfd_cell wm5110_devs[] = { ...@@ -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[] = { static const char * const wm8997_supplies[] = {
"MICVDD", "MICVDD",
"DBVDD2", "DBVDD2",
...@@ -963,7 +991,7 @@ static const struct mfd_cell wm8998_devs[] = { ...@@ -963,7 +991,7 @@ static const struct mfd_cell wm8998_devs[] = {
int arizona_dev_init(struct arizona *arizona) int arizona_dev_init(struct arizona *arizona)
{ {
struct device *dev = arizona->dev; struct device *dev = arizona->dev;
const char *type_name; const char *type_name = NULL;
unsigned int reg, val, mask; unsigned int reg, val, mask;
int (*apply_patch)(struct arizona *) = NULL; int (*apply_patch)(struct arizona *) = NULL;
const struct mfd_cell *subdevs = NULL; const struct mfd_cell *subdevs = NULL;
...@@ -987,6 +1015,8 @@ int arizona_dev_init(struct arizona *arizona) ...@@ -987,6 +1015,8 @@ int arizona_dev_init(struct arizona *arizona)
case WM8997: case WM8997:
case WM8998: case WM8998:
case WM1814: case WM1814:
case WM1831:
case CS47L24:
for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++) for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++)
arizona->core_supplies[i].supply arizona->core_supplies[i].supply
= wm5102_core_supplies[i]; = wm5102_core_supplies[i];
...@@ -1001,12 +1031,19 @@ int arizona_dev_init(struct arizona *arizona) ...@@ -1001,12 +1031,19 @@ int arizona_dev_init(struct arizona *arizona)
/* Mark DCVDD as external, LDO1 driver will clear if internal */ /* Mark DCVDD as external, LDO1 driver will clear if internal */
arizona->external_dcvdd = true; 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, ret = mfd_add_devices(arizona->dev, -1, early_devs,
ARRAY_SIZE(early_devs), NULL, 0, NULL); ARRAY_SIZE(early_devs), NULL, 0, NULL);
if (ret != 0) { if (ret != 0) {
dev_err(dev, "Failed to add early children: %d\n", ret); dev_err(dev, "Failed to add early children: %d\n", ret);
return ret; return ret;
} }
break;
}
ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies, ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies,
arizona->core_supplies); arizona->core_supplies);
...@@ -1069,6 +1106,7 @@ int arizona_dev_init(struct arizona *arizona) ...@@ -1069,6 +1106,7 @@ int arizona_dev_init(struct arizona *arizona)
case 0x5102: case 0x5102:
case 0x5110: case 0x5110:
case 0x6349: case 0x6349:
case 0x6363:
case 0x8997: case 0x8997:
break; break;
default: default:
...@@ -1167,6 +1205,30 @@ int arizona_dev_init(struct arizona *arizona) ...@@ -1167,6 +1205,30 @@ int arizona_dev_init(struct arizona *arizona)
n_subdevs = ARRAY_SIZE(wm5110_devs); n_subdevs = ARRAY_SIZE(wm5110_devs);
} }
break; 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: case 0x8997:
if (IS_ENABLED(CONFIG_MFD_WM8997)) { if (IS_ENABLED(CONFIG_MFD_WM8997)) {
type_name = "WM8997"; type_name = "WM8997";
......
...@@ -30,11 +30,13 @@ static int arizona_map_irq(struct arizona *arizona, int irq) ...@@ -30,11 +30,13 @@ static int arizona_map_irq(struct arizona *arizona, int irq)
{ {
int ret; int ret;
if (arizona->aod_irq_chip) {
ret = regmap_irq_get_virq(arizona->aod_irq_chip, irq); ret = regmap_irq_get_virq(arizona->aod_irq_chip, irq);
if (ret < 0) if (ret >= 0)
ret = regmap_irq_get_virq(arizona->irq_chip, irq);
return ret; return ret;
}
return regmap_irq_get_virq(arizona->irq_chip, irq);
} }
int arizona_request_irq(struct arizona *arizona, int irq, char *name, int arizona_request_irq(struct arizona *arizona, int irq, char *name,
...@@ -107,7 +109,7 @@ static irqreturn_t arizona_irq_thread(int irq, void *data) ...@@ -107,7 +109,7 @@ static irqreturn_t arizona_irq_thread(int irq, void *data)
do { do {
poll = false; poll = false;
/* Always handle the AoD domain */ if (arizona->aod_irq_chip)
handle_nested_irq(irq_find_mapping(arizona->virq, 0)); handle_nested_irq(irq_find_mapping(arizona->virq, 0));
/* /*
...@@ -219,6 +221,15 @@ int arizona_irq_init(struct arizona *arizona) ...@@ -219,6 +221,15 @@ int arizona_irq_init(struct arizona *arizona)
arizona->ctrlif_error = false; arizona->ctrlif_error = false;
break; break;
#endif #endif
#ifdef CONFIG_MFD_CS47L24
case WM1831:
case CS47L24:
aod = NULL;
irq = &cs47l24_irq;
arizona->ctrlif_error = false;
break;
#endif
#ifdef CONFIG_MFD_WM8997 #ifdef CONFIG_MFD_WM8997
case WM8997: case WM8997:
aod = &wm8997_aod; aod = &wm8997_aod;
...@@ -291,14 +302,17 @@ int arizona_irq_init(struct arizona *arizona) ...@@ -291,14 +302,17 @@ int arizona_irq_init(struct arizona *arizona)
goto err; goto err;
} }
if (aod) {
ret = regmap_add_irq_chip(arizona->regmap, ret = regmap_add_irq_chip(arizona->regmap,
irq_create_mapping(arizona->virq, 0), irq_create_mapping(arizona->virq, 0),
IRQF_ONESHOT, 0, aod, IRQF_ONESHOT, 0, aod,
&arizona->aod_irq_chip); &arizona->aod_irq_chip);
if (ret != 0) { 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; goto err_domain;
} }
}
ret = regmap_add_irq_chip(arizona->regmap, ret = regmap_add_irq_chip(arizona->regmap,
irq_create_mapping(arizona->virq, 1), irq_create_mapping(arizona->virq, 1),
......
...@@ -46,6 +46,11 @@ static int arizona_spi_probe(struct spi_device *spi) ...@@ -46,6 +46,11 @@ static int arizona_spi_probe(struct spi_device *spi)
if (IS_ENABLED(CONFIG_MFD_WM5110)) if (IS_ENABLED(CONFIG_MFD_WM5110))
regmap_config = &wm5110_spi_regmap; regmap_config = &wm5110_spi_regmap;
break; break;
case WM1831:
case CS47L24:
if (IS_ENABLED(CONFIG_MFD_CS47L24))
regmap_config = &cs47l24_spi_regmap;
break;
default: default:
dev_err(&spi->dev, "Unknown device type %ld\n", type); dev_err(&spi->dev, "Unknown device type %ld\n", type);
return -EINVAL; return -EINVAL;
...@@ -89,6 +94,8 @@ static const struct spi_device_id arizona_spi_ids[] = { ...@@ -89,6 +94,8 @@ static const struct spi_device_id arizona_spi_ids[] = {
{ "wm5102", WM5102 }, { "wm5102", WM5102 },
{ "wm5110", WM5110 }, { "wm5110", WM5110 },
{ "wm8280", WM8280 }, { "wm8280", WM8280 },
{ "wm1831", WM1831 },
{ "cs47l24", CS47L24 },
{ }, { },
}; };
MODULE_DEVICE_TABLE(spi, arizona_spi_ids); MODULE_DEVICE_TABLE(spi, arizona_spi_ids);
......
...@@ -25,6 +25,8 @@ extern const struct regmap_config wm5102_spi_regmap; ...@@ -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_i2c_regmap;
extern const struct regmap_config wm5110_spi_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 wm8997_i2c_regmap;
extern const struct regmap_config wm8998_i2c_regmap; extern const struct regmap_config wm8998_i2c_regmap;
...@@ -40,6 +42,8 @@ extern const struct regmap_irq_chip wm5110_aod; ...@@ -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_irq;
extern const struct regmap_irq_chip wm5110_revd_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_aod;
extern const struct regmap_irq_chip wm8997_irq; extern const struct regmap_irq_chip wm8997_irq;
......
This diff is collapsed.
...@@ -27,6 +27,8 @@ enum arizona_type { ...@@ -27,6 +27,8 @@ enum arizona_type {
WM8280 = 4, WM8280 = 4,
WM8998 = 5, WM8998 = 5,
WM1814 = 6, WM1814 = 6,
WM1831 = 7,
CS47L24 = 8,
}; };
#define ARIZONA_IRQ_GP1 0 #define ARIZONA_IRQ_GP1 0
...@@ -166,6 +168,7 @@ static inline int wm5102_patch(struct arizona *arizona) ...@@ -166,6 +168,7 @@ static inline int wm5102_patch(struct arizona *arizona)
#endif #endif
int wm5110_patch(struct arizona *arizona); int wm5110_patch(struct arizona *arizona);
int cs47l24_patch(struct arizona *arizona);
int wm8997_patch(struct arizona *arizona); int wm8997_patch(struct arizona *arizona);
int wm8998_patch(struct arizona *arizona); int wm8998_patch(struct arizona *arizona);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment