aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiam Girdwood <lrg@ti.com>2011-07-24 15:59:47 -0400
committerPaolo Pisati <paolo.pisati@canonical.com>2012-08-17 04:18:27 -0400
commitcd575d24e2d09d81ee02685f7c3116626e00319c (patch)
treef683d01f058d6d067e4a2a4a0b82cdb9fb6bddee
parent0532a15e8acd2dcd60fbc6473500b2e970df16e1 (diff)
Subject: [PATCH 083/104] ASoC: OMAP4 - DMIC DAI driver
Add both legacy DMA and ABE support for Digital Microphones on the OMAP4 platform. Signed-off-by: Liam Girdwood <lrg@ti.com>
-rw-r--r--sound/soc/omap/Kconfig3
-rw-r--r--sound/soc/omap/Makefile2
-rw-r--r--sound/soc/omap/omap-dmic.c623
-rw-r--r--sound/soc/omap/omap-dmic.h23
4 files changed, 651 insertions, 0 deletions
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index fb5d2a87a55..e28ca02c71a 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -15,6 +15,9 @@ config SND_OMAP_SOC_MCPDM
15config SND_OMAP_SOC_ABE 15config SND_OMAP_SOC_ABE
16 tristate 16 tristate
17 17
18config SND_OMAP_SOC_DMIC
19 tristate
20
18config SND_OMAP_SOC_N810 21config SND_OMAP_SOC_N810
19 tristate "SoC Audio support for Nokia N810" 22 tristate "SoC Audio support for Nokia N810"
20 depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C 23 depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 0d90f649ce7..7cc549ddb44 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -2,12 +2,14 @@
2snd-soc-omap-objs := omap-pcm.o 2snd-soc-omap-objs := omap-pcm.o
3snd-soc-omap-mcbsp-objs := omap-mcbsp.o 3snd-soc-omap-mcbsp-objs := omap-mcbsp.o
4snd-soc-omap-mcpdm-objs := omap-mcpdm.o 4snd-soc-omap-mcpdm-objs := omap-mcpdm.o
5snd-soc-omap-dmic-objs := omap-dmic.o
5snd-soc-omap-abe-objs := omap-abe.o 6snd-soc-omap-abe-objs := omap-abe.o
6snd-soc-omap-abe-dsp-objs := omap-abe-dsp.o 7snd-soc-omap-abe-dsp-objs := omap-abe-dsp.o
7 8
8obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o 9obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o
9obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o 10obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
10obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o 11obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o
12obj-$(CONFIG_SND_OMAP_SOC_DMIC) += snd-soc-omap-dmic.o
11obj-$(CONFIG_SND_OMAP_SOC_ABE) += snd-soc-omap-abe.o 13obj-$(CONFIG_SND_OMAP_SOC_ABE) += snd-soc-omap-abe.o
12obj-$(CONFIG_SND_OMAP_SOC_ABE_DSP) += snd-soc-omap-abe-dsp.o abe/ 14obj-$(CONFIG_SND_OMAP_SOC_ABE_DSP) += snd-soc-omap-abe-dsp.o abe/
13 15
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
new file mode 100644
index 00000000000..5f8aa2d1a35
--- /dev/null
+++ b/sound/soc/omap/omap-dmic.c
@@ -0,0 +1,623 @@
1/*
2 * omap-dmic.c -- OMAP ASoC DMIC DAI driver
3 *
4 * Copyright (C) 2010 Texas Instruments
5 *
6 * Author: Liam Girdwood <lrg@ti.com>
7 * David Lambert <dlambert@ti.com>
8 * Misael Lopez Cruz <misael.lopez@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 */
25
26#undef DEBUG
27
28#include <linux/init.h>
29#include <linux/module.h>
30#include <linux/platform_device.h>
31#include <linux/err.h>
32#include <linux/clk.h>
33#include <linux/io.h>
34#include <linux/slab.h>
35#include <linux/pm_runtime.h>
36
37#include <plat/dma.h>
38#include <plat/dmic.h>
39
40#include <sound/core.h>
41#include <sound/pcm.h>
42#include <sound/pcm_params.h>
43#include <sound/initval.h>
44#include <sound/soc.h>
45
46#include "omap-pcm.h"
47#include "omap-dmic.h"
48
49#define OMAP_DMIC_RATES (SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
50#define OMAP_DMIC_FORMATS SNDRV_PCM_FMTBIT_S32_LE
51
52#define OMAP4_LEGACY_DMIC0 0
53#define OMAP4_ABE_DMIC0 1
54#define OMAP4_ABE_DMIC1 2
55#define OMAP4_ABE_DMIC2 3
56
57struct omap_dmic {
58 struct device *dev;
59 void __iomem *io_base;
60 int clk_freq;
61 int sysclk;
62 int active;
63 int running;
64 int channels;
65 int abe_mode;
66 u32 up_enable;
67 struct mutex mutex;
68};
69
70/*
71 * Stream DMA parameters
72 */
73static struct omap_pcm_dma_data omap_dmic_dai_dma_params = {
74 .name = "DMIC capture",
75 .data_type = OMAP_DMA_DATA_TYPE_S32,
76 .sync_mode = OMAP_DMA_SYNC_PACKET,
77 .packet_size = 2,
78 .port_addr = OMAP44XX_DMIC_L3_BASE + OMAP_DMIC_DATA,
79};
80
81static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val)
82{
83 __raw_writel(val, dmic->io_base + reg);
84}
85
86static inline int omap_dmic_read(struct omap_dmic *dmic, u16 reg)
87{
88 return __raw_readl(dmic->io_base + reg);
89}
90
91/*
92 * Enables and disables DMIC channels through the DMIC interface
93 */
94static inline void dmic_set_up_channels(struct omap_dmic *dmic)
95{
96 u32 ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL) & ~OMAP_DMIC_UP_ENABLE_MASK;
97 omap_dmic_write(dmic, OMAP_DMIC_CTRL, ctrl | dmic->up_enable);
98}
99
100static inline int dmic_is_enabled(struct omap_dmic *dmic)
101{
102 return omap_dmic_read(dmic, OMAP_DMIC_CTRL) & OMAP_DMIC_UP_ENABLE_MASK;
103}
104
105static int omap_dmic_set_clkdiv(struct snd_soc_dai *dai,
106 int div_id, int div)
107{
108 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
109 int div_sel = -EINVAL;
110 u32 ctrl;
111
112 if (div_id != OMAP_DMIC_CLKDIV)
113 return -ENODEV;
114
115 switch (dmic->clk_freq) {
116 case 19200000:
117 switch (div) {
118 case 5:
119 div_sel = 0x1;
120 break;
121 case 8:
122 div_sel = 0x0;
123 break;
124 default:
125 dev_err(dai->dev, "invalid div_sel (%d) for 19200000Hz", div);
126 return -EINVAL;
127 }
128 break;
129 case 24000000:
130 switch (div) {
131 case 10:
132 div_sel = 0x2;
133 break;
134 default:
135 dev_err(dai->dev, "invalid div_sel (%d) for 24000000Hz", div);
136 return -EINVAL;
137 }
138 break;
139 case 24576000:
140 switch (div) {
141 case 8:
142 div_sel = 0x3;
143 break;
144 case 16:
145 div_sel = 0x4;
146 break;
147 default:
148 dev_err(dai->dev, "invalid div_sel (%d) for 24576000Hz", div);
149 return -EINVAL;
150 }
151 break;
152 case 12000000:
153 switch (div) {
154 case 5:
155 div_sel = 0x5;
156 break;
157 default:
158 dev_err(dai->dev, "invalid div_sel (%d) for 12000000Hz", div);
159 return -EINVAL;
160 }
161 break;
162 default:
163 dev_err(dai->dev, "invalid freq %d\n", dmic->clk_freq);
164 return -EINVAL;
165 }
166
167 if (div_sel < 0) {
168 dev_err(dai->dev, "divider not supported %d\n", div);
169 return -EINVAL;
170 }
171
172 ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL) & ~OMAP_DMIC_CLK_DIV_MASK;
173
174 omap_dmic_write(dmic, OMAP_DMIC_CTRL,
175 ctrl | (div_sel << OMAP_DMIC_CLK_DIV_SHIFT));
176
177 return 0;
178}
179
180/*
181 * Configures DMIC for audio recording.
182 * This function should be called before omap_dmic_start.
183 */
184static void omap_dmic_open(struct omap_dmic *dmic)
185{
186 u32 ctrl;
187
188 /* Configure uplink threshold */
189 omap_dmic_write(dmic, OMAP_DMIC_FIFO_CTRL, 2);
190
191 /* Set dmic out format */
192 ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL)
193 & ~(OMAP_DMIC_FORMAT | OMAP_DMIC_POLAR_MASK);
194 omap_dmic_write(dmic, OMAP_DMIC_CTRL,
195 ctrl | OMAP_DMICOUTFORMAT_LJUST |
196 OMAP_DMIC_POLAR1 | OMAP_DMIC_POLAR2 | OMAP_DMIC_POLAR3);
197}
198
199/*
200 * Cleans DMIC uplink configuration.
201 * This function should be called when the stream is closed.
202 */
203static void omap_dmic_close(struct omap_dmic *dmic)
204{
205 /* Disable DMA request generation */
206 omap_dmic_write(dmic, OMAP_DMIC_DMAENABLE_CLR, OMAP_DMIC_DMA_ENABLE);
207
208}
209
210static int omap_dmic_dai_startup(struct snd_pcm_substream *substream,
211 struct snd_soc_dai *dai)
212{
213 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
214 int ret = 0;
215
216 mutex_lock(&dmic->mutex);
217
218 if (!dmic->active) {
219 pm_runtime_get_sync(dmic->dev);
220
221 if (dai->id > OMAP4_LEGACY_DMIC0)
222 dmic->abe_mode = 1;
223
224 omap_dmic_open(dmic);
225 } else {
226 /* legacy and ABE mode are mutually exclusive */
227 if (dai->id > OMAP4_LEGACY_DMIC0 && !dmic->abe_mode) {
228 ret = -EBUSY;
229 goto out;
230 }
231 }
232
233 dmic->active++;
234
235out:
236 mutex_unlock(&dmic->mutex);
237 return ret;
238}
239
240static void omap_dmic_dai_shutdown(struct snd_pcm_substream *substream,
241 struct snd_soc_dai *dai)
242{
243 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
244
245 mutex_lock(&dmic->mutex);
246
247 if (--dmic->active == 0) {
248 omap_dmic_close(dmic);
249 pm_runtime_put_sync(dmic->dev);
250 dmic->abe_mode = 0;
251 }
252
253 mutex_unlock(&dmic->mutex);
254}
255
256static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
257 struct snd_pcm_hw_params *params,
258 struct snd_soc_dai *dai)
259{
260 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
261 int channels, rate, div;
262 int ret = 0;
263
264 channels = params_channels(params);
265 if (dai->id == OMAP4_LEGACY_DMIC0) {
266 switch (channels) {
267 case 2:
268 case 4:
269 case 6:
270 dmic->channels = channels;
271 break;
272 default:
273 dev_err(dmic->dev, "invalid number of legacy channels\n");
274 return -EINVAL;
275 }
276 } else {
277 if (channels != 2) {
278 dev_err(dmic->dev, "invalid number of ABE channels\n");
279 return -EINVAL;
280 }
281 }
282
283 rate = params_rate(params);
284 switch (rate) {
285 case 96000:
286 div = 8;
287 break;
288 case 192000:
289 div = 5;
290 break;
291 default:
292 dev_err(dmic->dev, "rate %d not supported\n", rate);
293 return -EINVAL;
294 }
295
296 /* packet size is threshold * channels */
297 omap_dmic_dai_dma_params.packet_size = 2 * channels;
298 snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params);
299
300 return ret;
301}
302
303static void dmic_config_up_channels(struct omap_dmic *dmic, int dai_id,
304 int enable)
305{
306 if (enable) {
307 switch (dai_id) {
308 case OMAP4_LEGACY_DMIC0:
309 switch (dmic->channels) {
310 case 6:
311 dmic->up_enable = OMAP_DMIC_UP1_ENABLE | OMAP_DMIC_UP2_ENABLE
312 | OMAP_DMIC_UP3_ENABLE;
313 break;
314 case 4:
315 dmic->up_enable = OMAP_DMIC_UP1_ENABLE | OMAP_DMIC_UP2_ENABLE;
316 break;
317 case 2:
318 dmic->up_enable = OMAP_DMIC_UP1_ENABLE;
319 break;
320 default:
321 break;
322 }
323 break;
324 case OMAP4_ABE_DMIC0:
325 case OMAP4_ABE_DMIC1:
326 case OMAP4_ABE_DMIC2:
327 /*
328 * ABE expects all the DMIC interfaces to be
329 * enabled, so enabling them when at least one
330 * DMIC DAI is running
331 */
332 if (dmic->running)
333 dmic->up_enable |= OMAP_DMIC_UP1_ENABLE |
334 OMAP_DMIC_UP2_ENABLE |
335 OMAP_DMIC_UP3_ENABLE;
336 break;
337 default:
338 break;
339 }
340 } else {
341 switch (dai_id) {
342 case OMAP4_LEGACY_DMIC0:
343 dmic->up_enable = 0;
344 break;
345 case OMAP4_ABE_DMIC0:
346 case OMAP4_ABE_DMIC1:
347 case OMAP4_ABE_DMIC2:
348 /*
349 * Disable all DMIC interfaces only when
350 * all DAIs are stopped
351 */
352 if (!dmic->running)
353 dmic->up_enable = 0;
354 break;
355 default:
356 break;
357 }
358 }
359}
360
361static int omap_dmic_dai_prepare(struct snd_pcm_substream *substream,
362 struct snd_soc_dai *dai)
363{
364 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
365
366 /* Configure DMA controller */
367 omap_dmic_write(dmic, OMAP_DMIC_DMAENABLE_SET, OMAP_DMIC_DMA_ENABLE);
368
369 return 0;
370}
371
372static int omap_dmic_dai_trigger(struct snd_pcm_substream *substream,
373 int cmd, struct snd_soc_dai *dai)
374{
375 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
376
377 switch (cmd) {
378 case SNDRV_PCM_TRIGGER_START:
379 dmic->running++;
380 dmic_config_up_channels(dmic, dai->id, 1);
381 dmic_set_up_channels(dmic);
382 break;
383 case SNDRV_PCM_TRIGGER_STOP:
384 dmic->running--;
385 dmic_config_up_channels(dmic, dai->id, 0);
386 dmic_set_up_channels(dmic);
387 break;
388 default:
389 break;
390 }
391
392 return 0;
393}
394
395static int omap_dmic_set_dai_sysclk(struct snd_soc_dai *dai,
396 int clk_id, unsigned int freq,
397 int dir)
398{
399 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
400 struct clk *dmic_clk, *parent_clk;
401 int ret = 0;
402
403 dmic_clk = clk_get(NULL, "dmic_fck");
404 if (IS_ERR(dmic_clk)) {
405 dev_err(dmic->dev, "cant get dmic_fck\n");
406 return -ENODEV;
407 }
408
409 switch (clk_id) {
410 case OMAP_DMIC_SYSCLK_PAD_CLKS:
411 parent_clk = clk_get(NULL, "pad_clks_ck");
412 if (IS_ERR(parent_clk)) {
413 dev_err(dmic->dev, "cant get pad_clks_ck\n");
414 ret = -ENODEV;
415 goto err_par;
416 }
417 break;
418 case OMAP_DMIC_SYSCLK_SLIMBLUS_CLKS:
419 parent_clk = clk_get(NULL, "slimbus_clk");
420 if (IS_ERR(parent_clk)) {
421 dev_err(dmic->dev, "cant get slimbus_clk\n");
422 ret = -ENODEV;
423 goto err_par;
424 }
425 break;
426 case OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS:
427 parent_clk = clk_get(NULL, "dmic_sync_mux_ck");
428 if (IS_ERR(parent_clk)) {
429 dev_err(dmic->dev, "cant get dmic_sync_mux_ck\n");
430 ret = -ENODEV;
431 goto err_par;
432 }
433 break;
434 default:
435 dev_err(dai->dev, "clk_id not supported %d\n", clk_id);
436 ret = -EINVAL;
437 goto err_par;
438 }
439
440 if (dmic->sysclk != clk_id) {
441 /* re-parent not allowed if a stream is ongoing */
442 if (dmic_is_enabled(dmic)) {
443 dev_err(dmic->dev, "cant re-parent when DMIC active\n");
444 ret = -EBUSY;
445 goto err_busy;
446 }
447
448 /* disable clock while reparenting */
449 pm_runtime_put_sync(dmic->dev);
450 ret = clk_set_parent(dmic_clk, parent_clk);
451 pm_runtime_get_sync(dmic->dev);
452 if (ret < 0) {
453 dev_err(dmic->dev, "re-parent failed\n");
454 goto err_busy;
455 }
456
457 dmic->sysclk = clk_id;
458
459 //ret = clk_set_rate(dmic_clk, freq);
460 if (ret < 0)
461 dev_err(dmic->dev, "clock set to %d Hz failed\n", freq);
462 else
463 dmic->clk_freq = freq;
464 }
465
466err_busy:
467 clk_put(parent_clk);
468err_par:
469 clk_put(dmic_clk);
470
471 return ret;
472}
473
474static struct snd_soc_dai_ops omap_dmic_dai_ops = {
475 .startup = omap_dmic_dai_startup,
476 .shutdown = omap_dmic_dai_shutdown,
477 .hw_params = omap_dmic_dai_hw_params,
478 .prepare = omap_dmic_dai_prepare,
479 .trigger = omap_dmic_dai_trigger,
480 .set_sysclk = omap_dmic_set_dai_sysclk,
481 .set_clkdiv = omap_dmic_set_clkdiv,
482};
483
484static struct snd_soc_dai_driver omap_dmic_dai[] = {
485{
486 .name = "omap-dmic-dai-0",
487 .id = OMAP4_LEGACY_DMIC0,
488 .capture = {
489 .channels_min = 2,
490 .channels_max = 6,
491 .rates = OMAP_DMIC_RATES,
492 .formats = OMAP_DMIC_FORMATS,
493 },
494 .ops = &omap_dmic_dai_ops,
495},
496{
497 .name = "omap-dmic-abe-dai-0",
498 .id = OMAP4_ABE_DMIC0,
499 .capture = {
500 .channels_min = 2,
501 .channels_max = 2,
502 .rates = OMAP_DMIC_RATES,
503 .formats = OMAP_DMIC_FORMATS,
504 },
505 .ops = &omap_dmic_dai_ops,
506},
507{
508 .name = "omap-dmic-abe-dai-1",
509 .id = OMAP4_ABE_DMIC1,
510 .capture = {
511 .channels_min = 2,
512 .channels_max = 2,
513 .rates = OMAP_DMIC_RATES,
514 .formats = OMAP_DMIC_FORMATS,
515 },
516 .ops = &omap_dmic_dai_ops,
517},
518{
519 .name = "omap-dmic-abe-dai-2",
520 .id = OMAP4_ABE_DMIC2,
521 .capture = {
522 .channels_min = 2,
523 .channels_max = 2,
524 .rates = OMAP_DMIC_RATES,
525 .formats = OMAP_DMIC_FORMATS,
526 },
527 .ops = &omap_dmic_dai_ops,
528},
529};
530
531static __devinit int asoc_dmic_probe(struct platform_device *pdev)
532{
533 struct omap_dmic *dmic;
534 struct resource *res;
535 int ret;
536
537 dmic = kzalloc(sizeof(struct omap_dmic), GFP_KERNEL);
538 if (!dmic)
539 return -ENOMEM;
540
541 platform_set_drvdata(pdev, dmic);
542 dmic->dev = &pdev->dev;
543 dmic->sysclk = OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS;
544
545 mutex_init(&dmic->mutex);
546
547 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
548 if (!res) {
549 dev_err(dmic->dev, "invalid memory resource\n");
550 ret = -ENODEV;
551 goto err_res;
552 }
553
554 dmic->io_base = ioremap(res->start, resource_size(res));
555 if (!dmic->io_base) {
556 ret = -ENOMEM;
557 goto err_res;
558 }
559
560 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
561 if (!res) {
562 dev_err(dmic->dev, "invalid dma resource\n");
563 ret = -ENODEV;
564 goto err_dai;
565 }
566 omap_dmic_dai_dma_params.dma_req = res->start;
567
568 pm_runtime_enable(dmic->dev);
569
570 /* Disable lines while request is ongoing */
571 omap_dmic_write(dmic, OMAP_DMIC_CTRL, 0x00);
572
573 ret = snd_soc_register_dais(&pdev->dev, omap_dmic_dai,
574 ARRAY_SIZE(omap_dmic_dai));
575 if (ret)
576 goto err_dai;
577
578 return 0;
579
580err_dai:
581 iounmap(dmic->io_base);
582err_res:
583 kfree(dmic);
584 return ret;
585}
586
587static int __devexit asoc_dmic_remove(struct platform_device *pdev)
588{
589 struct omap_dmic *dmic = platform_get_drvdata(pdev);
590
591 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(omap_dmic_dai));
592 iounmap(dmic->io_base);
593 pm_runtime_disable(dmic->dev);
594 kfree(dmic);
595
596 return 0;
597}
598
599static struct platform_driver asoc_dmic_driver = {
600 .driver = {
601 .name = "omap-dmic-dai",
602 .owner = THIS_MODULE,
603 },
604 .probe = asoc_dmic_probe,
605 .remove = __devexit_p(asoc_dmic_remove),
606};
607
608static int __init snd_omap_dmic_init(void)
609{
610 return platform_driver_register(&asoc_dmic_driver);
611}
612module_init(snd_omap_dmic_init);
613
614static void __exit snd_omap_dmic_exit(void)
615{
616 platform_driver_unregister(&asoc_dmic_driver);
617}
618module_exit(snd_omap_dmic_exit);
619
620MODULE_ALIAS("platform:omap-dmic-dai");
621MODULE_AUTHOR("David Lambert <dlambert@ti.com>");
622MODULE_DESCRIPTION("OMAP DMIC ASoC Interface");
623MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-dmic.h b/sound/soc/omap/omap-dmic.h
new file mode 100644
index 00000000000..728fed2c043
--- /dev/null
+++ b/sound/soc/omap/omap-dmic.h
@@ -0,0 +1,23 @@
1/*
2 * omap-dmic.h -- OMAP Digital Microphone Controller
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _OMAP_DMIC_H
10#define _OMAP_DMIC_H
11
12enum omap_dmic_clk {
13 OMAP_DMIC_SYSCLK_PAD_CLKS, /* PAD_CLKS */
14 OMAP_DMIC_SYSCLK_SLIMBLUS_CLKS, /* SLIMBUS_CLK */
15 OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS, /* DMIC_SYNC_MUX_CLK */
16};
17
18/* DMIC dividers */
19enum omap_dmic_div {
20 OMAP_DMIC_CLKDIV,
21};
22
23#endif