void omap2_mcbsp_set_recv_param(struct omap_mcbsp_reg_cfg *mcbsp_cfg, struct omap_mcbsp_cfg_param *rp) { mcbsp_cfg->spcr1 = RJUST(rp->justification); mcbsp_cfg->rcr2 = RCOMPAND(rp->reverse_compand) | RDATDLY(rp->data_delay); if (rp->phase == OMAP_MCBSP_FRAME_SINGLEPHASE) mcbsp_cfg->rcr2 = mcbsp_cfg->rcr2 & ~(RPHASE); else mcbsp_cfg->rcr2 = mcbsp_cfg->rcr2 | (RPHASE) | RWDLEN2(rp->word_length2) | RFRLEN2(rp->frame_length2); mcbsp_cfg->rcr1 = RWDLEN1(rp->word_length1) | RFRLEN1(rp->frame_length1); if (rp->fsync_src == OMAP_MCBSP_RXFSYNC_INTERNAL) mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | FSRM; if (rp->clk_mode == OMAP_MCBSP_CLKRXSRC_INTERNAL) mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | CLKRM; if (rp->clk_polarity == OMAP_MCBSP_CLKR_POLARITY_RISING) mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | CLKRP; if (rp->fs_polarity == OMAP_MCBSP_FS_ACTIVE_LOW) mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | FSRP; return; }
/* * This must be called before _set_clkdiv and _set_sysclk since McBSP register * cache is initialized here */ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; bool inv_fs = false; if (mcbsp_data->configured) return 0; mcbsp_data->fmt = fmt; memset(regs, 0, sizeof(*regs)); /* Generic McBSP register settings */ regs->spcr2 |= XINTM(3) | FREE; regs->spcr1 |= RINTM(3); /* RFIG and XFIG are not defined in 34xx */ if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) { regs->rcr2 |= RFIG; regs->xcr2 |= XFIG; } if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE; regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE; } switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: /* 1-bit data delay */ regs->rcr2 |= RDATDLY(1); regs->xcr2 |= XDATDLY(1); break; case SND_SOC_DAIFMT_LEFT_J: /* 0-bit data delay */ regs->rcr2 |= RDATDLY(0); regs->xcr2 |= XDATDLY(0); regs->spcr1 |= RJUST(2); /* Invert FS polarity configuration */ inv_fs = true; break; case SND_SOC_DAIFMT_DSP_A: /* 1-bit data delay */ regs->rcr2 |= RDATDLY(1); regs->xcr2 |= XDATDLY(1); /* Invert FS polarity configuration */ inv_fs = true; break; case SND_SOC_DAIFMT_DSP_B: /* 0-bit data delay */ regs->rcr2 |= RDATDLY(0); regs->xcr2 |= XDATDLY(0); /* Invert FS polarity configuration */ inv_fs = true; break; default: /* Unsupported data format */ return -EINVAL; } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: /* McBSP master. Set FS and bit clocks as outputs */ regs->pcr0 |= FSXM | FSRM | CLKXM | CLKRM; /* Sample rate generator drives the FS */ regs->srgr2 |= FSGM; break; case SND_SOC_DAIFMT_CBM_CFM: /* McBSP slave */ break; default: /* Unsupported master/slave configuration */ return -EINVAL; } /* Set bit clock (CLKX/CLKR) and FS polarities */ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: /* * Normal BCLK + FS. * FS active low. TX data driven on falling edge of bit clock * and RX data sampled on rising edge of bit clock. */ regs->pcr0 |= FSXP | FSRP | CLKXP | CLKRP; break; case SND_SOC_DAIFMT_NB_IF: regs->pcr0 |= CLKXP | CLKRP; break; case SND_SOC_DAIFMT_IB_NF: regs->pcr0 |= FSXP | FSRP; break; case SND_SOC_DAIFMT_IB_IF: break; default: return -EINVAL; } if (inv_fs == true) regs->pcr0 ^= FSXP | FSRP; return 0; }