void omap2_mcbsp_set_trans_param(struct omap_mcbsp_reg_cfg *mcbsp_cfg, struct omap_mcbsp_cfg_param *tp) { mcbsp_cfg->xcr2 = XCOMPAND(tp->reverse_compand) | XDATDLY(tp->data_delay); if (tp->phase == OMAP_MCBSP_FRAME_SINGLEPHASE) mcbsp_cfg->xcr2 = mcbsp_cfg->xcr2 & ~(XPHASE); else mcbsp_cfg->xcr2 = mcbsp_cfg->xcr2 | (XPHASE) | RWDLEN2(tp->word_length2) | RFRLEN2(tp->frame_length2); mcbsp_cfg->xcr1 = XWDLEN1(tp->word_length1) | XFRLEN1(tp->frame_length1); if (tp->fs_polarity == OMAP_MCBSP_FS_ACTIVE_LOW) mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | FSXP; if (tp->fsync_src == OMAP_MCBSP_TXFSYNC_INTERNAL) mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | FSXM; if (tp->clk_mode == OMAP_MCBSP_CLKTXSRC_INTERNAL) mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | CLKXM; if (tp->clk_polarity == OMAP_MCBSP_CLKX_POLARITY_FALLING) mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | CLKXP; 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 = to_mcbsp(cpu_dai->private_data); struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; unsigned int temp_fmt = fmt; 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); regs->rcr2 |= RFIG; regs->xcr2 |= XFIG; if (cpu_is_omap2430() || cpu_is_omap34xx()) { regs->xccr = DXENDLY(1); regs->rccr = RFULL_CYCLE; } switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: case SND_SOC_DAIFMT_I2S_1PHASE: /* 1-bit data delay */ regs->rcr2 |= RDATDLY(1); regs->xcr2 |= XDATDLY(1); break; case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_A_1PHASE: /* 1-bit data delay */ regs->rcr2 |= RDATDLY(1); regs->xcr2 |= XDATDLY(1); /* Invert FS polarity configuration */ temp_fmt ^= SND_SOC_DAIFMT_NB_IF; break; case SND_SOC_DAIFMT_DSP_B: /* 0-bit data delay */ regs->rcr2 |= RDATDLY(0); regs->xcr2 |= XDATDLY(0); /* Invert FS polarity configuration */ temp_fmt ^= SND_SOC_DAIFMT_NB_IF; break; case SND_SOC_DAIFMT_SPDIF: /* The recording has to work even if the output is in SPDIF mode, so receive in DSP-A mode */ /* 1-bit data delay */ regs->rcr2 |= RDATDLY(1); /* 0-bit data delay */ regs->xcr2 |= XDATDLY(0); /* LSB First */ regs->xcr2 |= XCOMPAND(1); 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 (temp_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; } return 0; }