[alsa-devel] [PATCH v2 0/4] ASoC: atmel_ssc: enable fslen extension feature
On at91sam9rl, at91sam9g10, at91sam9g20, at91sam9g45 and newer SoCs, the SSC peripheral supports frame sync length extension feature. When SSC works as master, it can generate frame sync lenght larger than 16 bits. After enable this feature, it can playback 24/32 bits audio clips.
Changes in v2: - Using compatible string to distinguish whether SSC supports frame sync length extension to replace check IP version. - Add related modification for dts file.
Bo Shen (4): ASoC: atmel-ssc: distinguish whether SSC supports fslen ext ASoC: atmel_ssc_dai: enable fslen extension feature dts: atmel: at91sam9rl: switch ssc compatible string dts: atmel: at91sam9g20: switch ssc compatible string
arch/arm/boot/dts/at91sam9g20.dtsi | 4 ++++ arch/arm/boot/dts/at91sam9rl.dtsi | 4 ++-- drivers/misc/atmel-ssc.c | 13 +++++++++++++ include/linux/atmel-ssc.h | 13 +++++++++++++ sound/soc/atmel/atmel_ssc_dai.c | 34 ++++++++++++++++++---------------- 5 files changed, 50 insertions(+), 18 deletions(-)
Add compatible string to distinguish whether SSC supports frame sync length extension.
Signed-off-by: Bo Shen voice.shen@atmel.com --- Changes in v2: - Using compatible string to distinguish whether SSC supports frame sync length extension to replace check IP version.
drivers/misc/atmel-ssc.c | 13 +++++++++++++ include/linux/atmel-ssc.h | 1 + 2 files changed, 14 insertions(+)
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index 22de137..60843a2 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c @@ -83,10 +83,17 @@ EXPORT_SYMBOL(ssc_free);
static struct atmel_ssc_platform_data at91rm9200_config = { .use_dma = 0, + .has_fslen_ext = 0, +}; + +static struct atmel_ssc_platform_data at91sam9rl_config = { + .use_dma = 0, + .has_fslen_ext = 1, };
static struct atmel_ssc_platform_data at91sam9g45_config = { .use_dma = 1, + .has_fslen_ext = 1, };
static const struct platform_device_id atmel_ssc_devtypes[] = { @@ -94,6 +101,9 @@ static const struct platform_device_id atmel_ssc_devtypes[] = { .name = "at91rm9200_ssc", .driver_data = (unsigned long) &at91rm9200_config, }, { + .name = "at91sam9rl_ssc", + .driver_data = (unsigned long) &at91sam9rl_config, + }, { .name = "at91sam9g45_ssc", .driver_data = (unsigned long) &at91sam9g45_config, }, { @@ -107,6 +117,9 @@ static const struct of_device_id atmel_ssc_dt_ids[] = { .compatible = "atmel,at91rm9200-ssc", .data = &at91rm9200_config, }, { + .compatible = "atmel,at91sam9rl-ssc", + .data = &at91sam9rl_config, + }, { .compatible = "atmel,at91sam9g45-ssc", .data = &at91sam9g45_config, }, { diff --git a/include/linux/atmel-ssc.h b/include/linux/atmel-ssc.h index 571a12e..e8dd408 100644 --- a/include/linux/atmel-ssc.h +++ b/include/linux/atmel-ssc.h @@ -7,6 +7,7 @@
struct atmel_ssc_platform_data { int use_dma; + int has_fslen_ext; };
struct ssc_device {
On 11/06/2014 12:14, Bo Shen :
Add compatible string to distinguish whether SSC supports frame sync length extension.
Signed-off-by: Bo Shen voice.shen@atmel.com
Ok, I am fine with this one:
Acked-by: Nicolas Ferre nicolas.ferre@atmel.com
Changes in v2:
- Using compatible string to distinguish whether SSC supports frame sync length extension to replace check IP version.
drivers/misc/atmel-ssc.c | 13 +++++++++++++ include/linux/atmel-ssc.h | 1 + 2 files changed, 14 insertions(+)
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index 22de137..60843a2 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c @@ -83,10 +83,17 @@ EXPORT_SYMBOL(ssc_free);
static struct atmel_ssc_platform_data at91rm9200_config = { .use_dma = 0,
- .has_fslen_ext = 0,
+};
+static struct atmel_ssc_platform_data at91sam9rl_config = {
- .use_dma = 0,
- .has_fslen_ext = 1,
};
static struct atmel_ssc_platform_data at91sam9g45_config = { .use_dma = 1,
- .has_fslen_ext = 1,
};
static const struct platform_device_id atmel_ssc_devtypes[] = { @@ -94,6 +101,9 @@ static const struct platform_device_id atmel_ssc_devtypes[] = { .name = "at91rm9200_ssc", .driver_data = (unsigned long) &at91rm9200_config, }, {
.name = "at91sam9rl_ssc",
.driver_data = (unsigned long) &at91sam9rl_config,
- }, { .name = "at91sam9g45_ssc", .driver_data = (unsigned long) &at91sam9g45_config, }, {
@@ -107,6 +117,9 @@ static const struct of_device_id atmel_ssc_dt_ids[] = { .compatible = "atmel,at91rm9200-ssc", .data = &at91rm9200_config, }, {
.compatible = "atmel,at91sam9rl-ssc",
.data = &at91sam9rl_config,
- }, { .compatible = "atmel,at91sam9g45-ssc", .data = &at91sam9g45_config, }, {
diff --git a/include/linux/atmel-ssc.h b/include/linux/atmel-ssc.h index 571a12e..e8dd408 100644 --- a/include/linux/atmel-ssc.h +++ b/include/linux/atmel-ssc.h @@ -7,6 +7,7 @@
struct atmel_ssc_platform_data { int use_dma;
- int has_fslen_ext;
};
struct ssc_device {
When SSC work as master, it will generate the frame sync signal. On old SoCs, it only supports frame sync length less or equal to 16bits, on newer SoCs, it supports frame sync length extension, which can support frame size larger than 16 bits. So, add this to make it supports playback 24/32 bits audio clips.
Signed-off-by: Bo Shen voice.shen@atmel.com Acked-by: Nicolas Ferre nicolas.ferre@atmel.com --- Changes in v2: - Add comments for the fslen extension bits.
include/linux/atmel-ssc.h | 12 ++++++++++++ sound/soc/atmel/atmel_ssc_dai.c | 34 ++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 16 deletions(-)
diff --git a/include/linux/atmel-ssc.h b/include/linux/atmel-ssc.h index e8dd408..7c0f654 100644 --- a/include/linux/atmel-ssc.h +++ b/include/linux/atmel-ssc.h @@ -72,6 +72,12 @@ void ssc_free(struct ssc_device *ssc); #define SSC_RFMR_DATNB_OFFSET 8 #define SSC_RFMR_FSEDGE_SIZE 1 #define SSC_RFMR_FSEDGE_OFFSET 24 +/* + * The FSLEN_EXT exist on at91sam9rl, at91sam9g10, + * at91sam9g20, and at91sam9g45 and newer SoCs + */ +#define SSC_RFMR_FSLEN_EXT_SIZE 4 +#define SSC_RFMR_FSLEN_EXT_OFFSET 28 #define SSC_RFMR_FSLEN_SIZE 4 #define SSC_RFMR_FSLEN_OFFSET 16 #define SSC_RFMR_FSOS_SIZE 4 @@ -110,6 +116,12 @@ void ssc_free(struct ssc_device *ssc); #define SSC_TFMR_FSDEN_OFFSET 23 #define SSC_TFMR_FSEDGE_SIZE 1 #define SSC_TFMR_FSEDGE_OFFSET 24 +/* + * The FSLEN_EXT exist on at91sam9rl, at91sam9g10, + * at91sam9g20, and at91sam9g45 and newer SoCs + */ +#define SSC_TFMR_FSLEN_EXT_SIZE 4 +#define SSC_TFMR_FSLEN_EXT_OFFSET 28 #define SSC_TFMR_FSLEN_SIZE 4 #define SSC_TFMR_FSLEN_OFFSET 16 #define SSC_TFMR_FSOS_SIZE 3 diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index de433cfd..f403f39 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -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 @@ -388,18 +389,6 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, }
/* - * 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. */ switch (ssc_p->daifmt @@ -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)
On Wed, Jun 11, 2014 at 06:14:40PM +0800, Bo Shen wrote:
When SSC work as master, it will generate the frame sync signal. On old SoCs, it only supports frame sync length less or equal to 16bits, on newer SoCs, it supports frame sync length extension, which can support frame size larger than 16 bits. So, add this to make it supports playback 24/32 bits audio clips.
Applied, thanks.
As the SSC integrate in at91sam9rl support frame sync length extension, so switch compatible string to support this feature.
Signed-off-by: Bo Shen voice.shen@atmel.com --- Changes in v2: - New
arch/arm/boot/dts/at91sam9rl.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi index 1da1831..fa32de9 100644 --- a/arch/arm/boot/dts/at91sam9rl.dtsi +++ b/arch/arm/boot/dts/at91sam9rl.dtsi @@ -203,7 +203,7 @@ };
ssc0: ssc@fffc0000 { - compatible = "atmel,at91rm9200-ssc"; + compatible = "atmel,at91sam9rl-ssc"; reg = <0xfffc0000 0x4000>; interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>; pinctrl-names = "default"; @@ -212,7 +212,7 @@ };
ssc1: ssc@fffc4000 { - compatible = "atmel,at91rm9200-ssc"; + compatible = "atmel,at91sam9rl-ssc"; reg = <0xfffc4000 0x4000>; interrupts = <15 IRQ_TYPE_LEVEL_HIGH 5>; pinctrl-names = "default";
On 11/06/2014 12:14, Bo Shen :
As the SSC integrate in at91sam9rl support frame sync length extension, so switch compatible string to support this feature.
Signed-off-by: Bo Shen voice.shen@atmel.com
I take the DT part of this series for at91-3.18-dt3: thanks!
Acked-by: Nicolas Ferre nicolas.ferre@atmel.com
Changes in v2:
- New
arch/arm/boot/dts/at91sam9rl.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi index 1da1831..fa32de9 100644 --- a/arch/arm/boot/dts/at91sam9rl.dtsi +++ b/arch/arm/boot/dts/at91sam9rl.dtsi @@ -203,7 +203,7 @@ };
ssc0: ssc@fffc0000 {
compatible = "atmel,at91rm9200-ssc";
compatible = "atmel,at91sam9rl-ssc"; reg = <0xfffc0000 0x4000>; interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>; pinctrl-names = "default";
@@ -212,7 +212,7 @@ };
ssc1: ssc@fffc4000 {
compatible = "atmel,at91rm9200-ssc";
compatible = "atmel,at91sam9rl-ssc"; reg = <0xfffc4000 0x4000>; interrupts = <15 IRQ_TYPE_LEVEL_HIGH 5>; pinctrl-names = "default";
As the SSC integrate in at91sam9g20 support frame sync length extension, so switch compatible string to support this feature.
Signed-off-by: Bo Shen voice.shen@atmel.com --- Changes in v2: - New
arch/arm/boot/dts/at91sam9g20.dtsi | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi index b8e7946..dcd39fe 100644 --- a/arch/arm/boot/dts/at91sam9g20.dtsi +++ b/arch/arm/boot/dts/at91sam9g20.dtsi @@ -22,6 +22,10 @@ compatible = "atmel,at91sam9g20-i2c"; };
+ ssc0: ssc@fffbc000 { + compatible = "atmel,at91sam9rl-ssc"; + }; + adc0: adc@fffe0000 { atmel,adc-startup-time = <40>; };
On 11/06/2014 12:14, Bo Shen :
As the SSC integrate in at91sam9g20 support frame sync length extension, so switch compatible string to support this feature.
Signed-off-by: Bo Shen voice.shen@atmel.com
Now that the audio part is included, I take the DT for at91-3.18-dt3: thanks!
Acked-by: Nicolas Ferre nicolas.ferre@atmel.com
Changes in v2:
- New
arch/arm/boot/dts/at91sam9g20.dtsi | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi index b8e7946..dcd39fe 100644 --- a/arch/arm/boot/dts/at91sam9g20.dtsi +++ b/arch/arm/boot/dts/at91sam9g20.dtsi @@ -22,6 +22,10 @@ compatible = "atmel,at91sam9g20-i2c"; };
ssc0: ssc@fffbc000 {
compatible = "atmel,at91sam9rl-ssc";
};
adc0: adc@fffe0000 { atmel,adc-startup-time = <40>; };
participants (3)
-
Bo Shen
-
Mark Brown
-
Nicolas Ferre