|
@@ -347,6 +347,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|
|
u32 tfmr, rfmr, tcmr, rcmr;
|
|
|
int start_event;
|
|
|
int ret;
|
|
|
+ int fslen, fslen_ext;
|
|
|
|
|
|
/*
|
|
|
* Currently, there is only one set of dma params for
|
|
@@ -387,18 +388,6 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
- /*
|
|
|
- * The SSC only supports up to 16-bit samples in I2S format, due
|
|
|
- * to the size of the Frame Mode Register FSLEN field.
|
|
|
- */
|
|
|
- if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S
|
|
|
- && bits > 16) {
|
|
|
- printk(KERN_WARNING
|
|
|
- "atmel_ssc_dai: sample size %d "
|
|
|
- "is too large for I2S\n", bits);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
/*
|
|
|
* Compute SSC register settings.
|
|
|
*/
|
|
@@ -413,6 +402,17 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|
|
* from the MCK divider, and the BCLK signal
|
|
|
* is output on the SSC TK line.
|
|
|
*/
|
|
|
+
|
|
|
+ if (bits > 16 && !ssc->pdata->has_fslen_ext) {
|
|
|
+ dev_err(dai->dev,
|
|
|
+ "sample size %d is too large for SSC device\n",
|
|
|
+ bits);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ fslen_ext = (bits - 1) / 16;
|
|
|
+ fslen = (bits - 1) % 16;
|
|
|
+
|
|
|
rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period)
|
|
|
| SSC_BF(RCMR_STTDLY, START_DELAY)
|
|
|
| SSC_BF(RCMR_START, SSC_START_FALLING_RF)
|
|
@@ -420,9 +420,10 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|
|
| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
|
|
|
| SSC_BF(RCMR_CKS, SSC_CKS_DIV);
|
|
|
|
|
|
- rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
|
|
|
+ rfmr = SSC_BF(RFMR_FSLEN_EXT, fslen_ext)
|
|
|
+ | SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
|
|
|
| SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE)
|
|
|
- | SSC_BF(RFMR_FSLEN, (bits - 1))
|
|
|
+ | SSC_BF(RFMR_FSLEN, fslen)
|
|
|
| SSC_BF(RFMR_DATNB, (channels - 1))
|
|
|
| SSC_BIT(RFMR_MSBF)
|
|
|
| SSC_BF(RFMR_LOOP, 0)
|
|
@@ -435,10 +436,11 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|
|
| SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
|
|
|
| SSC_BF(TCMR_CKS, SSC_CKS_DIV);
|
|
|
|
|
|
- tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
|
|
|
+ tfmr = SSC_BF(TFMR_FSLEN_EXT, fslen_ext)
|
|
|
+ | SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
|
|
|
| SSC_BF(TFMR_FSDEN, 0)
|
|
|
| SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE)
|
|
|
- | SSC_BF(TFMR_FSLEN, (bits - 1))
|
|
|
+ | SSC_BF(TFMR_FSLEN, fslen)
|
|
|
| SSC_BF(TFMR_DATNB, (channels - 1))
|
|
|
| SSC_BIT(TFMR_MSBF)
|
|
|
| SSC_BF(TFMR_DATDEF, 0)
|