IOT RTC rv-3028 driver is written for 5.13 and Torizon is 5.5

We have a low power RTC (a RV-3028) and supercap on my new board.

RV-3028-C7 - Micro Crystal

Following this approach, which is absolutely fine.

https://developer.toradex.com/knowledge-base/building-external-kernel-modules-with-torizon

To provision it we have a driver to add to Torizon

rv3028 (1).zip (1.4 MB)

The issue is that this driver has features that appear in a later version of the kernel

Specifically, the identifier RTC_FEATURE_ALARM has been added in kernel 5.13. That
means that the source code we have is too new for the current Torizon
kernel.

make: Entering directory ‘/workdir/rv3028-mod’
make -C /storage/linux M=/workdir/rv3028-mod
make[1]: Entering directory ‘/storage/linux’
AR /workdir/rv3028-mod/built-in.a
CC [M] /workdir/rv3028-mod/rtc-rv3028.o
/workdir/rv3028-mod/rtc-rv3028.c: In function ‘rv3028_ioctl’:
/workdir/rv3028-mod/rtc-rv3028.c:526:42: error: ‘RTC_VL_DATA_INVALID’
undeclared (first use in this function)
526 | status = status & RV3028_STATUS_PORF ? RTC_VL_DATA_INVALID : 0;
| ^~~~~~~~~~~~~~~~~~~
/workdir/rv3028-mod/rtc-rv3028.c:526:42: note: each undeclared
identifier is reported only once for each function it appears in
/workdir/rv3028-mod/rtc-rv3028.c: In function ‘rv3028_probe’:
/workdir/rv3028-mod/rtc-rv3028.c:844:13: error: ‘RTC_FEATURE_ALARM’
undeclared (first use in this function)
844 | clear_bit(RTC_FEATURE_ALARM, rv3028->rtc->features);
| ^~~~~~~~~~~~~~~~~
/workdir/rv3028-mod/rtc-rv3028.c:844:43: error: ‘struct rtc_device’
has no member named ‘features’
844 | clear_bit(RTC_FEATURE_ALARM, rv3028->rtc->features);
| ^~
/workdir/rv3028-mod/rtc-rv3028.c:884:8: error: implicit declaration of
function ‘devm_rtc_register_device’; did you mean
‘rtc_register_device’? [-Werror=implicit-function-declaration]
884 | ret = devm_rtc_register_device(rv3028->rtc);
| ^~~~~~~~~~~~~~~~~~~~~~~~
| rtc_register_device
/workdir/rv3028-mod/rtc-rv3028.c:889:2: error: implicit declaration of
function ‘devm_rtc_nvmem_register’; did you mean
‘devm_nvmem_register’? [-Werror=implicit-function-declaration]
889 | devm_rtc_nvmem_register(rv3028->rtc, &nvmem_cfg);
| ^~~~~~~~~~~~~~~~~~~~~~~
| devm_nvmem_register
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:262:
/workdir/rv3028-mod/rtc-rv3028.o] Error 1
make[1]: *** [Makefile:1734: /workdir/rv3028-mod] Error 2
make[1]: Leaving directory ‘/storage/linux’
make: *** [Makefile:6: all] Error 2
make: Leaving directory ‘/workdir/rv3028-mod’
Traceback (most recent call last):
File “/builder/tcbuilder/backend/kernel.py”, line 64, in build_module
subprocess.run(f"""PATH=$PATH:{toolchain} KERNEL_SRC={linux_src}
KDIR={linux_src}
File “/usr/lib/python3.9/subprocess.py”, line 528, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command
‘PATH=$PATH:/storage/toolchain/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin
KERNEL_SRC=/storage/linux KDIR=/storage/linux
CROSS_COMPILE=aarch64-none-linux-gnu- ARCH=arm64 make
-C /workdir/rv3028-mod’ returned non-zero exit status 2.

Error: Error building kernel module(s)!

Can you recommend what we do now? We don’t actually use the “wake up” processor event feature, so do we try to re-write the driver; dump the very smart RTC chip and the design we have; or is there a possibility of a newer Torizon on the horizon ?

Thanks

Fat Linux.

Greetings @FatLinux,

Sometime this year we plan to release a 6.0 of our BSP and TorizonCore software. Tentatively speaking the plan is that in this 6.0 the kernel version will then be 5.15.

With that said, the most straightforward option would be to just wait. However, this depends on your use-case and requirements of course. Also you’ll need some kind of work-around in the short-term.

Best Regards,
Jeremias

Hi,

Thank you for getting back to me.

I wish I could wait until next year, I have been taking a roasting for a few months now for being late (other stuff!).

So the device tree is like this:

torizon@Thinkcentrei9:~/torizoncore/custom_overlays$ cat re*
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/*

  • Copyright 2020-2021 Toradex
    */

// Enable the parallel RGB interface on Colibri iMX8X

/dts-v1/;
/plugin/;

/ {
compatible = “toradex,colibri-imx8x”;
};

&i2c1 {
status = “okay”;

    rtc_i2c: rv3028@52 {
            compatible = "microcrystal,rv3028";
            reg = <0x52>;
            status = "okay";
            trickle-resistor-ohms = <11000>;
    };

};

So the trickle resistor is on, and I measured the supercap with a probe and I get 3.1V which is nice.

I can then boot up the Imx8 module and

root@colibri-imx8x-07021201:~# dmesg | grep rtc2
[ 7.603848] rtc-rv3028 17-0052: registered as rtc2

I can set the clock

root@colibri-imx8x-07021201:~# hwclock -w -f /dev/rtc2

I check it …

root@colibri-imx8x-07021201:~# hwclock -r -f /dev/rtc2 --verbose
hwclock from util-linux 2.35.1
System Time: 1649452925.107593
Using the rtc interface to the clock.
Last drift adjustment done at 1649452817 seconds after 1969
Last calibration done at 1649452817 seconds after 1969
Hardware clock is on UTC time
Assuming hardware clock is kept in UTC time.
Waiting for clock tick…
…got clock tick
Time read from Hardware Clock: 2022/04/08 21:22:06
Hw clock time : 2022/04/08 21:22:06 = 1649452926 seconds since 1969
Time since last adjustment is 109 seconds
Calculated Hardware Clock drift is 0.000000 seconds
2022-04-08 21:22:05.103527+00:00

root@colibri-imx8x-07021201:~# shutdown now

And then pull the socket, I then put a meter on the supercap and it reads 3.2V.

Boot up again.

colibri-imx8x-07021201:~$ sudo su -
Password:
root@colibri-imx8x-07021201:~# hwclock -r -f /dev/rtc2 --verbose
hwclock from util-linux 2.35.1
System Time: 1649453129.848951
Using the rtc interface to the clock.
Last drift adjustment done at 1649452817 seconds after 1969
Last calibration done at 1649452817 seconds after 1969
Hardware clock is on UTC time
Assuming hardware clock is kept in UTC time.
Waiting for clock tick…
ioctl(3, RTC_UIE_ON, 0): Invalid argument
Waiting in loop for time from /dev/rtc2 to change
hwclock: ioctl(RTC_RD_TIME) to /dev/rtc2 to read the time failed: Invalid argument
…synchronization failed

root@colibri-imx8x-07021201:~# dmesg | grep rtc2
[ 6.947201] rtc-rv3028 17-0052: registered as rtc2

So the rtc backup is on, the trickle charger is on, but the power switch over is not working I think and the time is being lost. I will pursue Micro Crystal Switzerland for some help next week, maybe we get lucky and if so I will post the solution on here!

Meanwhile, any ideas are gladly appreciated.

Regards

Fat Linux

Hi,

What we need is a kernel patch for Torizon if you want to use the RV-3028 RTC module (which to be fair is a new product, but 45nA consumption and low ppm).

The kernel is rtc-rv3028.c

When supplied by Micro Crystal Switzerland the module has the battery trickle charge switched off. This is easily rectified in the device tree with a single line: you say the resistance to put in place to specify the trickle and it works.

However, there is a second part to this. The RV-3028 is shipped with the automatic VBACKUP switch over set to “off”. So the battery or cap backup charges but won’t power the module.

The onboard EEPROM has a register 0x37 which as 8 bits, bits 2 and 3 are both 0 when the module is supplied, but the smooth voltage threshold switchover option needs both these to be 1.

So patch for rtc-rv3028.c I think will be needed to write a pair of 1’s to the register 0x37, probably at the point where and when the trickle charge bits are being set. Finger crossed.

So are you now just attempting to patch or backport the driver to make it work for the older kernel that TorizonCore is running?

I didn’t reply to this because I made some practical evaluations (i.e. I built a rig to test that the supercap was charging as predicted, and to compare the two different switch over techniques.

I got some contradictions to the documentation and have written to the manufacturer to get some confirmations. At the moment the RTC is definitely being powered (so it keeps the time), but I haven’t finished my code to probe the registers to know which bits are enabled on x37. The docs definitely say these devices are shipped with these two bits off.

Will keep you posted.

Fat Linux.

Thank you for keeping us posted.