|
@@ -38,6 +38,7 @@
|
|
|
* @fsysclk: system clock source to derive HCK, SCK and FS
|
|
|
* @fifo_depth: depth of tx/rx FIFO
|
|
|
* @slot_width: width of each DAI slot
|
|
|
+ * @slots: number of slots
|
|
|
* @hck_rate: clock rate of desired HCKx clock
|
|
|
* @sck_rate: clock rate of desired SCKx clock
|
|
|
* @hck_dir: the direction of HCKx pads
|
|
@@ -56,6 +57,7 @@ struct fsl_esai {
|
|
|
struct clk *fsysclk;
|
|
|
u32 fifo_depth;
|
|
|
u32 slot_width;
|
|
|
+ u32 slots;
|
|
|
u32 hck_rate[2];
|
|
|
u32 sck_rate[2];
|
|
|
bool hck_dir[2];
|
|
@@ -363,6 +365,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
|
|
|
ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask));
|
|
|
|
|
|
esai_priv->slot_width = slot_width;
|
|
|
+ esai_priv->slots = slots;
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -510,10 +513,11 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
|
|
|
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
|
|
|
u32 width = snd_pcm_format_width(params_format(params));
|
|
|
u32 channels = params_channels(params);
|
|
|
+ u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
|
|
|
u32 bclk, mask, val;
|
|
|
int ret;
|
|
|
|
|
|
- bclk = params_rate(params) * esai_priv->slot_width * 2;
|
|
|
+ bclk = params_rate(params) * esai_priv->slot_width * esai_priv->slots;
|
|
|
|
|
|
ret = fsl_esai_set_bclk(dai, tx, bclk);
|
|
|
if (ret)
|
|
@@ -530,7 +534,7 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
|
|
|
mask = ESAI_xFCR_xFR_MASK | ESAI_xFCR_xWA_MASK | ESAI_xFCR_xFWM_MASK |
|
|
|
(tx ? ESAI_xFCR_TE_MASK | ESAI_xFCR_TIEN : ESAI_xFCR_RE_MASK);
|
|
|
val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) |
|
|
|
- (tx ? ESAI_xFCR_TE(channels) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(channels));
|
|
|
+ (tx ? ESAI_xFCR_TE(pins) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(pins));
|
|
|
|
|
|
regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val);
|
|
|
|
|
@@ -565,6 +569,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
|
|
|
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);
|
|
|
|
|
|
switch (cmd) {
|
|
|
case SNDRV_PCM_TRIGGER_START:
|
|
@@ -579,7 +584,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
|
|
|
|
|
|
regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
|
|
|
tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK,
|
|
|
- tx ? ESAI_xCR_TE(channels) : ESAI_xCR_RE(channels));
|
|
|
+ tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins));
|
|
|
break;
|
|
|
case SNDRV_PCM_TRIGGER_SUSPEND:
|
|
|
case SNDRV_PCM_TRIGGER_STOP:
|
|
@@ -783,6 +788,9 @@ static int fsl_esai_probe(struct platform_device *pdev)
|
|
|
/* Set a default slot size */
|
|
|
esai_priv->slot_width = 32;
|
|
|
|
|
|
+ /* Set a default slot number */
|
|
|
+ esai_priv->slots = 2;
|
|
|
+
|
|
|
/* Set a default master/slave state */
|
|
|
esai_priv->slave_mode = true;
|
|
|
|