This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/AM4378: AIC3106 configuration

Part Number: AM4378
Other Parts Discussed in Thread: TLV320AIC3106, TMDSEVM437X,

Tool/software: Linux

2 parter: 

1) when setting up my custom codec configuration for the tlv320aic3106 codec attached to the 4378 EVM GP board (not the on board codec, an additional one attached to a header) i am using this as the details:

sound1: sound1 {
compatible = "simple-audio-card";
simple-audio-card,name = "AM437x-GP-EVM-UTI";
simple-audio-card,widgets =
"Line Out Jack", "Headphone",
"Line In Jack", "Microphone";
simple-audio-card,routing =
"Line Out Jack", "MONO_LOUT",
"Headphone", "LLOUT",
"LINE1L", "Microphone",
"LINE2R", "Line In";
simple-audio-card,format = "dsp_b";
simple-audio-card,bitclock-master = <&sound1_master>;
simple-audio-card,frame-master = <&sound1_master>;
simple-audio-card,bitclock-inversion;

simple-audio-card,cpu {
sound-dai = <&mcasp0>;
system-clock-frequency = <12000000>;
};

sound1_master: simple-audio-card,codec {
sound-dai = <&tlv320aic3106>;
system-clock-frequency = <12000000>;
};
};

and i get this as output:

[ 19.191861] asoc-simple-card sound1: ASoC: no sink widget found for Line Out Jack 
[ 19.273897] FAT-fs (mmcblk1p1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck. 
[ 19.464054] asoc-simple-card sound1: ASoC: Failed to add route MONO_LOUT -> direct -> Line Out Jack 
[ 19.638265] asoc-simple-card sound1: ASoC: no source widget found for Line In 
[ 19.783832] asoc-simple-card sound1: ASoC: Failed to add route Line In -> direct -> LINE2R

based on "widgets.txt" i see my options are:

simple-audio-widgets =
"Microphone", "Microphone Jack",
"Line", "Line In Jack",
"Line", "Line Out Jack",
"Headphone", "Headphone Jack",
"Speaker", "Speaker External";

based on the file tlv320aic3x.c the only output options for the 3106 seem to be:

SND_SOC_DAPM_OUTPUT("LLOUT"),
SND_SOC_DAPM_OUTPUT("RLOUT"),
SND_SOC_DAPM_OUTPUT("HPLOUT"),
SND_SOC_DAPM_OUTPUT("HPROUT"),
SND_SOC_DAPM_OUTPUT("HPLCOM"),
SND_SOC_DAPM_OUTPUT("HPRCOM"),

SND_SOC_DAPM_INPUT("LINE1L"),
SND_SOC_DAPM_INPUT("LINE1R"),

and it seems that MONO_LOUT is not defined for the 3106 codec, but are 3104 only. is that correct?

i see this:

SND_SOC_DAPM_INPUT("MIC3L"),
SND_SOC_DAPM_INPUT("MIC3R"),
SND_SOC_DAPM_INPUT("LINE2L"),
SND_SOC_DAPM_INPUT("LINE2R"),  under the section "for other than 3104" but it still doesn't route upon booting. what's up with that?

2) what code do i have to execute to route audio to a different input/output in my program? assuming amixer for ALSA. there doesn't seem to be a very obvious example of this when i looked for it. i can't imagine this is that uncommon of a request that there aren't many examples or i am overhtinking it and it is easier than i am making it

thanks

  • Hi Cobsonchael,

    Do you use AM437x TI PSDK? If yes, which version?

    TMDSEVM437X comes with Headphone OUT connector (J16) and Microphone IN connector (J14). These two connectors are attached to default AIC3106 codec and are described as below:

    am437x-gp-evm.dts

    simple-audio-card,widgets =
    "Headphone", "Headphone Jack",
    "Line", "Line In";

    simple-audio-card,routing =
    "Headphone Jack", "HPLOUT",
    "Headphone Jack", "HPROUT",
    "LINE1L", "Line In",
    "LINE1R", "Line In";

    Do you use other connectors for your second AIC3106 codec? Please describe what exactly (headphone, microphone, etc) you have attached to your second AIC3106 codec.

    Regards,
    Pavel
  • yeah we are using the SDK, 4.03

    we have a daughter board that we connecting to the main EVM via a ribbon cable. this daughter board has a codec on it and i am trying to route the audio appropriately, hence my DTS file and attempting to connect to other ports on the codec.

    we have a telephone line interface connected to LINE2R input, and MONO_L output, a microphone connected to LINE1L input and a speaker connected to LEFT_LO

  • cobsonchael said:
    simple-audio-card,widgets =
    "Line Out Jack", "Headphone",

    cobsonchael said:
    [ 19.191861] asoc-simple-card sound1: ASoC: no sink widget found for Line Out Jack 

    You should use these widgets: "Microphone", "Line", "Headphone", "Speaker"

    For example:

    simple-audio-widgets =

    "Line", "Line Out Jack"

    "Headphone", "Headphone Jack"

    "Microphone", "Mic Jack",

    Each entry is a pair of strings in DT:

        "template-wname", "user-supplied-wname"

    The "template-wname" being the template widget name and currently includes: "Microphone", "Line", "Headphone" and "Speaker".

    The "user-supplied-wname" being the user specified widget name.

    Regards,
    Pavel

  • that is helpful information. thank you

    how about helping me with question #2?
  • cobsonchael said:
    2) what code do i have to execute to route audio to a different input/output in my program? assuming amixer for ALSA. there doesn't seem to be a very obvious example of this when i looked for it. i can't imagine this is that uncommon of a request that there aren't many examples or i am overhtinking it and it is easier than i am making it

    Yes, amixer can be used, please go through below pointers:

    Regards,
    Pavel

  • ok so helping with amixer stuff is beyond your scope

    given this setup:
    a telephone line interface connected to LINE2R input, and MONO_L output,
    a microphone connected to LINE1L input and a speaker connected to LEFT_LO

    is this the right way to declare widgets and routing:
    simple-audio-card,widgets =
    "Line", "POTS Line Out",
    "Speaker", "Handset Speaker";
    "Line", "POTS Line In",
    "Microphone", "Handset Mic",
    simple-audio-card,routing =
    "POTS Line Out", "MONO_LOUT",
    "Handset Speaker", "LLOUT",
    "LINE1L", "Handset Mic",
    "LINE2R", "POTS Line In";
  • cobsonchael said:
    is this the right way to declare widgets and routing:

    This seems correct to me.

    Regards,
    Pavel

  • i don't seem to be getting any meaningful input. i am getting samples but it just seems to be some DC value that barely changes on both inputs.

    is there any meaning to "Speaker" "Headphone" "Microphone" and "Line"? are they just labels that mean nothing or does something different happen depending on which one you use? do they correspond to the codec inputs and outputs?
  • cobsonchael said:
    i don't seem to be getting any meaningful input. i am getting samples but it just seems to be some DC value that barely changes on both inputs.

    On which input pins you are not getting the data you expect? On AM437x device McASP pins or AIC3106 codec pins?

    cobsonchael said:
    is there any meaning to "Speaker" "Headphone" "Microphone" and "Line"? are they just labels that mean nothing or does something different happen depending on which one you use? do they correspond to the codec inputs and outputs?

    These are just labels. You name the jacks of the board, then route these jacks (POTS Line Out, Handset Speaker) with audio codecs pins (MONO_LOUT, LLOUT).

    Regards,
    Pavel

  • the DC values i am reading from the codec coming off the McASP lines. it seems that there is audio going into the codec. i can transmit out of the codec just fine, but i don't seem to be getting any meaningful input. i had input working for the on-board codec using mostly the same code so i am unsure what would be different in this situation (besides the hardware). i am aware it could be an issue with our custom daughter board.


    i know you guys didn't invent the ALSA protocol/library/drivers/whatever, but it should does seem like it would make a lot more sense to just have "Input" and "Output" instead of arbitrary labels, especially when you come up with your own custom labels anyway and just use those. oh well, another quirk to learn
  • i did just get the handset microphone to work. the mic bias was not set and i found online that i needed to include this: ai3x-micbias-vg = <1>; and now that works.

    still no audio from the telephone line interface side of the codec but i did confirm that differential signals are going into the codec at Line2R

  • cobsonchael said:
    still no audio from the telephone line interface side of the codec but i did confirm that differential signals are going into the codec at Line2R

    From what I understand, you have:

    AM437x McASP <-------- AIC3106 codec <---- Telephone Line In <---------- LINE2R

    And you see that audio data is going from LINE2R pin to AIC3106 codec? But then this audio data is not going to AM437x McASP data pin?

    Regards,
    Pavel

  • it is Phone line from DAA chip -> LINE2R on codec -> McASP to AM4378 and a signal is going from DAA chip to Line2R but i hear nothing when i route that channel to my headset and when i look at the data it appears to be a DC value plus some slight noise
  • Cobsonchael,

    From what I understand, your current issue is related to AIC3106 audio codec. This codec is supported in other e2e forum (link below), you can try to ask/post there.

    e2e.ti.com/.../6

    If you have questions related to AM437x McASP module, please let me know.

    Regards,
    Pavel
  • that may not be true if the routing is incorrect. how do i VERIFY that my routing is correct and that i am trying to read from the right input port?
  • so is it a codec forum question or a linux question about how to verify that my audio is being source from the right port?
  • Cobsonchael,

    On AM437x TI EVM, when arecord command is executed (or audio capture appl is started), there should be audio data flow started on LINE1L and LINE1R pins. Check how the audio capture works there and compare with LINE2R.

    You can also enable debug messages and trace the kernel boot flow.

    Check also if below links will be in help:

    www.ti.com/.../sprac09a.pdf
    www.ti.com/.../sprac10.pdf

    processors.wiki.ti.com/.../Linux_Core_Audio_User's_Guide

    Regards,
    Pavel
  • everything i see in alsa shows only 1 recording device so is it possible that alsa only records 1 input at a time?
  • Yes, you can have more than one audio input. Use "arecord -l" to check what audio input you have available on your board. See also below pointers for more info:

    processors.wiki.ti.com/.../ALSA
    linux.die.net/.../arecord

    e2e.ti.com/.../1881020
    e2e.ti.com/.../2381238
    e2e.ti.com/.../214235

    Regards,
    Pavel
  • when i do "amixer" i get:

    Simple mixer control 'Left PGA Mixer Line1L',0
    Capabilities: pswitch pswitch-joined
    Playback channels: Mono
    Mono: Playback [on]

    which, if "Mono: Playback" means the samples are being collected is right

    and

    Simple mixer control 'Right PGA Mixer Line1L',0
    Capabilities: pswitch pswitch-joined
    Playback channels: Mono
    Mono: Playback [off]
    Simple mixer control 'Right PGA Mixer Line1R',0
    Capabilities: pswitch pswitch-joined
    Playback channels: Mono
    Mono: Playback [on]
    Simple mixer control 'Right PGA Mixer Line2R',0
    Capabilities: pswitch pswitch-joined
    Playback channels: Mono
    Mono: Playback [off]

    which looks like it is pulling from Line1R which is wrong

    even though in my DTS file i have:

    simple-audio-card,widgets =
    "Speaker", "POTS Line Out",
    "Speaker", "Handset Speaker",
    "Line", "POTS Line In",
    "Microphone", "Handset Mic";
    simple-audio-card,routing =
    "POTS Line Out", "MONO_LOUT",
    "Handset Speaker", "LLOUT",
    "LINE2R", "POTS Line In",
    "LINE1L", "Handset Mic",
    "Handset Mic", "Mic Bias";
  • i think i figured it out:

    /****************************************************************************************
    * found @ alsa.opensrc.org/HowTo_access_a_mixer_control
    */
    void SetInputToLine2R(void)
    {

    const char *card = "default";
    const char *selem_name_line1r = "Right PGA Mixer Line1R Switch";
    const char *selem_name_line2r = "Right PGA Mixer Line2R Switch";
    int err;

    snd_hctl_t *hctl;
    err = snd_hctl_open(&hctl, card, 0);
    err = snd_hctl_load(hctl);

    snd_ctl_elem_id_t *id;
    snd_ctl_elem_id_alloca(&id);
    snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
    //snd_ctl_elem_id_set_id(id, 1);

    snd_ctl_elem_id_set_name(id, selem_name_line1r);
    snd_hctl_elem_t *elem = snd_hctl_find_elem(hctl, id);

    if(elem != 0)
    {
    snd_ctl_elem_value_t *control;
    snd_ctl_elem_value_alloca(&control);
    snd_ctl_elem_value_set_id(control, id);

    snd_ctl_elem_value_set_integer(control, 0, 0);
    err = snd_hctl_elem_write(elem, control);

    //turn on line2r
    snd_ctl_elem_id_set_name(id, selem_name_line2r);
    elem = snd_hctl_find_elem(hctl, id);

    if(elem != 0)
    {
    snd_ctl_elem_value_set_integer(control, 0, 1);
    err = snd_hctl_elem_write(elem, control);
    }
    }
    snd_hctl_close(hctl);

    }