openwrt pcm driver on mt7620 or rt5350

查看datasheet可以知道,mt7620和rt5350有相通的Audio组件
从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/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值