diff --git a/builddtbo.sh b/builddtbo.sh index 22c0046..e98800f 100755 --- a/builddtbo.sh +++ b/builddtbo.sh @@ -1,8 +1,9 @@ #dtoverlay -r seeed-2mic-voicecard +DTC_FLAGS="-b 0 -Wno-unit_address_vs_reg -I dts -O dtb" -dtc -@ -I dts -O dtb -o seeed-2mic-voicecard.dtbo seeed-2mic-voicecard-overlay.dts -dtc -@ -I dts -O dtb -o seeed-4mic-voicecard.dtbo seeed-4mic-voicecard-overlay.dts -dtc -@ -I dts -O dtb -o seeed-8mic-voicecard.dtbo seeed-8mic-voicecard-overlay.dts +dtc -@ $DTC_FLAGS -o seeed-2mic-voicecard.dtbo seeed-2mic-voicecard-overlay.dts +dtc -@ $DTC_FLAGS -o seeed-4mic-voicecard.dtbo seeed-4mic-voicecard-overlay.dts +dtc -@ $DTC_FLAGS -o seeed-8mic-voicecard.dtbo seeed-8mic-voicecard-overlay.dts # cp *.dtbo /boot/overlays # dtoverlay seeed-2mic-voicecard diff --git a/install.sh b/install.sh index 105d058..fe6408a 100755 --- a/install.sh +++ b/install.sh @@ -39,6 +39,7 @@ _VER_RUN= function get_kernel_version() { local ZIMAGE IMG_OFFSET + _VER_RUN="" [ -z "$_VER_RUN" ] && { ZIMAGE=/boot/kernel.img IMG_OFFSET=$(LC_ALL=C grep -abo $'\x1f\x8b\x08\x00' $ZIMAGE | head -n 1 | cut -d ':' -f 1) @@ -173,6 +174,7 @@ git --git-dir=/etc/voicecard/.git --work-tree=/etc/voicecard/ commit -m "origin cp seeed-voicecard /usr/bin/ cp seeed-voicecard.service /lib/systemd/system/ systemctl enable seeed-voicecard.service +systemctl start seeed-voicecard echo "------------------------------------------------------" echo "Please reboot your raspberry pi to apply all settings" diff --git a/seeed-8mic-voicecard-overlay.dts b/seeed-8mic-voicecard-overlay.dts index 800e07c..6d60469 100644 --- a/seeed-8mic-voicecard-overlay.dts +++ b/seeed-8mic-voicecard-overlay.dts @@ -26,13 +26,15 @@ fragment@2 { target = <&gpio>; __overlay__ { - spk_amp_and_irq_pins: speaker_amp_and_irq_pins { + spk_amp_pins: spk_pins { brcm,pins = <17 22>; brcm,function = <1 0>; /* out in */ + brcm,pull = <0 0>; /* - - */ }; gpclk0_pins: gpclk0_pins { brcm,pins = <4>; brcm,function = <4>; /* alt func 0 */ + brcm,pull = <0>; /* - */ }; }; }; @@ -47,7 +49,7 @@ ac101: ac101@1a{ compatible = "x-power,ac101"; pinctrl-names = "default"; - pinctrl-0 = <&spk_amp_and_irq_pins>,<&gpclk0_pins>; + pinctrl-0 = <&spk_amp_pins &gpclk0_pins>; spk-amp-switch-gpios = <&gpio 17 0>; switch-irq-gpios = <&gpio 22 0>; reg = <0x1a>; @@ -80,6 +82,8 @@ seeed-voice-card,name = "seeed-8mic-voicecard"; seeed-voice-card,channels-playback-override = <8>; seeed-voice-card,channels-capture-override = <8>; + #address-cells = <1>; + #size-cells = <0>; status = "okay"; seeed-voice-card,dai-link@0 { @@ -88,6 +92,7 @@ frame-master = <&codec0_dai>; /* bitclock-inversion; */ /* frame-inversion; */ + reg = <0>; cpu { sound-dai = <&i2s>; diff --git a/seeed-8mic-voicecard.dtbo b/seeed-8mic-voicecard.dtbo index 1976f6e..4ef515b 100644 Binary files a/seeed-8mic-voicecard.dtbo and b/seeed-8mic-voicecard.dtbo differ diff --git a/seeed-voicecard b/seeed-voicecard index 2818554..22e95b2 100755 --- a/seeed-voicecard +++ b/seeed-voicecard @@ -29,6 +29,56 @@ modprobe i2c-dev #enable spi interface dtparam spi=on +_VER_RUN= +function get_kernel_version() { + local ZIMAGE IMG_OFFSET + + _VER_RUN="" + [ -z "$_VER_RUN" ] && { + ZIMAGE=/boot/kernel.img + IMG_OFFSET=$(LC_ALL=C grep -abo $'\x1f\x8b\x08\x00' $ZIMAGE | head -n 1 | cut -d ':' -f 1) + _VER_RUN=$(dd if=$ZIMAGE obs=64K ibs=4 skip=$(( IMG_OFFSET / 4)) | zcat | grep -a -m1 "Linux version" | strings | awk '{ print $3; }') + } + echo "$_VER_RUN" + return 0 +} + +CONFIG=/boot/config.txt +get_overlay() { + ov=$1 + if grep -q -E "^dtoverlay=$ov" $CONFIG; then + echo 0 + else + echo 1 + fi +} + +do_overlay() { + ov=$1 + RET=$2 + DEFAULT=--defaultno + CURRENT=0 + if [ $(get_overlay $ov) -eq 0 ]; then + DEFAULT= + CURRENT=1 + fi + if [ $RET -eq $CURRENT ]; then + ASK_TO_REBOOT=1 + fi + if [ $RET -eq 0 ]; then + sed $CONFIG -i -e "s/^#dtoverlay=$ov/dtoverlay=$ov/" + if ! grep -q -E "^dtoverlay=$ov" $CONFIG; then + printf "dtoverlay=$ov\n" >> $CONFIG + fi + STATUS=enabled + elif [ $RET -eq 1 ]; then + sed $CONFIG -i -e "s/^dtoverlay=$ov/#dtoverlay=$ov/" + STATUS=disabled + else + return $RET + fi +} + is_1a=$(i2cdetect -y 1 0x1a 0x1a | grep 1a | awk '{print $2}') is_35=$(i2cdetect -y 1 0x35 0x35 | grep 35 | awk '{print $2}') @@ -37,9 +87,12 @@ is_3b=$(i2cdetect -y 1 0x3b 0x3b | grep 3b | awk '{print $2}') rm /etc/asound.conf rm /var/lib/alsa/asound.state +RPI_HATS="seeed-2mic-voicecard seeed-4mic-voicecard seeed-8mic-voicecard" +overlay="" + if [ "x${is_1a}" == "x1a" ] && [ "x${is_35}" == "x" ] ; then echo "install 2mic" - dtoverlay seeed-2mic-voicecard + overlay=seeed-2mic-voicecard rm /etc/asound.conf rm /var/lib/alsa/asound.state echo "create 2mic asound configure file" @@ -51,7 +104,7 @@ fi if [ "x${is_3b}" == "x3b" ] && [ "x${is_35}" == "x" ] ; then echo "install 4mic" - dtoverlay seeed-4mic-voicecard + overlay=seeed-4mic-voicecard rm /etc/asound.conf rm /var/lib/alsa/asound.state echo "create 4mic asound configure file" @@ -63,7 +116,7 @@ fi if [ "x${is_3b}" == "x3b" ] && [ "x${is_35}" == "x35" ] ; then echo "install 6mic" - dtoverlay seeed-8mic-voicecard + overlay=seeed-8mic-voicecard rm /etc/asound.conf rm /var/lib/alsa/asound.state echo "create 6mic asound configure file" @@ -73,9 +126,30 @@ if [ "x${is_3b}" == "x3b" ] && [ "x${is_35}" == "x35" ] ; then ln -s /etc/voicecard/ac108_6mic.state /var/lib/alsa/asound.state fi +if [ "$overlay" ]; then + + echo Install $overlay ... + dtoverlay $overlay + + kernel_ver=$(get_kernel_version) + # echo kernel_ver=$kernel_ver + + # TODO: dynamic dtoverlay Bug of v4.19.x + # no DT node phandle inserted. + if [[ "$kernel_ver" =~ ^4\.19.*$ ]]; then + for i in $RPI_HATS; do + if [ "$i" == "$overlay" ]; then + do_overlay $overlay 0 + else + echo Uninstall $i ... + do_overlay $i 1 + fi + done + fi +fi + alsactl restore #Fore 3.5mm ('headphone') jack amixer cset numid=3 1 - diff --git a/seeed-voicecard.c b/seeed-voicecard.c index 1a5151d..f08fbd8 100644 --- a/seeed-voicecard.c +++ b/seeed-voicecard.c @@ -294,13 +294,19 @@ static int seeed_voice_card_dai_link_of(struct device_node *node, snprintf(prop, sizeof(prop), "%scpu", prefix); cpu = of_get_child_by_name(node, prop); + if (!cpu) { + ret = -EINVAL; + dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop); + goto dai_link_of_err; + } + snprintf(prop, sizeof(prop), "%splat", prefix); plat = of_get_child_by_name(node, prop); snprintf(prop, sizeof(prop), "%scodec", prefix); codec = of_get_child_by_name(node, prop); - if (!cpu || !codec) { + if (!codec) { ret = -EINVAL; dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop); goto dai_link_of_err; diff --git a/uninstall.sh b/uninstall.sh index cbade77..0106ed8 100755 --- a/uninstall.sh +++ b/uninstall.sh @@ -13,6 +13,42 @@ fi uname_r=$(uname -r) +CONFIG=/boot/config.txt +get_overlay() { + ov=$1 + if grep -q -E "^dtoverlay=$ov" $CONFIG; then + echo 0 + else + echo 1 + fi +} + +do_overlay() { + ov=$1 + RET=$2 + DEFAULT=--defaultno + CURRENT=0 + if [ $(get_overlay $ov) -eq 0 ]; then + DEFAULT= + CURRENT=1 + fi + if [ $RET -eq $CURRENT ]; then + ASK_TO_REBOOT=1 + fi + if [ $RET -eq 0 ]; then + sed $CONFIG -i -e "s/^#dtoverlay=$ov/dtoverlay=$ov/" + if ! grep -q -E "^dtoverlay=$ov" $CONFIG; then + printf "dtoverlay=$ov\n" >> $CONFIG + fi + STATUS=enabled + elif [ $RET -eq 1 ]; then + sed $CONFIG -i -e "s/^dtoverlay=$ov/#dtoverlay=$ov/" + STATUS=disabled + else + return $RET + fi +} + echo "remove dtbos" rm /boot/overlays/seeed-2mic-voicecard.dtbo || true @@ -37,6 +73,13 @@ rm /lib/modules/${uname_r}/kernel/sound/soc/codecs/snd-soc-wm8960.ko || true rm /lib/modules/${uname_r}/kernel/sound/soc/codecs/snd-soc-ac108.ko || true rm /lib/modules/${uname_r}/kernel/sound/soc/bcm/snd-soc-seeed-voicecard.ko || true +echo "remove $CONFIG configuration" +RPI_HATS="seeed-2mic-voicecard seeed-4mic-voicecard seeed-8mic-voicecard" +for i in $RPI_HATS; do + echo Uninstall $i ... + do_overlay $i 1 +done + echo "------------------------------------------------------" echo "Please reboot your raspberry pi to apply all settings" echo "Thank you!"