[TAS2557 / TAS2563] Implement driver from kernel source

Hello,

I would like to add driver to TAS2557 to my system, which is in source kernel for Jetpack 4.6.1. Finally I will use TAS2563 which is compatible with TAS2557 (information is based on TI webside).
Can you tell me what I should do to use this driver with I2S3 (pins 220, 222, 224,226) and I2C3 (232, 234)

Please refer to NVIDIA Jetson Linux Driver Package Software Features : Audio Setup and Development | NVIDIA Docs

Thanks

Hello,

Thanks for this link. I spent last days on implement TAS2563 IC in Linux system. Finally I use driver from manufacturer (lpaa-android-drivers/tas2505-linux-driver - Unnamed repository; edit this file 'description' to name the repository.).
What I did:

  1. placed driver to kernel source - kernel/kernel-4.9/sound/soc/codecs and added driver to Kconfig & Makefile
    tas2505.c (22.1 KB)
    tas2505.h (3.2 KB)

  2. Modified device tree:
    tegra210-porg-p3448-common.dtsi (22.1 KB)

  3. Modified kernel/nvidia/sound/soc/tegra_alt/machine_driver/tegra_machine_driver_mobile.c:
    tegra_machine_driver_mobile.c (23.6 KB)

  4. Selected SND_SOC_TAS2505 in kernel/nvidia/sound/soc/tegra_alt/Kconfig

  5. Added “CONFIG_SND_SOC_TAS2505=y” in file kernel/kernel-4.9/arch/arm64/configs/tegra_defconfig

Main problem is with load driver in system (sound card doesn’t display in system). I get error:
[ 1.832278] tegra-asoc: sound: ASoC: CPU DAI DAP not registered
[ 1.838808] tegra-asoc: sound: snd_soc_register_card failed (-517)

I read about this error but solutions on forum didn’t help me to resolve this problem.
Below is dmesg log with enable debug for soc-core.c and tegra210_i2s_alt.c::
dmesg_log_all.txt (77.3 KB)

Can you give me some advice what is wrong?

Since you replaced the kernel, what do you see for:
uname -r

Also, are there modules or files at:
/lib/modules/$(uname -r)/kernel/
(it doesn’t matter what files are there, I just want to know they are present for the kernel to find)

I work on Jetpack 4.6.1 and module p3448-0002-b00 in custom carrier board (layout is fine because I run this IC without driver - manualy)

The “uname -r” and list of files in “/lib/modules/$(uname -r)/kernel” should work. It is odd though that your “CONFIG_LOCALVERSION” shows as:
CONFIG_LOCALVERSION="-tegra-tegra"
(the “-tegra” is there twice…it won’t matter functionally, but it is quite odd to see it duplicated)

I found why “-tegra” was duplicated.
I wrote CONFIG_LOCALVERSION = “-tegra” in .config file then I used command “export LOCALVERSION=-tegra” I think that this is result of mixed two tutorials to build custom kernel.
Back to the main topic, I think that module for TAS2505 isn’t add to compilation because I don’t see any logs during compilation kernel. I added this modules to configuration file Jetson_Linux_R32_6_1/TEGRA_KERNEL_OUT.config. Logs from compilation:
compilation_kernel_logs.txt (73.9 KB)
Where else I must place information about this codec to compile module for it?

Yes, that sounds about right. And it is interesting!

About this step:

This “integrates” into the kernel Image (because it is “=y” and not “=m”) and does not build a module. Not all drivers can exist as a module, and not all modules can be integrated directly into the kernel, though almost everything can go directly into the kernel and much into the form of a module). To know if that config actually shows up you have to check “/proc/config.gz”, which is not a real file (it is in RAM and is provided directly by the kernel to show its configuration in a compressed format). If you run this command, what shows up?
zcat /proc/config.gz | egrep -i '(snd_soc_tas2505|soc_tas2505)'
(this will list those config items if they exist in either module or integrated format)

If those exist as either “=y” or “=m”, then it is possible the drivers work. If “=m”, then the module must also be loaded. For both cases there is probably also user space software on top of this. Once we know the drivers made it in we can look at whether user space software is doing its job.

I decided that I want to add driver to kernel Image so I set as previous CONFIG_SND_SOC_TAS2505=y in defconfig file.
Answer to command: zcat /proc/config.gz | egrep -i ‘tas2505’ is CONFIG_SND_SOC_TAS2505=y.
Still I don’t see sound card after use command sudo cat /proc/asound/cards.
I folow troubleshooting (https://docs.nvidia.com/jetson/archives/l4t-archived/l4t-3261/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/asoc_driver.19.2.html#wwpID0E0QE0HA)

$ dmesg | grep “ASoC”
dmesg_grep_ASoC.txt (38.4 KB)

$ sudo cat /sys/kernel/debug/asoc/codecs
tegra210-ope.1
tegra210-ope.0
tegra210-mvc.1
tegra210-mvc.0
tegra210-afc.5
tegra210-afc.4
tegra210-afc.3
tegra210-afc.2
tegra210-afc.1
tegra210-afc.0
tegra210-sfc.3
tegra210-sfc.2
tegra210-sfc.1
tegra210-sfc.0
tegra210-mixer
tegra210-adx.1
tegra210-adx.0
tegra210-amx.1
tegra210-amx.0
tegra210-dmic.1
tegra210-dmic.0
tegra210-i2s.2
tegra210-admaif
tegra210-axbar
tas2505-codec.3-004c
7.spdif-dit.7
6.spdif-dit.6
5.spdif-dit.5
4.spdif-dit.4
3.spdif-dit.3
2.spdif-dit.2
1.spdif-dit.1
0.spdif-dit.0
snd-soc-dummy

Above data show that:
“tegra210-i2s.2” tas2505 codec must config in nvidia,dai-link-2
“tas2505-codec.3-004c” and tas2505 is connect to I2S3 and use I2C address 0x4c.
Do I have right?

$ sudo zcat /proc/config.gz | grep CONFIG_SND_SOC_SPDIF
CONFIG_SND_SOC_SPDIF=y

$ sudo i2cdetect -y -r 2
[sudo] password for uni:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: – – – – – – – – – – – – –
10: – – – – – – – – – – – – – – – –
20: – – – – – – – – – – – – – – – –
30: – – – – – – – – – – – – – – – –
40: – – – – – – – – 48 – – – 4c – – –
50: 50 – – – – – – 57 – – – – – – – –
60: – – – – – – – – – 69 – – – – – –
70: – – – – – – – –

I think, that most problem is that address of I2C (0x4c) is still available so driver isn’t load correctly. Can you check my device tree files again?
tegra210-porg-p3448-common.dtsi (21.5 KB)
tegra210-porg-super-module-e2614.dtsi (8.9 KB)
tas2505.c (22.1 KB)
tas2505.h (3.2 KB)
tegra_machine_driver_mobile.c (23.6 KB)
I didn’t modify tegra210_i2s_alt.c
tegra210_i2s_alt.c (35.0 KB)

Likely this will do what you expect, but unless you set it to “=y” with a config editor, then you don’t know for sure that this was correct. Some content must be installed as a module (if this was from third party source external to the kernel, then likely integrating with “=y” would fail because most third party drivers from outside the kernel source intended for compile as a module).

I’m not qualified to help much with audio setup, but if the ASoC messages you logged are from this driver, then it sounds like the driver itself is installed and working. I’m not sure about the other setup, e.g., i2s or i2c, but even if I did know that, then the custom carrier board would have altered the instructions anyway. Someone else will have to help with configuring after this step.

Today I compiled system (without errors) based on setting “=m” for driver. Then I replace kernel and device tree. I add module manually :
sudo insmod snd-compress.ko
sudo insmod snd-soc-core.ko
sudo insmod snd-soc-tas2505.ko
sudo depmod -a

Modules was loaded:
$ lsmod
Module Size Used by
snd_soc_tas2505 10572 0
snd_soc_core 239679 1 snd_soc_tas2505
snd_compress 20182 1 snd_soc_core

debug logs:
$ sudo zcat /proc/config.gz | grep CONFIG_SND_SOC_SPDIF
CONFIG_SND_SOC_SPDIF=m

$ sudo zcat /proc/config.gz | egrep -i 'tas2505
CONFIG_SND_SOC_TAS2505=m

$ sudo cat /proc/asound/cards
0 [tegrahda ]: tegra-hda - tegra-hda
tegra-hda at 0x70038000 irq 82

$dmesg

[ 239.978963] No Device Node present for smmu client: snd-soc-dummy !!
[ 239.978972] platform snd-soc-dummy: No iommus property found in DT node, got swgids from fixup(101004000)
[ 239.988880] iommu: Adding device snd-soc-dummy to group 35
[ 239.989239] snd-soc-dummy snd-soc-dummy: codec register snd-soc-dummy
[ 239.989247] snd-soc-dummy snd-soc-dummy: ASoC: dai register snd-soc-dummy #1
[ 239.989251] snd-soc-dummy snd-soc-dummy: ASoC: dynamically register DAI snd-soc-dummy
[ 239.989255] snd-soc-dummy snd-soc-dummy: ASoC: Registered DAI ‘snd-soc-dummy-dai’
[ 239.989260] snd-soc-dummy snd-soc-dummy: ASoC: Registered codec ‘snd-soc-dummy’
[ 239.989264] snd-soc-dummy snd-soc-dummy: ASoC: platform register snd-soc-dummy
[ 239.989268] snd-soc-dummy snd-soc-dummy: ASoC: Registered platform ‘snd-soc-dummy’
[ 253.273206] tas2505-codec 3-004c: codec register 3-004c
[ 253.273217] tas2505-codec 3-004c: ASoC: dai register 3-004c #1
[ 253.273221] tas2505-codec 3-004c: ASoC: dynamically register DAI 3-004c
[ 253.273226] tas2505-codec 3-004c: ASoC: Registered DAI ‘tas2505-hifi’
[ 253.273231] tas2505-codec 3-004c: ASoC: Registered codec ‘tas2505-codec.3-004c’

As you can see modules was loaded but doesn’t work. Sound card doesn’t appeared.
Can you help me with debug?

If the module loads, then the hardware should be present (likely load would fail if there were no hardware). However, there might be some other requirement as well (just speculating, and I don’t know of any audio hardware requiring firmware, but firmware missing is an example of the device not working despite having the driver).

What happens if you monitor “dmesg --follow”, and then try to manually remove the module and reinsert it with rmmod and insmod? Refusing to rmmod would be a sign that the system saw the device and loaded the driver to it.

Above logs (post #12) was during manually adding modules via insmod.

I’m also interested in what happens if you’ve run commands to find or configure audio, and then “rmmod” the module. If it cannot rmmod, then it is a sign the kernel thinks or knows the hardware is there and in use.

Ok, I understand your approach, but below logs are after changes:

  • I made mistake in choose address of I2C. It should be i2c@7000c500 (earlierI set i2c@7000c700, because I made mistake in count when i2c@7000c500 didn’t exist i source)
  • I set SND_SOC_SPDIF, snd-compress, snd-soc-core build in kernel Image. snd-soc-tas2505 I compile as module.

After these changes I see that register 0x4c on I2C is “UU”, but sound card doesn’t exist.
Logs:
$ dmesg |grep “ASoC”
[ 1.899952] snd-soc-dummy snd-soc-dummy: ASoC: dai register snd-soc-dummy #1
[ 1.899955] snd-soc-dummy snd-soc-dummy: ASoC: dynamically register DAI snd-soc-dummy
[ 1.899960] snd-soc-dummy snd-soc-dummy: ASoC: Registered DAI ‘snd-soc-dummy-dai’
[ 1.899964] snd-soc-dummy snd-soc-dummy: ASoC: Registered codec ‘snd-soc-dummy’
[ 1.899967] snd-soc-dummy snd-soc-dummy: ASoC: platform register snd-soc-dummy
[ 1.899972] snd-soc-dummy snd-soc-dummy: ASoC: Registered platform ‘snd-soc-dummy’
[ 1.900270] spdif-dit 0.spdif-dit.0: ASoC: dai register 0.spdif-dit.0 #1
[ 1.900273] spdif-dit 0.spdif-dit.0: ASoC: dynamically register DAI 0.spdif-dit.0
[ 1.900277] spdif-dit 0.spdif-dit.0: ASoC: Registered DAI ‘dit-hifi’
[ 1.900280] spdif-dit 0.spdif-dit.0: ASoC: Registered codec ‘0.spdif-dit.0’
[ 1.900307] spdif-dit 1.spdif-dit.1: ASoC: dai register 1.spdif-dit.1 #1
[ 1.900310] spdif-dit 1.spdif-dit.1: ASoC: dynamically register DAI 1.spdif-dit.1
[ 1.900313] spdif-dit 1.spdif-dit.1: ASoC: Registered DAI ‘dit-hifi’
[ 1.900316] spdif-dit 1.spdif-dit.1: ASoC: Registered codec ‘1.spdif-dit.1’
[ 1.900342] spdif-dit 2.spdif-dit.2: ASoC: dai register 2.spdif-dit.2 #1
[ 1.900345] spdif-dit 2.spdif-dit.2: ASoC: dynamically register DAI 2.spdif-dit.2
[ 1.900349] spdif-dit 2.spdif-dit.2: ASoC: Registered DAI ‘dit-hifi’
[ 1.900352] spdif-dit 2.spdif-dit.2: ASoC: Registered codec ‘2.spdif-dit.2’
[ 1.900378] spdif-dit 3.spdif-dit.3: ASoC: dai register 3.spdif-dit.3 #1
[ 1.900381] spdif-dit 3.spdif-dit.3: ASoC: dynamically register DAI 3.spdif-dit.3
[ 1.900384] spdif-dit 3.spdif-dit.3: ASoC: Registered DAI ‘dit-hifi’
[ 1.900387] spdif-dit 3.spdif-dit.3: ASoC: Registered codec ‘3.spdif-dit.3’
[ 1.900412] spdif-dit 4.spdif-dit.4: ASoC: dai register 4.spdif-dit.4 #1
[ 1.900415] spdif-dit 4.spdif-dit.4: ASoC: dynamically register DAI 4.spdif-dit.4
[ 1.900418] spdif-dit 4.spdif-dit.4: ASoC: Registered DAI ‘dit-hifi’
[ 1.900421] spdif-dit 4.spdif-dit.4: ASoC: Registered codec ‘4.spdif-dit.4’
[ 1.900447] spdif-dit 5.spdif-dit.5: ASoC: dai register 5.spdif-dit.5 #1
[ 1.900449] spdif-dit 5.spdif-dit.5: ASoC: dynamically register DAI 5.spdif-dit.5
[ 1.900452] spdif-dit 5.spdif-dit.5: ASoC: Registered DAI ‘dit-hifi’
[ 1.900455] spdif-dit 5.spdif-dit.5: ASoC: Registered codec ‘5.spdif-dit.5’
[ 1.900480] spdif-dit 6.spdif-dit.6: ASoC: dai register 6.spdif-dit.6 #1
[ 1.900483] spdif-dit 6.spdif-dit.6: ASoC: dynamically register DAI 6.spdif-dit.6
[ 1.900486] spdif-dit 6.spdif-dit.6: ASoC: Registered DAI ‘dit-hifi’
[ 1.900489] spdif-dit 6.spdif-dit.6: ASoC: Registered codec ‘6.spdif-dit.6’
[ 1.900545] spdif-dit 7.spdif-dit.7: ASoC: dai register 7.spdif-dit.7 #1
[ 1.900548] spdif-dit 7.spdif-dit.7: ASoC: dynamically register DAI 7.spdif-dit.7
[ 1.900551] spdif-dit 7.spdif-dit.7: ASoC: Registered DAI ‘dit-hifi’
[ 1.900554] spdif-dit 7.spdif-dit.7: ASoC: Registered codec ‘7.spdif-dit.7’
[ 2.537115] tas2505-codec 2-004c: ASoC: dai register 2-004c #1
[ 2.537119] tas2505-codec 2-004c: ASoC: dynamically register DAI 2-004c
[ 2.537123] tas2505-codec 2-004c: ASoC: Registered DAI ‘tas2505-hifi’
[ 2.537128] tas2505-codec 2-004c: ASoC: Registered codec ‘tas2505-codec.2-004c’

$ sudo zcat /proc/config.gz | egrep -i 'tas2505
CONFIG_SND_SOC_TAS2505=m

$sudo zcat /proc/config.gz | grep CONFIG_SND_SOC_SPDIF
CONFIG_SND_SOC_SPDIF=y

$ sudo cat /proc/asound/cards
0 [tegrahda ]: tegra-hda - tegra-hda
tegra-hda at 0x70038000 irq 82

Below is logs after boot system (module is automaticali loaded via - /etc/modules-load.d file), when driver is registered → unregistered → registered
$ lsmod
Module Size Used by
bnep 16562 2
fuse 104554 3
xt_conntrack 3609 1
ipt_MASQUERADE 2346 1
nf_nat_masquerade_ipv4 3111 1 ipt_MASQUERADE
nf_conntrack_netlink 29413 0
nfnetlink 7959 2 nf_conntrack_netlink
xt_addrtype 3670 2
iptable_filter 2481 1
iptable_nat 2882 1
nf_conntrack_ipv4 11992 2
nf_defrag_ipv4 1836 1 nf_conntrack_ipv4
nf_nat_ipv4 6712 1 iptable_nat
nf_nat 20406 2 nf_nat_masquerade_ipv4,nf_nat_ipv4
nf_conntrack 106659 6 nf_conntrack_ipv4,nf_conntrack_netlink,nf_nat_masquerade_ipv4,xt_conntrack,nf_nat_ipv4,nf_nat
br_netfilter 16216 0
userspace_alert 5828 0
zram 25920 4
overlay 48718 0
snd_soc_tas2505 10572 0
nvgpu 1589200 18
ip_tables 19441 2 iptable_filter,iptable_nat
x_tables 28951 5 ip_tables,iptable_filter,ipt_MASQUERADE,xt_addrtype,xt_conntrack

$dmesg
[ 131.466580] tas2505-codec 2-004c: ASoC: Unregistered codec ‘tas2505-codec.2-004c’
[ 131.466585] tas2505-codec 2-004c: ASoC: Unregistered DAI ‘tas2505-hifi’

$sudo insmod snd-soc-tas2505.ko

$dmesg
[ 187.461282] tas2505-codec 2-004c: codec register 2-004c
[ 187.461300] tas2505-codec 2-004c: ASoC: dai register 2-004c #1
[ 187.461308] tas2505-codec 2-004c: ASoC: dynamically register DAI 2-004c
[ 187.461316] tas2505-codec 2-004c: ASoC: Registered DAI ‘tas2505-hifi’
[ 187.461325] tas2505-codec 2-004c: ASoC: Registered codec ‘tas2505-codec.2-004c’

$ lsmod
Module Size Used by
snd_soc_tas2505 10572 0
bnep 16562 2
fuse 104554 3
xt_conntrack 3609 1
ipt_MASQUERADE 2346 1
nf_nat_masquerade_ipv4 3111 1 ipt_MASQUERADE
nf_conntrack_netlink 29413 0
nfnetlink 7959 2 nf_conntrack_netlink
xt_addrtype 3670 2
iptable_filter 2481 1
iptable_nat 2882 1
nf_conntrack_ipv4 11992 2
nf_defrag_ipv4 1836 1 nf_conntrack_ipv4
nf_nat_ipv4 6712 1 iptable_nat
nf_nat 20406 2 nf_nat_masquerade_ipv4,nf_nat_ipv4
nf_conntrack 106659 6 nf_conntrack_ipv4,nf_conntrack_netlink,nf_nat_masquerade_ipv4,xt_conntrack,nf_nat_ipv4,nf_nat
br_netfilter 16216 0
userspace_alert 5828 0
zram 25920 4
overlay 48718 0
nvgpu 1589200 18
ip_tables 19441 2 iptable_filter,iptable_nat
x_tables 28951 5 ip_tables,iptable_filter,ipt_MASQUERADE,xt_addrtype,xt_conntrack

My main problem is that I don’t see sound card. Do you have any idea what I should change?
Below are $demesg_log
dmesg_log_all.txt (56.8 KB)
and source files
tegra210-porg-p3448-common.dtsi (21.1 KB)
tegra210-porg-super-module-e2614.dtsi (8.9 KB)
tas2505.c (22.1 KB)
tas2505.h (3.2 KB)
tegra_machine_driver_mobile.c (23.6 KB)

Unfortunately I don’t know enough specifically about audio devices to answer. What I can tell you though is:

  • If the device tree is wrong, then the device probably won’t be found if it depends on lane mapping (if the device is plug-n-play, e.g., USB or PCIe, then this won’t be an issue).
  • If you can “rmmod” the snd_soc_tas2505 module, then the kernel does not believe the hardware is present (you can often load a module which isn’t being used, but unloading a module in use is not allowed). I’m not sure if in your last “lsmod” this was proceeded by a manual “rmmod” or not since it was not labelled as such.

How is this device connected? I probably can’t answer, but someone who does answer would need to know this for a reply about device tree.

This amplifier use I2S to play sound and I2C to management it. It has additional gpios for enable and interrupt.
Previous logs was chronological:
→ system boot (modules load from script (modules-load.d)
→ lsmod (module present)
→ dmesg | grep “ASoC” (module was load, without errors)
→ rmmod (in previous message is lack of command on list, but it was done)
→ dmesg (codec and DAI was unregistered)
→ insmod
→ dmesg (codec, dai registered)
→ lsmod (module present again)
Sound card is still unavailable. Dmesg doesn’t has any error of fails about this topic. Do you think, that cause can be the driver source?

The above tends to indicate that if hardware is used for the particular module, then it is likely the hardware never used that module (otherwise rmmod would have been refused for a module in use).

I will emphasize that I do not know enough about the device tree for this case to be able to answer if it is correct, but this is likely at least a part of the problem. A contrived example is that if the GPIO is used for an interrupt, then perhaps the interrupt was never called due to an incorrect device tree routing of GPIO. No interrupt would mean no driver was used, and no driver would mean that (A) the module could have rmmod used, and (B) the hardware would not show up as being present. I have no way to tell you what to check for your particular device tree and thus I cannot verify if the above is the actual case, but I suspect it is.

Ok, thank for your help. Do you have any people in support, which can help with device tree configuration?

Yes, I’m sure someone from NVIDIA will see this and answer. There is also documentation on device bring up and customization. See:
https://developer.nvidia.com/embedded/downloads#?search=bring-up
https://developer.nvidia.com/embedded/downloads#?search=pinmux