Custom Beaglebone black Audio cape with TLV320AIC3110

1,303 views
Skip to first unread message

resande...@gmail.com

unread,
Nov 13, 2014, 8:46:32 PM11/13/14
to beagl...@googlegroups.com, al...@webbelectronicsinc.com
Hi,

I am trying to design a cape with TLV320AIC3110 for Beaglebone black using I2c2 and Mcasp0. I have compiled the driver into the kernel and modified the device tree. This is my procedure.

ubuntu@arm:~$ uname -r
3.15.10-bone8

1- Driver:
I am using the driver in /sound/soc/codecs/tlc320aic31xx.c
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
index d1929de..1c300a5 100644
--- a/sound/soc/codecs/tlv320aic31xx.c
+++ b/sound/soc/codecs/tlv320aic31xx.c
@@ -19,7 +19,7 @@
  * high performance codec which provides a stereo DAC, a mono ADC,
  * and mono/stereo Class-D speaker driver.
  */
-
+#define DEBUG 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>

2- Edit Kconfig
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index f0e8401..19036e3 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -461,7 +461,8 @@ config SND_SOC_TLV320AIC26
        depends on SPI
 
 config SND_SOC_TLV320AIC31XX
-        tristate
+        tristate "TI TLV320AIC31xx class D codecs"
+       depends on I2C
 
 config SND_SOC_TLV320AIC32X4
        tristate


3- ALSA Machine Layer Configuration:

Create a DAI (digital audio interface) Link structure. This should allow a specific configuration for the McASP to be called when Linux is directed to play audio to the TLV320AIC31XX. For Sitara McASP machine layer driver is found at sound/soc/davinci/davinci-evm.c

diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index cab98a5..41db457 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -8,7 +8,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define DEBUG
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/timer.h>
@@ -98,6 +98,13 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] 
        SND_SOC_DAPM_LINE("Line In", NULL),
 };
 
+static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = {
+       SND_SOC_DAPM_HP("Headphone Jack", NULL),
+       SND_SOC_DAPM_SPK("Speaker", NULL),
+       SND_SOC_DAPM_MIC("Mic Jack", NULL),
+};
+
+
 /* davinci-evm machine audio_mapnections to the codec pins */
 static const struct snd_soc_dapm_route audio_map[] = {
        /* Headphone connected to HPLOUT, HPROUT */
@@ -120,6 +127,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
        {"LINE2R", NULL, "Line In"},
 };
 
+
 /* Logic for a aic3x as connected on a davinci-evm */
 static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
 {
@@ -150,6 +158,42 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
        return 0;
 }
 
+/* Logic for a aic31xx as connected on a davinci-evm */
+static int evm_aic31xx_init (struct snd_soc_pcm_runtime *rtd)
+{        
+        struct snd_soc_codec *codec = rtd->codec;
+        struct snd_soc_dapm_context *dapm = &codec->dapm;
+        struct device_node *np = codec->card->dev->of_node;
+        int ret;
+
+        /* Add davinci-evm specific widgets */
+        snd_soc_dapm_new_controls(dapm, aic31xx_dapm_widgets,
+                                  ARRAY_SIZE(aic31xx_dapm_widgets));
+
+        if (np) {
+                ret = snd_soc_of_parse_audio_routing(codec->card, "ti,audio-rou
+                if (ret)
+                        return ret;
+        } 
+/*
+else {
+*/
+                /* Set up davinci-evm specific audio path audio_map */
+/*
+                snd_soc_dapm_add_routes(&card->dapm, audio_map,
+                                        ARRAY_SIZE(audio_map));
+        }
+*/
+        /* not connected */
+    /*    snd_soc_dapm_nc_pin(&codec->dapm, "MONO_LOUT");
+        snd_soc_dapm_nc_pin(&codec->dapm, "HPLCOM");
+        snd_soc_dapm_nc_pin(&codec->dapm, "HPRCOM");
+*/
+        return 0;
+}
+
+
+
 /* davinci-evm digital audio interface glue - connects codec <--> CPU */
 static struct snd_soc_dai_link dm6446_evm_dai = {
        .name = "TLV320AIC3X",
@@ -250,6 +294,8 @@ static struct snd_soc_dai_link da850_evm_dai = {
                   SND_SOC_DAIFMT_IB_NF,
 };
 
+
+
 /* davinci dm6446 evm audio machine driver */
 /*
  * ASP0 in DM6446 EVM is clocked by U55, as configured by
@@ -343,16 +389,33 @@ static struct snd_soc_dai_link evm_dai_tlv320aic3x = {
        .stream_name    = "AIC3X",
        .codec_dai_name = "tlv320aic3x-hifi",
        .ops            = &evm_ops,
-       .init           = evm_aic3x_init,
+        .init           = evm_aic3x_init,
        .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM |
                   SND_SOC_DAIFMT_IB_NF,
 };
+/*Modified evm_dai_tlv320aic3x() for aic3110   */
+static struct snd_soc_dai_link evm_dai_tlv320aic3110 = {
+        .name           = "TLV320AIC3110",
+        .stream_name    = "AIC3110",   /* What should I put here? */
+        .codec_dai_name = "tlv320aic31xx-hifi",
+        .ops            = &evm_ops,
+        .init           = evm_aic31xx_init,
+        .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM |
+                   SND_SOC_DAIFMT_IB_NF,
+};
 
 static const struct of_device_id davinci_evm_dt_ids[] = {
        {
                .compatible = "ti,da830-evm-audio",
-               .data = (void *) &evm_dai_tlv320aic3x,
+               .data = (void *) &evm_dai_tlv320aic3x,  
+/*              .data = (void *) &evm_dai_tlv320aic3110,*/     
        },
+
+        {
+                .compatible = "ti,TLV320AIC3110-audio",
+                .data = (void *) &evm_dai_tlv320aic3110,
+        },
+
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, davinci_evm_dt_ids);


4-Add TLV320AIC3110_SOC_EVM build option. 

--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -13,7 +13,7 @@ config SND_DAVINCI_SOC_VCIF
 
 config SND_DAVINCI_SOC_GENERIC_EVM
        tristate
-       select SND_SOC_TLV320AIC3X
+       select SND_SOC_TLV320AIC31XX 
        select SND_DAVINCI_SOC_MCASP
 
 config SND_AM33XX_SOC_EVM
@@ -22,7 +22,7 @@ config SND_AM33XX_SOC_EVM
        select SND_DAVINCI_SOC_GENERIC_EVM
        help
          Say Y or M if you want to add support for SoC audio on AM33XX
-         boards using McASP and TLV320AIC3X codec. For example AM335X-EVM,
+         boards using McASP and TLV320AIC31XX codec. For example AM335X-EVM,
          AM335X-EVMSK, and BeagelBone with AudioCape boards have this
          setup.
 



5- Adding Device tree entries:
For Beaglebone Black KERNEL/arch/arm/boot/dts/am335x-boneblack.dts is used so we modify it to add the sound card.
--- a/arch/arm/boot/dts/am335x-boneblack.dts
+++ b/arch/arm/boot/dts/am335x-boneblack.dts
@@ -64,6 +64,11 @@
 /* Pins: P9.24, P9.28, P9.29, P9.31, P9.30 */
 /* #include "am335x-bone-audio.dtsi" */
 
+/*Customized Audio codec TLV320AIC31XX.C       */
+#include "am335x-bone-tlv320aic31xx.dtsi"      
+
+
+
 /* #include "am335x-bone-lcd3-01-00a2.dtsi" */
 

6- Create 
KERNEL/arch/arm/boot/dts/am335x-bone-tlv320aic31xx.dtsi
#include <dt-bindings/sound/tlv320aic31xx-micbias.h>

&i2c2 {
        tlv320aic3110: tlv320aic3110@18 {
                compatible ="ti,tlv320aic3110" ;
                reg = <0x18>;
                ai31xx-micbias-vg = <1>;
                status = "okay";
                /* Regulators */
                /* This might be eddited        */
                HPVDD-supply = <&ldo4_reg>;
                SPRVDD-supply = <&ldo4_reg>;
                SPLVDD-supply = <&ldo4_reg>;
                AVDD-supply = <&ldo4_reg>;
                IOVDD-supply = <&ldo4_reg>;
                DVDD-supply = <&vbat>;
        };
};

&mcasp0 {
        pinctrl-names = "default";
        pinctrl-0 = <&mcasp0_pins_audio>;
        status = "okay";
        op-mode = <0>;          /* MCASP_IIS_MODE */
        tdm-slots = <2>;
        num-serializer = <16>;
        serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
                2 0 1 0
                0 0 0 0
                0 0 0 0
                0 0 0 0
        >;
        tx-num-evt = <1>;
        rx-num-evt = <1>;
};
/ {
        sound {
                compatible = "ti,TLV320AIC3110-audio";
                ti,model = "DA830 EVM";
                ti,audio-codec = <&tlv320aic3110>;
                ti,mcasp-controller = <&mcasp0>;
                ti,codec-clock-rate = <12000000>;
                ti,audio-routing =
        /*              Source                  Sink            */
        /*                                      output in driver*/
        /*              Speaker connections                     */
                        "Headphone Jack",       "HPL",
                        "Headphone Jack",       "HPR",
                        "Speaker",              "SPL",
                        "Speaker",              "SPR",
                        "Mic Jack",             "MICBIAS",
        /*              Microphone connections                  */
        /*              input in driver                         */
                        "MIC1LP",                "Mic Jack",
                        "MIC1RP",                "Mic Jack",
                        "MIC1LM",                "Mic Jack";
        };
};



So at this point everything should be fine and I get sound from the codec. The only error that I have is about 
ai31xx-micbias-vg which cannot be initialized. 
I know that this works but am I doing everything right? I wonder if my approach is correct. \
By the way, the reason I was writing this was that I could not get the codec to work but by the time I finished writing this post aic3110 was working:)
Thanks for reading and your comments
-Alex

John Syn

unread,
Nov 14, 2014, 1:34:17 PM11/14/14
to beagl...@googlegroups.com

From: <resande...@gmail.com>
Reply-To: "beagl...@googlegroups.com" <beagl...@googlegroups.com>
Date: Thursday, November 13, 2014 at 5:46 PM
To: "beagl...@googlegroups.com" <beagl...@googlegroups.com>
Cc: <al...@webbelectronicsinc.com>
Subject: [beagleboard] Custom Beaglebone black Audio cape with TLV320AIC3110
If you look at Documentation/devicetree/bindings/sound/davinci-evm-audio.txt, you will see:

“MIC3L”, “Mic Bias 2V”
“MIC3R”, “Mic Bias 2V”
“Mic Bias 2V”,  “Mic Jack"

Regards,
John


So at this point everything should be fine and I get sound from the codec. The only error that I have is about 
ai31xx-micbias-vg which cannot be initialized. 
I know that this works but am I doing everything right? I wonder if my approach is correct. \
By the way, the reason I was writing this was that I could not get the codec to work but by the time I finished writing this post aic3110 was working:)
Thanks for reading and your comments
-Alex

--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Rick M

unread,
Nov 25, 2014, 7:01:29 PM11/25/14
to beagl...@googlegroups.com, al...@webbelectronicsinc.com, resande...@gmail.com


On Thursday, November 13, 2014 5:46:32 PM UTC-8, resande...@gmail.com wrote:
Hi,

I am trying to design a cape with TLV320AIC3110 for Beaglebone black using I2c2 and Mcasp0. 

Alex, I, too am looking to develop an audio application using a BBB, but know very little about Linux audio (I'm a capable-enough hardware engineer, and have lots of software development experience on iOS/OS X and numerous small processors, bare-metal, but not a ton of Linux). I essentially want to build a "radio," so I'll be developing a cape with audio out and amplifier. Your choice of IC might be adequate, or I'll find some other I2S chip (is I2S the same as your "I2c2"?). My cape will also have some additional electronics for interfacing the rest of my "radio's" user interface.

Could I ask you additional questions as I get further into this?

Thanks!

-- 
Rick

Peter Gregory

unread,
Nov 25, 2014, 8:08:42 PM11/25/14
to beagl...@googlegroups.com
I'm developing a clock-radio device using a USB sound card and a USB radio tuner.
Since it is a one-off project, I decided to use existing USB devices:

ADS RDX-155-EF Instant FM Music - $7.50
Plugable USB Audio Adapter - $7.95

Just a suggestion.

Rick

unread,
Nov 25, 2014, 8:11:34 PM11/25/14
to beagl...@googlegroups.com
Thanks, Peter. I'm doing something similar for the first pass of this, but if it works out, I'll want to make the cape so I can make a few more (they are intended to be gifts for special people), and so others can do the same.

Mine doesn't actually have a radio or clock in it. It's just an appliance that plays MP3s.
> --
> For more options, visit http://beagleboard.org/discuss
> ---
> You received this message because you are subscribed to a topic in the Google Groups "BeagleBoard" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/topic/beagleboard/8RU9ayMPBlc/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to beagleboard...@googlegroups.com.

resande...@gmail.com

unread,
Nov 26, 2014, 6:54:18 PM11/26/14
to beagl...@googlegroups.com, al...@webbelectronicsinc.com, resande...@gmail.com
Hi Rick,

I am hardware engineer too; Sounds like we are in the same boat:)

I essentially want to build a "radio," so I'll be developing a cape with audio out and amplifier

I would recommend you to have look at TLV320AIC3100 with class D 4ohm speaker driver.  It saves you amplifier design for driving speakers and has stereo Headphone ports. Needless to say, with class D amplifier you get the lowest power consumption possible compared to class AB etc. 
If you need stereo speaker output consider TLV320AIC3110.

(is I2S the same as your "I2c2"?)
No, TI calls I2S, Inter IC Sound, McASP which is a four wire bus. I2C is Inter-Integrated Circuit and is a two wire bus. For codec you need both of them. You need I2C for programming the registers and I2S for transmission of voice. 

Could I ask you additional questions as I get further into this?
That's what forum is for. It is pretty simple. Just connect your I2C and I2S to micros I2C and McASP, do the procedure that I wrote above, and you are done. 

Best regards,

-Alex 

resande...@gmail.com

unread,
Nov 26, 2014, 6:58:23 PM11/26/14
to beagl...@googlegroups.com
Just by the audio cape and you are done for MP3 player.

regards,

-A. 

Rick

unread,
Dec 1, 2014, 5:15:58 PM12/1/14
to beagl...@googlegroups.com
Which audio cape? I only know about this one: http://elinux.org/CircuitCo:Audio_Cape_RevB, which can't power a speaker.

Rick

unread,
Dec 1, 2014, 5:18:52 PM12/1/14
to beagl...@googlegroups.com, al...@webbelectronicsinc.com, resande...@gmail.com

> On Nov 26, 2014, at 15:54 , resande...@gmail.com wrote:
>
> Hi Rick,
>
> I am hardware engineer too; Sounds like we are in the same boat:)
>
> I essentially want to build a "radio," so I'll be developing a cape with audio out and amplifier
>
> I would recommend you to have look at TLV320AIC3100 with class D 4ohm speaker driver. It saves you amplifier design for driving speakers and has stereo Headphone ports. Needless to say, with class D amplifier you get the lowest power consumption possible compared to class AB etc.
> If you need stereo speaker output consider TLV320AIC3110.

Okay, good. I found that IC in my research, thought it might be useful.

> (is I2S the same as your "I2c2"?)
> No, TI calls I2S, Inter IC Sound, McASP which is a four wire bus. I2C is Inter-Integrated Circuit and is a two wire bus. For codec you need both of them. You need I2C for programming the registers and I2S for transmission of voice.

I realized after reading more that "i2c2" must've been the Sitara's I2C bus #2, and that I2S support was provided by McASP.

> Could I ask you additional questions as I get further into this?
> That's what forum is for. It is pretty simple. Just connect your I2C and I2S to micros I2C and McASP, do the procedure that I wrote above, and you are done.

Awesome, thanks!
>
> Best regards,
>
> -Alex
>
>
>
>
>
> On Tuesday, November 25, 2014 4:01:29 PM UTC-8, Rick M wrote:
>
>
> On Thursday, November 13, 2014 5:46:32 PM UTC-8, resande...@gmail.com wrote:
> Hi,
>
> I am trying to design a cape with TLV320AIC3110 for Beaglebone black using I2c2 and Mcasp0.
>
> Alex, I, too am looking to develop an audio application using a BBB, but know very little about Linux audio (I'm a capable-enough hardware engineer, and have lots of software development experience on iOS/OS X and numerous small processors, bare-metal, but not a ton of Linux). I essentially want to build a "radio," so I'll be developing a cape with audio out and amplifier. Your choice of IC might be adequate, or I'll find some other I2S chip (is I2S the same as your "I2c2"?). My cape will also have some additional electronics for interfacing the rest of my "radio's" user interface.
>
> Could I ask you additional questions as I get further into this?
>
> Thanks!
>
> --
> Rick
>

liyaoshi

unread,
Dec 1, 2014, 7:46:20 PM12/1/14
to beagl...@googlegroups.com
If your radio mean FM and AM without DAB , i recommend TEF6657

If with DAB ,TEF7741 DIRANA2 is better choice ,and this is a very general chip in audio CAR 

BTW , I had write a demo version TEF6657 audio driver , 

About the TLVAIC3104 , Its only have about 2w amplifier ,

for a 25x4 w amplifier , Your 5v2A power is not enough .

You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.

Rick

unread,
Dec 1, 2014, 7:55:54 PM12/1/14
to beagl...@googlegroups.com
No AM or FM here; the BBB will provide all the audio data.

liyaoshi

unread,
Dec 1, 2014, 8:01:32 PM12/1/14
to beagl...@googlegroups.com
NXP will have the Audio codec chip and FM/AM/DAB  combined 
Since your will build another cape , do you mean this ?
maybe you can consider about this 
Reply all
Reply to author
Forward
0 new messages