[alsa-devel] Please help in adding ams-delta support to ASoC
Hi,
I am trying to add sound support for ams-delta omap machine, yet without much success.
Three years ago, Mark Underwood created an omap-alsa compatible driver that basically worked[1]. It was derieved from similiar driver for aic23 codec found on omap osk machine. It looks like Mark has never managed to finish his work. It's not clear for me if he has found that getting a working fullduplex sound is technically impossible on a voice modem codec, shared among modem and cpu, controlable only from modem side afaik, but I have decided to give it a try.
Since Mark's initial work, omap-alsa framework has been depreciated in favour of soc-omap. API changes are so significant that Mark's code is rather not useable directly any more. However, I am trying to use it as a starting point, by comparing it against it's prototype osk/aic23 code.
Following Mark, I am trying to derieve the new ams-delta sound driver from current asoc driver for omap osk9512. For codec part, I decided to base my work on much more simple ad73311 rather that tlv320aic23.
Comparing Mark's code agaist it's osk/aic23 prototype, I can see the folowing significant changes: 1. rate tables/bitmaps found in hw_constraint_rates, snd_omap_alsa_playback and snd_omap_alsa_capture structures limited to 8kHz, 2. hardware related code found in codec_configure_dev(), codec_clock_on() and codec_clock_off() callback functions replaced with ams-delta hardware specific code that switches the codec DAI pins from modem chip to mcbsp cpu interface and back, 3. codec_set_samplerate() and all mixer related functions replaced with stubs. 4. the following McBSP register settings changes:
- .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | - XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG, + .xcr2 = XPHASE | XWDLEN2(OMAP_MCBSP_WORD_16) | XFRLEN2(0),
- .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1), + .srgr1 = CLKGDV(0),
- .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1), + .srgr2 = GSYNC,
- .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
I have found points 1. to 3. rather trivial to implement in new framework. Regarding point 4., it looks like detailed register settings are now done inside omap-mcbsp.c, based on machine specified format, so I have to find out what format should be specified for ams-delta. Please correct me if I am missing something.
There was one more modification in Mark's code, addressing dma chaining problem on omap15xx hardware, but as far as I could see, the problem was already solved in the asoc omap framework.
Initially, I based my work on ompenembedded provided linux-omap.git revision 90e758af52ba803cba233fabee81176d99589f09. The results were rather poor - total system hangup after first device access, with no single message. So I have switched to linux-2.6.30-rc5 and now I can safely access the device, however it does not work as expected. aplay and arecord wait forever, cat to/from /dev/dsp breaks with hardware error messgae. DMA interrput counters stay at 0. However, codec switching that I do from machine->ops->startup/shutdown seems working, as modem stops producing any sounds while the alsa device is in use and gets back thereafter.
First of all, I'd like to make sure if my problem is related to my code only. As I am new in these areas, I would like to ask you if the omap asoc framework is stable enough to relay on. If yes, could you please look at my dirty code (attached) an give me some hints? I can provide you with more information if necessary.
Regards, Janusz
[1] http://www.earth.li/pipermail/e3-hacking/2006-April/000481.html
On Tuesday 26 May 2009 16:17:23 ext Janusz Krzysztofik wrote:
Hi,
I am trying to add sound support for ams-delta omap machine, yet without much success.
Three years ago, Mark Underwood created an omap-alsa compatible driver that basically worked[1]. It was derieved from similiar driver for aic23 codec found on omap osk machine. It looks like Mark has never managed to finish his work. It's not clear for me if he has found that getting a working fullduplex sound is technically impossible on a voice modem codec, shared among modem and cpu, controlable only from modem side afaik, but I have decided to give it a try.
Since Mark's initial work, omap-alsa framework has been depreciated in favour of soc-omap. API changes are so significant that Mark's code is rather not useable directly any more. However, I am trying to use it as a starting point, by comparing it against it's prototype osk/aic23 code.
Following Mark, I am trying to derieve the new ams-delta sound driver from current asoc driver for omap osk9512. For codec part, I decided to base my work on much more simple ad73311 rather that tlv320aic23.
Comparing Mark's code agaist it's osk/aic23 prototype, I can see the folowing significant changes:
- rate tables/bitmaps found in hw_constraint_rates,
snd_omap_alsa_playback and snd_omap_alsa_capture structures limited to 8kHz, 2. hardware related code found in codec_configure_dev(), codec_clock_on() and codec_clock_off() callback functions replaced with ams-delta hardware specific code that switches the codec DAI pins from modem chip to mcbsp cpu interface and back, 3. codec_set_samplerate() and all mixer related functions replaced with stubs. 4. the following McBSP register settings changes:
- .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG,
- .xcr2 = XPHASE | XWDLEN2(OMAP_MCBSP_WORD_16) | XFRLEN2(0),
- .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1),
- .srgr1 = CLKGDV(0),
- .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1),
.srgr2 = GSYNC,
- .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
Since I don't have the original osk/aic23 thing, this does not mean to much... Just a bit confusing. The configuration suggest slave McBSP with NB_IF polarity, dual phase format, 16 bit words, 16*2 long frames, the FS pulse is probably a pulse... Suggesting kind of DSP mode, but with not so correct configuration, which happens to be working.
I have found points 1. to 3. rather trivial to implement in new framework. Regarding point 4., it looks like detailed register settings are now done inside omap-mcbsp.c, based on machine specified format, so I have to find out what format should be specified for ams-delta. Please correct me if I am missing something.
Yes, that is correct. What you need for the point 4: Interface format of the cx20442 codec (I2S, DSP_A, DSP_B, etc) Clock polarities. Does the codec provides the clocks (bit, frame sync) - codec master or slave
When you know these the soc/omap/arms-delta.c can configure the CPU dai with: snd_soc_dai_set_fmt(cpu_dai, ...
There was one more modification in Mark's code, addressing dma chaining problem on omap15xx hardware, but as far as I could see, the problem was already solved in the asoc omap framework.
Initially, I based my work on ompenembedded provided linux-omap.git revision 90e758af52ba803cba233fabee81176d99589f09. The results were rather poor - total system hangup after first device access, with no single message. So I have switched to linux-2.6.30-rc5 and now I can safely access the device, however it does not work as expected. aplay and arecord wait forever, cat to/from /dev/dsp breaks with hardware error messgae. DMA interrput counters stay at 0.
This means that the McBSP module is not transmitting/receiving any data. Which suggests that the clocking is not working in your setup. Check the slave master mode for the codec. Also worth checking the PIN configuration for the McBSP1 module, just in case it is correct.
However, codec switching that I do from machine->ops->startup/shutdown seems working, as modem stops producing any sounds while the alsa device is in use and gets back thereafter.
First of all, I'd like to make sure if my problem is related to my code only. As I am new in these areas, I would like to ask you if the omap asoc framework is stable enough to relay on.
I believe that it is stable enough.
If yes, could you please look at my dirty code (attached) an give me some hints? I can provide you with more information if necessary.
Given that it is still early morning, I could not find anything that would prevent it to be somehow working...
Regards, Janusz
Hi Peter,
On Wuesday 27 May 2009 07:57 Peter Ujfalusi wrote:
On Tuesday 26 May 2009 16:17:23 ext Janusz Krzysztofik wrote:
- the following McBSP register settings changes:
- .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG,
- .xcr2 = XPHASE | XWDLEN2(OMAP_MCBSP_WORD_16) | XFRLEN2(0),
- .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1),
- .srgr1 = CLKGDV(0),
- .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1),
.srgr2 = GSYNC,
- .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
Since I don't have the original osk/aic23 thing, this does not mean to much... Just a bit confusing.
OK, once again then.
original omap-alsa mcbsp register settings for osk board, as found in linux-2.6.16/arch/arm/mach-omap1/board-osk.c: ----- #define DEFAULT_BITPERSAMPLE 16
static struct omap_mcbsp_reg_cfg mcbsp_regs = { .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), .spcr1 = RINTM(3) | RRST, .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0), .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16), .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG, .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16), .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1), .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1), /*.pcr0 = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,*/ /* mcbsp: master */ .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */ }; ----- the same for ams-delta, as found in Mark Underwood patch: ----- static struct omap_mcbsp_reg_cfg mcbsp_regs = { .spcr2 = FREE | XRST | GRST | XINTM(3) | FRST, .spcr1 = RINTM(3) | RRST, .rcr2 = RPHASE | RWDLEN2(OMAP_MCBSP_WORD_16) | RFRLEN2(0), .rcr1 = RWDLEN1(OMAP_MCBSP_WORD_16) | RFRLEN1(0), .xcr2 = XPHASE | XWDLEN2(OMAP_MCBSP_WORD_16) | XFRLEN2(0), .xcr1 = XWDLEN1(OMAP_MCBSP_WORD_16) | XFRLEN1(0), .srgr1 = CLKGDV(0), .srgr2 = GSYNC, }; ----- currnet soc-audio mcbsp config for osk, as found in linux-2.6.29/sound/soc/omap/osk5912.c: ----- err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); ----- Using exactly the same does not work on my ams-delta.
The configuration suggest slave McBSP with NB_IF polarity, dual phase format, 16 bit words, 16*2 long frames, the FS pulse is probably a pulse... Suggesting kind of DSP mode, but with not so correct configuration, which happens to be working.
So I will try the following then: err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_CBM_CFM); and this: err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_CBM_CFM); and give you a feedback.
... aplay and arecord wait forever, cat to/from /dev/dsp breaks with hardware error messgae. DMA interrput counters stay at 0.
This means that the McBSP module is not transmitting/receiving any data. Which suggests that the clocking is not working in your setup. Check the slave master mode for the codec.
Do you mean trying with codec as slave and McBSP as master, like this? err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_CBS_CFS); I'll give it a try as well.
Also worth checking the PIN configuration for the McBSP1 module, just in case it is correct.
Do you mean mux setup? Reading OMAP5910 Data Manual I found only 2 relevant signals, MCBSP1.FSX and MCBSP1.DX, that could be swapped from pin H15 to H18 and vice versa. However, there is no pin configuration entry for neither, both in 2.6.16 and 2.6.29 arch/arm/mach-omap1/mux.c, so I assume default setup should just work.
I keep on digging.
Thanks, Janusz
On Wednesday 27 May 2009 16:07:23 ext Janusz Krzysztofik wrote:
Hi Peter,
On Wuesday 27 May 2009 07:57 Peter Ujfalusi wrote:
On Tuesday 26 May 2009 16:17:23 ext Janusz Krzysztofik wrote:
- the following McBSP register settings changes:
- .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG,
- .xcr2 = XPHASE | XWDLEN2(OMAP_MCBSP_WORD_16) | XFRLEN2(0),
- .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1),
- .srgr1 = CLKGDV(0),
- .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1),
.srgr2 = GSYNC,
- .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
Since I don't have the original osk/aic23 thing, this does not mean to much... Just a bit confusing.
OK, once again then.
original omap-alsa mcbsp register settings for osk board, as found in linux-2.6.16/arch/arm/mach-omap1/board-osk.c:
#define DEFAULT_BITPERSAMPLE 16
static struct omap_mcbsp_reg_cfg mcbsp_regs = { .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), .spcr1 = RINTM(3) | RRST, .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0), .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16), .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG, .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16), .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1), .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1), /*.pcr0 = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,*/ /* mcbsp: master */ .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */ };
the same for ams-delta, as found in Mark Underwood patch:
static struct omap_mcbsp_reg_cfg mcbsp_regs = { .spcr2 = FREE | XRST | GRST | XINTM(3) | FRST, .spcr1 = RINTM(3) | RRST, .rcr2 = RPHASE | RWDLEN2(OMAP_MCBSP_WORD_16) | RFRLEN2(0), .rcr1 = RWDLEN1(OMAP_MCBSP_WORD_16) | RFRLEN1(0), .xcr2 = XPHASE | XWDLEN2(OMAP_MCBSP_WORD_16) | XFRLEN2(0), .xcr1 = XWDLEN1(OMAP_MCBSP_WORD_16) | XFRLEN1(0), .srgr1 = CLKGDV(0), .srgr2 = GSYNC, };
I wonder has this been working at all??? FPER is not configured in srgr2 (actually it is 0, which means that the frame period is 1...) FWID is not configured in srgr1 (it is 0, which means the FS is a pulse, length is 1) Since CLKXP, CLKRP is 0, it suggests inverted bitclock. FSXP, FSRP is 0, so it must have normal FS polarity in DSP mode, or inverted polarity in I2S mode??? Data delay is 0 for rx and tx.
In all, I think this is a missconfigured DSP_B mode with inverted bitclock. Can you try this: err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBM_CFM);
currnet soc-audio mcbsp config for osk, as found in linux-2.6.29/sound/soc/omap/osk5912.c:
err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
Using exactly the same does not work on my ams-delta.
The configuration suggest slave McBSP with NB_IF
polarity, dual phase format, 16 bit words, 16*2 long frames, the FS pulse is probably a pulse... Suggesting kind of DSP mode, but with not so correct configuration, which happens to be working.
So I will try the following then: err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_CBM_CFM); and this: err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_CBM_CFM); and give you a feedback.
... aplay and arecord wait forever, cat to/from /dev/dsp breaks with hardware error messgae. DMA interrput counters stay at 0.
This means that the McBSP module is not transmitting/receiving any data. Which suggests that the clocking is not working in your setup. Check the slave master mode for the codec.
Do you mean trying with codec as slave and McBSP as master, like this? err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_CBS_CFS); I'll give it a try as well.
Also worth checking the PIN configuration for the McBSP1 module, just in case it is correct.
Do you mean mux setup? Reading OMAP5910 Data Manual I found only 2 relevant signals, MCBSP1.FSX and MCBSP1.DX, that could be swapped from pin H15 to H18 and vice versa. However, there is no pin configuration entry for neither, both in 2.6.16 and 2.6.29 arch/arm/mach-omap1/mux.c, so I assume default setup should just work.
I keep on digging.
Thanks, Janusz _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Hi Peter,
Peter Ujfalusi wrote:
On Wednesday 27 May 2009 16:07:23 ext Janusz Krzysztofik wrote:
static struct omap_mcbsp_reg_cfg mcbsp_regs = { .spcr2 = FREE | XRST | GRST | XINTM(3) | FRST, .spcr1 = RINTM(3) | RRST, .rcr2 = RPHASE | RWDLEN2(OMAP_MCBSP_WORD_16) | RFRLEN2(0), .rcr1 = RWDLEN1(OMAP_MCBSP_WORD_16) | RFRLEN1(0), .xcr2 = XPHASE | XWDLEN2(OMAP_MCBSP_WORD_16) | XFRLEN2(0), .xcr1 = XWDLEN1(OMAP_MCBSP_WORD_16) | XFRLEN1(0), .srgr1 = CLKGDV(0), .srgr2 = GSYNC, };
I wonder has this been working at all??? FPER is not configured in srgr2 (actually it is 0, which means that the frame period is 1...) FWID is not configured in srgr1 (it is 0, which means the FS is a pulse, length is 1) Since CLKXP, CLKRP is 0, it suggests inverted bitclock. FSXP, FSRP is 0, so it must have normal FS polarity in DSP mode, or inverted polarity in I2S mode??? Data delay is 0 for rx and tx.
In all, I think this is a missconfigured DSP_B mode with inverted bitclock. Can you try this: err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBM_CFM);
Already tried before, did not help.
So I will try the following then: err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_CBM_CFM); and this: err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_CBM_CFM); and give you a feedback.
Sorry, I did not answer since I gave up trying different dai format settings after discovering that the original driver still worked with register settings taken directly form its prototype osk board code.
Anyway, I think I'll have to get back here after DMA interrupts start working.
Thanks, Janusz
Hi
On Tue, 26 May 2009 15:17:23 +0200 Janusz Krzysztofik jkrzyszt@tis.icnet.pl wrote:
Grr, these McBSP bits are always almost un-readable :-)
- the following McBSP register settings changes:
- .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG,
- .xcr2 = XPHASE | XWDLEN2(OMAP_MCBSP_WORD_16) | XFRLEN2(0),
XFIG is only difference (OMAP_MCBSP_WORD_8 = 0) -> transfer is aborted in case of unexpected frame sync.
- .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1),
- .srgr1 = CLKGDV(0),
Width of frame sync signal set to 1 here -> DSP_B format because no data delay set.
- .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE *
2 - 1),
.srgr2 = GSYNC,
- .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
No CLKXM, CLKRM and FSGM set -> codec is providing the frame sync and bit-clock signals -> SND_SOC_DAIFMT_CBM_CFM.
CLKXP and CLKRP not set -> rising edge of bit clock drives the transitions. This with DSP_B indicates inverted bit clock so SND_SOC_DAIFMT_IB_NF.
I wonder why the frame sync period (FWID) wasn't set in that original patch but probably McBSP is able to work without :-)
safely access the device, however it does not work as expected. aplay and arecord wait forever, cat to/from /dev/dsp breaks with hardware error messgae. DMA interrput counters stay at 0. However, codec
Looks like McBSP is not getting bit-clock and frame-sync signals from the codec. Do you have any way to measure is the codec sending those?
Another possibility are the OMAP pins muxed for McBSP? I assume they are if the bootloader is still the same but worth to find check was previous kernel doing any runtime remuxing for those pins with omap_cfg_reg calls.
First of all, I'd like to make sure if my problem is related to my code only. As I am new in these areas, I would like to ask you if the omap asoc framework is stable enough to relay on. If yes, could you please look at my dirty code (attached) an give me some hints? I can provide you with more information if necessary.
I hope it's stable enough for you to get going. It would be nice to get this working since it would be the first OMAP5910 == OMAP1510 based machine driver. OMAP1510 doesn't support DMA chaining so there are few cpu_is_omap1510() code snippets in sound/soc/omap/omap-pcm.c which I think I have only simulated using OMAP2420.
Hi Jarkko,
On Wed, 27 May 2009 08:59 Jarkko Nikula wrote:
On Tue, 26 May 2009 15:17:23 +0200 Janusz Krzysztofik jkrzyszt@tis.icnet.pl wrote:
- .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG,
- .xcr2 = XPHASE | XWDLEN2(OMAP_MCBSP_WORD_16) | XFRLEN2(0),
XFIG is only difference (OMAP_MCBSP_WORD_8 = 0) -> transfer is aborted in case of unexpected frame sync.
I tried commenting out RFIG and XFIG bits settings in sound/soc/omap/omap-mcbsp.c - did not help.
- .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1),
- .srgr1 = CLKGDV(0),
Width of frame sync signal set to 1 here -> DSP_B format because no data delay set.
That's what I have tried mostly.
- .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE *
2 - 1),
.srgr2 = GSYNC,
- .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
No CLKXM, CLKRM and FSGM set -> codec is providing the frame sync and bit-clock signals -> SND_SOC_DAIFMT_CBM_CFM.
This is my primary choice as well.
CLKXP and CLKRP not set -> rising edge of bit clock drives the transitions. This with DSP_B indicates inverted bit clock so SND_SOC_DAIFMT_IB_NF.
I have given it a try this morning - no go.
I wonder why the frame sync period (FWID) wasn't set in that original patch but probably McBSP is able to work without :-)
from linux-2.6.29/sound/soc/omap/omap-mcbsp.c: switch (mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: regs->srgr2 |= FPER(wlen * 2 - 1); regs->srgr1 |= FWID(wlen - 1); break; case SND_SOC_DAIFMT_DSP_B: regs->srgr2 |= FPER(wlen * channels - 1); regs->srgr1 |= FWID(0); break; }
So it looks like in case of SND_SOC_DAIFMT_DSP_B, FWID is not set, only FPER. However, in the original patch, FPER was not set either.
... aplay and arecord wait forever, cat to/from /dev/dsp breaks with hardware error messgae. DMA interrput counters stay at 0. However, codec
Looks like McBSP is not getting bit-clock and frame-sync signals from the codec. Do you have any way to measure is the codec sending those?
Well, I am not sure, but I'll try if nothing helps.
Another possibility are the OMAP pins muxed for McBSP? I assume they are if the bootloader is still the same
I boot both kernels, working 2.6.16 and not working 2.6.30-rc5, with the same u-boot.bin.
but worth to find check was previous kernel doing any runtime remuxing for those pins with omap_cfg_reg calls.
I was not able to find anything relevant.
... OMAP1510 doesn't support DMA chaining so there are few cpu_is_omap1510() code snippets in sound/soc/omap/omap-pcm.c which I think I have only simulated using OMAP2420.
I hope DMA chaining is not an issue here. If I remove the DMA chaining workaround from the original patch, I get signle DMA interrupts, so that is better than none that I get with my patch.
Thanks, Janusz -- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, 27 May 2009 16:33:22 +0200 Janusz Krzysztofik jkrzyszt@tis.icnet.pl wrote:
- .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE
- 2 - 1),
.srgr2 = GSYNC,
- .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
...
I wonder why the frame sync period (FWID) wasn't set in that original patch but probably McBSP is able to work without :-)
from linux-2.6.29/sound/soc/omap/omap-mcbsp.c: switch (mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: regs->srgr2 |= FPER(wlen * 2 - 1); regs->srgr1 |= FWID(wlen - 1); break; case SND_SOC_DAIFMT_DSP_B: regs->srgr2 |= FPER(wlen * channels - 1); regs->srgr1 |= FWID(0); break; }
So it looks like in case of SND_SOC_DAIFMT_DSP_B, FWID is not set, only FPER. However, in the original patch, FPER was not set either.
Sorry, my short above. Obviously I was wondering missing FPER setting in original patch which defines the length of frame sync period. FWID defines the length of frame sync pulse (n.o. bit clock pulses - 1).
Frame sync pulse length is half of the period in I2S and 1-bit clock cycle in DSP_B. WM9713 has nice drawings about different formats. Look pages 29 and 30.
http://www.wolfsonmicro.com/uploads/documents/en/WM9713.pdf
I hope DMA chaining is not an issue here. If I remove the DMA chaining workaround from the original patch, I get signle DMA interrupts, so that is better than none that I get with my patch.
I think chaining is not issue if you are not getting any interrupt. Basically if DMA transfer is working but DMA restarting is not then there should be one completed buffer transfer and >= 2 interrupts from completed periods.
Hi,
Tired with hopeless looking for the correct mcbsp dai format, I took the oposite direciton, trying to break what Mark Underwood had managed to get working. Step by step, I got to exactly the same mcbsp register configuration as used in the reference osk board, reverting all changes that Mark could introduce, and the driver still worked as before. So it looks like playing with mcbsp dai format is not the way to solve the problem.
Wednesday 27 May 2009 07:57:27 Peter Ujfalusi wrote:
This means that the McBSP module is not transmitting/receiving any data. Which suggests that the clocking is not working in your setup. Check the slave master mode for the codec.
Now I think I understand better what you mean. However, I don't know any way of configuring the codec except for switching its pin connections from msbcp to modem chip and back. I can find nothing relevant in the original patch that could help.
Also worth checking the PIN configuration for the McBSP1 module, just in case it is correct.
Wednesday 27 May 2009 08:59:49 Jarkko Nikula wrote:
Looks like McBSP is not getting bit-clock and frame-sync signals from the codec. Do you have any way to measure is the codec sending those?
Another possibility are the OMAP pins muxed for McBSP? I assume they are if the bootloader is still the same but worth to find check was previous kernel doing any runtime remuxing for those pins with omap_cfg_reg calls.
So I am going to restart with checking if the original patch still works with the latest kernel version supporting omap-alsa.
Thanks for your help so far. Any hints are still welcome.
Cheers, Janusz
-- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Janusz Krzysztofik wrote:
So I am going to restart with checking if the original patch still works with the latest kernel version supporting omap-alsa.
The original patch ported to linux-omap-2.6.27, the last omap release with omap-alsa support, gives me a working sound driver on ams-delta.
Jarkko Nikula wrote:
Looks like McBSP is not getting bit-clock and frame-sync signals from the codec. ... Another possibility are the OMAP pins muxed for McBSP? I assume they are if the bootloader is still the same but worth to find check was previous kernel doing any runtime remuxing for those pins with omap_cfg_reg calls.
Peter Ujfalusi wrote:
This means that the McBSP module is not transmitting/receiving any data. Which suggests that the clocking is not working in your setup. Check the slave master mode for the codec. Also worth checking the PIN configuration for the McBSP1 module, just in case it is correct.
My port of the original driver is still very generic. There are no mux setups. It containes only two simple hardware pin setup calls that make it working, those are invoked from two callback functions, omap_alsa_codec_config.codec_clock_on() and omap_alsa_codec_config.codec_clock_off(), as below:
----------------------------------- int vc_clock_on(void) { if (clk_get_usecount(vc_mclk) > 0) { /* MCLK is already in use */ printk(KERN_WARNING "MCLK in use at %d Hz. We change it to %d Hz\n", (uint) clk_get_rate(vc_mclk), CODEC_CLOCK); } clk_enable(vc_mclk);
printk(KERN_DEBUG "MCLK = %d [%d], usecount = %d\n", (uint) clk_get_rate(vc_mclk), CODEC_CLOCK, clk_get_usecount(vc_mclk));
/* Now turn the audio on */ ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC, AMS_DELTA_LATCH2_MODEM_NRESET); return 0; }
int vc_clock_off(void) { if (clk_get_usecount(vc_mclk) > 0) { if (clk_get_rate(vc_mclk) != CODEC_CLOCK) { printk(KERN_WARNING "MCLK for audio should be %d Hz. But is %d Hz\n", (uint) clk_get_rate(vc_mclk), CODEC_CLOCK); }
clk_disable(vc_mclk); }
ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, AMS_DELTA_LATCH2_MODEM_CODEC); return 0; } ... static int __init snd_omap_alsa_vc_probe(struct platform_device *pdev) { ... struct omap_alsa_codec_config *codec_cfg; ... codec_cfg->codec_clock_on = vc_clock_on; codec_cfg->codec_clock_off = vc_clock_off; ... }
static struct platform_driver omap_alsa_driver = { .probe = snd_omap_alsa_vc_probe, ... };
static int __init omap_alsa_vc_init(void) { int err;
err = platform_driver_register(&omap_alsa_driver); return err; } ----------------------------------
Jarkko Nikula wrote:
OMAP1510 doesn't support DMA chaining so there are few cpu_is_omap1510() code snippets in sound/soc/omap/omap-pcm.c which I think I have only simulated using OMAP2420.
To make the original driver work stable, I had to patch the omap-alsa framework to restore the original way that lack of dma chaining problem had been solved in the original patch (see below), so maybe there is a similiar issue in the currect ASoC McBSP framework?
---------------------------------- diff -uprN linux-2.6.27/sound/arm/omap/omap-alsa.c linux-2.6.27-sound/sound/arm/omap/omap-alsa.c --- linux-2.6.27/sound/arm/omap/omap-alsa.c 2009-05-30 21:27:09.000000000 +0000 +++ linux-2.6.27-sound/sound/arm/omap/omap-alsa.c 2009-05-30 22:12:12.000000000 +0000 @@ -52,6 +52,8 @@ #include <mach/omap-alsa.h> #include "omap-alsa-dma.h"
+#include <asm/mach-types.h> + MODULE_AUTHOR("Mika Laitio"); MODULE_AUTHOR("Daniel Petrini"); MODULE_AUTHOR("David Cohen"); @@ -210,7 +212,7 @@ static int audio_start_dma_chain(struct * irq from DMA after the first transfered/played buffer. * (invocation of callback_omap_alsa_sound_dma() method). */ - if (cpu_is_omap1510()) + if (cpu_is_omap1510() && !machine_is_ams_delta()) omap_stop_alsa_sound_dma(s);
dma_start_pos = (dma_addr_t)runtime->dma_area + offset; diff -uprN linux-2.6.27/sound/arm/omap/omap-alsa-dma.c linux-2.6.27-sound/sound/arm/omap/omap-alsa-dma.c --- linux-2.6.27/sound/arm/omap/omap-alsa-dma.c 2009-05-30 21:27:09.000000000 +0000 +++ linux-2.6.27-sound/sound/arm/omap/omap-alsa-dma.c 2009-05-30 22:12:12.000000000 +0000 @@ -70,6 +70,8 @@
#include <asm/arch/omap-alsa.h>
+#include <asm/mach-types.h> + #undef DEBUG
#define ERR(ARGS...) printk(KERN_ERR "{%s}-ERROR: ", __FUNCTION__);printk(ARGS); @@ -350,7 +352,7 @@ static int audio_start_dma_chain(struct omap_start_dma(channel); s->started = 1; s->hw_start(); /* start McBSP interface */ - } else if (cpu_is_omap310()) + } else if (cpu_is_omap310() || machine_is_ams_delta()) omap_start_dma(channel); /* else the dma itself will progress forward with out our help */ FN_OUT(0); ----------------------------------
My asoc based patch is also very generic and contains no more that the same two ams_delta_latch2_write() hardware related operations, called from inside snd_soc_dai_link.ops.startup() and snd_soc_dai_link.ops.shutdown() callback functions:
---------------------------------- static int ams_delta_startup(struct snd_pcm_substream *substream) { ams_delta_latch2_write(AMS_DELTA_LATCH_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC, AMS_DELTA_LATCH_MODEM_NRESET); return clk_enable(cx20442_mclk); }
static void ams_delta_shutdown(struct snd_pcm_substream *substream) { clk_disable(cx20442_mclk); ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, AMS_DELTA_LATCH2_MODEM_CODEC); } ... static struct snd_soc_ops ams_delta_ops = { .startup = ams_delta_startup, .hw_params = ams_delta_hw_params, .shutdown = ams_delta_shutdown, }; ... /* Digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link ams_delta_dai = { ... .ops = &ams_delta_ops, };
/* Audio machine driver */ static struct snd_soc_card snd_soc_card_ams_delta = { .name = "AMS_DELTA", .platform = &omap_soc_platform, .dai_link = &ams_delta_dai, .num_links = 1, };
/* Audio subsystem */ static struct snd_soc_device ams_delta_snd_devdata = { .card = &snd_soc_card_ams_delta, .codec_dev = &soc_codec_dev_cx20442, }; -----------------------------------------------------
When applied on top of linux-2.6.27, omap or mainline, my patch causes system hangup on sound device first access, exactly as I have already reported it for linux-omap.git revision 90e758af52ba803cba233fabee81176d99589f09.
However, when applied on top of linux-2.6.30-rc5, I still get a working system with non-functional sound device. DMA interrupt counters stay at 0.
My conclusuions so far:
1. If the new OMAP McBSP ASoC framework provides all the functionality of the depreciated OMAP Alsa under a different API, the only reason of my driver not working I can imagine is that I have put these two lines of hardware related code in wrong places. If this is the case, could someone please point me into the right direction?
2. Maybe the original ams-delta sound driver should not in theory work as is? Maybe Mark Underwood was just lucky enough to get it working without any real hardware setup?
3. Otherwise, there must be a significant difference in (alsa) MsBSP handling code that I am not able to identify and resolve myself. I can only say that I have seen much more mcbsp_...() stuff in the old omap-alsa framework than in the current one. The differece can be significant for OMAP15XX, or OMAP5910, or even ams-delta only.
4. Base (not alsa related) McBSP framework did not change since 2.6.16 (the original patch base) up to 2.6.27 in a way that could break the original patch. If my problem was related to base McBSP handling, changes should be looked for after 2.6.27, if any.
Jarkko Nikula wrote:
It would be nice to get this working since it would be the first OMAP5910 == OMAP1510 based machine driver.
I am personally interested in this, as I have bought two E3's recently in hope I can make use of them as IP phones. But for now, I have no idea what else I could try. I have noticed that Andrew de Quincey is going to fix sound on Nokia 770, maybe he finds something related.
Cheers, Janusz
-- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, 01 Jun 2009 14:41:59 +0200 Janusz Krzysztofik jkrzyszt@tis.icnet.pl wrote:
The original patch ported to linux-omap-2.6.27, the last omap release with omap-alsa support, gives me a working sound driver on ams-delta.
Ok, good to know.
To make the original driver work stable, I had to patch the omap-alsa framework to restore the original way that lack of dma chaining problem had been solved in the original patch (see below), so maybe there is a similiar issue in the currect ASoC McBSP framework?
Is the older implementation working at commit d8376cc482b241701f7606c81ad578b90853e175 in linux-omap, i.e. last commit before their removal?
What I see at quick look from the older implementation that it is doing somewhat similar way the DMA transfer and workaround for 1510 than current ASoC except that now the DMA parameters are not reprogrammed between the restarted transfers. I don't know if 1510 requires it?
My asoc based patch is also very generic and contains no more that the same two ams_delta_latch2_write() hardware related operations, called from inside snd_soc_dai_link.ops.startup() and snd_soc_dai_link.ops.shutdown() callback functions:
One thing worth to try would be try to use exactly same McBSP registers for omap_mcbsp_config in omap_mcbsp_dai_hw_params than used before for ams delta.
Sorry, have to cut my answer now here. I'll get back tomorrow.
On Monday 01 June 2009 21:04:13 ext Jarkko Nikula wrote:
On Mon, 01 Jun 2009 14:41:59 +0200
Janusz Krzysztofik jkrzyszt@tis.icnet.pl wrote:
The original patch ported to linux-omap-2.6.27, the last omap release with omap-alsa support, gives me a working sound driver on ams-delta.
Ok, good to know.
To make the original driver work stable, I had to patch the omap-alsa framework to restore the original way that lack of dma chaining problem had been solved in the original patch (see below), so maybe there is a similiar issue in the currect ASoC McBSP framework?
Is the older implementation working at commit d8376cc482b241701f7606c81ad578b90853e175 in linux-omap, i.e. last commit before their removal?
What I see at quick look from the older implementation that it is doing somewhat similar way the DMA transfer and workaround for 1510 than current ASoC except that now the DMA parameters are not reprogrammed between the restarted transfers. I don't know if 1510 requires it?
Good question, but at least on DMA round should have been completed anyways if this is the case...
My asoc based patch is also very generic and contains no more that the same two ams_delta_latch2_write() hardware related operations, called from inside snd_soc_dai_link.ops.startup() and snd_soc_dai_link.ops.shutdown() callback functions:
One thing worth to try would be try to use exactly same McBSP registers for omap_mcbsp_config in omap_mcbsp_dai_hw_params than used before for ams delta.
Good idea, I was about to suggest to print the McBSP config in the working old alsa implementation, than print the non working from the ASoC version and see the difference, but copying the working one to ASoC (hardwire for now) should get it working.
Sorry, have to cut my answer now here. I'll get back tomorrow.
On Mon, 1 Jun 2009 21:04:13 +0300 Jarkko Nikula jhnikula@gmail.com wrote:
What I see at quick look from the older implementation that it is doing somewhat similar way the DMA transfer and workaround for 1510 than current ASoC except that now the DMA parameters are not reprogrammed between the restarted transfers. I don't know if 1510 requires it?
Hmm, I forgot one major difference. Older implementation was transferring the buffer by transferring periods by own DMA transfers while ASoC implementation is transferring the whole buffer by single transfer but letting DMA to generate interrupts at period boundaries but this should be supported by the 1510 as well.
I just tried non-chained transfer, i.e. restarting DMA after buffer is transferred in omap-pcm.c by using N810 and 2420 and it worked as I was recalling. This was simulating 1510 by adding (1 || cpu_is_omap1510) or (0 && !cpu_is_omap1510()) where 1510 was tested.
But there is no DMA stop workaround before restarting like the original ams delta patch has. Could you try to add following line in omap-pcm.c does it help? However this doesn't explain why you are not getting any interrupts.
@@ -68,6 +68,7 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data) if (prtd->period_index >= 0) { if (++prtd->period_index == runtime->periods) { prtd->period_index = 0; + omap_stop_dma(prtd->dma_ch); omap_start_dma(prtd->dma_ch); } }
- If the new OMAP McBSP ASoC framework provides all the
functionality of the depreciated OMAP Alsa under a different API, the only reason of my driver not working I can imagine is that I have put these two lines of hardware related code in wrong places. If this is the case, could someone please point me into the right direction?
I don't think there is anything in a wrong place. It would help a lot if we would know for sure is the MCLK from OMAP to codec and McBSP FS and bit clocks from the codec really working since that is the first requirement for working transfer. Luckily we know that the HW is working :-)
- Otherwise, there must be a significant difference in (alsa)
MsBSP handling code that I am not able to identify and resolve myself. I can only say that I have seen much more mcbsp_...() stuff in the old omap-alsa framework than in the current one. The differece can be significant for OMAP15XX, or OMAP5910, or even ams-delta only.
At least one difference is that omap-mcbsp.c is constructing McBSP register bits itself while older implementation was passing raw register configuration from the board files. Probably you could try to hack omap_mcbsp_dai_hw_params and pass the same register settings there to see are there some missing bit in omap-mcbsp.c.
I am personally interested in this, as I have bought two E3's recently in hope I can make use of them as IP phones. But for now, I have no idea what else I could try. I have noticed that Andrew de Quincey is going to fix sound on Nokia 770, maybe he finds something related.
It's positive that Nokia 770 will be easier thanks to OSK5912. They both have the same CPU variant (1710 == 5912) and AIC23 codec!
Hi Jarkko,
Jarkko Nikula wrote:
On Mon, 1 Jun 2009 21:04:13 +0300 Jarkko Nikula jhnikula@gmail.com wrote:
Hmm, I forgot one major difference. Older implementation was transferring the buffer by transferring periods by own DMA transfers while ASoC implementation is transferring the whole buffer by single transfer but letting DMA to generate interrupts at period boundaries but this should be supported by the 1510 as well.
I am not sure if this is of any importance, but with the old working code, playing /dev/urandom to /dev/dsp I get only 3-4 DMA interrupts per second, while doing the same on a x86_64 via82cxxx results in 40-50 device interrupts per second.
I just tried non-chained transfer, i.e. restarting DMA after buffer is transferred in omap-pcm.c by using N810 and 2420 and it worked as I was recalling. This was simulating 1510 by adding (1 || cpu_is_omap1510) or (0 && !cpu_is_omap1510()) where 1510 was tested.
But there is no DMA stop workaround before restarting like the original ams delta patch has.
The original patch had no extra omap_dma_stop(), but extra unconditional (form ams-delta point of view) omap_dma_start() inside omap_start_alsa_sound_dma(). Later on, there was an extra omap_stop_alsa_sound_dma() call introduced in audio_process_dma() as a workaround for a similiar problem found on other omap1510 machines, that cleared the flag preventing omap_start_alsa_sound_dma() from calling omap_dma_start(). I found that with the latter, the old driver happened to stop working after a while or two.
Could you try to add following line in omap-pcm.c does it help? However this doesn't explain why you are not getting any interrupts.
@@ -68,6 +68,7 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data) if (prtd->period_index >= 0) { if (++prtd->period_index == runtime->periods) { prtd->period_index = 0;
}omap_stop_dma(prtd->dma_ch); omap_start_dma(prtd->dma_ch); }
OK, I will.
the only reason of my driver not working I can imagine is that I have put these two lines of hardware related code in wrong places.
I don't think there is anything in a wrong place. It would help a lot if we would know for sure is the MCLK from OMAP to codec and McBSP FS and bit clocks from the codec really working since that is the first requirement for working transfer. Luckily we know that the HW is working :-)
And we know mcbsp settings that make it working.
I did not find any documentation on the codec itself, only on its "master" modem chip cx81801. Regarding modem<->codec interface, there were only pins with breif description specified for both chips, nothing more, as this interface was probably not intended for access from outside. From the codec side, it looks like this:
- Sleep (SLEEP); input - Master Clock (M_CLKIN); input - Serial Clock (M_SCK); output - Control (M_CNTRLSIN); input - Serial Frame Sync (M_STROBE); output - Serial Transmit Data (M_TXSIN); input - Serial Receive Data (M_RXOUT); output - Reset (POR); input
However, I can't tell which lines are switched from modem to mcbsp and which are kept connected to the modem chip all the time. Anyway, it looks like we can be sure that both bit clock and frame sync should come from codec to mcbsp. It is not clear for me if MCLK is really used by the codec, or it is possible that it gets its master clock from an other, modem related source, and if this does really matter.
At least one difference is that omap-mcbsp.c is constructing McBSP register bits itself while older implementation was passing raw register configuration from the board files. Probably you could try to hack omap_mcbsp_dai_hw_params and pass the same register settings there to see are there some missing bit in omap-mcbsp.c.
OK, I'll see if I know how to do this.
Cheers, Janusz
-- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, 02 Jun 2009 15:35:10 +0200 Janusz Krzysztofik jkrzyszt@tis.icnet.pl wrote:
I am not sure if this is of any importance, but with the old working code, playing /dev/urandom to /dev/dsp I get only 3-4 DMA interrupts per second, while doing the same on a x86_64 via82cxxx results in 40-50 device interrupts per second.
Looks like via specific since both OMAP3 Beagle and my desktop are generating about 4 audio interrupts per second.
I did not find any documentation on the codec itself, only on its "master" modem chip cx81801. Regarding modem<->codec interface, there were only pins with breif description specified for both chips, nothing more, as this interface was probably not intended for access from outside. From the codec side, it looks like this:
- Sleep (SLEEP); input
- Master Clock (M_CLKIN); input
- Serial Clock (M_SCK); output
- Control (M_CNTRLSIN); input
- Serial Frame Sync (M_STROBE); output
- Serial Transmit Data (M_TXSIN); input
- Serial Receive Data (M_RXOUT); output
- Reset (POR); input
However, I can't tell which lines are switched from modem to mcbsp and which are kept connected to the modem chip all the time. Anyway, it looks like we can be sure that both bit clock and frame sync should come from codec to mcbsp. It is not clear for me if MCLK is really used by the codec, or it is possible that it gets its master clock from an other, modem related source, and if this does really matter.
Hmm. Are there any possibility that ams_delta_latch2_write requires working MCLK for latch change? I noticed that older implementation was activating MCLK before latch and your ASoC patch does opposite. Sounds a bit far but worth to try.
Probably you could use also older implementation to find out is the MCLK required for codec by commenting out vc_mclk control.
At least one difference is that omap-mcbsp.c is constructing McBSP register bits itself while older implementation was passing raw register configuration from the board files. Probably you could try to hack omap_mcbsp_dai_hw_params and pass the same register settings there to see are there some missing bit in omap-mcbsp.c.
OK, I'll see if I know how to do this.
Just hack the same "static struct omap_mcbsp_reg_cfg mcbsp_regs = { ..." in omap-mcbsp.c and pass that structure instead of &mcbsp_data->regs to omap_mcbsp_config in omap_mcbsp_dai_hw_params.
Hi,
Tuesday 02 June 2009 19:32:14 Jarkko Nikula wrote:
It is not clear for me if MCLK is really used by the codec, or it is possible that it gets its master clock from an other, modem related source, and if this does really matter.
Hmm. Are there any possibility that ams_delta_latch2_write requires working MCLK for latch change?
Looks like it doesn't. See below.
Probably you could use also older implementation to find out is the MCLK required for codec by commenting out vc_mclk control.
Thanks! The origial driver with commented out clk_enable(vc_clk) and clk_disable(vc_clk) still works for me, so MCLK is not required! If I only knew what to do with this finding...
Just hack the same "static struct omap_mcbsp_reg_cfg mcbsp_regs = { ..." in omap-mcbsp.c and pass that structure instead of &mcbsp_data->regs to omap_mcbsp_config in omap_mcbsp_dai_hw_params.
Done. Did not help. Again, I really don't know how to make use of this finding except for looking in a different place.
I tried to disassemble one of my deltas to get to those pins, but did not yet find a way to do it without breaking its case. I'll ask at E3-hacking list.
Thanks, Janusz -- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, 3 Jun 2009 09:24:12 +0200 Janusz Krzysztofik jkrzyszt@tis.icnet.pl wrote:
Thanks! The origial driver with commented out clk_enable(vc_clk) and clk_disable(vc_clk) still works for me, so MCLK is not required! If I only knew what to do with this finding...
Optimize out one needless clock :-)
Just hack the same "static struct omap_mcbsp_reg_cfg mcbsp_regs = { ..." in omap-mcbsp.c and pass that structure instead of &mcbsp_data->regs to omap_mcbsp_config in omap_mcbsp_dai_hw_params.
Done. Did not help. Again, I really don't know how to make use of this finding except for looking in a different place.
Ok, so looks that McBSP settings have nothing to do.
I got one another idea, quite far also, but omap_set_dma_params helper function calls omap_set_dma_xxx_params functions in different order than older sound/arm/omap/omap-alsa-dma.c: audio_set_dma_params_play.
While I don't believe that call order has something to do on 1510 versus other omaps, it's easy to try by changing call order in arch/arm/plat-omap/dma.c: omap_set_dma_params.
Of course you could try to also copy transfer setup from audio_set_dma_params_play into omap_pcm_prepare. Use prtd->dma_ch as channel, runtime->dma_addr as a dma_ptr and snd_pcm_lib_period_bytes(substream) as a dma_size. That should make the DMA setup same than older implementation.
Hopefully these speculations would help you to find out at least one DMA interrupt.
Hi Jarkko,
Thank you for still trying to support my efforts.
Friday 05 June 2009 15:55:31 Jarkko Nikula napisał(a):
Optimize out one needless clock :-)
:-)
Ok, so looks that McBSP settings have nothing to do.
That was what I was suggesting before as well, but now I'm back not so sure.
While I don't believe that call order has something to do on 1510 versus other omaps, it's easy to try by changing call order in arch/arm/plat-omap/dma.c: omap_set_dma_params.
Of course you could try to also copy transfer setup from audio_set_dma_params_play into omap_pcm_prepare... That should make the DMA setup same than older implementation.
Hopefully these speculations would help you to find out at least one DMA interrupt.
Tried this all, and guess what? Still no signle dma interrupt :(.
I disassembled my device and got with osscilloscope probe inside. Unfortunatelly, it was not possible to check what was going on on omap pins, as those were hidden. However, I was able to look at codec and modem pins.
The codec master clock input has ~2MHz square wave applied. The same waveform can be found on the modem master clock output, so I think we can be sure that the codec gets its master clock from the modem. I am not able to verify If the same signal is applied on mcbsp1 master clock input.
There is ~330kHz square wave on the codec bit clock output. I was not able to verify if this signal appears on modem or mcbsp1 pins, as it should.
On the codec frame sync output, I can see ~10kHz symmetric square wave (filled by 50%), the same on modem frame sync input, mcbsp1 status unknown. This shape suggests I2S protocol, not DSP_B as we deduced from the original driver code.
Reviewing the code of different asoc omap drivers and mcbsp documentation again and again, several questions comes on mind, like:
1. What is the default setting for mcbsp master clock source? Assuming that default register bit values are 0, OMAP_MCBSP_SYSCLK_CLKS_EXT would be default for omap1, and there would be no default for others. Sources other than OMAP_MCBSP_SYSCLK_CLKS_EXT or OMAP_MCBSP_SYSCLK_CLKS_FCLK require setting of CLKSM and/or SCLKME to 1, and both OMAP_MCBSP_SYSCLK_CLKS_EXT and OMAP_MCBSP_SYSCLK_CLKS_FCLK require additional omap_ctrl_writel() calls on omap2 and higher. Am I missing anything?
2. Why omap asoc drivers, except for omap3pandora, do not call snd_soc_dai_set_sysclk(cpu_dai, ...)? Does it mean that osk9512 uses default OMAP_MCBSP_SYSCLK_CLKS_EXT? What does it mean for others without default?
and more.
Anyway, we still have at least two potential reasons for my driver not working: wrong mcbsp clocks setup or broken mcbsp dma handling. My last idea was to create a generic test driver that would not use any external clocks, ie configured with OMAP_MCBSP_SYSCLK_CLK and SND_SOC_DAIFMT_CBS_CFS, right? That way, it should just work without any hardware support except for mcbsp and maybe we could then definitelly verify if current mcbsp and dma code works on omap1510 or not. Trying to select a template driver to base the test driver on, I felt into these troubles with more and more questions coming on mind. If you think my idea is worth of trying, could you please look at this and give me some hints?
Cheers, Janusz -- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sat, Jun 06, 2009 at 12:28:00AM +0200, Janusz Krzysztofik wrote:
On the codec frame sync output, I can see ~10kHz symmetric square wave (filled by 50%), the same on modem frame sync input, mcbsp1 status unknown. This shape suggests I2S protocol, not DSP_B as we deduced from the original driver code.
Not that this seems like an unreasonable conclusion but it's worth pointing out that the DSP modes only require the leading edge of the frame clock and that the falling edge can occur at any point before the next rising edge is due.
Anyway, we still have at least two potential reasons for my driver not working: wrong mcbsp clocks setup or broken mcbsp dma handling. My last idea was to create a generic test driver that would not use any external clocks, ie configured with OMAP_MCBSP_SYSCLK_CLK and SND_SOC_DAIFMT_CBS_CFS, right? That way, it should just work without any hardware support except for mcbsp and maybe we could then definitelly verify if current mcbsp and dma code works on omap1510 or not. Trying to select a template driver to base the test driver on, I felt into these troubles with more and more questions coming on mind. If you think my idea is worth of trying, could you please look at this and give me some hints?
That approach is one I use all the time in driver development - isolate the device as much as possible and confirm that it can at least interoperate with itself.
Hi Mark,
Saturday 06 June 2009 00:45:34 Mark Brown napisał(a):
On Sat, Jun 06, 2009 at 12:28:00AM +0200, Janusz Krzysztofik wrote:
On the codec frame sync output, I can see ~10kHz symmetric square wave (filled by 50%), the same on modem frame sync input, mcbsp1 status unknown. This shape suggests I2S protocol, not DSP_B as we deduced from the original driver code.
Not that this seems like an unreasonable conclusion but it's worth pointing out that the DSP modes only require the leading edge of the frame clock and that the falling edge can occur at any point before the next rising edge is due.
Right, thanks.
I'm not sure how that could happen, but I was wrong with some of those figures. After looking at the scope several more times I can only confirm that master clock really runs at 2MHz (0,5µs period). Frame sync is rather closer to 8kHz (~125µs period) than previously estimated 10kHz, with the same symmetric (50% fill) shape as before. But bit clock is very different from what I have seen before. It runs at 2MHz in 9µs long packets (18 periods), those are repeated every half period of frame sync (~62µs / 16kHz), ie every frame sync edge, both rising and falling. There is also a signal present on codec data output: 4µs long packets (8 bits each?) every ~62µs (16 kHz).
Is it possible that the codec speeks I2S, with 8-bit word, 1 word per frame, 2 channels at 8kHz each? Or 1 channel at 16 kHz? From what I can read in modem documentation, this should rather be one 8-bit channel at 8kHz. Anyway, can the transmission format I have seen ont the oscilloscope be matched against any format that mcbsp can be set with current code?
I'm still far from understanding mcbsp, but I wonder what happens if the bit clock stops ater 18th bit while maybe mcbsp expects more. Perhaps this is the cause of dma interrupts not being generated?
... My last idea was to create a generic test driver that would not use any external clocks, ie configured with OMAP_MCBSP_SYSCLK_CLK and SND_SOC_DAIFMT_CBS_CFS, right? That way, it should just work without any hardware support except for mcbsp and maybe we could then definitelly verify if current mcbsp and dma code works on omap1510 or not. Trying to select a template driver to base the test driver on, I felt into these troubles with more and more questions coming on mind...
That approach is one I use all the time in driver development - isolate the device as much as possible and confirm that it can at least interoperate with itself.
Thanks, I'll follow that way as soon as I get a hint from mcbsp experts.
Cheers, Janusz
On Sat, Jun 06, 2009 at 07:42:12PM +0200, Janusz Krzysztofik wrote:
Is it possible that the codec speeks I2S, with 8-bit word, 1 word per frame, 2 channels at 8kHz each? Or 1 channel at 16 kHz? From what I can read in modem documentation, this should rather be one 8-bit channel at 8kHz. Anyway, can the transmission format I have seen ont the oscilloscope be matched against any format that mcbsp can be set with current code?
The former is more likely. Since I2S is a stereo protocol I'd not be surprised to see a mono device choosing to transmit its data in both left and right channels for maximum interoperability with devices that do stereo.
I'm still far from understanding mcbsp, but I wonder what happens if the bit clock stops ater 18th bit while maybe mcbsp expects more. Perhaps this is the cause of dma interrupts not being generated?
That's certainly the sort of behaviour I'd expect to see from a programmable port like the McBSP - many of them also need to know exactly how many bit clocks there will be in order to implement I2S due to not paying attention to one of the edges of frame sync. In general things will cope if the bit clock stops providing there have been as many edges as they're expecting to get a full sample clocked in.
Hello Janusz,
On Saturday 06 June 2009 20:42:12 ext Janusz Krzysztofik wrote:
I'm not sure how that could happen, but I was wrong with some of those figures. After looking at the scope several more times I can only confirm that master clock really runs at 2MHz (0,5µs period). Frame sync is rather closer to 8kHz (~125µs period) than previously estimated 10kHz, with the same symmetric (50% fill) shape as before. But bit clock is very different from what I have seen before. It runs at 2MHz in 9µs long packets (18 periods), those are repeated every half period of frame sync (~62µs / 16kHz), ie every frame sync edge, both rising and falling. There is also a signal present on codec data output: 4µs long packets (8 bits each?) every ~62µs (16 kHz).
I'm kind of bad at visualizing things, is it possible to put somewhere the screenshoot of the scope showing at least one sample?
Is it possible that the codec speeks I2S, with 8-bit word, 1 word per frame, 2 channels at 8kHz each? Or 1 channel at 16 kHz? From what I can read in modem documentation, this should rather be one 8-bit channel at 8kHz. Anyway, can the transmission format I have seen ont the oscilloscope be matched against any format that mcbsp can be set with current code?
I have been looking for clues around the net, and it seams that the codec in question has stereo 16 bit format.
I'm still far from understanding mcbsp, but I wonder what happens if the bit clock stops ater 18th bit while maybe mcbsp expects more. Perhaps this is the cause of dma interrupts not being generated?
Without actual OMAP1510 HW it is really hard to tell what can be the problem. What I would do, if I had a HW: 1) See if the DMA actually was running and it is 'just' about the missing interrupt: --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -193,11 +193,15 @@ static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: prtd->period_index = 0; omap_start_dma(prtd->dma_ch); + printk("omap_pcm_trigger START: DMA pointer at 0x%08x\n", + (unsigned)omap_get_dma_src_pos(prtd->dma_ch)); break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + printk("omap_pcm_trigger STOP: DMA pointer at 0x%08x\n", + (unsigned)omap_get_dma_src_pos(prtd->dma_ch)); prtd->period_index = -1; omap_stop_dma(prtd->dma_ch); break;
Than start a playback, and stop it with CTRL+C, see if the two pointers are different...
2) I would I think try to port the 2.6.28 pure ALSA version to the head of l- o, with minimal (only the needed) changes and see if it is still working. I know, this is a long shot, but at least we can be sure, that the problem is in the ASoC McBSP/DMA integration or it is something else.
Meanwhile I'll try to locate one OMAP1510 based board to try to help with this issue.
Peter Ujfalusi wrote:
I'm kind of bad at visualizing things, is it possible to put somewhere the screenshoot of the scope showing at least one sample?
Good idea. I'll take some screenshots for future reference and let you know when available.
I have been looking for clues around the net, and it seams that the codec in question has stereo 16 bit format.
From the very minimal mcbsp setup I get best audio experience with (using original omap-alsa based driver - see below), it looks like the codec speeks DSP (single phase), 16-bit mono @8kHz on output, but 8-bit stereo @8kHz on input. Capturing one channel only (the first one) I can't hear myself speaking, so audio from the microphone must be sent over the second input channel.
+static struct omap_mcbsp_reg_cfg mcbsp_regs = { + .spcr2 = FREE | XINTM(3) | XRST, + .spcr1 = RINTM(3) | RRST, + .rcr1 = RFRLEN1(2 - 1) | RWDLEN1(OMAP_MCBSP_WORD_8), + .xcr1 = XFRLEN1(1 - 1) | XWDLEN1(OMAP_MCBSP_WORD_16), +};
+static snd_pcm_hardware_t vc_snd_omap_alsa_playback = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), + .formats = (SNDRV_PCM_FMTBIT_S16_LE), + .rates = (SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_KNOT), + .rate_min = 8000, + .rate_max = 8000, + .channels_min = 1, + .channels_max = 1, + .buffer_bytes_max = 128 * 1024, + .period_bytes_min = 32, + .period_bytes_max = 8 * 1024, + .periods_min = 16, + .periods_max = 255, + .fifo_size = 0, +}; + +static snd_pcm_hardware_t vc_snd_omap_alsa_capture = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), + .formats = (SNDRV_PCM_FMTBIT_U8), + .rates = (SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_KNOT), + .rate_min = 8000, + .rate_max = 8000, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = 128 * 1024, + .period_bytes_min = 32, + .period_bytes_max = 8 * 1024, + .periods_min = 16, + .periods_max = 255, + .fifo_size = 0, +};
For other combinations of single/dual phase, sample size, mono/stereo, sound I get is much more distorted. Playing with polarisation and delays for getting still better experience remains on my todo list.
BTW, I can't see any way of specifying a similiar mcbsp setup in new omap asoc framework.
--------------
--- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -193,11 +193,15 @@ static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: prtd->period_index = 0; omap_start_dma(prtd->dma_ch);
printk("omap_pcm_trigger START: DMA pointer at 0x%08x\n",
(unsigned)omap_get_dma_src_pos(prtd->dma_ch)); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
printk("omap_pcm_trigger STOP: DMA pointer at 0x%08x\n",
(unsigned)omap_get_dma_src_pos(prtd->dma_ch)); prtd->period_index = -1; omap_stop_dma(prtd->dma_ch); break;
Than start a playback, and stop it with CTRL+C, see if the two pointers are different...
Both playback and capture start with their own but always the same value (something like 0x1101a0d0 for playback, 0xe101a0d0 for capture), and always stop with this value unchanged.
- I would I think try to port the 2.6.28 pure ALSA version to the head of l-
o, with minimal (only the needed) changes and see if it is still working.
Trying to use the new driver on the last l-o revision supporting both omap-alsa and omap asoc, I got a broken system that hanged up completely at sound device first access. The same for earlier and later l-o revisions I have ever tried, unlike mainline that at least does not hang. From all that I would conclude that porting the old driver could be just waste of time, as the problem is probably omap asoc related, not just omap, probably existed from the start of omap asoc life, and could be solved on any l-o or mainline revision, including those eariler l-o that supported both frameworks. But I can be wrong, of course.
Cheers, Janusz
On Tuesday 09 June 2009 18:17:42 ext Janusz Krzysztofik wrote:
Peter Ujfalusi wrote:
I'm kind of bad at visualizing things, is it possible to put somewhere the screenshoot of the scope showing at least one sample?
Good idea. I'll take some screenshots for future reference and let you know when available.
I have been looking for clues around the net, and it seams that the codec in question has stereo 16 bit format.
From the very minimal mcbsp setup I get best audio experience with (using original omap-alsa based driver - see below), it looks like the codec speeks DSP (single phase), 16-bit mono @8kHz on output, but 8-bit stereo @8kHz on input. Capturing one channel only (the first one) I can't hear myself speaking, so audio from the microphone must be sent over the second input channel.
+static struct omap_mcbsp_reg_cfg mcbsp_regs = {
.spcr2 = FREE | XINTM(3) | XRST,
.spcr1 = RINTM(3) | RRST,
.rcr1 = RFRLEN1(2 - 1) | RWDLEN1(OMAP_MCBSP_WORD_8),
.xcr1 = XFRLEN1(1 - 1) | XWDLEN1(OMAP_MCBSP_WORD_16),
+};
+static snd_pcm_hardware_t vc_snd_omap_alsa_playback = {
.info = (SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
.formats = (SNDRV_PCM_FMTBIT_S16_LE),
.rates = (SNDRV_PCM_RATE_8000 |
SNDRV_PCM_RATE_KNOT),
.rate_min = 8000,
.rate_max = 8000,
.channels_min = 1,
.channels_max = 1,
.buffer_bytes_max = 128 * 1024,
.period_bytes_min = 32,
.period_bytes_max = 8 * 1024,
.periods_min = 16,
.periods_max = 255,
.fifo_size = 0,
+};
+static snd_pcm_hardware_t vc_snd_omap_alsa_capture = {
.info = (SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
.formats = (SNDRV_PCM_FMTBIT_U8),
.rates = (SNDRV_PCM_RATE_8000 |
SNDRV_PCM_RATE_KNOT),
.rate_min = 8000,
.rate_max = 8000,
.channels_min = 2,
.channels_max = 2,
.buffer_bytes_max = 128 * 1024,
.period_bytes_min = 32,
.period_bytes_max = 8 * 1024,
.periods_min = 16,
.periods_max = 255,
.fifo_size = 0,
+};
For other combinations of single/dual phase, sample size, mono/stereo, sound I get is much more distorted. Playing with polarisation and delays for getting still better experience remains on my todo list.
BTW, I can't see any way of specifying a similiar mcbsp setup in new omap asoc framework.
Yeah, 8 bit is not supported - in fact only 16 bit is supported - with ASoC on OMAP. But you should be able to use the playback with the current ASoC.
--- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -193,11 +193,15 @@ static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: prtd->period_index = 0; omap_start_dma(prtd->dma_ch);
printk("omap_pcm_trigger START: DMA pointer at 0x%08x\n",
(unsigned)omap_get_dma_src_pos(prtd->dma_ch)); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
printk("omap_pcm_trigger STOP: DMA pointer at 0x%08x\n",
(unsigned)omap_get_dma_src_pos(prtd->dma_ch)); prtd->period_index = -1; omap_stop_dma(prtd->dma_ch); break;
Than start a playback, and stop it with CTRL+C, see if the two pointers are different...
Both playback and capture start with their own but always the same value (something like 0x1101a0d0 for playback, 0xe101a0d0 for capture), and always stop with this value unchanged.
Hmm, this means that the DMA was not running at all (since it has not been progressed). So you might have the missing DMA interrupt problem, but first we should get the DMA to actually run. Looking at the dma code for clues... Even bigger Hmmm... For OMAP1 the DMA synchronization is not configured. I just wonder how this supposed to be working on OMAP1 platforms. Anyway, can you try the following patch (and please keep the previous printk in the omap-pcm.c):
--- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -266,6 +266,8 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, ccr &= ~(1 << 5); if (sync_mode == OMAP_DMA_SYNC_FRAME) ccr |= 1 << 5; + if (dma_trigger) + ccr |= dma_trigger & 0x1f; dma_write(ccr, CCR(lch));
ccr = dma_read(CCR2(lch));
in the if (cpu_class_is_omap1()) { path...
The interesting thing is the following: the old ALSA implementation configured the DMA in this way: omap_set_dma_transfer_params(channel, dt, cen, cfn, 0x00, 0, 0); Meaning, no DMA synchronization, which is fair, since the DMA code for OMAP1 does not configured it anyway.
- I would I think try to port the 2.6.28 pure ALSA version to the head
of l- o, with minimal (only the needed) changes and see if it is still working.
Trying to use the new driver on the last l-o revision supporting both omap-alsa and omap asoc, I got a broken system that hanged up completely at sound device first access. The same for earlier and later l-o revisions I have ever tried, unlike mainline that at least does not hang. From all that I would conclude that porting the old driver could be just waste of time, as the problem is probably omap asoc related, not just omap, probably existed from the start of omap asoc life, and could be solved on any l-o or mainline revision, including those eariler l-o that supported both frameworks. But I can be wrong, of course.
There seams to be no major difference between the 2.6.28 and the latest arch/arm/plat-omap/dma.c and mcbsp.c I would expected that by just copying (I know that there are other things involved) the old ALSA arm directory to the latest kernel and compiling it should be working... It seams I was wrong.
Hi Peter,
Wednesday 10 June 2009 10:12:32 Peter Ujfalusi napisał(a):
On Tuesday 09 June 2009 18:17:42 ext Janusz Krzysztofik wrote:
+static struct omap_mcbsp_reg_cfg mcbsp_regs = {
.spcr2 = FREE | XINTM(3) | XRST,
.spcr1 = RINTM(3) | RRST,
.rcr1 = RFRLEN1(2 - 1) | RWDLEN1(OMAP_MCBSP_WORD_8),
.xcr1 = XFRLEN1(1 - 1) | XWDLEN1(OMAP_MCBSP_WORD_16),
+};
BTW, I can't see any way of specifying a similiar mcbsp setup in new omap asoc framework.
Yeah, 8 bit is not supported - in fact only 16 bit is supported - with ASoC on OMAP.
Not only this. AFAICS, there is no way of specifying single phase stereo (with XPHASE/RPHASE unset), 2 words per frame (XFRLEN1/RFRLEN1(2 - 1)). Isn't this required for correct DSP_A/DSP_B support?
But you should be able to use the playback with the current ASoC.
Definitelly yes. I am aware that the above limitations have nothing to do with the main problem, as with current mcbsp code I should always be able to get some kind of noise at least using one of supported formats, as far as clocking is set up correctly.
--- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -266,6 +266,8 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, ccr &= ~(1 << 5); if (sync_mode == OMAP_DMA_SYNC_FRAME) ccr |= 1 << 5;
if (dma_trigger)
ccr |= dma_trigger & 0x1f; dma_write(ccr, CCR(lch)); ccr = dma_read(CCR2(lch));
Applied, sorry, did not help (with capture, unlike playback, set up for internal clocking for as much device isolation as possible).
# aplay -D hw:0,0 -f S16_LE /dev/urandom Playing raw data '/dev/urandom' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono omap_pcm_trigger START: DMA pointer at 0x11d4a0d0 omap_pcm_trigger STOP: DMA pointer at 0x11d4a0d0 error # arecord -D hw:0,0 -f S16_LE -t raw /dev/null Recording raw data '/dev/null' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono omap_pcm_trigger START: DMA pointer at 0xe101a0d0 arecord: pcm_read:1529: read error: Input/output error omap_pcm_trigger STOP: DMA pointer at 0xe101a0d0 # cat /dev/urandom >/dev/dsp omap_pcm_trigger START: DMA pointer at 0x11d4a0d0 cat: write error: Input/output error omap_pcm_trigger STOP: DMA pointer at 0x11d4a0d0 # cat /dev/dsp >/dev/null omap_pcm_trigger START: DMA pointer at 0xe101a0d0 cat: read error: Input/output eromap_pcm_trigger STOP: DMA pointer at 0xe101a0d0 ror #
BTW, I have found that, when invoked with those "-D hw:0,0 -f SE16_LE" options, aplay/arecord behave correctly, exactly as Mark has pointed out once at the beginning of this huge thread, stopping themselves after 10 seconds with an error message, without need for ^C.
I would expected that by just copying (I know that there are other things involved) the old ALSA arm directory to the latest kernel and compiling it should be working... It seams I was wrong.
Anyway, if you find porting one or another framework, back or forward, helpfull in any way, just let me know, I can try.
Thanks, Janusz -- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wednesday 10 June 2009 13:27:38 ext Janusz Krzysztofik wrote:
Not only this. AFAICS, there is no way of specifying single phase stereo (with XPHASE/RPHASE unset), 2 words per frame (XFRLEN1/RFRLEN1(2 - 1)). Isn't this required for correct DSP_A/DSP_B support?
Sure it is possible: format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; wpf = channels = params_channels(params); switch (channels) { case 2: if (format == SND_SOC_DAIFMT_I2S) { /* Use dual-phase frames */ regs->rcr2 |= RPHASE; regs->xcr2 |= XPHASE; /* Set 1 word per (McBSP) frame for phase1 and phase2 */ wpf--; regs->rcr2 |= RFRLEN2(wpf - 1); regs->xcr2 |= XFRLEN2(wpf - 1); } case 1: case 4: /* Set word per (McBSP) frame for phase1 */ regs->rcr1 |= RFRLEN1(wpf - 1); regs->xcr1 |= XFRLEN1(wpf - 1); break; default: /* Unsupported number of channels */ return -EINVAL; }
wpf = channels == 2, format is not I2S --> RFRLEN1(wpf - 1), XFRLEN1(wpf - 1), RFRLEN1(2 - 1), XFRLEN1(2 - 1)
But you should be able to use the playback with the current ASoC.
Definitelly yes. I am aware that the above limitations have nothing to do with the main problem, as with current mcbsp code I should always be able to get some kind of noise at least using one of supported formats, as far as clocking is set up correctly.
--- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -266,6 +266,8 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, ccr &= ~(1 << 5); if (sync_mode == OMAP_DMA_SYNC_FRAME) ccr |= 1 << 5;
if (dma_trigger)
ccr |= dma_trigger & 0x1f; dma_write(ccr, CCR(lch)); ccr = dma_read(CCR2(lch));
Applied, sorry, did not help (with capture, unlike playback, set up for internal clocking for as much device isolation as possible).
I would have guessed this, since even when the DMA was not HW synced, it did not sent a single bit to the McBSP DXR1 register...
Just out of curiosity, can you try this one as well:
--- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -191,6 +191,7 @@ static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (!mcbsp_data->active++) omap_mcbsp_start(mcbsp_data->bus_id); + omap_mcbsp_pollwrite(mcbsp_data->bus_id, 0xdb55); break;
basically write 0xdb55 to the DXR1 register (0xdb55 is 1101101101010101) With this, if McBSP is operating correctly you should be seeing this pattern going to the codec. If it does, than we have some problems with the McBSP/DMA cooperation, if this pattern is not seen on the bus, than the McBSP is not shifting data out for some reason.
I would expected that by just copying (I know that there are other things involved) the old ALSA arm directory to the latest kernel and compiling it should be working... It seams I was wrong.
Anyway, if you find porting one or another framework, back or forward, helpfull in any way, just let me know, I can try.
I'm not sure if it could prove anything at the end. There are - I think - other moving parts, which can break things.
Thanks, Janusz
Peter Ujfalusi wrote:
On Wednesday 10 June 2009 13:27:38 ext Janusz Krzysztofik wrote:
Not only this. AFAICS, there is no way of specifying single phase stereo (with XPHASE/RPHASE unset), 2 words per frame (XFRLEN1/RFRLEN1(2 - 1)). Isn't this required for correct DSP_A/DSP_B support?
Sure it is possible: format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; wpf = channels = params_channels(params); switch (channels) { case 2: if (format == SND_SOC_DAIFMT_I2S) { /* Use dual-phase frames */ regs->rcr2 |= RPHASE; regs->xcr2 |= XPHASE; /* Set 1 word per (McBSP) frame for phase1 and phase2 */ wpf--; regs->rcr2 |= RFRLEN2(wpf - 1); regs->xcr2 |= XFRLEN2(wpf - 1); } case 1: case 4: /* Set word per (McBSP) frame for phase1 */ regs->rcr1 |= RFRLEN1(wpf - 1); regs->xcr1 |= XFRLEN1(wpf - 1); break; default: /* Unsupported number of channels */ return -EINVAL; }
wpf = channels == 2, format is not I2S --> RFRLEN1(wpf - 1), XFRLEN1(wpf - 1), RFRLEN1(2 - 1), XFRLEN1(2 - 1)
OK, I see I have to update my base before commenting the code ;).
Thanks, Janusz -- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Wednesday 10 June 2009 12:53:42 Peter Ujfalusi napisał(a):
On Wednesday 10 June 2009 13:27:38 ext Janusz Krzysztofik wrote: Just out of curiosity, can you try this one as well:
--- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -191,6 +191,7 @@ static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (!mcbsp_data->active++) omap_mcbsp_start(mcbsp_data->bus_id);
omap_mcbsp_pollwrite(mcbsp_data->bus_id, 0xdb55); break;
basically write 0xdb55 to the DXR1 register (0xdb55 is 1101101101010101) With this, if McBSP is operating correctly you should be seeing this pattern going to the codec.
Peter,
I am not sure how did you expect me to see this pattern. On a scope screen? Unforunatelly I had to return the scope this morning.
I have further modified the code like this:
@@ -25,6 +25,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/device.h> +#include <linux/random.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -186,7 +186,7 @@ static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); - int err = 0; + int i, err = 0;
switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -191,6 +191,8 @@ static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (!mcbsp_data->active++) omap_mcbsp_start(mcbsp_data->bus_id); + for (i = 8000; i > 0; i--) + omap_mcbsp_pollwrite(mcbsp_data->bus_id, (u16)random32 ()); break;
case SNDRV_PCM_TRIGGER_STOP:
in hope I should be able to hear a noise for one second, shouldn't I.
If it does, than we have some problems with the McBSP/DMA cooperation, if this pattern is not seen on the bus, than the McBSP is not shifting data out for some reason.
Now aplay returns 1 second later than before, so I conclude the loop is processed correctly. However, I am not able to hear a single ripple nor see any error messages from omap_mcbsp_pollwrite() :(, so it looks like the latter is more probable.
Janusz -- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Janusz Krzysztofik wrote:
Peter Ujfalusi wrote:
I'm kind of bad at visualizing things, is it possible to put somewhere the screenshoot of the scope showing at least one sample?
Good idea. I'll take some screenshots for future reference and let you know when available.
Hi,
Some screenshots are available at http://www.icnet.pl/download/cx20442/
Cheers, Janusz
-- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sat, 6 Jun 2009 00:28:00 +0200 Janusz Krzysztofik jkrzyszt@tis.icnet.pl wrote:
Reviewing the code of different asoc omap drivers and mcbsp documentation again and again, several questions comes on mind, like:
- What is the default setting for mcbsp master clock source?
Assuming that default register bit values are 0, OMAP_MCBSP_SYSCLK_CLKS_EXT would be default for omap1, and there would be no default for others. Sources other than OMAP_MCBSP_SYSCLK_CLKS_EXT or OMAP_MCBSP_SYSCLK_CLKS_FCLK require setting of CLKSM and/or SCLKME to 1, and both OMAP_MCBSP_SYSCLK_CLKS_EXT and OMAP_MCBSP_SYSCLK_CLKS_FCLK require additional omap_ctrl_writel() calls on omap2 and higher. Am I missing anything?
Actually there is no master in such but transfers are operated from internal bit-clock and frame sync signals which can be delivered either from outside (this is the typical McBSP slave configuration) or from internal sample rate generator (SRG) which can use multiple clock sources.
CLKXM and CLKRM selects the SRG for transfer bit-clock source and FSXM and FSRM selects the SRG for frame sync source respectively.
Now if above bits are set and McBSP is used in master configuration, then CLKSM and SCLKME are used to select the SRG input clock. CLKS is one of those options and OMAP2 and later can use internal FCLK or external CLKS pin as a CLKS source.
These are best explained in figures 6 and 7 in OMAP5912 McBSP documentation [1]. It applies to later omaps and IRCC it applies to 1510 as well.
- Why omap asoc drivers, except for omap3pandora, do not call
snd_soc_dai_set_sysclk(cpu_dai, ...)? Does it mean that osk9512 uses default OMAP_MCBSP_SYSCLK_CLKS_EXT? What does it mean for others without default?
It is used to select SRG input clock when McBSP is master, i.e. when DAI is configured with SND_SOC_DAIFMT_CBS_CFS so it's null op for others since they don't use SRG.
Anyway, we still have at least two potential reasons for my driver not working: wrong mcbsp clocks setup or broken mcbsp dma handling. My last idea was to create a generic test driver that would not use any external clocks, ie configured with OMAP_MCBSP_SYSCLK_CLK and SND_SOC_DAIFMT_CBS_CFS, right? That way, it should just work without any hardware support except for mcbsp and maybe we could then definitelly verify if current mcbsp and dma code works on omap1510 or not. Trying to select a template driver to base the test driver on, I felt into these troubles with more and more questions coming on mind. If you think my idea is worth of trying, could you please look at this and give me some hints?
This could be a bit risky and can damage your HW since both OMAP and codec are then driving the bit-clock and FS signals but you could try to configure McBSP as a master and use the internal clock source as its input.
Basically it goes with current driver by passing SND_SOC_DAIFMT_CBS_CFS to snd_soc_dai_set_fmt(cpu_dai, ...) and by setting SRG source clock and divider:
snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLK, ...); snd_soc_dai_set_clkdiv(cpu_dai, OMAP_MCBSP_CLKGDV, divider);
I think internal clock source is the same than CPU clock on 1510 but this is and exact divider value are not so important here since we only want to verify is the DMA operating.
If you want to play safe you could try to find out how to mux those bit-clock and FS pins into GPIO inputs (if this is possible) so then it should not matter if also McBSP is the DAI master.
So remember, this can be dangerous to your HW :-)
Jarkko Nikula wrote:
On Sat, 6 Jun 2009 00:28:00 +0200 Janusz Krzysztofik jkrzyszt@tis.icnet.pl wrote:
My last idea was to create a generic test driver that would not use any external clocks, ie configured with OMAP_MCBSP_SYSCLK_CLK and SND_SOC_DAIFMT_CBS_CFS, right? That way, it should just work without any hardware support except for mcbsp and maybe we could then definitelly verify if current mcbsp and dma code works on omap1510 or not.
This could be a bit risky and can damage your HW since both OMAP and codec are then driving the bit-clock and FS signals but you could try to configure McBSP as a master and use the internal clock source as its input.
I found that in OMAP5910, CLKR and FSR signals are not connected to any pins, so I can safely set them as output. To make use of this feature, I have modified sound/soc/omap/omap-mcbsp.c slightly:
diff -Npru linux-2.6.29/sound/soc/omap/omap-msbsp.c.orig linux-2.6.29/sound/soc/omap/omap-mcbsp.c --- linux-2.6.29/sound/soc/omap/omap-mcbsp.c.orig 2009-06-09 02:16:32.000000000 +0200 +++ linux-2.6.29/sound/soc/omap/omap-mcbsp.c 2009-06-09 02:25:50.000000000 +0200 @@ -341,8 +341,8 @@ static int omap_mcbsp_dai_set_dai_fmt(st switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: /* McBSP master. Set FS and bit clocks as outputs */ - regs->pcr0 |= FSXM | FSRM | - CLKXM | CLKRM; + regs->pcr0 |= FSRM | + CLKRM; /* Sample rate generator drives the FS */ regs->srgr2 |= FSGM; break;
Basically it goes with current driver by passing SND_SOC_DAIFMT_CBS_CFS to snd_soc_dai_set_fmt(cpu_dai, ...) and by setting SRG source clock and divider:
snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLK, ...); snd_soc_dai_set_clkdiv(cpu_dai, OMAP_MCBSP_CLKGDV, divider);
So I restored all that 12MHz mclk stuff that I had already removed as redundant, then set up the following in oder to get internally generated ~256kHz CLKR and ~8kHz FSR:
+ /* Set cpu DAI configuration */ + err = snd_soc_dai_set_fmt(cpu_dai, + SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_IB_IF | + SND_SOC_DAIFMT_CBS_CFS); + if (err < 0) { + printk(KERN_ERR "can't set cpu DAI configuration\n"); + return err; + } + + /* Set cpu DAI master clock source */ + err = + snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLK, + 0, SND_SOC_CLOCK_IN); + + if (err < 0) { + printk(KERN_ERR "can't set cpu DAI clock source\n"); + return err; + } + + /* Set cpu DAI master clock divisor */ + err = + snd_soc_dai_set_clkdiv(cpu_dai, OMAP_MCBSP_CLKGDV, 47); + + if (err < 0) { + printk(KERN_ERR "can't set cpu DAI clock divisor\n"); + return err; + }
Tried with both arecord and </dev/dsp, it looks like the problem still persists, even with mcbsp internally generated clocking. I have also tested a similiar mcbsp configuration with old driver for reference - it works.
Importand or not, I have to fine down my provious reports on what works and what does not:
- original patch applied with other ams-delta related patches on linux-omap-2.6.16, as it was designed for: - playback: works, with both aplay and >/dev/dsp, - capture: works with </dev/dsp, gives null output with arecord
- original patch ported to the last l-o commit supporting omap-alsa: - playback: works as before, - capture: both </dev/dsp and arecord give null output, but DMA interrupts still work.
- new driver on l-o: total hangup
- new driver on mainline 2.6.30-rc5: no DMA interrupts.
Thanks, Janusz -- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Janusz Krzysztofik napisał(a):
Important or not, I have to fine down my provious reports on what works and what does not:
original patch applied with other ams-delta related patches on linux-omap-2.6.16, as it was designed for:
- playback: works, with both aplay and >/dev/dsp,
- capture: works with </dev/dsp, gives null output with arecord
original patch ported to the last l-o commit supporting omap-alsa:
- playback: works as before,
- capture: both </dev/dsp and arecord give null output, but DMA interrupts still work.
Not that I would see it as a real progress, but to clarify things: I have managed to solve this particular problem with capture by patching sound/arm/omap/omap-alsa.c (call omap_get_dma_dst_pos() instead of omap_get_dma_src_pos() from audio_get_dma_pos() in case of (stream_id == SNDRV_PCM_STREAM_CAPTURE)). The original code stopped working after changes introduced to omap_get_dma_src_pos() with this patch: http://marc.info/?l=linux-omap&m=121280267705523.
Unfortunatelly ;), sound/soc/omap/omap-pcm.c does it correctly without patching.
Janusz -- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, 15 Jun 2009 15:22:34 +0200 Janusz Krzysztofik jkrzyszt@tis.icnet.pl wrote:
- original patch ported to the last l-o commit supporting omap-alsa:
- playback: works as before,
- capture: both </dev/dsp and arecord give null output, but DMA interrupts still work.
Not that I would see it as a real progress, but to clarify things: I have managed to solve this particular problem with capture by patching sound/arm/omap/omap-alsa.c (call omap_get_dma_dst_pos() instead of omap_get_dma_src_pos() from audio_get_dma_pos() in case of (stream_id == SNDRV_PCM_STREAM_CAPTURE)). The original code stopped working after changes introduced to omap_get_dma_src_pos() with this patch: http://marc.info/?l=linux-omap&m=121280267705523.
Nice step forward. From quick look of the patch I see that patch is changing how the source and destination positions are read for omap1.
While I don't have idea can this explain the ceased DMA in 1510 but will the playback in original code work again if you change line "offset = dma_read (CPC(lch));" to "offset = dma_read(CSSA_L(lch));" in omap_get_dma_src_pos? Or read both CSSA_L and CSSA_U at once like code before?
Jarkko Nikula wrote:
On Mon, 15 Jun 2009 15:22:34 +0200 Janusz Krzysztofik jkrzyszt@tis.icnet.pl wrote:
- original patch ported to the last l-o commit supporting omap-alsa:
- playback: works as before,
- capture: both </dev/dsp and arecord give null output, but DMA interrupts still work.
Not that I would see it as a real progress, but to clarify things: I have managed to solve this particular problem with capture by patching sound/arm/omap/omap-alsa.c (call omap_get_dma_dst_pos() instead of omap_get_dma_src_pos() from audio_get_dma_pos() in case of (stream_id == SNDRV_PCM_STREAM_CAPTURE)). The original code stopped working after changes introduced to omap_get_dma_src_pos() with this patch: http://marc.info/?l=linux-omap&m=121280267705523.
Nice step forward. From quick look of the patch I see that patch is changing how the source and destination positions are read for omap1.
While I don't have idea can this explain the ceased DMA in 1510 but will the playback in original code work again if you change line "offset = dma_read (CPC(lch));" to "offset = dma_read(CSSA_L(lch));" in omap_get_dma_src_pos? Or read both CSSA_L and CSSA_U at once like code before?
Yes, it will, and even better than before, without undesirable scraps repeated at the end. But that does not help in getting the new driver handle mcbsp/dma correctly :(.
I can confirm that the old driver can set up mcbsp in a way that keeps it shifting the contents of its input register, loaded with a pattern using omap_mcbsp_pollwrite() as Peter suggested, even if I break dma by commenting out all omap_start_dma() invocations. I have verified this by detecting averaged voltage level changes on the codec input pin with a simple multimeter (I still have not get access to a scope back).
Using the new driver, I am not able to detect similiar voltage changes, whatever I do to get the mcbsp sending data to the codec over its serial output. I have modified omap-mcbsp code with a hacked in probe hook that initializes mcbsp at boot time exactly as the old driver does it - no results.
After all, it is more and more likely that the problem is not dma, but mcbsp just not shifting any data for some mysterious reason.
Thanks, Janusz -- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Janusz Krzysztofik wrote:
After all, it is more and more likely that the problem is not dma, but mcbsp just not shifting any data for some mysterious reason.
I finally did what I should have already done before: learned about dynamic debugging, turned it on and probably got the answer from omap_msbsp_dump_reg(): all mcbsp1 register read operations returned 0xffff. So it looks like I simply get no acccess to mcbsp1 at all. Now I wonder if I can close this thread with a conclusion that mcbsp1 on opam15xx is simply not yet supported by the mainline kernel that I have based my work on.
Thanks, Janusz -- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wednesday 17 June 2009 17:12:38 ext Janusz Krzysztofik wrote:
Janusz Krzysztofik wrote:
After all, it is more and more likely that the problem is not dma, but mcbsp just not shifting any data for some mysterious reason.
I finally did what I should have already done before: learned about dynamic debugging, turned it on and probably got the answer from omap_msbsp_dump_reg(): all mcbsp1 register read operations returned 0xffff. So it looks like I simply get no acccess to mcbsp1 at all. Now I wonder if I can close this thread with a conclusion that mcbsp1 on opam15xx is simply not yet supported by the mainline kernel that I have based my work on.
Hmmm, this is quite unexpected. Can you access to mcbsp2 or 3 registers, or only the mcbsp1 registers are not accessible? One thing that I have noticed is that the McBSP1 (and 3) is under the DSP Public Peripherals, while McBSP2 is under MPU Public Peripherals (in OMAP1510). I have to check it further what this actually means...
Thanks, Janusz
* Peter Ujfalusi peter.ujfalusi@nokia.com [090618 12:03]:
On Wednesday 17 June 2009 17:12:38 ext Janusz Krzysztofik wrote:
Janusz Krzysztofik wrote:
After all, it is more and more likely that the problem is not dma, but mcbsp just not shifting any data for some mysterious reason.
I finally did what I should have already done before: learned about dynamic debugging, turned it on and probably got the answer from omap_msbsp_dump_reg(): all mcbsp1 register read operations returned 0xffff. So it looks like I simply get no acccess to mcbsp1 at all. Now I wonder if I can close this thread with a conclusion that mcbsp1 on opam15xx is simply not yet supported by the mainline kernel that I have based my work on.
Hmmm, this is quite unexpected. Can you access to mcbsp2 or 3 registers, or only the mcbsp1 registers are not accessible? One thing that I have noticed is that the McBSP1 (and 3) is under the DSP Public Peripherals, while McBSP2 is under MPU Public Peripherals (in OMAP1510). I have to check it further what this actually means...
Hmmm, do you have the DSP code compiled (and loaded)?
On omap1, DSP needs to be powered and idled before some mcbsp clocks can be used. Or at least needs to be powered up.
Regards,
Tony -- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Tony Lindgren wrote:
- Peter Ujfalusi peter.ujfalusi@nokia.com [090618 12:03]:
On Wednesday 17 June 2009 17:12:38 ext Janusz Krzysztofik wrote:
Janusz Krzysztofik wrote:
After all, it is more and more likely that the problem is not dma, but mcbsp just not shifting any data for some mysterious reason.
I finally did what I should have already done before: learned about dynamic debugging, turned it on and probably got the answer from omap_msbsp_dump_reg(): all mcbsp1 register read operations returned 0xffff. So it looks like I simply get no acccess to mcbsp1 at all. Now I wonder if I can close this thread with a conclusion that mcbsp1 on opam15xx is simply not yet supported by the mainline kernel that I have based my work on.
Hmmm, this is quite unexpected. Can you access to mcbsp2 or 3 registers, or only the mcbsp1 registers are not accessible? One thing that I have noticed is that the McBSP1 (and 3) is under the DSP Public Peripherals, while McBSP2 is under MPU Public Peripherals (in OMAP1510). I have to check it further what this actually means...
Hmmm, do you have the DSP code compiled (and loaded)?
On omap1, DSP needs to be powered and idled before some mcbsp clocks can be used. Or at least needs to be powered up.
AFAICS there is no DSP code in mainline at all, so the answer is no, DSP was likely not powered up at all. For several weeks I was trying to do what was impossible :/. But fortunatelly, I have learned a lot ;).
Thanks, Janusz
-- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
* Janusz Krzysztofik jkrzyszt@tis.icnet.pl [090618 14:52]:
Tony Lindgren wrote:
- Peter Ujfalusi peter.ujfalusi@nokia.com [090618 12:03]:
On Wednesday 17 June 2009 17:12:38 ext Janusz Krzysztofik wrote:
Janusz Krzysztofik wrote:
After all, it is more and more likely that the problem is not dma, but mcbsp just not shifting any data for some mysterious reason.
I finally did what I should have already done before: learned about dynamic debugging, turned it on and probably got the answer from omap_msbsp_dump_reg(): all mcbsp1 register read operations returned 0xffff. So it looks like I simply get no acccess to mcbsp1 at all. Now I wonder if I can close this thread with a conclusion that mcbsp1 on opam15xx is simply not yet supported by the mainline kernel that I have based my work on.
Hmmm, this is quite unexpected. Can you access to mcbsp2 or 3 registers, or only the mcbsp1 registers are not accessible? One thing that I have noticed is that the McBSP1 (and 3) is under the DSP Public Peripherals, while McBSP2 is under MPU Public Peripherals (in OMAP1510). I have to check it further what this actually means...
Hmmm, do you have the DSP code compiled (and loaded)?
On omap1, DSP needs to be powered and idled before some mcbsp clocks can be used. Or at least needs to be powered up.
AFAICS there is no DSP code in mainline at all, so the answer is no, DSP was likely not powered up at all. For several weeks I was trying to do what was impossible :/. But fortunatelly, I have learned a lot ;).
We at least used to have code to power and idle the DSP even without the dspgateway compiled in.. Sorry I don't remember the details. But most likely you need to have the dspgateway patch enabled.
Tony -- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, 16 Jun 2009 16:43:53 +0200 Janusz Krzysztofik jkrzyszt@tis.icnet.pl wrote:
- original patch ported to the last l-o commit supporting
omap-alsa:
- playback: works as before,
- capture: both </dev/dsp and arecord give null output, but DMA interrupts still work.
I can confirm that the old driver can set up mcbsp in a way that keeps it shifting the contents of its input register, loaded with a pattern using omap_mcbsp_pollwrite() as Peter suggested, even if I break dma by commenting out all omap_start_dma() invocations. I have verified this by detecting averaged voltage level changes on the codec input pin with a simple multimeter (I still have not get access to a scope back).
Heh, clever and adequate enough test at the moment until we'll get bit running over the interface :-)
Using the new driver, I am not able to detect similiar voltage changes, whatever I do to get the mcbsp sending data to the codec over its serial output. I have modified omap-mcbsp code with a hacked in probe hook that initializes mcbsp at boot time exactly as the old driver does it - no results.
Hmm, recall, did you try hacking the ASoC driver at the same commit d8376cc482b241701f7606c81ad578b90853e175 where older driver still exists and works? There has been ASoC OMAP fixes and changes since then but nothing which can explain why it doesn't work now for 1510.
There we would know that clock framework, register access etc. works for McBSP on 1510.
Jarkko Nikula wrote:
Hmm, recall, did you try hacking the ASoC driver at the same commit d8376cc482b241701f7606c81ad578b90853e175 where older driver still exists and works? There has been ASoC OMAP fixes and changes since then but nothing which can explain why it doesn't work now for 1510.
There we would know that clock framework, register access etc. works for McBSP on 1510.
Yes, after realizing that possible lack of OMAP1510 McBSP1/3 / DSP support in the mainline tree could be the reason of my problem, I got back to omap tree. First I retried the new driver on commit 90e758af52ba803cba233fabee81176d99589f09 and confirmed the prevoiusly seen hangup. I found that it was omap_mcbsp_request() never returning back from.
Then I retired the same on the commit d8376cc482b241701f7606c81ad578b90853e175 and got similiar hangup. Next, I moved mcbsp initialization to a boot time hook and finally heard a sound and got my first DMA interrupt!
So it seams I have finally managed to take all necessary steps back, and now I can go forward, I hope :).
Thanks, Janusz -- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jun 18, 2009 at 4:40 AM, Janusz Krzysztofikjkrzyszt@tis.icnet.pl wrote:
Jarkko Nikula wrote:
Hmm, recall, did you try hacking the ASoC driver at the same commit d8376cc482b241701f7606c81ad578b90853e175 where older driver still exists and works? There has been ASoC OMAP fixes and changes since then but nothing which can explain why it doesn't work now for 1510.
There we would know that clock framework, register access etc. works for McBSP on 1510.
Yes, after realizing that possible lack of OMAP1510 McBSP1/3 / DSP support in the mainline tree could be the reason of my problem, I got back to omap tree. First I retried the new driver on commit 90e758af52ba803cba233fabee81176d99589f09 and confirmed the prevoiusly seen hangup. I found that it was omap_mcbsp_request() never returning back from.
I faced the same issue while writing ASoC driver for tlv320aic23b codec.
You can have a look at this thread: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg03852.html
It may help.
Then I retired the same on the commit d8376cc482b241701f7606c81ad578b90853e175 and got similiar hangup. Next, I moved mcbsp initialization to a boot time hook and finally heard a sound and got my first DMA interrupt!
So it seams I have finally managed to take all necessary steps back, and now I can go forward, I hope :).
Thanks, Janusz -- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
-- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Tony Lindgren wrote:
- Janusz Krzysztofik jkrzyszt@tis.icnet.pl [090618 14:52]:
Tony Lindgren wrote:
On omap1, DSP needs to be powered and idled before some mcbsp clocks can be used. Or at least needs to be powered up.
AFAICS there is no DSP code in mainline at all, so the answer is no, DSP was likely not powered up at all. For several weeks I was trying to do what was impossible :/. But fortunatelly, I have learned a lot ;).
We at least used to have code to power and idle the DSP even without the dspgateway compiled in.. Sorry I don't remember the details. But most likely you need to have the dspgateway patch enabled.
Tony, Thanks for clarifying things.
Arun K S wrote:
On Thu, Jun 18, 2009 at 4:40 AM, Janusz Krzysztofikjkrzyszt@tis.icnet.pl wrote:
... I retried the new driver on commit 90e758af52ba803cba233fabee81176d99589f09 and confirmed the prevoiusly seen hangup. I found that it was omap_mcbsp_request() never returning back from.
I faced the same issue while writing ASoC driver for tlv320aic23b codec.
You can have a look at this thread: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg03852.html
It may help.
Arun, Thanks, it's good to hear not only me having this problem ;). So what is the current status of your osk driver? What tree do you use, what extra patches do you apply to make it actually working?
---------------------------
After all, could someone please give me an advise, what tree, even with buggy omap1510 mcbsp/dsp support, should I base my work on for best results? Omap? Sound? Mainline? I mean not only easy getting the driver working, but also giving it the best possible path into the mainline.
Thanks, Janusz -- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, Jun 19, 2009 at 4:20 AM, Janusz Krzysztofikjkrzyszt@tis.icnet.pl wrote:
Tony Lindgren wrote:
- Janusz Krzysztofik jkrzyszt@tis.icnet.pl [090618 14:52]:
Tony Lindgren wrote:
On omap1, DSP needs to be powered and idled before some mcbsp clocks can be used. Or at least needs to be powered up.
AFAICS there is no DSP code in mainline at all, so the answer is no, DSP was likely not powered up at all. For several weeks I was trying to do what was impossible :/. But fortunatelly, I have learned a lot ;).
We at least used to have code to power and idle the DSP even without the dspgateway compiled in.. Sorry I don't remember the details. But most likely you need to have the dspgateway patch enabled.
Tony, Thanks for clarifying things.
Arun K S wrote:
On Thu, Jun 18, 2009 at 4:40 AM, Janusz Krzysztofikjkrzyszt@tis.icnet.pl wrote:
... I retried the new driver on commit 90e758af52ba803cba233fabee81176d99589f09 and confirmed the prevoiusly seen hangup. I found that it was omap_mcbsp_request() never returning back from.
I faced the same issue while writing ASoC driver for tlv320aic23b codec.
You can have a look at this thread: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg03852.html
It may help.
Arun, Thanks, it's good to hear not only me having this problem ;). So what is the current status of your osk driver? What tree do you use, what extra patches do you apply to make it actually working?
Currently osk driver works fine on 2.6.31. Initially i used to add the omap_mcbsp_request() at the boot time, other wise it hangs up. Audio in current mainline tree works fine for osk5912 with out any such hacks. I believe there are some patches from Russel for the DSP memory mapping during 2.6.29 kernel.
After all, could someone please give me an advise, what tree, even with buggy omap1510 mcbsp/dsp support, should I base my work on for best results? Omap? Sound? Mainline? I mean not only easy getting the driver working, but also giving it the best possible path into the mainline.
You have to use current omap tree with the patches from current sound tree(ASoC omap platform drivers changes) for testing the driver. Somebody correct me if i am wrong.
Thanks, Janusz
-- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, 18 Jun 2009 13:40:56 +0200 Janusz Krzysztofik jkrzyszt@tis.icnet.pl wrote:
Then I retired the same on the commit d8376cc482b241701f7606c81ad578b90853e175 and got similiar hangup. Next, I moved mcbsp initialization to a boot time hook and finally heard a sound and got my first DMA interrupt!
Great! :-)
I wonder what special boot time omap_mcbsp_request call has in respect to McBSP access. DSP issue pointed by Tony might be one answer and I'm also thinking can it be also some clock gating problem to the McBSP like some parent clock gets idled after booting?
Can you move this boot time initialization moment around with xxx_initcall variants to see what is the point where block is not anymore accessable? Basically around the DSP power up and idle code (were there such code for older audio drivers?) and where unused clocks are disabled (functions clk_disable_unused and omap1_clk_disable_unused).
Hi,
Arun K S wrote:
On Fri, Jun 19, 2009 at 4:20 AM, Janusz Krzysztofikjkrzyszt@tis.icnet.pl wrote:
After all, could someone please give me an advise, what tree, even with buggy omap1510 mcbsp/dsp support, should I base my work on for best results?
You have to use current omap tree with the patches from current sound tree(ASoC omap platform drivers changes) for testing the driver.
Arun, Thanks, from now on I use l-o master, right? As I do my development using OE, I am still investigating how to set up a bb recipe to get ALSA git tree applied over l-o.
Arun K S wrote:
On Fri, Jun 19, 2009 at 4:20 AM, Janusz Krzysztofikjkrzyszt@tis.icnet.pl wrote:
Arun K S wrote:
On Thu, Jun 18, 2009 at 4:40 AM, Janusz Krzysztofikjkrzyszt@tis.icnet.pl wrote:
... I retried the new driver on commit 90e758af52ba803cba233fabee81176d99589f09 and confirmed the prevoiusly seen hangup. I found that it was omap_mcbsp_request() never returning back from.
I faced the same issue while writing ASoC driver for tlv320aic23b codec.
You can have a look at this thread: http://www.mail-archive.com/linux-omap@vger.kernel.org/msg03852.html
Initially i used to add the omap_mcbsp_request() at the boot time, other wise it hangs up. ... I believe there are some patches from Russel for the DSP memory mapping during 2.6.29 kernel.
Jarkko Nikula wrote:
On Thu, 18 Jun 2009 13:40:56 +0200 Janusz Krzysztofik jkrzyszt@tis.icnet.pl wrote:
Then I retired the same on the commit d8376cc482b241701f7606c81ad578b90853e175 and got similiar hangup.
Can you move this boot time initialization moment around with xxx_initcall variants to see what is the point where block is not anymore accessable? Basically around the DSP power up and idle code (were there such code for older audio drivers?) and where unused clocks are disabled (functions clk_disable_unused and omap1_clk_disable_unused).
Arun, Jarkko, Thanks. Fortunatelly, I can confirm that the problem of omap_mcbsp_request() not returning back when called too late, has been already solved and no longer applies to 2.6.30, be it omap or mainline, with or without a working dsp.
Tony Lindgren wrote:
- Janusz Krzysztofik jkrzyszt@tis.icnet.pl [090618 14:52]:
Tony Lindgren wrote:
- Peter Ujfalusi peter.ujfalusi@nokia.com [090618 12:03]:
On Wednesday 17 June 2009 17:12:38 ext Janusz Krzysztofik wrote:
Janusz Krzysztofik wrote:
... got the answer from
omap_msbsp_dump_reg(): all mcbsp1 register read operations returned 0xffff. So it looks like I simply get no acccess to mcbsp1 at all.
One thing that I have noticed is that the McBSP1 (and 3) is under the DSP Public Peripherals, while McBSP2 is under MPU Public Peripherals (in OMAP1510).
On omap1, DSP needs to be powered and idled before some mcbsp clocks can be used. Or at least needs to be powered up.
AFAICS there is no DSP code in mainline at all, so the answer is no, DSP was likely not powered up at all.
We at least used to have code to power and idle the DSP even without the dspgateway compiled in.. Sorry I don't remember the details. But most likely you need to have the dspgateway patch enabled.
I hacked in the prevoiusly removed dsp_common.c containing omap_dsp_init(), with all header files required for successfull compilation, and finally got my driver working on top of current l-o.
Jarkko, Peter, Mark, Tony, Arun, Thanks for your help.
It seams that dsp_common.c with its omap_dsp_init() used to be always compiled into the kernel, even if the rest of dspgateway code was not compiled or compiled as a module. This file, initially existing in arch/arm/plat-omap, was moved to drivers/dsp (commit 23ed8b5cf043a9cd40b5d415645b3543357d9a1a), and then removed completely (commit 2512fd29db4eb09e82d182596304c7aaf76d2c5c), together with other dspgateway code. Since then, McBSP ports that are DSP public peripherals have probably no chance to work, at least on omap1510, as I have verified.
Perhaps this single file (or its part with omap_dsp_init() at least) should never happen to be moved out of arch/arm/plat-omap? One of its related header files, dsp_common.h, has survived in the tree after it was moved to include/asm-arm/arch-omap/ (commit d23b6a447c9cd1d7376c5ec109b4be015a121eec), and then to arch/arm/plat-omap/include/map/.
Can I do anything to get omap_dsp_init() back into the omap tree? Could I just start with readding that old dsp_common.c, including any necessary header files, back to arch/arm/plat-omap/dsp? Or what other way should I take to restore omap1510 mcbsp1/3 support back?
Thanks, Janusz
-- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Jarkko,
Jarkko Nikula wrote:
Is the older implementation working at commit d8376cc482b241701f7606c81ad578b90853e175 in linux-omap, i.e. last commit before their removal?
I have managed to check with that revision this morning and yes, the driver is working.
I'll try you other suggestions as soon as I get back home.
Cheers, Janusz
-- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hello Janusz,
On Tuesday 02 June 2009 13:50:50 ext Janusz Krzysztofik wrote:
Hi Jarkko,
Jarkko Nikula wrote:
Is the older implementation working at commit d8376cc482b241701f7606c81ad578b90853e175 in linux-omap, i.e. last commit before their removal?
I have managed to check with that revision this morning and yes, the driver is working.
I'll try you other suggestions as soon as I get back home.
Looking at the code at commit: d8376cc482b241701f7606c81ad578b90853e175 on l-o the comment about the need for the call the omap_stop_dma puzzled me. Can you try something like this:
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 6454e15..2df1792 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -67,6 +67,7 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data) spin_lock_irqsave(&prtd->lock, flags); if (prtd->period_index >= 0) { if (++prtd->period_index == runtime->periods) { + omap_stop_dma(prtd->dma_ch); prtd->period_index = 0; omap_start_dma(prtd->dma_ch); } @@ -191,6 +192,7 @@ static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + omap_stop_dma(prtd->dma_ch); prtd->period_index = 0; omap_start_dma(prtd->dma_ch); break;
This is on top of sound-2.6:topic/asoc, but l-o should not be that different. Call the omap_stop_dma before actually starting the dma, and call stop also before restarting it.
Wednesday 03 June 2009 07:28:06 Peter Ujfalusi napisał(a):
Looking at the code at commit: d8376cc482b241701f7606c81ad578b90853e175 on l-o the comment about the need for the call the omap_stop_dma puzzled me.
Peter,
It was omap_stop_alsa_sound_dma(), not just omap_stop_dma(), the was needed. In my opinion, the reason for that was not because it was calling omap_stop_dma(), but because it was clearing the audio_stream.started flag. That way, subsequent audio_start_dma_chain() would not jump over omap_start_dma(). From my experience with the original driver, it worked much better when calling omap_start_dma() unconditionally from audio_start_dma_chain() instead of doing this with that omap_stop_alsa_sound_dma() trick.
Can you try something like this:
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 6454e15..2df1792 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -67,6 +67,7 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data) spin_lock_irqsave(&prtd->lock, flags); if (prtd->period_index >= 0) { if (++prtd->period_index == runtime->periods) {
omap_stop_dma(prtd->dma_ch); prtd->period_index = 0; omap_start_dma(prtd->dma_ch); }
@@ -191,6 +192,7 @@ static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
omap_stop_dma(prtd->dma_ch); prtd->period_index = 0; omap_start_dma(prtd->dma_ch); break;
Never hurts. Unfortunatelly, it did not help, no single DMA interrupt again.
Thanks, Janusz -- To unsubscribe from this list: send the line "unsubscribe alsa-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, May 26, 2009 at 03:17:23PM +0200, Janusz Krzysztofik wrote:
single message. So I have switched to linux-2.6.30-rc5 and now I can safely access the device, however it does not work as expected. aplay and arecord wait forever, cat to/from /dev/dsp breaks with hardware
Do they really wait for ever or do they eventually time out? The default for both programs is to give up after 10 seconds if there's no DMA happening.
First of all, I'd like to make sure if my problem is related to my code only. As I am new in these areas, I would like to ask you if the omap asoc framework is stable enough to relay on. If yes, could you please
It seems to have quite a few users.
I can't spot anything obviously wrong in generic ASoC terms with your code, though I'm not at all familiar with the McBSP hardware so can't offer any specific suggestions there. A few comments below.
+#include <sound/ac97_codec.h> +#include <sound/initval.h> +#include <sound/soc.h>
+#include "cx20442.h"
Shouldn't need ac97_codec.h if it's not an AC97 CODEC.
+static int cx20442_soc_probe(struct platform_device *pdev) +{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (codec == NULL)
return -ENOMEM;
- mutex_init(&codec->mutex);
- codec->name = "CX20442";
- codec->owner = THIS_MODULE;
- codec->dai = &cx20442_dai;
- codec->num_dai = 1;
It'd be nice to switch this over to registering the CODEC as a platform device rather than using the old style ASoC probing - see something line WM8731 for a relatively simple example.
+MODULE_DESCRIPTION("ASoC cx20442 driver"); +MODULE_AUTHOR("Cliff Cai ");
You possibly want to update this one :)
Basically, the CODEC driver looks fine from an ASoC point of view.
+/*
- File: sound/soc/codec/cx20442.h
- Based on: sound/soc/codec/ad73311.h
- Author: Cliff Cai cliff.cai@analog.com
- Created: Thur Sep 25, 2008
- Description: definitions for cx20442 registers
- Modified:
Copyright 2006 Analog Devices Inc.
- Bugs: Enter bugs at http://blackfin.uclinux.org/
These comments have cut'n'paste issues too, and the register definitions should all be removed.
+static int ams_delta_startup(struct snd_pcm_substream *substream) +{
- ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0);
- return clk_enable(cx20442_mclk);
+}
+static void ams_delta_shutdown(struct snd_pcm_substream *substream) +{
- clk_disable(cx20442_mclk);
Possibly not an issue with this device but you might want to move the MCLK handling to your machine set_bias_level() function. That will mean that your MCLK will be left running for a while after audio stops, ensuring that the DAC has had time to clock out the final sample. Without that sometimes you can end up causing an audible artefact when starting the next playback.
Hi Mark,
On Wed, May 27, 2009 at 12:47, Mark Brown wrote:
On Tue, May 26, 2009 at 03:17:23PM +0200, Janusz Krzysztofik wrote:
... aplay and arecord wait forever, cat to/from /dev/dsp breaks with hardware
Do they really wait for ever or do they eventually time out? The default for both programs is to give up after 10 seconds if there's no DMA happening.
That was more than 10 seconds for sure.
... A few comments below.
+#include <sound/ac97_codec.h> +#include <sound/initval.h> +#include <sound/soc.h>
+#include "cx20442.h"
Shouldn't need ac97_codec.h if it's not an AC97 CODEC.
Yes, I am going to clean up the code if it ever starts working.
+static int cx20442_soc_probe(struct platform_device *pdev) +{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (codec == NULL)
return -ENOMEM;
- mutex_init(&codec->mutex);
- codec->name = "CX20442";
- codec->owner = THIS_MODULE;
- codec->dai = &cx20442_dai;
- codec->num_dai = 1;
It'd be nice to switch this over to registering the CODEC as a platform device rather than using the old style ASoC probing - see something line WM8731 for a relatively simple example.
OK, I'll follow it.
+MODULE_DESCRIPTION("ASoC cx20442 driver"); +MODULE_AUTHOR("Cliff Cai ");
You possibly want to update this one :)
Sure.
Basically, the CODEC driver looks fine from an ASoC point of view.
Fine.
+/*
- File: sound/soc/codec/cx20442.h
- Based on: sound/soc/codec/ad73311.h
- Author: Cliff Cai cliff.cai@analog.com
- Created: Thur Sep 25, 2008
- Description: definitions for cx20442 registers
- Modified:
Copyright 2006 Analog Devices Inc.
- Bugs: Enter bugs at http://blackfin.uclinux.org/
These comments have cut'n'paste issues too, and the register definitions should all be removed.
Yes, only extern struct declarations required here, I think.
+static int ams_delta_startup(struct snd_pcm_substream *substream) +{
- ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0);
- return clk_enable(cx20442_mclk);
+}
+static void ams_delta_shutdown(struct snd_pcm_substream *substream) +{
- clk_disable(cx20442_mclk);
Possibly not an issue with this device but you might want to move the MCLK handling to your machine set_bias_level() function. That will mean that your MCLK will be left running for a while after audio stops, ensuring that the DAC has had time to clock out the final sample. Without that sometimes you can end up causing an audible artefact when starting the next playback.
OK, I'll look at this, but first I have to learn what MCLK really is ;)
Thanks, Janusz
Hi Mark,
Wednesday 27 May 2009 12:47:11 Mark Brown wrote:
On Tue, May 26, 2009 at 03:17:23PM +0200, Janusz Krzysztofik wrote:
+static int cx20442_soc_probe(struct platform_device *pdev) +{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (codec == NULL)
return -ENOMEM;
- mutex_init(&codec->mutex);
- codec->name = "CX20442";
- codec->owner = THIS_MODULE;
- codec->dai = &cx20442_dai;
- codec->num_dai = 1;
It'd be nice to switch this over to registering the CODEC as a platform device rather than using the old style ASoC probing - see something line WM8731 for a relatively simple example.
Tired with solving tha main problem of not getting any DMA interrupts, I have followed your advices and modified my codec driver. I have used your wm8400 code as a template. The driver compiles and loads without errors, however I have no way to verify if and how it works as long as the DMA issue persists. I think the code is probably far from complete, but could you please have a look at it for possible problems?
I have choosen to register the codec device with platform_device_register_simple("cx20442-codec", ...) invoked form asoc machine driver, is this ok?
Thanks, Janusz
Signed-off by: Janusz Krzysztofik jkrzyszt@tis.icnet.pl ------------------------------- diff -Npru a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig --- a/sound/soc/codecs/Kconfig 2009-05-12 21:13:59.000000000 +0200 +++ b/sound/soc/codecs/Kconfig 2009-06-01 22:31:15.000000000 +0200 @@ -18,6 +18,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_AK4104 if SPI_MASTER select SND_SOC_AK4535 if I2C select SND_SOC_CS4270 if I2C + select SND_SOC_CX20442 select SND_SOC_PCM3008 select SND_SOC_SSM2602 if I2C select SND_SOC_TLV320AIC23 if I2C @@ -84,6 +85,9 @@ config SND_SOC_AC97_CODEC bool depends on SND_SOC_CS4270
+config SND_SOC_CX20442 + tristate + config SND_SOC_L3 tristate
diff -Npru a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile --- a/sound/soc/codecs/Makefile 2009-05-12 21:13:59.000000000 +0200 +++ b/sound/soc/codecs/Makefile 2009-06-01 22:33:32.000000000 +0200 @@ -5,6 +5,7 @@ snd-soc-ak4104-objs := ak4104.o snd-soc-ak4535-objs := ak4535.o snd-soc-cs4270-objs := cs4270.o +snd-soc-cx20442-objs := cx20442.o snd-soc-l3-objs := l3.o snd-soc-pcm3008-objs := pcm3008.o snd-soc-ssm2602-objs := ssm2602.o @@ -37,6 +38,7 @@ snd-soc-wm9713-objs := wm9713.o obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o +obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o diff -Npru a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c --- a/sound/soc/codecs/cx20442.c 1970-01-01 01:00:00.000000000 +0100 +++ b/sound/soc/codecs/cx20442.c 2009-06-01 21:26:20.000000000 +0200 @@ -0,0 +1,224 @@ +/* + * cx20442.c -- CX20442 ALSA Soc Audio driver + * + * Based on wm8400.c + * Copyright 2008, 2009 Wolfson Microelectronics PLC. + * Author: Mark Brown broonie@opensource.wolfsonmicro.com + * + * Copyright 2009 Janusz Krzysztofik jkrzyszt@tis.icnet.pl + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/soc.h> +#include <sound/soc-dapm.h> +#include <sound/initval.h> + +#include "cx20442.h" + +struct cx20442_priv { + struct snd_soc_codec codec; + struct work_struct work; +}; + +static int cx20442_add_controls(struct snd_soc_codec *codec) +{ + return 0; +} + +static int cx20442_add_widgets(struct snd_soc_codec *codec) +{ + snd_soc_dapm_new_widgets(codec); + return 0; +} + +static int cx20442_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + codec->bias_level = level; + return 0; +} + +#define CX20442_RATES SNDRV_PCM_RATE_8000 + +#define CX20442_FORMATS SNDRV_PCM_FMTBIT_S16_LE + +struct snd_soc_dai cx20442_dai = { + .name = "CX20442", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = CX20442_RATES, + .formats = CX20442_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = CX20442_RATES, + .formats = CX20442_FORMATS, + }, +}; +EXPORT_SYMBOL_GPL(cx20442_dai); + +static struct snd_soc_codec *cx20442_codec; + +static int cx20442_probe(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec; + int ret; + + if(!cx20442_codec) { + dev_err(&pdev->dev, "cx20442 not yet discovered\n"); + return -ENODEV; + } + codec = cx20442_codec; + + socdev->card->codec = codec; + + /* register pcms */ + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); + if (ret < 0) { + dev_err(&pdev->dev, "failed to create pcms\n"); + goto pcm_err; + } + + cx20442_add_controls(codec); + cx20442_add_widgets(codec); + + cx20442_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + ret = snd_soc_init_card(socdev); + if (ret < 0) { + dev_err(&pdev->dev, "failed to register card\n"); + goto card_err; + } + + return ret; + +card_err: + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); +pcm_err: + return ret; +} + +/* power down chip */ +static int cx20442_remove(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); + + return 0; +} + +struct snd_soc_codec_device soc_codec_dev_cx20442 = { + .probe = cx20442_probe, + .remove = cx20442_remove, +}; + +static int cx20442_codec_probe(struct platform_device *dev) +{ + struct cx20442_priv *priv; + int ret; + struct snd_soc_codec *codec; + + priv = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL); + if (priv == NULL) + return -ENOMEM; + + codec = &priv->codec; + codec->private_data = priv; + codec->control_data = dev->dev.driver_data; + + codec->dev = &dev->dev; + cx20442_dai.dev = &dev->dev; + + codec->name = "CX20442"; + codec->owner = THIS_MODULE; + codec->bias_level = SND_SOC_BIAS_OFF; + codec->set_bias_level = cx20442_set_bias_level; + codec->dai = &cx20442_dai; + codec->num_dai = 1; + mutex_init(&codec->mutex); + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths); + + cx20442_codec = codec; + + ret = snd_soc_register_codec(codec); + if (ret != 0) { + dev_err(&dev->dev, "Failed to register codec: %d\n", ret); + goto err; + } + + ret = snd_soc_register_dai(&cx20442_dai); + if (ret != 0) { + dev_err(&dev->dev, "Failed to register DAI: %d\n", ret); + goto err_codec; + } + + return 0; + +err_codec: + snd_soc_unregister_codec(codec); +err: + cx20442_codec = NULL; + kfree(priv); + return ret; +} + +static int __exit cx20442_codec_remove(struct platform_device *dev) +{ + struct cx20442_data *priv = cx20442_codec->private_data; + + snd_soc_unregister_dai(&cx20442_dai); + snd_soc_unregister_codec(cx20442_codec); + + kfree(priv); + + cx20442_codec = NULL; + + return 0; +} + +static struct platform_driver cx20442_codec_driver = { + .driver = { + .name = "cx20442-codec", + .owner = THIS_MODULE, + }, + .probe = cx20442_codec_probe, + .remove = __exit_p(cx20442_codec_remove), +}; + +static int __init cx20442_init(void) +{ + return platform_driver_register(&cx20442_codec_driver); +} +module_init(cx20442_init); + +static void __exit cx20442_exit(void) +{ + platform_driver_unregister(&cx20442_codec_driver); +} +module_exit(cx20442_exit); + +EXPORT_SYMBOL_GPL(soc_codec_dev_cx20442); + +MODULE_DESCRIPTION("ASoC CX20442 driver"); +MODULE_AUTHOR("Janusz Krzysztofik"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:cx20442-codec"); diff -Npru a/sound/soc/codecs/cx20442.h b/sound/soc/codecs/cx20442.h --- a/sound/soc/codecs/cx20442.h 1970-01-01 01:00:00.000000000 +0100 +++ b/sound/soc/codecs/cx20442.h 2009-06-01 21:25:46.000000000 +0200 @@ -0,0 +1,23 @@ +/* + * cx20442.h -- audio driver for CX20442 + * + * Based on wm8400.h + * Copyright 2008 Wolfson Microelectronics PLC. + * Author:Mark Brown broonie@opensource.wolfsonmicro.com + * + * Copyright 2009 Janusz Krzysztofik jkrzyszt@tis.icnet.pl + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef _CX20442_CODEC_H +#define _CX20442_CODEC_H + +extern struct snd_soc_dai cx20442_dai; +extern struct snd_soc_codec_device soc_codec_dev_cx20442; + +#endif
On Tue, Jun 02, 2009 at 09:24:39AM +0200, Janusz Krzysztofik wrote:
I have choosen to register the codec device with platform_device_register_simple("cx20442-codec", ...) invoked form asoc machine driver, is this ok?
Normally the platform device would be registered by the machine file under arch/arm but either works.
participants (6)
-
Arun K S
-
Janusz Krzysztofik
-
Jarkko Nikula
-
Mark Brown
-
Peter Ujfalusi
-
Tony Lindgren