[alsa-devel] [PATCH v2 0/4] ASoC: tlv320aic32x4: DT support
Hi,
The series adds basic DT support for the TI tlv320aic32x4 codec.
v2 adds a new patch to support regulators. The codec now decides on the given regulators if LDO for AVDD should be enabled. 'ti,ldo-enable' was removed.
Regards,
Markus
Changes in v2: - Regulator support - Fix documentation for gpio property
Markus Pargmann (4): ASoC: tlv320aic32x4: Use signed int mixer controls ASoC: tlv320aic32x4: DT support ASoC: tlv320aic32x4: Support for master clock ASoC: tlv320aic32x4: Support for regulators
.../devicetree/bindings/sound/tlv320aic32x4.txt | 28 +++++ sound/soc/codecs/tlv320aic32x4.c | 126 +++++++++++++++++++-- 2 files changed, 144 insertions(+), 10 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/tlv320aic32x4.txt
There are a number of mixer controls that support negative values. They use signed values for this with different number of bits for the values. Currently they only support the positive range.
This patch replaces the unsigned mixers with signed mixers to support the full range.
Signed-off-by: Markus Pargmann mpa@pengutronix.de --- sound/soc/codecs/tlv320aic32x4.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 36a9cb9..1c9f1d8 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -68,18 +68,24 @@ struct aic32x4_priv { int rstn_gpio; };
-/* 0dB min, 1dB steps */ -static DECLARE_TLV_DB_SCALE(tlv_step_1, 0, 100, 0); /* 0dB min, 0.5dB steps */ static DECLARE_TLV_DB_SCALE(tlv_step_0_5, 0, 50, 0); +/* -63.5dB min, 0.5dB steps */ +static DECLARE_TLV_DB_SCALE(tlv_pcm, -6350, 50, 0); +/* -6dB min, 1dB steps */ +static DECLARE_TLV_DB_SCALE(tlv_driver_gain, -600, 100, 0); +/* -12dB min, 0.5dB steps */ +static DECLARE_TLV_DB_SCALE(tlv_adc_vol, -1200, 50, 0);
static const struct snd_kcontrol_new aic32x4_snd_controls[] = { - SOC_DOUBLE_R_TLV("PCM Playback Volume", AIC32X4_LDACVOL, - AIC32X4_RDACVOL, 0, 0x30, 0, tlv_step_0_5), - SOC_DOUBLE_R_TLV("HP Driver Gain Volume", AIC32X4_HPLGAIN, - AIC32X4_HPRGAIN, 0, 0x1D, 0, tlv_step_1), - SOC_DOUBLE_R_TLV("LO Driver Gain Volume", AIC32X4_LOLGAIN, - AIC32X4_LORGAIN, 0, 0x1D, 0, tlv_step_1), + SOC_DOUBLE_R_S_TLV("PCM Playback Volume", AIC32X4_LDACVOL, + AIC32X4_RDACVOL, 0, (s8)0x81, 0x30, 7, 0, tlv_pcm), + SOC_DOUBLE_R_S_TLV("HP Driver Gain Volume", AIC32X4_HPLGAIN, + AIC32X4_HPRGAIN, 0, (s8)0xfa, 0x1d, 5, 0, + tlv_driver_gain), + SOC_DOUBLE_R_S_TLV("LO Driver Gain Volume", AIC32X4_LOLGAIN, + AIC32X4_LORGAIN, 0, (s8)0xfa, 0x1d, 5, 0, + tlv_driver_gain), SOC_DOUBLE_R("HP DAC Playback Switch", AIC32X4_HPLGAIN, AIC32X4_HPRGAIN, 6, 0x01, 1), SOC_DOUBLE_R("LO DAC Playback Switch", AIC32X4_LOLGAIN, @@ -90,8 +96,8 @@ static const struct snd_kcontrol_new aic32x4_snd_controls[] = { SOC_SINGLE("ADCFGA Left Mute Switch", AIC32X4_ADCFGA, 7, 1, 0), SOC_SINGLE("ADCFGA Right Mute Switch", AIC32X4_ADCFGA, 3, 1, 0),
- SOC_DOUBLE_R_TLV("ADC Level Volume", AIC32X4_LADCVOL, - AIC32X4_RADCVOL, 0, 0x28, 0, tlv_step_0_5), + SOC_DOUBLE_R_S_TLV("ADC Level Volume", AIC32X4_LADCVOL, + AIC32X4_RADCVOL, 0, (s8)0xe8, 0x28, 6, 0, tlv_adc_vol), SOC_DOUBLE_R_TLV("PGA Level Volume", AIC32X4_LMICPGAVOL, AIC32X4_RMICPGAVOL, 0, 0x5f, 0, tlv_step_0_5),
On Mon, Jan 20, 2014 at 01:05:55PM +0100, Markus Pargmann wrote:
- SOC_DOUBLE_R_S_TLV("PCM Playback Volume", AIC32X4_LDACVOL,
AIC32X4_RDACVOL, 0, (s8)0x81, 0x30, 7, 0, tlv_pcm),
These casts are icky - I'd expect either signed numbers being used here or the macros to deal with any required casting. On the other hand there's fun and games with the type sizes...
Also this seems to depend on the patch series adding these controls, please note such dependencies when submitting.
Hi,
On Tue, Jan 21, 2014 at 09:14:55PM +0000, Mark Brown wrote:
On Mon, Jan 20, 2014 at 01:05:55PM +0100, Markus Pargmann wrote:
- SOC_DOUBLE_R_S_TLV("PCM Playback Volume", AIC32X4_LDACVOL,
AIC32X4_RDACVOL, 0, (s8)0x81, 0x30, 7, 0, tlv_pcm),
These casts are icky - I'd expect either signed numbers being used here or the macros to deal with any required casting. On the other hand there's fun and games with the type sizes...
I used this cast for the minimum value to get a easily comparable hex value. The reference manual does not state the real negative number, instead it show it in binary '0b1000 0001'. But I can convert those casted values to negative numbers.
Also this seems to depend on the patch series adding these controls, please note such dependencies when submitting.
Yes, sorry, I had it in the summary of the first version of this series, forgot to add it in the summary for v2.
Thanks,
Markus
Add DT support for this codec. The bindings differ a bit from the aic3x codec bindings, so I created a new binding documentation.
Cc: Rob Herring robh+dt@kernel.org Cc: Pawel Moll pawel.moll@arm.com Cc: Mark Rutland mark.rutland@arm.com Cc: Ian Campbell ijc+devicetree@hellion.org.uk Cc: Kumar Gala galak@codeaurora.org Cc: devicetree@vger.kernel.org Signed-off-by: Markus Pargmann mpa@pengutronix.de --- .../devicetree/bindings/sound/tlv320aic32x4.txt | 18 ++++++++++++++++ sound/soc/codecs/tlv320aic32x4.c | 25 ++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/tlv320aic32x4.txt
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt new file mode 100644 index 0000000..cff06ea --- /dev/null +++ b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt @@ -0,0 +1,18 @@ +Texas Instruments - tlv320aic32x4 Codec module + +The tlv320aic32x4 serial control bus communicates through I2C protocols + +Required properties: + - compatible: Should be "ti,tlv320aic32x4" + - reg: I2C slave address + +Optional properties: + - gpio-reset: Reset-GPIO phandle with args as described in gpio/gpio.txt + + +Example: + +codec: tlv320aic32x4@18 { + compatible = "ti,tlv320aic32x4"; + reg = <0x18>; +}; diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 1c9f1d8..6c38cb7 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -29,6 +29,7 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/gpio.h> +#include <linux/of_gpio.h> #include <linux/i2c.h> #include <linux/cdev.h> #include <linux/slab.h> @@ -669,11 +670,22 @@ static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = { .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), };
+static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4, + struct device_node *np) +{ + aic32x4->swapdacs = false; + aic32x4->micpga_routing = 0; + aic32x4->rstn_gpio = of_get_named_gpio(np, "gpio-reset", 0); + + return 0; +} + static int aic32x4_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct aic32x4_pdata *pdata = i2c->dev.platform_data; struct aic32x4_priv *aic32x4; + struct device_node *np = i2c->dev.of_node; int ret;
aic32x4 = devm_kzalloc(&i2c->dev, sizeof(struct aic32x4_priv), @@ -692,6 +704,12 @@ static int aic32x4_i2c_probe(struct i2c_client *i2c, aic32x4->swapdacs = pdata->swapdacs; aic32x4->micpga_routing = pdata->micpga_routing; aic32x4->rstn_gpio = pdata->rstn_gpio; + } else if (np) { + ret = aic32x4_parse_dt(aic32x4, np); + if (ret) { + dev_err(&i2c->dev, "Failed to parse DT node\n"); + return ret; + } } else { aic32x4->power_cfg = 0; aic32x4->swapdacs = false; @@ -723,10 +741,17 @@ static const struct i2c_device_id aic32x4_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id);
+static const struct of_device_id aic32x4_of_id[] = { + { .compatible = "ti,tlv320aic32x4", }, + { /* senitel */ } +}; +MODULE_DEVICE_TABLE(of, aic32x4_of_id); + static struct i2c_driver aic32x4_i2c_driver = { .driver = { .name = "tlv320aic32x4", .owner = THIS_MODULE, + .of_match_table = aic32x4_of_id, }, .probe = aic32x4_i2c_probe, .remove = aic32x4_i2c_remove,
Am Montag, den 20.01.2014, 13:05 +0100 schrieb Markus Pargmann:
Add DT support for this codec. The bindings differ a bit from the aic3x codec bindings, so I created a new binding documentation.
Cc: Rob Herring robh+dt@kernel.org Cc: Pawel Moll pawel.moll@arm.com Cc: Mark Rutland mark.rutland@arm.com Cc: Ian Campbell ijc+devicetree@hellion.org.uk Cc: Kumar Gala galak@codeaurora.org Cc: devicetree@vger.kernel.org Signed-off-by: Markus Pargmann mpa@pengutronix.de
.../devicetree/bindings/sound/tlv320aic32x4.txt | 18 ++++++++++++++++ sound/soc/codecs/tlv320aic32x4.c | 25 ++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/tlv320aic32x4.txt
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt new file mode 100644 index 0000000..cff06ea --- /dev/null +++ b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt @@ -0,0 +1,18 @@ +Texas Instruments - tlv320aic32x4 Codec module
+The tlv320aic32x4 serial control bus communicates through I2C protocols
+Required properties:
- compatible: Should be "ti,tlv320aic32x4"
- reg: I2C slave address
+Optional properties:
- gpio-reset: Reset-GPIO phandle with args as described in gpio/gpio.txt
This should be "reset-gpios".
+Example:
+codec: tlv320aic32x4@18 {
- compatible = "ti,tlv320aic32x4";
- reg = <0x18>;
+}; diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 1c9f1d8..6c38cb7 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -29,6 +29,7 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/gpio.h> +#include <linux/of_gpio.h> #include <linux/i2c.h> #include <linux/cdev.h> #include <linux/slab.h> @@ -669,11 +670,22 @@ static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = { .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), };
+static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4,
struct device_node *np)
+{
- aic32x4->swapdacs = false;
- aic32x4->micpga_routing = 0;
- aic32x4->rstn_gpio = of_get_named_gpio(np, "gpio-reset", 0);
This should be "reset-gpios".
- return 0;
+}
static int aic32x4_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct aic32x4_pdata *pdata = i2c->dev.platform_data; struct aic32x4_priv *aic32x4;
struct device_node *np = i2c->dev.of_node; int ret;
aic32x4 = devm_kzalloc(&i2c->dev, sizeof(struct aic32x4_priv),
@@ -692,6 +704,12 @@ static int aic32x4_i2c_probe(struct i2c_client *i2c, aic32x4->swapdacs = pdata->swapdacs; aic32x4->micpga_routing = pdata->micpga_routing; aic32x4->rstn_gpio = pdata->rstn_gpio;
- } else if (np) {
ret = aic32x4_parse_dt(aic32x4, np);
if (ret) {
dev_err(&i2c->dev, "Failed to parse DT node\n");
return ret;
} else { aic32x4->power_cfg = 0; aic32x4->swapdacs = false;}
@@ -723,10 +741,17 @@ static const struct i2c_device_id aic32x4_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id);
+static const struct of_device_id aic32x4_of_id[] = {
- { .compatible = "ti,tlv320aic32x4", },
- { /* senitel */ }
+}; +MODULE_DEVICE_TABLE(of, aic32x4_of_id);
static struct i2c_driver aic32x4_i2c_driver = { .driver = { .name = "tlv320aic32x4", .owner = THIS_MODULE,
}, .probe = aic32x4_i2c_probe, .remove = aic32x4_i2c_remove,.of_match_table = aic32x4_of_id,
regards Philipp
On Mon, Jan 20, 2014 at 01:54:57PM +0100, Philipp Zabel wrote:
Am Montag, den 20.01.2014, 13:05 +0100 schrieb Markus Pargmann:
Add DT support for this codec. The bindings differ a bit from the aic3x codec bindings, so I created a new binding documentation.
Cc: Rob Herring robh+dt@kernel.org Cc: Pawel Moll pawel.moll@arm.com Cc: Mark Rutland mark.rutland@arm.com Cc: Ian Campbell ijc+devicetree@hellion.org.uk Cc: Kumar Gala galak@codeaurora.org Cc: devicetree@vger.kernel.org Signed-off-by: Markus Pargmann mpa@pengutronix.de
.../devicetree/bindings/sound/tlv320aic32x4.txt | 18 ++++++++++++++++ sound/soc/codecs/tlv320aic32x4.c | 25 ++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/tlv320aic32x4.txt
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt new file mode 100644 index 0000000..cff06ea --- /dev/null +++ b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt @@ -0,0 +1,18 @@ +Texas Instruments - tlv320aic32x4 Codec module
+The tlv320aic32x4 serial control bus communicates through I2C protocols
+Required properties:
- compatible: Should be "ti,tlv320aic32x4"
- reg: I2C slave address
+Optional properties:
- gpio-reset: Reset-GPIO phandle with args as described in gpio/gpio.txt
This should be "reset-gpios".
Thanks, I will fix it for v3.
Regards,
Markus
Add support for a master clock passed through DT. The master clock of the codec is only active when the codec is in use.
Cc: Rob Herring robh+dt@kernel.org Cc: Pawel Moll pawel.moll@arm.com Cc: Mark Rutland mark.rutland@arm.com Cc: Ian Campbell ijc+devicetree@hellion.org.uk Cc: Kumar Gala galak@codeaurora.org Cc: devicetree@vger.kernel.org Signed-off-by: Markus Pargmann mpa@pengutronix.de --- .../devicetree/bindings/sound/tlv320aic32x4.txt | 4 ++++ sound/soc/codecs/tlv320aic32x4.c | 23 ++++++++++++++++++++++ 2 files changed, 27 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt index cff06ea..e90e6f0 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt @@ -8,6 +8,8 @@ Required properties:
Optional properties: - gpio-reset: Reset-GPIO phandle with args as described in gpio/gpio.txt + - clocks/clock-names: Clock named 'mclk' for the master clock of the codec. + See clock/clock-bindings.txt for information about the detailed format.
Example: @@ -15,4 +17,6 @@ Example: codec: tlv320aic32x4@18 { compatible = "ti,tlv320aic32x4"; reg = <0x18>; + clocks = <&clks 201>; + clock-names = "mclk"; }; diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 6c38cb7..d7fa8dc 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -33,6 +33,7 @@ #include <linux/i2c.h> #include <linux/cdev.h> #include <linux/slab.h> +#include <linux/clk.h>
#include <sound/tlv320aic32x4.h> #include <sound/core.h> @@ -67,6 +68,7 @@ struct aic32x4_priv { u32 micpga_routing; bool swapdacs; int rstn_gpio; + struct clk *mclk; };
/* 0dB min, 0.5dB steps */ @@ -487,8 +489,21 @@ static int aic32x4_mute(struct snd_soc_dai *dai, int mute) static int aic32x4_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { + struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); + switch (level) { case SND_SOC_BIAS_ON: + /* Switch on master clock */ + if (!IS_ERR(aic32x4->mclk)) { + int ret; + + ret = clk_prepare_enable(aic32x4->mclk); + if (ret) { + dev_err(codec->dev, "Failed to enable master clock\n"); + return ret; + } + } + /* Switch on PLL */ snd_soc_update_bits(codec, AIC32X4_PLLPR, AIC32X4_PLLEN, AIC32X4_PLLEN); @@ -516,6 +531,10 @@ static int aic32x4_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: + /* Switch off master clock */ + if (!IS_ERR(aic32x4->mclk)) + clk_disable_unprepare(aic32x4->mclk); + /* Switch off PLL */ snd_soc_update_bits(codec, AIC32X4_PLLPR, AIC32X4_PLLEN, 0); @@ -717,6 +736,10 @@ static int aic32x4_i2c_probe(struct i2c_client *i2c, aic32x4->rstn_gpio = -1; }
+ aic32x4->mclk = devm_clk_get(&i2c->dev, "mclk"); + if (IS_ERR(aic32x4->mclk)) + dev_info(&i2c->dev, "No mclk found, continuing without clock\n"); + if (gpio_is_valid(aic32x4->rstn_gpio)) { ret = devm_gpio_request_one(&i2c->dev, aic32x4->rstn_gpio, GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn");
Support regulators to power up the codec. This patch also enables the AVDD LDO if no AV regulator was found.
Signed-off-by: Markus Pargmann mpa@pengutronix.de --- .../devicetree/bindings/sound/tlv320aic32x4.txt | 6 +++ sound/soc/codecs/tlv320aic32x4.c | 52 ++++++++++++++++++++++ 2 files changed, 58 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt index e90e6f0..1e1aed82 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt @@ -10,6 +10,12 @@ Optional properties: - gpio-reset: Reset-GPIO phandle with args as described in gpio/gpio.txt - clocks/clock-names: Clock named 'mclk' for the master clock of the codec. See clock/clock-bindings.txt for information about the detailed format. + - supply-*: Optional supply regulators for the codec. Possible regulators are + "ldoin" - LDO power supply + "iov" - digital IO power supply + "dv" - Digital core power supply + "av" - Analog core power supply + See regulator/regulator.txt for more information.
Example: diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index d7fa8dc..d3b265c 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -34,6 +34,7 @@ #include <linux/cdev.h> #include <linux/slab.h> #include <linux/clk.h> +#include <linux/regulator/consumer.h>
#include <sound/tlv320aic32x4.h> #include <sound/core.h> @@ -69,6 +70,11 @@ struct aic32x4_priv { bool swapdacs; int rstn_gpio; struct clk *mclk; + + struct regulator *supply_ldo; + struct regulator *supply_iov; + struct regulator *supply_dv; + struct regulator *supply_av; };
/* 0dB min, 0.5dB steps */ @@ -699,6 +705,46 @@ static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4, return 0; }
+static int aic32x4_i2c_setup_regulators(struct device *dev, + struct aic32x4_priv *aic32x4) +{ + int ret; + + aic32x4->supply_ldo = devm_regulator_get_optional(dev, "ldoin"); + aic32x4->supply_iov = devm_regulator_get_optional(dev, "iov"); + aic32x4->supply_dv = devm_regulator_get_optional(dev, "dv"); + aic32x4->supply_av = devm_regulator_get_optional(dev, "av"); + + if (!IS_ERR(aic32x4->supply_ldo)) { + ret = regulator_enable(aic32x4->supply_ldo); + if (ret) + return ret; + } + + if (!IS_ERR(aic32x4->supply_iov)) { + ret = regulator_enable(aic32x4->supply_iov); + if (ret) + return ret; + } + + if (!IS_ERR(aic32x4->supply_dv)) { + ret = regulator_enable(aic32x4->supply_dv); + if (ret) + return ret; + } + + if (!IS_ERR(aic32x4->supply_av)) { + ret = regulator_enable(aic32x4->supply_av); + if (ret) + return ret; + } + + if (!IS_ERR(aic32x4->supply_ldo) && IS_ERR(aic32x4->supply_av)) + aic32x4->power_cfg |= AIC32X4_PWR_AIC32X4_LDO_ENABLE; + + return 0; +} + static int aic32x4_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -736,6 +782,12 @@ static int aic32x4_i2c_probe(struct i2c_client *i2c, aic32x4->rstn_gpio = -1; }
+ ret = aic32x4_i2c_setup_regulators(&i2c->dev, aic32x4); + if (ret) { + dev_err(&i2c->dev, "Failed to setup regulators\n"); + return ret; + } + aic32x4->mclk = devm_clk_get(&i2c->dev, "mclk"); if (IS_ERR(aic32x4->mclk)) dev_info(&i2c->dev, "No mclk found, continuing without clock\n");
participants (3)
-
Mark Brown
-
Markus Pargmann
-
Philipp Zabel