openwrt pcm driver on mt7620 or rt5350
2015-08-19 18:22
459 查看
查看datasheet可以知道,mt7620和rt5350有相通的Audio组件
从openwrt14.07的kernel源码中,我们可以找到mt7620 i2s的驱动
我们的pcm驱动,可以基于i2s驱动进行改动。pcm驱动已传至github,相关代码可以看这里
主要改动了以下几点:
Peripheral Channel Connection部分可知,
PCM Channel0 对应的GDMA Slot为4(RX)、6(TX),
在配置dma channel的时候做对应的改动即可
sim800模块的pcm参数如下:
a) PCM clock 为256kHz
b) PCM sync 为 short sync,极性为高有效
于是参考datasheet对PCM_CFG寄存器的描述,可以得到下面改动
这部分通过修改dts文件即可,
另外,PCM驱动设备节点的声明,codec machine层、codec层驱动设备节点的声明
也都是在dts文件里完成,
具体如下
rt5350.dtsi
SXX.dts
来源:http://transing.xyz/2015/08/19/openwrt-pcm-driver-on-mt7620-or-rt5350/
从openwrt14.07的kernel源码中,我们可以找到mt7620 i2s的驱动
我们的pcm驱动,可以基于i2s驱动进行改动。pcm驱动已传至github,相关代码可以看这里
主要改动了以下几点:
1.寄存器相关
参考datasheet,定义PCM相关的寄存器,把i2s驱动里对应的寄存器操作换成对PCM部分寄存器的操作#define PCM_GLB_CFG 0x00 #define PCM_GLB_CFG_EN BIT(31) #define PCM_GLB_CFG_DMA_EN BIT(30) #define PCM_GLB_CFG_CH0_TX_EN BIT(8) #define PCM_GLB_CFG_CH0_RX_EN BIT(0) #define PCM_GLB_CFG_RFF_THRES 20 #define PCM_GLB_CFG_TFF_THRES 16 #define PCM_GLB_CFG_DFT_THRES (4 << PCM_GLB_CFG_RFF_THRES) | \ (4 << PCM_GLB_CFG_TFF_THRES) #define PCM_PCM_CFG 0x04 #define PCM_PCM_CFG_CLKOUT_EN BIT(30) #define PCM_PCM_CFG_EXT_FSYNC BIT(27) #define PCM_PCM_CFG_LONG_FSYNC BIT(26) #define PCM_PCM_CFG_FSYNC_POL BIT(25) #define PCM_INT_STATUS 0x08 #define PCM_INT_EN 0x0C #define PCM_FF_STATUS 0x10 #define PCM_CH0_CFG 0x20 #define PCM_CH1_CFG 0x24 #define PCM_FSYNC_CFG 0x30 #define PCM_CH_CFG2 0x34 #define PCM_DIVCOMP_CFG 0x50 #define PCM_DIVCOMP_CFG_CLK_EN BIT(31) #define PCM_DIVINT_CFG 0x54 #define PCM_DIGDELAY_CFG 0x60 #define PCM_CH0_FIFO 0x80 #define PCM_CH1_FIFO 0x84
2.PCM Config相关
参考RT5350 Preliminary Datasheet.pdf第3.12.3节Peripheral Channel Connection部分可知,
PCM Channel0 对应的GDMA Slot为4(RX)、6(TX),
在配置dma channel的时候做对应的改动即可
static void rt5350_init_pcm_config(struct rt5350_pcm *pcm) { struct snd_dmaengine_dai_dma_data *dma_data; /* Playback */ dma_data = &pcm->playback_dma_data; dma_data->maxburst = 16; dma_data->slave_id = 6; dma_data->addr = pcm->phys_base + PCM_CH0_FIFO; //only use channel 0 /* Capture */ dma_data = &pcm->capture_dma_data; dma_data->maxburst = 16; dma_data->slave_id = 4; dma_data->addr = pcm->phys_base + PCM_CH0_FIFO; }
3.PCM时序相关
以rt5350做pcm slave,sim800模块做master为例sim800模块的pcm参数如下:
a) PCM clock 为256kHz
b) PCM sync 为 short sync,极性为高有效
于是参考datasheet对PCM_CFG寄存器的描述,可以得到下面改动
rt5350_pcm_dai_probe ///////////// pcm general config cfg = rt5350_pcm_read(pcm, PCM_FSYNC_CFG); cfg &= ~PCM_PCM_CFG_LONG_FSYNC; //short sync mode cfg |= PCM_PCM_CFG_FSYNC_POL; // sync high active //slot mode, pcm clock = 256KHz cfg &= ~(0x07); cfg = 0; // 4 slots rt5350_pcm_write(pcm, PCM_PCM_CFG, cfg); ///////////// pcm sync config cfg = rt5350_pcm_read(pcm, PCM_FSYNC_CFG); // pol, etc. rt5350_pcm_write(pcm, PCM_FSYNC_CFG, cfg); //When using the external clock, the frequency clock //should be equal to the PCM_clock out. Otherwise, the //PCM_CLKin should be 8.192 MHz. rt5350_pcm_write(pcm, PCM_DIVINT_CFG, i2sMaster_inclk_int[PCMCLOCK_OUT]); rt5350_pcm_write(pcm, PCM_DIVCOMP_CFG, i2sMaster_inclk_comp[PCMCLOCK_OUT] | PCM_DIVCOMP_CFG_CLK_EN); ---------------------------- rt5350_pcm_set_fmt cfg = rt5350_pcm_read(pcm, PCM_PCM_CFG); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: cfg &= ~PCM_PCM_CFG_CLKOUT_EN; // pcm clock from external cfg |= PCM_PCM_CFG_EXT_FSYNC; // pcm sync from external break; case SND_SOC_DAIFMT_CBM_CFM: cfg |= PCM_PCM_CFG_CLKOUT_EN; // pcm clock from internal cfg &= ~PCM_PCM_CFG_EXT_FSYNC; // pcm sync from internal break; case SND_SOC_DAIFMT_CBM_CFS: default: return -EINVAL; } rt5350_pcm_write(pcm, PCM_PCM_CFG, cfg);
4.管脚定义
因为rt5350/mt7620上PCM是复用脚,所以需要配置成PCM功能,这部分通过修改dts文件即可,
另外,PCM驱动设备节点的声明,codec machine层、codec层驱动设备节点的声明
也都是在dts文件里完成,
具体如下
rt5350.dtsi
pcm: pcm@2000 { compatible = "ralink,rt5350-pcm"; reg = <0x2000 0x800>; resets = <&rstctrl 11>; reset-names = "pcm"; interrupt-parent = <&intc>; interrupts = <4>; dmas = <&gdma 4>, <&gdma 5>; dma-names = "tx", "rx"; status = "disabled"; };
SXX.dts
//使能pcm驱动 palmbus@10000000 { pcm@2000 { status = "okay"; }; } //管脚功能初始化 pinctrl { state_default: pinctrl0 { gpio { ralink,group = "i2c", "jtag"; ralink,function = "gpio"; }; uartf { ralink,group = "uartf"; ralink,function = "pcm uartf"; }; }; }; //声明codec设备节点 codec: sxx-pcm-codec { compatible = "ralink,sxx-pcm-codec"; }; //声明codec machine层设备节点 sound: sxx-pcm-machine { compatible = "ralink,sxx-pcm-machine"; model = "sxx-pcm-machine"; cpu-dai = <&pcm>; codec-dai = <&codec>; };
来源:http://transing.xyz/2015/08/19/openwrt-pcm-driver-on-mt7620-or-rt5350/
相关文章推荐
- Linux命令行下svn ignore忽略文件或文件夹用法
- DeveloperResource
- 每天一个linux命令(35):ln 命令
- 我怎么能确保non-corrupt 文件传输 in linux
- 我怎么能确保non-corrupt 文件传输 in linux
- 启动Tomcat报(Server Tomcat v6.0 Server at localhost was unable to start within 45 seconds)的问题
- Apache2.2+Tomcat7.0整合配置详解
- Centos磁盘的知识总结
- linux中的kill命令及强制终止进程的方法
- opencv 手动调整照片颜色小工具 对比度 亮度 BGR 各通道
- Linux内核的文件预读readahead
- 如何配置Mac系统自带的ApacheWeb服务器 测试10.10可用
- linux下源码安装realvnc
- mysql高可用之MHA(补充3)--管理多组主从复制
- 5款免费Windows远程连接Linux桌面软件(VNC客户端)
- linux -- chcp
- openstack theme topic
- linux Shell脚本编码格式
- unix/linux下线程私有数据实现原理及使用方法
- linux 下Time_wait过多问题解决