Linux向けAK449x Codec Driverの紹介
旭化成エレクトロニクス製 AK4490/AK4495/AK4497/AK4493向けLinux Driverの紹介です。NanoPi NEO2でAK449xシリーズを鳴らすために作成しました。
ALSA SoC Codecドライバとして実装しています。NanoPi NEO2/Raspberry Pi Zeroで動作確認済み。そのほかのSBCでもDAI LINKドライバとdevice-treeを適切に用意すれば使用可能だと思います。Raspberry Pi Zeroで鳴らす手順はそのうちブログに書く予定です。
ライセンスはLinux Kernel ModuleなのでGPLv2です。自由に組み込んで使用してください。何か面白いブツができたら教えて頂けるとうれしいです。
できること
- 標準機能
- Alsa Mixer設定可能項目
- ディエンファシス設定
- 電子ボリューム設定
- デジタルフィルタ設定
- Sound Control設定
- HLOAD ON/OFF設定(AK4497のみ)
- Gain Control設定(AK4493/AK4497のみ)
- ATT遷移時間設定(AK4493/AK4497のみ)
- 出力制御機能(device-treeで設定)
- STEREO出力の左右入れ替え
- MONOモード設定
- 出力位相の変更
ドライバのダウンロード
この辺にソースがあります。
https://raw.githubusercontent.com/tkztkztkz/linux/npi-audio-4.11.y/sound/soc/codecs/ak449x.c
https://raw.githubusercontent.com/tkztkztkz/linux/npi-audio-4.11.y/sound/soc/codecs/ak449x.h
NanoPi NEO2用のイメージだとこの辺に導入済みです。
NanoPi Neo2用 Volumio2 - _tkz_ memo
dts設定方法
NanoPi NEO2
dtsの設定例 通常のステレオ仕様(I2C ADDR 0x10)
&i2c0 { status = "okay"; ak449x: ak449x-codec@10 { #sound-dai-cells = <0>; compatible = "asahi-kasei,ak449x"; reg = <0x10>; /* I2C addr */ status = "okay"; chip = "AK4495"; /* AK4490/AK4495/AK4497/AK4493 */ reset-gpios = <&pio 6 7 GPIO_ACTIVE_LOW>; /* PG7 */ /* pdn pin */ mute-gpios = <&pio 6 8 GPIO_ACTIVE_LOW>; /* PG8 */ /* external mute */ }; &i2s0 { sound-dai = <&ak449x>; /* dai link target */ status = "okay"; };
dtsの設定例 DualMonoバランス出力仕様(I2C ADDR 0x10/0x11)
&i2c0 { ak449x1: ak449x-codec@10 { #sound-dai-cells = <0>; compatible = "asahi-kasei,ak449x"; reg = <0x10>; /* I2C addr */ status = "okay"; chip = "AK4495"; /* AK4490/AK4495/AK4497/AK4493 */ chmode = "MONO_LCH"; /* STEREO/STEREO_INVERT/MONO_LCH/MONO_RCH */ phase = "LIRN"; /* LNRN LNRI LIRN LIRI - N=non-invert I=invert*/ reset-gpios = <&pio 6 7 GPIO_ACTIVE_LOW>; /* PG7 */ /* pdn pin */ mute-gpios = <&pio 6 8 GPIO_ACTIVE_LOW>; /* PG8 */ /* external mute */ }; ak449x2: ak449x-codec@11 { #sound-dai-cells = <0>; compatible = "asahi-kasei,ak449x"; reg = <0x11>; /* I2C addr */ status = "okay"; chip = "AK4495"; /* AK4490/AK4495/AK4497/AK4493 */ chmode = "MONO_RCH"; /* STEREO/STEREO_INVERT/MONO_LCH/MONO_RCH */ phase = "LIRN"; /* LNRN LNRI LIRN LIRI - N=non-invert I=invert*/ }; }; &i2s0 { sound-dai = <&ak449x1 &ak449x2>; /* dai link target */ status = "okay"; };
Raspberry Pi Zero
dt-overlayの設定例 通常のステレオ仕様(I2C ADDR 0x10)
- 注 i2s-codecをdevice-treeから指定できるように改造したhifiberry-dac.cを使用した場合
- hifiberry-dac.cの改造はこの記事を参照
Raspberry Pi ZeroのI2Sオーディオドライバに非Codecドライバを追加登録する方法 - _tkz_ memo
// Definitions for HiFiBerry DAC /dts-v1/; /plugin/; / { compatible = "brcm,bcm2708"; fragment@0 { target = <&i2s>; __overlay__ { status = "okay"; }; }; fragment@1 { target = <&i2c1>; __overlay__ { #address-cells = <1>; #size-cells = <0>; status = "okay"; ak449x: ak449x-codec@10 { #sound-dai-cells = <0>; compatible = "asahi-kasei,ak449x"; reg = <0x10>; /* I2C addr */ status = "okay"; chip = "AK4495"; /* AK4490/AK4495/AK4497/AK4493 */ chmode = "STEREO"; /* STEREO/STEREO_INVERT/MONO_LCH/MONO_RCH */ reset-gpios = <&gpio 15 1>; /* GPIO15 */ /* pdn pin */ mute-gpios = <&gpio 23 1>; /* GPIO23 */ /* external mute */ }; }; }; fragment@2 { target = <&sound>; __overlay__ { compatible = "hifiberry,hifiberry-dac"; i2s-controller = <&i2s>; i2s-codec = <&ak449x>; status = "okay"; }; }; };
パラメータについて
- chip (AK4490/AK4495/AK4497/AK4493)
- 制御対象チップを設定します
- デフォルトは4495となります
- 下記項目の動作が変わります
- HLOAD(4497のみ)
- Gain Control(4493/4497のみ)
- ソフトMUTEの遷移時間
- chmode (STEREO/STEREO_INVERT/MONO_LCH/MONO_RCH)
- 動作モードを設定します
- デフォルトはSTEREOとなります
- Dual MonoやSTEREOの左右を入れ替える場合に指定します
- phase (LNRN LNRI LIRN LIRI - N=non-invert I=invert)
- 出力位相を設定します
- デフォルトはLNRNとなります。L/R CHとも正相出力。
- LIRIにするとL/R CHとも逆相出力となります。
- 出力位相を変えたり、Dual Mono設定時、バランス出力する場合などに指定します
- reset-gpios
- PDN制御出力を行うピンを指定します
- デフォルトは無効です
- 出力論理はGPIOドライバの指定に従います(出力論理変更ができない場合はActive Highになるはず)
- mute-gpios
- 外部MUTE制御出力を行うピンを指定します
- デフォルトは無効です
- 出力論理はGPIOドライバの指定に従います(出力論理変更ができない場合はActive Highになるはず)
- MUTEの制御順は下記となります
- Power On -> 外部MUTE assert
- 再生開始 MCLK/LRCLK設定 -> 外部MUTE negate -> ソフトMUTE negate -> wait
- 再生停止 ソフトMUTE assert -> wait -> 外部MUTE assert -> MCLK/LRCLK設定
備考
- ポップノイズ回避について
- AK449xシリーズはMCLK/LRCLKの開始・停止でポップノイズが発生します
- ソフトMUTE制御だけでは回避できません
- 外部MUTE制御を使用して、リレーかFETでMUTE回路を組むことをオススメします
- 複数のAK449Xを制御する場合には、最初に指定するcodecにのみGPIO設定を記述してください
- PDN制御について