28 #include <linux/module.h>
33 #include <linux/slab.h>
64 .name =
"DMIC capture",
77 static inline void omap_dmic_start(
struct omap_dmic *dmic)
88 static inline void omap_dmic_stop(
struct omap_dmic *dmic)
100 static inline int dmic_is_enabled(
struct omap_dmic *dmic)
109 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
121 snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params);
128 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
138 static int omap_dmic_select_divider(
struct omap_dmic *dmic,
int sample_rate)
146 if (sample_rate == 192000) {
151 "invalid clock configuration for 192KHz\n");
188 dev_err(dmic->
dev,
"invalid out frequency: %dHz\n",
196 dev_err(dmic->
dev,
"invalid out frequency %dHz for %dHz input\n",
205 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
211 dev_err(dmic->
dev,
"no valid divider for %dHz from %dHz\n",
227 dev_err(dmic->
dev,
"invalid number of legacy channels\n");
232 dma_data = snd_soc_dai_get_dma_data(dai, substream);
241 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
270 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
274 omap_dmic_start(dmic);
277 omap_dmic_stop(dmic);
286 static int omap_dmic_select_fclk(
struct omap_dmic *dmic,
int clk_id,
289 struct clk *parent_clk;
290 char *parent_clk_name;
300 dev_err(dmic->
dev,
"invalid input frequency: %dHz\n", freq);
305 if (dmic->
sysclk == clk_id) {
311 if (dmic->
active && dmic_is_enabled(dmic)) {
312 dev_err(dmic->
dev,
"can't re-parent when DMIC active\n");
318 parent_clk_name =
"pad_clks_ck";
321 parent_clk_name =
"slimbus_clk";
324 parent_clk_name =
"dmic_sync_mux_ck";
327 dev_err(dmic->
dev,
"fclk clk_id (%d) not supported\n", clk_id);
331 parent_clk =
clk_get(dmic->
dev, parent_clk_name);
332 if (IS_ERR(parent_clk)) {
333 dev_err(dmic->
dev,
"can't get %s\n", parent_clk_name);
340 pm_runtime_put_sync(dmic->
dev);
342 pm_runtime_get_sync(dmic->
dev);
362 static int omap_dmic_select_outclk(
struct omap_dmic *dmic,
int clk_id,
368 dev_err(dmic->
dev,
"output clk_id (%d) not supported\n",
381 dev_err(dmic->
dev,
"invalid out frequency: %dHz\n", freq);
389 static int omap_dmic_set_dai_sysclk(
struct snd_soc_dai *dai,
int clk_id,
390 unsigned int freq,
int dir)
392 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
395 return omap_dmic_select_fclk(dmic, clk_id, freq);
397 return omap_dmic_select_outclk(dmic, clk_id, freq);
399 dev_err(dmic->
dev,
"invalid clock direction (%d)\n", dir);
404 .startup = omap_dmic_dai_startup,
405 .shutdown = omap_dmic_dai_shutdown,
406 .hw_params = omap_dmic_dai_hw_params,
407 .prepare = omap_dmic_dai_prepare,
408 .trigger = omap_dmic_dai_trigger,
409 .set_sysclk = omap_dmic_set_dai_sysclk,
412 static int omap_dmic_probe(
struct snd_soc_dai *dai)
414 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
419 pm_runtime_get_sync(dmic->
dev);
421 pm_runtime_put_sync(dmic->
dev);
428 static int omap_dmic_remove(
struct snd_soc_dai *dai)
430 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
432 pm_runtime_disable(dmic->
dev);
439 .probe = omap_dmic_probe,
440 .remove = omap_dmic_remove,
448 .ops = &omap_dmic_dai_ops,
461 platform_set_drvdata(pdev, dmic);
468 if (IS_ERR(dmic->
fclk)) {
475 dev_err(dmic->
dev,
"invalid dma memory resource\n");
491 dev_err(dmic->
dev,
"invalid memory resource\n");
497 resource_size(res), pdev->
name)) {
498 dev_err(dmic->
dev,
"memory region already claimed\n");
523 struct omap_dmic *dmic = platform_get_drvdata(pdev);
531 static const struct of_device_id omap_dmic_of_match[] = {
532 { .compatible =
"ti,omap4-dmic", },
541 .of_match_table = omap_dmic_of_match,
543 .probe = asoc_dmic_probe,