1 // SPDX-License-Identifier: GPL-2.0
4 #include <linux/bitfield.h>
6 #include <linux/device.h>
7 #include <linux/interrupt.h>
8 #include <linux/kobject.h>
9 #include <linux/kernel.h>
10 #include <linux/module.h>
12 #include <linux/of_address.h>
13 #include <linux/of_irq.h>
14 #include <linux/of_platform.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/regmap.h>
17 #include <linux/sysfs.h>
18 #include <linux/types.h>
19 #include <linux/dma/imx-dma.h>
20 #include <sound/dmaengine_pcm.h>
21 #include <sound/pcm.h>
22 #include <sound/soc.h>
23 #include <sound/tlv.h>
24 #include <sound/core.h>
26 #include "fsl_micfil.h"
27 #include "fsl_utils.h"
29 #define MICFIL_OSR_DEFAULT 16
41 struct platform_device *pdev;
42 struct regmap *regmap;
43 const struct fsl_micfil_soc_data *soc;
46 struct clk *pll8k_clk;
47 struct clk *pll11k_clk;
48 struct snd_dmaengine_dai_dma_data dma_params_rx;
49 struct sdma_peripheral_config sdmacfg;
50 unsigned int dataline;
52 int irq[MICFIL_IRQ_LINES];
57 struct fsl_micfil_soc_data {
59 unsigned int fifo_depth;
60 unsigned int dataline;
65 static struct fsl_micfil_soc_data fsl_micfil_imx8mm = {
70 .formats = SNDRV_PCM_FMTBIT_S16_LE,
73 static struct fsl_micfil_soc_data fsl_micfil_imx8mp = {
78 .formats = SNDRV_PCM_FMTBIT_S32_LE,
81 static const struct of_device_id fsl_micfil_dt_ids[] = {
82 { .compatible = "fsl,imx8mm-micfil", .data = &fsl_micfil_imx8mm },
83 { .compatible = "fsl,imx8mp-micfil", .data = &fsl_micfil_imx8mp },
86 MODULE_DEVICE_TABLE(of, fsl_micfil_dt_ids);
88 static const char * const micfil_quality_select_texts[] = {
89 [QUALITY_HIGH] = "High",
90 [QUALITY_MEDIUM] = "Medium",
91 [QUALITY_LOW] = "Low",
92 [QUALITY_VLOW0] = "VLow0",
93 [QUALITY_VLOW1] = "Vlow1",
94 [QUALITY_VLOW2] = "Vlow2",
97 static const struct soc_enum fsl_micfil_quality_enum =
98 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(micfil_quality_select_texts),
99 micfil_quality_select_texts);
101 static DECLARE_TLV_DB_SCALE(gain_tlv, 0, 100, 0);
103 static int micfil_set_quality(struct fsl_micfil *micfil)
107 switch (micfil->quality) {
109 qsel = MICFIL_QSEL_HIGH_QUALITY;
112 qsel = MICFIL_QSEL_MEDIUM_QUALITY;
115 qsel = MICFIL_QSEL_LOW_QUALITY;
118 qsel = MICFIL_QSEL_VLOW0_QUALITY;
121 qsel = MICFIL_QSEL_VLOW1_QUALITY;
124 qsel = MICFIL_QSEL_VLOW2_QUALITY;
128 return regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2,
130 FIELD_PREP(MICFIL_CTRL2_QSEL, qsel));
133 static int micfil_quality_get(struct snd_kcontrol *kcontrol,
134 struct snd_ctl_elem_value *ucontrol)
136 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
137 struct fsl_micfil *micfil = snd_soc_component_get_drvdata(cmpnt);
139 ucontrol->value.integer.value[0] = micfil->quality;
144 static int micfil_quality_set(struct snd_kcontrol *kcontrol,
145 struct snd_ctl_elem_value *ucontrol)
147 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
148 struct fsl_micfil *micfil = snd_soc_component_get_drvdata(cmpnt);
150 micfil->quality = ucontrol->value.integer.value[0];
152 return micfil_set_quality(micfil);
155 static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {
156 SOC_SINGLE_SX_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL,
157 MICFIL_OUTGAIN_CHX_SHIFT(0), 0xF, 0x7, gain_tlv),
158 SOC_SINGLE_SX_TLV("CH1 Volume", REG_MICFIL_OUT_CTRL,
159 MICFIL_OUTGAIN_CHX_SHIFT(1), 0xF, 0x7, gain_tlv),
160 SOC_SINGLE_SX_TLV("CH2 Volume", REG_MICFIL_OUT_CTRL,
161 MICFIL_OUTGAIN_CHX_SHIFT(2), 0xF, 0x7, gain_tlv),
162 SOC_SINGLE_SX_TLV("CH3 Volume", REG_MICFIL_OUT_CTRL,
163 MICFIL_OUTGAIN_CHX_SHIFT(3), 0xF, 0x7, gain_tlv),
164 SOC_SINGLE_SX_TLV("CH4 Volume", REG_MICFIL_OUT_CTRL,
165 MICFIL_OUTGAIN_CHX_SHIFT(4), 0xF, 0x7, gain_tlv),
166 SOC_SINGLE_SX_TLV("CH5 Volume", REG_MICFIL_OUT_CTRL,
167 MICFIL_OUTGAIN_CHX_SHIFT(5), 0xF, 0x7, gain_tlv),
168 SOC_SINGLE_SX_TLV("CH6 Volume", REG_MICFIL_OUT_CTRL,
169 MICFIL_OUTGAIN_CHX_SHIFT(6), 0xF, 0x7, gain_tlv),
170 SOC_SINGLE_SX_TLV("CH7 Volume", REG_MICFIL_OUT_CTRL,
171 MICFIL_OUTGAIN_CHX_SHIFT(7), 0xF, 0x7, gain_tlv),
172 SOC_ENUM_EXT("MICFIL Quality Select",
173 fsl_micfil_quality_enum,
174 micfil_quality_get, micfil_quality_set),
177 /* The SRES is a self-negated bit which provides the CPU with the
178 * capability to initialize the PDM Interface module through the
179 * slave-bus interface. This bit always reads as zero, and this
180 * bit is only effective when MDIS is cleared
182 static int fsl_micfil_reset(struct device *dev)
184 struct fsl_micfil *micfil = dev_get_drvdata(dev);
187 ret = regmap_clear_bits(micfil->regmap, REG_MICFIL_CTRL1,
192 ret = regmap_set_bits(micfil->regmap, REG_MICFIL_CTRL1,
198 * SRES is self-cleared bit, but REG_MICFIL_CTRL1 is defined
199 * as non-volatile register, so SRES still remain in regmap
200 * cache after set, that every update of REG_MICFIL_CTRL1,
201 * software reset happens. so clear it explicitly.
203 ret = regmap_clear_bits(micfil->regmap, REG_MICFIL_CTRL1,
209 * Set SRES should clear CHnF flags, But even add delay here
210 * the CHnF may not be cleared sometimes, so clear CHnF explicitly.
212 ret = regmap_write_bits(micfil->regmap, REG_MICFIL_STAT, 0xFF, 0xFF);
219 static int fsl_micfil_startup(struct snd_pcm_substream *substream,
220 struct snd_soc_dai *dai)
222 struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai);
225 dev_err(dai->dev, "micfil dai priv_data not set\n");
232 static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd,
233 struct snd_soc_dai *dai)
235 struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai);
236 struct device *dev = &micfil->pdev->dev;
240 case SNDRV_PCM_TRIGGER_START:
241 case SNDRV_PCM_TRIGGER_RESUME:
242 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
243 ret = fsl_micfil_reset(dev);
245 dev_err(dev, "failed to soft reset\n");
249 /* DMA Interrupt Selection - DISEL bits
250 * 00 - DMA and IRQ disabled
251 * 01 - DMA req enabled
255 ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
257 FIELD_PREP(MICFIL_CTRL1_DISEL, MICFIL_CTRL1_DISEL_DMA));
261 /* Enable the module */
262 ret = regmap_set_bits(micfil->regmap, REG_MICFIL_CTRL1,
263 MICFIL_CTRL1_PDMIEN);
268 case SNDRV_PCM_TRIGGER_STOP:
269 case SNDRV_PCM_TRIGGER_SUSPEND:
270 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
271 /* Disable the module */
272 ret = regmap_clear_bits(micfil->regmap, REG_MICFIL_CTRL1,
273 MICFIL_CTRL1_PDMIEN);
277 ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
279 FIELD_PREP(MICFIL_CTRL1_DISEL, MICFIL_CTRL1_DISEL_DISABLE));
289 static int fsl_micfil_reparent_rootclk(struct fsl_micfil *micfil, unsigned int sample_rate)
291 struct device *dev = &micfil->pdev->dev;
292 u64 ratio = sample_rate;
299 /* Disable clock first, for it was enabled by pm_runtime */
300 clk_disable_unprepare(clk);
301 fsl_asoc_reparent_pll_clocks(dev, clk, micfil->pll8k_clk,
302 micfil->pll11k_clk, ratio);
303 ret = clk_prepare_enable(clk);
310 static int fsl_micfil_hw_params(struct snd_pcm_substream *substream,
311 struct snd_pcm_hw_params *params,
312 struct snd_soc_dai *dai)
314 struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai);
315 unsigned int channels = params_channels(params);
316 unsigned int rate = params_rate(params);
318 int osr = MICFIL_OSR_DEFAULT;
321 /* 1. Disable the module */
322 ret = regmap_clear_bits(micfil->regmap, REG_MICFIL_CTRL1,
323 MICFIL_CTRL1_PDMIEN);
327 /* enable channels */
328 ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
329 0xFF, ((1 << channels) - 1));
333 ret = fsl_micfil_reparent_rootclk(micfil, rate);
337 ret = clk_set_rate(micfil->mclk, rate * clk_div * osr * 8);
341 ret = micfil_set_quality(micfil);
345 ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2,
346 MICFIL_CTRL2_CLKDIV | MICFIL_CTRL2_CICOSR,
347 FIELD_PREP(MICFIL_CTRL2_CLKDIV, clk_div) |
348 FIELD_PREP(MICFIL_CTRL2_CICOSR, 16 - osr));
350 micfil->dma_params_rx.peripheral_config = &micfil->sdmacfg;
351 micfil->dma_params_rx.peripheral_size = sizeof(micfil->sdmacfg);
352 micfil->sdmacfg.n_fifos_src = channels;
353 micfil->sdmacfg.sw_done = true;
354 micfil->dma_params_rx.maxburst = channels * MICFIL_DMA_MAXBURST_RX;
359 static const struct snd_soc_dai_ops fsl_micfil_dai_ops = {
360 .startup = fsl_micfil_startup,
361 .trigger = fsl_micfil_trigger,
362 .hw_params = fsl_micfil_hw_params,
365 static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai)
367 struct fsl_micfil *micfil = dev_get_drvdata(cpu_dai->dev);
368 struct device *dev = cpu_dai->dev;
369 unsigned int val = 0;
372 micfil->quality = QUALITY_VLOW0;
374 /* set default gain to 2 */
375 regmap_write(micfil->regmap, REG_MICFIL_OUT_CTRL, 0x22222222);
377 /* set DC Remover in bypass mode*/
378 for (i = 0; i < MICFIL_OUTPUT_CHANNELS; i++)
379 val |= MICFIL_DC_BYPASS << MICFIL_DC_CHX_SHIFT(i);
380 ret = regmap_update_bits(micfil->regmap, REG_MICFIL_DC_CTRL,
381 MICFIL_DC_CTRL_CONFIG, val);
383 dev_err(dev, "failed to set DC Remover mode bits\n");
386 micfil->dc_remover = MICFIL_DC_BYPASS;
388 snd_soc_dai_init_dma_data(cpu_dai, NULL,
389 &micfil->dma_params_rx);
391 /* FIFO Watermark Control - FIFOWMK*/
392 ret = regmap_update_bits(micfil->regmap, REG_MICFIL_FIFO_CTRL,
393 MICFIL_FIFO_CTRL_FIFOWMK,
394 FIELD_PREP(MICFIL_FIFO_CTRL_FIFOWMK, micfil->soc->fifo_depth - 1));
401 static struct snd_soc_dai_driver fsl_micfil_dai = {
402 .probe = fsl_micfil_dai_probe,
404 .stream_name = "CPU-Capture",
407 .rates = SNDRV_PCM_RATE_8000_48000,
408 .formats = SNDRV_PCM_FMTBIT_S16_LE,
410 .ops = &fsl_micfil_dai_ops,
413 static const struct snd_soc_component_driver fsl_micfil_component = {
414 .name = "fsl-micfil-dai",
415 .controls = fsl_micfil_snd_controls,
416 .num_controls = ARRAY_SIZE(fsl_micfil_snd_controls),
417 .legacy_dai_naming = 1,
421 static const struct reg_default fsl_micfil_reg_defaults[] = {
422 {REG_MICFIL_CTRL1, 0x00000000},
423 {REG_MICFIL_CTRL2, 0x00000000},
424 {REG_MICFIL_STAT, 0x00000000},
425 {REG_MICFIL_FIFO_CTRL, 0x00000007},
426 {REG_MICFIL_FIFO_STAT, 0x00000000},
427 {REG_MICFIL_DATACH0, 0x00000000},
428 {REG_MICFIL_DATACH1, 0x00000000},
429 {REG_MICFIL_DATACH2, 0x00000000},
430 {REG_MICFIL_DATACH3, 0x00000000},
431 {REG_MICFIL_DATACH4, 0x00000000},
432 {REG_MICFIL_DATACH5, 0x00000000},
433 {REG_MICFIL_DATACH6, 0x00000000},
434 {REG_MICFIL_DATACH7, 0x00000000},
435 {REG_MICFIL_DC_CTRL, 0x00000000},
436 {REG_MICFIL_OUT_CTRL, 0x00000000},
437 {REG_MICFIL_OUT_STAT, 0x00000000},
438 {REG_MICFIL_VAD0_CTRL1, 0x00000000},
439 {REG_MICFIL_VAD0_CTRL2, 0x000A0000},
440 {REG_MICFIL_VAD0_STAT, 0x00000000},
441 {REG_MICFIL_VAD0_SCONFIG, 0x00000000},
442 {REG_MICFIL_VAD0_NCONFIG, 0x80000000},
443 {REG_MICFIL_VAD0_NDATA, 0x00000000},
444 {REG_MICFIL_VAD0_ZCD, 0x00000004},
447 static bool fsl_micfil_readable_reg(struct device *dev, unsigned int reg)
450 case REG_MICFIL_CTRL1:
451 case REG_MICFIL_CTRL2:
452 case REG_MICFIL_STAT:
453 case REG_MICFIL_FIFO_CTRL:
454 case REG_MICFIL_FIFO_STAT:
455 case REG_MICFIL_DATACH0:
456 case REG_MICFIL_DATACH1:
457 case REG_MICFIL_DATACH2:
458 case REG_MICFIL_DATACH3:
459 case REG_MICFIL_DATACH4:
460 case REG_MICFIL_DATACH5:
461 case REG_MICFIL_DATACH6:
462 case REG_MICFIL_DATACH7:
463 case REG_MICFIL_DC_CTRL:
464 case REG_MICFIL_OUT_CTRL:
465 case REG_MICFIL_OUT_STAT:
466 case REG_MICFIL_VAD0_CTRL1:
467 case REG_MICFIL_VAD0_CTRL2:
468 case REG_MICFIL_VAD0_STAT:
469 case REG_MICFIL_VAD0_SCONFIG:
470 case REG_MICFIL_VAD0_NCONFIG:
471 case REG_MICFIL_VAD0_NDATA:
472 case REG_MICFIL_VAD0_ZCD:
479 static bool fsl_micfil_writeable_reg(struct device *dev, unsigned int reg)
482 case REG_MICFIL_CTRL1:
483 case REG_MICFIL_CTRL2:
484 case REG_MICFIL_STAT: /* Write 1 to Clear */
485 case REG_MICFIL_FIFO_CTRL:
486 case REG_MICFIL_FIFO_STAT: /* Write 1 to Clear */
487 case REG_MICFIL_DC_CTRL:
488 case REG_MICFIL_OUT_CTRL:
489 case REG_MICFIL_OUT_STAT: /* Write 1 to Clear */
490 case REG_MICFIL_VAD0_CTRL1:
491 case REG_MICFIL_VAD0_CTRL2:
492 case REG_MICFIL_VAD0_STAT: /* Write 1 to Clear */
493 case REG_MICFIL_VAD0_SCONFIG:
494 case REG_MICFIL_VAD0_NCONFIG:
495 case REG_MICFIL_VAD0_ZCD:
502 static bool fsl_micfil_volatile_reg(struct device *dev, unsigned int reg)
505 case REG_MICFIL_STAT:
506 case REG_MICFIL_DATACH0:
507 case REG_MICFIL_DATACH1:
508 case REG_MICFIL_DATACH2:
509 case REG_MICFIL_DATACH3:
510 case REG_MICFIL_DATACH4:
511 case REG_MICFIL_DATACH5:
512 case REG_MICFIL_DATACH6:
513 case REG_MICFIL_DATACH7:
514 case REG_MICFIL_VAD0_STAT:
515 case REG_MICFIL_VAD0_NDATA:
522 static const struct regmap_config fsl_micfil_regmap_config = {
527 .max_register = REG_MICFIL_VAD0_ZCD,
528 .reg_defaults = fsl_micfil_reg_defaults,
529 .num_reg_defaults = ARRAY_SIZE(fsl_micfil_reg_defaults),
530 .readable_reg = fsl_micfil_readable_reg,
531 .volatile_reg = fsl_micfil_volatile_reg,
532 .writeable_reg = fsl_micfil_writeable_reg,
533 .cache_type = REGCACHE_RBTREE,
538 static irqreturn_t micfil_isr(int irq, void *devid)
540 struct fsl_micfil *micfil = (struct fsl_micfil *)devid;
541 struct platform_device *pdev = micfil->pdev;
548 regmap_read(micfil->regmap, REG_MICFIL_STAT, &stat_reg);
549 regmap_read(micfil->regmap, REG_MICFIL_CTRL1, &ctrl1_reg);
550 regmap_read(micfil->regmap, REG_MICFIL_FIFO_STAT, &fifo_stat_reg);
552 dma_enabled = FIELD_GET(MICFIL_CTRL1_DISEL, ctrl1_reg) == MICFIL_CTRL1_DISEL_DMA;
554 /* Channel 0-7 Output Data Flags */
555 for (i = 0; i < MICFIL_OUTPUT_CHANNELS; i++) {
556 if (stat_reg & MICFIL_STAT_CHXF(i))
558 "Data available in Data Channel %d\n", i);
559 /* if DMA is not enabled, field must be written with 1
563 regmap_write_bits(micfil->regmap,
569 for (i = 0; i < MICFIL_FIFO_NUM; i++) {
570 if (fifo_stat_reg & MICFIL_FIFO_STAT_FIFOX_OVER(i))
572 "FIFO Overflow Exception flag for channel %d\n",
575 if (fifo_stat_reg & MICFIL_FIFO_STAT_FIFOX_UNDER(i))
577 "FIFO Underflow Exception flag for channel %d\n",
584 static irqreturn_t micfil_err_isr(int irq, void *devid)
586 struct fsl_micfil *micfil = (struct fsl_micfil *)devid;
587 struct platform_device *pdev = micfil->pdev;
590 regmap_read(micfil->regmap, REG_MICFIL_STAT, &stat_reg);
592 if (stat_reg & MICFIL_STAT_BSY_FIL)
593 dev_dbg(&pdev->dev, "isr: Decimation Filter is running\n");
595 if (stat_reg & MICFIL_STAT_FIR_RDY)
596 dev_dbg(&pdev->dev, "isr: FIR Filter Data ready\n");
598 if (stat_reg & MICFIL_STAT_LOWFREQF) {
599 dev_dbg(&pdev->dev, "isr: ipg_clk_app is too low\n");
600 regmap_write_bits(micfil->regmap, REG_MICFIL_STAT,
601 MICFIL_STAT_LOWFREQF, 1);
607 static int fsl_micfil_probe(struct platform_device *pdev)
609 struct device_node *np = pdev->dev.of_node;
610 struct fsl_micfil *micfil;
611 struct resource *res;
615 micfil = devm_kzalloc(&pdev->dev, sizeof(*micfil), GFP_KERNEL);
620 strncpy(micfil->name, np->name, sizeof(micfil->name) - 1);
622 micfil->soc = of_device_get_match_data(&pdev->dev);
624 /* ipg_clk is used to control the registers
625 * ipg_clk_app is used to operate the filter
627 micfil->mclk = devm_clk_get(&pdev->dev, "ipg_clk_app");
628 if (IS_ERR(micfil->mclk)) {
629 dev_err(&pdev->dev, "failed to get core clock: %ld\n",
630 PTR_ERR(micfil->mclk));
631 return PTR_ERR(micfil->mclk);
634 micfil->busclk = devm_clk_get(&pdev->dev, "ipg_clk");
635 if (IS_ERR(micfil->busclk)) {
636 dev_err(&pdev->dev, "failed to get ipg clock: %ld\n",
637 PTR_ERR(micfil->busclk));
638 return PTR_ERR(micfil->busclk);
641 fsl_asoc_get_pll_clocks(&pdev->dev, &micfil->pll8k_clk,
642 &micfil->pll11k_clk);
645 regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
647 return PTR_ERR(regs);
649 micfil->regmap = devm_regmap_init_mmio(&pdev->dev,
651 &fsl_micfil_regmap_config);
652 if (IS_ERR(micfil->regmap)) {
653 dev_err(&pdev->dev, "failed to init MICFIL regmap: %ld\n",
654 PTR_ERR(micfil->regmap));
655 return PTR_ERR(micfil->regmap);
658 /* dataline mask for RX */
659 ret = of_property_read_u32_index(np,
664 micfil->dataline = 1;
666 if (micfil->dataline & ~micfil->soc->dataline) {
667 dev_err(&pdev->dev, "dataline setting error, Mask is 0x%X\n",
668 micfil->soc->dataline);
673 for (i = 0; i < MICFIL_IRQ_LINES; i++) {
674 micfil->irq[i] = platform_get_irq(pdev, i);
675 if (micfil->irq[i] < 0)
676 return micfil->irq[i];
679 /* Digital Microphone interface interrupt */
680 ret = devm_request_irq(&pdev->dev, micfil->irq[0],
681 micfil_isr, IRQF_SHARED,
682 micfil->name, micfil);
684 dev_err(&pdev->dev, "failed to claim mic interface irq %u\n",
689 /* Digital Microphone interface error interrupt */
690 ret = devm_request_irq(&pdev->dev, micfil->irq[1],
691 micfil_err_isr, IRQF_SHARED,
692 micfil->name, micfil);
694 dev_err(&pdev->dev, "failed to claim mic interface error irq %u\n",
699 micfil->dma_params_rx.chan_name = "rx";
700 micfil->dma_params_rx.addr = res->start + REG_MICFIL_DATACH0;
701 micfil->dma_params_rx.maxburst = MICFIL_DMA_MAXBURST_RX;
703 platform_set_drvdata(pdev, micfil);
705 pm_runtime_enable(&pdev->dev);
706 regcache_cache_only(micfil->regmap, true);
709 * Register platform component before registering cpu dai for there
710 * is not defer probe for platform component in snd_soc_add_pcm_runtime().
712 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
714 dev_err(&pdev->dev, "failed to pcm register\n");
718 fsl_micfil_dai.capture.formats = micfil->soc->formats;
720 ret = devm_snd_soc_register_component(&pdev->dev, &fsl_micfil_component,
723 dev_err(&pdev->dev, "failed to register component %s\n",
724 fsl_micfil_component.name);
730 static int __maybe_unused fsl_micfil_runtime_suspend(struct device *dev)
732 struct fsl_micfil *micfil = dev_get_drvdata(dev);
734 regcache_cache_only(micfil->regmap, true);
736 clk_disable_unprepare(micfil->mclk);
737 clk_disable_unprepare(micfil->busclk);
742 static int __maybe_unused fsl_micfil_runtime_resume(struct device *dev)
744 struct fsl_micfil *micfil = dev_get_drvdata(dev);
747 ret = clk_prepare_enable(micfil->busclk);
751 ret = clk_prepare_enable(micfil->mclk);
753 clk_disable_unprepare(micfil->busclk);
757 regcache_cache_only(micfil->regmap, false);
758 regcache_mark_dirty(micfil->regmap);
759 regcache_sync(micfil->regmap);
764 static int __maybe_unused fsl_micfil_suspend(struct device *dev)
766 pm_runtime_force_suspend(dev);
771 static int __maybe_unused fsl_micfil_resume(struct device *dev)
773 pm_runtime_force_resume(dev);
778 static const struct dev_pm_ops fsl_micfil_pm_ops = {
779 SET_RUNTIME_PM_OPS(fsl_micfil_runtime_suspend,
780 fsl_micfil_runtime_resume,
782 SET_SYSTEM_SLEEP_PM_OPS(fsl_micfil_suspend,
786 static struct platform_driver fsl_micfil_driver = {
787 .probe = fsl_micfil_probe,
789 .name = "fsl-micfil-dai",
790 .pm = &fsl_micfil_pm_ops,
791 .of_match_table = fsl_micfil_dt_ids,
794 module_platform_driver(fsl_micfil_driver);
796 MODULE_AUTHOR("Cosmin-Gabriel Samoila <cosmin.samoila@nxp.com>");
797 MODULE_DESCRIPTION("NXP PDM Microphone Interface (MICFIL) driver");
798 MODULE_LICENSE("GPL v2");