Merge tag 'v5.15.57' into rpi-5.15.y
[platform/kernel/linux-rpi.git] / sound / soc / bcm / iqaudio-dac.c
1 /*
2  * ASoC Driver for IQaudIO DAC
3  *
4  * Author:      Florian Meier <florian.meier@koalo.de>
5  *              Copyright 2013
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  */
16
17 #include <linux/module.h>
18 #include <linux/gpio/consumer.h>
19 #include <linux/platform_device.h>
20
21 #include <sound/core.h>
22 #include <sound/pcm.h>
23 #include <sound/pcm_params.h>
24 #include <sound/soc.h>
25 #include <sound/jack.h>
26
27 static bool digital_gain_0db_limit = true;
28
29 static struct gpio_desc *mute_gpio;
30
31 static int snd_rpi_iqaudio_dac_init(struct snd_soc_pcm_runtime *rtd)
32 {
33         if (digital_gain_0db_limit)
34         {
35                 int ret;
36                 struct snd_soc_card *card = rtd->card;
37
38                 ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207);
39                 if (ret < 0)
40                         dev_warn(card->dev, "Failed to set volume limit: %d\n", ret);
41         }
42
43         return 0;
44 }
45
46 static void snd_rpi_iqaudio_gpio_mute(struct snd_soc_card *card)
47 {
48         if (mute_gpio) {
49                 dev_info(card->dev, "%s: muting amp using GPIO22\n",
50                          __func__);
51                 gpiod_set_value_cansleep(mute_gpio, 0);
52         }
53 }
54
55 static void snd_rpi_iqaudio_gpio_unmute(struct snd_soc_card *card)
56 {
57         if (mute_gpio) {
58                 dev_info(card->dev, "%s: un-muting amp using GPIO22\n",
59                          __func__);
60                 gpiod_set_value_cansleep(mute_gpio, 1);
61         }
62 }
63
64 static int snd_rpi_iqaudio_set_bias_level(struct snd_soc_card *card,
65         struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
66 {
67         struct snd_soc_pcm_runtime *rtd;
68         struct snd_soc_dai *codec_dai;
69
70         rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]);
71         codec_dai = asoc_rtd_to_codec(rtd, 0);
72
73         if (dapm->dev != codec_dai->dev)
74                 return 0;
75
76         switch (level) {
77         case SND_SOC_BIAS_PREPARE:
78                 if (dapm->bias_level != SND_SOC_BIAS_STANDBY)
79                         break;
80
81                 /* UNMUTE AMP */
82                 snd_rpi_iqaudio_gpio_unmute(card);
83
84                 break;
85         case SND_SOC_BIAS_STANDBY:
86                 if (dapm->bias_level != SND_SOC_BIAS_PREPARE)
87                         break;
88
89                 /* MUTE AMP */
90                 snd_rpi_iqaudio_gpio_mute(card);
91
92                 break;
93         default:
94                 break;
95         }
96
97         return 0;
98 }
99
100 SND_SOC_DAILINK_DEFS(hifi,
101         DAILINK_COMP_ARRAY(COMP_CPU("bcm2708-i2s.0")),
102         DAILINK_COMP_ARRAY(COMP_CODEC("pcm512x.1-004c", "pcm512x-hifi")),
103         DAILINK_COMP_ARRAY(COMP_PLATFORM("bcm2708-i2s.0")));
104
105 static struct snd_soc_dai_link snd_rpi_iqaudio_dac_dai[] = {
106 {
107         .dai_fmt        = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
108                                 SND_SOC_DAIFMT_CBS_CFS,
109         .init           = snd_rpi_iqaudio_dac_init,
110         SND_SOC_DAILINK_REG(hifi),
111 },
112 };
113
114 /* audio machine driver */
115 static struct snd_soc_card snd_rpi_iqaudio_dac = {
116         .owner        = THIS_MODULE,
117         .dai_link     = snd_rpi_iqaudio_dac_dai,
118         .num_links    = ARRAY_SIZE(snd_rpi_iqaudio_dac_dai),
119 };
120
121 static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev)
122 {
123         int ret = 0;
124         bool gpio_unmute = false;
125
126         snd_rpi_iqaudio_dac.dev = &pdev->dev;
127
128         if (pdev->dev.of_node) {
129                 struct device_node *i2s_node;
130                 struct snd_soc_card *card = &snd_rpi_iqaudio_dac;
131                 struct snd_soc_dai_link *dai = &snd_rpi_iqaudio_dac_dai[0];
132                 bool auto_gpio_mute = false;
133
134                 i2s_node = of_parse_phandle(pdev->dev.of_node,
135                                             "i2s-controller", 0);
136                 if (i2s_node) {
137                         dai->cpus->dai_name = NULL;
138                         dai->cpus->of_node = i2s_node;
139                         dai->platforms->name = NULL;
140                         dai->platforms->of_node = i2s_node;
141                 }
142
143                 digital_gain_0db_limit = !of_property_read_bool(
144                         pdev->dev.of_node, "iqaudio,24db_digital_gain");
145
146                 if (of_property_read_string(pdev->dev.of_node, "card_name",
147                                             &card->name))
148                         card->name = "IQaudIODAC";
149
150                 if (of_property_read_string(pdev->dev.of_node, "dai_name",
151                                             &dai->name))
152                         dai->name = "IQaudIO DAC";
153
154                 if (of_property_read_string(pdev->dev.of_node,
155                                         "dai_stream_name", &dai->stream_name))
156                         dai->stream_name = "IQaudIO DAC HiFi";
157
158                 /* gpio_unmute - one time unmute amp using GPIO */
159                 gpio_unmute = of_property_read_bool(pdev->dev.of_node,
160                                                     "iqaudio-dac,unmute-amp");
161
162                 /* auto_gpio_mute - mute/unmute amp using GPIO */
163                 auto_gpio_mute = of_property_read_bool(pdev->dev.of_node,
164                                                 "iqaudio-dac,auto-mute-amp");
165
166                 if (auto_gpio_mute || gpio_unmute) {
167                         mute_gpio = devm_gpiod_get_optional(&pdev->dev, "mute",
168                                                             GPIOD_OUT_LOW);
169                         if (IS_ERR(mute_gpio)) {
170                                 ret = PTR_ERR(mute_gpio);
171                                 dev_err(&pdev->dev,
172                                         "Failed to get mute gpio: %d\n", ret);
173                                 return ret;
174                         }
175
176                         if (auto_gpio_mute && mute_gpio)
177                                 snd_rpi_iqaudio_dac.set_bias_level =
178                                                 snd_rpi_iqaudio_set_bias_level;
179                 }
180         }
181
182         ret = snd_soc_register_card(&snd_rpi_iqaudio_dac);
183         if (ret) {
184                 if (ret != -EPROBE_DEFER)
185                         dev_err(&pdev->dev,
186                                 "snd_soc_register_card() failed: %d\n", ret);
187                 return ret;
188         }
189
190         if (gpio_unmute && mute_gpio)
191                 snd_rpi_iqaudio_gpio_unmute(&snd_rpi_iqaudio_dac);
192
193         return 0;
194 }
195
196 static int snd_rpi_iqaudio_dac_remove(struct platform_device *pdev)
197 {
198         snd_rpi_iqaudio_gpio_mute(&snd_rpi_iqaudio_dac);
199
200         return snd_soc_unregister_card(&snd_rpi_iqaudio_dac);
201 }
202
203 static const struct of_device_id iqaudio_of_match[] = {
204         { .compatible = "iqaudio,iqaudio-dac", },
205         {},
206 };
207 MODULE_DEVICE_TABLE(of, iqaudio_of_match);
208
209 static struct platform_driver snd_rpi_iqaudio_dac_driver = {
210         .driver = {
211                 .name   = "snd-rpi-iqaudio-dac",
212                 .owner  = THIS_MODULE,
213                 .of_match_table = iqaudio_of_match,
214         },
215         .probe          = snd_rpi_iqaudio_dac_probe,
216         .remove         = snd_rpi_iqaudio_dac_remove,
217 };
218
219 module_platform_driver(snd_rpi_iqaudio_dac_driver);
220
221 MODULE_AUTHOR("Florian Meier <florian.meier@koalo.de>");
222 MODULE_DESCRIPTION("ASoC Driver for IQAudio DAC");
223 MODULE_LICENSE("GPL v2");