ASoC: tas6424: Add support for the mute pin
authorJean-Jacques Hiblot <jjhiblot@ti.com>
Fri, 27 Apr 2018 13:55:48 +0000 (15:55 +0200)
committerMark Brown <broonie@kernel.org>
Fri, 27 Apr 2018 18:24:01 +0000 (19:24 +0100)
mute can be connected to GPIO. In that case we have to drive it to the
correct value

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Documentation/devicetree/bindings/sound/ti,tas6424.txt
sound/soc/codecs/tas6424.c

index df71e414dc5be271e21480ed0280a7f004b6b3d5..eacb54f34188fa6cf10f3ad101b1c70bf590a488 100644 (file)
@@ -7,6 +7,7 @@ Required properties:
        - reg: I2C slave address
        - sound-dai-cells: must be equal to 0
        - standby-gpios: GPIO used to shut the TAS6424 down.
+       - mute-gpios: GPIO used to mute all the outputs
 
 Example:
 
index 5abb17f8d3dda2382e7c6843bf3b00197ab438cc..89fd0c1b39037350db34b848c4a2012d64392e65 100644 (file)
@@ -45,6 +45,7 @@ struct tas6424_data {
        unsigned int last_fault2;
        unsigned int last_warn;
        struct gpio_desc *standby_gpio;
+       struct gpio_desc *mute_gpio;
 };
 
 /*
@@ -251,10 +252,16 @@ static int tas6424_set_dai_tdm_slot(struct snd_soc_dai *dai,
 static int tas6424_mute(struct snd_soc_dai *dai, int mute)
 {
        struct snd_soc_component *component = dai->component;
+       struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component);
        unsigned int val;
 
        dev_dbg(component->dev, "%s() mute=%d\n", __func__, mute);
 
+       if (tas6424->mute_gpio) {
+               gpiod_set_value_cansleep(tas6424->mute_gpio, mute);
+               return 0;
+       }
+
        if (mute)
                val = TAS6424_ALL_STATE_MUTE;
        else
@@ -289,6 +296,7 @@ static int tas6424_power_on(struct snd_soc_component *component)
 {
        struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component);
        int ret;
+       u8 chan_states;
 
        ret = regulator_bulk_enable(ARRAY_SIZE(tas6424->supplies),
                                    tas6424->supplies);
@@ -305,7 +313,18 @@ static int tas6424_power_on(struct snd_soc_component *component)
                return ret;
        }
 
-       snd_soc_component_write(component, TAS6424_CH_STATE_CTRL, TAS6424_ALL_STATE_MUTE);
+       if (tas6424->mute_gpio) {
+               gpiod_set_value_cansleep(tas6424->mute_gpio, 0);
+               /*
+                * channels are muted via the mute pin.  Don't also mute
+                * them via the registers so that subsequent register
+                * access is not necessary to un-mute the channels
+                */
+               chan_states = TAS6424_ALL_STATE_PLAY;
+       } else {
+               chan_states = TAS6424_ALL_STATE_MUTE;
+       }
+       snd_soc_component_write(component, TAS6424_CH_STATE_CTRL, chan_states);
 
        /* any time we come out of HIZ, the output channels automatically run DC
         * load diagnostics, wait here until this completes
@@ -645,6 +664,22 @@ static int tas6424_i2c_probe(struct i2c_client *client,
                tas6424->standby_gpio = NULL;
        }
 
+       /*
+        * Get control of the mute pin and set it HIGH in order to start with
+        * all the output muted.
+        * Note: The actual pin polarity is taken care of in the GPIO lib
+        * according the polarity specified in the DTS.
+        */
+       tas6424->mute_gpio = devm_gpiod_get_optional(dev, "mute",
+                                                     GPIOD_OUT_HIGH);
+       if (IS_ERR(tas6424->mute_gpio)) {
+               if (PTR_ERR(tas6424->mute_gpio) == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+               dev_info(dev, "failed to get nmute GPIO: %ld\n",
+                       PTR_ERR(tas6424->mute_gpio));
+               tas6424->mute_gpio = NULL;
+       }
+
        for (i = 0; i < ARRAY_SIZE(tas6424->supplies); i++)
                tas6424->supplies[i].supply = tas6424_supply_names[i];
        ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(tas6424->supplies),