コード例 #1
0
ファイル: fsl_esai.c プロジェクト: Master-Traders/linux
static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
				     u32 rx_mask, int slots, int slot_width)
{
	struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);

	regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
			   ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));

	regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA,
			   ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask));
	regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB,
			   ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(tx_mask));

	regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
			   ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));

	regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA,
			   ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask));
	regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB,
			   ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(rx_mask));

	esai_priv->slot_width = slot_width;

	return 0;
}
コード例 #2
0
static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
			    struct snd_soc_dai *dai)
{
	struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
	u8 i, channels = substream->runtime->channels;
	u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
	u32 mask;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
				   ESAI_xFCR_xFEN_MASK, ESAI_xFCR_xFEN);

		/* Write initial words reqiured by ESAI as normal procedure */
		for (i = 0; tx && i < channels; i++)
			regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0);

		regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
				   tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK,
				   tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins));
		mask = tx ? esai_priv->tx_mask : esai_priv->rx_mask;
		regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
				   ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask));
		regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
				   ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask));

		break;
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
				   tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0);
		regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
				   ESAI_xSMA_xS_MASK, 0);
		regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
				   ESAI_xSMB_xS_MASK, 0);

		/* Disable and reset FIFO */
		regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
				   ESAI_xFCR_xFR | ESAI_xFCR_xFEN, ESAI_xFCR_xFR);
		regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
				   ESAI_xFCR_xFR, 0);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}