All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
To: linus.walleij@linaro.org, gnurou@gmail.com, robh+dt@kernel.org,
	tglx@linutronix.de, jason@lakedaemon.net, lee.jones@linaro.org,
	broonie@kernel.org
Cc: linux-gpio@vger.kernel.org, alsa-devel@alsa-project.org,
	patches@opensource.wolfsonmicro.com,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
Subject: [PATCH 07/16] regulator: madera-micsupp: Mic supply for Cirrus Logic Madera codecs
Date: Wed, 5 Apr 2017 11:07:55 +0100	[thread overview]
Message-ID: <1491386884-30689-8-git-send-email-rf@opensource.wolfsonmicro.com> (raw)
In-Reply-To: <1491386884-30689-1-git-send-email-rf@opensource.wolfsonmicro.com>

The adds a driver for the microphone supply regulator on Cirrus Logic
Madera class codecs.

Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 .../bindings/regulator/madera-micsupp.txt          |  27 +++
 drivers/regulator/Kconfig                          |   8 +
 drivers/regulator/Makefile                         |   1 +
 drivers/regulator/madera-micsupp.c                 | 260 +++++++++++++++++++++
 include/linux/regulator/madera-micsupp.h           |  21 ++
 5 files changed, 317 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/madera-micsupp.txt
 create mode 100644 drivers/regulator/madera-micsupp.c
 create mode 100644 include/linux/regulator/madera-micsupp.h

diff --git a/Documentation/devicetree/bindings/regulator/madera-micsupp.txt b/Documentation/devicetree/bindings/regulator/madera-micsupp.txt
new file mode 100644
index 0000000..08aec7f
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/madera-micsupp.txt
@@ -0,0 +1,27 @@
+Cirrus Logic Madera class audio codecs mic supply regulator driver
+
+Only required if the codec has an internal mic supply regulator.
+This is a subnode of the parent mfd node.
+
+See also the core bindings for the parent MFD driver:
+See Documentation/devicetree/bindings/mfd/madera.txt
+
+Required properties:
+  - compatible :  must be "cirrus,madera-micsupp"
+
+Optional subnodes:
+  Standard regulator bindings as described in bindings/regulator/regulator.txt
+
+Example:
+
+codec: cs47l85@0 {
+	compatible = "cirrus,cs47l85";
+
+	micvdd {
+		compatible = "cirrus,madera-micsupp";
+		regulator-min-microvolt = <900000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-allow-bypass = <1>;
+	};
+};
+
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index c96d9a6..4f4b531 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -376,6 +376,14 @@ config REGULATOR_MADERA_LDO1
 	  to supply DCVDD you must include this driver. If you are using an
 	  external DCVDD regulator you do not need this driver.
 
+config REGULATOR_MADERA_MICSUPP
+	tristate "Cirrus Logic Madera codecs mic supply regulator"
+	depends on MFD_MADERA
+	depends on SND_SOC
+	help
+	  Support for the microphone supply regulator on Cirrus Logic
+	  Madera class codecs
+
 config REGULATOR_MAX14577
 	tristate "Maxim 14577/77836 regulator"
 	depends on MFD_MAX14577
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 2db3592..28cdf6e 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o
 obj-$(CONFIG_REGULATOR_LTC3589) += ltc3589.o
 obj-$(CONFIG_REGULATOR_LTC3676) += ltc3676.o
 obj-$(CONFIG_REGULATOR_MADERA_LDO1) += madera-ldo1.o
+obj-$(CONFIG_REGULATOR_MADERA_MICSUPP) += madera-micsupp.o
 obj-$(CONFIG_REGULATOR_MAX14577) += max14577-regulator.o
 obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
 obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o
diff --git a/drivers/regulator/madera-micsupp.c b/drivers/regulator/madera-micsupp.c
new file mode 100644
index 0000000..ac8bcbd
--- /dev/null
+++ b/drivers/regulator/madera-micsupp.c
@@ -0,0 +1,260 @@
+/*
+ * madera-micsupp.c  --  Driver for the mic supply regulator on Madera codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/workqueue.h>
+#include <sound/soc.h>
+
+#include <linux/regulator/madera-micsupp.h>
+
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/pdata.h>
+#include <linux/mfd/madera/registers.h>
+
+struct madera_micsupp {
+	struct regulator_dev *regulator;
+	struct madera *madera;
+
+	struct regulator_consumer_supply supply;
+	struct regulator_init_data init_data;
+
+	struct work_struct check_cp_work;
+};
+
+static void madera_micsupp_check_cp(struct work_struct *work)
+{
+	struct madera_micsupp *micsupp =
+		container_of(work, struct madera_micsupp, check_cp_work);
+	struct snd_soc_dapm_context *dapm = micsupp->madera->dapm;
+	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
+	struct madera *madera = micsupp->madera;
+	struct regmap *regmap = madera->regmap;
+	unsigned int reg;
+	int ret;
+
+	if (dapm) {
+		ret = regmap_read(regmap, MADERA_MIC_CHARGE_PUMP_1, &reg);
+		if (ret) {
+			dev_err(madera->dev,
+				"Failed to read CP state: %d\n", ret);
+			return;
+		}
+
+		reg &= MADERA_CPMIC_ENA | MADERA_CPMIC_BYPASS;
+		if (reg == MADERA_CPMIC_ENA)
+			snd_soc_component_force_enable_pin(component,
+							   "MICSUPP");
+		else
+			snd_soc_component_disable_pin(component, "MICSUPP");
+
+		snd_soc_dapm_sync(dapm);
+	}
+}
+
+static int madera_micsupp_enable(struct regulator_dev *rdev)
+{
+	struct madera_micsupp *micsupp = rdev_get_drvdata(rdev);
+	int ret;
+
+	ret = regulator_enable_regmap(rdev);
+	if (ret == 0)
+		schedule_work(&micsupp->check_cp_work);
+
+	return ret;
+}
+
+static int madera_micsupp_disable(struct regulator_dev *rdev)
+{
+	struct madera_micsupp *micsupp = rdev_get_drvdata(rdev);
+	int ret;
+
+	ret = regulator_disable_regmap(rdev);
+	if (ret == 0)
+		schedule_work(&micsupp->check_cp_work);
+
+	return ret;
+}
+
+static int madera_micsupp_set_bypass(struct regulator_dev *rdev, bool ena)
+{
+	struct madera_micsupp *micsupp = rdev_get_drvdata(rdev);
+	int ret;
+
+	ret = regulator_set_bypass_regmap(rdev, ena);
+	if (ret == 0)
+		schedule_work(&micsupp->check_cp_work);
+
+	return ret;
+}
+
+static const struct regulator_ops madera_micsupp_ops = {
+	.enable = madera_micsupp_enable,
+	.disable = madera_micsupp_disable,
+	.is_enabled = regulator_is_enabled_regmap,
+
+	.list_voltage = regulator_list_voltage_linear_range,
+	.map_voltage = regulator_map_voltage_linear_range,
+
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+
+	.get_bypass = regulator_get_bypass_regmap,
+	.set_bypass = madera_micsupp_set_bypass,
+};
+
+static const struct regulator_linear_range madera_micsupp_ranges[] = {
+	REGULATOR_LINEAR_RANGE(900000,  0,    0x14, 25000),
+	REGULATOR_LINEAR_RANGE(1500000, 0x15, 0x27, 100000),
+};
+
+static const struct regulator_desc madera_micsupp = {
+	.name = "MICVDD",
+	.supply_name = "CPVDD1",
+	.type = REGULATOR_VOLTAGE,
+	.n_voltages = 40,
+	.ops = &madera_micsupp_ops,
+
+	.vsel_reg = MADERA_LDO2_CONTROL_1,
+	.vsel_mask = MADERA_LDO2_VSEL_MASK,
+	.enable_reg = MADERA_MIC_CHARGE_PUMP_1,
+	.enable_mask = MADERA_CPMIC_ENA,
+	.bypass_reg = MADERA_MIC_CHARGE_PUMP_1,
+	.bypass_mask = MADERA_CPMIC_BYPASS,
+
+	.linear_ranges = madera_micsupp_ranges,
+	.n_linear_ranges = ARRAY_SIZE(madera_micsupp_ranges),
+
+	.enable_time = 3000,
+
+	.owner = THIS_MODULE,
+};
+
+static const struct regulator_init_data madera_micsupp_default = {
+	.constraints = {
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS |
+				REGULATOR_CHANGE_VOLTAGE |
+				REGULATOR_CHANGE_BYPASS,
+		.min_uV = 900000,
+		.max_uV = 3300000,
+	},
+
+	.num_consumer_supplies = 1,
+};
+
+static int madera_micsupp_of_get_pdata(struct madera *madera,
+					struct regulator_config *config,
+					const struct regulator_desc *desc)
+{
+	struct madera_pdata *pdata = &madera->pdata;
+	struct madera_micsupp *micsupp = config->driver_data;
+	struct regulator_init_data *init_data;
+
+	init_data = of_get_regulator_init_data(config->dev, config->of_node,
+						desc);
+
+	if (init_data) {
+		init_data->consumer_supplies = &micsupp->supply;
+		init_data->num_consumer_supplies = 1;
+		pdata->micsupp.init_data = init_data;
+	}
+
+	return 0;
+}
+
+static int madera_micsupp_probe(struct platform_device *pdev)
+{
+	struct madera *madera = dev_get_drvdata(pdev->dev.parent);
+	const struct regulator_desc *desc;
+	struct regulator_config config = { };
+	struct madera_micsupp *micsupp;
+	int ret;
+
+	micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL);
+	if (!micsupp)
+		return -ENOMEM;
+
+	micsupp->madera = madera;
+	INIT_WORK(&micsupp->check_cp_work, madera_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.
+	 */
+	desc = &madera_micsupp;
+	micsupp->init_data = madera_micsupp_default;
+
+	micsupp->init_data.consumer_supplies = &micsupp->supply;
+	micsupp->supply.supply = "MICVDD";
+	micsupp->supply.dev_name = dev_name(madera->dev);
+
+	config.dev = madera->dev;
+	config.of_node = config.dev->of_node;
+	config.driver_data = micsupp;
+	config.regmap = madera->regmap;
+
+	if (IS_ENABLED(CONFIG_OF)) {
+		if (!dev_get_platdata(madera->dev)) {
+			ret = madera_micsupp_of_get_pdata(madera, &config,
+							  desc);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	if (madera->pdata.micsupp.init_data)
+		config.init_data = madera->pdata.micsupp.init_data;
+	else
+		config.init_data = &micsupp->init_data;
+
+	/* Default to regulated mode, in case bypass is not in constraints */
+	regmap_update_bits(madera->regmap, MADERA_MIC_CHARGE_PUMP_1,
+			   MADERA_CPMIC_BYPASS, 0);
+
+	micsupp->regulator = devm_regulator_register(&pdev->dev, desc,
+						     &config);
+
+	of_node_put(config.of_node);
+
+	if (IS_ERR(micsupp->regulator)) {
+		ret = PTR_ERR(micsupp->regulator);
+		dev_err(madera->dev, "Failed to register mic supply: %d\n",
+			ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, micsupp);
+
+	return 0;
+}
+
+static struct platform_driver madera_micsupp_driver = {
+	.probe = madera_micsupp_probe,
+	.driver		= {
+		.name	= "madera-micsupp",
+	},
+};
+
+module_platform_driver(madera_micsupp_driver);
+
+/* Module information */
+MODULE_DESCRIPTION("Madera microphone supply driver");
+MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.wolfsonmicro.com>");
+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:madera-micsupp");
diff --git a/include/linux/regulator/madera-micsupp.h b/include/linux/regulator/madera-micsupp.h
new file mode 100644
index 0000000..9913bc6
--- /dev/null
+++ b/include/linux/regulator/madera-micsupp.h
@@ -0,0 +1,21 @@
+/*
+ * Platform data for Madera codecs MICSUPP regulator
+ *
+ * Copyright 2016-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef MADERA_MICSUPP_H
+#define MADERA_MICSUPP_H
+
+struct regulator_init_data;
+
+struct madera_micsupp_pdata {
+	/** Regulator configuration for MICSUPP */
+	const struct regulator_init_data *init_data;
+};
+
+#endif
-- 
1.9.1

WARNING: multiple messages have this Message-ID (diff)
From: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
To: <linus.walleij@linaro.org>, <gnurou@gmail.com>,
	<robh+dt@kernel.org>, <tglx@linutronix.de>,
	<jason@lakedaemon.net>, <lee.jones@linaro.org>,
	<broonie@kernel.org>
Cc: <alsa-devel@alsa-project.org>,
	<patches@opensource.wolfsonmicro.com>,
	<linux-gpio@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>
Subject: [PATCH 07/16] regulator: madera-micsupp: Mic supply for Cirrus Logic Madera codecs
Date: Wed, 5 Apr 2017 11:07:55 +0100	[thread overview]
Message-ID: <1491386884-30689-8-git-send-email-rf@opensource.wolfsonmicro.com> (raw)
In-Reply-To: <1491386884-30689-1-git-send-email-rf@opensource.wolfsonmicro.com>

The adds a driver for the microphone supply regulator on Cirrus Logic
Madera class codecs.

Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 .../bindings/regulator/madera-micsupp.txt          |  27 +++
 drivers/regulator/Kconfig                          |   8 +
 drivers/regulator/Makefile                         |   1 +
 drivers/regulator/madera-micsupp.c                 | 260 +++++++++++++++++++++
 include/linux/regulator/madera-micsupp.h           |  21 ++
 5 files changed, 317 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/madera-micsupp.txt
 create mode 100644 drivers/regulator/madera-micsupp.c
 create mode 100644 include/linux/regulator/madera-micsupp.h

diff --git a/Documentation/devicetree/bindings/regulator/madera-micsupp.txt b/Documentation/devicetree/bindings/regulator/madera-micsupp.txt
new file mode 100644
index 0000000..08aec7f
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/madera-micsupp.txt
@@ -0,0 +1,27 @@
+Cirrus Logic Madera class audio codecs mic supply regulator driver
+
+Only required if the codec has an internal mic supply regulator.
+This is a subnode of the parent mfd node.
+
+See also the core bindings for the parent MFD driver:
+See Documentation/devicetree/bindings/mfd/madera.txt
+
+Required properties:
+  - compatible :  must be "cirrus,madera-micsupp"
+
+Optional subnodes:
+  Standard regulator bindings as described in bindings/regulator/regulator.txt
+
+Example:
+
+codec: cs47l85@0 {
+	compatible = "cirrus,cs47l85";
+
+	micvdd {
+		compatible = "cirrus,madera-micsupp";
+		regulator-min-microvolt = <900000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-allow-bypass = <1>;
+	};
+};
+
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index c96d9a6..4f4b531 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -376,6 +376,14 @@ config REGULATOR_MADERA_LDO1
 	  to supply DCVDD you must include this driver. If you are using an
 	  external DCVDD regulator you do not need this driver.
 
+config REGULATOR_MADERA_MICSUPP
+	tristate "Cirrus Logic Madera codecs mic supply regulator"
+	depends on MFD_MADERA
+	depends on SND_SOC
+	help
+	  Support for the microphone supply regulator on Cirrus Logic
+	  Madera class codecs
+
 config REGULATOR_MAX14577
 	tristate "Maxim 14577/77836 regulator"
 	depends on MFD_MAX14577
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 2db3592..28cdf6e 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o
 obj-$(CONFIG_REGULATOR_LTC3589) += ltc3589.o
 obj-$(CONFIG_REGULATOR_LTC3676) += ltc3676.o
 obj-$(CONFIG_REGULATOR_MADERA_LDO1) += madera-ldo1.o
+obj-$(CONFIG_REGULATOR_MADERA_MICSUPP) += madera-micsupp.o
 obj-$(CONFIG_REGULATOR_MAX14577) += max14577-regulator.o
 obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
 obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o
diff --git a/drivers/regulator/madera-micsupp.c b/drivers/regulator/madera-micsupp.c
new file mode 100644
index 0000000..ac8bcbd
--- /dev/null
+++ b/drivers/regulator/madera-micsupp.c
@@ -0,0 +1,260 @@
+/*
+ * madera-micsupp.c  --  Driver for the mic supply regulator on Madera codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/workqueue.h>
+#include <sound/soc.h>
+
+#include <linux/regulator/madera-micsupp.h>
+
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/pdata.h>
+#include <linux/mfd/madera/registers.h>
+
+struct madera_micsupp {
+	struct regulator_dev *regulator;
+	struct madera *madera;
+
+	struct regulator_consumer_supply supply;
+	struct regulator_init_data init_data;
+
+	struct work_struct check_cp_work;
+};
+
+static void madera_micsupp_check_cp(struct work_struct *work)
+{
+	struct madera_micsupp *micsupp =
+		container_of(work, struct madera_micsupp, check_cp_work);
+	struct snd_soc_dapm_context *dapm = micsupp->madera->dapm;
+	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
+	struct madera *madera = micsupp->madera;
+	struct regmap *regmap = madera->regmap;
+	unsigned int reg;
+	int ret;
+
+	if (dapm) {
+		ret = regmap_read(regmap, MADERA_MIC_CHARGE_PUMP_1, &reg);
+		if (ret) {
+			dev_err(madera->dev,
+				"Failed to read CP state: %d\n", ret);
+			return;
+		}
+
+		reg &= MADERA_CPMIC_ENA | MADERA_CPMIC_BYPASS;
+		if (reg == MADERA_CPMIC_ENA)
+			snd_soc_component_force_enable_pin(component,
+							   "MICSUPP");
+		else
+			snd_soc_component_disable_pin(component, "MICSUPP");
+
+		snd_soc_dapm_sync(dapm);
+	}
+}
+
+static int madera_micsupp_enable(struct regulator_dev *rdev)
+{
+	struct madera_micsupp *micsupp = rdev_get_drvdata(rdev);
+	int ret;
+
+	ret = regulator_enable_regmap(rdev);
+	if (ret == 0)
+		schedule_work(&micsupp->check_cp_work);
+
+	return ret;
+}
+
+static int madera_micsupp_disable(struct regulator_dev *rdev)
+{
+	struct madera_micsupp *micsupp = rdev_get_drvdata(rdev);
+	int ret;
+
+	ret = regulator_disable_regmap(rdev);
+	if (ret == 0)
+		schedule_work(&micsupp->check_cp_work);
+
+	return ret;
+}
+
+static int madera_micsupp_set_bypass(struct regulator_dev *rdev, bool ena)
+{
+	struct madera_micsupp *micsupp = rdev_get_drvdata(rdev);
+	int ret;
+
+	ret = regulator_set_bypass_regmap(rdev, ena);
+	if (ret == 0)
+		schedule_work(&micsupp->check_cp_work);
+
+	return ret;
+}
+
+static const struct regulator_ops madera_micsupp_ops = {
+	.enable = madera_micsupp_enable,
+	.disable = madera_micsupp_disable,
+	.is_enabled = regulator_is_enabled_regmap,
+
+	.list_voltage = regulator_list_voltage_linear_range,
+	.map_voltage = regulator_map_voltage_linear_range,
+
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+
+	.get_bypass = regulator_get_bypass_regmap,
+	.set_bypass = madera_micsupp_set_bypass,
+};
+
+static const struct regulator_linear_range madera_micsupp_ranges[] = {
+	REGULATOR_LINEAR_RANGE(900000,  0,    0x14, 25000),
+	REGULATOR_LINEAR_RANGE(1500000, 0x15, 0x27, 100000),
+};
+
+static const struct regulator_desc madera_micsupp = {
+	.name = "MICVDD",
+	.supply_name = "CPVDD1",
+	.type = REGULATOR_VOLTAGE,
+	.n_voltages = 40,
+	.ops = &madera_micsupp_ops,
+
+	.vsel_reg = MADERA_LDO2_CONTROL_1,
+	.vsel_mask = MADERA_LDO2_VSEL_MASK,
+	.enable_reg = MADERA_MIC_CHARGE_PUMP_1,
+	.enable_mask = MADERA_CPMIC_ENA,
+	.bypass_reg = MADERA_MIC_CHARGE_PUMP_1,
+	.bypass_mask = MADERA_CPMIC_BYPASS,
+
+	.linear_ranges = madera_micsupp_ranges,
+	.n_linear_ranges = ARRAY_SIZE(madera_micsupp_ranges),
+
+	.enable_time = 3000,
+
+	.owner = THIS_MODULE,
+};
+
+static const struct regulator_init_data madera_micsupp_default = {
+	.constraints = {
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS |
+				REGULATOR_CHANGE_VOLTAGE |
+				REGULATOR_CHANGE_BYPASS,
+		.min_uV = 900000,
+		.max_uV = 3300000,
+	},
+
+	.num_consumer_supplies = 1,
+};
+
+static int madera_micsupp_of_get_pdata(struct madera *madera,
+					struct regulator_config *config,
+					const struct regulator_desc *desc)
+{
+	struct madera_pdata *pdata = &madera->pdata;
+	struct madera_micsupp *micsupp = config->driver_data;
+	struct regulator_init_data *init_data;
+
+	init_data = of_get_regulator_init_data(config->dev, config->of_node,
+						desc);
+
+	if (init_data) {
+		init_data->consumer_supplies = &micsupp->supply;
+		init_data->num_consumer_supplies = 1;
+		pdata->micsupp.init_data = init_data;
+	}
+
+	return 0;
+}
+
+static int madera_micsupp_probe(struct platform_device *pdev)
+{
+	struct madera *madera = dev_get_drvdata(pdev->dev.parent);
+	const struct regulator_desc *desc;
+	struct regulator_config config = { };
+	struct madera_micsupp *micsupp;
+	int ret;
+
+	micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL);
+	if (!micsupp)
+		return -ENOMEM;
+
+	micsupp->madera = madera;
+	INIT_WORK(&micsupp->check_cp_work, madera_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.
+	 */
+	desc = &madera_micsupp;
+	micsupp->init_data = madera_micsupp_default;
+
+	micsupp->init_data.consumer_supplies = &micsupp->supply;
+	micsupp->supply.supply = "MICVDD";
+	micsupp->supply.dev_name = dev_name(madera->dev);
+
+	config.dev = madera->dev;
+	config.of_node = config.dev->of_node;
+	config.driver_data = micsupp;
+	config.regmap = madera->regmap;
+
+	if (IS_ENABLED(CONFIG_OF)) {
+		if (!dev_get_platdata(madera->dev)) {
+			ret = madera_micsupp_of_get_pdata(madera, &config,
+							  desc);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	if (madera->pdata.micsupp.init_data)
+		config.init_data = madera->pdata.micsupp.init_data;
+	else
+		config.init_data = &micsupp->init_data;
+
+	/* Default to regulated mode, in case bypass is not in constraints */
+	regmap_update_bits(madera->regmap, MADERA_MIC_CHARGE_PUMP_1,
+			   MADERA_CPMIC_BYPASS, 0);
+
+	micsupp->regulator = devm_regulator_register(&pdev->dev, desc,
+						     &config);
+
+	of_node_put(config.of_node);
+
+	if (IS_ERR(micsupp->regulator)) {
+		ret = PTR_ERR(micsupp->regulator);
+		dev_err(madera->dev, "Failed to register mic supply: %d\n",
+			ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, micsupp);
+
+	return 0;
+}
+
+static struct platform_driver madera_micsupp_driver = {
+	.probe = madera_micsupp_probe,
+	.driver		= {
+		.name	= "madera-micsupp",
+	},
+};
+
+module_platform_driver(madera_micsupp_driver);
+
+/* Module information */
+MODULE_DESCRIPTION("Madera microphone supply driver");
+MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.wolfsonmicro.com>");
+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:madera-micsupp");
diff --git a/include/linux/regulator/madera-micsupp.h b/include/linux/regulator/madera-micsupp.h
new file mode 100644
index 0000000..9913bc6
--- /dev/null
+++ b/include/linux/regulator/madera-micsupp.h
@@ -0,0 +1,21 @@
+/*
+ * Platform data for Madera codecs MICSUPP regulator
+ *
+ * Copyright 2016-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef MADERA_MICSUPP_H
+#define MADERA_MICSUPP_H
+
+struct regulator_init_data;
+
+struct madera_micsupp_pdata {
+	/** Regulator configuration for MICSUPP */
+	const struct regulator_init_data *init_data;
+};
+
+#endif
-- 
1.9.1

  parent reply	other threads:[~2017-04-05 10:07 UTC|newest]

Thread overview: 88+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-05 10:07 [PATCH 00/16] Add support for Cirrus Logic CS47L35/L85/L90/L91 codecs Richard Fitzgerald
2017-04-05 10:07 ` Richard Fitzgerald
2017-04-05 10:07 ` [PATCH 01/16] mfd: madera: Add register definitions for Cirrus Logic Madera codecs Richard Fitzgerald
2017-04-05 10:07   ` Richard Fitzgerald
2017-04-07  8:27   ` Linus Walleij
2017-04-07  8:27     ` Linus Walleij
2017-04-07  8:30     ` Linus Walleij
2017-04-07  8:30       ` Linus Walleij
2017-04-07  8:48       ` Charles Keepax
2017-04-07  8:48         ` Charles Keepax
2017-04-07  9:12         ` Linus Walleij
2017-04-07  9:12           ` Linus Walleij
     [not found]           ` <CACRpkdZLfL+dxMN-uaRp57u4yW4cLfLFoZVkNWFZL4eECOyR1A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-04-07 11:14             ` Mark Brown
2017-04-07 11:14               ` Mark Brown
2017-04-12 12:06   ` Lee Jones
2017-04-05 10:07 ` [PATCH 02/16] mfd: madera: Add common support " Richard Fitzgerald
2017-04-05 10:07   ` Richard Fitzgerald
2017-04-12 12:54   ` Lee Jones
2017-04-19 16:42     ` Richard Fitzgerald
2017-04-19 16:42       ` Richard Fitzgerald
     [not found]       ` <1492620124.4826.47.camel-WeElTRBN8n0bEPBeyYQi64iQ8/zYDDdY1BehtkLrGTY@public.gmane.org>
2017-04-24 10:03         ` Lee Jones
2017-04-24 10:03           ` Lee Jones
2017-04-05 10:07 ` [PATCH 03/16] mfd: madera: Register map tables for Cirrus Logic CS47L35 Richard Fitzgerald
2017-04-05 10:07   ` Richard Fitzgerald
2017-04-12 13:30   ` Lee Jones
2017-04-05 10:07 ` [PATCH 04/16] mfd: madera: Register map tables for Cirrus Logic CS47L85 Richard Fitzgerald
2017-04-05 10:07   ` Richard Fitzgerald
2017-04-12 13:31   ` Lee Jones
2017-04-05 10:07 ` [PATCH 05/16] mfd: madera: Register map tables for Cirrus Logic CS47L90/91 Richard Fitzgerald
2017-04-05 10:07   ` Richard Fitzgerald
     [not found]   ` <1491386884-30689-6-git-send-email-rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
2017-04-12 13:31     ` Lee Jones
2017-04-12 13:31       ` Lee Jones
2017-04-05 10:07 ` [PATCH 06/16] regulator: madera-ldo1: LDO1 driver for Cirrus Logic Madera codecs Richard Fitzgerald
2017-04-05 10:07   ` Richard Fitzgerald
2017-04-05 13:28   ` Mark Brown
2017-04-05 13:28     ` Mark Brown
2017-04-10 17:49   ` Rob Herring
2017-04-10 18:11     ` Mark Brown
2017-04-10 18:11       ` Mark Brown
     [not found]       ` <20170410181136.btpvcat2ijwiebvm-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2017-04-11 19:20         ` Rob Herring
2017-04-11 19:20           ` Rob Herring
     [not found]           ` <CAL_JsqLYi8txm2xb5emGvbC0P2cvtW2wXLdA=2qCO-wt_4JXXA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-04-11 20:03             ` Mark Brown
2017-04-11 20:03               ` Mark Brown
2017-04-05 10:07 ` Richard Fitzgerald [this message]
2017-04-05 10:07   ` [PATCH 07/16] regulator: madera-micsupp: Mic supply " Richard Fitzgerald
2017-04-05 13:40   ` Mark Brown
2017-04-05 13:40     ` Mark Brown
2017-04-05 13:53     ` Richard Fitzgerald
2017-04-05 13:53       ` Richard Fitzgerald
2017-04-06 10:57       ` Mark Brown
2017-04-06 10:57         ` Mark Brown
2017-04-05 10:07 ` [PATCH 08/16] irqchip: Add driver " Richard Fitzgerald
2017-04-05 10:07   ` Richard Fitzgerald
2017-04-10 17:53   ` Rob Herring
2017-04-10 17:53     ` Rob Herring
2017-04-05 10:07 ` [PATCH 09/16] pinctrl: madera: " Richard Fitzgerald
2017-04-05 10:07   ` Richard Fitzgerald
2017-04-07  8:54   ` Linus Walleij
2017-04-07  8:54     ` Linus Walleij
     [not found]     ` <CACRpkdZK3QXu4t2jud0-LPDj0LDVruAm33N4Lazjk44C3ndwwQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-04-07  9:43       ` Richard Fitzgerald
2017-04-07  9:43         ` Richard Fitzgerald
2017-04-10 17:56   ` Rob Herring
2017-04-10 17:56     ` Rob Herring
2017-04-05 10:07 ` [PATCH 10/16] gpio: madera: Support Cirrus Logic Madera class codecs Richard Fitzgerald
2017-04-05 10:07   ` Richard Fitzgerald
2017-04-07  9:11   ` Linus Walleij
2017-04-07  9:11     ` Linus Walleij
     [not found]     ` <CACRpkdatoJOg1U218Q-NteRdz6B+w_yr1PWvnfa1P1EgGm7zug-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-04-07  9:54       ` Richard Fitzgerald
2017-04-07  9:54         ` Richard Fitzgerald
2017-04-05 10:07 ` [PATCH 11/16] ASoC: wm_adsp: Add support for ADSP2V2 Richard Fitzgerald
2017-04-05 10:07   ` Richard Fitzgerald
2017-04-05 17:31   ` Applied "ASoC: wm_adsp: Add support for ADSP2V2" to the asoc tree Mark Brown
2017-04-05 17:31     ` Mark Brown
2017-04-05 10:08 ` [PATCH 12/16] ASoC: wm_adsp: add support for DSP region lock Richard Fitzgerald
2017-04-05 10:08   ` Richard Fitzgerald
     [not found]   ` <1491386884-30689-13-git-send-email-rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
2017-04-05 17:31     ` Applied "ASoC: wm_adsp: add support for DSP region lock" to the asoc tree Mark Brown
2017-04-05 17:31       ` Mark Brown
     [not found] ` <1491386884-30689-1-git-send-email-rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
2017-04-05 10:08   ` [PATCH 13/16] ASoC: madera: Add common support for Cirrus Logic Madera codecs Richard Fitzgerald
2017-04-05 10:08     ` Richard Fitzgerald
2017-04-10 18:03     ` Rob Herring
2017-04-14 21:01     ` kbuild test robot
2017-04-14 21:01       ` kbuild test robot
2017-04-05 10:08 ` [PATCH 14/16] ASoC: cs47l35: Add codec driver for Cirrus Logic CS47L35 Richard Fitzgerald
2017-04-05 10:08   ` Richard Fitzgerald
2017-04-05 10:08 ` [PATCH 15/16] ASoC: cs47l85: Add codec driver for Cirrus Logic CS47L85 Richard Fitzgerald
2017-04-05 10:08   ` Richard Fitzgerald
2017-04-05 10:08 ` [PATCH 16/16] ASoC: cs47l90: Add codec driver for Cirrus Logic CS47L90 Richard Fitzgerald
2017-04-05 10:08   ` Richard Fitzgerald

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1491386884-30689-8-git-send-email-rf@opensource.wolfsonmicro.com \
    --to=rf@opensource.wolfsonmicro.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=gnurou@gmail.com \
    --cc=jason@lakedaemon.net \
    --cc=lee.jones@linaro.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=patches@opensource.wolfsonmicro.com \
    --cc=robh+dt@kernel.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.