summaryrefslogtreecommitdiffstats
path: root/drivers/regulator/arizona-micsupp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/arizona-micsupp.c')
-rw-r--r--drivers/regulator/arizona-micsupp.c119
1 files changed, 69 insertions, 50 deletions
diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c
index 22bd71407622..120de94caf02 100644
--- a/drivers/regulator/arizona-micsupp.c
+++ b/drivers/regulator/arizona-micsupp.c
@@ -30,9 +30,14 @@
#include <linux/mfd/arizona/pdata.h>
#include <linux/mfd/arizona/registers.h>
+#include <linux/regulator/arizona-micsupp.h>
+
struct arizona_micsupp {
struct regulator_dev *regulator;
- struct arizona *arizona;
+ struct regmap *regmap;
+ struct snd_soc_dapm_context **dapm;
+ unsigned int enable_reg;
+ struct device *dev;
struct regulator_consumer_supply supply;
struct regulator_init_data init_data;
@@ -44,21 +49,22 @@ static void arizona_micsupp_check_cp(struct work_struct *work)
{
struct arizona_micsupp *micsupp =
container_of(work, struct arizona_micsupp, check_cp_work);
- struct snd_soc_dapm_context *dapm = micsupp->arizona->dapm;
- struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
- struct arizona *arizona = micsupp->arizona;
- struct regmap *regmap = arizona->regmap;
- unsigned int reg;
+ struct snd_soc_dapm_context *dapm = *micsupp->dapm;
+ struct snd_soc_component *component;
+ unsigned int val;
int ret;
- ret = regmap_read(regmap, ARIZONA_MIC_CHARGE_PUMP_1, &reg);
+ ret = regmap_read(micsupp->regmap, micsupp->enable_reg, &val);
if (ret != 0) {
- dev_err(arizona->dev, "Failed to read CP state: %d\n", ret);
+ dev_err(micsupp->dev,
+ "Failed to read CP state: %d\n", ret);
return;
}
if (dapm) {
- if ((reg & (ARIZONA_CPMIC_ENA | ARIZONA_CPMIC_BYPASS)) ==
+ component = snd_soc_dapm_to_component(dapm);
+
+ if ((val & (ARIZONA_CPMIC_ENA | ARIZONA_CPMIC_BYPASS)) ==
ARIZONA_CPMIC_ENA)
snd_soc_component_force_enable_pin(component,
"MICSUPP");
@@ -199,89 +205,67 @@ static const struct regulator_init_data arizona_micsupp_ext_default = {
.num_consumer_supplies = 1,
};
-static int arizona_micsupp_of_get_pdata(struct arizona *arizona,
+static int arizona_micsupp_of_get_pdata(struct arizona_micsupp_pdata *pdata,
struct regulator_config *config,
const struct regulator_desc *desc)
{
- struct arizona_pdata *pdata = &arizona->pdata;
struct arizona_micsupp *micsupp = config->driver_data;
struct device_node *np;
struct regulator_init_data *init_data;
- np = of_get_child_by_name(arizona->dev->of_node, "micvdd");
+ np = of_get_child_by_name(config->dev->of_node, "micvdd");
if (np) {
config->of_node = np;
- init_data = of_get_regulator_init_data(arizona->dev, np, desc);
+ init_data = of_get_regulator_init_data(config->dev, np, desc);
if (init_data) {
init_data->consumer_supplies = &micsupp->supply;
init_data->num_consumer_supplies = 1;
- pdata->micvdd = init_data;
+ pdata->init_data = init_data;
}
}
return 0;
}
-static int arizona_micsupp_probe(struct platform_device *pdev)
+static int arizona_micsupp_common_init(struct platform_device *pdev,
+ struct arizona_micsupp *micsupp,
+ const struct regulator_desc *desc,
+ struct arizona_micsupp_pdata *pdata)
{
- struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
- const struct regulator_desc *desc;
struct regulator_config config = { };
- struct arizona_micsupp *micsupp;
int ret;
- micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL);
- if (!micsupp)
- return -ENOMEM;
-
- micsupp->arizona = arizona;
INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp);
- /*
- * Since the chip usually supplies itself we provide some
- * default init_data for it. This will be overridden with
- * platform data if provided.
- */
- switch (arizona->type) {
- case WM5110:
- case WM8280:
- desc = &arizona_micsupp_ext;
- micsupp->init_data = arizona_micsupp_ext_default;
- break;
- default:
- desc = &arizona_micsupp;
- micsupp->init_data = arizona_micsupp_default;
- break;
- }
-
micsupp->init_data.consumer_supplies = &micsupp->supply;
micsupp->supply.supply = "MICVDD";
- micsupp->supply.dev_name = dev_name(arizona->dev);
+ micsupp->supply.dev_name = dev_name(micsupp->dev);
+ micsupp->enable_reg = desc->enable_reg;
- config.dev = arizona->dev;
+ config.dev = micsupp->dev;
config.driver_data = micsupp;
- config.regmap = arizona->regmap;
+ config.regmap = micsupp->regmap;
if (IS_ENABLED(CONFIG_OF)) {
- if (!dev_get_platdata(arizona->dev)) {
- ret = arizona_micsupp_of_get_pdata(arizona, &config,
+ if (!dev_get_platdata(micsupp->dev)) {
+ ret = arizona_micsupp_of_get_pdata(pdata, &config,
desc);
if (ret < 0)
return ret;
}
}
- if (arizona->pdata.micvdd)
- config.init_data = arizona->pdata.micvdd;
+ if (pdata->init_data)
+ config.init_data = pdata->init_data;
else
config.init_data = &micsupp->init_data;
- /* Default to regulated mode until the API supports bypass */
- regmap_update_bits(arizona->regmap, ARIZONA_MIC_CHARGE_PUMP_1,
+ /* Default to regulated mode */
+ regmap_update_bits(micsupp->regmap, micsupp->enable_reg,
ARIZONA_CPMIC_BYPASS, 0);
micsupp->regulator = devm_regulator_register(&pdev->dev,
@@ -292,7 +276,7 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
if (IS_ERR(micsupp->regulator)) {
ret = PTR_ERR(micsupp->regulator);
- dev_err(arizona->dev, "Failed to register mic supply: %d\n",
+ dev_err(micsupp->dev, "Failed to register mic supply: %d\n",
ret);
return ret;
}
@@ -302,6 +286,41 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
return 0;
}
+static int arizona_micsupp_probe(struct platform_device *pdev)
+{
+ struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
+ const struct regulator_desc *desc;
+ struct arizona_micsupp *micsupp;
+
+ micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL);
+ if (!micsupp)
+ return -ENOMEM;
+
+ micsupp->regmap = arizona->regmap;
+ micsupp->dapm = &arizona->dapm;
+ micsupp->dev = arizona->dev;
+
+ /*
+ * Since the chip usually supplies itself we provide some
+ * default init_data for it. This will be overridden with
+ * platform data if provided.
+ */
+ switch (arizona->type) {
+ case WM5110:
+ case WM8280:
+ desc = &arizona_micsupp_ext;
+ micsupp->init_data = arizona_micsupp_ext_default;
+ break;
+ default:
+ desc = &arizona_micsupp;
+ micsupp->init_data = arizona_micsupp_default;
+ break;
+ }
+
+ return arizona_micsupp_common_init(pdev, micsupp, desc,
+ &arizona->pdata.micvdd);
+}
+
static struct platform_driver arizona_micsupp_driver = {
.probe = arizona_micsupp_probe,
.driver = {