最新由於項目需要,調試S5PV210開發板 Linux系統上面的音頻功能,我們選擇的音頻編解碼晶片是WM8960,串連到CPU的IIS介面,調試過 程中遇到了一系列的問題,現總結如下:
調試WM8960使之能播放音頻,時鐘的配置是很重要的一部分,首先我們需要確定時鐘的配置是否正確。Linux啟動以後,使用示波器測量 IIS的三個時鐘CDClock(Codec Clock ),SClock(串列時鐘),LRClock(左右聲道選擇時鐘),發現這三個時鐘未按著SPV210的Datasheet中音頻子系統中描述的那樣工作,正常工作後,三個時鐘應該是(CDClock ~= 11.2MHZ, SClock ~= 1.41MHz, LRClock ~= 44KHZ ), 所以我用了一整天的時間來研究音頻子系統中時鐘的配置,下面的圖片是SPV210 Datasheet中 音頻子系統與IIS時鐘配置重要說明:
首先我們要讀懂上面圖中時鐘的路由,知道音頻子系統部分的時鐘源選擇,我們選擇的是EPLL,然後進行分頻,分頻後的時鐘作為時鐘源進入到IIS子系統,進入IIS子系統後,我們選擇I2SCLK作為 IIS模組的時鐘源,然後經過分頻可以得到 Root時鐘(RCLK),也就是Codec時鐘(CodecClock),Root時鐘再分頻可以得到 BCLK,也就是位時鐘也可以稱為串列時鐘(SClock). IIS 介面root時鐘與LRClock時鐘之間的關係如下圖:
RFS( root 時鐘)為256fs = 256*44.1KHz=11.2896 Mhz
另外:
模式寄存器中 BFS 和 RFS關鍵配置我們採用了預設值, Bit Clock=32 fs, Root clock=256 fs,這裡的fs=44.1 MHZ 也就是Codec的採用頻率,可以根據WM8960的Datasheet查到,從上面的時鐘計算關係圖中我們知道fs就是 LRCLK,左右聲道選擇時鐘.
------------------------------------------
下文轉載與:http://sparklecliz.cublog.cn/
------------------------------------------
一,前言:WM8960是一個音頻CODEC,與CPU通過I2S進行資料轉送,CPU通過I2C對WM8960進行控制。
Kernel:linux- 2.6.28.10 +TCC8900平台
二,實現I2C控制介面,在drivers/i2c/chips下加一個i2c驅動。Tcc_wm8960.c
#include
#include
#include
#include 2c.h>
#define WM8960_SLAVE_ADDR 0x1a
static unsigned short probe_i2c[] = {0, WM8960_SLAVE_ADDR, I2C_CLIENT_END}; /* { i2c_num, i2c_addr } */
static unsigned short dummy[] = {I2C_CLIENT_END};
static struct i2c_client_address_data addr_data = {
.normal_i2c = dummy,
.probe = probe_i2c,
.ignore = dummy,
};
static struct i2c_driver wm8960_i2c_driver;
struct i2c_client *wm8960_i2c_client;
EXPORT_SYMBOL(wm8960_i2c_client);
static int wm8960_i2c_probe(struct i2c_adapter *adap, int addr, int kind)
{
struct i2c_client *i2c;
i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
if (!i2c)
return -ENOMEM;
strcpy(i2c->name, "WM8960");
i2c->flags = 0;
i2c->addr = addr;
i2c->adapter = adap;
i2c->driver = &wm8960_i2c_driver;
wm8960_i2c_client = i2c;
return i2c_attach_client(i2c);
}
static int wm8960_i2c_detach(struct i2c_client *client)
{
i2c_detach_client(client);
kfree(wm8960_i2c_client);
return 0;
}
static int wm8960_i2c_attach(struct i2c_adapter *adap)
{
return i2c_probe(adap, &addr_data, wm8960_i2c_probe);
}
static struct i2c_driver wm8960_i2c_driver = {
.driver = {
.name = "WM8960",
.owner = THIS_MODULE,
},
.id = -1,
.attach_adapter = wm8960_i2c_attach,
.detach_client = wm8960_i2c_detach,
};
static int __init wm8960_i2c_init(void)
{
return i2c_add_driver(&wm8960_i2c_driver);
}
static void __exit wm8960_i2c_exit(void)
{
i2c_del_driver(&wm8960_i2c_driver);
}
module_init(wm8960_i2c_init);
module_exit(wm8960_i2c_exit);
MODULE_AUTHOR("Telechips Inc. SYS4-3 linux@telechips.com");
MODULE_DESCRIPTION("WM8960 I2C driver");
MODULE_LICENSE("GPL");
這個i2c驅動寫得很簡單,最重要的是匯出了wm8960_i2c_client這樣一個i2c_client,寫wm8960寄存器就是通過這個i2c_client完成的。
三,參照sound/soc/codecs目錄下的wm8731.c寫出一個wm8960.c。
四,修改一下sound/soc/tcc/tcc_board.c,主要是與wm8960有聯絡的地方改一下。關於音效卡驅動的架構以後有空再寫一篇分析出來。
五,修改一下相應目錄下的Kconfig和Makefile。
六,測試結果如下:
/nand2/mplayer # ./mplayer-y justonelastdance.mp3
MPlayer SVN-r4-4.3.2 (C) 2000-2009 MPlayer Team
Playing justonelastdance.mp3.
Audio only file format detected.
Clip info:
Title: Just One Last Dance
Artist: Sarah Connor
Album: Key To My Soul
Year: 2003
Comment: http://www.joyui.com
Track: 3
Genre: Pop
==========================================================================
Opening audio decoder: [mp3lib] MPEG layer-2, layer-3
AUDIO: 44100 Hz, 2 ch, s16le, 192.0 kbit/13.61% (ratio: 24000->176400)
Selected audio codec: [mp3] afm: mp3lib (mp3lib MPEG layer-2, layer-3)
==========================================================================
[AO OSS] audio_setup: Can't open audio device /dev/dsp: No such device or address