持续记录-菜鸟I2S驱动开发之更新

本来打算一个星期搞定的事情,拖到了五一之后,但并不是没有成果,至少见识了3.10内核的强大(这个真的是在黑)
这两周主要在看DTS相关的内容,以及linux声音体系,从ALSA一直看到了ASOC。自己写的一个声卡也能够map成功了,虽然并没有做什么卵用。
下一步就是做录音了,bug还是原来说的那种,而且比较离奇。
bug1:在插上hdmi和耳机的时候使用hdmi放音。这个不能忍,也不知道是哪里的问题,希望有大神指教。
bug2:我使用Firefly-RK3288_Ubuntu14.04_201512031755.img这个固件,烧录git下来最新内核进行编译,如果不选择ES8323的声卡驱动生成的内核就一切ok,能够正常启动,如果选择了在生成内核就直接启动失败,貌似是es8323的驱动有问题吧。
先来回忆下,上一周做的工作。

上一个帖子中http://developer.t-firefly.com/forum.php?mod=viewthread&tid=6945&page=3#pid16437
当时驱动模块加载进去会出错,这个问题的原因还不了解,知道的可以过来指教下。
但是!问题我最后解决掉了。
当然解决的方法也很无聊,就是不使用出厂自带的Ubuntu+Android系统,刷了Firefly-RK3288_Ubuntu14.04_201512031755.img这个固件,再使用git上的kernel进行编译就能够成功了。
Tips:
Ubuntu下给rk3288刷Ubuntu14.04的方法如下:
sudo upgrade_tool uf Firefly-RK3288_Ubuntu14.04_201512031755.img
就可以把整个镜像刷进去了,很方便。

然后就是写ASOC的驱动了,ASOC驱动分为三个部分machine 和 codec以及platform.
platform就直接使用kernel里面自带的i2s.h了。
那也就是需要写machine 和 codec的驱动了。
但是!相对与2.6的内核3.10引入了DTS概念,也就是没有显式的platform_device了。
也就是需要自己在dts文件中添加node节点。

我在firefly-rk3288_beta.dts文件中添加了ahu-codec节点和rockchip-ahu节点如下:

Selection_158.png

这些设置完成了之后,编译生成source.img烧写到rk3288上去。
这样每次开机就会自动展开生成rockchip-ahu设备节点和ahu-codec设备节点。
设备节点有了,下一步就可以写对应的平台驱动了。

codec部分如下:

这样把文件编译成ahu_codec.ko时,使用insmod插入到系统时,就会自动调用对应的ahu_codec_probe函数.

machine部分如下:

同样insmod时候就自动运行rockchip_ahu_audio_probe函数

在ahu_codec_probe函数中注册了一个codec

该codec的驱动为:

该codec中的dai(digital audio interface)驱动为

懒得在分析了,打印的log如下:
整个声卡的启动顺序如下:
[ 137.068702] Enter ahu_codec_probe—>在codec中平台驱动探针函数
[ 140.255786] Enter rockchip_ahu_audio_probe—>在machine中平台驱动探针函数
当codec有了 platform有了 machine有了
就触发了codec中的snd_soc_codec_driver结构体中的probe函数->在这个函数中对codec做一些初始化
[ 140.256451] Enter ahu_probe

[ 140.256830] Enter rk_ahu_init–>在machine中对machine做一些初始化,例如开启些运放之类的工作
[ 140.269018] rockchip-ahu rockchip-ahu.29: AHU HiFi ↔ rockchip-i2s.0 mapping ok—>codec驱动和platform驱动链接成功
然后播放的时候顺序如下:
[ 291.605974] ahu_pcm_startup—>codec中pcm启动要做的一些初始化
[ 291.607176] Enter rk_hw_params—>machine中要对codec dai和platform dai做一些初始化操作
[ 291.607193] Enter ahu_pcm_hw_params---->codec中要对codec做的一些硬件操作

对咯,还有一个问题,rk3288貌似无论是输出到es8323还是输出到hdmi的编码输出芯片使用的都是i2s_sdo0
这样真的没有影响吗?

还有到底hdmi播放耳机不播放的原因是什么???

支持一个,已经设置为精华

lz这么有经验,何不把es8323的驱动移植到mainline kernel?

pqy 发表于 2016-5-4 11:03
lz这么有经验,何不把es8323的驱动移植到mainline kernel?

我是小白啊:'(

楼主是用自己写的驱动导致接hdmi的时候耳机没声音?

linjc 发表于 2016-5-19 16:10
楼主是用自己写的驱动导致接hdmi的时候耳机没声音?

不是用的是自带的驱动

支持一个

qweqf

厉害厉害

本帖最后由 墨瞳 于 2016-8-10 09:43 编辑

楼主可以分享一下相关驱动的源码么,,最近在做i2s相关的东西。。由于不需要rk上自带的声卡(es8323),我们自己做了个类似于声卡的板子,通过i2s接口把板子上的数据发送给rk3288并读取其中的数据。完全没思路,要怎么做啊?多谢楼主啦。。对了,我们虽然用i2s的接口,但是发过来的数据并不是标准的数据,所以需要把发过来的数据都出来并解析。

你好,不知道你还能看到这个帖子吗
我和你一样 外接一个语音模块,前面的操作也和你完全一样,codec驱动和platform驱动也链接成功

但是当进行到
[ 291.607176] Enter rk_hw_params—>machine中要对codec dai和platform dai做一些初始化操作
我的报错了
[ 27.479790] ENTER::----------rk29_hw_params-----------
[ 27.479814] rk29_hw_params():failed to set the format for cpu side, ret=-----22—
[ 27.479825] rockchip-conextant rockchip-conextant.29: ASoC: machine hw_params failed: -22
是说我的传进snd_soc_dai_set_fmt 参数有问题,
是运行到return dai->driver->ops->set_fmt(dai, fmt); 这里挂的,这是什么原因楼主遇到过吗