aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolin Chen <nicoleotsuka@gmail.com>2016-06-21 19:50:13 -0400
committerMark Brown <broonie@kernel.org>2016-06-23 06:35:52 -0400
commit05f33bc5d6df03426e631cea5d1a8568d43ab07f (patch)
treee1f0294d8420d74f0b9f053d368081cd10958b6e
parentb0e71c0ddda4e1540b38658cac705222a648c756 (diff)
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>
-rw-r--r--Documentation/devicetree/bindings/sound/cs53l30.txt4
-rw-r--r--sound/soc/codecs/cs53l30.c30
-rw-r--r--sound/soc/codecs/cs53l30.h1
3 files changed, 35 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/sound/cs53l30.txt b/Documentation/devicetree/bindings/sound/cs53l30.txt
index 18d6b99e0a2d..4dbfb8274cd9 100644
--- a/Documentation/devicetree/bindings/sound/cs53l30.txt
+++ b/Documentation/devicetree/bindings/sound/cs53l30.txt
@@ -13,6 +13,10 @@ Optional properties:
13 13
14 - reset-gpios : a GPIO spec for the reset pin. 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 - cirrus,micbias-lvl : Set the output voltage level on the MICBIAS Pin. 20 - cirrus,micbias-lvl : Set the output voltage level on the MICBIAS Pin.
17 0 = Hi-Z 21 0 = Hi-Z
18 1 = 1.80 V 22 1 = 1.80 V
diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c
index b0a64a19a045..5988b5c672fe 100644
--- a/sound/soc/codecs/cs53l30.c
+++ b/sound/soc/codecs/cs53l30.c
@@ -35,6 +35,7 @@ struct cs53l30_private {
35 struct regulator_bulk_data supplies[CS53L30_NUM_SUPPLIES]; 35 struct regulator_bulk_data supplies[CS53L30_NUM_SUPPLIES];
36 struct regmap *regmap; 36 struct regmap *regmap;
37 struct gpio_desc *reset_gpio; 37 struct gpio_desc *reset_gpio;
38 struct gpio_desc *mute_gpio;
38 struct clk *mclk; 39 struct clk *mclk;
39 bool use_sdout2; 40 bool use_sdout2;
40 u32 mclk_rate; 41 u32 mclk_rate;
@@ -833,6 +834,16 @@ static int cs53l30_set_dai_tdm_slot(struct snd_soc_dai *dai,
833 return 0; 834 return 0;
834} 835}
835 836
837static int cs53l30_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
838{
839 struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
840
841 if (priv->mute_gpio)
842 gpiod_set_value_cansleep(priv->mute_gpio, mute);
843
844 return 0;
845}
846
836/* SNDRV_PCM_RATE_KNOT -> 12000, 24000 Hz, limit with constraint list */ 847/* SNDRV_PCM_RATE_KNOT -> 12000, 24000 Hz, limit with constraint list */
837#define CS53L30_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT) 848#define CS53L30_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT)
838 849
@@ -846,6 +857,7 @@ static const struct snd_soc_dai_ops cs53l30_ops = {
846 .set_sysclk = cs53l30_set_sysclk, 857 .set_sysclk = cs53l30_set_sysclk,
847 .set_tristate = cs53l30_set_tristate, 858 .set_tristate = cs53l30_set_tristate,
848 .set_tdm_slot = cs53l30_set_dai_tdm_slot, 859 .set_tdm_slot = cs53l30_set_dai_tdm_slot,
860 .mute_stream = cs53l30_mute_stream,
849}; 861};
850 862
851static struct snd_soc_dai_driver cs53l30_dai = { 863static struct snd_soc_dai_driver cs53l30_dai = {
@@ -991,6 +1003,24 @@ static int cs53l30_i2c_probe(struct i2c_client *client,
991 cs53l30->mclk = NULL; 1003 cs53l30->mclk = NULL;
992 } 1004 }
993 1005
1006 /* Fetch the MUTE control */
1007 cs53l30->mute_gpio = devm_gpiod_get_optional(dev, "mute",
1008 GPIOD_OUT_HIGH);
1009 if (IS_ERR(cs53l30->mute_gpio)) {
1010 ret = PTR_ERR(cs53l30->mute_gpio);
1011 goto error;
1012 }
1013
1014 if (cs53l30->mute_gpio) {
1015 /* Enable MUTE controls via MUTE pin */
1016 regmap_write(cs53l30->regmap, CS53L30_MUTEP_CTL1,
1017 CS53L30_MUTEP_CTL1_MUTEALL);
1018 /* Flip the polarity of MUTE pin */
1019 if (gpiod_is_active_low(cs53l30->mute_gpio))
1020 regmap_update_bits(cs53l30->regmap, CS53L30_MUTEP_CTL2,
1021 CS53L30_MUTE_PIN_POLARITY, 0);
1022 }
1023
994 if (!of_property_read_u8(np, "cirrus,micbias-lvl", &val)) 1024 if (!of_property_read_u8(np, "cirrus,micbias-lvl", &val))
995 regmap_update_bits(cs53l30->regmap, CS53L30_MICBIAS_CTL, 1025 regmap_update_bits(cs53l30->regmap, CS53L30_MICBIAS_CTL,
996 CS53L30_MIC_BIAS_CTRL_MASK, val); 1026 CS53L30_MIC_BIAS_CTRL_MASK, val);
diff --git a/sound/soc/codecs/cs53l30.h b/sound/soc/codecs/cs53l30.h
index 0dd4afbb5c64..5e39da568749 100644
--- a/sound/soc/codecs/cs53l30.h
+++ b/sound/soc/codecs/cs53l30.h
@@ -253,6 +253,7 @@
253#define CS53L30_MUTE_MB_ALL_PDN_MASK (1 << CS53L30_MUTE_MB_ALL_PDN_SHIFT) 253#define CS53L30_MUTE_MB_ALL_PDN_MASK (1 << CS53L30_MUTE_MB_ALL_PDN_SHIFT)
254#define CS53L30_MUTE_MB_ALL_PDN (1 << CS53L30_MUTE_MB_ALL_PDN_SHIFT) 254#define CS53L30_MUTE_MB_ALL_PDN (1 << CS53L30_MUTE_MB_ALL_PDN_SHIFT)
255 255
256#define CS53L30_MUTEP_CTL1_MUTEALL (0xdf)
256#define CS53L30_MUTEP_CTL1_DEFAULT (0) 257#define CS53L30_MUTEP_CTL1_DEFAULT (0)
257 258
258/* R32 (0x20) CS53L30_MUTEP_CTL2 - MUTE Pin Control 2 */ 259/* R32 (0x20) CS53L30_MUTEP_CTL2 - MUTE Pin Control 2 */