2399767_en-US

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

2399767_en-US

2399767_en-US

i.MX 8M Mini SAI: Where to perform I2C codec control before BCLK stops (PREEMPT_RT)
We are developing a system using an i.MX 8M Mini connected to an external audio codec (controlled via I2C) through SAI (I2S), running a kernel with the PREEMPT_RT configuration.

We need to perform codec operations (I2C) before the I2S BCLK stops.
Where would be the best place to insert this I2C handling?
Re: i.MX 8M Mini SAI: Where to perform I2C codec control before BCLK stops (PREEMPT_RT)

Best place: put the “must happen before BCLK stops” operation in the ASoC stop path before the fsl-sai CPU DAI trigger(STOP) runs — preferably as a codec/component stop-trigger callback, or as a machine-driver link/component trigger callback ordered before the CPU DAI stop.

Why: on i.MX 8M Mini the NXP fsl_sai_trigger() handles SNDRV_PCM_TRIGGER_STOP by disabling FIFO DMA request/interrupts and then calling fsl_sai_config_disable() , which clears FSL_SAI_CSR_TERE and waits until the current frame completes; in master mode it then resets the SAI block. That is the point where the SAI-generated BCLK is being stopped/disabled. The i.MX8MM SAI driver is registered with .trigger = fsl_sai_trigger and .hw_free = fsl_sai_hw_free in its DAI ops, so hw_free() is already too late for a “before BCLK stops” requirement. 

I would avoid adding codec I2C directly inside fsl_sai_trigger() unless this is a board-specific BSP hack. It couples a generic CPU-DAI driver to one codec/board policy. The Linux/NXP ASoC split is intended to keep codec control I/O in the codec driver and CPU interface control in the platform/CPU DAI driver; NXP documentation describes codec control I/O over I2C as codec-driver functionality exported through ASoC DAI ops. 

Two practical implementation patterns:

  • Codec DAI .trigger() / component .trigger() for STOP
    • Add the codec register writes on SNDRV_PCM_TRIGGER_STOP / SUSPEND / PAUSE_PUSH .
    • Make sure this callback runs before the CPU DAI fsl_sai_trigger(STOP) .
    • In current ASoC, the default stop order is DAI -> Component -> Link , and DAI iteration is CPU DAI then codec DAI, so a codec DAI trigger may be too late if the CPU DAI is first.
    • If you use a component trigger and keep/default stop order, component stop runs before the link callback but after DAI only in default order; alternatively set the DAI link’s trigger_stop order appropriately if your kernel supports it.
  • Machine driver snd_soc_ops.trigger() / link trigger
    • Put the board-specific codec I2C sequence in the machine driver’s .trigger() for stop commands.
    • Use ASoC trigger ordering so that the link-level stop runs before the DAI stop. The kernel exposes SND_SOC_TRIGGER_ORDER_LDC , documented as stop order Component -> DAI -> Link , and default stop order as DAI -> Component -> Link ; select the order that places your chosen callback before fsl_sai_trigger(STOP) .
    • This is often the cleanest place when the sequence is a board/system policy rather than a generic codec behavior.

Important PREEMPT_RT note: normal I2C transfers are task-context operations; kernel I2C documentation says I2C protocol operations are usable only from task context, with separate optional atomic transfer hooks for special late-shutdown cases.  Therefore, do not perform blocking I2C from an atomic PCM trigger path unless your PCM/ASoC path is configured as non-atomic and you have verified the callback context in your kernel. If the trigger path is atomic, use a safer architecture: prepare the codec state earlier, keep BCLK continuous/gated later, or move the operation to a sleepable ordered stop path rather than doing raw I2C in the CPU DAI trigger.

タグ(1)
評価なし
バージョン履歴
最終更新日:
1週間前
更新者: