This doesn't mean my onboard CA0132 works as expected. 
pretty like the onboard sound chip on my HPPA workstation, and if it's soldered onboard ... you cannot change it.
That's why I suggested you to buy an USB-sound card, choosing from one of the most Linux-friendly available.
weird behavior I've seen so far happens to others, too.
In my case, the sound chip is basically a couple of ADC with a FIFO and a weird ASIC circuit to control it, and there is a weird (crazy?) mode that allows the software to take samples only when the FIFO is full, this means that you are not sampling at the regular sample rate (let's say at 100Khz) because the filling of the FIFO depends on the speed with which the kernel reads the data to empty it, which must be considered "random behavior" since it depends on random factors.
To me, it makes no sense, but ... some engineers must have thought otherwise, and when some hobbyists like me tried to write a driver for Linux ... they came up with a mess (I don't blame them, it's really a very bad sound chip)... worse still for an experimental abandoned platform so you have ZERO interest from the Linux Devs
I wrote a kernel module assigning a timer to the ADC so the kernel reads the FIFO on regular frequency base and assign a timestamp to the samples. This solved my problem in a very simple way, but then ... it's not OSS compliant and it doesn't make the driver a "sound driver" (actually it's an ADC driver) therefore you have to deal with other parts of the kernel and with other parts of the userspace.
If you follow the rabbit down its hole ... well, it really goes deeper and faster than you ever imagined.
1. - How difficult is to apply a patch?
2. - Do I need to recompile the whole kernel, or the driver is just a separated module to be compiled then loaded?
3. - Do I need to manually re-apply the patch and recompile forever, at each new kernel version upgrade pushed by Ubuntu updates?
4. - I've seen this: https://help.ubuntu.com/community/Kernel/Compile Is this a good start, do I need other link to read for a brief intro about how this is usually done (applying a custom patch, then dealing with it at each future kernel version upgrade)?
1: you have to use the program "patch". Not complex, but you have to consider how patches are generated and handled. If a patch comes from a mailing list and it's "text malformed" you have to fix it before you can apply. That's not complex, it's simply annoying, but that's it.
2: it depends. If the kernel module has some dependency with the whole kernel tree, you have to recompile everything, otherwise you can create a special Makefile that only re-compiles your kernel module, it just needs to "point" the kernel source (especially for headers) and it will compile nothing but local files.
3: yes, unless the patch is integrated into the Vanilla source, if someone sends it to Linus Torvalds and * he * approves the code, in this case you will find it already applied into the latest binary kernel you will get from Ubuntu
4: dunno, here it's a personal path, mine started many many years ago with kernel 2.0.* , too years ago to remember how how I learned things
# mybuild
kernel-5.14.1(arm.32/nanopi-neo)
tc) show toolchain version
up) script_update
0) clean
1) configure
2) compile app
3) app module
4) tftp [email protected]:
5) tools
app_name = kernel-5.14.1-32bit-nanopi-neo
machine_note = experimental
qualified_host = macmini-intel
# mybuild 5
[step5] tools
1 - list actually used source
2 - archive actually_used_source
3 - backup files
4 - list all files to be patched
5 - apply patches
6 - make patches
7 - revert patches
# mybuild 5 6
[step5] tools
[step5.6] make patches
~ Makefile ... success
~ lib/dump_stack.c ... success
~ mm/page_alloc.c ... success
~ scripts/setlocalversion ... success
~ arch/arm/Kconfig ... success
~ init/main.c ... success
~ arch/arm/kernel/setup.c ... success
~ arch/arm/kernel/smp.c ... success
~ lib/dump_stack.c ... success
~ init/version.c ... success
~ mm/page_alloc.c ... success
~ kernel/printk/printk.c ... success
~ kernel/panic.c ... success
~ scripts/mkuboot.sh ... success
~ scripts/Makefile.lib ... success
# mybuild 2
[step2] compiling
kernel-5.14.1(arm/nanopi-neo)
toolchain(armv7a-unknown-linux-gnueabihf:2.34/9.3.0)
app_name = kernel-5.14.1-32bit-nanopi-neo
machine_note = experimental
qualified_host = macmini-intel
-----------------------------------------------
gadget_to_do(build) ... kernel/build
gadget_to_do(clean) ... kernel/clean
building kernel ... success
building dtb ... success
-----------------------------------------------
gadget_to_do(binary) ... overlay/binary
gadget_to_do(sweep) ... kernel/sweep
ram_size=32768
slice loading ... done, 22378 byte
slice saving ... done, 32768 byte
gadget_to_do(binary_report) ... kernel/binary_report
It uses a global recipe that can be overridden by a local recipe
# mybuild recipe
- version
- platform
- machine_arch_32
- machine_arch_64
- machine_loadaddr
- machine_image
- machine_note
- machine_bits
- platform
- chosen
- product
- tftp_server_ip
- toolchain_32
- toolchain_64
- binutils_ver_min
- binutils_ver_max
- gcc_ver_max
- gcc_ver_min
- gcc_opt
- qualified_host
- tftp_file_name
- overlay { check_tools.list, binary, binary_report, build, clean, sweep, uImage, dtb, tftp }
It tells you how it was compiled, on which machines (qualified hosts, can be virtual machines), with which toolchain, options, and it also reports things that are mandatory. So I can easily forget and don't care about details, this is useful when you have to deal with sources that can age faster than how you can remember or manage.