Solved rpi4 i2c devices

Hi,

I recently bought geekworm's x708 module for my RPI4. With linux everything works as expected. With FreeBSD I'm able to detect power loss and do automatic full hardware poweroff. It also would be nice to check voltage and battery capacity while running on batteries. And here comes the problem.
Same hardware. With Linux I can see I2C device(s) and this code (ups-read, ups-hat-c.zip) works. However with FreeBSD I can't even see the i2c devices.
Code:
root@linux:~# i2cdetect -l
i2c-1   i2c             bcm2835 (i2c@7e804000)                  I2C adapter
root@linux:~# i2cdetect -F 1
Functionalities implemented by /dev/i2c-1:
I2C                              yes
SMBus Quick Command              yes
SMBus Send Byte                  yes
SMBus Receive Byte               yes
SMBus Write Byte                 yes
SMBus Read Byte                  yes
SMBus Write Word                 yes
SMBus Read Word                  yes
SMBus Process Call               yes
SMBus Block Write                yes
SMBus Block Read                 no
SMBus Block Process Call         no
SMBus PEC                        yes
I2C Block Write                  yes
I2C Block Read                   yes

root@fbsd:~ # uname -a
FreeBSD fbsd 13.0-CURRENT FreeBSD 13.0-CURRENT #0 r367946: Mon Nov 23 14:28:53 EET 2020    
root@fbsd:/usr/obj/usr/src/arm64.aarch64/sys/GENERIC  arm64

root@fbsd:~ # i2c -s -v
dev: /dev/iic0, addr: 0x40100401, r/w: r, offset: 0x00, width: 8, count: 1
Hardware may not support START/STOP scanning; trying less-reliable read method.
Scanning I2C devices on /dev/iic0: <none found>

Can anyone point out what I'm doing wrong or i2c just does not work (yet) under FreeBSD?
Regards,
 
Hi,
I'm afraid this port/package does not help at all. In order to use any userland tools the device must be visible through kernel (and driver(s)). In this case it seems, that device is not known.
Code:
 # cat /boot/loader.conf
...
iicsmb_load="YES"
smbus_load="YES"

# kldstat
Id Refs Address                Size Name
 1   38 0xffff000000000000  139e9d8 kernel
 2    2 0xffff0000013a0000    23108 smbus.ko
...
 5    1 0xffff000001412000    238a0 iicsmb.ko

# ls -la /dev/ | egrep -i "iic|smb|bus"
crw-------   1 root  wheel     0x3f Nov 24 09:34 iic0

# dmesg |egrep -i "iic|smb"
iichb0: <BCM2708/2835 BSC controller> mem 0x7e804000-0x7e804fff irq 38 on simplebus0
iicbus0: <OFW I2C bus> on iichb0
iic0: <I2C generic I/O> on iicbus0
iicsmb0: <SMBus over I2C bridge> on iicbus0
smbus0: <System Management Bus> on iicsmb0

# deviceinfo -v
 ...
      iichb0 pnpinfo name=i2c@7e804000 compat=brcm,bcm2835-i2c
        iicbus0
          iic0 at addr=0
          iicsmb0 at addr=0
            smbus0
...
As i undestand the output of the last command, there are no devices known to i2c drivers.
 
I had a quick look at one of the source codes, and there is no special driver involved. The device is directly addressed via its address on the I²C bus. The first step would be to see, whether the bus is active and whether the device can be enumerated:
# i2c -f /dev/iic0 -s
If you left the I²C address at its factory setting, then this should report something like:
Code:
Scanning I2C devices on /dev/iic0: 36
On my Beaglebone, I see always another hint before: Hardware may not support START/STOP scanning; trying less-reliable read method. This can be ignored.

I don’t use Python, and I cannot tell whether there is a Python-I²C-Library for FreeBSD. If you are not a programmer, then you need some help from somebody who talks Python. I program all of my I²C-device myself in C without any special library by simply using ioctl(2) commands. Below comes a simple C example which configures the ADS1115 which is an ADC chip (Analog Digital Converter from TI). This is not rocket science, i.e. this shouldn’t be too complicated:
C:
//  ADS1115.c
//  ADS1115 ADC Device I2C Interface Testing

#include <unistd.h>
#include <fcntl.h>
#include <dev/iicbus/iic.h>

int main(int argc, char *const argv[])
{

   uint8_t addr = 0x48 << 1;
   uint8_t config[3] = {1, 0b10000101, 0b10000011};

   struct iic_msg msgs = {addr|IIC_M_WR, IIC_M_WR, 3, config};
   struct iic_rdwr_data config_msg = {&msgs, 1};

   int iic = open("/dev/iic1", O_RDWR);
   ioctl(iic, I2CRDWR, &config_msg);
   close(iic);

   return 0;
}
 
Some time ago I did some stuff on the old Raspberry, it could have been the second release. At that time it was about reading or setting GPIO pins. I would not wonder is the Linux driver does the same and relieve the user from doing that manually. From my archive a flashing GPIO:
Code:
cat blink.sh
#!/bin/sh

echo "22" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio22/direction
echo "0" > /sys/class/gpio/gpio22/value

for i in 1 2 3 4 5
do
#       echo $i
        echo "1" > /sys/class/gpio/gpio22/value
        sleep 1
        echo "0" > /sys/class/gpio/gpio22/value
        sleep 1
done

echo "22" > /sys/class/gpio/unexport
I have had attached an LED with a suitable resisotr to GPIO22. One could generate functions with shell scripts to mimic and I2C interface. It will not be super fast.

About your example
root@linux:~# i2cdetect -l i2c-1 i2c bcm2835 (i2c@7e804000) I2C adapter
the library seems to talk via the SOC of the Raspberry. You might want to compile the I2C driver using FreeBSD. If you are in doubt follow obsigna instead of myself ;). My post is more about the option of using the shell. C programming is not one of my strength.
 
Hi,
Thank You all for Your time and answers.
Now this is what I can't figure out:
# i2c -f /dev/iic0 -s
If you left the I²C address at its factory setting, then this should report something like:

Code:
Scanning I2C devices on /dev/iic0: 36
Thing is I don't see anything like that. None found. Like it does not exists at all.
Code:
root@fbsd:~# i2c -f /dev/iic0 -s
Hardware may not support START/STOP scanning; trying less-reliable read method.
Scanning I2C devices on /dev/iic0: <none found>
 
Hi, I recently bought geekworm's x708 module for my RPI4. With linux everything works as expected. With FreeBSD I'm able to detect power loss and do automatic full hardware poweroff. It also would be nice to check voltage and battery capacity while running on batteries. And here comes the problem. Same hardware. With Linux I can see I2C device(s) and this code (ups-read, ups-hat-c.zip) works. However with FreeBSD I can't even see the i2c devices.
Code:
root@linux:~# i2cdetect -l i2c-1 i2c bcm2835 (i2c@7e804000) I2C adapter root@linux:~# i2cdetect -F 1 Functionalities implemented by /dev/i2c-1: I2C yes SMBus Quick Command yes SMBus Send Byte yes SMBus Receive Byte yes SMBus Write Byte yes SMBus Read Byte yes SMBus Write Word yes SMBus Read Word yes SMBus Process Call yes SMBus Block Write yes SMBus Block Read no SMBus Block Process Call no SMBus PEC yes I2C Block Write yes I2C Block Read yes root@fbsd:~ # uname -a FreeBSD fbsd 13.0-CURRENT FreeBSD 13.0-CURRENT #0 r367946: Mon Nov 23 14:28:53 EET 2020 root@fbsd:/usr/obj/usr/src/arm64.aarch64/sys/GENERIC arm64 root@fbsd:~ # i2c -s -v dev: /dev/iic0, addr: 0x40100401, r/w: r, offset: 0x00, width: 8, count: 1 Hardware may not support START/STOP scanning; trying less-reliable read method. Scanning I2C devices on /dev/iic0:
Can anyone point out what I'm doing wrong or i2c just does not work (yet) under FreeBSD? Regards,
Is there an iic* device in /dev?

Edit: you're running 13-current, so it's quite possibly just bugged out at present. It sure works on RPI3/FreeBSD12.
 
Back
Top