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?
最適な場所:FSL-SAI CPU DAIトリガー(STOP)が実行される前にASoCの停止パスに「必須実行」操作を配置してください。できればコーデック/コンポーネントのストップトリガーコールバック、またはCPUのDAI停止前に注文されたマシン-ドライバリンク/コンポーネントトリガーコールバックとして。
なぜか:8M Mini i.MX NXP fsl_sai_trigger()はFIFO DMA要求や割り込みを無効にし、その後fsl_sai_config_disable()を呼び出してFSL_SAI_CSR_TEREをクリアし、現在のフレームが完成するまで待つことで処理SNDRV_PCM_TRIGGER_STOP。マスターモードではSAIブロックをリセットします。それは、SAIによって生成されたBCLKが停止/無効化される時点です。i.MX8MM SAIドライバーはDAI操作で.trigger = fsl_sai_trigger、.hw_free = fsl_sai_hw_freeとして登録されているhw_freeため、「BCLKが停止する前に」という要件はすでに遅すぎます。
ボード固有のBSPハックでない限り、fsl_sai_trigger()の中にコーデックI2Cを直接追加することは避けるべきです。汎用CPU-DAIドライバーを1つのコーデック/ボードポリシーに結合させます。Linux/NXP ASoCの分割は、コーデック制御I/Oをコーデックドライバに、CPUインターフェース制御をプラットフォーム/CPU DAIドライバに保持することを意図しています。NXPのドキュメントでは、I2Cを経由したコーデック制御I/OをASoC DAI操作を通じてエクスポートするコーデック・ドライバ機能として説明しています。
2つの実用的な実装パターン:
重要なPREEMPT_RT:通常のI2C転送はタスクコンテキスト操作であり、カーネルI2Cのドキュメントによると、I2Cプロトコル操作はタスクコンテキストでのみ使用可能であり、特別な遅延シャットダウンケース向けにオプションのアトミック転送フックが用意されています。したがって、PCM/ASoCパスが非アトミックとして構成され、カーネル内でコールバックコンテキストが検証されている場合を除き、アトミックPCMトリガーパスからブロッキングI2Cを実行しないでください。トリガーパスがアトミックな場合は、より安全なアーキテクチャを使用してください。コーデックの状態を早めに準備するか、BCLKを連続/ゲート状態に後から維持するか、CPU DAIトリガーで生のI2Cを実行するのではなく、スリープ可能な順序付きストップパスに操作を移動してください。