* [PATCH] ASoC: davinci-mcasp: set up user bits for S/PDIF mode
@ 2014-03-26 15:04 Daniel Mack
2014-03-27 8:16 ` Peter Ujfalusi
0 siblings, 1 reply; 6+ messages in thread
From: Daniel Mack @ 2014-03-26 15:04 UTC (permalink / raw)
To: broonie; +Cc: peter.ujfalusi, alsa-devel, Daniel Mack
In DIT (S/PDIF) mode, program the transmitted user bits to reflect the
configured sample rate, along with some other details.
Signed-off-by: Daniel Mack <zonque@gmail.com>
---
sound/soc/davinci/davinci-mcasp.c | 55 +++++++++++++++++++++++++++++++++++++--
1 file changed, 53 insertions(+), 2 deletions(-)
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 712a7cd..ec0463a 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -27,6 +27,7 @@
#include <linux/of_platform.h>
#include <linux/of_device.h>
+#include <sound/asoundef.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -566,8 +567,11 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream)
}
/* S/PDIF */
-static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp)
+static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp,
+ unsigned int rate)
{
+ u32 val = 0;
+
/* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
and LSB first */
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(6) | TXSSZ(15));
@@ -589,6 +593,53 @@ static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp)
/* Enable the DIT */
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN);
+ /* Set S/PDIF channel status bits */
+ mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRA_REG + 0,
+ IEC958_AES0_CON_NOT_COPYRIGHT);
+ mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRB_REG + 0,
+ IEC958_AES0_CON_NOT_COPYRIGHT);
+
+ mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRA_REG + 1,
+ IEC958_AES1_CON_PCM_CODER);
+ mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRB_REG + 1,
+ IEC958_AES1_CON_PCM_CODER);
+
+ switch (rate) {
+ case 22050:
+ val |= IEC958_AES3_CON_FS_22050;
+ break;
+ case 24000:
+ val |= IEC958_AES3_CON_FS_24000;
+ break;
+ case 32000:
+ val |= IEC958_AES3_CON_FS_32000;
+ break;
+ case 44100:
+ val |= IEC958_AES3_CON_FS_44100;
+ break;
+ case 48000:
+ val |= IEC958_AES3_CON_FS_48000;
+ break;
+ case 88200:
+ val |= IEC958_AES3_CON_FS_88200;
+ break;
+ case 96000:
+ val |= IEC958_AES3_CON_FS_96000;
+ break;
+ case 176400:
+ val |= IEC958_AES3_CON_FS_176400;
+ break;
+ case 192000:
+ val |= IEC958_AES3_CON_FS_192000;
+ break;
+ default:
+ printk(KERN_WARNING "unsupported sampling rate: %d\n", rate);
+ return -EINVAL;
+ }
+
+ mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRA_REG + 3, val);
+ mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRB_REG + 3, val);
+
return 0;
}
@@ -621,7 +672,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
fifo_level = mcasp->rxnumevt * active_serializers;
if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
- ret = mcasp_dit_hw_param(mcasp);
+ ret = mcasp_dit_hw_param(mcasp, params_rate(params));
else
ret = mcasp_i2s_hw_param(mcasp, substream->stream);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] ASoC: davinci-mcasp: set up user bits for S/PDIF mode
2014-03-26 15:04 [PATCH] ASoC: davinci-mcasp: set up user bits for S/PDIF mode Daniel Mack
@ 2014-03-27 8:16 ` Peter Ujfalusi
2014-03-27 8:39 ` Daniel Mack
0 siblings, 1 reply; 6+ messages in thread
From: Peter Ujfalusi @ 2014-03-27 8:16 UTC (permalink / raw)
To: Daniel Mack, broonie; +Cc: alsa-devel
On 03/26/2014 05:04 PM, Daniel Mack wrote:
> In DIT (S/PDIF) mode, program the transmitted user bits to reflect the
> configured sample rate, along with some other details.
>
> Signed-off-by: Daniel Mack <zonque@gmail.com>
> ---
> sound/soc/davinci/davinci-mcasp.c | 55 +++++++++++++++++++++++++++++++++++++--
> 1 file changed, 53 insertions(+), 2 deletions(-)
>
> diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
> index 712a7cd..ec0463a 100644
> --- a/sound/soc/davinci/davinci-mcasp.c
> +++ b/sound/soc/davinci/davinci-mcasp.c
> @@ -27,6 +27,7 @@
> #include <linux/of_platform.h>
> #include <linux/of_device.h>
>
> +#include <sound/asoundef.h>
> #include <sound/core.h>
> #include <sound/pcm.h>
> #include <sound/pcm_params.h>
> @@ -566,8 +567,11 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream)
> }
>
> /* S/PDIF */
> -static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp)
> +static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp,
> + unsigned int rate)
> {
> + u32 val = 0;
> +
> /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
> and LSB first */
> mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(6) | TXSSZ(15));
> @@ -589,6 +593,53 @@ static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp)
> /* Enable the DIT */
> mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN);
>
> + /* Set S/PDIF channel status bits */
> + mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRA_REG + 0,
> + IEC958_AES0_CON_NOT_COPYRIGHT);
I think it would be safer to set the channel status bits like:
u32 val = 0;
u8 *bytes = (u8*) &val;
byte[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;
byte[1] |= IEC958_AES1_CON_PCM_CODER;
> + mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRB_REG + 0,
> + IEC958_AES0_CON_NOT_COPYRIGHT);
> +
> + mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRA_REG + 1,
> + IEC958_AES1_CON_PCM_CODER);
> + mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRB_REG + 1,
> + IEC958_AES1_CON_PCM_CODER);
> +
> + switch (rate) {
> + case 22050:
> + val |= IEC958_AES3_CON_FS_22050;
val8[3] |= IEC958_AES3_CON_FS_22050;
> + break;
> + case 24000:
> + val |= IEC958_AES3_CON_FS_24000;
val8[3] |= IEC958_AES3_CON_FS_24000;
> + break;
> + case 32000:
> + val |= IEC958_AES3_CON_FS_32000;
> + break;
> + case 44100:
> + val |= IEC958_AES3_CON_FS_44100;
> + break;
> + case 48000:
> + val |= IEC958_AES3_CON_FS_48000;
> + break;
> + case 88200:
> + val |= IEC958_AES3_CON_FS_88200;
> + break;
> + case 96000:
> + val |= IEC958_AES3_CON_FS_96000;
> + break;
> + case 176400:
> + val |= IEC958_AES3_CON_FS_176400;
> + break;
> + case 192000:
> + val |= IEC958_AES3_CON_FS_192000;
> + break;
> + default:
> + printk(KERN_WARNING "unsupported sampling rate: %d\n", rate);
> + return -EINVAL;
> + }
> +
> + mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRA_REG + 3, val);
> + mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRB_REG + 3, val);
mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRA_REG, val);
mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRB_REG, val);
Since these registers are 32 bits and the mcasp_set_reg() uses __raw_writel()
at the end.
Also in this way you write only once to the registers.
> +
> return 0;
> }
>
> @@ -621,7 +672,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
> fifo_level = mcasp->rxnumevt * active_serializers;
>
> if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
> - ret = mcasp_dit_hw_param(mcasp);
> + ret = mcasp_dit_hw_param(mcasp, params_rate(params));
> else
> ret = mcasp_i2s_hw_param(mcasp, substream->stream);
>
>
--
Péter
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ASoC: davinci-mcasp: set up user bits for S/PDIF mode
2014-03-27 8:16 ` Peter Ujfalusi
@ 2014-03-27 8:39 ` Daniel Mack
2014-03-27 9:10 ` Peter Ujfalusi
0 siblings, 1 reply; 6+ messages in thread
From: Daniel Mack @ 2014-03-27 8:39 UTC (permalink / raw)
To: Peter Ujfalusi, broonie; +Cc: alsa-devel
Hi Peter,
Thanks for your review.
On 03/27/2014 09:16 AM, Peter Ujfalusi wrote:
> On 03/26/2014 05:04 PM, Daniel Mack wrote:
>> In DIT (S/PDIF) mode, program the transmitted user bits to reflect the
>> configured sample rate, along with some other details.
>>
>> Signed-off-by: Daniel Mack <zonque@gmail.com>
>> ---
>> sound/soc/davinci/davinci-mcasp.c | 55 +++++++++++++++++++++++++++++++++++++--
>> 1 file changed, 53 insertions(+), 2 deletions(-)
>>
>> diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
>> index 712a7cd..ec0463a 100644
>> --- a/sound/soc/davinci/davinci-mcasp.c
>> +++ b/sound/soc/davinci/davinci-mcasp.c
>> @@ -27,6 +27,7 @@
>> #include <linux/of_platform.h>
>> #include <linux/of_device.h>
>>
>> +#include <sound/asoundef.h>
>> #include <sound/core.h>
>> #include <sound/pcm.h>
>> #include <sound/pcm_params.h>
>> @@ -566,8 +567,11 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream)
>> }
>>
>> /* S/PDIF */
>> -static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp)
>> +static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp,
>> + unsigned int rate)
>> {
>> + u32 val = 0;
>> +
>> /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
>> and LSB first */
>> mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(6) | TXSSZ(15));
>> @@ -589,6 +593,53 @@ static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp)
>> /* Enable the DIT */
>> mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN);
>>
>> + /* Set S/PDIF channel status bits */
>> + mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRA_REG + 0,
>> + IEC958_AES0_CON_NOT_COPYRIGHT);
>
> I think it would be safer to set the channel status bits like:
> u32 val = 0;
> u8 *bytes = (u8*) &val;
>
> byte[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;
> byte[1] |= IEC958_AES1_CON_PCM_CODER;
No, these defines are mapped on to 32-bit values, as seen in
include/sound/asounddef.h. Over all 6 registers, 192 bits can be stored,
which is the full length of channel status bits. Hence, they really need
an individual mcasp_set_reg() each.
Also, I've measured the output of the S/PDIF port with external S/PDIF
introspectors and the result is correct :)
Thanks,
Daniel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ASoC: davinci-mcasp: set up user bits for S/PDIF mode
2014-03-27 8:39 ` Daniel Mack
@ 2014-03-27 9:10 ` Peter Ujfalusi
2014-03-27 9:31 ` Daniel Mack
0 siblings, 1 reply; 6+ messages in thread
From: Peter Ujfalusi @ 2014-03-27 9:10 UTC (permalink / raw)
To: Daniel Mack, broonie; +Cc: alsa-devel
On 03/27/2014 10:39 AM, Daniel Mack wrote:
> Hi Peter,
>
> Thanks for your review.
>
> On 03/27/2014 09:16 AM, Peter Ujfalusi wrote:
>> On 03/26/2014 05:04 PM, Daniel Mack wrote:
>>> In DIT (S/PDIF) mode, program the transmitted user bits to reflect the
>>> configured sample rate, along with some other details.
>>>
>>> Signed-off-by: Daniel Mack <zonque@gmail.com>
>>> ---
>>> sound/soc/davinci/davinci-mcasp.c | 55 +++++++++++++++++++++++++++++++++++++--
>>> 1 file changed, 53 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
>>> index 712a7cd..ec0463a 100644
>>> --- a/sound/soc/davinci/davinci-mcasp.c
>>> +++ b/sound/soc/davinci/davinci-mcasp.c
>>> @@ -27,6 +27,7 @@
>>> #include <linux/of_platform.h>
>>> #include <linux/of_device.h>
>>>
>>> +#include <sound/asoundef.h>
>>> #include <sound/core.h>
>>> #include <sound/pcm.h>
>>> #include <sound/pcm_params.h>
>>> @@ -566,8 +567,11 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream)
>>> }
>>>
>>> /* S/PDIF */
>>> -static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp)
>>> +static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp,
>>> + unsigned int rate)
>>> {
>>> + u32 val = 0;
>>> +
>>> /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
>>> and LSB first */
>>> mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(6) | TXSSZ(15));
>>> @@ -589,6 +593,53 @@ static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp)
>>> /* Enable the DIT */
>>> mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN);
>>>
>>> + /* Set S/PDIF channel status bits */
>>> + mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRA_REG + 0,
>>> + IEC958_AES0_CON_NOT_COPYRIGHT);
>>
>> I think it would be safer to set the channel status bits like:
>> u32 val = 0;
>> u8 *bytes = (u8*) &val;
>>
>> byte[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;
>> byte[1] |= IEC958_AES1_CON_PCM_CODER;
>
> No, these defines are mapped on to 32-bit values, as seen in
> include/sound/asounddef.h. Over all 6 registers, 192 bits can be stored,
> which is the full length of channel status bits. Hence, they really need
> an individual mcasp_set_reg() each.
I don't think they are mapped for the 32bit:
#define IEC958_AES0_CON_NOT_COPYRIGHT (1<<2)
#define IEC958_AES1_CON_DIGDIGCONV_ID 0x02
#define IEC958_AES1_CON_PCM_CODER (IEC958_AES1_CON_DIGDIGCONV_ID|0x00)
#define IEC958_AES3_CON_FS_48000 (2<<0) /* 48kHz */
#define IEC958_AES3_CON_FS_32000 (3<<0) /* 32kHz */
#define IEC958_AES3_CON_FS_22050 (4<<0) /* 22.05kHz */
#define IEC958_AES3_CON_FS_24000 (6<<0) /* 24kHz */
From the AES3 spec (byte numbers are 1 based while bit numbers are 0 based for
some reason in the specs):
Copyright bit is on Byte1's bit 2
Byte2 has the category code
and Byte4's 0-3 bits for the sampling frequency.
All of the setting you are changing ar in the first 32bit of the whole
channels status array, which is 24 byte long.
> Also, I've measured the output of the S/PDIF port with external S/PDIF
> introspectors and the result is correct :)
Well you essentially writing to the correct byte offset but I don't think in a
correct way:
write to DAVINCI_MCASP_DITCSRA_REG + 0 is a write starting at Byte1
write to DAVINCI_MCASP_DITCSRA_REG + 1 is a write starting at Byte2
write to DAVINCI_MCASP_DITCSRA_REG + 3 is a write starting at Byte4
The interconnect I think is clever enough to figure out that you try to write
to non 32bit boundary and does corrects the access (shifting the data to it's
correct place) but I don't think we should rely on that. It is much simpler to
configure the bits first and write it as one 32bit.
--
Péter
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ASoC: davinci-mcasp: set up user bits for S/PDIF mode
2014-03-27 9:10 ` Peter Ujfalusi
@ 2014-03-27 9:31 ` Daniel Mack
2014-03-27 9:38 ` Daniel Mack
0 siblings, 1 reply; 6+ messages in thread
From: Daniel Mack @ 2014-03-27 9:31 UTC (permalink / raw)
To: Peter Ujfalusi, broonie; +Cc: alsa-devel
On 03/27/2014 10:10 AM, Peter Ujfalusi wrote:
> On 03/27/2014 10:39 AM, Daniel Mack wrote:
>> No, these defines are mapped on to 32-bit values, as seen in
>> include/sound/asounddef.h. Over all 6 registers, 192 bits can be stored,
>> which is the full length of channel status bits. Hence, they really need
>> an individual mcasp_set_reg() each.
>
> I don't think they are mapped for the 32bit:
> #define IEC958_AES0_CON_NOT_COPYRIGHT (1<<2)
>
> #define IEC958_AES1_CON_DIGDIGCONV_ID 0x02
> #define IEC958_AES1_CON_PCM_CODER (IEC958_AES1_CON_DIGDIGCONV_ID|0x00)
>
> #define IEC958_AES3_CON_FS_48000 (2<<0) /* 48kHz */
> #define IEC958_AES3_CON_FS_32000 (3<<0) /* 32kHz */
> #define IEC958_AES3_CON_FS_22050 (4<<0) /* 22.05kHz */
> #define IEC958_AES3_CON_FS_24000 (6<<0) /* 24kHz */
Hmm, that's odd. What about this one then, which definitely needs a
larger type than uint16?
#define IEC958_AES4_CON_ORIGFS_44100 (15<<4) /* 44.1kHz */
I considered DITCSRA0 to DITCSRA5 to carry 6 32 bit values, which map to
the values defined as IEC958_AESX*.
> From the AES3 spec (byte numbers are 1 based while bit numbers are 0 based for
> some reason in the specs):
> Copyright bit is on Byte1's bit 2
"Byte 1" is the at index 0, right?
#define IEC958_AES0_CON_NOT_COPYRIGHT (1<<2)
> Byte2 has the category code
> and Byte4's 0-3 bits for the sampling frequency.
#define IEC958_AES3_CON_FS_44100 (0<<0)
...
You're right that my register address calculation has to go in 32bit
(DAVINCI_MCASP_DITCSRA_REG + 4, DAVINCI_MCASP_DITCSRA_REG + 8, ...), but
I still don't think the u8-mapping is correct.
I'm confused. :)
Daniel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ASoC: davinci-mcasp: set up user bits for S/PDIF mode
2014-03-27 9:31 ` Daniel Mack
@ 2014-03-27 9:38 ` Daniel Mack
0 siblings, 0 replies; 6+ messages in thread
From: Daniel Mack @ 2014-03-27 9:38 UTC (permalink / raw)
To: Daniel Mack, Peter Ujfalusi, broonie; +Cc: alsa-devel
On 03/27/2014 10:31 AM, Daniel Mack wrote:
> You're right that my register address calculation has to go in 32bit
> (DAVINCI_MCASP_DITCSRA_REG + 4, DAVINCI_MCASP_DITCSRA_REG + 8, ...), but
> I still don't think the u8-mapping is correct.
>
> I'm confused. :)
Ok ok, I am indeed. You're right, got it now. What puzzled me is that
there are registers DITCSRA0 to DITCSRA5, of which only 2 seem to be of use.
I'll resend a new version later today.
Thanks!
Daniel
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2014-03-27 9:38 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-26 15:04 [PATCH] ASoC: davinci-mcasp: set up user bits for S/PDIF mode Daniel Mack
2014-03-27 8:16 ` Peter Ujfalusi
2014-03-27 8:39 ` Daniel Mack
2014-03-27 9:10 ` Peter Ujfalusi
2014-03-27 9:31 ` Daniel Mack
2014-03-27 9:38 ` Daniel Mack
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).