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

ASoC: fsl_micfil: Add Hardware Voice Activity Detector support

The Hardware Voice Activity Detector (HWVAD) is a block
responsible for detect voice activity in a channel selected
by the user. It can be configured in Envelope-based or
Energy-based mode.

There are additional two interrupts for HWVAD, one is event
interrupt, another is error interrupt.

Enable hwvad in parallel with recording.
when voice activity detected, HWVAD will be disabled and
alsa control notification is triggerred.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Link: https://lore.kernel.org/r/1663925494-9941-1-git-send-email-shengjiu.wang@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Shengjiu Wang and committed by
Mark Brown
29dbfeec 2a9ad0cc

+439 -1
+434
sound/soc/fsl/fsl_micfil.c
··· 47 47 struct clk *pll11k_clk; 48 48 struct snd_dmaengine_dai_dma_data dma_params_rx; 49 49 struct sdma_peripheral_config sdmacfg; 50 + struct snd_soc_card *card; 50 51 unsigned int dataline; 51 52 char name[32]; 52 53 int irq[MICFIL_IRQ_LINES]; 53 54 enum quality quality; 54 55 int dc_remover; 56 + int vad_init_mode; 57 + int vad_enabled; 58 + int vad_detected; 55 59 }; 56 60 57 61 struct fsl_micfil_soc_data { ··· 156 152 return micfil_set_quality(micfil); 157 153 } 158 154 155 + static const char * const micfil_hwvad_enable[] = { 156 + "Disable (Record only)", 157 + "Enable (Record with Vad)", 158 + }; 159 + 160 + static const char * const micfil_hwvad_init_mode[] = { 161 + "Envelope mode", "Energy mode", 162 + }; 163 + 164 + static const char * const micfil_hwvad_hpf_texts[] = { 165 + "Filter bypass", 166 + "Cut-off @1750Hz", 167 + "Cut-off @215Hz", 168 + "Cut-off @102Hz", 169 + }; 170 + 171 + /* 172 + * DC Remover Control 173 + * Filter Bypassed 1 1 174 + * Cut-off @21Hz 0 0 175 + * Cut-off @83Hz 0 1 176 + * Cut-off @152HZ 1 0 177 + */ 178 + static const char * const micfil_dc_remover_texts[] = { 179 + "Cut-off @21Hz", "Cut-off @83Hz", 180 + "Cut-off @152Hz", "Bypass", 181 + }; 182 + 183 + static const struct soc_enum hwvad_enable_enum = 184 + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(micfil_hwvad_enable), 185 + micfil_hwvad_enable); 186 + static const struct soc_enum hwvad_init_mode_enum = 187 + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(micfil_hwvad_init_mode), 188 + micfil_hwvad_init_mode); 189 + static const struct soc_enum hwvad_hpf_enum = 190 + SOC_ENUM_SINGLE(REG_MICFIL_VAD0_CTRL2, 0, 191 + ARRAY_SIZE(micfil_hwvad_hpf_texts), 192 + micfil_hwvad_hpf_texts); 193 + static const struct soc_enum fsl_micfil_dc_remover_enum = 194 + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(micfil_dc_remover_texts), 195 + micfil_dc_remover_texts); 196 + 197 + static int micfil_put_dc_remover_state(struct snd_kcontrol *kcontrol, 198 + struct snd_ctl_elem_value *ucontrol) 199 + { 200 + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 201 + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); 202 + struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp); 203 + unsigned int *item = ucontrol->value.enumerated.item; 204 + int val = snd_soc_enum_item_to_val(e, item[0]); 205 + int i = 0, ret = 0; 206 + u32 reg_val = 0; 207 + 208 + if (val < 0 || val > 3) 209 + return -EINVAL; 210 + 211 + micfil->dc_remover = val; 212 + 213 + /* Calculate total value for all channels */ 214 + for (i = 0; i < MICFIL_OUTPUT_CHANNELS; i++) 215 + reg_val |= val << MICFIL_DC_CHX_SHIFT(i); 216 + 217 + /* Update DC Remover mode for all channels */ 218 + ret = snd_soc_component_update_bits(comp, REG_MICFIL_DC_CTRL, 219 + MICFIL_DC_CTRL_CONFIG, reg_val); 220 + if (ret < 0) 221 + return ret; 222 + 223 + return 0; 224 + } 225 + 226 + static int micfil_get_dc_remover_state(struct snd_kcontrol *kcontrol, 227 + struct snd_ctl_elem_value *ucontrol) 228 + { 229 + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); 230 + struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp); 231 + 232 + ucontrol->value.enumerated.item[0] = micfil->dc_remover; 233 + 234 + return 0; 235 + } 236 + 237 + static int hwvad_put_enable(struct snd_kcontrol *kcontrol, 238 + struct snd_ctl_elem_value *ucontrol) 239 + { 240 + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); 241 + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 242 + unsigned int *item = ucontrol->value.enumerated.item; 243 + struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp); 244 + int val = snd_soc_enum_item_to_val(e, item[0]); 245 + 246 + micfil->vad_enabled = val; 247 + 248 + return 0; 249 + } 250 + 251 + static int hwvad_get_enable(struct snd_kcontrol *kcontrol, 252 + struct snd_ctl_elem_value *ucontrol) 253 + { 254 + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); 255 + struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp); 256 + 257 + ucontrol->value.enumerated.item[0] = micfil->vad_enabled; 258 + 259 + return 0; 260 + } 261 + 262 + static int hwvad_put_init_mode(struct snd_kcontrol *kcontrol, 263 + struct snd_ctl_elem_value *ucontrol) 264 + { 265 + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); 266 + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 267 + unsigned int *item = ucontrol->value.enumerated.item; 268 + struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp); 269 + int val = snd_soc_enum_item_to_val(e, item[0]); 270 + 271 + /* 0 - Envelope-based Mode 272 + * 1 - Energy-based Mode 273 + */ 274 + micfil->vad_init_mode = val; 275 + 276 + return 0; 277 + } 278 + 279 + static int hwvad_get_init_mode(struct snd_kcontrol *kcontrol, 280 + struct snd_ctl_elem_value *ucontrol) 281 + { 282 + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); 283 + struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp); 284 + 285 + ucontrol->value.enumerated.item[0] = micfil->vad_init_mode; 286 + 287 + return 0; 288 + } 289 + 290 + static int hwvad_detected(struct snd_kcontrol *kcontrol, 291 + struct snd_ctl_elem_value *ucontrol) 292 + { 293 + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); 294 + struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp); 295 + 296 + ucontrol->value.enumerated.item[0] = micfil->vad_detected; 297 + 298 + return 0; 299 + } 300 + 159 301 static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = { 160 302 SOC_SINGLE_SX_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL, 161 303 MICFIL_OUTGAIN_CHX_SHIFT(0), 0xF, 0x7, gain_tlv), ··· 322 172 SOC_ENUM_EXT("MICFIL Quality Select", 323 173 fsl_micfil_quality_enum, 324 174 micfil_quality_get, micfil_quality_set), 175 + SOC_ENUM_EXT("HWVAD Enablement Switch", hwvad_enable_enum, 176 + hwvad_get_enable, hwvad_put_enable), 177 + SOC_ENUM_EXT("HWVAD Initialization Mode", hwvad_init_mode_enum, 178 + hwvad_get_init_mode, hwvad_put_init_mode), 179 + SOC_ENUM("HWVAD High-Pass Filter", hwvad_hpf_enum), 180 + SOC_SINGLE("HWVAD ZCD Switch", REG_MICFIL_VAD0_ZCD, 0, 1, 0), 181 + SOC_SINGLE("HWVAD ZCD Auto Threshold Switch", 182 + REG_MICFIL_VAD0_ZCD, 2, 1, 0), 183 + SOC_ENUM_EXT("MICFIL DC Remover Control", fsl_micfil_dc_remover_enum, 184 + micfil_get_dc_remover_state, micfil_put_dc_remover_state), 185 + SOC_SINGLE("HWVAD Input Gain", REG_MICFIL_VAD0_CTRL2, 8, 15, 0), 186 + SOC_SINGLE("HWVAD Sound Gain", REG_MICFIL_VAD0_SCONFIG, 0, 15, 0), 187 + SOC_SINGLE("HWVAD Noise Gain", REG_MICFIL_VAD0_NCONFIG, 0, 15, 0), 188 + SOC_SINGLE_RANGE("HWVAD Detector Frame Time", REG_MICFIL_VAD0_CTRL2, 16, 0, 63, 0), 189 + SOC_SINGLE("HWVAD Detector Initialization Time", REG_MICFIL_VAD0_CTRL1, 8, 31, 0), 190 + SOC_SINGLE("HWVAD Noise Filter Adjustment", REG_MICFIL_VAD0_NCONFIG, 8, 31, 0), 191 + SOC_SINGLE("HWVAD ZCD Threshold", REG_MICFIL_VAD0_ZCD, 16, 1023, 0), 192 + SOC_SINGLE("HWVAD ZCD Adjustment", REG_MICFIL_VAD0_ZCD, 8, 15, 0), 193 + SOC_SINGLE("HWVAD ZCD And Behavior Switch", 194 + REG_MICFIL_VAD0_ZCD, 4, 1, 0), 195 + SOC_SINGLE_BOOL_EXT("VAD Detected", 0, hwvad_detected, NULL), 325 196 }; 326 197 327 198 /* The SRES is a self-negated bit which provides the CPU with the ··· 381 210 return 0; 382 211 } 383 212 213 + /* Enable/disable hwvad interrupts */ 214 + static int fsl_micfil_configure_hwvad_interrupts(struct fsl_micfil *micfil, int enable) 215 + { 216 + u32 vadie_reg = enable ? MICFIL_VAD0_CTRL1_IE : 0; 217 + u32 vaderie_reg = enable ? MICFIL_VAD0_CTRL1_ERIE : 0; 218 + 219 + /* Voice Activity Detector Error Interruption */ 220 + regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1, 221 + MICFIL_VAD0_CTRL1_ERIE, vaderie_reg); 222 + 223 + /* Voice Activity Detector Interruption */ 224 + regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1, 225 + MICFIL_VAD0_CTRL1_IE, vadie_reg); 226 + 227 + return 0; 228 + } 229 + 230 + /* Configuration done only in energy-based initialization mode */ 231 + static int fsl_micfil_init_hwvad_energy_mode(struct fsl_micfil *micfil) 232 + { 233 + /* Keep the VADFRENDIS bitfield cleared. */ 234 + regmap_clear_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL2, 235 + MICFIL_VAD0_CTRL2_FRENDIS); 236 + 237 + /* Keep the VADPREFEN bitfield cleared. */ 238 + regmap_clear_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL2, 239 + MICFIL_VAD0_CTRL2_PREFEN); 240 + 241 + /* Keep the VADSFILEN bitfield cleared. */ 242 + regmap_clear_bits(micfil->regmap, REG_MICFIL_VAD0_SCONFIG, 243 + MICFIL_VAD0_SCONFIG_SFILEN); 244 + 245 + /* Keep the VADSMAXEN bitfield cleared. */ 246 + regmap_clear_bits(micfil->regmap, REG_MICFIL_VAD0_SCONFIG, 247 + MICFIL_VAD0_SCONFIG_SMAXEN); 248 + 249 + /* Keep the VADNFILAUTO bitfield asserted. */ 250 + regmap_set_bits(micfil->regmap, REG_MICFIL_VAD0_NCONFIG, 251 + MICFIL_VAD0_NCONFIG_NFILAUT); 252 + 253 + /* Keep the VADNMINEN bitfield cleared. */ 254 + regmap_clear_bits(micfil->regmap, REG_MICFIL_VAD0_NCONFIG, 255 + MICFIL_VAD0_NCONFIG_NMINEN); 256 + 257 + /* Keep the VADNDECEN bitfield cleared. */ 258 + regmap_clear_bits(micfil->regmap, REG_MICFIL_VAD0_NCONFIG, 259 + MICFIL_VAD0_NCONFIG_NDECEN); 260 + 261 + /* Keep the VADNOREN bitfield cleared. */ 262 + regmap_clear_bits(micfil->regmap, REG_MICFIL_VAD0_NCONFIG, 263 + MICFIL_VAD0_NCONFIG_NOREN); 264 + 265 + return 0; 266 + } 267 + 268 + /* Configuration done only in envelope-based initialization mode */ 269 + static int fsl_micfil_init_hwvad_envelope_mode(struct fsl_micfil *micfil) 270 + { 271 + /* Assert the VADFRENDIS bitfield */ 272 + regmap_set_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL2, 273 + MICFIL_VAD0_CTRL2_FRENDIS); 274 + 275 + /* Assert the VADPREFEN bitfield. */ 276 + regmap_set_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL2, 277 + MICFIL_VAD0_CTRL2_PREFEN); 278 + 279 + /* Assert the VADSFILEN bitfield. */ 280 + regmap_set_bits(micfil->regmap, REG_MICFIL_VAD0_SCONFIG, 281 + MICFIL_VAD0_SCONFIG_SFILEN); 282 + 283 + /* Assert the VADSMAXEN bitfield. */ 284 + regmap_set_bits(micfil->regmap, REG_MICFIL_VAD0_SCONFIG, 285 + MICFIL_VAD0_SCONFIG_SMAXEN); 286 + 287 + /* Clear the VADNFILAUTO bitfield */ 288 + regmap_clear_bits(micfil->regmap, REG_MICFIL_VAD0_NCONFIG, 289 + MICFIL_VAD0_NCONFIG_NFILAUT); 290 + 291 + /* Assert the VADNMINEN bitfield. */ 292 + regmap_set_bits(micfil->regmap, REG_MICFIL_VAD0_NCONFIG, 293 + MICFIL_VAD0_NCONFIG_NMINEN); 294 + 295 + /* Assert the VADNDECEN bitfield. */ 296 + regmap_set_bits(micfil->regmap, REG_MICFIL_VAD0_NCONFIG, 297 + MICFIL_VAD0_NCONFIG_NDECEN); 298 + 299 + /* Assert VADNOREN bitfield. */ 300 + regmap_set_bits(micfil->regmap, REG_MICFIL_VAD0_NCONFIG, 301 + MICFIL_VAD0_NCONFIG_NOREN); 302 + 303 + return 0; 304 + } 305 + 306 + /* 307 + * Hardware Voice Active Detection: The HWVAD takes data from the input 308 + * of a selected PDM microphone to detect if there is any 309 + * voice activity. When a voice activity is detected, an interrupt could 310 + * be delivered to the system. Initialization in section 8.4: 311 + * Can work in two modes: 312 + * -> Eneveope-based mode (section 8.4.1) 313 + * -> Energy-based mode (section 8.4.2) 314 + * 315 + * It is important to remark that the HWVAD detector could be enabled 316 + * or reset only when the MICFIL isn't running i.e. when the BSY_FIL 317 + * bit in STAT register is cleared 318 + */ 319 + static int fsl_micfil_hwvad_enable(struct fsl_micfil *micfil) 320 + { 321 + int ret; 322 + 323 + micfil->vad_detected = 0; 324 + 325 + /* envelope-based specific initialization */ 326 + if (micfil->vad_init_mode == MICFIL_HWVAD_ENVELOPE_MODE) 327 + ret = fsl_micfil_init_hwvad_envelope_mode(micfil); 328 + else 329 + ret = fsl_micfil_init_hwvad_energy_mode(micfil); 330 + if (ret) 331 + return ret; 332 + 333 + /* Voice Activity Detector Internal Filters Initialization*/ 334 + regmap_set_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1, 335 + MICFIL_VAD0_CTRL1_ST10); 336 + 337 + /* Voice Activity Detector Internal Filter */ 338 + regmap_clear_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1, 339 + MICFIL_VAD0_CTRL1_ST10); 340 + 341 + /* Enable Interrupts */ 342 + ret = fsl_micfil_configure_hwvad_interrupts(micfil, 1); 343 + if (ret) 344 + return ret; 345 + 346 + /* Voice Activity Detector Reset */ 347 + regmap_set_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1, 348 + MICFIL_VAD0_CTRL1_RST); 349 + 350 + /* Voice Activity Detector Enabled */ 351 + regmap_set_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1, 352 + MICFIL_VAD0_CTRL1_EN); 353 + 354 + return 0; 355 + } 356 + 357 + static int fsl_micfil_hwvad_disable(struct fsl_micfil *micfil) 358 + { 359 + struct device *dev = &micfil->pdev->dev; 360 + int ret = 0; 361 + 362 + /* Disable HWVAD */ 363 + regmap_clear_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1, 364 + MICFIL_VAD0_CTRL1_EN); 365 + 366 + /* Disable hwvad interrupts */ 367 + ret = fsl_micfil_configure_hwvad_interrupts(micfil, 0); 368 + if (ret) 369 + dev_err(dev, "Failed to disable interrupts\n"); 370 + 371 + return ret; 372 + } 373 + 384 374 static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd, 385 375 struct snd_soc_dai *dai) 386 376 { ··· 577 245 if (ret) 578 246 return ret; 579 247 248 + if (micfil->vad_enabled) 249 + fsl_micfil_hwvad_enable(micfil); 250 + 580 251 break; 581 252 case SNDRV_PCM_TRIGGER_STOP: 582 253 case SNDRV_PCM_TRIGGER_SUSPEND: 583 254 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 255 + if (micfil->vad_enabled) 256 + fsl_micfil_hwvad_disable(micfil); 257 + 584 258 /* Disable the module */ 585 259 ret = regmap_clear_bits(micfil->regmap, REG_MICFIL_CTRL1, 586 260 MICFIL_CTRL1_PDMIEN); ··· 666 328 FIELD_PREP(MICFIL_CTRL2_CLKDIV, clk_div) | 667 329 FIELD_PREP(MICFIL_CTRL2_CICOSR, 16 - osr)); 668 330 331 + /* Configure CIC OSR in VADCICOSR */ 332 + regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1, 333 + MICFIL_VAD0_CTRL1_CICOSR, 334 + FIELD_PREP(MICFIL_VAD0_CTRL1_CICOSR, 16 - osr)); 335 + 336 + /* Configure source channel in VADCHSEL */ 337 + regmap_update_bits(micfil->regmap, REG_MICFIL_VAD0_CTRL1, 338 + MICFIL_VAD0_CTRL1_CHSEL, 339 + FIELD_PREP(MICFIL_VAD0_CTRL1_CHSEL, (channels - 1))); 340 + 669 341 micfil->dma_params_rx.peripheral_config = &micfil->sdmacfg; 670 342 micfil->dma_params_rx.peripheral_size = sizeof(micfil->sdmacfg); 671 343 micfil->sdmacfg.n_fifos_src = channels; ··· 699 351 int ret, i; 700 352 701 353 micfil->quality = QUALITY_VLOW0; 354 + micfil->card = cpu_dai->component->card; 702 355 703 356 /* set default gain to 2 */ 704 357 regmap_write(micfil->regmap, REG_MICFIL_OUT_CTRL, 0x22222222); ··· 934 585 return IRQ_HANDLED; 935 586 } 936 587 588 + static irqreturn_t voice_detected_fn(int irq, void *devid) 589 + { 590 + struct fsl_micfil *micfil = (struct fsl_micfil *)devid; 591 + struct snd_kcontrol *kctl; 592 + 593 + if (!micfil->card) 594 + return IRQ_HANDLED; 595 + 596 + kctl = snd_soc_card_get_kcontrol(micfil->card, "VAD Detected"); 597 + if (!kctl) 598 + return IRQ_HANDLED; 599 + 600 + if (micfil->vad_detected) 601 + snd_ctl_notify(micfil->card->snd_card, 602 + SNDRV_CTL_EVENT_MASK_VALUE, 603 + &kctl->id); 604 + 605 + return IRQ_HANDLED; 606 + } 607 + 608 + static irqreturn_t hwvad_isr(int irq, void *devid) 609 + { 610 + struct fsl_micfil *micfil = (struct fsl_micfil *)devid; 611 + struct device *dev = &micfil->pdev->dev; 612 + u32 vad0_reg; 613 + int ret; 614 + 615 + regmap_read(micfil->regmap, REG_MICFIL_VAD0_STAT, &vad0_reg); 616 + 617 + /* 618 + * The only difference between MICFIL_VAD0_STAT_EF and 619 + * MICFIL_VAD0_STAT_IF is that the former requires Write 620 + * 1 to Clear. Since both flags are set, it is enough 621 + * to only read one of them 622 + */ 623 + if (vad0_reg & MICFIL_VAD0_STAT_IF) { 624 + /* Write 1 to clear */ 625 + regmap_write_bits(micfil->regmap, REG_MICFIL_VAD0_STAT, 626 + MICFIL_VAD0_STAT_IF, 627 + MICFIL_VAD0_STAT_IF); 628 + 629 + micfil->vad_detected = 1; 630 + } 631 + 632 + ret = fsl_micfil_hwvad_disable(micfil); 633 + if (ret) 634 + dev_err(dev, "Failed to disable hwvad\n"); 635 + 636 + return IRQ_WAKE_THREAD; 637 + } 638 + 639 + static irqreturn_t hwvad_err_isr(int irq, void *devid) 640 + { 641 + struct fsl_micfil *micfil = (struct fsl_micfil *)devid; 642 + struct device *dev = &micfil->pdev->dev; 643 + u32 vad0_reg; 644 + 645 + regmap_read(micfil->regmap, REG_MICFIL_VAD0_STAT, &vad0_reg); 646 + 647 + if (vad0_reg & MICFIL_VAD0_STAT_INSATF) 648 + dev_dbg(dev, "voice activity input overflow/underflow detected\n"); 649 + 650 + return IRQ_HANDLED; 651 + } 652 + 937 653 static int fsl_micfil_probe(struct platform_device *pdev) 938 654 { 939 655 struct device_node *np = pdev->dev.of_node; ··· 1087 673 micfil->name, micfil); 1088 674 if (ret) { 1089 675 dev_err(&pdev->dev, "failed to claim mic interface error irq %u\n", 676 + micfil->irq[1]); 677 + return ret; 678 + } 679 + 680 + /* Digital Microphone interface voice activity detector event */ 681 + ret = devm_request_threaded_irq(&pdev->dev, micfil->irq[2], 682 + hwvad_isr, voice_detected_fn, 683 + IRQF_SHARED, micfil->name, micfil); 684 + if (ret) { 685 + dev_err(&pdev->dev, "failed to claim hwvad event irq %u\n", 686 + micfil->irq[0]); 687 + return ret; 688 + } 689 + 690 + /* Digital Microphone interface voice activity detector error */ 691 + ret = devm_request_irq(&pdev->dev, micfil->irq[3], 692 + hwvad_err_isr, IRQF_SHARED, 693 + micfil->name, micfil); 694 + if (ret) { 695 + dev_err(&pdev->dev, "failed to claim hwvad error irq %u\n", 1090 696 micfil->irq[1]); 1091 697 return ret; 1092 698 }
+5 -1
sound/soc/fsl/fsl_micfil.h
··· 136 136 #define FIFO_PTRWID 3 137 137 #define FIFO_LEN BIT(FIFO_PTRWID) 138 138 139 - #define MICFIL_IRQ_LINES 2 139 + #define MICFIL_IRQ_LINES 4 140 140 #define MICFIL_MAX_RETRY 25 141 141 #define MICFIL_SLEEP_MIN 90000 /* in us */ 142 142 #define MICFIL_SLEEP_MAX 100000 /* in us */ 143 143 #define MICFIL_DMA_MAXBURST_RX 6 144 + 145 + /* HWVAD Constants */ 146 + #define MICFIL_HWVAD_ENVELOPE_MODE 0 147 + #define MICFIL_HWVAD_ENERGY_MODE 1 144 148 145 149 #endif /* _FSL_MICFIL_H */