RK 3288+ADAU 1977接続
既存のワークピース(RK 3399のマザーボードを使用)のオーディオチップセットが正常に動作しないようで、デバッグプロセスが必要で、テストボードを作成する必要があります.
ニードルマップと互換性のあるボードがあり、よくテストできると思っていたので、Tinkerボードを使用しました.
ほとんどのチップセットは、データテーブルの名前にかかわらず、回路図を提供しています.
回路は大体以下の通りです.
用意する。
ADAU 1977のSDATAUTは、RK 3288の ADAU 1977のBCL K線は、RK 3288の RK 3288受信データは、Masterとして動作する必要があります.
ADAU 1977のLLRCL K線は、RK 3288の
DirectionはOutputのはずです. AD11 - i2s_sclk - I2S_SCLK_GPIO6_A0 AG11 - i2s_lrckrx - I2S_LRCK_RX/GPIO6_A1 AE11 - i2s_sdi - I2S_SDI/GPIO6_A3 I 2 Cは、制御のためにSDA、SCLを接続する
I 2 S SCLK GPIO 6 A 0はGP 6 A 0 PCM CLK Rで、マザーボードの12番ピンに接続されています. I 2 S LLCK RX/GPIO 6 A 1はGP 6 A 1 PCM FSであり、マザーボードの37番ピンに接続されている. I 2 S SDI/GPIO 6 A 3 PCM SD、マザーボードの38番ピンに接続します. SDA/SCLはI 2 C 1に接続されている. カーネル設定の変更
SND_SOC_DAIFMT_I2S SND_SOC_DAIFMT_NB_NF SND_SOC_DAIFMT_CBM_CFM 上記の3つの定数を使用
I2S LEFT_J RIGHT_J DSP_A DSP_B NB_NF IB_NF NB_IF IB_IF ここで注意すべき部分は
IBの場合はblock Powerの6位を設定します.
これは、インバータlrclkとblockパワーを設定する部分のようです.
Bit/LR ClockのPolarityを変更した部分ですが、特に理由はないので変更する必要はありません.
(slaveと仮定し、使用状況が異なるため)
CBS CFS、CBM CFMの2種類が利用可能です.
アクションボディがslaveの場合、ファイルフォーマットもslaveに一致する必要があります.
従ってslaveとしてSND SOC DAIFMT CBS CFSを用いる.
同様に、データテーブルにも対応する内容があります.
ニードルマップと互換性のあるボードがあり、よくテストできると思っていたので、Tinkerボードを使用しました.
ほとんどのチップセットは、データテーブルの名前にかかわらず、回路図を提供しています.
回路は大体以下の通りです.
用意する。
Tinkerボード回路の点検
接続リンク DownloadプロジェクトのScheticsをダウンロードすればよい.
ボード上の40ピンのヘッダーからメインAPにアクセスできます.
ADAU 1977は、I 2 Cによって制御可能なADCである.
制御はI 2 C、データはI 2 Sです.
PIN名を覚えてデータテーブルを見ればいいです
RK 3288データテーブルの検証
I 2 Sシーケンスクロック(SCLK)LRクロック(RCK RX/TX)シーケンスデータ(SDI/O)などが確認できます.
やるべきこと
RK 3288は、ADAU 1977からデータを取得する必要があることを示す.
i2s_sdi
に接続する必要があります.i2s_sclk
に接続されている必要があります.ADAU 1977のLLRCL K線は、RK 3288の
i2s_lrclkrx
に接続されている.DirectionはOutputのはずです.
せつぞく
カーネル設定の変更
デバイスを追加する操作なので、デバイスツリーを変更する必要があります.
作業中、Rockchip linux kernelにはadau 1977の関連ソースコードがありません.
そこで、Raspberry piのカーネルソースコードを持ってきました.
リンクのadau 1977-adc.cをsound/soc/rockchipにコピーします.
構築準備
Kconfigの変更
config SND_SOC_ADAU1977_ADC
tristate "Support for ADAU1977 ADC"
depends on SND_SOC_ROCKCHIP_I2S
select SND_SOC_ADAU1977_I2S
help
Say Y or M if you want to add support for ADAU1977 ADC.
Makefileの変更
snd-soc-adau1977-adc-objs := adau1977-adc.o
obj-$(CONFIG_SND_SOC_ADAU1977_ADC) += snd-soc-adau1977-adc.o
デバイスドライバの準備
リンクのadau 1977-adc-overlay.dtsをarch/arm/boot/dts/overlaysにコピーします.
dtsの変更
// Definitions for ADAU1977 ADC
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2708";
fragment@0 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
adau1977: codec@11 {
compatible = "adi,adau1977";
reg = <0x11>;
reset-gpios = <&gpio 5 0>;
AVDD-supply = <&vdd_3v3_reg>;
};
};
};
fragment@1 {
target = <&i2s>;
__overlay__ {
status = "okay";
};
};
fragment@2 {
target = <&sound>;
__overlay__ {
compatible = "adi,adau1977-adc";
i2s-controller = <&i2s>;
status = "okay";
};
};
};
Overlayが登録して使用する場合、デバイスをキャプチャできないという問題があります.
rk3288-miniarm.クリップをdtsに直接追加することをお勧めします.(操作確認)
次にdefconfigを適用しmake menuconfigを実行してADAU 1977を有効にします
config設定が完了すると、構築後のカーネルインストールパスでイメージ、モジュール、およびデバイスに関連するファイルを上書きできます.
デバイス接続の検証
回路基板が起動すると、ドライバがオンラインになると、デバイスがキャプチャされているのが見えます.
ただし、初期化操作は行われていません.ドライバコードを変更する必要があります.
ドライバコードの変更
アナログデバイスが提供するリソースを参照して改訂した.linux/sound/soc/bcm/adau1977-adc.c
ファイルを修正すると、linux/sound/soc/rockchip
ディレクトリに入れなければなりません.static int eval_adau1977_init(struct snd_soc_pcm_runtime *rtd)
{
int ret;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
// I2S
// ret = snd_soc_dai_set_tdm_slot(codec_dai, 0, 0, 0, 0);
// TDM
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0, 0x0f, 8, 16);
if (ret < 0)
return ret;
// I2S
// return snd_soc_codec_set_sysclk(rtd->codec, ADAU1977_SYSCLK,
// ADAU1977_SYSCLK_SRC_LRCLK, 1228000, SND_SOC_CLOCK_IN);
// TDM
return snd_soc_codec_set_sysclk(rtd->codec, ADAU1977_SYSCLK,
ADAU1977_SYSCLK_SRC_LRCLK, 1228000, SND_SOC_CLOCK_IN);
}
以上のように変更して使用できます.
後で必要とされるのを恐れて記録した部分。
選択モード(I 2 S/TDM)
I 2 S/TDMモードにより、渡すパラメータが異なりますint snd_soc_dai_set_tdm_slot(
struct snd_soc_dai * dai**,
unsigned int** tx_mask**,
unsigned int** rx_mask**,
int** slots**,
int** slot_width**
);
リンクを参照すると、TDMモードは以下のようになる.ret = snd_soc_dai_set_tdm_slot(
snd_soc_dai = codec_dai,
tx_mask = 0x00, // 0000 0000 중 선택된 비트에 순서대로 채널을 할당한다.
rx_mask = 0x0f, // 0000 0000 중 선택된 비트에 순서대로 채널을 할당한다.
slots = 4, // 슬롯 수이며 채널을 얼만큼 전송할 것인지 의미한다.
slot_width = 32 // 슬롯당 데이터 길이를 의미한다.
);
上記の例は[0,1,2,3]スロット割り当て[1,2,3,4]チャネルである.
つまり、各スロットのデータ長を32ビットに設定します.static struct snd_soc_dai_link snd_rpi_adau1977_dai[] = {
{
.name = "adau1977",
.stream_name = "ADAU1977",
.cpu_dai_name = "bcm2708-i2s.0",
.codec_dai_name = "adau1977-hifi",
.platform_name = "bcm2708-i2s.0",
.codec_name = "adau1977.1-0011",
.init = eval_adau1977_init,
/* I2S
.dai_fmt = SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM,
},
*/
// TDM
.dai_fmt = SND_SOC_DAIFMT_DSP_B |
SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
},
};
ここで変更した部分は上記の部分と関係があります.
設定はI 2 SかTDMかによります.dai_fmt
は、ADAU 1977のデジタルオーディオインタフェースフォーマットをどのように設定および使用するかを変更するデジタルオーディオインタフェースフォーマットを表す.
必要な定数を設定するには、次の手順に従います.
定義はadau1979.cにあり、ADAU 1977の基本的な動作原理を体現している.
定数関連コンテンツ
config SND_SOC_ADAU1977_ADC
tristate "Support for ADAU1977 ADC"
depends on SND_SOC_ROCKCHIP_I2S
select SND_SOC_ADAU1977_I2S
help
Say Y or M if you want to add support for ADAU1977 ADC.
snd-soc-adau1977-adc-objs := adau1977-adc.o
obj-$(CONFIG_SND_SOC_ADAU1977_ADC) += snd-soc-adau1977-adc.o
// Definitions for ADAU1977 ADC
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2708";
fragment@0 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
adau1977: codec@11 {
compatible = "adi,adau1977";
reg = <0x11>;
reset-gpios = <&gpio 5 0>;
AVDD-supply = <&vdd_3v3_reg>;
};
};
};
fragment@1 {
target = <&i2s>;
__overlay__ {
status = "okay";
};
};
fragment@2 {
target = <&sound>;
__overlay__ {
compatible = "adi,adau1977-adc";
i2s-controller = <&i2s>;
status = "okay";
};
};
};
回路基板が起動すると、ドライバがオンラインになると、デバイスがキャプチャされているのが見えます.
ただし、初期化操作は行われていません.ドライバコードを変更する必要があります.
ドライバコードの変更
アナログデバイスが提供するリソースを参照して改訂した.linux/sound/soc/bcm/adau1977-adc.c
ファイルを修正すると、linux/sound/soc/rockchip
ディレクトリに入れなければなりません.static int eval_adau1977_init(struct snd_soc_pcm_runtime *rtd)
{
int ret;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
// I2S
// ret = snd_soc_dai_set_tdm_slot(codec_dai, 0, 0, 0, 0);
// TDM
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0, 0x0f, 8, 16);
if (ret < 0)
return ret;
// I2S
// return snd_soc_codec_set_sysclk(rtd->codec, ADAU1977_SYSCLK,
// ADAU1977_SYSCLK_SRC_LRCLK, 1228000, SND_SOC_CLOCK_IN);
// TDM
return snd_soc_codec_set_sysclk(rtd->codec, ADAU1977_SYSCLK,
ADAU1977_SYSCLK_SRC_LRCLK, 1228000, SND_SOC_CLOCK_IN);
}
以上のように変更して使用できます.
後で必要とされるのを恐れて記録した部分。
選択モード(I 2 S/TDM)
I 2 S/TDMモードにより、渡すパラメータが異なりますint snd_soc_dai_set_tdm_slot(
struct snd_soc_dai * dai**,
unsigned int** tx_mask**,
unsigned int** rx_mask**,
int** slots**,
int** slot_width**
);
リンクを参照すると、TDMモードは以下のようになる.ret = snd_soc_dai_set_tdm_slot(
snd_soc_dai = codec_dai,
tx_mask = 0x00, // 0000 0000 중 선택된 비트에 순서대로 채널을 할당한다.
rx_mask = 0x0f, // 0000 0000 중 선택된 비트에 순서대로 채널을 할당한다.
slots = 4, // 슬롯 수이며 채널을 얼만큼 전송할 것인지 의미한다.
slot_width = 32 // 슬롯당 데이터 길이를 의미한다.
);
上記の例は[0,1,2,3]スロット割り当て[1,2,3,4]チャネルである.
つまり、各スロットのデータ長を32ビットに設定します.static struct snd_soc_dai_link snd_rpi_adau1977_dai[] = {
{
.name = "adau1977",
.stream_name = "ADAU1977",
.cpu_dai_name = "bcm2708-i2s.0",
.codec_dai_name = "adau1977-hifi",
.platform_name = "bcm2708-i2s.0",
.codec_name = "adau1977.1-0011",
.init = eval_adau1977_init,
/* I2S
.dai_fmt = SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM,
},
*/
// TDM
.dai_fmt = SND_SOC_DAIFMT_DSP_B |
SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
},
};
ここで変更した部分は上記の部分と関係があります.
設定はI 2 SかTDMかによります.dai_fmt
は、ADAU 1977のデジタルオーディオインタフェースフォーマットをどのように設定および使用するかを変更するデジタルオーディオインタフェースフォーマットを表す.
必要な定数を設定するには、次の手順に従います.
定義はadau1979.cにあり、ADAU 1977の基本的な動作原理を体現している.
定数関連コンテンツ
static int eval_adau1977_init(struct snd_soc_pcm_runtime *rtd)
{
int ret;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
// I2S
// ret = snd_soc_dai_set_tdm_slot(codec_dai, 0, 0, 0, 0);
// TDM
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0, 0x0f, 8, 16);
if (ret < 0)
return ret;
// I2S
// return snd_soc_codec_set_sysclk(rtd->codec, ADAU1977_SYSCLK,
// ADAU1977_SYSCLK_SRC_LRCLK, 1228000, SND_SOC_CLOCK_IN);
// TDM
return snd_soc_codec_set_sysclk(rtd->codec, ADAU1977_SYSCLK,
ADAU1977_SYSCLK_SRC_LRCLK, 1228000, SND_SOC_CLOCK_IN);
}
選択モード(I 2 S/TDM)
I 2 S/TDMモードにより、渡すパラメータが異なります
int snd_soc_dai_set_tdm_slot(
struct snd_soc_dai * dai**,
unsigned int** tx_mask**,
unsigned int** rx_mask**,
int** slots**,
int** slot_width**
);
リンクを参照すると、TDMモードは以下のようになる.ret = snd_soc_dai_set_tdm_slot(
snd_soc_dai = codec_dai,
tx_mask = 0x00, // 0000 0000 중 선택된 비트에 순서대로 채널을 할당한다.
rx_mask = 0x0f, // 0000 0000 중 선택된 비트에 순서대로 채널을 할당한다.
slots = 4, // 슬롯 수이며 채널을 얼만큼 전송할 것인지 의미한다.
slot_width = 32 // 슬롯당 데이터 길이를 의미한다.
);
上記の例は[0,1,2,3]スロット割り当て[1,2,3,4]チャネルである.つまり、各スロットのデータ長を32ビットに設定します.
static struct snd_soc_dai_link snd_rpi_adau1977_dai[] = {
{
.name = "adau1977",
.stream_name = "ADAU1977",
.cpu_dai_name = "bcm2708-i2s.0",
.codec_dai_name = "adau1977-hifi",
.platform_name = "bcm2708-i2s.0",
.codec_name = "adau1977.1-0011",
.init = eval_adau1977_init,
/* I2S
.dai_fmt = SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM,
},
*/
// TDM
.dai_fmt = SND_SOC_DAIFMT_DSP_B |
SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
},
};
ここで変更した部分は上記の部分と関係があります.設定はI 2 SかTDMかによります.
dai_fmt
は、ADAU 1977のデジタルオーディオインタフェースフォーマットをどのように設定および使用するかを変更するデジタルオーディオインタフェースフォーマットを表す.必要な定数を設定するには、次の手順に従います.
定義はadau1979.cにあり、ADAU 1977の基本的な動作原理を体現している.
定数関連コンテンツ
static int adau1977_set_dai_fmt(
struct snd_soc_dai *dai,
unsigned int fmt
)
上記の関数の動作原理を検証できます.SND_SOC_DAIFMT_I2S
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
ctrl0 |= ADAU1977_SAI_CTRL0_FMT_I2S;
break;
case SND_SOC_DAIFMT_LEFT_J:
ctrl0 |= ADAU1977_SAI_CTRL0_FMT_LJ;
invert_lrclk = !invert_lrclk;
break;
case SND_SOC_DAIFMT_RIGHT_J:
ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_24BIT;
adau1977->right_j = true;
invert_lrclk = !invert_lrclk;
break;
case SND_SOC_DAIFMT_DSP_A:
ctrl1 |= ADAU1977_SAI_CTRL1_LRCLK_PULSE;
ctrl0 |= ADAU1977_SAI_CTRL0_FMT_I2S;
invert_lrclk = false;
break;
case SND_SOC_DAIFMT_DSP_B:
ctrl1 |= ADAU1977_SAI_CTRL1_LRCLK_PULSE;
ctrl0 |= ADAU1977_SAI_CTRL0_FMT_LJ;
invert_lrclk = false;
break;
default:
return -EINVAL;
}
SND_SOC_DAIFMT_NB_NF
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF:
invert_lrclk = false;
break;
case SND_SOC_DAIFMT_IB_NF:
block_power |= ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE;
invert_lrclk = false;
break;
case SND_SOC_DAIFMT_NB_IF:
invert_lrclk = true;
break;
case SND_SOC_DAIFMT_IB_IF:
block_power |= ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE;
invert_lrclk = true;
break;
default:
return -EINVAL;
}
#define ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE BIT(6)
.IBの場合はblock Powerの6位を設定します.
これは、インバータlrclkとblockパワーを設定する部分のようです.
Bit/LR ClockのPolarityを変更した部分ですが、特に理由はないので変更する必要はありません.
SND_SOC_DAIFMT_CBM_CFM
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
adau1977->master = false;
break;
case SND_SOC_DAIFMT_CBM_CFM:
ctrl1 |= ADAU1977_SAI_CTRL1_MASTER;
adau1977->master = true;
break;
default:
return -EINVAL;
}
これまでadau1977-adc.c
で動作主体がMasterかSlaveかの設定部分であることが確認されていた.(slaveと仮定し、使用状況が異なるため)
CBS CFS、CBM CFMの2種類が利用可能です.
アクションボディがslaveの場合、ファイルフォーマットもslaveに一致する必要があります.
従ってslaveとしてSND SOC DAIFMT CBS CFSを用いる.
同様に、データテーブルにも対応する内容があります.
Reference
この問題について(RK 3288+ADAU 1977接続), 我々は、より多くの情報をここで見つけました https://velog.io/@d3fau1t/RK3288-ADAU1977-연결テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol