hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/sound/soc/codecs/dmic.c
....@@ -1,22 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * dmic.c -- SoC audio for Generic Digital MICs
34 *
45 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public License
8
- * version 2 as published by the Free Software Foundation.
9
- *
10
- * This program is distributed in the hope that it will be useful, but
11
- * WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- * General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program; if not, write to the Free Software
17
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18
- * 02110-1301 USA
19
- *
206 */
217
228 #include <linux/delay.h>
....@@ -30,9 +16,39 @@
3016 #include <sound/soc.h>
3117 #include <sound/soc-dapm.h>
3218
19
+#define MAX_MODESWITCH_DELAY 70
20
+static int modeswitch_delay;
21
+module_param(modeswitch_delay, uint, 0644);
22
+
23
+static int wakeup_delay;
24
+module_param(wakeup_delay, uint, 0644);
25
+
3326 struct dmic {
3427 struct gpio_desc *gpio_en;
3528 int wakeup_delay;
29
+ /* Delay after DMIC mode switch */
30
+ int modeswitch_delay;
31
+};
32
+
33
+static int dmic_daiops_trigger(struct snd_pcm_substream *substream,
34
+ int cmd, struct snd_soc_dai *dai)
35
+{
36
+ struct snd_soc_component *component = dai->component;
37
+ struct dmic *dmic = snd_soc_component_get_drvdata(component);
38
+
39
+ switch (cmd) {
40
+ case SNDRV_PCM_TRIGGER_STOP:
41
+ if (dmic->modeswitch_delay)
42
+ mdelay(dmic->modeswitch_delay);
43
+
44
+ break;
45
+ }
46
+
47
+ return 0;
48
+}
49
+
50
+static const struct snd_soc_dai_ops dmic_dai_ops = {
51
+ .trigger = dmic_daiops_trigger,
3652 };
3753
3854 static int dmic_aif_event(struct snd_soc_dapm_widget *w,
....@@ -43,14 +59,14 @@
4359 switch (event) {
4460 case SND_SOC_DAPM_POST_PMU:
4561 if (dmic->gpio_en)
46
- gpiod_set_value(dmic->gpio_en, 1);
62
+ gpiod_set_value_cansleep(dmic->gpio_en, 1);
4763
4864 if (dmic->wakeup_delay)
4965 msleep(dmic->wakeup_delay);
5066 break;
5167 case SND_SOC_DAPM_POST_PMD:
5268 if (dmic->gpio_en)
53
- gpiod_set_value(dmic->gpio_en, 0);
69
+ gpiod_set_value_cansleep(dmic->gpio_en, 0);
5470 break;
5571 }
5672
....@@ -68,6 +84,7 @@
6884 | SNDRV_PCM_FMTBIT_S24_LE
6985 | SNDRV_PCM_FMTBIT_S16_LE,
7086 },
87
+ .ops = &dmic_dai_ops,
7188 };
7289
7390 static int dmic_component_probe(struct snd_soc_component *component)
....@@ -85,6 +102,15 @@
85102
86103 device_property_read_u32(component->dev, "wakeup-delay-ms",
87104 &dmic->wakeup_delay);
105
+ device_property_read_u32(component->dev, "modeswitch-delay-ms",
106
+ &dmic->modeswitch_delay);
107
+ if (wakeup_delay)
108
+ dmic->wakeup_delay = wakeup_delay;
109
+ if (modeswitch_delay)
110
+ dmic->modeswitch_delay = modeswitch_delay;
111
+
112
+ if (dmic->modeswitch_delay > MAX_MODESWITCH_DELAY)
113
+ dmic->modeswitch_delay = MAX_MODESWITCH_DELAY;
88114
89115 snd_soc_component_set_drvdata(component, dmic);
90116
....@@ -148,6 +174,7 @@
148174 {.compatible = "dmic-codec"},
149175 {}
150176 };
177
+MODULE_DEVICE_TABLE(of, dmic_dev_match);
151178
152179 static struct platform_driver dmic_driver = {
153180 .driver = {