android 13 from xiaosuan

This commit is contained in:
cpeng 2025-08-25 08:28:21 +08:00
commit 6cdeb5a31c
6288 changed files with 1873717 additions and 0 deletions

View File

@ -0,0 +1,16 @@
#
# Based on /build/soong/scripts/system-clang-format
#
BasedOnStyle: Google
Standard: Cpp11
AccessModifierOffset: -2
AllowShortFunctionsOnASingleLine: Inline
ColumnLimit: 100
CommentPragmas: NOLINT:.*
DerivePointerAlignment: false
IncludeBlocks: Preserve
IndentWidth: 4
ContinuationIndentWidth: 8
PointerAlignment: Left
TabWidth: 4
UseTab: Never

47
amlogic/yukawa/Android.bp Normal file
View File

@ -0,0 +1,47 @@
// Copyright 2018 The Android Open Source Project
//
// 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.
soong_namespace {}
// *** THIS PACKAGE HAS SPECIAL LICENSING CONDITIONS. PLEASE
// CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE
// DEPENDING ON IT IN YOUR PROJECT. ***
package {
default_applicable_licenses: ["device_amlogic_yukawa_license"],
}
// Added automatically by a large-scale-change that took the approach of
// 'apply every license found to every target'. While this makes sure we respect
// every license restriction, it may not be entirely correct.
//
// e.g. GPL in an MIT project might only apply to the contrib/ directory.
//
// Please consider splitting the single license below into multiple licenses,
// taking care not to lose any license_kind information, and overriding the
// default license using the 'licenses: [...]' property on targets as needed.
//
// For unused files, consider creating a 'fileGroup' with "//visibility:private"
// to attach the license to, and including a comment whether the files may be
// used in the current project.
// See: http://go/android-license-faq
license {
name: "device_amlogic_yukawa_license",
visibility: [":__subpackages__"],
license_kinds: [
"SPDX-license-identifier-Apache-2.0",
"SPDX-license-identifier-GPL-2.0",
"legacy_by_exception_only", // by exception only
],
// large-scale-change unable to identify any license_text files
}

41
amlogic/yukawa/Android.mk Normal file
View File

@ -0,0 +1,41 @@
#
# Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
#
# 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.
#
# WARNING: Everything listed here will be built on ALL platforms,
# including x86, the emulator, and the SDK. Modules must be uniquely
# named (liblights.panda), and must build everywhere, or limit themselves
# to only building on ARM if they include assembly. Individual makefiles
# are responsible for having their own logic, for fine-grained control.
ifneq ($(filter yukawa%, $(TARGET_DEVICE)),)
LOCAL_PATH := $(call my-dir)
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/binaries/bt-wifi-firmware,))
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/binaries/video_firmware,))
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/hal/audio,))
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/hal/camera,))
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/input,))
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/media_xml,))
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/wifi,))
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/,.rc))
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/,fstab.yukawa))
# if some modules are built directly from this directory (not subdirectories),
# their rules should be written here.
include $(call all-makefiles-under,$(LOCAL_PATH))
endif

View File

@ -0,0 +1,25 @@
#
# Copyright (C) 2017 The Android Open-Source Project
#
# 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.
#
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/yukawa_sei510.mk \
$(LOCAL_DIR)/yukawa32_sei510.mk \
$(LOCAL_DIR)/yukawa.mk \
$(LOCAL_DIR)/yukawa32.mk
COMMON_LUNCH_CHOICES := \
yukawa_sei510-userdebug \
yukawa-userdebug

View File

@ -0,0 +1,172 @@
#
# Product-specific compile-time definitions.
#
# The generic product target doesn't have any hardware-specific pieces.
# Primary Arch
TARGET_ARCH := arm64
TARGET_ARCH_VARIANT := armv8-a
TARGET_CPU_ABI := arm64-v8a
TARGET_CPU_VARIANT := cortex-a53
# Secondary Arch
TARGET_2ND_ARCH := arm
TARGET_2ND_ARCH_VARIANT := armv8-a
TARGET_2ND_CPU_ABI := armeabi-v7a
TARGET_2ND_CPU_ABI2 := armeabi
TARGET_2ND_CPU_VARIANT := cortex-a53
TARGET_USES_64_BIT_BINDER := true
TARGET_SUPPORTS_64_BIT_APPS := true
TARGET_BOARD_PLATFORM := yukawa
# Vulkan
BOARD_INSTALL_VULKAN := true
# OpenCL
BOARD_INSTALL_OPENCL := true
# BT configs
BOARD_HAVE_BLUETOOTH := true
# generic wifi
WPA_SUPPLICANT_VERSION := VER_0_8_X
BOARD_WPA_SUPPLICANT_DRIVER := NL80211
BOARD_HOSTAPD_DRIVER := NL80211
# Treble
PRODUCT_FULL_TREBLE_OVERRIDE := true
BOARD_VNDK_VERSION := current
# AVB
ifeq ($(TARGET_AVB_ENABLE), true)
BOARD_AVB_ENABLE := true
else
BOARD_AVB_ENABLE := false
endif
TARGET_NO_BOOTLOADER := true
TARGET_NO_KERNEL := false
ifeq ($(TARGET_USE_AB_SLOT), true)
BOARD_USES_RECOVERY_AS_BOOT := true
AB_OTA_UPDATER := true
AB_OTA_PARTITIONS += \
boot \
system \
vendor \
vbmeta
endif
BOARD_BOOTIMAGE_PARTITION_SIZE := 33554432
BOARD_DTBOIMG_PARTITION_SIZE := 8388608 # 8 MiB
BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE ?= ext4
BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
ifneq ($(TARGET_USE_AB_SLOT), true)
BOARD_CACHEIMAGE_PARTITION_SIZE := 268435456
BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
endif
TARGET_USERIMAGES_USE_EXT4 := true
TARGET_COPY_OUT_VENDOR := vendor
# Super partition
TARGET_USE_DYNAMIC_PARTITIONS := true
BOARD_BUILD_SUPER_IMAGE_BY_DEFAULT := true
BOARD_SUPER_PARTITION_GROUPS := db_dynamic_partitions
BOARD_DB_DYNAMIC_PARTITIONS_PARTITION_LIST := system vendor
ifeq ($(TARGET_USE_AB_SLOT), true)
BOARD_SUPER_PARTITION_SIZE := 4831838208
else
BOARD_SUPER_PARTITION_SIZE := 2415919104
endif
BOARD_DB_DYNAMIC_PARTITIONS_SIZE := 2411724800 # Reserve 4M for DAP metadata
BOARD_SUPER_PARTITION_METADATA_DEVICE := super
# BOARD_SUPER_IMAGE_IN_UPDATE_PACKAGE := true
# Recovery
TARGET_RECOVERY_PIXEL_FORMAT := RGBX_8888
ifeq ($(TARGET_AVB_ENABLE), true)
ifeq ($(TARGET_USE_AB_SLOT), true)
TARGET_RECOVERY_FSTAB := device/amlogic/yukawa/fstab.yukawa.avb.ab
else
TARGET_RECOVERY_FSTAB := device/amlogic/yukawa/fstab.recovery.yukawa.avb
BOARD_RECOVERYIMAGE_PARTITION_SIZE := 33554432
endif
BOARD_AVB_RECOVERY_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_RECOVERY_ALGORITHM := SHA256_RSA2048
BOARD_AVB_RECOVERY_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_RECOVERY_ROLLBACK_INDEX_LOCATION := 2
else
ifeq ($(TARGET_USE_AB_SLOT), true)
TARGET_RECOVERY_FSTAB := device/amlogic/yukawa/fstab.yukawa
else
TARGET_RECOVERY_FSTAB := device/amlogic/yukawa/fstab.recovery.yukawa
BOARD_RECOVERYIMAGE_PARTITION_SIZE := 33554432
endif
endif
BOARD_KERNEL_OFFSET := 0x1080000
BOARD_KERNEL_TAGS_OFFSET := 0x1000000
BOARD_INCLUDE_DTB_IN_BOOTIMG := true
BOARD_MKBOOTIMG_ARGS := --kernel_offset $(BOARD_KERNEL_OFFSET)
BOARD_BOOT_HEADER_VERSION := 2
BOARD_MKBOOTIMG_ARGS += --header_version $(BOARD_BOOT_HEADER_VERSION)
# Pass unsigned dtbo image (generated by build/tasks/dtimages.mk) to Android
# build system for AVB signing
DTBO_UNSIGNED := dtbo-unsigned.img
# $(PRODUCT_OUT) hasn't been defined yet, so use "=" instead of ":="
# so that it is resolved later
BOARD_PREBUILT_DTBOIMAGE = $(PRODUCT_OUT)/$(DTBO_UNSIGNED)
BOARD_KERNEL_CMDLINE += no_console_suspend console=ttyAML0,115200 earlycon
BOARD_KERNEL_CMDLINE += printk.devkmsg=on
BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/ffe07000.mmc
BOARD_KERNEL_CMDLINE += init=/init
BOARD_KERNEL_CMDLINE += firmware_class.path=/vendor/firmware
BOARD_KERNEL_CMDLINE += androidboot.hardware=yukawa
ifneq ($(TARGET_SELINUX_ENFORCE), true)
BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive
endif
ifeq ($(TARGET_BUILTIN_EDID), true)
BOARD_KERNEL_CMDLINE += drm.edid_firmware=edid/1920x1080.bin
endif
ifneq ($(TARGET_SENSOR_MEZZANINE),)
BOARD_KERNEL_CMDLINE += overlay_mgr.overlay_dt_entry=hardware_cfg_$(TARGET_SENSOR_MEZZANINE)
endif
ifneq ($(TARGET_MEM_SIZE),)
BOARD_KERNEL_CMDLINE += mem=$(TARGET_MEM_SIZE)
endif
ifneq ($(TARGET_KERNEL_CFG),)
BOARD_KERNEL_CMDLINE += $(TARGET_KERNEL_CFG)
endif
USE_E2FSPROGS := true
BOARD_USES_GENERIC_AUDIO := false
BOARD_USES_ALSA_AUDIO := true
TARGET_USES_MKE2FS := true
TARGET_USES_HWC2 := true
BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR := device/amlogic/yukawa/bluetooth
BOARD_SEPOLICY_DIRS += \
device/amlogic/yukawa/sepolicy
DEVICE_MANIFEST_FILE += device/amlogic/yukawa/manifest.xml
ifneq ($(TARGET_KERNEL_USE), 4.19)
DEVICE_MANIFEST_FILE += device/amlogic/yukawa/manifest_kernel5.xml
endif
DEVICE_MATRIX_FILE := device/amlogic/yukawa/compatibility_matrix.xml
ifneq ($(TARGET_SENSOR_MEZZANINE),)
DEVICE_MANIFEST_FILE += device/amlogic/yukawa/sensorhal/manifest.xml
endif
# Generate an APEX image for experiment b/119800099.
DEXPREOPT_GENERATE_APEX_IMAGE := true

101
amlogic/yukawa/CleanSpec.mk Normal file
View File

@ -0,0 +1,101 @@
# Copyright 2017 The Android Open Source Project
#
# 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.
#
# If you don't need to do a full clean build but would like to touch
# a file or delete some intermediate files, add a clean step to the end
# of the list. These steps will only be run once, if they haven't been
# run before.
#
# E.g.:
# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
#
# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
# files that are missing or have been moved.
#
# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
# Use $(OUT_DIR) to refer to the "out" directory.
#
# If you need to re-do something that's already mentioned, just copy
# the command and add it to the bottom of the list. E.g., if a change
# that you made last week required touching a file and a change you
# made today requires touching the same file, just copy the old
# touch step and add it to the end of the list.
#
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
# For example:
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor)
# Remove /system/lib[64]/vndk-sp/libz.so
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/vndk-sp/libz.so)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/vndk-sp/libz.so)
# Remove /product mount point
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/product)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product)
# Remove android.hardware.audio*@2.0 implementation
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/lib/hw/android.hardware.audio*@2.0-impl.so)
# Adds product.img
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/product)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/fonts)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/usr)
# Remove default android.hardware.health@2.0-service.yukawa
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/bin/hw/android.hardware.health@2.0-service.yukawa)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/init/android.hardware.health@2.0-service.yukawa.rc)
# Remove healthd
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/healthd)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/init/healthd.rc)
# Remove Codec2.0 software process
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/hw/hardware.google.media.c2@1.0-service-software)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/init/hardware.google.media.c2@1.0-service-software.rc)
# Remove keymaster service
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/init/android.hardware.keymaster@4.0-service*)
# Migrate to versioned VNDK directory
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/vndk-sp)
#AU300 cleanup
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/include)
# Remove /product mount point
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/product)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product)

6
amlogic/yukawa/METADATA Normal file
View File

@ -0,0 +1,6 @@
# *** THIS PACKAGE HAS SPECIAL LICENSING CONDITIONS. PLEASE
# CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE
# DEPENDING ON IT IN YOUR PROJECT. ***
third_party {
license_type: BY_EXCEPTION_ONLY
}

View File

View File

@ -0,0 +1,5 @@
[Options]
ignore_merged_commits = true
[Builtin Hooks]
clang_format = true

View File

@ -0,0 +1,2 @@
LOCAL_PATH:= $(call my-dir)
include $(call all-makefiles-under,$(LOCAL_PATH))

View File

@ -0,0 +1 @@
include $(call all-subdir-makefiles)

View File

@ -0,0 +1,33 @@
#
# Copyright 2019, The Android Open Source Project
#
# 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.
#
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_VENDOR_MODULE := true
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_SDK_VERSION := current
LOCAL_EXPORT_PACKAGE_RESOURCES := true
LOCAL_PROGUARD_ENABLED := disabled
LOCAL_USE_AAPT2 := true
LOCAL_AAPT2_ONLY := true
LOCAL_PACKAGE_NAME := YukawaAndroidOverlay
LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
LOCAL_LICENSE_CONDITIONS := notice
LOCAL_CERTIFICATE := platform
include $(BUILD_RRO_PACKAGE)

View File

@ -0,0 +1,21 @@
<!--
~ Copyright (C) 2019 The Android Open Source Project
~
~ 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.yukawa"
android:versionCode="1"
android:versionName="1.0">
<overlay android:targetPackage="android" android:priority="0" android:isStatic="true"/>
</manifest>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2019, The Android Open Source Project
**
** 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.
*/
-->
<!-- Mapping of keycodes to components which will be handled globally.
Modify this file to add global keys.
The key will NOT go to the foreground application and instead only ever be sent via targeted
broadcast to the specified component. The action of the intent will be
android.intent.action.GLOBAL_BUTTON and the KeyEvent will be included in the intent as
android.intent.extra.KEY_EVENT.
-->
<global_keys version="1">
<!-- Example format: id = keycode to handle globally. component = component which will handle this key. -->
<key keyCode="KEYCODE_PAIRING" component="com.google.android.yukawaservice/.RemoteSyncReceiver" />
</global_keys>

View File

@ -0,0 +1,18 @@
#
# Copyright 2017 The Android Open-Source Project
#
# 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.
#
LOCAL_PATH:= $(call my-dir)
include $(call all-makefiles-under,$(LOCAL_PATH))

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,222 @@
#AP6398S_NVRAM_V1.1_20170926
# BCM4359 WLBGA iPA, iLNA board for bringup -AP6359SA_V1.0NVRAM
NVRAMRev=$Rev: 528206 $
cckdigfilttype=5
#cckdigfilttype=4 (default)
#valid ofdm filter types are 0 and 1
ofdmfilttype_2gbe=127
ofdmfilttype_5gbe=127
sromrev=11
boardrev=0x1301
boardtype=0x0812
# JIRA:SW4349-945 MANDATORY! Update makefile in case you touch bfl
#boardflags=0x10081201
boardflags=0x00480201
boardflags2=0x40801000
boardflags3=0x48700106
#boardnum=57410
macaddr=00:90:4c:27:80:01
ccode=0
regrev=0
antswitch=0
pdgain5g=0
pdgain2g=0
lowpowerrange2g=0
lowpowerrange5g=0
tworangetssi2g=0
tworangetssi5g=0
# Low Power Range start value: 0dBm
olpc_thresh2g=0
olpc_thresh5g=0
AvVmid_c0=2,130,2,130,2,130,2,130,2,130
AvVmid_c1=2,130,2,130,2,130,2,130,2,130
# JIRA:SW4349-945 MANDATORY! Update makefile in case you touch femctl
femctrl=14
vendid=0x14e4
devid=0x43ef
manfid=0x2d0
#prodid=0x052e
nocrc=1
btc_mode=1
#btc_params82=0x1a0
otpimagesize=502
xtalfreq=37400
rxgains2gelnagaina0=3
rxgains2gtrisoa0=7
rxgains2gtrelnabypa0=1
rxgains5gelnagaina0=3
rxgains5gtrisoa0=6
rxgains5gtrelnabypa0=1
rxgains5gmelnagaina0=3
rxgains5gmtrisoa0=6
rxgains5gmtrelnabypa0=1
rxgains5ghelnagaina0=3
rxgains5ghtrisoa0=6
rxgains5ghtrelnabypa0=1
rxgains2gelnagaina1=3
rxgains2gtrisoa1=7
rxgains2gtrelnabypa1=1
rxgains5gelnagaina1=3
rxgains5gtrisoa1=6
rxgains5gtrelnabypa1=1
rxgains5gmelnagaina1=3
rxgains5gmtrisoa1=6
rxgains5gmtrelnabypa1=1
rxgains5ghelnagaina1=3
rxgains5ghtrisoa1=6
rxgains5ghtrelnabypa1=1
rxchain=3
txchain=3
aa2g=3
aa5g=3
agbg0=2
agbg1=2
aga0=2
aga1=2
tssipos2g=1
extpagain2g=2
tssipos5g=1
extpagain5g=2
tempthresh=255
tempoffset=255
rawtempsense=0x1ff
fdss_interp_en=1
#fdss_level_2g=3,3
fdss_level_5g=4,4
#pa2gccka0=-186,8076,-976
#pa2gccka1=-217,7061,-881
#pa2gccka2=-67,9864,-1253
#pa2gccka3=-115,9164,-1225
#pa2ga0=-196,6950,-832
#pa2ga1=-204,6710,-809
#pa2ga2=-220,4557,-593
#pa2ga3=-218,4596,-601
pa2ga0=-193,7335,-862
pa2ga1=-202,6968,-828
pa2ga2=-220,4685,-607
pa2ga3=-218,4724,-615
#pa5ga0=-191,6865,-844,-169,7525,-907,-168,7768,-938,-192,7073,-871
#pa5ga1=-182,7580,-919,-188,7614,-931,-219,6536,-818,-202,7220,-895
#pa5ga2=-220,4437,-628,-183,5005,-678,-229,4048,-551,-223,4448,-611
#pa5ga3=-263,3914,-566,-224,4649,-640,-230,4385,-596,-154,6488,-866
pa5ga0=-205,6664,-820,-201,6801,-835,-199,6767,-831,-178,7266,-873
pa5ga1=-200,7025,-858,-193,7170,-871,-186,7290,-879,-187,7227,-873
pa5ga2=-220,4616,-647,-183,5184,-694,-229,4227,-571,-223,4627,-631
pa5ga3=-263,4170,-599,-224,4905,-668,-230,4641,-625,-154,6744,-885
#pa5gbw4080a0=-201,6883,-859,-198,7088,-881,-202,6968,-870,-210,6522,-820
#pa5gbw4080a1=-217,6626,-832,-201,7517,-932,-201,7251,-896,-184,7500,-917
#pa5gbw4080a2=-272,3585,-525,-193,5404,-740,-229,4201,-572,-230,4036,-550
#pa5gbw4080a3=-278,3361,-486,-230,4794,-662,-268,3605,-508,-276,3337,-478
maxp2ga0=74
maxp2ga1=74
maxp5ga0=70,70,70,70
maxp5ga1=70,70,71,70
subband5gver=0x4
paparambwver=3
pdoffset2g40mvalid=0
cckpwroffset0=0x3
cckpwroffset1=0x3
pdoffset2g40ma0=0x2
pdoffset2g40ma1=0x3
pdoffset40ma0=0x0022
pdoffset80ma0=0xceff
pdoffset40ma1=0x0123
pdoffset80ma1=0xdfff
cckbw202gpo=0
cckbw20ul2gpo=0
mcsbw202gpo=0x44444444
mcsbw402gpo=0x44444444
dot11agofdmhrbw202gpo=0x2222
ofdmlrbw202gpo=0x0000
mcsbw205glpo=0x44444444
mcsbw405glpo=0x44444444
mcsbw805glpo=0xCCCCCCCC
mcsbw1605glpo=0
mcsbw205gmpo=0x44444444
mcsbw405gmpo=0x44444444
mcsbw805gmpo=0xCCCCCCCC
mcsbw1605gmpo=0
mcsbw205ghpo=0x44444444
mcsbw405ghpo=0x44444444
mcsbw805ghpo=0xCCCCCCCC
mcsbw1605ghpo=0
mcslr5glpo=0x0000
mcslr5gmpo=0x0000
mcslr5ghpo=0x0000
sb20in40hrpo=0x0
sb20in80and160hr5glpo=0x0
sb40and80hr5glpo=0x0
sb20in80and160hr5gmpo=0x0
sb40and80hr5gmpo=0x0
sb20in80and160hr5ghpo=0x0
sb40and80hr5ghpo=0x0
sb20in40lrpo=0x0
sb20in80and160lr5glpo=0x0
sb40and80lr5glpo=0x0
sb20in80and160lr5gmpo=0x0
sb40and80lr5gmpo=0x0
sb20in80and160lr5ghpo=0x0
sb40and80lr5ghpo=0x0
dot11agduphrpo=0x0
dot11agduplrpo=0x0
phycal_tempdelta=255
temps_period=15
temps_hysteresis=15
ltecxmux=0
ltecxpadnum=0x0504
ltecxfnsel=0x44
ltecxgcigpio=0x04
#OOB params
#device_wake_opt=1
#host_wake_opt=0
swctrlmap_2g=0x00000808,0x00001010,0x00001010,0x021010,0x3ff
swctrlmapext_2g=0x00000000,0x00000000,0x00000000,0x000000,0x003
swctrlmap_5g=0x00004040,0x00000000,0x00000000,0x000000,0x3e5
swctrlmapext_5g=0x00000000,0x00000101,0x00000101,0x000000,0x003
fem_table_init_val=0x00001010,0x00000000
rssi_delta_5gl_c0=3,3,2,2,5,5
rssi_delta_5gml_c0=0,2,0,2,3,5
rssi_delta_5gmu_c0=0,2,0,2,3,5
rssi_delta_5gh_c0=2,5,2,5,5,8
rssi_delta_5gl_c1=1,1,2,2,3,3
rssi_delta_5gml_c1=-1,1,0,2,1,3
rssi_delta_5gmu_c1=-1,1,0,2,1,3
rssi_delta_5gh_c1=0,3,2,5,3,6
rssi_delta_2g_c0=4,5,4,5
rssi_delta_2g_c1=2,3,2,3
#muxenab=1
#avs_enab=1
# ########### BTC Dynctl profile params ############
# flags:bit0 - dynctl enabled, bit1 dynamic desense, bit2 dynamic mode
btcdyn_flags=0x0
#btcdyn_dflt_dsns_level=0
#btcdyn_low_dsns_level=0
#btcdyn_mid_dsns_level=7
#btcdyn_high_dsns_level=2
#btcdyn_default_btc_mode=5
#btcdyn_btrssi_hyster=2
# --- number of rows in the array vars below ---
#btcdyn_msw_rows=3
#btcdyn_dsns_rows=2
# --- mode switch data rows (max is 4) ---
#btcdyn_msw_row0=1,8,0,-50,-100
#btcdyn_msw_row1=1,4,0,-55,-100
#btcdyn_msw_row2=1,0,0,-70,-100
#btcdyn_msw_row3=1,-4,0,-70,-100
# --- desense switching data rows (max is 4) ---
#btcdyn_dsns_row0=5,8,0,-40,-40
#btcdyn_dsns_row0=5,4,0,-60,-60
#btcdyn_dsns_row1=5,0,0,0,-75
powoffs2gtna0=1,3,3,1,0,0,1,2,2,2,1,1,0,0
powoffs2gtna1=-1,1,1,1,0,0,1,2,3,2,2,0,0,0
#new Jan 4th
#eps_shift0=-1,-6,-1,-5
#eps_shift1=-4,-6,-1,-2
#eps_shift2=-1,9,-2,-6
muxenab=0x10
#bandedge
fdss_level_2g=4,4
fdss_level_5g=5,5
fdss_interp_en=1

View File

@ -0,0 +1,53 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
TARGET := ${GPU_TYPE}
GPU_TARGET_PLATFORM ?= default_8a
GPU_DRV_VERSION ?= r16p0
LOCAL_ANDROID_VERSION_NUM := p-${GPU_DRV_VERSION}gralloc1
LOCAL_MODULE := libGLES_mali
LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
LOCAL_LICENSE_CONDITIONS := notice
LOCAL_MULTILIB := both
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK)
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/egl
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib/egl
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64/egl
else
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
LOCAL_MODULE_PATH_32 := $(TARGET_OUT)/lib/egl
LOCAL_MODULE_PATH_64 := $(TARGET_OUT)/lib64/egl
endif
ifeq ($(TARGET_2ND_ARCH),)
ifeq ($(TARGET_ARCH),arm)
LOCAL_SRC_FILES := $(TARGET)/libGLES_mali_$(GPU_TARGET_PLATFORM)_32-$(LOCAL_ANDROID_VERSION_NUM).so
else
LOCAL_SRC_FILES := $(TARGET)/libGLES_mali_$(GPU_TARGET_PLATFORM)_64-$(LOCAL_ANDROID_VERSION_NUM).so
endif
else
LOCAL_SRC_FILES_32 := $(TARGET)/libGLES_mali_$(GPU_TARGET_PLATFORM)_32-$(LOCAL_ANDROID_VERSION_NUM).so
LOCAL_SRC_FILES_64 := $(TARGET)/libGLES_mali_$(GPU_TARGET_PLATFORM)_64-$(LOCAL_ANDROID_VERSION_NUM).so
endif
LOCAL_SHARED_LIBRARIES := android.hardware.graphics.common@1.0 libz libnativewindow libc++ liblog libm libc libdl
LOCAL_STRIP_MODULE := false
ifeq ($(BOARD_INSTALL_VULKAN),true)
LOCAL_POST_INSTALL_CMD = $(hide) \
pushd $(dir $(LOCAL_INSTALLED_MODULE))../hw && \
ln -sf ../egl/$(notdir $(LOCAL_INSTALLED_MODULE)) vulkan.$(TARGET_DEVICE).so && \
popd;
endif
ifeq ($(BOARD_INSTALL_OPENCL),true)
LOCAL_POST_INSTALL_CMD += \
pushd $(dir $(LOCAL_INSTALLED_MODULE)).. && \
ln -sf egl/$(notdir $(LOCAL_INSTALLED_MODULE)) libOpenCL.so.1.1 && \
ln -sf libOpenCL.so.1.1 libOpenCL.so.1 && \
ln -sf libOpenCL.so.1.1 libOpenCL.so && \
popd;
endif
include $(BUILD_PREBUILT)

View File

@ -0,0 +1,194 @@
LES-PRE-20769
SP-Version: 1.0
25 November 2015
END USER LICENCE AGREEMENT FOR THE MALI USERSPACE DRIVER ("Mali DRIVER")
THIS END USER LICENCE AGREEMENT ("LICENCE") IS A LEGAL AGREEMENT
BETWEEN YOU (EITHER A SINGLE INDIVIDUAL, OR SINGLE LEGAL ENTITY) AND
ARM LIMITED ("ARM") FOR THE USE OF THE SOFTWARE ACCOMPANYING THIS
LICENCE. ARM IS ONLY WILLING TO LICENSE THE SOFTWARE TO YOU ON
CONDITION THAT YOU ACCEPT ALL OF THE TERMS IN THIS LICENCE. BY
INSTALLING OR OTHERWISE USING OR COPYING THE SOFTWARE YOU INDICATE
THAT YOU AGREE TO BE BOUND BY ALL OF THE TERMS OF THIS LICENCE. IF YOU
DO NOT AGREE TO THE TERMS OF THIS LICENCE, ARM IS UNWILLING TO LICENSE
THE SOFTWARE TO YOU AND YOU MAY NOT INSTALL, USE OR COPY THE SOFTWARE,
AND YOU SHOULD PROMPTLY RETURN THE SOFTWARE TO YOUR SUPPLIER.
"Applications" means applications for use solely in conjunction with
Mali-based products manufactured under licence from ARM.
"Output" means data resulting from your use of the Software and all
direct and indirect derivatives thereof.
"Software" means any software, firmware and data accompanying this
Licence, any printed, electronic or online documentation supplied with
it under the terms of this Licence for the Mali Driver.
1. LICENCE GRANTS TO YOU.
1.1 ARM hereby grants to you, subject to the terms and conditions of
this Licence, a non-exclusive, non-transferable, revocable, worldwide
licence to:
(i) use and copy the Software or certain components or optional
functionality in the Software, as applicable, solely for the
purposes of running, designing or developing Applications; and
(ii) subject to Clause 1.2, distribute the whole of the Software;
and/or (b) the whole or any part of the Software together
with, or as incorporated into, Applications; and
1.2 If you choose to redistribute the whole or any part of the
Software pursuant to the licences granted in Clause 1.1(ii), you
agree: (i) not to use ARM's or any of its licensors names, logos or
trademarks to market Applications; (ii) to retain any and all
copyright notices and other notices (whether ARM's or its licensor's)
which are included with the Software; and (iii) include a copy of this
Licence with such redistribution.
2. RESTRICTIONS ON USE OF THE SOFTWARE.
BENCHMARKING: This Licence does not prevent you from using the
Software for benchmarking purposes. However, you shall ensure that any
and all benchmarking data relating to the Software, and any other
results of your use or testing of the Software which are indicative of
its performance, efficacy, reliability or quality, shall not be used
to disparage ARM, its products or services, or in a manner that, in
ARM's reasonable judgment, may diminish or otherwise damage the
reputation of ARM.
COPYRIGHT AND RESERVATION OF RIGHTS: The Software is owned by ARM or
its licensors and is protected by copyright and other intellectual
property laws and international treaties. The Software is licensed not
sold. You acquire no rights to the Software other than as expressly
provided by this Licence. You shall not remove from the Software any
copyright notice or other notice and shall ensure that any such notice
is reproduced in any copies of the whole or any part of the Software
made by you or other permitted users.
REVERSE ENGINEERING: Except to the extent that such activity is
permitted by applicable law you shall not reverse engineer, decompile
or disassemble any of the Software. If the Software was provided to
you in Europe you shall not reverse engineer, decompile or disassemble
any of the Software for the purposes of error correction.
RESTRICTED USE: You agree that you shall not use the Software or the
Output other than pursuant to and in accordance with the exercise of
any of the licences granted under this Licence. Without limiting the
generality of the foregoing, you shall not use the Software or any
Output: (a) for determining if any features, functions or processes
provided by the Software are covered by any patents or patent
applications owned by you or a third party; or (b) for developing
technology, applications or products which avoid any of ARM's
intellectual property in the Software licensed hereunder; or (c) as a
reference for modifying existing patents or patent applications or
creating any continuation, continuation in part, or extension of
existing patents or patent applications.
3. SUPPORT.
ARM is not under an obligation to provide support, but it may do so at
its own discretion, and if it does, it will only be in respect of the
Software as delivered.
4. NO WARRANTIES.
YOU AGREE THAT THE SOFTWARE IS LICENSED "AS IS", AND THAT ARM
EXPRESSLY DISCLAIMS ALL REPRESENTATIONS, WARRANTIES, CONDITIONS OR
OTHER TERMS, EXPRESS OR IMPLIED OR STATUTORY, INCLUDING WITHOUT
LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, SATISFACTORY
QUALITY, AND FITNESS FOR A PARTICULAR PURPOSE.
YOU EXPRESSLY ASSUME ALL LIABILITIES AND RISKS, FOR USE OR OPERATION
OF APPLICATIONS, INCLUDING WITHOUT LIMITATION, APPLICATIONS DESIGNED
OR INTENDED FOR MISSION CRITICAL APPLICATIONS, SUCH AS PACEMAKERS,
WEAPONRY, AIRCRAFT NAVIGATION, FACTORY CONTROL SYSTEMS, ETC. SHOULD
THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE ENTIRE COST OF ALL
NECESSARY SERVICING, REPAIR OR CORRECTION.
5. LIMITATION OF LIABILITY.
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
ARM BE LIABLE FOR ANY INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
DAMAGES (INCLUDING LOSS OF PROFITS) ARISING OUT OF THE USE OR
INABILITY TO USE THE SOFTWARE WHETHER BASED ON A CLAIM UNDER CONTRACT,
TORT OR OTHER LEGAL THEORY, EVEN IF ARM WAS ADVISED OF THE POSSIBILITY
OF SUCH DAMAGES.
ARM does not seek to limit or exclude liability for death or personal
injury arising from ARM's negligence or ARM's fraud and because some
jurisdictions do not permit the exclusion or limitation of liability
for consequential or incidental damages the above limitation relating
to liability for consequential damages may not apply to you.
NOTWITHSTANDING ANYTHING TO THE CONTRARY CONTAINED IN THIS LICENCE,
THE MAXIMUM LIABILITY OF ARM TO YOU IN AGGREGATE FOR ALL CLAIMS MADE
AGAINST ARM IN CONTRACT TORT OR OTHERWISE UNDER OR IN CONNECTION WITH
THE SUBJECT MATTER OF THIS LICENCE SHALL NOT EXCEED THE GREATER OF:
(I) THE TOTAL OF SUMS PAID BY YOU TO ARM (IF ANY) FOR THIS LICENCE;
AND (II) $10.00 USD. THE EXISTENCE OF MORE THAN ONE CLAIM WILL NOT
ENLARGE OR EXTEND THE LIMIT.
6. U.S. GOVERNMENT END USERS.
US Government Restrictions: Use, duplication, reproduction, release,
modification, disclosure or transfer of the Software is restricted in
accordance with the terms of this Licence.
7. TERM AND TERMINATION.
This Licence shall remain in force until terminated by you or by ARM.
Without prejudice to any of its other rights if you are in breach of
any of the terms and conditions of this Licence then ARM may terminate
this Licence immediately upon giving written notice to you or on
thirty (30) days written notice without cause. You may terminate this
Licence at any time. Upon termination of this Licence by you or by ARM
, you shall stop using the Software and destroy all copies of the
Software in your possession, together with all documentation and
related materials. The provisions of clauses 2, 3, 4, 5, 6, 7, and 8
shall survive termination of this Licence.
8. GENERAL.
This Licence is governed by English Law. Except where ARM agrees
otherwise in: (i) a written contract signed by you and ARM; or (ii) a
written contract provided by ARM and accepted by you, this is the only
agreement between you and ARM relating to the Software and it may only
be modified by written agreement between you and ARM. Except as
expressly agreed in writing, this Licence may not be modified by
purchase orders, advertising or other representation by any person. If
any clause or sentence in this Licence is held by a court of law to be
illegal or unenforceable the remaining provisions of this Licence
shall not be affected thereby. The failure by ARM to enforce any of
the provisions of this Licence, unless waived in writing, shall not
constitute a waiver of ARM's rights to enforce such provision or any
other provision of this Licence in the future.
At ARM's request, you agree to check your computers for installations
of the Software and any other information requested by ARM relating to
Software installation and to provide this information to ARM. You
agree that auditors nominated by ARM may also perform such checking
and reporting on behalf of ARM by prior appointment during your normal
business hours on seven (7) days' notice. ARM shall bear the auditors'
costs for that audit unless it reveals unlicensed usage in which case
you shall promptly reimburse ARM for all reasonable costs and
expenses, including professional fees, relating to such audit. Any
information which is disclosed to ARM or such auditors during checking
or audit shall be treated as your confidential information and shall
only be used by ARM for licence management, compliance and enforcement
purposes.
The Software provided under this Agreement is subject to U.K.,
European Union, and U.S. export control laws and regulations,
including the U.S. Export Administration Act and its associated
regulations (hereafter collectively referred to as "Export
Regulations"). LICENSEE agrees to comply fully with all such Export
Regulations and LICENSEE agrees that it shall not, either directly or
indirectly, export in breach of the Export Regulations, any Software
received under this Agreement, nor any direct products thereof; (i) to
any country, company or person subject to export restrictions or
sanctions under the Export Regulations; or (ii) for any prohibited end
use, which at the time of export requires an export license or other
governmental approval, without first obtaining such license or
approval.

View File

@ -0,0 +1,17 @@
this is Android GPU Library
GPU_TARGET_PLATFORM is the same as the Kernel.
cpu kernel android GPU_TARGET_PLATFORM
cortex-a9 32bit 32bit default_7a
cortex-a53 32bit 32bit default_7a
cortex-a53 64bit 32bit default_8a
cortex-a53 64bit 64bit default_8a
GPU_TARGET_PLATFORM?= default_7a
library symbols was put at
ftp://ftp-china.amlogic.com/mbox/gpu-lib/
ddk git
git clone ssh://android@10.8.9.5/platform/hardware/gpu/mali/ddk -b aml-64bit-r5p1

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,46 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* 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 _BDROID_BUILDCFG_H
#define _BDROID_BUILDCFG_H
#define BTA_DM_COD \
{ 0x2C, 0x04, 0x14 }
#define BTA_AV_SINK_INCLUDED TRUE
#define BLE_VND_INCLUDED TRUE
// Turn off BLE_LOCAL_PRIVACY_ENABLED. Remote reconnect fails on
// often if this is enabled.
#define BLE_LOCAL_PRIVACY_ENABLED FALSE
/* minimum acceptable connection interval */
#define BTM_BLE_CONN_INT_MIN_LIMIT 0x0006 /*7.5ms=6*1.25*/
/*fix bt crash about init */
#define KERNEL_MISSING_CLOCK_BOOTTIME_ALARM TRUE
#define BTM_BLE_CONN_INT_MIN_DEF 6
#define BTM_BLE_CONN_INT_MAX_DEF 12
#define BTM_BLE_SCAN_SLOW_INT_1 64
#define BTM_BLE_SCAN_SLOW_WIN_1 16
#define BTA_SKIP_BLE_READ_REMOTE_FEAT TRUE
#define BLE_DELAY_REQUEST_ENC TRUE
#define BTA_AV_SINK_INCLUDED TRUE
#endif

View File

@ -0,0 +1,51 @@
Build Yukawa userdebug image:
=============================
$ . ./build/envsetup.sh
$ lunch yukawa-userdebug
$ make -j24
- For VIM3L: make TARGET_VIM3L=true -j24
Compile Kernel:
===============
$ git clone https://android.googlesource.com/kernel/hikey-linaro
$ export PATH=$ANDROID_BUILD_TOP/prebuilts/clang/host/linux-x86/clang-r365631c/bin:$PATH
$ cd hikey-linaro
$ git checkout -b android-amlogic-bmeson-4.19 origin/android-amlogic-bmeson-4.19
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- CLANG_TRIPLE=aarch64-linux-gnu- CC=clang meson_defconfig
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- CLANG_TRIPLE=aarch64-linux-gnu- CC=clang -j24
$ lz4c -f arch/arm64/boot/Image arch/arm64/boot/Image.lz4
$ cp arch/arm64/boot/Image.lz4 $ANDROID_BUILD_TOP/device/amlogic/yukawa-kernel
$ cp arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dtb $ANDROID_BUILD_TOP/device/amlogic/yukawa-kernel
$ cp arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dtb $ANDROID_BUILD_TOP/device/amlogic/yukawa-kernel
$ cp arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dtb $ANDROID_BUILD_TOP/device/amlogic/yukawa-kernel
$ cd <Path-to-AOSP>; rm out/target/product/yukawa/boot.img out/target/product/yukawa/kernel
$ make bootimage -j24
$ fastboot flash boot out/target/product/yukawa/boot.img
- For VIM3L: make TARGET_VIM3L=true bootimage -j24
- If yukawa-userdebug build was not launched, set direct path to aarch64:
$ export PATH=$ANDROID_BUILD_TOP/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin:$PATH
Recover Bootloader:
===================
Link to 'update' utility: https://github.com/khadas/utils/tree/master/aml-flash-tool/tools/linux-x86
- Enter USB recovery mode by pressing USB Boot Button and turning Power ON
- For VIM3L:
-- Use u-boot_kvim3l_noab.bin rather than u-boot_sei610.bin.
-- Enter recovery / upgrade mode by pressing function button 3 times in 2s.
$ update write u-boot_sei610.bin 0xfffa0000 0x10000
$ update run 0xfffa0000
$ update bl2_boot u-boot_sei610.bin
$ fastboot oem format
$ fastboot flash bootloader u-boot_sei610.bin
$ fastboot erase bootenv
$ fastboot reboot-bootloader

View File

@ -0,0 +1,2 @@
require board=sei510
require version-bootloader=U-Boot 2021.07-00051-g79f19c6307

View File

@ -0,0 +1,2 @@
require board=sei610
require version-bootloader=U-Boot 2021.07-00051-g79f19c6307

View File

@ -0,0 +1,2 @@
require board=vim3
require version-bootloader=U-Boot 2021.07-00051-g79f19c6307

View File

@ -0,0 +1,2 @@
require board=vim3l
require version-bootloader=U-Boot 2021.07-00051-g79f19c6307

View File

@ -0,0 +1,80 @@
Build Mainline u-boot - bl33:
=============================
Main Wiki Page : https://gitlab.com/baylibre/amlogic/atv/u-boot/wikis/home
Download the toolchain : gcc-linaro-7.2.1-2017.11-x86_64_aarch64-elf
http://releases.linaro.org/components/toolchain/binaries/7.2-2017.11/aarch64-elf/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-elf.tar.xz
Download U-Boot Source Code From :
https://gitlab.com/baylibre/amlogic/atv/u-boot.git
actual tag : u-boot/v2021.07/integ-20210712
dev branch : u-boot/v2021.07/integ
link to U-Boot aosp release wiki page :
https://gitlab.com/baylibre/amlogic/atv/u-boot/wikis/U-Boot-for-Yukawa-Release
Compile:
export PATH=<path-to-toolchain>/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-elf/bin:$PATH
export CROSS_COMPILE=aarch64-elf-
git clone https://gitlab.com/baylibre/amlogic/atv/u-boot.git
cd u-boot
git checkout u-boot/v2021.07/integ-20210712
make [sei510|sei610|sei610_ab|khadas-vim3_android|khadas-vim3_android_ab|khadas-vim3l_android|khadas-vim3l_android_ab]_defconfig
make
Generate fip binary
===================
use tarball in fip_packages folder and untar it
- For sei510 (yukawa_sei510):
tar -xaf fip-collect-g12a-g12a_u200_v1-amlogic-dev_9.2.1811_21-20191203-113239.tar.gz
- For sei610 (yukawa):
tar -xaf fip-collect-g12a-sm1_ac214_v1-amlogic-dev_9.2.1811_21-20191204-161855.tar.gz
- For VIM3L (yukawa):
tar -xaf fip-collect-g12a-kvim3l-khadas-vims-pie-20210111-211224.tar.gz
- For VIM3 (yukawa):
tar -xaf fip-collect-g12b-kvim3-khadas-vims-pie-20210111-211833.tar.gz
Then launch script for scripts folder:
./generate-bins-new.sh <fip-collect-directory> <target-bl33-binary>
flash result with:
fastboot flash bootloader uboot-bins/u-boot.bin
fastboot erase bootenv
fastboot reboot bootloader
after reboot if partitions table need to be updated:
fastboot oem format
More informations to update and flash bootloader on Yukawa:
https://gitlab.com/baylibre/amlogic/atv/u-boot/wikis/U-Boot-for-Yukawa
Generate new fip_packages for Khadas VIM3/3L
=============================================
- Launch collect script for script foler :
./collect-khadas_binaries-git-refboard.sh <khadas-uboot-branch> <soc> <refboard>
branch to use for VIM3/3L : khadas-vims-pie
soc VIM3 : g12b
VIM3L: sm1
refboard VIM3 : kvim3
VIM3L: kvim3l
- Generate tarball :
Example:
tar -czf fip-collect-g12b-kvim3-khadas-vims-pie-20210111-211833.tar.gz fip-collect-g12b-kvim3-khadas-vims-pie-20210111-211833
Adapt folder name with folder generate by collect script.
- to generate fip bin cf "Generate fip binary"

View File

@ -0,0 +1,121 @@
#!/usr/bin/env bash
set -o errexit
set -o pipefail
set -o nounset
set -o xtrace
# The goal of this script is gather all binaries provides by AML in order to generate
# our final u-boot image from the u-boot.bin (bl33)
#
# Some binaries come from the u-boot vendor kernel (bl21, acs, bl301)
# Others from the buildroot package (aml_encrypt tool, bl2.bin, bl30)
function usage() {
echo "Usage: $0 [openlinux branch] [soc] [refboard]"
}
if [[ $# -lt 3 ]]
then
usage
exit 22
fi
GITBRANCH=${1}
SOCFAMILY=${2}
REFBOARD=${3}
if [[ "$SOCFAMILY" == "sm1" ]]
then
SOCFAMILY="g12a"
fi
if ! [[ "$SOCFAMILY" == "g12a" || "$SOCFAMILY" == "g12b" || "$SOCFAMILY" == "sm1" ]]
then
echo "${SOCFAMILY} is not supported - should be [g12a, g12b, sm1]"
usage
exit 22
fi
BIN_LIST="$SOCFAMILY/bl2.bin \
$SOCFAMILY/bl30.bin \
$SOCFAMILY/bl31.bin \
$SOCFAMILY/bl31.img \
$SOCFAMILY/aml_encrypt_$SOCFAMILY "
FW_LIST="$SOCFAMILY/*.fw"
# path to clone the openlinux repos
TMP_GIT=$(mktemp -d)
TMP="fip-collect-${SOCFAMILY}-${REFBOARD}-${GITBRANCH}-$(date +%Y%m%d-%H%M%S)"
mkdir $TMP
# U-Boot
git clone --depth=2 https://github.com/khadas/u-boot -b $GITBRANCH $TMP_GIT/u-boot
mkdir $TMP_GIT/gcc-linaro-aarch64-none-elf
wget -qO- https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz | tar -xJ --strip-components=1 -C $TMP_GIT/gcc-linaro-aarch64-none-elf
mkdir $TMP_GIT/gcc-linaro-arm-none-eabi
wget -qO- https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz | tar -xJ --strip-components=1 -C $TMP_GIT/gcc-linaro-arm-none-eabi
sed -i "s,/opt/gcc-.*/bin/,," $TMP_GIT/u-boot/Makefile
(
cd $TMP_GIT/u-boot
make ${REFBOARD}_defconfig
PATH=$TMP_GIT/gcc-linaro-aarch64-none-elf/bin:$TMP_GIT/gcc-linaro-arm-none-eabi/bin:$PATH CROSS_COMPILE=aarch64-none-elf- make -j8 > /dev/null
cd fip/tools/ddr_parse && make clean && make
)
cp $TMP_GIT/u-boot/build/board/khadas/*/firmware/acs.bin $TMP/
cp $TMP_GIT/u-boot/build/scp_task/bl301.bin $TMP/
# cp $TMP_GIT/u-boot/fip/tools/ddr_parse/parse $TMP/
$TMP_GIT/u-boot/fip/tools/ddr_parse/parse ${TMP}/acs.bin
# FIP/BLX
echo $BIN_LIST
for item in $BIN_LIST
do
BIN=$(echo $item)
DIR1=$TMP_GIT/u-boot/$(basename --suffix=.bin $item)/bin/
DIR2=$TMP_GIT/u-boot/$(basename --suffix=.img $item)_1.3/bin/
DIR21=$TMP_GIT/u-boot/$(basename --suffix=.bin $item)_1.3/bin/
DIR22=$TMP_GIT/u-boot/$(basename --suffix=.img $item)_1.3/bin/
BRANCH=$GITBRANCH
if [[ -d $DIR1/$SOCFAMILY/ ]]
then
cp $DIR1/$BIN ${TMP}
elif [[ -d $DIR2/$SOCFAMILY/ ]]
then
cp $DIR2/$BIN ${TMP}
elif [[ -d $DIR21/$SOCFAMILY/ ]]
then
cp $DIR21/$BIN ${TMP}
elif [[ -d $DIR22/$SOCFAMILY/ ]]
then
cp $DIR22/$BIN ${TMP}
fi
done
echo $FW_LIST
cp $TMP_GIT/u-boot/fip/$FW_LIST ${TMP}
# Normalize
mv $TMP_GIT/u-boot/fip/$SOCFAMILY/aml_encrypt_$SOCFAMILY $TMP/aml_encrypt
date > $TMP/info.txt
echo "SOC: $SOCFAMILY" >> $TMP/info.txt
echo "BRANCH: $GITBRANCH ($(date +%Y%m%d))" >> $TMP/info.txt
for component in $TMP_GIT/*
do
if [[ -d $component/.git ]]
then
echo "$(basename $component): $(git --git-dir=$component/.git log --pretty=format:%H HEAD~1..HEAD)" >> $TMP/info.txt
fi
done
echo "BOARD: $REFBOARD" >> $TMP/info.txt
echo "export SOCFAMILY=$SOCFAMILY" > $TMP/soc-var.sh
rm -rf ${TMP_GIT}

View File

@ -0,0 +1,158 @@
#!/usr/bin/env bash
#1 is the Amlogic fip directory
#2 is u-boot directory
set -o errexit
set -o pipefail
set -o nounset
set -o xtrace
function fix_blx() {
#bl2 file size 41K, bl21 file size 3K (file size not equal runtime size)
#total 44K
#after encrypt process, bl2 add 4K header, cut off 4K tail
#bl30 limit 41K
#bl301 limit 12K
#bl2 limit 41K
#bl21 limit 3K, but encrypt tool need 48K bl2.bin, so fix to 7168byte.
declare blx_bin_limit=0
declare blx01_bin_limit=0
declare -i blx_size=0
declare -i zero_size=0
#$7:name flag
if [ "$7" = "bl30" ]; then
if [ -e ${FIPDIR}/lpddr3_1d.fw -a "$SOCFAMILY" = "g12a" ]; then
blx_bin_limit=47104 # VIM3L
else
blx_bin_limit=40960 # PD#132613 2016-10-31 update, 41984->40960
fi
blx01_bin_limit=13312 # PD#132613 2016-10-31 update, 12288->13312
elif [ "$7" = "bl2" ]; then
if [ "$SOCFAMILY" = "g12a" -o "$SOCFAMILY" = "sm1" -o "$SOCFAMILY" = "g12b" ]; then
blx_bin_limit=57344
blx01_bin_limit=4096
else
blx_bin_limit=41984
blx01_bin_limit=7168
fi
else
echo "blx_fix name flag not supported!"
exit 1
fi
# blx_size: blx.bin size, zero_size: fill with zeros
blx_size=`du -b $1 | awk '{print int($1)}'`
zero_size=$blx_bin_limit-$blx_size
dd if=/dev/zero of=$2 bs=1 count=$zero_size
cat $1 $2 > $3
rm $2
blx_size=`du -b $4 | awk '{print int($1)}'`
zero_size=$blx01_bin_limit-$blx_size
dd if=/dev/zero of=$2 bs=1 count=$zero_size
cat $4 $2 > $5
cat $3 $5 > $6
rm $2
}
FIPDIR=${1}
UBOOTBIN=${2:-u-boot.bin}
source ${FIPDIR}/soc-var.sh
TMP=$(mktemp -d)
if [ "$SOCFAMILY" = "gxl" ]
then
fix_blx ${FIPDIR}/bl30.bin ${TMP}/zero_tmp ${TMP}/bl30_zero.bin ${FIPDIR}/bl301.bin ${TMP}/bl301_zero.bin ${TMP}/bl30_new.bin bl30
/usr/bin/env python2 ${FIPDIR}/acs_tool.pyc ${FIPDIR}/bl2.bin ${TMP}/bl2_acs.bin ${FIPDIR}/acs.bin 0
fix_blx ${TMP}/bl2_acs.bin ${TMP}/zero_tmp ${TMP}/bl2_zero.bin ${FIPDIR}/bl21.bin ${TMP}/bl21_zero.bin ${TMP}/bl2_new.bin bl2
${FIPDIR}/aml_encrypt --bl3enc --input ${TMP}/bl30_new.bin --output ${TMP}/bl30_new.bin.enc
${FIPDIR}/aml_encrypt --bl3enc --input ${FIPDIR}/bl31.img --output ${TMP}/bl31.img.enc
${FIPDIR}/aml_encrypt --bl3enc --input ${UBOOTBIN} --output ${TMP}/bl33.bin.enc
${FIPDIR}/aml_encrypt --bl2sig --input ${TMP}/bl2_new.bin --output ${TMP}/bl2.n.bin.sig
${FIPDIR}/aml_encrypt --bootmk --output ${TMP}/u-boot.bin \
--bl2 ${TMP}/bl2.n.bin.sig \
--bl30 ${TMP}/bl30_new.bin.enc \
--bl31 ${TMP}/bl31.img.enc \
--bl33 ${TMP}/bl33.bin.enc
elif [ "$SOCFAMILY" = "axg" ]
then
fix_blx ${FIPDIR}/bl30.bin ${TMP}/zero_tmp ${TMP}/bl30_zero.bin ${FIPDIR}/bl301.bin ${TMP}/bl301_zero.bin ${TMP}/bl30_new.bin bl30
/usr/bin/env python2 ${FIPDIR}/acs_tool.pyc ${FIPDIR}/bl2.bin ${TMP}/bl2_acs.bin ${FIPDIR}/acs.bin 0
fix_blx ${TMP}/bl2_acs.bin ${TMP}/zero_tmp ${TMP}/bl2_zero.bin ${FIPDIR}/bl21.bin ${TMP}/bl21_zero.bin ${TMP}/bl2_new.bin bl2
${FIPDIR}/aml_encrypt --bl3sig --input ${TMP}/bl30_new.bin --output ${TMP}/bl30_new.bin.enc --level v3 --type bl30
${FIPDIR}/aml_encrypt --bl3sig --input ${FIPDIR}/bl31.img --output ${TMP}/bl31.img.enc --level v3 --type bl31
${FIPDIR}/aml_encrypt --bl3sig --input ${UBOOTBIN} --output ${TMP}/bl33.bin.enc --level v3 --type bl33 --compress lz4
${FIPDIR}/aml_encrypt --bl2sig --input ${TMP}/bl2_new.bin --output ${TMP}/bl2.n.bin.sig
${FIPDIR}/aml_encrypt --bootmk --output ${TMP}/u-boot.bin \
--bl2 ${TMP}/bl2.n.bin.sig \
--bl30 ${TMP}/bl30_new.bin.enc \
--bl31 ${TMP}/bl31.img.enc \
--bl33 ${TMP}/bl33.bin.enc \
--level v3
elif [ "$SOCFAMILY" = "g12a" -o "$SOCFAMILY" = "sm1" -o "$SOCFAMILY" = "g12b" ]
then
cp ${FIPDIR}/acs.bin ${TMP}/acs.bin
[ -e ${FIPDIR}/parse ] && ${FIPDIR}/parse ${TMP}/acs.bin
fix_blx ${FIPDIR}/bl30.bin ${TMP}/zero_tmp ${TMP}/bl30_zero.bin ${FIPDIR}/bl301.bin ${TMP}/bl301_zero.bin ${TMP}/bl30_new.bin bl30
fix_blx ${FIPDIR}/bl2.bin ${TMP}/zero_tmp ${TMP}/bl2_zero.bin ${TMP}/acs.bin ${TMP}/bl21_zero.bin ${TMP}/bl2_new.bin bl2
${FIPDIR}/aml_encrypt --bl30sig --input ${TMP}/bl30_new.bin --output ${TMP}/bl30_new.bin.g12.enc --level v3
${FIPDIR}/aml_encrypt --bl3sig --input ${TMP}/bl30_new.bin.g12.enc --output ${TMP}/bl30_new.bin.enc --level v3 --type bl30
${FIPDIR}/aml_encrypt --bl3sig --input ${FIPDIR}/bl31.img --output ${TMP}/bl31.img.enc --level v3 --type bl31
${FIPDIR}/aml_encrypt --bl3sig --input ${UBOOTBIN} --compress lz4 --output ${TMP}/bl33.bin.enc --level v3 --type bl33
${FIPDIR}/aml_encrypt --bl2sig --input ${TMP}/bl2_new.bin --output ${TMP}/bl2.n.bin.sig
if [ -e ${FIPDIR}/lpddr3_1d.fw ]
then
${FIPDIR}/aml_encrypt --bootmk --output ${TMP}/u-boot.bin \
--bl2 ${TMP}/bl2.n.bin.sig \
--bl30 ${TMP}/bl30_new.bin.enc \
--bl31 ${TMP}/bl31.img.enc \
--bl33 ${TMP}/bl33.bin.enc \
--ddrfw1 ${FIPDIR}/ddr4_1d.fw \
--ddrfw2 ${FIPDIR}/ddr4_2d.fw \
--ddrfw3 ${FIPDIR}/ddr3_1d.fw \
--ddrfw4 ${FIPDIR}/piei.fw \
--ddrfw5 ${FIPDIR}/lpddr4_1d.fw \
--ddrfw6 ${FIPDIR}/lpddr4_2d.fw \
--ddrfw7 ${FIPDIR}/diag_lpddr4.fw \
--ddrfw8 ${FIPDIR}/aml_ddr.fw \
--ddrfw9 ${FIPDIR}/lpddr3_1d.fw \
--level v3
else
${FIPDIR}/aml_encrypt --bootmk --output ${TMP}/u-boot.bin \
--bl2 ${TMP}/bl2.n.bin.sig \
--bl30 ${TMP}/bl30_new.bin.enc \
--bl31 ${TMP}/bl31.img.enc \
--bl33 ${TMP}/bl33.bin.enc \
--ddrfw1 ${FIPDIR}/ddr4_1d.fw \
--ddrfw2 ${FIPDIR}/ddr4_2d.fw \
--ddrfw3 ${FIPDIR}/ddr3_1d.fw \
--ddrfw4 ${FIPDIR}/piei.fw \
--ddrfw5 ${FIPDIR}/lpddr4_1d.fw \
--ddrfw6 ${FIPDIR}/lpddr4_2d.fw \
--ddrfw7 ${FIPDIR}/diag_lpddr4.fw \
--ddrfw8 ${FIPDIR}/aml_ddr.fw \
--level v3
fi
else
echo "${SOCFAMILY} is not supported - should be [gxl, axg, g12a, sm1, g12b]"
exit 22
fi
TMP2="uboot-bins-$(date +%Y%m%d-%H%M%S)"
mkdir $TMP2
ln -sfn $TMP2 uboot-bins
mv ${TMP}/u-boot.bin{,.sd.bin,.usb.bl2,.usb.tpl} ${TMP2}
rm -r ${TMP}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,54 @@
# Use this file to generate dtb.img and dtbo.img instead of using
# BOARD_PREBUILT_DTBIMAGE_DIR. We need to keep dtb and dtbo files at the fixed
# positions in images, so that bootloader can rely on their indexes in the
# image. As dtbo.img must be signed with AVB tool, we generate intermediate
# dtbo.img, and the resulting $(PRODUCT_OUT)/dtbo.img will be created with
# Android build system, by exploiting BOARD_PREBUILT_DTBOIMAGE variable.
ifneq ($(filter yukawa%, $(TARGET_DEVICE)),)
MKDTIMG := system/libufdt/utils/src/mkdtboimg.py
DTBIMAGE := $(PRODUCT_OUT)/dtb.img
DTBOIMAGE := $(PRODUCT_OUT)/$(DTBO_UNSIGNED)
# Please keep this list fixed: add new files in the end of the list
DTB_FILES := \
$(LOCAL_DTB)/meson-g12a-sei510.dtb \
$(LOCAL_DTB)/meson-sm1-sei610.dtb \
$(LOCAL_DTB)/meson-sm1-khadas-vim3l.dtb \
$(LOCAL_DTB)/meson-g12b-a311d-khadas-vim3.dtb
# Please keep this list fixed: add new files in the end of the list
DTBO_FILES := \
$(LOCAL_DTB)/meson-g12a-sei510-android.dtb \
$(LOCAL_DTB)/meson-sm1-sei610-android.dtb \
$(LOCAL_DTB)/meson-sm1-khadas-vim3l-android.dtb \
$(LOCAL_DTB)/meson-g12b-a311d-khadas-vim3-android.dtb \
$(DTBIMAGE): $(DTB_FILES)
cat $^ > $@
$(DTBOIMAGE): PRIVATE_MKDTIMG := $(MKDTIMG)
$(DTBOIMAGE): PRIVATE_DTBO_FILES := $(DTBO_FILES)
$(DTBOIMAGE): $(DTBO_FILES) $(MKDTIMG)
$(PRIVATE_MKDTIMG) create $@ $(PRIVATE_DTBO_FILES)
include $(CLEAR_VARS)
LOCAL_MODULE := dtbimage
LOCAL_LICENSE_KINDS := legacy_restricted
LOCAL_LICENSE_CONDITIONS := restricted
LOCAL_ADDITIONAL_DEPENDENCIES := $(DTBIMAGE)
include $(BUILD_PHONY_PACKAGE)
include $(CLEAR_VARS)
LOCAL_MODULE := dtboimage
LOCAL_LICENSE_KINDS := legacy_restricted
LOCAL_LICENSE_CONDITIONS := restricted
LOCAL_ADDITIONAL_DEPENDENCIES := $(DTBOIMAGE)
include $(BUILD_PHONY_PACKAGE)
droidcore: dtbimage dtboimage
$(call dist-for-goals, dist_files, $(DTBOIMAGE))
endif

View File

@ -0,0 +1,58 @@
<compatibility-matrix version="1.0" type="device">
<hal format="hidl" optional="false">
<name>android.frameworks.displayservice</name>
<version>1.0</version>
<interface>
<name>IDisplayService</name>
<instance>default</instance>
</interface>
</hal>
<hal format="hidl" optional="false">
<name>android.frameworks.sensorservice</name>
<version>1.0</version>
<interface>
<name>ISensorManager</name>
<instance>default</instance>
</interface>
</hal>
<hal format="hidl" optional="false">
<name>android.hidl.manager</name>
<version>1.2</version>
<interface>
<name>IServiceManager</name>
<instance>default</instance>
</interface>
</hal>
<hal format="hidl" optional="true">
<name>android.hidl.memory</name>
<version>1.0</version>
<interface>
<name>IMapper</name>
<instance>ashmem</instance>
</interface>
</hal>
<hal format="hidl" optional="false">
<name>android.hidl.token</name>
<version>1.0</version>
<interface>
<name>ITokenManager</name>
<instance>default</instance>
</interface>
</hal>
<hal format="hidl" optional="false">
<name>android.system.net.netd</name>
<version>1.1</version>
<interface>
<name>INetd</name>
<instance>default</instance>
</interface>
</hal>
<hal format="hidl" optional="false">
<name>android.system.wifi.keystore</name>
<version>1.0</version>
<interface>
<name>IKeystore</name>
<instance>default</instance>
</interface>
</hal>
</compatibility-matrix>

View File

@ -0,0 +1,385 @@
PRODUCT_SOONG_NAMESPACES += device/amlogic/yukawa
ifeq ($(TARGET_PREBUILT_KERNEL),)
LOCAL_KERNEL := device/amlogic/yukawa-kernel/$(TARGET_KERNEL_USE)/Image.lz4
else
LOCAL_KERNEL := $(TARGET_PREBUILT_KERNEL)
endif
PRODUCT_COPY_FILES += $(LOCAL_KERNEL):kernel
# Build and run only ART
PRODUCT_RUNTIMES := runtime_libart_default
# Enable updating of APEXes
$(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk)
# Enable Scoped Storage related
$(call inherit-product, $(SRC_TARGET_DIR)/product/emulated_storage.mk)
DEVICE_PACKAGE_OVERLAYS := device/amlogic/yukawa/overlay
ifeq ($(TARGET_USE_TABLET_LAUNCHER), true)
# Setup tablet build
$(call inherit-product, frameworks/native/build/tablet-10in-xhdpi-2048-dalvik-heap.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/full_base.mk)
else
# Setup TV Build
USE_OEM_TV_APP := true
$(call inherit-product, device/google/atv/products/atv_base.mk)
PRODUCT_CHARACTERISTICS := tv
PRODUCT_AAPT_PREF_CONFIG := tvdpi
PRODUCT_IS_ATV := true
endif
PRODUCT_PACKAGES += llkd
ifeq ($(TARGET_USE_AB_SLOT), true)
# A/B support
PRODUCT_PACKAGES += \
otapreopt_script \
cppreopts.sh \
update_engine \
update_verifier
AB_OTA_POSTINSTALL_CONFIG += \
RUN_POSTINSTALm=true \
POSTINSTALL_PATH=system/bin/otapreopt_script \
FILESYSTEM_TYPE=ext4 \
POSTINSTALL_OPTIONAL=true
PRODUCT_PACKAGES += \
update_engine_sideload \
sg_write_buffer \
f2fs_io
# The following modules are included in debuggable builds only.
PRODUCT_PACKAGES_DEBUG += \
bootctl \
update_engine_client
# Write flags to the vendor space in /misc partition.
PRODUCT_PACKAGES += \
misc_writer
PRODUCT_PACKAGES += \
fs_config_dirs \
fs_config_files
# Boot control
PRODUCT_PACKAGES += \
android.hardware.boot@1.2-impl \
android.hardware.boot@1.2-impl.recovery \
android.hardware.boot@1.2-service \
bootctrl.yukawa.recovery \
bootctrl.yukawa
endif
# Dynamic partitions
PRODUCT_BUILD_SUPER_PARTITION := true
PRODUCT_USE_DYNAMIC_PARTITIONS := true
PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true
PRODUCT_PACKAGES += \
android.hardware.fastboot@1.0 \
android.hardware.fastboot@1.0-impl-mock \
fastbootd
# All VNDK libraries (HAL interfaces, VNDK, VNDK-SP, LL-NDK)
PRODUCT_PACKAGES += vndk_package
PRODUCT_PACKAGES += \
android.hardware.health@2.1-impl-cuttlefish \
android.hardware.health@2.1-service
ifeq ($(TARGET_USE_AB_SLOT), true)
ifeq ($(TARGET_AVB_ENABLE), true)
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/fstab.yukawa.avb.ab:$(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk/fstab.yukawa \
$(LOCAL_PATH)/fstab.yukawa.avb.ab:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.yukawa
else
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/fstab.yukawa.ab:$(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk/fstab.yukawa \
$(LOCAL_PATH)/fstab.yukawa.ab:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.yukawa
endif
else
ifeq ($(TARGET_AVB_ENABLE), true)
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/fstab.ramdisk.common.avb:$(TARGET_COPY_OUT_RAMDISK)/fstab.yukawa \
$(LOCAL_PATH)/fstab.yukawa:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.yukawa
else
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/fstab.ramdisk.common:$(TARGET_COPY_OUT_RAMDISK)/fstab.yukawa \
$(LOCAL_PATH)/fstab.yukawa:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.yukawa
endif
endif
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/init.yukawa.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/init.yukawa.rc \
$(LOCAL_PATH)/init.yukawa.usb.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/init.yukawa.usb.rc \
$(LOCAL_PATH)/init.recovery.hardware.rc:recovery/root/init.recovery.yukawa.rc \
$(LOCAL_PATH)/ueventd.rc:$(TARGET_COPY_OUT_VENDOR)/ueventd.rc \
$(LOCAL_PATH)/wifi/wpa_supplicant.conf:$(TARGET_COPY_OUT_VENDOR)/etc/wifi/wpa_supplicant.conf \
$(LOCAL_PATH)/wifi/wpa_supplicant_overlay.conf:$(TARGET_COPY_OUT_VENDOR)/etc/wifi/wpa_supplicant_overlay.conf \
$(LOCAL_PATH)/wifi/p2p_supplicant_overlay.conf:$(TARGET_COPY_OUT_VENDOR)/etc/wifi/p2p_supplicant_overlay.conf
# BT and Wifi FW
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/binaries/bt-wifi-firmware/BCM.hcd:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/BCM4359C0.hcd \
$(LOCAL_PATH)/binaries/bt-wifi-firmware/fw_bcm4359c0_ag.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/fw_bcm4359c0_ag.bin \
$(LOCAL_PATH)/binaries/bt-wifi-firmware/nvram_ap6359.txt:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/nvram.txt
ifeq ($(TARGET_USE_TABLET_LAUNCHER), true)
# Use Launcher3QuickStep
PRODUCT_PACKAGES += Launcher3QuickStep
else
ifeq ($(TARGET_USE_SAMPLE_LAUNCHER), true)
PRODUCT_PACKAGES += \
TvSampleLeanbackLauncher
endif
# TV Specific Packages
PRODUCT_PACKAGES += \
LiveTv \
google-tv-pairing-protocol \
LeanbackSampleApp \
tv_input.default \
com.android.media.tv.remoteprovider \
InputDevices
PRODUCT_PACKAGES += \
LeanbackIME
ifeq (,$(filter $(TARGET_PRODUCT),yukawa_gms yukawa32_gms yukawa_sei510_gms))
PRODUCT_PACKAGES += \
TvProvision \
TVLauncherNoGms \
TVRecommendationsNoGms
endif
endif
PRODUCT_PACKAGES += \
libhidltransport \
libhwbinder
PRODUCT_PROPERTY_OVERRIDES += ro.sf.lcd_density=320
PRODUCT_PACKAGES += libGLES_mali
PRODUCT_PACKAGES += libGLES_android
# Vulkan
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.vulkan.version-1_1.xml:vendor/etc/permissions/android.hardware.vulkan.version.xml \
frameworks/native/data/etc/android.hardware.vulkan.compute-0.xml:vendor/etc/permissions/android.hardware.vulkan.compute.xml \
frameworks/native/data/etc/android.hardware.vulkan.level-1.xml:vendor/etc/permissions/android.hardware.vulkan.level.xml
PRODUCT_PACKAGES += vulkan.yukawa.so
# Bluetooth
PRODUCT_PACKAGES += android.hardware.bluetooth@1.1-service.btlinux
PRODUCT_PROPERTY_OVERRIDES += \
bluetooth.core.gap.le.privacy.enabled=false \
bluetooth.profile.asha.central.enabled=true \
bluetooth.profile.a2dp.source.enabled=true \
bluetooth.profile.avrcp.target.enabled=true \
bluetooth.profile.bap.broadcast.assist.enabled=true \
bluetooth.profile.bap.unicast.client.enabled=true \
bluetooth.profile.bas.client.enabled=true \
bluetooth.profile.ccp.server.enabled=true \
bluetooth.profile.csip.set_coordinator.enabled=true \
bluetooth.profile.gatt.enabled=true \
bluetooth.profile.hap.client.enabled=true \
bluetooth.profile.hfp.ag.enabled=true \
bluetooth.profile.hid.host.enabled=true \
bluetooth.profile.mcp.server.enabled=true \
bluetooth.profile.opp.enabled=true \
bluetooth.profile.pan.nap.enabled=true \
bluetooth.profile.pan.panu.enabled=true \
bluetooth.profile.vcp.controller.enabled=true
# Wifi
PRODUCT_PACKAGES += libwpa_client wpa_supplicant hostapd wificond wpa_cli
PRODUCT_PROPERTY_OVERRIDES += wifi.interface=wlan0 \
wifi.supplicant_scan_interval=15
# Build default bluetooth a2dp and usb audio HALs
PRODUCT_PACKAGES += \
android.hardware.bluetooth.audio@2.0-impl \
audio.usb.default \
audio.primary.yukawa \
audio.r_submix.default \
audio.bluetooth.default \
tinyplay \
tinycap \
tinymix \
tinypcminfo \
cplay
# Video
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/binaries/video_firmware/g12a_h264.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/meson/vdec/g12a_h264.bin \
$(LOCAL_PATH)/binaries/video_firmware/g12a_hevc_mmu.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/meson/vdec/g12a_hevc_mmu.bin \
$(LOCAL_PATH)/binaries/video_firmware/g12a_vp9.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/meson/vdec/g12a_vp9.bin \
$(LOCAL_PATH)/binaries/video_firmware/gxl_mpeg4_5.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/meson/vdec/gxl_mpeg4_5.bin \
$(LOCAL_PATH)/binaries/video_firmware/gxl_mpeg12.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/meson/vdec/gxl_mpeg12.bin \
$(LOCAL_PATH)/binaries/video_firmware/gxl_mjpeg.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/meson/vdec/gxl_mjpeg.bin \
$(LOCAL_PATH)/binaries/video_firmware/sm1_hevc_mmu.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/meson/vdec/sm1_hevc_mmu.bin \
$(LOCAL_PATH)/binaries/video_firmware/sm1_vp9_mmu.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/meson/vdec/sm1_vp9_mmu.bin
PRODUCT_PACKAGES += \
android.hardware.audio.service \
android.hardware.audio@7.0-impl \
android.hardware.audio.effect@7.0-impl \
android.hardware.soundtrigger@2.3-impl \
# Hardware Composer HAL
#
PRODUCT_PACKAGES += \
hwcomposer.drm_meson \
android.hardware.drm-service.widevine \
android.hardware.drm-service.clearkey
# CEC
PRODUCT_PACKAGES += \
android.hardware.tv.cec@1.0-impl \
android.hardware.tv.cec@1.0-service \
hdmi_cec.yukawa
PRODUCT_PROPERTY_OVERRIDES += ro.hdmi.device_type=4 \
persist.sys.hdmi.keep_awake=false
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/input/Generic.kl:$(TARGET_COPY_OUT_VENDOR)/usr/keylayout/Generic.kl \
frameworks/native/data/etc/android.hardware.hdmi.cec.xml:system/etc/permissions/android.hardware.hdmi.cec.xml
PRODUCT_PACKAGES += \
gralloc.yukawa \
android.hardware.graphics.composer@2.2-impl \
android.hardware.graphics.composer@2.2-service \
android.hardware.graphics.allocator@2.0-service \
android.hardware.graphics.allocator@2.0-impl \
android.hardware.graphics.mapper@2.0-impl-2.1
# PowerHAL
PRODUCT_PACKAGES += \
android.hardware.power-service.example
# PowerStats HAL
PRODUCT_PACKAGES += \
android.hardware.power.stats-service.example
# Sensor HAL
ifneq ($(TARGET_SENSOR_MEZZANINE),)
TARGET_USES_NANOHUB_SENSORHAL := true
NANOHUB_SENSORHAL_LID_STATE_ENABLED := true
NANOHUB_SENSORHAL_SENSORLIST := $(LOCAL_PATH)/sensorhal/sensorlist_$(TARGET_SENSOR_MEZZANINE).cpp
NANOHUB_SENSORHAL_DIRECT_REPORT_ENABLED := true
NANOHUB_SENSORHAL_DYNAMIC_SENSOR_EXT_ENABLED := true
PRODUCT_PACKAGES += \
context_hub.default \
sensors.yukawa \
android.hardware.sensors@1.0-service \
android.hardware.sensors@1.0-impl \
android.hardware.contexthub@1.2-service \
android.hardware.contexthub@1.2-impl
# Nanohub tools
PRODUCT_PACKAGES += stm32_flash nanoapp_cmd nanotool
PRODUCT_COPY_FILES += \
device/amlogic/yukawa/init.common.nanohub.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.nanohub.rc
# Copy sensors config file(s)
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.sensor.accelerometer.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.accelerometer.xml \
frameworks/native/data/etc/android.hardware.sensor.ambient_temperature.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.ambient_temperature.xml \
frameworks/native/data/etc/android.hardware.sensor.barometer.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.barometer.xml \
frameworks/native/data/etc/android.hardware.sensor.compass.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.compass.xml \
frameworks/native/data/etc/android.hardware.sensor.gyroscope.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.gyroscope.xml \
frameworks/native/data/etc/android.hardware.sensor.hifi_sensors.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.hifi_sensors.xml \
frameworks/native/data/etc/android.hardware.sensor.light.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.light.xml \
frameworks/native/data/etc/android.hardware.sensor.relative_humidity.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.relative_humidity.xml \
frameworks/native/data/etc/android.hardware.sensor.stepcounter.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.stepcounter.xml \
frameworks/native/data/etc/android.hardware.sensor.stepdetector.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.stepdetector.xml
# Argonkey VL53L0X proximity driver is not available yet. So we are going to copy conf file for neonkey only
ifeq ($(TARGET_SENSOR_MEZZANINE),neonkey)
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.sensor.proximity.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.proximity.xml
endif
endif
# Software Gatekeeper HAL
PRODUCT_PACKAGES += \
android.hardware.gatekeeper@1.0-service.software
PRODUCT_PACKAGES += \
android.hardware.keymaster@3.0-impl \
android.hardware.keymaster@3.0-service
# USB
PRODUCT_PACKAGES += \
android.hardware.usb@1.1-service
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.software.app_widgets.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.app_widgets.xml \
frameworks/native/data/etc/android.hardware.ethernet.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.ethernet.xml \
frameworks/native/data/etc/android.hardware.usb.accessory.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.usb.accessory.xml \
frameworks/native/data/etc/android.hardware.usb.host.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.usb.host.xml \
frameworks/native/data/etc/android.software.device_admin.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.device_admin.xml \
frameworks/native/data/etc/android.hardware.wifi.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.wifi.xml \
frameworks/native/data/etc/android.hardware.wifi.direct.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.wifi.direct.xml \
frameworks/native/data/etc/android.hardware.bluetooth.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.bluetooth.xml \
frameworks/native/data/etc/android.hardware.bluetooth_le.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.bluetooth_le.xml \
frameworks/native/data/etc/android.software.cts.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.cts.xml \
frameworks/native/data/etc/android.software.backup.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.backup.xml
# audio policy configuration
USE_XML_AUDIO_POLICY_CONF := 1
PRODUCT_COPY_FILES += \
frameworks/av/services/audiopolicy/config/a2dp_in_audio_policy_configuration_7_0.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_in_audio_policy_configuration_7_0.xml \
frameworks/av/services/audiopolicy/config/bluetooth_audio_policy_configuration_7_0.xml:$(TARGET_COPY_OUT_VENDOR)/etc/bluetooth_audio_policy_configuration_7_0.xml \
frameworks/av/services/audiopolicy/config/r_submix_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/r_submix_audio_policy_configuration.xml \
frameworks/av/services/audiopolicy/config/usb_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/usb_audio_policy_configuration.xml \
frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
frameworks/av/media/libeffects/data/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml
AUDIO_DEFAULT_OUTPUT ?= speaker
ifeq ($(AUDIO_DEFAULT_OUTPUT),hdmi)
PRODUCT_COPY_FILES += \
device/amlogic/yukawa/hal/audio/mixer_paths_hdmi_only.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
device/amlogic/yukawa/hal/audio/audio_policy_configuration_hdmi_only.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
DEVICE_PACKAGE_OVERLAYS += \
device/amlogic/yukawa/hal/audio/overlay_hdmi_only
TARGET_USE_HDMI_AUDIO ?= true
else
PRODUCT_COPY_FILES += \
device/amlogic/yukawa/hal/audio/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
device/amlogic/yukawa/hal/audio/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
endif
# Copy media codecs config file
PRODUCT_COPY_FILES += \
device/amlogic/yukawa/media_xml/media_codecs.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs.xml \
device/amlogic/yukawa/media_xml/media_profiles.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_profiles_V1_0.xml \
frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_audio.xml
# Enable BT Pairing with button BTN_0 (key 256)
PRODUCT_PACKAGES += YukawaService YukawaAndroidOverlay
PRODUCT_COPY_FILES += \
device/amlogic/yukawa/input/Vendor_0001_Product_0001.kl:$(TARGET_COPY_OUT_VENDOR)/usr/keylayout/Vendor_0001_Product_0001.kl
# Light HAL
PRODUCT_PACKAGES += \
android.hardware.light-service \
lights-yukawa
# Enable USB Camera
PRODUCT_PACKAGES += android.hardware.camera.provider@2.4-impl
PRODUCT_PACKAGES += android.hardware.camera.provider@2.4-external-service
PRODUCT_COPY_FILES += \
device/amlogic/yukawa/hal/camera/external_camera_config.xml:$(TARGET_COPY_OUT_VENDOR)/etc/external_camera_config.xml
# Include Virtualization APEX
$(call inherit-product, packages/modules/Virtualization/apex/product_packages.mk)

View File

@ -0,0 +1,45 @@
ifndef TARGET_KERNEL_USE
TARGET_KERNEL_USE := 5.10
endif
ifeq ($(TARGET_VIM3), true)
TARGET_DEV_BOARD := vim3
else ifeq ($(TARGET_VIM3L), true)
TARGET_DEV_BOARD := vim3l
else ifeq ($(TARGET_DEV_BOARD),)
TARGET_DEV_BOARD := sei610
endif
ifneq ($(filter $(TARGET_DEV_BOARD),vim3),)
AUDIO_DEFAULT_OUTPUT := hdmi
GPU_TYPE := gondul_ion
else ifneq ($(filter $(TARGET_DEV_BOARD),vim3l),)
AUDIO_DEFAULT_OUTPUT := hdmi
endif
$(call inherit-product, device/amlogic/yukawa/device-common.mk)
PRODUCT_PROPERTY_OVERRIDES += ro.product.device=$(TARGET_DEV_BOARD)
GPU_TYPE ?= dvalin_ion
BOARD_KERNEL_DTB := device/amlogic/yukawa-kernel/$(TARGET_KERNEL_USE)
ifeq ($(TARGET_PREBUILT_DTB),)
LOCAL_DTB := $(BOARD_KERNEL_DTB)
else
LOCAL_DTB := $(TARGET_PREBUILT_DTB)
endif
# Feature permissions
PRODUCT_COPY_FILES += \
device/amlogic/yukawa/permissions/yukawa.xml:/system/etc/sysconfig/yukawa.xml
# Speaker EQ
PRODUCT_COPY_FILES += \
device/amlogic/yukawa/hal/audio/speaker_eq_sei610.fir:$(TARGET_COPY_OUT_VENDOR)/etc/speaker_eq_sei610.fir
# Hotword Mic Toggle Provider
ifneq ($(filter $(TARGET_DEV_BOARD),sei610),)
PRODUCT_PACKAGES += \
YukawaHotwordMicToggleProvider
endif

View File

@ -0,0 +1,21 @@
ifndef TARGET_KERNEL_USE
TARGET_KERNEL_USE=5.10
endif
$(call inherit-product, device/amlogic/yukawa/device-common.mk)
PRODUCT_PROPERTY_OVERRIDES += ro.product.device=sei510
GPU_TYPE ?= dvalin_ion
BOARD_KERNEL_DTB := device/amlogic/yukawa-kernel/$(TARGET_KERNEL_USE)
ifeq ($(TARGET_PREBUILT_DTB),)
LOCAL_DTB := $(BOARD_KERNEL_DTB)
else
LOCAL_DTB := $(TARGET_PREBUILT_DTB)
endif
# Feature permissions
PRODUCT_COPY_FILES += \
device/amlogic/yukawa/permissions/yukawa.xml:/system/etc/sysconfig/yukawa.xml

View File

@ -0,0 +1,2 @@
system /system ext4 noatime,ro,errors=panic wait,logical,first_stage_mount
vendor /vendor ext4 noatime,ro,errors=panic wait,logical,first_stage_mount

View File

@ -0,0 +1,2 @@
system /system ext4 noatime,ro,errors=panic wait,avb=vbmeta,logical,first_stage_mount
vendor /vendor ext4 noatime,ro,errors=panic wait,avb,logical,first_stage_mount

View File

@ -0,0 +1,8 @@
system /system ext4 noatime,ro,errors=panic wait,logical,first_stage_mount
vendor /vendor ext4 noatime,ro,errors=panic wait,logical,first_stage_mount
/dev/block/platform/soc/ffe07000.mmc/by-name/userdata /data f2fs noatime,nosuid,nodev latemount,wait,check,quota,fileencryption=software,quota
/dev/block/platform/soc/ffe07000.mmc/by-name/userdata /data ext4 noatime,nosuid,nodev,nodelalloc,nomblk_io_submit,errors=panic latemount,wait,check,quota,formattable,reservedsize=32M
/dev/block/platform/soc/ffe07000.mmc/by-name/cache /cache ext4 noatime,nosuid,nodev,nodelalloc,nomblk_io_submit,errors=panic latemount,wait,check,formattable
/dev/block/platform/soc/ffe07000.mmc/by-name/misc /misc emmc defaults defaults
/dev/block/platform/soc/ffe07000.mmc/by-name/recovery /recovery emmc defaults defaults
/dev/block/platform/soc/ffe07000.mmc/by-name/boot /boot emmc defaults defaults

View File

@ -0,0 +1,8 @@
system /system ext4 noatime,ro,errors=panic wait,avb=vbmeta,logical,first_stage_mount
vendor /vendor ext4 noatime,ro,errors=panic wait,avb,logical,first_stage_mount
/dev/block/platform/soc/ffe07000.mmc/by-name/userdata /data f2fs noatime,nosuid,nodev latemount,wait,check,quota,fileencryption=software,quota
/dev/block/platform/soc/ffe07000.mmc/by-name/userdata /data ext4 noatime,nosuid,nodev,nodelalloc,nomblk_io_submit,errors=panic latemount,wait,check,quota,formattable,reservedsize=32M
/dev/block/platform/soc/ffe07000.mmc/by-name/cache /cache ext4 noatime,nosuid,nodev,nodelalloc,nomblk_io_submit,errors=panic latemount,wait,check,formattable
/dev/block/platform/soc/ffe07000.mmc/by-name/misc /misc emmc defaults defaults
/dev/block/platform/soc/ffe07000.mmc/by-name/recovery /recovery emmc defaults defaults
/dev/block/platform/soc/ffe07000.mmc/by-name/boot /boot emmc defaults defaults

View File

@ -0,0 +1,9 @@
/dev/block/platform/soc/ffe07000.mmc/by-name/userdata /data f2fs noatime,nosuid,nodev latemount,wait,check,quota,fileencryption=software,quota
/dev/block/platform/soc/ffe07000.mmc/by-name/userdata /data ext4 noatime,nosuid,nodev,nodelalloc,nomblk_io_submit,errors=panic latemount,wait,check,quota,formattable,reservedsize=32M
/dev/block/platform/soc/ffe07000.mmc/by-name/cache /cache ext4 noatime,nosuid,nodev,nodelalloc,nomblk_io_submit,errors=panic latemount,wait,check,formattable
/dev/block/platform/soc/ffe07000.mmc/by-name/misc /misc emmc defaults defaults
system /system ext4 ro,barrier=1 wait,logical,first_stage_mount
vendor /vendor ext4 ro,barrier=1 wait,logical,first_stage_mount
*/block/mmcblk0 auto auto defaults voldmanaged=sdcard1:auto,encryptable=userdata
*/block/sd* auto auto defaults voldmanaged=usb:auto,noemulatedsd
/dev/block/zram0 none swap defaults zramsize=268435456

View File

@ -0,0 +1,8 @@
system /system ext4 noatime,ro,errors=panic wait,slotselect,logical,first_stage_mount
vendor /vendor ext4 noatime,ro,errors=panic wait,slotselect,logical,first_stage_mount
/dev/block/by-name/userdata /data f2fs noatime,nosuid,nodev latemount,wait,check,quota,fileencryption=software,quota
/dev/block//by-name/userdata /data ext4 noatime,nosuid,nodev,nodelalloc,nomblk_io_submit,errors=panic latemount,wait,check,quota,formattable,reservedsize=32M
/dev/block/by-name/misc /misc emmc defaults defaults
*/block/mmcblk0 auto auto defaults voldmanaged=sdcard1:auto,encryptable=userdata
*/block/sd* auto auto defaults voldmanaged=usb:auto,noemulatedsd
/dev/block/zram0 none swap defaults zramsize=268435456

View File

@ -0,0 +1,8 @@
system /system ext4 noatime,ro,errors=panic wait,slotselect,avb=vbmeta,logical,first_stage_mount
vendor /vendor ext4 noatime,ro,errors=panic wait,slotselect,avb,logical,first_stage_mount
/dev/block/by-name/userdata /data f2fs noatime,nosuid,nodev latemount,wait,check,quota,fileencryption=software,quota
/dev/block//by-name/userdata /data ext4 noatime,nosuid,nodev,nodelalloc,nomblk_io_submit,errors=panic latemount,wait,check,quota,formattable,reservedsize=32M
/dev/block/by-name/misc /misc emmc defaults defaults
*/block/mmcblk0 auto auto defaults voldmanaged=sdcard1:auto,encryptable=userdata
*/block/sd* auto auto defaults voldmanaged=usb:auto,noemulatedsd
/dev/block/zram0 none swap defaults zramsize=268435456

View File

@ -0,0 +1,18 @@
#
# Copyright 2017 The Android Open-Source Project
#
# 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.
#
LOCAL_PATH:= $(call my-dir)
include $(call all-makefiles-under,$(LOCAL_PATH))

View File

@ -0,0 +1,53 @@
# Copyright (C) 2016 The Android Open Source Project
#
# 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.
LOCAL_PATH := $(call my-dir)
# The default audio HAL module, which is a stub, that is loaded if no other
# device specific modules are present. The exact load order can be seen in
# libhardware/hardware.c
#
# The format of the name is audio.<type>.<hardware/etc>.so where the only
# required type is 'primary'. Other possibilites are 'a2dp', 'usb', etc.
include $(CLEAR_VARS)
LOCAL_HEADER_LIBRARIES += libhardware_headers
LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
LOCAL_LICENSE_CONDITIONS := notice
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_VENDOR_MODULE := true
LOCAL_SRC_FILES := audio_hw.c \
audio_aec.c \
fifo_wrapper.cpp \
fir_filter.c
LOCAL_SHARED_LIBRARIES := liblog libcutils libtinyalsa libaudioroute libaudioutils
LOCAL_CFLAGS := -Wno-unused-parameter
LOCAL_C_INCLUDES += \
external/tinyalsa/include \
external/expat/lib \
$(call include-path-for, audio-route) \
system/media/audio_utils/include \
system/media/audio_effects/include
ifeq ($(TARGET_USE_HDMI_AUDIO),true)
LOCAL_CFLAGS += -DUSE_HDMI_AUDIO
endif
ifneq ($(findstring google_aec, $(call all-makefiles-under,$(TOPDIR)vendor/amlogic/yukawa)),)
LOCAL_SHARED_LIBRARIES += google_aec
LOCAL_CFLAGS += -DAEC_HAL
endif
include $(BUILD_SHARED_LIBRARY)

View File

@ -0,0 +1,708 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.
*/
// clang-format off
/*
* Typical AEC signal flow:
*
* Microphone Audio
* Timestamps
* +--------------------------------------+
* | | +---------------+
* | Microphone +---------------+ | | |
* O|====== | Audio | Sample Rate | +-------> |
* (from . +--+ Samples | + | | |
* mic . +==================> Format |==============> |
* codec) . | Conversion | | | Cleaned
* O|====== | (if required) | | Acoustic | Audio
* +---------------+ | Echo | Samples
* | Canceller |===================>
* | (AEC) |
* Reference +---------------+ | |
* Audio | Sample Rate | | |
* Samples | + | | |
* +=============> Format |==============> |
* | | Conversion | | |
* | | (if required) | +-------> |
* | +---------------+ | | |
* | | +---------------+
* | +-------------------------------+
* | | Reference Audio
* | | Timestamps
* | |
* +--+----+---------+ AUDIO CAPTURE
* | Speaker |
* +------------+ Audio/Timestamp +---------------------------------------------------------------------------+
* | Buffer |
* +--^----^---------+ AUDIO PLAYBACK
* | |
* | |
* | |
* | |
* |\ | |
* | +-+ | |
* (to | | +-----C----+
* speaker | | | | Playback
* codec) | | <=====+================================================================+ Audio
* | +-+ Samples
* |/
*
*/
// clang-format on
#define LOG_TAG "audio_hw_aec"
// #define LOG_NDEBUG 0
#include <audio_utils/primitives.h>
#include <stdio.h>
#include <inttypes.h>
#include <errno.h>
#include <malloc.h>
#include <sys/time.h>
#include <tinyalsa/asoundlib.h>
#include <unistd.h>
#include <log/log.h>
#include "audio_aec.h"
#ifdef AEC_HAL
#include "audio_aec_process.h"
#else
#define aec_spk_mic_init(...) ((int)0)
#define aec_spk_mic_reset(...) ((void)0)
#define aec_spk_mic_process(...) ((int32_t)0)
#define aec_spk_mic_release(...) ((void)0)
#endif
#define MAX_TIMESTAMP_DIFF_USEC 200000
#define MAX_READ_WAIT_TIME_MSEC 80
uint64_t timespec_to_usec(struct timespec ts) {
return (ts.tv_sec * 1e6L + ts.tv_nsec/1000);
}
void get_reference_audio_in_place(struct aec_t *aec, size_t frames) {
if (aec->num_reference_channels == aec->spk_num_channels) {
/* Reference count equals speaker channels, nothing to do here. */
return;
} else if (aec->num_reference_channels != 1) {
/* We don't have a rule for non-mono references, show error on log */
ALOGE("Invalid reference count - must be 1 or match number of playback channels!");
return;
}
int16_t *src_Nch = &aec->spk_buf_playback_format[0];
int16_t *dst_1ch = &aec->spk_buf_playback_format[0];
int32_t num_channels = (int32_t)aec->spk_num_channels;
size_t frame, ch;
for (frame = 0; frame < frames; frame++) {
int32_t acc = 0;
for (ch = 0; ch < aec->spk_num_channels; ch++) {
acc += src_Nch[ch];
}
*dst_1ch++ = clamp16(acc/num_channels);
src_Nch += aec->spk_num_channels;
}
}
void print_queue_status_to_log(struct aec_t *aec, bool write_side) {
ssize_t q1 = fifo_available_to_read(aec->spk_fifo);
ssize_t q2 = fifo_available_to_read(aec->ts_fifo);
ALOGV("Queue available %s: Spk %zd (count %zd) TS %zd (count %zd)",
(write_side) ? "(POST-WRITE)" : "(PRE-READ)",
q1, q1/aec->spk_frame_size_bytes/PLAYBACK_PERIOD_SIZE,
q2, q2/sizeof(struct aec_info));
}
void flush_aec_fifos(struct aec_t *aec) {
if (aec == NULL) {
return;
}
if (aec->spk_fifo != NULL) {
ALOGV("Flushing AEC Spk FIFO...");
fifo_flush(aec->spk_fifo);
}
if (aec->ts_fifo != NULL) {
ALOGV("Flushing AEC Timestamp FIFO...");
fifo_flush(aec->ts_fifo);
}
/* Reset FIFO read-write offset tracker */
aec->read_write_diff_bytes = 0;
}
void aec_set_spk_running_no_lock(struct aec_t* aec, bool state) {
aec->spk_running = state;
}
bool aec_get_spk_running_no_lock(struct aec_t* aec) {
return aec->spk_running;
}
void destroy_aec_reference_config_no_lock(struct aec_t* aec) {
if (!aec->spk_initialized) {
return;
}
aec_set_spk_running_no_lock(aec, false);
fifo_release(aec->spk_fifo);
fifo_release(aec->ts_fifo);
memset(&aec->last_spk_info, 0, sizeof(struct aec_info));
aec->spk_initialized = false;
}
void destroy_aec_mic_config_no_lock(struct aec_t* aec) {
if (!aec->mic_initialized) {
return;
}
release_resampler(aec->spk_resampler);
free(aec->mic_buf);
free(aec->spk_buf);
free(aec->spk_buf_playback_format);
free(aec->spk_buf_resampler_out);
memset(&aec->last_mic_info, 0, sizeof(struct aec_info));
aec->mic_initialized = false;
}
struct aec_t* init_aec_interface(struct aec_params* params) {
ALOGV("%s enter", __func__);
struct aec_t *aec = (struct aec_t *)calloc(1, sizeof(struct aec_t));
if (aec == NULL) {
ALOGE("%s: Failed to allocate memory for AEC interface!", __func__);
ALOGV("%s exit", __func__);
return NULL;
}
pthread_mutex_init(&aec->lock, NULL);
aec->num_reference_channels = params->num_reference_channels;
/* Set defaults, will be overridden by settings in init_aec_(mic|referece_config) */
/* Capture settings */
aec->mic_sampling_rate = params->mic_sampling_rate_hz;
aec->mic_frame_size_bytes = params->num_mic_channels * sizeof(int32_t);
aec->mic_num_channels = params->num_mic_channels;
/* Playback settings (before conversion to reference) */
aec->spk_sampling_rate = params->playback_sampling_rate_hz;
aec->spk_frame_size_bytes = params->num_playback_channels * sizeof(int32_t);
aec->spk_num_channels = params->num_playback_channels;
ALOGV("%s exit", __func__);
return aec;
}
void release_aec_interface(struct aec_t *aec) {
ALOGV("%s enter", __func__);
pthread_mutex_lock(&aec->lock);
destroy_aec_mic_config_no_lock(aec);
destroy_aec_reference_config_no_lock(aec);
pthread_mutex_unlock(&aec->lock);
free(aec);
ALOGV("%s exit", __func__);
}
int init_aec(struct aec_params* params, struct aec_t** aec_ptr) {
ALOGV("%s enter", __func__);
if ((params == NULL) || (aec_ptr == NULL)) {
ALOGE("%s: Invalid input arguments!", __func__);
return -EINVAL;
}
if (aec_spk_mic_init(params->mic_sampling_rate, params->num_reference_channels,
params->num_mic_channels)) {
ALOGE("%s: AEC object failed to initialize!", __func__);
return -EINVAL;
}
struct aec_t* aec = init_aec_interface(params);
if (aec == NULL) {
ALOGE("%s: Failed to allocate AEC struct!", __func__);
goto error_1;
}
(*aec_ptr) = aec;
ALOGV("%s exit", __func__);
return 0;
error_1:
aec_spk_mic_release();
return -EINVAL;
}
void release_aec(struct aec_t *aec) {
ALOGV("%s enter", __func__);
if (aec == NULL) {
return;
}
release_aec_interface(aec);
aec_spk_mic_release();
ALOGV("%s exit", __func__);
}
int init_aec_reference_config(struct aec_t *aec, struct alsa_stream_out *out) {
ALOGV("%s enter", __func__);
if (!aec) {
ALOGE("AEC: No valid interface found!");
return -EINVAL;
}
int ret = 0;
pthread_mutex_lock(&aec->lock);
if (aec->spk_initialized) {
destroy_aec_reference_config_no_lock(aec);
}
aec->spk_fifo = fifo_init(
out->config.period_count * out->config.period_size *
audio_stream_out_frame_size(&out->stream),
false /* reader_throttles_writer */);
if (aec->spk_fifo == NULL) {
ALOGE("AEC: Speaker loopback FIFO Init failed!");
ret = -EINVAL;
goto exit;
}
aec->ts_fifo = fifo_init(
out->config.period_count * sizeof(struct aec_info),
false /* reader_throttles_writer */);
if (aec->ts_fifo == NULL) {
ALOGE("AEC: Speaker timestamp FIFO Init failed!");
ret = -EINVAL;
fifo_release(aec->spk_fifo);
goto exit;
}
aec->spk_sampling_rate = out->config.rate;
aec->spk_frame_size_bytes = audio_stream_out_frame_size(&out->stream);
aec->spk_num_channels = out->config.channels;
aec->spk_initialized = true;
exit:
pthread_mutex_unlock(&aec->lock);
ALOGV("%s exit", __func__);
return ret;
}
void destroy_aec_reference_config(struct aec_t* aec) {
ALOGV("%s enter", __func__);
if (aec == NULL) {
ALOGV("%s exit", __func__);
return;
}
pthread_mutex_lock(&aec->lock);
destroy_aec_reference_config_no_lock(aec);
pthread_mutex_unlock(&aec->lock);
ALOGV("%s exit", __func__);
}
int write_to_reference_fifo(struct aec_t* aec, void* buffer, struct aec_info* info) {
ALOGV("%s enter", __func__);
int ret = 0;
size_t bytes = info->bytes;
/* Write audio samples to FIFO */
ssize_t written_bytes = fifo_write(aec->spk_fifo, buffer, bytes);
if (written_bytes != bytes) {
ALOGE("Could only write %zu of %zu bytes", written_bytes, bytes);
ret = -ENOMEM;
}
/* Write timestamp to FIFO */
info->bytes = written_bytes;
ALOGV("Speaker timestamp: %ld s, %ld nsec", info->timestamp.tv_sec, info->timestamp.tv_nsec);
ssize_t ts_bytes = fifo_write(aec->ts_fifo, info, sizeof(struct aec_info));
ALOGV("Wrote TS bytes: %zu", ts_bytes);
print_queue_status_to_log(aec, true);
ALOGV("%s exit", __func__);
return ret;
}
void get_spk_timestamp(struct aec_t* aec, ssize_t read_bytes, uint64_t* spk_time) {
*spk_time = 0;
uint64_t spk_time_offset = 0;
float usec_per_byte = 1E6 / ((float)(aec->spk_frame_size_bytes * aec->spk_sampling_rate));
if (aec->read_write_diff_bytes < 0) {
/* We're still reading a previous write packet. (We only need the first sample's timestamp,
* so even if we straddle packets we only care about the first one)
* So we just use the previous timestamp, with an appropriate offset
* based on the number of bytes remaining to be read from that write packet. */
spk_time_offset = (aec->last_spk_info.bytes + aec->read_write_diff_bytes) * usec_per_byte;
ALOGV("Reusing previous timestamp, calculated offset (usec) %" PRIu64, spk_time_offset);
} else {
/* If read_write_diff_bytes > 0, there are no new writes, so there won't be timestamps in
* the FIFO, and the check below will fail. */
if (!fifo_available_to_read(aec->ts_fifo)) {
ALOGE("Timestamp error: no new timestamps!");
return;
}
/* We just read valid data, so if we're here, we should have a valid timestamp to use. */
ssize_t ts_bytes = fifo_read(aec->ts_fifo, &aec->last_spk_info, sizeof(struct aec_info));
ALOGV("Read TS bytes: %zd, expected %zu", ts_bytes, sizeof(struct aec_info));
aec->read_write_diff_bytes -= aec->last_spk_info.bytes;
}
*spk_time = timespec_to_usec(aec->last_spk_info.timestamp) + spk_time_offset;
aec->read_write_diff_bytes += read_bytes;
struct aec_info spk_info = aec->last_spk_info;
while (aec->read_write_diff_bytes > 0) {
/* If read_write_diff_bytes > 0, it means that there are more write packet timestamps
* in FIFO (since there we read more valid data the size of the current timestamp's
* packet). Keep reading timestamps from FIFO to get to the most recent one. */
if (!fifo_available_to_read(aec->ts_fifo)) {
/* There are no more timestamps, we have the most recent one. */
ALOGV("At the end of timestamp FIFO, breaking...");
break;
}
fifo_read(aec->ts_fifo, &spk_info, sizeof(struct aec_info));
ALOGV("Fast-forwarded timestamp by %zd bytes, remaining bytes: %zd,"
" new timestamp (usec) %" PRIu64,
spk_info.bytes, aec->read_write_diff_bytes, timespec_to_usec(spk_info.timestamp));
aec->read_write_diff_bytes -= spk_info.bytes;
}
aec->last_spk_info = spk_info;
}
int get_reference_samples(struct aec_t* aec, void* buffer, struct aec_info* info) {
ALOGV("%s enter", __func__);
if (!aec->spk_initialized) {
ALOGE("%s called with no reference initialized", __func__);
return -EINVAL;
}
size_t bytes = info->bytes;
const size_t frames =
bytes * aec->num_reference_channels / aec->mic_num_channels / aec->mic_frame_size_bytes;
const size_t sample_rate_ratio = aec->spk_sampling_rate / aec->mic_sampling_rate;
const size_t resampler_in_frames = frames * sample_rate_ratio;
/* Read audio samples from FIFO */
const size_t req_bytes = resampler_in_frames * aec->spk_frame_size_bytes;
ssize_t available_bytes = 0;
unsigned int wait_count = MAX_READ_WAIT_TIME_MSEC;
while (true) {
available_bytes = fifo_available_to_read(aec->spk_fifo);
if (available_bytes >= req_bytes) {
break;
} else if (available_bytes < 0) {
ALOGE("fifo_read returned code %zu ", available_bytes);
return -ENOMEM;
}
ALOGV("Sleeping, required bytes: %zu, available bytes: %zd", req_bytes, available_bytes);
usleep(1000);
if ((wait_count--) == 0) {
ALOGE("Timed out waiting for read from reference FIFO");
return -ETIMEDOUT;
}
}
const size_t read_bytes = fifo_read(aec->spk_fifo, aec->spk_buf_playback_format, req_bytes);
/* Get timestamp*/
get_spk_timestamp(aec, read_bytes, &info->timestamp_usec);
/* Get reference - could be mono, downmixed from multichannel.
* Reference stored at spk_buf_playback_format */
get_reference_audio_in_place(aec, resampler_in_frames);
int16_t* resampler_out_buf;
/* Resample to mic sampling rate (16-bit resampler) */
if (aec->spk_resampler != NULL) {
size_t in_frame_count = resampler_in_frames;
size_t out_frame_count = frames;
aec->spk_resampler->resample_from_input(aec->spk_resampler, aec->spk_buf_playback_format,
&in_frame_count, aec->spk_buf_resampler_out,
&out_frame_count);
resampler_out_buf = aec->spk_buf_resampler_out;
} else {
if (sample_rate_ratio != 1) {
ALOGE("Speaker sample rate %d, mic sample rate %d but no resampler defined!",
aec->spk_sampling_rate, aec->mic_sampling_rate);
}
resampler_out_buf = aec->spk_buf_playback_format;
}
/* Convert to 32 bit */
int16_t* src16 = resampler_out_buf;
int32_t* dst32 = buffer;
size_t frame, ch;
for (frame = 0; frame < frames; frame++) {
for (ch = 0; ch < aec->num_reference_channels; ch++) {
*dst32++ = ((int32_t)*src16++) << 16;
}
}
info->bytes = bytes;
ALOGV("%s exit", __func__);
return 0;
}
int init_aec_mic_config(struct aec_t *aec, struct alsa_stream_in *in) {
ALOGV("%s enter", __func__);
#if DEBUG_AEC
remove("/data/local/traces/aec_in.pcm");
remove("/data/local/traces/aec_out.pcm");
remove("/data/local/traces/aec_ref.pcm");
remove("/data/local/traces/aec_timestamps.txt");
#endif /* #if DEBUG_AEC */
if (!aec) {
ALOGE("AEC: No valid interface found!");
return -EINVAL;
}
int ret = 0;
pthread_mutex_lock(&aec->lock);
if (aec->mic_initialized) {
destroy_aec_mic_config_no_lock(aec);
}
aec->mic_sampling_rate = in->config.rate;
aec->mic_frame_size_bytes = audio_stream_in_frame_size(&in->stream);
aec->mic_num_channels = in->config.channels;
aec->mic_buf_size_bytes = in->config.period_size * aec->mic_frame_size_bytes;
aec->mic_buf = (int32_t *)malloc(aec->mic_buf_size_bytes);
if (aec->mic_buf == NULL) {
ret = -ENOMEM;
goto exit;
}
memset(aec->mic_buf, 0, aec->mic_buf_size_bytes);
/* Reference buffer is the same number of frames as mic,
* only with a different number of channels in the frame. */
aec->spk_buf_size_bytes = in->config.period_size * aec->spk_num_channels *
aec->mic_frame_size_bytes / aec->mic_num_channels;
aec->spk_buf = (int32_t *)malloc(aec->spk_buf_size_bytes);
if (aec->spk_buf == NULL) {
ret = -ENOMEM;
goto exit_1;
}
memset(aec->spk_buf, 0, aec->spk_buf_size_bytes);
/* Pre-resampler buffer */
size_t spk_frame_out_format_bytes =
aec->spk_buf_size_bytes * aec->spk_sampling_rate / aec->mic_sampling_rate;
aec->spk_buf_playback_format = (int16_t *)malloc(spk_frame_out_format_bytes);
if (aec->spk_buf_playback_format == NULL) {
ret = -ENOMEM;
goto exit_2;
}
/* Resampler is 16-bit */
aec->spk_buf_resampler_out = (int16_t *)malloc(aec->spk_buf_size_bytes);
if (aec->spk_buf_resampler_out == NULL) {
ret = -ENOMEM;
goto exit_3;
}
/* Don't use resampler if it's not required */
if (in->config.rate == aec->spk_sampling_rate) {
aec->spk_resampler = NULL;
} else {
int resampler_ret = create_resampler(
aec->spk_sampling_rate, in->config.rate, aec->num_reference_channels,
RESAMPLER_QUALITY_MAX - 1, /* MAX - 1 is the real max */
NULL, /* resampler_buffer_provider */
&aec->spk_resampler);
if (resampler_ret) {
ALOGE("AEC: Resampler initialization failed! Error code %d", resampler_ret);
ret = resampler_ret;
goto exit_4;
}
}
flush_aec_fifos(aec);
aec_spk_mic_reset();
aec->mic_initialized = true;
exit:
pthread_mutex_unlock(&aec->lock);
ALOGV("%s exit", __func__);
return ret;
exit_4:
free(aec->spk_buf_resampler_out);
exit_3:
free(aec->spk_buf_playback_format);
exit_2:
free(aec->spk_buf);
exit_1:
free(aec->mic_buf);
pthread_mutex_unlock(&aec->lock);
ALOGV("%s exit", __func__);
return ret;
}
void aec_set_spk_running(struct aec_t *aec, bool state) {
ALOGV("%s enter", __func__);
pthread_mutex_lock(&aec->lock);
aec_set_spk_running_no_lock(aec, state);
pthread_mutex_unlock(&aec->lock);
ALOGV("%s exit", __func__);
}
bool aec_get_spk_running(struct aec_t *aec) {
ALOGV("%s enter", __func__);
pthread_mutex_lock(&aec->lock);
bool state = aec_get_spk_running_no_lock(aec);
pthread_mutex_unlock(&aec->lock);
ALOGV("%s exit", __func__);
return state;
}
void destroy_aec_mic_config(struct aec_t* aec) {
ALOGV("%s enter", __func__);
if (aec == NULL) {
ALOGV("%s exit", __func__);
return;
}
pthread_mutex_lock(&aec->lock);
destroy_aec_mic_config_no_lock(aec);
pthread_mutex_unlock(&aec->lock);
ALOGV("%s exit", __func__);
}
#ifdef AEC_HAL
int process_aec(struct aec_t *aec, void* buffer, struct aec_info *info) {
ALOGV("%s enter", __func__);
int ret = 0;
if (aec == NULL) {
ALOGE("AEC: Interface uninitialized! Cannot process.");
return -EINVAL;
}
if ((!aec->mic_initialized) || (!aec->spk_initialized)) {
ALOGE("%s called with initialization: mic: %d, spk: %d", __func__, aec->mic_initialized,
aec->spk_initialized);
return -EINVAL;
}
size_t bytes = info->bytes;
size_t frame_size = aec->mic_frame_size_bytes;
size_t in_frames = bytes / frame_size;
/* Copy raw mic samples to AEC input buffer */
memcpy(aec->mic_buf, buffer, bytes);
uint64_t mic_time = timespec_to_usec(info->timestamp);
uint64_t spk_time = 0;
/*
* Only run AEC if there is speaker playback.
* The first time speaker state changes to running, flush FIFOs, so we're not stuck
* processing stale reference input.
*/
bool spk_running = aec_get_spk_running(aec);
if (!spk_running) {
/* No new playback samples, so don't run AEC.
* 'buffer' already contains input samples. */
ALOGV("Speaker not running, skipping AEC..");
goto exit;
}
if (!aec->prev_spk_running) {
flush_aec_fifos(aec);
}
/* If there's no data in FIFO, exit */
if (fifo_available_to_read(aec->spk_fifo) <= 0) {
ALOGV("Echo reference buffer empty, zeroing reference....");
goto exit;
}
print_queue_status_to_log(aec, false);
/* Get reference, with format and sample rate required by AEC */
struct aec_info spk_info;
spk_info.bytes = bytes;
int ref_ret = get_reference_samples(aec, aec->spk_buf, &spk_info);
spk_time = spk_info.timestamp_usec;
if (ref_ret) {
ALOGE("get_reference_samples returned code %d", ref_ret);
ret = -ENOMEM;
goto exit;
}
int64_t time_diff = (mic_time > spk_time) ? (mic_time - spk_time) : (spk_time - mic_time);
if ((spk_time == 0) || (mic_time == 0) || (time_diff > MAX_TIMESTAMP_DIFF_USEC)) {
ALOGV("Speaker-mic timestamps diverged, skipping AEC");
flush_aec_fifos(aec);
aec_spk_mic_reset();
goto exit;
}
ALOGV("Mic time: %"PRIu64", spk time: %"PRIu64, mic_time, spk_time);
/*
* AEC processing call - output stored at 'buffer'
*/
int32_t aec_status = aec_spk_mic_process(
aec->spk_buf, spk_time,
aec->mic_buf, mic_time,
in_frames,
buffer);
if (!aec_status) {
ALOGE("AEC processing failed!");
ret = -EINVAL;
}
exit:
aec->prev_spk_running = spk_running;
ALOGV("Mic time: %"PRIu64", spk time: %"PRIu64, mic_time, spk_time);
if (ret) {
/* Best we can do is copy over the raw mic signal */
memcpy(buffer, aec->mic_buf, bytes);
flush_aec_fifos(aec);
aec_spk_mic_reset();
}
#if DEBUG_AEC
/* ref data is 32-bit at this point */
size_t ref_bytes = in_frames*aec->num_reference_channels*sizeof(int32_t);
FILE *fp_in = fopen("/data/local/traces/aec_in.pcm", "a+");
if (fp_in) {
fwrite((char *)aec->mic_buf, 1, bytes, fp_in);
fclose(fp_in);
} else {
ALOGE("AEC debug: Could not open file aec_in.pcm!");
}
FILE *fp_out = fopen("/data/local/traces/aec_out.pcm", "a+");
if (fp_out) {
fwrite((char *)buffer, 1, bytes, fp_out);
fclose(fp_out);
} else {
ALOGE("AEC debug: Could not open file aec_out.pcm!");
}
FILE *fp_ref = fopen("/data/local/traces/aec_ref.pcm", "a+");
if (fp_ref) {
fwrite((char *)aec->spk_buf, 1, ref_bytes, fp_ref);
fclose(fp_ref);
} else {
ALOGE("AEC debug: Could not open file aec_ref.pcm!");
}
FILE *fp_ts = fopen("/data/local/traces/aec_timestamps.txt", "a+");
if (fp_ts) {
fprintf(fp_ts, "%"PRIu64",%"PRIu64"\n", mic_time, spk_time);
fclose(fp_ts);
} else {
ALOGE("AEC debug: Could not open file aec_timestamps.txt!");
}
#endif /* #if DEBUG_AEC */
ALOGV("%s exit", __func__);
return ret;
}
#endif /*#ifdef AEC_HAL*/

View File

@ -0,0 +1,139 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.
*/
/*
* Definitions and interface related to HAL implementations of Acoustic Echo Canceller (AEC).
*
* AEC cleans the microphone signal by removing from it audio data corresponding to loudspeaker
* playback. Note that this process can be nonlinear.
*
*/
#ifndef _AUDIO_AEC_H_
#define _AUDIO_AEC_H_
#include <stdint.h>
#include <pthread.h>
#include <sys/time.h>
#include <hardware/audio.h>
#include <audio_utils/resampler.h>
#include "audio_hw.h"
#include "fifo_wrapper.h"
struct aec_t {
pthread_mutex_t lock;
size_t num_reference_channels;
bool mic_initialized;
int32_t *mic_buf;
size_t mic_num_channels;
size_t mic_buf_size_bytes;
size_t mic_frame_size_bytes;
uint32_t mic_sampling_rate;
struct aec_info last_mic_info;
bool spk_initialized;
int32_t *spk_buf;
size_t spk_num_channels;
size_t spk_buf_size_bytes;
size_t spk_frame_size_bytes;
uint32_t spk_sampling_rate;
struct aec_info last_spk_info;
int16_t *spk_buf_playback_format;
int16_t *spk_buf_resampler_out;
void *spk_fifo;
void *ts_fifo;
ssize_t read_write_diff_bytes;
struct resampler_itfe *spk_resampler;
bool spk_running;
bool prev_spk_running;
};
struct aec_params {
int num_mic_channels;
int num_reference_channels;
int num_playback_channels;
int mic_sampling_rate_hz;
int playback_sampling_rate_hz;
};
/* Initialize AEC object.
* This must be called when the audio device is opened.
* ALSA device mutex must be held before calling this API.
* Returns -EINVAL if AEC object fails to initialize, else returns 0. */
int init_aec(struct aec_params* params, struct aec_t** aec_ptr);
/* Release AEC object.
* This must be called when the audio device is closed. */
void release_aec(struct aec_t* aec);
/* Initialize reference configuration for AEC.
* Must be called when a new output stream is opened.
* Returns -EINVAL if any processing block fails to initialize,
* else returns 0. */
int init_aec_reference_config (struct aec_t *aec, struct alsa_stream_out *out);
/* Clear reference configuration for AEC.
* Must be called when the output stream is closed. */
void destroy_aec_reference_config (struct aec_t *aec);
/* Initialize microphone configuration for AEC.
* Must be called when a new input stream is opened.
* Returns -EINVAL if any processing block fails to initialize,
* else returns 0. */
int init_aec_mic_config(struct aec_t* aec, struct alsa_stream_in* in);
/* Clear microphone configuration for AEC.
* Must be called when the input stream is closed. */
void destroy_aec_mic_config (struct aec_t *aec);
/* Used to communicate playback state (running or not) to AEC interface.
* This is used by process_aec() to determine if AEC processing is to be run. */
void aec_set_spk_running (struct aec_t *aec, bool state);
/* Used to communicate playback state (running or not) to the caller. */
bool aec_get_spk_running(struct aec_t* aec);
/* Write audio samples to AEC reference FIFO for use in AEC.
* Both audio samples and timestamps are added in FIFO fashion.
* Must be called after every write to PCM.
* Returns -ENOMEM if the write fails, else returns 0. */
int write_to_reference_fifo(struct aec_t* aec, void* buffer, struct aec_info* info);
/* Get reference audio samples + timestamp, in the format expected by AEC,
* i.e. same sample rate and bit rate as microphone audio.
* Timestamp is updated in field 'timestamp_usec', and not in 'timestamp'.
* Returns:
* -EINVAL if the AEC object is invalid.
* -ENOMEM if the reference FIFO overflows or is corrupted.
* -ETIMEDOUT if we timed out waiting for the requested number of bytes
* 0 otherwise */
int get_reference_samples(struct aec_t* aec, void* buffer, struct aec_info* info);
#ifdef AEC_HAL
/* Processing function call for AEC.
* AEC output is updated at location pointed to by 'buffer'.
* This function does not run AEC when there is no playback -
* as communicated to this AEC interface using aec_set_spk_running().
* Returns -EINVAL if processing fails, else returns 0. */
int process_aec(struct aec_t* aec, void* buffer, struct aec_info* info);
#else /* #ifdef AEC_HAL */
#define process_aec(...) ((int)0)
#endif /* #ifdef AEC_HAL */
#endif /* _AUDIO_AEC_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,129 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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 _YUKAWA_AUDIO_HW_H_
#define _YUKAWA_AUDIO_HW_H_
#include <hardware/audio.h>
#include <tinyalsa/asoundlib.h>
#include "fir_filter.h"
#define CARD_OUT 0
#define PORT_HDMI 0
#define PORT_INTERNAL_SPEAKER 1
#define CARD_IN 0
#define PORT_BUILTIN_MIC 3
#define MIXER_XML_PATH "/vendor/etc/mixer_paths.xml"
/* Minimum granularity - Arbitrary but small value */
#define CODEC_BASE_FRAME_COUNT 32
#define CHANNEL_STEREO 2
#ifdef AEC_HAL
#define NUM_AEC_REFERENCE_CHANNELS 1
#else
/* App AEC uses 2-channel reference */
#define NUM_AEC_REFERENCE_CHANNELS 2
#endif /* #ifdef AEC_HAL */
#define DEBUG_AEC 0
#define PCM_OPEN_RETRIES 100
#define PCM_OPEN_WAIT_TIME_MS 20
/* Capture codec parameters */
/* Set up a capture period of 32 ms:
* CAPTURE_PERIOD = PERIOD_SIZE / SAMPLE_RATE, so (32e-3) = PERIOD_SIZE / (16e3)
* => PERIOD_SIZE = 512 frames, where each "frame" consists of 1 sample of every channel (here, 2ch) */
#define CAPTURE_PERIOD_MULTIPLIER 16
#define CAPTURE_PERIOD_SIZE (CODEC_BASE_FRAME_COUNT * CAPTURE_PERIOD_MULTIPLIER)
#define CAPTURE_PERIOD_COUNT 4
#define CAPTURE_PERIOD_START_THRESHOLD 0
#define CAPTURE_CODEC_SAMPLING_RATE 16000
/* Playback codec parameters */
/* number of base blocks in a short period (low latency) */
#define PLAYBACK_PERIOD_MULTIPLIER 32 /* 21 ms */
/* number of frames per short period (low latency) */
#define PLAYBACK_PERIOD_SIZE (CODEC_BASE_FRAME_COUNT * PLAYBACK_PERIOD_MULTIPLIER)
/* number of pseudo periods for low latency playback */
#define PLAYBACK_PERIOD_COUNT 4
#define PLAYBACK_PERIOD_START_THRESHOLD 2
#define PLAYBACK_CODEC_SAMPLING_RATE 48000
#define MIN_WRITE_SLEEP_US 5000
#define SPEAKER_EQ_FILE "/vendor/etc/speaker_eq_sei610.fir"
#define SPEAKER_MAX_EQ_LENGTH 512
struct alsa_audio_device {
struct audio_hw_device hw_device;
pthread_mutex_t lock; /* see notes in in_read/out_write on mutex acquisition order */
struct alsa_stream_in *active_input;
struct alsa_stream_out *active_output;
struct audio_route *audio_route;
struct mixer *mixer;
bool mic_mute;
struct aec_t *aec;
};
struct alsa_stream_in {
struct audio_stream_in stream;
pthread_mutex_t lock; /* see note in in_read() on mutex acquisition order */
audio_devices_t devices;
struct pcm_config config;
struct pcm *pcm;
bool unavailable;
bool standby;
struct alsa_audio_device *dev;
int read_threshold;
unsigned int frames_read;
uint64_t timestamp_nsec;
audio_source_t source;
};
struct alsa_stream_out {
struct audio_stream_out stream;
pthread_mutex_t lock; /* see note in out_write() on mutex acquisition order */
audio_devices_t devices;
struct pcm_config config;
struct pcm *pcm;
bool unavailable;
int standby;
struct alsa_audio_device *dev;
int write_threshold;
unsigned int frames_written;
struct timespec timestamp;
fir_filter_t* speaker_eq;
};
/* 'bytes' are the number of bytes written to audio FIFO, for which 'timestamp' is valid.
* 'available' is the number of frames available to read (for input) or yet to be played
* (for output) frames in the PCM buffer.
* timestamp and available are updated by pcm_get_htimestamp(), so they use the same
* datatypes as the corresponding arguments to that function. */
struct aec_info {
struct timespec timestamp;
uint64_t timestamp_usec;
unsigned int available;
size_t bytes;
};
#endif /* #ifndef _YUKAWA_AUDIO_HW_H_ */

View File

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright (C) 2019 The Android Open Source Project
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.
-->
<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude">
<!-- version section contains a “version” tag in the form “major.minor” e.g version=”1.0” -->
<!-- Global configuration Decalaration -->
<globalConfiguration speaker_drc_enabled="true"/>
<!-- Modules section:
There is one section per audio HW module present on the platform.
Each module section will contains two mandatory tags for audio HAL “halVersion” and “name”.
The module names are the same as in current .conf file:
“primary”, “A2DP”, “remote_submix”, “USB”
Each module will contain the following sections:
“devicePorts”: a list of device descriptors for all input and output devices accessible via this
module.
This contains both permanently attached devices and removable devices.
“mixPorts”: listing all output and input streams exposed by the audio HAL
“routes”: list of possible connections between input and output devices or between stream and
devices.
"route": is defined by an attribute:
-"type": <mux|mix> means all sources are mutual exclusive (mux) or can be mixed (mix)
-"sink": the sink involved in this route
-"sources": all the sources than can be connected to the sink via vis route
“attachedDevices”: permanently attached devices.
The attachedDevices section is a list of devices names. The names correspond to device names
defined in <devicePorts> section.
“defaultOutputDevice”: device to be used by default when no policy rule applies
-->
<modules>
<!-- Primary Audio HAL -->
<module name="primary" halVersion="3.0">
<attachedDevices>
<item>Speaker</item>
<item>Built-In Mic</item>
<item>Echo Reference</item>
</attachedDevices>
<defaultOutputDevice>Speaker</defaultOutputDevice>
<mixPorts>
<mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
<mixPort name="HDMI output" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
<mixPort name="built-in mic" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
samplingRates="16000"
channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
</mixPort>
<mixPort name="echo reference" role="sink">
<profile name="echo_reference" format="AUDIO_FORMAT_PCM_32_BIT"
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
</mixPort>
</mixPorts>
<devicePorts>
<!-- Output devices declaration, i.e. Sink DEVICE PORT -->
<devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
<devicePort tagName="HDMI Out" role="sink" type="AUDIO_DEVICE_OUT_HDMI" address="">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
<devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source"
address="top">
<profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
samplingRates="16000"
channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
</devicePort>
<devicePort tagName="Echo Reference" type="AUDIO_DEVICE_IN_ECHO_REFERENCE" role="source">
<profile name="echo_reference" format="AUDIO_FORMAT_PCM_32_BIT"
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
</devicePort>
</devicePorts>
<!-- route declaration, i.e. list all available sources for a given sink -->
<routes>
<route type="mix" sink="Speaker"
sources="primary output"/>
<route type="mix" sink="HDMI Out"
sources="HDMI output"/>
<route type="mix" sink="built-in mic"
sources="Built-In Mic"/>
<route type="mix" sink="echo reference"
sources="Echo Reference"/>
</routes>
</module>
<!-- A2dp Input Audio HAL -->
<xi:include href="a2dp_in_audio_policy_configuration_7_0.xml"/>
<!-- Bluetooth Audio HAL -->
<xi:include href="bluetooth_audio_policy_configuration_7_0.xml"/>
<!-- Usb Audio HAL -->
<xi:include href="usb_audio_policy_configuration.xml"/>
<!-- Remote Submix Audio HAL -->
<xi:include href="r_submix_audio_policy_configuration.xml"/>
</modules>
<!-- End of Modules section -->
<!-- Volume section -->
<xi:include href="audio_policy_volumes.xml"/>
<xi:include href="default_volume_tables.xml"/>
<!-- End of Volume section -->
</audioPolicyConfiguration>

View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright (C) 2019 The Android Open Source Project
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.
-->
<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude">
<!-- version section contains a “version” tag in the form “major.minor” e.g version=”1.0” -->
<!-- Global configuration Decalaration -->
<globalConfiguration speaker_drc_enabled="true"/>
<!-- Modules section:
There is one section per audio HW module present on the platform.
Each module section will contains two mandatory tags for audio HAL “halVersion” and “name”.
The module names are the same as in current .conf file:
“primary”, “A2DP”, “remote_submix”, “USB”
Each module will contain the following sections:
“devicePorts”: a list of device descriptors for all input and output devices accessible via this
module.
This contains both permanently attached devices and removable devices.
“mixPorts”: listing all output and input streams exposed by the audio HAL
“routes”: list of possible connections between input and output devices or between stream and
devices.
"route": is defined by an attribute:
-"type": <mux|mix> means all sources are mutual exclusive (mux) or can be mixed (mix)
-"sink": the sink involved in this route
-"sources": all the sources than can be connected to the sink via vis route
“attachedDevices”: permanently attached devices.
The attachedDevices section is a list of devices names. The names correspond to device names
defined in <devicePorts> section.
“defaultOutputDevice”: device to be used by default when no policy rule applies
-->
<modules>
<!-- Primary Audio HAL -->
<module name="primary" halVersion="3.0">
<attachedDevices>
<item>HDMI Out</item>
</attachedDevices>
<defaultOutputDevice>HDMI Out</defaultOutputDevice>
<mixPorts>
<mixPort name="HDMI output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
</mixPorts>
<devicePorts>
<devicePort tagName="HDMI Out" role="sink" type="AUDIO_DEVICE_OUT_HDMI" address="">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
</devicePorts>
<!-- route declaration, i.e. list all available sources for a given sink -->
<routes>
<route type="mix" sink="HDMI Out"
sources="HDMI output"/>
</routes>
</module>
<!-- A2dp Input Audio HAL -->
<xi:include href="a2dp_in_audio_policy_configuration_7_0.xml"/>
<!-- Bluetooth Audio HAL -->
<xi:include href="bluetooth_audio_policy_configuration_7_0.xml"/>
<!-- Usb Audio HAL -->
<xi:include href="usb_audio_policy_configuration.xml"/>
<!-- Remote Submix Audio HAL -->
<xi:include href="r_submix_audio_policy_configuration.xml"/>
</modules>
<!-- End of Modules section -->
<!-- Volume section -->
<xi:include href="audio_policy_volumes.xml"/>
<xi:include href="default_volume_tables.xml"/>
<!-- End of Volume section -->
</audioPolicyConfiguration>

View File

@ -0,0 +1,79 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.
*/
#define LOG_TAG "audio_utils_fifo_wrapper"
// #define LOG_NDEBUG 0
#include <stdint.h>
#include <errno.h>
#include <log/log.h>
#include <audio_utils/fifo.h>
#include "fifo_wrapper.h"
struct audio_fifo_itfe {
audio_utils_fifo *p_fifo;
audio_utils_fifo_reader *p_fifo_reader;
audio_utils_fifo_writer *p_fifo_writer;
int8_t *p_buffer;
};
void *fifo_init(uint32_t bytes, bool reader_throttles_writer) {
struct audio_fifo_itfe *interface = new struct audio_fifo_itfe;
interface->p_buffer = new int8_t[bytes];
if (interface->p_buffer == NULL) {
ALOGE("Failed to allocate fifo buffer!");
return NULL;
}
interface->p_fifo = new audio_utils_fifo(bytes, 1, interface->p_buffer, reader_throttles_writer);
interface->p_fifo_writer = new audio_utils_fifo_writer(*interface->p_fifo);
interface->p_fifo_reader = new audio_utils_fifo_reader(*interface->p_fifo);
return (void *)interface;
}
void fifo_release(void *fifo_itfe) {
struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
delete interface->p_fifo_writer;
delete interface->p_fifo_reader;
delete interface->p_fifo;
delete[] interface->p_buffer;
delete interface;
}
ssize_t fifo_read(void *fifo_itfe, void *buffer, size_t bytes) {
struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
return interface->p_fifo_reader->read(buffer, bytes);
}
ssize_t fifo_write(void *fifo_itfe, void *buffer, size_t bytes) {
struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
return interface->p_fifo_writer->write(buffer, bytes);
}
ssize_t fifo_available_to_read(void *fifo_itfe) {
struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
return interface->p_fifo_reader->available();
}
ssize_t fifo_available_to_write(void *fifo_itfe) {
struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
return interface->p_fifo_writer->available();
}
ssize_t fifo_flush(void *fifo_itfe) {
struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
return interface->p_fifo_reader->flush();
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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 _AUDIO_FIFO_WRAPPER_H_
#define _AUDIO_FIFO_WRAPPER_H_
#ifdef __cplusplus
extern "C" {
#endif
void *fifo_init(uint32_t bytes, bool reader_throttles_writer);
void fifo_release(void *fifo_itfe);
ssize_t fifo_read(void *fifo_itfe, void *buffer, size_t bytes);
ssize_t fifo_write(void *fifo_itfe, void *buffer, size_t bytes);
ssize_t fifo_available_to_read(void *fifo_itfe);
ssize_t fifo_available_to_write(void *fifo_itfe);
ssize_t fifo_flush(void *fifo_itfe);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef _AUDIO_FIFO_WRAPPER_H_ */

View File

@ -0,0 +1,154 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* 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.
*/
#define LOG_TAG "audio_hw_fir_filter"
//#define LOG_NDEBUG 0
#include <assert.h>
#include <audio_utils/primitives.h>
#include <errno.h>
#include <inttypes.h>
#include <log/log.h>
#include <malloc.h>
#include <string.h>
#include "fir_filter.h"
#ifdef __ARM_NEON
#include "arm_neon.h"
#endif /* #ifdef __ARM_NEON */
fir_filter_t* fir_init(uint32_t channels, fir_filter_mode_t mode, uint32_t filter_length,
uint32_t input_length, int16_t* coeffs) {
if ((channels == 0) || (filter_length == 0) || (coeffs == NULL)) {
ALOGE("%s: Invalid channel count, filter length or coefficient array.", __func__);
return NULL;
}
fir_filter_t* fir = (fir_filter_t*)calloc(1, sizeof(fir_filter_t));
if (fir == NULL) {
ALOGE("%s: Unable to allocate memory for fir_filter.", __func__);
return NULL;
}
fir->channels = channels;
fir->filter_length = filter_length;
/* Default: same filter coeffs for all channels */
fir->mode = FIR_SINGLE_FILTER;
uint32_t coeff_bytes = fir->filter_length * sizeof(int16_t);
if (mode == FIR_PER_CHANNEL_FILTER) {
fir->mode = FIR_PER_CHANNEL_FILTER;
coeff_bytes = fir->filter_length * fir->channels * sizeof(int16_t);
}
fir->coeffs = (int16_t*)malloc(coeff_bytes);
if (fir->coeffs == NULL) {
ALOGE("%s: Unable to allocate memory for FIR coeffs", __func__);
goto exit_1;
}
memcpy(fir->coeffs, coeffs, coeff_bytes);
fir->buffer_size = (input_length + fir->filter_length) * fir->channels;
fir->state = (int16_t*)malloc(fir->buffer_size * sizeof(int16_t));
if (fir->state == NULL) {
ALOGE("%s: Unable to allocate memory for FIR state", __func__);
goto exit_2;
}
#ifdef __ARM_NEON
ALOGI("%s: Using ARM Neon", __func__);
#endif /* #ifdef __ARM_NEON */
fir_reset(fir);
return fir;
exit_2:
free(fir->coeffs);
exit_1:
free(fir);
return NULL;
}
void fir_release(fir_filter_t* fir) {
if (fir == NULL) {
return;
}
free(fir->state);
free(fir->coeffs);
free(fir);
}
void fir_reset(fir_filter_t* fir) {
if (fir == NULL) {
return;
}
memset(fir->state, 0, fir->buffer_size * sizeof(int16_t));
}
void fir_process_interleaved(fir_filter_t* fir, int16_t* input, int16_t* output, uint32_t samples) {
assert(fir != NULL);
int start_offset = (fir->filter_length - 1) * fir->channels;
memcpy(&fir->state[start_offset], input, samples * fir->channels * sizeof(int16_t));
// int ch;
bool use_2nd_set_coeffs = (fir->channels > 1) && (fir->mode == FIR_PER_CHANNEL_FILTER);
int16_t* p_coeff_A = &fir->coeffs[0];
int16_t* p_coeff_B = use_2nd_set_coeffs ? &fir->coeffs[fir->filter_length] : &fir->coeffs[0];
int16_t* p_output;
for (int ch = 0; ch < fir->channels; ch += 2) {
p_output = &output[ch];
int offset = start_offset + ch;
for (int s = 0; s < samples; s++) {
int32_t acc_A = 0;
int32_t acc_B = 0;
#ifdef __ARM_NEON
int32x4_t acc_vec = vdupq_n_s32(0);
for (int k = 0; k < fir->filter_length; k++, offset -= fir->channels) {
int16x4_t coeff_vec = vdup_n_s16(p_coeff_A[k]);
coeff_vec = vset_lane_s16(p_coeff_B[k], coeff_vec, 1);
int16x4_t input_vec = vld1_s16(&fir->state[offset]);
acc_vec = vmlal_s16(acc_vec, coeff_vec, input_vec);
}
acc_A = vgetq_lane_s32(acc_vec, 0);
acc_B = vgetq_lane_s32(acc_vec, 1);
#else
for (int k = 0; k < fir->filter_length; k++, offset -= fir->channels) {
int32_t input_A = (int32_t)(fir->state[offset]);
int32_t coeff_A = (int32_t)(p_coeff_A[k]);
int32_t input_B = (int32_t)(fir->state[offset + 1]);
int32_t coeff_B = (int32_t)(p_coeff_B[k]);
acc_A += (input_A * coeff_A);
acc_B += (input_B * coeff_B);
}
#endif /* #ifdef __ARM_NEON */
*p_output = clamp16(acc_A >> 15);
if (ch < fir->channels - 1) {
*(p_output + 1) = clamp16(acc_B >> 15);
}
/* Move to next sample */
p_output += fir->channels;
offset += (fir->filter_length + 1) * fir->channels;
}
if (use_2nd_set_coeffs) {
p_coeff_A += (fir->filter_length << 1);
p_coeff_B += (fir->filter_length << 1);
}
}
memmove(fir->state, &fir->state[samples * fir->channels],
(fir->filter_length - 1) * fir->channels * sizeof(int16_t));
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* 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 FIR_FILTER_H
#define FIR_FILTER_H
#include <stdint.h>
typedef enum fir_filter_mode { FIR_SINGLE_FILTER = 0, FIR_PER_CHANNEL_FILTER } fir_filter_mode_t;
typedef struct fir_filter {
fir_filter_mode_t mode;
uint32_t channels;
uint32_t filter_length;
uint32_t buffer_size;
int16_t* coeffs;
int16_t* state;
} fir_filter_t;
fir_filter_t* fir_init(uint32_t channels, fir_filter_mode_t mode, uint32_t filter_length,
uint32_t input_length, int16_t* coeffs);
void fir_release(fir_filter_t* fir);
void fir_reset(fir_filter_t* fir);
void fir_process_interleaved(fir_filter_t* fir, int16_t* input, int16_t* output, uint32_t samples);
#endif /* #ifndef FIR_FILTER_H */

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<mixer>
<!-- FIXME: This should be moved to the appropriate path -->
<!-- Enable HDMITX Control from TDM B -->
<ctl name="TOHDMITX Switch" value="1" />
<ctl name="TOHDMITX I2S SRC" value="I2S B" />
<!-- PCM0 to TDMB -->
<ctl name="TDMOUT_B SRC SEL" value="IN 0" />
<ctl name="FRDDR_A SINK 1 SEL" value="OUT 1" />
<ctl name="FRDDR_A SRC 1 EN Switch" value="1" />
<!-- PDM to PCM3 -->
<ctl name="TODDR_A SRC SEL" value="IN 4" />
<!-- PDM to PCM1 (internal speaker) -->
<ctl name="FRDDR_B SINK 1 SEL" value="OUT 0" />
<ctl name="FRDDR_B SRC 1 EN Switch" value="1" />
<ctl name="TDMOUT_A SRC SEL" value="IN 1" />
</mixer>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<mixer>
<!-- FIXME: This should be moved to the appropriate path -->
<!-- Enable HDMITX Control from TDM A -->
<ctl name="TOHDMITX Switch" value="1" />
<ctl name="TOHDMITX I2S SRC" value="I2S A" />
<!-- PCM0 to TDMB -->
<ctl name="TDMOUT_A SRC SEL" value="IN 0" />
<ctl name="FRDDR_A SINK 1 SEL" value="OUT 0" />
<ctl name="FRDDR_A SRC 1 EN Switch" value="1" />
</mixer>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2020, The Android Open Source Project
**
** 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.
*/
-->
<resources>
<!-- For HDMI output only devices, volume is controlled by the HDMI sink. -->
<bool name="config_useFixedVolume">true</bool>
</resources>

View File

@ -0,0 +1,523 @@
# FIR speaker EQ file for SEI-610
# This filter attenuates 200-400Hz by 18dB,
# and some 6dB notch attenuation at 2.25kHz, 3.8kHz, 6.6kHz.
# Script to generate this file: https://drive.google.com/file/d/1_qvkZ8nU-c6tD6XrH80et2P12paardAz/view?usp=sharing
# Full frequency response here: https://b.corp.google.com/issues/159714063#comment3
# Each FIR coefficient is specified on one line (no leading spaces).
# First line is 0th coefficient.
# Values must be 16-bit integers. Currently, a max of 512 taps is supported.
18976
9870
-12520
2452
-766
-1023
1122
-2509
316
-1464
95
-817
-1191
-1882
-2299
-1806
-1180
-310
-68
-303
-957
-1544
-1738
-1490
-973
-517
-285
-261
-247
-68
305
729
983
931
612
210
-63
-100
48
234
313
244
99
3
36
183
350
435
398
286
191
188
282
409
483
454
336
192
92
63
83
100
73
2
-75
-114
-93
-27
41
73
55
9
-30
-38
-14
18
30
9
-34
-78
-100
-94
-75
-62
-68
-91
-116
-124
-109
-79
-50
-35
-37
-47
-53
-48
-33
-19
-14
-22
-38
-51
-55
-49
-38
-31
-32
-38
-45
-45
-38
-26
-17
-14
-16
-21
-23
-21
-16
-12
-13
-17
-25
-30
-32
-31
-29
-28
-30
-33
-36
-37
-35
-32
-30
-31
-33
-36
-38
-38
-37
-37
-38
-40
-43
-46
-47
-47
-46
-46
-47
-49
-50
-50
-50
-49
-48
-49
-50
-51
-51
-51
-51
-51
-51
-52
-53
-54
-54
-54
-54
-54
-54
-55
-55
-55
-54
-54
-54
-54
-54
-55
-55
-55
-55
-55
-55
-55
-56
-56
-56
-56
-56
-56
-56
-56
-56
-56
-56
-55
-55
-55
-56
-56
-56
-56
-55
-55
-55
-56
-56
-56
-55
-55
-55
-55
-55
-55
-55
-55
-55
-54
-54
-54
-54
-54
-54
-54
-53
-53
-53
-53
-53
-53
-52
-52
-52
-52
-51
-51
-51
-51
-50
-50
-50
-50
-49
-49
-49
-48
-48
-48
-48
-47
-47
-47
-46
-46
-46
-45
-45
-45
-44
-44
-44
-43
-43
-43
-42
-42
-41
-41
-41
-40
-40
-40
-39
-39
-38
-38
-38
-37
-37
-36
-36
-36
-35
-35
-34
-34
-33
-33
-33
-32
-32
-31
-31
-31
-30
-30
-29
-29
-28
-28
-27
-27
-27
-26
-26
-25
-25
-24
-24
-24
-23
-23
-22
-22
-21
-21
-20
-20
-20
-19
-19
-18
-18
-17
-17
-17
-16
-16
-15
-15
-14
-14
-14
-13
-13
-12
-12
-11
-11
-11
-10
-10
-9
-9
-9
-8
-8
-7
-7
-7
-6
-6
-5
-5
-5
-4
-4
-3
-3
-3
-2
-2
-1
-1
-1
0
0
0
0
0
0
1
1
1
2
2
2
3
3
3
4
4
4
5
5
5
6
6
6
7
7
7
7
8
8
8
9
9
9
9
10
10
10
10
11
11
11
11
12
12
12
12
13
13
13
13
13
14
14
14
14
14
15
15
15
15
15
16
16
16
16
16
16
17
17
17
17
17
17
17
18
18
18
18
18
18
18
18
19
19
19
19
19
19
19
19
19
19
19
20
20
20
20
20
20
20
20
20
20
20
20
20
20
20
20
20
20
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
20
20
20
20
20
20

View File

@ -0,0 +1,49 @@
// Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
//
// 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.
package {
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "device_amlogic_yukawa_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["device_amlogic_yukawa_license"],
}
cc_library_shared {
name: "bootctrl.yukawa",
vendor: true,
recovery_available: true,
relative_install_path: "hw",
srcs: [
"boot_control.cc",
"bootloader_message.cpp"
],
cflags: [
"-DLOG_TAG=\"amlogic_bootcontrol\"",
],
header_libs: ["libhardware_headers"],
static_libs: ["libfstab",],
shared_libs: [
"liblog",
"libcutils",
"libbase",
"libz"
],
}

View File

@ -0,0 +1,351 @@
/*
* Copyright (C) Texas Instruments Incorporated - http://www.ti.com/
*
* 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 <log/log.h>
#include <cutils/properties.h>
#include <zlib.h>
#include <hardware/boot_control.h>
#include <bootloader_message.h>
#include <string>
#define BOOT_SLOT_PROP "ro.boot.slot_suffix"
struct BootControlPrivate {
// The base struct needs to be first in the list.
boot_control_module_t base;
// Whether this struct was initialized with data from the bootloader message
// that doesn't change until next reboot.
bool initialized;
// The path to the misc_device as reported in the fstab.
const char* misc_device;
// The number of slots present on the device.
unsigned int num_slots;
// The slot where we are running from.
unsigned int current_slot;
};
constexpr unsigned int kMaxNumSlots =
sizeof(bootloader_control::slot_info) /
sizeof(bootloader_control::slot_info[0]);
constexpr const char* kSlotSuffixes[kMaxNumSlots] = { "_a", "_b", "_c", "_d" };
// Return the little-endian representation of the CRC-32 of the first fields
// in |boot_ctrl| up to the crc32_le field.
static uint32_t GetBootloaderControlCRC(const bootloader_control* boot_ctrl) {
return crc32(0, (const uint8_t*)boot_ctrl,
offsetof(bootloader_control, crc32_le));
}
static bool LoadBootloaderControl(const char* misc_device,
bootloader_control* boot_ctrl) {
std::string str_err;
if (read_bootloader_control_from(boot_ctrl, misc_device, &str_err))
return true;
ALOGE("%s", str_err.c_str());
return false;
}
static bool SaveBootloaderControl(const char* misc_device,
bootloader_control* boot_ctrl) {
boot_ctrl->crc32_le = GetBootloaderControlCRC(boot_ctrl);
std::string str_err;
if (write_bootloader_control_to(boot_ctrl, misc_device, &str_err))
return true;
ALOGE("%s", str_err.c_str());
return false;
}
// Return the index of the slot suffix passed or -1 if not a valid slot suffix.
static int SlotSuffixToIndex(const char* suffix) {
for (unsigned int slot = 0; slot < kMaxNumSlots; ++slot) {
if (!strcmp(kSlotSuffixes[slot], suffix)) return slot;
}
return -1;
}
static bool IsInitialized(const BootControlPrivate* module) {
if (!module->initialized) {
ALOGW("Module not initialized");
return false;
}
return true;
}
void BootControlInit(boot_control_module_t* module) {
struct BootControlPrivate* bootctrl_module =
reinterpret_cast<BootControlPrivate*>(module);
if (bootctrl_module->initialized) return;
if (!module) {
ALOGE("Invalid argument passed to %s", __func__);
return;
}
ALOGI("Init %s", module->common.name);
// Initialize the current_slot from the read-only property. If the property
// was not set (from either the command line or the device tree), we can later
// initialize it from the bootloader_control struct.
char suffix_prop[PROPERTY_VALUE_MAX] = {0};
property_get(BOOT_SLOT_PROP, suffix_prop, "");
bootctrl_module->current_slot = SlotSuffixToIndex(suffix_prop);
std::string err;
std::string device = get_bootloader_message_blk_device(&err);
bootloader_control boot_ctrl;
if (!LoadBootloaderControl(device.c_str(), &boot_ctrl))
ALOGE("Error loading metadata");
// Note that since there isn't a module unload function this memory is leaked.
bootctrl_module->misc_device = strdup(device.c_str());
uint32_t computed_crc32 = GetBootloaderControlCRC(&boot_ctrl);
if (boot_ctrl.crc32_le != computed_crc32) {
ALOGE("Invalid boot control found, expected CRC-32 0x%04X, "
"but found 0x%04X. Should re-initializing A/B metadata.",
computed_crc32, boot_ctrl.crc32_le);
return;
}
std::string metadata_suffix = "_" + std::string(boot_ctrl.slot_suffix);
if (SlotSuffixToIndex(metadata_suffix.c_str()) !=
bootctrl_module->current_slot) {
ALOGE("Kernel slot argument and A/B metadata do not match, "
"%s=%s, slot metadata=%s", BOOT_SLOT_PROP, suffix_prop,
boot_ctrl.slot_suffix);
return;
}
bootctrl_module->initialized = true;
bootctrl_module->num_slots = boot_ctrl.nb_slot;
ALOGI("Current slot: %s(%d), number of slots: %d", boot_ctrl.slot_suffix,
bootctrl_module->current_slot, bootctrl_module->num_slots);
return;
}
unsigned int GetNumberSlots(boot_control_module_t* module) {
BootControlPrivate* const bootctrl_module =
reinterpret_cast<BootControlPrivate*>(module);
if (!IsInitialized(bootctrl_module)) return -1;
return bootctrl_module->num_slots;
}
unsigned int GetCurrentSlot(boot_control_module_t* module) {
BootControlPrivate* const bootctrl_module =
reinterpret_cast<BootControlPrivate*>(module);
if (!IsInitialized(bootctrl_module)) return -1;
return bootctrl_module->current_slot;
}
int IsSlotMarkedSuccessful(boot_control_module_t* module, unsigned int slot) {
BootControlPrivate* const bootctrl_module =
reinterpret_cast<BootControlPrivate*>(module);
if (!IsInitialized(bootctrl_module)) return -1;
if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) {
// Invalid slot number.
return -1;
}
bootloader_control bootctrl;
if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl))
return -1;
return (bootctrl.slot_info[slot].successful_boot &&
bootctrl.slot_info[slot].tries_remaining);
}
int MarkBootSuccessful(boot_control_module_t* module) {
BootControlPrivate* const bootctrl_module =
reinterpret_cast<BootControlPrivate*>(module);
if (!IsInitialized(bootctrl_module)) return -1;
bootloader_control bootctrl;
if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl))
return -1;
bootctrl.slot_info[bootctrl_module->current_slot].successful_boot = 1;
// tries_remaining == 0 means that the slot is not bootable anymore, make
// sure we mark the current slot as bootable if it succeeds in the last
// attempt.
bootctrl.slot_info[bootctrl_module->current_slot].tries_remaining = 1;
if (!SaveBootloaderControl(bootctrl_module->misc_device, &bootctrl))
return -1;
ALOGI("Slot %d is marked as successfully booted",
bootctrl_module->current_slot);
return 0;
}
int SetActiveBootSlot(boot_control_module_t* module, unsigned int slot) {
BootControlPrivate* const bootctrl_module =
reinterpret_cast<BootControlPrivate*>(module);
if (!IsInitialized(bootctrl_module))
return -1;
if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) {
// Invalid slot number.
return -1;
}
bootloader_control bootctrl;
if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl))
return -1;
// Set every other slot with a lower priority than the new "active" slot.
const unsigned int kActivePriority = 15;
const unsigned int kActiveTries = 6;
for (unsigned int i = 0; i < bootctrl_module->num_slots; ++i) {
if (i != slot) {
if (bootctrl.slot_info[i].priority >= kActivePriority)
bootctrl.slot_info[i].priority = kActivePriority - 1;
}
}
// Note that setting a slot as active doesn't change the successful bit.
// The successful bit will only be changed by setSlotAsUnbootable().
bootctrl.slot_info[slot].priority = kActivePriority;
bootctrl.slot_info[slot].tries_remaining = kActiveTries;
// Setting the current slot as active is a way to revert the operation that
// set *another* slot as active at the end of an updater. This is commonly
// used to cancel the pending update. We should only reset the verity_corrpted
// bit when attempting a new slot, otherwise the verity bit on the current
// slot would be flip.
if (slot != bootctrl_module->current_slot)
bootctrl.slot_info[slot].verity_corrupted = 0;
if (!SaveBootloaderControl(bootctrl_module->misc_device, &bootctrl))
return -1;
ALOGI("Slot %d is set as active", slot);
return 0;
}
int SetSlotAsUnbootable(boot_control_module_t* module, unsigned int slot) {
BootControlPrivate* const bootctrl_module =
reinterpret_cast<BootControlPrivate*>(module);
if (!IsInitialized(bootctrl_module))
return -1;
if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) {
// Invalid slot number.
return -1;
}
bootloader_control bootctrl;
if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl))
return -1;
// The only way to mark a slot as unbootable, regardless of the priority is to
// set the tries_remaining to 0.
bootctrl.slot_info[slot].successful_boot = 0;
bootctrl.slot_info[slot].tries_remaining = 0;
if (!SaveBootloaderControl(bootctrl_module->misc_device, &bootctrl))
return -1;
ALOGI("Slot %d is marked as unbootable", slot);
return 0;
}
int IsSlotBootable(struct boot_control_module* module, unsigned int slot) {
BootControlPrivate* const bootctrl_module =
reinterpret_cast<BootControlPrivate*>(module);
if (!IsInitialized(bootctrl_module)) return -1;
if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) {
// Invalid slot number.
return -1;
}
bootloader_control bootctrl;
if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl))
return -1;
return bootctrl.slot_info[slot].tries_remaining;
}
const char* GetSuffix(boot_control_module_t* module, unsigned int slot) {
BootControlPrivate* const bootctrl_module =
reinterpret_cast<BootControlPrivate*>(module);
if (!IsInitialized(bootctrl_module)) return NULL;
if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) return NULL;
return kSlotSuffixes[slot];
}
static hw_module_methods_t boot_control_module_methods = {
.open = NULL,
};
BootControlPrivate HAL_MODULE_INFO_SYM = {
.base = {
.common ={
.tag = HARDWARE_MODULE_TAG,
.module_api_version = 1,
.hal_api_version = 0,
.id = BOOT_CONTROL_HARDWARE_MODULE_ID,
.name = "Yukawa Boot control HAL",
.author = "The Android Open Source Project",
.methods = &boot_control_module_methods
},
.init = BootControlInit,
.getNumberSlots = GetNumberSlots,
.getCurrentSlot = GetCurrentSlot,
.markBootSuccessful = MarkBootSuccessful,
.setActiveBootSlot = SetActiveBootSlot,
.setSlotAsUnbootable = SetSlotAsUnbootable,
.isSlotBootable = IsSlotBootable,
.getSuffix = GetSuffix,
.isSlotMarkedSuccessful = IsSlotMarkedSuccessful
},
.initialized = false,
.misc_device = nullptr,
.num_slots = 0,
.current_slot = 0
};

View File

@ -0,0 +1,252 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* 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 "bootloader_message.h"
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <string>
#include <vector>
#include <android-base/file.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
#include <fstab/fstab.h>
using android::fs_mgr::Fstab;
using android::fs_mgr::GetEntryForMountPoint;
using android::fs_mgr::ReadDefaultFstab;
constexpr off_t kBootloaderControlOffset = offsetof(bootloader_message_ab, slot_suffix);
static std::string get_misc_blk_device(std::string* err) {
Fstab fstab;
if (!ReadDefaultFstab(&fstab)) {
*err = "failed to read default fstab";
return "";
}
auto record = GetEntryForMountPoint(&fstab, "/misc");
if (record == nullptr) {
*err = "failed to find /misc partition";
return "";
}
return record->blk_device;
}
// In recovery mode, recovery can get started and try to access the misc
// device before the kernel has actually created it.
static bool wait_for_device(const std::string& blk_device, std::string* err) {
int tries = 0;
int ret;
err->clear();
do {
++tries;
struct stat buf;
ret = stat(blk_device.c_str(), &buf);
if (ret == -1) {
*err += android::base::StringPrintf("failed to stat %s try %d: %s\n",
blk_device.c_str(), tries, strerror(errno));
sleep(1);
}
} while (ret && tries < 10);
if (ret) {
*err += android::base::StringPrintf("failed to stat %s\n", blk_device.c_str());
}
return ret == 0;
}
static bool read_misc_partition(void* p, size_t size, const std::string& misc_blk_device,
size_t offset, std::string* err) {
if (!wait_for_device(misc_blk_device, err)) {
return false;
}
android::base::unique_fd fd(open(misc_blk_device.c_str(), O_RDONLY));
if (fd == -1) {
*err = android::base::StringPrintf("failed to open %s: %s", misc_blk_device.c_str(),
strerror(errno));
return false;
}
if (lseek(fd, static_cast<off_t>(offset), SEEK_SET) != static_cast<off_t>(offset)) {
*err = android::base::StringPrintf("failed to lseek %s: %s", misc_blk_device.c_str(),
strerror(errno));
return false;
}
if (!android::base::ReadFully(fd, p, size)) {
*err = android::base::StringPrintf("failed to read %s: %s", misc_blk_device.c_str(),
strerror(errno));
return false;
}
return true;
}
static bool write_misc_partition(const void* p, size_t size, const std::string& misc_blk_device,
size_t offset, std::string* err) {
android::base::unique_fd fd(open(misc_blk_device.c_str(), O_WRONLY));
if (fd == -1) {
*err = android::base::StringPrintf("failed to open %s: %s", misc_blk_device.c_str(),
strerror(errno));
return false;
}
if (lseek(fd, static_cast<off_t>(offset), SEEK_SET) != static_cast<off_t>(offset)) {
*err = android::base::StringPrintf("failed to lseek %s: %s", misc_blk_device.c_str(),
strerror(errno));
return false;
}
if (!android::base::WriteFully(fd, p, size)) {
*err = android::base::StringPrintf("failed to write %s: %s", misc_blk_device.c_str(),
strerror(errno));
return false;
}
if (fsync(fd) == -1) {
*err = android::base::StringPrintf("failed to fsync %s: %s", misc_blk_device.c_str(),
strerror(errno));
return false;
}
return true;
}
std::string get_bootloader_message_blk_device(std::string* err) {
std::string misc_blk_device = get_misc_blk_device(err);
if (misc_blk_device.empty()) return "";
if (!wait_for_device(misc_blk_device, err)) return "";
return misc_blk_device;
}
bool read_bootloader_message_from(bootloader_message* boot, const std::string& misc_blk_device,
std::string* err) {
return read_misc_partition(boot, sizeof(*boot), misc_blk_device,
BOOTLOADER_MESSAGE_OFFSET_IN_MISC, err);
}
bool read_bootloader_message(bootloader_message* boot, std::string* err) {
std::string misc_blk_device = get_misc_blk_device(err);
if (misc_blk_device.empty()) {
return false;
}
return read_bootloader_message_from(boot, misc_blk_device, err);
}
bool read_bootloader_control_from(bootloader_control* boot_ctrl, const std::string& misc_blk_device,
std::string* err) {
return read_misc_partition(boot_ctrl, sizeof(bootloader_control), misc_blk_device,
kBootloaderControlOffset, err);
}
bool write_bootloader_message_to(const bootloader_message& boot, const std::string& misc_blk_device,
std::string* err) {
return write_misc_partition(&boot, sizeof(boot), misc_blk_device,
BOOTLOADER_MESSAGE_OFFSET_IN_MISC, err);
}
bool write_bootloader_message(const bootloader_message& boot, std::string* err) {
std::string misc_blk_device = get_misc_blk_device(err);
if (misc_blk_device.empty()) {
return false;
}
return write_bootloader_message_to(boot, misc_blk_device, err);
}
bool write_bootloader_control_to(const bootloader_control* boot_ctrl, const std::string& misc_blk_device,
std::string* err) {
return write_misc_partition(boot_ctrl, sizeof(bootloader_control), misc_blk_device,
kBootloaderControlOffset, err);
}
bool clear_bootloader_message(std::string* err) {
bootloader_message boot = {};
return write_bootloader_message(boot, err);
}
bool write_bootloader_message(const std::vector<std::string>& options, std::string* err) {
bootloader_message boot = {};
update_bootloader_message_in_struct(&boot, options);
return write_bootloader_message(boot, err);
}
bool update_bootloader_message(const std::vector<std::string>& options, std::string* err) {
bootloader_message boot;
if (!read_bootloader_message(&boot, err)) {
return false;
}
update_bootloader_message_in_struct(&boot, options);
return write_bootloader_message(boot, err);
}
bool update_bootloader_message_in_struct(bootloader_message* boot,
const std::vector<std::string>& options) {
if (!boot) return false;
// Replace the command & recovery fields.
memset(boot->command, 0, sizeof(boot->command));
memset(boot->recovery, 0, sizeof(boot->recovery));
strlcpy(boot->command, "boot-recovery", sizeof(boot->command));
strlcpy(boot->recovery, "recovery\n", sizeof(boot->recovery));
for (const auto& s : options) {
strlcat(boot->recovery, s.c_str(), sizeof(boot->recovery));
if (s.back() != '\n') {
strlcat(boot->recovery, "\n", sizeof(boot->recovery));
}
}
return true;
}
bool write_reboot_bootloader(std::string* err) {
bootloader_message boot;
if (!read_bootloader_message(&boot, err)) {
return false;
}
if (boot.command[0] != '\0') {
*err = "Bootloader command pending.";
return false;
}
strlcpy(boot.command, "bootonce-bootloader", sizeof(boot.command));
return write_bootloader_message(boot, err);
}
bool read_wipe_package(std::string* package_data, size_t size, std::string* err) {
std::string misc_blk_device = get_misc_blk_device(err);
if (misc_blk_device.empty()) {
return false;
}
package_data->resize(size);
return read_misc_partition(&(*package_data)[0], size, misc_blk_device,
WIPE_PACKAGE_OFFSET_IN_MISC, err);
}
bool write_wipe_package(const std::string& package_data, std::string* err) {
std::string misc_blk_device = get_misc_blk_device(err);
if (misc_blk_device.empty()) {
return false;
}
return write_misc_partition(package_data.data(), package_data.size(), misc_blk_device,
WIPE_PACKAGE_OFFSET_IN_MISC, err);
}
extern "C" bool write_reboot_bootloader(void) {
std::string err;
return write_reboot_bootloader(&err);
}
extern "C" bool write_bootloader_message(const char* options) {
std::string err;
return write_bootloader_message({options}, &err);
}

View File

@ -0,0 +1,249 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* 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 _BOOTLOADER_MESSAGE_H
#define _BOOTLOADER_MESSAGE_H
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
// Spaces used by misc partition are as below:
// 0 - 2K For bootloader_message
// 2K - 16K Used by Vendor's bootloader (the 2K - 4K range may be optionally used
// as bootloader_message_ab struct)
// 16K - 64K Used by uncrypt and recovery to store wipe_package for A/B devices
// Note that these offsets are admitted by bootloader,recovery and uncrypt, so they
// are not configurable without changing all of them.
static const size_t BOOTLOADER_MESSAGE_OFFSET_IN_MISC = 0;
static const size_t WIPE_PACKAGE_OFFSET_IN_MISC = 16 * 1024;
/* Bootloader Message (2-KiB)
*
* This structure describes the content of a block in flash
* that is used for recovery and the bootloader to talk to
* each other.
*
* The command field is updated by linux when it wants to
* reboot into recovery or to update radio or bootloader firmware.
* It is also updated by the bootloader when firmware update
* is complete (to boot into recovery for any final cleanup)
*
* The status field was used by the bootloader after the completion
* of an "update-radio" or "update-hboot" command, which has been
* deprecated since Froyo.
*
* The recovery field is only written by linux and used
* for the system to send a message to recovery or the
* other way around.
*
* The stage field is written by packages which restart themselves
* multiple times, so that the UI can reflect which invocation of the
* package it is. If the value is of the format "#/#" (eg, "1/3"),
* the UI will add a simple indicator of that status.
*
* We used to have slot_suffix field for A/B boot control metadata in
* this struct, which gets unintentionally cleared by recovery or
* uncrypt. Move it into struct bootloader_message_ab to avoid the
* issue.
*/
struct bootloader_message {
char command[32];
char status[32];
char recovery[768];
// The 'recovery' field used to be 1024 bytes. It has only ever
// been used to store the recovery command line, so 768 bytes
// should be plenty. We carve off the last 256 bytes to store the
// stage string (for multistage packages) and possible future
// expansion.
char stage[32];
// The 'reserved' field used to be 224 bytes when it was initially
// carved off from the 1024-byte recovery field. Bump it up to
// 1184-byte so that the entire bootloader_message struct rounds up
// to 2048-byte.
char reserved[1184];
};
/**
* We must be cautious when changing the bootloader_message struct size,
* because A/B-specific fields may end up with different offsets.
*/
#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
static_assert(sizeof(struct bootloader_message) == 2048,
"struct bootloader_message size changes, which may break A/B devices");
#endif
/**
* The A/B-specific bootloader message structure (4-KiB).
*
* We separate A/B boot control metadata from the regular bootloader
* message struct and keep it here. Everything that's A/B-specific
* stays after struct bootloader_message, which should be managed by
* the A/B-bootloader or boot control HAL.
*
* The slot_suffix field is used for A/B implementations where the
* bootloader does not set the androidboot.ro.boot.slot_suffix kernel
* commandline parameter. This is used by fs_mgr to mount /system and
* other partitions with the slotselect flag set in fstab. A/B
* implementations are free to use all 32 bytes and may store private
* data past the first NUL-byte in this field. It is encouraged, but
* not mandatory, to use 'struct bootloader_control' described below.
*
* The update_channel field is used to store the Omaha update channel
* if update_engine is compiled with Omaha support.
*/
struct bootloader_message_ab {
struct bootloader_message message;
char slot_suffix[32];
char update_channel[128];
// Round up the entire struct to 4096-byte.
char reserved[1888];
};
/**
* Be cautious about the struct size change, in case we put anything post
* bootloader_message_ab struct (b/29159185).
*/
#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
static_assert(sizeof(struct bootloader_message_ab) == 4096,
"struct bootloader_message_ab size changes");
#endif
#define BOOT_CTRL_MAGIC 0x42414342 /* Bootloader Control AB */
#define BOOT_CTRL_VERSION 1
struct slot_metadata {
// Slot priority with 15 meaning highest priority, 1 lowest
// priority and 0 the slot is unbootable.
uint8_t priority : 4;
// Number of times left attempting to boot this slot.
uint8_t tries_remaining : 3;
// 1 if this slot has booted successfully, 0 otherwise.
uint8_t successful_boot : 1;
// 1 if this slot is corrupted from a dm-verity corruption, 0
// otherwise.
uint8_t verity_corrupted : 1;
// Reserved for further use.
uint8_t reserved : 7;
} __attribute__((packed));
/* Bootloader Control AB
*
* This struct can be used to manage A/B metadata. It is designed to
* be put in the 'slot_suffix' field of the 'bootloader_message'
* structure described above. It is encouraged to use the
* 'bootloader_control' structure to store the A/B metadata, but not
* mandatory.
*/
struct bootloader_control {
// NUL terminated active slot suffix.
char slot_suffix[4];
// Bootloader Control AB magic number (see BOOT_CTRL_MAGIC).
uint32_t magic;
// Version of struct being used (see BOOT_CTRL_VERSION).
uint8_t version;
// Number of slots being managed.
uint8_t nb_slot : 3;
// Number of times left attempting to boot recovery.
uint8_t recovery_tries_remaining : 3;
// Ensure 4-bytes alignment for slot_info field.
uint8_t reserved0[2];
// Per-slot information. Up to 4 slots.
struct slot_metadata slot_info[4];
// Reserved for further use.
uint8_t reserved1[8];
// CRC32 of all 28 bytes preceding this field (little endian
// format).
uint32_t crc32_le;
} __attribute__((packed));
#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
static_assert(sizeof(struct bootloader_control) ==
sizeof(((struct bootloader_message_ab *)0)->slot_suffix),
"struct bootloader_control has wrong size");
#endif
#ifdef __cplusplus
#include <string>
#include <vector>
// Return the block device name for the bootloader message partition and waits
// for the device for up to 10 seconds. In case of error returns the empty
// string.
std::string get_bootloader_message_blk_device(std::string* err);
// Read bootloader message into boot. Error message will be set in err.
bool read_bootloader_message(bootloader_message* boot, std::string* err);
// Read bootloader message from the specified misc device into boot.
bool read_bootloader_message_from(bootloader_message* boot, const std::string& misc_blk_device,
std::string* err);
// Read bootloader control block from the specified misc device into boot_ctrl.
bool read_bootloader_control_from(bootloader_control* boot_ctrl, const std::string& misc_blk_device,
std::string* err);
// Write bootloader message to BCB.
bool write_bootloader_message(const bootloader_message& boot, std::string* err);
// Write bootloader message to the specified BCB device.
bool write_bootloader_message_to(const bootloader_message& boot,
const std::string& misc_blk_device, std::string* err);
// Write bootloader message (boots into recovery with the options) to BCB. Will
// set the command and recovery fields, and reset the rest.
bool write_bootloader_message(const std::vector<std::string>& options, std::string* err);
// Write bootloader control block to the specified BCB device.
bool write_bootloader_control_to(const bootloader_control* boot_ctrl, const std::string& misc_blk_device,
std::string* err);
// Update bootloader message (boots into recovery with the options) to BCB. Will
// only update the command and recovery fields.
bool update_bootloader_message(const std::vector<std::string>& options, std::string* err);
// Update bootloader message (boots into recovery with the |options|) in |boot|. Will only update
// the command and recovery fields.
bool update_bootloader_message_in_struct(bootloader_message* boot,
const std::vector<std::string>& options);
// Clear BCB.
bool clear_bootloader_message(std::string* err);
// Writes the reboot-bootloader reboot reason to the bootloader_message.
bool write_reboot_bootloader(std::string* err);
// Read the wipe package from BCB (from offset WIPE_PACKAGE_OFFSET_IN_MISC).
bool read_wipe_package(std::string* package_data, size_t size, std::string* err);
// Write the wipe package into BCB (to offset WIPE_PACKAGE_OFFSET_IN_MISC).
bool write_wipe_package(const std::string& package_data, std::string* err);
#else
#include <stdbool.h>
// C Interface.
bool write_bootloader_message(const char* options);
bool write_reboot_bootloader(void);
#endif // ifdef __cplusplus
#endif // _BOOTLOADER_MESSAGE_H

View File

@ -0,0 +1,17 @@
<ExternalCamera>
<Provider>
<ignore> <!-- Internal video devices to be ignored by external camera HAL -->
<id>0</id>
</ignore>
</Provider>
<Device>
<MaxJpegBufferSize bytes="3145728"/>
<NumVideoBuffers count="4"/>
<NumStillBuffers count="2"/>
<FpsList>
<Limit width="640" height="480" fpsBound="30.0"/>
<Limit width="1280" height="720" fpsBound="30.0"/>
<Limit width="1920" height="1080" fpsBound="30.0"/>
</FpsList>
</Device>
</ExternalCamera>

View File

@ -0,0 +1,18 @@
package {
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "device_amlogic_yukawa_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
// SPDX-license-identifier-GPL-2.0
default_applicable_licenses: ["device_amlogic_yukawa_license"],
}
cc_library_shared {
name: "hwcomposer.drm_meson",
defaults: ["hwcomposer.drm_defaults"],
srcs: [
":drm_hwcomposer_common",
":drm_hwcomposer_platformmeson",
],
}

View File

@ -0,0 +1,20 @@
#
# Copyright (C) 2016 ARM Limited. All rights reserved.
#
# Copyright (C) 2008 The Android Open Source Project
#
# 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.
$(info gralloc for juno)
GRALLOC_FB_SWAP_RED_BLUE := 1
GRALLOC_DEPTH := GRALLOC_32_BITS

View File

@ -0,0 +1,185 @@
#
# Copyright (C) 2016-2017 ARM Limited. All rights reserved.
#
# Copyright (C) 2008 The Android Open Source Project
#
# 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.
LOCAL_PATH := $(call my-dir)
# Include platform specific makefiles
include $(if $(wildcard $(LOCAL_PATH)/Android.$(TARGET_BOARD_PLATFORM).mk), $(LOCAL_PATH)/Android.$(TARGET_BOARD_PLATFORM).mk,)
#
# Static hardware defines
#
# These defines are used in case runtime detection does not find the
# user-space driver to read out hardware capabilities
# GPU support for AFBC 1.0
MALI_GPU_SUPPORT_AFBC_BASIC?=0
# GPU support for AFBC 1.1 block split
MALI_GPU_SUPPORT_AFBC_SPLITBLK?=0
# GPU support for AFBC 1.1 wide block
MALI_GPU_SUPPORT_AFBC_WIDEBLK?=0
# GPU support for AFBC 1.2 tiled headers
MALI_GPU_SUPPORT_AFBC_TILED_HEADERS?=0
# GPU support YUV AFBC formats in wide block
MALI_GPU_USE_YUV_AFBC_WIDEBLK?=0
# VPU version we support
MALI_VIDEO_VERSION?=0
# DPU version we support
MALI_DISPLAY_VERSION?=0
#
# Software behaviour defines
#
# Gralloc1 support
GRALLOC_USE_GRALLOC1_API?=0
# Use ION DMA heap for all allocations. Default is system heap.
GRALLOC_USE_ION_DMA_HEAP?=0
# Use ION Compound heap for all allocations. Default is system heap.
GRALLOC_USE_ION_COMPOUND_PAGE_HEAP?=0
# Properly initializes an empty AFBC buffer
GRALLOC_INIT_AFBC?=0
# fbdev bitdepth to use
GRALLOC_DEPTH?=GRALLOC_32_BITS
# When enabled, forces display framebuffer format to BGRA_8888
GRALLOC_FB_SWAP_RED_BLUE?=1
# Disables the framebuffer HAL device. When a hwc impl is available.
GRALLOC_DISABLE_FRAMEBUFFER_HAL?=0
# When enabled, buffers will never be allocated with AFBC
GRALLOC_ARM_NO_EXTERNAL_AFBC?=0
# Minimum buffer dimensions in pixels when buffer will use AFBC
GRALLOC_DISP_W?=0
GRALLOC_DISP_H?=0
# Vsync backend(not used)
GRALLOC_VSYNC_BACKEND?=default
# HAL module implemenation, not prelinked and stored in
# hw/<OVERLAY_HARDWARE_MODULE_ID>.<ro.product.board>.so
include $(CLEAR_VARS)
ifeq ($(TARGET_BOARD_PLATFORM), juno)
ifeq ($(MALI_MMSS), 1)
# Use latest default MMSS build configuration if not already defined
ifeq ($(MALI_DISPLAY_VERSION), 0)
MALI_DISPLAY_VERSION = 650
endif
ifeq ($(MALI_VIDEO_VERSION), 0)
MALI_VIDEO_VERSION = 550
endif
GRALLOC_FB_SWAP_RED_BLUE = 0
GRALLOC_USE_ION_DMA_HEAP = 1
endif
endif
ifeq ($(TARGET_BOARD_PLATFORM), armboard_v7a)
ifeq ($(GRALLOC_MALI_DP),true)
GRALLOC_FB_SWAP_RED_BLUE = 0
GRALLOC_DISABLE_FRAMEBUFFER_HAL=1
MALI_DISPLAY_VERSION = 550
GRALLOC_USE_ION_DMA_HEAP=1
endif
endif
ifneq ($(MALI_DISPLAY_VERSION), 0)
#if Mali display is available, should disable framebuffer HAL
GRALLOC_DISABLE_FRAMEBUFFER_HAL := 1
#if Mali display is available, AFBC buffers should be initialised after allocation
GRALLOC_INIT_AFBC := 1
endif
ifeq ($(GRALLOC_USE_ION_DMA_HEAP), 1)
ifeq ($(GRALLOC_USE_ION_COMPOUND_PAGE_HEAP), 1)
$(error GRALLOC_USE_ION_DMA_HEAP and GRALLOC_USE_ION_COMPOUND_PAGE_HEAP can't be enabled at the same time)
endif
endif
PLATFORM_SDK_GREATER_THAN_24 := $(shell expr $(PLATFORM_SDK_VERSION) \> 24)
ifeq ($(PLATFORM_SDK_GREATER_THAN_24), 1)
ifeq ($(GRALLOC_EXPERIMENTAL), 1)
GRALLOC_USE_GRALLOC1_API := 1
endif
endif
LOCAL_C_INCLUDES := $(MALI_LOCAL_PATH) $(MALI_DDK_INCLUDES)
# General compilation flags
LOCAL_CFLAGS := -Werror -DLOG_TAG=\"gralloc\" -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION)
# Static hw flags
LOCAL_CFLAGS += -DMALI_GPU_SUPPORT_AFBC_BASIC=$(MALI_GPU_SUPPORT_AFBC_BASIC)
LOCAL_CFLAGS += -DMALI_GPU_SUPPORT_AFBC_SPLITBLK=$(MALI_GPU_SUPPORT_AFBC_SPLITBLK)
LOCAL_CFLAGS += -DMALI_GPU_SUPPORT_AFBC_WIDEBLK=$(MALI_GPU_SUPPORT_AFBC_WIDEBLK)
LOCAL_CFLAGS += -DMALI_GPU_USE_YUV_AFBC_WIDEBLK=$(MALI_GPU_USE_YUV_AFBC_WIDEBLK)
LOCAL_CFLAGS += -DMALI_GPU_SUPPORT_AFBC_TILED_HEADERS=$(MALI_GPU_SUPPORT_AFBC_TILED_HEADERS)
LOCAL_CFLAGS += -DMALI_DISPLAY_VERSION=$(MALI_DISPLAY_VERSION)
LOCAL_CFLAGS += -DMALI_VIDEO_VERSION=$(MALI_VIDEO_VERSION)
# Software behaviour flags
LOCAL_CFLAGS += -DGRALLOC_USE_GRALLOC1_API=$(GRALLOC_USE_GRALLOC1_API)
LOCAL_CFLAGS += -DGRALLOC_DISP_W=$(GRALLOC_DISP_W)
LOCAL_CFLAGS += -DGRALLOC_DISP_H=$(GRALLOC_DISP_H)
LOCAL_CFLAGS += -DDISABLE_FRAMEBUFFER_HAL=$(GRALLOC_DISABLE_FRAMEBUFFER_HAL)
LOCAL_CFLAGS += -DGRALLOC_USE_ION_DMA_HEAP=$(GRALLOC_USE_ION_DMA_HEAP)
LOCAL_CFLAGS += -DGRALLOC_USE_ION_COMPOUND_PAGE_HEAP=$(GRALLOC_USE_ION_COMPOUND_PAGE_HEAP)
LOCAL_CFLAGS += -DGRALLOC_INIT_AFBC=$(GRALLOC_INIT_AFBC)
LOCAL_CFLAGS += -D$(GRALLOC_DEPTH)
LOCAL_CFLAGS += -DGRALLOC_FB_SWAP_RED_BLUE=$(GRALLOC_FB_SWAP_RED_BLUE)
LOCAL_CFLAGS += -DGRALLOC_ARM_NO_EXTERNAL_AFBC=$(GRALLOC_ARM_NO_EXTERNAL_AFBC)
LOCAL_CFLAGS += -DGRALLOC_LIBRARY_BUILD=1
LOCAL_SHARED_LIBRARIES := libhardware liblog libcutils libGLESv1_CM libion libsync libutils
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
LOCAL_MODULE := gralloc.yukawa
LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-GPL-2.0
LOCAL_LICENSE_CONDITIONS := notice restricted
LOCAL_MODULE_TAGS := optional
LOCAL_MULTILIB := both
LOCAL_SRC_FILES := \
mali_gralloc_module.cpp \
framebuffer_device.cpp \
gralloc_buffer_priv.cpp \
gralloc_vsync_${GRALLOC_VSYNC_BACKEND}.cpp \
mali_gralloc_bufferaccess.cpp \
mali_gralloc_bufferallocation.cpp \
mali_gralloc_bufferdescriptor.cpp \
mali_gralloc_ion.cpp \
mali_gralloc_formats.cpp \
mali_gralloc_reference.cpp \
mali_gralloc_debug.cpp
ifeq ($(GRALLOC_USE_GRALLOC1_API), 1)
LOCAL_SRC_FILES += \
mali_gralloc_public_interface.cpp \
mali_gralloc_private_interface.cpp
else
LOCAL_SRC_FILES += legacy/alloc_device.cpp
endif
LOCAL_MODULE_OWNER := arm
include $(BUILD_SHARED_LIBRARY)

View File

@ -0,0 +1,20 @@
#
# Copyright (C) 2016 ARM Limited. All rights reserved.
#
# Copyright (C) 2008 The Android Open Source Project
#
# 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.
$(info gralloc for vexpress)
GRALLOC_FB_SWAP_RED_BLUE := 0
GRALLOC_DEPTH := GRALLOC_16_BITS

View File

@ -0,0 +1,54 @@
#
# Copyright (C) 2016 ARM Limited. All rights reserved.
#
# Copyright (C) 2008 The Android Open Source Project
#
# 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.
# GPU support for AFBC 1.0
MALI_GPU_SUPPORT_AFBC_BASIC=0
# GPU support for AFBC 1.1 block split
MALI_GPU_SUPPORT_AFBC_SPLITBLK=0
# GPU support for AFBC 1.1 wide block
MALI_GPU_SUPPORT_AFBC_WIDEBLK=0
# GPU support for AFBC 1.2 tiled headers
MALI_GPU_SUPPORT_AFBC_TILED_HEADERS=0
# GPU support YUV AFBC formats in wide block
MALI_GPU_USE_YUV_AFBC_WIDEBLK=0
#
# Software behaviour defines
#
# Gralloc1 support
GRALLOC_USE_GRALLOC1_API=1
# Use ION DMA heap for all allocations. Default is system heap.
GRALLOC_USE_ION_DMA_HEAP=1
# Use ION Compound heap for all allocations. Default is system heap.
GRALLOC_USE_ION_COMPOUND_PAGE_HEAP=0
# Properly initializes an empty AFBC buffer
GRALLOC_INIT_AFBC=0
# fbdev bitdepth to use
GRALLOC_DEPTH=GRALLOC_32_BITS
# When enabled, forces display framebuffer format to BGRA_8888
GRALLOC_FB_SWAP_RED_BLUE=0
# Disables the framebuffer HAL device. When a hwc impl is available.
GRALLOC_DISABLE_FRAMEBUFFER_HAL=1
# When enabled, buffers will never be allocated with AFBC
GRALLOC_ARM_NO_EXTERNAL_AFBC=1
# Minimum buffer dimensions in pixels when buffer will use AFBC
GRALLOC_DISP_W=0
GRALLOC_DISP_H=0
# Vsync backend(not used)
GRALLOC_VSYNC_BACKEND=default

View File

@ -0,0 +1,53 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* DMABUF Heaps Userspace API
*
* Copyright (C) 2011 Google, Inc.
* Copyright (C) 2019 Linaro Ltd.
*/
#ifndef _UAPI_LINUX_DMABUF_POOL_H
#define _UAPI_LINUX_DMABUF_POOL_H
#include <linux/ioctl.h>
#include <linux/types.h>
/**
* DOC: DMABUF Heaps Userspace API
*/
/* Valid FD_FLAGS are O_CLOEXEC, O_RDONLY, O_WRONLY, O_RDWR */
#define DMA_HEAP_VALID_FD_FLAGS (O_CLOEXEC | O_ACCMODE)
/* Currently no heap flags */
#define DMA_HEAP_VALID_HEAP_FLAGS (0)
/**
* struct dma_heap_allocation_data - metadata passed from userspace for
* allocations
* @len: size of the allocation
* @fd: will be populated with a fd which provides the
* handle to the allocated dma-buf
* @fd_flags: file descriptor flags used when allocating
* @heap_flags: flags passed to heap
*
* Provided by userspace as an argument to the ioctl
*/
struct dma_heap_allocation_data {
__u64 len;
__u32 fd;
__u32 fd_flags;
__u64 heap_flags;
};
#define DMA_HEAP_IOC_MAGIC 'H'
/**
* DOC: DMA_HEAP_IOCTL_ALLOC - allocate memory from pool
*
* Takes a dma_heap_allocation_data struct and returns it with the fd field
* populated with the dmabuf handle of the allocation.
*/
#define DMA_HEAP_IOCTL_ALLOC _IOWR(DMA_HEAP_IOC_MAGIC, 0x0,\
struct dma_heap_allocation_data)
#endif /* _UAPI_LINUX_DMABUF_POOL_H */

View File

@ -0,0 +1,650 @@
/*
* Copyright (C) 2010-2017 ARM Limited. All rights reserved.
*
* Copyright (C) 2008 The Android Open Source Project
*
* 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 <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <log/log.h>
#include <cutils/atomic.h>
#include <hardware/hardware.h>
#include <hardware/fb.h>
#include <GLES/gl.h>
#if GRALLOC_USE_GRALLOC1_API == 1
#include <hardware/gralloc1.h>
#else
#include <hardware/gralloc.h>
#endif
#include "mali_gralloc_module.h"
#include "mali_gralloc_private_interface_types.h"
#include "mali_gralloc_buffer.h"
#include "gralloc_helper.h"
#include "gralloc_vsync.h"
#include "mali_gralloc_bufferaccess.h"
#include "mali_gralloc_ion.h"
#define STANDARD_LINUX_SCREEN
// numbers of buffers for page flipping
#define NUM_BUFFERS NUM_FB_BUFFERS
enum
{
PAGE_FLIP = 0x00000001,
};
static int fb_set_swap_interval(struct framebuffer_device_t *dev, int interval)
{
if (interval < dev->minSwapInterval)
{
interval = dev->minSwapInterval;
}
else if (interval > dev->maxSwapInterval)
{
interval = dev->maxSwapInterval;
}
private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
m->swapInterval = interval;
if (0 == interval)
{
gralloc_vsync_disable(dev);
}
else
{
gralloc_vsync_enable(dev);
}
return 0;
}
static int fb_post(struct framebuffer_device_t *dev, buffer_handle_t buffer)
{
if (private_handle_t::validate(buffer) < 0)
{
return -EINVAL;
}
private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(buffer);
private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
if (m->currentBuffer)
{
mali_gralloc_unlock(m, m->currentBuffer);
m->currentBuffer = 0;
}
if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
{
mali_gralloc_lock(m, buffer, private_module_t::PRIV_USAGE_LOCKED_FOR_POST, -1, -1, -1, -1, NULL);
int interrupt;
m->info.activate = FB_ACTIVATE_VBL;
m->info.yoffset = hnd->offset / m->finfo.line_length;
#ifdef STANDARD_LINUX_SCREEN
if (ioctl(m->framebuffer->fd, FBIOPAN_DISPLAY, &m->info) == -1)
{
AERR("FBIOPAN_DISPLAY failed for fd: %d", m->framebuffer->fd);
mali_gralloc_unlock(m, buffer);
return -errno;
}
#else /*Standard Android way*/
if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1)
{
AERR("FBIOPUT_VSCREENINFO failed for fd: %d", m->framebuffer->fd);
mali_gralloc_unlock(m, buffer);
return -errno;
}
#endif
if (0 != gralloc_wait_for_vsync(dev))
{
AERR("Gralloc wait for vsync failed for fd: %d", m->framebuffer->fd);
mali_gralloc_unlock(m, buffer);
return -errno;
}
m->currentBuffer = buffer;
}
else
{
void *fb_vaddr;
void *buffer_vaddr;
mali_gralloc_lock(m, m->framebuffer, GRALLOC_USAGE_SW_WRITE_RARELY, -1, -1, -1, -1, &fb_vaddr);
mali_gralloc_lock(m, buffer, GRALLOC_USAGE_SW_READ_RARELY, -1, -1, -1, -1, &buffer_vaddr);
// If buffer's alignment match framebuffer alignment we can do a direct copy.
// If not we must fallback to do an aligned copy of each line.
if (hnd->byte_stride == (int)m->finfo.line_length)
{
memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres);
}
else
{
uintptr_t fb_offset = 0;
uintptr_t buffer_offset = 0;
unsigned int i;
for (i = 0; i < m->info.yres; i++)
{
memcpy((void *)((uintptr_t)fb_vaddr + fb_offset), (void *)((uintptr_t)buffer_vaddr + buffer_offset),
m->finfo.line_length);
fb_offset += m->finfo.line_length;
buffer_offset += hnd->byte_stride;
}
}
mali_gralloc_unlock(m, buffer);
mali_gralloc_unlock(m, m->framebuffer);
}
return 0;
}
static int init_frame_buffer_locked(struct private_module_t *module)
{
if (module->framebuffer)
{
return 0; // Nothing to do, already initialized
}
char const *const device_template[] = { "/dev/graphics/fb%u", "/dev/fb%u", NULL };
int fd = -1;
int i = 0;
char name[64];
while ((fd == -1) && device_template[i])
{
snprintf(name, 64, device_template[i], 0);
fd = open(name, O_RDWR, 0);
i++;
}
if (fd < 0)
{
return -errno;
}
struct fb_fix_screeninfo finfo;
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
{
return -errno;
}
struct fb_var_screeninfo info;
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
{
return -errno;
}
info.reserved[0] = 0;
info.reserved[1] = 0;
info.reserved[2] = 0;
info.xoffset = 0;
info.yoffset = 0;
info.activate = FB_ACTIVATE_NOW;
#ifdef GRALLOC_16_BITS
/*
* Explicitly request 5/6/5
*/
info.bits_per_pixel = 16;
info.red.offset = 11;
info.red.length = 5;
info.green.offset = 5;
info.green.length = 6;
info.blue.offset = 0;
info.blue.length = 5;
info.transp.offset = 0;
info.transp.length = 0;
#else
/*
* Explicitly request 8/8/8
*/
info.bits_per_pixel = 32;
info.red.offset = 16;
info.red.length = 8;
info.green.offset = 8;
info.green.length = 8;
info.blue.offset = 0;
info.blue.length = 8;
info.transp.offset = 0;
info.transp.length = 0;
#endif
/*
* Request NUM_BUFFERS screens (at lest 2 for page flipping)
*/
info.yres_virtual = info.yres * NUM_BUFFERS;
uint32_t flags = PAGE_FLIP;
if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1)
{
info.yres_virtual = info.yres;
flags &= ~PAGE_FLIP;
AWAR("FBIOPUT_VSCREENINFO failed, page flipping not supported fd: %d", fd);
}
if (info.yres_virtual < info.yres * 2)
{
// we need at least 2 for page-flipping
info.yres_virtual = info.yres;
flags &= ~PAGE_FLIP;
AWAR("page flipping not supported (yres_virtual=%d, requested=%d)", info.yres_virtual, info.yres * 2);
}
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
{
return -errno;
}
int refreshRate = 0;
if (info.pixclock > 0)
{
refreshRate =
1000000000000000LLU / (uint64_t(info.upper_margin + info.lower_margin + info.yres + info.hsync_len) *
(info.left_margin + info.right_margin + info.xres + info.vsync_len) * info.pixclock);
}
else
{
AWAR("fbdev pixclock is zero for fd: %d", fd);
}
if (refreshRate == 0)
{
refreshRate = 60 * 1000; // 60 Hz
}
if (int(info.width) <= 0 || int(info.height) <= 0)
{
// the driver doesn't return that information
// default to 160 dpi
info.width = ((info.xres * 25.4f) / 160.0f + 0.5f);
info.height = ((info.yres * 25.4f) / 160.0f + 0.5f);
}
float xdpi = (info.xres * 25.4f) / info.width;
float ydpi = (info.yres * 25.4f) / info.height;
float fps = refreshRate / 1000.0f;
AINF("using (fd=%d)\n"
"id = %s\n"
"xres = %d px\n"
"yres = %d px\n"
"xres_virtual = %d px\n"
"yres_virtual = %d px\n"
"bpp = %d\n"
"r = %2u:%u\n"
"g = %2u:%u\n"
"b = %2u:%u\n",
fd, finfo.id, info.xres, info.yres, info.xres_virtual, info.yres_virtual, info.bits_per_pixel, info.red.offset,
info.red.length, info.green.offset, info.green.length, info.blue.offset, info.blue.length);
AINF("width = %d mm (%f dpi)\n"
"height = %d mm (%f dpi)\n"
"refresh rate = %.2f Hz\n",
info.width, xdpi, info.height, ydpi, fps);
if (0 == strncmp(finfo.id, "CLCD FB", 7))
{
module->dpy_type = MALI_DPY_TYPE_CLCD;
}
else if (0 == strncmp(finfo.id, "ARM Mali HDLCD", 14))
{
module->dpy_type = MALI_DPY_TYPE_HDLCD;
}
else if (0 == strncmp(finfo.id, "ARM HDLCD Control", 16))
{
module->dpy_type = MALI_DPY_TYPE_HDLCD;
}
else
{
module->dpy_type = MALI_DPY_TYPE_UNKNOWN;
}
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
{
return -errno;
}
if (finfo.smem_len <= 0)
{
return -errno;
}
module->flags = flags;
module->info = info;
module->finfo = finfo;
module->xdpi = xdpi;
module->ydpi = ydpi;
module->fps = fps;
module->swapInterval = 1;
/*
* map the framebuffer
*/
size_t fbSize = round_up_to_page_size(finfo.line_length * info.yres_virtual);
void *vaddr = mmap(0, fbSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (vaddr == MAP_FAILED)
{
AERR("Error mapping the framebuffer (%s)", strerror(errno));
return -errno;
}
memset(vaddr, 0, fbSize);
// Create a "fake" buffer object for the entire frame buffer memory, and store it in the module
module->framebuffer = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, fbSize, vaddr,
GRALLOC_USAGE_HW_FB, GRALLOC_USAGE_HW_FB, dup(fd), 0);
module->numBuffers = info.yres_virtual / info.yres;
module->bufferMask = 0;
return 0;
}
static int init_frame_buffer(struct private_module_t *module)
{
pthread_mutex_lock(&module->lock);
int err = init_frame_buffer_locked(module);
pthread_mutex_unlock(&module->lock);
return err;
}
static int fb_close(struct hw_device_t *device)
{
framebuffer_device_t *dev = reinterpret_cast<framebuffer_device_t *>(device);
if (dev)
{
free(dev);
}
return 0;
}
static int fb_alloc_framebuffer_dmabuf(private_module_t *m, private_handle_t *hnd)
{
struct fb_dmabuf_export fb_dma_buf;
int res;
res = ioctl(m->framebuffer->fd, FBIOGET_DMABUF, &fb_dma_buf);
if (res == 0)
{
hnd->share_fd = fb_dma_buf.fd;
return 0;
}
else
{
AINF("FBIOGET_DMABUF ioctl failed(%d). See gralloc_priv.h and the integration manual for vendor framebuffer "
"integration",
res);
return -1;
}
}
static int fb_alloc_from_ion_module(mali_gralloc_module *m, size_t buffer_size, uint64_t consumer_usage,
uint64_t producer_usage, buffer_handle_t *pHandle)
{
buffer_descriptor_t fb_buffer_descriptor;
gralloc_buffer_descriptor_t gralloc_buffer_descriptor[1];
bool shared = false;
int err = 0;
fb_buffer_descriptor.size = buffer_size;
fb_buffer_descriptor.consumer_usage = consumer_usage;
fb_buffer_descriptor.producer_usage = producer_usage;
gralloc_buffer_descriptor[0] = (gralloc_buffer_descriptor_t)(&fb_buffer_descriptor);
err = mali_gralloc_ion_allocate(m, gralloc_buffer_descriptor, 1, pHandle, &shared);
return err;
}
static int fb_alloc_framebuffer_locked(mali_gralloc_module *m, uint64_t consumer_usage, uint64_t producer_usage,
buffer_handle_t *pHandle, int *stride, int *byte_stride)
{
// allocate the framebuffer
if (m->framebuffer == NULL)
{
// initialize the framebuffer, the framebuffer is mapped once and forever.
int err = init_frame_buffer_locked(m);
if (err < 0)
{
return err;
}
}
uint32_t bufferMask = m->bufferMask;
const uint32_t numBuffers = m->numBuffers;
/* framebufferSize is used for allocating the handle to the framebuffer and refers
* to the size of the actual framebuffer.
* alignedFramebufferSize is used for allocating a possible internal buffer and
* thus need to consider internal alignment requirements. */
const size_t framebufferSize = m->finfo.line_length * m->info.yres;
const size_t alignedFramebufferSize = GRALLOC_ALIGN(m->finfo.line_length, 64) * m->info.yres;
*stride = m->info.xres;
if (numBuffers == 1)
{
// If we have only one buffer, we never use page-flipping. Instead,
// we return a regular buffer which will be memcpy'ed to the main
// screen when post is called.
uint64_t newConsumerUsage = (consumer_usage & ~GRALLOC_USAGE_HW_FB);
uint64_t newProducerUsage = (producer_usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
AWAR("fallback to single buffering. Virtual Y-res too small %d", m->info.yres);
*byte_stride = GRALLOC_ALIGN(m->finfo.line_length, 64);
return fb_alloc_from_ion_module(m, alignedFramebufferSize, newConsumerUsage, newProducerUsage, pHandle);
}
if (bufferMask >= ((1LU << numBuffers) - 1))
{
// We ran out of buffers, reset bufferMask
bufferMask = 0;
m->bufferMask = 0;
}
uintptr_t framebufferVaddr = (uintptr_t)m->framebuffer->base;
// find a free slot
for (uint32_t i = 0; i < numBuffers; i++)
{
if ((bufferMask & (1LU << i)) == 0)
{
m->bufferMask |= (1LU << i);
break;
}
framebufferVaddr += framebufferSize;
}
// The entire framebuffer memory is already mapped, now create a buffer object for parts of this memory
private_handle_t *hnd = new private_handle_t(
private_handle_t::PRIV_FLAGS_FRAMEBUFFER, framebufferSize, (void *)framebufferVaddr, consumer_usage,
producer_usage, dup(m->framebuffer->fd), (framebufferVaddr - (uintptr_t)m->framebuffer->base));
/*
* Perform allocator specific actions. If these fail we fall back to a regular buffer
* which will be memcpy'ed to the main screen when fb_post is called.
*/
if (fb_alloc_framebuffer_dmabuf(m, hnd) == -1)
{
delete hnd;
uint64_t newConsumerUsage = (consumer_usage & ~GRALLOC_USAGE_HW_FB);
uint64_t newProducerUsage = (producer_usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
AERR("Fallback to single buffering. Unable to map framebuffer memory to handle:%p", hnd);
*byte_stride = GRALLOC_ALIGN(m->finfo.line_length, 64);
return fb_alloc_from_ion_module(m, alignedFramebufferSize, newConsumerUsage, newProducerUsage, pHandle);
}
*pHandle = hnd;
*byte_stride = m->finfo.line_length;
return 0;
}
int fb_alloc_framebuffer(mali_gralloc_module *m, uint64_t consumer_usage, uint64_t producer_usage,
buffer_handle_t *pHandle, int *stride, int *byte_stride)
{
pthread_mutex_lock(&m->lock);
int err = fb_alloc_framebuffer_locked(m, consumer_usage, producer_usage, pHandle, stride, byte_stride);
pthread_mutex_unlock(&m->lock);
return err;
}
int compositionComplete(struct framebuffer_device_t *dev)
{
GRALLOC_UNUSED(dev);
/* By doing a finish here we force the GL driver to start rendering
all the drawcalls up to this point, and to wait for the rendering to be complete.*/
glFinish();
/* The rendering of the backbuffer is now completed.
When SurfaceFlinger later does a call to eglSwapBuffer(), the swap will be done
synchronously in the same thread, and not asynchronoulsy in a background thread later.
The SurfaceFlinger requires this behaviour since it releases the lock on all the
SourceBuffers (Layers) after the compositionComplete() function returns.
However this "bad" behaviour by SurfaceFlinger should not affect performance,
since the Applications that render the SourceBuffers (Layers) still get the
full renderpipeline using asynchronous rendering. So they perform at maximum speed,
and because of their complexity compared to the Surface flinger jobs, the Surface flinger
is normally faster even if it does everyhing synchronous and serial.
*/
return 0;
}
int framebuffer_device_open(hw_module_t const *module, const char *name, hw_device_t **device)
{
int status = -EINVAL;
GRALLOC_UNUSED(name);
#if GRALLOC_USE_GRALLOC1_API == 1
gralloc1_device_t *gralloc_device;
#else
alloc_device_t *gralloc_device;
#endif
#if DISABLE_FRAMEBUFFER_HAL == 1
AERR("Framebuffer HAL not support/disabled %s",
#ifdef MALI_DISPLAY_VERSION
"with MALI display enable");
#else
"");
#endif
return -ENODEV;
#endif
#if GRALLOC_USE_GRALLOC1_API == 1
status = gralloc1_open(module, &gralloc_device);
#else
status = gralloc_open(module, &gralloc_device);
#endif
if (status < 0)
{
return status;
}
private_module_t *m = (private_module_t *)module;
status = init_frame_buffer(m);
/* malloc is used instead of 'new' to instantiate the struct framebuffer_device_t
* C++11 spec specifies that if a class/struct has a const member,default constructor
* is deleted. So, if 'new' is used to instantiate the class/struct, it will throw
* error complaining about deleted constructor. Even if the struct is wrapped in a class
* it will still try to use the base class constructor to initialize the members, resulting
* in error 'deleted constructor'.
* This leaves two options
* Option 1: initialize the const members at the instantiation time. With {value1, value2 ..}
* Which relies on the order of the members, and if members are reordered or a new member is introduced
* it will end up assiging wrong value to members. Designated assignment as well has been removed in C++11
* Option 2: use malloc instead of 'new' to allocate the class/struct and initialize the members in code.
* This is the only maintainable option available.
*/
framebuffer_device_t *dev = reinterpret_cast<framebuffer_device_t *>(malloc(sizeof(framebuffer_device_t)));
/* if either or both of init_frame_buffer() and malloc failed */
if ((status < 0) || (!dev))
{
#if GRALLOC_USE_GRALLOC1_API == 1
gralloc1_close(gralloc_device);
#else
gralloc_close(gralloc_device);
#endif
(!dev) ? (void)(status = -ENOMEM) : free(dev);
return status;
}
memset(dev, 0, sizeof(*dev));
/* initialize the procs */
dev->common.tag = HARDWARE_DEVICE_TAG;
dev->common.version = 0;
dev->common.module = const_cast<hw_module_t *>(module);
dev->common.close = fb_close;
dev->setSwapInterval = fb_set_swap_interval;
dev->post = fb_post;
dev->setUpdateRect = 0;
dev->compositionComplete = &compositionComplete;
int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);
const_cast<uint32_t &>(dev->flags) = 0;
const_cast<uint32_t &>(dev->width) = m->info.xres;
const_cast<uint32_t &>(dev->height) = m->info.yres;
const_cast<int &>(dev->stride) = stride;
#ifdef GRALLOC_16_BITS
const_cast<int &>(dev->format) = HAL_PIXEL_FORMAT_RGB_565;
#else
const_cast<int &>(dev->format) = HAL_PIXEL_FORMAT_BGRA_8888;
#endif
const_cast<float &>(dev->xdpi) = m->xdpi;
const_cast<float &>(dev->ydpi) = m->ydpi;
const_cast<float &>(dev->fps) = m->fps;
const_cast<int &>(dev->minSwapInterval) = 0;
const_cast<int &>(dev->maxSwapInterval) = 1;
*device = &dev->common;
gralloc_vsync_enable(dev);
return status;
}

View File

@ -0,0 +1,30 @@
/*
* Copyright (C) 2010 ARM Limited. All rights reserved.
*
* Copyright (C) 2008 The Android Open Source Project
*
* 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 <hardware/hardware.h>
#include "gralloc_priv.h"
// Create a framebuffer device
int framebuffer_device_open(hw_module_t const *module, const char *name, hw_device_t **device);
// Initialize the framebuffer (must keep module lock before calling
int init_frame_buffer_locked(struct private_module_t *module);
// Allocate framebuffer buffer
int fb_alloc_framebuffer(mali_gralloc_module *m, uint64_t consumer_usage, uint64_t producer_usage,
buffer_handle_t *pHandle, int *stride, int *byte_stride);

View File

@ -0,0 +1,145 @@
/*
* Copyright (C) 2014-2017 ARM Limited. All rights reserved.
*
* Copyright (C) 2008 The Android Open Source Project
*
* 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 <cutils/ashmem.h>
#include <log/log.h>
#include <sys/mman.h>
#if GRALLOC_USE_GRALLOC1_API == 1
#include <hardware/gralloc1.h>
#else
#include <hardware/gralloc.h>
#endif
#include "mali_gralloc_module.h"
#include "mali_gralloc_private_interface_types.h"
#include "mali_gralloc_buffer.h"
#include "gralloc_buffer_priv.h"
/*
* Allocate shared memory for attribute storage. Only to be
* used by gralloc internally.
*
* Return 0 on success.
*/
int gralloc_buffer_attr_allocate(private_handle_t *hnd)
{
int rval = -1;
if (!hnd)
{
goto out;
}
if (hnd->share_attr_fd >= 0)
{
ALOGW("Warning share attribute fd already exists during create. Closing.");
close(hnd->share_attr_fd);
}
hnd->share_attr_fd = ashmem_create_region("gralloc_shared_attr", PAGE_SIZE);
if (hnd->share_attr_fd < 0)
{
ALOGE("Failed to allocate page for shared attribute region");
goto err_ashmem;
}
/*
* Default protection on the shm region is PROT_EXEC | PROT_READ | PROT_WRITE.
*
* Personality flag READ_IMPLIES_EXEC which is used by some processes, namely gdbserver,
* causes a mmap with PROT_READ to be translated to PROT_READ | PROT_EXEC.
*
* If we were to drop PROT_EXEC here with a call to ashmem_set_prot_region()
* this can potentially cause clients to fail importing this gralloc attribute buffer
* with EPERM error since PROT_EXEC is not allowed.
*
* Because of this we keep the PROT_EXEC flag.
*/
hnd->attr_base = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_attr_fd, 0);
if (hnd->attr_base != MAP_FAILED)
{
/* The attribute region contains signed integers only.
* The reason for this is because we can set a value less than 0 for
* not-initialized values.
*/
attr_region *region = (attr_region *)hnd->attr_base;
memset(hnd->attr_base, 0xff, PAGE_SIZE);
munmap(hnd->attr_base, PAGE_SIZE);
hnd->attr_base = MAP_FAILED;
}
else
{
ALOGE("Failed to mmap shared attribute region");
goto err_ashmem;
}
rval = 0;
goto out;
err_ashmem:
if (hnd->share_attr_fd >= 0)
{
close(hnd->share_attr_fd);
hnd->share_attr_fd = -1;
}
out:
return rval;
}
/*
* Frees the shared memory allocated for attribute storage.
* Only to be used by gralloc internally.
* Return 0 on success.
*/
int gralloc_buffer_attr_free(private_handle_t *hnd)
{
int rval = -1;
if (!hnd)
{
goto out;
}
if (hnd->share_attr_fd < 0)
{
ALOGE("Shared attribute region not avail to free");
goto out;
}
if (hnd->attr_base != MAP_FAILED)
{
ALOGW("Warning shared attribute region mapped at free. Unmapping");
munmap(hnd->attr_base, PAGE_SIZE);
hnd->attr_base = MAP_FAILED;
}
close(hnd->share_attr_fd);
hnd->share_attr_fd = -1;
rval = 0;
out:
return rval;
}

View File

@ -0,0 +1,203 @@
/*
* Copyright (C) 2014-2017 ARM Limited. All rights reserved.
*
* Copyright (C) 2008 The Android Open Source Project
*
* 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 GRALLOC_BUFFER_PRIV_H_
#define GRALLOC_BUFFER_PRIV_H_
#include "gralloc_priv.h"
#include <errno.h>
#include <string.h>
#include "mali_gralloc_private_interface_types.h"
// private gralloc buffer manipulation API
struct attr_region
{
/* Rectangle to be cropped from the full frame (Origin in top-left corner!) */
int crop_top;
int crop_left;
int crop_height;
int crop_width;
int use_yuv_transform;
int use_sparse_alloc;
} __attribute__((packed));
typedef struct attr_region attr_region;
/*
* Allocate shared memory for attribute storage. Only to be
* used by gralloc internally.
*
* Return 0 on success.
*/
int gralloc_buffer_attr_allocate(struct private_handle_t *hnd);
/*
* Frees the shared memory allocated for attribute storage.
* Only to be used by gralloc internally.
* Return 0 on success.
*/
int gralloc_buffer_attr_free(struct private_handle_t *hnd);
/*
* Map the attribute storage area before attempting to
* read/write from it.
*
* Return 0 on success.
*/
static inline int gralloc_buffer_attr_map(struct private_handle_t *hnd, int readwrite)
{
int rval = -1;
int prot_flags = PROT_READ;
if (!hnd)
{
goto out;
}
if (hnd->share_attr_fd < 0)
{
ALOGE("Shared attribute region not available to be mapped");
goto out;
}
if (readwrite)
{
prot_flags |= PROT_WRITE;
}
hnd->attr_base = mmap(NULL, PAGE_SIZE, prot_flags, MAP_SHARED, hnd->share_attr_fd, 0);
if (hnd->attr_base == MAP_FAILED)
{
ALOGE("Failed to mmap shared attribute region err=%s", strerror(errno));
goto out;
}
rval = 0;
out:
return rval;
}
/*
* Unmap the attribute storage area when done with it.
*
* Return 0 on success.
*/
static inline int gralloc_buffer_attr_unmap(struct private_handle_t *hnd)
{
int rval = -1;
if (!hnd)
{
goto out;
}
if (hnd->attr_base != MAP_FAILED)
{
if (munmap(hnd->attr_base, PAGE_SIZE) == 0)
{
hnd->attr_base = MAP_FAILED;
rval = 0;
}
}
out:
return rval;
}
/*
* Read or write an attribute from/to the storage area.
*
* Return 0 on success.
*/
static inline int gralloc_buffer_attr_write(struct private_handle_t *hnd, buf_attr attr, int *val)
{
int rval = -1;
if (!hnd || !val || attr >= GRALLOC_ARM_BUFFER_ATTR_LAST)
{
goto out;
}
if (hnd->attr_base != MAP_FAILED)
{
attr_region *region = (attr_region *)hnd->attr_base;
switch (attr)
{
case GRALLOC_ARM_BUFFER_ATTR_CROP_RECT:
memcpy(&region->crop_top, val, sizeof(int) * 4);
rval = 0;
break;
case GRALLOC_ARM_BUFFER_ATTR_AFBC_YUV_TRANS:
region->use_yuv_transform = *val;
rval = 0;
break;
case GRALLOC_ARM_BUFFER_ATTR_AFBC_SPARSE_ALLOC:
region->use_sparse_alloc = *val;
rval = 0;
break;
}
}
out:
return rval;
}
static inline int gralloc_buffer_attr_read(struct private_handle_t *hnd, buf_attr attr, int *val)
{
int rval = -1;
if (!hnd || !val || attr >= GRALLOC_ARM_BUFFER_ATTR_LAST)
{
goto out;
}
if (hnd->attr_base != MAP_FAILED)
{
attr_region *region = (attr_region *)hnd->attr_base;
switch (attr)
{
case GRALLOC_ARM_BUFFER_ATTR_CROP_RECT:
memcpy(val, &region->crop_top, sizeof(int) * 4);
rval = 0;
break;
case GRALLOC_ARM_BUFFER_ATTR_AFBC_YUV_TRANS:
*val = region->use_yuv_transform;
rval = 0;
break;
case GRALLOC_ARM_BUFFER_ATTR_AFBC_SPARSE_ALLOC:
*val = region->use_sparse_alloc;
rval = 0;
break;
}
}
out:
return rval;
}
#endif /* GRALLOC_BUFFER_PRIV_H_ */

View File

@ -0,0 +1,51 @@
/*
* Copyright (C) 2010-2017 ARM Limited. All rights reserved.
*
* Copyright (C) 2008 The Android Open Source Project
*
* 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 GRALLOC_HELPER_H_
#define GRALLOC_HELPER_H_
#include <sys/mman.h>
#include <android/log.h>
#ifndef AWAR
#define AWAR(fmt, args...) \
__android_log_print(ANDROID_LOG_WARN, "[Gralloc-Warning]", "%s:%d " fmt, __func__, __LINE__, ##args)
#endif
#ifndef AINF
#define AINF(fmt, args...) __android_log_print(ANDROID_LOG_INFO, "[Gralloc]", fmt, ##args)
#endif
#ifndef AERR
#define AERR(fmt, args...) \
__android_log_print(ANDROID_LOG_ERROR, "[Gralloc-ERROR]", "%s:%d " fmt, __func__, __LINE__, ##args)
#endif
#ifndef AERR_IF
#define AERR_IF(eq, fmt, args...) \
if ((eq)) \
AERR(fmt, args)
#endif
#define GRALLOC_ALIGN(value, base) (((value) + ((base)-1)) & ~((base)-1))
#define GRALLOC_UNUSED(x) ((void)x)
static inline size_t round_up_to_page_size(size_t x)
{
return (x + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
}
#endif /* GRALLOC_HELPER_H_ */

View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2017 ARM Limited. All rights reserved.
*
* Copyright (C) 2008 The Android Open Source Project
*
* 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 GRALLOC_PRIV_H_
#define GRALLOC_PRIV_H_
#include <stdint.h>
#include <pthread.h>
#include <errno.h>
#include <linux/fb.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
#include <cutils/native_handle.h>
#include <utils/Log.h>
#if GRALLOC_USE_GRALLOC1_API
#include <hardware/gralloc1.h>
#else
#include <hardware/gralloc.h>
#endif
/**
* mali_gralloc_formats.h needs the define for GRALLOC_MODULE_API_VERSION_0_3 and
* GRALLOC_MODULE_API_VERSION_1_0, so include <gralloc1.h> or <gralloc.h> before
* including mali_gralloc_formats.h
**/
#include "mali_gralloc_formats.h"
#include "mali_gralloc_usages.h"
#include "gralloc_helper.h"
#if defined(GRALLOC_MODULE_API_VERSION_0_3) || \
(defined(GRALLOC_MODULE_API_VERSION_1_0) && !defined(GRALLOC_DISABLE_PRIVATE_BUFFER_DEF))
/*
* This header file contains the private buffer definition. For gralloc 0.3 it will
* always be exposed, but for gralloc 1.0 it will be removed at some point in the future.
*
* GRALLOC_DISABLE_PRIVATE_BUFFER_DEF is intended for DDKs to test while implementing
* the new private API.
*/
#include "mali_gralloc_buffer.h"
#endif
#if defined(GRALLOC_MODULE_API_VERSION_1_0)
/* gralloc 1.0 supports the new private interface that abstracts
* the private buffer definition to a set of defined APIs.
*/
#include "mali_gralloc_private_interface.h"
#endif
#endif /* GRALLOC_PRIV_H_ */

Some files were not shown because too many files have changed in this diff Show More