You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

493 lines
14 KiB

  1. #!/bin/bash
  2. : <<'DISCLAIMER'
  3. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  4. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  5. OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  6. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  7. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  8. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  9. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  10. OTHER DEALINGS IN THE SOFTWARE.
  11. This script is licensed under the terms of the MIT license.
  12. Unless otherwise noted, code reproduced herein
  13. was written for this script.
  14. - The Pimoroni Crew - (modified by Adafruit!)
  15. DISCLAIMER
  16. # script control variables
  17. productname="i2s amplifier" # the name of the product to install
  18. scriptname="i2samp" # the name of this script
  19. spacereq=1 # minimum size required on root partition in MB
  20. debugmode="no" # whether the script should use debug routines
  21. debuguser="none" # optional test git user to use in debug mode
  22. debugpoint="none" # optional git repo branch or tag to checkout
  23. forcesudo="no" # whether the script requires to be ran with root privileges
  24. promptreboot="no" # whether the script should always prompt user to reboot
  25. mininstall="no" # whether the script enforces minimum install routine
  26. customcmd="yes" # whether to execute commands specified before exit
  27. armhfonly="yes" # whether the script is allowed to run on other arch
  28. armv6="yes" # whether armv6 processors are supported
  29. armv7="yes" # whether armv7 processors are supported
  30. armv8="yes" # whether armv8 processors are supported
  31. raspbianonly="no" # whether the script is allowed to run on other OSes
  32. osreleases=( "Raspbian" ) # list os-releases supported
  33. oswarning=( "Debian" "Kano" "Mate" "PiTop" "Ubuntu" ) # list experimental os-releases
  34. osdeny=( "Darwin" "Kali" ) # list os-releases specifically disallowed
  35. FORCE=$1
  36. DEVICE_TREE=true
  37. ASK_TO_REBOOT=false
  38. CURRENT_SETTING=false
  39. UPDATE_DB=false
  40. BOOTCMD=/boot/cmdline.txt
  41. CONFIG=/boot/config.txt
  42. APTSRC=/etc/apt/sources.list
  43. INITABCONF=/etc/inittab
  44. BLACKLIST=/etc/modprobe.d/raspi-blacklist.conf
  45. LOADMOD=/etc/modules
  46. DTBODIR=/boot/overlays
  47. # function define
  48. confirm() {
  49. if [ "$FORCE" == '-y' ]; then
  50. true
  51. else
  52. read -r -p "$1 [y/N] " response < /dev/tty
  53. if [[ $response =~ ^(yes|y|Y)$ ]]; then
  54. true
  55. else
  56. false
  57. fi
  58. fi
  59. }
  60. prompt() {
  61. read -r -p "$1 [y/N] " response < /dev/tty
  62. if [[ $response =~ ^(yes|y|Y)$ ]]; then
  63. true
  64. else
  65. false
  66. fi
  67. }
  68. success() {
  69. echo -e "$(tput setaf 2)$1$(tput sgr0)"
  70. }
  71. inform() {
  72. echo -e "$(tput setaf 6)$1$(tput sgr0)"
  73. }
  74. warning() {
  75. echo -e "$(tput setaf 1)$1$(tput sgr0)"
  76. }
  77. newline() {
  78. echo ""
  79. }
  80. progress() {
  81. count=0
  82. until [ $count -eq $1 ]; do
  83. echo -n "..." && sleep 1
  84. ((count++))
  85. done
  86. echo
  87. }
  88. sudocheck() {
  89. if [ $(id -u) -ne 0 ]; then
  90. echo -e "Install must be run as root. Try 'sudo ./$scriptname'\n"
  91. exit 1
  92. fi
  93. }
  94. sysclean() {
  95. sudo apt-get clean && sudo apt-get autoclean
  96. sudo apt-get -y autoremove &> /dev/null
  97. }
  98. sysupdate() {
  99. if ! $UPDATE_DB; then
  100. echo "Updating apt indexes..." && progress 3 &
  101. sudo apt-get update 1> /dev/null || { warning "Apt failed to update indexes!" && exit 1; }
  102. echo "Reading package lists..."
  103. progress 3 && UPDATE_DB=true
  104. fi
  105. }
  106. sysupgrade() {
  107. sudo apt-get upgrade
  108. sudo apt-get clean && sudo apt-get autoclean
  109. sudo apt-get -y autoremove &> /dev/null
  110. }
  111. sysreboot() {
  112. warning "Some changes made to your system require"
  113. warning "your computer to reboot to take effect."
  114. newline
  115. if prompt "Would you like to reboot now?"; then
  116. sync && sudo reboot
  117. fi
  118. }
  119. arch_check() {
  120. IS_ARMHF=false
  121. IS_ARMv6=false
  122. if uname -m | grep "armv.l" > /dev/null; then
  123. IS_ARMHF=true
  124. if uname -m | grep "armv6l" > /dev/null; then
  125. IS_ARMv6=true
  126. fi
  127. fi
  128. }
  129. os_check() {
  130. IS_RASPBIAN=false
  131. IS_MACOSX=false
  132. IS_SUPPORTED=false
  133. IS_EXPERIMENTAL=false
  134. if [ -f /etc/os-release ]; then
  135. if cat /etc/os-release | grep "Raspbian" > /dev/null; then
  136. IS_RASPBIAN=true && IS_SUPPORTED=true
  137. fi
  138. if command -v apt-get > /dev/null; then
  139. for os in ${osreleases[@]}; do
  140. if cat /etc/os-release | grep $os > /dev/null; then
  141. IS_SUPPORTED=true && IS_EXPERIMENTAL=false
  142. fi
  143. done
  144. for os in ${oswarning[@]}; do
  145. if cat /etc/os-release | grep $os > /dev/null; then
  146. IS_SUPPORTED=false && IS_EXPERIMENTAL=true
  147. fi
  148. done
  149. for os in ${osdeny[@]}; do
  150. if cat /etc/os-release | grep $os > /dev/null; then
  151. IS_SUPPORTED=false && IS_EXPERIMENTAL=false
  152. fi
  153. done
  154. fi
  155. fi
  156. if [ -d ~/.kano-settings ] || [ -d ~/.kanoprofile ]; then
  157. IS_RASPBIAN=false
  158. for os in ${oswarning[@]}; do
  159. if [ $os == "Kano" ]; then
  160. IS_SUPPORTED=false && IS_EXPERIMENTAL=true
  161. fi
  162. done
  163. for os in ${osdeny[@]}; do
  164. if [ $os == "Kano" ]; then
  165. IS_SUPPORTED=false && IS_EXPERIMENTAL=false
  166. fi
  167. done
  168. fi
  169. if [ -f ~/.pt-dashboard-config ] || [ -d ~/.pt-dashboard ] || [ -d ~/.pt-os-dashboard ]; then
  170. IS_RASPBIAN=false
  171. for os in ${oswarning[@]}; do
  172. if [ $os == "PiTop" ]; then
  173. IS_SUPPORTED=false && IS_EXPERIMENTAL=true
  174. fi
  175. done
  176. for os in ${osdeny[@]}; do
  177. if [ $os == "PiTop" ]; then
  178. IS_SUPPORTED=false && IS_EXPERIMENTAL=false
  179. fi
  180. done
  181. fi
  182. if [ -d ~/.config/ubuntu-mate ]; then
  183. for os in ${osdeny[@]}; do
  184. if [ $os == "Mate" ]; then
  185. IS_SUPPORTED=false && IS_EXPERIMENTAL=false
  186. fi
  187. done
  188. fi
  189. if uname -s | grep "Darwin" > /dev/null; then
  190. IS_MACOSX=true
  191. for os in ${osdeny[@]}; do
  192. if [ $os == "Darwin" ]; then
  193. IS_SUPPORTED=false && IS_EXPERIMENTAL=false
  194. fi
  195. done
  196. fi
  197. }
  198. raspbian_check() {
  199. IS_SUPPORTED=false
  200. IS_EXPERIMENTAL=false
  201. if [ -f /etc/os-release ]; then
  202. if cat /etc/os-release | grep "/sid" > /dev/null; then
  203. IS_SUPPORTED=false && IS_EXPERIMENTAL=true
  204. elif cat /etc/os-release | grep "buster" > /dev/null; then
  205. IS_SUPPORTED=false && IS_EXPERIMENTAL=true
  206. elif cat /etc/os-release | grep "stretch" > /dev/null; then
  207. IS_SUPPORTED=false && IS_EXPERIMENTAL=true
  208. elif cat /etc/os-release | grep "jessie" > /dev/null; then
  209. IS_SUPPORTED=true && IS_EXPERIMENTAL=false
  210. elif cat /etc/os-release | grep "wheezy" > /dev/null; then
  211. IS_SUPPORTED=true && IS_EXPERIMENTAL=false
  212. else
  213. IS_SUPPORTED=false && IS_EXPERIMENTAL=false
  214. fi
  215. fi
  216. }
  217. : <<'MAINSTART'
  218. Perform all global variables declarations as well as function definition
  219. above this section for clarity, thanks!
  220. MAINSTART
  221. # checks and init
  222. arch_check
  223. os_check
  224. if [ $debugmode != "no" ]; then
  225. echo "USER_HOME is $USER_HOME" && newline
  226. echo "IS_RASPBIAN is $IS_RASPBIAN"
  227. echo "IS_MACOSX is $IS_MACOSX"
  228. echo "IS_SUPPORTED is $IS_SUPPORTED"
  229. echo "IS_EXPERIMENTAL is $IS_EXPERIMENTAL"
  230. newline
  231. fi
  232. if ! $IS_ARMHF; then
  233. warning "This hardware is not supported, sorry!"
  234. warning "Config files have been left untouched"
  235. newline && exit 1
  236. fi
  237. if $IS_ARMv8 && [ $armv8 == "no" ]; then
  238. warning "Sorry, your CPU is not supported by this installer"
  239. newline && exit 1
  240. elif $IS_ARMv7 && [ $armv7 == "no" ]; then
  241. warning "Sorry, your CPU is not supported by this installer"
  242. newline && exit 1
  243. elif $IS_ARMv6 && [ $armv6 == "no" ]; then
  244. warning "Sorry, your CPU is not supported by this installer"
  245. newline && exit 1
  246. fi
  247. if [ $raspbianonly == "yes" ] && ! $IS_RASPBIAN;then
  248. warning "This script is intended for Raspbian on a Raspberry Pi!"
  249. newline && exit 1
  250. fi
  251. if $IS_RASPBIAN; then
  252. raspbian_check
  253. if ! $IS_SUPPORTED && ! $IS_EXPERIMENTAL; then
  254. newline && warning "--- Warning ---" && newline
  255. echo "The $productname installer"
  256. echo "does not work on this version of Raspbian."
  257. echo "Check https://github.com/$gitusername/$gitreponame"
  258. echo "for additional information and support"
  259. newline && exit 1
  260. fi
  261. fi
  262. if ! $IS_SUPPORTED && ! $IS_EXPERIMENTAL; then
  263. warning "Your operating system is not supported, sorry!"
  264. newline && exit 1
  265. fi
  266. if $IS_EXPERIMENTAL; then
  267. warning "Support for your operating system is experimental. Please visit"
  268. warning "forums.adafruit.com if you experience issues with this product."
  269. newline
  270. fi
  271. if [ $forcesudo == "yes" ]; then
  272. sudocheck
  273. fi
  274. newline
  275. echo "This script will install everything needed to use"
  276. echo "$productname"
  277. newline
  278. warning "--- Warning ---"
  279. newline
  280. echo "Always be careful when running scripts and commands"
  281. echo "copied from the internet. Ensure they are from a"
  282. echo "trusted source."
  283. newline
  284. echo "If you want to see what this script does before"
  285. echo "running it, you should run:"
  286. echo " \curl -sS github.com/adafruit/Raspberry-Pi-Installer-Scripts/$scriptname"
  287. newline
  288. if confirm "Do you wish to continue?"; then
  289. newline
  290. echo "Checking hardware requirements..."
  291. if [ -e $CONFIG ] && grep -q "^device_tree=$" $CONFIG; then
  292. DEVICE_TREE=false
  293. fi
  294. if $DEVICE_TREE; then
  295. newline
  296. echo "Adding Device Tree Entry to $CONFIG"
  297. if [ -e $CONFIG ] && grep -q "^dtoverlay=hifiberry-dac$" $CONFIG; then
  298. echo "dtoverlay already active"
  299. else
  300. echo "dtoverlay=hifiberry-dac" | sudo tee -a $CONFIG
  301. ASK_TO_REBOOT=true
  302. fi
  303. if [ -e $CONFIG ] && grep -q "^dtoverlay=i2s-mmap$" $CONFIG; then
  304. echo "i2s mmap dtoverlay already active"
  305. else
  306. echo "dtoverlay=i2s-mmap" | sudo tee -a $CONFIG
  307. ASK_TO_REBOOT=true
  308. fi
  309. if [ -e $BLACKLIST ]; then
  310. newline
  311. echo "Commenting out Blacklist entry in "
  312. echo "$BLACKLIST"
  313. sudo sed -i -e "s|^blacklist[[:space:]]*i2c-bcm2708.*|#blacklist i2c-bcm2708|" \
  314. -e "s|^blacklist[[:space:]]*snd-soc-pcm512x.*|#blacklist snd-soc-pcm512x|" \
  315. -e "s|^blacklist[[:space:]]*snd-soc-wm8804.*|#blacklist snd-soc-wm8804|" $BLACKLIST &> /dev/null
  316. fi
  317. else
  318. newline
  319. echo "No Device Tree Detected, not supported"
  320. newline
  321. exit 1
  322. fi
  323. if [ -e $CONFIG ] && grep -q -E "^dtparam=audio=on$" $CONFIG; then
  324. bcm2835off="no"
  325. newline
  326. echo "Disabling default sound driver"
  327. sudo sed -i "s|^dtparam=audio=on$|#dtparam=audio=on|" $CONFIG &> /dev/null
  328. if [ -e $LOADMOD ] && grep -q "^snd-bcm2835" $LOADMOD; then
  329. sudo sed -i "s|^snd-bcm2835|#snd-bcm2835|" $LOADMOD &> /dev/null
  330. fi
  331. ASK_TO_REBOOT=true
  332. elif [ -e $LOADMOD ] && grep -q "^snd-bcm2835" $LOADMOD; then
  333. bcm2835off="no"
  334. newline
  335. echo "Disabling default sound module"
  336. sudo sed -i "s|^snd-bcm2835|#snd-bcm2835|" $LOADMOD &> /dev/null
  337. ASK_TO_REBOOT=true
  338. else
  339. newline
  340. echo "Default sound driver currently not loaded"
  341. bcm2835off="yes"
  342. fi
  343. echo "Configuring sound output"
  344. if [ -e /etc/asound.conf ]; then
  345. if [ -e /etc/asound.conf.old ]; then
  346. sudo rm -f /etc/asound.conf.old
  347. fi
  348. sudo mv /etc/asound.conf /etc/asound.conf.old
  349. fi
  350. cat > ~/asound.conf << 'EOL'
  351. pcm.speakerbonnet {
  352. type hw card 0
  353. }
  354. pcm.dmixer {
  355. type dmix
  356. ipc_key 1024
  357. ipc_perm 0666
  358. slave {
  359. pcm "speakerbonnet"
  360. period_time 0
  361. period_size 1024
  362. buffer_size 8192
  363. rate 44100
  364. channels 2
  365. }
  366. }
  367. ctl.dmixer {
  368. type hw card 0
  369. }
  370. pcm.softvol {
  371. type softvol
  372. slave.pcm "dmixer"
  373. control.name "PCM"
  374. control.card 0
  375. }
  376. ctl.softvol {
  377. type hw card 0
  378. }
  379. pcm.!default {
  380. type plug
  381. slave.pcm "softvol"
  382. }
  383. EOL
  384. sudo mv ~/asound.conf /etc/asound.conf
  385. newline
  386. echo "Installing aplay systemd unit"
  387. sudo sh -c 'cat > /etc/systemd/system/aplay.service' << 'EOL'
  388. [Unit]
  389. Description=Invoke aplay from /dev/zero at system start.
  390. [Service]
  391. ExecStart=/usr/bin/aplay -D default -t raw -r 44100 -c 2 -f S16_LE /dev/zero
  392. [Install]
  393. WantedBy=multi-user.target
  394. EOL
  395. sudo systemctl daemon-reload
  396. sudo systemctl disable aplay
  397. newline
  398. echo "You can optionally activate '/dev/zero' playback in"
  399. echo "the background at boot. This will remove all"
  400. echo "popping/clicking but does use some processor time."
  401. newline
  402. if confirm "Activate '/dev/zero' playback in background? [RECOMMENDED]"; then
  403. newline
  404. sudo systemctl enable aplay
  405. ASK_TO_REBOOT=true
  406. fi
  407. if [ $bcm2835off == "yes" ]; then
  408. newline
  409. echo "We can now test your $productname"
  410. warning "Set your speakers at a low volume if possible!"
  411. if confirm "Do you wish to test your system now?"; then
  412. echo "Testing..."
  413. speaker-test -l5 -c2 -t wav
  414. fi
  415. fi
  416. newline
  417. success "All done!"
  418. newline
  419. echo "Enjoy your new $productname!"
  420. newline
  421. if [ $promptreboot == "yes" ] || $ASK_TO_REBOOT; then
  422. sysreboot
  423. fi
  424. else
  425. newline
  426. echo "Aborting..."
  427. newline
  428. fi
  429. exit 0