static int mcbsp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); unsigned int be_id = rtd->dai_link->be_id; unsigned int threshold; switch (be_id) { case OMAP_ABE_DAI_MM_FM: channels->min = 2; threshold = 2; break; case OMAP_ABE_DAI_BT_VX: channels->min = 1; threshold = 1; break; default: threshold = 1; break; } snd_mask_set(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT - SNDRV_PCM_HW_PARAM_FIRST_MASK], SNDRV_PCM_FORMAT_S16_LE); omap_mcbsp_set_tx_threshold(cpu_dai->id, threshold); omap_mcbsp_set_rx_threshold(cpu_dai->id, threshold); return 0; }
static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); struct omap_pcm_dma_data *dma_data; int dma_op_mode = omap_mcbsp_get_dma_op_mode(mcbsp_data->bus_id); int words; dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) /* * Configure McBSP threshold based on either: * packet_size, when the sDMA is in packet mode, or * based on the period size. */ if (dma_data->packet_size) words = dma_data->packet_size; else words = snd_pcm_lib_period_bytes(substream) / (mcbsp_data->wlen / 8); else words = 1; /* Configure McBSP internal buffer usage */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) omap_mcbsp_set_tx_threshold(mcbsp_data->bus_id, words); else omap_mcbsp_set_rx_threshold(mcbsp_data->bus_id, words); }
/* * Stream DMA parameters. DMA request line and port address are set runtime * since they are different between OMAP1 and later OMAPs */ static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); struct omap_pcm_dma_data *dma_data; int words; dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); /* * Configure McBSP threshold based on either: * packet_size, when the sDMA is in packet mode, or based on the * period size in THRESHOLD mode, otherwise use McBSP threshold = 1 * for mono streams. */ if (dma_data->packet_size) words = dma_data->packet_size; else words = 1; /* Configure McBSP internal buffer usage */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) omap_mcbsp_set_tx_threshold(mcbsp, words); else omap_mcbsp_set_rx_threshold(mcbsp, words); }
static int sdp4430_mcbsp_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret = 0, channels = 0; unsigned int be_id, fmt; be_id = rtd->dai_link->be_id; if (be_id == OMAP_ABE_DAI_BT_VX) { if (machine_is_tuna()) fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM; else fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_CBM_CFM; } else { fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM; } ret = snd_soc_dai_set_fmt(cpu_dai, fmt); if (ret < 0) { printk(KERN_ERR "can't set cpu DAI configuration\n"); return ret; } /* * TODO: where does this clock come from (external source??) - * do we need to enable it. */ /* Set McBSP clock to external */ ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_FCLK, 32 * 96 * params_rate(params), SND_SOC_CLOCK_IN); if (ret < 0) printk(KERN_ERR "can't set cpu system clock\n"); ret = snd_soc_dai_set_clkdiv(cpu_dai, 0, 96); if (ret < 0) printk(KERN_ERR "can't set McBSP cpu DAI clkdiv\n"); /* * Configure McBSP internal buffer threshold * for playback/record */ channels = params_channels(params); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) omap_mcbsp_set_tx_threshold(cpu_dai->id, channels); else omap_mcbsp_set_rx_threshold(cpu_dai->id, channels); return ret; }
static int archos_omap4_mcbsp_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret = 0; unsigned int be_id, channels; be_id = rtd->dai_link->be_id; if (be_id == OMAP_ABE_DAI_BT_VX) { ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_CBM_CFM); } else if (be_id == OMAP_ABE_DAI_HDMI_IN) { ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); } else { /* Set cpu DAI configuration */ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); } if (ret < 0) { printk(KERN_ERR "can't set cpu DAI configuration\n"); return ret; } if (params != NULL) { /* Configure McBSP internal buffer usage */ /* this need to be done for playback and/or record */ channels = params_channels(params); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) omap_mcbsp_set_tx_threshold( cpu_dai->id, channels); else omap_mcbsp_set_rx_threshold( cpu_dai->id, channels); } /* * TODO: where does this clock come from (external source??) - * do we need to enable it. */ /* Set McBSP clock to external */ ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_FCLK, 64 * params_rate(params), SND_SOC_CLOCK_IN); if (ret < 0) printk(KERN_ERR "can't set cpu system clock\n"); return ret; }
static int sdp4430_modem_mcbsp_configure(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, int flag) { int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_pcm_substream *modem_substream[2]; struct snd_soc_pcm_runtime *modem_rtd; int channels; if (flag) { modem_substream[substream->stream] = snd_soc_get_dai_substream(rtd->card, OMAP_ABE_BE_MM_EXT1, substream->stream); if (unlikely(modem_substream[substream->stream] == NULL)) return -ENODEV; modem_rtd = modem_substream[substream->stream]->private_data; if (!mcbsp_cfg) { /* Set cpu DAI configuration */ ret = snd_soc_dai_set_fmt(modem_rtd->cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); if (unlikely(ret < 0)) { printk(KERN_ERR "can't set Modem cpu DAI configuration\n"); goto exit; } else { mcbsp_cfg = 1; } } if (params != NULL) { /* Configure McBSP internal buffer usage */ /* this need to be done for playback and/or record */ channels = params_channels(params); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) omap_mcbsp_set_rx_threshold( modem_rtd->cpu_dai->id, channels); else omap_mcbsp_set_tx_threshold( modem_rtd->cpu_dai->id, channels); } } else { mcbsp_cfg = 0; } exit: return ret; }
static int mcbsp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); struct snd_soc_dai *cpu_dai = rtd->cpu_dai; unsigned int be_id; unsigned int threshold; unsigned int val, min_mask; DBG ("%s: Entered \n", __func__); //DBG ("%s: CPU DAI %s BE_ID %d\n", __func__, cpu_dai->name, rtd->dai_link->be_id); be_id = rtd->dai_link->be_id; switch (be_id) { case OMAP_ABE_DAI_MM_FM: channels->min = 2; threshold = 2; val = SNDRV_PCM_FORMAT_S16_LE; break; case OMAP_ABE_DAI_BT_VX: channels->min = 1; threshold = 1; val = SNDRV_PCM_FORMAT_S16_LE; break; default: threshold = 1; val = SNDRV_PCM_FORMAT_S16_LE; break; } min_mask = snd_mask_min(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT - SNDRV_PCM_HW_PARAM_FIRST_MASK]); //DBG ("%s: Returned min_mask 0x%x Format %x\n", __func__, min_mask, val); snd_mask_reset(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT - SNDRV_PCM_HW_PARAM_FIRST_MASK], min_mask); //DBG ("%s: Returned min_mask 0x%x Format %x\n", __func__, min_mask, val); snd_mask_set(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT - SNDRV_PCM_HW_PARAM_FIRST_MASK], val); omap_mcbsp_set_tx_threshold(cpu_dai->id, threshold); omap_mcbsp_set_rx_threshold(cpu_dai->id, threshold); DBG ("%s: Exiting \n", __func__); return 0; }
static int omap_abe_mcbsp_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); struct clk *fclk; unsigned long fclk_rate; int ret; unsigned int channels; /* Set cpu DAI configuration */ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); if (ret < 0) { dev_err(card->dev, "can't set cpu DAI configuration\n"); return ret; } if (rtd->dai_link->no_pcm) { /* Configure McBSP internal buffer usage */ /* this need to be done for playback and/or record */ channels = params_channels(params); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) omap_mcbsp_set_tx_threshold(mcbsp, channels); else omap_mcbsp_set_rx_threshold(mcbsp, channels); } /* Get McBSP PRCM FCLK (internal clock) rate */ fclk = clk_get(mcbsp->dev, "prcm_fck"); if (IS_ERR(fclk)) { dev_err(card->dev, "can't get McBSP prcm_fck\n"); return PTR_ERR(fclk); } fclk_rate = clk_get_rate(fclk); clk_put(fclk); /* Set McBSP clock to external */ ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_FCLK, fclk_rate, SND_SOC_CLOCK_IN); if (ret < 0) dev_err(card->dev, "can't set cpu system clock\n"); return ret; }
static int omap_abe_modem_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_card *card = rtd->card; struct omap_abe_data *card_data = snd_soc_card_get_drvdata(card); struct snd_pcm_substream *modem_substream[2]; struct snd_soc_pcm_runtime *modem_rtd; int channels, ret = 0, stream = substream->stream; modem_substream[stream] = snd_soc_get_dai_substream(card, OMAP_ABE_BE_MM_EXT1, stream); if (modem_substream[stream] == NULL) return -ENODEV; modem_rtd = modem_substream[stream]->private_data; if (!card_data->mcbsp_cfg) { /* Set cpu DAI configuration */ ret = snd_soc_dai_set_fmt(modem_rtd->cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); if (ret < 0) { dev_err(card->dev, "can't set Modem cpu DAI configuration\n"); return ret; } else card_data->mcbsp_cfg = 1; } if (params != NULL) { struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata( modem_rtd->cpu_dai); /* Configure McBSP internal buffer usage */ /* this need to be done for playback and/or record */ channels = params_channels(params); if (stream == SNDRV_PCM_STREAM_PLAYBACK) omap_mcbsp_set_rx_threshold(mcbsp, channels); else omap_mcbsp_set_tx_threshold(mcbsp, channels); } return ret; }
static int omap_abe_mcbsp_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; int ret; unsigned int be_id, channels; be_id = rtd->dai_link->be_id; if (be_id == OMAP_ABE_DAI_BT_VX) ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_CBM_CFM); else /* Set cpu DAI configuration */ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); if (ret < 0) { dev_err(card->dev, "can't set cpu DAI configuration\n"); return ret; } if (params != NULL) { struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); /* Configure McBSP internal buffer usage */ /* this need to be done for playback and/or record */ channels = params_channels(params); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) omap_mcbsp_set_tx_threshold(mcbsp, channels); else omap_mcbsp_set_rx_threshold(mcbsp, channels); } /* Set McBSP clock to external */ ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_FCLK, 64 * params_rate(params), SND_SOC_CLOCK_IN); if (ret < 0) dev_err(card->dev, "can't set cpu system clock\n"); return ret; }
static int sdp4430_modem_mcbsp_configure(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, int flag) { int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_pcm_substream *modem_substream[2]; struct snd_soc_pcm_runtime *modem_rtd; int channels; if (flag) { modem_substream[substream->stream] = snd_soc_get_dai_substream(rtd->card, OMAP_ABE_BE_MM_EXT1, substream->stream); if (unlikely(modem_substream[substream->stream] == NULL)) return -ENODEV; modem_rtd = modem_substream[substream->stream]->private_data; if (!mcbsp_cfg) { if (omap4_tuna_get_type() == TUNA_TYPE_TORO) { /* Set cpu DAI configuration */ ret = snd_soc_dai_set_fmt(modem_rtd->cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (unlikely(ret < 0)) { printk(KERN_ERR "can't set Modem cpu DAI format\n"); goto exit; } /* McBSP2 fclk reparented to ABE_24M_FCLK */ ret = snd_soc_dai_set_sysclk(modem_rtd->cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_FCLK, 32 * 96 * params_rate(params), SND_SOC_CLOCK_IN); if (unlikely(ret < 0)) { printk(KERN_ERR "can't set Modem cpu DAI sysclk\n"); goto exit; } /* assuming McBSP2 is S16_LE stereo */ ret = snd_soc_dai_set_clkdiv(modem_rtd->cpu_dai, 0, 96); if (unlikely(ret < 0)) { printk(KERN_ERR "can't set Modem cpu DAI clkdiv\n"); goto exit; } } else { /* Set cpu DAI configuration */ ret = snd_soc_dai_set_fmt(modem_rtd->cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); if (unlikely(ret < 0)) { printk(KERN_ERR "can't set Modem cpu DAI configuration\n"); goto exit; } } mcbsp_cfg = 1; } if (params != NULL) { /* Configure McBSP internal buffer usage */ /* this need to be done for playback and/or record */ channels = params_channels(params); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) omap_mcbsp_set_rx_threshold( modem_rtd->cpu_dai->id, channels); else omap_mcbsp_set_tx_threshold( modem_rtd->cpu_dai->id, channels); } } else { mcbsp_cfg = 0; } exit: return ret; }