[alsa-devel] [PATCH 1/2] ASoC: rt5663: Add documentation for power supply support
rt5663 codec driver will support setting CPVDD and AVDD power supply from device tree.
Signed-off-by: Cheng-Yi Chiang cychiang@chromium.org --- Fixed the commit title of v1.
Documentation/devicetree/bindings/sound/rt5663.txt | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/rt5663.txt b/Documentation/devicetree/bindings/sound/rt5663.txt index 23386446c63d6..d4058dfde0392 100644 --- a/Documentation/devicetree/bindings/sound/rt5663.txt +++ b/Documentation/devicetree/bindings/sound/rt5663.txt @@ -36,6 +36,9 @@ Optional properties: "realtek,impedance_sensing_num" is 2. It means that there are 2 ranges of impedance in the impedance sensing function.
+- avdd-supply: Power supply for AVDD, providing 1.8V. +- cpvdd-supply: Power supply for CPVDD, providing 3.5V. + Pins on the device (for linking into audio routes) for RT5663:
* IN1P @@ -51,4 +54,6 @@ rt5663: codec@12 { compatible = "realtek,rt5663"; reg = <0x12>; interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + avdd-supply = <&pp1800_a_alc5662>; + cpvdd-supply = <&pp3500_a_alc5662>; };
Add regulator support to turn on cpvdd and avdd in probe. If a regulator is not given from device tree, a dummy regulator will be used.
Signed-off-by: Cheng-Yi Chiang cychiang@chromium.org --- sound/soc/codecs/rt5663.c | 68 +++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index 2444fad7c2dfe..7e9c1901a0a67 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -17,6 +17,7 @@ #include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/acpi.h> +#include <linux/regulator/consumer.h> #include <linux/workqueue.h> #include <sound/core.h> #include <sound/pcm.h> @@ -33,6 +34,9 @@ #define RT5663_DEVICE_ID_2 0x6451 #define RT5663_DEVICE_ID_1 0x6406
+#define RT5663_POWER_ON_DELAY_MS 300 +#define RT5663_SUPPLY_CURRENT_UA 500000 + enum { CODEC_VER_1, CODEC_VER_0, @@ -48,6 +52,11 @@ struct impedance_mapping_table { unsigned int dc_offset_r_manual_mic; };
+static const char *const rt5663_supply_names[] = { + "avdd", + "cpvdd", +}; + struct rt5663_priv { struct snd_soc_component *component; struct rt5663_platform_data pdata; @@ -56,6 +65,7 @@ struct rt5663_priv { struct snd_soc_jack *hs_jack; struct timer_list btn_check_timer; struct impedance_mapping_table *imp_table; + struct regulator_bulk_data supplies[ARRAY_SIZE(rt5663_supply_names)];
int codec_ver; int sysclk; @@ -3480,7 +3490,7 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, { struct rt5663_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5663_priv *rt5663; - int ret; + int ret, i; unsigned int val; struct regmap *regmap;
@@ -3497,6 +3507,37 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, else rt5663_parse_dp(rt5663, &i2c->dev);
+ for (i = 0; i < ARRAY_SIZE(rt5663->supplies); i++) + rt5663->supplies[i].supply = rt5663_supply_names[i]; + + ret = devm_regulator_bulk_get(&i2c->dev, + ARRAY_SIZE(rt5663->supplies), + rt5663->supplies); + if (ret) { + dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); + return ret; + } + + /* Set load for regulator. */ + for (i = 0; i < ARRAY_SIZE(rt5663->supplies); i++) { + ret = regulator_set_load(rt5663->supplies[i].consumer, + RT5663_SUPPLY_CURRENT_UA); + if (ret) { + dev_err(&i2c->dev, + "Failed to set regulator %s, ret: %d\n", + rt5663->supplies[i].supply, ret); + } + } + + ret = regulator_bulk_enable(ARRAY_SIZE(rt5663->supplies), + rt5663->supplies); + + if (ret) { + dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); + return ret; + } + msleep(RT5663_POWER_ON_DELAY_MS); + regmap = devm_regmap_init_i2c(i2c, &temp_regmap); if (IS_ERR(regmap)) { ret = PTR_ERR(regmap); @@ -3527,7 +3568,8 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, dev_err(&i2c->dev, "Device with ID register %#x is not rt5663\n", val); - return -ENODEV; + ret = -ENODEV; + goto err_enable; }
if (IS_ERR(rt5663->regmap)) { @@ -3632,20 +3674,30 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, ret = request_irq(i2c->irq, rt5663_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "rt5663", rt5663); - if (ret) + if (ret) { dev_err(&i2c->dev, "%s Failed to reguest IRQ: %d\n", __func__, ret); + goto err_enable; + } }
ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_rt5663, rt5663_dai, ARRAY_SIZE(rt5663_dai));
- if (ret) { - if (i2c->irq) - free_irq(i2c->irq, rt5663); - } + if (ret) + goto err_irq;
+ return 0; + +err_irq: + if (i2c->irq) + free_irq(i2c->irq, rt5663); + +err_enable: + dev_err(&i2c->dev, + "%s: Disable regulator after probe error\n", __func__); + regulator_bulk_disable(ARRAY_SIZE(rt5663->supplies), rt5663->supplies); return ret; }
@@ -3656,6 +3708,8 @@ static int rt5663_i2c_remove(struct i2c_client *i2c) if (i2c->irq) free_irq(i2c->irq, rt5663);
+ regulator_bulk_disable(ARRAY_SIZE(rt5663->supplies), rt5663->supplies); + return 0; }
On Thu, Nov 15, 2018 at 12:13:33PM +0800, Cheng-Yi Chiang wrote:
+++ b/Documentation/devicetree/bindings/sound/rt5663.txt @@ -36,6 +36,9 @@ Optional properties: "realtek,impedance_sensing_num" is 2. It means that there are 2 ranges of impedance in the impedance sensing function.
+- avdd-supply: Power supply for AVDD, providing 1.8V. +- cpvdd-supply: Power supply for CPVDD, providing 3.5V.
These should be mandatory properties, the device is going to need power to work. The regulator API will handle incompletely specified boards for you, that's not a problem.
participants (2)
-
Cheng-Yi Chiang
-
Mark Brown