hooverphonique
Posts: 10
Joined: Wed Nov 06, 2019 2:10 pm

Can't apply overlay mcp342x.dtbo

Mon Dec 02, 2019 2:24 pm

I'm trying to get an MCP3421 on I2C-1 working using the built-in mcp3422 driver.
The ADC shows up on addr 0x68 using i2cdetect (as the only device on that bus).

The only thing that seems to do anything successful is "sudo modprobe mcp3422" which creates "/sys/bus/iio", etc.

I can't create a new device using "sudo echo mcp3421 0x68 > /sys/class/i2c-adapter/i2c-1/new_device" (permission denied).
Are these permissions correct? "--w------- 1 root root 4096 Dec 2 15:01 /sys/class/i2c-adapter/i2c-1/new_device"

I also can't apply the Raspbian included mcp342x.dtbo using "sudo dtoverlay /boot/overlays/mcp342x.dtbo addr=0x68 mcp3421" (* Failed to apply overlay '0_mcp342x' (kernel)). udevadm monitor outputs nothing in this case, but dmesg shows:

[1553.084406] OF: overlay: find target, node: /[email protected], phandle 0xc8 not found
[ 1553.084421] OF: overlay: init_overlay_changeset() failed, ret = -22

Where the listed phandle value seems to change from time to time.

I tried on both a Pi 3B+ and 4 with the exact same results which makes me think I'm doing something wrong..

Raspbian GNU/Linux 10 (buster)
Linux raspberrypi 4.19.75-v7l+ #1270 SMP Tue Sep 24 18:51:41 BST 2019 armv7l GNU/Linux

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2480
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Can't apply overlay mcp342x.dtbo

Mon Dec 02, 2019 3:46 pm

I can't create a new device using "sudo echo mcp3421 0x68 > /sys/class/i2c-adapter/i2c-1/new_device" (permission denied).
Are these permissions correct? "--w------- 1 root root 4096 Dec 2 15:01 /sys/class/i2c-adapter/i2c-1/new_device"
Shell redirection can be confusing - even though the echo command is being run as root, it is just sending its output to the shell. The shell normally displays the output on the console/terminal window etc., but the ">" tells the shell to write it somewhere else, in this case to ".../new_device". However, the shell is running as "pi", so the write fails.

There are two common ways of solving this:

1. Run the echo as normal but use the tee command (running as root) to write the output:

Code: Select all

echo mcp3421 0x68 | sudo tee /sys/class/i2c-adapter/i2c-1/new_device
2. Run the whole command, including the output redirection, in a root shell:

Code: Select all

sudo sh -c "echo mcp3421 0x68 > /sys/class/i2c-adapter/i2c-1/new_device"
I also can't apply the Raspbian included mcp342x.dtbo using "sudo dtoverlay /boot/overlays/mcp342x.dtbo addr=0x68 mcp3421" (* Failed to apply overlay '0_mcp342x' (kernel)). udevadm monitor outputs nothing in this case, but dmesg shows:

[1553.084406] OF: overlay: find target, node: /[email protected], phandle 0xc8 not found
[ 1553.084421] OF: overlay: init_overlay_changeset() failed, ret = -22
Not all overlays will work when applied at runtime - some subsystems don't react well to dynamic device creation - but this one could if it was written differently. You should be able to make this work by adding "dtoverlay=mcp342x,addr=0x68,mcp3421". If that isn't a viable solution for you then you'll need a rewritten overlay structured more like the i2c-rtc overlay.

hooverphonique
Posts: 10
Joined: Wed Nov 06, 2019 2:10 pm

Re: Can't apply overlay mcp342x.dtbo

Mon Dec 02, 2019 4:23 pm

PhilE wrote:
Mon Dec 02, 2019 3:46 pm
Shell redirection can be confusing - even though the echo command is being run as root, it is just sending its output to the shell. The shell normally displays the output on the console/terminal window etc., but the ">" tells the shell to write it somewhere else, in this case to ".../new_device". However, the shell is running as "pi", so the write fails.
Thanks for pointing out my stupid redirection mistake..

Now I get "/sys/bus/iio/devices/iio:device0" when modprobing followed by echo, and it seems to be communicating with the ADC.
PhilE wrote:
Mon Dec 02, 2019 3:46 pm
Not all overlays will work when applied at runtime - some subsystems don't react well to dynamic device creation - but this one could if it was written differently. You should be able to make this work by adding "dtoverlay=mcp342x,addr=0x68,mcp3421". If that isn't a viable solution for you then you'll need a rewritten overlay structured more like the i2c-rtc overlay.
I suppose you meant adding "dtoverlay=mcp342x,addr=0x68,mcp3421" to "/boot/config.txt" !?
After doing that and rebooting, the "/sys/bus/iio/" directory is missing, but comes back after doing (just) the modprobe again - looks like it's the same as the problem in this thread (which you also replied to), but unfortunately it doesn't provide a solution.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2480
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Can't apply overlay mcp342x.dtbo

Mon Dec 02, 2019 5:12 pm

I think you're also seeing the effect of a change in 4.19 that suppresses "i2c:" aliases for I2C devices registered using Device Tree. Most drivers weren't affected by this, but some (including mcp342x) don't declare proper Device Tree compatible strings, causing the module not to be loaded.

The existing code is as follows:

Code: Select all

static const struct i2c_device_id mcp3422_id[] = {
        { "mcp3421", 1 },
        { "mcp3422", 2 },
        { "mcp3423", 3 },
        { "mcp3424", 4 },
        { "mcp3425", 5 },
        { "mcp3426", 6 },
        { "mcp3427", 7 },
        { "mcp3428", 8 },
        { }
};
MODULE_DEVICE_TABLE(i2c, mcp3422_id);

#ifdef CONFIG_OF
static const struct of_device_id mcp3422_of_match[] = {
        { .compatible = "mcp3422" },
        { }
};
MODULE_DEVICE_TABLE(of, mcp3422_of_match);
#endif
Note the single ".compatible" string ("mcp3422"), when it should really say "microchip,mcp3421", "microchip,mcp3422" etc. The driver also needs to be extended to be able to extract the device type based on the particular compatible string used (see the numbers listed with the I2C device strings).

Return to “Device Tree”