analogdevicesinc / ToF

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ADSD3500 i.MX8 Linux 5.10 V4L2 Call subdev s_power fail

pclass-sensonix opened this issue · comments

Hi - I have the EVAL-ADSD3175D kit and I built my own SD card image with the linux-imx patches supplied in this repository. When I boot Linux on the i.MX8M SoM, the kernel finds the ADSD3500 device - but in user space I get the error below.

root@gateway:~# v4l2-ctl --device /dev/video0 --set-fmt-video=width=1024,height=3072,pixelformat=BG12 --stream-mmap --stream-to=frame.bin --stream-count=$nr_frames
[  903.328243] mxc_isi.0: Call subdev s_power fail!
                VIDIOC_STREAMON returned -1 (Inappropriate ioctl for device)

Dmesg error:
mxc_isi.0: Call subdev s_power fail!

Kernel finds the camera on boot:

[    3.343041] mx8-img-md: Registered sensor subdevice: adsd3500 1-0038 (1)
[    3.343049] mx8-img-md: created link [mxc_isi.0] => [mxc_isi.0.capture]
[    3.343053] mx8-img-md: created link [mxc-mipi-csi2.0] => [mxc_isi.0]
[    3.343058] mx8-img-md: created link [adsd3500 1-0038] => [mxc-mipi-csi2.0]

v4l2-ctl Controls:

root@gateway:~# v4l2-ctl --list-ctrls   --device=/dev/v4l-subdev1 --list-formats

User Controls

                 operating_mode 0x009819e0 (int)    : min=0 max=10 step=1 default=0 value=0
                    chip_config 0x009819e1 (u8)     : min=0 max=255 step=1 default=0 [4099] flags=has-payload
               phase_depth_bits 0x009819e2 (intmenu): min=0 max=6 default=0 value=4
                        ab_bits 0x009819e3 (intmenu): min=0 max=6 default=0 value=0
                confidence_bits 0x009819e4 (intmenu): min=0 max=2 default=0 value=0
                   ab_averaging 0x009819e5 (bool)   : default=1 value=1
                   depth_enable 0x009819e6 (bool)   : default=1 value=1

Image Processing Controls

                 link_frequency 0x009f0901 (intmenu): min=0 max=0 default=0 value=0 flags=read-only
                     pixel_rate 0x009f0902 (int64)  : min=1 max=2147483647 step=1 default=1 value=488000000 flags=read-only
ioctl: VIDIOC_ENUM_FMT
        Type: Video Capture

I try to configure and capture using v4l2-ctl and the commands from wiki --> https://wiki.analog.com/resources/eval/user-guides/eval-adsd3175d-v4l2-device-driver

root@gateway:~# v4l2-ctl --set-ctrl=operating_mode=10 -d /dev/v4l-subdev1
root@gateway:~# v4l2-ctl --set-ctrl=phase_depth_bits=4 -d /dev/v4l-subdev1
root@gateway:~# v4l2-ctl --set-ctrl=ab_bits=0 -d /dev/v4l-subdev1
root@gateway:~# v4l2-ctl --set-ctrl=confidence_bits=0 -d /dev/v4l-subdev1
root@gateway:~# v4l2-ctl --set-ctrl=ab_averaging=0 -d /dev/v4l-subdev1
root@gateway:~# v4l2-ctl --set-ctrl=depth_enable=0 -d /dev/v4l-subdev1
root@gateway:~# v4l2-ctl --device /dev/video0 --set-fmt-video=width=1024,height=3072,pixelformat=BG12 --stream-mmap --stream-to=frame.bin --stream-count=$nr_frames
[  903.328243] mxc_isi.0: Call subdev s_power fail!
                VIDIOC_STREAMON returned -1 (Inappropriate ioctl for device)

Kernel:

root@banner-fusion-gateway:~# uname -r
5.10.72-lts-5.10.y+g3f8f2926de0a

@pclass-sensonix we will investigate what may be going wrong here.

Did you make any changes to the build scripts?

@andrestraker - thank you for looking into this. What I've done so far is take your kernel and u-boot patches and apply them to linux-imx in my own custom Yocto layer, and the meta-solidrun-arm-imx8 layer.

The image I produce boots and finds the camera. I have copied your ToF init script that I run manually for now and it prints the following:

./camera-init.sh 
DAC channel is 1563 mV
DAC channel is 628 mV
DAC channel is 468 mV
V_LD_SNS is 6.492 V
VMAIN is 4.165 V
VSYS is 4.171 V
VAUX is 24.330 V
V5V0 is 4.790 V
[   48.021458] imx8_media_dev: module is from the staging directory, the quality is unknown, you have been warned.
[   48.033039] mx8-img-md: Registered mxc_isi.0.capture as /dev/video0
[   48.040287] mx8-img-md: Registered sensor subdevice: adsd3500 1-0038 (1)
[   48.047075] mx8-img-md: created link [mxc_isi.0] => [mxc_isi.0.capture]
[   48.053784] mx8-img-md: created link [mxc-mipi-csi2.0] => [mxc_isi.0]
[   48.060265] mx8-img-md: created link [adsd3500 1-0038] => [mxc-mipi-csi2.0]

Camera init script:

#!/bin/bash

#V5V0 enable GPIO - GPIO4 / IO30 - Linux GPIO 126
#VMAIN enable GPIO - GPIO5 / IO00 - Linux GPIO 128
#VSYS enable GPIO - GPIO5 / IO01 - Linux GPIO 129
#VAUX enable GPIO - GPIO4 / IO31 - Linux GPIO 127
#VDAC enable GPIO - GPIO5 / IO02 - Linux GPIO 130

BOARD=$(strings /proc/device-tree/model)

if [[ $BOARD == "NXP i.MX8MPlus ADI TOF carrier + ADSD3500" ]]; then
        #ADSD3500 Reset Pin
        echo 122 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio122/direction
        echo 0 > /sys/class/gpio/gpio122/value

        # Boot strap MAX7321
        #OC0
        echo 496 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio496/direction
        echo 0 > /sys/class/gpio/gpio496/value

        #OC1
        echo 497 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio497/direction
        echo 0 > /sys/class/gpio/gpio497/value

        #OC2
        echo 498 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio498/direction
        echo 0 > /sys/class/gpio/gpio498/value

        #OC3
        echo 499 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio499/direction
        echo 0 > /sys/class/gpio/gpio499/value

        #OC4
        echo 500 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio500/direction
        echo 0 > /sys/class/gpio/gpio500/value

        #OC5
        echo 501 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio501/direction
        echo 0 > /sys/class/gpio/gpio501/value

        #OC6
        echo 502 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio502/direction
        echo 0 > /sys/class/gpio/gpio502/value

        #FLASH_WP
        echo 503 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio503/direction
        echo 1 > /sys/class/gpio/gpio503/value

        # Boot strap MAX7320
        #U0
        echo 507 > /sys/class/gpio/export
        echo 0 > /sys/class/gpio/gpio507/value

        #EN_1P8
        echo 510 > /sys/class/gpio/export
        echo 1 > /sys/class/gpio/gpio510/value

        sleep 1

        #EN_0P8
        echo 511 > /sys/class/gpio/export
        echo 1 > /sys/class/gpio/gpio511/value

        # Pull reset high
        echo 1 > /sys/class/gpio/gpio122/value
fi

if [[ $BOARD == "NXP i.MX8MPlus ADI TOF carrier + ADSD3030" ]]; then
        #ADSD3500 Reset Pin
        echo 122 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio122/direction
        echo 0 > /sys/class/gpio/gpio122/value

#U13    #U0 1 - INTERPOSER FLASH / 0 - TEMBIN FLASH
        echo 492 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio492/direction
        echo 0 > /sys/class/gpio/gpio492/value

#U5             #EN_AVDD
        echo 508 > /sys/class/gpio/export
        echo 1 > /sys/class/gpio/gpio508/value

#U12    #OC0
        echo 496 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio496/direction
        echo 0 > /sys/class/gpio/gpio496/value

#U12    #OC1
        echo 497 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio497/direction
        echo 0 > /sys/class/gpio/gpio497/value

#U12    #OC2
        echo 498 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio498/direction
        echo 0 > /sys/class/gpio/gpio498/value

#U12    #OC3
        echo 499 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio499/direction
        echo 0 > /sys/class/gpio/gpio499/value

#U12    #OC4
        echo 500 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio500/direction
        echo 0 > /sys/class/gpio/gpio500/value

#U12    #OC5
        echo 501 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio501/direction
        echo 0 > /sys/class/gpio/gpio501/value

#U12    #OC6
        echo 502 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio502/direction
        echo 1 > /sys/class/gpio/gpio502/value

#U12    #FLASH_WP
        echo 503 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio503/direction
        echo 1 > /sys/class/gpio/gpio503/value


#U13    #DS2_ON
        echo 493 > /sys/class/gpio/export
        echo out > /sys/class/gpio/gpio493/direction
        echo 0 > /sys/class/gpio/gpio493/value

#U5     #EN_3V3
        echo 504 > /sys/class/gpio/export
        echo 1 > /sys/class/gpio/gpio504/value

#U5     #EN_1V2
        echo 505 > /sys/class/gpio/export
        echo 1 > /sys/class/gpio/gpio505/value

#U5     #EN_1V8
        echo 506 > /sys/class/gpio/export
        echo 1 > /sys/class/gpio/gpio506/value

#U5     #EN_VLDD
        echo 507 > /sys/class/gpio/export
        echo 1 > /sys/class/gpio/gpio507/value

#U5     #EN_0V8
        echo 509 > /sys/class/gpio/export
        echo 1 > /sys/class/gpio/gpio509/value

#U5 #SHDWN_SEL
        echo 510 > /sys/class/gpio/export
        echo 0 > /sys/class/gpio/gpio510/value

        # Pull reset high
        echo 1 > /sys/class/gpio/gpio122/value
fi

# Deassert ADC reset - will pop on /dev/i2c1 address 0x10
echo 132 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio132/direction
echo 0 > /sys/class/gpio/gpio132/value
sleep 0.5
echo 1 > /sys/class/gpio/gpio132/value
i2cset -y 2 0x10 0x05 0x0700 w # Enable DAC bits 2..0
i2cset -y 2 0x10 0x0b 0x0002 w #

# Set DAC values -
i2cset -y 2 0x10 0x10 0x008a w # Vsys = 4.3V
#i2cset -y 2 0x10 0x11 0x6097 w # Vaux = 18V
#i2cset -y 2 0x10 0x11 0x0091 w # Vaux = 27V
i2cset -y 2 0x10 0x11 0x0594 w # Vaux = 22V
i2cset -y 2 0x10 0x12 0x00a3 w # V5v0 = 4.7V

i2cset -y 2 0x10 0x04 0xff00 w; i2cset -y 2 0x10 0x02 0xff03 w
for i in {0..8}; do 
VAL=`i2cget -y 2 0x10 0x40 w`
CH=$(($VAL & 0x00f0))
CH=$(($CH >> 4))
VOL1=$(($VAL & 0xf))
VOL1=$(($VOL1 << 8))
VOL2=$(($VAL & 0xff00))
VOL2=$(($VOL2 >> 8))
VOL=$(($VOL1 | $VOL2))
#echo $VAL $CH $VOL $VOL1 $VOL2

if [ $CH -le 2 ]; then
VALUE=`echo 1000*${VOL}*2.5/4096 | bc`
echo "DAC channel is $VALUE mV"
elif [ $CH -le 3 ]; then
VALUE=`echo ${VOL}*2.5/4096*133.2/33.2 | bc -l`
VALUE=`printf "%.3f" ${VALUE}`
echo "V_LD_SNS is $VALUE V"
elif [ $CH -le 4 ]; then
VALUE=`echo ${VOL}*2.5/4096*171.5/71.5 | bc -l`
VALUE=`printf "%.3f" ${VALUE}`
echo "VMAIN is $VALUE V"
elif [ $CH -le 5 ]; then
VALUE=`echo ${VOL}*2.5/4096*171.5/71.5 | bc -l`
VALUE=`printf "%.3f" ${VALUE}`
echo "VSYS is $VALUE V"
elif [ $CH -le 6 ]; then
VALUE=`echo ${VOL}*2.5/4096*108.66/8.66 | bc -l`
VALUE=`printf "%.3f" ${VALUE}`
echo "VAUX is $VALUE V"
elif [ $CH -le 7 ]; then
VALUE=`echo ${VOL}*2.5/4096*171.5/71.5 | bc -l`
VALUE=`printf "%.3f" ${VALUE}`
echo "V5V0 is $VALUE V"
fi
done # Reads back channel 0..7 and temperature (channel #8)

if [[ $BOARD == "NXP i.MX8MPlus ADI TOF board" ]]; then
        modprobe adsd3100 fw_load=0 calib_load=0
        modprobe spi_nor
fi
modprobe imx8_media_devroot

My 'camera-test.sh' script is what is failing with the s_power message. That script is here:

#!/bin/bash

# Turn on kernel driver debug
echo 'file adsd3500.c +p'>/sys/kernel/debug/dynamic_debug/control
echo 8 > /proc/sys/kernel/printk

# List the V4L controls and formats for the ADSD3500
v4l2-ctl --list-ctrls   --device=/dev/v4l-subdev1 --list-formats

# Select mega-pixel mode (10)
v4l2-ctl --set-ctrl=operating_mode=10 -d /dev/v4l-subdev1

# Set the phase/depth bits to 12-bit
v4l2-ctl --set-ctrl=phase_depth_bits=4 -d /dev/v4l-subdev1

# Set AB frames to off
v4l2-ctl --set-ctrl=ab_bits=0 -d /dev/v4l-subdev1

# Set confidence frames to off
v4l2-ctl --set-ctrl=confidence_bits=0 -d /dev/v4l-subdev1

# Disable AB averaging
v4l2-ctl --set-ctrl=ab_averaging=0 -d /dev/v4l-subdev1

# Disable depth processing
v4l2-ctl --set-ctrl=depth_enable=0 -d /dev/v4l-subdev1

# Start the stream; width is MP width of 1024; height is 3072 pixels - 3 phase frames (1024×1024 each), no AB, no confidence; pixel format
nr_frames=${1:-1} # Define number of frames
v4l2-ctl --device /dev/video0 --set-fmt-video=width=1024,height=3072,pixelformat=BG12 --stream-mmap --stream-to=frame.bin --stream-count=$nr_frames
#v4l2-ctl --device /dev/video0 --set-fmt-video=width=2048,height=2560,pixelformat=BA81 --stream-mmap --stream-to=mode0.bin --stream-count=$nr_frames

The output from that script shows this error:

./camera-test.sh 
[  502.474737] adsd3500 1-0038: set_fmt: 3001 512x512 0

User Controls

                 operating_mode 0x009819e0 (int)    : min=0 max=10 step=1 de[  502.488026] adsd3500 1-0038: set_fmt: 3001 512x512 0
fault=0 value=10
                    chip_config 0x009819e1 (u8)     : min=0 max=255 step=1 de[  502.501382] adsd3500 1-0038: set_fmt: 3001 512x512 0
fault=0 [4099] flags=has-payload
               phase_depth_bits 0x009819e2 (intmenu): min=0 m[  502.514438] adsd3500 1-0038: set_fmt: 3001 512x512 0
ax=6 default=0 value=4
                        ab_bits 0x009819e3 (intmenu): min=0 max=6 defau[  502.527567] adsd3500 1-0038: set_fmt: 3001 512x512 0
lt=0 value=0
                confidence_bits 0x009819e4 (intmenu): min=0 max=2 default=0 value[  502.540627] adsd3500 1-0038: set_fmt: 3001 512x512 0
=0
                   ab_averaging 0x009819e5 (bool)   : default=1 value=0
                  [  502.553994] adsd3500 1-0038: set_fmt: 3001 512x512 0
 depth_enable 0x009819e6 (bool)   : default=1 value=0

Image Processing Controls

                 link_frequency 0x009f0901 (intmenu): min=0 max=0 default=0 value=0 flags=read-only
                     pixel_rate [  502.578409] mxc_isi.0: Call subdev s_power fail!
0x009f0902 (int64)  : min=1 max=2147483647 step=1 default=1 value=488000000 flags=read-only
ioctl: VIDIOC_ENUM_FMT
        Type: Video Capture

                VIDIOC_STREAMON returned -1 (Inappropriate ioctl for device)

I made sure your latest release image does work with my hardware and crosschecked the GPIO usage between the working image and my custom one. There was 1 difference I noticed - my image is missing this 'pwm' line:

gpio-156 ( |pwm ) out lo

ADI's image:

/sys/class/gpio/gpiochip0
label:30200000.gpio
base: 0
ngpio 32
/sys/class/gpio/gpiochip128
label:30240000.gpio
base: 128
ngpio 32
/sys/class/gpio/gpiochip32
label:30210000.gpio
base: 32
ngpio 32
/sys/class/gpio/gpiochip496
label:max7321
base: 496
ngpio 8
/sys/class/gpio/gpiochip504
label:max7320
base: 504
ngpio 8
/sys/class/gpio/gpiochip64
label:30220000.gpio
base: 64
ngpio 32
/sys/class/gpio/gpiochip96
label:30230000.gpio
base: 96
ngpio 32


gpiochip0: GPIOs 0-31, parent: platform/30200000.gpio, 30200000.gpio:
 gpio-9   (                    |interrupt           ) in  lo IRQ ACTIVE LOW
 gpio-13  (                    |switch              ) out hi ACTIVE LOW
 gpio-14  (                    |regulator-usb1-vbus ) out hi 

gpiochip1: GPIOs 32-63, parent: platform/30210000.gpio, 30210000.gpio:
 gpio-38  (                    |?                   ) out hi 
 gpio-43  (                    |sd1_regulator       ) out hi 
 gpio-44  (                    |cd                  ) in  lo IRQ ACTIVE LOW
 gpio-51  (                    |regulator-usdhc2    ) out lo ACTIVE LOW

gpiochip2: GPIOs 64-95, parent: platform/30220000.gpio, 30220000.gpio:
 gpio-64  (                    |reset               ) out lo ACTIVE LOW

gpiochip3: GPIOs 96-127, parent: platform/30230000.gpio, 30230000.gpio:
 gpio-122 (                    |sysfs               ) out hi 
 gpio-126 (                    |regulator-v5v0      ) out hi 
 gpio-127 (                    |regulator-vaux      ) out hi 

gpiochip4: GPIOs 128-159, parent: platform/30240000.gpio, 30240000.gpio:
 gpio-128 (                    |regulator-vmain     ) out hi 
 gpio-129 (                    |regulator-vsys      ) out hi 
 gpio-130 (                    |regulator-vcc-3p3   ) out hi 
 gpio-132 (                    |sysfs               ) out hi 
 gpio-133 (                    |LED1                ) out lo 
 gpio-156 (                    |pwm                 ) out lo 

gpiochip6: GPIOs 496-503, parent: i2c/1-0068, max7321, can sleep:
 gpio-496 (OC0                 |sysfs               ) out lo 
 gpio-497 (OC1                 |sysfs               ) out lo 
 gpio-498 (OC2                 |sysfs               ) out lo 
 gpio-499 (OC3                 |sysfs               ) out lo 
 gpio-500 (OC4                 |sysfs               ) out lo 
 gpio-501 (OC5                 |sysfs               ) out lo 
 gpio-502 (OC6                 |sysfs               ) out lo 
 gpio-503 (FLASH_WP            |sysfs               ) out hi 

gpiochip5: GPIOs 504-511, parent: i2c/1-0058, max7320, can sleep:
 gpio-504 (M0                  )
 gpio-505 (M1                  )
 gpio-506 (SI0                 )
 gpio-507 (U0                  |sysfs               ) out lo 
 gpio-508 (IDSEL               )
 gpio-509 (DS2                 )
 gpio-510 (EN_1P8              |sysfs               ) out hi 
 gpio-511 (EN_0P8              |sysfs               ) out hi 

My custom image:

/sys/class/gpio/gpiochip0
label:30200000.gpio
base: 0
ngpio 32
/sys/class/gpio/gpiochip128
label:30240000.gpio
base: 128
ngpio 32
/sys/class/gpio/gpiochip32
label:30210000.gpio
base: 32
ngpio 32
/sys/class/gpio/gpiochip496
label:max7321
base: 496
ngpio 8
/sys/class/gpio/gpiochip504
label:max7320
base: 504
ngpio 8
/sys/class/gpio/gpiochip64
label:30220000.gpio
base: 64
ngpio 32
/sys/class/gpio/gpiochip96
label:30230000.gpio
base: 96
ngpio 32


gpiochip0: GPIOs 0-31, parent: platform/30200000.gpio, 30200000.gpio:
 gpio-9   (                    |interrupt           ) in  lo IRQ ACTIVE LOW
 gpio-13  (                    |switch              ) out hi ACTIVE LOW
 gpio-14  (                    |regulator-usb1-vbus ) out hi 

gpiochip1: GPIOs 32-63, parent: platform/30210000.gpio, 30210000.gpio:
 gpio-38  (                    |?                   ) out hi 
 gpio-43  (                    |sd1_regulator       ) out hi 
 gpio-44  (                    |cd                  ) in  lo IRQ ACTIVE LOW
 gpio-51  (                    |regulator-usdhc2    ) out lo ACTIVE LOW

gpiochip2: GPIOs 64-95, parent: platform/30220000.gpio, 30220000.gpio:
 gpio-64  (                    |reset               ) out lo ACTIVE LOW

gpiochip3: GPIOs 96-127, parent: platform/30230000.gpio, 30230000.gpio:
 gpio-122 (                    |sysfs               ) out hi 
 gpio-126 (                    |regulator-v5v0      ) out hi 
 gpio-127 (                    |regulator-vaux      ) out hi 

gpiochip4: GPIOs 128-159, parent: platform/30240000.gpio, 30240000.gpio:
 gpio-128 (                    |regulator-vmain     ) out hi 
 gpio-129 (                    |regulator-vsys      ) out hi 
 gpio-130 (                    |regulator-vcc-3p3   ) out hi 
 gpio-132 (                    |sysfs               ) out hi 
 gpio-133 (                    |LED1                ) out lo 

gpiochip6: GPIOs 496-503, parent: i2c/1-0068, max7321, can sleep:
 gpio-496 (OC0                 |sysfs               ) out lo 
 gpio-497 (OC1                 |sysfs               ) out lo 
 gpio-498 (OC2                 |sysfs               ) out lo 
 gpio-499 (OC3                 |sysfs               ) out lo 
 gpio-500 (OC4                 |sysfs               ) out lo 
 gpio-501 (OC5                 |sysfs               ) out lo 
 gpio-502 (OC6                 |sysfs               ) out lo 
 gpio-503 (FLASH_WP            |sysfs               ) out hi 

gpiochip5: GPIOs 504-511, parent: i2c/1-0058, max7320, can sleep:
 gpio-504 (M0                  )
 gpio-505 (M1                  )
 gpio-506 (SI0                 )
 gpio-507 (U0                  |sysfs               ) out lo 
 gpio-508 (IDSEL               )
 gpio-509 (DS2                 )
 gpio-510 (EN_1P8              |sysfs               ) out hi 
 gpio-511 (EN_0P8              |sysfs               ) out hi

Also, here is the defconfig that Yocto is building with.

yocto-defconfig.txt

It works now - I must have been missing a config item from your defconfig. I used your defconfig for the kernel wholesale and it worked. Thank you for taking a look - this is closed.

Great to hear @pclass-sensonix.