#include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 
 struct rk3328_codec_priv {
        struct regmap *regmap;
-       struct regmap *grf;
+       struct gpio_desc *mute;
        struct clk *mclk;
        struct clk *pclk;
        unsigned int sclk;
        return 0;
 }
 
-static void rk3328_analog_output(struct rk3328_codec_priv *rk3328, int mute)
-{
-       unsigned int val = BIT(17);
-
-       if (mute)
-               val |= BIT(1);
-
-       regmap_write(rk3328->grf, RK3328_GRF_SOC_CON10, val);
-}
-
 static int rk3328_digital_mute(struct snd_soc_dai *dai, int mute)
 {
        struct rk3328_codec_priv *rk3328 =
        }
 
        msleep(rk3328->spk_depop_time);
-       rk3328_analog_output(rk3328, 1);
+       gpiod_set_value(rk3328->mute, 0);
 
        regmap_update_bits(rk3328->regmap, HPOUTL_GAIN_CTRL,
                           HPOUTL_GAIN_MASK, OUT_VOLUME);
 {
        size_t i;
 
-       rk3328_analog_output(rk3328, 0);
+       gpiod_set_value(rk3328->mute, 1);
 
        regmap_update_bits(rk3328->regmap, HPOUTL_GAIN_CTRL,
                           HPOUTL_GAIN_MASK, 0);
                dev_err(&pdev->dev, "missing 'rockchip,grf'\n");
                return PTR_ERR(grf);
        }
-       rk3328->grf = grf;
        /* enable i2s_acodec_en */
        regmap_write(grf, RK3328_GRF_SOC_CON2,
                     (BIT(14) << 16 | BIT(14)));
                rk3328->spk_depop_time = 200;
        }
 
-       rk3328_analog_output(rk3328, 0);
+       rk3328->mute = gpiod_get_optional(&pdev->dev, "mute", GPIOD_OUT_HIGH);
+       if (IS_ERR(rk3328->mute))
+               return PTR_ERR(rk3328->mute);
+       /*
+        * Rock64 is the only supported platform to have widely relied on
+        * this; if we do happen to come across an old DTB, just leave the
+        * external mute forced off.
+        */
+       if (!rk3328->mute && of_machine_is_compatible("pine64,rock64")) {
+               dev_warn(&pdev->dev, "assuming implicit control of GPIO_MUTE; update devicetree if possible\n");
+               regmap_write(grf, RK3328_GRF_SOC_CON10, BIT(17) | BIT(1));
+       }
 
        rk3328->mclk = devm_clk_get(&pdev->dev, "mclk");
        if (IS_ERR(rk3328->mclk))