Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions br-ext-chip-ambarella/configs/s3l_lite_defconfig
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Architecture
BR2_arm=y
BR2_cortex_a7=y
BR2_cortex_a9=y
BR2_ARM_EABI=y
BR2_ARM_FPU_NEON_VFPV4=y
BR2_ARM_ENABLE_NEON=y
BR2_ARM_ENABLE_VFP=y
BR2_ARM_FPU_NEON=y
BR2_ARM_INSTRUCTIONS_THUMB2=y

# Toolchain
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#!/bin/sh
#
# Ambarella S3L driver bring-up, in the vendor's order: iav and what it needs,
# then the sensor, then the DSP microcode.
#
# iav registers plain character devices and no device class, so mdev never sees
# them and the nodes have to be made here. The major comes from /proc/devices;
# the minors are fixed.
#
# The microcode (orccode.bin, orcme.bin, default_binary.bin) and the load_ucode
# tool are Ambarella's and are not part of this package, and the stock tool is
# a glibc armhf binary that will not run on this musl image. Without them the
# drivers load and the DSP does not start, so no video. Drop working ones in
# place and this script uses them.

vendor=$(ipcinfo -v)
ucode_dir=/lib/firmware

log_vendor() {
logger -s -p daemon.info -t "${vendor:-ambarella}" "$1"
}

load() {
mod=$1
shift
grep -q "^${mod} " /proc/modules && return 0
# modprobe, not insmod: iav needs dsp, hw_timer, imgproc and vout, and
# modules.dep knows that.
modprobe "${mod}" "$@"
}

make_node() {
major=$(awk -v name="$1" '$2 == name { print $1; exit }' /proc/devices)
if [ -z "${major}" ]; then
log_vendor "No $1 in /proc/devices, /dev/$1 not created"
return 1
fi
[ -c "/dev/$1" ] || mknod -m 600 "/dev/$1" c "${major}" "$2"
}

# ipcinfo reports a bare name and cannot tell the interface, so a bare name
# means MIPI. imx290 and imx326 also come as LVDS drivers, reached by setting
# sensor=imx290_lvds or sensor=imx326_lvds.
sensor_module() {
case "$1" in
ov4689 | ov2718 | imx290 | imx274 | imx326)
echo "$1_mipi"
;;
*_mipi)
case "$1" in
ov4689_mipi | ov2718_mipi | imx290_mipi | imx274_mipi | imx326_mipi)
echo "$1"
;;
esac
;;
imx290_lvds | imx326_lvds)
echo "${1%_lvds}"
;;
ar0230 | ar0237 | imx172 | imx178 | imx226)
echo "$1"
;;
esac
}

load_sensor() {
sensor=$(fw_printenv -n sensor 2>/dev/null | tr 'A-Z' 'a-z')
# A failed probe may have been stored as "unknown". That must not stop
# this one from trying again.
if [ -z "${sensor}" ] || [ "${sensor}" = unknown ]; then
sensor=$(ipcinfo -s 2>/dev/null | tr 'A-Z' 'a-z')
fi

if [ -z "${sensor}" ]; then
log_vendor "No sensor in the environment and none detected"
return 1
fi

module=$(sensor_module "${sensor}")
if [ -z "${module}" ]; then
log_vendor "No driver in this package for sensor ${sensor}"
return 1
fi

load "${module}" || log_vendor "Failed to load ${module}"
}

load_microcode() {
if ! command -v load_ucode >/dev/null || [ ! -f "${ucode_dir}/orccode.bin" ]; then
log_vendor "No DSP microcode on this image, video will not start"
return 1
fi

load_ucode "${ucode_dir}" >/dev/null || log_vendor "load_ucode failed"
}

insert_ko() {
if ! load iav; then
log_vendor "Failed to load iav"
return 1
fi

make_node iav 0
make_node ucode 1
load_sensor
load_microcode
}

case "$1" in
-i | "")
insert_ko
;;
*)
echo "Usage: $0 [-i]"
exit 1
;;
esac
Loading