ALSA/ASoC:如何正確載入設備/驅動程序?
我正在使用 Buildroot 為 NXP LPC3250 微控制器建構嵌入式 Linux (2.6.39.2) 系統。
現在,我正在嘗試啟動並執行 ALSA/ASoC,但在讓模組協同工作方面遇到了一些問題。(我認為!)
一些重要的背景:
我正在測試的開發板是Embedded Artists 3250 V2 開發板。V2 與 V1 的不同之處在於它沒有 LCD 螢幕,但包含I2S 音頻編解碼器:NXP UDA1380。對 EA3250 V1的板級支持包含在核心的LPCLinux版本中。還有一個不同的開發板,稱為Phytec 3250,它包含相同的 UDA1380 編解碼器晶片。LPCLinux 發行版還支持 Phytec 板以及音頻編解碼器晶片。據我所知,Phytec 3250 板在 I2C 地址0x18上有 UDA1380 編解碼器。在我的 EA3250 V2 板上,音頻編解碼器位於 I2C 地址0x1a。(我已驗證晶片已通電,並且可以使用 I2C-tools 包與其通信。它響應 i2cdetect,我可以使用 i2cget 從晶片中正確讀取寄存器。)
修改源碼:
我需要編輯 Phytec 3250 驅動程序文件來更改編解碼器晶片的地址。我編輯了lpc3xxx-uda1380.c的這一部分:
static struct snd_soc_dai_link phy3250_uda1380_dai[] = { { .name = "uda1380", .stream_name = "UDA1380 Duplex", #if defined(CONFIG_SND_LPC32XX_USEI2S1) .cpu_dai_name = "lpc3xxx-i2s1", #else .cpu_dai_name = "lpc3xxx-i2s0", #endif .codec_dai_name = "uda1380-hifi", .init = phy3250_uda1380_init, .platform_name = "lpc3xxx-audio.0", //EDIT// .codec_name = "uda1380-codec.0-0018", //EDIT// .codec_name = "uda1380-codec.0-001a", .ops = &phy3250_uda1380_ops, }, };
進行此更改後,我繼續重新建構系統,一切編譯正常。啟動到系統後,我有以下模組(除了標準核心模組)
/lib/modules/2.6.39.2/kernel/sound
:./soc/codecs: snd-soc-uda1380.ko <-- ASoC codec driver ./soc/lpc3xxx: snd-soc-lpc3xxx-i2s.ko <-- ASoC DAI snd-soc-lpc3xxx-uda1380.ko <-- ASoC machine driver snd-soc-lpc3xxx.ko <-- ASoC platform driver
現在,我如何真正將所有這些東西綁定在一起?
僅插入模組
modprobe
實際上並不會將設備提供給 ALSA/ASoC。我無法檢測到音效卡。這是否意味著我現在必須uda1380-codec
在地址0x1a處創建一個新設備並將其綁定到驅動程序?我嘗試執行以下操作:
echo uda1380-codec 0x01a > /sys/bus/i2c/devices/i2c-0/new_device
並收到:
i2c i2c-0: new_device: Instantiated device uda1380-codec at 0x1a
然後我嘗試將驅動程序綁定到設備:
echo 0x1a > /sys/bus/i2c/drivers/uda1380-codec/bind
並收到:
sh: write error: No such device
我嘗試的所有操作都收到此錯誤!我感覺我沒有正確創建設備,然後我不確定如何將它綁定到正確的驅動程序。
請注意:
昨晚我在玩這個,不知何故能夠讓 ASoC 醒來並至少探測卡。我猜我在玩不同的綁定。記住我的步驟已經很晚了,但我至少能夠以某種方式得到以下錯誤:
uda1380-codec 0-001a: asoc: failed to probe CODEC uda1380-codec.0-001a: -22 asoc: failed to instantiate card LPC32XX: -22
我一直無法重現此錯誤!
編輯:
我已經確認我的修改程式碼正在編譯,所以驅動程序現在應該與正確的地址通信。手動載入模組後,輸出
lsmod
為:Module Size Used by Not tainted snd_soc_lpc3xxx_uda1380 2087 0 snd_soc_lpc3xxx 3089 0 snd_soc_lpc3xxx_i2s 4089 1 snd_soc_uda1380 10865 0 snd_soc_core 51549 4 snd_soc_lpc3xxx_uda1380,snd_soc_lpc3xxx,snd_soc_lpc3xxx_i2s,snd_soc_uda1380 snd_pcm 52098 2 snd_soc_lpc3xxx,snd_soc_core snd_timer 15590 1 snd_pcm snd_page_alloc 3021 1 snd_pcm snd 37286 3 snd_soc_core,snd_pcm,snd_timer
這看起來對嗎?
還有我的設備表:
# Audio stuff /dev/audio c 666 0 29 14 4 - - - #/dev/audio1 c 666 0 29 14 20 - - - /dev/dsp c 666 0 29 14 3 - - - #/dev/dsp1 c 666 0 29 14 19 - - - #/dev/sndstat c 666 0 29 14 6 - - - /dev/mixer c 666 0 29 14 0 - - - /dev/snd d 755 0 29 - - - - - /dev/snd/controlC0 c 666 0 29 116 0 - - - /dev/snd/pcmC0D0c c 666 0 29 116 24 - - - /dev/snd/pcmC0D0p c 666 0 29 116 16 - - - /dev/snd/seq c 666 0 29 116 1 - - - /dev/snd/timer c 666 0 29 116 33 - - -
需要編輯定義平台設備的電路板文件。我需要修改
arch/arm/mach-lpc32xx/ea3250.c
:添加這個:
/* * Platform Data for UDA1380 Audiocodec. * As there are no GPIOs for codec power & reset pins, * dummy GPIO numbers are used. */ static struct uda1380_platform_data uda1380_info = { .gpio_power = LPC32XX_GPIO(LPC32XX_GPO_P3_GRP,10), .gpio_reset = LPC32XX_GPIO(LPC32XX_GPO_P3_GRP,2), .dac_clk = UDA1380_DAC_CLK_WSPLL, };
編輯它以包含編解碼器:
static struct i2c_board_info __initdata ea3250_i2c_board_info [] = { { I2C_BOARD_INFO("uda1380", 0x1a), .platform_data = &uda1380_info, }, #if defined (CONFIG_LEDS_PCA9532) { I2C_BOARD_INFO("pca9532", I2C_PCA9532_ADDR), .platform_data = &ea3250_leds, }, #endif #if defined (CONFIG_FB_ARMCLCD) { /* 8Kb Configuration EEPROM on display board */ I2C_BOARD_INFO("ea_i2c_disp_cfg", LCDB_CONFIG_EEPROM_I2C_ADDR), }, { I2C_BOARD_INFO("ea_i2c_video", LCDB_PCA9532_I2C_ADDR), }, #endif #if defined (CONFIG_EEPROM_AT24) { I2C_BOARD_INFO("24c256", I2C_24LC256_ADDR), }, #endif }; #endif
現在我擁有了所有設備:
# cat cards 0 [LPC32XX ]: - LPC32XX LPC32XX # cat devices 2: [ 0- 0]: digital audio playback 3: [ 0- 0]: digital audio capture 4: [ 0] : control 33: : timer # cat pcm 00-00: UDA1380 Duplex uda1380-hifi-0 : : playback 1 : capture 1
雖然我還無法
aplay
檢測到任何東西,但也許這是一個不同的問題。編輯:是的,這是一個不同的問題。顯示的設備前面的編號
cat devices
應與 /dev/snd 設備條目中的次要設備編號匹配。現在 ALSA 端的一切似乎都很好,但我沒有來自 LPC3250 的 I2S 數據……EDIT2:已解決已解決。如果沒有 I2S 數據/時鐘,請確保正確配置輸出多路復用器寄存器以將輸出引腳連接到 I2S 外設!!!