Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: Add MICFIL SoC Digital Audio Interface driver.

Add Digital Audio Interface driver that convers PDM bitstream to PCM
format.

Features:
- Fixed filtering characteristics for audio application.
- Full or partial set of channels operation with individual enable control.
- Programmable PDM clock generator.
- Programmable decimation rate.
- 16-bit signed output result.
- Overall stopband attenuation more than 80dB.
- Overall passband ripple less than 0.2dB.

Signed-off-by: Cosmin-Gabriel Samoila <cosmin.samoila@nxp.com>
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Cosmin Samoila and committed by
Mark Brown
47a70e6f e595da28

+1120
+9
sound/soc/fsl/Kconfig
··· 57 57 This option is only useful for out-of-tree drivers since 58 58 in-tree drivers select it automatically. 59 59 60 + config SND_SOC_FSL_MICFIL 61 + tristate "Pulse Density Modulation Microphone Interface (MICFIL) module support" 62 + select REGMAP_MMIO 63 + select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n 64 + select SND_SOC_GENERIC_DMAENGINE_PCM 65 + help 66 + Say Y if you want to add Pulse Density Modulation microphone 67 + interface (MICFIL) support for NXP. 68 + 60 69 config SND_SOC_FSL_UTILS 61 70 tristate 62 71
+2
sound/soc/fsl/Makefile
··· 19 19 snd-soc-fsl-ssi-$(CONFIG_DEBUG_FS) += fsl_ssi_dbg.o 20 20 snd-soc-fsl-spdif-objs := fsl_spdif.o 21 21 snd-soc-fsl-esai-objs := fsl_esai.o 22 + snd-soc-fsl-micfil-objs := fsl_micfil.o 22 23 snd-soc-fsl-utils-objs := fsl_utils.o 23 24 snd-soc-fsl-dma-objs := fsl_dma.o 24 25 obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o ··· 28 27 obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o 29 28 obj-$(CONFIG_SND_SOC_FSL_SPDIF) += snd-soc-fsl-spdif.o 30 29 obj-$(CONFIG_SND_SOC_FSL_ESAI) += snd-soc-fsl-esai.o 30 + obj-$(CONFIG_SND_SOC_FSL_MICFIL) += snd-soc-fsl-micfil.o 31 31 obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o 32 32 obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o 33 33
+826
sound/soc/fsl/fsl_micfil.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright 2018 NXP 3 + 4 + #include <linux/clk.h> 5 + #include <linux/device.h> 6 + #include <linux/interrupt.h> 7 + #include <linux/kobject.h> 8 + #include <linux/kernel.h> 9 + #include <linux/module.h> 10 + #include <linux/of.h> 11 + #include <linux/of_address.h> 12 + #include <linux/of_irq.h> 13 + #include <linux/of_platform.h> 14 + #include <linux/pm_runtime.h> 15 + #include <linux/regmap.h> 16 + #include <linux/sysfs.h> 17 + #include <linux/types.h> 18 + #include <sound/dmaengine_pcm.h> 19 + #include <sound/pcm.h> 20 + #include <sound/soc.h> 21 + #include <sound/tlv.h> 22 + #include <sound/core.h> 23 + 24 + #include "fsl_micfil.h" 25 + #include "imx-pcm.h" 26 + 27 + #define FSL_MICFIL_RATES SNDRV_PCM_RATE_8000_48000 28 + #define FSL_MICFIL_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) 29 + 30 + struct fsl_micfil { 31 + struct platform_device *pdev; 32 + struct regmap *regmap; 33 + const struct fsl_micfil_soc_data *soc; 34 + struct clk *mclk; 35 + struct snd_dmaengine_dai_dma_data dma_params_rx; 36 + unsigned int dataline; 37 + char name[32]; 38 + int irq[MICFIL_IRQ_LINES]; 39 + unsigned int mclk_streams; 40 + int quality; /*QUALITY 2-0 bits */ 41 + bool slave_mode; 42 + int channel_gain[8]; 43 + }; 44 + 45 + struct fsl_micfil_soc_data { 46 + unsigned int fifos; 47 + unsigned int fifo_depth; 48 + unsigned int dataline; 49 + bool imx; 50 + }; 51 + 52 + static struct fsl_micfil_soc_data fsl_micfil_imx8mm = { 53 + .imx = true, 54 + .fifos = 8, 55 + .fifo_depth = 8, 56 + .dataline = 0xf, 57 + }; 58 + 59 + static const struct of_device_id fsl_micfil_dt_ids[] = { 60 + { .compatible = "fsl,imx8mm-micfil", .data = &fsl_micfil_imx8mm }, 61 + {} 62 + }; 63 + MODULE_DEVICE_TABLE(of, fsl_micfil_dt_ids); 64 + 65 + /* Table 5. Quality Modes 66 + * Medium 0 0 0 67 + * High 0 0 1 68 + * Very Low 2 1 0 0 69 + * Very Low 1 1 0 1 70 + * Very Low 0 1 1 0 71 + * Low 1 1 1 72 + */ 73 + static const char * const micfil_quality_select_texts[] = { 74 + "Medium", "High", 75 + "N/A", "N/A", 76 + "VLow2", "VLow1", 77 + "VLow0", "Low", 78 + }; 79 + 80 + static const struct soc_enum fsl_micfil_quality_enum = 81 + SOC_ENUM_SINGLE(REG_MICFIL_CTRL2, 82 + MICFIL_CTRL2_QSEL_SHIFT, 83 + ARRAY_SIZE(micfil_quality_select_texts), 84 + micfil_quality_select_texts); 85 + 86 + static DECLARE_TLV_DB_SCALE(gain_tlv, 0, 100, 0); 87 + 88 + static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = { 89 + SOC_SINGLE_SX_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL, 90 + MICFIL_OUTGAIN_CHX_SHIFT(0), 0xF, 0x7, gain_tlv), 91 + SOC_SINGLE_SX_TLV("CH1 Volume", REG_MICFIL_OUT_CTRL, 92 + MICFIL_OUTGAIN_CHX_SHIFT(1), 0xF, 0x7, gain_tlv), 93 + SOC_SINGLE_SX_TLV("CH2 Volume", REG_MICFIL_OUT_CTRL, 94 + MICFIL_OUTGAIN_CHX_SHIFT(2), 0xF, 0x7, gain_tlv), 95 + SOC_SINGLE_SX_TLV("CH3 Volume", REG_MICFIL_OUT_CTRL, 96 + MICFIL_OUTGAIN_CHX_SHIFT(3), 0xF, 0x7, gain_tlv), 97 + SOC_SINGLE_SX_TLV("CH4 Volume", REG_MICFIL_OUT_CTRL, 98 + MICFIL_OUTGAIN_CHX_SHIFT(4), 0xF, 0x7, gain_tlv), 99 + SOC_SINGLE_SX_TLV("CH5 Volume", REG_MICFIL_OUT_CTRL, 100 + MICFIL_OUTGAIN_CHX_SHIFT(5), 0xF, 0x7, gain_tlv), 101 + SOC_SINGLE_SX_TLV("CH6 Volume", REG_MICFIL_OUT_CTRL, 102 + MICFIL_OUTGAIN_CHX_SHIFT(6), 0xF, 0x7, gain_tlv), 103 + SOC_SINGLE_SX_TLV("CH7 Volume", REG_MICFIL_OUT_CTRL, 104 + MICFIL_OUTGAIN_CHX_SHIFT(7), 0xF, 0x7, gain_tlv), 105 + SOC_ENUM_EXT("MICFIL Quality Select", 106 + fsl_micfil_quality_enum, 107 + snd_soc_get_enum_double, snd_soc_put_enum_double), 108 + }; 109 + 110 + static inline int get_pdm_clk(struct fsl_micfil *micfil, 111 + unsigned int rate) 112 + { 113 + u32 ctrl2_reg; 114 + int qsel, osr; 115 + int bclk; 116 + 117 + regmap_read(micfil->regmap, REG_MICFIL_CTRL2, &ctrl2_reg); 118 + osr = 16 - ((ctrl2_reg & MICFIL_CTRL2_CICOSR_MASK) 119 + >> MICFIL_CTRL2_CICOSR_SHIFT); 120 + 121 + regmap_read(micfil->regmap, REG_MICFIL_CTRL2, &ctrl2_reg); 122 + qsel = ctrl2_reg & MICFIL_CTRL2_QSEL_MASK; 123 + 124 + switch (qsel) { 125 + case MICFIL_HIGH_QUALITY: 126 + bclk = rate * 8 * osr / 2; /* kfactor = 0.5 */ 127 + break; 128 + case MICFIL_MEDIUM_QUALITY: 129 + case MICFIL_VLOW0_QUALITY: 130 + bclk = rate * 4 * osr * 1; /* kfactor = 1 */ 131 + break; 132 + case MICFIL_LOW_QUALITY: 133 + case MICFIL_VLOW1_QUALITY: 134 + bclk = rate * 2 * osr * 2; /* kfactor = 2 */ 135 + break; 136 + case MICFIL_VLOW2_QUALITY: 137 + bclk = rate * osr * 4; /* kfactor = 4 */ 138 + break; 139 + default: 140 + dev_err(&micfil->pdev->dev, 141 + "Please make sure you select a valid quality.\n"); 142 + bclk = -1; 143 + break; 144 + } 145 + 146 + return bclk; 147 + } 148 + 149 + static inline int get_clk_div(struct fsl_micfil *micfil, 150 + unsigned int rate) 151 + { 152 + u32 ctrl2_reg; 153 + long mclk_rate; 154 + int osr; 155 + int clk_div; 156 + 157 + regmap_read(micfil->regmap, REG_MICFIL_CTRL2, &ctrl2_reg); 158 + osr = 16 - ((ctrl2_reg & MICFIL_CTRL2_CICOSR_MASK) 159 + >> MICFIL_CTRL2_CICOSR_SHIFT); 160 + 161 + mclk_rate = clk_get_rate(micfil->mclk); 162 + 163 + clk_div = mclk_rate / (get_pdm_clk(micfil, rate) * 2); 164 + 165 + return clk_div; 166 + } 167 + 168 + /* The SRES is a self-negated bit which provides the CPU with the 169 + * capability to initialize the PDM Interface module through the 170 + * slave-bus interface. This bit always reads as zero, and this 171 + * bit is only effective when MDIS is cleared 172 + */ 173 + static int fsl_micfil_reset(struct device *dev) 174 + { 175 + struct fsl_micfil *micfil = dev_get_drvdata(dev); 176 + int ret; 177 + 178 + ret = regmap_update_bits(micfil->regmap, 179 + REG_MICFIL_CTRL1, 180 + MICFIL_CTRL1_MDIS_MASK, 181 + 0); 182 + if (ret) { 183 + dev_err(dev, "failed to clear MDIS bit %d\n", ret); 184 + return ret; 185 + } 186 + 187 + ret = regmap_update_bits(micfil->regmap, 188 + REG_MICFIL_CTRL1, 189 + MICFIL_CTRL1_SRES_MASK, 190 + MICFIL_CTRL1_SRES); 191 + if (ret) { 192 + dev_err(dev, "failed to reset MICFIL: %d\n", ret); 193 + return ret; 194 + } 195 + 196 + return 0; 197 + } 198 + 199 + static int fsl_micfil_set_mclk_rate(struct fsl_micfil *micfil, 200 + unsigned int freq) 201 + { 202 + struct device *dev = &micfil->pdev->dev; 203 + int ret; 204 + 205 + clk_disable_unprepare(micfil->mclk); 206 + 207 + ret = clk_set_rate(micfil->mclk, freq * 1024); 208 + if (ret) 209 + dev_warn(dev, "failed to set rate (%u): %d\n", 210 + freq * 1024, ret); 211 + 212 + clk_prepare_enable(micfil->mclk); 213 + 214 + return ret; 215 + } 216 + 217 + static int fsl_micfil_startup(struct snd_pcm_substream *substream, 218 + struct snd_soc_dai *dai) 219 + { 220 + struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai); 221 + 222 + if (!micfil) { 223 + dev_err(dai->dev, 224 + "micfil dai priv_data not set\n"); 225 + return -EINVAL; 226 + } 227 + 228 + return 0; 229 + } 230 + 231 + static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd, 232 + struct snd_soc_dai *dai) 233 + { 234 + struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai); 235 + struct device *dev = &micfil->pdev->dev; 236 + int ret; 237 + 238 + switch (cmd) { 239 + case SNDRV_PCM_TRIGGER_START: 240 + case SNDRV_PCM_TRIGGER_RESUME: 241 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 242 + ret = fsl_micfil_reset(dev); 243 + if (ret) { 244 + dev_err(dev, "failed to soft reset\n"); 245 + return ret; 246 + } 247 + 248 + /* DMA Interrupt Selection - DISEL bits 249 + * 00 - DMA and IRQ disabled 250 + * 01 - DMA req enabled 251 + * 10 - IRQ enabled 252 + * 11 - reserved 253 + */ 254 + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1, 255 + MICFIL_CTRL1_DISEL_MASK, 256 + (1 << MICFIL_CTRL1_DISEL_SHIFT)); 257 + if (ret) { 258 + dev_err(dev, "failed to update DISEL bits\n"); 259 + return ret; 260 + } 261 + 262 + /* Enable the module */ 263 + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1, 264 + MICFIL_CTRL1_PDMIEN_MASK, 265 + MICFIL_CTRL1_PDMIEN); 266 + if (ret) { 267 + dev_err(dev, "failed to enable the module\n"); 268 + return ret; 269 + } 270 + 271 + break; 272 + case SNDRV_PCM_TRIGGER_STOP: 273 + case SNDRV_PCM_TRIGGER_SUSPEND: 274 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 275 + /* Disable the module */ 276 + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1, 277 + MICFIL_CTRL1_PDMIEN_MASK, 278 + 0); 279 + if (ret) { 280 + dev_err(dev, "failed to enable the module\n"); 281 + return ret; 282 + } 283 + 284 + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1, 285 + MICFIL_CTRL1_DISEL_MASK, 286 + (0 << MICFIL_CTRL1_DISEL_SHIFT)); 287 + if (ret) { 288 + dev_err(dev, "failed to update DISEL bits\n"); 289 + return ret; 290 + } 291 + break; 292 + default: 293 + return -EINVAL; 294 + } 295 + return 0; 296 + } 297 + 298 + static int fsl_set_clock_params(struct device *dev, unsigned int rate) 299 + { 300 + struct fsl_micfil *micfil = dev_get_drvdata(dev); 301 + int clk_div; 302 + int ret = 0; 303 + 304 + ret = fsl_micfil_set_mclk_rate(micfil, rate); 305 + if (ret < 0) 306 + dev_err(dev, "failed to set mclk[%lu] to rate %u\n", 307 + clk_get_rate(micfil->mclk), rate); 308 + 309 + /* set CICOSR */ 310 + ret |= regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2, 311 + MICFIL_CTRL2_CICOSR_MASK, 312 + MICFIL_CTRL2_OSR_DEFAULT); 313 + if (ret) 314 + dev_err(dev, "failed to set CICOSR in reg 0x%X\n", 315 + REG_MICFIL_CTRL2); 316 + 317 + /* set CLK_DIV */ 318 + clk_div = get_clk_div(micfil, rate); 319 + if (clk_div < 0) 320 + ret = -EINVAL; 321 + 322 + ret |= regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2, 323 + MICFIL_CTRL2_CLKDIV_MASK, clk_div); 324 + if (ret) 325 + dev_err(dev, "failed to set CLKDIV in reg 0x%X\n", 326 + REG_MICFIL_CTRL2); 327 + 328 + return ret; 329 + } 330 + 331 + static int fsl_micfil_hw_params(struct snd_pcm_substream *substream, 332 + struct snd_pcm_hw_params *params, 333 + struct snd_soc_dai *dai) 334 + { 335 + struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai); 336 + unsigned int channels = params_channels(params); 337 + unsigned int rate = params_rate(params); 338 + struct device *dev = &micfil->pdev->dev; 339 + int ret; 340 + 341 + /* 1. Disable the module */ 342 + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1, 343 + MICFIL_CTRL1_PDMIEN_MASK, 0); 344 + if (ret) { 345 + dev_err(dev, "failed to disable the module\n"); 346 + return ret; 347 + } 348 + 349 + /* enable channels */ 350 + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1, 351 + 0xFF, ((1 << channels) - 1)); 352 + if (ret) { 353 + dev_err(dev, "failed to enable channels %d, reg 0x%X\n", ret, 354 + REG_MICFIL_CTRL1); 355 + return ret; 356 + } 357 + 358 + ret = fsl_set_clock_params(dev, rate); 359 + if (ret < 0) { 360 + dev_err(dev, "Failed to set clock parameters [%d]\n", ret); 361 + return ret; 362 + } 363 + 364 + micfil->dma_params_rx.maxburst = channels * MICFIL_DMA_MAXBURST_RX; 365 + 366 + return 0; 367 + } 368 + 369 + static int fsl_micfil_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, 370 + unsigned int freq, int dir) 371 + { 372 + struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai); 373 + struct device *dev = &micfil->pdev->dev; 374 + 375 + int ret; 376 + 377 + if (!freq) 378 + return 0; 379 + 380 + ret = fsl_micfil_set_mclk_rate(micfil, freq); 381 + if (ret < 0) 382 + dev_err(dev, "failed to set mclk[%lu] to rate %u\n", 383 + clk_get_rate(micfil->mclk), freq); 384 + 385 + return ret; 386 + } 387 + 388 + static struct snd_soc_dai_ops fsl_micfil_dai_ops = { 389 + .startup = fsl_micfil_startup, 390 + .trigger = fsl_micfil_trigger, 391 + .hw_params = fsl_micfil_hw_params, 392 + .set_sysclk = fsl_micfil_set_dai_sysclk, 393 + }; 394 + 395 + static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai) 396 + { 397 + struct fsl_micfil *micfil = dev_get_drvdata(cpu_dai->dev); 398 + struct device *dev = cpu_dai->dev; 399 + unsigned int val; 400 + int ret; 401 + int i; 402 + 403 + /* set qsel to medium */ 404 + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2, 405 + MICFIL_CTRL2_QSEL_MASK, MICFIL_MEDIUM_QUALITY); 406 + if (ret) { 407 + dev_err(dev, "failed to set quality mode bits, reg 0x%X\n", 408 + REG_MICFIL_CTRL2); 409 + return ret; 410 + } 411 + 412 + /* set default gain to max_gain */ 413 + regmap_write(micfil->regmap, REG_MICFIL_OUT_CTRL, 0x77777777); 414 + for (i = 0; i < 8; i++) 415 + micfil->channel_gain[i] = 0xF; 416 + 417 + snd_soc_dai_init_dma_data(cpu_dai, NULL, 418 + &micfil->dma_params_rx); 419 + 420 + /* FIFO Watermark Control - FIFOWMK*/ 421 + val = MICFIL_FIFO_CTRL_FIFOWMK(micfil->soc->fifo_depth) - 1; 422 + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_FIFO_CTRL, 423 + MICFIL_FIFO_CTRL_FIFOWMK_MASK, 424 + val); 425 + if (ret) { 426 + dev_err(dev, "failed to set FIFOWMK\n"); 427 + return ret; 428 + } 429 + 430 + snd_soc_dai_set_drvdata(cpu_dai, micfil); 431 + 432 + return 0; 433 + } 434 + 435 + static struct snd_soc_dai_driver fsl_micfil_dai = { 436 + .probe = fsl_micfil_dai_probe, 437 + .capture = { 438 + .stream_name = "CPU-Capture", 439 + .channels_min = 1, 440 + .channels_max = 8, 441 + .rates = FSL_MICFIL_RATES, 442 + .formats = FSL_MICFIL_FORMATS, 443 + }, 444 + .ops = &fsl_micfil_dai_ops, 445 + }; 446 + 447 + static const struct snd_soc_component_driver fsl_micfil_component = { 448 + .name = "fsl-micfil-dai", 449 + .controls = fsl_micfil_snd_controls, 450 + .num_controls = ARRAY_SIZE(fsl_micfil_snd_controls), 451 + 452 + }; 453 + 454 + /* REGMAP */ 455 + static const struct reg_default fsl_micfil_reg_defaults[] = { 456 + {REG_MICFIL_CTRL1, 0x00000000}, 457 + {REG_MICFIL_CTRL2, 0x00000000}, 458 + {REG_MICFIL_STAT, 0x00000000}, 459 + {REG_MICFIL_FIFO_CTRL, 0x00000007}, 460 + {REG_MICFIL_FIFO_STAT, 0x00000000}, 461 + {REG_MICFIL_DATACH0, 0x00000000}, 462 + {REG_MICFIL_DATACH1, 0x00000000}, 463 + {REG_MICFIL_DATACH2, 0x00000000}, 464 + {REG_MICFIL_DATACH3, 0x00000000}, 465 + {REG_MICFIL_DATACH4, 0x00000000}, 466 + {REG_MICFIL_DATACH5, 0x00000000}, 467 + {REG_MICFIL_DATACH6, 0x00000000}, 468 + {REG_MICFIL_DATACH7, 0x00000000}, 469 + {REG_MICFIL_DC_CTRL, 0x00000000}, 470 + {REG_MICFIL_OUT_CTRL, 0x00000000}, 471 + {REG_MICFIL_OUT_STAT, 0x00000000}, 472 + {REG_MICFIL_VAD0_CTRL1, 0x00000000}, 473 + {REG_MICFIL_VAD0_CTRL2, 0x000A0000}, 474 + {REG_MICFIL_VAD0_STAT, 0x00000000}, 475 + {REG_MICFIL_VAD0_SCONFIG, 0x00000000}, 476 + {REG_MICFIL_VAD0_NCONFIG, 0x80000000}, 477 + {REG_MICFIL_VAD0_NDATA, 0x00000000}, 478 + {REG_MICFIL_VAD0_ZCD, 0x00000004}, 479 + }; 480 + 481 + static bool fsl_micfil_readable_reg(struct device *dev, unsigned int reg) 482 + { 483 + switch (reg) { 484 + case REG_MICFIL_CTRL1: 485 + case REG_MICFIL_CTRL2: 486 + case REG_MICFIL_STAT: 487 + case REG_MICFIL_FIFO_CTRL: 488 + case REG_MICFIL_FIFO_STAT: 489 + case REG_MICFIL_DATACH0: 490 + case REG_MICFIL_DATACH1: 491 + case REG_MICFIL_DATACH2: 492 + case REG_MICFIL_DATACH3: 493 + case REG_MICFIL_DATACH4: 494 + case REG_MICFIL_DATACH5: 495 + case REG_MICFIL_DATACH6: 496 + case REG_MICFIL_DATACH7: 497 + case REG_MICFIL_DC_CTRL: 498 + case REG_MICFIL_OUT_CTRL: 499 + case REG_MICFIL_OUT_STAT: 500 + case REG_MICFIL_VAD0_CTRL1: 501 + case REG_MICFIL_VAD0_CTRL2: 502 + case REG_MICFIL_VAD0_STAT: 503 + case REG_MICFIL_VAD0_SCONFIG: 504 + case REG_MICFIL_VAD0_NCONFIG: 505 + case REG_MICFIL_VAD0_NDATA: 506 + case REG_MICFIL_VAD0_ZCD: 507 + return true; 508 + default: 509 + return false; 510 + } 511 + } 512 + 513 + static bool fsl_micfil_writeable_reg(struct device *dev, unsigned int reg) 514 + { 515 + switch (reg) { 516 + case REG_MICFIL_CTRL1: 517 + case REG_MICFIL_CTRL2: 518 + case REG_MICFIL_STAT: /* Write 1 to Clear */ 519 + case REG_MICFIL_FIFO_CTRL: 520 + case REG_MICFIL_FIFO_STAT: /* Write 1 to Clear */ 521 + case REG_MICFIL_DC_CTRL: 522 + case REG_MICFIL_OUT_CTRL: 523 + case REG_MICFIL_OUT_STAT: /* Write 1 to Clear */ 524 + case REG_MICFIL_VAD0_CTRL1: 525 + case REG_MICFIL_VAD0_CTRL2: 526 + case REG_MICFIL_VAD0_STAT: /* Write 1 to Clear */ 527 + case REG_MICFIL_VAD0_SCONFIG: 528 + case REG_MICFIL_VAD0_NCONFIG: 529 + case REG_MICFIL_VAD0_ZCD: 530 + return true; 531 + default: 532 + return false; 533 + } 534 + } 535 + 536 + static bool fsl_micfil_volatile_reg(struct device *dev, unsigned int reg) 537 + { 538 + switch (reg) { 539 + case REG_MICFIL_STAT: 540 + case REG_MICFIL_DATACH0: 541 + case REG_MICFIL_DATACH1: 542 + case REG_MICFIL_DATACH2: 543 + case REG_MICFIL_DATACH3: 544 + case REG_MICFIL_DATACH4: 545 + case REG_MICFIL_DATACH5: 546 + case REG_MICFIL_DATACH6: 547 + case REG_MICFIL_DATACH7: 548 + case REG_MICFIL_VAD0_STAT: 549 + case REG_MICFIL_VAD0_NDATA: 550 + return true; 551 + default: 552 + return false; 553 + } 554 + } 555 + 556 + static const struct regmap_config fsl_micfil_regmap_config = { 557 + .reg_bits = 32, 558 + .reg_stride = 4, 559 + .val_bits = 32, 560 + 561 + .max_register = REG_MICFIL_VAD0_ZCD, 562 + .reg_defaults = fsl_micfil_reg_defaults, 563 + .num_reg_defaults = ARRAY_SIZE(fsl_micfil_reg_defaults), 564 + .readable_reg = fsl_micfil_readable_reg, 565 + .volatile_reg = fsl_micfil_volatile_reg, 566 + .writeable_reg = fsl_micfil_writeable_reg, 567 + .cache_type = REGCACHE_RBTREE, 568 + }; 569 + 570 + /* END OF REGMAP */ 571 + 572 + static irqreturn_t micfil_isr(int irq, void *devid) 573 + { 574 + struct fsl_micfil *micfil = (struct fsl_micfil *)devid; 575 + struct platform_device *pdev = micfil->pdev; 576 + u32 stat_reg; 577 + u32 fifo_stat_reg; 578 + u32 ctrl1_reg; 579 + bool dma_enabled; 580 + int i; 581 + 582 + regmap_read(micfil->regmap, REG_MICFIL_STAT, &stat_reg); 583 + regmap_read(micfil->regmap, REG_MICFIL_CTRL1, &ctrl1_reg); 584 + regmap_read(micfil->regmap, REG_MICFIL_FIFO_STAT, &fifo_stat_reg); 585 + 586 + dma_enabled = MICFIL_DMA_ENABLED(ctrl1_reg); 587 + 588 + /* Channel 0-7 Output Data Flags */ 589 + for (i = 0; i < MICFIL_OUTPUT_CHANNELS; i++) { 590 + if (stat_reg & MICFIL_STAT_CHXF_MASK(i)) 591 + dev_dbg(&pdev->dev, 592 + "Data available in Data Channel %d\n", i); 593 + /* if DMA is not enabled, field must be written with 1 594 + * to clear 595 + */ 596 + if (!dma_enabled) 597 + regmap_write_bits(micfil->regmap, 598 + REG_MICFIL_STAT, 599 + MICFIL_STAT_CHXF_MASK(i), 600 + 1); 601 + } 602 + 603 + for (i = 0; i < MICFIL_FIFO_NUM; i++) { 604 + if (fifo_stat_reg & MICFIL_FIFO_STAT_FIFOX_OVER_MASK(i)) 605 + dev_dbg(&pdev->dev, 606 + "FIFO Overflow Exception flag for channel %d\n", 607 + i); 608 + 609 + if (fifo_stat_reg & MICFIL_FIFO_STAT_FIFOX_UNDER_MASK(i)) 610 + dev_dbg(&pdev->dev, 611 + "FIFO Underflow Exception flag for channel %d\n", 612 + i); 613 + } 614 + 615 + return IRQ_HANDLED; 616 + } 617 + 618 + static irqreturn_t micfil_err_isr(int irq, void *devid) 619 + { 620 + struct fsl_micfil *micfil = (struct fsl_micfil *)devid; 621 + struct platform_device *pdev = micfil->pdev; 622 + u32 stat_reg; 623 + 624 + regmap_read(micfil->regmap, REG_MICFIL_STAT, &stat_reg); 625 + 626 + if (stat_reg & MICFIL_STAT_BSY_FIL_MASK) 627 + dev_dbg(&pdev->dev, "isr: Decimation Filter is running\n"); 628 + 629 + if (stat_reg & MICFIL_STAT_FIR_RDY_MASK) 630 + dev_dbg(&pdev->dev, "isr: FIR Filter Data ready\n"); 631 + 632 + if (stat_reg & MICFIL_STAT_LOWFREQF_MASK) { 633 + dev_dbg(&pdev->dev, "isr: ipg_clk_app is too low\n"); 634 + regmap_write_bits(micfil->regmap, REG_MICFIL_STAT, 635 + MICFIL_STAT_LOWFREQF_MASK, 1); 636 + } 637 + 638 + return IRQ_HANDLED; 639 + } 640 + 641 + static int fsl_micfil_probe(struct platform_device *pdev) 642 + { 643 + struct device_node *np = pdev->dev.of_node; 644 + const struct of_device_id *of_id; 645 + struct fsl_micfil *micfil; 646 + struct resource *res; 647 + void __iomem *regs; 648 + int ret, i; 649 + unsigned long irqflag = 0; 650 + 651 + micfil = devm_kzalloc(&pdev->dev, sizeof(*micfil), GFP_KERNEL); 652 + if (!micfil) 653 + return -ENOMEM; 654 + 655 + micfil->pdev = pdev; 656 + strncpy(micfil->name, np->name, sizeof(micfil->name) - 1); 657 + 658 + of_id = of_match_device(fsl_micfil_dt_ids, &pdev->dev); 659 + if (!of_id || !of_id->data) 660 + return -EINVAL; 661 + 662 + micfil->soc = of_id->data; 663 + 664 + /* ipg_clk is used to control the registers 665 + * ipg_clk_app is used to operate the filter 666 + */ 667 + micfil->mclk = devm_clk_get(&pdev->dev, "ipg_clk_app"); 668 + if (IS_ERR(micfil->mclk)) { 669 + dev_err(&pdev->dev, "failed to get core clock: %ld\n", 670 + PTR_ERR(micfil->mclk)); 671 + return PTR_ERR(micfil->mclk); 672 + } 673 + 674 + /* init regmap */ 675 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 676 + regs = devm_ioremap_resource(&pdev->dev, res); 677 + if (IS_ERR(regs)) 678 + return PTR_ERR(regs); 679 + 680 + micfil->regmap = devm_regmap_init_mmio_clk(&pdev->dev, 681 + "ipg_clk", 682 + regs, 683 + &fsl_micfil_regmap_config); 684 + if (IS_ERR(micfil->regmap)) { 685 + dev_err(&pdev->dev, "failed to init MICFIL regmap: %ld\n", 686 + PTR_ERR(micfil->regmap)); 687 + return PTR_ERR(micfil->regmap); 688 + } 689 + 690 + /* dataline mask for RX */ 691 + ret = of_property_read_u32_index(np, 692 + "fsl,dataline", 693 + 0, 694 + &micfil->dataline); 695 + if (ret) 696 + micfil->dataline = 1; 697 + 698 + if (micfil->dataline & ~micfil->soc->dataline) { 699 + dev_err(&pdev->dev, "dataline setting error, Mask is 0x%X\n", 700 + micfil->soc->dataline); 701 + return -EINVAL; 702 + } 703 + 704 + /* get IRQs */ 705 + for (i = 0; i < MICFIL_IRQ_LINES; i++) { 706 + micfil->irq[i] = platform_get_irq(pdev, i); 707 + dev_err(&pdev->dev, "GET IRQ: %d\n", micfil->irq[i]); 708 + if (micfil->irq[i] < 0) { 709 + dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); 710 + return micfil->irq[i]; 711 + } 712 + } 713 + 714 + if (of_property_read_bool(np, "fsl,shared-interrupt")) 715 + irqflag = IRQF_SHARED; 716 + 717 + /* Digital Microphone interface interrupt - IRQ 109 */ 718 + ret = devm_request_irq(&pdev->dev, micfil->irq[0], 719 + micfil_isr, irqflag, 720 + micfil->name, micfil); 721 + if (ret) { 722 + dev_err(&pdev->dev, "failed to claim mic interface irq %u\n", 723 + micfil->irq[0]); 724 + return ret; 725 + } 726 + 727 + /* Digital Microphone interface error interrupt - IRQ 110 */ 728 + ret = devm_request_irq(&pdev->dev, micfil->irq[1], 729 + micfil_err_isr, irqflag, 730 + micfil->name, micfil); 731 + if (ret) { 732 + dev_err(&pdev->dev, "failed to claim mic interface error irq %u\n", 733 + micfil->irq[1]); 734 + return ret; 735 + } 736 + 737 + micfil->dma_params_rx.chan_name = "rx"; 738 + micfil->dma_params_rx.addr = res->start + REG_MICFIL_DATACH0; 739 + micfil->dma_params_rx.maxburst = MICFIL_DMA_MAXBURST_RX; 740 + 741 + 742 + platform_set_drvdata(pdev, micfil); 743 + 744 + pm_runtime_enable(&pdev->dev); 745 + 746 + ret = devm_snd_soc_register_component(&pdev->dev, &fsl_micfil_component, 747 + &fsl_micfil_dai, 1); 748 + if (ret) { 749 + dev_err(&pdev->dev, "failed to register component %s\n", 750 + fsl_micfil_component.name); 751 + return ret; 752 + } 753 + 754 + ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); 755 + if (ret) 756 + dev_err(&pdev->dev, "failed to pcm register\n"); 757 + 758 + return ret; 759 + } 760 + 761 + #ifdef CONFIG_PM 762 + static int __maybe_unused fsl_micfil_runtime_suspend(struct device *dev) 763 + { 764 + struct fsl_micfil *micfil = dev_get_drvdata(dev); 765 + 766 + regcache_cache_only(micfil->regmap, true); 767 + 768 + clk_disable_unprepare(micfil->mclk); 769 + 770 + return 0; 771 + } 772 + 773 + static int __maybe_unused fsl_micfil_runtime_resume(struct device *dev) 774 + { 775 + struct fsl_micfil *micfil = dev_get_drvdata(dev); 776 + int ret; 777 + 778 + ret = clk_prepare_enable(micfil->mclk); 779 + if (ret < 0) 780 + return ret; 781 + 782 + regcache_cache_only(micfil->regmap, false); 783 + regcache_mark_dirty(micfil->regmap); 784 + regcache_sync(micfil->regmap); 785 + 786 + return 0; 787 + } 788 + #endif /* CONFIG_PM*/ 789 + 790 + #ifdef CONFIG_PM_SLEEP 791 + static int __maybe_unused fsl_micfil_suspend(struct device *dev) 792 + { 793 + pm_runtime_force_suspend(dev); 794 + 795 + return 0; 796 + } 797 + 798 + static int __maybe_unused fsl_micfil_resume(struct device *dev) 799 + { 800 + pm_runtime_force_resume(dev); 801 + 802 + return 0; 803 + } 804 + #endif /* CONFIG_PM_SLEEP */ 805 + 806 + static const struct dev_pm_ops fsl_micfil_pm_ops = { 807 + SET_RUNTIME_PM_OPS(fsl_micfil_runtime_suspend, 808 + fsl_micfil_runtime_resume, 809 + NULL) 810 + SET_SYSTEM_SLEEP_PM_OPS(fsl_micfil_suspend, 811 + fsl_micfil_resume) 812 + }; 813 + 814 + static struct platform_driver fsl_micfil_driver = { 815 + .probe = fsl_micfil_probe, 816 + .driver = { 817 + .name = "fsl-micfil-dai", 818 + .pm = &fsl_micfil_pm_ops, 819 + .of_match_table = fsl_micfil_dt_ids, 820 + }, 821 + }; 822 + module_platform_driver(fsl_micfil_driver); 823 + 824 + MODULE_AUTHOR("Cosmin-Gabriel Samoila <cosmin.samoila@nxp.com>"); 825 + MODULE_DESCRIPTION("NXP PDM Microphone Interface (MICFIL) driver"); 826 + MODULE_LICENSE("GPL v2");
+283
sound/soc/fsl/fsl_micfil.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * PDM Microphone Interface for the NXP i.MX SoC 4 + * Copyright 2018 NXP 5 + */ 6 + 7 + #ifndef _FSL_MICFIL_H 8 + #define _FSL_MICFIL_H 9 + 10 + /* MICFIL Register Map */ 11 + #define REG_MICFIL_CTRL1 0x00 12 + #define REG_MICFIL_CTRL2 0x04 13 + #define REG_MICFIL_STAT 0x08 14 + #define REG_MICFIL_FIFO_CTRL 0x10 15 + #define REG_MICFIL_FIFO_STAT 0x14 16 + #define REG_MICFIL_DATACH0 0x24 17 + #define REG_MICFIL_DATACH1 0x28 18 + #define REG_MICFIL_DATACH2 0x2C 19 + #define REG_MICFIL_DATACH3 0x30 20 + #define REG_MICFIL_DATACH4 0x34 21 + #define REG_MICFIL_DATACH5 0x38 22 + #define REG_MICFIL_DATACH6 0x3C 23 + #define REG_MICFIL_DATACH7 0x40 24 + #define REG_MICFIL_DC_CTRL 0x64 25 + #define REG_MICFIL_OUT_CTRL 0x74 26 + #define REG_MICFIL_OUT_STAT 0x7C 27 + #define REG_MICFIL_VAD0_CTRL1 0x90 28 + #define REG_MICFIL_VAD0_CTRL2 0x94 29 + #define REG_MICFIL_VAD0_STAT 0x98 30 + #define REG_MICFIL_VAD0_SCONFIG 0x9C 31 + #define REG_MICFIL_VAD0_NCONFIG 0xA0 32 + #define REG_MICFIL_VAD0_NDATA 0xA4 33 + #define REG_MICFIL_VAD0_ZCD 0xA8 34 + 35 + /* MICFIL Control Register 1 -- REG_MICFILL_CTRL1 0x00 */ 36 + #define MICFIL_CTRL1_MDIS_SHIFT 31 37 + #define MICFIL_CTRL1_MDIS_MASK BIT(MICFIL_CTRL1_MDIS_SHIFT) 38 + #define MICFIL_CTRL1_MDIS BIT(MICFIL_CTRL1_MDIS_SHIFT) 39 + #define MICFIL_CTRL1_DOZEN_SHIFT 30 40 + #define MICFIL_CTRL1_DOZEN_MASK BIT(MICFIL_CTRL1_DOZEN_SHIFT) 41 + #define MICFIL_CTRL1_DOZEN BIT(MICFIL_CTRL1_DOZEN_SHIFT) 42 + #define MICFIL_CTRL1_PDMIEN_SHIFT 29 43 + #define MICFIL_CTRL1_PDMIEN_MASK BIT(MICFIL_CTRL1_PDMIEN_SHIFT) 44 + #define MICFIL_CTRL1_PDMIEN BIT(MICFIL_CTRL1_PDMIEN_SHIFT) 45 + #define MICFIL_CTRL1_DBG_SHIFT 28 46 + #define MICFIL_CTRL1_DBG_MASK BIT(MICFIL_CTRL1_DBG_SHIFT) 47 + #define MICFIL_CTRL1_DBG BIT(MICFIL_CTRL1_DBG_SHIFT) 48 + #define MICFIL_CTRL1_SRES_SHIFT 27 49 + #define MICFIL_CTRL1_SRES_MASK BIT(MICFIL_CTRL1_SRES_SHIFT) 50 + #define MICFIL_CTRL1_SRES BIT(MICFIL_CTRL1_SRES_SHIFT) 51 + #define MICFIL_CTRL1_DBGE_SHIFT 26 52 + #define MICFIL_CTRL1_DBGE_MASK BIT(MICFIL_CTRL1_DBGE_SHIFT) 53 + #define MICFIL_CTRL1_DBGE BIT(MICFIL_CTRL1_DBGE_SHIFT) 54 + #define MICFIL_CTRL1_DISEL_SHIFT 24 55 + #define MICFIL_CTRL1_DISEL_WIDTH 2 56 + #define MICFIL_CTRL1_DISEL_MASK ((BIT(MICFIL_CTRL1_DISEL_WIDTH) - 1) \ 57 + << MICFIL_CTRL1_DISEL_SHIFT) 58 + #define MICFIL_CTRL1_DISEL(v) (((v) << MICFIL_CTRL1_DISEL_SHIFT) \ 59 + & MICFIL_CTRL1_DISEL_MASK) 60 + #define MICFIL_CTRL1_ERREN_SHIFT 23 61 + #define MICFIL_CTRL1_ERREN_MASK BIT(MICFIL_CTRL1_ERREN_SHIFT) 62 + #define MICFIL_CTRL1_ERREN BIT(MICFIL_CTRL1_ERREN_SHIFT) 63 + #define MICFIL_CTRL1_CHEN_SHIFT 0 64 + #define MICFIL_CTRL1_CHEN_WIDTH 8 65 + #define MICFIL_CTRL1_CHEN_MASK(x) (BIT(x) << MICFIL_CTRL1_CHEN_SHIFT) 66 + #define MICFIL_CTRL1_CHEN(x) (MICFIL_CTRL1_CHEN_MASK(x)) 67 + 68 + /* MICFIL Control Register 2 -- REG_MICFILL_CTRL2 0x04 */ 69 + #define MICFIL_CTRL2_QSEL_SHIFT 25 70 + #define MICFIL_CTRL2_QSEL_WIDTH 3 71 + #define MICFIL_CTRL2_QSEL_MASK ((BIT(MICFIL_CTRL2_QSEL_WIDTH) - 1) \ 72 + << MICFIL_CTRL2_QSEL_SHIFT) 73 + #define MICFIL_HIGH_QUALITY BIT(MICFIL_CTRL2_QSEL_SHIFT) 74 + #define MICFIL_MEDIUM_QUALITY (0 << MICFIL_CTRL2_QSEL_SHIFT) 75 + #define MICFIL_LOW_QUALITY (7 << MICFIL_CTRL2_QSEL_SHIFT) 76 + #define MICFIL_VLOW0_QUALITY (6 << MICFIL_CTRL2_QSEL_SHIFT) 77 + #define MICFIL_VLOW1_QUALITY (5 << MICFIL_CTRL2_QSEL_SHIFT) 78 + #define MICFIL_VLOW2_QUALITY (4 << MICFIL_CTRL2_QSEL_SHIFT) 79 + 80 + #define MICFIL_CTRL2_CICOSR_SHIFT 16 81 + #define MICFIL_CTRL2_CICOSR_WIDTH 4 82 + #define MICFIL_CTRL2_CICOSR_MASK ((BIT(MICFIL_CTRL2_CICOSR_WIDTH) - 1) \ 83 + << MICFIL_CTRL2_CICOSR_SHIFT) 84 + #define MICFIL_CTRL2_CICOSR(v) (((v) << MICFIL_CTRL2_CICOSR_SHIFT) \ 85 + & MICFIL_CTRL2_CICOSR_MASK) 86 + #define MICFIL_CTRL2_CLKDIV_SHIFT 0 87 + #define MICFIL_CTRL2_CLKDIV_WIDTH 8 88 + #define MICFIL_CTRL2_CLKDIV_MASK ((BIT(MICFIL_CTRL2_CLKDIV_WIDTH) - 1) \ 89 + << MICFIL_CTRL2_CLKDIV_SHIFT) 90 + #define MICFIL_CTRL2_CLKDIV(v) (((v) << MICFIL_CTRL2_CLKDIV_SHIFT) \ 91 + & MICFIL_CTRL2_CLKDIV_MASK) 92 + 93 + /* MICFIL Status Register -- REG_MICFIL_STAT 0x08 */ 94 + #define MICFIL_STAT_BSY_FIL_SHIFT 31 95 + #define MICFIL_STAT_BSY_FIL_MASK BIT(MICFIL_STAT_BSY_FIL_SHIFT) 96 + #define MICFIL_STAT_BSY_FIL BIT(MICFIL_STAT_BSY_FIL_SHIFT) 97 + #define MICFIL_STAT_FIR_RDY_SHIFT 30 98 + #define MICFIL_STAT_FIR_RDY_MASK BIT(MICFIL_STAT_FIR_RDY_SHIFT) 99 + #define MICFIL_STAT_FIR_RDY BIT(MICFIL_STAT_FIR_RDY_SHIFT) 100 + #define MICFIL_STAT_LOWFREQF_SHIFT 29 101 + #define MICFIL_STAT_LOWFREQF_MASK BIT(MICFIL_STAT_LOWFREQF_SHIFT) 102 + #define MICFIL_STAT_LOWFREQF BIT(MICFIL_STAT_LOWFREQF_SHIFT) 103 + #define MICFIL_STAT_CHXF_SHIFT(v) (v) 104 + #define MICFIL_STAT_CHXF_MASK(v) BIT(MICFIL_STAT_CHXF_SHIFT(v)) 105 + #define MICFIL_STAT_CHXF(v) BIT(MICFIL_STAT_CHXF_SHIFT(v)) 106 + 107 + /* MICFIL FIFO Control Register -- REG_MICFIL_FIFO_CTRL 0x10 */ 108 + #define MICFIL_FIFO_CTRL_FIFOWMK_SHIFT 0 109 + #define MICFIL_FIFO_CTRL_FIFOWMK_WIDTH 3 110 + #define MICFIL_FIFO_CTRL_FIFOWMK_MASK ((BIT(MICFIL_FIFO_CTRL_FIFOWMK_WIDTH) - 1) \ 111 + << MICFIL_FIFO_CTRL_FIFOWMK_SHIFT) 112 + #define MICFIL_FIFO_CTRL_FIFOWMK(v) (((v) << MICFIL_FIFO_CTRL_FIFOWMK_SHIFT) \ 113 + & MICFIL_FIFO_CTRL_FIFOWMK_MASK) 114 + 115 + /* MICFIL FIFO Status Register -- REG_MICFIL_FIFO_STAT 0x14 */ 116 + #define MICFIL_FIFO_STAT_FIFOX_OVER_SHIFT(v) (v) 117 + #define MICFIL_FIFO_STAT_FIFOX_OVER_MASK(v) BIT(MICFIL_FIFO_STAT_FIFOX_OVER_SHIFT(v)) 118 + #define MICFIL_FIFO_STAT_FIFOX_UNDER_SHIFT(v) ((v) + 8) 119 + #define MICFIL_FIFO_STAT_FIFOX_UNDER_MASK(v) BIT(MICFIL_FIFO_STAT_FIFOX_UNDER_SHIFT(v)) 120 + 121 + /* MICFIL HWVAD0 Control 1 Register -- REG_MICFIL_VAD0_CTRL1*/ 122 + #define MICFIL_VAD0_CTRL1_CHSEL_SHIFT 24 123 + #define MICFIL_VAD0_CTRL1_CHSEL_WIDTH 3 124 + #define MICFIL_VAD0_CTRL1_CHSEL_MASK ((BIT(MICFIL_VAD0_CTRL1_CHSEL_WIDTH) - 1) \ 125 + << MICFIL_VAD0_CTRL1_CHSEL_SHIFT) 126 + #define MICFIL_VAD0_CTRL1_CHSEL(v) (((v) << MICFIL_VAD0_CTRL1_CHSEL_SHIFT) \ 127 + & MICFIL_VAD0_CTRL1_CHSEL_MASK) 128 + #define MICFIL_VAD0_CTRL1_CICOSR_SHIFT 16 129 + #define MICFIL_VAD0_CTRL1_CICOSR_WIDTH 4 130 + #define MICFIL_VAD0_CTRL1_CICOSR_MASK ((BIT(MICFIL_VAD0_CTRL1_CICOSR_WIDTH) - 1) \ 131 + << MICFIL_VAD0_CTRL1_CICOSR_SHIFT) 132 + #define MICFIL_VAD0_CTRL1_CICOSR(v) (((v) << MICFIL_VAD0_CTRL1_CICOSR_SHIFT) \ 133 + & MICFIL_VAD0_CTRL1_CICOSR_MASK) 134 + #define MICFIL_VAD0_CTRL1_INITT_SHIFT 8 135 + #define MICFIL_VAD0_CTRL1_INITT_WIDTH 5 136 + #define MICFIL_VAD0_CTRL1_INITT_MASK ((BIT(MICFIL_VAD0_CTRL1_INITT_WIDTH) - 1) \ 137 + << MICFIL_VAD0_CTRL1_INITT_SHIFT) 138 + #define MICFIL_VAD0_CTRL1_INITT(v) (((v) << MICFIL_VAD0_CTRL1_INITT_SHIFT) \ 139 + & MICFIL_VAD0_CTRL1_INITT_MASK) 140 + #define MICFIL_VAD0_CTRL1_ST10_SHIFT 4 141 + #define MICFIL_VAD0_CTRL1_ST10_MASK BIT(MICFIL_VAD0_CTRL1_ST10_SHIFT) 142 + #define MICFIL_VAD0_CTRL1_ST10 BIT(MICFIL_VAD0_CTRL1_ST10_SHIFT) 143 + #define MICFIL_VAD0_CTRL1_ERIE_SHIFT 3 144 + #define MICFIL_VAD0_CTRL1_ERIE_MASK BIT(MICFIL_VAD0_CTRL1_ERIE_SHIFT) 145 + #define MICFIL_VAD0_CTRL1_ERIE BIT(MICFIL_VAD0_CTRL1_ERIE_SHIFT) 146 + #define MICFIL_VAD0_CTRL1_IE_SHIFT 2 147 + #define MICFIL_VAD0_CTRL1_IE_MASK BIT(MICFIL_VAD0_CTRL1_IE_SHIFT) 148 + #define MICFIL_VAD0_CTRL1_IE BIT(MICFIL_VAD0_CTRL1_IE_SHIFT) 149 + #define MICFIL_VAD0_CTRL1_RST_SHIFT 1 150 + #define MICFIL_VAD0_CTRL1_RST_MASK BIT(MICFIL_VAD0_CTRL1_RST_SHIFT) 151 + #define MICFIL_VAD0_CTRL1_RST BIT(MICFIL_VAD0_CTRL1_RST_SHIFT) 152 + #define MICFIL_VAD0_CTRL1_EN_SHIFT 0 153 + #define MICFIL_VAD0_CTRL1_EN_MASK BIT(MICFIL_VAD0_CTRL1_EN_SHIFT) 154 + #define MICFIL_VAD0_CTRL1_EN BIT(MICFIL_VAD0_CTRL1_EN_SHIFT) 155 + 156 + /* MICFIL HWVAD0 Control 2 Register -- REG_MICFIL_VAD0_CTRL2*/ 157 + #define MICFIL_VAD0_CTRL2_FRENDIS_SHIFT 31 158 + #define MICFIL_VAD0_CTRL2_FRENDIS_MASK BIT(MICFIL_VAD0_CTRL2_FRENDIS_SHIFT) 159 + #define MICFIL_VAD0_CTRL2_FRENDIS BIT(MICFIL_VAD0_CTRL2_FRENDIS_SHIFT) 160 + #define MICFIL_VAD0_CTRL2_PREFEN_SHIFT 30 161 + #define MICFIL_VAD0_CTRL2_PREFEN_MASK BIT(MICFIL_VAD0_CTRL2_PREFEN_SHIFT) 162 + #define MICFIL_VAD0_CTRL2_PREFEN BIT(MICFIL_VAD0_CTRL2_PREFEN_SHIFT) 163 + #define MICFIL_VAD0_CTRL2_FOUTDIS_SHIFT 28 164 + #define MICFIL_VAD0_CTRL2_FOUTDIS_MASK BIT(MICFIL_VAD0_CTRL2_FOUTDIS_SHIFT) 165 + #define MICFIL_VAD0_CTRL2_FOUTDIS BIT(MICFIL_VAD0_CTRL2_FOUTDIS_SHIFT) 166 + #define MICFIL_VAD0_CTRL2_FRAMET_SHIFT 16 167 + #define MICFIL_VAD0_CTRL2_FRAMET_WIDTH 6 168 + #define MICFIL_VAD0_CTRL2_FRAMET_MASK ((BIT(MICFIL_VAD0_CTRL2_FRAMET_WIDTH) - 1) \ 169 + << MICFIL_VAD0_CTRL2_FRAMET_SHIFT) 170 + #define MICFIL_VAD0_CTRL2_FRAMET(v) (((v) << MICFIL_VAD0_CTRL2_FRAMET_SHIFT) \ 171 + & MICFIL_VAD0_CTRL2_FRAMET_MASK) 172 + #define MICFIL_VAD0_CTRL2_INPGAIN_SHIFT 8 173 + #define MICFIL_VAD0_CTRL2_INPGAIN_WIDTH 4 174 + #define MICFIL_VAD0_CTRL2_INPGAIN_MASK ((BIT(MICFIL_VAD0_CTRL2_INPGAIN_WIDTH) - 1) \ 175 + << MICFIL_VAD0_CTRL2_INPGAIN_SHIFT) 176 + #define MICFIL_VAD0_CTRL2_INPGAIN(v) (((v) << MICFIL_VAD0_CTRL2_INPGAIN_SHIFT) \ 177 + & MICFIL_VAD0_CTRL2_INPGAIN_MASK) 178 + #define MICFIL_VAD0_CTRL2_HPF_SHIFT 0 179 + #define MICFIL_VAD0_CTRL2_HPF_WIDTH 2 180 + #define MICFIL_VAD0_CTRL2_HPF_MASK ((BIT(MICFIL_VAD0_CTRL2_HPF_WIDTH) - 1) \ 181 + << MICFIL_VAD0_CTRL2_HPF_SHIFT) 182 + #define MICFIL_VAD0_CTRL2_HPF(v) (((v) << MICFIL_VAD0_CTRL2_HPF_SHIFT) \ 183 + & MICFIL_VAD0_CTRL2_HPF_MASK) 184 + 185 + /* MICFIL HWVAD0 Signal CONFIG Register -- REG_MICFIL_VAD0_SCONFIG */ 186 + #define MICFIL_VAD0_SCONFIG_SFILEN_SHIFT 31 187 + #define MICFIL_VAD0_SCONFIG_SFILEN_MASK BIT(MICFIL_VAD0_SCONFIG_SFILEN_SHIFT) 188 + #define MICFIL_VAD0_SCONFIG_SFILEN BIT(MICFIL_VAD0_SCONFIG_SFILEN_SHIFT) 189 + #define MICFIL_VAD0_SCONFIG_SMAXEN_SHIFT 30 190 + #define MICFIL_VAD0_SCONFIG_SMAXEN_MASK BIT(MICFIL_VAD0_SCONFIG_SMAXEN_SHIFT) 191 + #define MICFIL_VAD0_SCONFIG_SMAXEN BIT(MICFIL_VAD0_SCONFIG_SMAXEN_SHIFT) 192 + #define MICFIL_VAD0_SCONFIG_SGAIN_SHIFT 0 193 + #define MICFIL_VAD0_SCONFIG_SGAIN_WIDTH 4 194 + #define MICFIL_VAD0_SCONFIG_SGAIN_MASK ((BIT(MICFIL_VAD0_SCONFIG_SGAIN_WIDTH) - 1) \ 195 + << MICFIL_VAD0_SCONFIG_SGAIN_SHIFT) 196 + #define MICFIL_VAD0_SCONFIG_SGAIN(v) (((v) << MICFIL_VAD0_SCONFIG_SGAIN_SHIFT) \ 197 + & MICFIL_VAD0_SCONFIG_SGAIN_MASK) 198 + 199 + /* MICFIL HWVAD0 Noise CONFIG Register -- REG_MICFIL_VAD0_NCONFIG */ 200 + #define MICFIL_VAD0_NCONFIG_NFILAUT_SHIFT 31 201 + #define MICFIL_VAD0_NCONFIG_NFILAUT_MASK BIT(MICFIL_VAD0_NCONFIG_NFILAUT_SHIFT) 202 + #define MICFIL_VAD0_NCONFIG_NFILAUT BIT(MICFIL_VAD0_NCONFIG_NFILAUT_SHIFT) 203 + #define MICFIL_VAD0_NCONFIG_NMINEN_SHIFT 30 204 + #define MICFIL_VAD0_NCONFIG_NMINEN_MASK BIT(MICFIL_VAD0_NCONFIG_NMINEN_SHIFT) 205 + #define MICFIL_VAD0_NCONFIG_NMINEN BIT(MICFIL_VAD0_NCONFIG_NMINEN_SHIFT) 206 + #define MICFIL_VAD0_NCONFIG_NDECEN_SHIFT 29 207 + #define MICFIL_VAD0_NCONFIG_NDECEN_MASK BIT(MICFIL_VAD0_NCONFIG_NDECEN_SHIFT) 208 + #define MICFIL_VAD0_NCONFIG_NDECEN BIT(MICFIL_VAD0_NCONFIG_NDECEN_SHIFT) 209 + #define MICFIL_VAD0_NCONFIG_NOREN_SHIFT 28 210 + #define MICFIL_VAD0_NCONFIG_NOREN BIT(MICFIL_VAD0_NCONFIG_NOREN_SHIFT) 211 + #define MICFIL_VAD0_NCONFIG_NFILADJ_SHIFT 8 212 + #define MICFIL_VAD0_NCONFIG_NFILADJ_WIDTH 5 213 + #define MICFIL_VAD0_NCONFIG_NFILADJ_MASK ((BIT(MICFIL_VAD0_NCONFIG_NFILADJ_WIDTH) - 1) \ 214 + << MICFIL_VAD0_NCONFIG_NFILADJ_SHIFT) 215 + #define MICFIL_VAD0_NCONFIG_NFILADJ(v) (((v) << MICFIL_VAD0_NCONFIG_NFILADJ_SHIFT) \ 216 + & MICFIL_VAD0_NCONFIG_NFILADJ_MASK) 217 + #define MICFIL_VAD0_NCONFIG_NGAIN_SHIFT 0 218 + #define MICFIL_VAD0_NCONFIG_NGAIN_WIDTH 4 219 + #define MICFIL_VAD0_NCONFIG_NGAIN_MASK ((BIT(MICFIL_VAD0_NCONFIG_NGAIN_WIDTH) - 1) \ 220 + << MICFIL_VAD0_NCONFIG_NGAIN_SHIFT) 221 + #define MICFIL_VAD0_NCONFIG_NGAIN(v) (((v) << MICFIL_VAD0_NCONFIG_NGAIN_SHIFT) \ 222 + & MICFIL_VAD0_NCONFIG_NGAIN_MASK) 223 + 224 + /* MICFIL HWVAD0 Zero-Crossing Detector - REG_MICFIL_VAD0_ZCD */ 225 + #define MICFIL_VAD0_ZCD_ZCDTH_SHIFT 16 226 + #define MICFIL_VAD0_ZCD_ZCDTH_WIDTH 10 227 + #define MICFIL_VAD0_ZCD_ZCDTH_MASK ((BIT(MICFIL_VAD0_ZCD_ZCDTH_WIDTH) - 1) \ 228 + << MICFIL_VAD0_ZCD_ZCDTH_SHIFT) 229 + #define MICFIL_VAD0_ZCD_ZCDTH(v) (((v) << MICFIL_VAD0_ZCD_ZCDTH_SHIFT)\ 230 + & MICFIL_VAD0_ZCD_ZCDTH_MASK) 231 + #define MICFIL_VAD0_ZCD_ZCDADJ_SHIFT 8 232 + #define MICFIL_VAD0_ZCD_ZCDADJ_WIDTH 4 233 + #define MICFIL_VAD0_ZCD_ZCDADJ_MASK ((BIT(MICFIL_VAD0_ZCD_ZCDADJ_WIDTH) - 1)\ 234 + << MICFIL_VAD0_ZCD_ZCDADJ_SHIFT) 235 + #define MICFIL_VAD0_ZCD_ZCDADJ(v) (((v) << MICFIL_VAD0_ZCD_ZCDADJ_SHIFT)\ 236 + & MICFIL_VAD0_ZCD_ZCDADJ_MASK) 237 + #define MICFIL_VAD0_ZCD_ZCDAND_SHIFT 4 238 + #define MICFIL_VAD0_ZCD_ZCDAND_MASK BIT(MICFIL_VAD0_ZCD_ZCDAND_SHIFT) 239 + #define MICFIL_VAD0_ZCD_ZCDAND BIT(MICFIL_VAD0_ZCD_ZCDAND_SHIFT) 240 + #define MICFIL_VAD0_ZCD_ZCDAUT_SHIFT 2 241 + #define MICFIL_VAD0_ZCD_ZCDAUT_MASK BIT(MICFIL_VAD0_ZCD_ZCDAUT_SHIFT) 242 + #define MICFIL_VAD0_ZCD_ZCDAUT BIT(MICFIL_VAD0_ZCD_ZCDAUT_SHIFT) 243 + #define MICFIL_VAD0_ZCD_ZCDEN_SHIFT 0 244 + #define MICFIL_VAD0_ZCD_ZCDEN_MASK BIT(MICFIL_VAD0_ZCD_ZCDEN_SHIFT) 245 + #define MICFIL_VAD0_ZCD_ZCDEN BIT(MICFIL_VAD0_ZCD_ZCDEN_SHIFT) 246 + 247 + /* MICFIL HWVAD0 Status Register - REG_MICFIL_VAD0_STAT */ 248 + #define MICFIL_VAD0_STAT_INITF_SHIFT 31 249 + #define MICFIL_VAD0_STAT_INITF_MASK BIT(MICFIL_VAD0_STAT_INITF_SHIFT) 250 + #define MICFIL_VAD0_STAT_INITF BIT(MICFIL_VAD0_STAT_INITF_SHIFT) 251 + #define MICFIL_VAD0_STAT_INSATF_SHIFT 16 252 + #define MICFIL_VAD0_STAT_INSATF_MASK BIT(MICFIL_VAD0_STAT_INSATF_SHIFT) 253 + #define MICFIL_VAD0_STAT_INSATF BIT(MICFIL_VAD0_STAT_INSATF_SHIFT) 254 + #define MICFIL_VAD0_STAT_EF_SHIFT 15 255 + #define MICFIL_VAD0_STAT_EF_MASK BIT(MICFIL_VAD0_STAT_EF_SHIFT) 256 + #define MICFIL_VAD0_STAT_EF BIT(MICFIL_VAD0_STAT_EF_SHIFT) 257 + #define MICFIL_VAD0_STAT_IF_SHIFT 0 258 + #define MICFIL_VAD0_STAT_IF_MASK BIT(MICFIL_VAD0_STAT_IF_SHIFT) 259 + #define MICFIL_VAD0_STAT_IF BIT(MICFIL_VAD0_STAT_IF_SHIFT) 260 + 261 + /* MICFIL Output Control Register */ 262 + #define MICFIL_OUTGAIN_CHX_SHIFT(v) (4 * (v)) 263 + 264 + /* Constants */ 265 + #define MICFIL_DMA_IRQ_DISABLED(v) ((v) & MICFIL_CTRL1_DISEL_MASK) 266 + #define MICFIL_DMA_ENABLED(v) ((0x1 << MICFIL_CTRL1_DISEL_SHIFT) \ 267 + == ((v) & MICFIL_CTRL1_DISEL_MASK)) 268 + #define MICFIL_IRQ_ENABLED(v) ((0x2 << MICFIL_CTRL1_DISEL_SHIFT) \ 269 + == ((v) & MICFIL_CTRL1_DISEL_MASK)) 270 + #define MICFIL_OUTPUT_CHANNELS 8 271 + #define MICFIL_FIFO_NUM 8 272 + 273 + #define FIFO_PTRWID 3 274 + #define FIFO_LEN BIT(FIFO_PTRWID) 275 + 276 + #define MICFIL_IRQ_LINES 2 277 + #define MICFIL_MAX_RETRY 25 278 + #define MICFIL_SLEEP_MIN 90000 /* in us */ 279 + #define MICFIL_SLEEP_MAX 100000 /* in us */ 280 + #define MICFIL_DMA_MAXBURST_RX 6 281 + #define MICFIL_CTRL2_OSR_DEFAULT (0 << MICFIL_CTRL2_CICOSR_SHIFT) 282 + 283 + #endif /* _FSL_MICFIL_H */