Audio関連

現在、まったく分かっていません…orz
アドバイス等あれば、 Twitter か下記コメント欄に記入して頂けると幸いです。

現在の状況

完了

  • msm_audio_dev_ctrl への入出力
  • ae2drv をkernelモジュール化した
  • ae2drv の完全可視化は完了(※エラー処理除く)
  • ae2drv関連については別ページにした。→ae2関連
  • /dev/msm_* は kernel/arch/arm/mach-msm/qdsp6 以下にある
  • /dev/ae2 をオープンすると、ma_Open が呼ばれる
  • Audio初期化ルーチン周辺でkernel の ma_Open が呼ばれる→ae2関連

確認中

  • ae2drv.c 内で GPIO 関連の呼び出しがある→GPIO関連
  • どうも再生時に /dev/i2c-0 へ書き込みをしている→I2C関連
  • 無保証です。DEBUG中に2回ほど、リブートしました。(/dev/ae2 を2重openするとダメのようだ)
  • 電源管理(音源チップ、スピーカアンプ)→kernel関連???
  • msm8k_cad はkernel内で呼び出されているようだ。


現状の未着手な課題

  • I2Cの内容は不明
  • I2Sの内容も未解明 (仕様すら調べていない…)
  • smd_shdiag_open とは何か?
  • ボリューム調整
  • kernel の pmem の調査
  • /dev/pmem_adsp は全く着手していない


予想される流れ、進捗と現在

/dev/msm_audio_dev_ctrl 初期化 実装完了

/dev/ae2 初期化 ソースコード部分ほぼ実装完了。 変数、未完了。
→ ae2drv 内にてGPIOもONされる

どこかで、パワーマネージメント関連が関係?? /dev/power以下を試験中

I2Cアクセス 実装完了 変数、未完了

(I2S)→(msm8k_cad)→(msm8k_eqlzr)

/dev/msm_pcm へ Audio データ転送 実装完了

  • ( )は直接コールせず、kernel内で連鎖的に呼び出されるかも(?)な項目
  • ae2…dump&trace完了 ただし、バイナリの意味は不明
  • GPIO…dump&trace半完了 ただし、バイナリの意味は不明
  • msm_audio_dev_ctrl…dump&trace完了 内容もほぼ判明
  • msm_pcm…デフォルトのDEBUGをonにした。詳細未解明だが、PCMデータを流し込めばいけそう。


本内容について

  • 2ch root4スレにて、27氏の発言169-172における sound コマンド
  • fi01氏の214における /dev/i2c-0 周り情報
  • kernel 内にて必要箇所の DEBUG を有効にした結果
をまとめたもの。

はじめに

私はコレをチェックせずにちょっと遠回りした。
ls -l /dev/ | grep audio
crw-rw-rw- system   audio    239,   0 2011-02-10 23:50 ae2
crw-rw---- system   audio     10,   1 2011-02-10 23:50 pmem_adsp
crw-rw---- system   audio     10,  44 2011-02-10 23:50 msm_qcelp_in
crw-rw---- system   audio     10,  45 2011-02-10 23:50 msm_evrc_in
crw-rw-rw- system   audio     10,  46 2011-02-10 23:50 msm_audio_dev_ctrl
crw-rw-rw- system   audio     10,  49 2011-02-10 23:50 msm_voice
crw-rw---- system   audio     10,  51 2011-02-10 23:50 msm_mp3
crw-rw---- system   audio     10,  52 2011-02-10 23:50 msm_aac_in
crw-rw---- system   audio     10,  53 2011-02-10 23:50 msm_aac
crw-rw-rw- system   audio     10,  54 2011-02-10 23:50 msm_pcm_in
crw-rw-rw- system   audio     10,  55 2011-02-10 23:50 msm_pcm

アドレスで分かっている事

kernel/drivers/yamaha/ae2drv.c
gpsDriver->pMemory = ioremap( 0x90000000, 64 );
物理アドレス0x90000000を先頭として64バイト幅をカーネル空間へマッピング?

IRQ周り

抽出しただけで、まだ定義を追いかけていない。
kernel/drivers/yamaha/ae2drv.c
gpsDriver->dIrq = MSM_GPIO_TO_INT(28);
sdResult = request_irq( gpsDriver->dIrq, ma_IrqHandler, IRQF_TRIGGER_FALLING, MA_DEVICE_NAME, gpsDriver );

GPIO周り

番号 方向 プル状態 Drive Strength (?) 有効/無効
027 出力 無し GPIO_2MA 有効
028 入力 プルダウン GPIO_2MA 有効
102 出力 無し GPIO_2MA 有効
121 出力 無し GPIO_2MA 有効

ソース部分
kernel/drivers/yamaha/ae2drv.c
gpio_tlmm_config(GPIO_CFG(27,  0, GPIO_OUTPUT, GPIO_NO_PULL,   GPIO_2MA), GPIO_ENABLE);
gpio_tlmm_config(GPIO_CFG(28,  0, GPIO_INPUT,  GPIO_PULL_DOWN, GPIO_2MA), GPIO_ENABLE);
gpio_tlmm_config(GPIO_CFG(102, 1, GPIO_OUTPUT, GPIO_NO_PULL,   GPIO_2MA), GPIO_ENABLE);
gpio_tlmm_config(GPIO_CFG(121, 0, GPIO_OUTPUT, GPIO_NO_PULL,   GPIO_2MA), GPIO_ENABLE);

arch/arm/mach-msm/board-deckard.c
static unsigned audio_gpio_on[] = {
	GPIO_CFG(68, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA),	/* PCM_DOUT */
	GPIO_CFG(69, 1, GPIO_INPUT,  GPIO_NO_PULL, GPIO_2MA),	/* PCM_DIN */
	GPIO_CFG(70, 2, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA),	/* PCM_SYNC */
	GPIO_CFG(71, 2, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA),	/* PCM_CLK */
	GPIO_CFG(142, 2, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA),	/* CC_I2S_CLK */
	GPIO_CFG(143, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA),	/* SADC_WSOUT */
	GPIO_CFG(144, 1, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA),	/* SADC_DIN */
	GPIO_CFG(145, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA),	/* SDAC_DOUT */
	GPIO_CFG(146, 2, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA),	/* MA_CLK_OUT */
};

/dev/msm_* 関連の include ファイル

kernel/include/linux/msm_audio.h
kernel/arch/arm/mach-msm/include/mach/qdsp6/msm8k_cad_ioctl.h
kernel/arch/arm/mach-msm/include/mach/qdsp6/msm8k_cad_devices.h
kernel/arch/arm/mach-msm/include/mach/qdsp6/msm8k_cad_volume.h
kernel/arch/arm/mach-msm/include/mach/qdsp6/msm8k_adsp_audio_device.h

/dev/msm_* 関連の DEBUG を有効にする。

kernelにおいて Audio 周りをつかさどっているであろう部分で DEBUG 情報を出力するように改変する。
kernel/arch/arm/mach-msm/qdsp6
以下にある、*.c ファイルの下記部分を
#if 0
#define D(fmt, args...) printk(KERN_INFO "msm8k_pcm: " fmt, ##args)
#else
#define D(fmt, args...) do {} while (0)
#endif
を片っ端から次のように編集する。
#if 1
#define D(fmt, args...) printk(KERN_INFO "msm8k_pcm: " fmt, ##args)
#else
#define D(fmt, args...) do {} while (0)
#endif
これで、かなりの DEBUG メッセージが dmesg すると出てくるようになる。
さらに、ioctl されているが、内容が分からないので出力するように変更した。
下記は、msm8k_pcm.c の例である。
$ diff -u msm8k_pcm.c.orig msm8k_pcm.c
--- msm8k_pcm.c.orig	2011-02-09 00:39:31.563458406 +0900
+++ msm8k_pcm.c	2011-02-07 23:36:23.694297428 +0900
@@ -89,7 +89,7 @@
 #include <mach/qdsp6/msm8k_cad_volume.h>
 #include <mach/qdsp6/msm8k_cad_q6eq_drvi.h>
 
-#if 0
+#if 1
 #define D(fmt, args...) printk(KERN_INFO "msm8k_pcm: " fmt, ##args)
 #else
 #define D(fmt, args...) do {} while (0)
@@ -237,7 +237,7 @@
 	u32 percentage;
 	struct cad_event_struct_type eos_event;
 
-	D("%s\n", __func__);
+	D("%s cmd=%x , arg=%lx\n", __func__ , cmd , arg );
 
 	memset(&cad_dev, 0, sizeof(struct cad_device_struct_type));
	memset(&cad_stream_dev, 0,

あとは、make、boot.img化、ubi化して実機に転送すればok。
私の環境では、make は下記のようになる、CROSS_COMPILE=以降は適宜、自分の環境に合わせて欲しい。
make ARCH=arm CROSS_COMPILE=../../froyo_orig/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-
kernel は arch/arm/boot/Image がその本体である。
cp -a arch/arm/boot/Image ../../mtd/froyo_boot/


/dev/msm_* 関連の DEBUG 情報の見方

DEBUGを有効にして起動したkernelにて、
# dmesg
した結果を抜粋して、数値データの意味を説明する。
<6>[ 134.871839] msm8k_cad: Registered the async callback function!!!
<6>[ 134.871859] msm8k_pcm: msm8k_pcm_ioctl cmd=80046103 , arg=7e896b08
<6>[ 134.871886] msm8k_pcm: msm8k_pcm_ioctl cmd=40046104 , arg=7e896b08
<6>[ 134.872099] msm8k_pcm: msm8k_pcm_ioctl cmd=40046100 , arg=0
まず、cmd = 80046103 等の cmd の値だが、
$ANDROID_SRC/system/extras/sound/playwav.c
を例に挙げて説明すると、
#include <linux/ioctl.h>
(省略)
#define AUDIO_IOCTL_MAGIC 'a'

#define AUDIO_START        _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned)
#define AUDIO_STOP         _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned)
#define AUDIO_FLUSH        _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned)
#define AUDIO_GET_CONFIG   _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned)
#define AUDIO_SET_CONFIG   _IOW(AUDIO_IOCTL_MAGIC, 4, unsigned)
#define AUDIO_GET_STATS    _IOR(AUDIO_IOCTL_MAGIC, 5, unsigned)
(省略)
        /* config change should be a read-modify-write operation */
    if (ioctl(afd, AUDIO_GET_CONFIG, &cfg)) {
で、AUDIO_GET_CONFIG は _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned) と変換される。
_IOR や _IOW は kernelのヘッダファイルの linux/ioctl.h で定義されている。
ざっと見た感じでは、unsigned int に変換されていて、下記のようなフォーマットに至る。(と思う…あとで、確認します^^;)
cmd = 80046103 だと、
32bit
2bit 14bit 8bit 8bit
read write 引数のsize(バイト数) type nr
1 0 (unsigned int)=32bi=4byte=0x004 AUDIO_IOCTL_MAGIC='a'=0x61 AUDIO_GET_CONFIG=3
と言う事になる(ようだ^^;)。 間違ってたらごめんなさい。
(書いてるときに面倒になってきて、ヘッダファイルのビット数の所確認していない。32bitが4になってるので4バイトか4オクテットの意味と思う)
arg は変数へのポインタなので実行時によって変わるはず。

また、AUDIO_START等のioctlでの全cmd定義は
kernel/linux/msm_audio.h
にある。

間違いが多く含まれているかもしれません、何かお気づきの点が有りましたら、Twitterか下記まで。
コメント
  • IS01 root スレ4 で、goroh_kun さんがオーディオ関連の情報を書き込んでいました。
    以下に引用します。

    カーネルのソースコード見ると、
    arch/arm/mach-msm/pmic_debugfs.c
    っていうのがあって、

    #mount -t debugfs debugfs /sys/kernel/debug
    #/sys/kernel/debug/pmic
    #ls
    debug
    index
    # cat /proc/kmsg&
    # echo 9 > index #RTC_GET_TIME_PROC
    # cat debug
    とかやると、いろいろなデバッグ用関数を呼び出せます。
    debugはechoでパラメータ入れてあげるか、catで内容を見れます。
    indexに書き込む数字とdebugへの操作はソースコード参照してください。
    arch/arm/mach-msm/pmic.cを見るとだいたいindexに書き込む数字と
    機能の割り当て対応は分かると思います。
    音源関連のデバッグ関数も多数存在します。 -- (Yukto8492) 2011-03-30 10:57:31
名前:
コメント:

すべてのコメントを見る



最終更新:2011年03月07日 23:17
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。