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.
Tool/software:
We are currently using TLV320AIC3106 codec on Sitara AM437x architecture and using SDK.05.02.00.10.
I have two questions.
Q1. Do you have suggestion on a different codec we can use that can give us better quality of AGC and noise filtering capabilities while also giving us an additional Echo Cancellation feature? We want to keep the overall design of our hardware based on the AM437x Starter Kit but replace the codec with minimal software changes? I believe the TLV320AIC32x0 Series codecs could be a good choice. Can I use the TLV320AIC32x0 Series codecs in place of the TLV320AIC3106 codec on Sitara AM437x architecture without requiring lots of changes in hardware and software design?
Q2. For our existing architecture, I wrote a program to write/read the TLV320AIC3106 codec registers using the i2c interface. I can write to enable LAGC on Register 26 Bit 7 for example and verify it was written by reading back the register. However, when using the amixer to verify if the write has occurred, I still get AGC set to off.
~# amixer sget AGC
Simple mixer control 'AGC',0
Capabilities: pswitch
Playback channels: Front Left - Front Right
Mono:
Front Left: Playback [off]
Front Right: Playback [off]
Isn't amixer reading back the registers? I also tried to set volume, microphone mute/unmute, and other features using the amixer command. And, still when I read back the registers using the i2c interface, I still do not get the updated value. Could you point me why the values amixer returns and the values I read directly from he registers do not match?
Regards,
Solan Bongase
Alertus Technologies
Hi Solan,
Q1) The AIC320x (I think there's a typo) is a direct upgrade from AIC310x. So you could replace with the AIC3206. https://www.ti.com/product/TLV320AIC3206. Pin wise and software wise they are very similar.
However the AGC architecture is the same in all of the TLV320AIC codecs. The AGC wasn't changed until some of our newer ADCs were released and the upgrade will be in the TAC5212 and its family of codecs which are releasing shortly, but you can buy samples now.
We also don't natively support echo cancellation on our codecs. The DSP strength required out paces what our current DSP codecs are able to do. We encourage customers to host the algorithm on some other SoC or DSP for the best performance and experience.
Q2) This will need to go to a different member of our team. I've forwarded the ticket.
Best regards,
Jeff McPherson
Hi Solan,
Just to make sure, do you have pulseaudio-alsa installed? Also, have you added yourself to the audio user group on the Linux device? It sounds like your ALSA is not communicating with the codec.
Let me know about this and also if you can run:
aplay -lL amixer -c1 pactl list cards pactl list sinks pactl list sink-inputs
And let me know what happens.
Best,
Mir
Thanks a lot, Jeff, for the quick response during the holiday season. I have a follow up question. I get your point that when it comes to AGC support, both AIC310x and AIC320x perform similarly. If we still however replace the AIC310x with AIC320x, do we expect better performance and features support for noise filtering and dynamic range compression?
Regards,
Solan
Hi Mir,
Thanks a lot for the quick response this week.
Yes, we have installed pulseudio-alsa on the board. In addition, the root is part of the audio group as also done here and verified.
root@board:~# usermod -a -G audio root
root@board:~# id -G root
0 29
root@board:~# id
uid=0(root) gid=0(root) groups=0(root),29(audio)
Here are also the responses of the commands you listed::
root@board:~# aplay -lL
null
Discard all samples (playback) or generate zero samples (capture)
pulse
PulseAudio Sound Server
default:CARD=SNDCARDNAME
SNDCARD-NAME,
Default Audio Device
sysdefault:CARD=SNDCARDNAME
SNDCARD-NAME,
Default Audio Device
**** List of PLAYBACK Hardware Devices ****
card 0: SNDCARDNAME [SNDCARD-NAME], device 0: davinci-mcasp.0-tlv320aic3x-hifi tlv320aic3x-hifi-0 []
Subdevices: 1/1
Subdevice #0: subdevice #0
root@board:~# amixer -c1
Invalid card number.
Usage: amixer <options> [command]
Available options:
-h,--help this help
-c,--card N select the card
-D,--device N select the device, default 'default'
-d,--debug debug mode
-n,--nocheck do not perform range checking
-v,--version print version of this program
-q,--quiet be quiet
-i,--inactive show also inactive controls
-a,--abstract L select abstraction level (none or basic)
-s,--stdin Read and execute commands from stdin sequentially
-R,--raw-volume Use the raw value (default)
-M,--mapped-volume Use the mapped volume
Available commands:
scontrols show all mixer simple controls
scontents show contents of all mixer simple controls (default command)
sset sID P set contents for one mixer simple control
sget sID get contents for one mixer simple control
controls show all controls for given card
contents show contents of all controls for given card
cset cID P set control contents for one control
cget cID get control contents for one control
root@board:~# pactl list cards
Card #0
Name: alsa_card.platform-sound
Driver: module-alsa-card.c
Owner Module: 1
Properties:
alsa.card = "0"
alsa.card_name = "SNDCARD-NAME"
alsa.long_card_name = "SNDCARD-NAME"
alsa.driver_name = "snd_soc_simple_card"
device.bus_path = "platform-sound"
sysfs.path = "/devices/platform/sound/sound/card0"
device.form_factor = "internal"
device.string = "0"
device.description = "Built-in Audio"
module-udev-detect.discovered = "1"
device.icon_name = "audio-card"
Profiles:
input:analog-stereo: Analog Stereo Input (sinks: 0, sources: 1, priority: 60, available: yes)
output:analog-stereo: Analog Stereo Output (sinks: 1, sources: 0, priority: 6000, available: yes)
output:analog-stereo+input:analog-stereo: Analog Stereo Duplex (sinks: 1, sources: 1, priority: 6060, available: yes)
off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
Active Profile: output:analog-stereo+input:analog-stereo
Ports:
analog-input: Analog Input (priority: 10000, latency offset: 0 usec)
Part of profile(s): input:analog-stereo, output:analog-stereo+input:analog-stereo
analog-output: Analog Output (priority: 9900, latency offset: 0 usec)
Part of profile(s): output:analog-stereo, output:analog-stereo+input:analog-stereo
root@board:~# pactl list sinks
Sink #0
State: SUSPENDED
Name: alsa_output.platform-sound.analog-stereo
Description: Built-in Audio Analog Stereo
Driver: module-alsa-card.c
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right
Owner Module: 1
Mute: no
Volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
balance 0.00
Base Volume: 65536 / 100% / 0.00 dB
Monitor Source: alsa_output.platform-sound.analog-stereo.monitor
Latency: 0 usec, configured 0 usec
Flags: HARDWARE HW_VOLUME_CTRL DECIBEL_VOLUME LATENCY
Properties:
alsa.resolution_bits = "16"
device.api = "alsa"
device.class = "sound"
alsa.class = "generic"
alsa.subclass = "generic-mix"
alsa.name = ""
alsa.id = "davinci-mcasp.0-tlv320aic3x-hifi tlv320aic3x-hifi-0"
alsa.subdevice = "0"
alsa.subdevice_name = "subdevice #0"
alsa.device = "0"
alsa.card = "0"
alsa.card_name = "SNDCARD-NAME"
alsa.long_card_name = "SNDCARD-NAME"
alsa.driver_name = "snd_soc_simple_card"
device.bus_path = "platform-sound"
sysfs.path = "/devices/platform/sound/sound/card0"
device.form_factor = "internal"
device.string = "hw:0"
device.buffering.buffer_size = "131072"
device.buffering.fragment_size = "65536"
device.access_mode = "mmap+timer"
device.profile.name = "analog-stereo"
device.profile.description = "Analog Stereo"
device.description = "Built-in Audio Analog Stereo"
module-udev-detect.discovered = "1"
device.icon_name = "audio-card"
Ports:
analog-output: Analog Output (priority: 9900)
Active Port: analog-output
Formats:
pcm
root@board:~# pactl list sink-inputs
root@board:~#
Thanks again for your time, Mir.
Regards,
Solan
Hi Solan,
It looks like you are not using the device's driver, just an example driver. snd_soc_simple card. So, the device is not linked correctly to ALSA. Make sure you download the tlv320aic3x driver and are using it in this implementation. You may have to specify in a dts file. Here is the driver and its documentation:
Let me know what happens with those commands after this driver is installed.
Best,
Mir
Hi Mir,
This is what I am getting from the dmesg. As you can see, the snd_soc_tlv320aic3x driver is liked.
[ 8.193212] of_get_named_gpiod_flags: can't parse 'gpio-reset' property of node '/ocp@44000000/i2c@4802a000/tlv320aic3106@1b[0]'
[ 8.300444] spidev spi1.0: buggy DT: spidev listed directly in DT
[ 8.300452] ------------[ cut here ]------------
[ 8.300479] WARNING: CPU: 0 PID: 140 at drivers/spi/spidev.c:730 spidev_probe+0x1a4/0x1d4 [spidev]
[ 8.300483] Modules linked in: spidev(+) snd_soc_tlv320aic3x wkup_m3_ipc at24 phy_omap_usb2 rtc_omap omap_wdt wkup_m3_rproc remoteproc sch_fq_codel uio_module_drv(O) uio ftdi_sio usbserial usbcore usb_common cryptodev(O) cmemk(O)
[ 9.171970] of_get_named_gpiod_flags: can't parse 'simple-audio-card,hp-det-gpio' property of node '/sound[0]'
[ 9.171980] of_get_named_gpiod_flags: can't parse 'simple-audio-card,mic-det-gpio' property of node '/sound[0]'
[ 9.201967] asoc-simple-card sound: tlv320aic3x-hifi <-> 4803c000.mcasp mapping ok
Using lsmod, the following drivers are loaded too:
root@alertus-tts2:~# lsmod | grep snd
snd_soc_simple_card 16384 2
snd_soc_simple_card_utils 16384 1 snd_soc_simple_card
snd_soc_tlv320aic3x 57344 1
The dts we are using specfies the tlv320aic3x module as follows also:
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "Alertus-TTS2";
simple-audio-card,widgets =
"Headphone", "Headphone Jack",
"Microphone", "Mic Jack"; //Edited to enable analog MIC
simple-audio-card,routing =
"Headphone Jack", "HPLOUT",
"Headphone Jack", "HPROUT",
"MIC3L", "Mic Jack", //Edited to enable analog MIC
"MIC3R", "Mic Jack", //Edited to enable analog MIC
"Mic Jack", "Mic Bias"; //Added to enable analog MIC
simple-audio-card,format = "dsp_b";
simple-audio-card,bitclock-master = <&sound_master>;
simple-audio-card,frame-master = <&sound_master>;
simple-audio-card,bitclock-inversion;
simple-audio-card,cpu {
sound-dai = <&mcasp1>;
};
sound_master: simple-audio-card,codec {
sound-dai = <&tlv320aic3106>;
system-clock-frequency = <24000000>;
};
};
&i2c1 { //CODEC
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins>;
clock-frequency = <400000>;
tlv320aic3106: tlv320aic3106@1b { //Audio Codec
#sound-dai-cells = <0>;
compatible = "ti,tlv320aic3106";
reg = <0x1b>;
status = "okay";
ai3x-micbias-vg = <1>; //AVDD selected as MIC Bias voltage (1 = 2.0V, 2 = 2.5V, 3 = 3.3V)
/* Regulators */
AVDD-supply = <&dcdc4>;
IOVDD-supply = <&dcdc4>;
DRVDD-supply = <&dcdc4>;
DVDD-supply = <&ldo1>;
};
};
root@alertus-tts2:~# cat /sys/module/snd_soc_tlv320aic3x/drivers/i2c\:tlv320aic3x-codec/1-001b/name
tlv320aic3106
From what I see, the board is using the driver for the codec tlv320aic3106.
Am I missing something here?
Thanks again for your time.
Regards,
Solan
Hi,
Maybe your issue is from incorrect routing terminology? Looking at the driver I don't see the term "Headphone" fully written out anywhere in the routing setup. You can check the "snd_soc_dapm_route" sections of the driver to see the possible options for the routing connection. Can you try "HPLOUT", "Left HP Out" and similar language in your routing and widgets sections?
This yaml file also explains which names can be used in the routing property: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/devicetree/bindings/sound/ti,tlv320aic3x.yaml
If this isn't the issue, I apologize. Are you sure that the mute and unmute and volume change is not working? Or is it just not updating the i2c?
Best,
Mir
Hi Mir,
I will check the routing as you suggested. In the meantime, I wanted to let you know that mute, unmute and AGC commands using the amixer command actually work for me So, it is definitely able to make changes. However, when I then read the corresponding registers of the TLV320AIC3106 codec using i2c, then I still see the registers not being set accordingly. That is my issue.
Regards,
Solan
Interesting, I can ask our Linux driver expert about this. Maybe the amixer commands do not affect the actual i2c and are another layer of audio control on the computer instead of on the codec itself. Not sure, this is just a theory. I will ask around and see what I find out next week.
Hi Mir,
I hope you had a good weekend. I wanted to check with you if you have heard from your Linux driver expert with respect to the issue where what we set with amixer is not correspondingly read from the i2c registers..
Regards,
Solan
Hi Solan,
I heard back, and yes the amixer normally sets i2c commands corresponding to the action, at least for AGC and routing settings. There is a chance that the mute doesn't change the i2c... but if nothing is changing in the i2c even after you change the routing for example, it is likely an issue with i2c register caching. You may want to change, in the tlv320aic3x.c driver:
.cache_type = REGCACHE_NONE, //originally "REGCACHE_RBTREE,"
This is here in the driver.
I got this idea to fix it from this forum post: https://forums.developer.nvidia.com/t/i2c-read-problem/274668 which isn't your exact problem but I hope it helps. Let me know if this fixes the issue!
Best,
Mir