Re: recording problem in beagleboard-mcbsp

noman pouigt
2015-04-09T23:02:41Z

[-- Attachment #1: Type: text/plain, Size: 4211 bytes --]

On Thu, Apr 9, 2015 at 5:06 AM, Peter Ujfalusi <peter.ujfalusi@ti.com> wrote:
> On 04/09/2015 02:44 AM, noman pouigt wrote:
>>> First check the /proc/asound/card0/pcm0c/sub0/status while the capture is
>>> running and look at the hw_ptr if it has moved at all.
>>
>> It has not moved at all.
>
> So McBSP does not detect start condition on the FS line.
>
>>> Enable more interrupts in sound/soc/omap/mcbsp.c:omap_mcbsp_config(), like
>>> RUNDFLEN, ROVFLEN and see if you have overflow in McBSP.
>>
>> I did enable the interrupt but all i am getting is below for both
>> playback and capture
>> usecase:
>> omap-mcbsp 48074000.mcbsp: RX Buffer Underflow!
>
> This is because you dump the registers and it read the DDR register. The FIFO
> is empty and you try to read data out.
>
>> Remember playback is working in both the slave and master mode (codec slave
>> and codec master).
>>>
>>> If the DMA has not moved it means that McBSP does not received the FS which
>>> would indicate the frame start, thus it will not sample data in, thus it will
>>> not trigger the DMA to read the data out.
>>
>> Used scope to check FS and Bit clock and found below (running arecord
>> with 44100):
>> bit clock is running at 1.420 MHz and FS at 44100 kHz. Configured MCBsp
>> in master mode this time.
>>
>>>
>>> Since the capture is working on McBSP2 in McBSP slave (and master also) the
>>> only thing which can be wrong is the way the max98090 is wired up or some mux
>>> issue again as it was before for you.
>>
>> Below is the mux setting which i did and because of which playback is working:
>> MCBsp in master mode
>> configured mcbsp1_clkx, mcbsp1_fsx, mcbsp1_dx and mcbsp1_dr
>> +
>> + mcbsp1_pins: pinmux_mcbsp1_pins {
>> + pinctrl-single,pins = <
>> + OMAP3_CORE1_IOPAD(0x2196, PIN_OUTPUT | MUX_MODE0)
>> + OMAP3_CORE1_IOPAD(0x2198, PIN_OUTPUT | MUX_MODE0)
>> + OMAP3_CORE1_IOPAD(0x2190, PIN_OUTPUT | MUX_MODE0)
>> + OMAP3_CORE1_IOPAD(0x2192, PIN_INPUT | MUX_MODE0)
>> + OMAP3_CORE1_IOPAD(0x218C, PIN_OUTPUT | MUX_MODE0)
>> + >;
>> + };
>> };
>>
>> Even if MCBSP_DR is not connected properly it should record atleast noise.
>>
>> I also tried Thomas Niederprüm below advice when running McBsp in slave mode
>> shorten the CLKR and CLKX pins and mux the CLKR pin as INPUT in your
>> dts. Then your
>> bitclock would enter through CLKR as well as CLKX.
>> But this also didn't work.
>>
>> Found out only below register changes between playback and capture:
>> In playback
>> SPCR2: 0x02f5
>> SPCR1: 0x0030
>> In capture:
>> SPCR2: 0x02f0
>> SPCR1: 0x0031
>>
>> There are no difference between any other register. I think mcbsp
>> registers are fine
>> but can you confirm if there should be any more differences?
>> Please advice what might be going wrong?
>
> Hrm, McBSP1 is kind of problematic port since it has 6pin config by default.
> It might worth a try to do something like:
> http://lists.infradead.org/pipermail/linux-arm-kernel/2012-August/113058.html
> has removed.
This patch seems pretty old and I am not able to apply it as i am
using latest kernel.
kernel: 3.19

> Or to switch to use McBSP3.

tried this as well but even playback didn't work.
+ mcbsp3_pins: pinmux_mcbsp3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x216C, PIN_OUTPUT | MUX_MODE1)
+ OMAP3_CORE1_IOPAD(0x216E, PIN_INPUT | MUX_MODE1)
+ OMAP3_CORE1_IOPAD(0x2170, PIN_OUTPUT | MUX_MODE1)
+ OMAP3_CORE1_IOPAD(0x2172, PIN_OUTPUT | MUX_MODE0)
+ >;
+ };

attached patch where i replaced the mcbsp1 to mcbsp3 number in machine file.
do you think this configuration is right? I tried both master and slave mode
and both didn't work but i was getting right bit clock and FS clock.

>
> But for some reason now I can not get the recording working via McBSP1 either.
> I remember that it worked not that long time ago...
>
> --
> Péter

[-- Attachment #2: mcbsp3.patch --]
[-- Type: text/x-patch, Size: 5599 bytes --]

diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts b/arch/arm/boot/dts/omap3-beagle-xm.dts
index 25f7b0a..215eb86 100644
--- a/arch/arm/boot/dts/omap3-beagle-xm.dts
+++ b/arch/arm/boot/dts/omap3-beagle-xm.dts
@@ -59,8 +59,8 @@
compatible = "ti,omap-twl4030";
ti,model = "omap3beagle";

- ti,mcbsp = <&mcbsp2>;
- ti,codec = <&twl_audio>;
+ ti,mcbsp = <&mcbsp3>;
+ ti,codec = <&max98090>;
};

gpio_keys {
@@ -246,6 +246,15 @@
OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE3) /* dss_data23.dss_data5 */
>;
};
+
+ mcbsp3_pins: pinmux_mcbsp3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x216C, PIN_OUTPUT | MUX_MODE1)
+ OMAP3_CORE1_IOPAD(0x216E, PIN_INPUT | MUX_MODE1)
+ OMAP3_CORE1_IOPAD(0x2170, PIN_OUTPUT | MUX_MODE1)
+ OMAP3_CORE1_IOPAD(0x2172, PIN_OUTPUT | MUX_MODE0)
+ >;
+ };
};

&omap3_pmx_core2 {
@@ -292,6 +301,11 @@

&i2c2 {
clock-frequency = <400000>;
+
+ max98090: max98090@10 {
+ compatible = "maxim,max98090";
+ reg = <0x10>;
+ };
};

&i2c3 {
@@ -339,6 +353,7 @@
pinctrl-0 = <&uart3_pins>;
};

+
&gpio1 {
pinctrl-names = "default";
pinctrl-0 = <&gpio1_pins>;
@@ -363,6 +378,23 @@
status = "okay";
};

+/*&mcbsp1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcbsp1_pins>;
+
+ status = "okay";
+};*/
+
+&mcbsp1 {
+ status = "disabled";
+};
+
+&mcbsp3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcbsp3_pins>;
+
+ status = "okay";
+};
&dss {
status = "ok";

diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index b112b1c..a4c3748 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -1997,6 +1997,10 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
snd_soc_update_bits(codec, M98090_REG_INTERFACE_FORMAT,
M98090_WS_MASK, 0);
break;
+ case 24:
+ snd_soc_update_bits(codec, M98090_REG_INTERFACE_FORMAT,
+ M98090_WS_MASK, 2);
+ break;
default:
return -EINVAL;
}
@@ -2089,6 +2093,7 @@ static int max98090_dai_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;
+ int reg;
struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);

switch (cmd) {
@@ -2589,15 +2594,6 @@ static int max98090_i2c_probe(struct i2c_client *i2c,
goto err_enable;
}

- ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
- max98090_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- "max98090_interrupt", max98090);
- if (ret < 0) {
- dev_err(&i2c->dev, "request_irq failed: %d\n",
- ret);
- return ret;
- }
-
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_max98090, max98090_dai,
ARRAY_SIZE(max98090_dai));
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c
index fb1f6bb..3176f1b 100644
--- a/sound/soc/omap/omap-twl4030.c
+++ b/sound/soc/omap/omap-twl4030.c
@@ -54,6 +54,12 @@ static int omap_twl4030_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
unsigned int fmt;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int err = 0;
+ int ret = 0;
+#if 0
+int div, clk_id,freq;

switch (params_channels(params)) {
case 2: /* Stereo I2S mode */
@@ -70,7 +76,58 @@ static int omap_twl4030_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}

+ snd_soc_runtime_set_dai_fmt(rtd, fmt);
+ snd_soc_dai_set_sysclk(codec_dai, 0, 13000000,
+ SND_SOC_CLOCK_IN);
+div = clk_id = freq = 0;
+switch (params_rate(params)) {
+case 44100: /* 44.117 */
+ div = 68;
+ clk_id = OMAP_MCBSP_SYSCLK_CLKS_FCLK;
+ freq = 96000000;
+ break;
+case 48000: /* 48.032 */
+ div = 54;
+ clk_id = OMAP_MCBSP_SYSCLK_CLK;
+ freq = 83000000;
+ break;
+default:
+ printk(KERN_ERR "hw params: unknown rate %d\n",
+ params_rate(params));
+ return -EINVAL;
+}
+
+ret = snd_soc_dai_set_sysclk(cpu_dai, clk_id, freq, SND_SOC_CLOCK_IN);
+if (ret < 0) {
+ printk("what the hell\n");
+ return -EINVAL;
+}
+ret = snd_soc_dai_set_clkdiv(cpu_dai, OMAP_MCBSP_CLKGDV, div);
+if (ret < 0) {
+ printk("what the hell going on\n");
+ return -EINVAL;
+}
+ return ret;
+#else
+ switch (params_channels(params)) {
+ case 2: /* Stereo I2S mode */
+ fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM;
+ break;
+ case 4: /* Four channel TDM mode */
+ fmt = SND_SOC_DAIFMT_DSP_A |
+ SND_SOC_DAIFMT_IB_NF |
+ SND_SOC_DAIFMT_CBM_CFM;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_dai_set_sysclk(codec_dai, 0, 13000000,
+ SND_SOC_CLOCK_IN);
return snd_soc_runtime_set_dai_fmt(rtd, fmt);
+#endif
}

static struct snd_soc_ops omap_twl4030_ops = {
@@ -228,13 +285,12 @@ static int omap_twl4030_card_remove(struct snd_soc_card *card)
/* Digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link omap_twl4030_dai_links[] = {
{
- .name = "TWL4030 HiFi",
- .stream_name = "TWL4030 HiFi",
- .cpu_dai_name = "omap-mcbsp.2",
- .codec_dai_name = "twl4030-hifi",
- .platform_name = "omap-mcbsp.2",
- .codec_name = "twl4030-codec",
- .init = omap_twl4030_init,
+ .name = "max98090 HiFi",
+ .stream_name = "max98090 HiFi",
+ .cpu_dai_name = "omap-mcbsp.3",
+ .codec_dai_name = "HiFi",
+ .platform_name = "omap-mcbsp.3",
+ .codec_name = "max98090.1-0010",
.ops = &omap_twl4030_ops,
},
{

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]