diff --git a/.gitignore b/.gitignore index 14cdf13b..a5e81b47 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,6 @@ # Ignore build directory build*/ -# Created by coffee-maker.sh -/*.coffee - # Ignore shared directories shared-*/ diff --git a/README.md b/README.md index 254dc0da..2025a3e3 100755 --- a/README.md +++ b/README.md @@ -32,6 +32,10 @@ distribution is [supported](https://docs.yoctoproject.org/singleindex.html#suppo Additional host tools need to be installed for native builds to work. +* Install the "npm" package, doing it like this circumvents issues with broken dependencies: + sudo apt-get install nodejs-dev node-gyp libssl1.0-dev + sudo apt-get install npm + * Run the barys build script: `./balena-yocto-scripts/build/barys` diff --git a/layers/meta-balena-topic/README.md b/layers/meta-balena-topic/README.md old mode 100644 new mode 100755 index 1413d589..2b51b77f --- a/layers/meta-balena-topic/README.md +++ b/layers/meta-balena-topic/README.md @@ -5,3 +5,4 @@ This repository enables building BalenaOS for chosen meta-topic machines. ## Supported machines * tdpzu9 +* lcbzu9 \ No newline at end of file diff --git a/layers/meta-balena-topic/conf/samples/bblayers.conf.sample b/layers/meta-balena-topic/conf/samples/bblayers.conf.sample old mode 100644 new mode 100755 index 33cd4559..7b648b1a --- a/layers/meta-balena-topic/conf/samples/bblayers.conf.sample +++ b/layers/meta-balena-topic/conf/samples/bblayers.conf.sample @@ -20,4 +20,5 @@ BBLAYERS ?= " \ ${TOPDIR}/../layers/meta-xilinx/meta-xilinx-bsp \ ${TOPDIR}/../layers/meta-xilinx/meta-xilinx-core \ ${TOPDIR}/../layers/meta-topic \ + ${TOPDIR}/../layers/meta-lowpad-lcb \ " diff --git a/layers/meta-balena-topic/conf/samples/local.conf.sample b/layers/meta-balena-topic/conf/samples/local.conf.sample index 5efa4f03..657b10cc 100755 --- a/layers/meta-balena-topic/conf/samples/local.conf.sample +++ b/layers/meta-balena-topic/conf/samples/local.conf.sample @@ -1,5 +1,6 @@ # Supported machines MACHINE ?= "tdpzu9" +MACHINE ?= "lcbzu9" LICENSE_FLAGS_WHITELIST += "xilinx" diff --git a/layers/meta-balena-topic/recipes-core/images/balena-image.bbappend b/layers/meta-balena-topic/recipes-core/images/balena-image.bbappend index 6eabdeaa..987a56f9 100755 --- a/layers/meta-balena-topic/recipes-core/images/balena-image.bbappend +++ b/layers/meta-balena-topic/recipes-core/images/balena-image.bbappend @@ -1,5 +1,8 @@ DEPENDS += "balena-bootscript" +BALENA_BOOT_BIN ?= "" +DEPENDS += "${BALENA_BOOT_BIN}" + # Add components that we need to boot IMAGE_INSTALL += "\ bootscript \ @@ -10,6 +13,7 @@ IMAGE_INSTALL += "\ BALENA_EXTRA_BOOT_FILES:zynqmp = "boot.bin:/boot.bin u-boot.itb:/u-boot.itb balena-bootscript.scr:/boot.scr" BALENA_EXTRA_BOOT_FILES:zynq = "boot.bin:/boot.bin u-boot.img:/u-boot.img balena-bootscript.scr:/boot.scr" +BALENA_EXTRA_BOOT_FILES:lcbzu9 = "lcb-boot.bin:/boot.bin u-boot.itb:/u-boot.itb balena-bootscript.scr:/boot.scr" BALENA_BOOT_PARTITION_FILES:append = " ${BALENA_EXTRA_BOOT_FILES}" DEVICETREELINKS ??= "system.dtb ${DEVICETREE}" @@ -33,3 +37,9 @@ ROOTFS_POSTPROCESS_COMMAND += "topicbalena_rootfs_postprocess; " # We need to increase the rootfs size to make space for additional drivers in ROOTFS. # BalenaOS image has a 700MB max size defined in 'image_types_balena.bbclass' IMAGE_ROOTFS_SIZE="409600" + +# We require access to the git repository here, so we must run outside fakeroot +do_addrevisioninfo() { + git rev-parse --verify --short HEAD >> ${IMAGE_ROOTFS}${sysconfdir}/revision +} +addtask do_addrevisioninfo before do_image after do_rootfs \ No newline at end of file diff --git a/layers/meta-balena-topic/recipes-kernel/linux/linux-xlnx_%.bbappend b/layers/meta-balena-topic/recipes-kernel/linux/linux-xlnx_%.bbappend old mode 100644 new mode 100755 diff --git a/layers/meta-balena-topic/recipes-kernel/module/kernel-module-rtl88x2bu/0001-Makefile-Sanitize-config-for-non-x86-platforms.patch b/layers/meta-balena-topic/recipes-kernel/module/kernel-module-rtl88x2bu/0001-Makefile-Sanitize-config-for-non-x86-platforms.patch old mode 100755 new mode 100644 index abeb627f..667e5063 --- a/layers/meta-balena-topic/recipes-kernel/module/kernel-module-rtl88x2bu/0001-Makefile-Sanitize-config-for-non-x86-platforms.patch +++ b/layers/meta-balena-topic/recipes-kernel/module/kernel-module-rtl88x2bu/0001-Makefile-Sanitize-config-for-non-x86-platforms.patch @@ -1,4 +1,4 @@ -From 8d7a238307d8a1afc93738d676cd90aef06b2cea Mon Sep 17 00:00:00 2001 +From 5c3a5e306bca1e4bd28920cb4c7db63600287bcd Mon Sep 17 00:00:00 2001 From: Francois Date: Tue, 10 May 2022 17:23:04 +0200 Subject: [PATCH 1/3] Makefile: Sanitize config for non-x86 platforms @@ -8,10 +8,10 @@ Subject: [PATCH 1/3] Makefile: Sanitize config for non-x86 platforms 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile -index 22bd0e0..e5bc585 100755 +index b06bbbe..9a46be2 100755 --- a/Makefile +++ b/Makefile -@@ -118,7 +118,7 @@ CONFIG_RTW_SDIO_PM_KEEP_POWER = y +@@ -120,7 +120,7 @@ CONFIG_RTW_SDIO_PM_KEEP_POWER = y ###################### MP HW TX MODE FOR VHT ####################### CONFIG_MP_VHT_HW_TX_MODE = n ###################### Platform Related ####################### diff --git a/layers/meta-balena-topic/recipes-kernel/module/kernel-module-rtl88x2bu/0002-Add-CONFIG_PLATFORM_OPENEMBEDDED-to-Makefile-as-defa.patch b/layers/meta-balena-topic/recipes-kernel/module/kernel-module-rtl88x2bu/0002-Add-CONFIG_PLATFORM_OPENEMBEDDED-to-Makefile-as-defa.patch old mode 100755 new mode 100644 index 6b2b6f56..4ea6341d --- a/layers/meta-balena-topic/recipes-kernel/module/kernel-module-rtl88x2bu/0002-Add-CONFIG_PLATFORM_OPENEMBEDDED-to-Makefile-as-defa.patch +++ b/layers/meta-balena-topic/recipes-kernel/module/kernel-module-rtl88x2bu/0002-Add-CONFIG_PLATFORM_OPENEMBEDDED-to-Makefile-as-defa.patch @@ -1,4 +1,4 @@ -From 90b467e0c40343553de7cf31e075caa25ab2538b Mon Sep 17 00:00:00 2001 +From 0b43fbe6d038362c499c3238ac3920457fc3717c Mon Sep 17 00:00:00 2001 From: Francois Date: Wed, 11 May 2022 10:38:55 +0200 Subject: [PATCH 2/3] Add CONFIG_PLATFORM_OPENEMBEDDED to Makefile as default @@ -9,10 +9,10 @@ Subject: [PATCH 2/3] Add CONFIG_PLATFORM_OPENEMBEDDED to Makefile as default 1 file changed, 20 insertions(+) diff --git a/Makefile b/Makefile -index e5bc585..2b1742c 100755 +index 9a46be2..ddc9a99 100755 --- a/Makefile +++ b/Makefile -@@ -118,6 +118,7 @@ CONFIG_RTW_SDIO_PM_KEEP_POWER = y +@@ -120,6 +120,7 @@ CONFIG_RTW_SDIO_PM_KEEP_POWER = y ###################### MP HW TX MODE FOR VHT ####################### CONFIG_MP_VHT_HW_TX_MODE = n ###################### Platform Related ####################### @@ -20,7 +20,7 @@ index e5bc585..2b1742c 100755 CONFIG_PLATFORM_I386_PC = n CONFIG_PLATFORM_ANDROID_X86 = n CONFIG_PLATFORM_ANDROID_INTEL_X86 = n -@@ -1324,6 +1325,18 @@ endif +@@ -1326,6 +1327,18 @@ endif INSTALL_PREFIX := endif @@ -39,7 +39,7 @@ index e5bc585..2b1742c 100755 ifeq ($(CONFIG_PLATFORM_NV_TK1), y) EXTRA_CFLAGS += -DCONFIG_PLATFORM_NV_TK1 EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -@@ -2386,8 +2399,15 @@ export CONFIG_RTL8822BU = m +@@ -2388,8 +2401,15 @@ export CONFIG_RTL8822BU = m all: modules diff --git a/layers/meta-balena-topic/recipes-kernel/module/kernel-module-rtl88x2bu/0003-Don-t-use-__DATE__.patch b/layers/meta-balena-topic/recipes-kernel/module/kernel-module-rtl88x2bu/0003-Don-t-use-__DATE__.patch old mode 100755 new mode 100644 index 990702bb..df7a2eee --- a/layers/meta-balena-topic/recipes-kernel/module/kernel-module-rtl88x2bu/0003-Don-t-use-__DATE__.patch +++ b/layers/meta-balena-topic/recipes-kernel/module/kernel-module-rtl88x2bu/0003-Don-t-use-__DATE__.patch @@ -1,7 +1,8 @@ -From d5444ed2b58624a478f7d048bfe38080dfa0dc2d Mon Sep 17 00:00:00 2001 +From c01b09470970963f07dd4efb35653067c0178892 Mon Sep 17 00:00:00 2001 From: Francois Date: Wed, 11 May 2022 11:33:20 +0200 Subject: [PATCH 3/3] Don't use __DATE__ Solves this error: error: macro + __DATE__ might prevent reproducible builds [-Werror=date-time] Remove the 'bc' kludge that checks the GCC version as well @@ -12,12 +13,12 @@ Remove the 'bc' kludge that checks the GCC version as well mode change 100644 => 100755 core/rtw_debug.c diff --git a/Makefile b/Makefile -index 2b1742c..01dd7d9 100755 +index ddc9a99..ef0476d 100755 --- a/Makefile +++ b/Makefile -@@ -11,11 +11,6 @@ EXTRA_CFLAGS += -Wno-unused-function - EXTRA_CFLAGS += -Wno-unused-parameter - EXTRA_CFLAGS += -Wno-unused-variable +@@ -13,11 +13,6 @@ EXTRA_CFLAGS += -Wno-unused-variable + EXTRA_CFLAGS += -Wno-array-bounds + EXTRA_CFLAGS += -Wno-address -GCC_VER_49 := $(shell echo `$(CC) -dumpversion | cut -f1-2 -d.` \>= 4.9 | bc ) -ifeq ($(GCC_VER_49),1) diff --git a/layers/meta-balena-topic/recipes-support/bmap-tools/bmap-tools_3.6.bbappend b/layers/meta-balena-topic/recipes-support/bmap-tools/bmap-tools_3.6.bbappend new file mode 100644 index 00000000..809e8a0a --- /dev/null +++ b/layers/meta-balena-topic/recipes-support/bmap-tools/bmap-tools_3.6.bbappend @@ -0,0 +1 @@ +SRC_URI = "git://github.com/intel/${BPN};branch=main;protocol=https" diff --git a/layers/meta-lowpad-lcb/COPYING.Apache-2.0 b/layers/meta-lowpad-lcb/COPYING.Apache-2.0 new file mode 100755 index 00000000..b3201abf --- /dev/null +++ b/layers/meta-lowpad-lcb/COPYING.Apache-2.0 @@ -0,0 +1,204 @@ + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don`t include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/layers/meta-lowpad-lcb/README.md b/layers/meta-lowpad-lcb/README.md new file mode 100755 index 00000000..a3a4afe6 --- /dev/null +++ b/layers/meta-lowpad-lcb/README.md @@ -0,0 +1,7 @@ +# Resin.io layer for meta-topic supported boards + +## Description +This repository enables building BalenaOS for chosen meta-topic machines. + +## Supported machines +* lcbzu9 diff --git a/layers/meta-lowpad-lcb/conf/layer.conf b/layers/meta-lowpad-lcb/conf/layer.conf new file mode 100755 index 00000000..bf8334fa --- /dev/null +++ b/layers/meta-lowpad-lcb/conf/layer.conf @@ -0,0 +1,18 @@ +# OE layer configuration + +# We have a conf directory, append to BBPATH +BBPATH .= ":${LAYERDIR}" + +# We have recipes-* directories, add to BBFILES +BBFILES += "${LAYERDIR}/recipes-*/*/*.bb ${LAYERDIR}/recipes-*/*/*.bbappend" + +BBFILE_COLLECTIONS += "lowpad-lcb-layer" +BBFILE_PATTERN_lowpad-lcb-layer := "^${LAYERDIR}/" + +LAYERDEPENDS_lowpad-lcb-layer = "topic-layer" + +LAYERSERIES_COMPAT_lowpad-lcb-layer = "honister" + +# Give this layer precendence +BBFILE_PRIORITY_lowpad-lcb-layer = "20" + diff --git a/layers/meta-lowpad-lcb/conf/machine/lcbzu9.conf b/layers/meta-lowpad-lcb/conf/machine/lcbzu9.conf new file mode 100755 index 00000000..8f154d46 --- /dev/null +++ b/layers/meta-lowpad-lcb/conf/machine/lcbzu9.conf @@ -0,0 +1,37 @@ +# machine: Eurotec Lowpad Carrier Board with Topic Miami MPSoC Plus (Zynq Ultrascale 9EG) + +MACHINE_BOARD = "lcbzu" +FPGA_FAMILY = "xczu9eg" +FPGA_FAMILY_SHORT = "xczu" +FPGA_PART = "xczu9eg-ffvb1156-1-i" + +BALENA_BOOT_BIN = "lcb-boot-bin" + +require conf/machine/include/topic-miamimp.inc + +# Add SOM to overrides, takes precedence over topic-miamimp +SOM_FAMILY .= ":tspzu" + +BOARD_PL_REFERENCE = "dtb-lowpad-lcb" + +# Out of kernel devicetree +MACHINE_ESSENTIAL_EXTRA_RDEPENDS += "device-tree" + +# Extra packages to install for the board +MACHINE_EXTRA_RRECOMMENDS += "\ + kernel-module-topic-pl-fanctrl \ + pwm-fancontrol \ + " + +MACHINE_FEATURES += "rtc usbhost ethernet" + +DEVICETREE = "devicetree/${MACHINE}.dtb" +DEVICETREELINKS = "\ + system.dtb ${DEVICETREE} \n\ +" + +# Make Xilinx happy, we don't use it... +#HDF_MACHINE = "${MACHINE}" +# Define XSA to create PMUFW and FSBL +#TOPIC_XSA_DESIGN_NAME="fpga-image-lowpad-lcb-lcb-45+110a993.xsa" +#HDF_PATH = "fpga-server.local/downloads/fpga/lowpad-lcb/${TOPIC_XSA_DESIGN_NAME};name=${HDF_MACHINE}" diff --git a/layers/meta-lowpad-lcb/recipes-bsp/device-tree/device-tree.bbappend b/layers/meta-lowpad-lcb/recipes-bsp/device-tree/device-tree.bbappend new file mode 100755 index 00000000..399ac6d5 --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-bsp/device-tree/device-tree.bbappend @@ -0,0 +1,8 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +COMPATIBLE_MACHINE:lcbzu9 = '.*' + +SRC_URI:lcbzu9 = "\ + file://zynqmp-topic-miamiplusmp.dts \ + file://${MACHINE}.dts \ + " diff --git a/layers/meta-lowpad-lcb/recipes-bsp/device-tree/dtb-lowpad-lcb.bb b/layers/meta-lowpad-lcb/recipes-bsp/device-tree/dtb-lowpad-lcb.bb new file mode 100755 index 00000000..a9e762ae --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-bsp/device-tree/dtb-lowpad-lcb.bb @@ -0,0 +1,15 @@ +SUMMARY = "Devicetree overlay for FPGA image" +require recipes-bsp/device-tree/dtb-overlay.inc + +COMPATIBLE_MACHINE = ".*" + +BITSTREAM = "fpga-image-lowpad-lcb" + +RDEPENDS:${PN} += "\ + kernel-module-topic-pl-fanctrl \ + kernel-module-uartlite \ + kernel-module-8250 kernel-module-8250-base kernel-module-8250-of \ + kernel-module-gpio-xilinx \ + kernel-module-i2c-xiic \ + kernel-module-xilinx-can \ + " diff --git a/layers/meta-lowpad-lcb/recipes-bsp/device-tree/dtb-lowpad-lcb/pl.dts b/layers/meta-lowpad-lcb/recipes-bsp/device-tree/dtb-lowpad-lcb/pl.dts new file mode 100755 index 00000000..78312348 --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-bsp/device-tree/dtb-lowpad-lcb/pl.dts @@ -0,0 +1,606 @@ +/dts-v1/; +/plugin/; + +#include +#include +#include +#include +#include +#include + +/ { + /* This fragment causes the FPGA image to load */ + fragment@0 { + target = <&fpga_full>; + __overlay__ { + firmware-name = "fpga.bin.@BITSTREAM@"; + }; + }; + + fragment@1 { + target-path = "/"; + __overlay__ { + gpio-key-power { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + power { + label = "power"; + gpios = <&gpio 115 GPIO_ACTIVE_LOW>; /* EMIO 37, active low */ + linux,code = <116>; /* KEY_POWER */ + }; + }; + + leds-pl { + compatible = "gpio-leds"; + user-led { + label = "pl-user:green"; + gpios = <&gpio 83 GPIO_ACTIVE_LOW>; /* EMIO 5 */ + linux,default-trigger = "mmc0"; /* Blink on eMMC activity */ + }; + }; + + reg_3v3_analog: regulator-3v3-a { + compatible = "regulator-fixed"; + regulator-name = "3v3a"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + reg_12v_lp: regulator-12v-lp { + compatible = "regulator-fixed"; + regulator-name = "lp-12v"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + gpio = <&gpio 110 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + }; + + reg_24v: regulator-24v-amp { + compatible = "regulator-fixed"; + regulator-name = "24v"; + regulator-min-microvolt = <24000000>; + regulator-max-microvolt = <24000000>; + }; + + /* Use S/PDIF transmitter as codec required by simple-audio-card */ + playback_codec: playback-codec { + compatible = "linux,spdif-dit"; + #sound-dai-cells = <0>; + }; + + /* Audio */ + topic_pwm_audio: topic-pwm-audio { + compatible = "topic,pwm-audio"; + dmas = <&axi_dmac_s 0>; + dma-names = "tx"; + #sound-dai-cells = <0>; + enable-gpios = <&gpio 124 GPIO_ACTIVE_HIGH>; /* EMIO 46 to enable audio core */ + mute-gpios = <&axi_gpio_eio 30 GPIO_ACTIVE_LOW>; /* Set nRESET to low to mute output */ + }; + + speaker_amp: speaker-amplifier { + compatible = "simple-audio-amplifier"; + /* nRESET of the amplifier chip */ + // enable-gpios = <&axi_gpio_eio 30 GPIO_ACTIVE_HIGH>; + sound-name-prefix = "Speaker Amplifier"; + /* 12V analog supply */ + VCC-supply = <®_12v_lp>; + }; + + simple-audio { + compatible = "simple-audio-card"; + simple-audio-card,name = "Simple-Audio"; + simple-audio-card,widgets = + "Speaker", "Speaker"; + simple-audio-card,routing = + "Speaker Amplifier INL", "spdif-out", + "Speaker Amplifier INR", "spdif-out", + "Speaker", "Speaker Amplifier OUTL", + "Speaker", "Speaker Amplifier OUTR"; + simple-audio-card,aux-devs = <&speaker_amp>; + + #address-cells = <1>; + #size-cells = <0>; + + playback_link: simple-audio-card,dai-link@0 { + reg = <0>; + format = "i2s"; /* PWM? */ + + bitclock-master = <&p_cpu_dai>; + frame-master = <&p_cpu_dai>; + mclk-fs = <2048>; + + p_cpu_dai: cpu { + /* Link to PWM audio controller and DMA */ + sound-dai = <&topic_pwm_audio>; + clocks = <&si5345 0 7>; + }; + + p_codec_dai: codec { + sound-dai = <&playback_codec>; + }; + }; + }; + }; + }; + + + fragment@2 { + target = <&amba>; + __overlay__ { + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&gic>; + + /* FAN controller */ + pl_fan_controller: fan-controller@a0003000 { + compatible = "topic,axi-pwm-fan-controller"; + reg = <0x0 0xa0030000 0x0 0x10000>; + nr-fans = <1>; + clocks = <&zynqmp_clk PL1_REF>; + topic,initial-pwm = <100>; /* Run at 40% */ + vcc-supply = <®_12v_lp>; /* Not used by driver yet */ + }; + + /* temperature sensor on i2c Uses lm75 hwmon driver */ + axi_iic_0: i2c@80000000 { + #address-cells = <1>; + #size-cells = <0>; + clock-names = "s_axi_aclk"; + clocks = <&zynqmp_clk PL0_REF>; + compatible = "xlnx,axi-iic-2.0", "xlnx,xps-iic-2.00.a"; + interrupt-names = "iic2intc_irpt"; + interrupt-parent = <&gic>; + interrupts = <0 89 4>; /* PL0 - 0 (89 + 0)*/ + reg = <0x0 0x80000000 0x0 0x1000>; + + tmp101pl: sensor@4a{ + compatible = "ti,tmp101"; + reg = <0x4a>; + vs-supply = <®_3v3_miami>; + }; + }; + /* I2C Key E */ + axi_iic_1: i2c@a0000000 { + #address-cells = <1>; + #size-cells = <0>; + clock-names = "s_axi_aclk"; + clocks = <&zynqmp_clk PL1_REF>; + compatible = "xlnx,xps-iic-2.00.a"; + interrupt-names = "iic2intc_irpt"; + interrupt-parent = <&gic>; + interrupts = <0 104 4>; /* PL1 - 0 (104 + 0)*/ + reg = <0x0 0xa0000000 0x0 0x1000>; + + }; + /* I2C Key B */ + axi_iic_2: i2c@a0010000 { + #address-cells = <1>; + #size-cells = <0>; + clock-names = "s_axi_aclk"; + clocks = <&zynqmp_clk PL1_REF>; + compatible = "xlnx,xps-iic-2.00.a"; + interrupt-names = "iic2intc_irpt"; + interrupt-parent = <&gic>; + interrupts = <0 105 4>; /* PL1 - 1 (104 + 1) */ + reg = <0x0 0xa0010000 0x0 0x1000>; + + }; + /* UART key E */ + uart_axi_uartlite_0: serial@a0050000 { + clock-names = "s_axi_aclk"; + clocks = <&zynqmp_clk PL1_REF>; + compatible = "xlnx,xps-uartlite-1.00.a"; + current-speed = <115200>; + device_type = "serial"; + interrupt-names = "interrupt"; + interrupt-parent = <&gic>; + interrupts = <0 91 4>; /* PL0 - 2 (89+2) */ + port-number = <0>; + reg = <0x0 0xa0050000 0x0 0x10000>; + xlnx,baudrate = <0x2580>; + xlnx,data-bits = <0x8>; + xlnx,odd-parity = <0x0>; + xlnx,s-axi-aclk-freq-hz-d = "99.999001"; + xlnx,use-parity = <0x0>; + }; + /* Real time gpio controller */ + axi_gpio_eio: gpio@80010000 { + #gpio-cells = <2>; + clock-names = "s_axi_aclk"; + clocks = <&zynqmp_clk PL0_REF>; + compatible = "xlnx,xps-gpio-1.00.a"; + gpio-controller; + reg = <0x0 0x80010000 0x0 0x1000>; + xlnx,all-inputs = <0x0>; + xlnx,all-inputs-2 = <0x0>; + xlnx,all-outputs = <0x0>; + xlnx,all-outputs-2 = <0x0>; + xlnx,dout-default = <0x00000000>; + xlnx,dout-default-2 = <0x00000000>; + xlnx,gpio-width = <32>; + xlnx,gpio2-width = <24>; + xlnx,interrupt-present = <0x0>; + xlnx,is-dual = <1>; + xlnx,tri-default = <0xFFFFFFFF>; + xlnx,tri-default-2 = <0xFFFFFFFF>; + /* According to the README in the fpga image, these are the line names */ + gpio-line-names = \ + "BUMPER0_11", "BUMPER0_12", "BUMPER0_33", "BUMPER0_34", + "BUMPER1_11", "BUMPER1_12", "BUMPER1_33", "BUMPER1_34", + "BUMPER2_11", "BUMPER2_12", "BUMPER2_33", "BUMPER2_34", + "BUMPER3_11", "BUMPER3_12", "BUMPER3_33", "BUMPER3_34", + "EMER_STOP0_11", "EMER_STOP0_12", "EMER_STOP0_21", "EMER_STOP0_22", + "EMER_STOP1_11", "EMER_STOP1_12", "EMER_STOP1_21", "EMER_STOP1_22", + "WDI", "WD_EN", "nWDI_EN", "ADC_IRQ_IMON", + "AUDIO_CNRL_nCLIP", "AUDIO_CNRL_nFAULT", "AUDIO_CNRL_nRESET", "AUDIO_CNRL_nOTW", + "adc_irq_loadcell", "INPUT_24V_0", "INPUT_24V_1", "INPUT_24V_2", + "INPUT_24V_3", "INPUT_24V_4", "INPUT_24V_5", "INPUT_24V_6", + "OUTPUT_24V_0", "OUTPUT_24V_1", "OUTPUT_24V_2", "OUTPUT_24V_3", + "OUTPUT_24V_4", "OUTPUT_24V_5", "OUTPUT_24V_6", "OUTPUT_24V_7", + "LED_SUPPLY_EN", "LED_SUPPLY_PGOOD", "LIDAR0_OSSD0", "LIDAR0_OSSD1", + "LIDAR1_OSSD0", "LIDAR1_OSSD1", "LIDAR2_OSSD0", "LIDAR2_OSSD1"; + wdt-wdi { + /* Enables the WDT timer signal from FPGA to watchdog */ + gpio-hog; + gpios = <24 0>; + output-high; + line-name = "WDI"; + }; + wdt-wden { + /* Enables the WDT */ + gpio-hog; + gpios = <25 0>; + output-high; + line-name = "WD_EN"; + }; + wdt-nwdoen { + /* Allows the FET_EN_3V3 to go high */ + gpio-hog; + gpios = <26 0>; + output-low; + line-name = "nWDO_EN"; + }; + }; + + /* SPI channel for ADCs */ + axi_quad_spi_1: spi@80020000 { + compatible = "xlnx,xps-spi-2.00.a"; + interrupt-parent = <&gic>; + interrupts = <0 92 4>; /* PL0 - 3 (89 + 3) */ + reg = <0x0 0x80020000 0x0 0x10000>; + clock-names = "s_axi_aclk"; + clocks = <&zynqmp_clk PL0_REF>; + #address-cells = <1>; + #size-cells = <0>; + is-dual = <0>; + num-cs = <3>; + fifo-size = <16>; + bits-per-word = <8>; + adc@0 { /* Load cell */ + compatible = "microchip,mcp3564r"; + reg = <0>; + device-addr = <1>; + spi-max-frequency = <20000000>; + label = "adc-load"; + vref-supply = <®_3v3_analog>; /* Uses 3V3 reference */ + interrupt-parent = <&gpio>; + interrupts = <122 IRQ_TYPE_LEVEL_LOW>; /* EMIO 44, shared */ + drive-open-drain; + }; + adc@1 { /* MCB current */ + /* Chip select has wrong voltage, doesn't work */ + compatible = "microchip,mcp3564r"; + reg = <1>; + device-addr = <1>; + spi-max-frequency = <20000000>; + label = "adc-mcb-curr"; + /* Use internal reference */ + interrupt-parent = <&gpio>; + interrupts = <122 IRQ_TYPE_LEVEL_LOW>; /* EMIO 44, shared */ + drive-open-drain; + }; + }; + + axi_dmac_s: axi_dmac@a0060000 { + compatible = "adi,axi-dmac-1.00.a"; + reg = <0 0xa0060000 0 0x10000>; + interrupt-parent = <&gic>; + interrupts = <0 106 4>; /* PL1 - 2 : 104 + 2 */ + clock-names = "s_axi_aclk", "m_dest_axi_aclk", "s_axis_aclk"; + clocks = <&zynqmp_clk PL1_REF>, <&zynqmp_clk PL1_REF>, <&zynqmp_clk PL1_REF>; + #dma-cells = <1>; + adi,channels { + #size-cells = <0>; + #address-cells = <1>; + dma-channel@0 { + reg = <0>; + adi,source-bus-width = <128>; + adi,source-bus-type = <0>; /* ADI_AXI_DMAC_TYPE_MM_AXI */ + adi,destination-bus-width = <32>; + adi,destination-bus-type = <1>; /* AXI_DMAC_TYPE_AXI_STREAM */ + }; + }; + }; + }; + }; + + fragment@4 { + /* GEM 0 is connected via GMII to PCS/PMA 1000-BaseX interface */ + target = <&gem0>; + __overlay__ { + status = "disabled"; /* Doesn't work, so disable for now */ + phy-handle = <&gem0phy3>; + phy-mode = "gmii"; + mdio { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + /* Add 100 ms extra delay */ + reset-gpios = <&gpio 125 GPIO_ACTIVE_HIGH>; /* EMIO 47 */ + reset-delay-us = <1000>; + reset-post-delay-us = <100000>; + gem0phy3: gem0phy@3 { + reg = <3>; + device_type = "ethernet-phy"; + xlnx,phy-type = <5>; /* XAE_PHY_TYPE_1000BASE_X */ + }; + }; + }; + }; + + fragment@5 { + target = <&spi0>; /* PS SPI 0 (not QSPI) */ + __overlay__ { + status = "okay"; + num-cs = <1>; + imu0: imu@0 { + compatible = "st,lsm6dso"; + reg = <0>; + interrupt-parent = <&gpio>; + interrupts = <91 IRQ_TYPE_LEVEL_LOW>, <92 IRQ_TYPE_LEVEL_LOW>; /* EMIO 13 (+78), EMIO 14 */ + spi-max-frequency = <10000000>; + label = "imu0"; + vdd-supply = <®_1v8_miami>; + vddio-supply = <®_1v8_miami>; + }; + }; + }; + + fragment@6 { + target = <&spi1>; /* PS SPI 1 (not QSPI) */ + __overlay__ { + status = "okay"; + num-cs = <1>; + imu1: imu@0 { + compatible = "st,lsm6dso"; + reg = <0>; + interrupt-parent = <&gpio>; + interrupts = <93 IRQ_TYPE_LEVEL_LOW>, <94 IRQ_TYPE_LEVEL_LOW>; /* EMIO 15 (+78), EMIO 16 */ + spi-max-frequency = <10000000>; + label = "imu1"; + vdd-supply = <®_1v8_miami>; + vddio-supply = <®_1v8_miami>; + }; + }; + }; + + /* + * Devices on this bus require level shifters, which the FPGA enables. + * The PCIe and USB (at least) depend on the FPGA being programmed, + * as a result, we cannot use these devices and the I2C bus they're + * connected to. + */ + fragment@7 { + target = <&i2c0>; + __overlay__ { + status = "okay"; + }; + }; + fragment@8 { + target = <&pcie>; + __overlay__ { + status = "okay"; + }; + }; + fragment@9 { + target = <&usb1>; + __overlay__ { + status = "okay"; + }; + }; + fragment@10 { + target = <&dwc3_1>; + __overlay__ { + status = "okay"; + }; + }; + fragment@11 { + target = <&gem1>; + __overlay__ { + status = "okay"; + phy-connection-type = "sgmii"; + phy-mode = "sgmii"; + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; + + mdio { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + switch0: switch@0 { + compatible = "marvell,mv88e6190"; + reg = <0>; + reset-gpios = <&gpio 112 GPIO_ACTIVE_LOW>; /* EMIO 34 (+ 78) */ + interrupt-parent = <&gpio>; + interrupts = <121 IRQ_TYPE_LEVEL_LOW>; /* EMIO 43 */ + mdio { + #address-cells = <1>; + #size-cells = <0>; + switch0phy1: switch0phy1@1 { + reg = <1>; + }; + switch0phy2: switch0phy2@2 { + reg = <2>; + }; + switch0phy3: switch0phy3@3 { + reg = <3>; + }; + switch0phy4: switch0phy4@4 { + reg = <4>; + }; + switch0phy5: switch0phy5@5 { + reg = <5>; + }; + switch0phy6: switch0phy6@6 { + reg = <6>; + }; + switch0phy7: switch0phy7@7 { + reg = <7>; + }; + switch0phy8: switch0phy8@8 { + reg = <8>; + }; + }; + + mdio1 { + compatible = "marvell,mv88e6xxx-mdio-external"; + #address-cells = <1>; + #size-cells = <0>; + reset-gpios = <&gpio 114 GPIO_ACTIVE_LOW>; /* EMIO 36 (+ 78) */ + /* 100ns, 15 ms */ + reset-delay-us = <1000>; /* 100 ns reset duration, but I don't trust the analog circuit, hence 1ms */ + reset-post-delay-us = <16000>; /* Access to SMI registers 15 ms after reset */ + switch1phy0: switch1phy0@0 { + reg = <0>; + device_type = "ethernet-phy"; + /* Disable EEE advertisement */ + eee-broken-100tx; + eee-broken-1000t; + }; + }; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + label = "swp0"; + /* External PHY */ + phy-handle = <&switch1phy0>; + phy-mode = "rgmii"; + }; + + port@1 { + reg = <1>; + label = "swp1"; + phy-handle = <&switch0phy1>; + }; + + port@2 { + reg = <2>; + label = "swp2"; + phy-handle = <&switch0phy2>; + }; + + port@3 { + reg = <3>; + label = "swp3"; + phy-handle = <&switch0phy3>; + }; + + port@4 { + reg = <4>; + label = "swp4"; + phy-handle = <&switch0phy4>; + }; + + port@5 { + reg = <5>; + label = "swp5"; + phy-handle = <&switch0phy5>; + }; + + port@6 { + reg = <6>; + label = "swp6"; + phy-handle = <&switch0phy6>; + }; + + port@7 { + reg = <7>; + label = "swp7"; + phy-handle = <&switch0phy7>; + }; + + port@8 { + reg = <8>; + label = "swp8"; + phy-handle = <&switch0phy8>; + }; + + /* Port 9 to PL */ + port@9 { + reg = <9>; + phy-mode = "1000base-x"; + /* ethernet = <&gem0>; */ + label = "swp9"; + status = "disabled"; /* Doesn't work, so disable for now */ + + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; + }; + + /* Port 10 to PS GTR */ + port@a { + reg = <10>; + phy-mode = "sgmii"; + ethernet = <&gem1>; + label = "cpu"; + + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; + }; + }; + }; + }; + }; + }; + fragment@12 { + target = <&can0>; + __overlay__ { + status = "okay"; + }; + }; + fragment@13 { + target = <&can1>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@14 { + target = <&gpio>; + __overlay__ { + smarc-vin-pwr-bad { + gpio-hog; + gpios = <117 0>; /* EMIO 39 */ + output-high; + line-name = "smarc_vin_pwr_bad"; + }; + }; + }; +}; diff --git a/layers/meta-lowpad-lcb/recipes-bsp/device-tree/files/lcbzu9.dts b/layers/meta-lowpad-lcb/recipes-bsp/device-tree/files/lcbzu9.dts new file mode 100755 index 00000000..9163086e --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-bsp/device-tree/files/lcbzu9.dts @@ -0,0 +1,222 @@ +/* + * dts file for lcbzu9 (Lowpad Carrier Board) without PL + * + * (C) Copyright 2022, Topic Embedded Products BV + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include "zynqmp-topic-miamiplusmp.dts" + +/ { + aliases { + ethernet0 = &gem2; + ethernet1 = &gem1; + ethernet2 = &gem0; + }; +}; + +/* SD1 to SD-card, fixed 3v3 level shifter */ +&sdhci1 { + status = "okay"; + bus-width = <4>; + xlnx,mio_bank = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdhci1_default>; + /* Use GPIO based card detect */ + cd-gpios = <&gpio 45 GPIO_ACTIVE_LOW>; + disable-wp; + no-1-8-v; /* no 1v8/3v3 selection hence limited to high-speed */ +}; + +&i2c0 { + /* Devices on this bus depend on the level shifters being enabled, so we + * have to wait until the FPGA has been programmed */ + status = "disabled"; + /* USB hub has max 100kHz frequency, so that's the max speed for this bus */ + clock-frequency = <100000>; + + /* USB hub, 0x2d */ + usbhub@2d { + compatible = "microchip,usb5807"; + reg = <0x2d>; + reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>; + swap-dx-lanes = <0>; /* Swap D+/D- on upstream port */ + upstream-port = <0>; + }; + + /* EEPROM @ 0x50 : M24C32-RMN6TP 32 Kbit */ + eeprom@50 { + compatible = "atmel,24c32"; + reg = <0x50>; + pagesize = <32>; + #address-cells = <1>; + #size-cells = <1>; + vcc-supply = <®_1v8_miami>; + }; + + /* Real time clock, 0x51 */ + rtc@51 { + compatible = "nxp,pcf85263"; + reg = <0x51>; + #clock-cells = <0>; + wakeup-source; /* Can power up the board */ + }; + + /* PCIe Packet switch, E 0x6f */ +}; + +/* USB0 not used */ +&usb0 { + status = "disabled"; +}; +&dwc3_0 { + status = "disabled"; +}; + +/* USB3 to HUB. Might be OTG since the HUB allows switching upstream port */ +&usb1 { + status = "disabled"; /* Need level shifter */ +}; +&dwc3_1 { + status = "disabled"; /* Need level shifter */ + dr_mode = "host"; + /* refclk0 from clock synth */ + assigned-clocks = <&si5345 0 3>; + assigned-clock-rates = <100000000>; + phy-names = "usb3-phy"; + phys = <&psgtr 3 PHY_TYPE_USB3 1 0>; + maximum-speed = "super-speed"; + snps,usb3_lpm_capable; +}; + +&pcie { + status = "disabled"; /* Need level shifter */ + phys = <&psgtr 0 PHY_TYPE_PCIE 0 0>; + /* refclk0 from clock synth */ + assigned-clocks = <&si5345 0 3>; + assigned-clock-rates = <100000000>; +}; + +&gpio { + usb-hub-flex-cmd { + gpio-hog; + gpios = <38 0>; + input; + line-name = "usb_hub_flex_cmd"; + }; + usb-hub-vbus-det { + gpio-hog; + gpios = <43 0>; + input; + line-name = "usb_hub_vbus_det"; + }; + pcie-pwr-sav { + gpio-hog; + gpios = <111 0>; /* EMIO 33 */ + output-low; + line-name = "pcie_pwr_sav"; + }; + nreset-ftdi { + gpio-hog; + gpios = <116 0>; /* EMIO 38 */ + output-high; + line-name = "nreset_ftdi"; + }; +}; + +/* Don't use the ZynqMP RTC, there's an I2C RTC on the carrier */ +&rtc { + status = "disabled"; +}; + +&si5345 { + /* Configure PLL for audio */ + assigned-clock-parents = <0>, <0>, <0>, <0>, <0>, + <&si5345 1 0>, /* out 0 */ + <&si5345 1 0>, + <&si5345 1 0>, + <&si5345 1 0>, + <&si5345 1 0>, + <&si5345 1 0>, /* out 5 */ + <&si5345 1 0>, + <&si5345 1 1>, /* out 7 */ + <&si5345 1 0>, + <&si5345 1 0>; + assigned-clock-rates = <1000000000>, /* synth 0 */ + < 393216000>, /* 48000 * 8192 for audio */ + <0>, + <0>, + <0>, + <100000000>, /* out 0 */ + <100000000>, + <125000000>, + <100000000>, + <100000000>, + < 25000000>, /* out 5 (ethernet) */ + <100000000>, + < 98304000>, /* out 7 (Audio MCLK) */ + <100000000>, /* out 8 (PS refclk3) */ + <100000000>; + out@7 { + silabs,synth-master; /* Allow changing PLL frequency */ + }; + out@8 { + /delete-property/ always-on; + }; +}; + +/* GEM 1 is connected from PS to switch directly using SGMII. MDIO to switch. */ +&gem1 { + status = "disabled"; /* Some parts connected through PL */ + phy-mode = "sgmii"; + phys = <&psgtr 1 PHY_TYPE_SGMII 1 1>; /* Lane 1 refclk 1 */ + /* Need 125MHz GT clock (Xilinx drivers lack proper clk support) */ + assigned-clocks = <&si5345 0 2>; + assigned-clock-rates = <125000000>; +}; + +/* Remove the TSU clock, we use clock 7 for audio */ +&gem2 { + /* Need 25MHz and 125MHz clocks (Xilinx drivers lack proper clk support) */ + assigned-clocks = <&si5345 0 5>, <&si5345 0 2>; + assigned-clock-rates = <25000000>, <125000000>; + /* Revert TSU clock (copied from zynqmp-clk-ccf.dtsi) */ + clocks = <&zynqmp_clk LPD_LSBUS>, <&zynqmp_clk GEM2_REF>, + <&zynqmp_clk GEM2_TX>, <&zynqmp_clk GEM2_RX>, + <&zynqmp_clk GEM_TSU>; +}; + +&pinctrl0 { + status = "okay"; + + pinctrl_sdhci1_default: sdhci1-sd-default { + /* SD using pins 46 .. 51 in 4-bit mode */ + mux { + groups = "sdio1_2_grp"; + function = "sdio1"; + }; + conf { + groups = "sdio1_2_grp"; + slew-rate = ; + io-standard = ; + bias-disable; + }; + + /* Card detect on pin 45 */ + mux-cd { + groups = "gpio0_45_grp"; + function = "gpio0"; + }; + conf-cd { + groups = "gpio0_45_grp"; + bias-high-impedance; + slew-rate = ; + io-standard = ; + bias-pull-up; + }; + }; +}; diff --git a/layers/meta-lowpad-lcb/recipes-bsp/fpga/fpga-image-lowpad-lcb.bb b/layers/meta-lowpad-lcb/recipes-bsp/fpga/fpga-image-lowpad-lcb.bb new file mode 100755 index 00000000..8cb72912 --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-bsp/fpga/fpga-image-lowpad-lcb.bb @@ -0,0 +1,22 @@ +SUMMARY = "FPGA image for Lowpad" +require recipes-bsp/fpga/fpga-image.inc +LICENSE = "CLOSED" + +COMPATIBLE_MACHINE = ".*" + +BITSTREAM:tdpzu9 = "fpga-image-lowpad-lcb" + +PV = "47+6a2b89e" +FPGA_BITFILE = "fpga-image-lowpad-lcb-lcb-${PV}.bit" +BOARD_DESIGN_URI = "https://topic.nl/downloads/${FPGA_BITFILE}.xz" + +SRC_URI[sha256sum] = "c4a148e1d14a5b372d35baf24589ab62b98db93a43c445976b1907ed30b52b76" + +PKGV = "${PV}" +S = "${WORKDIR}" +B = "${S}" + +# Nothing to build +do_compile() { + cp ${FPGA_BITFILE} fpga.bit +} diff --git a/layers/meta-lowpad-lcb/recipes-bsp/lcb-boot-bin/lcb-boot-bin.bb b/layers/meta-lowpad-lcb/recipes-bsp/lcb-boot-bin/lcb-boot-bin.bb new file mode 100755 index 00000000..3a99471d --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-bsp/lcb-boot-bin/lcb-boot-bin.bb @@ -0,0 +1,22 @@ +# The LCB board requires a custom boot.bin that is available on the topic downloads server. +DESCRIPTION = "Custom boot.bin for lcbzu9" +LICENSE = "CLOSED" + +COMPATIBLE_MACHINE = "^lcbzu" + +inherit deploy + +PV = "7fa3b44ba92c" + +BINFILE = "boot-lcbzu9-${PV}.bin" +SRC_URI = "https://topic.nl/downloads/${BINFILE}.xz" +SRC_URI[sha256sum] = "712dc316b324ab396e942465cd5a1ed7fe8e3ae614706418f6b400427b90ad3c" + +S = "${WORKDIR}" + +do_deploy () { + install -d ${DEPLOYDIR} + install ${S}/${BINFILE} ${DEPLOYDIR}/lcb-boot.bin +} +addtask deploy before do_build after do_compile + diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-ASoc-adi-Kconfig-Remove-depends-on-for-ADI-reference.patch b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-ASoc-adi-Kconfig-Remove-depends-on-for-ADI-reference.patch new file mode 100755 index 00000000..f6a322d7 --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-ASoc-adi-Kconfig-Remove-depends-on-for-ADI-reference.patch @@ -0,0 +1,28 @@ +From 91c0364479b932f473f72671c140d566dc758891 Mon Sep 17 00:00:00 2001 +From: Bogdan Togorean +Date: Tue, 3 Dec 2019 16:40:58 +0200 +Subject: [PATCH] ASoc: adi: Kconfig: Remove depends on for ADI reference + designs + +Audio ADI reference designs are used on some non ZYNQ or Microblaze +platforms like ADRV2CRR-FMC Carrier Board so remove this dependency. + +Signed-off-by: Bogdan Togorean +--- + sound/soc/adi/Kconfig | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/sound/soc/adi/Kconfig b/sound/soc/adi/Kconfig +index 1ed3d0cc63b8..759072557c76 100644 +--- a/sound/soc/adi/Kconfig ++++ b/sound/soc/adi/Kconfig +@@ -1,6 +1,5 @@ + config SND_SOC_ADI + tristate "Audio support for Analog Devices reference designs" +- depends on MICROBLAZE || ARCH_ZYNQ || COMPILE_TEST + help + Audio support for various reference designs by Analog Devices. + +-- +2.17.1 + diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-dma-axi-dmac-simple-device_config-operation-implemen.patch b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-dma-axi-dmac-simple-device_config-operation-implemen.patch new file mode 100755 index 00000000..2d46383c --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-dma-axi-dmac-simple-device_config-operation-implemen.patch @@ -0,0 +1,74 @@ +From 00c17b90fcb014d40bad436166e04188f96c5a84 Mon Sep 17 00:00:00 2001 +From: Rodrigo Alencar <7062044+rodrigo455@users.noreply.github.com> +Date: Wed, 11 Sep 2019 15:58:22 -0300 +Subject: [PATCH] dma: axi-dmac: simple device_config operation implemented + +dmaengine_slave_config is called by dmaengine_pcm_hw_params when using +axi-i2s with axi-dmac. If device_config is NULL, -ENOSYS is returned, +which breaks the snd_pcm_hw_params function. +This is a fix for the error: + +$ aplay -D plughw:ADAU1761 /usr/share/sounds/alsa/Front_Center.wav +Playing WAVE '/usr/share/sounds/alsa/Front_Center.wav' : Signed 16 bit +Little Endian, Rate 48000 Hz, Mono +axi-i2s 43c20000.axi-i2s: ASoC: 43c20000.axi-i2s hw params failed: -38 +aplay: set_params:1403: Unable to install hw params: +ACCESS: RW_INTERLEAVED +FORMAT: S16_LE +SUBFORMAT: STD +SAMPLE_BITS: 16 +FRAME_BITS: 16 +CHANNELS: 1 +RATE: 48000 +PERIOD_TIME: 125000 +PERIOD_SIZE: 6000 +PERIOD_BYTES: 12000 +PERIODS: 4 +BUFFER_TIME: 500000 +BUFFER_SIZE: 24000 +BUFFER_BYTES: 48000 +TICK_TIME: 0 + +Signed-off-by: Rodrigo Alencar +(cherry picked from commit 5f6f0b22947e0682ce75f0e56eb49ca5c1ceecb7) +--- + drivers/dma/dma-axi-dmac.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c +index 5161b73c30c4..f2894ded3c2f 100644 +--- a/drivers/dma/dma-axi-dmac.c ++++ b/drivers/dma/dma-axi-dmac.c +@@ -573,6 +573,21 @@ static struct dma_async_tx_descriptor *axi_dmac_prep_slave_sg( + return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); + } + ++static int axi_dmac_device_config(struct dma_chan *c, ++ struct dma_slave_config *slave_config) ++{ ++ struct axi_dmac_chan *chan = to_axi_dmac_chan(c); ++ struct axi_dmac *dmac = chan_to_axi_dmac(chan); ++ ++ /* no configuration required, a sanity check is done instead */ ++ if (slave_config->direction != chan->direction) { ++ dev_err(dmac->dma_dev.dev, "Direction not supported by this DMA Channel"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + static struct dma_async_tx_descriptor *axi_dmac_prep_dma_cyclic( + struct dma_chan *c, dma_addr_t buf_addr, size_t buf_len, + size_t period_len, enum dma_transfer_direction direction, +@@ -956,6 +971,7 @@ static int axi_dmac_probe(struct platform_device *pdev) + dma_dev->device_tx_status = dma_cookie_status; + dma_dev->device_issue_pending = axi_dmac_issue_pending; + dma_dev->device_prep_slave_sg = axi_dmac_prep_slave_sg; ++ dma_dev->device_config = axi_dmac_device_config; + dma_dev->device_prep_dma_cyclic = axi_dmac_prep_dma_cyclic; + dma_dev->device_prep_interleaved_dma = axi_dmac_prep_interleaved; + dma_dev->device_terminate_all = axi_dmac_terminate_all; +-- +2.17.1 + diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-iio-adc-Add-driver-for-microchip-MCP3561-2-4R-device.patch b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-iio-adc-Add-driver-for-microchip-MCP3561-2-4R-device.patch new file mode 100755 index 00000000..e4968653 --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-iio-adc-Add-driver-for-microchip-MCP3561-2-4R-device.patch @@ -0,0 +1,861 @@ +From 94517b9d64af0f01b1cc41721cbd15b7b317ba88 Mon Sep 17 00:00:00 2001 +From: Mike Looijmans +Date: Thu, 4 May 2023 15:33:39 +0200 +Subject: [PATCH] iio: adc: Add driver for microchip MCP3561/2/4R devices + +The MCP3564R is a 24-bit ADC with 8 multiplexed inputs. The MCP3561R is +the same device with 2 inputs, the MCP3562R has 4 inputs. The device +contains one ADC and a multiplexer to select the inputs to the ADC. +To facilitate buffered reading, only channels that can be continuously +sampled are exported to the IIO subsystem. The driver does not support +buffered reading yet. + +Signed-off-by: Mike Looijmans +--- + drivers/iio/adc/Kconfig | 11 + + drivers/iio/adc/Makefile | 1 + + drivers/iio/adc/mcp356xr.c | 798 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 810 insertions(+) + create mode 100644 drivers/iio/adc/mcp356xr.c + +diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig +index d875d469aad4..e3369c49a172 100644 +--- a/drivers/iio/adc/Kconfig ++++ b/drivers/iio/adc/Kconfig +@@ -707,6 +707,17 @@ config MCP3422 + This driver can also be built as a module. If so, the module will be + called mcp3422. + ++config MCP356XR ++ tristate "Microchip Technology MCP3561/2/4R driver" ++ depends on SPI ++ default y ++ help ++ Say yes here to build support for Microchip Technology's MCP3561R, ++ MCP3562R, MCP3564R analog to digital converters. ++ ++ This driver can also be built as a module. If so, the module will be ++ called mcp356xr. ++ + config MCP3911 + tristate "Microchip Technology MCP3911 driver" + depends on SPI +diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile +index d0c323b0b62f..e1b132d39fb4 100644 +--- a/drivers/iio/adc/Makefile ++++ b/drivers/iio/adc/Makefile +@@ -65,6 +65,7 @@ obj-$(CONFIG_MAX1363) += max1363.o + obj-$(CONFIG_MAX9611) += max9611.o + obj-$(CONFIG_MCP320X) += mcp320x.o + obj-$(CONFIG_MCP3422) += mcp3422.o ++obj-$(CONFIG_MCP356XR) += mcp356xr.o + obj-$(CONFIG_MCP3911) += mcp3911.o + obj-$(CONFIG_MEDIATEK_MT6360_ADC) += mt6360-adc.o + obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o +diff --git a/drivers/iio/adc/mcp356xr.c b/drivers/iio/adc/mcp356xr.c +new file mode 100644 +index 000000000000..039e5cefe1d0 +--- /dev/null ++++ b/drivers/iio/adc/mcp356xr.c +@@ -0,0 +1,798 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Driver for Microchip MCP3561/2/4R, ADC with 1, 2 or 4 differential or 2, 4 or ++ * 8 single-ended inputs. The chip has a single ADC unit that can be muxed to ++ * any external input, internal reference or internal temperature sensor. ++ * ++ * Copyright (C) 2023 Topic Embedded Products ++ * ++ * Datasheet and product information: ++ * https://www.microchip.com/en-us/product/MCP3564R ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MCP396XR_REG_ADCDATA 0x00 ++#define MCP396XR_REG_CONFIG0 0x01 ++#define MCP396XR_REG_CONFIG1 0x02 ++#define MCP396XR_REG_CONFIG2 0x03 ++#define MCP396XR_REG_CONFIG3 0x04 ++#define MCP396XR_REG_IRQ 0x05 ++#define MCP396XR_REG_MUX 0x06 ++#define MCP396XR_REG_SCAN 0x07 ++#define MCP396XR_REG_TIMER 0x08 ++#define MCP396XR_REG_OFFSETCAL 0x09 ++#define MCP396XR_REG_GAINCAL 0x0a ++#define MCP396XR_REG_LOCK 0x0d ++#define MCP396XR_REG_CRCCFG 0x0f ++ ++#define MCP396XR_FASTCMD_START 0x0a ++#define MCP396XR_FASTCMD_RESET 0x0e ++ ++#define MCP396XR_STATUS_DR BIT(2) ++ ++#define MCP396XR_CMD_MASK_DEV_ADDR GENMASK(7, 6) ++#define MCP396XR_CMD_MASK_REG_ADDR GENMASK(5, 2) ++#define MCP396XR_CMD_MASK_TYPE GENMASK(1, 0) ++ ++#define MCP396XR_CMD_TYPE_FAST 0x0 ++#define MCP396XR_CMD_TYPE_READ_STATIC 0x1 ++#define MCP396XR_CMD_TYPE_WRITE_SEQ 0x2 ++#define MCP396XR_CMD_TYPE_READ_SEQ 0x3 ++ ++#define MCP396XR_CONFIG0_VREF_SEL BIT(7) ++#define MCP396XR_CONFIG0_PARTIAL_SHDN BIT(6) ++#define MCP396XR_CONFIG0_CLK_SEL_MASK GENMASK(5, 4) ++#define MCP396XR_CONFIG0_CS_SEL_MASK GENMASK(3, 2) ++#define MCP396XR_CONFIG0_ADC_MODE GENMASK(1, 0) ++ ++#define MCP396XR_CONFIG1_AMCLK_PRE GENMASK(7, 6) ++#define MCP396XR_CONFIG1_OSR GENMASK(5, 2) ++#define MCP396XR_CONFIG1_DEFAULT FIELD_PREP(MCP396XR_CONFIG1_OSR, 0x3) ++ ++#define MCP396XR_CONFIG2_BOOST GENMASK(7, 6) ++#define MCP396XR_CONFIG2_GAIN GENMASK(5, 3) ++#define MCP396XR_CONFIG2_AZ_MUX BIT(2) ++#define MCP396XR_CONFIG2_AZ_REF BIT(1) ++#define MCP396XR_CONFIG2_RESERVED1 BIT(0) ++#define MCP396XR_CONFIG2_DEFAULT \ ++ (FIELD_PREP(MCP396XR_CONFIG2_BOOST, 0x2) | \ ++ FIELD_PREP(MCP396XR_CONFIG2_GAIN, 0x1) | \ ++ MCP396XR_CONFIG2_RESERVED1) ++ ++#define MCP396XR_CONFIG3_CONV_MODE GENMASK(7, 6) ++#define MCP396XR_CONFIG3_DATA_FORMAT GENMASK(5, 4) ++#define MCP396XR_CONFIG3_CRC_FORMAT BIT(3) ++#define MCP396XR_CONFIG3_EN_CRCCOM BIT(2) ++#define MCP396XR_CONFIG3_EN_OFFCAL BIT(1) ++#define MCP396XR_CONFIG3_EN_GAINCAL BIT(0) ++#define MCP396XR_CONFIG3_DEFAULT \ ++ (FIELD_PREP(MCP396XR_CONFIG3_CONV_MODE, 0x1) | \ ++ FIELD_PREP(MCP396XR_CONFIG3_DATA_FORMAT, 0x3)) ++ ++#define MCP396XR_CLK_SEL_EXTERNAL 0x1 ++#define MCP396XR_CLK_SEL_INTERNAL 0x2 ++ ++#define MCP396XR_ADC_MODE_SHUTDOWN 0x1 ++#define MCP396XR_ADC_MODE_STANDBY 0x2 ++#define MCP396XR_ADC_MODE_CONVERSION 0x3 ++ ++#define MCP396XR_IRQ_ENABLE_FASTCMD BIT(1) ++#define MCP396XR_IRQ_PUSH_PULL BIT(2) ++ ++#define MCP396XR_LOCK_PASSWORD 0xA5 ++ ++#define MCP396XR_INT_VREF_UV 2400000 ++#define MCP396XR_MAX_CHANNELS 8 ++#define MCP396XR_MAX_TRANSFER_SIZE 4 ++/* Internal RC oscilator runs between 3.3 and 6.6 MHz, use the average value */ ++#define MCP396XR_INTERNAL_CLOCK_FREQ 4950000 ++ ++enum chip_ids { ++ mcp3564r, ++ mcp3562r, ++ mcp3561r, ++}; ++ ++struct mcp356xr { ++ struct spi_device *spi; ++ struct mutex lock; ++ struct regulator *vref; ++ struct clk *clki; ++ struct completion sample_available; ++ u8 dev_addr; ++ u8 n_inputs; ++ u8 config[4]; ++ int scale_avail[8 * 2]; /* 8 gain settings */ ++ /* SPI transfer buffer */ ++ u8 buf[1 + MCP396XR_MAX_TRANSFER_SIZE] ____cacheline_aligned; ++}; ++ ++static const int mcp356xr_oversampling_rates[] = { ++ 32, 64, 128, 256, ++ 512, 1024, 2048, 4096, ++ 8192, 16384, 20480, 24576, ++ 40960, 49152, 81920, 98304, ++}; ++ ++/* Transfers len bytes starting at address reg, results in adc->buf */ ++static int mcp356xr_read(struct mcp356xr *adc, u8 reg, u8 len) ++{ ++ int ret; ++ struct spi_transfer xfer = { ++ .tx_buf = adc->buf, ++ .rx_buf = adc->buf, ++ .len = len + 1, ++ }; ++ ++ adc->buf[0] = FIELD_PREP(MCP396XR_CMD_MASK_DEV_ADDR, adc->dev_addr) | ++ FIELD_PREP(MCP396XR_CMD_MASK_REG_ADDR, reg) | ++ MCP396XR_CMD_TYPE_READ_SEQ; ++ memset(adc->buf + 1, 0, len); ++ ++ ret = spi_sync_transfer(adc->spi, &xfer, 1); ++ if (ret < 0) ++ return ret; ++ ++ return ret; ++} ++ ++static int mcp356xr_fast_command(struct mcp356xr *adc, u8 cmd) ++{ ++ u8 buf = FIELD_PREP(MCP396XR_CMD_MASK_DEV_ADDR, adc->dev_addr) | ++ FIELD_PREP(MCP396XR_CMD_MASK_REG_ADDR, cmd) | ++ MCP396XR_CMD_TYPE_FAST; ++ ++ return spi_write(adc->spi, &buf, 1); ++} ++ ++static int mcp356xr_write(struct mcp356xr *adc, u8 reg, void *val, u8 len) ++{ ++ int ret; ++ struct spi_transfer xfer = { ++ .tx_buf = adc->buf, ++ .rx_buf = adc->buf, ++ .len = len + 1, ++ }; ++ ++ adc->buf[0] = FIELD_PREP(MCP396XR_CMD_MASK_DEV_ADDR, adc->dev_addr) | ++ FIELD_PREP(MCP396XR_CMD_MASK_REG_ADDR, reg) | ++ MCP396XR_CMD_TYPE_WRITE_SEQ; ++ memcpy(adc->buf + 1, val, len); ++ ++ ret = spi_sync_transfer(adc->spi, &xfer, 1); ++ ++ return ret; ++} ++ ++static int mcp356xr_write_u8(struct mcp356xr *adc, u8 reg, u8 value) ++{ ++ return mcp356xr_write(adc, reg, &value, 1); ++} ++ ++static int mcp356xr_update_config(struct mcp356xr *adc, u8 index, u8 value) ++{ ++ int ret; ++ ++ if (value == adc->config[index]) ++ return 0; ++ ++ ret = mcp356xr_write(adc, MCP396XR_REG_CONFIG0 + index, &value, 1); ++ if (ret < 0) ++ return ret; ++ ++ adc->config[index] = value; ++ return 0; ++} ++ ++static int mcp356xr_calc_scale_avail(struct mcp356xr *adc) ++{ ++ int millivolts; ++ int i; ++ int *scale_avail = adc->scale_avail; ++ ++ if (adc->vref) { ++ millivolts = regulator_get_voltage(adc->vref); ++ if (millivolts < 0) ++ return millivolts; ++ } else { ++ millivolts = MCP396XR_INT_VREF_UV; ++ } ++ millivolts /= 1000; ++ ++ /* Gain setting 0 is 0.333x */ ++ scale_avail[0] = millivolts * 3; ++ scale_avail[1] = 23; /* 23 bits for full scale */ ++ /* Other gain settings are power-of-two */ ++ for (i = 1; i < 8; i++) { ++ scale_avail[i * 2 + 0] = millivolts; ++ scale_avail[i * 2 + 1] = 22 + i; ++ } ++ ++ return 0; ++} ++ ++static int mcp356xr_set_oversampling_rate(struct mcp356xr *adc, int val) ++{ ++ int i; ++ u8 cfg; ++ ++ for (i = 0; i < ARRAY_SIZE(mcp356xr_oversampling_rates); ++i) { ++ if (mcp356xr_oversampling_rates[i] == val) { ++ cfg = adc->config[1] & ~MCP396XR_CONFIG1_OSR; ++ cfg |= FIELD_PREP(MCP396XR_CONFIG1_OSR, i); ++ return mcp356xr_update_config(adc, 1, cfg); ++ } ++ } ++ ++ return -EINVAL; ++} ++ ++static int mcp356xr_get_oversampling_rate(struct mcp356xr *adc) ++{ ++ return mcp356xr_oversampling_rates[FIELD_GET(MCP396XR_CONFIG1_OSR, ++ adc->config[1])]; ++} ++ ++static int mcp356xr_set_scale(struct mcp356xr *adc, int val, int val2) ++{ ++ int millivolts = adc->scale_avail[2]; ++ int gain; ++ u8 regval; ++ ++ /* The scale is always below 1 */ ++ if (val) ++ return -EINVAL; ++ ++ if (!val2) ++ return -EINVAL; ++ ++ /* ++ * val2 is in 'micro' units, n = val2 / 1000000 ++ * the full-scale value is millivolts / n, corresponds to 2^23, ++ * hence the gain = ((val2 / 1000000) << 23) / millivolts ++ * Approximate ((val2 / 1000000) << 23) as (549755 * val2) >> 16 ++ * because 2 << (23 + 16) / 1000000 = 549755 ++ */ ++ gain = DIV_ROUND_CLOSEST(millivolts, (549755 * val2) >> 16); ++ if (gain >= BIT(7)) ++ return -EINVAL; ++ ++ regval = adc->config[2] & ~MCP396XR_CONFIG2_GAIN; ++ if (gain) ++ regval |= FIELD_PREP(MCP396XR_CONFIG2_GAIN, ffs(gain)); ++ ++ return mcp356xr_update_config(adc, 2, regval); ++} ++ ++/* Calculate AMCLK (audio master clock) */ ++static long mcp356xr_get_amclk_freq(struct mcp356xr *adc) ++{ ++ long result; ++ ++ if (adc->clki) { ++ result = clk_get_rate(adc->clki); ++ if (result > 0) { ++ result >>= FIELD_GET(MCP396XR_CONFIG1_AMCLK_PRE, ++ adc->config[1]); ++ } ++ } else { ++ result = MCP396XR_INTERNAL_CLOCK_FREQ; ++ } ++ ++ return result; ++} ++ ++static int mcp356xr_get_samp_freq(struct mcp356xr *adc) ++{ ++ long freq = mcp356xr_get_amclk_freq(adc); ++ int osr = mcp356xr_get_oversampling_rate(adc); ++ ++ /* DMCLK runs at 1/4 of AMCLK, data rate is DMCLK/OSR */ ++ return freq / (osr << 2); ++} ++ ++static int mcp356xr_adc_conversion(struct mcp356xr *adc, ++ struct iio_chan_spec const *channel, ++ int *val) ++{ ++ long freq = mcp356xr_get_amclk_freq(adc); ++ int osr = mcp356xr_get_oversampling_rate(adc); ++ /* Over-estimate timeout by a factor 2 */ ++ int timeout_ms = DIV_ROUND_UP((osr << 2) * 2 * 1000, freq); ++ int ret; ++ ++ /* Setup input mux (address field is the mux setting) */ ++ ret = mcp356xr_write_u8(adc, MCP396XR_REG_MUX, channel->address); ++ if (ret) ++ return ret; ++ ++ reinit_completion(&adc->sample_available); ++ /* Start conversion */ ++ ret = mcp356xr_fast_command(adc, MCP396XR_FASTCMD_START); ++ if (ret) ++ return ret; ++ ++ if (timeout_ms < 10) ++ timeout_ms = 10; ++ ret = wait_for_completion_interruptible_timeout( ++ &adc->sample_available, msecs_to_jiffies(timeout_ms)); ++ if (ret == 0) { ++ /* Interrupt did not fire, check status and report */ ++ dev_warn(&adc->spi->dev, "Timeout (%d ms)\n", timeout_ms); ++ ret = mcp356xr_read(adc, MCP396XR_REG_ADCDATA, 4); ++ if (!ret) { ++ /* Check if data-ready was asserted */ ++ if ((adc->buf[0] & MCP396XR_STATUS_DR)) ++ return -ETIMEDOUT; ++ } ++ } ++ ++ if (ret < 0) ++ return ret; ++ ++ /* ++ * We're using data format 0b11 (see datasheet). While the ADC output is ++ * 24-bit, it allows over-ranging it and produces a 25-bit output in ++ * this mode. Hence the "24". ++ */ ++ *val = sign_extend32(get_unaligned_be32(&adc->buf[1]), 24); ++ ++ return 0; ++} ++ ++static int mcp356xr_read_avail(struct iio_dev *indio_dev, ++ struct iio_chan_spec const *chan, ++ const int **vals, int *type, int *length, ++ long mask) ++{ ++ struct mcp356xr *adc = iio_priv(indio_dev); ++ int ret = -EINVAL; ++ ++ switch (mask) { ++ case IIO_CHAN_INFO_OVERSAMPLING_RATIO: ++ *vals = mcp356xr_oversampling_rates; ++ *type = IIO_VAL_INT; ++ *length = ARRAY_SIZE(mcp356xr_oversampling_rates); ++ ret = IIO_AVAIL_LIST; ++ break; ++ ++ case IIO_CHAN_INFO_SCALE: ++ *type = IIO_VAL_FRACTIONAL_LOG2; ++ *vals = adc->scale_avail; ++ *length = ARRAY_SIZE(adc->scale_avail); ++ ret = IIO_AVAIL_LIST; ++ break; ++ } ++ ++ return ret; ++} ++ ++static int mcp356xr_read_raw(struct iio_dev *indio_dev, ++ struct iio_chan_spec const *channel, int *val, ++ int *val2, long mask) ++{ ++ struct mcp356xr *adc = iio_priv(indio_dev); ++ int ret = -EINVAL; ++ ++ switch (mask) { ++ case IIO_CHAN_INFO_RAW: ++ ret = iio_device_claim_direct_mode(indio_dev); ++ if (ret) ++ break; ++ ++ ret = mcp356xr_adc_conversion(adc, channel, val); ++ if (ret >= 0) ++ ret = IIO_VAL_INT; ++ iio_device_release_direct_mode(indio_dev); ++ break; ++ case IIO_CHAN_INFO_SCALE: ++ ret = FIELD_GET(MCP396XR_CONFIG2_GAIN, adc->config[2]); ++ *val = adc->scale_avail[ret * 2 + 0]; ++ *val2 = adc->scale_avail[ret * 2 + 1]; ++ ret = IIO_VAL_FRACTIONAL_LOG2; ++ if (channel->type == IIO_TEMP) { ++ /* To obtain temperature scale, divide by 0.0002973 */ ++ *val = 100 * ((*val * 100000) / 2973); ++ } ++ break; ++ case IIO_CHAN_INFO_OFFSET: ++ if (channel->type == IIO_TEMP) { ++ ret = FIELD_GET(MCP396XR_CONFIG2_GAIN, adc->config[2]); ++ /* temperature has 80 mV offset */ ++ *val = (-80 << adc->scale_avail[ret * 2 + 1]) / ++ adc->scale_avail[ret * 2 + 0]; ++ ret = IIO_VAL_INT; ++ } ++ break; ++ case IIO_CHAN_INFO_SAMP_FREQ: ++ *val = mcp356xr_get_samp_freq(adc); ++ ret = IIO_VAL_INT; ++ break; ++ case IIO_CHAN_INFO_OVERSAMPLING_RATIO: ++ *val = mcp356xr_get_oversampling_rate(adc); ++ ret = IIO_VAL_INT; ++ break; ++ } ++ ++ return ret; ++} ++ ++static int mcp356xr_write_raw(struct iio_dev *indio_dev, ++ struct iio_chan_spec const *channel, int val, ++ int val2, long mask) ++{ ++ struct mcp356xr *adc = iio_priv(indio_dev); ++ int ret = -EINVAL; ++ ++ switch (mask) { ++ case IIO_CHAN_INFO_OVERSAMPLING_RATIO: ++ ret = mcp356xr_set_oversampling_rate(adc, val); ++ break; ++ case IIO_CHAN_INFO_SCALE: ++ ret = mcp356xr_set_scale(adc, val, val2); ++ break; ++ } ++ ++ return ret; ++} ++ ++/* ++ * The "address" field corresponds to the MUX setting entry in table 5-15 in ++ * the datasheet. The scan_index is the index into this table. ++ */ ++ ++#define MCP396XR_SHARED_BY_ALL \ ++ .info_mask_shared_by_all = \ ++ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | \ ++ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ ++ .info_mask_shared_by_all_available = \ ++ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | \ ++ BIT(IIO_CHAN_INFO_SCALE) \ ++ ++#define MCP396XR_VOLTAGE_CHANNEL(num) \ ++ { \ ++ .type = IIO_VOLTAGE, \ ++ .indexed = 1, \ ++ .channel = (num), \ ++ .address = ((num) << 4) | 0x08, \ ++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ ++ .info_mask_shared_by_type = \ ++ BIT(IIO_CHAN_INFO_SCALE), \ ++ MCP396XR_SHARED_BY_ALL, \ ++ .scan_index = (num), \ ++ } ++ ++#define MCP396XR_VOLTAGE_CHANNEL_DIFF(chan1, chan2) \ ++ { \ ++ .type = IIO_VOLTAGE, \ ++ .indexed = 1, \ ++ .channel = (chan1), \ ++ .channel2 = (chan2), \ ++ .address = ((chan1) << 4) | (chan2), \ ++ .differential = 1, \ ++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ ++ .info_mask_shared_by_type = \ ++ BIT(IIO_CHAN_INFO_SCALE), \ ++ MCP396XR_SHARED_BY_ALL, \ ++ .scan_index = (chan1) / 2 + 8, \ ++ } ++ ++#define MCP396XR_TEMP_CHANNEL \ ++ { \ ++ .type = IIO_TEMP, \ ++ .address = 0xDE, \ ++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ ++ .info_mask_shared_by_type = \ ++ BIT(IIO_CHAN_INFO_SCALE) | \ ++ BIT(IIO_CHAN_INFO_OFFSET), \ ++ MCP396XR_SHARED_BY_ALL, \ ++ .scan_index = 12, \ ++ .datasheet_name = "TEMP", \ ++ } ++ ++/* Internal voltage channels */ ++#define MCP396XR_VOLTAGE_CHANNEL_INT(num, addr, name) \ ++ { \ ++ .type = IIO_VOLTAGE, \ ++ .indexed = 1, \ ++ .channel = (num), \ ++ .address = (addr), \ ++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ ++ .info_mask_shared_by_type = \ ++ BIT(IIO_CHAN_INFO_SCALE), \ ++ MCP396XR_SHARED_BY_ALL, \ ++ .scan_index = (num), \ ++ .datasheet_name = (name), \ ++ } ++ ++static const struct iio_chan_spec mcp3564r_channels[] = { ++ MCP396XR_VOLTAGE_CHANNEL(0), ++ MCP396XR_VOLTAGE_CHANNEL(1), ++ MCP396XR_VOLTAGE_CHANNEL(2), ++ MCP396XR_VOLTAGE_CHANNEL(3), ++ MCP396XR_VOLTAGE_CHANNEL(4), ++ MCP396XR_VOLTAGE_CHANNEL(5), ++ MCP396XR_VOLTAGE_CHANNEL(6), ++ MCP396XR_VOLTAGE_CHANNEL(7), ++ MCP396XR_VOLTAGE_CHANNEL_DIFF(0, 1), ++ MCP396XR_VOLTAGE_CHANNEL_DIFF(2, 3), ++ MCP396XR_VOLTAGE_CHANNEL_DIFF(4, 5), ++ MCP396XR_VOLTAGE_CHANNEL_DIFF(6, 7), ++ MCP396XR_TEMP_CHANNEL, ++ MCP396XR_VOLTAGE_CHANNEL_INT(13, 0x98, "AVDD"), ++ MCP396XR_VOLTAGE_CHANNEL_INT(14, 0xF8, "VCM"), ++ MCP396XR_VOLTAGE_CHANNEL_INT(15, 0x88, "OFFSET"), ++}; ++ ++static const struct iio_chan_spec mcp3562r_channels[] = { ++ MCP396XR_VOLTAGE_CHANNEL(0), ++ MCP396XR_VOLTAGE_CHANNEL(1), ++ MCP396XR_VOLTAGE_CHANNEL(2), ++ MCP396XR_VOLTAGE_CHANNEL(3), ++ MCP396XR_VOLTAGE_CHANNEL_DIFF(0, 1), ++ MCP396XR_VOLTAGE_CHANNEL_DIFF(2, 3), ++ MCP396XR_TEMP_CHANNEL, ++ MCP396XR_VOLTAGE_CHANNEL_INT(13, 0x98, "AVDD"), ++ MCP396XR_VOLTAGE_CHANNEL_INT(14, 0xF8, "VCM"), ++ MCP396XR_VOLTAGE_CHANNEL_INT(15, 0x88, "OFFSET"), ++}; ++ ++static const struct iio_chan_spec mcp3561r_channels[] = { ++ MCP396XR_VOLTAGE_CHANNEL(0), ++ MCP396XR_VOLTAGE_CHANNEL(1), ++ MCP396XR_VOLTAGE_CHANNEL_DIFF(0, 1), ++ MCP396XR_TEMP_CHANNEL, ++ MCP396XR_VOLTAGE_CHANNEL_INT(13, 0x98, "AVDD"), ++ MCP396XR_VOLTAGE_CHANNEL_INT(14, 0xF8, "VCM"), ++ MCP396XR_VOLTAGE_CHANNEL_INT(15, 0x88, "OFFSET"), ++}; ++ ++static const struct iio_info mcp356xr_info = { ++ .read_raw = mcp356xr_read_raw, ++ .read_avail = mcp356xr_read_avail, ++ .write_raw = mcp356xr_write_raw, ++}; ++ ++/* Interrupt handler */ ++static irqreturn_t mcp356xr_irq_handler(int irq, void *private) ++{ ++ struct mcp356xr *adc = private; ++ int ret; ++ ++ ret = mcp356xr_read(adc, MCP396XR_REG_ADCDATA, 4); ++ if (!ret) { ++ /* Check if data-ready bit is 0 (active) */ ++ if (!(adc->buf[0] & MCP396XR_STATUS_DR)) ++ complete(&adc->sample_available); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static int mcp356xr_config(struct mcp356xr *adc, struct device_node *of_node) ++{ ++ int ret; ++ u32 value; ++ u8 regval; ++ ++ if (!of_property_read_u32(of_node, "device-addr", &value)) { ++ if (value > 3) { ++ dev_err(&adc->spi->dev, ++ "invalid device address (%u). Must be <3.\n", ++ value); ++ return -EINVAL; ++ } ++ adc->dev_addr = value; ++ } else { ++ /* Default address is "1" unless you special-order them */ ++ adc->dev_addr = 0x1; ++ } ++ dev_dbg(&adc->spi->dev, "use device address %u\n", adc->dev_addr); ++ ++ /* ++ * Datasheet mentions this POR procedure: ++ * - Write LOCK register to 0xA5 ++ * - Write IRQ register to 0x03 ++ * - Send a fast CMD full reset (1110) ++ * - Reconfigure the chip as desired ++ */ ++ ret = mcp356xr_write_u8(adc, MCP396XR_REG_LOCK, MCP396XR_LOCK_PASSWORD); ++ if (ret) ++ return ret; ++ ++ ret = mcp356xr_write_u8(adc, MCP396XR_REG_IRQ, 0x03); ++ if (ret) ++ return ret; ++ ++ ret = mcp356xr_fast_command(adc, MCP396XR_FASTCMD_RESET); ++ if (ret) ++ return ret; ++ ++ usleep_range(200, 400); ++ ++ /* Default values */ ++ regval = MCP396XR_CONFIG0_PARTIAL_SHDN | MCP396XR_ADC_MODE_SHUTDOWN; ++ ++ if (!adc->vref) { ++ dev_dbg(&adc->spi->dev, ++ "use internal voltage reference (2.4V)\n"); ++ regval |= MCP396XR_CONFIG0_VREF_SEL; ++ } ++ ++ if (adc->clki) { ++ dev_dbg(&adc->spi->dev, "use external clock\n"); ++ regval |= FIELD_PREP(MCP396XR_CONFIG0_CLK_SEL_MASK, ++ MCP396XR_CLK_SEL_EXTERNAL); ++ } else { ++ dev_dbg(&adc->spi->dev, ++ "use internal RC oscillator\n"); ++ regval |= FIELD_PREP(MCP396XR_CONFIG0_CLK_SEL_MASK, ++ MCP396XR_CLK_SEL_INTERNAL); ++ } ++ adc->config[0] = regval; ++ adc->config[1] = MCP396XR_CONFIG1_DEFAULT; ++ adc->config[2] = MCP396XR_CONFIG2_DEFAULT; ++ adc->config[3] = MCP396XR_CONFIG3_DEFAULT; ++ ++ ret = mcp356xr_write(adc, MCP396XR_REG_CONFIG0, adc->config, ++ sizeof(adc->config)); ++ if (ret) ++ return ret; ++ ++ /* Enable fast commands, disable start-of-conversion interrupt */ ++ regval = MCP396XR_IRQ_ENABLE_FASTCMD; ++ if (!of_property_read_bool(of_node, "drive-open-drain")) ++ regval |= MCP396XR_IRQ_PUSH_PULL; ++ ret = mcp356xr_write_u8(adc, MCP396XR_REG_IRQ, regval); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static void mcp356xr_reg_disable(void *reg) ++{ ++ regulator_disable(reg); ++} ++ ++static void mcp356xr_clk_disable(void *clk) ++{ ++ clk_disable_unprepare(clk); ++} ++ ++static int mcp356xr_probe(struct spi_device *spi) ++{ ++ struct device *dev = &spi->dev; ++ struct iio_dev *indio_dev; ++ struct mcp356xr *adc; ++ enum chip_ids chip; ++ int ret; ++ ++ indio_dev = devm_iio_device_alloc(dev, sizeof(*adc)); ++ if (!indio_dev) ++ return -ENOMEM; ++ ++ adc = iio_priv(indio_dev); ++ adc->spi = spi; ++ mutex_init(&adc->lock); ++ init_completion(&adc->sample_available); ++ ++ adc->vref = devm_regulator_get_optional(dev, "vref"); ++ if (IS_ERR(adc->vref)) { ++ if (PTR_ERR(adc->vref) == -ENODEV) { ++ adc->vref = NULL; ++ } else { ++ return dev_err_probe(dev, PTR_ERR(adc->vref), ++ "Failed to get vref regulator\n"); ++ } ++ } else { ++ ret = regulator_enable(adc->vref); ++ if (ret) ++ return ret; ++ ++ ret = devm_add_action_or_reset(dev, mcp356xr_reg_disable, ++ adc->vref); ++ if (ret) ++ return ret; ++ } ++ ++ adc->clki = devm_clk_get(dev, NULL); ++ if (IS_ERR(adc->clki)) { ++ if (PTR_ERR(adc->clki) == -ENOENT) { ++ adc->clki = NULL; ++ } else { ++ return dev_err_probe(dev, PTR_ERR(adc->clki), ++ "Failed to get adc clk\n"); ++ } ++ } else { ++ ret = clk_prepare_enable(adc->clki); ++ if (ret < 0) ++ return dev_err_probe(dev, ret, ++ "Failed to enable adc clk\n"); ++ ++ ret = devm_add_action_or_reset(dev, mcp356xr_clk_disable, ++ adc->clki); ++ if (ret) ++ return ret; ++ } ++ ++ ret = mcp356xr_calc_scale_avail(adc); ++ if (ret) ++ return ret; ++ ++ ret = mcp356xr_config(adc, dev->of_node); ++ if (ret) ++ return ret; ++ ++ indio_dev->name = spi_get_device_id(spi)->name; ++ indio_dev->modes = INDIO_DIRECT_MODE; ++ indio_dev->info = &mcp356xr_info; ++ spi_set_drvdata(spi, indio_dev); ++ ++ chip = (enum chip_ids)spi_get_device_id(spi)->driver_data; ++ switch (chip) { ++ case mcp3564r: ++ indio_dev->channels = mcp3564r_channels; ++ indio_dev->num_channels = ARRAY_SIZE(mcp3564r_channels); ++ break; ++ case mcp3562r: ++ indio_dev->channels = mcp3562r_channels; ++ indio_dev->num_channels = ARRAY_SIZE(mcp3562r_channels); ++ break; ++ case mcp3561r: ++ indio_dev->channels = mcp3561r_channels; ++ indio_dev->num_channels = ARRAY_SIZE(mcp3561r_channels); ++ break; ++ } ++ ++ ret = devm_request_threaded_irq(dev, spi->irq, NULL, ++ mcp356xr_irq_handler, ++ IRQF_TRIGGER_LOW | IRQF_ONESHOT | ++ IRQF_SHARED, ++ spi->dev.driver->name, adc); ++ if (ret < 0) ++ return dev_err_probe(dev, ret, "Failed to allocate IRQ\n"); ++ ++ ret = devm_iio_device_register(dev, indio_dev); ++ return ret; ++} ++ ++static const struct of_device_id mcp356xr_dt_ids[] = { ++ { .compatible = "microchip,mcp3561r", .data = (void *)mcp3561r }, ++ { .compatible = "microchip,mcp3562r", .data = (void *)mcp3562r }, ++ { .compatible = "microchip,mcp3564r", .data = (void *)mcp3564r }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, mcp356xr_dt_ids); ++ ++static const struct spi_device_id mcp356xr_id[] = { ++ { "mcp3561r", mcp3561r }, ++ { "mcp3562r", mcp3562r }, ++ { "mcp3564r", mcp3564r }, ++ { } ++}; ++MODULE_DEVICE_TABLE(spi, mcp356xr_id); ++ ++static struct spi_driver mcp356xr_driver = { ++ .driver = { ++ .name = "mcp356xr", ++ .of_match_table = mcp356xr_dt_ids, ++ }, ++ .probe = mcp356xr_probe, ++ .id_table = mcp356xr_id, ++}; ++module_spi_driver(mcp356xr_driver); ++ ++MODULE_AUTHOR("Mike Looijmans "); ++MODULE_DESCRIPTION("Microchip Technology MCP356XR"); ++MODULE_LICENSE("GPL v2"); +-- +2.17.1 + diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-net-dsa-mv88e6xxx-Configure-port-0.patch b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-net-dsa-mv88e6xxx-Configure-port-0.patch new file mode 100755 index 00000000..e2eb7009 --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-net-dsa-mv88e6xxx-Configure-port-0.patch @@ -0,0 +1,88 @@ +From 900a456d26a34398046502ab3d9991bc43ba5b82 Mon Sep 17 00:00:00 2001 +From: Mike Looijmans +Date: Wed, 21 Jun 2023 11:50:53 +0200 +Subject: [PATCH] net: dsa: mv88e6xxx: Configure port 0 + +Port 0 configuration never actually happened, as it was considered +"internal". Fix the logic (at least for our chip) and consider port 0 +an external one. This makes the call to the CMODE configuration +actually arrive. Also arrange that RGMII configuration actually +happens for port 0. + +Does not make the port work yet, but appears to be a step forward. + +Upstream-status: Inappropriate +--- + drivers/net/dsa/mv88e6xxx/chip.c | 4 ++-- + drivers/net/dsa/mv88e6xxx/port.c | 23 ++++++++++++++--------- + 2 files changed, 16 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c +index 0830d7bb7a00..78c6416a1dd1 100644 +--- a/drivers/net/dsa/mv88e6xxx/chip.c ++++ b/drivers/net/dsa/mv88e6xxx/chip.c +@@ -463,7 +463,7 @@ static int mv88e6xxx_phy_is_internal(struct dsa_switch *ds, int port) + { + struct mv88e6xxx_chip *chip = ds->priv; + +- return port < chip->info->num_internal_phys; ++ return port < chip->info->num_internal_phys && port != 0; + } + + static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port) +@@ -475,7 +475,7 @@ static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port) + * report whether the port is internal. + */ + if (chip->info->family == MV88E6XXX_FAMILY_6250) +- return port < chip->info->num_internal_phys; ++ return port < chip->info->num_internal_phys && port != 0; + + err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); + if (err) { +diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c +index a9f8ddc5143d..59c7c7827163 100644 +--- a/drivers/net/dsa/mv88e6xxx/port.c ++++ b/drivers/net/dsa/mv88e6xxx/port.c +@@ -616,6 +616,8 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, + chip->ports[port].cmode = cmode; + + lane = mv88e6xxx_serdes_get_lane(chip, port); ++ if (lane == -ENODEV) ++ return 0; + if (lane < 0) + return lane; + +@@ -645,18 +647,21 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, + int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port, + phy_interface_t mode) + { +- if (port != 9 && port != 10) ++ if (port != 0 && port != 9 && port != 10) + return -EOPNOTSUPP; + +- switch (mode) { +- case PHY_INTERFACE_MODE_NA: ++ if (mode == PHY_INTERFACE_MODE_NA) + return 0; +- case PHY_INTERFACE_MODE_XGMII: +- case PHY_INTERFACE_MODE_XAUI: +- case PHY_INTERFACE_MODE_RXAUI: +- return -EINVAL; +- default: +- break; ++ ++ if (port == 9 || port == 10) { ++ switch (mode) { ++ case PHY_INTERFACE_MODE_XGMII: ++ case PHY_INTERFACE_MODE_XAUI: ++ case PHY_INTERFACE_MODE_RXAUI: ++ return -EINVAL; ++ default: ++ break; ++ } + } + + return mv88e6xxx_port_set_cmode(chip, port, mode, false); +-- +2.17.1 + diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-net-dsa-mv88e6xxx-support-RGMII-cmode.patch b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-net-dsa-mv88e6xxx-support-RGMII-cmode.patch new file mode 100755 index 00000000..9ff28aff --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-net-dsa-mv88e6xxx-support-RGMII-cmode.patch @@ -0,0 +1,63 @@ +From 1b55a39c89f59da1165f7ffc764f6f7da8b0d1dc Mon Sep 17 00:00:00 2001 +From: Marcus Carlberg +Date: Mon, 22 Aug 2022 16:41:36 +0200 +Subject: [PATCH] net: dsa: mv88e6xxx: support RGMII cmode + +Since the probe defaults all interfaces to the highest speed possible +(10GBASE-X in mv88e6393x) before the phy mode configuration from the +devicetree is considered it is currently impossible to use port 0 in +RGMII mode. + +This change will allow RGMII modes to be configurable for port 0 +enabling port 0 to be configured as RGMII as well as serial depending +on configuration. + +[ML] backported from mainline kernel + +Signed-off-by: Marcus Carlberg +Link: https://lore.kernel.org/r/20220822144136.16627-1-marcus.carlberg@axis.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/mv88e6xxx/port.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c +index ab41619a809b..9232e1e5b329 100644 +--- a/drivers/net/dsa/mv88e6xxx/port.c ++++ b/drivers/net/dsa/mv88e6xxx/port.c +@@ -550,6 +550,12 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, + mode = PHY_INTERFACE_MODE_1000BASEX; + + switch (mode) { ++ case PHY_INTERFACE_MODE_RGMII: ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ cmode = MV88E6XXX_PORT_STS_CMODE_RGMII; ++ break; + case PHY_INTERFACE_MODE_1000BASEX: + cmode = MV88E6XXX_PORT_STS_CMODE_1000BASEX; + break; +@@ -665,6 +674,19 @@ int mv88e6393x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, + if (port != 0 && port != 9 && port != 10) + return -EOPNOTSUPP; + ++ if (port == 9 || port == 10) { ++ switch (mode) { ++ case PHY_INTERFACE_MODE_RMII: ++ case PHY_INTERFACE_MODE_RGMII: ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ return -EINVAL; ++ default: ++ break; ++ } ++ } ++ + /* mv88e6393x errata 4.5: EEE should be disabled on SERDES ports */ + err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®); + if (err) +-- +2.17.1 + diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-rtc-pcf85363-Allow-to-wake-up-system-without-IRQ.patch b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-rtc-pcf85363-Allow-to-wake-up-system-without-IRQ.patch new file mode 100755 index 00000000..15b3901f --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-rtc-pcf85363-Allow-to-wake-up-system-without-IRQ.patch @@ -0,0 +1,45 @@ +From 308ffacd4f51a512f7933068e192d0f17b48cc9b Mon Sep 17 00:00:00 2001 +From: Mike Looijmans +Date: Mon, 1 May 2023 11:47:35 +0200 +Subject: [PATCH] rtc-pcf85363: Allow to wake up system without IRQ + +When wakeup-source is set in the devicetree, set up the device for +using the output as interrupt instead of clock. +--- + drivers/rtc/rtc-pcf85363.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c +index bb3e9ba75f6c..886cac1bc5d1 100644 +--- a/drivers/rtc/rtc-pcf85363.c ++++ b/drivers/rtc/rtc-pcf85363.c +@@ -400,18 +400,22 @@ static int pcf85363_probe(struct i2c_client *client, + pcf85363->rtc->range_max = RTC_TIMESTAMP_END_2099; + clear_bit(RTC_FEATURE_ALARM, pcf85363->rtc->features); + +- if (client->irq > 0) { ++ if (client->irq > 0 || device_property_read_bool(&client->dev, ++ "wakeup-source")) { + regmap_write(pcf85363->regmap, CTRL_FLAGS, 0); + regmap_update_bits(pcf85363->regmap, CTRL_PIN_IO, + PIN_IO_INTA_OUT, PIN_IO_INTAPM); ++ device_init_wakeup(&client->dev, true); ++ set_bit(RTC_FEATURE_ALARM, pcf85363->rtc->features); ++ } ++ ++ if (client->irq > 0) { + ret = devm_request_threaded_irq(&client->dev, client->irq, + NULL, pcf85363_rtc_handle_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "pcf85363", client); + if (ret) +- dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); +- else +- set_bit(RTC_FEATURE_ALARM, pcf85363->rtc->features); ++ dev_warn(&client->dev, "unable to request IRQ, alarm not functional\n"); + } + + ret = devm_rtc_register_device(pcf85363->rtc); +-- +2.17.1 + diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-sound-soc-codecs-spdif_transmitter-less-restrictions.patch b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-sound-soc-codecs-spdif_transmitter-less-restrictions.patch new file mode 100755 index 00000000..da71d9ee --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-sound-soc-codecs-spdif_transmitter-less-restrictions.patch @@ -0,0 +1,36 @@ +From 6ef45bbe919a3cdf60fb95b6847c08acec96dd1a Mon Sep 17 00:00:00 2001 +From: Mike Looijmans +Date: Mon, 22 May 2023 16:57:32 +0200 +Subject: [PATCH 1/2] sound: soc: codecs: spdif_transmitter: less restrictions, + fix dapm + +Don't force DAPM bias to always on (messes with other components) +Allow any PCM rate, not just a standard set. +--- + sound/soc/codecs/spdif_transmitter.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/spdif_transmitter.c b/sound/soc/codecs/spdif_transmitter.c +index 2c8cebfc6603..81ce317ba904 100644 +--- a/sound/soc/codecs/spdif_transmitter.c ++++ b/sound/soc/codecs/spdif_transmitter.c +@@ -21,7 +21,7 @@ + + #define DRV_NAME "spdif-dit" + +-#define STUB_RATES SNDRV_PCM_RATE_8000_192000 ++#define STUB_RATES SNDRV_PCM_RATE_CONTINUOUS + #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ +@@ -40,7 +40,6 @@ static struct snd_soc_component_driver soc_codec_spdif_dit = { + .num_dapm_widgets = ARRAY_SIZE(dit_widgets), + .dapm_routes = dit_routes, + .num_dapm_routes = ARRAY_SIZE(dit_routes), +- .idle_bias_on = 1, + .use_pmdown_time = 1, + .endianness = 1, + .non_legacy_dai_naming = 1, +-- +2.17.1 + diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-usb-misc-usb5807-Add-driver.patch b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-usb-misc-usb5807-Add-driver.patch new file mode 100755 index 00000000..e1696dcb --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0001-usb-misc-usb5807-Add-driver.patch @@ -0,0 +1,278 @@ +From e18c7c90681e634a92dfb211e9ca52c126705e54 Mon Sep 17 00:00:00 2001 +From: Mike Looijmans +Date: Tue, 2 May 2023 14:44:12 +0200 +Subject: [PATCH 1/2] usb: misc: usb5807: Add driver + +The USB5807 is a 7-port USB 3.1 hub that can be configured by I2C. +This drivers resets the chip, optionally allows D+/D- lines to be +swapped in the devicetree config, and then sends an ATTACH command to +put the device in operational mode. + +Signed-off-by: Mike Looijmans + +Series-to: linux-usb@vger.kernel.org +Series-version: 4 + +Series-changes: 2 +Add regulator support for vddXX supplies + +Series-changes: 4 +Add upstream-port support +--- + drivers/usb/misc/Kconfig | 9 ++ + drivers/usb/misc/Makefile | 1 + + drivers/usb/misc/usb5807.c | 210 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 220 insertions(+) + create mode 100644 drivers/usb/misc/usb5807.c + +diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig +index eefacfb13da9..0d6c7ef2cfd2 100644 +--- a/drivers/usb/misc/Kconfig ++++ b/drivers/usb/misc/Kconfig +@@ -233,6 +233,15 @@ config USB_EZUSB_FX2 + Say Y here if you need EZUSB device support. + (Cypress FX/FX2/FX2LP microcontrollers) + ++config USB_HUB_USB5807 ++ tristate "USB5807 Hub Controller Configuration Driver" ++ depends on I2C ++ help ++ This option enables support for configuration via SMBus of the ++ Microchip USB5807 USB 3.1 Hub Controller. Configuration parameters may ++ be set in devicetree. ++ Say Y or M here if you need to configure such a device via SMBus. ++ + config USB_HUB_USB251XB + tristate "USB251XB Hub Controller Configuration Driver" + depends on I2C +diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile +index e97a876300e7..8b47330eae52 100644 +--- a/drivers/usb/misc/Makefile ++++ b/drivers/usb/misc/Makefile +@@ -27,6 +27,7 @@ obj-$(CONFIG_USB_YUREX) += yurex.o + obj-$(CONFIG_USB_HUB_USB251XB) += usb251xb.o + obj-$(CONFIG_USB_USB2244) += usb2244.o + obj-$(CONFIG_USB_USB5744) += usb5744.o ++obj-$(CONFIG_USB_HUB_USB5807) += usb5807.o + obj-$(CONFIG_USB_HSIC_USB3503) += usb3503.o + obj-$(CONFIG_USB_HSIC_USB4604) += usb4604.o + obj-$(CONFIG_USB_CHAOSKEY) += chaoskey.o +diff --git a/drivers/usb/misc/usb5807.c b/drivers/usb/misc/usb5807.c +new file mode 100644 +index 000000000000..5c5a543bf8c9 +--- /dev/null ++++ b/drivers/usb/misc/usb5807.c +@@ -0,0 +1,210 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Driver for Microchip USB5807 USB 3.1 Hub ++ * Configuration via SMBus. ++ * ++ * Copyright (c) 2023 Topic Embedded Products ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define USB5807_CMD_ATTACH 0xAA55 ++#define USB5807_CMD_CONFIG 0x9937 ++ ++#define USB5807_REG_LANE_SWAP 0x30FA ++#define USB5807_REG_CONNECT_CFG 0x318E ++#define USB5807_REG_GBYFLEXCONTROL 0x4177 ++ ++#define USB5807_GBYFLEXCONTROL_DISABLE 0x20 ++ ++#define USB5807_NUM_PORTS 7 ++ ++ ++static int usb5807_write(struct i2c_client *i2c, void *buf, u8 len) ++{ ++ int ret; ++ struct i2c_msg msg = { ++ .addr = i2c->addr, ++ .flags = 0x0, ++ .len = len, ++ .buf = buf, ++ }; ++ ++ ret = i2c_transfer(i2c->adapter, &msg, 1); ++ return ret < 0 ? ret : 0; ++} ++ ++/* ++ * Send a command sequence, which is an I2C write transaction, with the command ++ * word in big endian and a terminating "0" byte. ++ */ ++static int usb5807_command(struct i2c_client *i2c, u16 cmd) ++{ ++ u8 buf[3] = {cmd >> 8, cmd & 0xff, 0}; ++ ++ return usb5807_write(i2c, buf, sizeof(buf)); ++} ++ ++static int usb5807_prepare_reg_u8(struct i2c_client *i2c, u16 reg, u8 value) ++{ ++ u8 buf[] = { ++ 0x00, ++ 0x00, /* Memory offset */ ++ 1 + 4, /* Transaction size */ ++ 0x00, /* 0 = Register write operation */ ++ 1, /* Size of register data */ ++ (reg >> 8) & 0xff, ++ reg & 0xff, /* Register offset */ ++ value, /* Register data */ ++ 0 /* Terminating zero */ ++ }; ++ ++ return usb5807_write(i2c, buf, sizeof(buf)); ++} ++ ++/* ++ * Write an 8-bit register. First we must write the "set register" operation to ++ * the chip's internal memory at offset 0, then issue a command to execute said ++ * operation. ++ */ ++static int usb5807_write_reg_u8(struct i2c_client *i2c, u16 reg, u8 value) ++{ ++ int ret; ++ ++ ret = usb5807_prepare_reg_u8(i2c, reg, value); ++ if (ret) ++ return ret; ++ ++ return usb5807_command(i2c, USB5807_CMD_CONFIG); ++} ++ ++/* Decode array of port numbers property into bit mask */ ++static u8 usb5807_get_ports_field(struct device *dev, const char *prop_name) ++{ ++ struct property *prop; ++ const __be32 *p; ++ u32 port; ++ u8 result = 0; ++ ++ of_property_for_each_u32(dev->of_node, prop_name, prop, p, port) { ++ if (port < USB5807_NUM_PORTS) ++ result |= BIT(port); ++ else ++ dev_warn(dev, "%s: port %u doesn't exist\n", prop_name, ++ port); ++ } ++ return result; ++} ++ ++static void usb5807_set_upstream_port(struct i2c_client *i2c, u32 val) ++{ ++ if (val > 1) { ++ dev_err(&i2c->dev, "Invalid upstream port: %d\n", val); ++ return; ++ } ++ ++ /* bit 0 in this register is the upstream port */ ++ usb5807_write_reg_u8(i2c, USB5807_REG_CONNECT_CFG, val); ++ ++ /* ++ * Disable flex pin control when we set this through I2C. Changing the ++ * pin state would return the chip to its config mode. ++ */ ++ usb5807_write_reg_u8(i2c, USB5807_REG_GBYFLEXCONTROL, ++ USB5807_GBYFLEXCONTROL_DISABLE); ++} ++ ++ ++static int usb5807_i2c_probe(struct i2c_client *i2c) ++{ ++ struct gpio_desc *reset_gpio; ++ int ret; ++ u32 val; ++ ++ /* Reset the chip to bring it into configuration mode */ ++ reset_gpio = devm_gpiod_get_optional(&i2c->dev, "reset", ++ GPIOD_OUT_HIGH); ++ if (IS_ERR(reset_gpio)) { ++ return dev_err_probe(&i2c->dev, PTR_ERR(reset_gpio), ++ "Failed to request reset GPIO\n"); ++ } ++ ++ /* Enable power supplies while chip is held in reset */ ++ ret = devm_regulator_get_enable(&i2c->dev, "vdd12"); ++ if (ret) ++ return ret; ++ ++ ret = devm_regulator_get_enable(&i2c->dev, "vdd33"); ++ if (ret) ++ return ret; ++ ++ /* Reset timing: Assert for >= 5 us */ ++ usleep_range(5, 10); ++ ++ /* Lock the bus for >= 1ms while the hub reads the I2C strapping */ ++ i2c_lock_bus(i2c->adapter, I2C_LOCK_SEGMENT); ++ ++ gpiod_set_value_cansleep(reset_gpio, 0); ++ usleep_range(1000, 2000); ++ ++ i2c_unlock_bus(i2c->adapter, I2C_LOCK_SEGMENT); ++ ++ /* The hub device needs additional time to boot up */ ++ msleep(20); ++ ++ val = usb5807_get_ports_field(&i2c->dev, "swap-dx-lanes"); ++ if (val) { ++ ret = usb5807_write_reg_u8(i2c, USB5807_REG_LANE_SWAP, val); ++ if (ret < 0) ++ dev_err(&i2c->dev, "Failed writing config: %d\n", ret); ++ } ++ ++ if (!of_property_read_u32(i2c->dev.of_node, "upstream-port", &val)) ++ usb5807_set_upstream_port(i2c, val); ++ ++ /* ++ * Send the "Attach" command which makes the device disappear from the ++ * I2C bus and starts USB enumeration. ++ */ ++ ret = usb5807_command(i2c, USB5807_CMD_ATTACH); ++ if (ret) { ++ dev_err(&i2c->dev, "Failed sending ATTACH command: %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id usb5807_of_match[] = { ++ { .compatible = "microchip,usb5807" }, ++ { } /* sentinel */ ++}; ++MODULE_DEVICE_TABLE(of, usb5807_of_match); ++ ++static const struct i2c_device_id usb5807_id[] = { ++ { "usb5807", }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(i2c, usb5807_id); ++ ++static struct i2c_driver usb5807_i2c_driver = { ++ .driver = { ++ .name = "usb5807", ++ .of_match_table = of_match_ptr(usb5807_of_match), ++ }, ++ .probe_new = usb5807_i2c_probe, ++ .id_table = usb5807_id, ++}; ++ ++module_i2c_driver(usb5807_i2c_driver); ++ ++MODULE_AUTHOR("Mike Looijmans "); ++MODULE_DESCRIPTION("USB5807 USB 3.1 Hub Controller Driver"); ++MODULE_LICENSE("GPL"); +-- +2.17.1 + diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0002-sound-soc-Add-topic-pwm-audio.patch b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0002-sound-soc-Add-topic-pwm-audio.patch new file mode 100755 index 00000000..e8662ea2 --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0002-sound-soc-Add-topic-pwm-audio.patch @@ -0,0 +1,228 @@ +From c57713ddc308d87edcd9adc7d8c895b0a264ff8a Mon Sep 17 00:00:00 2001 +From: Mike Looijmans +Date: Mon, 22 May 2023 16:56:53 +0200 +Subject: [PATCH 2/2] sound: soc: Add topic-pwm-audio + +Driver for PWM audio IP in FPGA. Basically just an "enable" GPIO and +some sampling rate restrictions, and some glue code to activate the +DMA engine. + +Upstream-status: Inappropriate +--- + sound/soc/adi/Kconfig | 7 ++ + sound/soc/adi/Makefile | 2 + + sound/soc/adi/topic-pwm-audio.c | 174 ++++++++++++++++++++++++++++++++ + 3 files changed, 183 insertions(+) + create mode 100644 sound/soc/adi/topic-pwm-audio.c + +diff --git a/sound/soc/adi/Kconfig b/sound/soc/adi/Kconfig +index 0236dc5b4e9f..e65a3fdb5c9b 100644 +--- a/sound/soc/adi/Kconfig ++++ b/sound/soc/adi/Kconfig +@@ -19,3 +19,10 @@ config SND_SOC_ADI_AXI_SPDIF + select REGMAP_MMIO + help + ASoC driver for the Analog Devices AXI-SPDIF softcore peripheral. ++ ++config SND_SOC_TOPIC_PWM_AUDIO ++ tristate "TOPIC PWM Audio core support" ++ default y ++ select SND_SOC_GENERIC_DMAENGINE_PCM ++ help ++ ASoC driver for the TOPIC PWM Audio softcore. +diff --git a/sound/soc/adi/Makefile b/sound/soc/adi/Makefile +index 125f667b0e08..ca763dad9ab7 100644 +--- a/sound/soc/adi/Makefile ++++ b/sound/soc/adi/Makefile +@@ -1,6 +1,8 @@ + # SPDX-License-Identifier: GPL-2.0-only + snd-soc-adi-axi-i2s-objs := axi-i2s.o + snd-soc-adi-axi-spdif-objs := axi-spdif.o ++snd-soc-adi-topic-pwm-audio-objs := topic-pwm-audio.o + + obj-$(CONFIG_SND_SOC_ADI_AXI_I2S) += snd-soc-adi-axi-i2s.o + obj-$(CONFIG_SND_SOC_ADI_AXI_SPDIF) += snd-soc-adi-axi-spdif.o ++obj-$(CONFIG_SND_SOC_TOPIC_PWM_AUDIO) += snd-soc-adi-topic-pwm-audio.o +diff --git a/sound/soc/adi/topic-pwm-audio.c b/sound/soc/adi/topic-pwm-audio.c +new file mode 100644 +index 000000000000..e3e746192cbf +--- /dev/null ++++ b/sound/soc/adi/topic-pwm-audio.c +@@ -0,0 +1,174 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2023, Topic Embedded Systems ++ * Based on axi-i2s ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++struct pwm_audio { ++ struct gpio_desc *gpio_enable; ++ struct gpio_desc *gpio_mute; ++}; ++ ++static int pwm_audio_trigger(struct snd_pcm_substream *substream, int cmd, ++ struct snd_soc_dai *dai) ++{ ++ struct pwm_audio *data = snd_soc_dai_get_drvdata(dai); ++ ++ pr_info("%s (%d)\n", __func__, cmd); ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ gpiod_set_value(data->gpio_enable, 1); ++ break; ++ case SNDRV_PCM_TRIGGER_STOP: ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ gpiod_set_value(data->gpio_enable, 0); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int pwm_audio_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ int ret; ++ ++ ret = snd_pcm_hw_constraint_minmax(substream->runtime, ++ SNDRV_PCM_HW_PARAM_RATE, ++ 44000, 50000); ++ ++ pr_info("%s: %d\n", __func__, ret); ++ ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++ ++static int pwm_audio_mute_stream(struct snd_soc_dai *dai, int mute, int direction) ++{ ++ struct pwm_audio *data = snd_soc_dai_get_drvdata(dai); ++ ++ pr_info("%s (%d, %d)\n", __func__, mute, direction); ++ ++ gpiod_set_value_cansleep(data->gpio_mute, mute); ++ ++ return 0; ++} ++ ++static const struct snd_dmaengine_dai_dma_data pwm_audio_playback_dma_data = { ++ .addr = 0, /* Data going nowhere ... */ ++ .addr_width = 4, ++ .maxburst = 1, ++}; ++ ++static int pwm_audio_dai_probe(struct snd_soc_dai *dai) ++{ ++ snd_soc_dai_init_dma_data(dai, &pwm_audio_playback_dma_data, NULL); ++ ++ return 0; ++} ++ ++static const struct snd_soc_dai_ops pwm_audio_dai_ops = { ++ .startup = pwm_audio_startup, ++ .mute_stream = pwm_audio_mute_stream, ++ .trigger = pwm_audio_trigger, ++}; ++ ++static struct snd_soc_dai_driver pwm_audio_dai = { ++ .name = "PWM-Audio", ++ .playback = { ++ .stream_name = "Playback", ++ .channels_min = 2, ++ .channels_max = 2, ++ /* DMA configured for 32-bit, even though we're only 12-bit */ ++ .formats = SNDRV_PCM_FMTBIT_S32_LE, ++ /* We support anything between 44 and 50kHz */ ++ .rates = SNDRV_PCM_RATE_CONTINUOUS, ++ .rate_min = 44000, ++ .rate_max = 50000, ++ }, ++ .probe = pwm_audio_dai_probe, ++ .ops = &pwm_audio_dai_ops, ++}; ++ ++static const struct snd_soc_component_driver pwm_audio_component = { ++ .name = "topic-pwm-audio", ++}; ++ ++static int pwm_audio_probe(struct platform_device *pdev) ++{ ++ struct pwm_audio *data; ++ int ret; ++ ++ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, data); ++ ++ data->gpio_mute = devm_gpiod_get_optional(&pdev->dev, "mute", ++ GPIOD_OUT_HIGH); ++ if (IS_ERR(data->gpio_mute)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(data->gpio_mute), ++ "Failed to get mute gpio\n"); ++ ++ data->gpio_enable = devm_gpiod_get_optional(&pdev->dev, "enable", ++ GPIOD_OUT_LOW); ++ if (IS_ERR(data->gpio_enable)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(data->gpio_enable), ++ "Failed to get enable gpio\n"); ++ ++ ret = devm_snd_soc_register_component(&pdev->dev, &pwm_audio_component, ++ &pwm_audio_dai, 1); ++ if (ret) ++ return ret; ++ ++ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); ++ if (ret) ++ return ret; ++ ++ dev_info(&pdev->dev, "probed"); ++ ++ return 0; ++} ++ ++static const struct of_device_id pwm_audio_of_match[] = { ++ { .compatible = "topic,pwm-audio", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, pwm_audio_of_match); ++ ++static struct platform_driver pwm_audio_driver = { ++ .driver = { ++ .name = "topic-pwm-audio", ++ .of_match_table = pwm_audio_of_match, ++ }, ++ .probe = pwm_audio_probe, ++}; ++module_platform_driver(pwm_audio_driver); ++ ++MODULE_AUTHOR("Mike Looijmans "); ++MODULE_DESCRIPTION("TOPIC PWM Audio core"); ++MODULE_LICENSE("GPL"); +-- +2.17.1 + diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0002-usb5807-backport-to-5.15.patch b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0002-usb5807-backport-to-5.15.patch new file mode 100755 index 00000000..da3f77f3 --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/0002-usb5807-backport-to-5.15.patch @@ -0,0 +1,33 @@ +From 28060b5f91207e70276be968073822a3dd06410a Mon Sep 17 00:00:00 2001 +From: Mike Looijmans +Date: Tue, 30 May 2023 08:45:36 +0200 +Subject: [PATCH 2/2] usb5807: backport to 5.15 + +Remove the devm_regulator... calls that aren't available in 5.15 yet +--- + drivers/usb/misc/usb5807.c | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/drivers/usb/misc/usb5807.c b/drivers/usb/misc/usb5807.c +index 5c5a543bf8c9..60864fa13f06 100644 +--- a/drivers/usb/misc/usb5807.c ++++ b/drivers/usb/misc/usb5807.c +@@ -136,15 +136,6 @@ static int usb5807_i2c_probe(struct i2c_client *i2c) + "Failed to request reset GPIO\n"); + } + +- /* Enable power supplies while chip is held in reset */ +- ret = devm_regulator_get_enable(&i2c->dev, "vdd12"); +- if (ret) +- return ret; +- +- ret = devm_regulator_get_enable(&i2c->dev, "vdd33"); +- if (ret) +- return ret; +- + /* Reset timing: Assert for >= 5 us */ + usleep_range(5, 10); + +-- +2.17.1 + diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/balena-only.cfg b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/balena-only.cfg new file mode 100755 index 00000000..95f6002a --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/balena-only.cfg @@ -0,0 +1,5 @@ +CONFIG_I2C_CADENCE=y +CONFIG_I2C_XILINX=y +CONFIG_SPI_CADENCE=y +CONFIG_SPI_ZYNQMP_GQSPI=y +CONFIG_GPIO_XILINX=y \ No newline at end of file diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/lcb-can.cfg b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/lcb-can.cfg new file mode 100755 index 00000000..c7181521 --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/lcb-can.cfg @@ -0,0 +1,6 @@ +CONFIG_CAN=y +CONFIG_CAN_RAW=y +CONFIG_CAN_VCAN=y +CONFIG_CAN_XILINXCAN=y +CONFIG_CAN_KVASER_USB=y +CONFIG_CAN_PEAK_USB=y \ No newline at end of file diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/lcb-network.cfg b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/lcb-network.cfg new file mode 100755 index 00000000..273b56b2 --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/lcb-network.cfg @@ -0,0 +1,43 @@ +CONFIG_NET_DSA=y +CONFIG_NET_DSA_TAG_DSA=y +CONFIG_NET_DSA_TAG_EDSA=y +CONFIG_NET_SWITCHDEV=y +CONFIG_NET_DEVLINK=y +CONFIG_NET_DSA_MV88E6XXX=y +CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y +CONFIG_NET_DSA_MV88E6XXX_PTP=y +CONFIG_MICROSEMI_PHY=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_ADAPTEC is not set +# CONFIG_NET_VENDOR_AGERE is not set +# CONFIG_NET_VENDOR_ALTEON is not set +# CONFIG_NET_VENDOR_ATHEROS is not set +# CONFIG_NET_VENDOR_BROCADE is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_CISCO is not set +# CONFIG_NET_VENDOR_DEC is not set +# CONFIG_NET_VENDOR_DLINK is not set +# CONFIG_NET_VENDOR_EMULEX is not set +# CONFIG_NET_VENDOR_GOOGLE is not set +# CONFIG_NET_VENDOR_MYRI is not set +# CONFIG_NET_VENDOR_NETERION is not set +# CONFIG_NET_VENDOR_NVIDIA is not set +# CONFIG_NET_VENDOR_OKI is not set +# CONFIG_NET_VENDOR_PACKET_ENGINES is not set +# CONFIG_NET_VENDOR_PENSANDO is not set +# CONFIG_NET_VENDOR_QLOGIC is not set +# CONFIG_NET_VENDOR_RDC is not set +# CONFIG_NET_VENDOR_REALTEK is not set +# CONFIG_NET_VENDOR_SILAN is not set +# CONFIG_NET_VENDOR_SIS is not set +# CONFIG_NET_VENDOR_SUN is not set +# CONFIG_NET_VENDOR_TEHUTI is not set +# CONFIG_NET_VENDOR_TI is not set +# CONFIG_NET_VENDOR_XILINX is not set +# CONFIG_MARVELL_10G_PHY is not set +# CONFIG_XILINX_GMII2RGMII is not set +# CONFIG_XEN_NETDEV_FRONTEND is not set +# CONFIG_XEN_NETDEV_BACKEND is not set +# CONFIG_USB_USB2244 is not set +# CONFIG_USB_USB5744 is not set + diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/lcb-perf.cfg b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/lcb-perf.cfg new file mode 100755 index 00000000..51764522 --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/lcb-perf.cfg @@ -0,0 +1,28 @@ +CONFIG_MCP3911=y + +CONFIG_IIO_ST_LSM6DSX=y +CONFIG_IIO_ST_LSM6DSX_I2C=y +CONFIG_IIO_ST_LSM6DSX_SPI=y + +# CONFIG_I2C_SLAVE is not set +CONFIG_SPI_CADENCE=y +CONFIG_SPI_XILINX=y +# CONFIG_MEDIA_SUPPORT is not set +# CONFIG_VGA_ARB is not set +# CONFIG_SND_USB is not set +CONFIG_SND_DMAENGINE_PCM=y +CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y +CONFIG_SND_SOC_ADI=y +CONFIG_SND_SOC_TOPIC_PWM_AUDIO=y +# CONFIG_SND_SOC_ADI_AXI_I2S is not set +# CONFIG_SND_SOC_ADI_AXI_SPDIF is not set +CONFIG_SND_SOC_SPDIF=y +CONFIG_SND_SIMPLE_CARD_UTILS=y +CONFIG_SND_SIMPLE_CARD=y +CONFIG_SND_AUDIO_GRAPH_CARD=y +CONFIG_SND_SOC_SIMPLE_AMPLIFIER=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_AXI_DMAC=y +# CONFIG_XILINX_DMA is not set + +CONFIG_USB_HUB_USB5807=y diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/lcb-wireless.cfg b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/lcb-wireless.cfg new file mode 100755 index 00000000..aa04e208 --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/lcb-wireless.cfg @@ -0,0 +1,22 @@ +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CONSOLE=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_SIMPLE=y +CONFIG_USB_SERIAL_QCAUX=y +CONFIG_USB_SERIAL_QUALCOMM=y +CONFIG_USB_SERIAL_SIERRAWIRELESS=y +CONFIG_USB_SERIAL_OPTION=y +CONFIG_USB_SERIAL_WWAN=y +CONFIG_MHI_BUS=y +CONFIG_WLAN_VENDOR_INTEL=y +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_IWL4965 is not set +# CONFIG_IWL3945 is not set +CONFIG_IWLWIFI=m +CONFIG_IWLWIFI_LEDS=y +CONFIG_IWLDVM=m +CONFIG_IWLMVM=m +CONFIG_IWLWIFI_OPMODE_MODULAR=y +# CONFIG_IWLWIFI_BCAST_FILTERING is not set +# CONFIG_WLAN_VENDOR_MICROCHIP is not set diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/tdpzu-extra.cfg b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/tdpzu-extra.cfg new file mode 100755 index 00000000..a5ccda8f --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/tdpzu-extra.cfg @@ -0,0 +1,30 @@ +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_SERIO is not set +# CONFIG_VT is not set +CONFIG_GPIO_XILINX=m +# CONFIG_MEDIA_CEC_SUPPORT is not set +# CONFIG_MEDIA_SUPPORT is not set +# CONFIG_VGA_ARB is not set +# CONFIG_COMMON_CLK_SI514 is not set +# CONFIG_COMMON_CLK_SI544 is not set +# CONFIG_COMMON_CLK_IDT8T49N24X is not set +# CONFIG_COMMON_CLK_CDCE925 is not set +CONFIG_PINCTRL_MCP23S08=y +CONFIG_TYPEC=y +# CONFIG_TYPEC_TCPM is not set +# CONFIG_TYPEC_UCSI is not set +CONFIG_TYPEC_HD3SS3220=y +# CONFIG_TYPEC_TPS6598X is not set +# CONFIG_TYPEC_STUSB160X is not set + +# +# USB Type-C Multiplexer/DeMultiplexer Switch support +# +# CONFIG_TYPEC_MUX_PI3USB30532 is not set +# end of USB Type-C Multiplexer/DeMultiplexer Switch support + +# +# USB Type-C Alternate Mode drivers +# +# CONFIG_TYPEC_DP_ALTMODE is not set +# end of USB Type-C Alternate Mode drivers diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/zynqmp-rtc.cfg b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/zynqmp-rtc.cfg new file mode 100755 index 00000000..375d43f1 --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx/zynqmp-rtc.cfg @@ -0,0 +1,108 @@ +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set +CONFIG_RTC_NVMEM=y + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +# CONFIG_RTC_INTF_PROC is not set +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_ABB5ZES3 is not set +# CONFIG_RTC_DRV_ABX80X is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_HYM8563 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_ISL12026 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8523 is not set +# CONFIG_RTC_DRV_PCF85063 is not set +CONFIG_RTC_DRV_PCF85363=y +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8010 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV8803 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1302 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1343 is not set +# CONFIG_RTC_DRV_DS1347 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6916 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RX4581 is not set +# CONFIG_RTC_DRV_RX6110 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_PCF2123 is not set +# CONFIG_RTC_DRV_MCP795 is not set +CONFIG_RTC_I2C_AND_SPI=y + +# +# SPI and I2C RTC drivers +# +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_PCF2127 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1685_FAMILY is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_DS2404 is not set +# CONFIG_RTC_DRV_EFI is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_ZYNQMP is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +# CONFIG_RTC_DRV_FTRTC010 is not set +# CONFIG_RTC_DRV_SNVS is not set +# CONFIG_RTC_DRV_R7301 is not set + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set diff --git a/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx_%.bbappend b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx_%.bbappend new file mode 100755 index 00000000..a45ea32b --- /dev/null +++ b/layers/meta-lowpad-lcb/recipes-kernel/linux/linux-xlnx_%.bbappend @@ -0,0 +1,24 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" + +TOPICBSPCONFIG:lcbzu9 = "\ + file://topic-miamimp-standard.cfg \ + file://topic-miamiplusmp-extra.cfg \ + file://tdpzu-extra.cfg \ + file://usb-wired-network-adapters.cfg \ + file://lcb-network.cfg \ + file://lcb-perf.cfg \ + file://lcb-wireless.cfg \ + file://lcb-can.cfg \ + " + +SRC_URI:append = "\ + file://0001-net-dsa-mv88e6xxx-support-RGMII-cmode.patch \ + file://0001-net-dsa-mv88e6xxx-Configure-port-0.patch \ + file://0001-rtc-pcf85363-Allow-to-wake-up-system-without-IRQ.patch \ + file://0001-dma-axi-dmac-simple-device_config-operation-implemen.patch \ + file://0001-sound-soc-codecs-spdif_transmitter-less-restrictions.patch \ + file://0002-sound-soc-Add-topic-pwm-audio.patch \ + file://0001-usb-misc-usb5807-Add-driver.patch \ + file://0002-usb5807-backport-to-5.15.patch \ + file://0001-iio-adc-Add-driver-for-microchip-MCP3561-2-4R-device.patch \ + " \ No newline at end of file diff --git a/layers/meta-topic b/layers/meta-topic index 02cd7f1e..d8d80607 160000 --- a/layers/meta-topic +++ b/layers/meta-topic @@ -1 +1 @@ -Subproject commit 02cd7f1e19c86bc67dc22c1879d398f8a001b617 +Subproject commit d8d806072dd78764071679c3eb57b93a98c801c5 diff --git a/lcbzu9.coffee b/lcbzu9.coffee new file mode 100644 index 00000000..3e8de55b --- /dev/null +++ b/lcbzu9.coffee @@ -0,0 +1,34 @@ +deviceTypesCommon = require '@resin.io/device-types/common' +{ networkOptions, commonImg, instructions } = deviceTypesCommon + +module.exports = + version: 1 + slug: 'lcbzu9' + aliases: [] + name: 'Eurotec Lowpad (lcbzu9)' + arch: 'aarch64' + state: 'released' + + instructions: commonImg.instructions + gettingStartedLink: + windows: 'https://www.balena.io/docs/learn/getting-started/' + osx: 'https://www.balena.io/docs/learn/getting-started/' + linux: 'https://www.balena.io/docs/learn/getting-started/' + supportsBlink: true + + options: [ networkOptions.group ] + + yocto: + machine: 'lcbzu9' + image: 'balena-image' + fstype: 'balenaos-img' + version: 'yocto-honister' + deployArtifact: 'balena-image-lcbzu9.balenaos-img' + + configuration: + config: + partition: + primary: 1 + path: '/config.json' + + initialization: commonImg.initialization diff --git a/scripts/autobuild.sh b/scripts/autobuild.sh index 33c1ab53..1a160c8a 100755 --- a/scripts/autobuild.sh +++ b/scripts/autobuild.sh @@ -9,7 +9,7 @@ mkdir -p ~/.balena/ touch ~/.balena/token mkdir -p build/artefacts -for m in t*.coffee +for m in *.coffee do MACHINE=`basename $m .coffee` ./balena-yocto-scripts/build/balena-build.sh -d ${MACHINE} -s ~/shared_downloads_and_sstate diff --git a/scripts/coffeemaker.sh b/scripts/coffeemaker.sh deleted file mode 100755 index 62320f1c..00000000 --- a/scripts/coffeemaker.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -e -for m in layers/meta-topic/conf/machine/t*.conf -do - MACHINE=`basename $m .conf` - sed "s/MACHINE/${MACHINE}/g" scripts/template.coffee > ${MACHINE}.coffee -done diff --git a/tdpzu9.coffee b/tdpzu9.coffee old mode 100755 new mode 100644