/* * Set the SSP ports SYSCLK.
*/ staticint mmp_sspa_set_dai_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsignedint freq, int dir)
{ struct sspa_priv *sspa = snd_soc_dai_get_drvdata(cpu_dai); struct device *dev = cpu_dai->component->dev; int ret = 0;
if (dev->of_node) return -ENOTSUPP;
switch (clk_id) { case MMP_SSPA_CLK_AUDIO:
ret = clk_set_rate(sspa->audio_clk, freq); if (ret) return ret; break; case MMP_SSPA_CLK_PLL: case MMP_SSPA_CLK_VCXO: /* not support yet */ return -EINVAL; default: return -EINVAL;
}
return 0;
}
staticint mmp_sspa_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, int source, unsignedint freq_in, unsignedint freq_out)
{ struct sspa_priv *sspa = snd_soc_dai_get_drvdata(cpu_dai); struct device *dev = cpu_dai->component->dev; int ret = 0;
if (dev->of_node) return -ENOTSUPP;
switch (pll_id) { case MMP_SYSCLK:
ret = clk_set_rate(sspa->sysclk, freq_out); if (ret) return ret; break; case MMP_SSPA_CLK:
ret = clk_set_rate(sspa->clk, freq_out); if (ret) return ret; break; default: return -ENODEV;
}
return 0;
}
/* * Set up the sspa dai format.
*/ staticint mmp_sspa_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsignedint fmt)
{ struct sspa_priv *sspa = snd_soc_dai_get_drvdata(cpu_dai);
/* Since we are configuring the timings for the format by hand * we have to defer some things until hw_params() where we * know parameters like the sample size.
*/ return 0;
}
/* * Set the SSPA audio DMA parameters and sample size. * Can be called multiple times by oss emulation.
*/ staticint mmp_sspa_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{ struct sspa_priv *sspa = snd_soc_dai_get_drvdata(dai); struct device *dev = dai->component->dev;
u32 sspa_ctrl = sspa->ctrl; int bits; int bitval;
staticint mmp_sspa_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
{ struct sspa_priv *sspa = snd_soc_dai_get_drvdata(dai); int ret = 0;
switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* * whatever playback or capture, must enable rx. * this is a hw issue, so need check if rx has been * enabled or not; if has been enabled by another * stream, do not enable again.
*/ if (!sspa->running_cnt)
mmp_sspa_rx_enable(sspa);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
mmp_sspa_tx_enable(sspa);
sspa->running_cnt++; break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
sspa->running_cnt--;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
mmp_sspa_tx_disable(sspa);
/* have no capture stream, disable rx port */ if (!sspa->running_cnt)
mmp_sspa_rx_disable(sspa); break;
/* we can only change the settings if the port is not in use */ if ((__raw_readl(sspa->tx_base + SSPA_SP) & SSPA_SP_S_EN) ||
(__raw_readl(sspa->rx_base + SSPA_SP) & SSPA_SP_S_EN)) {
dev_err(component->dev, "can't change hardware dai format: stream is in use\n"); return -EBUSY;
}
/* * FIXME: hw issue, for the tx serial port, * can not config the master/slave mode; * so must clean this bit. * The master/slave mode has been set in the * rx port.
*/
__raw_writel(sspa->sp & ~SSPA_SP_MSL, sspa->tx_base + SSPA_SP);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.