From 29cf1b1a0f272d478477eccece96800385efaad8 Mon Sep 17 00:00:00 2001 From: zianed Date: Mon, 27 Sep 2021 09:46:26 +0800 Subject: [PATCH 1/4] delete unused file Signed-off-by: zianed --- model/audio/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/model/audio/Makefile b/model/audio/Makefile index 1485c6b..f6eeeb8 100755 --- a/model/audio/Makefile +++ b/model/audio/Makefile @@ -25,7 +25,6 @@ obj-y += \ $(KHDF_AUDIO_ROOT_DIR)/core/src/audio_parse.o \ $(KHDF_AUDIO_ROOT_DIR)/common/src/audio_accessory_base.o \ $(KHDF_AUDIO_ROOT_DIR)/common/src/audio_codec_base.o \ - $(KHDF_AUDIO_ROOT_DIR)/common/src/audio_dsp_base.o \ $(KHDF_AUDIO_ROOT_DIR)/common/src/audio_platform_base.o \ $(KHDF_AUDIO_ROOT_DIR)/sapm/src/audio_sapm.o \ $(KHDF_AUDIO_ROOT_DIR)/dispatch/src/audio_stream_dispatch.o \ @@ -47,7 +46,6 @@ obj-$(CONFIG_ARCH_HI3516DV300) += \ $(KHDF_AUDIO_ROOT_DIR)/core/src/audio_parse.o \ $(KHDF_AUDIO_ROOT_DIR)/common/src/audio_accessory_base.o \ $(KHDF_AUDIO_ROOT_DIR)/common/src/audio_codec_base.o \ - $(KHDF_AUDIO_ROOT_DIR)/common/src/audio_dsp_base.o \ $(KHDF_AUDIO_ROOT_DIR)/common/src/audio_platform_base.o \ $(KHDF_AUDIO_ROOT_DIR)/sapm/src/audio_sapm.o \ $(KHDF_AUDIO_ROOT_DIR)/dispatch/src/audio_stream_dispatch.o \ -- Gitee From 9f83cc1a0606fcc49f5ce38f1cb0cc6d2ffe5b5f Mon Sep 17 00:00:00 2001 From: YOUR_NAME Date: Mon, 15 Nov 2021 10:00:47 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BB=8E=E4=B8=BB=E7=BA=BF=E5=90=8C?= =?UTF-8?q?=E6=AD=A5-PWM=203=E4=B8=AA=E5=A4=B1=E8=B4=A5=E6=A0=B7=E4=BE=8B?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: YOUR_NAME --- platform/pwm/pwm_adapter.c | 16 ++++++++----- platform/pwm/pwm_hi35xx.h | 6 ++--- platform/pwm/pwm_hi35xx_linux.c | 40 ++++++++++++++++++++------------- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/platform/pwm/pwm_adapter.c b/platform/pwm/pwm_adapter.c index e94cb71..504f782 100644 --- a/platform/pwm/pwm_adapter.c +++ b/platform/pwm/pwm_adapter.c @@ -18,14 +18,11 @@ #include #include "device_resource_if.h" -#include "hdf_base.h" #include "hdf_log.h" -#include "osal_io.h" #include "osal_mem.h" #include "pwm_core.h" -#include "pwm_if.h" -#define HDF_LOG_TAG HDF_PWM_LINUX_ADAPTER +#define HDF_LOG_TAG pwm_adapter int32_t HdfPwmOpen(struct PwmDev *pwm) { @@ -60,6 +57,7 @@ int32_t HdfPwmClose(struct PwmDev *pwm) int32_t HdfPwmSetConfig(struct PwmDev *pwm, struct PwmConfig *config) { + int32_t ret; struct pwm_state state; if (pwm == NULL || pwm->priv == NULL || config == NULL) { @@ -71,7 +69,15 @@ int32_t HdfPwmSetConfig(struct PwmDev *pwm, struct PwmConfig *config) state.enabled = (config->status == PWM_ENABLE_STATUS) ? true : false; state.period = config->period; state.polarity = config->polarity; - return pwm_apply_state(pwm->priv, &state); + HDF_LOGI("%s: set PwmConfig: number %u, period %u, duty %u, polarity %u, enable %u.", + __func__, config->number, config->period, config->duty, config->polarity, config->status); + ret = pwm_apply_state(pwm->priv, &state); + if (ret < 0) { + HDF_LOGE("%s: [pwm_apply_state] failed.", __func__); + return HDF_FAILURE; + } + HDF_LOGI("%s: success.", __func__); + return HDF_SUCCESS; } struct PwmMethod g_pwmOps = { diff --git a/platform/pwm/pwm_hi35xx.h b/platform/pwm/pwm_hi35xx.h index ecdb5a7..fab0859 100644 --- a/platform/pwm/pwm_hi35xx.h +++ b/platform/pwm/pwm_hi35xx.h @@ -36,9 +36,9 @@ #define PWM_INV_OFFSET 1 #define PWM_KEEP_OFFSET 2 -#define PWM_DEFAULT_PERIOD 0x018F +#define PWM_DEFAULT_PERIOD 0x3E7 #define PWM_DEFAULT_POLARITY 0 -#define PWM_DEFAULT_DUTY_CYCLE 0x00C7 +#define PWM_DEFAULT_DUTY_CYCLE 0x14D struct HiPwmRegs { volatile uint32_t cfg0; @@ -55,7 +55,7 @@ static inline void HiPwmDisable(struct HiPwmRegs *reg) if (reg == NULL) { return; } - reg->ctrl = PWM_DISABLE; + reg->ctrl &= ~1; } static inline void HiPwmAlwaysOutput(struct HiPwmRegs *reg) diff --git a/platform/pwm/pwm_hi35xx_linux.c b/platform/pwm/pwm_hi35xx_linux.c index 38c411d..68f1e7e 100644 --- a/platform/pwm/pwm_hi35xx_linux.c +++ b/platform/pwm/pwm_hi35xx_linux.c @@ -16,20 +16,15 @@ * */ -#include +#include "pwm_hi35xx.h" #include -#include -#include -#include -#include -#include #include #include -#include #include #include -#include "pwm_hi35xx.h" +#include "hdf_log.h" +#define HDF_LOG_TAG pwm_hi35xx_linux #define PWM_ENABLE_MASK 0x1 #define PWM_HI35XX_N_CELLS 2 @@ -50,42 +45,51 @@ static int Hi35xxPwmApply(struct pwm_chip *chip, struct pwm_device *pwm, struct struct Hi35xxPwmChip *hi35xxChip = (struct Hi35xxPwmChip *)chip; if (hi35xxChip == NULL || pwm == NULL || state == NULL) { - pr_err("%s: parameter is null\n", __func__); + HDF_LOGE("%s: parameter is null\n", __func__); return -EINVAL; } reg = (struct HiPwmRegs *)hi35xxChip->base; if (state->polarity != PWM_POLARITY_NORMAL && state->polarity != PWM_POLARITY_INVERSED) { - pr_err("%s: polarity %u is invalid", __func__, state->polarity); + HDF_LOGE("%s: polarity %u is invalid", __func__, state->polarity); return -EINVAL; } if (state->period < PWM_MIN_PERIOD) { - pr_err("%s: period %u is not support, min period %u", __func__, state->period, PWM_MIN_PERIOD); + HDF_LOGE("%s: period %llu is not support, min period %d", __func__, state->period, PWM_MIN_PERIOD); return -EINVAL; } if (state->duty_cycle < 1 || state->duty_cycle > state->period) { - pr_err("%s: duty_cycle %u is not support, min duty_cycle 1 max duty_cycle %u", - __func__, state->duty_cycle , state->period); + HDF_LOGE("%s: duty %llu is not support, duty must in [1, period = %llu].", + __func__, state->duty_cycle , state->period); return -EINVAL; } HiPwmDisable(reg); + HDF_LOGI("%s: [HiPwmDisable] done.", __func__); if (pwm->state.polarity != state->polarity) { HiPwmSetPolarity(reg, state->polarity); + HDF_LOGI("%s: [HiPwmSetPolarity] done, polarity: %u -> %u.", __func__, pwm->state.polarity, state->polarity); } if (pwm->state.period != state->period) { HiPwmSetPeriod(reg, state->period); + HDF_LOGI("%s: [HiPwmSetPeriod] done, period: %llu -> %llu.", __func__, pwm->state.period, state->period); } if (pwm->state.duty_cycle != state->duty_cycle) { HiPwmSetDuty(reg, state->duty_cycle); + HDF_LOGI("%s: [HiPwmSetDuty] done, duty: %llu -> %llu.", __func__, pwm->state.duty_cycle, state->duty_cycle); } if (state->enabled) { HiPwmAlwaysOutput(reg); + HDF_LOGI("%s: [HiPwmAlwaysOutput] done, then enable.", __func__); } + + HDF_LOGI("%s: set PwmConfig done: number none, period %llu, duty %llu, polarity %u, enable %u.", + __func__, state->period, state->duty_cycle, state->polarity, state->enabled); + HDF_LOGI("%s: success.", __func__); + return 0; } - static void Hi35xxGetState(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_state *state) { struct HiPwmRegs *reg = NULL; @@ -96,9 +100,13 @@ static void Hi35xxGetState(struct pwm_chip *chip, struct pwm_device *pwm, struct return; } reg = (struct HiPwmRegs *)hi35xxChip->base; - state->period = reg->cfg0; - state->duty_cycle = reg->cfg1; + state->period = reg->cfg0 * PWM_CLK_PERIOD; + state->duty_cycle = reg->cfg1 * PWM_CLK_PERIOD; + state->polarity = (reg->ctrl & (1 << PWM_INV_OFFSET)) >> PWM_INV_OFFSET; state->enabled = reg->ctrl & PWM_ENABLE_MASK; + + HDF_LOGI("%s: get PwmConfig: number none, period %llu, duty %llu, polarity %u, enable %u.", + __func__, state->period, state->duty_cycle, state->polarity, state->enabled); } static struct pwm_ops Hi35xxPwmOps = { -- Gitee From bb71d8118b549d62d5877752f18d4fe031528aa4 Mon Sep 17 00:00:00 2001 From: s00442234 Date: Sat, 11 Dec 2021 16:19:55 +0800 Subject: [PATCH 3/4] fix:delete mipi-dis screen refresh logs Signed-off-by: s00442234 --- platform/mipi_dsi/mipi_tx_hi35xx.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/platform/mipi_dsi/mipi_tx_hi35xx.c b/platform/mipi_dsi/mipi_tx_hi35xx.c index dc8a2b8..0c43806 100644 --- a/platform/mipi_dsi/mipi_tx_hi35xx.c +++ b/platform/mipi_dsi/mipi_tx_hi35xx.c @@ -704,7 +704,6 @@ static int32_t LinuxCopyToKernel(void *dest, uint32_t max, const void *src, uint HDF_LOGE("%s: [memcpy_s] failed.", __func__); } } - HDF_LOGI("%s: success.", __func__); return ret; } @@ -756,7 +755,6 @@ static int MipiTxDrvSetCmdInfo(const CmdInfoTag *cmdInfo) HDF_LOGE("%s: [MipiTxWaitWriteFifoEmpty] failed.", __func__); return HDF_FAILURE; } - HDF_LOGI("%s: cmdSize = 0x%x, dataType = 0x%x", __func__, cmdInfo->cmdSize, cmdInfo->dataType); return HDF_SUCCESS; } @@ -878,7 +876,6 @@ static void MipiTxReset(void) static int MipiTxDrvGetCmdInfo(GetCmdInfoTag *getCmdInfo) { unsigned char *dataBuf = NULL; - HDF_LOGI("%s: enter!", __func__); dataBuf = (unsigned char*)OsalMemAlloc(getCmdInfo->getDataSize); if (dataBuf == NULL) { @@ -916,7 +913,6 @@ static int MipiTxDrvGetCmdInfo(GetCmdInfoTag *getCmdInfo) } OsalMemFree(dataBuf); dataBuf = NULL; - HDF_LOGI("%s: success!", __func__); return HDF_SUCCESS; fail0: @@ -1084,7 +1080,6 @@ static int MipiTxCheckCombDevCfg(const ComboDevCfgTag *devCfg) return HDF_FAILURE; } - HDF_LOGI("%s: success!", __func__); return HDF_SUCCESS; } @@ -1230,7 +1225,6 @@ static int MipiTxGetCmd(GetCmdInfoTag *getCmdInfo) static int32_t Hi35xxGetCmd(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd, uint32_t readLen, uint8_t *out) { GetCmdInfoTag cmdInfo; - HDF_LOGI("%s: enter!", __func__); (void)cntlr; if (cmd == NULL || out == NULL) { @@ -1277,7 +1271,6 @@ static struct MipiDsiCntlrMethod g_method = { static int32_t Hi35xxMipiTxInit(struct HdfDeviceObject *device) { int32_t ret; - HDF_LOGI("%s: enter!", __func__); g_mipiTx.priv = NULL; g_mipiTx.ops = &g_method; -- Gitee From 0092ff4826a061adc7c1606e2f2a55dc092a7a68 Mon Sep 17 00:00:00 2001 From: puyj0604 Date: Fri, 24 Dec 2021 22:25:53 +0800 Subject: [PATCH 4/4] device modify piaoyingjie Signed-off-by: puyj0604 --- nxp/build/BUILD.gn | 23 + nxp/build/ohos.build | 10 + nxp/drivers/ethernet/adapter/Kconfig | 6 + nxp/drivers/ethernet/adapter/Makefile | 39 + .../ethernet/adapter/ethernet_config.mk | 54 + .../ethernet/adapter/hdf_driver_register.c | 74 ++ nxp/drivers/ethernet/adapter/modules.builtin | 0 nxp/drivers/ethernet/adapter/modules.order | 0 nxp/drivers/ethernet/adapter/net_adapter.c | 122 ++ nxp/drivers/ethernet/adapter/net_adapter.h | 36 + nxp/drivers/ethernet/adapter/nxpeth_mac.c | 79 ++ nxp/drivers/ethernet/adapter/nxpeth_mac.h | 38 + nxp/drivers/ethernet/adapter/nxpeth_phy.c | 78 ++ nxp/drivers/ethernet/adapter/nxpeth_phy.h | 48 + nxp/drivers/wifi/ap6212/Makefile | 39 + .../ap6212/hdfadapter/hdf_driver_register.c | 133 ++ .../wifi/ap6212/hdfadapter/hdf_mac80211.c | 1143 +++++++++++++++++ .../wifi/ap6212/hdfadapter/hdfinit_ap6212.c | 117 ++ .../wifi/ap6212/hdfadapter/net_adpater.c | 376 ++++++ .../wifi/ap6212/hdfadapter/net_adpater.h | 53 + nxp/drivers/wifi/ap6212/modules.builtin | 0 nxp/drivers/wifi/ap6212/modules.order | 0 nxp/drivers/wifi/ap6212/wifi_config.mk | 55 + nxp/imx8mm/BUILD.gn | 12 + nxp/imx8mm/bootloader/flash.bin | 3 + nxp/imx8mm/build/BUILD.gn | 106 ++ nxp/imx8mm/build/LICENSE | 177 +++ nxp/imx8mm/build/rootfs/BUILD.gn | 39 + nxp/imx8mm/build/rootfs/init.imx8mm.cfg | 51 + nxp/imx8mm/build/rootfs/init.imx8mm.rc | 80 ++ .../build/rootfs/init.imx8mm.updater.cfg | 16 + nxp/imx8mm/build/rootfs/init.imx8mm.usb.cfg | 51 + nxp/imx8mm/build/rootfs/init.imx8mm.usb.rc | 35 + nxp/imx8mm/build/rootfs/ueventd.imx8mm.rc | 44 + nxp/imx8mm/build/rootfs/ueventd.rc | 49 + nxp/imx8mm/build/sepolicy/file.te | 1 + nxp/imx8mm/build/sepolicy/file_contexts | 2 + nxp/imx8mm/build/sepolicy/hos.te | 1 + nxp/imx8mm/build/updater_config/BOARD.list | 3 + nxp/imx8mm/build/updater_config/VERSION.mbn | 1 + .../updater_config/rsa_private_key2048.pem | 27 + .../build/updater_config/signing_cert.crt | 21 + nxp/imx8mm/build/vendor/etc/fstab.imx8mm | 3 + nxp/imx8mm/build/vendor/etc/fstab.updater | 6 + .../build/vendor/etc/vb_config_user.ini | 24 + nxp/imx8mm/camera/BUILD.gn | 100 ++ .../camera/camera_demo/project_camera_demo.h | 32 + .../camera/include/device_manager/mx6s_csi.h | 39 + .../include/device_manager/project_hardware.h | 29 + nxp/imx8mm/camera/product.gni | 31 + nxp/imx8mm/camera/src/device_manager/BUILD.gn | 80 ++ .../camera/src/device_manager/mx6s_csi.cpp | 72 ++ .../main_test/project_v4l2_main.h | 27 + .../camera/src/driver_adapter/test/BUILD.gn | 80 ++ .../test/unittest/include/utest_v4l2_dev.h | 42 + .../test/unittest/utest_v4l2_dev.cpp | 190 +++ nxp/imx8mm/camera/src/pipeline_core/BUILD.gn | 159 +++ .../ipp_algo_example/ipp_algo_example.c | 96 ++ nxp/imx8mm/firmware/bcm43438a1.hcd | Bin 0 -> 33376 bytes nxp/imx8mm/firmware/fw_bcm43438a1.bin | 3 + nxp/imx8mm/firmware/fw_bcm43438a1_apsta.bin | 3 + nxp/imx8mm/firmware/fw_bcm43438a1_p2p.bin | 3 + nxp/imx8mm/firmware/nvram_ap6212a.txt | 55 + 63 files changed, 4316 insertions(+) create mode 100755 nxp/build/BUILD.gn create mode 100755 nxp/build/ohos.build create mode 100755 nxp/drivers/ethernet/adapter/Kconfig create mode 100644 nxp/drivers/ethernet/adapter/Makefile create mode 100644 nxp/drivers/ethernet/adapter/ethernet_config.mk create mode 100755 nxp/drivers/ethernet/adapter/hdf_driver_register.c create mode 100644 nxp/drivers/ethernet/adapter/modules.builtin create mode 100644 nxp/drivers/ethernet/adapter/modules.order create mode 100755 nxp/drivers/ethernet/adapter/net_adapter.c create mode 100755 nxp/drivers/ethernet/adapter/net_adapter.h create mode 100755 nxp/drivers/ethernet/adapter/nxpeth_mac.c create mode 100755 nxp/drivers/ethernet/adapter/nxpeth_mac.h create mode 100755 nxp/drivers/ethernet/adapter/nxpeth_phy.c create mode 100755 nxp/drivers/ethernet/adapter/nxpeth_phy.h create mode 100644 nxp/drivers/wifi/ap6212/Makefile create mode 100644 nxp/drivers/wifi/ap6212/hdfadapter/hdf_driver_register.c create mode 100644 nxp/drivers/wifi/ap6212/hdfadapter/hdf_mac80211.c create mode 100644 nxp/drivers/wifi/ap6212/hdfadapter/hdfinit_ap6212.c create mode 100644 nxp/drivers/wifi/ap6212/hdfadapter/net_adpater.c create mode 100644 nxp/drivers/wifi/ap6212/hdfadapter/net_adpater.h create mode 100644 nxp/drivers/wifi/ap6212/modules.builtin create mode 100644 nxp/drivers/wifi/ap6212/modules.order create mode 100644 nxp/drivers/wifi/ap6212/wifi_config.mk create mode 100755 nxp/imx8mm/BUILD.gn create mode 100644 nxp/imx8mm/bootloader/flash.bin create mode 100644 nxp/imx8mm/build/BUILD.gn create mode 100755 nxp/imx8mm/build/LICENSE create mode 100755 nxp/imx8mm/build/rootfs/BUILD.gn create mode 100755 nxp/imx8mm/build/rootfs/init.imx8mm.cfg create mode 100755 nxp/imx8mm/build/rootfs/init.imx8mm.rc create mode 100755 nxp/imx8mm/build/rootfs/init.imx8mm.updater.cfg create mode 100755 nxp/imx8mm/build/rootfs/init.imx8mm.usb.cfg create mode 100644 nxp/imx8mm/build/rootfs/init.imx8mm.usb.rc create mode 100755 nxp/imx8mm/build/rootfs/ueventd.imx8mm.rc create mode 100755 nxp/imx8mm/build/rootfs/ueventd.rc create mode 100755 nxp/imx8mm/build/sepolicy/file.te create mode 100755 nxp/imx8mm/build/sepolicy/file_contexts create mode 100755 nxp/imx8mm/build/sepolicy/hos.te create mode 100755 nxp/imx8mm/build/updater_config/BOARD.list create mode 100755 nxp/imx8mm/build/updater_config/VERSION.mbn create mode 100755 nxp/imx8mm/build/updater_config/rsa_private_key2048.pem create mode 100755 nxp/imx8mm/build/updater_config/signing_cert.crt create mode 100755 nxp/imx8mm/build/vendor/etc/fstab.imx8mm create mode 100755 nxp/imx8mm/build/vendor/etc/fstab.updater create mode 100755 nxp/imx8mm/build/vendor/etc/vb_config_user.ini create mode 100755 nxp/imx8mm/camera/BUILD.gn create mode 100755 nxp/imx8mm/camera/camera_demo/project_camera_demo.h create mode 100755 nxp/imx8mm/camera/include/device_manager/mx6s_csi.h create mode 100755 nxp/imx8mm/camera/include/device_manager/project_hardware.h create mode 100755 nxp/imx8mm/camera/product.gni create mode 100755 nxp/imx8mm/camera/src/device_manager/BUILD.gn create mode 100755 nxp/imx8mm/camera/src/device_manager/mx6s_csi.cpp create mode 100755 nxp/imx8mm/camera/src/driver_adapter/main_test/project_v4l2_main.h create mode 100755 nxp/imx8mm/camera/src/driver_adapter/test/BUILD.gn create mode 100644 nxp/imx8mm/camera/src/driver_adapter/test/unittest/include/utest_v4l2_dev.h create mode 100644 nxp/imx8mm/camera/src/driver_adapter/test/unittest/utest_v4l2_dev.cpp create mode 100755 nxp/imx8mm/camera/src/pipeline_core/BUILD.gn create mode 100755 nxp/imx8mm/camera/src/pipeline_core/ipp_algo_example/ipp_algo_example.c create mode 100644 nxp/imx8mm/firmware/bcm43438a1.hcd create mode 100644 nxp/imx8mm/firmware/fw_bcm43438a1.bin create mode 100644 nxp/imx8mm/firmware/fw_bcm43438a1_apsta.bin create mode 100644 nxp/imx8mm/firmware/fw_bcm43438a1_p2p.bin create mode 100644 nxp/imx8mm/firmware/nvram_ap6212a.txt diff --git a/nxp/build/BUILD.gn b/nxp/build/BUILD.gn new file mode 100755 index 0000000..06405d7 --- /dev/null +++ b/nxp/build/BUILD.gn @@ -0,0 +1,23 @@ +# Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED. +# 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. + +import("//build/ohos.gni") + +device_type = "imx8mm" +group("products_group") { + if (device_type == "imx8mm") { + deps = [ + "//device/nxp/imx8mm:imx8mm_group", + ] + } +} diff --git a/nxp/build/ohos.build b/nxp/build/ohos.build new file mode 100755 index 0000000..77153cd --- /dev/null +++ b/nxp/build/ohos.build @@ -0,0 +1,10 @@ +{ + "subsystem": "nxp_products", + "parts": { + "nxp_products": { + "module_list": [ + "//device/nxp/build:products_group" + ] + } + } +} \ No newline at end of file diff --git a/nxp/drivers/ethernet/adapter/Kconfig b/nxp/drivers/ethernet/adapter/Kconfig new file mode 100755 index 0000000..c24193e --- /dev/null +++ b/nxp/drivers/ethernet/adapter/Kconfig @@ -0,0 +1,6 @@ +config DRIVERS_HDF_IMX8MM_ETHERNET + bool "Enable HDF imx8mm ethernet driver" + default n + depends on DRIVERS_HDF_PLATFORM + help + Answer Y to enable HDF imx8mm ethernet driver. diff --git a/nxp/drivers/ethernet/adapter/Makefile b/nxp/drivers/ethernet/adapter/Makefile new file mode 100644 index 0000000..bf589d0 --- /dev/null +++ b/nxp/drivers/ethernet/adapter/Makefile @@ -0,0 +1,39 @@ +# +# Copyright (c) 2021 Huawei Device Co., Ltd. +# +# This software is licensed under the terms of the GNU General Public +# License version 2, as published by the Free Software Foundation, and +# may be copied, distributed, and modified under those terms. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# + +MODULE_NAME := hdf_ethernet_model + +ETHERNET_PATH := $(shell pwd) +$(warning ETHERNET_PATH=$(ETHERNET_PATH)) + +include $(ETHERNET_PATH)/../../../../../device/nxp/drivers/ethernet/adapter/ethernet_config.mk + +ETHERNET_FW_PATH := ../../../../../out/KERNEL_OBJ/kernel/src_tmp/linux-4.19/drivers/hdf/framework/model/network/ethernet/src + +obj-y += $(ETHERNET_FW_PATH)/eth_chip_driver.o \ + $(ETHERNET_FW_PATH)/eth_device.o \ + $(ETHERNET_FW_PATH)/hdf_eth_core.o \ + +obj-y += $(MODULE_NAME).o +$(MODULE_NAME)-objs := hdf_driver_register.o \ + net_adapter.o \ + nxpeth_mac.o \ + nxpeth_phy.o +ccflags-y += \ + $(HDF_FRAMEWORKS_INC) \ + $(HDF_ETHERNET_FRAMEWORKS_INC) \ + $(SECURE_LIB_INC) \ + $(HDF_ETHERNET_ADAPTER_INC) \ + $(HDF_ETHERNET_FLAGS) + diff --git a/nxp/drivers/ethernet/adapter/ethernet_config.mk b/nxp/drivers/ethernet/adapter/ethernet_config.mk new file mode 100644 index 0000000..be7783c --- /dev/null +++ b/nxp/drivers/ethernet/adapter/ethernet_config.mk @@ -0,0 +1,54 @@ +# +# Copyright (c) 2021 Huawei Device Co., Ltd. +# +# This software is licensed under the terms of the GNU General Public +# License version 2, as published by the Free Software Foundation, and +# may be copied, distributed, and modified under those terms. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# +ETHERNET_CONFIG_PATH := $(shell pwd) +$(warning ETHERNET_CONFIG_PATH=$(ETHERNET_CONFIG_PATH)) + +HDF_FRAMEWORKS_INC := \ + -I./ \ + -Idrivers/hdf/framework/ability/sbuf/include \ + -Idrivers/hdf/framework/core/common/include/host \ + -Idrivers/hdf/framework/core/host/include \ + -Idrivers/hdf/framework/core/manager/include \ + -Idrivers/hdf/framework/core/shared/include \ + -Idrivers/hdf/framework/include \ + -Idrivers/hdf/framework/include/config \ + -Idrivers/hdf/framework/include/core \ + -Idrivers/hdf/framework/include/platform \ + -Idrivers/hdf/framework/include/utils \ + -Idrivers/hdf/framework/support/platform/include \ + -Idrivers/hdf/framework/support/platform/include/platform \ + -Idrivers/hdf/framework/utils/include \ + -Idrivers/hdf/khdf/osal/include \ + -Idrivers/hdf/khdf/config/include \ + -Iinclude/hdf \ + -Iinclude/hdf/osal \ + -Iinclude/hdf/utils \ + -Idrivers/hdf/framework/include/ethernet\ + -Idrivers/hdf/framework/include/net\ + -Idrivers/hdf/framework/model/network/common/netdevice\ + +HDF_ETHERNET_FRAMEWORKS_INC := \ + -Idrivers/hdf/framework/model/network/ethernet/include + +SECURE_LIB_INC := \ + -I./../../../../../third_party/bounds_checking_function/include + +HDF_ETHERNET_ADAPTER_INC := \ + -I./../../../../../device/nxp/drivers/ethernet/adapter \ + -Idrivers/hdf/khdf/network/include \ + -Idrivers/net/ethernet/freescale/ + +HDF_ETHERNET_FLAGS +=-D_PRE_OS_VERSION_LINUX=1 +HDF_ETHERNET_FLAGS +=-D_PRE_OS_VERSION_LITEOS=2 +HDF_ETHERNET_FLAGS +=-D_PRE_OS_VERSION=_PRE_OS_VERSION_LINUX diff --git a/nxp/drivers/ethernet/adapter/hdf_driver_register.c b/nxp/drivers/ethernet/adapter/hdf_driver_register.c new file mode 100755 index 0000000..3fec910 --- /dev/null +++ b/nxp/drivers/ethernet/adapter/hdf_driver_register.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED. + * 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. + */ + +#include "devsvc_manager_clnt.h" +#include "eth_chip_driver.h" +#include "hdf_device_desc.h" +#include "hdf_log.h" +#include "nxpeth_mac.h" +#include "nxpeth_phy.h" +#include "osal_mem.h" + +static const char* const NXP_ETHERNET_DRIVER_NAME = "nxpeth-fec"; + +static int32_t HdfEthRegNxpDriverFactory(void) +{ + static struct HdfEthChipDriverFactory tmpFactory = { 0 }; + struct HdfEthChipDriverManager *driverMgr = HdfEthGetChipDriverMgr(); + + if (driverMgr == NULL && driverMgr->RegChipDriver == NULL) { + HDF_LOGE("%s fail: driverMgr is NULL", __func__); + return HDF_FAILURE; + } + tmpFactory.driverName = NXP_ETHERNET_DRIVER_NAME; + tmpFactory.InitEthDriver = InitNxpethDriver; + tmpFactory.GetMacAddr = EthNxpRandomAddr; + tmpFactory.DeinitEthDriver = DeinitNxpethDriver; + tmpFactory.BuildMacDriver = BuildNxpMacDriver; + tmpFactory.ReleaseMacDriver = ReleaseNxpMacDriver; + if (driverMgr->RegChipDriver(&tmpFactory) != HDF_SUCCESS) { + HDF_LOGE("%s fail: driverMgr is NULL", __func__); + return HDF_FAILURE; + } + HDF_LOGI("nxp eth driver register success"); + return HDF_SUCCESS; +} + +static int32_t HdfEthNxpChipDriverInit(struct HdfDeviceObject *device) +{ + (void)device; + return HdfEthRegNxpDriverFactory(); +} + +static int32_t HdfEthNxpDriverBind(struct HdfDeviceObject *dev) +{ + (void)dev; + return HDF_SUCCESS; +} + +static void HdfEthNxpChipRelease(struct HdfDeviceObject *object) +{ + (void)object; +} + +struct HdfDriverEntry g_hdfNxpEthChipEntry = { + .moduleVersion = 1, + .Bind = HdfEthNxpDriverBind, + .Init = HdfEthNxpChipDriverInit, + .Release = HdfEthNxpChipRelease, + .moduleName = "HDF_ETHERNET_CHIPS" +}; + +HDF_INIT(g_hdfNxpEthChipEntry); diff --git a/nxp/drivers/ethernet/adapter/modules.builtin b/nxp/drivers/ethernet/adapter/modules.builtin new file mode 100644 index 0000000..e69de29 diff --git a/nxp/drivers/ethernet/adapter/modules.order b/nxp/drivers/ethernet/adapter/modules.order new file mode 100644 index 0000000..e69de29 diff --git a/nxp/drivers/ethernet/adapter/net_adapter.c b/nxp/drivers/ethernet/adapter/net_adapter.c new file mode 100755 index 0000000..ff32591 --- /dev/null +++ b/nxp/drivers/ethernet/adapter/net_adapter.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED. + * 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. + */ + +#include "net_adapter.h" +#include "eth_chip_driver.h" +#include "net_device.h" +#include "netbuf_adapter.h" +#include "net_device_adapter.h" +#include +#include +#include +#include "nxpeth_phy.h" + +struct net_device *save_eth_net = NULL; +extern const struct net_device_ops fec_netdev_ops; +extern struct net_device *get_eth_netdev(void); +extern int nxp_fec_set_mac(unsigned char * mac_address, struct net_device *ndev); +static int32_t EthSetMacAddr(struct NetDevice *netDev, void *addr) +{ + struct net_device *dev = NULL; + dev = get_eth_netdev(); + + if (NULL == dev || NULL == addr) { + HDF_LOGE("%s dev is null || addr is null!", __func__); + } + + nxp_fec_set_mac((unsigned char *)addr, dev); + HDF_LOGE("%s SetMac successful !", __func__); + return HDF_SUCCESS; +} + +static int32_t EthXmit(struct NetDevice *netDev, NetBuf *netbuf) +{ + int32_t ret = 0; + struct net_device *dev = NULL; + dev = get_eth_netdev(); + fec_netdev_ops.ndo_start_xmit(netbuf, dev); + + return ret; +} + +static int32_t EthOpen(struct NetDevice *netDev) +{ + int32_t ret = 0; + struct net_device *dev = NULL; + dev = get_eth_netdev(); + if (NULL == dev) { + HDF_LOGE("%s dev is null !", __func__); + } + + fec_netdev_ops.ndo_open(dev); + HDF_LOGE("%s open successful !", __func__); + return ret; +} + +static int32_t EthStop(struct NetDevice *netDev) +{ + int32_t ret = 0; + struct net_device *dev = NULL; + dev = get_eth_netdev(); + if (NULL == dev) { + HDF_LOGE("%s dev is null !", __func__); + } + + fec_netdev_ops.ndo_stop(dev); + HDF_LOGE("%s stop successful !", __func__); + + return ret; +} + +struct NetDeviceInterFace g_ethNetDevOps = { + .xmit = EthXmit, + .setMacAddr = EthSetMacAddr, + .open = EthOpen, + .stop = EthStop, +}; + +int32_t EthernetInitNetdev(NetDevice *netdev) +{ + int32_t ret = HDF_FAILURE; + + if (netdev == NULL) { + HDF_LOGE("%s netdev is null!", __func__); + return HDF_ERR_INVALID_PARAM; + } + netdev->netDeviceIf = &g_ethNetDevOps; + + ret = NetDeviceAdd(netdev); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s NetDeviceAdd return error code %d!", __func__, ret); + return ret; + } + + // open netdevice + HDF_LOGE("%s netdev->netDeviceIf->open!", __func__); + netdev->netDeviceIf->open(netdev); + + return ret; +} + +void set_eth_netdev(struct net_device *dev) { + save_eth_net = dev; +} + +struct net_device *get_eth_netdev(void) { + return save_eth_net; +} + +EXPORT_SYMBOL(set_eth_netdev); +EXPORT_SYMBOL(get_eth_netdev); diff --git a/nxp/drivers/ethernet/adapter/net_adapter.h b/nxp/drivers/ethernet/adapter/net_adapter.h new file mode 100755 index 0000000..7dc4013 --- /dev/null +++ b/nxp/drivers/ethernet/adapter/net_adapter.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED. + * 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. + */ + +#ifndef NET_ADAPTER_H +#define NET_ADAPTER_H + +#include "eth_chip_driver.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +int32_t EthernetInitNetdev(NetDevice *netdev); +struct NetDeviceInterFace *EthGetNetdevOps(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* NET_ADAPTER_H */ diff --git a/nxp/drivers/ethernet/adapter/nxpeth_mac.c b/nxp/drivers/ethernet/adapter/nxpeth_mac.c new file mode 100755 index 0000000..e52039c --- /dev/null +++ b/nxp/drivers/ethernet/adapter/nxpeth_mac.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED. + * 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. + */ + +#include "nxpeth_mac.h" +#include "osal_mem.h" + +extern void nxp_fec_get_mac(unsigned char * mac_address); +void NxpethMacCoreInit(void) +{ + return; +} + +int32_t NxpethPortReset(struct EthDevice *ethDevice) +{ + return HDF_SUCCESS; +} + +int32_t NxpethPortInit(struct EthDevice *ethDevice) +{ + return HDF_SUCCESS; +} + +static struct EthMacOps g_macOps = { + .MacInit = NxpethMacCoreInit, + .PortReset = NxpethPortReset, + .PortInit = NxpethPortInit, +}; + +struct HdfEthMacChipDriver *BuildNxpMacDriver(void) +{ + HDF_LOGE("BuildNxpMacDriver start !!!!!!!!!!!!\n"); + struct HdfEthMacChipDriver *macChipDriver = (struct HdfEthMacChipDriver *)OsalMemCalloc( + sizeof(struct HdfEthMacChipDriver)); + + if (macChipDriver == NULL) { + HDF_LOGE("%s fail: OsalMemCalloc fail!", __func__); + return NULL; + } + macChipDriver->ethMacOps = &g_macOps; + return macChipDriver; +} + +void ReleaseNxpMacDriver(struct HdfEthMacChipDriver *chipDriver) +{ + if (chipDriver == NULL) { + HDF_LOGE("%s fail: chipDriver == NULL!", __func__); + return; + } + OsalMemFree(chipDriver); +} + +struct HdfEthMacChipDriver *GetNxpEthMacChipDriver(const struct NetDevice *netDev) +{ + struct HdfEthNetDeviceData *data = GetEthNetDeviceData(netDev); + if (data != NULL) { + return data->macChipDriver; + } + return NULL; +} + +void EthNxpRandomAddr(uint8_t *addr, int32_t len) +{ + nxp_fec_get_mac(addr); + + return; +} + diff --git a/nxp/drivers/ethernet/adapter/nxpeth_mac.h b/nxp/drivers/ethernet/adapter/nxpeth_mac.h new file mode 100755 index 0000000..718b028 --- /dev/null +++ b/nxp/drivers/ethernet/adapter/nxpeth_mac.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED. + * 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. + */ + +#ifndef NXPETH_MAC_H +#define NXPETH_MAC_H + +#include "eth_chip_driver.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +struct HdfEthMacChipDriver *BuildNxpMacDriver(void); +void ReleaseNxpMacDriver(struct HdfEthMacChipDriver *chipDriver); +struct HdfEthMacChipDriver *GetNxpEthMacChipDriver(const struct NetDevice *netDev); +void EthNxpRandomAddr(uint8_t *addr, int32_t len); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* NXPETH_MAC_H */ diff --git a/nxp/drivers/ethernet/adapter/nxpeth_phy.c b/nxp/drivers/ethernet/adapter/nxpeth_phy.c new file mode 100755 index 0000000..e69d728 --- /dev/null +++ b/nxp/drivers/ethernet/adapter/nxpeth_phy.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED. + * 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. + */ + +#include "nxpeth_phy.h" +#include +#include "net_adapter.h" +#include "eth_chip_driver.h" +#include "net_device.h" +#include "net_device_adapter.h" +#include +#include +#include +#include "osal_mem.h" + +struct NetDevice *g_hdf_netDev; +extern int fec_driver_init(void); +extern int fec_driver_init(void); +extern int32_t GetSizeOfPrivData(void); +int32_t InitNxpethDriver(struct EthDevice *ethDevice) +{ + int32_t ret; + int32_t size = GetSizeOfPrivData(); + + if (ethDevice == NULL) { + HDF_LOGE("%s input is NULL!", __func__); + return HDF_FAILURE; + } + + g_hdf_netDev = ethDevice->netdev; + g_hdf_netDev->mlPriv = (struct fec_enet_private *)OsalMemCalloc(size); + if (NULL == g_hdf_netDev->mlPriv) { + HDF_LOGE("%s kzalloc mlPriv failed!", __func__); + return HDF_FAILURE; + } else { + HDF_LOGE("%s kzalloc mlPriv ok!", __func__); + } + + fec_driver_init(); + ret = EthernetInitNetdev(ethDevice->netdev); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s failed to init ethernet netDev", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +int32_t DeinitNxpethDriver(struct EthDevice *ethDevice) +{ + return HDF_SUCCESS; +} + +int32_t GetSizeOfPrivData(void) +{ + return sizeof(struct fec_enet_private); +} + +struct fec_enet_private * +fec_get_priv_data(struct net_device *ndev) +{ + (void)ndev; + return (struct fec_enet_private*)g_hdf_netDev->mlPriv; +} + +EXPORT_SYMBOL(GetSizeOfPrivData); +EXPORT_SYMBOL(fec_get_priv_data); \ No newline at end of file diff --git a/nxp/drivers/ethernet/adapter/nxpeth_phy.h b/nxp/drivers/ethernet/adapter/nxpeth_phy.h new file mode 100755 index 0000000..7ed010c --- /dev/null +++ b/nxp/drivers/ethernet/adapter/nxpeth_phy.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED. + * 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. + */ + +#ifndef NXPETH_PHY_H +#define NXPETH_PHY_H + +#include "eth_chip_driver.h" +#include +#include +#include "net_device_impl.h" +#include "fec.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +int32_t InitNxpethDriver(struct EthDevice *ethDevice); +int32_t DeinitNxpethDriver(struct EthDevice *ethDevice); +bool NxpethHwInit(struct EthDevice *ethDevice); +int32_t NxpethInit(struct EthDevice *ethDevice); + +struct FullNetDeviceImx8mmEthPriv { + struct net_device *dev; + struct NetDeviceImpl *impl; + struct fec_enet_private *lfecp; +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* NXPETH_PHY_H */ diff --git a/nxp/drivers/wifi/ap6212/Makefile b/nxp/drivers/wifi/ap6212/Makefile new file mode 100644 index 0000000..d2f50fe --- /dev/null +++ b/nxp/drivers/wifi/ap6212/Makefile @@ -0,0 +1,39 @@ +# +# Copyright (c) 2021 Huawei Device Co., Ltd. +# +# This software is licensed under the terms of the GNU General Public +# License version 2, as published by the Free Software Foundation, and +# may be copied, distributed, and modified under those terms. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +#5 + +MODULE_NAME := ap6212 + +VENDOR_WIFI_ROOT = . + +WIFI_PATH := $(shell pwd) +$(warning WIFI_PATH=$(WIFI_PATH)) + +include $(WIFI_PATH)/../../../../../device/nxp/drivers/wifi/ap6212/wifi_config.mk + +$(warning HDF_FRAMEWORKS_INC=$(HDF_FRAMEWORKS_INC)) +$(warning HDF_WIFI_FRAMEWORKS_INC=$(HDF_WIFI_FRAMEWORKS_INC)) +$(warning SECURE_LIB_INC=$(SECURE_LIB_INC)) +$(warning HDF_WIFI_ADAPTER_INC=$(HDF_WIFI_ADAPTER_INC)) + +obj-y += $(MODULE_NAME).o +$(MODULE_NAME)-objs := $(VENDOR_WIFI_ROOT)/hdfadapter/hdf_driver_register.o \ + $(VENDOR_WIFI_ROOT)/hdfadapter/hdfinit_ap6212.o \ + $(VENDOR_WIFI_ROOT)/hdfadapter/net_adpater.o \ + $(VENDOR_WIFI_ROOT)/hdfadapter/hdf_mac80211.o + +ccflags-y += \ + $(HDF_FRAMEWORKS_INC) \ + $(HDF_WIFI_FRAMEWORKS_INC) \ + $(SECURE_LIB_INC) \ + $(HDF_WIFI_ADAPTER_INC) diff --git a/nxp/drivers/wifi/ap6212/hdfadapter/hdf_driver_register.c b/nxp/drivers/wifi/ap6212/hdfadapter/hdf_driver_register.c new file mode 100644 index 0000000..386fc63 --- /dev/null +++ b/nxp/drivers/wifi/ap6212/hdfadapter/hdf_driver_register.c @@ -0,0 +1,133 @@ +#include "hdf_device_desc.h" +#include "hdf_wifi_product.h" +#include "hdf_log.h" +#include "osal_mem.h" +#include "hdf_wlan_chipdriver_manager.h" +#include "securec.h" +#include "wifi_module.h" + + +#define HDF_LOG_TAG Ap6212Driver +static const char * const AP6212_DRIVER_NAME = "ap6212"; + +int32_t InitAp6212Chip(struct HdfWlanDevice *device); +int32_t DeinitAp6212Chip(struct HdfWlanDevice *device); +int32_t Ap6212Deinit(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice); +int32_t Ap6212Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice); +void ApMac80211Init(struct HdfChipDriver *chipDriver); + +static struct HdfChipDriver *BuildAp6212Driver(struct HdfWlanDevice *device, uint8_t ifIndex) +{ + struct HdfChipDriver *specificDriver = NULL; + + HDF_LOGE("%s: Enter ", __func__); + + if (device == NULL) { + HDF_LOGE("%s fail : channel is NULL", __func__); + return NULL; + } + (void)device; + (void)ifIndex; + specificDriver = (struct HdfChipDriver *)OsalMemCalloc(sizeof(struct HdfChipDriver)); + if (specificDriver == NULL) { + HDF_LOGE("%s fail: OsalMemCalloc fail!", __func__); + return NULL; + } + if (memset_s(specificDriver, sizeof(struct HdfChipDriver), 0, sizeof(struct HdfChipDriver)) != EOK) { + HDF_LOGE("%s fail: memset_s fail!", __func__); + OsalMemFree(specificDriver); + return NULL; + } + + if (strcpy_s(specificDriver->name, MAX_WIFI_COMPONENT_NAME_LEN, AP6212_DRIVER_NAME) != EOK) { + HDF_LOGE("%s fail : strcpy_s fail", __func__); + OsalMemFree(specificDriver); + return NULL; + } + specificDriver->init = Ap6212Init; + specificDriver->deinit = Ap6212Deinit; + + ApMac80211Init(specificDriver); + + return specificDriver; +} + +static void ReleaseAp6212Driver(struct HdfChipDriver *chipDriver) +{ + HDF_LOGE("%s: Enter ", __func__); + return; + + if (chipDriver == NULL) { + return; + } + if (strcmp(chipDriver->name, AP6212_DRIVER_NAME) != 0) { + HDF_LOGE("%s:Not my driver!", __func__); + return; + } + OsalMemFree(chipDriver); +} + +static uint8_t GetAp6212GetMaxIFCount(struct HdfChipDriverFactory *factory) +{ + (void)factory; + HDF_LOGE("%s: Enter ", __func__); + + return 1; +} + +/* ap6212's register */ +static int32_t HDFWlanRegApDriverFactory(void) +{ + static struct HdfChipDriverFactory tmpFactory = { 0 }; + struct HdfChipDriverManager *driverMgr = NULL; + + HDF_LOGE("%s: Enter ", __func__); + driverMgr = HdfWlanGetChipDriverMgr(); + if (driverMgr == NULL) { + HDF_LOGE("%s fail: driverMgr is NULL!", __func__); + return HDF_FAILURE; + } + tmpFactory.driverName = AP6212_DRIVER_NAME; + tmpFactory.GetMaxIFCount = GetAp6212GetMaxIFCount; + tmpFactory.InitChip = InitAp6212Chip; + tmpFactory.DeinitChip = DeinitAp6212Chip; + tmpFactory.Build = BuildAp6212Driver; + tmpFactory.Release = ReleaseAp6212Driver; + tmpFactory.ReleaseFactory = NULL; + if (driverMgr->RegChipDriver(&tmpFactory) != HDF_SUCCESS) { + HDF_LOGE("%s fail: driverMgr is NULL!", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +static int32_t HdfWlanApChipDriverInit(struct HdfDeviceObject *device) +{ + (void)device; + HDF_LOGE("%s: Enter ", __func__); + return HDFWlanRegApDriverFactory(); +} + +static int HdfWlanApDriverBind(struct HdfDeviceObject *dev) +{ + (void)dev; + HDF_LOGE("%s: Enter ", __func__); + return HDF_SUCCESS; +} + +static void HdfWlanApChipRelease(struct HdfDeviceObject *object) +{ + (void)object; + HDF_LOGE("%s: Enter ", __func__); +} + +struct HdfDriverEntry g_hdfApChipEntry = { + .moduleVersion = 1, + .Bind = HdfWlanApDriverBind, + .Init = HdfWlanApChipDriverInit, + .Release = HdfWlanApChipRelease, + .moduleName = "HDF_WLAN_CHIPS" +}; + +HDF_INIT(g_hdfApChipEntry); diff --git a/nxp/drivers/wifi/ap6212/hdfadapter/hdf_mac80211.c b/nxp/drivers/wifi/ap6212/hdfadapter/hdf_mac80211.c new file mode 100644 index 0000000..b608dd0 --- /dev/null +++ b/nxp/drivers/wifi/ap6212/hdfadapter/hdf_mac80211.c @@ -0,0 +1,1143 @@ +/* + * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "wifi_mac80211_ops.h" +#include "net_adpater.h" +#include "hdf_wlan_utils.h" +#include "wifi_module.h" +#include +#include +#include "osal_mem.h" +#include "hdf_wifi_event.h" + +#define HDF_LOG_TAG Ap6212Driver +#ifndef errno_t +typedef int errno_t; +#endif + +extern struct net_device_ops dhd_ops_pri; +extern struct cfg80211_ops wl_cfg80211_ops; + +extern NetDevice *get_netDev(void); +extern struct wiphy* wrap_get_wiphy(void); +extern struct net_device *get_krn_netdev(void); +extern struct wireless_dev* wrap_get_widev(void); +extern const struct ieee80211_regdomain * wrp_get_regdomain(void); +extern int32_t wl_get_all_sta(struct net_device *ndev, uint32_t *num); +extern void dhd_get_mac_address(struct net_device *dev, void **addr); +extern s32 wl_get_all_sta_info(struct net_device *ndev, char* mac, uint32_t num); +extern int32_t wal_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct net_device *netDev); +extern int32_t wl_cfg80211_set_wps_p2p_ie_wrp(struct net_device *ndev, char *buf, int len, int8_t type); +extern int32_t wal_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *netDev, int32_t freq, unsigned int duration); +extern void wl_cfg80211_add_virtual_iface_wrap(struct wiphy *wiphy, char *name, enum nl80211_iftype type, struct vif_params *params); +extern int32_t wl_cfg80211_set_country_code(struct net_device *net, char *country_code, bool notify, bool user_enforced, int revinfo); +extern int32_t HdfWifiEventInformBssFrame(const struct NetDevice *netDev, const struct WlanChannel *channel, const struct ScannedBssInfo *bssInfo); +extern int32_t wl_cfg80211_change_beacon_wrap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_beacon_data *info, int interval, int dtimPeriod, bool hidden_ssid); + +extern errno_t memcpy_s(void *dest, size_t dest_max, const void *src, size_t count); +extern int snprintf_s(char *dest, size_t dest_max, size_t count, const char *format, ...); + +typedef enum { + WLAN_BAND_2G, + WLAN_BAND_BUTT +} wlan_channel_band_enum; + +#define WIFI_24G_CHANNEL_NUMS (14) +#define WAL_MIN_CHANNEL_2G (1) +#define WAL_MAX_CHANNEL_2G (14) +#define WAL_MIN_FREQ_2G (2412 + 5*(WAL_MIN_CHANNEL_2G - 1)) +#define WAL_MAX_FREQ_2G (2484) +#define WAL_FREQ_2G_INTERVAL (5) +#define WLAN_WPS_IE_MAX_SIZE (352) // (WLAN_MEM_EVENT_SIZE2 - 32) /* 32表示事件自身占用的空间 */ +/* Driver supports AP mode */ +#define HISI_DRIVER_FLAGS_AP 0x00000040 +/* Driver supports concurrent P2P operations */ +#define HISI_DRIVER_FLAGS_P2P_CONCURRENT 0x00000200 + +#define HISI_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE 0x00000400 +/* P2P capable (P2P GO or P2P Client) */ +#define HISI_DRIVER_FLAGS_P2P_CAPABLE 0x00000800 +/* Driver supports a dedicated interface for P2P Device */ +#define HISI_DRIVER_FLAGS_DEDICATED_P2P_DEVICE 0x20000000 + +/*--------------------------------------------------------------------------------------------------*/ +/* public */ +/*--------------------------------------------------------------------------------------------------*/ +static int32_t GetIfName(enum nl80211_iftype type, char *ifName, uint32_t len) +{ + if (ifName == NULL || len == 0) { + HDF_LOGE("%s:para is null!", __func__); + return HDF_FAILURE; + } + switch (type) { + case NL80211_IFTYPE_P2P_DEVICE: + if (snprintf_s(ifName, len, len -1, "p2p%d", 0) < 0) { + HDF_LOGE("%s:format ifName failed!", __func__); + return HDF_FAILURE; + } + break; + case NL80211_IFTYPE_P2P_CLIENT: + /* fall-through */ + case NL80211_IFTYPE_P2P_GO: + if (snprintf_s(ifName, len, len -1, "p2p-p2p0-%d", 0) < 0) { + HDF_LOGE("%s:format ifName failed!", __func__); + return HDF_FAILURE; + } + break; + default: + HDF_LOGE("%s:GetIfName::not supported dev type!", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +void WalReleaseHwCapability(struct WlanHwCapability *self) +{ + uint8_t i; + if (self == NULL) { + return; + } + for (i = 0; i < IEEE80211_NUM_BANDS; i++) { + if (self->bands[i] != NULL) { + OsalMemFree(self->bands[i]); + self->bands[i] = NULL; + } + } + if (self->supportedRates != NULL) { + OsalMemFree(self->supportedRates); + self->supportedRates = NULL; + } + OsalMemFree(self); +} + +static struct ieee80211_channel *GetChannelByFreq(struct wiphy* wiphy, uint16_t center_freq) +{ + enum Ieee80211Band band; + struct ieee80211_supported_band *currentBand = NULL; + int32_t loop; + for (band = (enum Ieee80211Band)0; band < IEEE80211_NUM_BANDS; band++) { + currentBand = wiphy->bands[band]; + if (currentBand == NULL) { + continue; + } + for (loop = 0; loop < currentBand->n_channels; loop++) { + if (currentBand->channels[loop].center_freq == center_freq) { + return ¤tBand->channels[loop]; + } + } + } + return NULL; +} + +static struct ieee80211_channel *WalGetChannel(struct wiphy *wiphy, int32_t freq) +{ + int32_t loop = 0; + enum Ieee80211Band band = IEEE80211_BAND_2GHZ; + struct ieee80211_supported_band *currentBand = NULL; + + if (wiphy == NULL) { + HDF_LOGE("%s: capality is NULL!", __func__); + return NULL; + } + + for (band = (enum Ieee80211Band)0; band < IEEE80211_NUM_BANDS; band++) { + currentBand = wiphy->bands[band]; + if (currentBand == NULL) { + continue; + } + + for (loop = 0; loop < currentBand->n_channels; loop++) { + if (currentBand->channels[loop].center_freq == freq) { + return ¤tBand->channels[loop]; + } + } + } + + return NULL; +} + +void inform_bss_frame(struct ieee80211_channel *channel, int32_t signal, int16_t freq, struct ieee80211_mgmt *mgmt, uint32_t mgmtLen) +{ + int32_t retVal = 0; + NetDevice *netDev = get_netDev(); + struct ScannedBssInfo bssInfo; + struct WlanChannel hdfchannel; + + if (channel == NULL || netDev == NULL || mgmt == NULL) { + HDF_LOGE("%s: inform_bss_frame channel = null or netDev = null!", __func__); + return; + } + + bssInfo.signal = signal; + bssInfo.freq = freq; + bssInfo.mgmtLen = mgmtLen; + bssInfo.mgmt = (struct Ieee80211Mgmt *)mgmt; + + hdfchannel.flags = channel->flags; + hdfchannel.channelId = channel->hw_value; + hdfchannel.centerFreq = channel->center_freq; + + HDF_LOGE("%s: hdfchannel flags:%d--channelId:%d--centerFreq:%d--dstMac:%02x:%02x:%02x:%02x:%02x:%02x!", + __func__, hdfchannel.flags, hdfchannel.channelId, hdfchannel.centerFreq, + bssInfo.mgmt->bssid[0], bssInfo.mgmt->bssid[1], bssInfo.mgmt->bssid[2], + bssInfo.mgmt->bssid[3], bssInfo.mgmt->bssid[4], bssInfo.mgmt->bssid[5]); + + retVal = HdfWifiEventInformBssFrame(netDev, &hdfchannel, &bssInfo); + if (retVal < 0) { + HDF_LOGE("%s: hdf wifi event inform bss frame failed!", __func__); + } +} + +#define HDF_ETHER_ADDR_LEN (6) +void inform_connect_result(uint8_t *bssid, uint8_t *rspIe, uint8_t *reqIe, uint32_t reqIeLen, uint32_t rspIeLen, uint16_t connectStatus) +{ + int32_t retVal = 0; + NetDevice *netDev = get_netDev(); + struct ConnetResult connResult; + + if (netDev == NULL || bssid == NULL || rspIe == NULL || reqIe == NULL) { + HDF_LOGE("%s: netDev / bssid / rspIe / reqIe null!", __func__); + return; + } + + memcpy(&connResult.bssid[0], bssid, HDF_ETHER_ADDR_LEN); + HDF_LOGE("%s: connResult:%02x:%02x:%02x:%02x:%02x:%02x\n", __func__, + connResult.bssid[0], connResult.bssid[1], connResult.bssid[2], connResult.bssid[3], connResult.bssid[4], connResult.bssid[5]); + + connResult.rspIe = rspIe; + connResult.rspIeLen = rspIeLen; + + connResult.reqIe = reqIe; + connResult.reqIeLen = reqIeLen; + + connResult.connectStatus = connectStatus; + + // TODO: modify freq & statusCode + connResult.freq = 0; + connResult.statusCode = connectStatus; + + retVal = HdfWifiEventConnectResult(netDev, &connResult); + if (retVal < 0) { + HDF_LOGE("%s: hdf wifi event inform connect result failed!", __func__); + } +} + +struct wireless_dev ap_wireless_dev; +struct ieee80211_channel ap_ieee80211_channel; +#define GET_DEV_CFG80211_WIRELESS(dev) ((struct wireless_dev*)((dev)->ieee80211_ptr)) +static int32_t SetupWireLessDev(struct net_device *netDev, struct WlanAPConf *apSettings) +{ + + if (netDev->ieee80211_ptr == NULL) { + netDev->ieee80211_ptr = &ap_wireless_dev; + } + + if (GET_DEV_CFG80211_WIRELESS(netDev)->preset_chandef.chan == NULL) { + GET_DEV_CFG80211_WIRELESS(netDev)->preset_chandef.chan = &ap_ieee80211_channel; + } + GET_DEV_CFG80211_WIRELESS(netDev)->iftype = NL80211_IFTYPE_AP; + GET_DEV_CFG80211_WIRELESS(netDev)->preset_chandef.width = (enum nl80211_channel_type)apSettings->width; + GET_DEV_CFG80211_WIRELESS(netDev)->preset_chandef.center_freq1 = apSettings->centerFreq1; + GET_DEV_CFG80211_WIRELESS(netDev)->preset_chandef.center_freq2 = apSettings->centerFreq2; + GET_DEV_CFG80211_WIRELESS(netDev)->preset_chandef.chan->hw_value = apSettings->channel; + GET_DEV_CFG80211_WIRELESS(netDev)->preset_chandef.chan->band = IEEE80211_BAND_2GHZ; + GET_DEV_CFG80211_WIRELESS(netDev)->preset_chandef.chan->center_freq = apSettings->centerFreq1; + + return HDF_SUCCESS; +} + +/*--------------------------------------------------------------------------------------------------*/ +/* HdfMac80211BaseOps */ +/*--------------------------------------------------------------------------------------------------*/ +// OK +int32_t WalSetMode(NetDevice *netDev, enum WlanWorkMode iftype) +{ + int32_t retVal = 0; + struct wiphy* wiphy = wrap_get_wiphy(); + struct net_device *netdev = get_krn_netdev(); + + HDF_LOGE("%s: start... iftype=%d ", __func__, iftype); + retVal = (int32_t)wl_cfg80211_ops.change_virtual_intf(wiphy, netdev, (enum nl80211_iftype)iftype, NULL); + if (retVal < 0) { + HDF_LOGE("%s: set mode failed!", __func__); + } + + return retVal; +} + + +int32_t WalAddKey(struct NetDevice *netDev, uint8_t keyIndex, bool pairwise, const uint8_t *macAddr, + struct KeyParams *params) +{ + int32_t retVal = 0; + struct wiphy* wiphy = wrap_get_wiphy(); + struct net_device *netdev = get_krn_netdev(); + + HDF_LOGE("%s: start...", __func__); + + (void)netDev; + retVal = (int32_t)wl_cfg80211_ops.add_key(wiphy, netdev, keyIndex, pairwise, macAddr, (struct key_params *)params); + if (retVal < 0) { + HDF_LOGE("%s: add key failed!", __func__); + } + + return retVal; +} + +int32_t WalDelKey(struct NetDevice *netDev, uint8_t keyIndex, bool pairwise, const uint8_t *macAddr) +{ + int32_t retVal = 0; + struct wiphy* wiphy = wrap_get_wiphy(); + struct net_device *netdev = get_krn_netdev(); + + HDF_LOGE("%s: start...", __func__); + + (void)netDev; + retVal = (int32_t)wl_cfg80211_ops.del_key(wiphy, netdev, keyIndex, pairwise, macAddr); + if (retVal < 0) { + HDF_LOGE("%s: delete key failed!", __func__); + } + + return retVal; +} + +int32_t WalSetDefaultKey(struct NetDevice *netDev, uint8_t keyIndex, bool unicast, bool multicas) +{ + int32_t retVal = 0; + struct wiphy* wiphy = wrap_get_wiphy(); + struct net_device *netdev = get_krn_netdev(); + + HDF_LOGE("%s: start...", __func__); + + retVal = (int32_t)wl_cfg80211_ops.set_default_key(wiphy, netdev, keyIndex, unicast, multicas); + if (retVal < 0) { + HDF_LOGE("%s: set default key failed!", __func__); + } + + return retVal; +} + +int32_t WalGetDeviceMacAddr(NetDevice *netDev, int32_t type, uint8_t *mac, uint8_t len) +{ + struct net_device *netdev = get_krn_netdev(); + + (void)len; + (void)type; + (void)netDev; + HDF_LOGE("%s: start...", __func__); + + dhd_get_mac_address(netdev, (void**)&mac); + + return HDF_SUCCESS; +} + +int32_t WalSetMacAddr(NetDevice *netDev, uint8_t *mac, uint8_t len) +{ + int32_t retVal = 0; + struct net_device *netdev = get_krn_netdev(); + + (void)len; + (void)netDev; + HDF_LOGE("%s: start...", __func__); + + retVal = (int32_t)dhd_ops_pri.ndo_set_mac_address(netdev, mac); + if (retVal < 0) { + HDF_LOGE("%s: set mac address failed!", __func__); + } + + return retVal; +} + +int32_t WalSetTxPower(NetDevice *netDev, int32_t power) +{ + int retVal = 0; + struct wiphy* wiphy = wrap_get_wiphy(); + struct wireless_dev *wdev = GET_NET_DEV_CFG80211_WIRELESS(netDev); + + HDF_LOGE("%s: start...", __func__); + + retVal = (int32_t)wl_cfg80211_ops.set_tx_power(wiphy, wdev, NL80211_TX_POWER_FIXED ,power); + + if (retVal < 0) { + HDF_LOGE("%s: set_tx_power failed!", __func__); + } + + return HDF_SUCCESS; +} + +int32_t WalGetValidFreqsWithBand(NetDevice *netDev, int32_t band, int32_t *freqs, uint32_t *num) +{ + uint32_t freqIndex = 0; + uint32_t channelNumber; + uint32_t freqTmp; + uint32_t minFreq; + uint32_t maxFreq; + const struct ieee80211_regdomain *regdom = wrp_get_regdomain(); + if (regdom == NULL) { + HDF_LOGE("%s: wal_get_cfg_regdb failed!", __func__); + return HDF_FAILURE; + } + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + + minFreq = regdom->reg_rules[0].freq_range.start_freq_khz / MHZ_TO_KHZ(1); + maxFreq = regdom->reg_rules[0].freq_range.end_freq_khz / MHZ_TO_KHZ(1); + switch (band) { + case WLAN_BAND_2G: + for (channelNumber = 1; channelNumber <= WIFI_24G_CHANNEL_NUMS; channelNumber++) { + if (channelNumber < WAL_MAX_CHANNEL_2G) { + freqTmp = WAL_MIN_FREQ_2G + (channelNumber - 1) * WAL_FREQ_2G_INTERVAL; + } else if (channelNumber == WAL_MAX_CHANNEL_2G) { + freqTmp = WAL_MAX_FREQ_2G; + } + if (freqTmp < minFreq || freqTmp > maxFreq) { + continue; + } + freqs[freqIndex] = freqTmp; + freqIndex++; + } + *num = freqIndex; + break; + default: + HDF_LOGE("%s: no support band!", __func__); + return HDF_ERR_NOT_SUPPORT; + } + return HDF_SUCCESS; +} + + +int32_t WalGetHwCapability(struct NetDevice *netDev, struct WlanHwCapability **capability) +{ + uint8_t loop = 0; + struct wiphy* wiphy = wrap_get_wiphy(); + struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_2GHZ]; + struct WlanHwCapability *hwCapability = (struct WlanHwCapability *)OsalMemCalloc(sizeof(struct WlanHwCapability)); + + (void)netDev; + if (hwCapability == NULL) { + HDF_LOGE("%s: oom!\n", __func__); + return HDF_FAILURE; + } + hwCapability->Release = WalReleaseHwCapability; + if (hwCapability->bands[IEEE80211_BAND_2GHZ] == NULL) { + hwCapability->bands[IEEE80211_BAND_2GHZ] = + OsalMemCalloc(sizeof(struct WlanBand) + (sizeof(struct WlanChannel) * band->n_channels)); + if (hwCapability->bands[IEEE80211_BAND_2GHZ] == NULL) { + HDF_LOGE("%s: oom!\n", __func__); + WalReleaseHwCapability(hwCapability); + return HDF_FAILURE; + } + } + hwCapability->htCapability = band->ht_cap.cap; + hwCapability->bands[IEEE80211_BAND_2GHZ]->channelCount = band->n_channels; + for (loop = 0; loop < band->n_channels; loop++) { + hwCapability->bands[IEEE80211_BAND_2GHZ]->channels[loop].centerFreq = band->channels[loop].center_freq; + hwCapability->bands[IEEE80211_BAND_2GHZ]->channels[loop].flags = band->channels[loop].flags; + hwCapability->bands[IEEE80211_BAND_2GHZ]->channels[loop].channelId = band->channels[loop].hw_value; + } + hwCapability->supportedRateCount = band->n_bitrates; + hwCapability->supportedRates = OsalMemCalloc(sizeof(uint16_t) * band->n_bitrates); + if (hwCapability->supportedRates == NULL) { + HDF_LOGE("%s: oom!\n", __func__); + WalReleaseHwCapability(hwCapability); + return HDF_FAILURE; + } + for (loop = 0; loop < band->n_bitrates; loop++) { + hwCapability->supportedRates[loop] = band->bitrates[loop].bitrate; + } + *capability = hwCapability; + return HDF_SUCCESS; +} + +int32_t WalRemainOnChannel(struct NetDevice *netDev, WifiOnChannel *onChannel) +{ + int32_t retVal = 0; + struct wiphy* wiphy = wrap_get_wiphy(); + struct net_device *netdev = get_krn_netdev(); + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + if (netdev == NULL || onChannel == NULL) { + HDF_LOGE("%s:NULL ptr!", __func__); + return HDF_FAILURE; + } + + retVal = (int32_t)wal_cfg80211_remain_on_channel(wiphy, netdev, onChannel->freq, onChannel->duration); + if (retVal < 0) { + HDF_LOGE("%s: remain on channel failed!", __func__); + } + + return retVal; +} + +int32_t WalCancelRemainOnChannel(struct NetDevice *netDev) +{ + int32_t retVal = 0; + struct wiphy* wiphy = wrap_get_wiphy(); + struct net_device *netdev = get_krn_netdev(); + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + if (netdev == NULL) { + HDF_LOGE("%s:NULL ptr!", __func__); + return HDF_FAILURE; + } + + retVal = (int32_t)wal_cfg80211_cancel_remain_on_channel(wiphy, netdev); + if (retVal < 0) { + HDF_LOGE("%s: cancel remain on channel failed!", __func__); + } + + return retVal; +} + +int32_t WalProbeReqReport(struct NetDevice *netDev, int32_t report) +{ + // NO SUPPORT + (void)report; + HDF_LOGE("%s: start...", __func__); + if (netDev == NULL) { + HDF_LOGE("%s:NULL ptr!", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t WalAddIf(struct NetDevice *netDev, WifiIfAdd *ifAdd) +{ + char ifName[16] = {0}; + struct wiphy* wiphy = wrap_get_wiphy(); + + HDF_LOGE("%s: start...", __func__); + + GetIfName(ifAdd->type, ifName, 16); + wl_cfg80211_ops.add_virtual_intf(wiphy, ifName, 0, ifAdd->type, NULL); + + return HDF_SUCCESS; +} + + +int32_t WalRemoveIf(struct NetDevice *netDev, WifiIfRemove *ifRemove) +{ + struct NetDevice *removeNetdev = NULL; + struct wireless_dev *wdev = NULL; + struct wiphy* wiphy = wrap_get_wiphy(); + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + if (ifRemove == NULL) { + HDF_LOGE("%s:NULL ptr!", __func__); + return HDF_FAILURE; + } + + removeNetdev = NetDeviceGetInstByName((const char*)(ifRemove->ifname)); + if (removeNetdev == NULL) { + return HDF_FAILURE; + } + + wdev = GET_NET_DEV_CFG80211_WIRELESS(removeNetdev); + wl_cfg80211_ops.del_virtual_intf(wiphy, wdev); + + return HDF_SUCCESS; +} + +int32_t WalSetApWpsP2pIe(struct NetDevice *netDev, WifiAppIe *appIe) +{ + int32_t retVal = 0; + struct net_device *netdev = get_krn_netdev(); + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + if (netdev == NULL || appIe == NULL) { + HDF_LOGE("%s:NULL ptr!", __func__); + return HDF_FAILURE; + } + + if (appIe->ieLen > WLAN_WPS_IE_MAX_SIZE) { + HDF_LOGE("%s:app ie length is too large!", __func__); + return HDF_FAILURE; + } + + retVal = (int32_t)wl_cfg80211_set_wps_p2p_ie_wrp(netdev, appIe->ie, appIe->ieLen, (int8_t)appIe->appIeType); + if (retVal < 0) { + HDF_LOGE("%s: set_wps_p2p_ie failed!", __func__); + } + + return retVal; +} + +// ?? +int32_t WalGetDriverFlag(struct NetDevice *netDev, WifiGetDrvFlags **params) +{ + struct wireless_dev *wdev = GET_NET_DEV_CFG80211_WIRELESS(netDev); + WifiGetDrvFlags *getDrvFlag = (WifiGetDrvFlags *)OsalMemCalloc(sizeof(WifiGetDrvFlags)); + + if (netDev == NULL || params == NULL) { + HDF_LOGE("%s:NULL ptr!", __func__); + return HDF_FAILURE; + } + + HDF_LOGE("%s: start...", __func__); + + if (NULL == wdev) { + HDF_LOGE("%s: wdev NULL", __func__); + return HDF_FAILURE; + } else { + HDF_LOGE("%s: p_wdev:%p", __func__, wdev); + } + + if (NULL == getDrvFlag) { + HDF_LOGE("%s: getDrvFlag NULL", __func__); + } + switch (wdev->iftype) { + case NL80211_IFTYPE_P2P_CLIENT: + /* fall-through */ + case NL80211_IFTYPE_P2P_GO: + HDF_LOGE("%s: NL80211_IFTYPE_P2P_GO case!", __func__); + getDrvFlag->drvFlags = HISI_DRIVER_FLAGS_AP; + break; + case NL80211_IFTYPE_P2P_DEVICE: + HDF_LOGE("%s: NL80211_IFTYPE_P2P_DEVICE case!", __func__); + getDrvFlag->drvFlags = (HISI_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE | + HISI_DRIVER_FLAGS_P2P_CONCURRENT | + HISI_DRIVER_FLAGS_P2P_CAPABLE); + break; + default: + HDF_LOGE("%s: getDrvFlag->drvFlags default to 0 case!", __func__); + getDrvFlag->drvFlags = 0; + } + *params = getDrvFlag; + return HDF_SUCCESS; +} + +// ?? +int32_t WalSendAction(struct NetDevice *netDev, WifiActionData *actionData) +{ + (void)netDev; + (void)actionData; + HDF_LOGE("%s: start...", __func__); + return HDF_ERR_NOT_SUPPORT; +} + +int32_t WalGetIftype(struct NetDevice *netDev, uint8_t *iftype) +{ + iftype = (uint8_t *)(&(GET_NET_DEV_CFG80211_WIRELESS(netDev)->iftype)); + HDF_LOGE("%s: start...", __func__); + return HDF_SUCCESS; +} + + +/*--------------------------------------------------------------------------------------------------*/ +/* HdfMac80211STAOps */ +/*--------------------------------------------------------------------------------------------------*/ +static int32_t WalConnect(NetDevice *netDev, WlanConnectParams *param) +{ + int ret = 0; + int32_t retVal = 0; + struct wiphy* wiphy = wrap_get_wiphy(); + struct net_device *netdev = get_krn_netdev(); + struct cfg80211_connect_params cfg80211_params = { 0 }; + + HDF_LOGE("%s: start ...!", __func__); + + (void)netDev; + if (netdev == NULL || param == NULL) { + HDF_LOGE("%s:NULL ptr!", __func__); + return HDF_FAILURE; + } + + if (param->centerFreq != WLAN_FREQ_NOT_SPECFIED) { + cfg80211_params.channel = WalGetChannel(wiphy, param->centerFreq); + if ((cfg80211_params.channel == NULL) || (cfg80211_params.channel->flags & WIFI_CHAN_DISABLED)) { + HDF_LOGE("%s:illegal channel.flags=%u", __func__, + (cfg80211_params.channel == NULL) ? 0 : cfg80211_params.channel->flags); + return HDF_FAILURE; + } + } + cfg80211_params.bssid = param->bssid; + cfg80211_params.ssid = param->ssid; + cfg80211_params.ie = param->ie; + cfg80211_params.ssid_len = param->ssidLen; + cfg80211_params.ie_len = param->ieLen; + ret = memcpy_s(&cfg80211_params.crypto, sizeof(cfg80211_params.crypto), ¶m->crypto, sizeof(param->crypto)); + if (ret != 0) { + HDF_LOGE("%s:Copy crypto info failed!ret=%d", __func__, ret); + return HDF_FAILURE; + } + cfg80211_params.key = param->key; + cfg80211_params.auth_type = (u_int8_t)param->authType; + cfg80211_params.privacy = param->privacy; + cfg80211_params.key_len = param->keyLen; + cfg80211_params.key_idx = param->keyIdx; + cfg80211_params.mfp = (u_int8_t)param->mfp; + + retVal = wl_cfg80211_ops.connect(wiphy, netdev, &cfg80211_params); + if (retVal < 0) { + HDF_LOGE("%s: connect failed!\n", __func__); + } + + return retVal; +} + +int32_t WalDisconnect(NetDevice *netDev, uint16_t reasonCode) +{ + int32_t retVal = 0; + struct wiphy* wiphy = wrap_get_wiphy(); + struct net_device *netdev = get_krn_netdev(); + + (void)netDev; + HDF_LOGE("%s: start...reasonCode:%d", __func__, reasonCode); + + retVal = (int32_t)wl_cfg80211_ops.disconnect(wiphy, netdev, reasonCode); + if (retVal < 0) { + HDF_LOGE("%s: sta disconnect failed!", __func__); + } + + return retVal; +} + +int32_t WalStartScan(NetDevice *netDev, struct WlanScanRequest *scanParam) +{ + int32_t loop; + int32_t count = 0; + int32_t retVal = 0; + enum Ieee80211Band band = IEEE80211_BAND_2GHZ; + struct ieee80211_channel *chan = NULL; + struct wiphy* wiphy = wrap_get_wiphy(); + + struct cfg80211_scan_request *request = + (struct cfg80211_scan_request *)OsalMemCalloc(sizeof(struct cfg80211_scan_request)); + + if (request == NULL) { + HDF_LOGE("%s: calloc request null!\n", __func__); + return HDF_FAILURE; + } + + // basic info + request->wiphy = wiphy; + // request->dev = netdev; // for sched scan + request->wdev = GET_NET_DEV_CFG80211_WIRELESS(netDev); + request->n_ssids = scanParam->ssidCount; + // request->prefix_ssid_scan_flag = 0; // for sched scan + + // channel info + if ((scanParam->freqs == NULL) || (scanParam->freqsCount == 0)) { + if (wiphy->bands[band] == NULL) { + HDF_LOGE("%s: wiphy->bands[band] = NULL!\n", __func__); + return HDF_FAILURE; + } + + for (loop = 0; loop < (int32_t)wiphy->bands[band]->n_channels; loop++) { + chan = &wiphy->bands[band]->channels[loop]; + if ((chan->flags & WIFI_CHAN_DISABLED) != 0) { + continue; + } + request->channels[count++] = chan; + } + } else { + for (loop = 0; loop < scanParam->freqsCount; loop++) { + chan = GetChannelByFreq(wiphy, (uint16_t)(scanParam->freqs[loop])); + if (chan == NULL) { + HDF_LOGE("%s: freq not found!freq=%d!\n", __func__, scanParam->freqs[loop]); + continue; + } + + request->channels[count++] = chan; + } + } + + if (count == 0) { + HDF_LOGE("%s: invalid freq info!\n", __func__); + return HDF_FAILURE; + } + request->n_channels = count; + + // ssid info + count = 0; + loop = 0; + if (scanParam->ssidCount > WPAS_MAX_SCAN_SSIDS) { + HDF_LOGE("%s:unexpected numSsids!numSsids=%u", __func__, scanParam->ssidCount); + return HDF_FAILURE; + } + + if (scanParam->ssidCount == 0) { + HDF_LOGE("%s:ssid number is 0!", __func__); + } + + request->ssids = (struct cfg80211_ssid *)OsalMemCalloc(scanParam->ssidCount * sizeof(struct cfg80211_ssid)); + if (request->ssids == NULL) { + HDF_LOGE("%s: calloc request->ssids null", __func__); + return HDF_FAILURE; + } + + for (loop = 0; loop < scanParam->ssidCount; loop++) { + if (count >= DRIVER_MAX_SCAN_SSIDS) { + break; + } + + if (scanParam->ssids[loop].ssidLen > IEEE80211_MAX_SSID_LEN) { + continue; + } + + request->ssids[count].ssid_len = scanParam->ssids[loop].ssidLen; + if (memcpy_s(request->ssids[count].ssid, OAL_IEEE80211_MAX_SSID_LEN, scanParam->ssids[loop].ssid, + scanParam->ssids[loop].ssidLen) != 0) { + continue; + } + count++; + } + request->n_ssids = count; + + // User Ie Info + if (scanParam->extraIEsLen > 512) { + HDF_LOGE("%s:unexpected extra len!extraIesLen=%d", __func__, scanParam->extraIEsLen); + return HDF_FAILURE; + } + + if ((scanParam->extraIEs != NULL) && (scanParam->extraIEsLen != 0)) { + request->ie = (uint8_t *)OsalMemCalloc(scanParam->extraIEsLen); + if (request->ie == NULL) { + HDF_LOGE("%s: calloc request->ie null", __func__); + goto fail; + } + (void)memcpy_s((void*)request->ie, scanParam->extraIEsLen, scanParam->extraIEs, scanParam->extraIEsLen); + request->ie_len = scanParam->extraIEsLen; + } + + retVal = (int32_t)wl_cfg80211_ops.scan(wiphy, request); + if (retVal < 0) { + HDF_LOGE("%s: scan Failed!", __func__); + if (request != NULL) { + if ((request)->ie != NULL) { + OsalMemFree((void*)(request->ie)); + request->ie = NULL; + } + if ((request)->ssids != NULL) { + OsalMemFree(request->ssids); + (request)->ssids = NULL; + } + OsalMemFree(request); + request = NULL; + } + } else { + HDF_LOGE("%s: scan OK!", __func__); + } + + return retVal; + +fail: + if (request->ie != NULL) { + OsalMemFree((void*)request->ie); + request->ie = NULL; + } + + return HDF_FAILURE; +} + +int32_t WalAbortScan(NetDevice *netDev) +{ + struct wiphy* wiphy = wrap_get_wiphy(); + struct wireless_dev* wdev = wrap_get_widev(); + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + wl_cfg80211_ops.abort_scan(wiphy, wdev); + + return HDF_SUCCESS; +} + +int32_t WalSetScanningMacAddress(NetDevice *netDev, unsigned char *mac, uint32_t len) +{ + (void)netDev; + (void)mac; + (void)len; + return HDF_ERR_NOT_SUPPORT; +} + +/*--------------------------------------------------------------------------------------------------*/ +/* HdfMac80211APOps */ +/*--------------------------------------------------------------------------------------------------*/ +struct cfg80211_ap_settings ap_setting_info; +u8 ap_ssid[IEEE80211_MAX_SSID_LEN]; +struct ieee80211_channel ap_chan; +int32_t WalConfigAp(NetDevice *netDev, struct WlanAPConf *apConf) +{ + int32_t ret = 0; + struct wiphy* wiphy = wrap_get_wiphy(); + struct net_device *netdev = get_krn_netdev(); + + (void)netDev; + ret = SetupWireLessDev(netdev, apConf); + if (0 != ret) { + HDF_LOGE("%s: set up wireless device failed!", __func__); + return HDF_FAILURE; + } + + HDF_LOGE("%s: before iftype = %d!", __func__, netdev->ieee80211_ptr->iftype); + netdev->ieee80211_ptr->iftype = NL80211_IFTYPE_AP; + HDF_LOGE("%s: after iftype = %d!", __func__, netdev->ieee80211_ptr->iftype); + + ap_setting_info.ssid_len = apConf->ssidConf.ssidLen; + memcpy(&ap_ssid[0], &apConf->ssidConf.ssid[0], apConf->ssidConf.ssidLen); + + ap_setting_info.ssid = &ap_ssid[0]; + ap_setting_info.chandef.center_freq1 = apConf->centerFreq1; + ap_setting_info.chandef.center_freq2 = apConf->centerFreq2; + ap_setting_info.chandef.width = apConf->width; + + ap_chan.center_freq = apConf->centerFreq1; + ap_chan.hw_value= apConf->channel; + ap_chan.band = apConf->band; + ap_chan.band = IEEE80211_BAND_2GHZ; + ap_setting_info.chandef.chan = &ap_chan; + + ret = (int32_t)wl_cfg80211_ops.change_virtual_intf(wiphy, netdev, (enum nl80211_iftype)netdev->ieee80211_ptr->iftype, NULL); + if (ret < 0) { + HDF_LOGE("%s: set mode failed!", __func__); + } + + return HDF_SUCCESS; +} + +int32_t WalStartAp(NetDevice *netDev) +{ + int32_t retVal = 0; + struct wiphy* wiphy = wrap_get_wiphy(); + struct net_device *netdev = get_krn_netdev(); + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + GET_DEV_CFG80211_WIRELESS(netdev)->preset_chandef.chan->center_freq = netdev->ieee80211_ptr->preset_chandef.center_freq1; + retVal = (int32_t)wl_cfg80211_ops.start_ap(wiphy, netdev, &ap_setting_info); + if (retVal < 0) { + HDF_LOGE("%s: start_ap failed!", __func__); + } + + return retVal; +} + +int32_t WalStopAp(NetDevice *netDev) +{ + int32_t retVal = 0; + struct wiphy* wiphy = wrap_get_wiphy(); + struct net_device *netdev = get_krn_netdev(); + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + + retVal = (int32_t)wl_cfg80211_ops.stop_ap(wiphy, netdev); + if (retVal < 0) { + HDF_LOGE("%s: stop_ap failed!", __func__); + } + + return retVal; +} + +int32_t WalChangeBeacon(NetDevice *netDev, struct WlanBeaconConf *param) +{ + int32_t retVal = 0; + struct cfg80211_beacon_data info; + struct wiphy* wiphy = wrap_get_wiphy(); + struct net_device *netdev = get_krn_netdev(); + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + + memset(&info, 0x00, sizeof(info)); + info.head = param->headIEs; + info.head_len = (size_t)param->headIEsLength; + info.tail = param->tailIEs; + info.tail_len = (size_t)param->tailIEsLength; + + info.beacon_ies = NULL; + info.proberesp_ies = NULL; + info.assocresp_ies = NULL; + info.probe_resp = NULL; + info.lci = NULL; + info.civicloc = NULL; + info.ftm_responder = 0X00; + info.beacon_ies_len = 0X00; + info.proberesp_ies_len = 0X00; + info.assocresp_ies_len = 0X00; + info.probe_resp_len = 0X00; + info.lci_len = 0X00; + info.civicloc_len = 0X00; + + // add beacon data for start ap + ap_setting_info.dtim_period = param->DTIMPeriod; + ap_setting_info.hidden_ssid = param->hiddenSSID; + ap_setting_info.beacon_interval = param->interval; + HDF_LOGE("%s: dtim_period:%d---hidden_ssid:%d---beacon_interval:%d!", + __func__, ap_setting_info.dtim_period, ap_setting_info.hidden_ssid, ap_setting_info.beacon_interval); + + ap_setting_info.beacon.head = param->headIEs; + ap_setting_info.beacon.head_len = param->headIEsLength; + ap_setting_info.beacon.tail = param->tailIEs; + ap_setting_info.beacon.tail_len = param->tailIEsLength; + + ap_setting_info.beacon.beacon_ies = NULL; + ap_setting_info.beacon.proberesp_ies = NULL; + ap_setting_info.beacon.assocresp_ies = NULL; + ap_setting_info.beacon.probe_resp = NULL; + ap_setting_info.beacon.lci = NULL; + ap_setting_info.beacon.civicloc = NULL; + ap_setting_info.beacon.ftm_responder = 0X00; + ap_setting_info.beacon.beacon_ies_len = 0X00; + ap_setting_info.beacon.proberesp_ies_len = 0X00; + ap_setting_info.beacon.assocresp_ies_len = 0X00; + ap_setting_info.beacon.probe_resp_len = 0X00; + ap_setting_info.beacon.lci_len = 0X00; + ap_setting_info.beacon.civicloc_len = 0X00; + + HDF_LOGE("%s: headIEsLen:%d---tailIEsLen:%d!", __func__, param->headIEsLength, param->tailIEsLength); + + retVal = (int32_t)wl_cfg80211_ops.change_beacon(wiphy, netdev, &info); + if (retVal < 0) { + HDF_LOGE("%s: change_beacon failed!", __func__); + } + + return HDF_SUCCESS; +} + +int32_t WalDelStation(NetDevice *netDev, const uint8_t *macAddr) +{ + int32_t retVal = 0; + struct wiphy* wiphy = wrap_get_wiphy(); + struct net_device *netdev = get_krn_netdev(); + struct station_del_parameters del_param = {macAddr, 10, 0}; + + (void)netDev; + (void)macAddr; + HDF_LOGE("%s: start...", __func__); + + retVal = (int32_t)wl_cfg80211_ops.del_station(wiphy, netdev, &del_param); + if (retVal < 0) { + HDF_LOGE("%s: del_station failed!", __func__); + } + + return retVal; +} + +int32_t WalSetCountryCode(NetDevice *netDev, const char *code, uint32_t len) +{ + int32_t retVal = 0; + struct net_device *netdev = get_krn_netdev(); + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + + retVal = (int32_t)wl_cfg80211_set_country_code(netdev, (char*)code, false, true, len); + if (retVal < 0) { + HDF_LOGE("%s: set_country_code failed!", __func__); + } + + return retVal; +} + +int32_t WalGetAssociatedStasCount(NetDevice *netDev, uint32_t *num) +{ + int32_t retVal = 0; + struct net_device *netdev = get_krn_netdev(); + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + + retVal = (int32_t)wl_get_all_sta(netdev, num); + if (retVal < 0) { + HDF_LOGE("%s: wl_get_all_sta failed!", __func__); + } + return retVal; +} + +int32_t WalGetAssociatedStasInfo(NetDevice *netDev, WifiStaInfo *staInfo, uint32_t num) +{ + int32_t retVal = 0; + struct net_device *netdev = get_krn_netdev(); + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + + retVal = (int32_t)wl_get_all_sta_info(netdev, staInfo->mac, num); + if (retVal < 0) { + HDF_LOGE("%s: wl_get_all_sta_info failed!", __func__); + } + + return retVal; +} +/*--------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------------------------------*/ +static struct HdfMac80211BaseOps g_baseOps = +{ + .SetMode = WalSetMode, + .AddKey = WalAddKey, + .DelKey = WalDelKey, + .SetDefaultKey = WalSetDefaultKey, + .GetDeviceMacAddr = WalGetDeviceMacAddr, + .SetMacAddr = WalSetMacAddr, + .SetTxPower = WalSetTxPower, + .GetValidFreqsWithBand = WalGetValidFreqsWithBand, + .GetHwCapability = WalGetHwCapability, + .RemainOnChannel = WalRemainOnChannel, + .CancelRemainOnChannel = WalCancelRemainOnChannel, + .ProbeReqReport = WalProbeReqReport, + .AddIf = WalAddIf, + .RemoveIf = WalRemoveIf, + .SetApWpsP2pIe = WalSetApWpsP2pIe, + .GetDriverFlag = WalGetDriverFlag, + .SendAction = WalSendAction, + .GetIftype = WalGetIftype, +}; + +static struct HdfMac80211STAOps g_staOps = +{ + .Connect = WalConnect, + .Disconnect = WalDisconnect, + .StartScan = WalStartScan, + .AbortScan = WalAbortScan, + .SetScanningMacAddress = WalSetScanningMacAddress, +}; + +static struct HdfMac80211APOps g_apOps = +{ + .ConfigAp = WalConfigAp, + .StartAp = WalStartAp, + .StopAp = WalStopAp, + .ConfigBeacon = WalChangeBeacon, + .DelStation = WalDelStation, + .SetCountryCode = WalSetCountryCode, + .GetAssociatedStasCount = WalGetAssociatedStasCount, + .GetAssociatedStasInfo = WalGetAssociatedStasInfo +}; + +void ApMac80211Init(struct HdfChipDriver *chipDriver) +{ + HDF_LOGE("%s: start...", __func__); + + if (chipDriver == NULL) { + HDF_LOGE("%s: input is NULL", __func__); + return; + } + chipDriver->ops = &g_baseOps; + chipDriver->staOps = &g_staOps; + chipDriver->apOps = &g_apOps; +} + +EXPORT_SYMBOL(inform_bss_frame); +EXPORT_SYMBOL(inform_connect_result); diff --git a/nxp/drivers/wifi/ap6212/hdfadapter/hdfinit_ap6212.c b/nxp/drivers/wifi/ap6212/hdfadapter/hdfinit_ap6212.c new file mode 100644 index 0000000..2a29972 --- /dev/null +++ b/nxp/drivers/wifi/ap6212/hdfadapter/hdfinit_ap6212.c @@ -0,0 +1,117 @@ +#include "hdf_wifi_product.h" +#include "wifi_mac80211_ops.h" +#include "hdf_wlan_utils.h" + +/***********************************************************/ +/* marco declare */ +/***********************************************************/ +#define AP_SUCCESS (0) +#define HDF_LOG_TAG Ap6212Driver + +/***********************************************************/ +/* variable and function declare */ +/***********************************************************/ +struct NetDevice *g_hdf_netDevice; +struct net_device *save_kernel_net = NULL; + +/***********************************************************/ +/* variable and function declare */ +/***********************************************************/ +extern struct net_device_ops dhd_ops_pri; +extern struct net_device *save_kernel_net; +extern int get_dhd_priv_data_size(void); +extern int32_t hdf_netdev_init(struct NetDevice *netDev); +extern int32_t hdf_netdev_open(struct NetDevice *netDev); +extern int32_t hdf_netdev_stop(struct NetDevice *netDev); + +/***********************************************************/ +/* Function declare */ +/***********************************************************/ +int32_t InitAp6212Chip(struct HdfWlanDevice *device) +{ + HDF_LOGE("%s: start...", __func__); + return HDF_SUCCESS; +} + +int32_t DeinitAp6212Chip(struct HdfWlanDevice *device) +{ + int32_t ret = 0; + + (void)device; + HDF_LOGE("%s: start...", __func__); + if (ret != 0) + { + HDF_LOGE("%s:Deinit failed!ret=%d", __func__, ret); + } + return ret; +} + +int32_t Ap6212Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) +{ + int32_t ret = 0; + int private_data_size = 0; + struct HdfWifiNetDeviceData *data = NULL; + + (void)chipDriver; + HDF_LOGE("%s: start...", __func__); + + if (netDevice == NULL) + { + HDF_LOGE("%s:para is null!", __func__); + return HDF_FAILURE; + } + + data = GetPlatformData(netDevice); + if (data == NULL) + { + HDF_LOGE("%s:netdevice data null!", __func__); + return HDF_FAILURE; + } + + /* set netdevice ops to netDevice */ + hdf_netdev_init(netDevice); + netDevice->classDriverName = netDevice->classDriverName; + netDevice->classDriverPriv = data; + g_hdf_netDevice = netDevice; + + private_data_size = get_dhd_priv_data_size(); + g_hdf_netDevice->mlPriv = kzalloc(private_data_size, GFP_KERNEL); + if (NULL == g_hdf_netDevice->mlPriv) + { + printk("%s:kzalloc mlPriv failed\n", __func__); + return HDF_FAILURE; + } + dhd_module_init(save_kernel_net); + NetDeviceAdd(netDevice); + + HDF_LOGE("%s:NetDeviceAdd success", __func__); + + ret = hdf_netdev_open(netDevice); + return HDF_SUCCESS; +} + +int32_t Ap6212Deinit(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) +{ + HDF_LOGE("%s: start...", __func__); + (void)netDevice; + (void)chipDriver; + hdf_netdev_stop(netDevice); + return HDF_SUCCESS; +} + +void set_krn_netdev(struct net_device *dev) { + save_kernel_net = dev; +} + +struct net_device *get_krn_netdev(void) { + return save_kernel_net; +} + +void* getDevicePrivateData(void) +{ + return g_hdf_netDevice->mlPriv; +} + +EXPORT_SYMBOL(set_krn_netdev); +EXPORT_SYMBOL(get_krn_netdev); +EXPORT_SYMBOL(getDevicePrivateData); \ No newline at end of file diff --git a/nxp/drivers/wifi/ap6212/hdfadapter/net_adpater.c b/nxp/drivers/wifi/ap6212/hdfadapter/net_adpater.c new file mode 100644 index 0000000..6038229 --- /dev/null +++ b/nxp/drivers/wifi/ap6212/hdfadapter/net_adpater.c @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* **************************************************************************** + 1 头文件包含 +**************************************************************************** */ +#include "net_adpater.h" +#include "hdf_base.h" +#include "net_device.h" +#include +#include +#include "eapol.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/* **************************************************************************** + 2 全局变量声明 +**************************************************************************** */ +NetDevice *gp_hdf_netDev; +extern struct net_device_ops dhd_ops_pri; +extern struct wiphy* wrap_get_wiphy(void); +extern struct net_device *get_krn_netdev(void); +extern struct NetDeviceInterFace *wal_get_net_dev_ops(void); +extern int dhd_netdev_changemtu_wrapper(struct net_device *netdev, int mtu); +extern struct wireless_dev *wl_cfg80211_add_monitor_if_wrap(struct net_device * netdev, struct wiphy *wiphy, const char *name); +/* **************************************************************************** + 2 全局变量定义 +**************************************************************************** */ + +/* **************************************************************************** + 3 函数实现 +**************************************************************************** */ +int32_t hdf_netdev_init(struct NetDevice *netDev) +{ + HDF_LOGE("%s: start...", __func__); + if (NULL == netDev) { + HDF_LOGE("%s: netDev null!", __func__); + return HDF_FAILURE; + } + + HDF_LOGE("%s: netDev->name:%s\n", __func__, netDev->name); + netDev->netDeviceIf = wal_get_net_dev_ops(); + CreateEapolData(netDev); + + return HDF_SUCCESS; +} + +void hdf_netdev_deinit(struct NetDevice *netDev) +{ + HDF_LOGE("%s: start...", __func__); + (void)netDev; +} + +int32_t hdf_netdev_open(struct NetDevice *netDev) +{ + int32_t retVal = 0; + struct wiphy* wiphy = wrap_get_wiphy(); + struct net_device * netdev = get_krn_netdev(); + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + + if (NULL == netdev) { + HDF_LOGE("%s: netDev null!", __func__); + return HDF_FAILURE; + } + + HDF_LOGE("%s: ndo_stop...", __func__); + retVal = (int32_t)dhd_ops_pri.ndo_stop(netdev); + if (retVal < 0) { + HDF_LOGE("%s: hdf net device stop failed! ret = %d", __func__, retVal); + } + + retVal = (int32_t)dhd_ops_pri.ndo_open(netdev); + if (retVal < 0) { + HDF_LOGE("%s: hdf net device open failed! ret = %d", __func__, retVal); + } + + netDev->ieee80211Ptr = netdev->ieee80211_ptr; + if (NULL == netDev->ieee80211Ptr) { + HDF_LOGE("%s: NULL == netDev->ieee80211Ptr", __func__); + } + + dhd_get_mac_address(netdev, netDev->macAddr); + HDF_LOGE("%s: %02x:%02x:%02x:%02x:%02x:%02x", __func__, + netDev->macAddr[0], + netDev->macAddr[1], + netDev->macAddr[2], + netDev->macAddr[3], + netDev->macAddr[4], + netDev->macAddr[5] + ); + + struct wireless_dev *wdev = GET_NET_DEV_CFG80211_WIRELESS(netDev); + gp_hdf_netDev = netDev; + + return retVal; +} + +int32_t hdf_netdev_stop(struct NetDevice *netDev) +{ + int32_t retVal = 0; + struct net_device * netdev = get_krn_netdev(); + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + + if (NULL == netdev) { + HDF_LOGE("%s: netDev null!", __func__); + return HDF_FAILURE; + } + + retVal = (int32_t)dhd_ops_pri.ndo_stop(netdev); + if (retVal < 0) { + HDF_LOGE("%s: hdf net device stop failed! ret = %d", __func__, retVal); + } + + return retVal; +} + +int32_t hdf_netdev_xmit(struct NetDevice *netDev, NetBuf *netBuff) +{ + int32_t retVal = 0; + struct net_device * netdev = get_krn_netdev(); + + (void)netDev; + HDF_LOGI("%s: start...", __func__); + + if (NULL == netdev || NULL == netBuff) { + HDF_LOGE("%s: netdev or netBuff null!", __func__); + return HDF_FAILURE; + } + + retVal = (int32_t)dhd_ops_pri.ndo_start_xmit((struct sk_buff *)netBuff, netdev); + if (retVal < 0) { + HDF_LOGE("%s: hdf net device xmit failed! ret = %d", __func__, retVal); + } + + return retVal; +} + +int32_t hdf_netdev_ioctl(struct NetDevice *netDev, IfReq *req, int32_t cmd) +{ + int32_t retVal = 0; + struct ifreq *dhd_req = NULL; + struct net_device * netdev = get_krn_netdev(); + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + + if (NULL == netdev || NULL == req) { + HDF_LOGE("%s: netdev or req null!", __func__); + return HDF_FAILURE; + } + + dhd_req->ifr_ifru.ifru_data = req->ifrData; + + retVal = (int32_t)dhd_ops_pri.ndo_do_ioctl(netdev, dhd_req, cmd); + if (retVal < 0) { + HDF_LOGE("%s: hdf net device ioctl failed! ret = %d", __func__, retVal); + } + + return retVal; +} + +int32_t hdf_netdev_setmacaddr(struct NetDevice *netDev, void *addr) +{ + int32_t retVal = 0; + struct net_device * netdev = get_krn_netdev(); + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + + if (NULL == netdev || NULL == addr) { + HDF_LOGE("%s: netDev or addr null!", __func__); + return HDF_FAILURE; + } + + retVal = (int32_t)dhd_ops_pri.ndo_set_mac_address(netdev, addr); + if (retVal < 0) { + HDF_LOGE("%s: hdf net device setmacaddr failed! ret = %d", __func__, retVal); + } + + return retVal; +} + +struct NetDevStats *hdf_netdev_getstats(struct NetDevice *netDev) +{ + static struct NetDevStats devStat = {0}; + struct net_device_stats * kdevStat = NULL; + struct net_device * netdev = get_krn_netdev(); + + (void)netDev; + HDF_LOGE("%s: start...", __func__); + + if (NULL == netdev) { + HDF_LOGE("%s: netDev null!", __func__); + return NULL; + } + + kdevStat = dhd_ops_pri.ndo_get_stats(netdev); + if (NULL == kdevStat) { + HDF_LOGE("%s: ndo_get_stats return null!", __func__); + return NULL; + } + + devStat.rxPackets = kdevStat->rx_packets; + devStat.txPackets = kdevStat->tx_packets; + devStat.rxBytes = kdevStat->rx_bytes; + devStat.txBytes = kdevStat->tx_bytes; + devStat.rxErrors = kdevStat->rx_errors; + devStat.txErrors = kdevStat->tx_errors; + devStat.rxDropped = kdevStat->rx_dropped; + devStat.txDropped = kdevStat->tx_dropped; + + return &devStat; +} + +void hdf_netdev_setnetifstats(struct NetDevice *netDev, NetIfStatus status) +{ + HDF_LOGE("%s: start...", __func__); + (void)netDev; + (void)status; +} + +uint16_t hdf_netdev_selectqueue(struct NetDevice *netDev, NetBuf *netBuff) +{ + HDF_LOGE("%s: start...", __func__); + (void)netDev; + (void)netBuff; + return HDF_SUCCESS; +} + +uint32_t hdf_netdev_netifnotify(struct NetDevice *netDev, NetDevNotify *notify) +{ + HDF_LOGE("%s: start...", __func__); + (void)netDev; + (void)notify; + return HDF_SUCCESS; +} + +int32_t hdf_netdev_changemtu(struct NetDevice *netDev, int32_t mtu) +{ + int32_t retVal = 0; + struct net_device * netdev = get_krn_netdev(); + HDF_LOGE("%s: start...", __func__); + + (void)netDev; + if (NULL == netdev) { + HDF_LOGE("%s: netdev null!", __func__); + return HDF_FAILURE; + } + HDF_LOGE("%s: change mtu to %d\n", __FUNCTION__, mtu); + + retVal = (int32_t)dhd_netdev_changemtu_wrapper(netdev, mtu); + if (retVal < 0) { + HDF_LOGE("%s: hdf net device chg mtu failed! ret = %d", __func__, retVal); + } + + return retVal; +} + +void hdf_netdev_linkstatuschanged(struct NetDevice *netDev) +{ + HDF_LOGE("%s: start...", __func__); + (void)netDev; +} + +ProcessingResult hdf_netdev_specialethertypeprocess(const struct NetDevice *netDev, NetBuf *buff) +{ + struct EtherHeader *header = NULL; + uint16_t etherType; + const struct Eapol *eapolInstance = NULL; + int ret; + uint16_t protocol; + + HDF_LOGE("%s: start...", __func__); + + if (netDev == NULL || buff == NULL) { + return PROCESSING_ERROR; + } + + header = (struct EtherHeader *)NetBufGetAddress(buff, E_DATA_BUF); + + protocol = (buff->data[12] << 8) | buff->data[13]; + if (protocol != ETHER_TYPE_PAE) { + HDF_LOGE("%s: return PROCESSING_CONTINUE", __func__); + return PROCESSING_CONTINUE; + } + if (netDev->specialProcPriv == NULL) { + HDF_LOGE("%s: return PROCESSING_ERROR", __func__); + return PROCESSING_ERROR; + } + + eapolInstance = EapolGetInstance(); + ret = eapolInstance->eapolOp->writeEapolToQueue(netDev, buff); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: writeEapolToQueue failed", __func__); + NetBufFree(buff); + } + return PROCESSING_COMPLETE; +} + +/***************************************************************************** + net_device上挂接的net_device_ops函数 +**************************************************************************** */ +struct NetDeviceInterFace g_wal_net_dev_ops = +{ + .init = hdf_netdev_init, + .deInit = hdf_netdev_deinit, + .open = hdf_netdev_open, + .stop = hdf_netdev_stop, + .xmit = hdf_netdev_xmit, + .ioctl = hdf_netdev_ioctl, + .setMacAddr = hdf_netdev_setmacaddr, + .getStats = hdf_netdev_getstats, + .setNetIfStatus = hdf_netdev_setnetifstats, + .selectQueue = hdf_netdev_selectqueue, + .netifNotify = hdf_netdev_netifnotify, + .changeMtu = hdf_netdev_changemtu, + .linkStatusChanged = hdf_netdev_linkstatuschanged, + .specialEtherTypeProcess = hdf_netdev_specialethertypeprocess, +}; + +struct NetDeviceInterFace *wal_get_net_dev_ops(void) +{ + return &g_wal_net_dev_ops; +} + +void wal_netif_rx_ni(struct sk_buff *skb) +{ + NetIfRxNi(gp_hdf_netDev, skb); +} + +void wal_netif_rx(struct sk_buff *skb) +{ + NetIfRx(gp_hdf_netDev, skb); +} + +NetDevice *get_netDev(void) +{ + return gp_hdf_netDev; +} + +EXPORT_SYMBOL(get_netDev); +EXPORT_SYMBOL(wal_netif_rx); +EXPORT_SYMBOL(wal_netif_rx_ni); + +// #ifdef CHG_FOR_HDF +EXPORT_SYMBOL(hdf_netdev_open); +EXPORT_SYMBOL(hdf_netdev_stop); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif diff --git a/nxp/drivers/wifi/ap6212/hdfadapter/net_adpater.h b/nxp/drivers/wifi/ap6212/hdfadapter/net_adpater.h new file mode 100644 index 0000000..2b732fd --- /dev/null +++ b/nxp/drivers/wifi/ap6212/hdfadapter/net_adpater.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NET_ADAPTER_H +#define NET_ADAPTER_H + +/* **************************************************************************** + 1 其他头文件包含 +**************************************************************************** */ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/* **************************************************************************** + 2 宏定义 +**************************************************************************** */ + +/* **************************************************************************** + 3 枚举定义 +**************************************************************************** */ + +/* **************************************************************************** + 7 STRUCT定义 +**************************************************************************** */ + +/* **************************************************************************** + 10 函数声明 +**************************************************************************** */ +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif diff --git a/nxp/drivers/wifi/ap6212/modules.builtin b/nxp/drivers/wifi/ap6212/modules.builtin new file mode 100644 index 0000000..e69de29 diff --git a/nxp/drivers/wifi/ap6212/modules.order b/nxp/drivers/wifi/ap6212/modules.order new file mode 100644 index 0000000..e69de29 diff --git a/nxp/drivers/wifi/ap6212/wifi_config.mk b/nxp/drivers/wifi/ap6212/wifi_config.mk new file mode 100644 index 0000000..a130b0a --- /dev/null +++ b/nxp/drivers/wifi/ap6212/wifi_config.mk @@ -0,0 +1,55 @@ +# +# Copyright (c) 2021 Huawei Device Co., Ltd. +# +# This software is licensed under the terms of the GNU General Public +# License version 2, as published by the Free Software Foundation, and +# may be copied, distributed, and modified under those terms. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# +WIFI_CONFIG_PATH := $(shell pwd) +$(warning WIFI_CONFIG_PATH=$(WIFI_CONFIG_PATH)) + +HDF_FRAMEWORKS_INC := \ + -I./ \ + -Idrivers/hdf/framework/ability/sbuf/include \ + -Idrivers/hdf/framework/core/common/include/host \ + -Idrivers/hdf/framework/core/host/include \ + -Idrivers/hdf/framework/core/manager/include \ + -Idrivers/hdf/framework/core/shared/include \ + -Idrivers/hdf/framework/include \ + -Idrivers/hdf/framework/include/config \ + -Idrivers/hdf/framework/include/core \ + -Idrivers/hdf/framework/include/platform \ + -Idrivers/hdf/framework/include/utils \ + -Idrivers/hdf/framework/support/platform/include \ + -Idrivers/hdf/framework/support/platform/include/platform \ + -Idrivers/hdf/framework/utils/include \ + -Idrivers/hdf/khdf/osal/include \ + -Idrivers/hdf/khdf/config/include \ + -Iinclude/hdf \ + -Iinclude/hdf/osal \ + -Iinclude/hdf/utils \ + -Idrivers/hdf/framework/include/ethernet\ + -Idrivers/hdf/framework/include/net\ + -Idrivers/hdf/framework/model/network/common/netdevice\ + -Idrivers/hdf/framework/include/wifi\ + -Idrivers/hdf/framework/model/network/wifi/platform/include \ + -Idrivers/hdf/framework/model/network/wifi/core/components/eapol + + + +HDF_WIFI_FRAMEWORKS_INC := \ + -Idrivers/hdf/framework/model/network/ethernet/include \ + -Idrivers/hdf/framework/model/network/wifi/include + +SECURE_LIB_INC := \ + -I./../../../../../third_party/bounds_checking_function/include + +HDF_WIFI_ADAPTER_INC := \ + -I./../../../../../device/nxp/drivers/wifi/adapter \ + -Idrivers/hdf/khdf/network/include \ No newline at end of file diff --git a/nxp/imx8mm/BUILD.gn b/nxp/imx8mm/BUILD.gn new file mode 100755 index 0000000..eee00f2 --- /dev/null +++ b/nxp/imx8mm/BUILD.gn @@ -0,0 +1,12 @@ +# Copyright (C) 2021 Hisilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + +import("//build/ohos.gni") + +print("imx8mm_group in") +group("imx8mm_group") { + deps = [ + "build:rc_files", + "build/rootfs:init_configs", + "//kernel/linux/build:linux_kernel", + ] +} diff --git a/nxp/imx8mm/bootloader/flash.bin b/nxp/imx8mm/bootloader/flash.bin new file mode 100644 index 0000000..bee860a --- /dev/null +++ b/nxp/imx8mm/bootloader/flash.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9c24b7370b37e2fbde5ae9aa44e4b6c46604f5095e031c13d4bcc935d4f87f8 +size 1073552 diff --git a/nxp/imx8mm/build/BUILD.gn b/nxp/imx8mm/build/BUILD.gn new file mode 100644 index 0000000..a3bcb5e --- /dev/null +++ b/nxp/imx8mm/build/BUILD.gn @@ -0,0 +1,106 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") + +ohos_prebuilt_etc("init.imx8mm.rc") { + source = "rootfs/init.imx8mm.rc" + module_install_dir = "etc/init" + install_images = [ "vendor" ] + part_name = "nxp_products" +} + +ohos_prebuilt_etc("init.imx8mm.usb.rc") { + source = "rootfs/init.imx8mm.usb.rc" + module_install_dir = "etc/init" + install_images = [ "vendor" ] + part_name = "nxp_products" +} + +ohos_prebuilt_etc("ueventd.rc") { + source = "rootfs/ueventd.rc" + install_images = [ "vendor" ] + module_install_dir = "./" + part_name = "nxp_products" +} + +ohos_prebuilt_etc("fstab.imx8mm") { + source = "vendor/etc/fstab.imx8mm" + module_install_dir = "etc" + install_images = [ "vendor" ] + part_name = "nxp_products" +} + +ohos_prebuilt_etc("vb_config_user.ini") { + source = "vendor/etc/vb_config_user.ini" + module_install_dir = "./" + install_images = [ "vendor" ] + part_name = "nxp_products" +} + +ohos_copy("flash.bin") { + sources = [ "//device/nxp/imx8mm/bootloader/flash.bin" ] + outputs = + [ "$root_build_dir/packages/phone/images/flash.bin" ] +} + +ohos_prebuilt_etc("firmware_apsta_bin") { + source = "//device/nxp/imx8mm/firmware/fw_bcm43438a1_apsta.bin" + module_install_dir = "./etc/wifi" + install_images = [ "system" ] + part_name = "nxp_products" +} + +ohos_prebuilt_etc("firmware_p2p_bin") { + source = "//device/nxp/imx8mm/firmware/fw_bcm43438a1_p2p.bin" + module_install_dir = "./etc/wifi" + install_images = [ "system" ] + part_name = "nxp_products" +} + +ohos_prebuilt_etc("firmware_bin") { + source = "//device/nxp/imx8mm/firmware/fw_bcm43438a1.bin" + module_install_dir = "./etc/wifi" + install_images = [ "system" ] + part_name = "nxp_products" +} + +ohos_prebuilt_etc("firmware_a_nvram") { + source = "//device/nxp/imx8mm/firmware/nvram_ap6212a.txt" + module_install_dir = "./etc/wifi" + install_images = [ "system" ] + part_name = "nxp_products" +} + +ohos_prebuilt_etc("firmware_hcd") { + source = "//device/nxp/imx8mm/firmware/bcm43438a1.hcd" + module_install_dir = "./etc/wifi" + install_images = [ "system" ] + part_name = "nxp_products" +} + +group("rc_files") { + deps = [ + ":flash.bin", + ":firmware_apsta_bin", + ":firmware_p2p_bin", + ":firmware_bin", + ":firmware_a_nvram", + ":firmware_hcd", + ":fstab.imx8mm", + ":init.imx8mm.rc", + ":init.imx8mm.usb.rc", + ":ueventd.rc", + ":vb_config_user.ini", + ] +} diff --git a/nxp/imx8mm/build/LICENSE b/nxp/imx8mm/build/LICENSE new file mode 100755 index 0000000..4947287 --- /dev/null +++ b/nxp/imx8mm/build/LICENSE @@ -0,0 +1,177 @@ + + 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 \ No newline at end of file diff --git a/nxp/imx8mm/build/rootfs/BUILD.gn b/nxp/imx8mm/build/rootfs/BUILD.gn new file mode 100755 index 0000000..b9baf2c --- /dev/null +++ b/nxp/imx8mm/build/rootfs/BUILD.gn @@ -0,0 +1,39 @@ +# Copyright (c) 2020 Huawei Device Co., Ltd. +# 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. +import("//build/ohos.gni") + +ohos_prebuilt_etc("init.imx8mm.cfg") { + source = "init.imx8mm.cfg" + install_images = [ "system" ] + part_name = "nxp_products" +} + +ohos_prebuilt_etc("init.imx8mm.usb.cfg") { + source = "init.imx8mm.usb.cfg" + install_images = [ "system" ] + part_name = "nxp_products" +} + +ohos_prebuilt_etc("init.imx8mm.updater.cfg") { + source = "init.imx8mm.updater.cfg" + install_images = [ "updater" ] + part_name = "nxp_products" +} + +group("init_configs") { + deps = [ + ":init.imx8mm.cfg", + ":init.imx8mm.updater.cfg", + ":init.imx8mm.usb.cfg", + ] +} diff --git a/nxp/imx8mm/build/rootfs/init.imx8mm.cfg b/nxp/imx8mm/build/rootfs/init.imx8mm.cfg new file mode 100755 index 0000000..e28c3e3 --- /dev/null +++ b/nxp/imx8mm/build/rootfs/init.imx8mm.cfg @@ -0,0 +1,51 @@ +{ + "import" : [ + "init.${ro.hardware}.usb.cfg" + ], + "jobs" : [{ + "name" : "pre-init", + "cmds" : [ + "write /proc/sys/vm/min_free_kbytes 10240" + ] + }, { + "name" : "init", + "cmds" : [ + "mount debugfs /sys/kernel/debug /sys/kernel/debug mode=755", + "write /sys/kernel/debug/hisi_inno_phy/role peripheral" + ] + }, { + "name" : "fs", + "cmds" : [ + "insmod /vendor/modules/hi_securec.ko", + "insmod /vendor/modules/hi_osal.ko anony=1 mmz_allocator=hisi mmz=anonymous,0,0xA8000000,384M || report_error", + "insmod /vendor/modules/hi_irq.ko", + "insmod /vendor/modules/hi_proc.ko", + "insmod /vendor/modules/sys_config.ko chip=hi3516dv300 sensors=sns0=imx335,sns1=NULL,g_cmos_yuv_flag=0", + "insmod /vendor/modules/hi3516cv500_base.ko", + "insmod /vendor/modules/hi3516cv500_sys.ko", + "insmod /vendor/modules/hi3516cv500_tde.ko", + "insmod /vendor/modules/hi3516cv500_vo_dev.ko", + "insmod /vendor/modules/hifb.ko video=\"hifb:vram0_size:16200\"", + "insmod /vendor/modules/hi3516cv500_hdmi.ko", + "insmod /vendor/modules/hi_mipi_rx.ko" + ] + }, { + "name" : "boot", + "cmds" : [ + "chmod 777 /dev/ttyAMA2", + "chmod 775 /sys/class/rfkill/rfkill0/state", + "chmod 777 /dev/rtkbt_dev", + "chmod 0440 /proc/interrupts", + "chmod 0440 /proc/stat", + "chmod 0640 /dev/xt_qtaguid", + "chmod 0660 /proc/net/xt_qtaguid/ctrl", + "chmod 0440 /proc/net/xt_qtaguid/stats", + "chmod 666 /dev/mali0", + "chown system graphics /dev/mali0", + "chown system graphics /dev/graphics/fb0", + "chmod 666 /dev/ion", + "chown system system /dev/ion" + ] + } + ] +} diff --git a/nxp/imx8mm/build/rootfs/init.imx8mm.rc b/nxp/imx8mm/build/rootfs/init.imx8mm.rc new file mode 100755 index 0000000..6833220 --- /dev/null +++ b/nxp/imx8mm/build/rootfs/init.imx8mm.rc @@ -0,0 +1,80 @@ +import init.${ro.hardware}.usb.rc + +on early-init +# copy from goldfish + write /proc/sys/vm/min_free_kbytes 10240 + +on init + # mount debugfs + mount debugfs /sys/kernel/debug /sys/kernel/debug mode=755 + + # switch USB to peripheral + write /sys/kernel/debug/hisi_inno_phy/role "peripheral" + +on fs + #mount_all /vendor/etc/fstab.Hi3559A + mount_all /vendor/etc/fstab.Hi3516DV300 + swapon_all /vendor/etc/fstab.Hi3516DV300 + + # hos partition + #chown root root /hos + #chmod 777 /hos + #restorecon_recursive /hos + + # insmod hisi ko + insmod /vendor/modules/hi_securec.ko + insmod /vendor/modules/hi_osal.ko anony=1 mmz_allocator=hisi mmz=anonymous,0,0xA8000000,384M || report_error + insmod /vendor/modules/hi_irq.ko + insmod /vendor/modules/hi_proc.ko + + insmod /vendor/modules/sys_config.ko chip=hi3516dv300 sensors=sns0=imx335,sns1=NULL,g_cmos_yuv_flag=0 + insmod /vendor/modules/hi3516cv500_base.ko + insmod /vendor/modules/hi3516cv500_sys.ko + insmod /vendor/modules/hi3516cv500_tde.ko + insmod /vendor/modules/hi3516cv500_vo_dev.ko + insmod /vendor/modules/hifb.ko video="hifb:vram0_size:16200" + + insmod /vendor/modules/hi3516cv500_hdmi.ko + insmod /vendor/modules/hi_mipi_rx.ko + insmod /vendor/modules/hi3516cv500_drm.ko + +on boot + chmod 777 /dev/ttyAMA2 + chmod 775 /sys/class/rfkill/rfkill0/state + chmod 777 /dev/rtkbt_dev + + chmod 0440 /proc/interrupts + chmod 0440 /proc/stat + + chmod 0640 /dev/xt_qtaguid + chmod 0660 /proc/net/xt_qtaguid/ctrl + chmod 0440 /proc/net/xt_qtaguid/stats + chmod 666 /dev/mali0 + chown system graphics /dev/mali0 + chown system graphics /dev/graphics/fb0 + chmod 666 /dev/ion + chown system system /dev/ion + # FIXME temp modify for nonencrypted + class_start main + class_start late_start + + +# zygote need to be started after otapreopt which will be done on post-fs-data +on zygote-start + # zygote is started in common init.rc + # and now we can continue initialize /data/ + + # Create the directories used by the Wireless subsystem + mkdir /data/vendor/wifi 0771 wifi wifi + mkdir /data/vendor/wifi/wpa 0770 wifi wifi + mkdir /data/vendor/wifi/wpa/sockets 0770 wifi wifi + +#on property:sys.boot_completed=1 && property:sys.logbootcomplete=1 +# chmod 0666 /dev/hal_ion_vb_server + + +#service hi_server_msghdr /vendor/bin/server_msghdr +# class main +# user root +# group root system audio graphics +# oneshot diff --git a/nxp/imx8mm/build/rootfs/init.imx8mm.updater.cfg b/nxp/imx8mm/build/rootfs/init.imx8mm.updater.cfg new file mode 100755 index 0000000..8145a6a --- /dev/null +++ b/nxp/imx8mm/build/rootfs/init.imx8mm.updater.cfg @@ -0,0 +1,16 @@ +{ + "jobs" : [ + { + "name" : "init", + "cmds" : [ + "insmod /modules/hi_osal.ko anony=1 mmz_allocator=hisi mmz=anonymous,0,0xA8000000,384M", + "insmod /modules/sys_config.ko chip=hi3516dv300 sensors=sns0=imx335,sns1=NULL,g_cmos_yuv_flag=0", + "insmod /modules/hi3516cv500_base.ko", + "insmod /modules/hi3516cv500_sys.ko", + "insmod /modules/hi3516cv500_vo_dev.ko", + "insmod /modules/hifb.ko video=\"hifb:vram0_size:16200\"", + "insmod /modules/hi3516cv500_hdmi.ko" + ] + } + ] +} diff --git a/nxp/imx8mm/build/rootfs/init.imx8mm.usb.cfg b/nxp/imx8mm/build/rootfs/init.imx8mm.usb.cfg new file mode 100755 index 0000000..a6df325 --- /dev/null +++ b/nxp/imx8mm/build/rootfs/init.imx8mm.usb.cfg @@ -0,0 +1,51 @@ +{ + "jobs" : [{ + "name" : "boot", + "cmds" : [ + "mkdir /dev/usb-ffs 0770 shell shell", + "mkdir /dev/usb-ffs/hdc 0770 shell shell", + "mount configfs none /config", + "mkdir /config/usb_gadget/g1 0770 shell shell", + "write /config/usb_gadget/g1/idVendor 0x12D1", + "write /config/usb_gadget/g1/idProduct 0x5000", + "write /config/usb_gadget/g1/os_desc/use 1", + "write /config/usb_gadget/g1/bcdDevice 0x0223", + "write /config/usb_gadget/g1/bcdUSB 0x0200", + "mkdir /config/usb_gadget/g1/strings/0x409 0770", + "copy /sys/block/mmcblk0/device/cid /config/usb_gadget/g1/strings/0x409/serialnumber", + "write /config/usb_gadget/g1/strings/0x409/manufacturer HISILICON", + "write /config/usb_gadget/g1/strings/0x409/product \"HDC Device\"", + "mkdir /config/usb_gadget/g1/functions/ffs.hdc", + "mkdir /config/usb_gadget/g1/configs/b.1 0770 shell shell", + "mkdir /config/usb_gadget/g1/configs/b.1/strings/0x409 0770 shell shell", + "write /config/usb_gadget/g1/os_desc/b_vendor_code 0x1", + "write /config/usb_gadget/g1/os_desc/qw_sign MSFT100", + "write /config/usb_gadget/g1/configs/b.1/MaxPower 500", + "symlink /config/usb_gadget/g1/configs/b.1 /config/usb_gadget/g1/os_desc/b.1", + "mount functionfs hdc /dev/usb-ffs/hdc uid=2000,gid=2000", + "setparam sys.usb.configfs 1", + "setparam sys.usb.controller 100e0000.hidwc3_0" + ] + }, { + "name" : "param:sys.usb.config=none && param:sys.usb.configfs=1", + "condition" : "sys.usb.config=none && sys.usb.configfs=1", + "cmds" : [ + "write /config/usb_gadget/g1/os_desc/use 0", + "setparam sys.usb.ffs.ready 0" + ] + }, { + "name" : "param:init.svc.hdcd=stopped", + "condition" : "init.svc.hdcd=stopped", + "cmds" : [ + "setparam sys.usb.ffs.ready 0" + ] + }, { + "name" : "param:sys.usb.config=hdc && param:sys.usb.configfs=1", + "condition" : "sys.usb.config=hdc && sys.usb.configfs=1", + "cmds" : [ + "write /config/usb_gadget/g1/idProduct 0x5000", + "write /config/usb_gadget/g1/os_desc/use 1" + ] + } + ] +} diff --git a/nxp/imx8mm/build/rootfs/init.imx8mm.usb.rc b/nxp/imx8mm/build/rootfs/init.imx8mm.usb.rc new file mode 100644 index 0000000..cf0868b --- /dev/null +++ b/nxp/imx8mm/build/rootfs/init.imx8mm.usb.rc @@ -0,0 +1,35 @@ +on boot + mkdir /dev/usb-ffs 0770 shell shell + mkdir /dev/usb-ffs/hdc 0770 shell shell + mount configfs none /config + mkdir /config/usb_gadget/g1 0770 shell shell + write /config/usb_gadget/g1/idVendor 0x12D1 + write /config/usb_gadget/g1/idProduct 0x5000 + write /config/usb_gadget/g1/os_desc/use 1 + write /config/usb_gadget/g1/bcdDevice 0x0223 + write /config/usb_gadget/g1/bcdUSB 0x0200 + mkdir /config/usb_gadget/g1/strings/0x409 0770 + copy /sys/block/mmcblk0/device/cid /config/usb_gadget/g1/strings/0x409/serialnumber + write /config/usb_gadget/g1/strings/0x409/manufacturer "HISILICON" + write /config/usb_gadget/g1/strings/0x409/product "HDC Device" + mkdir /config/usb_gadget/g1/functions/ffs.hdc + mkdir /config/usb_gadget/g1/configs/b.1 0770 shell shell + mkdir /config/usb_gadget/g1/configs/b.1/strings/0x409 0770 shell shell + write /config/usb_gadget/g1/os_desc/b_vendor_code 0x1 + write /config/usb_gadget/g1/os_desc/qw_sign "MSFT100" + write /config/usb_gadget/g1/configs/b.1/MaxPower 500 + symlink /config/usb_gadget/g1/configs/b.1 /config/usb_gadget/g1/os_desc/b.1 + mount functionfs hdc /dev/usb-ffs/hdc uid=2000,gid=2000 + setprop sys.usb.configfs 1 + setprop sys.usb.controller "100e0000.hidwc3_0" + +on property:sys.usb.config=none && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/os_desc/use 0 + setprop sys.usb.ffs.ready 0 + +on property:init.svc.hdcd=stopped + setprop sys.usb.ffs.ready 0 + +on property:sys.usb.config=hdc,adb && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/idProduct 0x5000 + write /config/usb_gadget/g1/os_desc/use 1 diff --git a/nxp/imx8mm/build/rootfs/ueventd.imx8mm.rc b/nxp/imx8mm/build/rootfs/ueventd.imx8mm.rc new file mode 100755 index 0000000..acf35f1 --- /dev/null +++ b/nxp/imx8mm/build/rootfs/ueventd.imx8mm.rc @@ -0,0 +1,44 @@ +/dev/jpeg 0666 system graphics +/dev/vinput 0660 system input +/dev/mmz_userdev 0644 system audio +/dev/graphics/fb* 0660 system graphics +/dev/mem 0660 system audio +/dev/video* 0660 system camera +/dev/ion 0666 system system +/dev/mali* 0666 system graphics +#for Bluetooth USB driver +/dev/btusb0 0660 bluetooth bluetooth +/dev/uhid 0660 bluetooth bluetooth +/dev/bt_usb* 0660 bluetooth bluetooth +/dev/tc_ns_client 0660 system audio +/dev/rtk_btusb 0660 bluetooth net_bt_stack +/dev/sil9293 0660 system audio +/dev/stpbt 0660 bluetooth radio +#for hisilicon dev +/dev/avs 0660 system audio +/dev/gdc 0660 system audio +/dev/hdmi 0660 system audio +/dev/hi_mipi 0660 system audio +/dev/hi_mipi_tx 0660 system audio +/dev/hi_tde 0644 system graphics +/dev/isp_dev 0660 system camera +/dev/match 0660 system audio +/dev/photo 0660 system audio +/dev/rect 0660 system audio +/dev/rgn 0660 system audio +/dev/sys 0660 system audio +/dev/vb 0666 system audio +/dev/vdec 0666 system audio +/dev/venc 0666 system audio +/dev/vi 0660 system audio +/dev/vo 0660 system audio +/dev/vpss 0660 system audio +/dev/i2c-0 0660 system camera +/dev/i2c-1 0660 system camera +/dev/i2c-2 0660 system camera +/dev/i2c-3 0660 system camera +/dev/i2c-4 0660 system camera +/dev/i2c-5 0660 system camera +/dev/i2c-6 0660 system camera +/dev/i2c-7 0660 system camera +/dev/vgs 0666 system audio diff --git a/nxp/imx8mm/build/rootfs/ueventd.rc b/nxp/imx8mm/build/rootfs/ueventd.rc new file mode 100755 index 0000000..127d7a7 --- /dev/null +++ b/nxp/imx8mm/build/rootfs/ueventd.rc @@ -0,0 +1,49 @@ +subsystem functionfs + devname uevent_devpath + dirname /dev/functionfs + +/dev/jpeg 0666 system graphics +/dev/vinput 0660 system input +/dev/mmz_userdev 0644 system audio +/dev/graphics/fb* 0660 system graphics +/dev/functionfs/f_g* 0660 system functionfs +/dev/mem 0660 system audio +/dev/video* 0660 system camera +/dev/ion 0666 system system +/dev/mali* 0666 system graphics +#for Bluetooth USB driver +/dev/btusb0 0660 bluetooth bluetooth +/dev/uhid 0660 bluetooth bluetooth +/dev/bt_usb* 0660 bluetooth bluetooth +/dev/tc_ns_client 0660 system audio +/dev/rtk_btusb 0660 bluetooth net_bt_stack +/dev/sil9293 0660 system audio +/dev/stpbt 0660 bluetooth radio +#for hisilicon dev +/dev/avs 0660 system audio +/dev/gdc 0660 system audio +/dev/hdmi 0660 system audio +/dev/hi_mipi 0660 system audio +/dev/hi_mipi_tx 0660 system audio +/dev/hi_tde 0644 system graphics +/dev/isp_dev 0660 system camera +/dev/match 0660 system audio +/dev/photo 0660 system audio +/dev/rect 0660 system audio +/dev/rgn 0660 system audio +/dev/sys 0660 system audio +/dev/vb 0666 system audio +/dev/vdec 0666 system audio +/dev/venc 0666 system audio +/dev/vi 0660 system audio +/dev/vo 0660 system audio +/dev/vpss 0660 system audio +/dev/i2c-0 0660 system camera +/dev/i2c-1 0660 system camera +/dev/i2c-2 0660 system camera +/dev/i2c-3 0660 system camera +/dev/i2c-4 0660 system camera +/dev/i2c-5 0660 system camera +/dev/i2c-6 0660 system camera +/dev/i2c-7 0660 system camera +/dev/vgs 0666 system audio diff --git a/nxp/imx8mm/build/sepolicy/file.te b/nxp/imx8mm/build/sepolicy/file.te new file mode 100755 index 0000000..35f787d --- /dev/null +++ b/nxp/imx8mm/build/sepolicy/file.te @@ -0,0 +1 @@ +type hos_file, file_type; diff --git a/nxp/imx8mm/build/sepolicy/file_contexts b/nxp/imx8mm/build/sepolicy/file_contexts new file mode 100755 index 0000000..64ba5e1 --- /dev/null +++ b/nxp/imx8mm/build/sepolicy/file_contexts @@ -0,0 +1,2 @@ + +/hos(/.*)? u:object_r:hos_file:s0 diff --git a/nxp/imx8mm/build/sepolicy/hos.te b/nxp/imx8mm/build/sepolicy/hos.te new file mode 100755 index 0000000..f6eb0bc --- /dev/null +++ b/nxp/imx8mm/build/sepolicy/hos.te @@ -0,0 +1 @@ +allow rootfs labeledfs:filesystem { associate }; diff --git a/nxp/imx8mm/build/updater_config/BOARD.list b/nxp/imx8mm/build/updater_config/BOARD.list new file mode 100755 index 0000000..7d680ab --- /dev/null +++ b/nxp/imx8mm/build/updater_config/BOARD.list @@ -0,0 +1,3 @@ +HI3516 +HI3518 +HI3559 \ No newline at end of file diff --git a/nxp/imx8mm/build/updater_config/VERSION.mbn b/nxp/imx8mm/build/updater_config/VERSION.mbn new file mode 100755 index 0000000..edb5612 --- /dev/null +++ b/nxp/imx8mm/build/updater_config/VERSION.mbn @@ -0,0 +1 @@ +Hi3516DV300-eng 10 QP1A.190711.020 diff --git a/nxp/imx8mm/build/updater_config/rsa_private_key2048.pem b/nxp/imx8mm/build/updater_config/rsa_private_key2048.pem new file mode 100755 index 0000000..b44ddc3 --- /dev/null +++ b/nxp/imx8mm/build/updater_config/rsa_private_key2048.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA49SUn9WClk/whGbVLVc8ol4FiSt/jw5EZ8T9PVFiYirAf4Cm +R0/bBZhlGiHtfFSOeHwednGhdbDVPb9dZl/a9SwhuCPhhQVICne8RvqzgJFsgpO5 +CBxW1xspM/HDuz9c5gOLnu1+df3EASsv56xh6hH1LOe5QkGEA5QPZ9WoRlOJaP5T +ndZ+BEih4IPgQswRlCRFpx/Idiv8gi4bg9ZxmJ8CVMusSPHGm64dvlkn+LSZ9KMh +vhWFSZAFtcHK9hz55wQwMrhN+LCjVZA+MPUvaU1L+cT0ZDh+qxH0MQuL1wbgkd1b +HfYCUu+8D2q0PLfk4d6ncZRvjiChalX5g2mVLQIDAQABAoIBACIhhKp1N/0AuM19 +Ak6qlQDWCQpFo/RwdLr+/dkjyhNeyDvRsBda1Tr/W5YQox1PJZDTN1UTLNcOyMNZ +WcqubYTxOZP2fCCLbAF1cpVHlYCbSKA/NScL586N2RxZCbORiH9E5LPIbHuMqsJq +D+ErJ/gC/LHffRd57ScEFVK+5VizfrCddBsPbbF2aCoQZyiDX4DBIQ+kMUgNChN7 +I7J5yA8DrTjzEATArOlnKUvnlVx/jKT3ncCYQujxwQlzJWDbaSgon5ZhjBazSUiC +eHPbE+bCvcD90pWddUByeS885eMDIOhErJFS+lYYdI+bT3T5rILzK8wR2CupMhkX +a9RYuZkCgYEA9lGoxWyWIFK3ymeT6DOhqK6Cr7MJiYgAvgk+fA3dDVsGuEM6Xy/O +wwt915cZvKzcb018AmeSVwYvy7l3EuYDKXP/YzntV7OLuH9Fu3zuoZ4U3VOHtKLD +VOHeWO/dg/BB96mP2xxltwv64ZT3gPf9MIpDmgVnL4QREUG4K6T/XEsCgYEA7Mjl +8AK/Hu9cIPAwB0NNCU3ptnlznu42c+lj1SHfCtYV9me14nVEIynevyniZ3y8jMi6 +5Ozo/Rt26W+WuxZj6vPH2FBtB3kMgxDPDGunphl6wKJ+3RqvBrErAu9AW6e/H5NP +gxU8V8PVO+Qo3CwIhjnjkobi7nBXe6gU1iqkeWcCgYAubqJD5P4/xZgDvZayFNmK +dKsJ99P6avrI1/FBbVOYKuqPXYzpWJe/SLFGLKObX3KGQLL5uRBq+y2TV7jMhTNf +YxBnYgoNmDjkZIl+mERbjvMb7Z0NPglYPOOvHDhDoMyupPYLNcUuxkFauLwXQagm +uEmaBR64ZErbV+ohwA6rFQKBgQC9P6RnvAo9E1ozCUWZyHSd5yPQsCl08TecVQFx +q2y1IH7VPfblVIxs/l4Fs9g8ljms3BJkPeXJxlW4JXP3e+HIO6eSgFVkD5+scZbK +epC39M1jgXycA2O4mYmjAs4Rc3USK471Wdes3dxjzevKbXcysLnutthRcoC5WJGu +ys5CKQKBgQDpYc/LxUR4K5k55kQyPofkyIlVK/De3VwsD7eCeRDb1jfcF52Xuuxg +Pm6RlIvVRy7RsrG7kKqWCiVAFauQQswW6DDBbjmrFd6CrruEAqwwgbCHZjE5Dy+0 +ZKsKfkm/bymEiq7ATwzvWfuU3T3R0O9+S1RbTNYo+D3N2soTfPnXyw== +-----END RSA PRIVATE KEY----- diff --git a/nxp/imx8mm/build/updater_config/signing_cert.crt b/nxp/imx8mm/build/updater_config/signing_cert.crt new file mode 100755 index 0000000..eca5d72 --- /dev/null +++ b/nxp/imx8mm/build/updater_config/signing_cert.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDazCCAlOgAwIBAgIUDbbfN0ry6xlKrFyylM9asKzjANYwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTAyMjUxMjA2MTNaFw0yMjAy +MjUxMjA2MTNaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDj1JSf1YKWT/CEZtUtVzyiXgWJK3+PDkRnxP09UWJi +KsB/gKZHT9sFmGUaIe18VI54fB52caF1sNU9v11mX9r1LCG4I+GFBUgKd7xG+rOA +kWyCk7kIHFbXGykz8cO7P1zmA4ue7X51/cQBKy/nrGHqEfUs57lCQYQDlA9n1ahG +U4lo/lOd1n4ESKHgg+BCzBGUJEWnH8h2K/yCLhuD1nGYnwJUy6xI8cabrh2+WSf4 +tJn0oyG+FYVJkAW1wcr2HPnnBDAyuE34sKNVkD4w9S9pTUv5xPRkOH6rEfQxC4vX +BuCR3Vsd9gJS77wParQ8t+Th3qdxlG+OIKFqVfmDaZUtAgMBAAGjUzBRMB0GA1Ud +DgQWBBQR55YSUMEzkyqHQKGQ51bBcqbvazAfBgNVHSMEGDAWgBQR55YSUMEzkyqH +QKGQ51bBcqbvazAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBy +30XquNfGVCOlXBaJJ/gyl5TP0nFZ9iQ9P0Tk6Ya6tN+Nh4lqA4uG1rUqPrQCd0+N +DUnJlwdto8E2fznfJQ0ojkQdlPv3zkqW25QSYTb9wegQ6CnWq2ANnvoXPcSebHXE +yXcEXybgaWkBg3h8VHcwVns5psXSDsprisFGyETBwMIqM15Z81bEpejKz2viW5ow ++c3ToGs8VhymfG3Pbls3nFeFYSD/A4sOOzM+O/ioG4YI6cGfSBztrAShtdvadHL6 +Cbp6X36ZSveGOkfS/Yrq4z/yE2V0kCJXBMo+9SrhxUrwACjMDIdE5YLlw9qpkLQV +t5MJhDWJe6tCRSBSmoA4 +-----END CERTIFICATE----- diff --git a/nxp/imx8mm/build/vendor/etc/fstab.imx8mm b/nxp/imx8mm/build/vendor/etc/fstab.imx8mm new file mode 100755 index 0000000..e3bcf06 --- /dev/null +++ b/nxp/imx8mm/build/vendor/etc/fstab.imx8mm @@ -0,0 +1,3 @@ +# fstab file. +# +/dev/block/platform/soc/10100000.himci.eMMC/by-name/userdata /data ext4 nosuid,nodev,noatime,barrier=1,data=ordered,noauto_da_alloc wait,reservedsize=104857600 diff --git a/nxp/imx8mm/build/vendor/etc/fstab.updater b/nxp/imx8mm/build/vendor/etc/fstab.updater new file mode 100755 index 0000000..24386a1 --- /dev/null +++ b/nxp/imx8mm/build/vendor/etc/fstab.updater @@ -0,0 +1,6 @@ +# +/dev/block/platform/soc/10100000.himci.eMMC/by-name/system /system ext4 ro,barrier=1 wait +/dev/block/platform/soc/10100000.himci.eMMC/by-name/vendor /vendor ext4 ro,barrier=1 wait +/dev/block/platform/soc/10100000.himci.eMMC/by-name/userdata /data ext4 nosuid,nodev,noatime,barrier=1,data=ordered,noauto_da_alloc wait,reservedsize=104857600 +/dev/block/platform/soc/10100000.himci.eMMC/by-name/misc /misc none none wait +/dev/block/platform/soc/100f0000.himci.SD/mmcblk1p1 /sdcard ext4 rw wait diff --git a/nxp/imx8mm/build/vendor/etc/vb_config_user.ini b/nxp/imx8mm/build/vendor/etc/vb_config_user.ini new file mode 100755 index 0000000..0d3fce9 --- /dev/null +++ b/nxp/imx8mm/build/vendor/etc/vb_config_user.ini @@ -0,0 +1,24 @@ +<-Creator/HeapName : String Name, max length 64 chars + +<-PixelWidth/PixelHigh/BlockNum : DEC numbers chars,BlockNum >= 1, Pixelformate : 90P~2160P,width:high=16:9 + +<-PixelFormate : [YVU_SEMIPLANAR_420] [YVU_SEMIPLANAR_422] [RGB_BAYER_16BPP] + +<-BitWidth : [DATA_BITWIDTH_8] [DATA_BITWIDTH_10] + +<-CompressMode : [COMPRESS_MODE_NONE] [COMPRESS_MODE_SEG] + +<-MapType : [NONE] [NOCACHE] [CACHE] + +<-!!!Note : This config file max file size < 10K bytes, Line < 256 bytes word < 64 bytes + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +Creator PixelWidth PixelHigh PixelFormate BitWidth CompressMode MapType BlockNum HeapName +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +Public 3840 2160 YVU_SEMIPLANAR_420 DATA_BITWIDTH_10 COMPRESS_MODE_SEG NONE 10 HeapVI +Public 3840 2160 RGB_BAYER_16BPP DATA_BITWIDTH_8 COMPRESS_MODE_NONE NONE 4 HeapCamera +OMX_VCODEC 320 180 YVU_SEMIPLANAR_420 DATA_BITWIDTH_8 COMPRESS_MODE_NONE NONE 190 omx +OMX_VCODEC 640 360 YVU_SEMIPLANAR_420 DATA_BITWIDTH_8 COMPRESS_MODE_NONE NONE 110 omx +OMX_VCODEC 1280 720 YVU_SEMIPLANAR_420 DATA_BITWIDTH_8 COMPRESS_MODE_NONE NONE 16 omx +OMX_VCODEC 1920 1080 YVU_SEMIPLANAR_420 DATA_BITWIDTH_8 COMPRESS_MODE_NONE NONE 14 omx +OMX_VCODEC 4096 2304 YVU_SEMIPLANAR_420 DATA_BITWIDTH_8 COMPRESS_MODE_NONE NONE 19 omx \ No newline at end of file diff --git a/nxp/imx8mm/camera/BUILD.gn b/nxp/imx8mm/camera/BUILD.gn new file mode 100755 index 0000000..f0d34ae --- /dev/null +++ b/nxp/imx8mm/camera/BUILD.gn @@ -0,0 +1,100 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. +import("//build/ohos.gni") +import("//drivers/adapter/uhdf2/uhdf.gni") +import("//drivers/peripheral/camera/hal/camera.gni") + +action("build_camera_host_config") { + script = "$hdf_framework_path/tools/hc-gen/build_hcs.py" + sources = [ rebase_path( + "$camera_product_name_path/hdf_config/uhdf/camera/hdi_impl/camera_host_config.hcs") ] + outputs = [ "$target_gen_dir/config/hdi_impl/camera_host_config.hcb" ] + args = [ + "-o", + rebase_path(outputs[0]), + sources[0], + ] +} + +ohos_prebuilt_etc("camera_host_config.hcb") { + deps = [ ":build_camera_host_config" ] + hcs_outputs = get_target_outputs(":build_camera_host_config") + source = hcs_outputs[0] + relative_install_dir = "hdfconfig" + subsystem_name = "hdf" + part_name = "hdf" +} + +ohos_prebuilt_etc("config.c") { + source = + "$camera_path/pipeline_core/pipeline_impl/src/strategy/config/config.c" + exec_script( + "//drivers/framework/tools/hc-gen/build_hcs.py", + [ + "-o", + rebase_path( + "$camera_path/pipeline_core/pipeline_impl/src/strategy/config/config.c"), + "-t", + rebase_path( + "$camera_product_name_path/hdf_config/uhdf/camera/pipeline_core/config.hcs"), + ], + "") +} + +ohos_prebuilt_etc("params.c") { + source = + "$camera_path/pipeline_core/pipeline_impl/src/strategy/config/params.c" + exec_script( + "//drivers/framework/tools/hc-gen/build_hcs.py", + [ + "-o", + rebase_path( + "$camera_path/pipeline_core/pipeline_impl/src/strategy/config/params.c"), + "-t", + rebase_path( + "$camera_product_name_path/hdf_config/uhdf/camera/pipeline_core/params.hcs"), + ], + "") +} + +action("build_ipp_algo_config") { + script = "$hdf_framework_path/tools/hc-gen/build_hcs.py" + sources = [ rebase_path( + "$camera_product_name_path/hdf_config/uhdf/camera/pipeline_core/ipp_algo_config.hcs") ] + outputs = [ "$target_gen_dir/pipeline_core/ipp_algo_config.hcb" ] + args = [ + "-o", + rebase_path(outputs[0]), + sources[0], + ] +} + +ohos_prebuilt_etc("ipp_algo_config.hcb") { + deps = [ ":build_ipp_algo_config" ] + hcs_outputs = get_target_outputs(":build_ipp_algo_config") + source = hcs_outputs[0] + relative_install_dir = "hdfconfig" + subsystem_name = "hdf" + part_name = "hdf" +} + +config("example_config") { + visibility = [ ":*" ] + + cflags = [ + "-Wno-error", + "-Wno-unused-function", + "-Wno-unused-parameter", + ] +} + +group("chipset_build") { + public_deps = [ + ":camera_host_config.hcb", + ":config.c", + ":ipp_algo_config.hcb", + ":params.c", + "$camera_device_name_path/camera/src/pipeline_core:camera_ipp_algo_example", + "//drivers/peripheral/camera/hal/adapter/platform/v4l2/src/driver_adapter:camera_v4l2_adapter", + "//drivers/peripheral/camera/hal/adapter/platform/v4l2/src/driver_adapter/main_test:v4l2_main", + ] +} diff --git a/nxp/imx8mm/camera/camera_demo/project_camera_demo.h b/nxp/imx8mm/camera/camera_demo/project_camera_demo.h new file mode 100755 index 0000000..d53b45f --- /dev/null +++ b/nxp/imx8mm/camera/camera_demo/project_camera_demo.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef HOS_CAMERA_PROJET_CAMERA_DEMO_H +#define HOS_CAMERA_PROJET_CAMERA_DEMO_H + +namespace OHOS::Camera { +#define CAMERA_PREVIEW_WIDTH 640 +#define CAMERA_PREVIEW_HEIGHT 480 +#define CAMERA_CAPTURE_WIDTH 640 +#define CAMERA_CAPTURE_HEIGHT 480 +#define CAMERA_VIDEO_WIDTH 640 +#define CAMERA_VIDEO_HEIGHT 480 + +#define CAMERA_CAPTURE_ENCODE_TYPE ENCODE_TYPE_JPEG +#define CAMERA_VIDEO_ENCODE_TYPE ENCODE_TYPE_H264 + +#define CAMERA_FORMAT PIXEL_FMT_RGBA_8888 +} // namespace OHOS::Camera +#endif diff --git a/nxp/imx8mm/camera/include/device_manager/mx6s_csi.h b/nxp/imx8mm/camera/include/device_manager/mx6s_csi.h new file mode 100755 index 0000000..79abfbc --- /dev/null +++ b/nxp/imx8mm/camera/include/device_manager/mx6s_csi.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef HOS_CAMERA_BM2835_H +#define HOS_CAMERA_BM2835_H + +#include "isensor.h" +#include "create_sensor_factory.h" +#include "device_manager_adapter.h" + +namespace OHOS::Camera { +class Mx6s : public ISensor { + DECLARE_SENSOR(Mx6s) +public: + Mx6s(); + virtual ~Mx6s(); + void InitSensitivityRange(CameraStandard::CameraMetadata& camera_meta_data); + void InitAwbModes(CameraStandard::CameraMetadata& camera_meta_data); + void InitCompensationRange(CameraStandard::CameraMetadata& camera_meta_data); + void InitFpsTarget(CameraStandard::CameraMetadata& camera_meta_data); + void InitAvailableModes(CameraStandard::CameraMetadata& camera_meta_data); + void InitAntiBandingModes(CameraStandard::CameraMetadata& camera_meta_data); + void InitPhysicalSize(CameraStandard::CameraMetadata& camera_meta_data); + void Init(CameraStandard::CameraMetadata& camera_meta_data); +}; +} // namespace OHOS::Camera +#endif diff --git a/nxp/imx8mm/camera/include/device_manager/project_hardware.h b/nxp/imx8mm/camera/include/device_manager/project_hardware.h new file mode 100755 index 0000000..0001f75 --- /dev/null +++ b/nxp/imx8mm/camera/include/device_manager/project_hardware.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef HOS_CAMERA_PROJET_HARDWARE_H +#define HOS_CAMERA_PROJET_HARDWARE_H + +namespace OHOS::Camera { +std::vector hardware = { + {CAMERA_FIRST, DM_M_SENSOR, DM_C_SENSOR, (std::string) "mx6s-csi"}, + {CAMERA_FIRST, DM_M_ISP, DM_C_ISP, (std::string) "isp"}, + {CAMERA_FIRST, DM_M_FLASH, DM_C_FLASH, (std::string) "flash"}, + {CAMERA_THIRD, DM_M_SENSOR, DM_C_SENSOR, (std::string) "uvcvideo"}, + {CAMERA_THIRD, DM_M_ISP, DM_C_ISP, (std::string) "isp"}, + {CAMERA_THIRD, DM_M_FLASH, DM_C_FLASH, (std::string) "flash"} +}; +} // namespace OHOS::Camera +#endif diff --git a/nxp/imx8mm/camera/product.gni b/nxp/imx8mm/camera/product.gni new file mode 100755 index 0000000..c493669 --- /dev/null +++ b/nxp/imx8mm/camera/product.gni @@ -0,0 +1,31 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. +import("//build/ohos.gni") +if (!defined(defines)) { + defines = [] +} + +camera_product_name_path = + "//vendor/nxp/imx8mm" +camera_device_name_path = + "//device/nxp/imx8mm" +is_support_v4l2 = true +if (is_support_v4l2) { + is_support_mpi = false + defines += [ "SUPPORT_V4L2" ] + chipset_build_deps = "$camera_device_name_path/camera/:chipset_build" + camera_device_manager_deps = + "$camera_device_name_path/camera/src/device_manager:camera_device_manager" + camera_pipeline_core_deps = + "$camera_device_name_path/camera/src/pipeline_core:camera_pipeline_core" +} diff --git a/nxp/imx8mm/camera/src/device_manager/BUILD.gn b/nxp/imx8mm/camera/src/device_manager/BUILD.gn new file mode 100755 index 0000000..ce2e3f0 --- /dev/null +++ b/nxp/imx8mm/camera/src/device_manager/BUILD.gn @@ -0,0 +1,80 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. +import("//build/ohos.gni") +import("//drivers/peripheral/camera/hal/camera.gni") + +config("device_manager_config") { + visibility = [ ":*" ] + + cflags_cc = [ + "-Wall", + "-Wextra", + "-Werror", + "-Wno-error", + "-DGST_DISABLE_DEPRECATED", + "-DHAVE_CONFIG_H", + "-DCOLORSPACE=\"videoconvert\"", + "-fno-strict-aliasing", + "-Wno-sign-compare", + "-Wno-builtin-requires-header", + "-Wno-unused-variable", + "-Wno-unused-label", + "-Wno-implicit-function-declaration", + "-Wno-format", + "-Wno-int-conversion", + "-Wno-unused-function", + "-Wno-thread-safety-attributes", + "-Wno-inconsistent-missing-override", + "-fno-rtti", + "-fno-exceptions", + "-ffunction-sections", + "-fdata-sections", + ] +} + +ohos_shared_library("camera_device_manager") { + sources = [ + "$camera_device_name_path/camera/src/device_manager/mx6s_csi.cpp", + "$camera_path/adapter/platform/v4l2/src/device_manager/enumerator_manager.cpp", + "$camera_path/adapter/platform/v4l2/src/device_manager/flash_controller.cpp", + "$camera_path/adapter/platform/v4l2/src/device_manager/flash_manager.cpp", + "$camera_path/adapter/platform/v4l2/src/device_manager/idevice_manager.cpp", + "$camera_path/adapter/platform/v4l2/src/device_manager/isp_controller.cpp", + "$camera_path/adapter/platform/v4l2/src/device_manager/isp_manager.cpp", + "$camera_path/adapter/platform/v4l2/src/device_manager/sensor_controller.cpp", + "$camera_path/adapter/platform/v4l2/src/device_manager/sensor_manager.cpp", + "$camera_path/adapter/platform/v4l2/src/device_manager/v4l2_device_manager.cpp", + "$camera_path/device_manager/src/icontroller.cpp", + "$camera_path/device_manager/src/imanager.cpp", + "$camera_path/device_manager/src/isensor.cpp", + ] + + include_dirs = [ + "//base/hiviewdfx/interfaces/innerkits/libhilog/include", + "$camera_path/include", + "$camera_path/utils/event", + "$camera_path/device_manager/include", + "$camera_device_name_path/camera/include/device_manager", + "$camera_path/adapter/platform/v4l2/src/device_manager/include", + "$camera_path/adapter/platform/v4l2/src/driver_adapter/include/", + "//utils/native/base/include", + "//drivers/framework/include/utils", + "//drivers/adapter/uhdf2/osal/include", + "//foundation/multimedia/camera_standard/frameworks/innerkitsimpl/metadata/include", + ] + + deps = [ + "$camera_path/adapter/platform/v4l2/src/driver_adapter:camera_v4l2_adapter", + "//foundation/multimedia/camera_standard/frameworks/innerkitsimpl/metadata:metadata", + "//utils/native/base:utils", + ] + + if (is_standard_system) { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } else { + external_deps = [ "hilog:libhilog" ] + } + + public_configs = [ ":device_manager_config" ] + subsystem_name = "hdf" + part_name = "hdf" +} diff --git a/nxp/imx8mm/camera/src/device_manager/mx6s_csi.cpp b/nxp/imx8mm/camera/src/device_manager/mx6s_csi.cpp new file mode 100755 index 0000000..ce40d4e --- /dev/null +++ b/nxp/imx8mm/camera/src/device_manager/mx6s_csi.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "mx6s_csi.h" +#include + +namespace OHOS::Camera { +IMPLEMENT_SENSOR(Mx6s) +Mx6s::Mx6s() : ISensor("mx6s-csi") {} + +Mx6s::~Mx6s() {} +void Mx6s::InitPhysicalSize(CameraStandard::CameraMetadata& camera_meta_data) +{ + ISensor::InitPhysicalSize(camera_meta_data); +} +void Mx6s::InitAntiBandingModes(CameraStandard::CameraMetadata& camera_meta_data) +{ + ISensor::InitAntiBandingModes(camera_meta_data); +} +void Mx6s::InitAvailableModes(CameraStandard::CameraMetadata& camera_meta_data) +{ + ISensor::InitAvailableModes(camera_meta_data); +} +void Mx6s::InitFpsTarget(CameraStandard::CameraMetadata& camera_meta_data) +{ + ISensor::InitFpsTarget(camera_meta_data); +} +void Mx6s::InitCompensationRange(CameraStandard::CameraMetadata& camera_meta_data) +{ + ISensor::InitCompensationRange(camera_meta_data); +} + +void Mx6s::InitAwbModes(CameraStandard::CameraMetadata& camera_meta_data) +{ + ISensor::InitAwbModes(camera_meta_data); +} + +void Mx6s::InitSensitivityRange(CameraStandard::CameraMetadata& camera_meta_data) +{ + ISensor::InitSensitivityRange(camera_meta_data); +} + +void Mx6s::Init(CameraStandard::CameraMetadata& camera_metaData) +{ + InitPhysicalSize(camera_metaData); + InitAntiBandingModes(camera_metaData); + InitAvailableModes(camera_metaData); + InitFpsTarget(camera_metaData); + InitCompensationRange(camera_metaData); + + const camera_rational_t aeCompensationStep[] = {{0, 1}}; + camera_metaData.addEntry(OHOS_CONTROL_AE_COMPENSATION_STEP, aeCompensationStep, 1); + + InitAwbModes(camera_metaData); + InitSensitivityRange(camera_metaData); + + uint8_t faceDetectMode = OHOS_CAMERA_FACE_DETECT_MODE_OFF; + camera_metaData.addEntry(OHOS_STATISTICS_FACE_DETECT_MODE, &faceDetectMode, 1); +} +} // namespace OHOS::Camera diff --git a/nxp/imx8mm/camera/src/driver_adapter/main_test/project_v4l2_main.h b/nxp/imx8mm/camera/src/driver_adapter/main_test/project_v4l2_main.h new file mode 100755 index 0000000..d9af200 --- /dev/null +++ b/nxp/imx8mm/camera/src/driver_adapter/main_test/project_v4l2_main.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef HOS_CAMERA_PROJET_HARDWARE_H +#define HOS_CAMERA_PROJET_HARDWARE_H +#include + +namespace OHOS::Camera { +#define PREVIEW_PIXEL_FORMAT V4L2_PIX_FMT_YUYV +#define CAPTURE_PIXEL_FORMAT V4L2_PIX_FMT_YUYV +#define VIDEO_PIXEL_FORMAT V4L2_PIX_FMT_YUYV + +#define TEST_SENSOR_NAME "mx6s-csi" +} // namespace OHOS::Camera +#endif diff --git a/nxp/imx8mm/camera/src/driver_adapter/test/BUILD.gn b/nxp/imx8mm/camera/src/driver_adapter/test/BUILD.gn new file mode 100755 index 0000000..bc472c8 --- /dev/null +++ b/nxp/imx8mm/camera/src/driver_adapter/test/BUILD.gn @@ -0,0 +1,80 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. + +import("//build/test.gni") +import("//drivers/adapter/uhdf2/uhdf.gni") +import("//drivers/peripheral/camera/hal/camera.gni") + +module_output_path = "hdf/v4l2_adapter_test" + +config("v4l2_utest_config") { + visibility = [ ":*" ] + + cflags = [ + "-Wall", + "-Wextra", + "-Werror", + "-Wno-error", + "-DGST_DISABLE_DEPRECATED", + "-DHAVE_CONFIG_H", + "-DCOLORSPACE=\"videoconvert\"", + "-fno-strict-aliasing", + "-Wno-sign-compare", + "-Wno-builtin-requires-header", + "-Wno-unused-variable", + "-Wno-unused-label", + "-Wno-implicit-function-declaration", + "-Wno-format", + "-Wno-int-conversion", + "-Wno-unused-function", + "-Wno-thread-safety-attributes", + "-Wno-inconsistent-missing-override", + "-fno-rtti", + "-fno-exceptions", + "-ffunction-sections", + "-fdata-sections", + ] +} + +ohos_unittest("v4l2_adapter_unittest") { + test_type = "unittest" + testonly = true + module_out_path = module_output_path + sources = [ "unittest/utest_v4l2_dev.cpp" ] + + include_dirs = [ + "$camera_path/include", + "$camera_path/adapter/platform/v4l2/src/driver_adapter/include", + "$camera_device_name_path/camera/src/driver_adapter/test/unittest/include", + "//third_party/googletest/googletest/include/gtest", + "//utils/native/base/include", + ] + + deps = [ + "$camera_path/adapter/platform/v4l2/src/driver_adapter:camera_v4l2_adapter", + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + defines += [ "V4L2_UTEST" ] + + if (is_standard_system) { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } else { + external_deps = [ "hilog:libhilog" ] + } + + public_configs = [ ":v4l2_utest_config" ] +} diff --git a/nxp/imx8mm/camera/src/driver_adapter/test/unittest/include/utest_v4l2_dev.h b/nxp/imx8mm/camera/src/driver_adapter/test/unittest/include/utest_v4l2_dev.h new file mode 100644 index 0000000..0d19399 --- /dev/null +++ b/nxp/imx8mm/camera/src/driver_adapter/test/unittest/include/utest_v4l2_dev.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef HOS_CAMERA_UTEST_V4L2_H +#define HOS_CAMERA_UTEST_V4L2_H + +#include +#include +#include "v4l2_dev.h" +#include "v4l2_uvc.h" + +namespace OHOS::Camera { +class UtestV4L2Dev : public testing::Test { +public: + + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(void); + void TearDown(void); + + static std::shared_ptr V4L2UVC_; + static std::shared_ptr V4L2Dev_; + + static std::vector cameraIDs_; +}; +std::shared_ptr UtestV4L2Dev::V4L2UVC_ = nullptr; +std::shared_ptr UtestV4L2Dev::V4L2Dev_ = nullptr; +std::vector UtestV4L2Dev::cameraIDs_ = {}; +} // namespace OHOS::Camera +#endif diff --git a/nxp/imx8mm/camera/src/driver_adapter/test/unittest/utest_v4l2_dev.cpp b/nxp/imx8mm/camera/src/driver_adapter/test/unittest/utest_v4l2_dev.cpp new file mode 100644 index 0000000..5044de3 --- /dev/null +++ b/nxp/imx8mm/camera/src/driver_adapter/test/unittest/utest_v4l2_dev.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#include +#include +#include + +#include "utest_v4l2.h" + +using namespace testing::ext; +namespace OHOS::Camera { +void V4L2UvcCallback(const std::string cameraId, const std::vector& control, + const std::vector& fromat, const bool inOut) +{ + std::cout << "V4L2UvcCallback" << std::endl; +} + +void V4L2BufferCallback(std::shared_ptr buffer) +{ + std::cout << "V4L2BufferCallback" << std::endl; +} + +void UtestV4L2Dev::SetUpTestCase(void) +{ + std::cout << "SetUpTestCase.." << std::endl; + + V4L2UVC_ = std::make_shared(); + EXPECT_EQ(true, V4L2UVC_ != nullptr); + + V4L2Dev_ = std::make_shared(); + EXPECT_EQ(true, V4L2Dev_ != nullptr); +} + +void UtestV4L2Dev::TearDownTestCase(void) +{ + std::cout << "TearDownTestCase.." << std::endl; +} + +void UtestV4L2Dev::SetUp(void) +{ + std::cout << "SetUp.." << std::endl; +} + +void UtestV4L2Dev::TearDown(void) +{ + std::cout << "TearDown.." << std::endl; +} + +HWTEST_F(UtestV4L2Dev, InitUvc, TestSize.Level0) +{ + V4L2UVC_->V4L2UvcDetectInit(V4L2UvcCallback); +} + +HWTEST_F(UtestV4L2Dev, InitCamera, TestSize.Level0) +{ + int rc = 0; + + cameraIDs_.push_back("bm2835 mmal"); + rc = HosV4L2Dev::Init(cameraIDs_); + + EXPECT_EQ(true, rc != RC_ERROR); +} + +HWTEST_F(UtestV4L2Dev, SetFormat, TestSize.Level0) +{ + constexpr uint32_t width = 640; + constexpr uint32_t height = 480; + + int rc = 0; + std::string devname = "bm2835 mmal"; + DeviceFormat format = {}; + + rc = V4L2Dev_->start(devname); + EXPECT_EQ(RC_OK, rc); + + rc = V4L2Dev_->ConfigSys(devname, CMD_V4L2_GET_FORMAT, format); + EXPECT_EQ(RC_OK, rc); + + format.fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV; + format.fmtdesc.width = width; + format.fmtdesc.height = height; + + rc = V4L2Dev_->ConfigSys(devname, CMD_V4L2_SET_FORMAT, format); + EXPECT_EQ(RC_OK, rc); + + rc = V4L2Dev_->ConfigSys(devname, CMD_V4L2_GET_FPS, format); + EXPECT_EQ(RC_OK, rc); +} + +HWTEST_F(UtestV4L2Dev, SetBuffer, TestSize.Level0) +{ + constexpr uint32_t bufferCount = 4; + + unsigned char* addr[bufferCount]; + std::shared_ptr buffptr[bufferCount]; + std::string devname = "bm2835 mmal"; + DeviceFormat format = {}; + unsigned int bufSize; + int i; + int rc = 0; + + rc = V4L2Dev_->ReqBuffers(devname, bufferCount); + EXPECT_EQ(RC_OK, rc); + + rc = V4L2Dev_->ConfigSys(devname, CMD_V4L2_GET_FORMAT, format); + EXPECT_EQ(RC_OK, rc); + + bufSize = format.fmtdesc.sizeimage; + for (i = 0; i < bufferCount; ++i) { + buffptr[i] = std::make_shared(); + buffptr[i]->buffer_ = std::make_shared(); + + buffptr[i]->buffer_->SetIndex(i); + buffptr[i]->buffer_->SetSize(bufSize); + buffptr[i]->buffer_->SetUsage(1); + buffptr[i]->bufferPoolId_ = 0; + addr[i] = (unsigned char*)malloc(bufSize); + if (addr == nullptr) { + std::cout << " malloc buffers fail \n" << std::endl; + break; + } + buffptr[i]->buffer_->SetVirAddress(addr[i]); + + rc = V4L2Dev_->CreatBuffer(devname, buffptr[i]); + EXPECT_EQ(RC_OK, rc); + } + + if (i != bufferCount) { + for (int j = 0; j < i; ++j) { + free(addr[j]); + } + V4L2Dev_->stop(devname); + } + + EXPECT_EQ(bufferCount, i); +} + + +HWTEST_F(UtestV4L2Dev, SetFrameCallback, TestSize.Level0) +{ + int rc = 0; + + rc = V4L2Dev_->SetCallback(V4L2BufferCallback); + EXPECT_EQ(RC_OK, rc); +} + +HWTEST_F(UtestV4L2Dev, StreamStart, TestSize.Level0) +{ + int rc = 0; + int value; + std::string devname = "bm2835 mmal"; + + constexpr uint32_t awbValue = 8; + + rc = V4L2Dev_->StartStream(devname); + EXPECT_EQ(RC_OK, rc); + + rc = V4L2Dev_->QuerySetting(devname, CMD_AWB_MODE, &value); + EXPECT_EQ(RC_OK, rc); + + int setValue = awbValue; + rc = V4L2Dev_->UpdateSetting(devname, CMD_AWB_MODE, &setValue); + EXPECT_EQ(RC_OK, rc); + + sleep(3); +} + +HWTEST_F(UtestV4L2Dev, ReleaseAll, TestSize.Level0) +{ + std::string devname = "bm2835 mmal"; + + V4L2Dev_->StopStream(devname); + V4L2Dev_->ReleaseBuffers(devname); + V4L2Dev_->stop(devname); + + V4L2UVC_->V4L2UvcDetectUnInit(); +} +} // namespace OHOS::Camera \ No newline at end of file diff --git a/nxp/imx8mm/camera/src/pipeline_core/BUILD.gn b/nxp/imx8mm/camera/src/pipeline_core/BUILD.gn new file mode 100755 index 0000000..4da3e12 --- /dev/null +++ b/nxp/imx8mm/camera/src/pipeline_core/BUILD.gn @@ -0,0 +1,159 @@ +import("//build/ohos.gni") +import("//drivers/adapter/uhdf2/uhdf.gni") +import("//drivers/peripheral/camera/hal/camera.gni") + +config("pipe_config") { + visibility = [ ":*" ] + + cflags_cc = [ + "-Wall", + "-Wextra", + "-Werror", + "-Wno-error", + "-DGST_DISABLE_DEPRECATED", + "-DHAVE_CONFIG_H", + "-DCOLORSPACE=\"videoconvert\"", + "-fno-strict-aliasing", + "-Wno-sign-compare", + "-Wno-builtin-requires-header", + "-Wno-unused-variable", + "-Wno-unused-label", + "-Wno-implicit-function-declaration", + "-Wno-format", + "-Wno-int-conversion", + "-Wno-unused-function", + "-Wno-thread-safety-attributes", + "-Wno-inconsistent-missing-override", + "-fno-rtti", + "-fno-exceptions", + "-ffunction-sections", + "-fdata-sections", + ] +} + +ohos_shared_library("camera_pipeline_core") { + sources = [ + "$camera_path/adapter/platform/v4l2/src/pipeline_core/nodes/uvc_node/uvc_node.cpp", + "$camera_path/adapter/platform/v4l2/src/pipeline_core/nodes/v4l2_source_node/v4l2_source_node.cpp", + "$camera_path/pipeline_core/host_stream/src/host_stream_impl.cpp", + "$camera_path/pipeline_core/host_stream/src/host_stream_mgr_impl.cpp", + "$camera_path/pipeline_core/ipp/src/algo_plugin.cpp", + "$camera_path/pipeline_core/ipp/src/algo_plugin_manager.cpp", + "$camera_path/pipeline_core/ipp/src/ipp_algo_parser.cpp", + "$camera_path/pipeline_core/ipp/src/ipp_node.cpp", + "$camera_path/pipeline_core/ipp/src/offline_pipeline.cpp", + "$camera_path/pipeline_core/ipp/src/offline_pipeline_manager.cpp", + "$camera_path/pipeline_core/nodes/src/dummy_node/dummy_node.cpp", + "$camera_path/pipeline_core/nodes/src/fork_node/fork_node.cpp", + "$camera_path/pipeline_core/nodes/src/merge_node/merge_node.cpp", + "$camera_path/pipeline_core/nodes/src/node_base/node_base.cpp", + "$camera_path/pipeline_core/nodes/src/sensor_node/sensor_node.cpp", + "$camera_path/pipeline_core/nodes/src/sink_node/sink_node.cpp", + "$camera_path/pipeline_core/nodes/src/source_node/source_node.cpp", + "$camera_path/pipeline_core/pipeline_impl/src/builder/stream_pipeline_builder.cpp", + "$camera_path/pipeline_core/pipeline_impl/src/dispatcher/stream_pipeline_dispatcher.cpp", + "$camera_path/pipeline_core/pipeline_impl/src/parser/config_parser.cpp", + "$camera_path/pipeline_core/pipeline_impl/src/strategy/config/config.c", + "$camera_path/pipeline_core/pipeline_impl/src/strategy/config/params.c", + "$camera_path/pipeline_core/pipeline_impl/src/strategy/stream_pipeline_strategy.cpp", + "$camera_path/pipeline_core/pipeline_impl/src/stream_pipeline_core.cpp", + "$camera_path/pipeline_core/src/pipeline_core.cpp", + ] + include_dirs = [ + "//utils/native/base/include", + "//base/hiviewdfx/interfaces/innerkits/libhilog/include", + "$camera_path/../interfaces/include", + "$camera_path/../interfaces/hdi_ipc", + "$camera_path/include", + "$camera_path/hdi_impl", + "$camera_path/hdi_impl/camera_host/include", + "$camera_path/hdi_impl/camera_device/include", + "$camera_path/hdi_impl/stream_operator/include", + "$camera_path/hdi_impl/include", + "$camera_path/device_manager", + "$camera_path/device_manager/include", + "$camera_path/pipeline_core", + "$camera_path/pipeline_core/host_stream/include", + "$camera_path/pipeline_core/utils", + "$camera_path/pipeline_core/nodes/include", + "$camera_path/pipeline_core/nodes/src/sensor_node", + "$camera_path/pipeline_core/nodes/src/node_base", + "$camera_path/pipeline_core/nodes/src/sink_node", + "$camera_path/pipeline_core/nodes/src/source_node", + "$camera_path/pipeline_core/nodes/src/merge_node", + "$camera_path/pipeline_core/nodes/src/dummy_node", + "$camera_path/pipeline_core/pipeline_impl/include", + "$camera_path/pipeline_core/pipeline_impl/src", + "$camera_path/pipeline_core/include", + "$camera_path/pipeline_core/pipeline_impl/src/builder", + "$camera_path/pipeline_core/pipeline_impl/src/dispatcher", + "$camera_path/pipeline_core/pipeline_impl/src/parser", + "$camera_path/pipeline_core/pipeline_impl/src/strategy", + "$camera_path/pipeline_core/pipeline_impl/src/strategy/config", + "$camera_path/pipeline_core/ipp/include", + "$camera_path/utils/event", + "$camera_path/adapter/platform/v4l2/src/device_manager/include", + "$camera_device_name_path/camera/include/device_manager", + "$camera_path/adapter/platform/v4l2/src/pipeline_core/nodes/v4l2_source_node", + "$camera_path/adapter/platform/v4l2/src/pipeline_core/nodes/uvc_node", + "//drivers/peripheral/camera/hal/adapter/platform/v4l2/src/driver_adapter/include/", + "//foundation/communication/ipc/ipc/native/src/core/include", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", + "//utils/native/base/include", + "//foundation/multimedia/camera_standard/frameworks/innerkitsimpl/metadata/include", + + # hcs parser + "//drivers/framework/include/osal", + "//drivers/framework/include/config", + "//drivers/adapter/uhdf2/osal/include", + "//system/core/include/cutils", + "//drivers/framework/utils/include", + "//drivers/adapter/uhdf2/include/config", + "//drivers/adapter/uhdf2/config", + ] + + deps = [ + "$camera_path/buffer_manager:camera_buffer_manager", + "$camera_path/device_manager:camera_device_manager", + "//foundation/multimedia/camera_standard/frameworks/innerkitsimpl/metadata:metadata", + + # hcs parser + "$hdf_uhdf_path/osal:libhdf_utils", + "$hdf_uhdf_path/config:libhdf_hcs", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core", + "//foundation/graphic/standard:libsurface", + ] + + if (is_standard_system) { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } else { + external_deps = [ "hilog:libhilog" ] + } + + public_configs = [ ":pipe_config" ] + subsystem_name = "hdf" + part_name = "hdf" +} + +config("example_config") { + visibility = [ ":*" ] + + cflags = [ + "-Wno-error", + "-Wno-unused-function", + "-Wno-unused-parameter", + ] +} + +ohos_shared_library("camera_ipp_algo_example") { + sources = [ "$camera_device_name_path/camera/src/pipeline_core/ipp_algo_example/ipp_algo_example.c" ] + + include_dirs = [ + "$camera_path/pipeline_core/ipp/include", + "//utils/native/base/include", + ] + deps = [ "//utils/native/base:utils" ] + public_configs = [ ":example_config" ] + subsystem_name = "hdf" + part_name = "hdf" +} diff --git a/nxp/imx8mm/camera/src/pipeline_core/ipp_algo_example/ipp_algo_example.c b/nxp/imx8mm/camera/src/pipeline_core/ipp_algo_example/ipp_algo_example.c new file mode 100755 index 0000000..6b86b5b --- /dev/null +++ b/nxp/imx8mm/camera/src/pipeline_core/ipp_algo_example/ipp_algo_example.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#include +#include "ipp_algo.h" +#include "securec.h" + +#define MAX_BUFFER_COUNT 100 + +int Init(const IppAlgoMeta *meta) +{ + printf("ipp algo example Init ...\n"); + return 0; +} + +int Start(void) +{ + printf("ipp algo example Start ...\n"); + return 0; +} + +int Flush(void) +{ + printf("ipp algo example Flush ...\n"); + return 0; +} + +int Process(IppAlgoBuffer *inBuffer[], int inBufferCount, IppAlgoBuffer *outBuffer, const IppAlgoMeta *meta) +{ + printf("ipp algo example Process ...\n"); + if (inBuffer == NULL || inBufferCount > MAX_BUFFER_COUNT) { + printf("inBuffer is NULL\n"); + return -1; + } + + for (int i = 0; i < inBufferCount; i++) { + if (inBuffer[i] != NULL) { + printf("in buffer addr = %p, width = %u, height = %u, stride = %u, size = %u, id = %d\n", inBuffer[i]->addr, + inBuffer[i]->width, inBuffer[i]->height, inBuffer[i]->stride, inBuffer[i]->size, inBuffer[i]->id); + } else { + printf("in buffer %d is NULL\n", i); + } + } + + if (outBuffer != NULL && outBuffer->addr != NULL) { + printf("out buffer addr = %p, size = %u, id = %d\n", outBuffer->addr, outBuffer->size, outBuffer->id); + } else { + printf("out buffer is NULL\n"); + } + + if (inBufferCount == 1) { + if (inBuffer[0] == NULL || outBuffer == NULL || inBuffer[0]->addr == NULL || outBuffer->addr == NULL) { + return 0; + } + char *in = (char*)(inBuffer[0]->addr); + char *out = (char*)(outBuffer->addr); + if (memcpy_s(out, outBuffer->size, in, outBuffer->size) != 0) { + printf("memcpy_s failed."); + } + return 0; + } + + if (inBufferCount == 2) { // 2:2 inports + if (inBuffer[0] == NULL || inBuffer[1] == NULL || inBuffer[0]->addr == NULL || inBuffer[1]->addr == NULL) { + return -1; + } + printf("example algo merge 2 camera images\n"); + // format is yuv422 + char *startBuffer1 = (char*)(inBuffer[0]->addr) + inBuffer[0]->stride * inBuffer[0]->height; + char *startBuffer2 = (char*)(inBuffer[1]->addr) + inBuffer[1]->stride * inBuffer[1]->height; + if (memcpy_s(startBuffer1, inBuffer[0]->size - inBuffer[0]->stride * inBuffer[0]->height, + startBuffer2, inBuffer[0]->stride * inBuffer[0]->height) != 0) { + printf("memcpy_s failed."); + } + return 0; + } + return 0; +} + +int Stop(void) +{ + printf("ipp algo example Stop ...\n"); + return 0; +} diff --git a/nxp/imx8mm/firmware/bcm43438a1.hcd b/nxp/imx8mm/firmware/bcm43438a1.hcd new file mode 100644 index 0000000000000000000000000000000000000000..c4a4b5510f6c672e2eaa2734a40f26ae20b29d6e GIT binary patch literal 33376 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