Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: cs53l30: Add MUTE pin control support via GPIO

The codec chip has a physical MUTE pin to let users control it via
GPIO. So this patch add a mute control support to the driver.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Acked-by: Paul Handrigan <Paul.Handrigan@cirrus.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Nicolin Chen and committed by
Mark Brown
05f33bc5 b0e71c0d

+35
+4
Documentation/devicetree/bindings/sound/cs53l30.txt
··· 13 13 14 14 - reset-gpios : a GPIO spec for the reset pin. 15 15 16 + - mute-gpios : a GPIO spec for the MUTE pin. The active state can be either 17 + GPIO_ACTIVE_HIGH or GPIO_ACTIVE_LOW, which would be handled 18 + by the driver automatically. 19 + 16 20 - cirrus,micbias-lvl : Set the output voltage level on the MICBIAS Pin. 17 21 0 = Hi-Z 18 22 1 = 1.80 V
+30
sound/soc/codecs/cs53l30.c
··· 35 35 struct regulator_bulk_data supplies[CS53L30_NUM_SUPPLIES]; 36 36 struct regmap *regmap; 37 37 struct gpio_desc *reset_gpio; 38 + struct gpio_desc *mute_gpio; 38 39 struct clk *mclk; 39 40 bool use_sdout2; 40 41 u32 mclk_rate; ··· 834 833 return 0; 835 834 } 836 835 836 + static int cs53l30_mute_stream(struct snd_soc_dai *dai, int mute, int stream) 837 + { 838 + struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec); 839 + 840 + if (priv->mute_gpio) 841 + gpiod_set_value_cansleep(priv->mute_gpio, mute); 842 + 843 + return 0; 844 + } 845 + 837 846 /* SNDRV_PCM_RATE_KNOT -> 12000, 24000 Hz, limit with constraint list */ 838 847 #define CS53L30_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT) 839 848 ··· 857 846 .set_sysclk = cs53l30_set_sysclk, 858 847 .set_tristate = cs53l30_set_tristate, 859 848 .set_tdm_slot = cs53l30_set_dai_tdm_slot, 849 + .mute_stream = cs53l30_mute_stream, 860 850 }; 861 851 862 852 static struct snd_soc_dai_driver cs53l30_dai = { ··· 1001 989 } 1002 990 /* Otherwise mark the mclk pointer to NULL */ 1003 991 cs53l30->mclk = NULL; 992 + } 993 + 994 + /* Fetch the MUTE control */ 995 + cs53l30->mute_gpio = devm_gpiod_get_optional(dev, "mute", 996 + GPIOD_OUT_HIGH); 997 + if (IS_ERR(cs53l30->mute_gpio)) { 998 + ret = PTR_ERR(cs53l30->mute_gpio); 999 + goto error; 1000 + } 1001 + 1002 + if (cs53l30->mute_gpio) { 1003 + /* Enable MUTE controls via MUTE pin */ 1004 + regmap_write(cs53l30->regmap, CS53L30_MUTEP_CTL1, 1005 + CS53L30_MUTEP_CTL1_MUTEALL); 1006 + /* Flip the polarity of MUTE pin */ 1007 + if (gpiod_is_active_low(cs53l30->mute_gpio)) 1008 + regmap_update_bits(cs53l30->regmap, CS53L30_MUTEP_CTL2, 1009 + CS53L30_MUTE_PIN_POLARITY, 0); 1004 1010 } 1005 1011 1006 1012 if (!of_property_read_u8(np, "cirrus,micbias-lvl", &val))
+1
sound/soc/codecs/cs53l30.h
··· 253 253 #define CS53L30_MUTE_MB_ALL_PDN_MASK (1 << CS53L30_MUTE_MB_ALL_PDN_SHIFT) 254 254 #define CS53L30_MUTE_MB_ALL_PDN (1 << CS53L30_MUTE_MB_ALL_PDN_SHIFT) 255 255 256 + #define CS53L30_MUTEP_CTL1_MUTEALL (0xdf) 256 257 #define CS53L30_MUTEP_CTL1_DEFAULT (0) 257 258 258 259 /* R32 (0x20) CS53L30_MUTEP_CTL2 - MUTE Pin Control 2 */